3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-06 00:00:47 +01:00

Introduce ServerConnection interface

This will become very useful for plugin messaging support.
Dieser Commit ist enthalten in:
Andrew Steinborn 2018-08-21 21:51:31 -04:00
Ursprung 9c4e43e1b0
Commit 2d0c826ec9
6 geänderte Dateien mit 58 neuen und 43 gelöschten Zeilen

Datei anzeigen

@ -29,7 +29,7 @@ public interface Player extends CommandSource, InboundConnection {
* Returns the server that the player is currently connected to. * 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 * @return an {@link Optional} the server that the player is connected to, which may be empty
*/ */
Optional<ServerInfo> getCurrentServer(); Optional<ServerConnection> getCurrentServer();
/** /**
* Sends a chat message to the player's client. * Sends a chat message to the player's client.

Datei anzeigen

@ -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();
}

Datei anzeigen

@ -11,22 +11,22 @@ import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
public class BackendPlaySessionHandler implements MinecraftSessionHandler { public class BackendPlaySessionHandler implements MinecraftSessionHandler {
private final ServerConnection connection; private final VelocityServerConnection connection;
public BackendPlaySessionHandler(ServerConnection connection) { public BackendPlaySessionHandler(VelocityServerConnection connection) {
this.connection = connection; this.connection = connection;
} }
@Override @Override
public void activated() { public void activated() {
VelocityServer.getServer().getEventManager().fireAndForget(new ServerConnectedEvent(connection.getProxyPlayer(), VelocityServer.getServer().getEventManager().fireAndForget(new ServerConnectedEvent(connection.getPlayer(),
connection.getServerInfo())); connection.getServerInfo()));
} }
@Override @Override
public void handle(MinecraftPacket packet) { public void handle(MinecraftPacket packet) {
//Not handleable packets: Chat, TabCompleteResponse, Respawn, Scoreboard* //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" // Connection was left open accidentally. Close it so as to avoid "You logged in from another location"
// errors. // errors.
connection.getMinecraftConnection().close(); connection.getMinecraftConnection().close();
@ -34,14 +34,14 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
} }
ClientPlaySessionHandler playerHandler = ClientPlaySessionHandler playerHandler =
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler(); (ClientPlaySessionHandler) connection.getPlayer().getConnection().getSessionHandler();
if (packet instanceof KeepAlive) { if (packet instanceof KeepAlive) {
// Forward onto the player // Forward onto the player
playerHandler.setLastPing(((KeepAlive) packet).getRandomId()); playerHandler.setLastPing(((KeepAlive) packet).getRandomId());
connection.getProxyPlayer().getConnection().write(packet); connection.getPlayer().getConnection().write(packet);
} else if (packet instanceof Disconnect) { } else if (packet instanceof Disconnect) {
Disconnect original = (Disconnect) packet; Disconnect original = (Disconnect) packet;
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), original); connection.getPlayer().handleConnectionException(connection.getServerInfo(), original);
} else if (packet instanceof JoinGame) { } else if (packet instanceof JoinGame) {
playerHandler.handleBackendJoinGame((JoinGame) packet); playerHandler.handleBackendJoinGame((JoinGame) packet);
} else if (packet instanceof BossBar) { } else if (packet instanceof BossBar) {
@ -54,7 +54,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
playerHandler.getServerBossBars().remove(bossBar.getUuid()); playerHandler.getServerBossBars().remove(bossBar.getUuid());
break; break;
} }
connection.getProxyPlayer().getConnection().write(packet); connection.getPlayer().getConnection().write(packet);
} else if (packet instanceof PluginMessage) { } else if (packet instanceof PluginMessage) {
PluginMessage pm = (PluginMessage) packet; PluginMessage pm = (PluginMessage) packet;
if (!canForwardPluginMessage(pm)) { if (!canForwardPluginMessage(pm)) {
@ -62,20 +62,20 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
} }
if (PluginMessageUtil.isMCBrand(pm)) { if (PluginMessageUtil.isMCBrand(pm)) {
connection.getProxyPlayer().getConnection().write(PluginMessageUtil.rewriteMCBrand(pm)); connection.getPlayer().getConnection().write(PluginMessageUtil.rewriteMCBrand(pm));
return; return;
} }
connection.getProxyPlayer().getConnection().write(pm); connection.getPlayer().getConnection().write(pm);
} else { } else {
// Just forward the packet on. We don't have anything to handle at this time. // 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 @Override
public void handleUnknown(ByteBuf buf) { 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" // Connection was left open accidentally. Close it so as to avoid "You logged in from another location"
// errors. // errors.
connection.getMinecraftConnection().close(); connection.getMinecraftConnection().close();
@ -83,19 +83,19 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
} }
ClientPlaySessionHandler playerHandler = ClientPlaySessionHandler playerHandler =
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler(); (ClientPlaySessionHandler) connection.getPlayer().getConnection().getSessionHandler();
ByteBuf remapped = playerHandler.getIdRemapper().remap(buf, ProtocolConstants.Direction.CLIENTBOUND); ByteBuf remapped = playerHandler.getIdRemapper().remap(buf, ProtocolConstants.Direction.CLIENTBOUND);
connection.getProxyPlayer().getConnection().write(remapped); connection.getPlayer().getConnection().write(remapped);
} }
@Override @Override
public void exception(Throwable throwable) { public void exception(Throwable throwable) {
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable); connection.getPlayer().handleConnectionException(connection.getServerInfo(), throwable);
} }
private boolean canForwardPluginMessage(PluginMessage message) { private boolean canForwardPluginMessage(PluginMessage message) {
ClientPlaySessionHandler playerHandler = ClientPlaySessionHandler playerHandler =
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler(); (ClientPlaySessionHandler) connection.getPlayer().getConnection().getSessionHandler();
if (connection.getMinecraftConnection().getProtocolVersion() <= ProtocolConstants.MINECRAFT_1_12_2) { if (connection.getMinecraftConnection().getProtocolVersion() <= ProtocolConstants.MINECRAFT_1_12_2) {
return message.getChannel().startsWith("MC|") || return message.getChannel().startsWith("MC|") ||
playerHandler.getClientPluginMsgChannels().contains(message.getChannel()); playerHandler.getClientPluginMsgChannels().contains(message.getChannel());

Datei anzeigen

@ -25,10 +25,10 @@ import java.security.NoSuchAlgorithmException;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class LoginSessionHandler implements MinecraftSessionHandler { public class LoginSessionHandler implements MinecraftSessionHandler {
private final ServerConnection connection; private final VelocityServerConnection connection;
private boolean informationForwarded; private boolean informationForwarded;
public LoginSessionHandler(ServerConnection connection) { public LoginSessionHandler(VelocityServerConnection connection) {
this.connection = connection; this.connection = connection;
} }
@ -45,8 +45,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
response.setSuccess(true); response.setSuccess(true);
response.setId(message.getId()); response.setId(message.getId());
response.setData(createForwardingData(configuration.getForwardingSecret(), response.setData(createForwardingData(configuration.getForwardingSecret(),
connection.getProxyPlayer().getRemoteAddress().getHostString(), connection.getPlayer().getRemoteAddress().getHostString(),
connection.getProxyPlayer().getProfile())); connection.getPlayer().getProfile()));
connection.getMinecraftConnection().write(response); connection.getMinecraftConnection().write(response);
informationForwarded = true; informationForwarded = true;
} else { } else {
@ -76,10 +76,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
// The player has been logged on to the backend server. // The player has been logged on to the backend server.
connection.getMinecraftConnection().setState(StateRegistry.PLAY); connection.getMinecraftConnection().setState(StateRegistry.PLAY);
ServerConnection existingConnection = connection.getProxyPlayer().getConnectedServer(); VelocityServerConnection existingConnection = connection.getPlayer().getConnectedServer();
if (existingConnection == null) { if (existingConnection == null) {
// Strap on the play session handler // Strap on the play session handler
connection.getProxyPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(connection.getProxyPlayer())); connection.getPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(connection.getPlayer()));
} else { } else {
// The previous server connection should become obsolete. // The previous server connection should become obsolete.
existingConnection.disconnect(); existingConnection.disconnect();
@ -87,14 +87,14 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
doNotify(ConnectionRequestResults.SUCCESSFUL); doNotify(ConnectionRequestResults.SUCCESSFUL);
connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection)); connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection));
connection.getProxyPlayer().setConnectedServer(connection); connection.getPlayer().setConnectedServer(connection);
} }
} }
@Override @Override
public void exception(Throwable throwable) { public void exception(Throwable throwable) {
CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel() CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel()
.attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null); .attr(VelocityServerConnection.CONNECTION_NOTIFIER).getAndSet(null);
if (future != null) { if (future != null) {
future.completeExceptionally(throwable); future.completeExceptionally(throwable);
} }
@ -102,7 +102,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
private void doNotify(ConnectionRequestBuilder.Result result) { private void doNotify(ConnectionRequestBuilder.Result result) {
CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel() CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel()
.attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null); .attr(VelocityServerConnection.CONNECTION_NOTIFIER).getAndSet(null);
if (future != null) { if (future != null) {
future.complete(result); future.complete(result);
} }

Datei anzeigen

@ -1,9 +1,10 @@
package com.velocitypowered.proxy.connection.backend; package com.velocitypowered.proxy.connection.backend;
import com.velocitypowered.api.proxy.ConnectionRequestBuilder; 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.config.PlayerInfoForwarding;
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation; import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
import com.velocitypowered.proxy.protocol.ProtocolConstants; import com.velocitypowered.proxy.protocol.ProtocolConstants;
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder; import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder; 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.READ_TIMEOUT;
import static com.velocitypowered.network.Connections.SERVER_READ_TIMEOUT_SECONDS; import static com.velocitypowered.network.Connections.SERVER_READ_TIMEOUT_SECONDS;
public class ServerConnection implements MinecraftConnectionAssociation { public class VelocityServerConnection implements MinecraftConnectionAssociation, ServerConnection {
static final AttributeKey<CompletableFuture<ConnectionRequestBuilder.Result>> CONNECTION_NOTIFIER = static final AttributeKey<CompletableFuture<ConnectionRequestBuilder.Result>> CONNECTION_NOTIFIER =
AttributeKey.newInstance("connection-notification-result"); AttributeKey.newInstance("connection-notification-result");
@ -40,7 +41,7 @@ public class ServerConnection implements MinecraftConnectionAssociation {
private final VelocityServer server; private final VelocityServer server;
private MinecraftConnection minecraftConnection; private MinecraftConnection minecraftConnection;
public ServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) { public VelocityServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) {
this.serverInfo = target; this.serverInfo = target;
this.proxyPlayer = proxyPlayer; this.proxyPlayer = proxyPlayer;
this.server = server; this.server = server;
@ -62,7 +63,7 @@ public class ServerConnection implements MinecraftConnectionAssociation {
ch.attr(CONNECTION_NOTIFIER).set(result); ch.attr(CONNECTION_NOTIFIER).set(result);
MinecraftConnection connection = new MinecraftConnection(ch); MinecraftConnection connection = new MinecraftConnection(ch);
connection.setState(StateRegistry.HANDSHAKE); connection.setState(StateRegistry.HANDSHAKE);
connection.setAssociation(ServerConnection.this); connection.setAssociation(VelocityServerConnection.this);
ch.pipeline().addLast(HANDLER, connection); ch.pipeline().addLast(HANDLER, connection);
} }
}) })
@ -74,7 +75,7 @@ public class ServerConnection implements MinecraftConnectionAssociation {
minecraftConnection = future.channel().pipeline().get(MinecraftConnection.class); minecraftConnection = future.channel().pipeline().get(MinecraftConnection.class);
// Kick off the connection process // Kick off the connection process
minecraftConnection.setSessionHandler(new LoginSessionHandler(ServerConnection.this)); minecraftConnection.setSessionHandler(new LoginSessionHandler(VelocityServerConnection.this));
startHandshake(); startHandshake();
} else { } else {
result.completeExceptionally(future.cause()); result.completeExceptionally(future.cause());
@ -118,10 +119,6 @@ public class ServerConnection implements MinecraftConnectionAssociation {
minecraftConnection.write(login); minecraftConnection.write(login);
} }
public ConnectedPlayer getProxyPlayer() {
return proxyPlayer;
}
public MinecraftConnection getMinecraftConnection() { public MinecraftConnection getMinecraftConnection() {
return minecraftConnection; return minecraftConnection;
} }
@ -130,6 +127,11 @@ public class ServerConnection implements MinecraftConnectionAssociation {
return serverInfo; return serverInfo;
} }
@Override
public ConnectedPlayer getPlayer() {
return proxyPlayer;
}
public void disconnect() { public void disconnect() {
minecraftConnection.close(); minecraftConnection.close();
minecraftConnection = null; minecraftConnection = null;

Datei anzeigen

@ -6,6 +6,7 @@ import com.velocitypowered.api.event.player.ServerPreConnectEvent;
import com.velocitypowered.api.permission.PermissionFunction; import com.velocitypowered.api.permission.PermissionFunction;
import com.velocitypowered.api.permission.PermissionProvider; import com.velocitypowered.api.permission.PermissionProvider;
import com.velocitypowered.api.proxy.ConnectionRequestBuilder; import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.util.MessagePosition; import com.velocitypowered.api.util.MessagePosition;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.VelocityServer; 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.api.util.GameProfile;
import com.velocitypowered.proxy.protocol.packet.Chat; import com.velocitypowered.proxy.protocol.packet.Chat;
import com.velocitypowered.proxy.connection.MinecraftConnection; 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.protocol.packet.ClientSettings;
import com.velocitypowered.proxy.util.ThrowableUtils; import com.velocitypowered.proxy.util.ThrowableUtils;
import com.velocitypowered.api.server.ServerInfo; import com.velocitypowered.api.server.ServerInfo;
@ -48,9 +49,9 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
private final InetSocketAddress virtualHost; private final InetSocketAddress virtualHost;
private PermissionFunction permissionFunction = null; private PermissionFunction permissionFunction = null;
private int tryIndex = 0; private int tryIndex = 0;
private ServerConnection connectedServer; private VelocityServerConnection connectedServer;
private ClientSettings clientSettings; private ClientSettings clientSettings;
private ServerConnection connectionInFlight; private VelocityServerConnection connectionInFlight;
public ConnectedPlayer(GameProfile profile, MinecraftConnection connection, InetSocketAddress virtualHost) { public ConnectedPlayer(GameProfile profile, MinecraftConnection connection, InetSocketAddress virtualHost) {
this.profile = profile; this.profile = profile;
@ -69,8 +70,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
} }
@Override @Override
public Optional<ServerInfo> getCurrentServer() { public Optional<ServerConnection> getCurrentServer() {
return connectedServer != null ? Optional.of(connectedServer.getServerInfo()) : Optional.empty(); return Optional.ofNullable(connectedServer);
} }
public GameProfile getProfile() { public GameProfile getProfile() {
@ -133,7 +134,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
return new ConnectionRequestBuilderImpl(info); return new ConnectionRequestBuilderImpl(info);
} }
public ServerConnection getConnectedServer() { public VelocityServerConnection getConnectedServer() {
return connectedServer; 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())) { if (this.connectedServer != null && !serverConnection.getServerInfo().equals(connectedServer.getServerInfo())) {
this.tryIndex = 0; this.tryIndex = 0;
} }