From f71899e9c0a099e6afd71261dfe4bc09558447a1 Mon Sep 17 00:00:00 2001 From: William Mantly Date: Thu, 11 May 2023 11:09:50 -0400 Subject: [PATCH] added say command and comments --- nodejs/controller/commands/default.js | 9 +++ nodejs/controller/commands/invite.js | 15 ++--- nodejs/index.js | 2 - nodejs/model/minecraft.js | 79 +++++++++++++++++++-------- 4 files changed, 72 insertions(+), 33 deletions(-) diff --git a/nodejs/controller/commands/default.js b/nodejs/controller/commands/default.js index 6243f17..52b7ada 100644 --- a/nodejs/controller/commands/default.js +++ b/nodejs/controller/commands/default.js @@ -12,5 +12,14 @@ module.exports = { `${command} -- ${this.commands[command].desc || ''}` )); } + }, + 'say': { + desc: `Make the bot say stuff in chat`, + allowed: ['wmantly', 'useless666', 'tux4242'], + ignoreLock: true, + async function(from, ...messages){ + await this.say((messages || []).join(' ')); + } + } }; diff --git a/nodejs/controller/commands/invite.js b/nodejs/controller/commands/invite.js index dffff1e..9d6ff0a 100644 --- a/nodejs/controller/commands/invite.js +++ b/nodejs/controller/commands/invite.js @@ -35,7 +35,7 @@ let sites = { foend: { bot: 'ez', desc: `Get an invite to the Farming outpost in the end.`, - allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', 'pi_chef', '1_cut',], + allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', '1_cut',], }, sb: { bot: 'owen', @@ -47,11 +47,11 @@ let sites = { desc: `Get an invite to the Core.`, allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', 'pi_chef', '1_cut', 'Ethan63020', 'Ethan63021', 'VinceNL', 'nootbot'], }, - // city: { - // bot: 'art', - // desc: 'Invite to the city', - // allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'VinceNL', 'Ethan63020', 'Ethan63021'] - // }, + art: { + bot: 'art', + desc: 'Invite to art', + allowed: ['wmantly', 'useless666', 'tux4242'] + }, german: { bot: 'linda', desc: `Get an invite you Germans area.`, @@ -71,6 +71,7 @@ module.exports = { '.invite': { desc: `The bot will /accept an /invite from you.`, allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'pi_chef'], + ignoreLock: true, async function(from){ await this.whisper('Coming'); await this.say(`/accept`); @@ -78,7 +79,7 @@ module.exports = { }, 'inv': { desc: `Have bot.\n Site -- one'`, - // allowed: townMemebers, + ignoreLock: true, async function(from, site){ this.__unLockCommand(); diff --git a/nodejs/index.js b/nodejs/index.js index 7c157c0..07793cd 100644 --- a/nodejs/index.js +++ b/nodejs/index.js @@ -1,5 +1,3 @@ 'use strict'; const botController = require('./controller/mc-bot'); -// const chatController = require('./controller/mc-chatbot'); -// const actionController = require('./controller/mc-actionbot'); \ No newline at end of file diff --git a/nodejs/model/minecraft.js b/nodejs/model/minecraft.js index acbd16b..1b0d42e 100644 --- a/nodejs/model/minecraft.js +++ b/nodejs/model/minecraft.js @@ -8,33 +8,54 @@ class CJbot{ isReady = false; listeners = {}; + // Holds the minimum cool down time for chat messages nextChatTime = 1500; + + // Prevents executing commands while one is running commandLock = false; commandCollDownTime = 1500; + + // Holds the list of commands this bot can execute commands = {}; + + combatTag = false; doLogOut = false; + // Map of all the bots currently in use static bots = {}; + + // Forces the code to wait while until the bot is loaded before moving on to + // the next static __addLock = false; + + // Holds a list of bots that still needs to be connect static __toConnect = []; + constructor(args){ - this.name = args.name; + + // Friendly name to access the bot in `CJbot.bots` + this.name = args.name || args.username; this.username = args.username; this.password = args.password; this.host = args.host; this.auth = args.auth || 'microsoft'; this.version = args.version || '1.19.2'; + + // States if the bot should connect when its loaded this.autoReConnect = 'autoConnect' in args ? args.autoReConnect : true; this.autoConnect = 'autoConnect' in args ? args.autoConnect : true; + // If we want the be always connected, kick off the function to auto + // reconnect if(this.autoReConnect) this.__autoReConnect() } connect(){ return new Promise((resolve, reject) =>{ + // Create the mineflayer instance this.bot = mineflayer.createBot({ host: this.host, username: this.username, @@ -43,43 +64,51 @@ class CJbot{ auth: this.auth, }); - // this.bot.on('message', (m)=> console.log(m.toString())) - this.bot.on('error', (m)=>{ + // If an error happens before the login event, toss an error back to + // the caller of the function + let onError = this.bot.on('error', (m)=>{ console.log(this.bot.version, m.toString()) reject(m) }) + // If the connection ends before the login event, toss an error back + // to the caller of the function this.bot.on('end', (m)=>{ console.log(this.name, 'Connection ended:', m); this.isReady = false; reject(m); }); + // When the bot is ready, return to the caller success this.bot.on('login', ()=>{ this.__onReady() resolve() }); + // Set a timer to try to connect again in 30 seconds if the bot is + // not connected setTimeout(async ()=>{try{ if(this.autoReConnect && !this.isReady) await this.connect(); }catch(error){ - console.error('minecraft.js/connect/setTimeout/', this.name, ' ', error) + console.error('minecraft.js | connect | setTimeout |', this.name, ' ', error) }}, 30000); }); } - static - + // Wrap the once method so it works correctly with await once(event){ return new Promise((resolve, reject)=> this.bot.once(event, resolve)); } + // Internal method to kick off the functionality after its loaded in the + // server async __onReady(){try{ + // Add the listeners to the bot. We do this so if the bot loses + // connection, the mineflayer instance will also be lost. this.__startListeners(); - // console.log('listeners', this.listeners.onReady) - + // Call the internal listeners when the bot is ready for(let callback of this.listeners.onReady || []){ console.log('calling listener', callback) await callback(this) @@ -93,10 +122,9 @@ class CJbot{ this.__listen(); }catch(error){ - console.error('minecraft.js/__onReady/', this.name, ' ', error) + console.error('minecraft.js | __onReady | ', this.name, ' ', error) }} - __startListeners(){ for(let event in this.listeners){ for(let callback of this.listeners[event]){ @@ -105,11 +133,14 @@ class CJbot{ } } + // Wrap the .on method so we can hold the listeners internally on(event, callback){ if(!this.listeners[event]) this.listeners[event] = []; this.listeners[event].push(callback); + // If the bot is already loaded, add the passed listener to the + // mineflayer instance if(this.isReady){ if(event === 'onReady') callback(this); else this.bot.on(event, callback); @@ -118,13 +149,16 @@ class CJbot{ return event === 'onReady' ? true : ()=> this.bot.off(listener, callback); } + // todo; add .off wrapper + + // Listen for ending events and call connect again __autoReConnect(){ try{ console.log('auto connect function') this.on('end', async (reason)=>{ console.error('_autorestart MC on end', reason) - await sleep('30000') + await sleep(30000) this.connect() }); @@ -137,7 +171,6 @@ class CJbot{ }); }catch(error){ console.error('error in __autoReConnect', error); - } } @@ -148,6 +181,15 @@ class CJbot{ } + quit(force){ + if(!this.combatTag || force){ + this.bot.quit(); + }else{ + console.log('Logout prevented due to combatTag'); + this.doLogOut = true; + } + } + /* Chat and messaging*/ __listen(){ @@ -176,8 +218,6 @@ class CJbot{ if(message.toString().includes(' invited you to teleport to him.')){ // teleport invite - // console.log('ChatBot on message', message.toString()) - console.log('found teleport', message.toString().split(' ')[0]) this.__doCommand(message.toString().split(' ')[0], '.invite'); } @@ -206,15 +246,6 @@ class CJbot{ }); } - quit(force){ - if(!this.combatTag || force){ - this.bot.quit(); - }else{ - console.log('Logout prevented due to combatTag'); - this.doLogOut = true; - } - } - __chatCoolDown(){ return Math.floor(Math.random() * (3000 - 1500) + 1500); } @@ -269,7 +300,7 @@ class CJbot{ this.whisper(from, `I dont know anything about ${cmd}`); } }catch(error){ - console.error('minecraft.js/__doCommand/', this.name, ' ', error) + console.error('minecraft.js | __doCommand |', this.name, ' ', error) }} addCommand(name, obj){