Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-26 16:12:50 +01:00
Actually fix the login plugin messaging
Dieser Commit ist enthalten in:
Ursprung
2f5f93a427
Commit
2f5ca386a6
@ -67,9 +67,6 @@ public class VelocityConfiguration {
|
|||||||
case NONE:
|
case NONE:
|
||||||
logger.info("IP forwarding is disabled! All players will appear to be connecting from the proxy and will have offline-mode UUIDs.");
|
logger.info("IP forwarding is disabled! All players will appear to be connecting from the proxy and will have offline-mode UUIDs.");
|
||||||
break;
|
break;
|
||||||
case MODERN:
|
|
||||||
logger.warn("Modern IP forwarding is not currently implemented.");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (servers.isEmpty()) {
|
if (servers.isEmpty()) {
|
||||||
|
@ -171,6 +171,9 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
|
public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
|
||||||
|
if (this.sessionHandler != null) {
|
||||||
|
this.sessionHandler.deactivated();
|
||||||
|
}
|
||||||
this.sessionHandler = sessionHandler;
|
this.sessionHandler = sessionHandler;
|
||||||
sessionHandler.activated();
|
sessionHandler.activated();
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ public interface MinecraftSessionHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void deactivated() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
default void exception(Throwable throwable) {
|
default void exception(Throwable throwable) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
||||||
if (packet instanceof KeepAlive) {
|
if (packet instanceof KeepAlive) {
|
||||||
// Forward onto the server
|
// Forward onto the server
|
||||||
connection.getChannel().write(packet);
|
connection.getMinecraftConnection().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.getProxyPlayer().handleConnectionException(connection.getServerInfo(), original);
|
||||||
@ -92,7 +92,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
private boolean canForwardPluginMessage(PluginMessage message) {
|
private boolean canForwardPluginMessage(PluginMessage message) {
|
||||||
ClientPlaySessionHandler playerHandler =
|
ClientPlaySessionHandler playerHandler =
|
||||||
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
|
||||||
if (connection.getChannel().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());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,29 +1,69 @@
|
|||||||
package com.velocitypowered.proxy.connection.backend;
|
package com.velocitypowered.proxy.connection.backend;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
|
import com.velocitypowered.proxy.config.IPForwardingMode;
|
||||||
|
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
|
import com.velocitypowered.proxy.data.GameProfile;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packets.*;
|
import com.velocitypowered.proxy.protocol.packets.*;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.kyori.text.TextComponent;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class LoginSessionHandler implements MinecraftSessionHandler {
|
public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||||
private final ServerConnection connection;
|
private final ServerConnection connection;
|
||||||
private int forwardingPacketId = -1;
|
private ScheduledFuture<?> modernForwardingNotice;
|
||||||
|
|
||||||
public LoginSessionHandler(ServerConnection connection) {
|
public LoginSessionHandler(ServerConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void activated() {
|
||||||
|
if (VelocityServer.getServer().getConfiguration().getIpForwardingMode() == IPForwardingMode.MODERN) {
|
||||||
|
modernForwardingNotice = 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) {
|
||||||
throw new IllegalStateException("Backend server is online-mode!");
|
throw new IllegalStateException("Backend server is online-mode!");
|
||||||
} else if (packet instanceof LoginPluginResponse) {
|
} else if (packet instanceof LoginPluginMessage) {
|
||||||
LoginPluginResponse lpr = (LoginPluginResponse) packet;
|
LoginPluginMessage message = (LoginPluginMessage) packet;
|
||||||
if (lpr.getId() == forwardingPacketId) {
|
if (VelocityServer.getServer().getConfiguration().getIpForwardingMode() == IPForwardingMode.MODERN &&
|
||||||
if (!lpr.isSuccess()) {
|
message.getChannel().equals(VelocityConstants.VELOCITY_IP_FORWARDING_CHANNEL)) {
|
||||||
throw new IllegalStateException("Unable to forward player information to server! Is it configured properly?");
|
LoginPluginResponse response = new LoginPluginResponse();
|
||||||
|
response.setSuccess(true);
|
||||||
|
response.setId(message.getId());
|
||||||
|
response.setData(createForwardingData(connection.getProxyPlayer().getRemoteAddress().getHostString(),
|
||||||
|
connection.getProxyPlayer().getProfile()));
|
||||||
|
connection.getMinecraftConnection().write(response);
|
||||||
|
if (modernForwardingNotice != null) {
|
||||||
|
modernForwardingNotice.cancel(false);
|
||||||
|
modernForwardingNotice = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerLogin login = new ServerLogin();
|
||||||
|
login.setUsername(connection.getProxyPlayer().getUsername());
|
||||||
|
connection.getMinecraftConnection().write(login);
|
||||||
|
} else {
|
||||||
|
// Don't understand
|
||||||
|
LoginPluginResponse response = new LoginPluginResponse();
|
||||||
|
response.setSuccess(false);
|
||||||
|
response.setId(message.getId());
|
||||||
|
response.setData(Unpooled.EMPTY_BUFFER);
|
||||||
|
connection.getMinecraftConnection().write(response);
|
||||||
}
|
}
|
||||||
} else if (packet instanceof Disconnect) {
|
} else if (packet instanceof Disconnect) {
|
||||||
Disconnect disconnect = (Disconnect) packet;
|
Disconnect disconnect = (Disconnect) packet;
|
||||||
@ -31,10 +71,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), 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.getChannel().setCompressionThreshold(sc.getThreshold());
|
connection.getMinecraftConnection().setCompressionThreshold(sc.getThreshold());
|
||||||
} else if (packet instanceof ServerLoginSuccess) {
|
} else if (packet instanceof ServerLoginSuccess) {
|
||||||
// The player has been logged on to the backend server.
|
// The player has been logged on to the backend server.
|
||||||
connection.getChannel().setState(StateRegistry.PLAY);
|
connection.getMinecraftConnection().setState(StateRegistry.PLAY);
|
||||||
ServerConnection existingConnection = connection.getProxyPlayer().getConnectedServer();
|
ServerConnection existingConnection = connection.getProxyPlayer().getConnectedServer();
|
||||||
if (existingConnection == null) {
|
if (existingConnection == null) {
|
||||||
// Strap on the play session handler
|
// Strap on the play session handler
|
||||||
@ -43,21 +83,41 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
// The previous server connection should become obsolete.
|
// The previous server connection should become obsolete.
|
||||||
existingConnection.disconnect();
|
existingConnection.disconnect();
|
||||||
}
|
}
|
||||||
connection.getChannel().setSessionHandler(new BackendPlaySessionHandler(connection));
|
connection.getMinecraftConnection().setSessionHandler(new BackendPlaySessionHandler(connection));
|
||||||
connection.getProxyPlayer().setConnectedServer(connection);
|
connection.getProxyPlayer().setConnectedServer(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deactivated() {
|
||||||
|
if (modernForwardingNotice != null) {
|
||||||
|
modernForwardingNotice.cancel(false);
|
||||||
|
modernForwardingNotice = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exception(Throwable throwable) {
|
public void exception(Throwable throwable) {
|
||||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getForwardingPacketId() {
|
private static ByteBuf createForwardingData(String address, GameProfile profile) {
|
||||||
return forwardingPacketId;
|
ByteBuf buf = Unpooled.buffer();
|
||||||
}
|
ProtocolUtils.writeString(buf, address);
|
||||||
|
ProtocolUtils.writeString(buf, profile.getName());
|
||||||
public void setForwardingPacketId(int forwardingPacketId) {
|
ProtocolUtils.writeUuid(buf, profile.idAsUuid());
|
||||||
this.forwardingPacketId = forwardingPacketId;
|
ProtocolUtils.writeVarInt(buf, profile.getProperties().size());
|
||||||
|
for (GameProfile.Property property : profile.getProperties()) {
|
||||||
|
ProtocolUtils.writeString(buf, property.getName());
|
||||||
|
ProtocolUtils.writeString(buf, property.getValue());
|
||||||
|
String signature = property.getSignature();
|
||||||
|
if (signature != null) {
|
||||||
|
buf.writeBoolean(true);
|
||||||
|
ProtocolUtils.writeString(buf, signature);
|
||||||
|
} else {
|
||||||
|
buf.writeBoolean(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,28 +2,21 @@ package com.velocitypowered.proxy.connection.backend;
|
|||||||
|
|
||||||
import com.velocitypowered.proxy.config.IPForwardingMode;
|
import com.velocitypowered.proxy.config.IPForwardingMode;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
||||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
|
||||||
import com.velocitypowered.proxy.data.GameProfile;
|
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
|
||||||
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;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.packets.Handshake;
|
import com.velocitypowered.proxy.protocol.packets.Handshake;
|
||||||
import com.velocitypowered.proxy.protocol.packets.LoginPluginMessage;
|
|
||||||
import com.velocitypowered.proxy.protocol.packets.ServerLogin;
|
import com.velocitypowered.proxy.protocol.packets.ServerLogin;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.data.ServerInfo;
|
import com.velocitypowered.proxy.data.ServerInfo;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.*;
|
import io.netty.channel.*;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.velocitypowered.network.Connections.FRAME_DECODER;
|
import static com.velocitypowered.network.Connections.FRAME_DECODER;
|
||||||
@ -38,7 +31,7 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
private final ServerInfo serverInfo;
|
private final ServerInfo serverInfo;
|
||||||
private final ConnectedPlayer proxyPlayer;
|
private final ConnectedPlayer proxyPlayer;
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
private MinecraftConnection channel;
|
private MinecraftConnection minecraftConnection;
|
||||||
|
|
||||||
public ServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) {
|
public ServerConnection(ServerInfo target, ConnectedPlayer proxyPlayer, VelocityServer server) {
|
||||||
this.serverInfo = target;
|
this.serverInfo = target;
|
||||||
@ -60,7 +53,6 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
|
|
||||||
MinecraftConnection connection = new MinecraftConnection(ch);
|
MinecraftConnection connection = new MinecraftConnection(ch);
|
||||||
connection.setState(StateRegistry.HANDSHAKE);
|
connection.setState(StateRegistry.HANDSHAKE);
|
||||||
connection.setSessionHandler(new LoginSessionHandler(ServerConnection.this));
|
|
||||||
connection.setAssociation(ServerConnection.this);
|
connection.setAssociation(ServerConnection.this);
|
||||||
ch.pipeline().addLast(HANDLER, connection);
|
ch.pipeline().addLast(HANDLER, connection);
|
||||||
}
|
}
|
||||||
@ -70,9 +62,10 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
channel = 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));
|
||||||
startHandshake();
|
startHandshake();
|
||||||
} else {
|
} else {
|
||||||
proxyPlayer.handleConnectionException(serverInfo, future.cause());
|
proxyPlayer.handleConnectionException(serverInfo, future.cause());
|
||||||
@ -102,43 +95,27 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
handshake.setServerAddress(serverInfo.getAddress().getHostString());
|
handshake.setServerAddress(serverInfo.getAddress().getHostString());
|
||||||
}
|
}
|
||||||
handshake.setPort(serverInfo.getAddress().getPort());
|
handshake.setPort(serverInfo.getAddress().getPort());
|
||||||
channel.write(handshake);
|
minecraftConnection.write(handshake);
|
||||||
|
|
||||||
int protocolVersion = proxyPlayer.getConnection().getProtocolVersion();
|
int protocolVersion = proxyPlayer.getConnection().getProtocolVersion();
|
||||||
channel.setProtocolVersion(protocolVersion);
|
minecraftConnection.setProtocolVersion(protocolVersion);
|
||||||
channel.setState(StateRegistry.LOGIN);
|
minecraftConnection.setState(StateRegistry.LOGIN);
|
||||||
|
|
||||||
// 1.13 stuff
|
// Send the server login packet for <=1.12.2 and for 1.13+ servers not using "modern" forwarding.
|
||||||
if (protocolVersion >= ProtocolConstants.MINECRAFT_1_13) {
|
if (protocolVersion <= ProtocolConstants.MINECRAFT_1_12_2 ||
|
||||||
if (VelocityServer.getServer().getConfiguration().getIpForwardingMode() == IPForwardingMode.MODERN) {
|
VelocityServer.getServer().getConfiguration().getIpForwardingMode() != IPForwardingMode.MODERN) {
|
||||||
// Velocity's IP forwarding includes the player's IP address and their game profile.
|
|
||||||
GameProfile profile = proxyPlayer.getProfile();
|
|
||||||
ByteBuf buf = createForwardingData(proxyPlayer.getRemoteAddress().getHostString(), profile);
|
|
||||||
|
|
||||||
// Send the message on
|
|
||||||
LoginPluginMessage forwarding = new LoginPluginMessage();
|
|
||||||
forwarding.setId(ThreadLocalRandom.current().nextInt());
|
|
||||||
forwarding.setChannel(VelocityConstants.VELOCITY_IP_FORWARDING_CHANNEL);
|
|
||||||
forwarding.setData(buf);
|
|
||||||
|
|
||||||
LoginSessionHandler lsh = (LoginSessionHandler) channel.getSessionHandler();
|
|
||||||
lsh.setForwardingPacketId(forwarding.getId());
|
|
||||||
channel.write(forwarding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Login
|
|
||||||
ServerLogin login = new ServerLogin();
|
ServerLogin login = new ServerLogin();
|
||||||
login.setUsername(proxyPlayer.getUsername());
|
login.setUsername(proxyPlayer.getUsername());
|
||||||
channel.write(login);
|
minecraftConnection.write(login);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectedPlayer getProxyPlayer() {
|
public ConnectedPlayer getProxyPlayer() {
|
||||||
return proxyPlayer;
|
return proxyPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinecraftConnection getChannel() {
|
public MinecraftConnection getMinecraftConnection() {
|
||||||
return channel;
|
return minecraftConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerInfo getServerInfo() {
|
public ServerInfo getServerInfo() {
|
||||||
@ -146,32 +123,12 @@ public class ServerConnection implements MinecraftConnectionAssociation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
channel.close();
|
minecraftConnection.close();
|
||||||
channel = null;
|
minecraftConnection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[server connection] " + proxyPlayer.getProfile().getName() + " -> " + serverInfo.getName();
|
return "[server connection] " + proxyPlayer.getProfile().getName() + " -> " + serverInfo.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ByteBuf createForwardingData(String address, GameProfile profile) {
|
|
||||||
ByteBuf buf = Unpooled.buffer();
|
|
||||||
ProtocolUtils.writeString(buf, address);
|
|
||||||
ProtocolUtils.writeString(buf, profile.getName());
|
|
||||||
ProtocolUtils.writeUuid(buf, profile.idAsUuid());
|
|
||||||
ProtocolUtils.writeVarInt(buf, profile.getProperties().size());
|
|
||||||
for (GameProfile.Property property : profile.getProperties()) {
|
|
||||||
ProtocolUtils.writeString(buf, property.getName());
|
|
||||||
ProtocolUtils.writeString(buf, property.getValue());
|
|
||||||
String signature = property.getSignature();
|
|
||||||
if (signature != null) {
|
|
||||||
buf.writeBoolean(true);
|
|
||||||
ProtocolUtils.writeString(buf, signature);
|
|
||||||
} else {
|
|
||||||
buf.writeBoolean(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -93,18 +93,18 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we don't want to handle this packet, just forward it on.
|
// If we don't want to handle this packet, just forward it on.
|
||||||
player.getConnectedServer().getChannel().write(packet);
|
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleUnknown(ByteBuf buf) {
|
public void handleUnknown(ByteBuf buf) {
|
||||||
ByteBuf remapped = idRemapper.remap(buf, ProtocolConstants.Direction.SERVERBOUND);
|
ByteBuf remapped = idRemapper.remap(buf, ProtocolConstants.Direction.SERVERBOUND);
|
||||||
player.getConnectedServer().getChannel().write(remapped);
|
player.getConnectedServer().getMinecraftConnection().write(remapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnected() {
|
public void disconnected() {
|
||||||
player.getConnectedServer().disconnect();
|
player.teardown();
|
||||||
|
|
||||||
if (pingTask != null && !pingTask.isCancelled()) {
|
if (pingTask != null && !pingTask.isCancelled()) {
|
||||||
pingTask.cancel(false);
|
pingTask.cancel(false);
|
||||||
@ -150,7 +150,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// Resend client settings packet to remote server if we have it, this preserves client settings across
|
// Resend client settings packet to remote server if we have it, this preserves client settings across
|
||||||
// transitions.
|
// transitions.
|
||||||
if (player.getClientSettings() != null) {
|
if (player.getClientSettings() != null) {
|
||||||
player.getConnectedServer().getChannel().delayedWrite(player.getClientSettings());
|
player.getConnectedServer().getMinecraftConnection().delayedWrite(player.getClientSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove old boss bars.
|
// Remove old boss bars.
|
||||||
@ -169,19 +169,19 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (!clientPluginMsgChannels.isEmpty()) {
|
if (!clientPluginMsgChannels.isEmpty()) {
|
||||||
String channel = player.getConnection().getProtocolVersion() >= ProtocolConstants.MINECRAFT_1_13 ?
|
String channel = player.getConnection().getProtocolVersion() >= ProtocolConstants.MINECRAFT_1_13 ?
|
||||||
"minecraft:register" : "REGISTER";
|
"minecraft:register" : "REGISTER";
|
||||||
player.getConnectedServer().getChannel().delayedWrite(
|
player.getConnectedServer().getMinecraftConnection().delayedWrite(
|
||||||
PluginMessageUtil.constructChannelsPacket(channel, clientPluginMsgChannels));
|
PluginMessageUtil.constructChannelsPacket(channel, clientPluginMsgChannels));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the server the client's brand
|
// Tell the server the client's brand
|
||||||
if (brandMessage != null) {
|
if (brandMessage != null) {
|
||||||
brandMessage.getData().retain();
|
brandMessage.getData().retain();
|
||||||
player.getConnectedServer().getChannel().delayedWrite(brandMessage);
|
player.getConnectedServer().getMinecraftConnection().delayedWrite(brandMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush everything
|
// Flush everything
|
||||||
player.getConnection().flush();
|
player.getConnection().flush();
|
||||||
player.getConnectedServer().getChannel().flush();
|
player.getConnectedServer().getMinecraftConnection().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentDimension(int currentDimension) {
|
public void setCurrentDimension(int currentDimension) {
|
||||||
@ -213,7 +213,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (actuallyRegistered.size() > 0) {
|
if (actuallyRegistered.size() > 0) {
|
||||||
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
logger.info("Rewritten register packet: {}", actuallyRegistered);
|
||||||
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket(packet.getChannel(), actuallyRegistered);
|
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket(packet.getChannel(), actuallyRegistered);
|
||||||
player.getConnectedServer().getChannel().write(newRegisterPacket);
|
player.getConnectedServer().getMinecraftConnection().write(newRegisterPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -242,7 +242,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
packet.getData().retain();
|
packet.getData().retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
player.getConnectedServer().getChannel().write(packet);
|
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||||
} finally {
|
} finally {
|
||||||
ReferenceCountUtil.release(original.getData());
|
ReferenceCountUtil.release(original.getData());
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -35,6 +36,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation {
|
|||||||
private int tryIndex = 0;
|
private int tryIndex = 0;
|
||||||
private ServerConnection connectedServer;
|
private ServerConnection connectedServer;
|
||||||
private ClientSettings clientSettings;
|
private ClientSettings clientSettings;
|
||||||
|
private ServerConnection connectionInFlight;
|
||||||
|
|
||||||
public ConnectedPlayer(GameProfile profile, MinecraftConnection connection) {
|
public ConnectedPlayer(GameProfile profile, MinecraftConnection connection) {
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
@ -101,7 +103,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation {
|
|||||||
handleConnectionException(info, disconnectReason);
|
handleConnectionException(info, disconnectReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleConnectionException(ServerInfo info, Component disconnectReason) {
|
public void handleConnectionException(ServerInfo info, Component disconnectReason) {
|
||||||
if (connectedServer == null || connectedServer.getServerInfo().equals(info)) {
|
if (connectedServer == null || connectedServer.getServerInfo().equals(info)) {
|
||||||
// The player isn't yet connected to a server or they are already connected to the server
|
// The player isn't yet connected to a server or they are already connected to the server
|
||||||
// they're disconnected from.
|
// they're disconnected from.
|
||||||
@ -124,7 +126,9 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation {
|
|||||||
|
|
||||||
public void connect(ServerInfo info) {
|
public void connect(ServerInfo info) {
|
||||||
Preconditions.checkNotNull(info, "info");
|
Preconditions.checkNotNull(info, "info");
|
||||||
|
Preconditions.checkState(connectionInFlight == null, "A connection is already active!");
|
||||||
ServerConnection connection = new ServerConnection(info, this, VelocityServer.getServer());
|
ServerConnection connection = new ServerConnection(info, this, VelocityServer.getServer());
|
||||||
|
connectionInFlight = connection;
|
||||||
connection.connect();
|
connection.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +143,15 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation {
|
|||||||
connection.closeWith(Disconnect.create(reason));
|
connection.closeWith(Disconnect.create(reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void teardown() {
|
||||||
|
if (connectionInFlight != null) {
|
||||||
|
connectionInFlight.disconnect();
|
||||||
|
}
|
||||||
|
if (connectedServer != null) {
|
||||||
|
connectedServer.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[connected player] " + getProfile().getName() + " (" + getRemoteAddress() + ")";
|
return "[connected player] " + getProfile().getName() + " (" + getRemoteAddress() + ")";
|
||||||
|
@ -18,6 +18,6 @@ public class InitialConnectSessionHandler implements MinecraftSessionHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void disconnected() {
|
public void disconnected() {
|
||||||
// the user cancelled the login process
|
// the user cancelled the login process
|
||||||
player.getConnectedServer().disconnect();
|
player.teardown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||||
import com.velocitypowered.proxy.data.GameProfile;
|
import com.velocitypowered.proxy.data.GameProfile;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packets.*;
|
import com.velocitypowered.proxy.protocol.packets.*;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
@ -35,27 +36,33 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
private final MinecraftConnection inbound;
|
private final MinecraftConnection inbound;
|
||||||
private ServerLogin login;
|
private ServerLogin login;
|
||||||
private byte[] verify;
|
private byte[] verify;
|
||||||
|
private int playerInfoId;
|
||||||
|
|
||||||
public LoginSessionHandler(MinecraftConnection inbound) {
|
public LoginSessionHandler(MinecraftConnection inbound) {
|
||||||
this.inbound = Preconditions.checkNotNull(inbound, "inbound");
|
this.inbound = Preconditions.checkNotNull(inbound, "inbound");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void activated() {
|
||||||
|
if (inbound.getProtocolVersion() >= ProtocolConstants.MINECRAFT_1_13) {
|
||||||
|
LoginPluginMessage message = new LoginPluginMessage();
|
||||||
|
playerInfoId = ThreadLocalRandom.current().nextInt();
|
||||||
|
message.setId(playerInfoId);
|
||||||
|
message.setChannel(VelocityConstants.VELOCITY_IP_FORWARDING_CHANNEL);
|
||||||
|
message.setData(Unpooled.EMPTY_BUFFER);
|
||||||
|
inbound.write(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(MinecraftPacket packet) throws Exception {
|
public void handle(MinecraftPacket packet) throws Exception {
|
||||||
if (packet instanceof LoginPluginMessage) {
|
if (packet instanceof LoginPluginResponse) {
|
||||||
LoginPluginMessage lpm = (LoginPluginMessage) packet;
|
LoginPluginResponse lpr = (LoginPluginResponse) packet;
|
||||||
if (lpm.getChannel().equals(VelocityConstants.VELOCITY_IP_FORWARDING_CHANNEL)) {
|
if (lpr.getId() == playerInfoId && lpr.isSuccess()) {
|
||||||
// Uh oh, someone's trying to run Velocity behind Velocity. We don't want that happening.
|
// Uh oh, someone's trying to run Velocity behind Velocity. We don't want that happening.
|
||||||
inbound.closeWith(Disconnect.create(
|
inbound.closeWith(Disconnect.create(
|
||||||
TextComponent.of("Running Velocity behind Velocity isn't supported.", TextColor.RED)
|
TextComponent.of("Running Velocity behind Velocity isn't supported.", TextColor.RED)
|
||||||
));
|
));
|
||||||
} else {
|
|
||||||
// We don't know what this message is.
|
|
||||||
LoginPluginResponse response = new LoginPluginResponse();
|
|
||||||
response.setId(lpm.getId());
|
|
||||||
response.setSuccess(false);
|
|
||||||
response.setData(Unpooled.EMPTY_BUFFER);
|
|
||||||
inbound.write(response);
|
|
||||||
}
|
}
|
||||||
} else if (packet instanceof ServerLogin) {
|
} else if (packet instanceof ServerLogin) {
|
||||||
this.login = (ServerLogin) packet;
|
this.login = (ServerLogin) packet;
|
||||||
|
@ -108,7 +108,7 @@ public enum StateRegistry {
|
|||||||
genericMappings(0x00));
|
genericMappings(0x00));
|
||||||
SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new,
|
SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new,
|
||||||
genericMappings(0x01));
|
genericMappings(0x01));
|
||||||
SERVERBOUND.register(LoginPluginMessage.class, LoginPluginMessage::new,
|
SERVERBOUND.register(LoginPluginResponse.class, LoginPluginResponse::new,
|
||||||
map(0x02, MINECRAFT_1_13));
|
map(0x02, MINECRAFT_1_13));
|
||||||
|
|
||||||
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
|
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
|
||||||
@ -119,7 +119,7 @@ public enum StateRegistry {
|
|||||||
genericMappings(0x02));
|
genericMappings(0x02));
|
||||||
CLIENTBOUND.register(SetCompression.class, SetCompression::new,
|
CLIENTBOUND.register(SetCompression.class, SetCompression::new,
|
||||||
genericMappings(0x03));
|
genericMappings(0x03));
|
||||||
CLIENTBOUND.register(LoginPluginResponse.class, LoginPluginResponse::new,
|
CLIENTBOUND.register(LoginPluginMessage.class, LoginPluginMessage::new,
|
||||||
map(0x04, MINECRAFT_1_13));
|
map(0x04, MINECRAFT_1_13));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren