diff --git a/src/main/java/org/geysermc/multi/MasterServer.java b/src/main/java/org/geysermc/multi/MasterServer.java index 65c0afb..d61daea 100644 --- a/src/main/java/org/geysermc/multi/MasterServer.java +++ b/src/main/java/org/geysermc/multi/MasterServer.java @@ -5,8 +5,10 @@ import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; import com.nukkitx.protocol.bedrock.BedrockServerSession; import lombok.Getter; +import org.geysermc.multi.proxy.GeyserProxyBootstrap; import org.geysermc.multi.utils.Logger; import org.geysermc.multi.utils.Player; +import org.geysermc.multi.utils.Server; import java.net.InetSocketAddress; import java.util.HashMap; @@ -37,6 +39,9 @@ public class MasterServer { @Getter private final Map players = new HashMap<>(); + @Getter + private GeyserProxyBootstrap geyserProxy; + public MasterServer() { logger = new Logger(); logger.setDebug(true); @@ -95,5 +100,16 @@ public class MasterServer { public void shutdown() { shuttingDown = true; generalThreadPool.shutdown(); + + if (geyserProxy != null) { + geyserProxy.onDisable(); + } + } + + public void createGeyserProxy() { + if (geyserProxy == null) { + this.geyserProxy = new GeyserProxyBootstrap(); + geyserProxy.onEnable(); + } } } diff --git a/src/main/java/org/geysermc/multi/PacketHandler.java b/src/main/java/org/geysermc/multi/PacketHandler.java index 736ef9b..a981991 100644 --- a/src/main/java/org/geysermc/multi/PacketHandler.java +++ b/src/main/java/org/geysermc/multi/PacketHandler.java @@ -38,9 +38,7 @@ public class PacketHandler implements BedrockPacketHandler { public void disconnect(DisconnectReason reason) { if (player != null) { - player.onDisconnect(); - masterServer.getLogger().info(player.getDisplayName() + " has disconnected (" + reason + ")"); - masterServer.getPlayers().remove(session.getAddress()); + masterServer.getLogger().info(player.getDisplayName() + " has disconnected from the master server (" + reason + ")"); } } @@ -180,4 +178,10 @@ public class PacketHandler implements BedrockPacketHandler { return true; } + + @Override + public boolean handle(NetworkStackLatencyPacket packet) { + masterServer.getLogger().debug(packet.toString()); + return false; + } } diff --git a/src/main/java/org/geysermc/multi/proxy/GeyserProxyBootstrap.java b/src/main/java/org/geysermc/multi/proxy/GeyserProxyBootstrap.java index ba21c66..4129ce9 100644 --- a/src/main/java/org/geysermc/multi/proxy/GeyserProxyBootstrap.java +++ b/src/main/java/org/geysermc/multi/proxy/GeyserProxyBootstrap.java @@ -22,14 +22,14 @@ public class GeyserProxyBootstrap implements GeyserBootstrap { private GeyserProxyCommandManager geyserCommandManager; private GeyserProxyConfiguration geyserConfig; - private Logger geyserLogger; + private GeyserProxyLogger geyserLogger; private IGeyserPingPassthrough geyserPingPassthrough; private GeyserConnector connector; @Override public void onEnable() { - geyserLogger = MasterServer.getInstance().getLogger(); + geyserLogger = new GeyserProxyLogger(); try { InputStream configFile = GeyserProxyBootstrap.class.getClassLoader().getResourceAsStream("proxy_config.yml"); @@ -45,6 +45,8 @@ public class GeyserProxyBootstrap implements GeyserBootstrap { geyserCommandManager = new GeyserProxyCommandManager(connector); geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector); + + connector.getBedrockServer().setHandler(new ProxyConnectorServerEventHandler(connector)); } @Override @@ -58,7 +60,7 @@ public class GeyserProxyBootstrap implements GeyserBootstrap { } @Override - public Logger getGeyserLogger() { + public GeyserProxyLogger getGeyserLogger() { return geyserLogger; } @@ -71,11 +73,5 @@ public class GeyserProxyBootstrap implements GeyserBootstrap { public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserPingPassthrough; } - - public void setServer(Server server) { - geyserLogger.debug("Updated remote server info"); - connector.getRemoteServer().setAddress(server.getAddress()); - connector.getRemoteServer().setPort(server.getPort()); - } } diff --git a/src/main/java/org/geysermc/multi/proxy/GeyserProxyLogger.java b/src/main/java/org/geysermc/multi/proxy/GeyserProxyLogger.java new file mode 100644 index 0000000..3d3330b --- /dev/null +++ b/src/main/java/org/geysermc/multi/proxy/GeyserProxyLogger.java @@ -0,0 +1,11 @@ +package org.geysermc.multi.proxy; + +import lombok.extern.log4j.Log4j2; +import org.apache.logging.log4j.core.config.Configurator; +import org.geysermc.common.ChatColor; +import org.geysermc.multi.utils.Logger; + +@Log4j2 +public class GeyserProxyLogger extends Logger { + public void debug(String message) { } +} diff --git a/src/main/java/org/geysermc/multi/proxy/GeyserProxySession.java b/src/main/java/org/geysermc/multi/proxy/GeyserProxySession.java new file mode 100644 index 0000000..5a57279 --- /dev/null +++ b/src/main/java/org/geysermc/multi/proxy/GeyserProxySession.java @@ -0,0 +1,30 @@ +package org.geysermc.multi.proxy; + +import com.nukkitx.protocol.bedrock.BedrockServerSession; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.multi.MasterServer; +import org.geysermc.multi.utils.Player; + +public class GeyserProxySession extends GeyserSession { + + private final GeyserConnector connector; + private final BedrockServerSession bedrockServerSession; + + public GeyserProxySession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { + super(connector, bedrockServerSession); + this.connector = connector; + this.bedrockServerSession = bedrockServerSession; + } + + public void authenticate(String username, String password) { + Player player = MasterServer.getInstance().getPlayers().get(bedrockServerSession.getAddress()); + if (player != null) { + connector.getRemoteServer().setAddress(player.getCurrentServer().getAddress()); + connector.getRemoteServer().setPort(player.getCurrentServer().getPort()); + super.authenticate(username, password); + }else{ + bedrockServerSession.disconnect("Please connect to the master server and pick a server first!"); + } + } +} diff --git a/src/main/java/org/geysermc/multi/proxy/ProxyConnectorServerEventHandler.java b/src/main/java/org/geysermc/multi/proxy/ProxyConnectorServerEventHandler.java new file mode 100644 index 0000000..03304a4 --- /dev/null +++ b/src/main/java/org/geysermc/multi/proxy/ProxyConnectorServerEventHandler.java @@ -0,0 +1,36 @@ +package org.geysermc.multi.proxy; + +import com.nukkitx.protocol.bedrock.BedrockServerSession; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.ConnectorServerEventHandler; +import org.geysermc.connector.network.UpstreamPacketHandler; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.multi.MasterServer; +import org.geysermc.multi.utils.Player; + +public class ProxyConnectorServerEventHandler extends ConnectorServerEventHandler { + private final GeyserConnector connector; + + public ProxyConnectorServerEventHandler(GeyserConnector connector) { + super(connector); + this.connector = connector; + MasterServer.getInstance().getLogger().debug("Registered custom ConnectorServerEventHandler"); + } + + @Override + public void onSessionCreation(BedrockServerSession bedrockServerSession) { + Player player = MasterServer.getInstance().getPlayers().get(bedrockServerSession.getAddress()); + if (player == null) { + bedrockServerSession.disconnect("Please connect to the master server and pick a server first!"); + return; + } + + super.onSessionCreation(bedrockServerSession); + + bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserProxySession(connector, bedrockServerSession))); + bedrockServerSession.addDisconnectHandler(disconnectReason -> { + MasterServer.getInstance().getLogger().debug("Player disconnected from geyser proxy: " + player.getDisplayName() + " (" + disconnectReason + ")"); + MasterServer.getInstance().getPlayers().remove(bedrockServerSession.getAddress()); + }); + } +} diff --git a/src/main/java/org/geysermc/multi/ui/FormID.java b/src/main/java/org/geysermc/multi/ui/FormID.java index c97369a..4d8763d 100644 --- a/src/main/java/org/geysermc/multi/ui/FormID.java +++ b/src/main/java/org/geysermc/multi/ui/FormID.java @@ -5,6 +5,7 @@ public enum FormID { DIRECT_CONNECT, ADD_SERVER, REMOVE_SERVER, + CONNECTING, ERROR; private static final FormID[] VALUES = values(); diff --git a/src/main/java/org/geysermc/multi/ui/UIHandler.java b/src/main/java/org/geysermc/multi/ui/UIHandler.java index 3755c35..732483f 100644 --- a/src/main/java/org/geysermc/multi/ui/UIHandler.java +++ b/src/main/java/org/geysermc/multi/ui/UIHandler.java @@ -23,11 +23,25 @@ public class UIHandler { return window; } + public static FormWindow getWaitingScreen(Server server) { + SimpleFormWindow window = new SimpleFormWindow("Servers", "Please wait while we connect you to " + server.toString()); + return window; + } + public static void handleServerListResponse(Player player, SimpleFormResponse data) { MasterServer.getInstance().getLogger().debug(data.getClickedButton().getText()); + // Get the server Server server = player.getServers().get(data.getClickedButtonId()); - player.createGeyserProxy(server); + + // Tell the user we are connecting them + player.sendWindow(FormID.CONNECTING, getWaitingScreen(server)); + + // Create the geyser instance if its not already running + MasterServer.getInstance().createGeyserProxy(); + + // Send the user over to the serverty + player.setCurrentServer(server); player.connectToProxy(); } } diff --git a/src/main/java/org/geysermc/multi/utils/Player.java b/src/main/java/org/geysermc/multi/utils/Player.java index 747776e..689727b 100644 --- a/src/main/java/org/geysermc/multi/utils/Player.java +++ b/src/main/java/org/geysermc/multi/utils/Player.java @@ -8,10 +8,13 @@ import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; +import lombok.Setter; import org.geysermc.common.window.FormWindow; +import org.geysermc.multi.MasterServer; import org.geysermc.multi.proxy.GeyserProxyBootstrap; import org.geysermc.multi.ui.FormID; +import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -30,7 +33,8 @@ public class Player { private FormWindow currentWindow; private FormID currentWindowId; - private GeyserProxyBootstrap geyserProxy; + @Setter + private Server currentServer; public Player(JsonNode extraData, BedrockServerSession session) { this.xuid = extraData.get("XUID").asText(); @@ -121,12 +125,6 @@ public class Player { session.sendPacket(setEntityMotionPacket); } - public void onDisconnect() { - if (geyserProxy != null) { - //geyserProxy.onDisable(); - } - } - public void sendWindow(FormID id, FormWindow window) { this.currentWindow = window; @@ -142,19 +140,10 @@ public class Player { sendWindow(currentWindowId, currentWindow); } - public void createGeyserProxy(Server server) { - if (this.geyserProxy == null) { - this.geyserProxy = new GeyserProxyBootstrap(); - geyserProxy.onEnable(); - } - - geyserProxy.setServer(server); - } - public void connectToProxy() { TransferPacket transferPacket = new TransferPacket(); transferPacket.setAddress("127.0.0.1"); - transferPacket.setPort(geyserProxy.getGeyserConfig().getBedrock().getPort()); + transferPacket.setPort(MasterServer.getInstance().getGeyserProxy().getGeyserConfig().getBedrock().getPort()); session.sendPacket(transferPacket); } } diff --git a/src/main/java/org/geysermc/multi/utils/Server.java b/src/main/java/org/geysermc/multi/utils/Server.java index 1e6b223..8e3334d 100644 --- a/src/main/java/org/geysermc/multi/utils/Server.java +++ b/src/main/java/org/geysermc/multi/utils/Server.java @@ -12,4 +12,9 @@ public class Server { public Server(String address) { this(address, 25565); } + + @Override + public String toString() { + return address + ":" + port; + } }