Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-16 21:10:30 +01:00
Fix up player info forwarding.
Dieser Commit ist enthalten in:
Ursprung
95bd152fee
Commit
8068f72729
@ -15,7 +15,6 @@ import com.velocitypowered.proxy.protocol.packet.*;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import net.kyori.text.TextComponent;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
@ -23,27 +22,16 @@ import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
private final ServerConnection connection;
|
||||
private ScheduledFuture<?> forwardingCheckTask;
|
||||
private boolean informationForwarded;
|
||||
|
||||
public LoginSessionHandler(ServerConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activated() {
|
||||
if (VelocityServer.getServer().getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN) {
|
||||
forwardingCheckTask = connection.getMinecraftConnection().getChannel().eventLoop().schedule(() -> {
|
||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(),
|
||||
TextComponent.of("Your server did not send the forwarding request in time. Is it set up correctly?"));
|
||||
}, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MinecraftPacket packet) {
|
||||
if (packet instanceof EncryptionRequest) {
|
||||
@ -60,11 +48,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
connection.getProxyPlayer().getRemoteAddress().getHostString(),
|
||||
connection.getProxyPlayer().getProfile()));
|
||||
connection.getMinecraftConnection().write(response);
|
||||
cancelForwardingCheck();
|
||||
|
||||
ServerLogin login = new ServerLogin();
|
||||
login.setUsername(connection.getProxyPlayer().getUsername());
|
||||
connection.getMinecraftConnection().write(login);
|
||||
informationForwarded = true;
|
||||
} else {
|
||||
// Don't understand
|
||||
LoginPluginResponse response = new LoginPluginResponse();
|
||||
@ -75,16 +59,21 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
} else if (packet instanceof Disconnect) {
|
||||
Disconnect disconnect = (Disconnect) packet;
|
||||
connection.disconnect();
|
||||
|
||||
// Do we have an outstanding notification? If so, fulfill it.
|
||||
doNotify(ConnectionRequestResults.forDisconnect(disconnect));
|
||||
|
||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), disconnect);
|
||||
connection.disconnect();
|
||||
} else if (packet instanceof SetCompression) {
|
||||
SetCompression sc = (SetCompression) packet;
|
||||
connection.getMinecraftConnection().setCompressionThreshold(sc.getThreshold());
|
||||
} else if (packet instanceof ServerLoginSuccess) {
|
||||
if (VelocityServer.getServer().getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN &&
|
||||
!informationForwarded) {
|
||||
doNotify(ConnectionRequestResults.forDisconnect(
|
||||
TextComponent.of("Your server did not send a forwarding request to the proxy. Is it set up correctly?")));
|
||||
connection.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
// The player has been logged on to the backend server.
|
||||
connection.getMinecraftConnection().setState(StateRegistry.PLAY);
|
||||
ServerConnection existingConnection = connection.getProxyPlayer().getConnectedServer();
|
||||
@ -96,37 +85,26 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
existingConnection.disconnect();
|
||||
}
|
||||
|
||||
// Do we have an outstanding notification? If so, fulfill it.
|
||||
doNotify(ConnectionRequestResults.SUCCESSFUL);
|
||||
|
||||
connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection));
|
||||
connection.getProxyPlayer().setConnectedServer(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivated() {
|
||||
cancelForwardingCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exception(Throwable throwable) {
|
||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
||||
}
|
||||
|
||||
private void doNotify(ConnectionRequestBuilder.Result result) {
|
||||
ChannelPipeline pipeline = connection.getMinecraftConnection().getChannel().pipeline();
|
||||
ServerConnection.ConnectionNotifier n = pipeline.get(ServerConnection.ConnectionNotifier.class);
|
||||
if (n != null) {
|
||||
n.getResult().complete(result);
|
||||
pipeline.remove(ServerConnection.ConnectionNotifier.class);
|
||||
CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel()
|
||||
.attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null);
|
||||
if (future != null) {
|
||||
future.completeExceptionally(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelForwardingCheck() {
|
||||
if (forwardingCheckTask != null) {
|
||||
forwardingCheckTask.cancel(false);
|
||||
forwardingCheckTask = null;
|
||||
private void doNotify(ConnectionRequestBuilder.Result result) {
|
||||
CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel()
|
||||
.attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null);
|
||||
if (future != null) {
|
||||
future.complete(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -31,7 +32,8 @@ import static com.velocitypowered.network.Connections.READ_TIMEOUT;
|
||||
import static com.velocitypowered.network.Connections.SERVER_READ_TIMEOUT_SECONDS;
|
||||
|
||||
public class ServerConnection implements MinecraftConnectionAssociation {
|
||||
static final String CONNECTION_NOTIFIER = "connection-notifier";
|
||||
static final AttributeKey<CompletableFuture<ConnectionRequestBuilder.Result>> CONNECTION_NOTIFIER =
|
||||
AttributeKey.newInstance("connection-notification-result");
|
||||
|
||||
private final ServerInfo serverInfo;
|
||||
private final ConnectedPlayer proxyPlayer;
|
||||
@ -55,9 +57,9 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolConstants.Direction.CLIENTBOUND))
|
||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND))
|
||||
.addLast(CONNECTION_NOTIFIER, new ConnectionNotifier(result));
|
||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND));
|
||||
|
||||
ch.attr(CONNECTION_NOTIFIER).set(result);
|
||||
MinecraftConnection connection = new MinecraftConnection(ch);
|
||||
connection.setState(StateRegistry.HANDSHAKE);
|
||||
connection.setAssociation(ServerConnection.this);
|
||||
@ -93,7 +95,7 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
||||
}
|
||||
|
||||
private void startHandshake() {
|
||||
PlayerInfoForwarding forwardingMode = VelocityServer.getServer().getConfiguration().getPlayerInfoForwardingMode();
|
||||
PlayerInfoForwarding forwardingMode = VelocityServer.getServer().getConfiguration().getPlayerInfoForwardingMode();
|
||||
|
||||
// Initiate a handshake.
|
||||
Handshake handshake = new Handshake();
|
||||
@ -111,12 +113,9 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
||||
minecraftConnection.setProtocolVersion(protocolVersion);
|
||||
minecraftConnection.setState(StateRegistry.LOGIN);
|
||||
|
||||
// Send the server login packet for <=1.12.2 and for 1.13+ servers not using "modern" forwarding.
|
||||
if (protocolVersion <= ProtocolConstants.MINECRAFT_1_12_2 || forwardingMode != PlayerInfoForwarding.MODERN) {
|
||||
ServerLogin login = new ServerLogin();
|
||||
login.setUsername(proxyPlayer.getUsername());
|
||||
minecraftConnection.write(login);
|
||||
}
|
||||
ServerLogin login = new ServerLogin();
|
||||
login.setUsername(proxyPlayer.getUsername());
|
||||
minecraftConnection.write(login);
|
||||
}
|
||||
|
||||
public ConnectedPlayer getProxyPlayer() {
|
||||
@ -140,25 +139,4 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
||||
public String toString() {
|
||||
return "[server connection] " + proxyPlayer.getProfile().getName() + " -> " + serverInfo.getName();
|
||||
}
|
||||
|
||||
static class ConnectionNotifier extends ChannelInboundHandlerAdapter {
|
||||
private final CompletableFuture<ConnectionRequestBuilder.Result> result;
|
||||
|
||||
public ConnectionNotifier(CompletableFuture<ConnectionRequestBuilder.Result> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public CompletableFuture<ConnectionRequestBuilder.Result> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void onComplete() {
|
||||
result.complete(ConnectionRequestResults.SUCCESSFUL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
result.completeExceptionally(cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
@Override
|
||||
public void fireAndForget() {
|
||||
connect()
|
||||
.whenComplete((status, throwable) -> {
|
||||
.whenCompleteAsync((status, throwable) -> {
|
||||
if (throwable != null) {
|
||||
handleConnectionException(info, throwable);
|
||||
return;
|
||||
@ -267,7 +267,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
handleConnectionException(info, Disconnect.create(status.getReason().orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR)));
|
||||
break;
|
||||
}
|
||||
});
|
||||
}, connection.getChannel().eventLoop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.velocitypowered.proxy.connection.util;
|
||||
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
||||
import com.velocitypowered.proxy.protocol.packet.Disconnect;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.serializer.ComponentSerializers;
|
||||
|
||||
import java.util.Optional;
|
||||
@ -42,4 +43,18 @@ public class ConnectionRequestResults {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ConnectionRequestBuilder.Result forDisconnect(TextComponent component) {
|
||||
return new ConnectionRequestBuilder.Result() {
|
||||
@Override
|
||||
public ConnectionRequestBuilder.Status getStatus() {
|
||||
return ConnectionRequestBuilder.Status.SERVER_DISCONNECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> getReason() {
|
||||
return Optional.of(component);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren