Added bungee forwarding support

This commit is contained in:
themode 2020-11-10 21:38:08 +01:00
parent bcee5424dc
commit bbf9f92b52
6 changed files with 83 additions and 14 deletions

View File

@ -0,0 +1,27 @@
package net.minestom.server.extras.bungee;
/**
* BungeeCord forwarding support. This does not count as a security feature and you will still be required to manage your firewall.
* <p>
* Please consider using {@link net.minestom.server.extras.velocity.VelocityProxy} instead.
*/
public final class BungeeCordProxy {
private static boolean enabled;
/**
* Enables bungee IP forwarding.
*/
public static void enable() {
BungeeCordProxy.enabled = true;
}
/**
* Gets if bungee IP forwarding is enabled.
*
* @return true if forwarding is enabled
*/
public static boolean isEnabled() {
return enabled;
}
}

View File

@ -14,13 +14,19 @@ import net.minestom.server.network.packet.client.handshake.HandshakePacket;
import net.minestom.server.network.player.NettyPlayerConnection;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.Readable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public final class PacketProcessor {
private final static Logger LOGGER = LoggerFactory.getLogger(PacketProcessor.class);
private final Map<ChannelHandlerContext, PlayerConnection> connectionPlayerConnectionMap = new ConcurrentHashMap<>();
// Protocols state
@ -34,7 +40,7 @@ public final class PacketProcessor {
this.playPacketsHandler = new ClientPlayPacketsHandler();
}
public void process(ChannelHandlerContext channel, InboundPacket packet) {
public void process(@NotNull ChannelHandlerContext channel, @NotNull InboundPacket packet) {
// Create the netty player connection object if not existing
PlayerConnection playerConnection = connectionPlayerConnectionMap.computeIfAbsent(
channel, c -> new NettyPlayerConnection((SocketChannel) channel.channel())
@ -51,7 +57,7 @@ public final class PacketProcessor {
// Should be handshake packet
if (packet.packetId == 0) {
HandshakePacket handshakePacket = new HandshakePacket();
handshakePacket.read(binaryReader);
safeRead(playerConnection, handshakePacket, binaryReader);
handshakePacket.process(playerConnection);
}
return;
@ -61,17 +67,17 @@ public final class PacketProcessor {
case PLAY:
final Player player = playerConnection.getPlayer();
ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketInstance(packet.packetId);
playPacket.read(binaryReader);
safeRead(playerConnection, playPacket, binaryReader);
player.addPacketToQueue(playPacket);
break;
case LOGIN:
final ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketInstance(packet.packetId);
loginPacket.read(binaryReader);
safeRead(playerConnection, loginPacket, binaryReader);
loginPacket.process(playerConnection);
break;
case STATUS:
final ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketInstance(packet.packetId);
statusPacket.read(binaryReader);
safeRead(playerConnection, statusPacket, binaryReader);
statusPacket.process(playerConnection);
break;
}
@ -91,4 +97,14 @@ public final class PacketProcessor {
public void removePlayerConnection(ChannelHandlerContext channel) {
connectionPlayerConnectionMap.remove(channel);
}
private void safeRead(@NotNull PlayerConnection connection, @NotNull Readable readable, @NotNull BinaryReader reader) {
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.");
}
}
}

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.extras.bungee.BungeeCordProxy;
import net.minestom.server.network.ConnectionState;
import net.minestom.server.network.packet.client.ClientPreplayPacket;
import net.minestom.server.network.packet.server.login.LoginDisconnectPacket;
@ -11,6 +12,8 @@ import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.binary.BinaryReader;
import org.jetbrains.annotations.NotNull;
import java.net.SocketAddress;
public class HandshakePacket implements ClientPreplayPacket {
/**
@ -18,6 +21,8 @@ public class HandshakePacket implements ClientPreplayPacket {
*/
private static final ColoredText INVALID_VERSION_TEXT = ColoredText.of(ChatColor.RED, "Invalid Version, please use " + MinecraftServer.VERSION_NAME);
private static final ColoredText INVALID_BUNGEE_FORWARDING = ColoredText.of(ChatColor.RED, "If you wish to use IP forwarding, please enable it in your BungeeCord config as well!");
private int protocolVersion;
private String serverAddress;
private int serverPort;
@ -33,6 +38,29 @@ public class HandshakePacket implements ClientPreplayPacket {
@Override
public void process(@NotNull PlayerConnection connection) {
if (BungeeCordProxy.isEnabled() && connection instanceof NettyPlayerConnection) {
NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) connection;
if (serverAddress != null) {
final String[] split = serverAddress.split("\00");
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());
nettyPlayerConnection.setRemoteAddress(socketAddress);
} else {
nettyPlayerConnection.sendPacket(new LoginDisconnectPacket(INVALID_BUNGEE_FORWARDING));
nettyPlayerConnection.disconnect();
return;
}
} else {
// Happen when a client ping the server, ignore
return;
}
}
switch (nextState) {
case 1:
connection.setConnectionState(ConnectionState.STATUS);

View File

@ -7,6 +7,7 @@ import demo.commands.GamemodeCommand;
import demo.commands.TestCommand;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.instance.block.rule.vanilla.RedstonePlacementRule;
import net.minestom.server.storage.StorageManager;
@ -51,8 +52,9 @@ public class Main {
PlayerInit.init();
//VelocityProxy.enable("rBeJJ79W4MVU");
BungeeCordProxy.enable();
//MojangAuth.init();
// MojangAuth.init();
minecraftServer.start("0.0.0.0", 25565, PlayerInit.getResponseDataConsumer());
}

View File

@ -5,8 +5,6 @@ import demo.generator.NoiseTestGenerator;
import net.minestom.server.MinecraftServer;
import net.minestom.server.benchmark.BenchmarkManager;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.data.Data;
import net.minestom.server.data.NbtDataImpl;
import net.minestom.server.entity.*;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.type.monster.EntityZombie;
@ -174,11 +172,7 @@ public class PlayerInit {
}
ItemStack itemStack = new ItemStack(Material.DIAMOND_PICKAXE, (byte) 64);
Data data = new NbtDataImpl();
data.set("test", 51);
itemStack.setData(data);
player.getInventory().addItemStack(itemStack);
System.out.println("test " + data.get("test"));
//player.getInventory().addItemStack(new ItemStack(Material.STONE, (byte)64));
});

View File

@ -5,6 +5,7 @@ import net.minestom.server.command.builder.Arguments;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.item.ItemStack;
public class TestCommand extends Command {
@ -17,7 +18,7 @@ public class TestCommand extends Command {
//addSyntax(this::execute, dynamicWord);
}
Argument test = ArgumentType.DynamicWord("testArg").fromRestrictions(value -> value.contains("a"));
Argument test = ArgumentType.ItemStack("item");
test.setCallback((source, value, error) -> {
System.out.println("ERROR " + error);
@ -29,7 +30,8 @@ public class TestCommand extends Command {
});
addSyntax((source, args) -> {
System.out.println("HEY IT WORKS");
ItemStack itemStack = args.getItemStack("item");
System.out.println("HEY IT WORKS "+itemStack.getMaterial());
}, test);
}