From 47c3a22df5a743f5e760c1d7b7f259e2f2d87ad9 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Feb 2021 16:43:12 -0500 Subject: [PATCH] Allow Bedrock to manage entering server and not us (#22) --- pom.xml | 2 +- .../org/geysermc/connect/MasterServer.java | 36 +++++++++++++------ .../org/geysermc/connect/PacketHandler.java | 11 ++---- .../connect/proxy/GeyserProxySession.java | 30 ++++++++-------- .../GeyserProxyUpstreamPacketHandler.java | 3 +- .../ProxyConnectorServerEventHandler.java | 4 +-- 6 files changed, 46 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index d002528..3d17af0 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ com.github.CloudburstMC.Protocol bedrock-v422 - d41b84e86c + 294e7e53b6 compile diff --git a/src/main/java/org/geysermc/connect/MasterServer.java b/src/main/java/org/geysermc/connect/MasterServer.java index 51c2eff..ba80ca3 100644 --- a/src/main/java/org/geysermc/connect/MasterServer.java +++ b/src/main/java/org/geysermc/connect/MasterServer.java @@ -25,12 +25,15 @@ package org.geysermc.connect; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.nukkitx.protocol.bedrock.*; import lombok.Getter; import lombok.Setter; import org.geysermc.connect.storage.DisabledStorageManager; import org.geysermc.connect.utils.Server; import org.geysermc.connect.utils.ServerCategory; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.BedrockProtocol; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connect.proxy.GeyserProxyBootstrap; @@ -44,12 +47,12 @@ import java.net.InetSocketAddress; import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class MasterServer { private BedrockServer bdServer; - private BedrockPong bdPong; @Getter private boolean shuttingDown = false; @@ -66,6 +69,14 @@ public class MasterServer { @Getter private final Map players = new HashMap<>(); + /** + * Players that are transferring and are expected to rejoin on the Geyser side. + */ + @Getter + private final Cache transferringPlayers = CacheBuilder.newBuilder() + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(); + @Getter private GeyserProxyBootstrap geyserProxy; @@ -134,16 +145,6 @@ public class MasterServer { InetSocketAddress bindAddress = new InetSocketAddress(geyserConnectConfig.getAddress(), port); bdServer = new BedrockServer(bindAddress); - bdPong = new BedrockPong(); - bdPong.setEdition("MCPE"); - bdPong.setMotd(geyserConnectConfig.getMotd()); - bdPong.setPlayerCount(0); - bdPong.setMaximumPlayerCount(geyserConnectConfig.getMaxPlayers()); - bdPong.setGameType("Survival"); - bdPong.setIpv4Port(port); - bdPong.setProtocolVersion(BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()); - bdPong.setVersion(null); // Server tries to connect either way and it looks better - bdServer.setHandler(new BedrockServerEventHandler() { @Override public boolean onConnectionRequest(InetSocketAddress address) { @@ -152,6 +153,19 @@ public class MasterServer { @Override public BedrockPong onQuery(InetSocketAddress address) { + int playerCount = players.size(); + if (GeyserConnector.getInstance() != null) { + playerCount += GeyserConnector.getInstance().getPlayers().size(); + } + BedrockPong bdPong = new BedrockPong(); + bdPong.setEdition("MCPE"); + bdPong.setMotd(geyserConnectConfig.getMotd()); + bdPong.setPlayerCount(playerCount); + bdPong.setMaximumPlayerCount(geyserConnectConfig.getMaxPlayers()); + bdPong.setGameType("Survival"); + bdPong.setIpv4Port(port); + bdPong.setProtocolVersion(BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()); + bdPong.setVersion(null); // Server tries to connect either way and it looks better return bdPong; } diff --git a/src/main/java/org/geysermc/connect/PacketHandler.java b/src/main/java/org/geysermc/connect/PacketHandler.java index 575df7e..f40e778 100644 --- a/src/main/java/org/geysermc/connect/PacketHandler.java +++ b/src/main/java/org/geysermc/connect/PacketHandler.java @@ -79,9 +79,10 @@ public class PacketHandler implements BedrockPacketHandler { masterServer.getLogger().info(player.getDisplayName() + " has disconnected from the master server (" + reason + ")"); masterServer.getStorageManager().saveServers(player); - if (player.getCurrentServer() == null || player.getCurrentServer().isBedrock()) { - masterServer.getPlayers().remove(player.getXuid(), player); + if (player.getCurrentServer() != null && !player.getCurrentServer().isBedrock()) { + masterServer.getTransferringPlayers().put(player.getXuid(), player); } + masterServer.getPlayers().remove(player.getXuid(), player); } } @@ -203,12 +204,6 @@ public class PacketHandler implements BedrockPacketHandler { @Override public boolean handle(SetLocalPlayerAsInitializedPacket packet) { - // Disconnect the player if the server is full - if (MasterServer.getInstance().getPlayers().size() > MasterServer.getInstance().getGeyserConnectConfig().getMaxPlayers()) { - session.disconnect("disconnectionScreen.serverFull"); - return false; - } - masterServer.getLogger().debug("Player initialized: " + player.getDisplayName()); // Handle the virtual host if specified diff --git a/src/main/java/org/geysermc/connect/proxy/GeyserProxySession.java b/src/main/java/org/geysermc/connect/proxy/GeyserProxySession.java index 2c1bae2..9ef3163 100644 --- a/src/main/java/org/geysermc/connect/proxy/GeyserProxySession.java +++ b/src/main/java/org/geysermc/connect/proxy/GeyserProxySession.java @@ -26,6 +26,7 @@ package org.geysermc.connect.proxy; import com.nukkitx.protocol.bedrock.BedrockServerSession; +import lombok.Getter; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.common.AuthType; import org.geysermc.connector.network.session.GeyserSession; @@ -37,6 +38,8 @@ public class GeyserProxySession extends GeyserSession { private final GeyserConnector connector; private final BedrockServerSession bedrockServerSession; + @Getter + private Player player; public GeyserProxySession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { super(connector, bedrockServerSession); @@ -44,10 +47,20 @@ public class GeyserProxySession extends GeyserSession { this.bedrockServerSession = bedrockServerSession; } + @Override + public void setAuthenticationData(AuthData authData) { + super.setAuthenticationData(authData); + + player = MasterServer.getInstance().getTransferringPlayers().getIfPresent(authData.getXboxUUID()); + if (player == null) { + bedrockServerSession.disconnect("Please connect to the master server and pick a server first!"); + } else { + MasterServer.getInstance().getTransferringPlayers().invalidate(authData.getXboxUUID()); + } + } + @Override public void authenticate(String username, String password) { - // Get the player based on the connection address - Player player = MasterServer.getInstance().getPlayers().get(getAuthData().getXboxUUID()); if (player != null && player.getCurrentServer() != null) { // Set the remote server info for the player connector.getRemoteServer().setAddress(player.getCurrentServer().getAddress()); @@ -64,8 +77,6 @@ public class GeyserProxySession extends GeyserSession { @Override public void authenticateWithMicrosoftCode() { - // Get the player based on the connection address - Player player = MasterServer.getInstance().getPlayers().get(getAuthData().getXboxUUID()); if (player != null && player.getCurrentServer() != null) { // Set the remote server info for the player connector.getRemoteServer().setAddress(player.getCurrentServer().getAddress()); @@ -82,19 +93,8 @@ public class GeyserProxySession extends GeyserSession { @Override public void login() { - Player player = MasterServer.getInstance().getPlayers().get(getAuthData().getXboxUUID()); connector.setAuthType(player.getCurrentServer().isOnline() ? AuthType.ONLINE : AuthType.OFFLINE); super.login(); } - - @Override - public void setAuthenticationData(AuthData authData) { - super.setAuthenticationData(authData); - - Player player = MasterServer.getInstance().getPlayers().get(authData.getXboxUUID()); - if (player == null) { - bedrockServerSession.disconnect("Please connect to the master server and pick a server first!"); - } - } } diff --git a/src/main/java/org/geysermc/connect/proxy/GeyserProxyUpstreamPacketHandler.java b/src/main/java/org/geysermc/connect/proxy/GeyserProxyUpstreamPacketHandler.java index 22deb25..4f74d58 100644 --- a/src/main/java/org/geysermc/connect/proxy/GeyserProxyUpstreamPacketHandler.java +++ b/src/main/java/org/geysermc/connect/proxy/GeyserProxyUpstreamPacketHandler.java @@ -40,8 +40,7 @@ public class GeyserProxyUpstreamPacketHandler extends UpstreamPacketHandler { @Override public boolean handle(SetLocalPlayerAsInitializedPacket packet) { - Player player = MasterServer.getInstance().getPlayers().get(session.getAuthData().getXboxUUID()); - connector.setAuthType(player.getCurrentServer().isOnline() ? AuthType.ONLINE : AuthType.OFFLINE); + connector.setAuthType(((GeyserProxySession) session).getPlayer().getCurrentServer().isOnline() ? AuthType.ONLINE : AuthType.OFFLINE); return super.handle(packet); } diff --git a/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java b/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java index de48828..ab95c05 100644 --- a/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java +++ b/src/main/java/org/geysermc/connect/proxy/ProxyConnectorServerEventHandler.java @@ -55,16 +55,14 @@ public class ProxyConnectorServerEventHandler extends ConnectorServerEventHandle bedrockServerSession.addDisconnectHandler(disconnectReason -> { // Make sure nothing is null before locating the player if (MasterServer.getInstance() == null - || MasterServer.getInstance().getPlayers().size() == 0 || session.getAuthData() == null || session.getAuthData().getXboxUUID() == null) { return; } - Player player = MasterServer.getInstance().getPlayers().get(session.getAuthData().getXboxUUID()); + Player player = session.getPlayer(); if (player != null) { MasterServer.getInstance().getLogger().debug("Player disconnected from Geyser proxy: " + player.getDisplayName() + " (" + disconnectReason + ")"); - MasterServer.getInstance().getPlayers().remove(session.getAuthData().getXboxUUID()); // Set the last disconnect time MasterServer.getInstance().setLastDisconnectTime(System.currentTimeMillis());