Don't send more than one ServerboundSwingPacket per tick

Should address #2875
This commit is contained in:
Camotoy 2023-01-03 15:51:58 -05:00
parent c483204446
commit 00df4c26ba
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
2 changed files with 18 additions and 4 deletions

View file

@ -457,7 +457,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
* Counts how many ticks have occurred since an arm animation started. * Counts how many ticks have occurred since an arm animation started.
* -1 means there is no active arm swing. * -1 means there is no active arm swing.
*/ */
@Getter(AccessLevel.NONE)
private int armAnimationTicks = -1; private int armAnimationTicks = -1;
/** /**

View file

@ -49,11 +49,26 @@ public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
case SWING_ARM -> case SWING_ARM ->
// Delay so entity damage can be processed first // Delay so entity damage can be processed first
session.scheduleInEventLoop(() -> { session.scheduleInEventLoop(() -> {
if (session.getArmAnimationTicks() != 0) {
// So, generally, a Java player can only do one *thing* at a time.
// If a player right-clicks, for example, then there's probably only one action associated with
// that right-click that will send a swing.
// The only exception I can think of to this, *maybe*, is a player dropping items
// Bedrock is a little funkier than this - it can send several arm animation packets in the
// same tick, notably with high levels of haste applied.
// Packet limiters do not like this and can crash the player.
// If arm animation ticks is 0, then we just sent an arm swing packet this tick.
// See https://github.com/GeyserMC/Geyser/issues/2875
// This behavior was last touched on with ViaVersion 4.5.1 (with its packet limiter), Java 1.16.5,
// and Bedrock 1.19.51.
// Note for the future: we should probably largely ignore this packet and instead replicate
// all actions on our end, and send swings where needed.
session.sendDownstreamPacket(new ServerboundSwingPacket(Hand.MAIN_HAND)); session.sendDownstreamPacket(new ServerboundSwingPacket(Hand.MAIN_HAND));
session.activateArmAnimationTicking(); session.activateArmAnimationTicking();
}, }
25, },
TimeUnit.MILLISECONDS 25,
TimeUnit.MILLISECONDS
); );
// These two might need to be flipped, but my recommendation is getting moving working first // These two might need to be flipped, but my recommendation is getting moving working first
case ROW_LEFT -> { case ROW_LEFT -> {