forked from GeyserMC/Geyser
Fix bucket interactions on creative mode (#1369)
* Fix bucket interactions on creative mode Bedrock uses the BLOCK_INTERACT enum of BedrockActionTranslator to truly indicate if a bucket should be used or not. In order to hook into this, we need to delay the bucket placing by about 5 milliseconds - this gives us time to cancel the interaction if needed. Bucket sounds will now not play in this case as well.
This commit is contained in:
parent
ffcff96bea
commit
96db37c14c
4 changed files with 27 additions and 10 deletions
|
@ -84,6 +84,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Getter
|
||||
|
@ -210,6 +211,13 @@ public class GeyserSession implements CommandSender {
|
|||
@Setter
|
||||
private long lastInteractionTime;
|
||||
|
||||
/**
|
||||
* Stores a future interaction to place a bucket. Will be cancelled if the client instead intended to
|
||||
* interact with a block.
|
||||
*/
|
||||
@Setter
|
||||
private ScheduledFuture<?> bucketScheduledFuture;
|
||||
|
||||
private boolean reducedDebugInfo = false;
|
||||
|
||||
@Setter
|
||||
|
|
|
@ -61,6 +61,8 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
|||
import org.geysermc.connector.utils.BlockUtils;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Translator(packet = InventoryTransactionPacket.class)
|
||||
public class BedrockInventoryTransactionTranslator extends PacketTranslator<InventoryTransactionPacket> {
|
||||
|
||||
|
@ -120,18 +122,19 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
session.sendDownstreamPacket(itemPacket);
|
||||
}
|
||||
// Check actions, otherwise buckets may be activated when block inventories are accessed
|
||||
// But don't check actions if the item damage is 0
|
||||
else if (packet.getItemInHand() != null && packet.getItemInHand().getId() == ItemRegistry.BUCKET.getBedrockId() &&
|
||||
(packet.getItemInHand().getDamage() == 0 || !packet.getActions().isEmpty())) {
|
||||
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
|
||||
session.sendDownstreamPacket(itemPacket);
|
||||
|
||||
else if (packet.getItemInHand() != null && packet.getItemInHand().getId() == ItemRegistry.BUCKET.getBedrockId()) {
|
||||
// Let the server decide if the bucket item should change, not the client, and revert the changes the client made
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(ContainerId.INVENTORY);
|
||||
slotPacket.setSlot(packet.getHotbarSlot());
|
||||
slotPacket.setItem(packet.getItemInHand());
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
// Delay the interaction in case the client doesn't intend to actually use the bucket
|
||||
// See BedrockActionTranslator.java
|
||||
session.setBucketScheduledFuture(session.getConnector().getGeneralThreadPool().schedule(() -> {
|
||||
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
|
||||
session.sendDownstreamPacket(itemPacket);
|
||||
}, 5, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
if (packet.getActions().isEmpty()) {
|
||||
|
@ -167,10 +170,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
break;
|
||||
}
|
||||
|
||||
// Handled in ITEM_USE
|
||||
// Handled in ITEM_USE if the item is not milk
|
||||
if (packet.getItemInHand() != null && packet.getItemInHand().getId() == ItemRegistry.BUCKET.getBedrockId() &&
|
||||
// Normal bucket, water bucket, lava bucket
|
||||
(packet.getItemInHand().getDamage() == 0 || packet.getItemInHand().getDamage() == 8 || packet.getItemInHand().getDamage() == 10)) {
|
||||
packet.getItemInHand().getDamage() != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,12 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||
session.sendDownstreamPacket(stopSleepingPacket);
|
||||
break;
|
||||
case BLOCK_INTERACT:
|
||||
// Handled in BedrockInventoryTransactionTranslator
|
||||
// Client means to interact with a block; cancel bucket interaction, if any
|
||||
if (session.getBucketScheduledFuture() != null) {
|
||||
session.getBucketScheduledFuture().cancel(true);
|
||||
session.setBucketScheduledFuture(null);
|
||||
}
|
||||
// Otherwise handled in BedrockInventoryTransactionTranslator
|
||||
break;
|
||||
case START_BREAK:
|
||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
||||
|
|
|
@ -38,6 +38,7 @@ public class BucketSoundInteractionHandler implements BlockSoundInteractionHandl
|
|||
|
||||
@Override
|
||||
public void handleInteraction(GeyserSession session, Vector3f position, String identifier) {
|
||||
if (session.getBucketScheduledFuture() == null) return; // No bucket was really interacted with
|
||||
String handItemIdentifier = ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
|
||||
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
|
||||
soundEventPacket.setPosition(position);
|
||||
|
@ -68,5 +69,6 @@ public class BucketSoundInteractionHandler implements BlockSoundInteractionHandl
|
|||
soundEventPacket.setSound(soundEvent);
|
||||
session.sendUpstreamPacket(soundEventPacket);
|
||||
}
|
||||
session.setBucketScheduledFuture(null);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue