From 3a73a93ff02dde8334169942cdb6a220ab975c21 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Mon, 14 Jan 2019 03:35:21 +0000 Subject: [PATCH] Provide an option to disable entity metadata rewriting The work here is derived from the research and guidance of various members of the minecraft community This patch provides the ability to disable entity remapping, which creates various incompatability issues with mods, however, may also create various issues with mods which do not support this, hence why the configuration option is provided diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java index e0baca9c..f3bced0a 100644 --- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java +++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java @@ -252,4 +252,9 @@ public interface ProxyConfig * @return should we disable the tab completion limit for 1.13+ clients */ boolean isDisableModernTabLimiter(); + + /** + * @return Should we disable entity metadata rewriting? + */ + boolean isDisableEntityMetadataRewrite(); } diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java index 4ff8da6d..e860214f 100644 --- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java +++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java @@ -42,6 +42,8 @@ public class WaterfallConfiguration extends Configuration { private int tabThrottle = 1000; private boolean disableModernTabLimiter = true; + private boolean disableEntityMetadataRewrite = false; + @Override public void load() { super.load(); @@ -53,6 +55,7 @@ public class WaterfallConfiguration extends Configuration { // Throttling options tabThrottle = config.getInt("throttling.tab_complete", tabThrottle); disableModernTabLimiter = config.getBoolean("disable_modern_tab_limiter", disableModernTabLimiter); + disableEntityMetadataRewrite = config.getBoolean("disable_entity_metadata_rewrite", disableEntityMetadataRewrite); } @Override @@ -79,4 +82,9 @@ public class WaterfallConfiguration extends Configuration { public boolean isDisableModernTabLimiter() { return disableModernTabLimiter; } + + @Override + public boolean isDisableEntityMetadataRewrite() { + return disableEntityMetadataRewrite; + } } diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index f981313e..f8de9716 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -40,23 +40,7 @@ import net.md_5.bungee.protocol.MinecraftDecoder; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; import net.md_5.bungee.protocol.ProtocolConstants; -import net.md_5.bungee.protocol.packet.EncryptionRequest; -import net.md_5.bungee.protocol.packet.EntityStatus; -import net.md_5.bungee.protocol.packet.GameState; -import net.md_5.bungee.protocol.packet.Handshake; -import net.md_5.bungee.protocol.packet.Kick; -import net.md_5.bungee.protocol.packet.Login; -import net.md_5.bungee.protocol.packet.LoginPayloadRequest; -import net.md_5.bungee.protocol.packet.LoginPayloadResponse; -import net.md_5.bungee.protocol.packet.LoginRequest; -import net.md_5.bungee.protocol.packet.LoginSuccess; -import net.md_5.bungee.protocol.packet.PluginMessage; -import net.md_5.bungee.protocol.packet.Respawn; -import net.md_5.bungee.protocol.packet.ScoreboardObjective; -import net.md_5.bungee.protocol.packet.ScoreboardScore; -import net.md_5.bungee.protocol.packet.SetCompression; -import net.md_5.bungee.protocol.packet.StartConfiguration; -import net.md_5.bungee.protocol.packet.ViewDistance; +import net.md_5.bungee.protocol.packet.*; import net.md_5.bungee.util.AddressUtil; import net.md_5.bungee.util.BufUtil; import net.md_5.bungee.util.QuietException; @@ -254,7 +238,8 @@ public class ServerConnector extends PacketHandler ch.write( new PluginMessage( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:register" : "REGISTER", Joiner.on( "\0" ).join( registeredChannels ).getBytes( StandardCharsets.UTF_8 ), false ) ); } - if ( user.getSettings() != null ) + // Something deeper is going wrong here, but, as it stands, this project is EOL, so, we'll just shove this through. + if (user.getSettings() != null && (!user.isDisableEntityMetadataRewrite() || user.getPendingConnection().getVersion() <= ProtocolConstants.MINECRAFT_1_20_2)) { ch.write( user.getSettings() ); } @@ -309,6 +294,7 @@ public class ServerConnector extends PacketHandler user.getTabListHandler().onServerChange(); Scoreboard serverScoreboard = user.getServerSentScoreboard(); + if ( !user.isDisableEntityMetadataRewrite() ) { // Waterfall for ( Objective objective : serverScoreboard.getObjectives() ) { user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), objective.getValue(), ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), (byte) 1 ) ); @@ -321,6 +307,7 @@ public class ServerConnector extends PacketHandler { user.unsafe().sendPacket( new net.md_5.bungee.protocol.packet.Team( team.getName() ) ); } + } // Waterfall serverScoreboard.clear(); for ( UUID bossbar : user.getSentBossBars() ) @@ -339,13 +326,34 @@ public class ServerConnector extends PacketHandler } user.setDimensionChange( true ); - if ( login.getDimension() == user.getDimension() ) + if ( !user.isDisableEntityMetadataRewrite() && login.getDimension() == user.getDimension() ) // Waterfall - defer { user.unsafe().sendPacket( new Respawn( (Integer) login.getDimension() >= 0 ? -1 : 0, login.getWorldName(), login.getSeed(), login.getDifficulty(), login.getGameMode(), login.getPreviousGameMode(), login.getLevelType(), login.isDebug(), login.isFlat(), (byte) 0, login.getDeathLocation(), login.getPortalCooldown() ) ); } user.setServerEntityId( login.getEntityId() ); + + // Waterfall start + if ( user.isDisableEntityMetadataRewrite() ) { + // Ensure that we maintain consistency + user.setClientEntityId( login.getEntityId() ); + // Only send if we are not in the same dimension + if ( login.getDimension() != user.getDimension() ) // Waterfall - defer + { + user.unsafe().sendPacket( new Respawn( (Integer) user.getDimension() >= 0 ? -1 : 0, login.getWorldName(), login.getSeed(), login.getDifficulty(), login.getGameMode(), login.getPreviousGameMode(), login.getLevelType(), login.isDebug(), login.isFlat(), (byte) 0, login.getDeathLocation(), login.getPortalCooldown() ) ); + } + Login modLogin = new Login( login.getEntityId(), login.isHardcore(), login.getGameMode(), login.getPreviousGameMode(), login.getWorldNames(), login.getDimensions(), login.getDimension(), login.getWorldName(), login.getSeed(), login.getDifficulty(), + (byte) user.getPendingConnection().getListener().getTabListSize(), login.getLevelType(), login.getViewDistance(), login.getSimulationDistance(), login.isReducedDebugInfo(), login.isNormalRespawn(), login.isLimitedCrafting(), login.isDebug(), login.isFlat(), login.getDeathLocation(), + login.getPortalCooldown() ); + user.unsafe().sendPacket(modLogin); + // Only send if we're in the same dimension + if ( login.getDimension() == user.getDimension() ) // Waterfall - defer + { + user.unsafe().sendPacket( new Respawn( (Integer) login.getDimension() >= 0 ? -1 : 0, login.getWorldName(), login.getSeed(), login.getDifficulty(), login.getGameMode(), login.getPreviousGameMode(), login.getLevelType(), login.isDebug(), login.isFlat(), (byte) 0, login.getDeathLocation(), login.getPortalCooldown() ) ); + } + } + // Waterfall end user.unsafe().sendPacket( new Respawn( login.getDimension(), login.getWorldName(), login.getSeed(), login.getDifficulty(), login.getGameMode(), login.getPreviousGameMode(), login.getLevelType(), login.isDebug(), login.isFlat(), (byte) 0, login.getDeathLocation(), login.getPortalCooldown() ) ); if ( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_14 ) 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 85adab0f..9e2046a4 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -801,4 +801,10 @@ public final class UserConnection implements ProxiedPlayer { return serverSentScoreboard; } + + // Waterfall start + public boolean isDisableEntityMetadataRewrite() { + return entityRewrite == net.md_5.bungee.entitymap.EntityMap_Dummy.INSTANCE; + } + // Waterfall end } 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 c412bbab..5966469b 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 @@ -741,6 +741,7 @@ public class DownstreamBridge extends PacketHandler @Override public void handle(net.md_5.bungee.protocol.packet.EntityEffect entityEffect) throws Exception { + if (con.isDisableEntityMetadataRewrite()) return; // Waterfall // 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()) { @@ -752,6 +753,7 @@ public class DownstreamBridge extends PacketHandler @Override public void handle(net.md_5.bungee.protocol.packet.EntityRemoveEffect removeEffect) throws Exception { + if (con.isDisableEntityMetadataRewrite()) return; // Waterfall con.getPotions().remove(rewriteEntityId(removeEffect.getEntityId()), removeEffect.getEffectId()); } diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java index b9d250d9..d7c3b871 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java @@ -308,7 +308,6 @@ public class UpstreamBridge extends PacketHandler public void handle(ClientSettings settings) throws Exception { con.setSettings( settings ); - SettingsChangedEvent settingsEvent = new SettingsChangedEvent( con ); bungee.getPluginManager().callEvent( settingsEvent ); } diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java index c033118f..69accd42 100644 --- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java @@ -27,6 +27,11 @@ public abstract class EntityMap // Returns the correct entity map for the protocol version public static EntityMap getEntityMap(int version) { + // Waterfall start + if (net.md_5.bungee.api.ProxyServer.getInstance().getConfig().isDisableEntityMetadataRewrite()) { + return EntityMap_Dummy.INSTANCE; + } + // Waterfall end switch ( version ) { case ProtocolConstants.MINECRAFT_1_8: @@ -300,7 +305,13 @@ public abstract class EntityMap DefinedPacket.readVarInt( packet ); break; default: - throw new IllegalArgumentException( "Unknown meta type " + type ); + // Waterfall start - Don't lie + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) + { + type++; + } + throw new IllegalArgumentException( "Unknown meta type " + type + ": Using mods? refer to disable_entity_metadata_rewrite in waterfall.yml" ); + // Waterfall end } } diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_Dummy.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_Dummy.java new file mode 100644 index 00000000..cb81d1dd --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_Dummy.java @@ -0,0 +1,30 @@ + +package net.md_5.bungee.entitymap; + +import io.netty.buffer.ByteBuf; +// Waterfall start + +public class EntityMap_Dummy extends EntityMap { + + public static final EntityMap_Dummy INSTANCE = new EntityMap_Dummy(); + + EntityMap_Dummy() { + } + + @Override + public void rewriteServerbound(ByteBuf packet, int oldId, int newId) { + } + + @Override + public void rewriteServerbound(ByteBuf packet, int oldId, int newId, int protocolVersion) { + } + + @Override + public void rewriteClientbound(ByteBuf packet, int oldId, int newId) { + } + + @Override + public void rewriteClientbound(ByteBuf packet, int oldId, int newId, int protocolVersion) { + } +} +// Waterfall end \ No newline at end of file -- 2.39.3 (Apple Git-145)