Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update digging.js for state changes #3136

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Vakore
Copy link

@Vakore Vakore commented Jul 31, 2023

Made digging.js compatible with state changes, i.e. when the bot switches from being on ground to not on ground and in water, the digging progress is saved and accurately updated.

Made digging.js compatible with state changes, i.e. when the bot switches from being on ground to not on ground and in water, the digging progress is saved and accurately updated.
@Vakore
Copy link
Author

Vakore commented Aug 1, 2023

I have no idea if this would break other people's projects due to variable name changes/complete functionality differences, but the reason for suggesting this fix would be because currently if the bot starts digging a block in one state, i.e. in the water, and then exits the water, or vice versa, the time needed till completion is not adjusted accordingly.

@rom1504
Copy link
Member

rom1504 commented Aug 5, 2023

/fixlint

@rom1504
Copy link
Member

rom1504 commented Aug 5, 2023

please remove commented code

@rom1504bot
Copy link
Contributor

I ran npm run fix, but there are errors still left that must be manually resolved:

> [email protected] fix
> standard --fix && standard-markdown --fix

  /home/runner/work/mineflayer/mineflayer/lib/plugins/digging.js:24:30: Expected '!==' and instead saw '!='. (eqeqeq)
  /home/runner/work/mineflayer/mineflayer/lib/plugins/digging.js:114:11: 'waitTime' is assigned a value but never used. (no-unused-vars)
