Compare commits
	
		
			51 Commits
		
	
	
		
			nogameplay
			...
			2f88eedce9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2f88eedce9 | ||
|  | a0893f2b29 | ||
|  | b1a592dbbd | ||
|  | f336e3d736 | ||
|  | d953bd4cf6 | ||
|  | fc43985337 | ||
|  | 6b1157147d | ||
|  | e6d29576e7 | ||
|  | 974d460061 | ||
|  | 1d361e04a6 | ||
|  | 7597620626 | ||
|  | e5faa6f022 | ||
|  | cc18ac5c2e | ||
|  | 7050a1621b | ||
|  | 7cbfa16476 | ||
|  | 63849e0729 | ||
|  | 4e7f8d59fd | ||
|  | 7b2b936f81 | ||
|  | 8a39596b1d | ||
|  | 2601b7cfb1 | ||
|  | 67932b2f6a | ||
|  | 9a6e684b11 | ||
|  | 3488a94233 | ||
|  | 4d21327086 | ||
|  | e74d796124 | ||
|  | 3d5ffe38cd | ||
|  | b519913355 | ||
|  | b1dab1968c | ||
|  | 3219ec6155 | ||
|  | f38ad8c819 | ||
|  | 4b8a39d38c | ||
|  | 6b71de0356 | ||
|  | 96214ffe37 | ||
|  | 034f8d331a | ||
|  | 69d0f5830d | ||
|  | 8e719d5ccf | ||
|  | 112eb04a8d | ||
|  | ba7c53be0c | ||
|  | 5b4718fa5d | ||
|  | 902732c6dd | ||
|  | 65d13a3379 | ||
|  | 288b7045b6 | ||
|  | 94574a4296 | ||
|  | 68e60921b1 | ||
|  | f2281a7cb3 | ||
|  | e9f2080556 | ||
|  | 086251bce6 | ||
|  | 0ae961521f | ||
|  | eae4e95803 | ||
|  | fb066ee8a5 | ||
|  | f4445749e6 | 
							
								
								
									
										8
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| { | ||||
|     "conventionalCommits.scopes": [ | ||||
|         "command", | ||||
|         "mover", | ||||
|         "sleeper", | ||||
|         "informer" | ||||
|     ] | ||||
| } | ||||
							
								
								
									
										36
									
								
								lib/index.js
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								lib/index.js
									
									
									
									
									
								
							| @@ -9,19 +9,22 @@ let cfg = { | ||||
| const mineflayer = require("mineflayer"); | ||||
| // const { createGetAccessor } = require('typescript'); | ||||
|  | ||||
| const bot = | ||||
|     !isNaN(parseInt(process.argv[3])) && parseInt(process.argv[3]) > 1e2 ? | ||||
|         mineflayer.createBot({ | ||||
|             host: process.argv[2] || process.env.MINECRAFT_HOST || env.MINECRAFT_HOST || 'localhost',  // Change this to the ip you want. | ||||
|             port: parseInt(process.argv[3]) || process.env.MINECRAFT_PORT || env.MINECRAFT_PORT // || 58471, | ||||
|         }) | ||||
|         : | ||||
|         mineflayer.createBot({ | ||||
|             host: process.argv[2] || process.env.MINECRAFT_HOST || env.MINECRAFT_HOST || 'localhost',  // Change this to the ip you want. | ||||
|             username: process.argv[3] || process.env.MINECRAFT_USER || env.MINECRAFT_USER, | ||||
|             password: process.argv[4] || process.env.MINECRAFT_PASS || env.MINECRAFT_PASS, | ||||
|             // port: process.argv[5] || process.env.MINECRAFT_PORT || 58471, | ||||
|         }) | ||||
| const options = !isNaN(parseInt(process.argv[3])) && parseInt(process.argv[3]) > 1e2 ? | ||||
|     { | ||||
|         host: process.argv[2] || process.env.MINECRAFT_HOST || env.MINECRAFT_HOST || 'localhost',  // Change this to the ip you want. | ||||
|         port: parseInt(process.argv[3]) || process.env.MINECRAFT_PORT || env.MINECRAFT_PORT // || 58471, | ||||
|     } | ||||
|     : | ||||
|     { | ||||
|         host: process.argv[2] || process.env.MINECRAFT_HOST || env.MINECRAFT_HOST || 'localhost',  // Change this to the ip you want. | ||||
|         username: process.argv[3] || process.env.MINECRAFT_USER || env.MINECRAFT_USER, | ||||
|         password: process.argv[4] || process.env.MINECRAFT_PASS || env.MINECRAFT_PASS, | ||||
|         // port: process.argv[5] || process.env.MINECRAFT_PORT || 58471, | ||||
|     } | ||||
|  | ||||
| const bot = mineflayer.createBot(options) | ||||
|  | ||||
| cfg.botOptions = options | ||||
|  | ||||
|  | ||||
| let plugins = {} | ||||
| @@ -92,13 +95,14 @@ cfg.quiet = true | ||||
| bot.once("spawn", () => { | ||||
|     plugins = { | ||||
|         command: require('./plugins/command'), | ||||
|         eater: require('./plugins/eater'), | ||||
|         inventory: require('./plugins/inventory'), | ||||
|         informer: require('./plugins/informer'), | ||||
|         finder: require('./plugins/finder'), | ||||
|         sleeper: require('./plugins/sleeper'), | ||||
|         armor: require('./plugins/armor'), | ||||
|         mover: require('./plugins/mover'), | ||||
|         guard: require('./plugins/guard'), | ||||
|         inventory: require('./plugins/inventory'), | ||||
|         eater: require('./plugins/eater'), | ||||
|         finder: require('./plugins/finder'), | ||||
|         // miner: require('./plugins/miner.js'), | ||||
|         // statemachine: require('./plugins/statemachine'), | ||||
|     } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| const v = require('vec3') | ||||
| let mcData = require('minecraft-data') | ||||
| let mcData | ||||
|  | ||||
| let cfg = {} | ||||
| let bot = {} | ||||
| @@ -46,7 +46,17 @@ const events = { | ||||
|         } | ||||
|     } | ||||
|     , chat: command | ||||
|     , kicked: (reason, loggedIn) => console.warn(reason, loggedIn) | ||||
|     , kicked: function rejoin(reason, loggedIn) { | ||||
|         console.warn(reason, loggedIn && "logged_in") | ||||
|         if (reason.extra && reason.extra[0].text === "Server closed") { | ||||
|             bot.quit() | ||||
|             bot.end() | ||||
|             // TODO implement all startup features (maybe refactor all into a single function / module?) | ||||
|             setTimeout((bot, cfg) => { | ||||
|                 bot = mineflayer.createBot(cfg.botOptions) | ||||
|             }, 15 * 60 * 1000, bot, cfg); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| const events_registered = [] | ||||
| @@ -183,105 +193,45 @@ function command(username, message) { | ||||
|                     break; | ||||
|  | ||||
|                 case "follow": | ||||
|                     subcommand("go follow me") | ||||
|                     break; | ||||
|                 case "come": | ||||
|                     subcommand("go follow once") | ||||
|                     break; | ||||
|                 case "move": | ||||
|                 case "go": | ||||
|                     // TODO move most of the subcommands into mover.js? | ||||
|                     const message_parts2 = message_parts.slice(2) | ||||
|                     switch (message_parts[1]) { | ||||
|                         case "init": | ||||
|                             cfg.plugins.mover.initMoves() | ||||
|                             break | ||||
|                         case "near": | ||||
|                             // message_parts2 = message_parts.slice(2) | ||||
|                             switch (message_parts2.length) { | ||||
|                                 case 0: | ||||
|                                     cfg.plugins.mover.moveNear(bot.nearestEntity().position) | ||||
|                                     break | ||||
|                                 case 1: | ||||
|                                     switch (message_parts2[0]) { | ||||
|                                         case "me": | ||||
|                                             if (player) { | ||||
|                                                 cfg.plugins.mover.moveNear(player.position) | ||||
|                                             } else { | ||||
|                                                 cfg.quiet || bot.chat("can't see you") | ||||
|                                             } | ||||
|                                             break; | ||||
|                     switch (message_parts.length) { | ||||
|                         case 1: | ||||
|                             subcommand("go follow me") | ||||
|                             break; | ||||
|  | ||||
|                                         default: | ||||
|                                             const aPlayer = bot.players[message_parts[2]] ? bot.players[message_parts[2]].entity : null | ||||
|                                             if (aPlayer) { | ||||
|                                                 cfg.plugins.mover.moveNear(aPlayer.position) | ||||
|                                             } else { | ||||
|                                                 cfg.quiet || bot.chat(`can't see ${message_parts[2]}`) | ||||
|                                             } | ||||
|                                             break; | ||||
|                                     } | ||||
|                                     break | ||||
|                                 case 2: | ||||
|                                     todo() | ||||
|                                     // bot.lookAt({}) goalxz? | ||||
|                                     break | ||||
|                                 case 3: | ||||
|                                     //TODO more checks | ||||
|                                     cfg.plugins.mover.moveNear(message_parts2) | ||||
|                                     break | ||||
|                                 default: | ||||
|                                     break | ||||
|                             } | ||||
|                             break | ||||
|  | ||||
|                         case "follow": | ||||
|                             // message_parts2 = message_parts.slice(2) | ||||
|                             switch (message_parts2.length) { | ||||
|                                 case 0: | ||||
|                                     cfg.plugins.mover.follow(bot.nearestEntity()) | ||||
|                                     break | ||||
|                                 case 1: | ||||
|                                     switch (message_parts2[0]) { | ||||
|                                         case "me": | ||||
|                                         case "once": | ||||
|                                             if (player) { | ||||
|                                                 cfg.plugins.mover.follow(player, message_parts2[0] !== "once") | ||||
|                                             } else { | ||||
|                                                 cfg.quiet || bot.chat("can't see you") | ||||
|                                             } | ||||
|                                             break; | ||||
|  | ||||
|                                         default: | ||||
|                                             const aPlayer = bot.players[message_parts[2]] ? bot.players[message_parts[2]].entity : null | ||||
|                                             if (aPlayer) { | ||||
|                                                 cfg.plugins.mover.follow(aPlayer) | ||||
|                                             } else { | ||||
|                                                 cfg.quiet || bot.chat(`can't see ${message_parts[2]}`) | ||||
|                                             } | ||||
|                                             break; | ||||
|                                     } | ||||
|                                     break | ||||
|                                 // case 2: | ||||
|                                 // bot.lookAt({}) goalxz? | ||||
|                                 // break | ||||
|                                 // case 3: | ||||
|                                 //TODO more checks | ||||
|                                 // cfg.plugins.mover.moveNear(message_parts2) | ||||
|                                 // break | ||||
|                                 default: | ||||
|                                     todo() | ||||
|                                     break | ||||
|                             } | ||||
|                             break | ||||
|                         case "stop": | ||||
|                             cfg.plugins.mover.stop() | ||||
|                             break | ||||
|                         default: | ||||
|                             return todo() | ||||
|                             subcommand("go " + message) | ||||
|                             break; | ||||
|                     } | ||||
|                     break; | ||||
|                 case "come": | ||||
|                     switch (message_parts[1]) { | ||||
|                         case "close": | ||||
|                         case "closer": | ||||
|                             subcommand("go follow close") | ||||
|                             break | ||||
|                         case "up": | ||||
|                         case "down": | ||||
|                             cfg.plugins.mover.moveY(player.position) | ||||
|                             break | ||||
|                         default: | ||||
|                             subcommand("go follow once") | ||||
|                     } | ||||
|                     break; | ||||
|                 case "ride": | ||||
|                 case "mount": | ||||
|                     cfg.plugins.mover.command(message_parts) | ||||
|                     break | ||||
|                 case "unride": | ||||
|                 case "getoff": | ||||
|                 case "unmount": | ||||
|                 case "dismount": | ||||
|                     bot.dismount() | ||||
|                     bot.vehicle = void 0 | ||||
|                     break | ||||
|                 case "move": | ||||
|                 case "go": | ||||
|                     cfg.plugins.mover.command(message_parts.slice(1), player) | ||||
|                     break; | ||||
|  | ||||
|                 case "attack": | ||||
|                 case "rage": | ||||
| @@ -331,6 +281,8 @@ function command(username, message) { | ||||
|                             break; | ||||
|                     } | ||||
|                     break | ||||
|                 // TODO move look (and maybe find) to informer plugin? | ||||
|                 case "look": | ||||
|                 case "lookat": | ||||
|                     // const coords = v(message_parts.splice(1)) | ||||
|                     switch (message_parts.length) { | ||||
| @@ -349,13 +301,12 @@ function command(username, message) { | ||||
|  | ||||
|                                 case "this": | ||||
|                                     // TODO lookat the block the user is looking at | ||||
|                                     // Currently looks player position | ||||
|                                     if (player) { | ||||
|                                         bot.lookAt((new v.Vec3(0, 1, 0)).add(player.position)) | ||||
|                                         todo() | ||||
|                                         bot.lookAt(player.position) | ||||
|                                     } else { | ||||
|                                         cfg.quiet || bot.chat("can't see you") | ||||
|                                     } | ||||
|                                     break; | ||||
|                                     break | ||||
|                                 default: | ||||
|                                     const aPlayer = bot.players[message_parts[2]] ? bot.players[message_parts[2]].entity : null | ||||
| @@ -375,17 +326,8 @@ function command(username, message) { | ||||
|                             break | ||||
|                     } | ||||
|                     break | ||||
|                 case "ride": | ||||
|                 case "mount": | ||||
|                     bot.mount(bot.nearestEntity()) | ||||
|                     break | ||||
|                 case "getoff": | ||||
|                 case "unmount": | ||||
|                 case "dismount": | ||||
|                     bot.dismount() | ||||
|                     break | ||||
|                 case "go": | ||||
|                     bot.moveVehicle(0, 10) | ||||
|                 case "info": | ||||
|                     cfg.plugins.informer.command(message_parts.splice(1)) | ||||
|                     break | ||||
|                 // case "use": | ||||
|                 //     bot.useOn(bot.nearestEntity()) | ||||
| @@ -416,29 +358,52 @@ function command(username, message) { | ||||
|                 // case "take": | ||||
|                 //     // TODO take only what's requested, then throw all the rest | ||||
|                 //     // TODO take all | ||||
|                 // case "toss": | ||||
|                 // case "drop": | ||||
|                 //     if (!message_parts[1]) { return false } // FIXME, works but ugly | ||||
|                 //     if (!checkItemExists(message_parts[1])) { return false } | ||||
|                 //     switch (message_parts.length) { | ||||
|                 //         case 2: | ||||
|                 //             bot.toss(mcData.blocksByName[message_parts[1]].id) | ||||
|                 //             break | ||||
|                 //         case 3: | ||||
|                 //             bot.tossStack( | ||||
|                 //                 mcData.itemsByName[message_parts[1]].id, | ||||
|                 //                 (err) => { | ||||
|                 //                     if (err) { | ||||
|                 //                         console.log(err) | ||||
|                 //                         bot.chat(err) | ||||
|                 //                     } | ||||
|                 //                 } | ||||
|                 //             ) | ||||
|                 //             break | ||||
|                 //         default: | ||||
|                 //             break | ||||
|                 //     } | ||||
|                 //     break; | ||||
|  | ||||
|                 // TODO move subcommands to cfg.plugins.inventory.itemByName | ||||
|                 case "toss": | ||||
|                 case "drop": | ||||
|                     if (!message_parts[1]) { return false } // FIXME, works but ugly | ||||
|                     if (!mcData.findItemOrBlockByName(message_parts[1])) { | ||||
|                         console.log("doesn't exist:", message_parts[1]) | ||||
|                         cfg.quiet || bot.chat(`item doesn't exist: ${message_parts[1]}`) | ||||
|                         return false | ||||
|                     } | ||||
|                     const item = cfg.plugins.inventory.itemByName(message_parts[1]) | ||||
|                     if (!item) { | ||||
|                         console.log("don't have:", message_parts[1]) | ||||
|                         cfg.quiet || bot.chat(`don't have item: ${message_parts[1]}`) | ||||
|                         return false | ||||
|                     } | ||||
|                     switch (message_parts.length) { | ||||
|                         case 2: | ||||
|                             bot.tossStack( | ||||
|                                 item, | ||||
|                                 (err) => { | ||||
|                                     if (err) { | ||||
|                                         console.error(err) | ||||
|                                         cfg.quiet || bot.chat(err.message) | ||||
|                                     } | ||||
|                                 } | ||||
|                             ) | ||||
|                             break | ||||
|                         case 3: | ||||
|                             const amount = parseInt(message_parts[2]) | ||||
|                             bot.toss( | ||||
|                                 item.type, | ||||
|                                 null, //metadata | ||||
|                                 amount, | ||||
|                                 (err) => { | ||||
|                                     if (err) { | ||||
|                                         console.error(err) | ||||
|                                         cfg.quiet || bot.chat(err.message) | ||||
|                                     } | ||||
|                                 } | ||||
|                             ) | ||||
|                             break | ||||
|                         default: | ||||
|                             break | ||||
|                     } | ||||
|                     break; | ||||
|                 case "location": | ||||
|                     // TODO put in /lib/location | ||||
|                     switch (message_parts[1]) { | ||||
| @@ -537,13 +502,12 @@ const load = (config) => { | ||||
|     cfg = config | ||||
|     bot = cfg.bot | ||||
|  | ||||
|     mcData = mcData(bot.version) | ||||
|     mcData = bot.mcData || (bot.mcData = require('minecraft-data')(bot.version)) | ||||
|     for (const [key, fn] of Object.entries(events)) { | ||||
|         events_registered.push( | ||||
|             bot.on(key, fn) | ||||
|         ) | ||||
|     } | ||||
|     mcData = require('minecraft-data')(bot.version) | ||||
| } | ||||
|  | ||||
| const unload = () => { | ||||
|   | ||||
							
								
								
									
										128
									
								
								lib/plugins/informer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								lib/plugins/informer.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| let cfg | ||||
| let bot | ||||
| let mcData | ||||
| const v = require('vec3') | ||||
|  | ||||
| function block(pos) { | ||||
|     const block = pos ? bot.blockAt(v(pos)) : bot.blockAtCursor() | ||||
|     console.log(block, block && block.getProperties()) | ||||
|     if (!block) { | ||||
|         cfg.quiet || bot.chat("empty block") | ||||
|         return block | ||||
|     } | ||||
|     let info = [block.type, block.name] | ||||
|     if (block.metadata) info.push(Object.entries(block.getProperties())) | ||||
|     cfg.quiet || bot.chat(info.join(": ")) | ||||
| } | ||||
|  | ||||
| function item( | ||||
|     slot, | ||||
|     entity = bot.entity | ||||
| ) { | ||||
|     const item = slot ? | ||||
|         bot.inventory.slots[parseInt(slot) + bot.QUICK_BAR_START] : | ||||
|         entity.heldItem | ||||
|     console.log(item) | ||||
|     if (!item) { | ||||
|         cfg.quiet || bot.chat("no item") | ||||
|         return item | ||||
|     } | ||||
|     let info = [item.type, item.name] | ||||
|     if (item.metadata) info.push("meta: " + item.metadata.length) | ||||
|     if (item.nbt) { | ||||
|         info.push(compound_value(item.nbt)) | ||||
|     } | ||||
|     cfg.quiet || bot.chat(info.join("; ")) | ||||
|     function compound_value(obj) { | ||||
|         if (typeof obj.value == "object") { | ||||
|             return compound_value(obj.value) | ||||
|         } else if (obj.value) { | ||||
|             return obj.value | ||||
|         } else if (typeof obj == "object") { | ||||
|             const keys = Object.keys(obj) | ||||
|             return keys.map(key => { | ||||
|                 return `${key}: ${compound_value(obj[key])}` | ||||
|             }); | ||||
|         } else { | ||||
|             return obj | ||||
|         } | ||||
|     } | ||||
|     return item | ||||
| } | ||||
|  | ||||
| function entity(name) { | ||||
|     const entity = bot.nearestEntity((entity) => { | ||||
|         const ename = entity.name || entity.username | ||||
|         return name && ename ? ename == name : true | ||||
|     }) | ||||
|     console.log(entity) | ||||
|     if (!entity) { | ||||
|         cfg.quiet || bot.chat("no entity") | ||||
|         return entity | ||||
|     } | ||||
|     let info = [entity.type, entity.name || entity.username] | ||||
|     if (entity.metadata) info.push("len: " + entity.metadata.length) | ||||
|     cfg.quiet || bot.chat(info.join("; ")) | ||||
| } | ||||
|  | ||||
| function command(message_parts) { | ||||
|     switch (message_parts.length) { | ||||
|         case 0: | ||||
|             // TODO most recent command? | ||||
|             block() | ||||
|             break; | ||||
|         case 1: | ||||
|             switch (message_parts[0]) { | ||||
|                 case "item": | ||||
|                     item() | ||||
|                     break | ||||
|                 case "entity": | ||||
|                     entity() | ||||
|                     break | ||||
|                 case "block": | ||||
|                 default: | ||||
|                     block() | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|             break; | ||||
|  | ||||
|         case 2: | ||||
|             switch (message_parts[0]) { | ||||
|                 case "item": | ||||
|                     item(message_parts[1]) | ||||
|                     break | ||||
|                 case "entity": | ||||
|                 default: | ||||
|                     entity(message_parts[1]) | ||||
|                     break; | ||||
|             } | ||||
|             break | ||||
|  | ||||
|         case 4: | ||||
|             switch (message_parts[0]) { | ||||
|                 case "block": | ||||
|                 default: | ||||
|                     block(message_parts.slice(1)) | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|             break; | ||||
|  | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const load = (config) => { | ||||
|     cfg = config | ||||
|     bot = cfg.bot | ||||
|     cfg.info = { | ||||
|         quiet: cfg.quiet, | ||||
|     } | ||||
|     mcData = bot.mcData || (bot.mcData = require('minecraft-data')(bot.version)) | ||||
| } | ||||
|  | ||||
| const unload = () => {} | ||||
|  | ||||
| module.exports = { load, unload, command, block, item, entity } | ||||
| @@ -225,4 +225,4 @@ const unload = () => { | ||||
|     bot.off('chat', inventory) | ||||
| } | ||||
|  | ||||
| module.exports = { load, unload, equipItem, craftItem } | ||||
| module.exports = { load, unload, equipItem, craftItem, itemByName } | ||||
| @@ -1,27 +1,28 @@ | ||||
| // import { EntityFilters } from "mineflayer-statemachine" | ||||
| // import v from "vec3" | ||||
|  | ||||
| // import { Movements } from "mineflayer-pathfinder" | ||||
|  | ||||
| // const mineflayer = require('mineflayer') | ||||
| const { Movements } = require('mineflayer-pathfinder') | ||||
| // const { GoalBLah } = require('mineflayer-pathfinder').goals | ||||
| const v = require('vec3') | ||||
|  | ||||
| let cfg = {} | ||||
| let bot = {} | ||||
| // let moving | ||||
| let pathfinder | ||||
| let mcData | ||||
| let movements = [] | ||||
|  | ||||
|  | ||||
| function initMoves(bot = bot, mcData = require('minecraft-data')(bot.version)) { | ||||
| function initMoves(bot = bot, mcData = bot.mcData) { | ||||
|     console.info(movements) | ||||
|     if (movements.length > 0) { | ||||
|         bot.pathfinder.setMovements(movements.defaultMove) | ||||
|         return console.warn("movements already initialized!") | ||||
|     } | ||||
|     let defaultMove = new Movements(bot, mcData) | ||||
|     defaultMove.canDig = false | ||||
|     defaultMove.scafoldingBlocks.push(mcData.blocksByName.slime_block.id) | ||||
|     // defaultMove.blocksCantBreak.add(mcData.blocksByName.glass.id) | ||||
|     // defaultMove.blocksToAvoid.add(mcData.blocksByName.magma.id) | ||||
|     movements.defaultMove = defaultMove | ||||
|     defaultMove.blocksCantBreak.add(mcData.blocksByName.glass.id) | ||||
|     defaultMove.blocksToAvoid.add(mcData.blocksByName.magma_block.id) | ||||
|     movements.push(defaultMove) | ||||
|     movements.defaultMove = movements[0] | ||||
|  | ||||
|     bot.pathfinder.setMovements(defaultMove) | ||||
| } | ||||
| @@ -29,43 +30,243 @@ function initMoves(bot = bot, mcData = require('minecraft-data')(bot.version)) { | ||||
|  | ||||
| function moveNear(pos, distance = 3) { | ||||
|     const { GoalNear } = require('mineflayer-pathfinder').goals | ||||
|     cfg.quiet || bot.chat(`moving to ${pos}`) | ||||
|  | ||||
|     pos = v(pos) | ||||
|     cfg.quiet || bot.chat(`moving to ${pos.floored()}`) | ||||
|     bot.pathfinder.setMovements(movements.defaultMove) | ||||
|     bot.pathfinder.setGoal(new GoalNear(pos.x, pos.y, pos.z, distance)) | ||||
| } | ||||
|  | ||||
| function follow(entity, dynamic = true) { | ||||
| function moveXZ(pos) { | ||||
|     const { GoalXZ } = require('mineflayer-pathfinder').goals | ||||
|  | ||||
|     if (Array.isArray(pos) && pos.length == 2) { | ||||
|         pos = v(pos[0], 0, pos[1]) | ||||
|     } | ||||
|     pos = v(pos) | ||||
|     console.log(pos) | ||||
|     cfg.quiet || bot.chat(`moving to ${pos.floored()}`) | ||||
|     bot.pathfinder.setMovements(movements.defaultMove) | ||||
|     bot.pathfinder.setGoal(new GoalXZ(pos.x, pos.z)) | ||||
| } | ||||
|  | ||||
| function moveY(pos) { | ||||
|     const { GoalY } = require('mineflayer-pathfinder').goals | ||||
|  | ||||
|     if (Array.isArray(pos) && pos.length == 1) { | ||||
|         pos = v(null, pos[0], null) | ||||
|     } | ||||
|     pos = v(pos) | ||||
|     console.log(pos) | ||||
|     cfg.quiet || bot.chat(`moving to ${pos.floored()}`) | ||||
|     bot.pathfinder.setMovements(movements.defaultMove) | ||||
|     bot.pathfinder.setGoal(new GoalY(pos.y)) | ||||
| } | ||||
|  | ||||
| function follow(entity, dynamic = true, distance = 3) { | ||||
|     console.assert(entity) | ||||
|     const { GoalFollow } = require('mineflayer-pathfinder').goals | ||||
|  | ||||
|  | ||||
|  | ||||
|     cfg.quiet && console.log(entity) | ||||
|         || bot.chat( | ||||
|             `following ${entity.type | ||||
|             }: ${entity.username || entity.displayName | ||||
|             }${dynamic ? "" : " once"}` | ||||
|         ) | ||||
|     // console.log(entity) | ||||
|     cfg.quiet || bot.chat( | ||||
|         `following ${entity.type | ||||
|         }: ${entity.username || entity.displayName | ||||
|         }${dynamic ? "" : " once"}` | ||||
|     ) | ||||
|  | ||||
|     entity = entity.entity ? entity.entity : entity | ||||
|  | ||||
|     // console.log(entity) | ||||
|  | ||||
|     bot.pathfinder.setMovements(movements.defaultMove) | ||||
|     bot.pathfinder.setGoal(new GoalFollow(entity, 3), dynamic) | ||||
|     bot.pathfinder.setGoal(new GoalFollow(entity, distance), dynamic) | ||||
| } | ||||
|  | ||||
| function ride(entity) { | ||||
|     entity = entity?.entity || entity | ||||
|     const ridableMobs = ["Horse", "Donkey", "Pig", "Strider"] | ||||
|     const vehicle = entity && typeof entity !== "string" ? entity : bot.nearestEntity(e => { | ||||
|         if (typeof entity === "string") return e.name === entity | ||||
|         const maybeRidableMob = e.mobType?.split(" ") | ||||
|         return e.kind == "Vehicles" | ||||
|             || ridableMobs.includes(e.mobType) | ||||
|             || maybeRidableMob && ridableMobs.includes(maybeRidableMob[maybeRidableMob.length - 1]) | ||||
|     }) | ||||
|     if (!vehicle) { | ||||
|         return cfg.quiet || bot.chat(`nothing to ride!`) | ||||
|     } else if ((dist = bot.entity.position.distanceSquared(vehicle.position)) > 36) { | ||||
|         bot.lookAt(vehicle.position) | ||||
|         follow(vehicle, false) | ||||
|         bot.once('goal_reached', ride) | ||||
|         return cfg.quiet || bot.chat(`${vehicle.name} bit far`) | ||||
|     } | ||||
|     console.log("vehicle:", vehicle) | ||||
|     bot.mount(vehicle) | ||||
| } | ||||
|  | ||||
| function moveOrRide(turn = false, reverse = -1, directionLabel, message_parts2) { | ||||
|     // bot.once("attach", state = "vehiccel") | ||||
|     if (bot.vehicle) { | ||||
|         const amount = parseInt(message_parts2[0]) || 10 * -reverse | ||||
|         bot.moveVehicle(turn && amount || 0, !turn && amount || 0) | ||||
|     } else { | ||||
|         command([directionLabel].concat(message_parts2)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| function hit(blockOrEntity) { | ||||
|     bot.chat(`hitting ${entity.name || entity.type}`) | ||||
| } | ||||
|  | ||||
| function goalReached(goal) { | ||||
|     console.log(goal) | ||||
|     const entity = goal?.entity | ||||
|     let entityInfo = "" | ||||
|     if (entity) { | ||||
|         entityInfo += entity.type + ": " | ||||
|         switch (entity.type) { | ||||
|             case "player": | ||||
|                 entityInfo += entity.username | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|     cfg.quiet || bot.chat(`goal reached: ${entityInfo}; pos: [x:${goal?.x}, y:${goal?.y}, z:${goal?.z}]`) | ||||
| } | ||||
|  | ||||
| function stop() { | ||||
|     bot.pathfinder.setGoal(null) | ||||
|     bot.stopDigging() | ||||
| } | ||||
|  | ||||
| function command(message_parts, player) { | ||||
|     const message_parts2 = message_parts.slice(1) | ||||
|     switch (message_parts[0]) { | ||||
|         case "init": | ||||
|             initMoves() | ||||
|             break | ||||
|         case "near": | ||||
|             switch (message_parts2.length) { | ||||
|                 case 0: | ||||
|                     moveNear(bot.nearestEntity().position) | ||||
|                     break | ||||
|                 case 1: | ||||
|                     switch (message_parts2[0]) { | ||||
|                         case "me": | ||||
|                             if (player) { | ||||
|                                 moveNear(player.position) | ||||
|                             } else { | ||||
|                                 cfg.quiet || bot.chat("can't see you") | ||||
|                             } | ||||
|                             break; | ||||
|  | ||||
|                         default: | ||||
|                             const aPlayer = bot.players[message_parts2[0]] ? bot.players[message_parts2[0]].entity : null | ||||
|                             if (aPlayer) { | ||||
|                                 moveNear(aPlayer.position) | ||||
|                             } else { | ||||
|                                 cfg.quiet || bot.chat(`can't see ${message_parts2[0]}`) | ||||
|                             } | ||||
|                             break; | ||||
|                     } | ||||
|                     break | ||||
|                 case 2: | ||||
|                     //TODO this isn't near | ||||
|                     moveXZ(message_parts2) | ||||
|                     break | ||||
|                 case 3: | ||||
|                     //TODO more checks | ||||
|                     moveNear(message_parts2) | ||||
|                     break | ||||
|                 default: | ||||
|                     break | ||||
|             } | ||||
|             break | ||||
|  | ||||
|         case "follow": | ||||
|             // message_parts2 = message_parts.slice(2) | ||||
|             switch (message_parts2.length) { | ||||
|                 case 0: | ||||
|                     follow(bot.nearestEntity()) | ||||
|                     break | ||||
|                 case 1: | ||||
|                     let dist = 3 | ||||
|                     switch (message_parts2[0]) { | ||||
|                         case "close": | ||||
|                             dist = 1 | ||||
|                         case "me": | ||||
|                         case "once": | ||||
|                             if (player) { | ||||
|                                 follow(player, message_parts2[0] === "me", dist) | ||||
|                             } else { | ||||
|                                 cfg.quiet || bot.chat("can't see you") | ||||
|                             } | ||||
|                             break; | ||||
|  | ||||
|                         default: | ||||
|                             const aPlayer = bot.players[message_parts2[0]] ? bot.players[message_parts2[0]].entity : null | ||||
|                             if (aPlayer) { | ||||
|                                 follow(aPlayer) | ||||
|                             } else { | ||||
|                                 cfg.quiet || bot.chat(`can't see ${message_parts2[0]}`) | ||||
|                             } | ||||
|                             break; | ||||
|                     } | ||||
|                     break | ||||
|                 // case 2: | ||||
|                 // bot.lookAt({}) goalxz? | ||||
|                 // break | ||||
|                 // case 3: | ||||
|                 //TODO more checks | ||||
|                 // moveNear(message_parts2) | ||||
|                 // break | ||||
|                 default: | ||||
|                     cfg.quiet || bot.chat("unknown or bad command") | ||||
|                     break | ||||
|             } | ||||
|             break | ||||
|         case "ride": | ||||
|         case "mount": | ||||
|             ride(message_parts2[0]) | ||||
|             break | ||||
|         case "w": | ||||
|         case "f": | ||||
|             moveOrRide(0, -1, "forward", message_parts2) | ||||
|             break | ||||
|         case "s": | ||||
|         case "b": | ||||
|             moveOrRide(0, 1, "back", message_parts2) | ||||
|             break | ||||
|         case "a": | ||||
|         case "l": | ||||
|             moveOrRide(1, -1, "right", message_parts2) | ||||
|             break | ||||
|         case "d": | ||||
|         case "r": | ||||
|             moveOrRide(1, 1, "left", message_parts2) | ||||
|             break | ||||
|         case "back": | ||||
|         case "forward": | ||||
|         case "jump": | ||||
|         case "left": | ||||
|         case "right": | ||||
|         case "sneak": | ||||
|         case "sprint": | ||||
|             console.info(bot.controlState[message_parts[0]], bot.entity.position.floored()) | ||||
|             bot.setControlState(message_parts[0], true) | ||||
|             console.info(bot.controlState[message_parts[0]]) | ||||
|             setTimeout(bot.setControlState, 100 * (message_parts[1] || 2), message_parts[0], false) | ||||
|             setTimeout(console.info, 5000, bot.controlState[message_parts[0]], bot.entity.position.floored()) | ||||
|             break | ||||
|         case "stop": | ||||
|             stop() | ||||
|             break | ||||
|         default: | ||||
|             return cfg.quiet || bot.chat(`unknown command ${message_parts[0]}`) | ||||
|     } | ||||
| } | ||||
|  | ||||
| const load = (config) => { | ||||
|     cfg = config | ||||
|     bot = cfg.bot | ||||
| @@ -77,19 +278,23 @@ const load = (config) => { | ||||
|         movements: [] | ||||
|     } | ||||
|  | ||||
|     mcData = bot.mcData || (bot.mcData = require('minecraft-data')(bot.version)) | ||||
|     pathfinder = bot.pathfinder || bot.loadPlugin(require('mineflayer-pathfinder').pathfinder) | ||||
|  | ||||
|     // initMoves(bot, mcData) | ||||
|     setTimeout(initMoves, 500, bot) | ||||
|  | ||||
|     // bot.loadPlugin(pathfinder) | ||||
|  | ||||
|     // bot.on('time', hello) | ||||
|     setTimeout(initMoves, 500, bot, mcData) | ||||
|     bot.on('goal_reached', goalReached) | ||||
|  | ||||
| } | ||||
|  | ||||
| const unload = () => { | ||||
|     // TODO stop pathfinding maybe? | ||||
|     stop() | ||||
|     bot.off('goal_reached', goalReached) | ||||
| } | ||||
|  | ||||
| module.exports = { load, unload, stop, initMoves, moveNear, follow } | ||||
| module.exports = { | ||||
|     load, unload, command, | ||||
|     stop, initMoves, | ||||
|     moveNear, moveXZ, moveY, follow, | ||||
|     ride | ||||
| } | ||||
| @@ -7,49 +7,78 @@ let bot = {} | ||||
| let inv | ||||
| // cfg.autosleep = false | ||||
|  | ||||
| function sleep(quiet) { | ||||
|     quiet = quiet !== undefined ? quiet : cfg.sleep.quiet | ||||
| function sleep(quiet = cfg.sleep.quiet) { | ||||
|     if(bot.game.dimension !== "minecraft:overworld" || cfg.sleep.force){ | ||||
|         !quiet && bot.chat("can't sleep, not in overworld now") | ||||
|         return | ||||
|     } | ||||
|     if (bot.isSleeping && !cfg.sleep.force) { | ||||
|         !quiet && bot.chat("already in bed!") | ||||
|         return | ||||
|     } | ||||
|     let bed = bot.findBlock({ | ||||
|         matching: block => bot.isABed(block) | ||||
|     }) | ||||
|     let bedstatus = bed && bot.parseBedMetadata(bed).occupied ? "n unoccupied" : "" | ||||
|     if(bed && bedstatus == "n unoccupied"){ | ||||
|     let bed_occupied = bed && bot.parseBedMetadata(bed).occupied | ||||
|     if (bed && bed_occupied) { | ||||
|         bot.lookAt(bed.position) | ||||
|         bed = bot.findBlock({ | ||||
|             matching: block => bot.isABed(block) && !bot.parseBedMetadata(block).occupied | ||||
|         }) || bed | ||||
|         bedstatus = bot.parseBedMetadata(bed).occupied ? "n unoccupied" : "" | ||||
|         bed_occupied = bot.parseBedMetadata(bed).occupied | ||||
|     } | ||||
|     if (bed && bedstatus == "") { | ||||
|     if (bed && !bed_occupied) { | ||||
|         bot.lookAt(bed.position) | ||||
|         bot.waitForChunksToLoad(() => { | ||||
|             cfg.plugins.moveNear(bed.position) | ||||
|             bot.sleep(bed, (err) => { | ||||
|                 if (err) { | ||||
|                     !quiet && bot.chat(`can't sleep: ${err.message}`) | ||||
|                 } else { | ||||
|                     !quiet && bot.chat("zzz") | ||||
|                     console.log("sleeping? ", bot.isSleeping) | ||||
|                     // hack until this is fixed | ||||
|                     // bot.isSleeping = bot.isSleeping ? bot.isSleeping : true | ||||
|                     bot.isSleeping = true | ||||
|             cfg.plugins.mover && cfg.plugins.mover.moveNear(bed.position, 2) | ||||
|             bot.once('goal_reached', (goal) => { | ||||
|                 console.info(goal) | ||||
|                 try { | ||||
|                     bot.sleep(bed, (err) => { | ||||
|                         if (err) { | ||||
|                             !quiet && bot.chat(`can't sleep: ${err.message}`) | ||||
|                         } else { | ||||
|                             !quiet && bot.chat("zzz") | ||||
|                             // apparently, `bot.isSleeping = true` takes a while | ||||
|                             // maybe it's async | ||||
|                             console.log("sleeping? ", bot.isSleeping) | ||||
|                         } | ||||
|                     }) | ||||
|                 } catch (error) { | ||||
|                     console.error(error) | ||||
|                 } | ||||
|             }) | ||||
|         }) | ||||
|     } else if (inv && inv.equipItem("red_bed", "hand", true)) { | ||||
|         // doesn't work fortunately | ||||
|         // FIXME: DONT IMPLEMENT until it is detected as NOT NETHER | ||||
|         // bot.placeBlock() | ||||
|     } else if (bed = bot.inventory.items().filter(bot.isABed)[0]) { | ||||
|         const v = require('vec3') | ||||
|         bot.equip(bed, "hand", (err) => { if (err) console.error(err) }) | ||||
|         bot.waitForChunksToLoad(() => { | ||||
|             let refBlock = | ||||
|                 // FIXME hack to get around findBlock returning null | ||||
|                 bot.blockAt(bot.entity.position.offset(1, 0, 1), false) | ||||
|             // bot.findBlock({ | ||||
|             //     matching: (block) => { | ||||
|             //         // if (block && block.type !== 0 && block.position) { | ||||
|             //         if (block && block.position) { | ||||
|             //             console.info("found", block) | ||||
|             //             const blockAbove = bot.blockAt(block.position.offset(0, 1, 0)) | ||||
|             //             return !blockAbove || blockAbove.type === 0 | ||||
|             //         } | ||||
|             //         // console.info("not found", block) | ||||
|             //         return false | ||||
|             //     } | ||||
|             //     , maxDistance: 10 | ||||
|             // }) | ||||
|             console.log(refBlock) | ||||
|             bot.placeBlock(refBlock, new v.Vec3(0, 1, 0), console.error) | ||||
|             setTimeout(sleep, 3000, true) | ||||
|         }) | ||||
|     } else { | ||||
|         // TODO: use mover | ||||
|         // bot.gameplay.solveFor( | ||||
|         //     new ObtainItem("bed"), (err) => { | ||||
|         //         if (err) { | ||||
|         //             !quiet && bot.chat(`need a${bedstatus} bed: may not see if just placed`) | ||||
|         !quiet && bot.chat(`need a${bed_occupied ? "n unoccupied" : ""} bed: may not see if just placed`) | ||||
|         //         } | ||||
|         //     } | ||||
|         // ) | ||||
| @@ -72,7 +101,7 @@ function autoSleep() { | ||||
|     if (!bot.time.isDay && !cfg.sleep.timeoutFn && cfg.sleep.auto && !bot.isSleeping) { | ||||
|         sleep() | ||||
|         cfg.sleep.timeoutFn = setTimeout(() => { cfg.sleep.timeoutFn = null }, cfg.sleep.timeout) | ||||
|         console.log("sleeping?", bot.isSleeping, bot.time) | ||||
|         console.log("sleeping?", bot.isSleeping, bot.time.isDay, bot.time.timeOfDay) | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										24
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								package.json
									
									
									
									
									
								
							| @@ -34,20 +34,20 @@ | ||||
|     "require-self": "^0.2.3" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "minecraft-data": "^2.70.2", | ||||
|     "mineflayer": "^2.34.0", | ||||
|     "mineflayer-armor-manager": "^1.3", | ||||
|     "mineflayer-pathfinder": "^1.1", | ||||
|     "mineflayer-pvp": "^1", | ||||
|     "prismarine-block": "^1", | ||||
|     "prismarine-chat": "^1", | ||||
|     "dotenv-packed": "^1.2.1", | ||||
|     "minecraft-data": "^2.73.1", | ||||
|     "mineflayer": "^2.40.1", | ||||
|     "mineflayer-armor-manager": "^1.4.0", | ||||
|     "mineflayer-pathfinder": "^1.3.6", | ||||
|     "mineflayer-pvp": "^1.0.2", | ||||
|     "prismarine-block": "^1.7.3", | ||||
|     "prismarine-chat": "^1.0.3", | ||||
|     "prismarine-entity": "^1.1.0", | ||||
|     "prismarine-item": "^1.5.0", | ||||
|     "prismarine-nbt": "^1.3", | ||||
|     "prismarine-recipe": "^1", | ||||
|     "typescript": "^4", | ||||
|     "vec3": "^0.1", | ||||
|     "dotenv-packed": "^1.2" | ||||
|     "prismarine-nbt": "^1.4.0", | ||||
|     "prismarine-recipe": "^1.1.0", | ||||
|     "typescript": "^4.1.3", | ||||
|     "vec3": "^0.1.7" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "lib/**/*" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user