From 2d0c826ec9c8f523757cb48f358ae0e55fe68182 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Tue, 21 Aug 2018 21:51:31 -0400 Subject: [PATCH] Introduce ServerConnection interface This will become very useful for plugin messaging support. --- .../com/velocitypowered/api/proxy/Player.java | 2 +- .../api/proxy/ServerConnection.java | 12 +++++++ .../backend/BackendPlaySessionHandler.java | 32 +++++++++---------- .../backend/LoginSessionHandler.java | 18 +++++------ ...ion.java => VelocityServerConnection.java} | 20 ++++++------ .../connection/client/ConnectedPlayer.java | 17 +++++----- 6 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 api/src/main/java/com/velocitypowered/api/proxy/ServerConnection.java rename proxy/src/main/java/com/velocitypowered/proxy/connection/backend/{ServerConnection.java => VelocityServerConnection.java} (92%) diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index 86978ab57..08bf0c440 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -29,7 +29,7 @@ public interface Player extends CommandSource, InboundConnection { * Returns the server that the player is currently connected to. * @return an {@link Optional} the server that the player is connected to, which may be empty */ - Optional getCurrentServer(); + Optional getCurrentServer(); /** * Sends a chat message to the player's client. diff --git a/api/src/main/java/com/velocitypowered/api/proxy/ServerConnection.java b/api/src/main/java/com/velocitypowered/api/proxy/ServerConnection.java new file mode 100644 index 000000000..8753019d4 --- /dev/null +++ b/api/src/main/java/com/velocitypowered/api/proxy/ServerConnection.java @@ -0,0 +1,12 @@ +package com.velocitypowered.api.proxy; + +import com.velocitypowered.api.server.ServerInfo; + +/** + * Represents a connection to a backend server from the proxy for a client. + */ +public interface ServerConnection { + ServerInfo getServerInfo(); + + Player getPlayer(); +} diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java index 5d3797fec..3bf35fe17 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java @@ -11,22 +11,22 @@ import com.velocitypowered.proxy.protocol.util.PluginMessageUtil; import io.netty.buffer.ByteBuf; public class BackendPlaySessionHandler implements MinecraftSessionHandler { - private final ServerConnection connection; + private final VelocityServerConnection connection; - public BackendPlaySessionHandler(ServerConnection connection) { + public BackendPlaySessionHandler(VelocityServerConnection connection) { this.connection = connection; } @Override public void activated() { - VelocityServer.getServer().getEventManager().fireAndForget(new ServerConnectedEvent(connection.getProxyPlayer(), + VelocityServer.getServer().getEventManager().fireAndForget(new ServerConnectedEvent(connection.getPlayer(), connection.getServerInfo())); } @Override public void handle(MinecraftPacket packet) { //Not handleable packets: Chat, TabCompleteResponse, Respawn, Scoreboard* - if (!connection.getProxyPlayer().isActive()) { + if (!connection.getPlayer().isActive()) { // Connection was left open accidentally. Close it so as to avoid "You logged in from another location" // errors. connection.getMinecraftConnection().close(); @@ -34,14 +34,14 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { } ClientPlaySessionHandler playerHandler = - (ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler(); + (ClientPlaySessionHandler) connection.getPlayer().getConnection().getSessionHandler(); if (packet instanceof KeepAlive) { // Forward onto the player playerHandler.setLastPing(((KeepAlive) packet).getRandomId()); - connection.getProxyPlayer().getConnection().write(packet); + connection.getPlayer().getConnection().write(packet); } else if (packet instanceof Disconnect) { Disconnect original = (Disconnect) packet; - connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), original); + connection.getPlayer().handleConnectionException(connection.getServerInfo(), original); } else if (packet instanceof JoinGame) { playerHandler.handleBackendJoinGame((JoinGame) packet); } else if (packet instanceof BossBar) { @@ -54,7 +54,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { playerHandler.getServerBossBars().remove(bossBar.getUuid()); break; } - connection.getProxyPlayer().getConnection().write(packet); + connection.getPlayer().getConnection().write(packet); } else if (packet instanceof PluginMessage) { PluginMessage pm = (PluginMessage) packet; if (!canForwardPluginMessage(pm)) { @@ -62,20 +62,20 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { } if (PluginMessageUtil.isMCBrand(pm)) { - connection.getProxyPlayer().getConnection().write(PluginMessageUtil.rewriteMCBrand(pm)); + connection.getPlayer().getConnection().write(PluginMessageUtil.rewriteMCBrand(pm)); return; } - connection.getProxyPlayer().getConnection().write(pm); + connection.getPlayer().getConnection().write(pm); } else { // Just forward the packet on. We don't have anything to handle at this time. - connection.getProxyPlayer().getConnection().write(packet); + connection.getPlayer().getConnection().write(packet); } } @Override public void handleUnknown(ByteBuf buf) { - if (!connection.getProxyPlayer().isActive()) { + if (!connection.getPlayer().isActive()) { // Connection was left open accidentally. Close it so as to avoid "You logged in from another location" // errors. connection.getMinecraftConnection().close(); @@ -83,19 +83,19 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { } ClientPlaySessionHandler playerHandler = - (ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler(); + (ClientPlaySessionHandler) connection.getPlayer().getConnection().getSessionHandler(); ByteBuf remapped = playerHandler.getIdRemapper().remap(buf, ProtocolConstants.Direction.CLIENTBOUND); - connection.getProxyPlayer().getConnection().write(remapped); + connection.getPlayer().getConnection().write(remapped); } @Override public void exception(Throwable throwable) { - connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable); + connection.getPlayer().handleConnectionException(connection.getServerInfo(), throwable); } private boolean canForwardPluginMessage(PluginMessage message) { ClientPlaySessionHandler playerHandler = - (ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler(); + (ClientPlaySessionHandler) connection.getPlayer().getConnection().getSessionHandler(); if (connection.getMinecraftConnection().getProtocolVersion() <= ProtocolConstants.MINECRAFT_1_12_2) { return message.getChannel().startsWith("MC|") || playerHandler.getClientPluginMsgChannels().contains(message.getChannel()); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java index 4cd1cd9c2..cd0513582 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java @@ -25,10 +25,10 @@ import java.security.NoSuchAlgorithmException; import java.util.concurrent.CompletableFuture; public class LoginSessionHandler implements MinecraftSessionHandler { - private final ServerConnection connection; + private final VelocityServerConnection connection; private boolean informationForwarded; - public LoginSessionHandler(ServerConnection connection) { + public LoginSessionHandler(VelocityServerConnection connection) { this.connection = connection; } @@ -45,8 +45,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler { response.setSuccess(true); response.setId(message.getId()); response.setData(createForwardingData(configuration.getForwardingSecret(), - connection.getProxyPlayer().getRemoteAddress().getHostString(), - connection.getProxyPlayer().getProfile())); + connection.getPlayer().getRemoteAddress().getHostString(), + connection.getPlayer().getProfile())); connection.getMinecraftConnection().write(response); informationForwarded = true; } else { @@ -76,10 +76,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler { // The player has been logged on to the backend server. connection.getMinecraftConnection().setState(StateRegistry.PLAY); - ServerConnection existingConnection = connection.getProxyPlayer().getConnectedServer(); + VelocityServerConnection existingConnection = connection.getPlayer().getConnectedServer(); if (existingConnection == null) { // Strap on the play session handler - connection.getProxyPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(connection.getProxyPlayer())); + connection.getPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(connection.getPlayer())); } else { // The previous server connection should become obsolete. existingConnection.disconnect(); @@ -87,14 +87,14 @@ public class LoginSessionHandler implements MinecraftSessionHandler { doNotify(ConnectionRequestResults.SUCCESSFUL); connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection)); - connection.getProxyPlayer().setConnectedServer(connection); + connection.getPlayer().setConnectedServer(connection); } } @Override public void exception(Throwable throwable) { CompletableFuture future = connection.getMinecraftConnection().getChannel() - .attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null); + .attr(VelocityServerConnection.CONNECTION_NOTIFIER).getAndSet(null); if (future != null) { future.completeExceptionally(throwable); } @@ -102,7 +102,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { private void doNotify(ConnectionRequestBuilder.Result result) { CompletableFuture future = connection.getMinecraftConnection().getChannel() - .attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null); + .attr(VelocityServerConnection.CONNECTION_NOTIFIER).getAndSet(null); if (future != null) { future.complete(result); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/ServerConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java similarity index 92% rename from proxy/src/main/java/com/velocitypowered/proxy/connection/backend/ServerConnection.java rename to proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java index 98e4cd72d..e901ead3a 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/ServerConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java @@ -1,9 +1,10 @@ package com.velocitypowered.proxy.connection.backend; import com.velocitypowered.api.proxy.ConnectionRequestBuilder; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.proxy.config.PlayerInfoForwarding; import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation; -import com.velocitypowered.proxy.connection.util.ConnectionRequestResults; import com.velocitypowered.proxy.protocol.ProtocolConstants; import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder; import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder; @@ -31,7 +32,7 @@ import static com.velocitypowered.network.Connections.MINECRAFT_ENCODER; import static com.velocitypowered.network.Connections.READ_TIMEOUT; import static com.velocitypowered.network.Connections.SERVER_READ_TIMEOUT_SECONDS; -public class ServerConnection implements MinecraftConnectionAssociation { +public class VelocityServerConnection implements MinecraftConnectionAssociation, ServerConnection { static final AttributeKey> CONNECTION_NOTIFIER = AttributeKey.newInstance("connection-notification-result"); @@ -40,7 +41,7 @@ public class ServerConnection implements MinecraftConnectionAssociation { private final VelocityServer server; private MinecraftConnection minecraftConnection; - public ServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) { + public VelocityServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) { this.serverInfo = target; this.proxyPlayer = proxyPlayer; this.server = server; @@ -62,7 +63,7 @@ public class ServerConnection implements MinecraftConnectionAssociation { ch.attr(CONNECTION_NOTIFIER).set(result); MinecraftConnection connection = new MinecraftConnection(ch); connection.setState(StateRegistry.HANDSHAKE); - connection.setAssociation(ServerConnection.this); + connection.setAssociation(VelocityServerConnection.this); ch.pipeline().addLast(HANDLER, connection); } }) @@ -74,7 +75,7 @@ public class ServerConnection implements MinecraftConnectionAssociation { minecraftConnection = future.channel().pipeline().get(MinecraftConnection.class); // Kick off the connection process - minecraftConnection.setSessionHandler(new LoginSessionHandler(ServerConnection.this)); + minecraftConnection.setSessionHandler(new LoginSessionHandler(VelocityServerConnection.this)); startHandshake(); } else { result.completeExceptionally(future.cause()); @@ -118,10 +119,6 @@ public class ServerConnection implements MinecraftConnectionAssociation { minecraftConnection.write(login); } - public ConnectedPlayer getProxyPlayer() { - return proxyPlayer; - } - public MinecraftConnection getMinecraftConnection() { return minecraftConnection; } @@ -130,6 +127,11 @@ public class ServerConnection implements MinecraftConnectionAssociation { return serverInfo; } + @Override + public ConnectedPlayer getPlayer() { + return proxyPlayer; + } + public void disconnect() { minecraftConnection.close(); minecraftConnection = null; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index ad1d3583a..4c47e4565 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -6,6 +6,7 @@ import com.velocitypowered.api.event.player.ServerPreConnectEvent; import com.velocitypowered.api.permission.PermissionFunction; import com.velocitypowered.api.permission.PermissionProvider; import com.velocitypowered.api.proxy.ConnectionRequestBuilder; +import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.util.MessagePosition; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.proxy.VelocityServer; @@ -15,7 +16,7 @@ import com.velocitypowered.proxy.connection.util.ConnectionRequestResults; import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.proxy.protocol.packet.Chat; import com.velocitypowered.proxy.connection.MinecraftConnection; -import com.velocitypowered.proxy.connection.backend.ServerConnection; +import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.protocol.packet.ClientSettings; import com.velocitypowered.proxy.util.ThrowableUtils; import com.velocitypowered.api.server.ServerInfo; @@ -48,9 +49,9 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { private final InetSocketAddress virtualHost; private PermissionFunction permissionFunction = null; private int tryIndex = 0; - private ServerConnection connectedServer; + private VelocityServerConnection connectedServer; private ClientSettings clientSettings; - private ServerConnection connectionInFlight; + private VelocityServerConnection connectionInFlight; public ConnectedPlayer(GameProfile profile, MinecraftConnection connection, InetSocketAddress virtualHost) { this.profile = profile; @@ -69,8 +70,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { } @Override - public Optional getCurrentServer() { - return connectedServer != null ? Optional.of(connectedServer.getServerInfo()) : Optional.empty(); + public Optional getCurrentServer() { + return Optional.ofNullable(connectedServer); } public GameProfile getProfile() { @@ -133,7 +134,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { return new ConnectionRequestBuilderImpl(info); } - public ServerConnection getConnectedServer() { + public VelocityServerConnection getConnectedServer() { return connectedServer; } @@ -222,11 +223,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { ); } - return new ServerConnection(newEvent.getResult().getInfo().get(), this, VelocityServer.getServer()).connect(); + return new VelocityServerConnection(newEvent.getResult().getInfo().get(), this, VelocityServer.getServer()).connect(); }); } - public void setConnectedServer(ServerConnection serverConnection) { + public void setConnectedServer(VelocityServerConnection serverConnection) { if (this.connectedServer != null && !serverConnection.getServerInfo().equals(connectedServer.getServerInfo())) { this.tryIndex = 0; }