standard: Use JavaScript Standard Style (https://standardjs.com)

@Vakore
Copy link
Author

Vakore commented Aug 5, 2023

I believe I have made the appropriate changes, though I missed a piece of commented debugging code on line 75.
Vakore@4471376

// bot.referenceTime = window.performance.now();
waitInterval = setInterval(() => { //! !!!
bot.digPercentage += (50 / bot.digTime(block))
// bot.digPercentage += (Math.abs(bot.referenceTime - window.performance.now()) / bot.digTime(block));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code

@rom1504
Copy link
Member

rom1504 commented Aug 13, 2023

Clean it up please

0.5 + (i === 'y' ? visibleFaces[i] * 0.5 : 0),
0.5 + (i === 'z' ? visibleFaces[i] * 0.5 : 0)
)
const targetPos = block.position.offset(0.5 + (i === 'x' ? visibleFaces[i] * 0.5 : 0), 0.5 + (i === 'y' ? visibleFaces[i] * 0.5 : 0), 0.5 + (i === 'z' ? visibleFaces[i] * 0.5 : 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

const dx = bot.entity.position.x - (block.position.x + 0.5)
const dy = bot.entity.position.y + bot.entity.height - (block.position.y + 0.5)
const dz = bot.entity.position.z - (block.position.z + 0.5)
const dx = bot.entity.position.x - block.position.x + 0.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

const dx = bot.entity.position.x - block.position.x + 0.5
const dy = bot.entity.position.y - block.position.y - 0.5 + bot.entity.height // -0.5 because the bot position
// is calculated from the block position that is inside its feet so 0.5 - 1 = -0.5
const dz = bot.entity.position.z - block.position.z + 0.5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is incorrect

const cDist = new Vec3(tPos.x, tPos.y, tPos.z).distanceSquared(
bot.entity.position.offset(0, bot.entity.height, 0)
)
const cDist = new Vec3(tPos.x, tPos.y, tPos.z).distanceSquared(bot.entity.position.offset(0, bot.entity.height, 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

rayPos.y === block.position.y &&
rayPos.z === block.position.z
) {
if (rayPos.x === block.position.x && rayPos.y === block.position.y && rayPos.z === block.position.z) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

enchantments,
bot.entity.effects
)
return block.digTime(type, creative, bot.entity.isInWater, !bot.entity.onGround, enchantments, bot.entity.effects)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

block.diggable &&
block.position.offset(0.5, 0.5, 0.5).distanceTo(bot.entity.position.offset(0, 1.65, 0)) <= 5.1
)
return block && block.diggable && block.position.offset(0.5, 0.5, 0.5).distanceTo(bot.entity.position.offset(0, 1.65, 0)) <= 5.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

block.position.offset(0.5, 0.5, 0.5).offset(digFace.x * 0.5, digFace.y * 0.5, digFace.z * 0.5),
forceLook
)
await bot.lookAt(block.position.offset(0.5, 0.5, 0.5).offset(digFace.x * 0.5, digFace.y * 0.5, digFace.z * 0.5), forceLook)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a formatting change, undo

@@ -162,13 +184,14 @@ function inject (bot) {
function onBlockUpdate (oldBlock, newBlock) {
// vanilla server never actually interrupt digging, but some server send block update when you start digging
// so ignore block update if not air
// All block update listeners receive (null, null) when the world is unloaded. So newBlock can be null.
if (newBlock?.type !== 0) return
if (!newBlock) return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't change anything, see the ? below
you can remove this change

} else {
clearInterval(swingInterval)
}
}, 250)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the change from 350 to 250 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Vakore can you change this back or give w reason to why you changed the interval?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the interval to fix the arm swing bug

waitTimeout = setTimeout(finishDigging, waitTime)
if (waitInterval) { clearInterval(waitInterval) }
waitInterval = setInterval(() => {
bot.digPercentage += (50 / bot.digTime(block))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the vanilla client follow this algorithm when state change while digging ? do you have a reference ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not this exact algorithm but it mimics what I've seen in game, and I've yet to see something abnormal from it.

@Vakore
Copy link
Author

Vakore commented Aug 13, 2023

image What I am attempting to change can be mostly summarized by these two changes.

The first change(upper) is meant to fix an issue with the digging function. In Minecraft, if a player starts digging a block while on the ground, then there is a definitive time it will take to break the block if the player continues digging and stays on the ground. Likewise, with if the player mines a block while in the air, or underwater. This is what the original code assumes.

The problem with this is the time to finish breaking something will vary if the player switches between these states(on the ground, in the air, underwater), so if it were to take 1 second to mine a block while grounded the entire time, but 2 seconds when in the air, and the player spends the first half of the digging progress on the ground and the second half in the air, it'll break in 1.5 seconds. Mineflayer currently does not account for this. If the bot begins mining while in the air, then lands on the ground, it will not finish breaking the block until the first computed time, that is the 'in the air' time, has elapsed.

The changes relating to 'digPercentage' allow for the progress to be properly stored and calculated as the mineflayer bot breaks blocks while constantly switching these states, and more accurate to a vanilla client's behavior to my knowledge.

The second change is relating to a common 'arm swinging' bug when breaking blocks. Sometimes, the arm keeps swinging and will never stop. The changes I made add a safety check to the interval to make sure not to swing the arm if the bot isn't breaking a block, and if it isn't, clear the swing interval. The change from '350' to '250' is simply to make the arm swing speed faster and closer to vanilla, though I don't think I made it fast enough to match the vanilla client's arm swinging speed.

@@ -162,13 +184,13 @@ function inject (bot) {
function onBlockUpdate (oldBlock, newBlock) {
// vanilla server never actually interrupt digging, but some server send block update when you start digging
// so ignore block update if not air
// All block update listeners receive (null, null) when the world is unloaded. So newBlock can be null.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove this comment?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably on accident.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the comment back?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a more updated version of digging.js on the discord. Search for attachments from 'Vakore', unable to do stuff with npm rn.

bot.on('heldItemChanged', () => {
let nameToCompare = ''
if (bot.heldItem) { nameToCompare = bot.heldItem.name }
if (bot.lastHeldItemName !== nameToCompare) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think any held item change cancels the dig process? Even increasing the item amount in a slot.

Copy link
Author

@Vakore Vakore Aug 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprisingly no. If you have two pickaxes with equal durability and/or nbt, and switch between them, or switch between different fist slots while mining, it won't cancel the mining timer. Mining a tree with fists and picking up a log while mining will reset it, though constantly mining with logs while the stack size increases doesn't last time I checked. I'll double check later today but I'm pretty sure this is correct.

Though now that I'm looking at this the system here won't take into account durability/enchant differences, though that's just nbt and can likely be changed easily. This system will still work in most cases though and is better than nothing, but it should be fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better way to check if items are equal is the stringify the item and compare that. You could make a string of the item you started mining with and reset the progress if the string of the held item changes.

@IceTank
Copy link
Contributor

IceTank commented Aug 14, 2023

Btw you don't have to use an external site for linting. Mineflayer comes with its own linter. Just do npm run fix.

@rom1504
Copy link
Member

rom1504 commented Mar 17, 2024

@IceTank do you want to check this one and tell me if it looks good?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Almost too old
Development

Successfully merging this pull request may close these issues.

4 participants