PrismarineJS/mineflayer

bot.equip awaits indefinetely

hatkidchan opened this issue · 7 comments

  • The FAQ doesn't contain a resolution to my issue

Versions

  • mineflayer: 3.7.0
  • server: Paper version git-Paper-79 (MC: 1.17) (Implementing API version 1.17-R0.1-SNAPSHOT) (Git: a831634)
  • node: v16.3.0

Detailed description of a problem

Bot hangs while trying to equip item. It appears that issue caused by await response in clickWindow not to fulfill

What did you try yet?

I tried backtracing issue until I found what I described above. Maybe problem is that transaction is not confirmed by server or something. Also I tried opening bot inventory while it tries to move item, and it appears that bot clicks to that slot, but didn't receive confirmation.

Did you try any method from the API?

I don't think I should copy-paste entire equip and functions bellow that and tweak them for a week until they work

Did you try any example? Any error from those?

  • auto-eat isn't working, but that's for another reason I'm fixing now.
  • inventory also isn't working

Your current code

const mineflayer = require("mineflayer")

const bot = mineflayer.createBot({
    host: '127.0.0.1',
    port: 25565,
    username: 'player',
})

bot.on('health', async () => {
    if (bot.food == 20) return;

    var apple;
    for (const it of bot.inventory.items())
        if (it.name === 'apple')
            apple = it;

    await bot.chat(`Found item: ${apple.name}, equipping`)
    await bot.equip(apple, 'hand')
    await bot.chat(`Equipped item, consuming`)
    await bot.consume()
    await bot.chat(`Consumed`)
});

Expected behavior

Bot equips specified item and returns from waiting

Additional context

Also when I stop bot, it drops selected item, so that may also be sign of that server accepts that click
Also, even when server works on 1.17, bot connected via version 1.16.5 because I'm using ViaBackwards

Is that the correct syntax for a for loop?

Yes it is

Also while I'm looking at it, I'm not checking for apple to be not null, because it's minimal reproducible code and I'm assuming that bot always has apple in inventory. So that's not an issue

image
Related to examples/inventory.js test
According to source code of that, it should say equipped ${name} on success, but it does nothing. Not even crashing. Bot stopped manually after couple of seconds of doing nothing but waiting

After debugging protocol messages, I found that client doesn't receive confirmation for transaction for some reason. After writing window_click packet, I've got no transaction packets in response.

2021-07-10T11:54:23.130Z minecraft-protocol writing packet play.window_click
2021-07-10T11:54:23.130Z minecraft-protocol {
  windowId: 0,
  slot: 31,
  mouseButton: 0,
  action: 1,
  mode: 0,
  item: { present: true, itemId: 573, itemCount: 59 }
}

full debug.log

Now I tried using vanilla 1.16.5 without ViaBackwards plugin and it seems to work fine, play.transaction packet is received and bot equips item to hand. So maybe that's not library issue and with plugin.

2021-07-10T12:28:19.805Z minecraft-protocol writing packet play.window_click
2021-07-10T12:28:19.806Z minecraft-protocol {
  windowId: 0,
  slot: 31,
  mouseButton: 0,
  action: 1,
  mode: 0,
  item: { present: true, itemId: 573, itemCount: 63 }
}
...
2021-07-10T12:28:19.922Z minecraft-protocol read packet play.transaction
2021-07-10T12:28:19.922Z minecraft-protocol {
  "windowId": 0,
  "action": 1,
  "accepted": true
}

debug.1.16.5.log, lines 25467 and 25482

I found dirty fix for that, just disable confirmation for inventory, like that:

bot.once('spawn', () => {
    bot.inventory.requiresConfirmation = false;
});

Seems to work, but I'm not sure if it's correct way. I think it'd be better to just wait until library updates to 1.17 and not use ViaBackwards for that

u9g commented

That’s the fix, just enabling that, I guess viabackwards doesnt confirm transactions.