Fix interaction spam bug (#1324)

* Fix interaction spam bug

This references the Nukkit 1.0 fix for the client bug of spamming to interact. Holding down still works.

* Remove interaction position set at action type 1

* Remove debug line
This commit is contained in:
Camotoy 2020-09-24 12:54:18 -04:00 committed by GitHub
parent 0cd43818f1
commit 1ec768d95d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 4 deletions

View file

@ -156,8 +156,13 @@ public class GeyserSession implements CommandSender {
@Setter @Setter
private boolean interacting; private boolean interacting;
/**
* Stores the last position of the block the player interacted with. This can either be a block that the client
* placed or an existing block the player interacted with (for example, a chest). <br>
* Initialized as (0, 0, 0) so it is always not-null.
*/
@Setter @Setter
private Vector3i lastInteractionPosition; private Vector3i lastInteractionPosition = Vector3i.ZERO;
private boolean manyDimPackets = false; private boolean manyDimPackets = false;
private ServerRespawnPacket lastDimPacket = null; private ServerRespawnPacket lastDimPacket = null;
@ -193,6 +198,13 @@ public class GeyserSession implements CommandSender {
@Setter @Setter
private long lastHitTime; private long lastHitTime;
/**
* Store the last time the player interacted. Used to fix a right-click spam bug.
* See https://github.com/GeyserMC/Geyser/issues/503 for context.
*/
@Setter
private long lastInteractionTime;
private boolean reducedDebugInfo = false; private boolean reducedDebugInfo = false;
@Setter @Setter

View file

@ -78,6 +78,17 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
case ITEM_USE: case ITEM_USE:
switch (packet.getActionType()) { switch (packet.getActionType()) {
case 0: case 0:
// Check to make sure the client isn't spamming interaction
// Based on Nukkit 1.0, with changes to ensure holding down still works
boolean hasAlreadyClicked = System.currentTimeMillis() - session.getLastInteractionTime() < 110.0 &&
packet.getBlockPosition().distanceSquared(session.getLastInteractionPosition()) < 0.00001;
session.setLastInteractionPosition(packet.getBlockPosition());
if (hasAlreadyClicked) {
break;
} else {
// Only update the interaction time if it's valid - that way holding down still works.
session.setLastInteractionTime(System.currentTimeMillis());
}
// Bedrock sends block interact code for a Java entity so we send entity code back to Java // Bedrock sends block interact code for a Java entity so we send entity code back to Java
if (BlockTranslator.isItemFrame(packet.getBlockRuntimeId()) && if (BlockTranslator.isItemFrame(packet.getBlockRuntimeId()) &&
@ -153,7 +164,6 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
session.setLastBlockPlacePosition(blockPos); session.setLastBlockPlacePosition(blockPos);
session.setLastBlockPlacedId(handItem.getJavaIdentifier()); session.setLastBlockPlacedId(handItem.getJavaIdentifier());
} }
session.setLastInteractionPosition(packet.getBlockPosition());
session.setInteracting(true); session.setInteracting(true);
break; break;
case 1: case 1:
@ -170,8 +180,6 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.sendDownstreamPacket(useItemPacket); session.sendDownstreamPacket(useItemPacket);
// Used for sleeping in beds
session.setLastInteractionPosition(packet.getBlockPosition());
break; break;
case 2: case 2:
int blockState = session.getConnector().getWorldManager().getBlockAt(session, packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ()); int blockState = session.getConnector().getWorldManager().getBlockAt(session, packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ());