mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
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
This commit is contained in:
parent
3d4fff8dee
commit
b176fc7a2f
6 changed files with 41 additions and 61 deletions
|
@ -140,9 +140,9 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.steveice10</groupId>
|
<groupId>com.github.GeyserMC</groupId>
|
||||||
<artifactId>PacketLib</artifactId>
|
<artifactId>PacketLib</artifactId>
|
||||||
<version>54f761c</version>
|
<version>b77a427</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion> <!-- Move this exclusion back to MCProtocolLib it gets the latest PacketLib -->
|
<exclusion> <!-- Move this exclusion back to MCProtocolLib it gets the latest PacketLib -->
|
||||||
|
|
|
@ -40,7 +40,6 @@ import org.geysermc.connector.common.AuthType;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
import org.geysermc.connector.metrics.Metrics;
|
import org.geysermc.connector.metrics.Metrics;
|
||||||
import org.geysermc.connector.network.ConnectorServerEventHandler;
|
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.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.BiomeTranslator;
|
import org.geysermc.connector.network.translators.BiomeTranslator;
|
||||||
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
|
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
|
||||||
|
@ -97,9 +96,8 @@ public class GeyserConnector {
|
||||||
|
|
||||||
private static GeyserConnector instance;
|
private static GeyserConnector instance;
|
||||||
|
|
||||||
private RemoteServer remoteServer;
|
|
||||||
@Setter
|
@Setter
|
||||||
private AuthType authType;
|
private AuthType defaultAuthType;
|
||||||
|
|
||||||
private boolean shuttingDown = false;
|
private boolean shuttingDown = false;
|
||||||
|
|
||||||
|
@ -166,7 +164,7 @@ public class GeyserConnector {
|
||||||
String remoteAddress = config.getRemote().getAddress();
|
String remoteAddress = config.getRemote().getAddress();
|
||||||
int remotePort = config.getRemote().getPort();
|
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.
|
// 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 {
|
try {
|
||||||
// Searches for a server address and a port from a SRV record of the specified host name
|
// Searches for a server address and a port from a SRV record of the specified host name
|
||||||
InitialDirContext ctx = new InitialDirContext();
|
InitialDirContext ctx = new InitialDirContext();
|
||||||
|
@ -186,8 +184,7 @@ public class GeyserConnector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteServer = new RemoteServer(config.getRemote().getAddress(), remotePort);
|
defaultAuthType = AuthType.getByName(config.getRemote().getAuthType());
|
||||||
authType = AuthType.getByName(config.getRemote().getAuthType());
|
|
||||||
|
|
||||||
CooldownUtils.setShowCooldown(config.isShowCooldown());
|
CooldownUtils.setShowCooldown(config.isShowCooldown());
|
||||||
DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
|
DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
|
||||||
|
@ -334,8 +331,7 @@ public class GeyserConnector {
|
||||||
generalThreadPool.shutdown();
|
generalThreadPool.shutdown();
|
||||||
bedrockServer.close();
|
bedrockServer.close();
|
||||||
players.clear();
|
players.clear();
|
||||||
remoteServer = null;
|
defaultAuthType = null;
|
||||||
authType = null;
|
|
||||||
this.getCommandManager().getCommands().clear();
|
this.getCommandManager().getCommands().clear();
|
||||||
|
|
||||||
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.done"));
|
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.done"));
|
||||||
|
@ -371,6 +367,7 @@ public class GeyserConnector {
|
||||||
* @param xuid the Xbox user identifier
|
* @param xuid the Xbox user identifier
|
||||||
* @return the player or <code>null</code> if there is no player online with this xuid
|
* @return the player or <code>null</code> if there is no player online with this xuid
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused") // API usage
|
||||||
public GeyserSession getPlayerByXuid(String xuid) {
|
public GeyserSession getPlayerByXuid(String xuid) {
|
||||||
for (GeyserSession session : players) {
|
for (GeyserSession session : players) {
|
||||||
if (session.getAuthData() != null && session.getAuthData().getXboxUUID().equals(xuid)) {
|
if (session.getAuthData() != null && session.getAuthData().getXboxUUID().equals(xuid)) {
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||||
public boolean handle(ResourcePackClientResponsePacket packet) {
|
public boolean handle(ResourcePackClientResponsePacket packet) {
|
||||||
switch (packet.getStatus()) {
|
switch (packet.getStatus()) {
|
||||||
case COMPLETED:
|
case COMPLETED:
|
||||||
session.connect(connector.getRemoteServer());
|
session.connect();
|
||||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.connect", session.getAuthData().getName()));
|
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.connect", session.getAuthData().getName()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||||
public boolean handle(SetLocalPlayerAsInitializedPacket packet) {
|
public boolean handle(SetLocalPlayerAsInitializedPacket packet) {
|
||||||
LanguageUtils.loadGeyserLocale(session.getLocale());
|
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)
|
// TODO it is safer to key authentication on something that won't change (UUID, not username)
|
||||||
if (!couldLoginUserByName(session.getAuthData().getName())) {
|
if (!couldLoginUserByName(session.getAuthData().getName())) {
|
||||||
LoginEncryptionUtils.showLoginWindow(session);
|
LoginEncryptionUtils.showLoginWindow(session);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -81,7 +81,6 @@ import org.geysermc.connector.entity.player.SessionPlayerEntity;
|
||||||
import org.geysermc.connector.entity.player.SkullPlayerEntity;
|
import org.geysermc.connector.entity.player.SkullPlayerEntity;
|
||||||
import org.geysermc.connector.inventory.Inventory;
|
import org.geysermc.connector.inventory.Inventory;
|
||||||
import org.geysermc.connector.inventory.PlayerInventory;
|
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.AuthData;
|
||||||
import org.geysermc.connector.network.session.auth.BedrockClientData;
|
import org.geysermc.connector.network.session.auth.BedrockClientData;
|
||||||
import org.geysermc.connector.network.session.cache.*;
|
import org.geysermc.connector.network.session.cache.*;
|
||||||
|
@ -113,13 +112,21 @@ public class GeyserSession implements CommandSender {
|
||||||
|
|
||||||
private final GeyserConnector connector;
|
private final GeyserConnector connector;
|
||||||
private final UpstreamSession upstream;
|
private final UpstreamSession upstream;
|
||||||
private RemoteServer remoteServer;
|
|
||||||
private Client downstream;
|
private Client downstream;
|
||||||
@Setter
|
@Setter
|
||||||
private AuthData authData;
|
private AuthData authData;
|
||||||
@Setter
|
@Setter
|
||||||
private BedrockClientData clientData;
|
private BedrockClientData clientData;
|
||||||
|
|
||||||
|
/* Setter for GeyserConnect */
|
||||||
|
@Setter
|
||||||
|
private String remoteAddress;
|
||||||
|
@Setter
|
||||||
|
private int remotePort;
|
||||||
|
@Setter
|
||||||
|
private AuthType remoteAuthType;
|
||||||
|
/* Setter for GeyserConnect */
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Setter
|
@Setter
|
||||||
private boolean microsoftAccount;
|
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();
|
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
|
// Set the hardcoded shield ID to the ID we just defined in StartGamePacket
|
||||||
upstream.getSession().getHardcodedBlockingId().set(ItemRegistry.SHIELD.getBedrockId());
|
upstream.getSession().getHardcodedBlockingId().set(ItemRegistry.SHIELD.getBedrockId());
|
||||||
|
@ -485,8 +497,8 @@ public class GeyserSession implements CommandSender {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void login() {
|
public void login() {
|
||||||
if (connector.getAuthType() != AuthType.ONLINE) {
|
if (this.remoteAuthType != AuthType.ONLINE) {
|
||||||
if (connector.getAuthType() == AuthType.OFFLINE) {
|
if (this.remoteAuthType == AuthType.OFFLINE) {
|
||||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.offline"));
|
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.offline"));
|
||||||
} else {
|
} else {
|
||||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.floodgate"));
|
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.
|
* After getting whatever credentials needed, we attempt to join the Java server.
|
||||||
*/
|
*/
|
||||||
private void connectDownstream() {
|
private void connectDownstream() {
|
||||||
boolean floodgate = connector.getAuthType() == AuthType.FLOODGATE;
|
boolean floodgate = this.remoteAuthType == AuthType.FLOODGATE;
|
||||||
final PublicKey publicKey;
|
final PublicKey publicKey;
|
||||||
|
|
||||||
if (floodgate) {
|
if (floodgate) {
|
||||||
|
@ -618,7 +630,8 @@ public class GeyserSession implements CommandSender {
|
||||||
// Start ticking
|
// Start ticking
|
||||||
tickThread = connector.getGeneralThreadPool().scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS);
|
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()) {
|
if (connector.getConfig().getRemote().isUseProxyProtocol()) {
|
||||||
downstream.getSession().setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
|
downstream.getSession().setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
|
||||||
downstream.getSession().setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
|
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()));
|
disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.remote.invalid_account", clientData.getLanguageCode()));
|
||||||
return;
|
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.setUuid(protocol.getProfile().getId());
|
||||||
playerEntity.setUsername(protocol.getProfile().getName());
|
playerEntity.setUsername(protocol.getProfile().getName());
|
||||||
|
|
||||||
|
@ -687,7 +700,7 @@ public class GeyserSession implements CommandSender {
|
||||||
public void disconnected(DisconnectedEvent event) {
|
public void disconnected(DisconnectedEvent event) {
|
||||||
loggingIn = false;
|
loggingIn = false;
|
||||||
loggedIn = 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) {
|
if (event.getCause() != null) {
|
||||||
event.getCause().printStackTrace();
|
event.getCause().printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -705,7 +718,7 @@ public class GeyserSession implements CommandSender {
|
||||||
playerEntity.setUuid(profile.getId());
|
playerEntity.setUuid(profile.getId());
|
||||||
|
|
||||||
// Check if they are not using a linked account
|
// 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);
|
SkinManager.handleBedrockSkin(playerEntity, clientData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,6 +806,13 @@ public class GeyserSession implements CommandSender {
|
||||||
collisionManager.updateScaffoldingFlags();
|
collisionManager.updateScaffoldingFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will be overwritten for GeyserConnect.
|
||||||
|
*/
|
||||||
|
protected void disableSrvResolving() {
|
||||||
|
this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return authData.getName();
|
return authData.getName();
|
||||||
|
|
|
@ -286,7 +286,7 @@ public class SkinManager {
|
||||||
|
|
||||||
String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl();
|
String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl();
|
||||||
String capeUrl = SkinProvider.EMPTY_CAPE.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());
|
GeyserSession session = GeyserConnector.getInstance().getPlayerByUuid(profile.getId());
|
||||||
|
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
|
|
Loading…
Reference in a new issue