diff --git a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java index 425a158db..2cc9d2576 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java +++ b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java @@ -1,10 +1,12 @@ package us.myles.ViaVersion; import com.google.gson.JsonObject; +import net.md_5.bungee.UserConnection; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.event.EventHandler; @@ -19,6 +21,7 @@ import us.myles.ViaVersion.bungee.commands.BungeeCommand; import us.myles.ViaVersion.bungee.commands.BungeeCommandHandler; import us.myles.ViaVersion.bungee.commands.BungeeCommandSender; import us.myles.ViaVersion.bungee.platform.*; +import us.myles.ViaVersion.bungee.service.ProtocolDetectorService; import us.myles.ViaVersion.dump.PluginInfo; import us.myles.ViaVersion.util.GsonUtil; @@ -44,7 +47,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener { Via.init(ViaManager.builder() .platform(this) .injector(new BungeeViaInjector()) - .loader(new BungeeViaLoader()) + .loader(new BungeeViaLoader(this)) .commandHandler(commandHandler) .build()); @@ -159,4 +162,38 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener { Via.getManager().removePortedClient(e.getPlayer().getUniqueId()); } + // Set the handshake version every time someone connects to any server TODO reflection + @EventHandler + public void onServerConnect(ServerConnectEvent e) throws NoSuchFieldException, IllegalAccessException { + int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName()); + UserConnection connection = (UserConnection) e.getPlayer(); + connection.getPendingConnection().getHandshake().setProtocolVersion(protocolId); + } + + /* + TODO: Change when connected + System.out.println("Switching servers.."); + if (!ProtocolDetectorService.hasProtocolId(e.getServer().getInfo().getName())) { + getLogger().severe("Could not find the protocol id for server " + e.getServer()); + return; + } + + int protocolId = ProtocolDetectorService.getProtocolId(e.getServer().getInfo().getName()); + UserConnection connection = (UserConnection) e.getPlayer(); + + ChannelWrapper wrapper = ReflectionUtil.get(connection, "ch", ChannelWrapper.class); + wrapper.setVersion(protocolId); + + us.myles.ViaVersion.api.data.UserConnection viaConnection = Via.getManager().getConnection(e.getPlayer().getUniqueId()); + ProtocolInfo info = viaConnection.get(ProtocolInfo.class); + // Choose the pipe + List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId); + ProtocolPipeline pipeline = viaConnection.get(ProtocolInfo.class).getPipeline(); + if (protocols != null) { + pipeline.pipes().clear(); + for (Pair prot : protocols) { + pipeline.add(prot.getValue()); + } + }*/ + } diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java index b3a0efe48..d8efb2627 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java @@ -5,9 +5,11 @@ import io.netty.channel.ChannelInitializer; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.platform.ViaInjector; import us.myles.ViaVersion.bungee.handlers.BungeeChannelInitializer; +import us.myles.ViaVersion.util.ReflectionUtil; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.List; public class BungeeViaInjector implements ViaInjector { @Override @@ -42,7 +44,7 @@ public class BungeeViaInjector implements ViaInjector { @Override public int getServerProtocolVersion() throws Exception { - return 47; // TODO Config Option + return (int) ReflectionUtil.getStatic(Class.forName("net.md_5.bungee.protocol.ProtocolConstants"), "SUPPORTED_VERSION_IDS", List.class).get(0); } @Override diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java index 9e44f86af..ef552bfa9 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java @@ -1,13 +1,23 @@ package us.myles.ViaVersion.bungee.platform; +import lombok.AllArgsConstructor; +import us.myles.ViaVersion.BungeePlugin; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.platform.ViaPlatformLoader; import us.myles.ViaVersion.bungee.providers.BungeeMovementTransmitter; +import us.myles.ViaVersion.bungee.service.ProtocolDetectorService; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import java.util.concurrent.TimeUnit; + +@AllArgsConstructor public class BungeeViaLoader implements ViaPlatformLoader { + private BungeePlugin plugin; + @Override public void load() { Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter()); + + plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, 1, TimeUnit.MINUTES); } } diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java new file mode 100644 index 000000000..d8a27dcf9 --- /dev/null +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java @@ -0,0 +1,43 @@ +package us.myles.ViaVersion.bungee.service; + +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.config.ServerInfo; +import us.myles.ViaVersion.BungeePlugin; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ProtocolDetectorService implements Runnable { + private static final Map protocolIds = new ConcurrentHashMap<>(); + private BungeePlugin plugin; + + public ProtocolDetectorService(BungeePlugin plugin) { + this.plugin = plugin; + } + + public static Integer getProtocolId(String serverName) { + if (!hasProtocolId(serverName)) + return -1; + return protocolIds.get(serverName); + } + + public static boolean hasProtocolId(String serverName) { + return protocolIds.containsKey(serverName); + } + + @Override + public void run() { + System.out.println("Checking protocol ids"); // TODO remove message after confirming that it works + + for (final Map.Entry lists : plugin.getProxy().getServers().entrySet()) { + lists.getValue().ping(new Callback() { + @Override + public void done(ServerPing serverPing, Throwable throwable) { + if (throwable == null) + protocolIds.put(lists.getKey(), serverPing.getVersion().getProtocol()); + } + }); + } + } +}