forked from wmantly/mc-bot-town
		
	multi bots online
This commit is contained in:
		| @ -1,12 +1,12 @@ | ||||
| module.exports = { | ||||
| 	"mc": { | ||||
| 		"server": "corejourney.org._vAUTO.mc.proxy", | ||||
| 		"bots": { | ||||
| 			"bot_name": { | ||||
| 				"username": "<configure in secrets>", | ||||
| 				"password": "<configure in secrets>", | ||||
| 				'auth': "microsoft" | ||||
| 			} | ||||
| 		} | ||||
| 		"host": "corejourney.org", | ||||
| 		// "bots": { | ||||
| 		// 	"bot_name": { | ||||
| 		// 		"username": "<configure in secrets>", | ||||
| 		// 		"password": "<configure in secrets>", | ||||
| 		// 		'auth': "microsoft" | ||||
| 		// 	} | ||||
| 		// } | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										16
									
								
								nodejs/controller/commands/default.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								nodejs/controller/commands/default.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| module.exports =  { | ||||
| 	'help': { | ||||
| 	    desc: `Print the allowed commands.`, | ||||
| 	    async function(from){ | ||||
| 	        console.log('called help', from) | ||||
| 	        let intro = [ | ||||
| 	            'I am a bot owned and operated by', | ||||
| 	            'wmantly <wmantly@gmail.com>', | ||||
| 	            'You have access to the following commands:' | ||||
| 	        ] | ||||
| 	        await this.whisper(from, ...intro, ...this.__reduceCommands(from).map(command => | ||||
| 	            `${command} -- ${this.commands[command].desc || ''}` | ||||
| 	        )); | ||||
| 	    } | ||||
| 	} | ||||
| }; | ||||
							
								
								
									
										161
									
								
								nodejs/controller/commands/fun.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								nodejs/controller/commands/fun.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,161 @@ | ||||
| let ballOptions = [ | ||||
|     "It is certain.", | ||||
|     "It is decidedly so.", | ||||
|     "Without a doubt.", | ||||
|     "Yes definitely.", | ||||
|     "You may rely on it.", | ||||
|     "As I see it, yes.", | ||||
|     "Most likely.", | ||||
|     "Outlook good.", | ||||
|     "The Core gods will it to be!", | ||||
|     "Yes.", | ||||
|     "Signs point to yes.", | ||||
|     "Reply hazy, try again.", | ||||
|     "You should ask Ethan", | ||||
|     "Ask again later.", | ||||
|     "Better not tell you now.", | ||||
|     "Cannot predict now.", | ||||
|     "Concentrate and ask again.", | ||||
|     "You will find the answers during you journey to The Core!", | ||||
|     "Don't count on it.", | ||||
|     "My reply is no.", | ||||
|     "My sources say no.", | ||||
|     "Outlook not so good.", | ||||
|     "Very doubtful.", | ||||
| ]; | ||||
|  | ||||
|  | ||||
| module.exports = { | ||||
|     '8ball':{ | ||||
|         desc: `magic 8 Ball pick.`, | ||||
|         async function(from){ | ||||
|             await this.say( | ||||
|                 `> The 8 Ball says...`, | ||||
|                 `> ${ballOptions[Math.floor(Math.random()*ballOptions.length)]}` | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // bot.addCommand("joke", { | ||||
| //     desc: "Tells a random joke.", | ||||
| //     async function(from){ | ||||
| //         await this.say('> Let me think...'); | ||||
| //         let res = await axios.get('https://v2.jokeapi.dev/joke/Any?type=single') | ||||
| //         await this.say(...res.data.joke.split('\n').map(e => `> ${e}`)); | ||||
| //     }, | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand("quote", { | ||||
| //     desc: 'Say an inspirational quote.', | ||||
| //     async function(from){ | ||||
| //         await this.say('> Right away!'); | ||||
| //         let res = await axios.get('https://zenquotes.io/api/random') | ||||
| //         await this.say(`> ${res.data[0].q} -- ${res.data[0].a}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('west-quote', {  | ||||
| //     desc: `Say a random Kanye West quote.`, | ||||
| //     async function(from) { | ||||
| //         await this.say('> And here we go!'); | ||||
| //         let res = await axios.get('https://api.kanye.rest/'); | ||||
| //         await this.say(`> ${res.data.quote} -- Kanye West`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('pink-quote', {  | ||||
| //     desc: `Say a random Pink Floyd quote.`, | ||||
| //     async function(from) { | ||||
| //         await this.say( | ||||
| //             `> Rock 'n' Roll`, | ||||
| //             `> ${pink_quotes[Math.floor(Math.random()*pink_quotes.length)]} -- Pink Floyd` | ||||
| //         );         | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand("fact", { | ||||
| //     desc: `Say a random fact.`, | ||||
| //     async function(from){ | ||||
| //         await this.say('> The internet says this is true?'); | ||||
| //         let res = await axios.get('https://uselessfacts.jsph.pl/random.json?language=en') | ||||
| //         await this.say( | ||||
| //             `> ${res.data.text}`, | ||||
| //             `> source: ${res.data.source}` | ||||
| //         ); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand("advice", {  | ||||
| //     desc: `Say some random advice.`, | ||||
| //     async function(from){ | ||||
| //         await this.say('> Try this:'); | ||||
| //         let res = await axios.get('https://api.adviceslip.com/advice'); | ||||
| //         await this.say(`> ${res.data.slip.advice}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('idea', { | ||||
| //     desc: `Say a random start up idea.`, | ||||
| //     async function(from){ | ||||
| //         await this.say('> How about?'); | ||||
| //         let res = await axios.get('https://itsthisforthis.com/api.php?text') | ||||
| //         await this.say(`> ${res.data}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('discord', { | ||||
| //     desc: `Say the CJ discord invite link.`, | ||||
| //     async function(from) { | ||||
| //         await this.say('https://discord.gg/hyby9m8'); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('dice',{ | ||||
| //     desc: `Roll a die. You can state the max size on the dice. Default is 6.`, | ||||
| //     async function(from, size){ | ||||
| //         size = size || 6; | ||||
| //         if(!Number.isInteger(Number(size))){ | ||||
| //             this.whisper(from, `${size} is not a whole number...`) | ||||
| //             return ; | ||||
| //         } | ||||
| //         await this.say( | ||||
| //             `> Rolling a dice for ${from}`, | ||||
| //             `> ${Math.floor(Math.random()*size)+1}` | ||||
| //         ); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('random-player', { | ||||
| //     desc: `Return a random online player.`, | ||||
| //     async function(from){ | ||||
| //         let players = bot.getPlayers() | ||||
|          | ||||
| //         delete players[bot.bot.entity.username] | ||||
|  | ||||
| //         let keys = Object.keys(players); | ||||
| //         let player = players[keys[ keys.length * Math.random() << 0]]; | ||||
|  | ||||
| //         await this.say(`> I pick [${player.lvl}]${player.username}`) | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| // bot.addCommand('flip', { | ||||
| //     desc: `Flip a coin.`, | ||||
| //     async function(from){ | ||||
| //         await this.say( | ||||
| //             `> Flipping a coin for ${from}`, | ||||
| //             `> ${!!(Math.floor(Math.random() * (3000 - 1500) + 1500)%2) ? "Heads" : "Tails"}` | ||||
| //         ); | ||||
| //     } | ||||
| // }); | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										7
									
								
								nodejs/controller/commands/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								nodejs/controller/commands/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| module.exports = { | ||||
| 	default: require('./default'), | ||||
| 	fun: require('./fun'), | ||||
| 	invite: require('./invite'), | ||||
| }; | ||||
							
								
								
									
										103
									
								
								nodejs/controller/commands/invite.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								nodejs/controller/commands/invite.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const {sleep} = require('../../utils'); | ||||
|  | ||||
| let myAccounts = ['wmantly', 'useless666', 'tux4242'] | ||||
|  | ||||
| let germans = ['YTMatze', 'mytzor'] | ||||
|  | ||||
| let townMemebers = [ | ||||
|     'wmantly', 'useless666', 'tux4242',  | ||||
|     'VinceNL', | ||||
|     'Ethan63020', 'Ethan63021',  | ||||
|     'pi_chef',  | ||||
|     'EXLAlphaWolf', 'Sillychubbs', | ||||
|     'BearSkates420', 'hloop',  | ||||
|     'ogeiDNight', 'BobinaBlu', 'Roby_G_27', | ||||
|     'kawiimeowz', 'RaindropCake24', 'KimiKava', | ||||
|     'Keebyys', | ||||
|     'YTMatze', 'mytzor', | ||||
|     'jj_disaster', 'Cuttaway', | ||||
|     'sonic_joe', | ||||
| ] | ||||
|  | ||||
| let sites = { | ||||
|     fo: { | ||||
|         bot: 'jimin', | ||||
|         desc: `Get an invite to the Farming outpost.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', 'pi_chef', '1_cut', 'nootbot', 'VinceNL', 'Ethan63020', 'Ethan63021', 'KimiKava', 'kawiimeowz', 'RaindropCake24'], | ||||
|     }, | ||||
|     fo2: { | ||||
|         bot: 'henry', | ||||
|         desc: `Get an invite to the Farming outpost 2.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', 'pi_chef', '1_cut', 'Ethan63020', 'Ethan63021', 'VinceNL', 'nootbot'], | ||||
|     }, | ||||
|     foend: { | ||||
|         bot: 'ez', | ||||
|         desc: `Get an invite to the Farming outpost in the end.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', 'pi_chef', '1_cut',], | ||||
|     }, | ||||
|     sb: { | ||||
|         bot: 'owen', | ||||
|         desc: `Get an invite to the Sky Base.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef', 'pi_chef', '1_cut', 'Ethan63020', 'Ethan63021', 'VinceNL', 'nootbot'], | ||||
|     }, | ||||
|     core: { | ||||
|         bot: 'nova', | ||||
|         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'] | ||||
|     // }, | ||||
|     german: { | ||||
|         bot: 'linda', | ||||
|         desc: `Get an invite you Germans area.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'VinceNL', 'Ethan63020', 'Ethan63021', 'pi_chef', 'YTMatze', 'mytzor', 'pi_chef', '1_cut', 'nootbot'], | ||||
|     }, | ||||
| } | ||||
|  | ||||
| function getSiteFromBot(name){ | ||||
|     for(let site in sites){ | ||||
|         if(sites[site].bot === name){ | ||||
|             return sites[site]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
| 	'inv': { | ||||
| 	    desc: `Have bot.\n  Site -- one'`, | ||||
| 	    // allowed: townMemebers, | ||||
| 	    async function(from, site){ | ||||
|             this.__unLockCommand(); | ||||
|  | ||||
|             if(sites[site] && sites[site].allowed.includes(from)){ | ||||
|                 let bot = this.constructor.bots[sites[site].bot]; | ||||
|  | ||||
|                 if(!bot.isReady){ | ||||
|                     try{ | ||||
|                         await bot.connect(); | ||||
|                     }catch(error){ | ||||
|                         console.log('inv error connecting to bot'); | ||||
|                         this.whisper('Bot is not available right now, try again in 30 seconds.'); | ||||
|                     } | ||||
|                     var clear = setTimeout(()=> bot.quit(), 10000); | ||||
|                 } | ||||
|                 await bot.bot.chat(`/invite ${from}`); | ||||
|                 await bot.whisper(from, `accept invite from ${bot.bot.entity.username} within 10 seconds...`); | ||||
|                 bot.on('message', (message) =>{ | ||||
|                     if(message.toString() === `${from} teleported to you.`){ | ||||
|                         if(clear){ | ||||
|                             clearTimeout(clear); | ||||
|                             bot.quit(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
| 	    } | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| @ -1,55 +1,48 @@ | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| const {sleep} = require('../utils'); | ||||
| const conf = require('../conf'); | ||||
| const {CJbot} = require('../model/minecraft'); | ||||
| const inventoryViewer = require('mineflayer-web-inventory'); | ||||
| // const inventoryViewer = require('mineflayer-web-inventory'); | ||||
|  | ||||
| const bot = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	...conf.mc.bots.art | ||||
| }); | ||||
|  | ||||
| const henry = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	autoConnect: false, | ||||
| 	__autoReConnect: false, | ||||
| 	...conf.mc.bots.henry | ||||
| }); | ||||
|  | ||||
| const nova = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	autoConnect: false, | ||||
| 	__autoReConnect: false, | ||||
| 	...conf.mc.bots.nova | ||||
| }); | ||||
|  | ||||
| const owen = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	autoConnect: false, | ||||
| 	__autoReConnect: false, | ||||
| 	...conf.mc.bots.owen | ||||
| }); | ||||
|  | ||||
| const linda = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	autoConnect: false, | ||||
| 	__autoReConnect: false, | ||||
| 	...conf.mc.bots.linda | ||||
| }); | ||||
|  | ||||
| const jimin = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	autoConnect: false, | ||||
| 	__autoReConnect: false, | ||||
| 	...conf.mc.bots.jimin | ||||
| }); | ||||
|  | ||||
| const ez = new CJbot({ | ||||
| 	host: conf.mc.server, | ||||
| 	autoConnect: false, | ||||
| 	__autoReConnect: false, | ||||
| 	...conf.mc.bots.ez | ||||
| }); | ||||
| const commands = require('./commands'); | ||||
|  | ||||
|  | ||||
| module.exports = {bot, henry, owen, linda, jimin, nova, ez}; | ||||
| for(let name in conf.mc.bots){ | ||||
| 	if(CJbot.bots[name]) continue; | ||||
| 	let bot = new CJbot({name, host: conf.mc.host, ...conf.mc.bots[name]}); | ||||
| 	CJbot.bots[name] = bot; | ||||
|  | ||||
|  | ||||
| 	for(let command of conf.mc.bots[name].commands || ['default']){ | ||||
|  | ||||
| 		for(let [name, toAdd] of Object.entries(commands[command])){ | ||||
| 			bot.addCommand(name, toAdd) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| (async ()=>{ | ||||
| try{ | ||||
| 	for(let name in CJbot.bots){ | ||||
| 		let bot = CJbot.bots[name]; | ||||
| 		if(bot.autoConnect){ | ||||
| 			console.log('Trying to connect', name) | ||||
| 			console.log('Status for', name, await bot.connect()); | ||||
|  | ||||
| 			await sleep(30000); | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| }catch(e){ | ||||
|  | ||||
| 	console.log('!!!!!!!! error:', e) | ||||
| }})() | ||||
|  | ||||
| // module.exports = {bot: ez, henry, owen, linda, jimin, nova, ez}; | ||||
|  | ||||
| @ -4,9 +4,49 @@ const axios = require('axios'); | ||||
| const {sleep} = require('../utils'); | ||||
| const conf = require('../conf'); | ||||
|  | ||||
| const {bot, henry, owen, linda, jimin, nova, ez} = require('./mc-bot'); | ||||
| const pink_quotes = require('../model/pink_quotes') | ||||
|  | ||||
|  | ||||
| let sites = { | ||||
|     city: { | ||||
|         bot: art, | ||||
|         desc: 'Invite to the city', | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
|     core: { | ||||
|         bot: nova, | ||||
|         desc: `Get an invite to New Detroit.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
|     sb: { | ||||
|         bot:owen, | ||||
|         desc: `Get an invite to the Sky Base.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'VinceNL', 'Ethan63020', 'Ethan63021'], | ||||
|     }, | ||||
|     fo: { | ||||
|         bot: jimin, | ||||
|         desc: `Get an invite to the Farming outpost.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
|     fo2: { | ||||
|         bot:henry, | ||||
|         desc: `Get an invite to the Farming outpost 2.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
|     german: { | ||||
|         bot:linda, | ||||
|         desc: `Get an invite you Germans area.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'VinceNL', 'Ethan63020', 'Ethan63021', 'pi_chef', 'YTMatze', 'mytzor'], | ||||
|     }, | ||||
|     foend: { | ||||
|         bot: ez, | ||||
|         desc: `Get an invite to the Farming outpost in the end.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
| } | ||||
|  | ||||
| console.log('HERERERER SITESSSS', sites) | ||||
|  | ||||
| let myAccounts = ['wmantly', 'useless666', 'tux4242'] | ||||
|  | ||||
| let germans = ['YTMatze', 'mytzor'] | ||||
| @ -36,13 +76,16 @@ let ballOptions = [ | ||||
|     "As I see it, yes.", | ||||
|     "Most likely.", | ||||
|     "Outlook good.", | ||||
|     "The Core gods will it to be!", | ||||
|     "Yes.", | ||||
|     "Signs point to yes.", | ||||
|     "Reply hazy, try again.", | ||||
|     "You should ask Ethan", | ||||
|     "Ask again later.", | ||||
|     "Better not tell you now.", | ||||
|     "Cannot predict now.", | ||||
|     "Concentrate and ask again.", | ||||
|     "You will find the answers during you journey to The Core!", | ||||
|     "Don't count on it.", | ||||
|     "My reply is no.", | ||||
|     "My sources say no.", | ||||
| @ -50,240 +93,218 @@ let ballOptions = [ | ||||
|     "Very doubtful.", | ||||
| ]; | ||||
|  | ||||
| let sites = { | ||||
|     city: { | ||||
|         bot: bot, | ||||
|         desc: 'Invite to the city', | ||||
|         allowed: townMemebers | ||||
|     }, | ||||
|     nd: { | ||||
|         bot: nova, | ||||
|         desc: `Get an invite to New Detroit.`, | ||||
|         allowed: townMemebers, | ||||
|     }, | ||||
|     sb: { | ||||
|         bot:owen, | ||||
|         desc: `Get an invite to the Sky Base.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'VinceNL', 'Ethan63020', 'Ethan63021'], | ||||
|     }, | ||||
|     fo: { | ||||
|         bot: jimin, | ||||
|         desc: `Get an invite to the Farming outpost.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
|     fo2: { | ||||
|         bot:henry, | ||||
|         desc: `Get an invite to the Farming outpost 2.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
|     german: { | ||||
|         bot:linda, | ||||
|         desc: `Get an invite you Germans area.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'VinceNL', 'Ethan63020', 'Ethan63021', 'pi_chef', 'YTMatze', 'mytzor'], | ||||
|     }, | ||||
|     foend: { | ||||
|         bot: ez, | ||||
|         desc: `Get an invite to the Farming outpost in the end.`, | ||||
|         allowed: ['wmantly', 'useless666', 'tux4242', 'pi_chef'], | ||||
|     }, | ||||
| } | ||||
|  | ||||
|  | ||||
| async function offSiteInvite(from, site){ | ||||
|     let offSiteBot = sites[site].bot | ||||
|     this.__unLockCommand(); | ||||
|     await offSiteBot.connect(); | ||||
|     await offSiteBot.bot.chat(`/invite ${from}`); | ||||
|     await this.whisper(from, `accept invite from ${offSiteBot.bot.entity.username} within 10 seconds...`) | ||||
|     let clear = setTimeout(()=>offSiteBot.quit(), 10000) | ||||
|     offSiteBot.on('message', (message) =>{ | ||||
|         if(message.toString() === `${from} teleported to you.`){ | ||||
|             offSiteBot.quit(); | ||||
| const commands = { | ||||
|     '8ball':{ | ||||
|         desc: `magic 8 Ball pick.`, | ||||
|         async function(from){ | ||||
|             await this.say( | ||||
|                 `> The 8 Ball says...`, | ||||
|                 `> ${ballOptions[Math.floor(Math.random()*ballOptions.length)]}` | ||||
|             ); | ||||
|         } | ||||
|     }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| bot.addCommand('inv', { | ||||
|     desc: `Have bot invite you to its position.`, | ||||
|     allowed: townMemebers, | ||||
|     async function(from, site){ | ||||
|         await this.say(`/invite ${from}`); | ||||
|     } | ||||
| }); | ||||
|  | ||||
|  | ||||
| // async function offSiteInvite(from, site){ | ||||
| //     let offSiteBot = sites[site].bot | ||||
| //     this.__unLockCommand(); | ||||
|  | ||||
|  | ||||
| //     await offSiteBot.connect(); | ||||
| //     await offSiteBot.bot.chat(`/invite ${from}`); | ||||
| //     await this.whisper(from, `accept invite from ${offSiteBot.bot.entity.username} within 10 seconds...`) | ||||
| //     let clear = setTimeout(()=>offSiteBot.quit(), 10000) | ||||
| //     offSiteBot.on('message', (message) =>{ | ||||
| //         if(message.toString() === `${from} teleported to you.`){ | ||||
| //             offSiteBot.quit(); | ||||
| //         } | ||||
| //     }) | ||||
| // } | ||||
|  | ||||
| // bot.addCommand('inv', { | ||||
| //     desc: `Have bot invite you to its position.`, | ||||
| //     allowed: townMemebers, | ||||
| //     async function(from, site){ | ||||
| //         if(getSiteFromBot(this.name).allowed.includes(from) await this.say(`/invite ${from}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| console.log('sites,', sites) | ||||
|  | ||||
| for(const [name, site] of Object.entries(sites)){ | ||||
|     bot.addCommand(`inv-${name}`, { | ||||
|     console.log('site', name) | ||||
|  | ||||
|     commands[`inv-${name}`] = { | ||||
|         ...site, | ||||
|         ignoreLock: true, | ||||
|         async function(from){ | ||||
|             this.__unLockCommand(); | ||||
|             await site.bot.connect(); | ||||
|  | ||||
|             if(!site.bit.isReady){ | ||||
|                 await site.bot.connect(); | ||||
|                 var clear = setTimeout(()=>site.bot.quit(), 10000); | ||||
|             } | ||||
|             await site.bot.bot.chat(`/invite ${from}`); | ||||
|             await this.whisper(from, `accept invite from ${site.bot.bot.entity.username} within 10 seconds...`) | ||||
|             let clear = setTimeout(()=>site.bot.quit(), 10000) | ||||
|             site.bot.on('message', (message) =>{ | ||||
|                 if(message.toString() === `${from} teleported to you.`){ | ||||
|                     site.bot.quit(); | ||||
|                     if(clear){ | ||||
|                         clearTimeout(clear); | ||||
|                         site.bot.quit(); | ||||
|                     } | ||||
|                 } | ||||
|             }) | ||||
|         } | ||||
|     }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| bot.addCommand('.invite', { | ||||
| 	desc: `The bot will /accept an /invite from you.`, | ||||
| 	allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'BobinaBlu', 'pi_chef'], | ||||
| 	async function(from){ | ||||
| 		await this.whisper('Coming'); | ||||
| 		await this.say(`/accept`); | ||||
| 	} | ||||
| }); | ||||
| // bot.addCommand('.invite', { | ||||
| // 	desc: `The bot will /accept an /invite from you.`, | ||||
| // 	allowed: ['wmantly', 'useless666', 'tux4242', 'owenshorts', 'BobinaBlu', 'pi_chef'], | ||||
| // 	async function(from){ | ||||
| // 		await this.whisper('Coming'); | ||||
| // 		await this.say(`/accept`); | ||||
| // 	} | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('say', { | ||||
|     desc: `Make bot say stuff.`, | ||||
|     allowed: ['wmantlys', 'useless666', 'tux4242'], | ||||
|     ignoreLock: true, | ||||
|     async function(from, ...messages){ | ||||
|         await this.say((messages || []).join(' ')); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('say', { | ||||
| //     desc: `Make bot say stuff.`, | ||||
| //     allowed: ['wmantlys', 'useless666', 'tux4242'], | ||||
| //     ignoreLock: true, | ||||
| //     async function(from, ...messages){ | ||||
| //         await this.say((messages || []).join(' ')); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand("joke", { | ||||
|     desc: "Tells a random joke.", | ||||
|     async function(from){ | ||||
|         await this.say('> Let me think...'); | ||||
|         let res = await axios.get('https://v2.jokeapi.dev/joke/Any?type=single') | ||||
|         await this.say(...res.data.joke.split('\n').map(e => `> ${e}`)); | ||||
|     }, | ||||
| }); | ||||
| // bot.addCommand("joke", { | ||||
| //     desc: "Tells a random joke.", | ||||
| //     async function(from){ | ||||
| //         await this.say('> Let me think...'); | ||||
| //         let res = await axios.get('https://v2.jokeapi.dev/joke/Any?type=single') | ||||
| //         await this.say(...res.data.joke.split('\n').map(e => `> ${e}`)); | ||||
| //     }, | ||||
| // }); | ||||
|  | ||||
| bot.addCommand("quote", { | ||||
|     desc: 'Say an inspirational quote.', | ||||
|     async function(from){ | ||||
|         await this.say('> Right away!'); | ||||
|         let res = await axios.get('https://zenquotes.io/api/random') | ||||
|         await this.say(`> ${res.data[0].q} -- ${res.data[0].a}`); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand("quote", { | ||||
| //     desc: 'Say an inspirational quote.', | ||||
| //     async function(from){ | ||||
| //         await this.say('> Right away!'); | ||||
| //         let res = await axios.get('https://zenquotes.io/api/random') | ||||
| //         await this.say(`> ${res.data[0].q} -- ${res.data[0].a}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('west-quote', {  | ||||
|     desc: `Say a random Kanye West quote.`, | ||||
|     async function(from) { | ||||
|         await this.say('> And here we go!'); | ||||
|         let res = await axios.get('https://api.kanye.rest/'); | ||||
|         await this.say(`> ${res.data.quote} -- Kanye West`); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('west-quote', {  | ||||
| //     desc: `Say a random Kanye West quote.`, | ||||
| //     async function(from) { | ||||
| //         await this.say('> And here we go!'); | ||||
| //         let res = await axios.get('https://api.kanye.rest/'); | ||||
| //         await this.say(`> ${res.data.quote} -- Kanye West`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('pink-quote', {  | ||||
|     desc: `Say a random Pink Floyd quote.`, | ||||
|     async function(from) { | ||||
|         await this.say( | ||||
|             `> Rock 'n' Roll`, | ||||
|             `> ${pink_quotes[Math.floor(Math.random()*pink_quotes.length)]} -- Pink Floyd` | ||||
|         );         | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('pink-quote', {  | ||||
| //     desc: `Say a random Pink Floyd quote.`, | ||||
| //     async function(from) { | ||||
| //         await this.say( | ||||
| //             `> Rock 'n' Roll`, | ||||
| //             `> ${pink_quotes[Math.floor(Math.random()*pink_quotes.length)]} -- Pink Floyd` | ||||
| //         );         | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand("fact", { | ||||
|     desc: `Say a random fact.`, | ||||
|     async function(from){ | ||||
|         await this.say('> The internet says this is true?'); | ||||
|         let res = await axios.get('https://uselessfacts.jsph.pl/random.json?language=en') | ||||
|         await this.say( | ||||
|             `> ${res.data.text}`, | ||||
|             `> source: ${res.data.source}` | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand("fact", { | ||||
| //     desc: `Say a random fact.`, | ||||
| //     async function(from){ | ||||
| //         await this.say('> The internet says this is true?'); | ||||
| //         let res = await axios.get('https://uselessfacts.jsph.pl/random.json?language=en') | ||||
| //         await this.say( | ||||
| //             `> ${res.data.text}`, | ||||
| //             `> source: ${res.data.source}` | ||||
| //         ); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand("advice", {  | ||||
|     desc: `Say some random advice.`, | ||||
|     async function(from){ | ||||
|         await this.say('> Try this:'); | ||||
|         let res = await axios.get('https://api.adviceslip.com/advice'); | ||||
|         await this.say(`> ${res.data.slip.advice}`); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand("advice", {  | ||||
| //     desc: `Say some random advice.`, | ||||
| //     async function(from){ | ||||
| //         await this.say('> Try this:'); | ||||
| //         let res = await axios.get('https://api.adviceslip.com/advice'); | ||||
| //         await this.say(`> ${res.data.slip.advice}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('idea', { | ||||
|     desc: `Say a random start up idea.`, | ||||
|     async function(from){ | ||||
|         await this.say('> How about?'); | ||||
|         let res = await axios.get('https://itsthisforthis.com/api.php?text') | ||||
|         await this.say(`> ${res.data}`); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('idea', { | ||||
| //     desc: `Say a random start up idea.`, | ||||
| //     async function(from){ | ||||
| //         await this.say('> How about?'); | ||||
| //         let res = await axios.get('https://itsthisforthis.com/api.php?text') | ||||
| //         await this.say(`> ${res.data}`); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('discord', { | ||||
|     desc: `Say the CJ discord invite link.`, | ||||
|     async function(from) { | ||||
|         await this.say('https://discord.gg/hyby9m8'); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('discord', { | ||||
| //     desc: `Say the CJ discord invite link.`, | ||||
| //     async function(from) { | ||||
| //         await this.say('https://discord.gg/hyby9m8'); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('8ball',{ | ||||
|     desc: `magic 8 Ball pick.`, | ||||
|     async function(from){ | ||||
|         await this.say( | ||||
|             `> The 8 Ball says...`, | ||||
|             `> ${ballOptions[Math.floor(Math.random()*ballOptions.length)]}` | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('dice',{ | ||||
| //     desc: `Roll a die. You can state the max size on the dice. Default is 6.`, | ||||
| //     async function(from, size){ | ||||
| //         size = size || 6; | ||||
| //         if(!Number.isInteger(Number(size))){ | ||||
| //             this.whisper(from, `${size} is not a whole number...`) | ||||
| //             return ; | ||||
| //         } | ||||
| //         await this.say( | ||||
| //             `> Rolling a dice for ${from}`, | ||||
| //             `> ${Math.floor(Math.random()*size)+1}` | ||||
| //         ); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('dice',{ | ||||
|     desc: `Roll a die. You can state the max size on the dice. Default is 6.`, | ||||
|     async function(from, size){ | ||||
|         size = size || 6; | ||||
|         if(!Number.isInteger(Number(size))){ | ||||
|             this.whisper(from, `${size} is not a whole number...`) | ||||
|             return ; | ||||
|         } | ||||
|         await this.say( | ||||
|             `> Rolling a dice for ${from}`, | ||||
|             `> ${Math.floor(Math.random()*size)+1}` | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('random-player', { | ||||
| //     desc: `Return a random online player.`, | ||||
| //     async function(from){ | ||||
| //         let players = bot.getPlayers() | ||||
|          | ||||
| bot.addCommand('random-player', { | ||||
|     desc: `Return a random online player.`, | ||||
|     async function(from){ | ||||
|         let players = bot.getPlayers() | ||||
| //         delete players[bot.bot.entity.username] | ||||
|  | ||||
|         delete players[bot.bot.entity.username] | ||||
| //         let keys = Object.keys(players); | ||||
| //         let player = players[keys[ keys.length * Math.random() << 0]]; | ||||
|  | ||||
|         let keys = Object.keys(players); | ||||
|         let player = players[keys[ keys.length * Math.random() << 0]]; | ||||
| //         await this.say(`> I pick [${player.lvl}]${player.username}`) | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
|         await this.say(`> I pick [${player.lvl}]${player.username}`) | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('flip', { | ||||
| //     desc: `Flip a coin.`, | ||||
| //     async function(from){ | ||||
| //         await this.say( | ||||
| //             `> Flipping a coin for ${from}`, | ||||
| //             `> ${!!(Math.floor(Math.random() * (3000 - 1500) + 1500)%2) ? "Heads" : "Tails"}` | ||||
| //         ); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('flip', { | ||||
|     desc: `Flip a coin.`, | ||||
|     async function(from){ | ||||
|         await this.say( | ||||
|             `> Flipping a coin for ${from}`, | ||||
|             `> ${!!(Math.floor(Math.random() * (3000 - 1500) + 1500)%2) ? "Heads" : "Tails"}` | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
| // bot.addCommand('help', { | ||||
| //     desc: `Print the allowed commands.`, | ||||
| //     async function(from){ | ||||
| //         console.log('called help', from) | ||||
| //         let intro = [ | ||||
| //             'I am a bot owned and operated by', | ||||
| //             'wmantly <wmantly@gmail.com>', | ||||
| //             'You have access to the following commands:' | ||||
| //         ] | ||||
| //         await this.whisper(from, ...intro, ...this.__reduceCommands(from).map(command => | ||||
| //             `${command} -- ${this.commands[command].desc || ''}` | ||||
| //         )); | ||||
| //     } | ||||
| // }); | ||||
|  | ||||
| bot.addCommand('help', { | ||||
|     desc: `Print the allowed commands.`, | ||||
|     async function(from){ | ||||
|         console.log('called help', from) | ||||
|         let intro = [ | ||||
|             'I am a bot owned and operated by', | ||||
|             'wmantly <wmantly@gmail.com>', | ||||
|             'You have access to the following commands:' | ||||
|         ] | ||||
|         await this.whisper(from, ...intro, ...this.__reduceCommands(from).map(command => | ||||
|             `${command} -- ${this.commands[command].desc || ''}` | ||||
|         )); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| module.exports = {bot}; | ||||
| module.exports = commands; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| const botController = require('./controller/mc-bot'); | ||||
| const chatController = require('./controller/mc-chatbot'); | ||||
| // const chatController = require('./controller/mc-chatbot'); | ||||
| // const actionController = require('./controller/mc-actionbot'); | ||||
| @ -15,28 +15,38 @@ class CJbot{ | ||||
| 	combatTag = false; | ||||
| 	doLogOut = false; | ||||
|  | ||||
| 	static bots = {}; | ||||
| 	static __addLock = false; | ||||
| 	static __toConnect = []; | ||||
|  | ||||
| 	constructor(args){ | ||||
| 		this.name = args.name; | ||||
| 		this.username = args.username; | ||||
| 		this.password = args.password; | ||||
| 		this.host = args.host; | ||||
| 		this.auth = args.auth || 'microsoft'; | ||||
| 		this.version = args.version || '1.18.2'; | ||||
| 		this.version = args.version || '1.19.2'; | ||||
| 		this.autoReConnect = 'autoConnect' in args ? args.autoReConnect : true; | ||||
| 		this.autoConnect = 'autoConnect' in args  ? args.autoConnect : true; | ||||
|  | ||||
| 		if(this.autoConnect){ | ||||
| 			console.log('connecting', this.username, this.autoConnect) | ||||
| 			this.connect(); | ||||
| 		} | ||||
|  | ||||
| 		if(this.autoReConnect){ | ||||
| 			this.__autoReConnect() | ||||
| 		} | ||||
|  | ||||
| 		if(this.autoReConnect) this.__autoReConnect() | ||||
| 	} | ||||
|  | ||||
| 	connect(){ | ||||
| 		return new Promise((resolve, reject) =>{ | ||||
| 			// let cancle = setTimeout(()=>{ | ||||
| 			// 	reject('TimeOut') | ||||
| 			// }, 10000) | ||||
|  | ||||
| 			// resolve = (...args)=>{ | ||||
| 			// 	clearTimeout(cancle); | ||||
| 			// 	return resolve(...args); | ||||
| 			// } | ||||
|  | ||||
| 			// reject = (...args)=>{ | ||||
| 			// 	// clearTimeout(cancle); | ||||
| 			// 	return reject(...args); | ||||
| 			// } | ||||
| 			this.bot = mineflayer.createBot({ | ||||
| 				host: this.host, | ||||
| 				username: this.username, | ||||
| @ -51,29 +61,36 @@ class CJbot{ | ||||
| 				reject(m) | ||||
| 			}) | ||||
|  | ||||
|  | ||||
| 			this.bot.on('end', reason =>{ | ||||
| 					console.log('Connection ended:', reason) | ||||
| 					this.isReady = false | ||||
| 				} | ||||
| 			); | ||||
| 			this.bot.on('end', (m)=>{ | ||||
| 				console.log(this.name, 'Connection ended:', m); | ||||
| 				this.isReady = false; | ||||
| 				reject(m); | ||||
| 			}); | ||||
|  | ||||
| 			this.bot.on('login', ()=>{ | ||||
| 				this.__onReady() | ||||
| 				resolve() | ||||
| 			}); | ||||
|  | ||||
| 			setTimeout(async ()=>{try{ | ||||
| 				if(this.autoReConnect && !this.isReady) await this.connect(); | ||||
| 			}catch(error){ | ||||
| 				console.error('minecraft.js/connect/setTimeout/', this.name, ' ', error) | ||||
| 			}}, 30000); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
|  | ||||
| 	once(event){ | ||||
| 		return new Promise((resolve, reject)=> this.bot.once(event, resolve)); | ||||
| 	} | ||||
|  | ||||
| 	async __onReady(){ | ||||
| 	async __onReady(){try{ | ||||
|  | ||||
| 		this.__startListeners(); | ||||
|  | ||||
| 		console.log('listeners', this.listeners.onReady) | ||||
| 		// console.log('listeners', this.listeners.onReady) | ||||
|  | ||||
| 		for(let callback of this.listeners.onReady || []){ | ||||
| 			console.log('calling listener', callback) | ||||
| @ -86,7 +103,10 @@ class CJbot{ | ||||
| 		 | ||||
| 		// Start chat listeners | ||||
| 		this.__listen(); | ||||
| 	} | ||||
| 	 | ||||
| 	}catch(error){ | ||||
| 		console.error('minecraft.js/__onReady/', this.name, ' ', error) | ||||
| 	}} | ||||
|  | ||||
|  | ||||
| 	__startListeners(){ | ||||
| @ -111,37 +131,34 @@ class CJbot{ | ||||
| 	} | ||||
|  | ||||
| 	__autoReConnect(){ | ||||
| 		console.log('auto connect function') | ||||
| 		this.on('end', (reason)=>{ | ||||
| 			console.error('MC on end', reason) | ||||
| 		try{ | ||||
| 			console.log('auto connect function') | ||||
| 			this.on('end', async (reason)=>{ | ||||
| 				console.error('_autorestart MC on end', reason) | ||||
|  | ||||
| 				await sleep('30000') | ||||
| 				this.connect() | ||||
| 			}); | ||||
|  | ||||
| 			this.connect() | ||||
| 		}); | ||||
| 			this.on('kick', console.error) | ||||
|  | ||||
| 		this.bot.on('kick', console.error) | ||||
| 			this.on('error', (error)=>{ | ||||
| 				console.error('MC on error', error); | ||||
|  | ||||
| 		this.on('error', (error)=>{ | ||||
| 			console.error('MC on error', error); | ||||
| 				this.connect(); | ||||
| 			}); | ||||
| 		}catch(error){ | ||||
| 			console.error('error in __autoReConnect', error); | ||||
|  | ||||
| 			this.connect(); | ||||
| 		}); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	__error(){ | ||||
| 	__error(message){ | ||||
| 		this.bot.on('error', (error)=>{ | ||||
| 			console.error(`ERROR!!! MC bot ${this.username} on ${this.host} had an error:\n`, error) | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	getPlayers(){ | ||||
| 		for (let [username, value] of Object.entries(this.bot.players)){ | ||||
| 			value.lvl = Number(value.displayName.extra[0].text) | ||||
| 		} | ||||
|  | ||||
| 		return this.bot.players; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* Chat and messaging*/ | ||||
|  | ||||
| @ -200,10 +217,10 @@ class CJbot{ | ||||
| 	} | ||||
|  | ||||
| 	quit(force){ | ||||
| 		if(!this.combatTag){ | ||||
| 		if(!this.combatTag || force){ | ||||
| 			this.bot.quit(); | ||||
| 		}else{ | ||||
| 			console.log('stoped logout due to combatTag') | ||||
| 			console.log('Logout prevented due to combatTag'); | ||||
| 			this.doLogOut = true; | ||||
| 		} | ||||
| 	} | ||||
| @ -241,7 +258,7 @@ class CJbot{ | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	async __doCommand(from, command){ | ||||
| 	async __doCommand(from, command){try{ | ||||
| 		if(this.commandLock){ | ||||
| 			this.whisper(from, `cool down, try again in ${this.commandCollDownTime/1000} seconds...`); | ||||
| 			return ; | ||||
| @ -261,12 +278,23 @@ class CJbot{ | ||||
| 		}else{ | ||||
| 			this.whisper(from, `I dont know anything about ${cmd}`); | ||||
| 		} | ||||
| 	} | ||||
| 	}catch(error){ | ||||
| 		console.error('minecraft.js/__doCommand/', this.name, ' ', error) | ||||
| 	}} | ||||
|  | ||||
| 	addCommand(name, obj){ | ||||
| 		if(this.commands[name]) return false; | ||||
|  | ||||
| 		this.commands[name] = obj; | ||||
| 	} | ||||
|  | ||||
| 	getPlayers(){ | ||||
| 		for (let [username, value] of Object.entries(this.bot.players)){ | ||||
| 			value.lvl = Number(value.displayName.extra[0].text) | ||||
| 		} | ||||
|  | ||||
| 		return this.bot.players; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| module.exports = {CJbot}; | ||||
|  | ||||
							
								
								
									
										635
									
								
								nodejs/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										635
									
								
								nodejs/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -21,7 +21,7 @@ | ||||
|     "dotenv": "^16.0.1", | ||||
|     "extend": "^3.0.2", | ||||
|     "minecraft-data": "^3.5.0", | ||||
|     "mineflayer": "^4.3.0", | ||||
|     "mineflayer": "^4.8.0", | ||||
|     "mineflayer-auto-eat": "^2.3.3", | ||||
|     "mineflayer-pathfinder": "^2.2.0", | ||||
|     "mineflayer-web-inventory": "^1.8.3", | ||||
| @ -29,6 +29,6 @@ | ||||
|     "prismarine-windows": "^2.4.4" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "nodemon": "^2.0.18" | ||||
|     "nodemon": "^2.0.22" | ||||
|   } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user