Fix double sending ServerboundPlayerActionPacket in creative (both of which Spigot interprets as a BlockBreakEvent) (Fixes #4021) (#3996)

This commit is contained in:
Roman Alexander 2023-07-30 16:48:29 -04:00 committed by GitHub
parent d147ee37dc
commit 7725651726
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -144,19 +144,22 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
ServerboundPlayerCommandPacket stopSleepingPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.LEAVE_BED); ServerboundPlayerCommandPacket stopSleepingPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.LEAVE_BED);
session.sendDownstreamPacket(stopSleepingPacket); session.sendDownstreamPacket(stopSleepingPacket);
break; break;
case START_BREAK: case START_BREAK: {
// Start the block breaking animation // Start the block breaking animation
if (session.getGameMode() != GameMode.CREATIVE) { // Ignore START_BREAK when the player is CREATIVE to avoid Spigot receiving 2 packets it interpets as block breaking. https://github.com/GeyserMC/Geyser/issues/4021
int blockState = session.getGeyser().getWorldManager().getBlockAt(session, vector); if (session.getGameMode() == GameMode.CREATIVE) {
LevelEventPacket startBreak = new LevelEventPacket(); break;
startBreak.setType(LevelEvent.BLOCK_START_BREAK);
startBreak.setPosition(vector.toFloat());
double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(blockState)) * 20;
startBreak.setData((int) (65535 / breakTime));
session.setBreakingBlock(blockState);
session.sendUpstreamPacket(startBreak);
} }
int blockState = session.getGeyser().getWorldManager().getBlockAt(session, vector);
LevelEventPacket startBreak = new LevelEventPacket();
startBreak.setType(LevelEvent.BLOCK_START_BREAK);
startBreak.setPosition(vector.toFloat());
double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(blockState)) * 20;
startBreak.setData((int) (65535 / breakTime));
session.setBreakingBlock(blockState);
session.sendUpstreamPacket(startBreak);
// Account for fire - the client likes to hit the block behind. // Account for fire - the client likes to hit the block behind.
Vector3i fireBlockPos = BlockUtils.getBlockPosition(vector, packet.getFace()); Vector3i fireBlockPos = BlockUtils.getBlockPosition(vector, packet.getFace());
int blockUp = session.getGeyser().getWorldManager().getBlockAt(session, fireBlockPos); int blockUp = session.getGeyser().getWorldManager().getBlockAt(session, fireBlockPos);
@ -165,15 +168,13 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING, fireBlockPos, ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING, fireBlockPos,
Direction.VALUES[packet.getFace()], session.getWorldCache().nextPredictionSequence()); Direction.VALUES[packet.getFace()], session.getWorldCache().nextPredictionSequence());
session.sendDownstreamPacket(startBreakingPacket); session.sendDownstreamPacket(startBreakingPacket);
if (session.getGameMode() == GameMode.CREATIVE) {
break;
}
} }
ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING, ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING,
vector, Direction.VALUES[packet.getFace()], session.getWorldCache().nextPredictionSequence()); vector, Direction.VALUES[packet.getFace()], session.getWorldCache().nextPredictionSequence());
session.sendDownstreamPacket(startBreakingPacket); session.sendDownstreamPacket(startBreakingPacket);
break; break;
}
case CONTINUE_BREAK: case CONTINUE_BREAK:
if (session.getGameMode() == GameMode.CREATIVE) { if (session.getGameMode() == GameMode.CREATIVE) {
break; break;