Added bungee skin/uuid forwarding

This commit is contained in:
themode 2020-11-14 23:18:52 +01:00
parent ae8a182eb8
commit 4353e10741
6 changed files with 104 additions and 10 deletions

View File

@ -1,5 +1,12 @@
package net.minestom.server.extras.bungee; package net.minestom.server.extras.bungee;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.minestom.server.entity.PlayerSkin;
import org.jetbrains.annotations.NotNull;
/** /**
* BungeeCord forwarding support. This does not count as a security feature and you will still be required to manage your firewall. * BungeeCord forwarding support. This does not count as a security feature and you will still be required to manage your firewall.
* <p> * <p>
@ -24,4 +31,29 @@ public final class BungeeCordProxy {
public static boolean isEnabled() { public static boolean isEnabled() {
return enabled; return enabled;
} }
public static PlayerSkin readSkin(@NotNull String json) {
JsonArray array = JsonParser.parseString(json).getAsJsonArray();
String skinTexture = null;
String skinSignature = null;
for (JsonElement element : array) {
JsonObject jsonObject = element.getAsJsonObject();
final String name = jsonObject.get("name").getAsString();
final String value = jsonObject.get("value").getAsString();
final String signature = jsonObject.get("signature").getAsString();
if (name.equals("textures")) {
skinTexture = value;
skinSignature = signature;
}
}
if (skinTexture != null && skinSignature != null) {
return new PlayerSkin(skinTexture, skinSignature);
} else {
return null;
}
}
} }

View File

@ -149,12 +149,20 @@ public final class PacketProcessor {
* @param reader the buffer containing the packet * @param reader the buffer containing the packet
*/ */
private void safeRead(@NotNull PlayerConnection connection, @NotNull Readable readable, @NotNull BinaryReader reader) { private void safeRead(@NotNull PlayerConnection connection, @NotNull Readable readable, @NotNull BinaryReader reader) {
final int readableBytes = reader.getBuffer().readableBytes();
// Check if there is anything to read
if (readableBytes == 0) {
return;
}
try { try {
readable.read(reader); readable.read(reader);
} catch (Exception e) { } catch (Exception e) {
final Player player = connection.getPlayer(); final Player player = connection.getPlayer();
final String username = player != null ? player.getUsername() : "null"; final String username = player != null ? player.getUsername() : "null";
LOGGER.warn("Connection " + connection.getRemoteAddress() + " (" + username + ") sent an unexpected packet."); LOGGER.warn("Connection " + connection.getRemoteAddress() + " (" + username + ") sent an unexpected packet.");
e.printStackTrace();
} }
} }
} }

View File

