PrismarineJS / prismarine-physics

Provide the physics engine for minecraft entities
MIT License
35 stars 39 forks source link

fix deleteAttributeModifier function #69

Closed bendgk closed 2 years ago

bendgk commented 2 years ago

attributes.modifiers is a list of modifiers. The delete keyword is not being used correctly in this case and should be opted out for a better approach such as filter.

The deletion of attributes like this was causing a nasty bug in mineflayer control state:

1) set control state to move forward and sprint 2) call bot.attack 3) set control state for sprint to false 4) observe that the bot is still sprinting

Im sure other attribute bugs were also affected by this incorrect usage of delete modifier.

kashalls commented 2 years ago

Congratulations on PR #69 👏

Have you tested this with the latest version of mineflayer?

bendgk commented 2 years ago

Can confirm bug exists in latest version of mineflayer/prismarine-physics

const mineflayer = require('mineflayer')

if (process.argv.length < 3 || process.argv.length > 5) {
    console.log('Usage : node echo.js <host> <port> [<name>]')
    process.exit(1)
}

const bot = mineflayer.createBot({
    host: process.argv[2],
    port: parseInt(process.argv[3]),
    username: process.argv[4] ? process.argv[4] : 'echo',
})

setTimeout(() => {
    //initialize forward sprinting control state
    bot.setControlState('forward', true)
    bot.setControlState('sprint', true)

    //main bot loop
    setInterval(() => {
        const target = bot.players["bendgk"].entity
        if (!target) return
        bot.lookAt(target.position)

        if (target.position.distanceTo(bot.entity.position) < 3) {
            //sprinting bug occurs here
            bot.attack(target)

            setTimeout(() => {
                console.log("setting sprint control state to false")
                bot.setControlState('sprint', false)
            }, 3000)
        } else {
            bot.swingArm("right")
        }
    }, 500)
}, 5000)

To reproduce: 1) start paper 1.18.2 server 2) join server 3) give regeneration effect to yourself 4) make sure you are in survival mode and pvp is enabled 5) run the above bot script 6) observe that once the bot hits you it will not stop sprinting, and the control state becomes desynced

note: the bot will not show sprinting particles, but its speed attribute modifier will remain in a sprinting state.

IceTank commented 2 years ago

LGTM. I can confirm that the bug currently exists. And this does indeed fix this issue. I don't see any issue with using a filter either.