Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-25 07:40:13 +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 com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelPipeline;
|
|
||||||
import net.kyori.text.TextComponent;
|
import net.kyori.text.TextComponent;
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
@ -23,27 +22,16 @@ import javax.crypto.SecretKey;
|
|||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class LoginSessionHandler implements MinecraftSessionHandler {
|
public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||||
private final ServerConnection connection;
|
private final ServerConnection connection;
|
||||||
private ScheduledFuture<?> forwardingCheckTask;
|
private boolean informationForwarded;
|
||||||
|
|
||||||
public LoginSessionHandler(ServerConnection connection) {
|
public LoginSessionHandler(ServerConnection connection) {
|
||||||
this.connection = 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
|
@Override
|
||||||
public void handle(MinecraftPacket packet) {
|
public void handle(MinecraftPacket packet) {
|
||||||
if (packet instanceof EncryptionRequest) {
|
if (packet instanceof EncryptionRequest) {
|
||||||
@ -60,11 +48,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.getProxyPlayer().getRemoteAddress().getHostString(),
|
connection.getProxyPlayer().getRemoteAddress().getHostString(),
|
||||||
connection.getProxyPlayer().getProfile()));
|
connection.getProxyPlayer().getProfile()));
|
||||||
connection.getMinecraftConnection().write(response);
|
connection.getMinecraftConnection().write(response);
|
||||||
cancelForwardingCheck();
|
informationForwarded = true;
|
||||||
|
|
||||||
ServerLogin login = new ServerLogin();
|
|
||||||
login.setUsername(connection.getProxyPlayer().getUsername());
|
|
||||||
connection.getMinecraftConnection().write(login);
|
|
||||||
} else {
|
} else {
|
||||||
// Don't understand
|
// Don't understand
|
||||||
LoginPluginResponse response = new LoginPluginResponse();
|
LoginPluginResponse response = new LoginPluginResponse();
|
||||||
@ -75,16 +59,21 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
} else if (packet instanceof Disconnect) {
|
} else if (packet instanceof Disconnect) {
|
||||||
Disconnect disconnect = (Disconnect) packet;
|
Disconnect disconnect = (Disconnect) packet;
|
||||||
connection.disconnect();
|
|
||||||
|
|
||||||
// Do we have an outstanding notification? If so, fulfill it.
|
// Do we have an outstanding notification? If so, fulfill it.
|
||||||
doNotify(ConnectionRequestResults.forDisconnect(disconnect));
|
doNotify(ConnectionRequestResults.forDisconnect(disconnect));
|
||||||
|
connection.disconnect();
|
||||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), disconnect);
|
|
||||||
} else if (packet instanceof SetCompression) {
|
} else if (packet instanceof SetCompression) {
|
||||||
SetCompression sc = (SetCompression) packet;
|
SetCompression sc = (SetCompression) packet;
|
||||||
connection.getMinecraftConnection().setCompressionThreshold(sc.getThreshold());
|
connection.getMinecraftConnection().setCompressionThreshold(sc.getThreshold());
|
||||||
} else if (packet instanceof ServerLoginSuccess) {
|
} 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.
|
// 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();
|
ServerConnection existingConnection = connection.getProxyPlayer().getConnectedServer();
|
||||||
@ -96,37 +85,26 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
existingConnection.disconnect();
|
existingConnection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have an outstanding notification? If so, fulfill it.
|
|
||||||
doNotify(ConnectionRequestResults.SUCCESSFUL);
|
doNotify(ConnectionRequestResults.SUCCESSFUL);
|
||||||
|
|
||||||
connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection));
|
connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection));
|
||||||
connection.getProxyPlayer().setConnectedServer(connection);
|
connection.getProxyPlayer().setConnectedServer(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deactivated() {
|
|
||||||
cancelForwardingCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exception(Throwable throwable) {
|
public void exception(Throwable throwable) {
|
||||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel()
|
||||||
|
.attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null);
|
||||||
|
if (future != null) {
|
||||||
|
future.completeExceptionally(throwable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doNotify(ConnectionRequestBuilder.Result result) {
|
private void doNotify(ConnectionRequestBuilder.Result result) {
|
||||||
ChannelPipeline pipeline = connection.getMinecraftConnection().getChannel().pipeline();
|
CompletableFuture<ConnectionRequestBuilder.Result> future = connection.getMinecraftConnection().getChannel()
|
||||||
ServerConnection.ConnectionNotifier n = pipeline.get(ServerConnection.ConnectionNotifier.class);
|
.attr(ServerConnection.CONNECTION_NOTIFIER).getAndSet(null);
|
||||||
if (n != null) {
|
if (future != null) {
|
||||||
n.getResult().complete(result);
|
future.complete(result);
|
||||||
pipeline.remove(ServerConnection.ConnectionNotifier.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelForwardingCheck() {
|
|
||||||
if (forwardingCheckTask != null) {
|
|
||||||
forwardingCheckTask.cancel(false);
|
|
||||||
forwardingCheckTask = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import com.velocitypowered.proxy.VelocityServer;
|
|||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import io.netty.channel.*;
|
import io.netty.channel.*;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
|
import io.netty.util.AttributeKey;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
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;
|
import static com.velocitypowered.network.Connections.SERVER_READ_TIMEOUT_SECONDS;
|
||||||
|
|
||||||
public class ServerConnection implements MinecraftConnectionAssociation {
|
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 ServerInfo serverInfo;
|
||||||
private final ConnectedPlayer proxyPlayer;
|
private final ConnectedPlayer proxyPlayer;
|
||||||
@ -55,9 +57,9 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolConstants.Direction.CLIENTBOUND))
|
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolConstants.Direction.CLIENTBOUND))
|
||||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND))
|
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND));
|
||||||
.addLast(CONNECTION_NOTIFIER, new ConnectionNotifier(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(ServerConnection.this);
|
||||||
@ -111,13 +113,10 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
minecraftConnection.setProtocolVersion(protocolVersion);
|
minecraftConnection.setProtocolVersion(protocolVersion);
|
||||||
minecraftConnection.setState(StateRegistry.LOGIN);
|
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();
|
ServerLogin login = new ServerLogin();
|
||||||
login.setUsername(proxyPlayer.getUsername());
|
login.setUsername(proxyPlayer.getUsername());
|
||||||
minecraftConnection.write(login);
|
minecraftConnection.write(login);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public ConnectedPlayer getProxyPlayer() {
|
public ConnectedPlayer getProxyPlayer() {
|
||||||
return proxyPlayer;
|
return proxyPlayer;
|
||||||
@ -140,25 +139,4 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "[server connection] " + proxyPlayer.getProfile().getName() + " -> " + serverInfo.getName();
|
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
|
@Override
|
||||||
public void fireAndForget() {
|
public void fireAndForget() {
|
||||||
connect()
|
connect()
|
||||||
.whenComplete((status, throwable) -> {
|
.whenCompleteAsync((status, throwable) -> {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
handleConnectionException(info, throwable);
|
handleConnectionException(info, throwable);
|
||||||
return;
|
return;
|
||||||
@ -267,7 +267,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
handleConnectionException(info, Disconnect.create(status.getReason().orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR)));
|
handleConnectionException(info, Disconnect.create(status.getReason().orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
}, connection.getChannel().eventLoop());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.velocitypowered.proxy.connection.util;
|
|||||||
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.proxy.protocol.packet.Disconnect;
|
import com.velocitypowered.proxy.protocol.packet.Disconnect;
|
||||||
import net.kyori.text.Component;
|
import net.kyori.text.Component;
|
||||||
|
import net.kyori.text.TextComponent;
|
||||||
import net.kyori.text.serializer.ComponentSerializers;
|
import net.kyori.text.serializer.ComponentSerializers;
|
||||||
|
|
||||||
import java.util.Optional;
|
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