@ -3,6 +3,7 @@ package net.minestom.server.network.packet.client.handshake;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor; import net.minestom.server.chat.ChatColor;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.extras.bungee.BungeeCordProxy; import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.network.ConnectionState; import net.minestom.server.network.ConnectionState;
import net.minestom.server.network.packet.client.ClientPreplayPacket; import net.minestom.server.network.packet.client.ClientPreplayPacket;
@ -13,6 +14,7 @@ import net.minestom.server.utils.binary.BinaryReader;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.UUID;
public class HandshakePacket implements ClientPreplayPacket { public class HandshakePacket implements ClientPreplayPacket {
@ -31,7 +33,7 @@ public class HandshakePacket implements ClientPreplayPacket {
@Override @Override
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
this.protocolVersion = reader.readVarInt(); this.protocolVersion = reader.readVarInt();
this.serverAddress = reader.readSizedString(256); this.serverAddress = reader.readSizedString(BungeeCordProxy.isEnabled() ? Short.MAX_VALUE : 255);
this.serverPort = reader.readUnsignedShort(); this.serverPort = reader.readUnsignedShort();
this.nextState = reader.readVarInt(); this.nextState = reader.readVarInt();
} }
@ -49,8 +51,25 @@ public class HandshakePacket implements ClientPreplayPacket {
if (split.length == 3 || split.length == 4) { if (split.length == 3 || split.length == 4) {
this.serverAddress = split[0]; this.serverAddress = split[0];
final SocketAddress socketAddress = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) connection.getRemoteAddress()).getPort()); final SocketAddress socketAddress = new java.net.InetSocketAddress(split[1],
((java.net.InetSocketAddress) connection.getRemoteAddress()).getPort());
nettyPlayerConnection.setRemoteAddress(socketAddress); nettyPlayerConnection.setRemoteAddress(socketAddress);
UUID playerUuid = UUID.fromString(
split[2]
.replaceFirst(
"(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5"
)
);
PlayerSkin playerSkin = null;
if (split.length == 4) {
playerSkin = BungeeCordProxy.readSkin(split[3]);
}
nettyPlayerConnection.UNSAFE_setBungeeUuid(playerUuid);
nettyPlayerConnection.UNSAFE_setBungeeSkin(playerSkin);
} else { } else {
nettyPlayerConnection.sendPacket(new LoginDisconnectPacket(INVALID_BUNGEE_FORWARDING)); nettyPlayerConnection.sendPacket(new LoginDisconnectPacket(INVALID_BUNGEE_FORWARDING));
nettyPlayerConnection.disconnect(); nettyPlayerConnection.disconnect();

View File

@ -3,7 +3,9 @@ package net.minestom.server.network.packet.client.login;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor; import net.minestom.server.chat.ChatColor;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.Player;
import net.minestom.server.extras.MojangAuth; import net.minestom.server.extras.MojangAuth;
import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.extras.velocity.VelocityProxy; import net.minestom.server.extras.velocity.VelocityProxy;
import net.minestom.server.network.ConnectionState; import net.minestom.server.network.ConnectionState;
import net.minestom.server.network.packet.client.ClientPreplayPacket; import net.minestom.server.network.packet.client.ClientPreplayPacket;
@ -27,8 +29,10 @@ public class LoginStartPacket implements ClientPreplayPacket {
@Override @Override
public void process(@NotNull PlayerConnection connection) { public void process(@NotNull PlayerConnection connection) {
final boolean isNettyClient = connection instanceof NettyPlayerConnection;
// Cache the login username and start compression if enabled // Cache the login username and start compression if enabled
if (connection instanceof NettyPlayerConnection) { if (isNettyClient) {
NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection; NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection;
nettyPlayerConnection.UNSAFE_setLoginUsername(username); nettyPlayerConnection.UNSAFE_setLoginUsername(username);
@ -40,7 +44,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
} }
// Proxy support (only for netty clients) // Proxy support (only for netty clients)
if (connection instanceof NettyPlayerConnection) { if (isNettyClient) {
final NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection; final NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection;
{ {
@ -65,7 +69,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
} }
if (MojangAuth.isUsingMojangAuth() && connection instanceof NettyPlayerConnection) { if (MojangAuth.isUsingMojangAuth() && isNettyClient) {
// Mojang auth // Mojang auth
if (CONNECTION_MANAGER.getPlayer(username) != null) { if (CONNECTION_MANAGER.getPlayer(username) != null) {
connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED_JSON)); connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED_JSON));
@ -79,10 +83,16 @@ public class LoginStartPacket implements ClientPreplayPacket {
EncryptionRequestPacket encryptionRequestPacket = new EncryptionRequestPacket(nettyPlayerConnection); EncryptionRequestPacket encryptionRequestPacket = new EncryptionRequestPacket(nettyPlayerConnection);
nettyPlayerConnection.sendPacket(encryptionRequestPacket); nettyPlayerConnection.sendPacket(encryptionRequestPacket);
} else { } else {
final boolean bungee = BungeeCordProxy.isEnabled();
// Offline // Offline
final UUID playerUuid = CONNECTION_MANAGER.getPlayerConnectionUuid(connection, username); final UUID playerUuid = bungee && isNettyClient ?
((NettyPlayerConnection) connection).getBungeeUuid() :
CONNECTION_MANAGER.getPlayerConnectionUuid(connection, username);
CONNECTION_MANAGER.startPlayState(connection, playerUuid, username); Player player = CONNECTION_MANAGER.startPlayState(connection, playerUuid, username);
if (bungee && isNettyClient) {
player.setSkin(((NettyPlayerConnection) connection).getBungeeSkin());
}
} }
} }

View File

@ -4,6 +4,7 @@ import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.extras.mojangAuth.Decrypter; import net.minestom.server.extras.mojangAuth.Decrypter;
import net.minestom.server.extras.mojangAuth.Encrypter; import net.minestom.server.extras.mojangAuth.Encrypter;
import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.extras.mojangAuth.MojangCrypt;
@ -18,6 +19,7 @@ import org.jetbrains.annotations.Nullable;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
@ -40,6 +42,7 @@ public class NettyPlayerConnection extends PlayerConnection {
@Setter @Setter
private byte[] nonce = new byte[4]; private byte[] nonce = new byte[4];
// Data from client packets
private String loginUsername; private String loginUsername;
private String serverAddress; private String serverAddress;
private int serverPort; private int serverPort;
@ -48,6 +51,10 @@ public class NettyPlayerConnection extends PlayerConnection {
// cleared once the player enters the play state // cleared once the player enters the play state
private final Map<Integer, String> pluginRequestMap = new ConcurrentHashMap<>(); private final Map<Integer, String> pluginRequestMap = new ConcurrentHashMap<>();
// Bungee
private UUID bungeeUuid;
private PlayerSkin bungeeSkin;
public NettyPlayerConnection(@NotNull SocketChannel channel) { public NettyPlayerConnection(@NotNull SocketChannel channel) {
super(); super();
this.channel = channel; this.channel = channel;
@ -158,6 +165,24 @@ public class NettyPlayerConnection extends PlayerConnection {
return serverPort; return serverPort;
} }
@Nullable
public UUID getBungeeUuid() {
return bungeeUuid;
}
public void UNSAFE_setBungeeUuid(UUID bungeeUuid) {
this.bungeeUuid = bungeeUuid;
}
@Nullable
public PlayerSkin getBungeeSkin() {
return bungeeSkin;
}
public void UNSAFE_setBungeeSkin(PlayerSkin bungeeSkin) {
this.bungeeSkin = bungeeSkin;
}
/** /**
* Adds an entry to the plugin request map. * Adds an entry to the plugin request map.
* <p> * <p>

View File

@ -6,8 +6,8 @@ import demo.blocks.UpdatableBlockDemo;
import demo.commands.*; import demo.commands.*;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager; import net.minestom.server.command.CommandManager;
import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.extras.optifine.OptifineSupport; import net.minestom.server.extras.optifine.OptifineSupport;
import net.minestom.server.extras.velocity.VelocityProxy;
import net.minestom.server.instance.block.BlockManager; import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.instance.block.rule.vanilla.RedstonePlacementRule; import net.minestom.server.instance.block.rule.vanilla.RedstonePlacementRule;
import net.minestom.server.storage.StorageManager; import net.minestom.server.storage.StorageManager;
@ -52,8 +52,8 @@ public class Main {
OptifineSupport.enable(); OptifineSupport.enable();
VelocityProxy.enable("rBeJJ79W4MVU"); //VelocityProxy.enable("rBeJJ79W4MVU");
//BungeeCordProxy.enable(); BungeeCordProxy.enable();
// MojangAuth.init(); // MojangAuth.init();