Пишем себе подчиненного(пока только в Minecraft) (Часть 1)

При помощи Node JS и API mineflayer

Для Minecraft существует несколько API для создания ботов, я расскажу о самой популярной из них, mineflayer.

Я, к слову, далеко не специалист в js так что могу допускать кучу ошибок. В следующей части обещаю рассмотреть интересные плагины и более сложные методы

Mineflayer

Mineflayer — высокоуровневое API написанное на Node. js.

Разработчики постоянно его обновляют, тем не менее API всё ещё не поддерживает версию 1.19, посему «подчиненного» мы будем писать на версии 1.18.2.

У mineflayer есть собственный сайт Там указан подробный список фич и модулей апи, видео-туториалы, примеры и список сторонних плагинов дополняющих оригинальный API.

Это апи мы и будем использовать для создания бота.

Собственно начинаем создавать «подчиненного»

Скачиваем Node. js с официального сайта и прописывайте npm install mineflayer в консоль дабы установить API

Далее заходим в Minecraft, создаем новый мир и открываем его для локальной сети. Получаем порт

Пишем себе подчиненного(пока только в Minecraft) (Часть 1)

Теперь нам нужно создать. js файл где мы собственно и будем писать нашего бота. Для меня это dtf. js

Редактировать его можно и в блокноте, но я рекомендую воспользоваться месячным пробным IDE - WebStorm от JetBrains.
Редактировать его можно и в блокноте, но я рекомендую воспользоваться месячным пробным IDE - WebStorm от JetBrains.

Начинаем писать бота

Для начала стоит импортировать библиотеку и создать бота. У бота есть множество параметров. Основные — host, port, username. host отвечает за IP на которое бот будет заходить(в нашем случае — «localhost« или-же »127.0.0.1» поскольку машина должна подключаться к миру в локальной сети). port отвечает за порт на который будет заходить бот, нужно указать тот что вы получили при открытии мира для сети. username отвечает за никнейм бота на сервере. В моем случае это DTFBot, вы можете указать любой.

const mineflayer = require("mineflayer"); const bot = mineflayer.createBot({host: 'localhost', port: 60179, username: 'DTFBot'})

Уже на данном этапе вы можете запустить бота при помощи node ваш_файл. js, и он даже зайдет в мир! Правда не будет ничего делать.

Добавляем первые функции

Давайте научим нашего бота говорить хоть что-то. Например «Я родился» при появлении в мире

const mineflayer = require("mineflayer"); const bot = mineflayer.createBot({host: 'localhost', port: 60179, username: 'DTFBot'}) bot.once('spawn', function () { bot.chat('Я родился') })

Результат:

При ивенте "spawn" вызывается метод chat и бот выводит в чат определенный текст. Список ивентов и методов с относительно подробными описаниями можно посмотреть в официальном <a href="https://github.com/PrismarineJS/mineflayer/blob/master/docs/api.md" rel="nofollow noreferrer noopener" target="_blank">api.md</a>
При ивенте "spawn" вызывается метод chat и бот выводит в чат определенный текст. Список ивентов и методов с относительно подробными описаниями можно посмотреть в официальном api.md

Реакция на сообщения

Научим бота реагировать на слова начальника, а то какой-же тогда будет подчиненный?

const mineflayer = require("mineflayer"); const bot = mineflayer.createBot({host: 'localhost', port: 60179, username: 'DTFBot'}) bot.once('spawn', function () { bot.chat('Я родился') }) bot.on('chat', function (username, message) { if(message === "Работать, огузок"){ bot.chat('(') } })
В этом примере всё ещё используется ивент, но уже с 2-мя параметрами. Никнейм игрока и сообщение. Каждый раз когда кто-то пишет в чат бот проверяет текст сообщения и если это "Работать, огузок" написанное начальником он откликается.
В этом примере всё ещё используется ивент, но уже с 2-мя параметрами. Никнейм игрока и сообщение. Каждый раз когда кто-то пишет в чат бот проверяет текст сообщения и если это "Работать, огузок" написанное начальником он откликается.

