2020-12-21 16:08:38 +00:00
|
|
|
/*
|
|
|
|
* Using the inventory is one of the first things you learn in Minecraft,
|
|
|
|
* now it's time to teach your bot the same skill.
|
|
|
|
*
|
|
|
|
* Command your bot with chat messages and make him toss, equip, use items
|
|
|
|
* and even craft new items using the built-in recipe book.
|
|
|
|
*
|
|
|
|
* To learn more about the recipe system and how crafting works
|
|
|
|
* remember to read the API documentation!
|
|
|
|
*/
|
|
|
|
const mineflayer = require('mineflayer')
|
|
|
|
|
|
|
|
|
|
|
|
let cfg = {}
|
|
|
|
let bot = {}
|
|
|
|
// let mcd
|
|
|
|
|
2020-12-22 06:29:31 +00:00
|
|
|
const alt_destinations = {
|
|
|
|
offhand: "off-hand",
|
|
|
|
lefthand: "off-hand",
|
|
|
|
shield: "off-hand",
|
|
|
|
chest: "torso",
|
|
|
|
}
|
|
|
|
|
2020-12-21 16:08:38 +00:00
|
|
|
function inventory(username, message) {
|
|
|
|
if (username === bot.username) return
|
|
|
|
const command = message.split(' ')
|
|
|
|
switch (true) {
|
|
|
|
// case message === 'loaded':
|
|
|
|
// bot.waitForChunksToLoad(() => {
|
|
|
|
// bot.chat('Ready!')
|
|
|
|
// })
|
|
|
|
// break
|
|
|
|
case /^list$/.test(message):
|
|
|
|
sayItems()
|
|
|
|
break
|
|
|
|
case /^toss \d+ \w+$/.test(message):
|
|
|
|
// toss amount name
|
|
|
|
// ex: toss 64 diamond
|
|
|
|
tossItem(command[2], command[1])
|
|
|
|
break
|
|
|
|
case /^toss \w+$/.test(message):
|
|
|
|
// toss name
|
|
|
|
// ex: toss diamond
|
|
|
|
tossItem(command[1])
|
|
|
|
break
|
|
|
|
case /^equip \w+ \w+$/.test(message):
|
|
|
|
// equip destination name
|
|
|
|
// ex: equip hand diamond
|
|
|
|
equipItem(command[2], command[1], quiet = cfg.quiet)
|
|
|
|
break
|
|
|
|
case /^unequip \w+$/.test(message):
|
|
|
|
// unequip testination
|
|
|
|
// ex: unequip hand
|
|
|
|
unequipItem(command[1])
|
|
|
|
break
|
|
|
|
case /^use$/.test(message):
|
|
|
|
useEquippedItem()
|
|
|
|
break
|
|
|
|
case /^craft \d+ \w+$/.test(message):
|
|
|
|
// craft amount item
|
|
|
|
// ex: craft 64 stick
|
|
|
|
craftItem(command[2], command[1])
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function sayItems(items = bot.inventory.items()) {
|
|
|
|
const output = items.map(itemToString).join(', ')
|
2020-12-22 06:29:31 +00:00
|
|
|
console.info("inventory:", output)
|
2020-12-21 16:08:38 +00:00
|
|
|
if (output) {
|
|
|
|
!cfg.quiet && bot.chat(output)
|
|
|
|
} else {
|
|
|
|
!cfg.quiet && bot.chat('empty')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function tossItem(name, amount) {
|
|
|
|
amount = parseInt(amount, 10)
|
|
|
|
const item = itemByName(name)
|
|
|
|
if (!item) {
|
|
|
|
bot.chat(`I have no ${name}`)
|
|
|
|
} else if (amount) {
|
|
|
|
bot.toss(item.type, null, amount, checkIfTossed)
|
|
|
|
} else {
|
|
|
|
bot.tossStack(item, checkIfTossed)
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkIfTossed(err) {
|
|
|
|
if (err) {
|
|
|
|
bot.chat(`unable to toss: ${err.message}`)
|
|
|
|
} else if (amount) {
|
|
|
|
bot.chat(`tossed ${amount} x ${name}`)
|
|
|
|
} else {
|
|
|
|
bot.chat(`tossed ${name}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function equipItem(name, destination, quiet = false) {
|
|
|
|
const item = itemByName(name)
|
2020-12-22 06:29:31 +00:00
|
|
|
|
2020-12-21 16:08:38 +00:00
|
|
|
if (item) {
|
2020-12-22 06:29:31 +00:00
|
|
|
if (Object.keys(alt_destinations).includes(destination)) {
|
|
|
|
destination = alt_destinations[destination]
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
bot.equip(item, destination, checkIfEquipped)
|
|
|
|
} catch (error) {
|
|
|
|
if (error.code == 'ERR_ASSERTION' && error.message.startsWith("invalid destination:")) {
|
|
|
|
bot.chat(error.message)
|
|
|
|
} else {
|
|
|
|
console.error(error)
|
|
|
|
}
|
|
|
|
}
|
2020-12-21 16:08:38 +00:00
|
|
|
} else {
|
|
|
|
!quiet && bot.chat(`I have no ${name}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkIfEquipped(err) {
|
|
|
|
if (err) {
|
|
|
|
bot.chat(`cannot equip ${name}: ${err.message}`)
|
|
|
|
} else {
|
|
|
|
!quiet && bot.chat(`equipped ${name}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function unequipItem(destination) {
|
2020-12-22 06:29:31 +00:00
|
|
|
if (Object.keys(alt_destinations).includes(destination)) {
|
|
|
|
destination = alt_destinations[destination]
|
|
|
|
}
|
2020-12-21 16:08:38 +00:00
|
|
|
bot.unequip(destination, (err) => {
|
|
|
|
if (err) {
|
|
|
|
bot.chat(`cannot unequip: ${err.message}`)
|
|
|
|
} else {
|
|
|
|
bot.chat('unequipped')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function useEquippedItem() {
|
|
|
|
bot.chat('activating item')
|
|
|
|
bot.activateItem()
|
|
|
|
}
|
|
|
|
|
2020-12-22 06:29:31 +00:00
|
|
|
function craftItem(name, amount = 1) {
|
2020-12-21 16:08:38 +00:00
|
|
|
amount = parseInt(amount, 10)
|
2020-12-22 06:29:31 +00:00
|
|
|
const mcData = require('minecraft-data')(bot.version)
|
|
|
|
const item = mcData.findItemOrBlockByName(name)
|
2020-12-21 16:08:38 +00:00
|
|
|
const craftingTable = bot.findBlock({
|
2020-12-22 06:29:31 +00:00
|
|
|
matching: mcData.blocksByName["crafting_table"].id
|
2020-12-21 16:08:38 +00:00
|
|
|
})
|
|
|
|
|
2020-12-22 06:29:31 +00:00
|
|
|
const recipesNoTable = bot.recipesFor(item.id)
|
|
|
|
let recipes
|
|
|
|
|
|
|
|
if (recipesNoTable.length > 0) {
|
|
|
|
bot.chat("can make without crafting table!")
|
|
|
|
recipes = recipesNoTable
|
|
|
|
} else if (craftingTable) {
|
|
|
|
recipes = bot.recipesFor(item.id, null, null, craftingTable)
|
|
|
|
} else {
|
|
|
|
bot.chat("Couldn't find a crafting table. Maybe craft one?")
|
|
|
|
}
|
|
|
|
|
2020-12-21 16:08:38 +00:00
|
|
|
if (item) {
|
2020-12-22 06:29:31 +00:00
|
|
|
let craftSuccess
|
|
|
|
recipes && cfg.quiet || bot.chat(`${recipes.length} recipes`)
|
|
|
|
for (let recipe in recipes) {
|
|
|
|
if (craftSuccess) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
setTimeout(craftIt, Math.random() * 5000, recipes[recipe], amount, craftingTable)
|
|
|
|
}
|
|
|
|
function craftIt(recipe, amount, craftingTable) {
|
|
|
|
cfg.quiet || bot.chat(`I can make ${name}`)
|
|
|
|
console.log("craft:", recipe)
|
|
|
|
console.time("craft recipe")
|
|
|
|
bot.craft(recipe, amount, craftingTable, craftError)
|
|
|
|
console.timeEnd("craft recipe")
|
|
|
|
}
|
|
|
|
function craftError(err) {
|
|
|
|
if (err) {
|
|
|
|
console.error(err)
|
|
|
|
cfg.quiet || bot.chat(`error making ${name}: ${err.message}`)
|
|
|
|
// continue
|
|
|
|
} else {
|
|
|
|
craftSuccess = true
|
|
|
|
bot.chat(`did the recipe for ${name} ${amount} times`)
|
|
|
|
// break
|
|
|
|
}
|
2020-12-21 16:08:38 +00:00
|
|
|
}
|
2020-12-22 06:29:31 +00:00
|
|
|
craftSuccess || cfg.quiet || bot.chat(`I couldn't make ${name}`)
|
2020-12-21 16:08:38 +00:00
|
|
|
} else {
|
|
|
|
bot.chat(`unknown item: ${name}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function itemToString(item) {
|
|
|
|
if (item) {
|
|
|
|
return `${item.name} x ${item.count}`
|
|
|
|
} else {
|
|
|
|
return '(nothing)'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function itemByName(name) {
|
|
|
|
return bot.inventory.items().filter(item => item.name === name)[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const load = (config) => {
|
|
|
|
cfg = config
|
|
|
|
bot = cfg.bot
|
|
|
|
// cfg.inventory = {
|
|
|
|
// auto: true,
|
|
|
|
// quiet: false
|
|
|
|
// }
|
|
|
|
bot.on('chat', inventory)
|
|
|
|
}
|
|
|
|
|
|
|
|
const unload = () => {
|
|
|
|
bot.off('chat', inventory)
|
|
|
|
}
|
|
|
|
|
2020-12-22 06:29:31 +00:00
|
|
|
module.exports = { load, unload, equipItem, craftItem }
|