├── .gitignore ├── README.md ├── lumberjack.js ├── package.json └── tools.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dutieflayer 2 | Using Dutie with Mineflayer = Awesome 3 | -------------------------------------------------------------------------------- /lumberjack.js: -------------------------------------------------------------------------------- 1 | var mineflayer = require('mineflayer'); 2 | var navigatePlugin = require('mineflayer-navigate')(mineflayer); 3 | var scaffoldPlugin = require('mineflayer-scaffold')(mineflayer); 4 | var blockFinderPlugin = require('mineflayer-blockfinder')(mineflayer); 5 | 6 | var vec3 = require('vec3'); 7 | var Dutie = require('dutie'); 8 | var Task = Dutie.Task, 9 | CallTask = Dutie.CallTask, 10 | RunTask = Dutie.RunTask, 11 | ExecTask = Dutie.ExecTask; 12 | 13 | var main = new Dutie(); 14 | 15 | /*if(process.argv.length<3 || process.argv.length>5) 16 | { 17 | console.log("Usage : node dudieflayer.js [] []"); 18 | process.exit(1); 19 | }*/ 20 | 21 | //bot.on('spawn', function() { console.log(bot.inventory) }); 22 | 23 | /*var bot = mineflayer.createBot({ 24 | username: process.argv[4] ? process.argv[4] : "Duter", 25 | verbose: true, 26 | port:parseInt(process.argv[3]), 27 | host:process.argv[2], 28 | password:process.argv[5] 29 | });*/ 30 | 31 | 32 | var activeTree = []; 33 | var path = []; 34 | 35 | //bot.on('chat', chatMessage); 36 | 37 | function chatMessage(username, message) { 38 | if (message == 'lumberjack') { 39 | getWood(32, bot); 40 | } 41 | } 42 | 43 | function getWood(amt, bt) { 44 | bot = bt; 45 | navigatePlugin(bot); 46 | blockFinderPlugin(bot); 47 | scaffoldPlugin(bot); 48 | 49 | var wood = bot.inventory.findInventoryItem(17, null); 50 | if (wood && wood.count >= amt) { 51 | console.log('enough wood', wood, amt); 52 | return new RunTask(function() {}); 53 | } 54 | 55 | var lumberjack = new RunTask(treeFinder, [amt], { priority: 5, actPriority: 8, check: lumberCheck}); 56 | return lumberjack; 57 | //main.add(lumberjack); 58 | } 59 | 60 | 61 | 62 | function treeFinder(lumberDutie, amt) { 63 | var wood = bot.inventory.findInventoryItem(17, null); 64 | if (wood && wood.count >= amt) return; 65 | 66 | var findTreeTask = new CallTask(bot.findBlock, [ { // Find tree task. Sets activeTree to the tree it finds 67 | matching: 17, 68 | maxDistance: 64, 69 | count: 50, 70 | point: bot.entity.position 71 | } ], {complete: function(err, blockPoints) { 72 | for (var i = 0; i < blockPoints.length; i++) { 73 | var tree = findTree(blockPoints[i].position); 74 | if (tree) { 75 | activeTree = tree; 76 | cutTree(lumberDutie, amt); 77 | return; 78 | } 79 | } 80 | lumberDutie.tasks = []; 81 | }}); 82 | lumberDutie.add(findTreeTask); 83 | } 84 | 85 | function cutTree(lumberDutie, amt) { 86 | var goToTree = new CallTask(bot.scaffold.to, [activeTree[0].position]); 87 | lumberDutie.add(goToTree); 88 | 89 | for (var i = 0; i < activeTree.length; i++) { 90 | var block = activeTree[i]; 91 | var lookAt = new ExecTask(bot.lookAt, [block.position, true]); 92 | var mineBlock = new CallTask(bot.dig, [block], { cancel: bot.stopDigging, start: function() { 93 | return block.name == 'air'; 94 | }, complete: function() { 95 | if (lumberDutie.tasks.length == 0) { 96 | lumberDutie.add(new CallTask(setTimeout, [null, 1000], {location: 0, complete: treeFinder, completeParams: [lumberDutie, amt]})); 97 | } 98 | }}); 99 | lumberDutie.addAll(mineBlock.dependOn(lookAt)); 100 | } 101 | } 102 | 103 | 104 | 105 | function lumberCheck() { 106 | console.log('equip'); 107 | var axe = null; 108 | var axeList = [279, 258, 275, 271]; 109 | for (var i = 0; i < axeList.length; i++) { 110 | axe = bot.inventory.findInventoryItem(axeList[i], null); 111 | if (axe) break; 112 | } 113 | if (!axe) { 114 | console.log('none :('); 115 | return true; 116 | } else { 117 | bot.equip(axe, 'hand', function(err) { 118 | if (err) console.log(err.stack); 119 | else bot.hand = axe; 120 | }); 121 | console.log(axe); 122 | return true; 123 | } 124 | } 125 | 126 | function findTree(p) { 127 | var point = p.clone(); 128 | var oldY = p.y; 129 | var bottom; 130 | var top; 131 | while (!bottom) { 132 | point.subtract(vec3(0, 1, 0)); 133 | var block = bot.blockAt(point); 134 | if (block.name != 'log') { 135 | if (block.name == 'dirt') bottom = point.clone().add(vec3(0, 1, 0)); 136 | else return false; 137 | } 138 | } 139 | point.y = oldY; 140 | while (!top) { 141 | point.add(vec3(0, 1, 0)); 142 | var block = bot.blockAt(point); 143 | if (block.name != 'log') { 144 | if (block.name == 'leaves') top = point.clone().subtract(vec3(0, 1, 0)); 145 | else return false; 146 | } 147 | } 148 | var sides = [vec3(1, 0, 0), vec3(-1, 0, 0), vec3(0, 0, 1), vec3(0, 0, -1)]; 149 | for (var s = 0; s < sides.length; s++) { 150 | point = top.clone().add(sides[s]); 151 | if (bot.blockAt(point).name != 'leaves') return false; 152 | } 153 | 154 | 155 | var tree = Array(); 156 | for (var i = bottom.y; i <= top.y; i++) { 157 | var block = bot.blockAt(vec3(bottom.x, i, bottom.z)); 158 | tree.push(block); 159 | } 160 | return tree; 161 | } 162 | 163 | module.exports = getWood; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dutieflayer", 3 | "version": "0.1.0", 4 | "description": "Dutie and Mineflayer combined into a minecraft bot(s)", 5 | "main": "tools.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/demipixel/dutieflayer.git" 12 | }, 13 | "keywords": [ 14 | "dutie", 15 | "mineflayer", 16 | "flayer", 17 | "minecraft", 18 | "bot", 19 | "automated" 20 | ], 21 | "author": "Lucas Simon ", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/demipixel/dutieflayer/issues" 25 | }, 26 | "homepage": "https://github.com/demipixel/dutieflayer", 27 | "dependencies": { 28 | "mineflayer-blockfinder": "git://github.com/rom1504/mineflayer-blockfinder.git#fix_recursion", 29 | "mineflayer-navigate": "^0.0.9", 30 | "dutie": "^1.2.4", 31 | "mineflayer": "git://github.com/andrewrk/mineflayer.git#master", 32 | "vec3": "^0.1.3", 33 | "mineflayer-scaffold": "^0.0.5", 34 | "spiralloop": "^1.0.1" 35 | }, 36 | "devDependencies": {} 37 | } 38 | -------------------------------------------------------------------------------- /tools.js: -------------------------------------------------------------------------------- 1 | var mineflayer = require('mineflayer'); 2 | var lumberjack = require('./lumberjack'); 3 | var navigatePlugin = require('mineflayer-navigate')(mineflayer); 4 | var scaffoldPlugin = require('mineflayer-scaffold')(mineflayer); 5 | var blockFinderPlugin = require('mineflayer-blockfinder')(mineflayer); 6 | 7 | var vec3 = require('vec3'); 8 | var Dutie = require('dutie'); 9 | var spiral = require('spiralloop'); 10 | var Task = Dutie.Task, 11 | CallTask = Dutie.CallTask, 12 | RunTask = Dutie.RunTask, 13 | ExecTask = Dutie.ExecTask; 14 | 15 | var main = new Dutie(); 16 | 17 | if(process.argv.length<3 || process.argv.length>6) 18 | { 19 | console.log("Usage : node tools.js [] []"); 20 | process.exit(1); 21 | } 22 | var bot = mineflayer.createBot({ 23 | username: process.argv[4] ? process.argv[4] : "Toolster", 24 | verbose: true, 25 | port:parseInt(process.argv[3]), 26 | host:process.argv[2], 27 | password:process.argv[5] 28 | }); 29 | 30 | navigatePlugin(bot); 31 | blockFinderPlugin(bot); 32 | scaffoldPlugin(bot); 33 | 34 | bot.on('chat', chatMessage); 35 | 36 | bot.on('kicked', function(reason) { 37 | console.log('KICKED!',reason); 38 | }); 39 | 40 | bot.on('end', function() { 41 | console.log('ENDED!'); 42 | }); 43 | 44 | /*bot.on('spawn', function() { 45 | setTimeout(function() { 46 | var tools = new RunTask(getTools, [], { priority: 5, actPriority: 8 }); 47 | main.add(tools); 48 | 49 | var player = 'Your username'; 50 | var give = new RunTask(tossTools, [player], { priority: 3, actPriority: 4}); 51 | main.add(give); 52 | },10*1000); 53 | });*/ 54 | 55 | function chatMessage(username, message) { 56 | console.log(username + ': ' + message); 57 | if (message == 'tools') { 58 | var tools = new RunTask(getTools, [], { priority: 5, actPriority: 8 }); 59 | main.add(tools); 60 | } else if (message == 'list') { 61 | listInventory(); 62 | } else if (message == 'give tools') { 63 | var give = new RunTask(tossTools, [username], { priority: 3, actPriority: 4}); 64 | main.add(give); 65 | } else if (message == 'toss all') { 66 | console.log('tossing all'); 67 | var toss = new RunTask(tossAll, [username], { priority: 1, actPriority: 2}); 68 | main.add(toss); 69 | } else if (message == 'come') { 70 | var entity = bot.players[username].entity; 71 | console.log(entity.position); 72 | var path = bot.navigate.findPathSync(entity.position); 73 | var come = new CallTask(bot.navigate.walk, [path.path], { priority: 2, actPriority: 3, complete: function() { console.log('done') }}); 74 | main.add(come); 75 | } 76 | if (message == 'follow') { 77 | var entity = bot.players[username].entity; 78 | //var follow = new CallTask(bot.navigate.to, [entity.position], { priority: 2, actPriority: 3}); 79 | } 80 | //////////// COPIED FROM INVENTORY.JS 81 | /*if (/^toss (\d+) /.test(message)) { 82 | words = message.split(" "); 83 | amount = parseInt(words[1], 10); 84 | name = words[2]; 85 | item = itemByName(name); 86 | if (item) { 87 | var entity = bot.players[username].entity; 88 | bot.lookAt(entity.position.offset(0, entity.height, 0)); 89 | 90 | bot.toss(item.type, null, amount, function(err) { 91 | if (err) { 92 | bot.chat("unable to toss " + item.name); 93 | console.error(err.stack); 94 | } else { 95 | bot.chat("tossed " + amount + " " + item.name); 96 | } 97 | }); 98 | } else { 99 | bot.chat("I have no " + name); 100 | } 101 | } else if (/^toss /.test(message)) { 102 | words = message.split(" "); 103 | name = words[1]; 104 | item = itemByName(name); 105 | if (item) { 106 | var entity = bot.players[username].entity; 107 | bot.lookAt(entity.position.offset(0, entity.height, 0)); 108 | 109 | bot.tossStack(item, function(err) { 110 | if (err) { 111 | bot.chat("unable to toss " + item.name); 112 | console.error(err.stack); 113 | } else { 114 | bot.chat("tossed " + item.name); 115 | } 116 | }); 117 | } else { 118 | bot.chat("I have no " + name); 119 | } 120 | }*/ 121 | //////////////////////// 122 | //////////////////////// 123 | } 124 | 125 | 126 | function getTools(m) { 127 | var lumb = lumberjack(4, bot); 128 | console.log('lumb'); 129 | 130 | /*var wood = bot.inventory.findInventoryItem(17, null); 131 | bot.lookAt(bot.entity.position.offset(-2, 0, 0)); 132 | if (wood) bot.tossStack(wood);*/ 133 | 134 | var location = vec3(0, 0, 0); 135 | var foundBench = { val: false}; 136 | var benchExists = new ExecTask(function() { 137 | spiral([7, 4, 7], function(x, y, z) { 138 | x += Math.floor(bot.entity.position.x) - 3; 139 | y += Math.floor(bot.entity.position.y) - 1; 140 | z += Math.floor(bot.entity.position.z) - 3; 141 | var block = bot.blockAt(vec3(x, y, z)) || { name: null }; 142 | if (block.name == 'workbench') { 143 | location.x = x; 144 | location.y = y; 145 | location.z = z; 146 | foundBench.val = true; 147 | console.log('FOUND BENCH'); 148 | return true; 149 | } 150 | }); 151 | }); 152 | 153 | var makePlanks = new RunTask(craftPlanks, [foundBench]); 154 | 155 | var getBenchLocation = new ExecTask(function() { 156 | if (foundBench.val) return; 157 | spiral([7, 6, 7], function(x, y, z) { 158 | if (x == 3 && z == 3) return; 159 | x += Math.floor(bot.entity.position.x) - 3; 160 | y += Math.floor(bot.entity.position.y) - 3; 161 | z += Math.floor(bot.entity.position.z) - 3; 162 | y -= 1; // Prefer feet height 163 | var block = bot.blockAt(vec3(x, y, z)); 164 | var block_under = bot.blockAt(vec3(x, y-1, z)); 165 | console.log(x + ', ' + y + ', ' + z + ' => ' + block.name + ', ' + block_under.name); 166 | if (block.name == 'air' && block_under.name != 'air') { 167 | location.x = x; 168 | location.y = y; 169 | location.z = z; 170 | return true; 171 | } 172 | } 173 | )}, [], { start: function() { if (foundBench.val) return true; }}); 174 | 175 | var centerTask = new ExecTask(function() { 176 | if (location.y == -1) return; 177 | bot.entity.position = center(bot.entity.position); 178 | }); 179 | var waitTask = new CallTask(setTimeout, [null, 200], { location: 0, start: function() { if (foundBench.val) return true; }}); 180 | 181 | var placeBench = new RunTask(placeCraftBench, [location], { start: function() { 182 | if (foundBench.val) return true; 183 | }}); 184 | 185 | var craftPick = new RunTask(craftPickaxe, [location]); 186 | 187 | var stone = Array(); 188 | var safeStandLocation = vec3(0, 0, 0); 189 | 190 | var findStone = new ExecTask(function() { 191 | console.log('searching for stone'); 192 | safeStandLocation.x = bot.entity.position.x; 193 | safeStandLocation.y = bot.entity.position.y; 194 | safeStandLocation.z = bot.entity.position.z; 195 | 196 | spiral([40, 16, 40], function(x, y, z) { 197 | x += Math.floor(bot.entity.position.x) - 20; 198 | y += Math.floor(bot.entity.position.y) - 8; 199 | z += Math.floor(bot.entity.position.z) - 20; 200 | 201 | var block = bot.blockAt(vec3(x, y, z)); 202 | if (block.name == 'stone' && block.metadata == 0) stone.push(block); 203 | if (stone.length > 35) return true; // Have plenty just in case some get destroyed. 204 | }); 205 | }); 206 | var switchPick = new RunTask(switchToPick); 207 | var mineStone = new RunTask(getStone, [stone]); 208 | var goBack = new RunTask(goBackToBench, [safeStandLocation]); 209 | var craftTools = new RunTask(craftStoneTools, [location]); 210 | 211 | lumb.dependBy(benchExists).dependBy(makePlanks).dependBy(getBenchLocation).dependBy(centerTask).dependBy(waitTask).dependBy(placeBench) 212 | .dependBy(craftPick).dependBy(findStone).dependBy(switchPick).dependBy(mineStone).dependBy(goBack).dependBy(craftTools); 213 | m.addAll(lumb); 214 | } 215 | 216 | function craftPlanks(m, b) { 217 | console.log('craft planks'); 218 | var bench = b.val; 219 | var wood = bot.inventory.findInventoryItem(17, null); 220 | var plankRecipeList = bot.recipesFor(5, null, null, null); 221 | var plankRecipe; 222 | for (var i = 0; i < plankRecipeList.length; i++) { 223 | var listmeta = plankRecipeList[i].ingredients[0].metadata 224 | if (wood.metadata == listmeta || !listmeta) plankRecipe = plankRecipeList[i]; 225 | } 226 | if (!plankRecipe) { 227 | plankRecipe = plankRecipeList[0]; 228 | } 229 | 230 | var benchRecipe = bot.recipesAll(58, null, null, null)[0]; 231 | if (!bench) console.log('craft crafting bench'); 232 | 233 | var craftTask = new CallTask(bot.craft, [plankRecipe, (bench ? 3 : 4), null]); // 3:4 => Don't need to make extra if we already have a crafting bench 234 | var benchTask = new CallTask(bot.craft, [benchRecipe, 1, null]); 235 | if (!bench) { // loc contains position of crafting table if one exists 236 | benchTask.dependOn(craftTask); 237 | m.addAll(craftTask); 238 | } else { 239 | m.add(craftTask); // Don't make crafting bench if we already have one nearby 240 | } 241 | } 242 | 243 | function placeCraftBench(m, loc) { 244 | console.log('place crafting bench'); 245 | var bench = bot.inventory.findInventoryItem(58, null); 246 | var switchToBench = new CallTask(bot.equip, [bench, 'hand']); 247 | var wait = new CallTask(setTimeout, [null, 200], { location: 0}); 248 | 249 | var refBlock = bot.blockAt(loc.clone().minus(vec3(0, 1, 0))); 250 | console.log('refBlock',refBlock); 251 | var placeBench = new RunTask(bot.placeBlock, [refBlock, vec3(0, 1, 0)], { manager: false}); 252 | switchToBench.dependBy(wait); 253 | wait.dependBy(placeBench); 254 | 255 | m.addAll(placeBench); 256 | } 257 | 258 | function center(p) { 259 | console.log('center on block'); 260 | return p.floored().offset(0.5,0,0.5); 261 | } 262 | 263 | function craftPickaxe(m, location) { 264 | console.log('Craft sticks and pickaxe'); 265 | var stickRecipe = bot.recipesAll(280, null, false)[0]; 266 | var craftSticks = new CallTask(bot.craft, [stickRecipe, 3, null]); 267 | 268 | var woodPickRecipe = bot.recipesAll(270, null, true)[0]; 269 | var craftWoodPick = new CallTask(bot.craft, [woodPickRecipe, 1, bot.blockAt(location)]); 270 | console.log(bot.blockAt(location)); 271 | console.log('this',woodPickRecipe.inShape); 272 | 273 | craftWoodPick.dependOn(craftSticks); 274 | m.addAll(craftWoodPick); 275 | } 276 | 277 | function switchToPick(m) { 278 | console.log('switch to pickaxe'); 279 | var pick = bot.inventory.findInventoryItem(270); 280 | var switchToBench = new CallTask(bot.equip, [pick, 'hand']); 281 | m.add(switchToBench); 282 | } 283 | 284 | function getStone(m, stone) { 285 | 286 | var finish = function() { 287 | if (this.currentTask.startFunc) { // If just bot.scaffold.to rather than digImmediate 288 | m.add(new RunTask(switchToPick)); 289 | } 290 | var stoneInv = bot.inventory.findInventoryItem(4, null) || { count: 0}; 291 | if (stoneInv.count < 9) { // 9 is the exact amount needed for tools. Add more if needed. 292 | stone.splice(0, 1); 293 | 294 | var sides = [vec3(1, 0, 0), vec3(-1, 0, 0), vec3(0, 0, 1), vec3(0, 0, -1)]; 295 | var found = false; 296 | for (var y = 0; y < 2; y++) { 297 | for (var s = 0; s < sides.length; s++) { 298 | var location = bot.entity.position.clone().floor(); 299 | location.add(sides[s]); 300 | location.add(vec3(0, y, 0)); 301 | if (bot.blockAt(location).name == 'stone') { 302 | found = true; 303 | console.log('Location',location); 304 | digImmediate.reset([bot.blockAt(location)]); 305 | m.add(digImmediate); 306 | break; 307 | } 308 | } 309 | if (found) break; 310 | } 311 | 312 | if (!found) { 313 | if (!stone[0].position) return; 314 | digStone.reset([stone[0].position]); 315 | m.add(digStone); 316 | } 317 | } else console.log('collected all stone'); 318 | } 319 | 320 | var start = function() { 321 | if (bot.blockAt(stone[0].position).name != 'stone') { 322 | stone.splice(0, 1); 323 | m.add(digStone); 324 | } 325 | } 326 | 327 | var digStone = new CallTask(bot.scaffold.to, [stone[0].position], { complete: finish, start: start }); 328 | 329 | var digImmediate = new CallTask(bot.dig, [stone[0].position], { complete: finish }); 330 | 331 | m.add(digStone); 332 | } 333 | 334 | function goBackToBench(m, loc) { 335 | m.add(new CallTask(bot.scaffold.to, [loc])); 336 | } 337 | 338 | function craftStoneTools(m, loc) { 339 | var bench = bot.blockAt(loc); 340 | 341 | var stoneSwordRecipe = bot.recipesAll(272, null, true)[0]; 342 | var craftStoneSword = new CallTask(bot.craft, [stoneSwordRecipe, 1, bench]); 343 | 344 | var stonePickRecipe = bot.recipesAll(274, null, true)[0]; 345 | var craftStonePick = new CallTask(bot.craft, [stonePickRecipe, 1, bench]); 346 | 347 | var stoneAxeRecipe = bot.recipesAll(275, null, true)[0]; 348 | var craftStoneAxe = new CallTask(bot.craft, [stoneAxeRecipe, 1, bench]); 349 | 350 | var stoneShovelRecipe = bot.recipesAll(273, null, true)[0]; 351 | var craftStoneShovel = new CallTask(bot.craft, [stoneShovelRecipe, 1, bench]); 352 | 353 | m.add(craftStoneSword).add(craftStonePick).add(craftStoneAxe).add(craftStoneShovel); 354 | } 355 | 356 | 357 | function tossAll(m, username) { 358 | var entity; 359 | if (bot.players[username]) entity = bot.players[username].entity; 360 | if (entity) bot.lookAt(entity.position.offset(0, entity.height, 0)); 361 | 362 | console.log(bot.inventory.slots); 363 | 364 | for (var i = 0; i < bot.inventory.slots.length; i++) { 365 | console.log(bot.inventory.slots[i]); 366 | var item = bot.inventory.slots[i]; 367 | if (item) { 368 | var toss = new CallTask(bot.tossStack, [item]); 369 | m.add(toss); 370 | } 371 | } 372 | } 373 | 374 | function tossTools(m, player) { 375 | var entity = bot.players[player].entity; 376 | bot.lookAt(entity.position.offset(0, entity.height, 0), true); 377 | var wait = new CallTask(setTimeout, [null, 500], {location: 0, priority: 1}); 378 | m.add(wait); 379 | 380 | for (var i = 272; i <= 275; i++) { 381 | var item = bot.inventory.findInventoryItem(i); 382 | if (item) { 383 | var toss = new CallTask(bot.tossStack, [item]); 384 | m.add(toss); 385 | } 386 | } 387 | } 388 | 389 | function listInventory() { 390 | var text = bot.inventory.items().map(itemStr).join(", "); 391 | if (text == '') bot.chat('(Nothing)'); 392 | else bot.chat(text); 393 | } 394 | 395 | function itemStr(item) { 396 | if (item) { 397 | return item.name + " x " + item.count; 398 | } else { 399 | return "(nothing)"; 400 | } 401 | } 402 | 403 | function itemByName(name) { 404 | return bot.inventory.items().filter(function(item) { 405 | return item.name === name; 406 | })[0]; 407 | } --------------------------------------------------------------------------------