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;
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.
* <p>
@ -24,4 +31,29 @@ public final class BungeeCordProxy {
public static boolean isEnabled() {
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
*/
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 {
readable.read(reader);
} catch (Exception e) {
final Player player = connection.getPlayer();
final String username = player != null ? player.getUsername() : "null";
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.chat.ChatColor;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.network.ConnectionState;
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 java.net.SocketAddress;
import java.util.UUID;
public class HandshakePacket implements ClientPreplayPacket {
@ -31,7 +33,7 @@ public class HandshakePacket implements ClientPreplayPacket {
@Override
public void read(@NotNull BinaryReader reader) {
this.protocolVersion = reader.readVarInt();
this.serverAddress = reader.readSizedString(256);
this.serverAddress = reader.readSizedString(BungeeCordProxy.isEnabled() ? Short.MAX_VALUE : 255);
this.serverPort = reader.readUnsignedShort();
this.nextState = reader.readVarInt();
}
@ -49,8 +51,25 @@ public class HandshakePacket implements ClientPreplayPacket {
if (split.length == 3 || split.length == 4) {
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);
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 {
nettyPlayerConnection.sendPacket(new LoginDisconnectPacket(INVALID_BUNGEE_FORWARDING));
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.chat.ChatColor;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.Player;
import net.minestom.server.extras.MojangAuth;
import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.extras.velocity.VelocityProxy;
import net.minestom.server.network.ConnectionState;
import net.minestom.server.network.packet.client.ClientPreplayPacket;
@ -27,8 +29,10 @@ public class LoginStartPacket implements ClientPreplayPacket {
@Override
public void process(@NotNull PlayerConnection connection) {
final boolean isNettyClient = connection instanceof NettyPlayerConnection;
// Cache the login username and start compression if enabled
if (connection instanceof NettyPlayerConnection) {
if (isNettyClient) {
NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection;
nettyPlayerConnection.UNSAFE_setLoginUsername(username);
@ -40,7 +44,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
}
// Proxy support (only for netty clients)
if (connection instanceof NettyPlayerConnection) {
if (isNettyClient) {
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
if (CONNECTION_MANAGER.getPlayer(username) != null) {
connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED_JSON));
@ -79,10 +83,16 @@ public class LoginStartPacket implements ClientPreplayPacket {
EncryptionRequestPacket encryptionRequestPacket = new EncryptionRequestPacket(nettyPlayerConnection);
nettyPlayerConnection.sendPacket(encryptionRequestPacket);
} else {
final boolean bungee = BungeeCordProxy.isEnabled();
// 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 lombok.Getter;
import lombok.Setter;
import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.extras.mojangAuth.Decrypter;
import net.minestom.server.extras.mojangAuth.Encrypter;
import net.minestom.server.extras.mojangAuth.MojangCrypt;
@ -18,6 +19,7 @@ import org.jetbrains.annotations.Nullable;
import javax.crypto.SecretKey;
import java.net.SocketAddress;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
@ -40,6 +42,7 @@ public class NettyPlayerConnection extends PlayerConnection {
@Setter
private byte[] nonce = new byte[4];
// Data from client packets
private String loginUsername;
private String serverAddress;
private int serverPort;
@ -48,6 +51,10 @@ public class NettyPlayerConnection extends PlayerConnection {
// cleared once the player enters the play state
private final Map<Integer, String> pluginRequestMap = new ConcurrentHashMap<>();
// Bungee
private UUID bungeeUuid;
private PlayerSkin bungeeSkin;
public NettyPlayerConnection(@NotNull SocketChannel channel) {
super();
this.channel = channel;
@ -158,6 +165,24 @@ public class NettyPlayerConnection extends PlayerConnection {
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.
* <p>

View File

@ -6,8 +6,8 @@ import demo.blocks.UpdatableBlockDemo;
import demo.commands.*;
import net.minestom.server.MinecraftServer;
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.velocity.VelocityProxy;
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.instance.block.rule.vanilla.RedstonePlacementRule;
import net.minestom.server.storage.StorageManager;
@ -52,8 +52,8 @@ public class Main {
OptifineSupport.enable();
VelocityProxy.enable("rBeJJ79W4MVU");
//BungeeCordProxy.enable();
//VelocityProxy.enable("rBeJJ79W4MVU");
BungeeCordProxy.enable();
// MojangAuth.init();