From b176fc7a2ff024f9ec8131ea3e6797a8a89413ba Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:15:57 -0400 Subject: [PATCH] SRV improvements and improvements for GeyserConnect (#2048) - Individual per-player remote, port, and address - Removal of RemoteServer class - Do SRV lookup on startup and that's it --- connector/pom.xml | 4 +- .../geysermc/connector/GeyserConnector.java | 13 +++--- .../network/UpstreamPacketHandler.java | 4 +- .../network/remote/RemoteServer.java | 37 ---------------- .../network/session/GeyserSession.java | 42 ++++++++++++++----- .../geysermc/connector/skin/SkinManager.java | 2 +- 6 files changed, 41 insertions(+), 61 deletions(-) delete mode 100644 connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java diff --git a/connector/pom.xml b/connector/pom.xml index cb528e27b..6f2cdab4e 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -140,9 +140,9 @@ - com.github.steveice10 + com.github.GeyserMC PacketLib - 54f761c + b77a427 compile diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 0b7f84646..f0dd696f6 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -40,7 +40,6 @@ import org.geysermc.connector.common.AuthType; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.metrics.Metrics; import org.geysermc.connector.network.ConnectorServerEventHandler; -import org.geysermc.connector.network.remote.RemoteServer; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.BiomeTranslator; import org.geysermc.connector.network.translators.EntityIdentifierRegistry; @@ -97,9 +96,8 @@ public class GeyserConnector { private static GeyserConnector instance; - private RemoteServer remoteServer; @Setter - private AuthType authType; + private AuthType defaultAuthType; private boolean shuttingDown = false; @@ -166,7 +164,7 @@ public class GeyserConnector { String remoteAddress = config.getRemote().getAddress(); int remotePort = config.getRemote().getPort(); // Filters whether it is not an IP address or localhost, because otherwise it is not possible to find out an SRV entry. - if ((config.isLegacyPingPassthrough() || platformType == PlatformType.STANDALONE) && !remoteAddress.matches(IP_REGEX) && !remoteAddress.equalsIgnoreCase("localhost")) { + if (!remoteAddress.matches(IP_REGEX) && !remoteAddress.equalsIgnoreCase("localhost")) { try { // Searches for a server address and a port from a SRV record of the specified host name InitialDirContext ctx = new InitialDirContext(); @@ -186,8 +184,7 @@ public class GeyserConnector { } } - remoteServer = new RemoteServer(config.getRemote().getAddress(), remotePort); - authType = AuthType.getByName(config.getRemote().getAuthType()); + defaultAuthType = AuthType.getByName(config.getRemote().getAuthType()); CooldownUtils.setShowCooldown(config.isShowCooldown()); DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether @@ -334,8 +331,7 @@ public class GeyserConnector { generalThreadPool.shutdown(); bedrockServer.close(); players.clear(); - remoteServer = null; - authType = null; + defaultAuthType = null; this.getCommandManager().getCommands().clear(); bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.done")); @@ -371,6 +367,7 @@ public class GeyserConnector { * @param xuid the Xbox user identifier * @return the player or null if there is no player online with this xuid */ + @SuppressWarnings("unused") // API usage public GeyserSession getPlayerByXuid(String xuid) { for (GeyserSession session : players) { if (session.getAuthData() != null && session.getAuthData().getXboxUUID().equals(xuid)) { diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index 829ae23ef..c85bb773b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -97,7 +97,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { public boolean handle(ResourcePackClientResponsePacket packet) { switch (packet.getStatus()) { case COMPLETED: - session.connect(connector.getRemoteServer()); + session.connect(); connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.connect", session.getAuthData().getName())); break; @@ -186,7 +186,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { public boolean handle(SetLocalPlayerAsInitializedPacket packet) { LanguageUtils.loadGeyserLocale(session.getLocale()); - if (!session.isLoggedIn() && !session.isLoggingIn() && session.getConnector().getAuthType() == AuthType.ONLINE) { + if (!session.isLoggedIn() && !session.isLoggingIn() && session.getRemoteAuthType() == AuthType.ONLINE) { // TODO it is safer to key authentication on something that won't change (UUID, not username) if (!couldLoginUserByName(session.getAuthData().getName())) { LoginEncryptionUtils.showLoginWindow(session); diff --git a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java deleted file mode 100644 index b957b90d6..000000000 --- a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteServer.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019-2021 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.connector.network.remote; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class RemoteServer { - - private String address; - private int port; -} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index ee3f07f3e..d16cb1c2b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -81,7 +81,6 @@ import org.geysermc.connector.entity.player.SessionPlayerEntity; import org.geysermc.connector.entity.player.SkullPlayerEntity; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.PlayerInventory; -import org.geysermc.connector.network.remote.RemoteServer; import org.geysermc.connector.network.session.auth.AuthData; import org.geysermc.connector.network.session.auth.BedrockClientData; import org.geysermc.connector.network.session.cache.*; @@ -113,13 +112,21 @@ public class GeyserSession implements CommandSender { private final GeyserConnector connector; private final UpstreamSession upstream; - private RemoteServer remoteServer; private Client downstream; @Setter private AuthData authData; @Setter private BedrockClientData clientData; + /* Setter for GeyserConnect */ + @Setter + private String remoteAddress; + @Setter + private int remotePort; + @Setter + private AuthType remoteAuthType; + /* Setter for GeyserConnect */ + @Deprecated @Setter private boolean microsoftAccount; @@ -438,9 +445,14 @@ public class GeyserSession implements CommandSender { }); } - public void connect(RemoteServer remoteServer) { + /** + * Send all necessary packets to load Bedrock into the server + */ + public void connect() { startGame(); - this.remoteServer = remoteServer; + this.remoteAddress = connector.getConfig().getRemote().getAddress(); + this.remotePort = connector.getConfig().getRemote().getPort(); + this.remoteAuthType = connector.getDefaultAuthType(); // Set the hardcoded shield ID to the ID we just defined in StartGamePacket upstream.getSession().getHardcodedBlockingId().set(ItemRegistry.SHIELD.getBedrockId()); @@ -485,8 +497,8 @@ public class GeyserSession implements CommandSender { } public void login() { - if (connector.getAuthType() != AuthType.ONLINE) { - if (connector.getAuthType() == AuthType.OFFLINE) { + if (this.remoteAuthType != AuthType.ONLINE) { + if (this.remoteAuthType == AuthType.OFFLINE) { connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.offline")); } else { connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.floodgate")); @@ -595,7 +607,7 @@ public class GeyserSession implements CommandSender { * After getting whatever credentials needed, we attempt to join the Java server. */ private void connectDownstream() { - boolean floodgate = connector.getAuthType() == AuthType.FLOODGATE; + boolean floodgate = this.remoteAuthType == AuthType.FLOODGATE; final PublicKey publicKey; if (floodgate) { @@ -618,7 +630,8 @@ public class GeyserSession implements CommandSender { // Start ticking tickThread = connector.getGeneralThreadPool().scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS); - downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory()); + downstream = new Client(this.remoteAddress, this.remotePort, protocol, new TcpSessionFactory()); + disableSrvResolving(); if (connector.getConfig().getRemote().isUseProxyProtocol()) { downstream.getSession().setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true); downstream.getSession().setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress()); @@ -666,7 +679,7 @@ public class GeyserSession implements CommandSender { disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.remote.invalid_account", clientData.getLanguageCode())); return; } - connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.connect", authData.getName(), protocol.getProfile().getName(), remoteServer.getAddress())); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.connect", authData.getName(), protocol.getProfile().getName(), remoteAddress)); playerEntity.setUuid(protocol.getProfile().getId()); playerEntity.setUsername(protocol.getProfile().getName()); @@ -687,7 +700,7 @@ public class GeyserSession implements CommandSender { public void disconnected(DisconnectedEvent event) { loggingIn = false; loggedIn = false; - connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.disconnect", authData.getName(), remoteServer.getAddress(), event.getReason())); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.disconnect", authData.getName(), remoteAddress, event.getReason())); if (event.getCause() != null) { event.getCause().printStackTrace(); } @@ -705,7 +718,7 @@ public class GeyserSession implements CommandSender { playerEntity.setUuid(profile.getId()); // Check if they are not using a linked account - if (connector.getAuthType() == AuthType.OFFLINE || playerEntity.getUuid().getMostSignificantBits() == 0) { + if (remoteAuthType == AuthType.OFFLINE || playerEntity.getUuid().getMostSignificantBits() == 0) { SkinManager.handleBedrockSkin(playerEntity, clientData); } } @@ -793,6 +806,13 @@ public class GeyserSession implements CommandSender { collisionManager.updateScaffoldingFlags(); } + /** + * Will be overwritten for GeyserConnect. + */ + protected void disableSrvResolving() { + this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, false); + } + @Override public String getName() { return authData.getName(); diff --git a/connector/src/main/java/org/geysermc/connector/skin/SkinManager.java b/connector/src/main/java/org/geysermc/connector/skin/SkinManager.java index 5a0e41ed5..5af08292a 100644 --- a/connector/src/main/java/org/geysermc/connector/skin/SkinManager.java +++ b/connector/src/main/java/org/geysermc/connector/skin/SkinManager.java @@ -286,7 +286,7 @@ public class SkinManager { String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl(); String capeUrl = SkinProvider.EMPTY_CAPE.getTextureUrl(); - if (("steve".equals(skinUrl) || "alex".equals(skinUrl)) && GeyserConnector.getInstance().getAuthType() != AuthType.ONLINE) { + if (("steve".equals(skinUrl) || "alex".equals(skinUrl)) && GeyserConnector.getInstance().getDefaultAuthType() != AuthType.ONLINE) { GeyserSession session = GeyserConnector.getInstance().getPlayerByUuid(profile.getId()); if (session != null) {