mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-31 21:48:08 +01:00
Fixed copied packets and compression using velocity forwarding
This commit is contained in:
parent
f2e52ff463
commit
bcee5424dc
@ -1,10 +1,13 @@
|
|||||||
package net.minestom.server.extras.velocity;
|
package net.minestom.server.extras.velocity;
|
||||||
|
|
||||||
|
import com.google.common.net.InetAddresses;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minestom.server.utils.binary.BinaryReader;
|
import net.minestom.server.utils.binary.BinaryReader;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -17,6 +20,7 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
public final class VelocityProxy {
|
public final class VelocityProxy {
|
||||||
|
|
||||||
public static final String PLAYER_INFO_CHANNEL = "velocity:player_info";
|
public static final String PLAYER_INFO_CHANNEL = "velocity:player_info";
|
||||||
|
private static final int SUPPORTED_FORWARDING_VERSION = 1;
|
||||||
|
|
||||||
private static boolean enabled;
|
private static boolean enabled;
|
||||||
private static byte[] secret;
|
private static byte[] secret;
|
||||||
@ -48,7 +52,9 @@ public final class VelocityProxy {
|
|||||||
|
|
||||||
final byte[] signature = reader.readBytes(32);
|
final byte[] signature = reader.readBytes(32);
|
||||||
|
|
||||||
final byte[] data = reader.getRemainingBytes();
|
ByteBuf buf = reader.getBuffer();
|
||||||
|
final byte[] data = new byte[buf.readableBytes()];
|
||||||
|
buf.getBytes(buf.readerIndex(), data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Mac mac = Mac.getInstance("HmacSHA256");
|
final Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
@ -61,12 +67,12 @@ public final class VelocityProxy {
|
|||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*int version = buf.readVarInt();
|
final int version = reader.readVarInt();
|
||||||
if (version != SUPPORTED_FORWARDING_VERSION) {
|
return version == SUPPORTED_FORWARDING_VERSION;
|
||||||
throw new IllegalStateException("Unsupported forwarding version " + version + ", wanted " + SUPPORTED_FORWARDING_VERSION);
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
return true;
|
public static InetAddress readAddress(@NotNull BinaryReader reader) {
|
||||||
|
return InetAddresses.forString(reader.readSizedString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,6 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
|
|||||||
final String string3 = new BigInteger(digestedData).toString(16);
|
final String string3 = new BigInteger(digestedData).toString(16);
|
||||||
final GameProfile gameProfile = MinecraftServer.getSessionService().hasJoinedServer(new GameProfile(null, loginUsername), string3);
|
final GameProfile gameProfile = MinecraftServer.getSessionService().hasJoinedServer(new GameProfile(null, loginUsername), string3);
|
||||||
nettyConnection.setEncryptionKey(getSecretKey());
|
nettyConnection.setEncryptionKey(getSecretKey());
|
||||||
final int threshold = MinecraftServer.getCompressionThreshold();
|
|
||||||
|
|
||||||
if (threshold > 0) {
|
|
||||||
nettyConnection.enableCompression(threshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftServer.getLOGGER().info("UUID of player {} is {}", loginUsername, gameProfile.getId());
|
MinecraftServer.getLOGGER().info("UUID of player {} is {}", loginUsername, gameProfile.getId());
|
||||||
CONNECTION_MANAGER.startPlayState(connection, gameProfile.getId(), gameProfile.getName());
|
CONNECTION_MANAGER.startPlayState(connection, gameProfile.getId(), gameProfile.getName());
|
||||||
|
@ -12,6 +12,9 @@ import net.minestom.server.network.player.PlayerConnection;
|
|||||||
import net.minestom.server.utils.binary.BinaryReader;
|
import net.minestom.server.utils.binary.BinaryReader;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class LoginPluginResponsePacket implements ClientPreplayPacket {
|
public class LoginPluginResponsePacket implements ClientPreplayPacket {
|
||||||
@ -34,16 +37,27 @@ public class LoginPluginResponsePacket implements ClientPreplayPacket {
|
|||||||
|
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
|
SocketAddress socketAddress = null;
|
||||||
|
|
||||||
// Velocity
|
// Velocity
|
||||||
if (VelocityProxy.isEnabled() && channel.equals(VelocityProxy.PLAYER_INFO_CHANNEL)) {
|
if (VelocityProxy.isEnabled() && channel.equals(VelocityProxy.PLAYER_INFO_CHANNEL)) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
BinaryReader reader = new BinaryReader(data);
|
BinaryReader reader = new BinaryReader(data);
|
||||||
success = VelocityProxy.checkIntegrity(reader);
|
success = VelocityProxy.checkIntegrity(reader);
|
||||||
|
if (success) {
|
||||||
|
// Get the real connection address
|
||||||
|
final InetAddress address = VelocityProxy.readAddress(reader);
|
||||||
|
final int port = ((java.net.InetSocketAddress) connection.getRemoteAddress()).getPort();
|
||||||
|
socketAddress = new InetSocketAddress(address, port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
if (socketAddress != null) {
|
||||||
|
nettyPlayerConnection.setRemoteAddress(socketAddress);
|
||||||
|
}
|
||||||
|
|
||||||
// Proxy usage always mean that the server is in offline mode
|
// Proxy usage always mean that the server is in offline mode
|
||||||
final String username = nettyPlayerConnection.getLoginUsername();
|
final String username = nettyPlayerConnection.getLoginUsername();
|
||||||
final UUID playerUuid = CONNECTION_MANAGER.getPlayerConnectionUuid(connection, username);
|
final UUID playerUuid = CONNECTION_MANAGER.getPlayerConnectionUuid(connection, username);
|
||||||
|
@ -27,9 +27,16 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
|||||||
@Override
|
@Override
|
||||||
public void process(@NotNull PlayerConnection connection) {
|
public void process(@NotNull PlayerConnection connection) {
|
||||||
|
|
||||||
// Cache the login username
|
// Cache the login username and start compression if enabled
|
||||||
if (connection instanceof NettyPlayerConnection) {
|
if (connection instanceof NettyPlayerConnection) {
|
||||||
((NettyPlayerConnection) connection).UNSAFE_setLoginUsername(username);
|
NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection;
|
||||||
|
nettyPlayerConnection.UNSAFE_setLoginUsername(username);
|
||||||
|
|
||||||
|
// Compression
|
||||||
|
final int threshold = MinecraftServer.getCompressionThreshold();
|
||||||
|
if (threshold > 0) {
|
||||||
|
nettyPlayerConnection.enableCompression(threshold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proxy support (only for netty clients)
|
// Proxy support (only for netty clients)
|
||||||
@ -75,12 +82,6 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
|||||||
// Offline
|
// Offline
|
||||||
final UUID playerUuid = CONNECTION_MANAGER.getPlayerConnectionUuid(connection, username);
|
final UUID playerUuid = CONNECTION_MANAGER.getPlayerConnectionUuid(connection, username);
|
||||||
|
|
||||||
final int threshold = MinecraftServer.getCompressionThreshold();
|
|
||||||
|
|
||||||
if (threshold > 0 && connection instanceof NettyPlayerConnection) {
|
|
||||||
((NettyPlayerConnection) connection).enableCompression(threshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
CONNECTION_MANAGER.startPlayState(connection, playerUuid, username);
|
CONNECTION_MANAGER.startPlayState(connection, playerUuid, username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
public class NettyPlayerConnection extends PlayerConnection {
|
public class NettyPlayerConnection extends PlayerConnection {
|
||||||
|
|
||||||
private final SocketChannel channel;
|
private final SocketChannel channel;
|
||||||
|
|
||||||
|
private SocketAddress remoteAddress;
|
||||||
@Getter
|
@Getter
|
||||||
private boolean encrypted = false;
|
private boolean encrypted = false;
|
||||||
@Getter
|
@Getter
|
||||||
@ -50,6 +52,7 @@ public class NettyPlayerConnection extends PlayerConnection {
|
|||||||
public NettyPlayerConnection(@NotNull SocketChannel channel) {
|
public NettyPlayerConnection(@NotNull SocketChannel channel) {
|
||||||
super();
|
super();
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
|
this.remoteAddress = channel.remoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,25 +83,25 @@ public class NettyPlayerConnection extends PlayerConnection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPacket(@NotNull ByteBuf buffer, boolean copy) {
|
public void sendPacket(@NotNull ByteBuf buffer, boolean copy) {
|
||||||
if ((encrypted || compressed) && copy) {
|
if (copy) {
|
||||||
buffer = buffer.copy();
|
buffer = buffer.copy();
|
||||||
buffer.retain();
|
buffer.retain();
|
||||||
channel.writeAndFlush(buffer);
|
channel.writeAndFlush(buffer);
|
||||||
buffer.release();
|
buffer.release();
|
||||||
} else {
|
} else {
|
||||||
getChannel().writeAndFlush(buffer);
|
channel.writeAndFlush(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writePacket(@NotNull ByteBuf buffer, boolean copy) {
|
public void writePacket(@NotNull ByteBuf buffer, boolean copy) {
|
||||||
if ((encrypted || compressed) && copy) {
|
if (copy) {
|
||||||
buffer = buffer.copy();
|
buffer = buffer.copy();
|
||||||
buffer.retain();
|
buffer.retain();
|
||||||
channel.write(buffer);
|
channel.write(buffer);
|
||||||
buffer.release();
|
buffer.release();
|
||||||
} else {
|
} else {
|
||||||
getChannel().write(buffer);
|
channel.write(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +118,18 @@ public class NettyPlayerConnection extends PlayerConnection {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public SocketAddress getRemoteAddress() {
|
public SocketAddress getRemoteAddress() {
|
||||||
return getChannel().remoteAddress();
|
return remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the internal remote address field.
|
||||||
|
* <p>
|
||||||
|
* Mostly unsafe, used internally when interacting with a proxy.
|
||||||
|
*
|
||||||
|
* @param remoteAddress the new connection remote address
|
||||||
|
*/
|
||||||
|
public void setRemoteAddress(@NotNull SocketAddress remoteAddress) {
|
||||||
|
this.remoteAddress = remoteAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -141,7 +155,7 @@ public class NettyPlayerConnection extends PlayerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the internal login username field
|
* Sets the internal login username field.
|
||||||
*
|
*
|
||||||
* @param loginUsername the new login username field
|
* @param loginUsername the new login username field
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user