Waterfall/BungeeCord-Patches/0031-Fix-potion-race-condition-on-Forge-1.8.9.patch

286 lines
11 KiB
Diff
Raw Normal View History

From abf53bfc51be02b7d0dc498174a7f78a58be28a2 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 15a61b7e..ee2317e8 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
@@ -8,6 +8,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.GameState;
import net.md_5.bungee.protocol.packet.Handshake;
@@ -193,4 +195,14 @@ public abstract class AbstractPacketHandler
public void handle(GameState gameState) throws Exception
{
}
2018-12-21 16:24:26 +01:00
+
+ // 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 220365dd..7f0b71c9 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
@@ -18,6 +18,8 @@ import net.md_5.bungee.protocol.packet.EncryptionRequest;
import net.md_5.bungee.protocol.packet.EncryptionResponse;
2018-12-21 16:24:26 +01:00
import net.md_5.bungee.protocol.packet.EntityStatus;
import net.md_5.bungee.protocol.packet.GameState;
+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;
@@ -120,6 +122,20 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_16, 0x0C ),
map( ProtocolConstants.MINECRAFT_1_17, 0x0D )
);
+ // Waterfall start
+ TO_CLIENT.registerPacket(
+ EntityEffect.class,
+ EntityEffect::new,
+ map(ProtocolConstants.MINECRAFT_1_8, 0x1D),
+ map(ProtocolConstants.MINECRAFT_1_9, Integer.MIN_VALUE)
+ );
+ TO_CLIENT.registerPacket(
+ EntityRemoveEffect.class,
+ EntityRemoveEffect::new,
+ map(ProtocolConstants.MINECRAFT_1_8, 0x1E),
+ map(ProtocolConstants.MINECRAFT_1_9, Integer.MIN_VALUE)
+ );
+ // Waterfall end
TO_CLIENT.registerPacket(
PlayerListItem.class, // PlayerInfo
PlayerListItem::new,
@@ -571,10 +587,11 @@ public enum Protocol
mappingIndex++;
}
}
-
+ if (mapping.packetID != Integer.MIN_VALUE) { // Waterfall
ProtocolData data = protocols.get( protocol );
data.packetMap.put( packetClass, mapping.packetID );
data.packetConstructors[mapping.packetID] = constructor;
+ } // Waterfall
}
}
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 a8f4378e..95dc97b9 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
2018-11-04 21:27:05 +01:00
@@ -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;
@@ -125,6 +127,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 314b08bc..b205cc0f 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
2020-08-12 15:44:07 +02:00
@@ -52,6 +52,8 @@ import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.BossBar;
2018-12-21 16:24:26 +01:00
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;
@@ -659,6 +661,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
2016-10-30 15:46:05 +01:00
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
2018-05-28 23:00:27 +02:00
@@ -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.30.1 (Apple Git-130)