From 145d57679e722573acb4b6e9bb9c71a0601e2322 Mon Sep 17 00:00:00 2001 From: "Pantera (Mad_Daniel)" <89838384+Pantera07@users.noreply.github.com> Date: Wed, 11 Oct 2023 19:00:57 +0900 Subject: [PATCH 01/15] Better Packet Limiter Reference: https://github.com/Spottedleaf/PacketLimiter --- .../limbo/configuration/LimboConfig.java | 18 +-- .../connection/ClientChannelInitializer.java | 4 +- .../pipeline/ChannelTrafficHandler.java | 112 ++++++++++++------ src/main/resources/settings.yml | 20 ++-- 4 files changed, 96 insertions(+), 58 deletions(-) diff --git a/src/main/java/ua/nanit/limbo/configuration/LimboConfig.java b/src/main/java/ua/nanit/limbo/configuration/LimboConfig.java index 615b9e22..11cceb52 100644 --- a/src/main/java/ua/nanit/limbo/configuration/LimboConfig.java +++ b/src/main/java/ua/nanit/limbo/configuration/LimboConfig.java @@ -73,8 +73,8 @@ public final class LimboConfig { private boolean useTrafficLimits; private int maxPacketSize; - private int maxPacketsPerSec; - private int maxBytesPerSec; + private double interval; + private double maxPacketRate; public LimboConfig(Path root) { this.root = root; @@ -134,9 +134,9 @@ public void load() throws Exception { workerGroupSize = conf.node("netty", "threads", "workerGroup").getInt(4); useTrafficLimits = conf.node("traffic", "enable").getBoolean(false); - maxPacketSize = conf.node("traffic", "packetSize").getInt(-1); - maxPacketsPerSec = conf.node("traffic", "packets").getInt(-1); - maxBytesPerSec = conf.node("traffic", "bytes").getInt(-1); + maxPacketSize = conf.node("traffic", "maxPacketSize").getInt(-1); + interval = conf.node("traffic", "interval").getDouble(-1.0); + maxPacketRate = conf.node("traffic", "maxPacketRate").getDouble(-1.0); } private BufferedReader getReader() throws IOException { @@ -269,11 +269,11 @@ public int getMaxPacketSize() { return maxPacketSize; } - public int getMaxPacketsPerSec() { - return maxPacketsPerSec; + public double getInterval() { + return interval; } - public int getMaxBytesPerSec() { - return maxBytesPerSec; + public double getMaxPacketRate() { + return maxPacketRate; } } diff --git a/src/main/java/ua/nanit/limbo/connection/ClientChannelInitializer.java b/src/main/java/ua/nanit/limbo/connection/ClientChannelInitializer.java index 6f7fc94e..57d7944e 100644 --- a/src/main/java/ua/nanit/limbo/connection/ClientChannelInitializer.java +++ b/src/main/java/ua/nanit/limbo/connection/ClientChannelInitializer.java @@ -50,8 +50,8 @@ protected void initChannel(Channel channel) { if (server.getConfig().isUseTrafficLimits()) { pipeline.addLast("traffic_limit", new ChannelTrafficHandler( server.getConfig().getMaxPacketSize(), - server.getConfig().getMaxPacketsPerSec(), - server.getConfig().getMaxBytesPerSec() + server.getConfig().getInterval(), + server.getConfig().getMaxPacketRate() )); } diff --git a/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java b/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java index b9acaf1b..7d1babcc 100644 --- a/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java +++ b/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java @@ -6,21 +6,18 @@ import org.jetbrains.annotations.NotNull; import ua.nanit.limbo.server.Logger; -public class ChannelTrafficHandler extends ChannelInboundHandlerAdapter { - - private final int packetSize; - private final int packetsPerSec; - private final int bytesPerSec; +import java.util.Arrays; - private int packetsCounter; - private int bytesCounter; +public class ChannelTrafficHandler extends ChannelInboundHandlerAdapter { - private long lastPacket; + private final int maxPacketSize; + private final double maxPacketRate; + private final PacketBucket packetBucket; - public ChannelTrafficHandler(int packetSize, int packetsPerSec, int bytesPerSec) { - this.packetSize = packetSize; - this.packetsPerSec = packetsPerSec; - this.bytesPerSec = bytesPerSec; + public ChannelTrafficHandler(int maxPacketSize, double interval, double maxPacketRate) { + this.maxPacketSize = maxPacketSize; + this.maxPacketRate = maxPacketRate; + this.packetBucket = (interval > 0.0 && maxPacketRate > 0.0) ? new PacketBucket(interval * 1000.0, 150) : null; } @Override @@ -29,47 +26,86 @@ public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) ByteBuf in = (ByteBuf) msg; int bytes = in.readableBytes(); - if (packetSize > 0 && bytes > packetSize) { - closeConnection(ctx, "Closed %s due too large packet size (%d bytes)", ctx.channel().remoteAddress(), bytes); + if (maxPacketSize > 0 && bytes > maxPacketSize) { + closeConnection(ctx, "Closed %s due to large packet size (%d bytes)", ctx.channel().remoteAddress(), bytes); return; } - if (!measureTraffic(ctx, bytes)) return; + if (packetBucket != null) { + packetBucket.incrementPackets(1); + if (packetBucket.getCurrentPacketRate() > maxPacketRate) { + closeConnection(ctx, "Closed %s due to many packets sent (%d in the last %.1f seconds)", ctx.channel().remoteAddress(), packetBucket.sum, (packetBucket.intervalTime / 1000.0)); + return; + } + } } super.channelRead(ctx, msg); } - private boolean measureTraffic(ChannelHandlerContext ctx, int bytes) { - if (packetsPerSec < 0 && bytesPerSec < 0) return true; - - long time = System.currentTimeMillis(); + private void closeConnection(ChannelHandlerContext ctx, String reason, Object... args) { + ctx.close(); + Logger.info(reason, args); + } - if (time - lastPacket >= 1000) { - bytesCounter = 0; - packetsCounter = 0; + private static class PacketBucket { + private static final double NANOSECONDS_TO_MILLISECONDS = 1.0e-6; + private static final int MILLISECONDS_TO_SECONDS = 1000; + + private final double intervalTime; + private final double intervalResolution; + private final int[] data; + private int newestData; + private double lastBucketTime; + private int sum; + + public PacketBucket(final double intervalTime, final int totalBuckets) { + this.intervalTime = intervalTime; + this.intervalResolution = intervalTime / totalBuckets; + this.data = new int[totalBuckets]; } - packetsCounter++; - bytesCounter += bytes; + public void incrementPackets(final int packets) { + double timeMs = System.nanoTime() * NANOSECONDS_TO_MILLISECONDS; + double timeDelta = timeMs - this.lastBucketTime; - if (packetsPerSec > 0 && packetsCounter > packetsPerSec) { - closeConnection(ctx, "Closed %s due too frequent packet sending (%d per sec)", ctx.channel().remoteAddress(), packetsCounter); - return false; - } + if (timeDelta < 0.0) { + timeDelta = 0.0; + } - if (bytesPerSec > 0 && bytesCounter > bytesPerSec) { - closeConnection(ctx, "Closed %s due too many bytes sent per second (%d per sec)", ctx.channel().remoteAddress(), bytesCounter); - return false; - } + if (timeDelta < this.intervalResolution) { + this.data[this.newestData] += packets; + this.sum += packets; + return; + } - lastPacket = time; + int bucketsToMove = (int)(timeDelta / this.intervalResolution); + double nextBucketTime = this.lastBucketTime + bucketsToMove * this.intervalResolution; - return true; - } + if (bucketsToMove >= this.data.length) { + Arrays.fill(this.data, 0); + this.data[0] = packets; + this.sum = packets; + this.newestData = 0; + this.lastBucketTime = timeMs; + return; + } - private void closeConnection(ChannelHandlerContext ctx, String reason, Object... args) { - ctx.close(); - Logger.info(reason, args); + for (int i = 1; i < bucketsToMove; ++i) { + int index = (this.newestData + i) % this.data.length; + this.sum -= this.data[index]; + this.data[index] = 0; + } + + int newestDataIndex = (this.newestData + bucketsToMove) % this.data.length; + this.sum += packets - this.data[newestDataIndex]; + this.data[newestDataIndex] = packets; + this.newestData = newestDataIndex; + this.lastBucketTime = nextBucketTime; + } + + public double getCurrentPacketRate() { + return this.sum / (this.intervalTime / MILLISECONDS_TO_SECONDS); + } } } diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 62aaceb2..2b584793 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -114,18 +114,20 @@ netty: bossGroup: 1 workerGroup: 4 -# [Experimental] # Options to check incoming traffic and kick potentially malicious connections. # Take into account that player can send many small packets, for example just moving mouse. traffic: # If true, then additional handler will be added to channel pipeline - enable: false + enable: true # Max packet size in bytes # Unlimited if -1 - packetSize: 1024 - # How many packets per second allowed for single connection - # Ignored if -1 - packets: -1 - # How many bytes per second allowed for single connection - # Ignored if -1 - bytes: 2048 \ No newline at end of file + maxPacketSize: 4096 + # The interval to measure packets over + # Lowering this value will limit peak packets from players which would target people with bad connections + # Raising this value will allow higher peak packet rates, which will help with people who have poor connections + # Ignored if -1.0 + interval: 7.0 + # The maximum maximum packets per second for players + # It is measured over the configured interval + # Ignored if -1.0 + maxPacketRate: 500.0 From 9dc7027a22be0cb76f913c9aeeadf410c88cfe31 Mon Sep 17 00:00:00 2001 From: Michel Elkenwaat Date: Wed, 22 Nov 2023 16:29:15 +0100 Subject: [PATCH 02/15] feat: optimize VarInt writing (See https://steinborn.me/posts/performance/how-fast-can-you-write-a-varint/) --- .../ua/nanit/limbo/protocol/ByteMessage.java | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/java/ua/nanit/limbo/protocol/ByteMessage.java b/src/main/java/ua/nanit/limbo/protocol/ByteMessage.java index 65fe318e..e6cdf677 100644 --- a/src/main/java/ua/nanit/limbo/protocol/ByteMessage.java +++ b/src/main/java/ua/nanit/limbo/protocol/ByteMessage.java @@ -74,14 +74,37 @@ public int readVarInt() { } public void writeVarInt(int value) { - while (true) { - if ((value & 0xFFFFFF80) == 0) { - buf.writeByte(value); - return; - } + // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes + // that the proxy will write, to improve inlining. + if ((value & (0xFFFFFFFF << 7)) == 0) { + buf.writeByte(value); + } else if ((value & (0xFFFFFFFF << 14)) == 0) { + int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); + buf.writeShort(w); + } else { + writeVarIntFull(value); + } + } - buf.writeByte(value & 0x7F | 0x80); - value >>>= 7; + private void writeVarIntFull(final int value) { + // See https://steinborn.me/posts/performance/how-fast-can-you-write-a-varint/ + if ((value & (0xFFFFFFFF << 7)) == 0) { + buf.writeByte(value); + } else if ((value & (0xFFFFFFFF << 14)) == 0) { + int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); + buf.writeShort(w); + } else if ((value & (0xFFFFFFFF << 21)) == 0) { + int w = (value & 0x7F | 0x80) << 16 | ((value >>> 7) & 0x7F | 0x80) << 8 | (value >>> 14); + buf.writeMedium(w); + } else if ((value & (0xFFFFFFFF << 28)) == 0) { + int w = (value & 0x7F | 0x80) << 24 | (((value >>> 7) & 0x7F | 0x80) << 16) + | ((value >>> 14) & 0x7F | 0x80) << 8 | (value >>> 21); + buf.writeInt(w); + } else { + int w = (value & 0x7F | 0x80) << 24 | ((value >>> 7) & 0x7F | 0x80) << 16 + | ((value >>> 14) & 0x7F | 0x80) << 8 | ((value >>> 21) & 0x7F | 0x80); + buf.writeInt(w); + buf.writeByte(value >>> 28); } } From ebe9c19a0559e649e3f7fd8de8ad6ed4be57cbf5 Mon Sep 17 00:00:00 2001 From: "Pantera (Mad_Daniel)" <89838384+Pantera07@users.noreply.github.com> Date: Mon, 22 Jan 2024 10:39:52 +0900 Subject: [PATCH 03/15] Increase maxPacketSize --- src/main/resources/settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 2b584793..478b15cc 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -121,7 +121,7 @@ traffic: enable: true # Max packet size in bytes # Unlimited if -1 - maxPacketSize: 4096 + maxPacketSize: 8192 # The interval to measure packets over # Lowering this value will limit peak packets from players which would target people with bad connections # Raising this value will allow higher peak packet rates, which will help with people who have poor connections From f5684107c8177b45b7b287b32446736358de56e1 Mon Sep 17 00:00:00 2001 From: BoomEaro <21033866+BoomEaro@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:06:07 +0300 Subject: [PATCH 04/15] Add support for 1.20.5 --- .../limbo/connection/ClientConnection.java | 15 +++- .../limbo/connection/PacketSnapshots.java | 37 +++++++++ .../nanit/limbo/protocol/MetadataWriter.java | 10 +++ .../configuration/PacketRegistryData.java | 12 +++ .../packets/login/PacketLoginSuccess.java | 3 + .../protocol/packets/play/PacketJoinGame.java | 28 ++++++- .../nanit/limbo/protocol/registry/State.java | 75 ++++++++++++------- .../limbo/protocol/registry/Version.java | 3 +- .../nanit/limbo/world/DimensionRegistry.java | 36 ++++++--- 9 files changed, 178 insertions(+), 41 deletions(-) create mode 100644 src/main/java/ua/nanit/limbo/protocol/MetadataWriter.java diff --git a/src/main/java/ua/nanit/limbo/connection/ClientConnection.java b/src/main/java/ua/nanit/limbo/connection/ClientConnection.java index a11f46b3..1d988472 100644 --- a/src/main/java/ua/nanit/limbo/connection/ClientConnection.java +++ b/src/main/java/ua/nanit/limbo/connection/ClientConnection.java @@ -115,7 +115,7 @@ public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) public void handlePacket(Object packet) { if (packet instanceof Packet) { - ((Packet)packet).handle(this, server); + ((Packet) packet).handle(this, server); } } @@ -199,7 +199,14 @@ public void onLoginAcknowledgedReceived() { if (PacketSnapshots.PACKET_PLUGIN_MESSAGE != null) writePacket(PacketSnapshots.PACKET_PLUGIN_MESSAGE); - writePacket(PacketSnapshots.PACKET_REGISTRY_DATA); + + if (clientVersion.moreOrEqual(Version.V1_20_5)) { + for (PacketSnapshot packet : PacketSnapshots.PACKETS_REGISTRY_DATA) { + writePacket(packet); + } + } else { + writePacket(PacketSnapshots.PACKET_REGISTRY_DATA); + } sendPacket(PacketSnapshots.PACKET_FINISH_CONFIGURATION); } @@ -272,7 +279,7 @@ public void updateVersion(Version version) { } public void setAddress(String host) { - this.address = new InetSocketAddress(host, ((InetSocketAddress)this.address).getPort()); + this.address = new InetSocketAddress(host, ((InetSocketAddress) this.address).getPort()); } boolean checkBungeeGuardHandshake(String handshake) { @@ -333,7 +340,7 @@ boolean checkVelocityKeyIntegrity(ByteMessage buf) { byte[] mySignature = mac.doFinal(data); if (!MessageDigest.isEqual(signature, mySignature)) return false; - } catch (InvalidKeyException |java.security.NoSuchAlgorithmException e) { + } catch (InvalidKeyException | java.security.NoSuchAlgorithmException e) { throw new AssertionError(e); } int version = buf.readVarInt(); diff --git a/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java b/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java index 0c82723f..f5f5797e 100644 --- a/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java +++ b/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java @@ -17,6 +17,9 @@ package ua.nanit.limbo.connection; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; import ua.nanit.limbo.LimboConstants; import ua.nanit.limbo.protocol.PacketSnapshot; import ua.nanit.limbo.protocol.packets.configuration.PacketFinishConfiguration; @@ -27,6 +30,7 @@ import ua.nanit.limbo.server.data.Title; import ua.nanit.limbo.util.NbtMessageUtil; import ua.nanit.limbo.util.UuidUtil; +import ua.nanit.limbo.world.Dimension; import java.util.ArrayList; import java.util.Collections; @@ -60,6 +64,7 @@ public final class PacketSnapshots { public static PacketSnapshot PACKET_TITLE_LEGACY_TIMES; public static PacketSnapshot PACKET_REGISTRY_DATA; + public static List PACKETS_REGISTRY_DATA; public static PacketSnapshot PACKET_FINISH_CONFIGURATION; public static List PACKETS_EMPTY_CHUNKS; @@ -193,6 +198,38 @@ public static void initPackets(LimboServer server) { packetRegistryData.setDimensionRegistry(server.getDimensionRegistry()); PACKET_REGISTRY_DATA = PacketSnapshot.of(packetRegistryData); + + Dimension dimension1_20_5 = server.getDimensionRegistry().getDimension_1_20_5(); + List packetRegistries = new ArrayList<>(); + CompoundBinaryTag dimensionTag = dimension1_20_5.getData(); + for (String registryType : dimensionTag.keySet()) { + CompoundBinaryTag compundRegistryType = dimensionTag.getCompound(registryType); + + PacketRegistryData registryData = new PacketRegistryData(); + registryData.setDimensionRegistry(server.getDimensionRegistry()); + + ListBinaryTag values = compundRegistryType.getList("value"); + registryData.setMetadataWriter((message, version) -> { + message.writeString(registryType); + + message.writeVarInt(values.size()); + for (BinaryTag entry : values) { + CompoundBinaryTag entryTag = (CompoundBinaryTag) entry; + + String name = entryTag.getString("name"); + CompoundBinaryTag element = entryTag.getCompound("element"); + + message.writeString(name); + message.writeBoolean(true); + message.writeNamelessCompoundTag(element); + } + }); + + packetRegistries.add(PacketSnapshot.of(registryData)); + } + + PACKETS_REGISTRY_DATA = packetRegistries; + PACKET_FINISH_CONFIGURATION = PacketSnapshot.of(new PacketFinishConfiguration()); PacketGameEvent packetGameEvent = new PacketGameEvent(); diff --git a/src/main/java/ua/nanit/limbo/protocol/MetadataWriter.java b/src/main/java/ua/nanit/limbo/protocol/MetadataWriter.java new file mode 100644 index 00000000..54a46f58 --- /dev/null +++ b/src/main/java/ua/nanit/limbo/protocol/MetadataWriter.java @@ -0,0 +1,10 @@ +package ua.nanit.limbo.protocol; + +import ua.nanit.limbo.protocol.registry.Version; + +@FunctionalInterface +public interface MetadataWriter { + + void writeData(ByteMessage message, Version version); + +} diff --git a/src/main/java/ua/nanit/limbo/protocol/packets/configuration/PacketRegistryData.java b/src/main/java/ua/nanit/limbo/protocol/packets/configuration/PacketRegistryData.java index 3f3a6e9f..7b284aeb 100644 --- a/src/main/java/ua/nanit/limbo/protocol/packets/configuration/PacketRegistryData.java +++ b/src/main/java/ua/nanit/limbo/protocol/packets/configuration/PacketRegistryData.java @@ -1,6 +1,7 @@ package ua.nanit.limbo.protocol.packets.configuration; import ua.nanit.limbo.protocol.ByteMessage; +import ua.nanit.limbo.protocol.MetadataWriter; import ua.nanit.limbo.protocol.PacketOut; import ua.nanit.limbo.protocol.registry.Version; import ua.nanit.limbo.world.DimensionRegistry; @@ -8,13 +9,24 @@ public class PacketRegistryData implements PacketOut { private DimensionRegistry dimensionRegistry; + private MetadataWriter metadataWriter; public void setDimensionRegistry(DimensionRegistry dimensionRegistry) { this.dimensionRegistry = dimensionRegistry; } + public void setMetadataWriter(MetadataWriter metadataWriter) { + this.metadataWriter = metadataWriter; + } + @Override public void encode(ByteMessage msg, Version version) { + if (metadataWriter != null) { + if (version.moreOrEqual(Version.V1_20_5)) { + metadataWriter.writeData(msg, version); + return; + } + } msg.writeNamelessCompoundTag(dimensionRegistry.getCodec_1_20()); } } diff --git a/src/main/java/ua/nanit/limbo/protocol/packets/login/PacketLoginSuccess.java b/src/main/java/ua/nanit/limbo/protocol/packets/login/PacketLoginSuccess.java index a07dd2ae..309fb3e5 100644 --- a/src/main/java/ua/nanit/limbo/protocol/packets/login/PacketLoginSuccess.java +++ b/src/main/java/ua/nanit/limbo/protocol/packets/login/PacketLoginSuccess.java @@ -49,6 +49,9 @@ public void encode(ByteMessage msg, Version version) { if (version.moreOrEqual(Version.V1_19)) { msg.writeVarInt(0); } + if (version.moreOrEqual(Version.V1_20_5)) { + msg.writeBoolean(true); + } } @Override diff --git a/src/main/java/ua/nanit/limbo/protocol/packets/play/PacketJoinGame.java b/src/main/java/ua/nanit/limbo/protocol/packets/play/PacketJoinGame.java index fbb190fd..ffefa2b1 100644 --- a/src/main/java/ua/nanit/limbo/protocol/packets/play/PacketJoinGame.java +++ b/src/main/java/ua/nanit/limbo/protocol/packets/play/PacketJoinGame.java @@ -39,6 +39,7 @@ public class PacketJoinGame implements PacketOut { private boolean isDebug; private boolean isFlat; private boolean limitedCrafting; + private boolean secureProfile; public void setEntityId(int entityId) { this.entityId = entityId; @@ -100,6 +101,10 @@ public void setLimitedCrafting(boolean limitedCrafting) { this.limitedCrafting = limitedCrafting; } + public void setSecureProfile(boolean secureProfile) { + this.secureProfile = secureProfile; + } + @Override public void encode(ByteMessage msg, Version version) { msg.writeInt(entityId); @@ -255,7 +260,7 @@ public void encode(ByteMessage msg, Version version) { msg.writeVarInt(0); } - if (version.moreOrEqual(Version.V1_20_2)) { + if (version.fromTo(Version.V1_20_2, Version.V1_20_3)) { msg.writeBoolean(isHardcore); msg.writeStringsArray(worldNames); msg.writeVarInt(maxPlayers); @@ -274,6 +279,27 @@ public void encode(ByteMessage msg, Version version) { msg.writeBoolean(false); msg.writeVarInt(0); } + + if (version.moreOrEqual(Version.V1_20_5)) { + msg.writeBoolean(isHardcore); + msg.writeStringsArray(worldNames); + msg.writeVarInt(maxPlayers); + msg.writeVarInt(viewDistance); + msg.writeVarInt(viewDistance); // Simulation Distance + msg.writeBoolean(reducedDebugInfo); + msg.writeBoolean(enableRespawnScreen); + msg.writeBoolean(limitedCrafting); + msg.writeVarInt(dimensionRegistry.getDimension_1_20_5().getId()); + msg.writeString(worldName); + msg.writeLong(hashedSeed); + msg.writeByte(gameMode); + msg.writeByte(previousGameMode); + msg.writeBoolean(isDebug); + msg.writeBoolean(isFlat); + msg.writeBoolean(false); + msg.writeVarInt(0); + msg.writeBoolean(secureProfile); + } } } diff --git a/src/main/java/ua/nanit/limbo/protocol/registry/State.java b/src/main/java/ua/nanit/limbo/protocol/registry/State.java index f8564f70..52a30839 100644 --- a/src/main/java/ua/nanit/limbo/protocol/registry/State.java +++ b/src/main/java/ua/nanit/limbo/protocol/registry/State.java @@ -66,7 +66,7 @@ public enum State { ); serverBound.register( PacketLoginAcknowledged::new, - map(0x03, V1_20_2, V1_20_3) + map(0x03, V1_20_2, V1_20_5) ); clientBound.register(PacketDisconnect::new, map(0x00, Version.getMin(), Version.getMax()) @@ -83,36 +83,44 @@ public enum State { { clientBound.register( PacketPluginMessage::new, - map(0x00, V1_20_2, V1_20_3) + map(0x00, V1_20_2, V1_20_3), + map(0x01, V1_20_5, V1_20_5) ); clientBound.register( PacketDisconnect::new, - map(0x01, V1_20_2, V1_20_3) + map(0x01, V1_20_2, V1_20_3), + map(0x02, V1_20_5, V1_20_5) ); clientBound.register( PacketFinishConfiguration::new, - map(0x02, V1_20_2, V1_20_3) + map(0x02, V1_20_2, V1_20_3), + map(0x03, V1_20_5, V1_20_5) ); clientBound.register( PacketKeepAlive::new, - map(0x03, V1_20_2, V1_20_3) + map(0x03, V1_20_2, V1_20_3), + map(0x05, V1_20_5, V1_20_5) ); clientBound.register( PacketRegistryData::new, - map(0x05, V1_20_2, V1_20_3) + map(0x05, V1_20_2, V1_20_3), + map(0x07, V1_20_5, V1_20_5) ); serverBound.register( PacketPluginMessage::new, - map(0x01, V1_20_2, V1_20_3) + map(0x01, V1_20_2, V1_20_3), + map(0x02, V1_20_2, V1_20_5) ); serverBound.register( PacketFinishConfiguration::new, - map(0x02, V1_20_2, V1_20_3) + map(0x02, V1_20_2, V1_20_3), + map(0x03, V1_20_5, V1_20_5) ); serverBound.register( PacketKeepAlive::new, - map(0x03, V1_20_2, V1_20_3) + map(0x03, V1_20_2, V1_20_3), + map(0x04, V1_20_5, V1_20_5) ); } }, @@ -132,7 +140,8 @@ public enum State { map(0x11, V1_19_3, V1_19_3), map(0x12, V1_19_4, V1_20), map(0x14, V1_20_2, V1_20_2), - map(0x15, V1_20_3, V1_20_3) + map(0x15, V1_20_3, V1_20_3), + map(0x18, V1_20_5, V1_20_5) ); clientBound.register(PacketDeclareCommands::new, @@ -144,7 +153,7 @@ public enum State { map(0x0F, V1_19, V1_19_1), map(0x0E, V1_19_3, V1_19_3), map(0x10, V1_19_4, V1_20), - map(0x11, V1_20_2, V1_20_3) + map(0x11, V1_20_2, V1_20_5) ); clientBound.register(PacketJoinGame::new, map(0x01, V1_7_2, V1_8), @@ -158,7 +167,8 @@ public enum State { map(0x25, V1_19_1, V1_19_1), map(0x24, V1_19_3, V1_19_3), map(0x28, V1_19_4, V1_20), - map(0x29, V1_20_2, V1_20_3) + map(0x29, V1_20_2, V1_20_3), + map(0x2B, V1_20_5, V1_20_5) ); clientBound.register(PacketPluginMessage::new, map(0x19, V1_13, V1_13_2), @@ -171,7 +181,8 @@ public enum State { map(0x16, V1_19_1, V1_19_1), map(0x15, V1_19_3, V1_19_3), map(0x17, V1_19_4, V1_20), - map(0x18, V1_20_2, V1_20_3) + map(0x18, V1_20_2, V1_20_3), + map(0x19, V1_20_5, V1_20_5) ); clientBound.register(PacketPlayerAbilities::new, map(0x39, V1_7_2, V1_8), @@ -187,7 +198,8 @@ public enum State { map(0x31, V1_19_1, V1_19_1), map(0x30, V1_19_3, V1_19_3), map(0x34, V1_19_4, V1_20), - map(0x36, V1_20_2, V1_20_3) + map(0x36, V1_20_2, V1_20_3), + map(0x38, V1_20_5, V1_20_5) ); clientBound.register(PacketPlayerPositionAndLook::new, map(0x08, V1_7_2, V1_8), @@ -203,7 +215,8 @@ public enum State { map(0x39, V1_19_1, V1_19_1), map(0x38, V1_19_3, V1_19_3), map(0x3C, V1_19_4, V1_20), - map(0x3E, V1_20_2, V1_20_3) + map(0x3E, V1_20_2, V1_20_3), + map(0x40, V1_20_5, V1_20_5) ); clientBound.register(PacketKeepAlive::new, map(0x00, V1_7_2, V1_8), @@ -218,7 +231,8 @@ public enum State { map(0x20, V1_19_1, V1_19_1), map(0x1F, V1_19_3, V1_19_3), map(0x23, V1_19_4, V1_20), - map(0x24, V1_20_2, V1_20_3) + map(0x24, V1_20_2, V1_20_3), + map(0x26, V1_20_5, V1_20_5) ); clientBound.register(PacketChatMessage::new, map(0x02, V1_7_2, V1_8), @@ -232,7 +246,8 @@ public enum State { map(0x60, V1_19_3, V1_19_3), map(0x64, V1_19_4, V1_20), map(0x67, V1_20_2, V1_20_2), - map(0x69, V1_20_3, V1_20_3) + map(0x69, V1_20_3, V1_20_3), + map(0x6C, V1_20_5, V1_20_5) ); clientBound.register(PacketBossBar::new, map(0x0C, V1_9, V1_14_4), @@ -241,7 +256,7 @@ public enum State { map(0x0D, V1_17, V1_18_2), map(0x0A, V1_19, V1_19_3), map(0x0B, V1_19_4, V1_20), - map(0x0A, V1_20_2, V1_20_3) + map(0x0A, V1_20_2, V1_20_5) ); clientBound.register(PacketPlayerInfo::new, map(0x38, V1_7_2, V1_8), @@ -257,7 +272,8 @@ public enum State { map(0x37, V1_19_1, V1_19_1), map(0x36, V1_19_3, V1_19_3), map(0x3A, V1_19_4, V1_20), - map(0x3C, V1_20_2, V1_20_3) + map(0x3C, V1_20_2, V1_20_3), + map(0x3E, V1_20_5, V1_20_5) ); clientBound.register(PacketTitleLegacy::new, map(0x45, V1_8, V1_11_1), @@ -275,7 +291,8 @@ public enum State { map(0x5B, V1_19_3, V1_19_3), map(0x5F, V1_19_4, V1_20), map(0x61, V1_20_2, V1_20_2), - map(0x63, V1_20_3, V1_20_3) + map(0x63, V1_20_3, V1_20_3), + map(0x65, V1_20_5, V1_20_5) ); clientBound.register(PacketTitleSetSubTitle::new, map(0x57, V1_17, V1_17_1), @@ -284,7 +301,8 @@ public enum State { map(0x59, V1_19_3, V1_19_3), map(0x5D, V1_19_4, V1_20), map(0x5F, V1_20_2, V1_20_2), - map(0x61, V1_20_3, V1_20_3) + map(0x61, V1_20_3, V1_20_3), + map(0x63, V1_20_5, V1_20_5) ); clientBound.register(PacketTitleTimes::new, map(0x5A, V1_17, V1_17_1), @@ -293,7 +311,8 @@ public enum State { map(0x5C, V1_19_3, V1_19_3), map(0x60, V1_19_4, V1_20), map(0x62, V1_20_2, V1_20_2), - map(0x64, V1_20_3, V1_20_3) + map(0x64, V1_20_3, V1_20_3), + map(0x66, V1_20_5, V1_20_5) ); clientBound.register(PacketPlayerListHeader::new, map(0x47, V1_8, V1_8), @@ -312,19 +331,23 @@ public enum State { map(0x61, V1_19_3, V1_19_3), map(0x65, V1_19_4, V1_20), map(0x68, V1_20_2, V1_20_2), - map(0x6A, V1_20_3, V1_20_3) + map(0x6A, V1_20_3, V1_20_3), + map(0x6D, V1_20_5, V1_20_5) ); clientBound.register(PacketSpawnPosition::new, map(0x4C, V1_19_3, V1_19_3), map(0x50, V1_19_4, V1_20), map(0x52, V1_20_2, V1_20_2), - map(0x54, V1_20_3, V1_20_3) + map(0x54, V1_20_3, V1_20_3), + map(0x56, V1_20_5, V1_20_5) ); clientBound.register(PacketGameEvent::new, - map(0x20, V1_20_3, V1_20_3) + map(0x20, V1_20_3, V1_20_3), + map(0x22, V1_20_5, V1_20_5) ); clientBound.register(PacketEmptyChunk::new, - map(0x25, V1_20_3, V1_20_3) + map(0x25, V1_20_3, V1_20_3), + map(0x27, V1_20_5, V1_20_5) ); } }; diff --git a/src/main/java/ua/nanit/limbo/protocol/registry/Version.java b/src/main/java/ua/nanit/limbo/protocol/registry/Version.java index 3418c4b9..81b91559 100644 --- a/src/main/java/ua/nanit/limbo/protocol/registry/Version.java +++ b/src/main/java/ua/nanit/limbo/protocol/registry/Version.java @@ -71,7 +71,8 @@ public enum Version { V1_20(763), // 1.20.1 has same protocol number V1_20_2(764), - V1_20_3(765); + V1_20_3(765), + V1_20_5(766); private static final Map VERSION_MAP; private static final Version MAX; diff --git a/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java b/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java index d90f8c97..49954b61 100644 --- a/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java +++ b/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java @@ -33,6 +33,7 @@ public final class DimensionRegistry { private Dimension defaultDimension_1_16; private Dimension defaultDimension_1_18_2; + private Dimension dimension_1_20_5; private CompoundBinaryTag codec_1_16; private CompoundBinaryTag codec_1_18_2; @@ -82,6 +83,10 @@ public Dimension getDefaultDimension_1_18_2() { return defaultDimension_1_18_2; } + public Dimension getDimension_1_20_5() { + return dimension_1_20_5; + } + public void load(String def) throws IOException { codec_1_16 = readCodecFile("/dimension/codec_1_16.snbt"); codec_1_18_2 = readCodecFile("/dimension/codec_1_18_2.snbt"); @@ -94,6 +99,8 @@ public void load(String def) throws IOException { defaultDimension_1_16 = getDefaultDimension(def, codec_1_16); defaultDimension_1_18_2 = getDefaultDimension(def, codec_1_18_2); + + dimension_1_20_5 = getModernDimension(def, codec_1_20); } private Dimension getDefaultDimension(String def, CompoundBinaryTag tag) { @@ -116,24 +123,35 @@ private Dimension getDefaultDimension(String def, CompoundBinaryTag tag) { } } + private Dimension getModernDimension(String def, CompoundBinaryTag tag) { + switch (def.toLowerCase()) { + case "overworld": + return new Dimension(0, "minecraft:overworld", tag); + case "the_nether": + return new Dimension(2, "minecraft:nether", tag); + case "the_end": + return new Dimension(3, "minecraft:the_end", tag); + default: + Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def); + return new Dimension(3, "minecraft:the_end", tag); + } + } + private CompoundBinaryTag readCodecFile(String resPath) throws IOException { InputStream in = server.getClass().getResourceAsStream(resPath); - if(in == null) + if (in == null) throw new FileNotFoundException("Cannot find dimension registry file"); return TagStringIO.get().asCompound(streamToString(in)); } private String streamToString(InputStream in) throws IOException { - InputStreamReader isReader = new InputStreamReader(in, StandardCharsets.UTF_8); - BufferedReader bufReader = new BufferedReader(isReader); - String content = bufReader.lines() - .collect(Collectors.joining("\n")); - - isReader.close(); - bufReader.close(); + try (BufferedReader bufReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + String content = bufReader.lines() + .collect(Collectors.joining("\n")); - return content; + return content; + } } } From e54d8d6ed3582f47b87a5d589cde9749f32b1884 Mon Sep 17 00:00:00 2001 From: BoomEaro <21033866+BoomEaro@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:59:02 +0300 Subject: [PATCH 05/15] Fix wrong mappings for KeepAlive packet --- src/main/java/ua/nanit/limbo/protocol/registry/State.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ua/nanit/limbo/protocol/registry/State.java b/src/main/java/ua/nanit/limbo/protocol/registry/State.java index 52a30839..f52488b7 100644 --- a/src/main/java/ua/nanit/limbo/protocol/registry/State.java +++ b/src/main/java/ua/nanit/limbo/protocol/registry/State.java @@ -99,7 +99,7 @@ public enum State { clientBound.register( PacketKeepAlive::new, map(0x03, V1_20_2, V1_20_3), - map(0x05, V1_20_5, V1_20_5) + map(0x04, V1_20_5, V1_20_5) ); clientBound.register( PacketRegistryData::new, From a750bc50d2bade1a2ac13eaa0695cb81a8a4ae52 Mon Sep 17 00:00:00 2001 From: BoomEaro <21033866+BoomEaro@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:38:24 +0300 Subject: [PATCH 06/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 46ce9091..65ca2ec8 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Symbol `X` means all minor versions. - [x] 1.17.X - [x] 1.18.X - [x] 1.19.X -- [x] 1.20-1.20.4 +- [x] 1.20-1.20.5 The server **doesn't** support snapshots. From e3e12db0065a879c508ec9577a84434b6f229734 Mon Sep 17 00:00:00 2001 From: BoomEaro <21033866+BoomEaro@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:36:48 +0300 Subject: [PATCH 07/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65ca2ec8..0dd19b1b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Symbol `X` means all minor versions. - [x] 1.17.X - [x] 1.18.X - [x] 1.19.X -- [x] 1.20-1.20.5 +- [x] 1.20-1.20.6 The server **doesn't** support snapshots. From f36f8dac6c0f55241ca1ddd9ca196ebe90b55160 Mon Sep 17 00:00:00 2001 From: Nan1t Date: Thu, 2 May 2024 13:52:42 +0300 Subject: [PATCH 08/15] Removed unused code --- src/main/java/ua/nanit/limbo/connection/ClientConnection.java | 4 ---- src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java | 2 +- src/main/java/ua/nanit/limbo/protocol/PacketSnapshot.java | 4 ++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/ua/nanit/limbo/connection/ClientConnection.java b/src/main/java/ua/nanit/limbo/connection/ClientConnection.java index 1d988472..611039bc 100644 --- a/src/main/java/ua/nanit/limbo/connection/ClientConnection.java +++ b/src/main/java/ua/nanit/limbo/connection/ClientConnection.java @@ -264,10 +264,6 @@ public void updateState(State state) { encoder.updateState(state); } - public void updateDecoderState(State state) { - decoder.updateState(state); - } - public void updateEncoderState(State state) { encoder.updateState(state); } diff --git a/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java b/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java index f5f5797e..67ef12cd 100644 --- a/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java +++ b/src/main/java/ua/nanit/limbo/connection/PacketSnapshots.java @@ -52,7 +52,7 @@ public final class PacketSnapshots { public static PacketSnapshot PACKET_HEADER_AND_FOOTER; public static PacketSnapshot PACKET_PLAYER_POS_AND_LOOK_LEGACY; - // For 1.19 we need to spawn player outside world to avoid stuck in terrain loading + // For 1.19 we need to spawn player outside the world to avoid stuck in terrain loading public static PacketSnapshot PACKET_PLAYER_POS_AND_LOOK; public static PacketSnapshot PACKET_TITLE_TITLE; diff --git a/src/main/java/ua/nanit/limbo/protocol/PacketSnapshot.java b/src/main/java/ua/nanit/limbo/protocol/PacketSnapshot.java index 9f0fe0e1..2be644c3 100644 --- a/src/main/java/ua/nanit/limbo/protocol/PacketSnapshot.java +++ b/src/main/java/ua/nanit/limbo/protocol/PacketSnapshot.java @@ -23,8 +23,8 @@ import java.util.Map; /** - * PacketSnapshot encodes packet to byte array for each MC version. - * Some versions have same snapshot, so there are mappings to avoid data copying + * PacketSnapshot encodes a packet to byte array for each MC version. + * Some versions have the same snapshot, so there are mappings to avoid data copying */ public class PacketSnapshot implements PacketOut { From 6bbde1f5785ad44fee74f4db843bc778f7e07735 Mon Sep 17 00:00:00 2001 From: Nan1t Date: Thu, 2 May 2024 14:01:45 +0300 Subject: [PATCH 09/15] Fixed spelling --- src/main/resources/settings.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 478b15cc..3f43a5ef 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -7,7 +7,7 @@ bind: ip: 'localhost' port: 65535 -# Max amount of players can join to server +# Max number of players can join to server # Set -1 to make it infinite maxPlayers: 100 @@ -16,7 +16,7 @@ ping: description: '{"text": "&9NanoLimbo"}' version: 'NanoLimbo' # Return static protocol version number in ping result - # By default, its -1 to return the client version, if it supported + # By default, its -1 to return the client version if it supported # https://wiki.vg/Protocol_version_numbers protocol: -1 @@ -24,7 +24,7 @@ ping: dimension: THE_END # Whether to display the player in the player list -# For 1.16.5 clients, player list will be sent even if disabled, to avoid crash +# For 1.16.5 clients, the player list will be sent even if disabled, to avoid crash playerList: enable: false username: 'NanoLimbo' @@ -50,12 +50,12 @@ brandName: enable: true content: 'NanoLimbo' -# Message sends when player join to server +# Message sends when player joins to the server joinMessage: enable: true text: '{"text": "&eWelcome to the Limbo!"}' -# BossBar displays when player join to server +# BossBar displays when player joins to the server # For 1.9+ clients bossBar: enable: true @@ -87,7 +87,7 @@ title: # - LEGACY # - MODERN # - BUNGEE_GUARD -# Don't use secret if you not use MODERN type +# Don't use secret if you do not use MODERN type infoForwarding: type: NONE secret: '' @@ -105,9 +105,9 @@ readTimeout: 30000 # 3 - Display errors, warnings, info, debug debugLevel: 2 -# Warning! Do not touch params of this block, if you not completely sure what is this! +# Warning! Do not touch params of this block if you are not completely sure what is this! netty: - # Use Linux native transport type, if it possible + # Use a Linux native transport type, if it possible useEpoll: true # EventLoopGroup threads count threads: @@ -115,9 +115,9 @@ netty: workerGroup: 4 # Options to check incoming traffic and kick potentially malicious connections. -# Take into account that player can send many small packets, for example just moving mouse. +# Take into account that player can send many small packets, for example, just moving mouse. traffic: - # If true, then additional handler will be added to channel pipeline + # If true, then additional handler will be added to the channel pipeline enable: true # Max packet size in bytes # Unlimited if -1 @@ -127,7 +127,7 @@ traffic: # Raising this value will allow higher peak packet rates, which will help with people who have poor connections # Ignored if -1.0 interval: 7.0 - # The maximum maximum packets per second for players + # The maximum packets per second for players # It is measured over the configured interval # Ignored if -1.0 maxPacketRate: 500.0 From e9b6c888bcff8cc5c9f63d9a92baee1b8876782b Mon Sep 17 00:00:00 2001 From: Nan1t Date: Thu, 2 May 2024 16:10:40 +0300 Subject: [PATCH 10/15] Added logback logging --- README.md | 10 ++-- build.gradle | 9 ++- src/main/java/ua/nanit/limbo/NanoLimbo.java | 4 +- .../limbo/connection/ClientConnection.java | 6 +- .../nanit/limbo/connection/PacketHandler.java | 4 +- .../pipeline/ChannelTrafficHandler.java | 4 +- .../connection/pipeline/PacketDecoder.java | 16 +++-- .../connection/pipeline/PacketEncoder.java | 10 ++-- .../pipeline/VarIntFrameDecoder.java | 6 +- .../ua/nanit/limbo/server/CommandManager.java | 4 +- .../ua/nanit/limbo/server/Connections.java | 4 +- .../ua/nanit/limbo/server/LimboServer.java | 16 ++--- .../limbo/server/{Logger.java => Log.java} | 59 ++++++++++--------- .../nanit/limbo/server/commands/CmdConn.java | 4 +- .../nanit/limbo/server/commands/CmdHelp.java | 6 +- .../nanit/limbo/server/commands/CmdMem.java | 12 ++-- .../limbo/server/commands/CmdVersion.java | 4 +- .../nanit/limbo/world/DimensionRegistry.java | 6 +- src/main/resources/logback.xml | 30 ++++++++++ 19 files changed, 123 insertions(+), 91 deletions(-) rename src/main/java/ua/nanit/limbo/server/{Logger.java => Log.java} (60%) create mode 100644 src/main/resources/logback.xml diff --git a/README.md b/README.md index 0dd19b1b..dad8808b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The main goal of this project is maximum simplicity with a minimum number of sen The limbo is empty; there is no ability to set a schematic building since this is not necessary. You can send useful information via chat or boss bar. -No plugins, no logs. The server is fully clear. It is only able keep a lot of players while the main server is down. +No plugins, no logs. The server is fully clear. It is only able to keep a lot of players while the main server is down. General features: * High performance. The server doesn't save or cache any useless (for limbo) data. @@ -14,7 +14,7 @@ General features: * Support for [BungeeGuard](https://www.spigotmc.org/resources/79601/) handshake format. * Multiple versions support. * Fully configurable. -* Lightweight. App size around **2MB**. +* Lightweight. App size around **3MB**. ![](https://i.imgur.com/sT8p1Gz.png) @@ -56,8 +56,8 @@ The installation process is simple. 2. Put the jar file in the folder you want. 3. Create a start script as you did for Bukkit or BungeeCord, with a command like this: `java -jar NanoLimbo-.jar` -5. The server will create `settings.yml` file, which is the server configuration. -6. Configure it as you want and restart the server. +4. The server will create `settings.yml` file, which is the server configuration. +5. Configure it as you want and restart the server. ### Player info forwarding @@ -75,7 +75,7 @@ Then add your tokens to `tokens` list. ### Contributing -Feel free to create a pull request if you found some bug or optimization opportunity, or if you want +Feel free to create a pull request if you find some bug or optimization opportunity, or if you want to add some functionality that is suitable for a limbo server and won't significantly load the server. ### Building diff --git a/build.gradle b/build.gradle index 6851014d..e3a733fe 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,8 @@ plugins { id 'com.github.gmazzo.buildconfig' version '3.1.0' } -group 'ru.nanit' -version '1.7' +group 'ua.nanit' +version '1.8' compileJava { options.encoding = "UTF-8" @@ -24,6 +24,7 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.3' + implementation 'ch.qos.logback:logback-classic:1.5.6' implementation 'org.spongepowered:configurate-yaml:4.1.2' implementation 'io.netty:netty-all:4.1.101.Final' implementation 'net.kyori:adventure-nbt:4.14.0' @@ -44,7 +45,9 @@ shadowJar { attributes('Main-Class': 'ua.nanit.limbo.NanoLimbo') } - minimize() + minimize { + exclude(dependency('ch.qos.logback:logback-classic:.*:.*')) + } } test { diff --git a/src/main/java/ua/nanit/limbo/NanoLimbo.java b/src/main/java/ua/nanit/limbo/NanoLimbo.java index 25a580a0..262ad518 100644 --- a/src/main/java/ua/nanit/limbo/NanoLimbo.java +++ b/src/main/java/ua/nanit/limbo/NanoLimbo.java @@ -18,7 +18,7 @@ package ua.nanit.limbo; import ua.nanit.limbo.server.LimboServer; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; public final class NanoLimbo { @@ -26,7 +26,7 @@ public static void main(String[] args) { try { new LimboServer().start(); } catch (Exception e) { - Logger.error("Cannot start server: ", e); + Log.error("Cannot start server: ", e); } } diff --git a/src/main/java/ua/nanit/limbo/connection/ClientConnection.java b/src/main/java/ua/nanit/limbo/connection/ClientConnection.java index 611039bc..9d938423 100644 --- a/src/main/java/ua/nanit/limbo/connection/ClientConnection.java +++ b/src/main/java/ua/nanit/limbo/connection/ClientConnection.java @@ -36,7 +36,7 @@ import ua.nanit.limbo.protocol.registry.State; import ua.nanit.limbo.protocol.registry.Version; import ua.nanit.limbo.server.LimboServer; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import ua.nanit.limbo.util.UuidUtil; import javax.crypto.Mac; @@ -104,7 +104,7 @@ public void channelInactive(@NotNull ChannelHandlerContext ctx) throws Exception @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { if (channel.isActive()) { - Logger.error("Unhandled exception: ", cause); + Log.error("Unhandled exception: ", cause); } } @@ -312,7 +312,7 @@ boolean checkBungeeGuardHandshake(String handshake) { setAddress(socketAddressHostname); gameProfile.setUuid(uuid); - Logger.debug("Successfully verified BungeeGuard token"); + Log.debug("Successfully verified BungeeGuard token"); return true; } diff --git a/src/main/java/ua/nanit/limbo/connection/PacketHandler.java b/src/main/java/ua/nanit/limbo/connection/PacketHandler.java index fc3832b1..f1bacda1 100644 --- a/src/main/java/ua/nanit/limbo/connection/PacketHandler.java +++ b/src/main/java/ua/nanit/limbo/connection/PacketHandler.java @@ -29,7 +29,7 @@ import ua.nanit.limbo.protocol.packets.status.PacketStatusRequest; import ua.nanit.limbo.protocol.packets.status.PacketStatusResponse; import ua.nanit.limbo.server.LimboServer; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import ua.nanit.limbo.util.UuidUtil; import java.util.concurrent.ThreadLocalRandom; @@ -46,7 +46,7 @@ public void handle(ClientConnection conn, PacketHandshake packet) { conn.updateVersion(packet.getVersion()); conn.updateState(packet.getNextState()); - Logger.debug("Pinged from %s [%s]", conn.getAddress(), + Log.debug("Pinged from %s [%s]", conn.getAddress(), conn.getClientVersion().toString()); if (server.getConfig().getInfoForwarding().isLegacy()) { diff --git a/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java b/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java index 7d1babcc..6809c387 100644 --- a/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java +++ b/src/main/java/ua/nanit/limbo/connection/pipeline/ChannelTrafficHandler.java @@ -4,7 +4,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.jetbrains.annotations.NotNull; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import java.util.Arrays; @@ -45,7 +45,7 @@ public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) private void closeConnection(ChannelHandlerContext ctx, String reason, Object... args) { ctx.close(); - Logger.info(reason, args); + Log.info(reason, args); } private static class PacketBucket { diff --git a/src/main/java/ua/nanit/limbo/connection/pipeline/PacketDecoder.java b/src/main/java/ua/nanit/limbo/connection/pipeline/PacketDecoder.java index 5fe1eecb..0bcf6d27 100644 --- a/src/main/java/ua/nanit/limbo/connection/pipeline/PacketDecoder.java +++ b/src/main/java/ua/nanit/limbo/connection/pipeline/PacketDecoder.java @@ -24,7 +24,7 @@ import ua.nanit.limbo.protocol.Packet; import ua.nanit.limbo.protocol.registry.State; import ua.nanit.limbo.protocol.registry.Version; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import java.util.List; @@ -47,22 +47,20 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List out) Packet packet = mappings.getPacket(packetId); if (packet != null) { - Logger.debug("Received packet %s[0x%s] (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes()); + Log.debug("Received packet %s[0x%s] (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes()); try { packet.decode(msg, version); } catch (Exception e) { - if (Logger.isDebug()) { - Logger.warning("Cannot decode packet 0x%s", Integer.toHexString(packetId)); - e.printStackTrace(); - } - else { - Logger.warning("Cannot decode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage()); + if (Log.isDebug()) { + Log.warning("Cannot decode packet 0x%s", e, Integer.toHexString(packetId)); + } else { + Log.warning("Cannot decode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage()); } } ctx.fireChannelRead(packet); } else { - Logger.debug("Undefined incoming packet: 0x" + Integer.toHexString(packetId)); + Log.debug("Undefined incoming packet: 0x" + Integer.toHexString(packetId)); } } diff --git a/src/main/java/ua/nanit/limbo/connection/pipeline/PacketEncoder.java b/src/main/java/ua/nanit/limbo/connection/pipeline/PacketEncoder.java index 6a491390..38454a73 100644 --- a/src/main/java/ua/nanit/limbo/connection/pipeline/PacketEncoder.java +++ b/src/main/java/ua/nanit/limbo/connection/pipeline/PacketEncoder.java @@ -25,7 +25,7 @@ import ua.nanit.limbo.protocol.PacketSnapshot; import ua.nanit.limbo.protocol.registry.State; import ua.nanit.limbo.protocol.registry.Version; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; public class PacketEncoder extends MessageToByteEncoder { @@ -51,7 +51,7 @@ protected void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf out) thr } if (packetId == -1) { - Logger.warning("Undefined packet class: %s[0x%s] (%d bytes)", packet.getClass().getName(), Integer.toHexString(packetId), msg.readableBytes()); + Log.warning("Undefined packet class: %s[0x%s] (%d bytes)", packet.getClass().getName(), Integer.toHexString(packetId), msg.readableBytes()); return; } @@ -60,11 +60,11 @@ protected void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf out) thr try { packet.encode(msg, version); - if (Logger.getLevel() >= Logger.Level.DEBUG.getIndex()) { - Logger.debug("Sending %s[0x%s] packet (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes()); + if (Log.isDebug()) { + Log.debug("Sending %s[0x%s] packet (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes()); } } catch (Exception e) { - Logger.error("Cannot encode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage()); + Log.error("Cannot encode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage()); } } diff --git a/src/main/java/ua/nanit/limbo/connection/pipeline/VarIntFrameDecoder.java b/src/main/java/ua/nanit/limbo/connection/pipeline/VarIntFrameDecoder.java index 96538566..25f8779a 100644 --- a/src/main/java/ua/nanit/limbo/connection/pipeline/VarIntFrameDecoder.java +++ b/src/main/java/ua/nanit/limbo/connection/pipeline/VarIntFrameDecoder.java @@ -20,7 +20,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import java.util.List; @@ -42,7 +42,7 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { int readVarInt = reader.getReadVarInt(); int bytesRead = reader.getBytesRead(); if (readVarInt < 0) { - Logger.error("[VarIntFrameDecoder] Bad data length"); + Log.error("[VarIntFrameDecoder] Bad data length"); } else if (readVarInt == 0) { in.readerIndex(varIntEnd + 1); } else { @@ -54,7 +54,7 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { } } } else if (reader.getResult() == VarIntByteDecoder.DecodeResult.TOO_BIG) { - Logger.error("[VarIntFrameDecoder] Too big data"); + Log.error("[VarIntFrameDecoder] Too big data"); } } } \ No newline at end of file diff --git a/src/main/java/ua/nanit/limbo/server/CommandManager.java b/src/main/java/ua/nanit/limbo/server/CommandManager.java index 3949cf69..15689c5b 100644 --- a/src/main/java/ua/nanit/limbo/server/CommandManager.java +++ b/src/main/java/ua/nanit/limbo/server/CommandManager.java @@ -40,12 +40,12 @@ public void run() { try { handler.execute(); } catch (Throwable t) { - Logger.error("Cannot execute command:", t); + Log.error("Cannot execute command:", t); } continue; } - Logger.info("Unknown command. Type \"help\" to get commands list"); + Log.info("Unknown command. Type \"help\" to get commands list"); } } diff --git a/src/main/java/ua/nanit/limbo/server/Connections.java b/src/main/java/ua/nanit/limbo/server/Connections.java index 710f2006..3c127a92 100644 --- a/src/main/java/ua/nanit/limbo/server/Connections.java +++ b/src/main/java/ua/nanit/limbo/server/Connections.java @@ -43,12 +43,12 @@ public int getCount() { public void addConnection(ClientConnection connection) { connections.put(connection.getUuid(), connection); - Logger.info("Player %s connected (%s) [%s]", connection.getUsername(), + Log.info("Player %s connected (%s) [%s]", connection.getUsername(), connection.getAddress(), connection.getClientVersion()); } public void removeConnection(ClientConnection connection) { connections.remove(connection.getUuid()); - Logger.info("Player %s disconnected", connection.getUsername()); + Log.info("Player %s disconnected", connection.getUsername()); } } diff --git a/src/main/java/ua/nanit/limbo/server/LimboServer.java b/src/main/java/ua/nanit/limbo/server/LimboServer.java index 3616303b..6470a9e7 100644 --- a/src/main/java/ua/nanit/limbo/server/LimboServer.java +++ b/src/main/java/ua/nanit/limbo/server/LimboServer.java @@ -72,13 +72,15 @@ public CommandManager getCommandManager() { } public void start() throws Exception { - Logger.info("Starting server..."); + Log.info("Starting server..."); ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); config = new LimboConfig(Paths.get("./")); config.load(); + Log.setLevel(config.getDebugLevel()); + packetHandler = new PacketHandler(this); dimensionRegistry = new DimensionRegistry(this); dimensionRegistry.load(config.getDimensionType()); @@ -92,9 +94,7 @@ public void start() throws Exception { Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "NanoLimbo shutdown thread")); - Logger.info("Server started on %s", config.getAddress()); - - Logger.setLevel(config.getDebugLevel()); + Log.info("Server started on %s", config.getAddress()); commandManager = new CommandManager(); commandManager.registerAll(this); @@ -110,12 +110,12 @@ private void startBootstrap() { bossGroup = new EpollEventLoopGroup(config.getBossGroupSize()); workerGroup = new EpollEventLoopGroup(config.getWorkerGroupSize()); channelClass = EpollServerSocketChannel.class; - Logger.debug("Using Epoll transport type"); + Log.debug("Using Epoll transport type"); } else { bossGroup = new NioEventLoopGroup(config.getBossGroupSize()); workerGroup = new NioEventLoopGroup(config.getWorkerGroupSize()); channelClass = NioServerSocketChannel.class; - Logger.debug("Using Java NIO transport type"); + Log.debug("Using Java NIO transport type"); } new ServerBootstrap() @@ -132,7 +132,7 @@ private void broadcastKeepAlive() { } private void stop() { - Logger.info("Stopping server..."); + Log.info("Stopping server..."); if (keepAliveTask != null) { keepAliveTask.cancel(true); @@ -146,7 +146,7 @@ private void stop() { workerGroup.shutdownGracefully(); } - Logger.info("Server stopped, Goodbye!"); + Log.info("Server stopped, Goodbye!"); } } diff --git a/src/main/java/ua/nanit/limbo/server/Logger.java b/src/main/java/ua/nanit/limbo/server/Log.java similarity index 60% rename from src/main/java/ua/nanit/limbo/server/Logger.java rename to src/main/java/ua/nanit/limbo/server/Log.java index c910a3ef..8618b684 100644 --- a/src/main/java/ua/nanit/limbo/server/Logger.java +++ b/src/main/java/ua/nanit/limbo/server/Log.java @@ -17,65 +17,66 @@ package ua.nanit.limbo.server; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; +import ch.qos.logback.classic.Logger; +import org.slf4j.LoggerFactory; -public final class Logger { +public final class Log { - private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("hh:mm:ss"); + private static final Logger LOGGER = (Logger) LoggerFactory.getLogger("Limbo"); private static int debugLevel = Level.INFO.getIndex(); - private Logger() {} - - public static int getLevel() { - return debugLevel; - } + private Log() {} public static void info(Object msg, Object... args) { - print(Level.INFO, msg, null, args); + LOGGER.info(String.format(msg.toString(), args)); } public static void debug(Object msg, Object... args) { - print(Level.DEBUG, msg, null, args); + LOGGER.debug(String.format(msg.toString(), args)); } public static void warning(Object msg, Object... args) { - print(Level.WARNING, msg, null, args); + LOGGER.warn(String.format(msg.toString(), args)); } public static void warning(Object msg, Throwable t, Object... args) { - print(Level.WARNING, msg, t, args); + LOGGER.warn(String.format(msg.toString(), args), t); } public static void error(Object msg, Object... args) { - print(Level.ERROR, msg, null, args); + LOGGER.error(msg.toString(), args); } public static void error(Object msg, Throwable t, Object... args) { - print(Level.ERROR, msg, t, args); - } - - public static void print(Level level, Object msg, Throwable t, Object... args) { - if (debugLevel >= level.getIndex()) { - System.out.printf("%s: %s%n", getPrefix(level), String.format(msg.toString(), args)); - if (t != null) t.printStackTrace(); - } + LOGGER.error(String.format(msg.toString(), args), t); } public static boolean isDebug() { return debugLevel >= Level.DEBUG.getIndex(); } - private static String getPrefix(Level level) { - return String.format("[%s] [%s]", getTime(), level.getDisplay()); - } + static void setLevel(int level) { + debugLevel = level; + Logger logback = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); - private static String getTime() { - return LocalTime.now().format(FORMATTER); + if (logback != null) { + logback.setLevel(convertLevel(level)); + } } - static void setLevel(int level) { - debugLevel = level; + private static ch.qos.logback.classic.Level convertLevel(int level) { + switch (level) { + case 0: + return ch.qos.logback.classic.Level.ERROR; + case 1: + return ch.qos.logback.classic.Level.WARN; + case 2: + return ch.qos.logback.classic.Level.INFO; + case 3: + return ch.qos.logback.classic.Level.DEBUG; + default: + throw new IllegalStateException("Undefined log level: " + level); + } } public enum Level { diff --git a/src/main/java/ua/nanit/limbo/server/commands/CmdConn.java b/src/main/java/ua/nanit/limbo/server/commands/CmdConn.java index 0f779efc..24954b04 100644 --- a/src/main/java/ua/nanit/limbo/server/commands/CmdConn.java +++ b/src/main/java/ua/nanit/limbo/server/commands/CmdConn.java @@ -2,7 +2,7 @@ import ua.nanit.limbo.server.Command; import ua.nanit.limbo.server.LimboServer; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; public class CmdConn implements Command { @@ -14,7 +14,7 @@ public CmdConn(LimboServer server) { @Override public void execute() { - Logger.info("Connections: %d", server.getConnections().getCount()); + Log.info("Connections: %d", server.getConnections().getCount()); } @Override diff --git a/src/main/java/ua/nanit/limbo/server/commands/CmdHelp.java b/src/main/java/ua/nanit/limbo/server/commands/CmdHelp.java index 6f1e7433..08a885cf 100644 --- a/src/main/java/ua/nanit/limbo/server/commands/CmdHelp.java +++ b/src/main/java/ua/nanit/limbo/server/commands/CmdHelp.java @@ -2,7 +2,7 @@ import ua.nanit.limbo.server.Command; import ua.nanit.limbo.server.LimboServer; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import java.util.Map; @@ -18,10 +18,10 @@ public CmdHelp(LimboServer server) { public void execute() { Map commands = server.getCommandManager().getCommands(); - Logger.info("Available commands:"); + Log.info("Available commands:"); for (Map.Entry entry : commands.entrySet()) { - Logger.info("%s - %s", entry.getKey(), entry.getValue().description()); + Log.info("%s - %s", entry.getKey(), entry.getValue().description()); } } diff --git a/src/main/java/ua/nanit/limbo/server/commands/CmdMem.java b/src/main/java/ua/nanit/limbo/server/commands/CmdMem.java index 25e1c438..69290ecd 100644 --- a/src/main/java/ua/nanit/limbo/server/commands/CmdMem.java +++ b/src/main/java/ua/nanit/limbo/server/commands/CmdMem.java @@ -1,7 +1,7 @@ package ua.nanit.limbo.server.commands; import ua.nanit.limbo.server.Command; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; public class CmdMem implements Command { @@ -14,11 +14,11 @@ public void execute() { long free = runtime.freeMemory() / mb; long max = runtime.maxMemory() / mb; - Logger.info("Memory usage:"); - Logger.info("Used: %d MB", used); - Logger.info("Total: %d MB", total); - Logger.info("Free: %d MB", free); - Logger.info("Max: %d MB", max); + Log.info("Memory usage:"); + Log.info("Used: %d MB", used); + Log.info("Total: %d MB", total); + Log.info("Free: %d MB", free); + Log.info("Max: %d MB", max); } @Override diff --git a/src/main/java/ua/nanit/limbo/server/commands/CmdVersion.java b/src/main/java/ua/nanit/limbo/server/commands/CmdVersion.java index 3b2862dc..2c979ced 100644 --- a/src/main/java/ua/nanit/limbo/server/commands/CmdVersion.java +++ b/src/main/java/ua/nanit/limbo/server/commands/CmdVersion.java @@ -1,14 +1,14 @@ package ua.nanit.limbo.server.commands; import ua.nanit.limbo.server.Command; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import ua.nanit.limbo.BuildConfig; public class CmdVersion implements Command { @Override public void execute() { - Logger.info("Version: %s", BuildConfig.LIMBO_VERSION); + Log.info("Version: %s", BuildConfig.LIMBO_VERSION); } @Override diff --git a/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java b/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java index 49954b61..a2b2537d 100644 --- a/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java +++ b/src/main/java/ua/nanit/limbo/world/DimensionRegistry.java @@ -21,7 +21,7 @@ import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.TagStringIO; import ua.nanit.limbo.server.LimboServer; -import ua.nanit.limbo.server.Logger; +import ua.nanit.limbo.server.Log; import java.io.*; import java.nio.charset.StandardCharsets; @@ -118,7 +118,7 @@ private Dimension getDefaultDimension(String def, CompoundBinaryTag tag) { case "the_end": return new Dimension(1, "minecraft:the_end", theEnd); default: - Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def); + Log.warning("Undefined dimension type: '%s'. Using THE_END as default", def); return new Dimension(1, "minecraft:the_end", theEnd); } } @@ -132,7 +132,7 @@ private Dimension getModernDimension(String def, CompoundBinaryTag tag) { case "the_end": return new Dimension(3, "minecraft:the_end", tag); default: - Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def); + Log.warning("Undefined dimension type: '%s'. Using THE_END as default", def); return new Dimension(3, "minecraft:the_end", tag); } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 00000000..b6df6257 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + %d{HH:mm:ss.SSS} %-5level %logger{36} -%kvp- %msg%n + + + + + logs/log-${bySecond}.txt + true + + + %d{HH:mm:ss.SSS} %-5level %logger{36} -%kvp- %msg%n + + + + + + + + \ No newline at end of file From 3f7c8bb1df53746680b27928b42b27be91f14a18 Mon Sep 17 00:00:00 2001 From: Nan1t Date: Thu, 2 May 2024 16:38:56 +0300 Subject: [PATCH 11/15] Moved initial logging after config loaded --- src/main/java/ua/nanit/limbo/server/LimboServer.java | 7 +++---- src/main/java/ua/nanit/limbo/server/Log.java | 7 ++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/ua/nanit/limbo/server/LimboServer.java b/src/main/java/ua/nanit/limbo/server/LimboServer.java index 6470a9e7..fbe26841 100644 --- a/src/main/java/ua/nanit/limbo/server/LimboServer.java +++ b/src/main/java/ua/nanit/limbo/server/LimboServer.java @@ -72,14 +72,13 @@ public CommandManager getCommandManager() { } public void start() throws Exception { - Log.info("Starting server..."); - - ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); - config = new LimboConfig(Paths.get("./")); config.load(); Log.setLevel(config.getDebugLevel()); + Log.info("Starting server..."); + + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); packetHandler = new PacketHandler(this); dimensionRegistry = new DimensionRegistry(this); diff --git a/src/main/java/ua/nanit/limbo/server/Log.java b/src/main/java/ua/nanit/limbo/server/Log.java index 8618b684..1bf0ef55 100644 --- a/src/main/java/ua/nanit/limbo/server/Log.java +++ b/src/main/java/ua/nanit/limbo/server/Log.java @@ -57,13 +57,18 @@ public static boolean isDebug() { static void setLevel(int level) { debugLevel = level; - Logger logback = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + + Logger logback = getRootLogger(); if (logback != null) { logback.setLevel(convertLevel(level)); } } + private static Logger getRootLogger() { + return (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + } + private static ch.qos.logback.classic.Level convertLevel(int level) { switch (level) { case 0: From 32b75fb9d8f7adbb244e4ea93cc19768d4fcbe5a Mon Sep 17 00:00:00 2001 From: Nan1t Date: Thu, 2 May 2024 16:55:03 +0300 Subject: [PATCH 12/15] Edit README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dad8808b..4ddc633f 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ The main goal of this project is maximum simplicity with a minimum number of sen The limbo is empty; there is no ability to set a schematic building since this is not necessary. You can send useful information via chat or boss bar. -No plugins, no logs. The server is fully clear. It is only able to keep a lot of players while the main server is down. +The server is fully clear. It is only able to keep a lot of players while the main server is down. General features: * High performance. The server doesn't save or cache any useless (for limbo) data. -* Doesn't spawn threads per player. Uses a fixed thread pool. +* Doesn't spawn threads per player. Use a fixed thread pool. * Support for **BungeeCord** and **Velocity** info forwarding. * Support for [BungeeGuard](https://www.spigotmc.org/resources/79601/) handshake format. * Multiple versions support. From 402484c838c5c0210b8b3e52b49888d746515983 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 2 May 2024 17:31:57 +0300 Subject: [PATCH 13/15] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4ddc633f..de06fb82 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ Note that the server also will be closed correctly if you just press `Ctrl+C`. ### Installation +Required software: JRE 11+ + The installation process is simple. 1. Download the latest version of the program [**here**](https://github.com/Nan1t/NanoLimbo/releases). From 48346762bf99f9750fe23a5ecbf55a2935e8e9f4 Mon Sep 17 00:00:00 2001 From: Nan1t Date: Thu, 2 May 2024 17:36:57 +0300 Subject: [PATCH 14/15] Edit README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de06fb82..1b56b437 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ to add some functionality that is suitable for a limbo server and won't signific Required software: -* JDK 1.8+ +* JDK 11+ * Gradle 7+ (optional) To build a minimized jar, go to the project root directory and run in the terminal: From d22a21e118979db643622d4fe85e4f3c7bf4538d Mon Sep 17 00:00:00 2001 From: bivashy Date: Thu, 9 May 2024 17:37:18 +0500 Subject: [PATCH 15/15] Stop the server instead of killing proxy --- .../java/ua/nanit/limbo/server/commands/CmdStop.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/ua/nanit/limbo/server/commands/CmdStop.java b/api/src/main/java/ua/nanit/limbo/server/commands/CmdStop.java index 7ccbccc6..6dc4ed1b 100644 --- a/api/src/main/java/ua/nanit/limbo/server/commands/CmdStop.java +++ b/api/src/main/java/ua/nanit/limbo/server/commands/CmdStop.java @@ -1,12 +1,19 @@ package ua.nanit.limbo.server.commands; import ua.nanit.limbo.server.Command; +import ua.nanit.limbo.server.LimboServer; public class CmdStop implements Command { + private final LimboServer server; + + public CmdStop(LimboServer server) { + this.server = server; + } + @Override public void execute() { - System.exit(0); + server.stop(); } @Override @@ -18,4 +25,5 @@ public String name() { public String description() { return "Stop the server"; } + }