Waterfall/BungeeCord-Patches/0033-Fix-potion-race-condition-on-Forge-1.8.9.patch
Shane Freeder cca83dfaf6
Updated Upstream (BungeeCord)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

BungeeCord Changes:
a3ab2bf5 Update checkstyle
adee7bd2 Source jar does not need to fork build
7bd8a027 Always print remote IP in InitialHandler
0cf27a09 Update scriptus
bf673c5d Add pretty colours to console log levels
2235a323 Optimize ColouredWriter slightly
1dee0490 Don't send/construct redundant kick messages
e9ba95b9 Don't log full CorruptedFrameException
d3bd7852 #2762: Work correctly with disabled timeout
3ce4132c Switch keepalive queue to ArrayDeque
ce2dcaf7 #2763: Fix .DS_Store entry in .gitignore
cf72c3a7 Show slow event times in milliseconds
cd7a3ab2 #2758: Improve server list ping response where remote ping failed
0a4b9b49 #2752: Configurable connect and ping timeouts
2020-02-01 15:39:53 +00:00

282 lines
11 KiB
Diff

From cb58c49decf1797f281bf3beb8c773574af6f396 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Thu, 15 Sep 2016 22:38:37 +0200
Subject: [PATCH] Fix potion race condition on Forge 1.8.9
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java b/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java
index 39e257c3..e4f14974 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java
@@ -7,6 +7,8 @@ import net.md_5.bungee.protocol.packet.ClientStatus;
import net.md_5.bungee.protocol.packet.Commands;
import net.md_5.bungee.protocol.packet.EncryptionRequest;
import net.md_5.bungee.protocol.packet.EncryptionResponse;
+import net.md_5.bungee.protocol.packet.EntityEffect; // Waterfall
+import net.md_5.bungee.protocol.packet.EntityRemoveEffect; // Waterfall
import net.md_5.bungee.protocol.packet.EntityStatus;
import net.md_5.bungee.protocol.packet.Handshake;
import net.md_5.bungee.protocol.packet.KeepAlive;
@@ -173,4 +175,14 @@ public abstract class AbstractPacketHandler
public void handle(ViewDistance viewDistance) throws Exception
{
}
+
+ // Waterfall start
+ public void handle(EntityEffect entityEffect) throws Exception
+ {
+ }
+
+ public void handle(EntityRemoveEffect removeEffect) throws Exception
+ {
+ }
+ // Waterfall end
}
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
index 31cbaa53..3556eda0 100644
--- a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
@@ -16,6 +16,8 @@ import net.md_5.bungee.protocol.packet.Commands;
import net.md_5.bungee.protocol.packet.EncryptionRequest;
import net.md_5.bungee.protocol.packet.EncryptionResponse;
import net.md_5.bungee.protocol.packet.EntityStatus;
+import net.md_5.bungee.protocol.packet.EntityEffect;
+import net.md_5.bungee.protocol.packet.EntityRemoveEffect;
import net.md_5.bungee.protocol.packet.Handshake;
import net.md_5.bungee.protocol.packet.KeepAlive;
import net.md_5.bungee.protocol.packet.Kick;
@@ -97,6 +99,29 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_9, 0x0C ),
map( ProtocolConstants.MINECRAFT_1_15, 0x0D )
);
+ // Waterfall start
+ TO_CLIENT.registerPacket(
+ EntityEffect.class,
+ map(ProtocolConstants.MINECRAFT_1_8, 0x1D),
+ map(ProtocolConstants.MINECRAFT_1_9, 0x4C),
+ map(ProtocolConstants.MINECRAFT_1_9_4, 0x4B),
+ map(ProtocolConstants.MINECRAFT_1_12, 0x4E),
+ map(ProtocolConstants.MINECRAFT_1_12_1, 0x4F),
+ map(ProtocolConstants.MINECRAFT_1_13, 0x53),
+ map(ProtocolConstants.MINECRAFT_1_14, 0x59),
+ map(ProtocolConstants.MINECRAFT_1_15, 0x5A)
+ );
+ TO_CLIENT.registerPacket(
+ EntityRemoveEffect.class,
+ map(ProtocolConstants.MINECRAFT_1_8, 0x1E),
+ map(ProtocolConstants.MINECRAFT_1_9, 0x31),
+ map(ProtocolConstants.MINECRAFT_1_12, 0x32),
+ map(ProtocolConstants.MINECRAFT_1_12_1, 0x33),
+ map(ProtocolConstants.MINECRAFT_1_13, 0x36),
+ map(ProtocolConstants.MINECRAFT_1_14, 0x38),
+ map(ProtocolConstants.MINECRAFT_1_15, 0x39)
+ );
+ // Waterfall end
TO_CLIENT.registerPacket(
PlayerListItem.class, // PlayerInfo
map( ProtocolConstants.MINECRAFT_1_8, 0x38 ),
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java
new file mode 100644
index 00000000..d11a9ea9
--- /dev/null
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java
@@ -0,0 +1,45 @@
+package net.md_5.bungee.protocol.packet;
+
+import io.netty.buffer.ByteBuf;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import net.md_5.bungee.protocol.AbstractPacketHandler;
+import net.md_5.bungee.protocol.DefinedPacket;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class EntityEffect extends DefinedPacket {
+
+ private int entityId;
+ private int effectId;
+ private int amplifier;
+ private int duration;
+ private boolean hideParticles;
+
+ @Override
+ public void read(ByteBuf buf) {
+ this.entityId = readVarInt(buf);
+ this.effectId = buf.readUnsignedByte();
+ this.amplifier = buf.readUnsignedByte();
+ this.duration = readVarInt(buf);
+ this.hideParticles = buf.readBoolean();
+ }
+
+ @Override
+ public void write(ByteBuf buf) {
+ writeVarInt(this.entityId, buf);
+ buf.writeByte(this.effectId);
+ buf.writeByte(this.amplifier);
+ writeVarInt(this.duration, buf);
+ buf.writeBoolean(this.hideParticles);
+ }
+
+ @Override
+ public void handle(AbstractPacketHandler handler) throws Exception {
+ handler.handle(this);
+ }
+}
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java
new file mode 100644
index 00000000..7ed2dc3a
--- /dev/null
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java
@@ -0,0 +1,36 @@
+package net.md_5.bungee.protocol.packet;
+
+import io.netty.buffer.ByteBuf;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import net.md_5.bungee.protocol.AbstractPacketHandler;
+import net.md_5.bungee.protocol.DefinedPacket;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class EntityRemoveEffect extends DefinedPacket {
+
+ private int entityId;
+ private int effectId;
+
+ @Override
+ public void read(ByteBuf buf) {
+ this.entityId = readVarInt(buf);
+ this.effectId = buf.readUnsignedByte();
+ }
+
+ @Override
+ public void write(ByteBuf buf) {
+ writeVarInt(this.entityId, buf);
+ buf.writeByte(effectId);
+ }
+
+ @Override
+ public void handle(AbstractPacketHandler handler) throws Exception {
+ handler.handle(this);
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
index 3f9a91e3..a5da62f3 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
@@ -1,7 +1,9 @@
package net.md_5.bungee;
import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Multimap;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
@@ -124,6 +126,10 @@ public final class UserConnection implements ProxiedPlayer
private final Scoreboard serverSentScoreboard = new Scoreboard();
@Getter
private final Collection<UUID> sentBossBars = new HashSet<>();
+ // Waterfall start
+ @Getter
+ private final Multimap<Integer, Integer> potions = HashMultimap.create();
+ // Waterfall end
/*========================================================================*/
@Getter
private String displayName;
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
index d1654bcc..cfd25859 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
@@ -50,6 +50,8 @@ import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.BossBar;
import net.md_5.bungee.protocol.packet.Commands;
+import net.md_5.bungee.protocol.packet.EntityEffect;
+import net.md_5.bungee.protocol.packet.EntityRemoveEffect;
import net.md_5.bungee.protocol.packet.KeepAlive;
import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.PlayerListItem;
@@ -595,6 +597,32 @@ public class DownstreamBridge extends PacketHandler
}
}
+ // Waterfall start
+ @Override
+ public void handle(EntityEffect entityEffect) throws Exception
+ {
+ // Don't send any potions when switching between servers (which involves a handshake), which can trigger a race
+ // condition on the client.
+ if (this.con.getForgeClientHandler().isForgeUser() && !this.con.getForgeClientHandler().isHandshakeComplete()) {
+ throw CancelSendSignal.INSTANCE;
+ }
+ con.getPotions().put(rewriteEntityId(entityEffect.getEntityId()), entityEffect.getEffectId());
+ }
+
+ @Override
+ public void handle(EntityRemoveEffect removeEffect) throws Exception
+ {
+ con.getPotions().remove(rewriteEntityId(removeEffect.getEntityId()), removeEffect.getEffectId());
+ }
+
+ private int rewriteEntityId(int entityId) {
+ if (entityId == con.getServerEntityId()) {
+ return con.getClientEntityId();
+ }
+ return entityId;
+ }
+ // Waterfall end
+
@Override
public void handle(Respawn respawn)
{
diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java
index d15044f4..bea2bbff 100644
--- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java
@@ -9,6 +9,8 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.md_5.bungee.UserConnection;
+import net.md_5.bungee.protocol.ProtocolConstants;
+import net.md_5.bungee.protocol.packet.EntityRemoveEffect;
import net.md_5.bungee.protocol.packet.PluginMessage;
/**
@@ -94,9 +96,23 @@ public class ForgeClientHandler
public void resetHandshake()
{
state = ForgeClientHandshakeState.HELLO;
+
+ // This issue only exists in Forge 1.8.9
+ if (this.con.getPendingConnection().getVersion() == ProtocolConstants.MINECRAFT_1_8) {
+ this.resetAllThePotions(con);
+ }
+
con.unsafe().sendPacket( ForgeConstants.FML_RESET_HANDSHAKE );
}
+ private void resetAllThePotions(UserConnection con) {
+ // Just to be sure
+ for (Map.Entry<Integer, Integer> entry: con.getPotions().entries()) {
+ con.unsafe().sendPacket(new EntityRemoveEffect(entry.getKey(), entry.getValue()));
+ }
+ con.getPotions().clear();
+ }
+
/**
* Sends the server mod list to the client, or stores it for sending later.
*
--
2.25.0