Buuz135 / FunctionalStorage

FunctionalStorage
MIT License
30 stars 33 forks source link

[1.20.1] Withdrawing one item sometimes takes two #212

Closed ocram9 closed 1 year ago

ocram9 commented 1 year ago

When I withdraw an item by left clicking a storage drawer I sometimes withdraw two items instead of one. It seems to be randomly switching between withdrawing one or two items. This only seems to happen when you don't already have the item you're withdrawing in your inventory. See video for an example:

https://www.youtube.com/watch?v=uXsOjueonQk&ab_channel=TheMarmarax

Functional Storage Version: 1.20.1-1.2.3

Titanium Version: 1.20.1-3.8.21

ChampionAsh5357 commented 1 year ago

Ok, this bug is a doozy. TL;DR, weird mechanics at play.

It has to do with IForgeItem#shouldCauseBlockBreakReset. Essentially, this method is return true when continuing the attack determining that it is the same target. Because of this, it assumes that the block is being destroyed again, causing two START_DESTROY_BLOCK packets to be sent. This triggers two calls to the Block#attack method, which ends up resulting in this issue.

However, how can this method cause the attack method to be called twice? Well, it has to do with how Minecraft determines whether you are targeting the same block. Essentially it checks the item the player is holding when the player started destroying the block and compares it to the current item the player is holding when destroying the block.

What does a storage container do when extracting an item? It adds the item to the inventory in the first available slot. So, assuming you are punching with the first slot on the hotbar empty, and that is your currently selected item, the container will add the block to that spot, notifying the game that the destroy target has changed because of a new held item, and attack the block again with the new item.

To summarize, the bug occurs when the slot in the hotbar being populated by the drawer was originally empty, and the player is using that slot to hit the block.