Created
September 15, 2016 20:27
-
-
Save Aaron1011/6a98b2a633d225d178427634503ffedd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From 12516b0a27dfa89bf7aeec22c16dab2f77d1800f Mon Sep 17 00:00:00 2001 | |
| From: Aaron Hill <[email protected]> | |
| Date: Wed, 3 Aug 2016 18:19:25 -0400 | |
| Subject: [PATCH] Fix potion race condition on forge | |
| Signed-off-by: Aaron Hill <[email protected]> | |
| 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 6f782c8..2d5fc48 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 | |
| @@ -1,6 +1,8 @@ | |
| package net.md_5.bungee.protocol; | |
| import net.md_5.bungee.protocol.packet.BossBar; | |
| +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.ClientSettings; | |
| import net.md_5.bungee.protocol.packet.ClientStatus; | |
| @@ -148,4 +150,13 @@ public abstract class AbstractPacketHandler | |
| public void handle(BossBar bossBar) 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 4decbb2..430ed22 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.Chat; | |
| import net.md_5.bungee.protocol.packet.ClientSettings; | |
| import net.md_5.bungee.protocol.packet.EncryptionRequest; | |
| import net.md_5.bungee.protocol.packet.EncryptionResponse; | |
| +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; | |
| @@ -81,6 +83,18 @@ public enum Protocol | |
| BossBar.class, | |
| map( ProtocolConstants.MINECRAFT_1_9, 0x0C ) | |
| ); | |
| + // Waterfall start | |
| + TO_CLIENT.registerPacket( | |
| + EntityEffect.class, | |
| + map(ProtocolConstants.MINECRAFT_1_8, 0x1D), | |
| + map(ProtocolConstants.MINECRAFT_1_9, 0x4B) | |
| + ); | |
| + TO_CLIENT.registerPacket( | |
| + EntityRemoveEffect.class, | |
| + map(ProtocolConstants.MINECRAFT_1_8, 0x1E), | |
| + map(ProtocolConstants.MINECRAFT_1_9, 0x31) | |
| + ); | |
| + // Waterfall start | |
| 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 0000000..d11a9ea | |
| --- /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 0000000..7ed2dc3 | |
| --- /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 fead216..9b45b6a 100644 | |
| --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java | |
| +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java | |
| @@ -2,7 +2,9 @@ package net.md_5.bungee; | |
| import com.google.common.base.Objects; | |
| 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; | |
| @@ -10,20 +12,6 @@ import io.netty.channel.ChannelFutureListener; | |
| import io.netty.channel.ChannelInitializer; | |
| import io.netty.channel.ChannelOption; | |
| import io.netty.util.internal.PlatformDependent; | |
| -import java.net.InetSocketAddress; | |
| -import java.util.ArrayList; | |
| -import java.util.Arrays; | |
| -import java.util.Collection; | |
| -import java.util.Collections; | |
| -import java.util.HashSet; | |
| -import java.util.LinkedList; | |
| -import java.util.List; | |
| -import java.util.Locale; | |
| -import java.util.Map; | |
| -import java.util.Queue; | |
| -import java.util.UUID; | |
| -import java.util.concurrent.TimeUnit; | |
| -import java.util.logging.Level; | |
| import lombok.Getter; | |
| import lombok.NonNull; | |
| import lombok.RequiredArgsConstructor; | |
| @@ -41,8 +29,6 @@ import net.md_5.bungee.api.event.ServerConnectEvent; | |
| import net.md_5.bungee.api.score.Scoreboard; | |
| import net.md_5.bungee.chat.ComponentSerializer; | |
| import net.md_5.bungee.connection.InitialHandler; | |
| -import net.md_5.bungee.connection.LoginResult; | |
| -import net.md_5.bungee.connection.LoginResult.Property; | |
| import net.md_5.bungee.entitymap.EntityMap; | |
| import net.md_5.bungee.forge.ForgeClientHandler; | |
| import net.md_5.bungee.forge.ForgeConstants; | |
| @@ -62,12 +48,21 @@ import net.md_5.bungee.protocol.packet.Kick; | |
| import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; | |
| import net.md_5.bungee.protocol.packet.PluginMessage; | |
| import net.md_5.bungee.protocol.packet.SetCompression; | |
| -import net.md_5.bungee.tab.Global; | |
| -import net.md_5.bungee.tab.GlobalPing; | |
| import net.md_5.bungee.tab.ServerUnique; | |
| import net.md_5.bungee.tab.TabList; | |
| import net.md_5.bungee.util.CaseInsensitiveSet; | |
| +import java.net.InetSocketAddress; | |
| +import java.util.Collection; | |
| +import java.util.Collections; | |
| +import java.util.HashSet; | |
| +import java.util.LinkedList; | |
| +import java.util.Locale; | |
| +import java.util.Map; | |
| +import java.util.Queue; | |
| +import java.util.UUID; | |
| +import java.util.logging.Level; | |
| + | |
| @RequiredArgsConstructor | |
| public final class UserConnection implements ProxiedPlayer | |
| { | |
| @@ -131,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; | |
| @@ -187,7 +186,7 @@ public final class UserConnection implements ProxiedPlayer | |
| // No-config FML handshake marker. | |
| // Set whether the connection has a 1.8 FML marker in the handshake. | |
| - if (this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN )) | |
| + if (this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN )) | |
| { | |
| forgeClientHandler.setFmlTokenInHandshake( true ); | |
| } | |
| 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 6463f75..58cbc84 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 | |
| @@ -30,6 +30,8 @@ import net.md_5.bungee.netty.PacketHandler; | |
| import net.md_5.bungee.protocol.DefinedPacket; | |
| import net.md_5.bungee.protocol.PacketWrapper; | |
| import net.md_5.bungee.protocol.packet.BossBar; | |
| +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.PlayerListItem; | |
| import net.md_5.bungee.protocol.packet.ScoreboardObjective; | |
| @@ -515,6 +517,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 String toString() | |
| { | |
| 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 314fd43..17e250d 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 | |
| @@ -7,8 +7,9 @@ import lombok.Getter; | |
| import lombok.NonNull; | |
| import lombok.RequiredArgsConstructor; | |
| import lombok.Setter; | |
| -import net.md_5.bungee.BungeeCord; | |
| 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; | |
| /** | |
| @@ -91,9 +92,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.9.3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment