LookAtMySuitBot/js/node_modules/mineflayer/lib/plugins/anvil.js

116 lines
3.9 KiB
JavaScript

const assert = require('assert')
const { sleep } = require('../promise_utils')
const { once } = require('events')
module.exports = inject
function inject (bot) {
const Item = require('prismarine-item')(bot.registry)
const matchWindowType = window => /minecraft:(?:chipped_|damaged_)?anvil/.test(window.type)
async function openAnvil (anvilBlock) {
const anvil = await bot.openBlock(anvilBlock)
if (!matchWindowType(anvil)) {
throw new Error('This is not a anvil-like window')
}
function err (name) {
anvil.close()
throw new Error(name)
}
function sendItemName (name) {
if (bot.supportFeature('useMCItemName')) {
bot._client.writeChannel('MC|ItemName', name)
} else {
bot._client.write('name_item', { name })
}
}
async function addCustomName (name) {
if (!name) return
for (let i = 1; i < name.length + 1; i++) {
sendItemName(name.substring(0, i))
await sleep(50)
}
}
async function putInAnvil (itemOne, itemTwo) {
await putSomething(0, itemOne.type, itemOne.metadata, itemOne.count, itemOne.nbt)
sendItemName('') // sent like this by vnailla
if (!bot.supportFeature('useMCItemName')) sendItemName('')
await putSomething(1, itemTwo.type, itemTwo.metadata, itemTwo.count, itemTwo.nbt)
}
async function combine (itemOne, itemTwo, name) {
if (name?.length > 35) err('Name is too long.')
if (bot.supportFeature('useMCItemName')) {
bot._client.registerChannel('MC|ItemName', 'string')
}
assert.ok(itemOne && itemTwo)
const { xpCost: normalCost } = Item.anvil(itemOne, itemTwo, bot.game.gameMode === 'creative', name)
const { xpCost: inverseCost } = Item.anvil(itemTwo, itemOne, bot.game.gameMode === 'creative', name)
if (normalCost === 0 && inverseCost === 0) err('Not anvil-able (in either direction), cancelling.')
const smallest = (normalCost < inverseCost ? normalCost : inverseCost) === 0 ? inverseCost : 0
if (bot.game.gameMode !== 'creative' && bot.experience.level < smallest) {
err('Player does not have enough xp to do action, cancelling.')
}
const xpPromise = bot.game.gameMode === 'creative' ? Promise.resolve() : once(bot, 'experience')
if (normalCost === 0) await putInAnvil(itemTwo, itemOne)
else if (inverseCost === 0) await putInAnvil(itemOne, itemTwo)
else if (normalCost < inverseCost) await putInAnvil(itemOne, itemTwo)
else await putInAnvil(itemTwo, itemOne)
await addCustomName(name)
await bot.putAway(2)
await xpPromise
}
async function rename (item, name) {
if (name?.length > 35) err('Name is too long.')
if (bot.supportFeature('useMCItemName')) {
bot._client.registerChannel('MC|ItemName', 'string')
}
assert.ok(item)
const { xpCost: normalCost } = Item.anvil(item, null, bot.game.gameMode === 'creative', name)
if (normalCost === 0) err('Not valid rename, cancelling.')
if (bot.game.gameMode !== 'creative' && bot.experience.level < normalCost) {
err('Player does not have enough xp to do action, cancelling.')
}
const xpPromise = once(bot, 'experience')
await putSomething(0, item.type, item.metadata, item.count, item.nbt)
sendItemName('') // sent like this by vnailla
if (!bot.supportFeature('useMCItemName')) sendItemName('')
await addCustomName(name)
await bot.putAway(2)
await xpPromise
}
async function putSomething (destSlot, itemId, metadata, count, nbt) {
const options = {
window: anvil,
itemType: itemId,
metadata,
count,
nbt,
sourceStart: anvil.inventoryStart,
sourceEnd: anvil.inventoryEnd,
destStart: destSlot,
destEnd: destSlot + 1
}
await bot.transfer(options)
}
anvil.combine = combine
anvil.rename = rename
return anvil
}
bot.openAnvil = openAnvil
}