Учим бота защищать начальника

Как каждый самурай должен быть готов отдать жизнь за своего господина, так каждый подчиненный должен быть готов биться за своего начальника. Поскольку у mineflayer довольно гибкая система взаимодействия с энтити мы можем легко это реализовать!

Защищать нас бот будет от глупых крестьян не имеющих даже пары миллионов наличными.

const mineflayer = require("mineflayer"); const bot = mineflayer.createBot({host: 'localhost', port: 60179, username: 'DTFBot'}) bot.once('spawn', function () { bot.chat('Я родился') setInterval(() => { const sword = bot.inventory.items().find(item => item.name.includes('sword')) if (sword) bot.equip(sword, 'hand') const villagerFilter = e => e.type === 'mob' && e.mobType === 'Villager' const villager = bot.nearestEntity(villagerFilter) if (!villager) return; const pos = villager.position; bot.lookAt(pos); bot.attack(villager); }, 1000); }) bot.on('chat', function (username, message) { if(message === "Работать, огузок" && username === 'Grammf'){ bot.chat('(') } })

Теперь после появления в мире каждую секунду бот будет пытаться атаковать ближайшего крестьянина вооружившись мечём если таковой есть в инвентаре. Сначала бот ищет в инвентаре Item в названии которого есть «меч», а затем берет его в руку при помощи bot. equip. Вооружившись мечем бот ищет ближайшего крестьянина по фильтру villagerFilter и атакует его если видит.

Пишем себе подчиненного(пока только в Minecraft) (Часть 1)

Учим подчиненного ходить за начальником

А если начальник решит пройтись? Что бот будет делать? Да ничего, просто стоять на месте. Исправляем!

Тут нам понадобится плагин mineflayer-pathfinder что добавляет возможность пазфайндинга в бота

Устанавливаем его при помощи npm install mineflayer-pathfinder и начинаем работу.

Импортируем пазфайндер и основные его цели при помощи

const {pathfinder, Movements, goals: {GoalNear, GoalBlock, GoalFollow}} = require('mineflayer-pathfinder');

и загружаем его после объявления бота при помощи

bot.loadPlugin(pathfinder);

Так-же нам понадобится minecraft-data

const mcData = require('minecraft-data')(bot.version)

Теперь нам остается только добавить комманды «За мной«, «Ко мне» и »Остановись».

const mineflayer = require("mineflayer"); const {pathfinder, Movements, goals: {GoalNear, GoalBlock, GoalFollow}} = require('mineflayer-pathfinder'); const bot = mineflayer.createBot({host: 'localhost', port: 60179, username: 'DTFBot'}) bot.loadPlugin(pathfinder); bot.once('spawn', function () { const mcData = require('minecraft-data')(bot.version) const defaultMove = new Movements(bot, mcData) bot.chat('Я родился') setInterval(() => { const sword = bot.inventory.items().find(item => item.name.includes('sword')) if (sword) bot.equip(sword, 'hand') const villagerFilter = e => e.type === 'mob' && e.mobType === 'Villager' const villager = bot.nearestEntity(villagerFilter) if (!villager) return; const pos = villager.position; bot.lookAt(pos); bot.attack(villager); }, 1000); }) bot.on('chat', function (username, message) { if(username !== "Grammf") return; if(message === "Работать, огузок"){ bot.chat('(') } if(message === "За мной"){ const player = bot.players[username] bot.pathfinder.setGoal(new GoalFollow(player.entity, 1), true) } if(message === "Ко мне"){ const player = bot.players[username] bot.pathfinder.setGoal(new GoalNear(player.entity.position.x, player.entity.position.y, player.entity.position.z, 1)) } if(message === "Остановись"){ bot.pathfinder.setGoal(null, 1) } })

