diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index bff1fa29b..67d7bd75d 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -60,10 +60,6 @@ public final class MinecraftServer { public static final int TICK_PER_SECOND = Integer.getInteger("minestom.tps", 20); public static final int TICK_MS = 1000 / TICK_PER_SECOND; - // Network monitoring - private static int rateLimit = 300; - private static int maxPacketSize = 30_000; - // In-Game Manager private static volatile ServerProcess serverProcess; @@ -112,42 +108,6 @@ public final class MinecraftServer { PacketUtils.broadcastPacket(PluginMessagePacket.getBrandPacket()); } - /** - * Gets the maximum number of packets a client can send over 1 second. - * - * @return the packet count limit over 1 second, 0 if not enabled - */ - public static int getRateLimit() { - return rateLimit; - } - - /** - * Changes the number of packet a client can send over 1 second without being disconnected. - * - * @param rateLimit the number of packet, 0 to disable - */ - public static void setRateLimit(int rateLimit) { - MinecraftServer.rateLimit = rateLimit; - } - - /** - * Gets the maximum packet size (in bytes) that a client can send without getting disconnected. - * - * @return the maximum packet size - */ - public static int getMaxPacketSize() { - return maxPacketSize; - } - - /** - * Changes the maximum packet size (in bytes) that a client can send without getting disconnected. - * - * @param maxPacketSize the new max packet size - */ - public static void setMaxPacketSize(int maxPacketSize) { - MinecraftServer.maxPacketSize = maxPacketSize; - } - /** * Gets the server difficulty showed in game option. * diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 1a4534ec6..ddd3ce43c 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -44,6 +44,7 @@ import net.minestom.server.inventory.PlayerInventory; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import net.minestom.server.item.metadata.WrittenBookMeta; +import net.minestom.server.listener.manager.PacketListenerManager; import net.minestom.server.message.ChatMessageType; import net.minestom.server.message.ChatPosition; import net.minestom.server.message.Messenger; @@ -106,6 +107,8 @@ import java.util.function.UnaryOperator; public class Player extends LivingEntity implements CommandSender, Localizable, HoverEventSource, Identified, NamedAndIdentified { private static final Component REMOVE_MESSAGE = Component.text("You have been removed from the server without reason.", NamedTextColor.RED); + private static final int PACKET_PER_TICK = Integer.getInteger("minestom.packet-per-tick", 20); + private static final int PACKET_QUEUE_SIZE = Integer.getInteger("minestom.packet-queue-size", 1000); private long lastKeepAlive; private boolean answerKeepAlive; @@ -319,9 +322,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable, @Override public void update(long time) { - // Network tick - this.playerConnection.update(); - // Process received packets interpretPacketQueue(); @@ -1731,8 +1731,13 @@ public class Player extends LivingEntity implements CommandSender, Localizable, @ApiStatus.Internal @ApiStatus.Experimental public void interpretPacketQueue() { + if (this.packets.size() >= PACKET_QUEUE_SIZE) { + kick(Component.text("Too Many Packets", NamedTextColor.RED)); + return; + } + final PacketListenerManager manager = MinecraftServer.getPacketListenerManager(); // This method is NOT thread-safe - this.packets.drain(packet -> MinecraftServer.getPacketListenerManager().processClientPacket(packet, this)); + this.packets.drain(packet -> manager.processClientPacket(packet, this), PACKET_PER_TICK); } /** diff --git a/src/main/java/net/minestom/server/network/PacketProcessor.java b/src/main/java/net/minestom/server/network/PacketProcessor.java index 25968c5af..e96ad530e 100644 --- a/src/main/java/net/minestom/server/network/PacketProcessor.java +++ b/src/main/java/net/minestom/server/network/PacketProcessor.java @@ -1,6 +1,5 @@ package net.minestom.server.network; -import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; import net.minestom.server.network.packet.client.ClientPacket; import net.minestom.server.network.packet.client.ClientPacketsHandler; @@ -41,11 +40,7 @@ public record PacketProcessor(@NotNull ClientPacketsHandler statusHandler, } public void process(@NotNull PlayerConnection connection, int packetId, ByteBuffer body) { - if (MinecraftServer.getRateLimit() > 0) { - // Increment packet count (checked in PlayerConnection#update) - connection.getPacketCounter().incrementAndGet(); - } - var packet = create(connection.getConnectionState(), packetId, body); + final ClientPacket packet = create(connection.getConnectionState(), packetId, body); if (packet instanceof ClientPreplayPacket prePlayPacket) { prePlayPacket.process(connection); } else { diff --git a/src/main/java/net/minestom/server/network/player/PlayerConnection.java b/src/main/java/net/minestom/server/network/player/PlayerConnection.java index c9f1a6e51..ac00bbbc7 100644 --- a/src/main/java/net/minestom/server/network/player/PlayerConnection.java +++ b/src/main/java/net/minestom/server/network/player/PlayerConnection.java @@ -1,11 +1,8 @@ package net.minestom.server.network.player; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Entity; import net.minestom.server.entity.Player; -import net.minestom.server.listener.manager.PacketListenerManager; import net.minestom.server.network.ConnectionState; import net.minestom.server.network.packet.server.SendablePacket; import org.jetbrains.annotations.ApiStatus; @@ -15,57 +12,21 @@ import org.jetbrains.annotations.Nullable; import java.net.SocketAddress; import java.util.Collection; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; /** * A PlayerConnection is an object needed for all created {@link Player}. * It can be extended to create a new kind of player (NPC for instance). */ public abstract class PlayerConnection { - protected static final PacketListenerManager PACKET_LISTENER_MANAGER = MinecraftServer.getPacketListenerManager(); - private Player player; private volatile ConnectionState connectionState; volatile boolean online; - // Text used to kick client sending too many packets - private static final Component rateLimitKickMessage = Component.text("Too Many Packets", NamedTextColor.RED); - - //Connection Stats - private final AtomicInteger packetCounter = new AtomicInteger(0); - private final AtomicInteger lastPacketCounter = new AtomicInteger(0); - private short tickCounter = 0; - public PlayerConnection() { this.online = true; this.connectionState = ConnectionState.UNKNOWN; } - /** - * Updates values related to the network connection. - */ - public void update() { - // Check rate limit - if (MinecraftServer.getRateLimit() > 0) { - tickCounter++; - if (tickCounter % MinecraftServer.TICK_PER_SECOND == 0 && tickCounter > 0) { - tickCounter = 0; - // Retrieve the packet count - final int count = packetCounter.getAndSet(0); - this.lastPacketCounter.set(count); - if (count > MinecraftServer.getRateLimit()) { - // Sent too many packets - player.kick(rateLimitKickMessage); - disconnect(); - } - } - } - } - - public @NotNull AtomicInteger getPacketCounter() { - return packetCounter; - } - /** * Returns a printable identifier for this connection, will be the player username * or the connection remote address. @@ -189,15 +150,6 @@ public abstract class PlayerConnection { return connectionState; } - /** - * Gets the number of packet the client sent over the last second. - * - * @return the number of packet sent over the last second - */ - public int getLastPacketCounter() { - return lastPacketCounter.get(); - } - @Override public String toString() { return "PlayerConnection{" +