From 44ca95bf85cc1943d0acf54930b12c706a03e496 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Fri, 18 Jan 2019 08:05:23 -0200 Subject: [PATCH 1/2] Fix bungee and velocity boss bar, implement Velocity channel workaround --- .../bungee/handlers/BungeeServerHandler.java | 76 ++++++++++--------- .../handlers/VelocityServerHandler.java | 60 ++++++++++++++- .../velocity/storage/VelocityStorage.java | 14 ++-- 3 files changed, 105 insertions(+), 45 deletions(-) diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java index 6a7e2b14d..c19965df1 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java @@ -8,25 +8,27 @@ import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventPriority; import net.md_5.bungee.protocol.packet.PluginMessage; +import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Pair; import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.boss.BossBar; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.protocol.ProtocolPipeline; import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.bungee.service.ProtocolDetectorService; import us.myles.ViaVersion.bungee.storage.BungeeStorage; import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.UUID; public class BungeeServerHandler implements Listener { private static Method getHandshake; @@ -87,13 +89,14 @@ public class BungeeServerHandler implements Listener { public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception { if (user == null) return; // Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666) - if (user.has(EntityTracker.class)) { + // Will be cleared by code below or by ServerConnector#handle(Login) + /*if (user.has(EntityTracker.class)) { EntityTracker tracker = user.get(EntityTracker.class); if (tracker.getBossBarMap() != null) for (BossBar bar : tracker.getBossBarMap().values()) bar.hide(); - } + }*/ // Handle server/version change if (user.has(BungeeStorage.class)) { BungeeStorage storage = user.get(BungeeStorage.class); @@ -107,6 +110,18 @@ public class BungeeServerHandler implements Listener { int protocolId = ProtocolDetectorService.getProtocolId(serverName); + if (protocolId <= ProtocolVersion.v1_8.getId()) { // 1.8 doesn't have BossBar packet + if (storage.getBossbar() != null) { + for (UUID uuid : storage.getBossbar()) { + PacketWrapper wrapper = new PacketWrapper(0x0C, null, user); + wrapper.write(Type.UUID, uuid); + wrapper.write(Type.VAR_INT, 1); // remove + wrapper.send(Protocol1_9TO1_8.class, true, true); + } + storage.getBossbar().clear(); + } + } + ProtocolInfo info = user.get(ProtocolInfo.class); int previousServerProtocol = info.getServerProtocolVersion(); @@ -130,41 +145,32 @@ public class BungeeServerHandler implements Listener { // Workaround 1.13 server change Object relayMessages = getRelayMessages.invoke(e.getPlayer().getPendingConnection()); - if (relayMessages instanceof List) { - for (Object message : (List) relayMessages) { - if (message instanceof PluginMessage) { - PluginMessage plMsg = (PluginMessage) message; - String channel = plMsg.getTag(); - if (previousServerProtocol != -1) { - if (previousServerProtocol < ProtocolVersion.v1_13.getId() - && protocolId >= ProtocolVersion.v1_13.getId()) { - channel = InventoryPackets.getNewPluginChannelId(channel); - if (channel.equals("minecraft:register")) { - String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0"); - for (int i = 0; i < channels.length; i++) { - channels[i] = InventoryPackets.getNewPluginChannelId(channels[i]); - } - plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8)); - } - } else if (previousServerProtocol >= ProtocolVersion.v1_13.getId() - && protocolId < ProtocolVersion.v1_13.getId()) { - channel = InventoryPackets.getOldPluginChannelId(channel); - if (channel.equals("REGISTER")) { - String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0"); - for (int i = 0; i < channels.length; i++) { - channels[i] = InventoryPackets.getOldPluginChannelId(channels[i]); - } - plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8)); - } + for (Object message : (List) relayMessages) { + PluginMessage plMsg = (PluginMessage) message; + String channel = plMsg.getTag(); + int id1_13 = ProtocolVersion.v1_13.getId(); + if (previousServerProtocol != -1) { + if (previousServerProtocol < id1_13 && protocolId >= id1_13) { + channel = InventoryPackets.getNewPluginChannelId(channel); + if (channel.equals("minecraft:register")) { + String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0"); + for (int i = 0; i < channels.length; i++) { + channels[i] = InventoryPackets.getNewPluginChannelId(channels[i]); } + plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8)); + } + } else if (previousServerProtocol >= id1_13 && protocolId < id1_13) { + channel = InventoryPackets.getOldPluginChannelId(channel); + if (channel.equals("REGISTER")) { + String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0"); + for (int i = 0; i < channels.length; i++) { + channels[i] = InventoryPackets.getOldPluginChannelId(channels[i]); + } + plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8)); } - plMsg.setTag(channel); - } else { - Via.getPlatform().getLogger().warning("relayMessages contains a element that isn't a Handshake " + message); } } - } else { - Via.getPlatform().getLogger().warning("relayMessages isn't a List! " + relayMessages); + plMsg.setTag(channel); } user.put(info); diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java index 3d07d23f1..c234a1e92 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java @@ -5,21 +5,27 @@ import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.player.ServerConnectedEvent; import com.velocitypowered.api.event.player.ServerPreConnectEvent; import com.velocitypowered.api.network.ProtocolVersion; +import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Pair; import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.boss.BossBar; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.protocol.ProtocolPipeline; import us.myles.ViaVersion.api.protocol.ProtocolRegistry; +import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.protocols.base.ProtocolInfo; -import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion.util.ReflectionUtil; import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; import us.myles.ViaVersion.velocity.storage.VelocityStorage; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.Semaphore; public class VelocityServerHandler { @@ -27,6 +33,7 @@ public class VelocityServerHandler { private static Method setNextProtocolVersion; private static Method getMinecraftConnection; private static Method getNextProtocolVersion; + private static Method getKnownChannels; static { try { @@ -38,6 +45,8 @@ public class VelocityServerHandler { .getDeclaredMethod("getMinecraftConnection"); getNextProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection") .getDeclaredMethod("getNextProtocolVersion"); + getKnownChannels = Class.forName("com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler") + .getDeclaredMethod("getKnownChannels"); } catch (NoSuchMethodException | ClassNotFoundException e) { e.printStackTrace(); } @@ -79,13 +88,14 @@ public class VelocityServerHandler { public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception { if (user == null) return; // Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666) - if (user.has(EntityTracker.class)) { + // Will be cleared by code below or by Velocity's handleBackendJoinGame + /*if (user.has(EntityTracker.class)) { EntityTracker tracker = user.get(EntityTracker.class); if (tracker.getBossBarMap() != null) for (BossBar bar : tracker.getBossBarMap().values()) bar.hide(); - } + }*/ // Handle server/version change if (user.has(VelocityStorage.class)) { // Wait all the scheduled packets be sent @@ -99,6 +109,8 @@ public class VelocityServerHandler { VelocityStorage storage = user.get(VelocityStorage.class); + if (storage.getBossbar() == null) storage.saveServerBossBars(); + if (e.getServer() != null) { if (!e.getServer().getServerInfo().getName().equals(storage.getCurrentServer())) { String serverName = e.getServer().getServerInfo().getName(); @@ -107,7 +119,20 @@ public class VelocityServerHandler { int protocolId = ProtocolDetectorService.getProtocolId(serverName); + if (protocolId <= ProtocolVersion.MINECRAFT_1_8.getProtocol()) { // 1.8 doesn't have BossBar packet + if (storage.getBossbar() != null) { + for (UUID uuid : storage.getBossbar()) { + PacketWrapper wrapper = new PacketWrapper(0x0C, null, user); + wrapper.write(Type.UUID, uuid); + wrapper.write(Type.VAR_INT, 1); // remove + wrapper.send(Protocol1_9TO1_8.class, true, true); + } + storage.getBossbar().clear(); + } + } + ProtocolInfo info = user.get(ProtocolInfo.class); + int previousServerProtocol = info.getServerProtocolVersion(); // Refresh the pipes List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId); @@ -127,6 +152,33 @@ public class VelocityServerHandler { // Add version-specific base Protocol pipeline.add(ProtocolRegistry.getBaseProtocol(protocolId)); + // Workaround 1.13 server change + Set knownChannels = (Set) getKnownChannels.invoke( + ReflectionUtil.invoke( + getMinecraftConnection.invoke(e.getPlayer()), + "getSessionHandler" + ) + ); + if (previousServerProtocol != -1) { + int id1_13 = ProtocolVersion.MINECRAFT_1_13.getProtocol(); + if (previousServerProtocol < id1_13 && protocolId >= id1_13) { + ArrayList newChannels = new ArrayList<>(); + for (String oldChannel : knownChannels) { + newChannels.add(InventoryPackets.getNewPluginChannelId(oldChannel)); + } + knownChannels.clear(); + knownChannels.addAll(newChannels); + + } else if (previousServerProtocol >= id1_13 && protocolId < id1_13) { + ArrayList newChannels = new ArrayList<>(); + for (String oldChannel : knownChannels) { + newChannels.add(InventoryPackets.getOldPluginChannelId(oldChannel)); + } + knownChannels.clear(); + knownChannels.addAll(newChannels); + } + } + user.put(info); user.put(storage); diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java index bddd50852..27b5b6d3e 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java @@ -5,8 +5,10 @@ import lombok.Data; import lombok.EqualsAndHashCode; import us.myles.ViaVersion.api.data.StoredObject; import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.util.ReflectionUtil; -import java.util.Set; +import java.lang.reflect.InvocationTargetException; +import java.util.List; import java.util.UUID; @Data @@ -14,24 +16,24 @@ import java.util.UUID; public class VelocityStorage extends StoredObject { private Player player; private String currentServer; - private Set bossbar; + private List bossbar; public VelocityStorage(UserConnection user, Player player) { super(user); this.player = player; this.currentServer = ""; + } + public void saveServerBossBars() { // Get bossbar list if it's supported - /* TODO make this work - do we need this? try { - Object connection = ReflectionUtil.invoke(player, "getConnection"); + Object connection = ReflectionUtil.invoke(player, "getMinecraftConnection"); Object sessionHandler = ReflectionUtil.invoke(connection, "getSessionHandler"); if (sessionHandler.getClass().getSimpleName().contains("Play")) { - bossbar = (Set) ReflectionUtil.invoke(sessionHandler, "getServerBossBars"); + bossbar = (List) ReflectionUtil.invoke(sessionHandler, "getServerBossBars"); } } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } - */ } } From 7e8bd606fe7d53ffd89be93dd9f0616deb8ff88a Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Fri, 18 Jan 2019 14:34:51 -0200 Subject: [PATCH 2/2] remove commented code --- .../ViaVersion/bungee/handlers/BungeeServerHandler.java | 9 --------- .../velocity/handlers/VelocityServerHandler.java | 9 --------- 2 files changed, 18 deletions(-) diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java index c19965df1..8383e73ca 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java @@ -88,15 +88,6 @@ public class BungeeServerHandler implements Listener { public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception { if (user == null) return; - // Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666) - // Will be cleared by code below or by ServerConnector#handle(Login) - /*if (user.has(EntityTracker.class)) { - EntityTracker tracker = user.get(EntityTracker.class); - - if (tracker.getBossBarMap() != null) - for (BossBar bar : tracker.getBossBarMap().values()) - bar.hide(); - }*/ // Handle server/version change if (user.has(BungeeStorage.class)) { BungeeStorage storage = user.get(BungeeStorage.class); diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java index c234a1e92..d8c662937 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java @@ -87,15 +87,6 @@ public class VelocityServerHandler { public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception { if (user == null) return; - // Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666) - // Will be cleared by code below or by Velocity's handleBackendJoinGame - /*if (user.has(EntityTracker.class)) { - EntityTracker tracker = user.get(EntityTracker.class); - - if (tracker.getBossBarMap() != null) - for (BossBar bar : tracker.getBossBarMap().values()) - bar.hide(); - }*/ // Handle server/version change if (user.has(VelocityStorage.class)) { // Wait all the scheduled packets be sent