После получения комманды бот получает игрока написавшего комманду по его никнейму и создает Goal на его основе. В данном случае это GoalFollow которая дает боту комманду следовать за определенным энтити и GoalNear дающая боту комманду подойти недалеко от указанных координат. Что-бы остановиться мы просто обнуляем Goal

Пишем себе подчиненного(пока только в Minecraft) (Часть 1)

Наблюдаем за работником

Никакой свободы сотрудникам, будем за ними следить!
Для этого нам понадобится prismarine-viewer

По привычной схеме устанавливаем prismarine-viewer и импортируем его в бота

const mineflayerViewer = require('prismarine-viewer').mineflayer

Затем добавляем запуск вьювера на порте 3000 в код

const mineflayer = require("mineflayer"); const {pathfinder, Movements, goals: {GoalNear, GoalBlock, GoalFollow}} = require('mineflayer-pathfinder'); const bot = mineflayer.createBot({host: 'localhost', port: 60179, username: 'DTFBot'}) const mineflayerViewer = require('prismarine-viewer').mineflayer bot.loadPlugin(pathfinder); bot.once('spawn', function () { mineflayerViewer(bot, { firstPerson: true, port: 3000 }) const mcData = require('minecraft-data')(bot.version) const defaultMove = new Movements(bot, mcData) bot.chat('Я родился') setInterval(() => { const sword = bot.inventory.items().find(item => item.name.includes('sword')) if (sword) bot.equip(sword, 'hand') const villagerFilter = e => e.type === 'mob' && e.mobType === 'Villager' const villager = bot.nearestEntity(villagerFilter) if (!villager) return; const pos = villager.position; bot.lookAt(pos); bot.attack(villager); }, 1000); }) bot.on('chat', function (username, message) { if(username !== "Grammf") return; if(message === "Работать, огузок"){ bot.chat('(') } if(message === "За мной"){ const player = bot.players[username] bot.pathfinder.setGoal(new GoalFollow(player.entity, 1), true) } if(message === "Ко мне"){ const player = bot.players[username] bot.pathfinder.setGoal(new GoalNear(player.entity.position.x, player.entity.position.y, player.entity.position.z, 1)) } if(message === "Остановись"){ bot.pathfinder.setGoal(null, 1) } })

Готово! Веб сервер запускается и достаточно перейти в браузере на localhost:3000 как вам откроется вид от первого лица бота

У меня блоки не загрузились, но у вас этой проблемы быть не должно
У меня блоки не загрузились, но у вас этой проблемы быть не должно

А если начальник покушать захочет?

У майнфлеера есть и довольно специфичные методы, давайте их используем!

if (message === "Порыбачь!") { const rod = bot.inventory.items().find(item => item.name.includes('rod')) if (rod) bot.equip(rod, 'hand') bot.fish() }

Простой код что заставляет бота взять в руки удочку и воспользоваться ею. Как только бот увидит что рыба клюет он её подцепит.

Пишем себе подчиненного(пока только в Minecraft) (Часть 1)

Плагины

Для mineflayer есть множество интересных плагинов. Лично я рекомендую

Они наиболее хорошо расширяют возможности API

Обязательно посмотрите видео-туториалы по mineflayer
Удачи вам в создании эффективных сотрудников

3030
49 комментариев

Там где много ифов имхо симпатичнее будет смотреться свитч кейс

1
Ответить

Свитчкейс ещё и быстрее работают (если компилятор не додумался ифы свернуть в него)

1
Ответить

И function declaration это уже моветон имхо опять же

Ответить

Комментарий недоступен

1
Ответить

Конечно можно, mineflayer-collectblock позволяет собирать блоки разнообразные. Можно даже сделать баритон на "радио управлении"

Ответить

а можно его на сервера с регистрацией засунуть и потом на СкайПвп переместить ? или чтоб он пати принимал

Ответить

Конечно можно. У меня даже есть бот который капчу умеет решать

Ответить