diff --git a/divinemc-server/minecraft-patches/features/0008-Misc-Optimizations.patch b/divinemc-server/minecraft-patches/features/0008-Misc-Optimizations.patch index bb01fc4..9aa0cfe 100644 --- a/divinemc-server/minecraft-patches/features/0008-Misc-Optimizations.patch +++ b/divinemc-server/minecraft-patches/features/0008-Misc-Optimizations.patch @@ -4,19 +4,6 @@ Date: Fri, 31 Jan 2025 21:50:46 +0300 Subject: [PATCH] Misc Optimizations -diff --git a/com/mojang/brigadier/tree/CommandNode.java b/com/mojang/brigadier/tree/CommandNode.java -index 2ae5b80338282ac73c74765fc0729af2d54f6d6c..00a63a6a5983e6a25f2a9014a2f9eefeda468cdf 100644 ---- a/com/mojang/brigadier/tree/CommandNode.java -+++ b/com/mojang/brigadier/tree/CommandNode.java -@@ -24,7 +24,7 @@ import java.util.concurrent.CompletableFuture; - import java.util.function.Predicate; - - public abstract class CommandNode implements Comparable> { -- private final Map> children = new LinkedHashMap<>(); -+ private final Map> children = Collections.synchronizedMap(new LinkedHashMap<>()); // DivineMC - Misc Optimizations - private final Map> literals = new LinkedHashMap<>(); - private final Map> arguments = new LinkedHashMap<>(); - public Predicate requirement; // Paper - public-f diff --git a/com/mojang/math/Transformation.java b/com/mojang/math/Transformation.java index 5fb382be4d86328690c49f2a5a0c3ec698a38e21..f333d9028f315e7912dd335c8158abd525c27ecd 100644 --- a/com/mojang/math/Transformation.java @@ -58,6 +45,63 @@ index 761e583a56b1c4a605b0cbb04b61c4df60b8b9bb..c07155589ef44cbbacafe03b36d2cd4c private Lifecycle registryLifecycle; private final Map, HolderSet.Named> frozenTags = new IdentityHashMap<>(); MappedRegistry.TagSet allTags = MappedRegistry.TagSet.unbound(); +diff --git a/net/minecraft/network/VarInt.java b/net/minecraft/network/VarInt.java +index 4897ff4648083ebe737ae5b32bae344af27357e4..0d103821d7220daa5cc0d5d3231e794fca0ca055 100644 +--- a/net/minecraft/network/VarInt.java ++++ b/net/minecraft/network/VarInt.java +@@ -52,16 +52,43 @@ public class VarInt { + + public static ByteBuf write(ByteBuf buffer, int value) { + // Paper start - Optimize VarInts +- // 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) { +- buffer.writeByte(value); +- } else if ((value & (0xFFFFFFFF << 14)) == 0) { +- int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); +- buffer.writeShort(w); +- } else { +- writeOld(buffer, value); ++ // DivineMC start - Misc optimizations ++ int bytesNeeded = getByteSize(value); ++ ++ switch (bytesNeeded) { ++ case 1: ++ buffer.writeByte(value); ++ break; ++ case 2: ++ int w2 = ((value & 0x7F) << 8) | (value >>> 7) | 0x00008000; ++ buffer.writeShort(w2); ++ break; ++ case 3: ++ int w3 = (value & 0x7F) << 16 ++ | (value & 0x3F80) << 1 ++ | (value >>> 14) ++ | 0x00808000; ++ buffer.writeMedium(w3); ++ break; ++ case 4: ++ int w4 = (value & 0x7F) << 24 ++ | ((value & 0x3F80) << 9) ++ | (value & 0x1FC000) >> 6 ++ | (value >>> 21) ++ | 0x80808000; ++ buffer.writeInt(w4); ++ break; ++ case 5: ++ int w5 = (value & 0x7F) << 24 ++ | (value & 0x3F80) << 9 ++ | (value & 0x1FC000) >> 6 ++ | ((value >>> 21) & 0x7F) ++ | 0x80808080; ++ buffer.writeInt(w5); ++ buffer.writeByte(value >>> 28); ++ break; + } ++ // DivineMC end - Slightly optimized VarInt#write + return buffer; + } + public static ByteBuf writeOld(ByteBuf buffer, int value) { diff --git a/net/minecraft/server/level/ChunkTrackingView.java b/net/minecraft/server/level/ChunkTrackingView.java index bee90335677f7d8b01589ce5cfd81a40fd422886..a5e488d14fd2016ee188b114d0e681562b5b09cc 100644 --- a/net/minecraft/server/level/ChunkTrackingView.java @@ -422,7 +466,7 @@ index a18240418a19a95147341a634527d774f3d5bb92..66f74ad2a194a6676574da2932cf4677 public DebugSampleSubscriptionTracker(PlayerList playerList) { this.playerList = playerList; diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index d513b82c0681fdc990af082af69278bd773225a9..18718693412f3cc0848c462361c2f06e1ad65a6e 100644 +index d513b82c0681fdc990af082af69278bd773225a9..b065accf4ca3e87a4c35506f8cbf4d88759e1128 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -149,7 +149,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -434,6 +478,30 @@ index d513b82c0681fdc990af082af69278bd773225a9..18718693412f3cc0848c462361c2f06e // Paper start - replace random private static final class RandomRandomSource extends ca.spottedleaf.moonrise.common.util.ThreadUnsafeRandom { public RandomRandomSource() { +@@ -4502,10 +4502,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + // Paper start - optimise collisions + public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { +- if (this.touchingUnloadedChunk()) { +- return false; +- } +- + final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); + + final Level world = this.level; +@@ -4541,7 +4537,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { +- final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).getSections(); ++ // DivineMC start - Misc optimizations ++ final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false); ++ if (chunk == null) continue; ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); ++ // DivineMC end - Misc optimizations + + // bound y + for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java index 5bcbebf35eb726a43b957aca5b8b7a1dca7648cd..d618752727e2f2f5c0c1afa97f455e349cb7e76c 100644 --- a/net/minecraft/world/entity/Mob.java diff --git a/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch b/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch index c0027b0..706fbb0 100644 --- a/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch +++ b/divinemc-server/minecraft-patches/features/0009-Chunk-System-Optimizations.patch @@ -3319,7 +3319,7 @@ index 66d0a6390febe929ef774b0a7813329015bc8cc2..d1917dee4ca6bba5f2c92475811c724c } diff --git a/net/minecraft/world/ticks/LevelTicks.java b/net/minecraft/world/ticks/LevelTicks.java -index 0a9805d42142678ca5213c511235daa6505ddbf3..cd73f1a3ccc80e4ab1766147fccc67d81eeb4cc3 100644 +index 0a9805d42142678ca5213c511235daa6505ddbf3..6e3d4e78a7d92a846e68fe60271cfe5a5cd7b569 100644 --- a/net/minecraft/world/ticks/LevelTicks.java +++ b/net/minecraft/world/ticks/LevelTicks.java @@ -30,17 +30,18 @@ public class LevelTicks implements LevelTickAccess { @@ -3386,10 +3386,11 @@ index 0a9805d42142678ca5213c511235daa6505ddbf3..cd73f1a3ccc80e4ab1766147fccc67d8 if (!this.toRunThisTickSet.isEmpty()) { this.toRunThisTickSet.remove(scheduledTick); } -@@ -183,6 +189,7 @@ public class LevelTicks implements LevelTickAccess { +@@ -182,7 +188,7 @@ public class LevelTicks implements LevelTickAccess { + } private void cleanupAfterTick() { - this.toRunThisTick.clear(); +- this.toRunThisTick.clear(); + this.toRunThisTickCount.set(0); // DivineMC - Chunk System Optimizations this.containersToTick.clear(); this.alreadyRunThisTick.clear(); diff --git a/divinemc-server/minecraft-patches/features/0046-Player-ProfileResult-caching.patch b/divinemc-server/minecraft-patches/features/0046-Player-ProfileResult-caching.patch new file mode 100644 index 0000000..4c72530 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0046-Player-ProfileResult-caching.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Sat, 26 Apr 2025 22:30:35 +0300 +Subject: [PATCH] Player ProfileResult caching + + +diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +index 738c8749593cf3c30a1c321664abf12ba8dac635..7dbd73d8b5f5d2888cede36f9ea0d0cf71b4a49d 100644 +--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +@@ -74,6 +74,11 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, + private net.minecraft.server.level.ServerPlayer player; // CraftBukkit + public boolean iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation = false; // Paper - username validation overriding + private int velocityLoginMessageId = -1; // Paper - Add Velocity IP Forwarding Support ++ // DivineMC start - Player ProfileResult caching ++ private static final com.google.common.cache.Cache playerProfileResultCache = com.google.common.cache.CacheBuilder.newBuilder() ++ .expireAfterWrite(1, java.util.concurrent.TimeUnit.MINUTES) ++ .build(); ++ // DivineMC end - Player ProfileResult caching + + public ServerLoginPacketListenerImpl(MinecraftServer server, Connection connection, boolean transferred) { + this.server = server; +@@ -293,9 +298,23 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, + String string1 = Objects.requireNonNull(ServerLoginPacketListenerImpl.this.requestedUsername, "Player name not initialized"); + + try { +- ProfileResult profileResult = ServerLoginPacketListenerImpl.this.server +- .getSessionService() +- .hasJoinedServer(string1, string, this.getAddress()); ++ // DivineMC start - Player ProfileResult caching ++ ProfileResult profileResult; ++ if (org.bxteam.divinemc.DivineConfig.playerProfileResultCachingEnabled) { ++ profileResult = playerProfileResultCache.getIfPresent(string1); ++ ++ if (profileResult == null) { ++ profileResult = ServerLoginPacketListenerImpl.this.server ++ .getSessionService() ++ .hasJoinedServer(string1, string, this.getAddress()); ++ playerProfileResultCache.put(string1, profileResult); ++ } ++ } else { ++ profileResult = ServerLoginPacketListenerImpl.this.server ++ .getSessionService() ++ .hasJoinedServer(string1, string, this.getAddress()); ++ } ++ // DivineMC end - Player ProfileResult caching + if (profileResult != null) { + GameProfile gameProfile = profileResult.profile(); + // CraftBukkit start - fire PlayerPreLoginEvent diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java index d4ad79c..2cbe505 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java @@ -327,6 +327,8 @@ public class DivineConfig { public static boolean disableDisconnectSpam = false; public static boolean gracefulTeleportHandling = false; public static boolean dontRespondPingBeforeStart = true; + public static boolean playerProfileResultCachingEnabled = true; + public static int playerProfileResultCachingTimeout = 1440; private static void networkSettings() { disableDisconnectSpam = getBoolean("settings.network.disable-disconnect-spam", disableDisconnectSpam, "Prevents players being disconnected by 'disconnect.spam' when sending too many chat packets"); @@ -334,6 +336,11 @@ public class DivineConfig { "Disables being disconnected from 'multiplayer.disconnect.invalid_player_movement' (also declines the packet handling)."); dontRespondPingBeforeStart = getBoolean("settings.network.dont-respond-ping-before-start", dontRespondPingBeforeStart, "Prevents the server from responding to pings before the server is fully booted."); + + playerProfileResultCachingEnabled = getBoolean("settings.network.player-profile-result-caching.enabled", playerProfileResultCachingEnabled, + "Enables caching of player profile results on first join."); + playerProfileResultCachingTimeout = getInt("settings.network.player-profile-result-caching.timeout", playerProfileResultCachingTimeout, + "The amount of time in minutes to cache player profile results."); } public static boolean enableFasterTntOptimization = true;