diff --git a/patches/server/0041-Petal-Multithreaded-Tracker.patch b/patches/server/0041-Petal-Multithreaded-Tracker.patch index 4e39c0f7..e52d2ebb 100644 --- a/patches/server/0041-Petal-Multithreaded-Tracker.patch +++ b/patches/server/0041-Petal-Multithreaded-Tracker.patch @@ -193,7 +193,7 @@ index 4f91107f9ae42f96c060c310596db9aa869a8dbc..faad96f04af2e368f0276ade417dd1ba public boolean visible = true; diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index cb2683c7e090a8d040b581bc95a0505998f17f43..539934a75df64e7accf4829d8d4b075833bb5bc9 100644 +index cb2683c7e090a8d040b581bc95a0505998f17f43..55d339ef8782e6b7ab08aebd2b96a4147ac6bcc6 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -295,7 +295,11 @@ public class ServerEntity { @@ -235,7 +235,7 @@ index cb2683c7e090a8d040b581bc95a0505998f17f43..539934a75df64e7accf4829d8d4b0758 if (!set.isEmpty()) { + // Leaf start - petal - sync -+ final var copy = Lists.newArrayList(set); ++ final Set copy = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(set); + ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> { // CraftBukkit start - Send scaled max health if (this.entity instanceof ServerPlayer) { diff --git a/patches/server/0044-Optimize-Minecart-collisions.patch b/patches/server/0043-Optimize-Minecart-collisions.patch similarity index 100% rename from patches/server/0044-Optimize-Minecart-collisions.patch rename to patches/server/0043-Optimize-Minecart-collisions.patch diff --git a/patches/server/0045-Reduce-canSee-work.patch b/patches/server/0044-Reduce-canSee-work.patch similarity index 96% rename from patches/server/0045-Reduce-canSee-work.patch rename to patches/server/0044-Reduce-canSee-work.patch index 20c1c05a..9c144db3 100644 --- a/patches/server/0045-Reduce-canSee-work.patch +++ b/patches/server/0044-Reduce-canSee-work.patch @@ -36,7 +36,7 @@ index 968186bef3ff92cfdc23241d67233407b629263e..25e93a0a58b0ecf02f2669fc8f01ef2f if (net.minecraft.world.phys.shapes.Shapes.joinIsNotEmpty(voxelshape, net.minecraft.world.phys.shapes.Shapes.create(entity.getBoundingBox()), net.minecraft.world.phys.shapes.BooleanOp.AND)) { return false; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index bbbac669bcadd596ad40a0eed99e2587db9c900e..bbc8135343b8206c5348eab802a257555b16836f 100644 +index 70b5cf477a4cfdfd998fc846fbee24dabf308af7..ff547f908b0390fac7e165c5765f0f9f4d9ce5b8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -636,6 +636,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0046-Faster-Natural-Spawning.patch b/patches/server/0045-Faster-Natural-Spawning.patch similarity index 100% rename from patches/server/0046-Faster-Natural-Spawning.patch rename to patches/server/0045-Faster-Natural-Spawning.patch diff --git a/patches/server/0047-Fix-sprint-glitch.patch b/patches/server/0046-Fix-sprint-glitch.patch similarity index 90% rename from patches/server/0047-Fix-sprint-glitch.patch rename to patches/server/0046-Fix-sprint-glitch.patch index 24eff23a..5980834d 100644 --- a/patches/server/0047-Fix-sprint-glitch.patch +++ b/patches/server/0046-Fix-sprint-glitch.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix sprint glitch diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d4cee0133f8e7df5321b00cf97bb7f43b1d198bc..f1c0ca7baa6297813c5e5deeaf6ad698086ffddb 100644 +index fa773a29ec77f277546e418aab9b06ccd9567a8f..99e8d0221685da1182258ebf3367b26ea3f70d0d 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1451,7 +1451,8 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0048-Configurable-movement-speed-of-more-entities.patch b/patches/server/0047-Configurable-movement-speed-of-more-entities.patch similarity index 100% rename from patches/server/0048-Configurable-movement-speed-of-more-entities.patch rename to patches/server/0047-Configurable-movement-speed-of-more-entities.patch diff --git a/patches/server/0049-Faster-sequencing-of-futures-for-chunk-structure-gen.patch b/patches/server/0048-Faster-sequencing-of-futures-for-chunk-structure-gen.patch similarity index 100% rename from patches/server/0049-Faster-sequencing-of-futures-for-chunk-structure-gen.patch rename to patches/server/0048-Faster-sequencing-of-futures-for-chunk-structure-gen.patch diff --git a/patches/server/0050-Reduce-items-finding-hopper-nearby-check.patch b/patches/server/0049-Reduce-items-finding-hopper-nearby-check.patch similarity index 100% rename from patches/server/0050-Reduce-items-finding-hopper-nearby-check.patch rename to patches/server/0049-Reduce-items-finding-hopper-nearby-check.patch diff --git a/patches/server/0051-Plazma-Add-some-missing-Pufferfish-configurations.patch b/patches/server/0050-Plazma-Add-some-missing-Pufferfish-configurations.patch similarity index 100% rename from patches/server/0051-Plazma-Add-some-missing-Pufferfish-configurations.patch rename to patches/server/0050-Plazma-Add-some-missing-Pufferfish-configurations.patch diff --git a/patches/server/0052-Plazma-Add-missing-purpur-configuration-options.patch b/patches/server/0051-Plazma-Add-missing-purpur-configuration-options.patch similarity index 100% rename from patches/server/0052-Plazma-Add-missing-purpur-configuration-options.patch rename to patches/server/0051-Plazma-Add-missing-purpur-configuration-options.patch diff --git a/patches/server/0053-Skip-event-if-no-listeners.patch b/patches/server/0052-Skip-event-if-no-listeners.patch similarity index 100% rename from patches/server/0053-Skip-event-if-no-listeners.patch rename to patches/server/0052-Skip-event-if-no-listeners.patch diff --git a/patches/server/0054-PaperPR-Rewrite-framed-map-tracker-ticking.patch b/patches/server/0053-PaperPR-Rewrite-framed-map-tracker-ticking.patch similarity index 99% rename from patches/server/0054-PaperPR-Rewrite-framed-map-tracker-ticking.patch rename to patches/server/0053-PaperPR-Rewrite-framed-map-tracker-ticking.patch index 45c7f183..5034b60c 100644 --- a/patches/server/0054-PaperPR-Rewrite-framed-map-tracker-ticking.patch +++ b/patches/server/0053-PaperPR-Rewrite-framed-map-tracker-ticking.patch @@ -16,7 +16,7 @@ now is just updating dirty map/decoration data. When no bukkit renderers are added to the map, we also re-use the same packet for all players who are tracking it which avoids a lot of work. diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 539934a75df64e7accf4829d8d4b075833bb5bc9..1aba5405b4b452c9972288f941e861d60331d8b9 100644 +index 55d339ef8782e6b7ab08aebd2b96a4147ac6bcc6..fb93f3400ac693f28fb25e5d370d0f6dae8e120a 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -120,27 +120,40 @@ public class ServerEntity { diff --git a/patches/server/0054-SparklyPaper-Skip-distanceToSqr-call-in-ServerEntity.patch b/patches/server/0054-SparklyPaper-Skip-distanceToSqr-call-in-ServerEntity.patch new file mode 100644 index 00000000..71da86da --- /dev/null +++ b/patches/server/0054-SparklyPaper-Skip-distanceToSqr-call-in-ServerEntity.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrPowerGamerBR +Date: Wed, 15 Nov 2023 23:39:36 -0300 +Subject: [PATCH] SparklyPaper: Skip "distanceToSqr" call in + "ServerEntity#sendChanges" if the delta movement hasn't changed + +Original project: https://github.com/SparklyPower/SparklyPaper + +The "distanceToSqr" call is a bit expensive, so avoiding it is pretty nice, around ~15% calls are skipped with this check + +We could also check if the x,y,z coordinates are equal, but for now, let's just keep the identity check, which also helps us since Minecraft's code does reuse the original delta movement Vec3 object + +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index fb93f3400ac693f28fb25e5d370d0f6dae8e120a..5a17ccd4a620f17c6434f457244ae2b790e2f34e 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -230,12 +230,14 @@ public class ServerEntity { + + if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) { + Vec3 vec3d1 = this.entity.getDeltaMovement(); ++ if (vec3d1 != this.ap) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed + double d0 = vec3d1.distanceToSqr(this.ap); + + if (d0 > 1.0E-7D || d0 > 0.0D && vec3d1.lengthSqr() == 0.0D) { + this.ap = vec3d1; + this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap)); + } ++ } // SparklyPaper end + } + + if (packet1 != null) { diff --git a/patches/server/0056-SparklyPaper-Skip-EntityScheduler-s-executeTick-chec.patch b/patches/server/0056-SparklyPaper-Skip-EntityScheduler-s-executeTick-chec.patch new file mode 100644 index 00000000..e07b3866 --- /dev/null +++ b/patches/server/0056-SparklyPaper-Skip-EntityScheduler-s-executeTick-chec.patch @@ -0,0 +1,138 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrPowerGamerBR +Date: Sun, 19 Nov 2023 12:35:16 -0300 +Subject: [PATCH] SparklyPaper: Skip EntityScheduler's executeTick checks if + there isn't any tasks to be run + +Original project: https://github.com/SparklyPower/SparklyPaper + +On each tick, Paper runs EntityScheduler's executeTick of each entity. This is a bit expensive, due to ArrayDeque's size() call because it ain't a simple "get the current queue size" function, due to the thread checks, and because it needs to iterate all entities in all worlds. + +To avoid the hefty ArrayDeque's size() call, we check if we *really* need to execute the executeTick, by adding all entities with scheduled tasks to a global set. + +Most entities won't have any scheduled tasks, so this is a nice performance bonus. These optimizations, however, wouldn't work in a Folia environment, but because in SparklyPaper executeTick is always executed on the main thread, it ain't an issue for us (yay). + +diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java +index 62484ebf4550b05182f693a3180bbac5d5fd906d..67800e426445060a8343e27a7452b8d7ed27ac5f 100644 +--- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java ++++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java +@@ -36,6 +36,7 @@ public final class EntityScheduler { + * The Entity. Note that it is the CraftEntity, since only that class properly tracks world transfers. + */ + public final CraftEntity entity; ++ public final net.minecraft.server.MinecraftServer server; // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run + + private static final record ScheduledTask(Consumer run, Consumer retired) {} + +@@ -46,7 +47,8 @@ public final class EntityScheduler { + + private final ArrayDeque currentlyExecuting = new ArrayDeque<>(); + +- public EntityScheduler(final CraftEntity entity) { ++ public EntityScheduler(final net.minecraft.server.MinecraftServer server, final CraftEntity entity) { // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run ++ this.server = Validate.notNull(server); + this.entity = Validate.notNull(entity); + } + +@@ -61,14 +63,16 @@ public final class EntityScheduler { + * @throws IllegalStateException If the scheduler is already retired. + */ + public void retire() { ++ final Entity thisEntity = this.entity.getHandleRaw(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run + synchronized (this.stateLock) { + if (this.tickCount == RETIRED_TICK_COUNT) { + throw new IllegalStateException("Already retired"); + } + this.tickCount = RETIRED_TICK_COUNT; ++ this.server.entitiesWithScheduledTasks.remove(thisEntity); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run + } + +- final Entity thisEntity = this.entity.getHandleRaw(); ++ // final Entity thisEntity = this.entity.getHandleRaw(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (moved up) + + // correctly handle and order retiring while running executeTick + for (int i = 0, len = this.currentlyExecuting.size(); i < len; ++i) { +@@ -124,6 +128,7 @@ public final class EntityScheduler { + if (this.tickCount == RETIRED_TICK_COUNT) { + return false; + } ++ this.server.entitiesWithScheduledTasks.add(this.entity.getHandleRaw()); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run + this.oneTimeDelayed.computeIfAbsent(this.tickCount + Math.max(1L, delay), (final long keyInMap) -> { + return new ArrayList<>(); + }).add(task); +@@ -143,6 +148,13 @@ public final class EntityScheduler { + TickThread.ensureTickThread(thisEntity, "May not tick entity scheduler asynchronously"); + final List toRun; + synchronized (this.stateLock) { ++ // SparklyPaper start - skip EntityScheduler's executeTick checks if there isn't any tasks to be run ++ // Do we *really* have scheduled tasks tho? ++ if (this.currentlyExecuting.isEmpty() && this.oneTimeDelayed.isEmpty()) { // Check if we have any pending tasks and, if not, skip! ++ this.server.entitiesWithScheduledTasks.remove(thisEntity); // We don't! Bye bye!! ++ return; ++ } ++ // SparklyPaper end + if (this.tickCount == RETIRED_TICK_COUNT) { + throw new IllegalStateException("Ticking retired scheduler"); + } +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 3e150865ba40413a9caf5e92cd6c4d60debb59da..b6ad776a0a1bc9f7bd25fa665633a75ac500544c 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -304,6 +304,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async) ++ + public gg.pufferfish.pufferfish.util.AsyncExecutor mobSpawnExecutor = new gg.pufferfish.pufferfish.util.AsyncExecutor("pufferfish-async-mob-spawning"); // Pufferfish - optimize mob spawning // Leaf - Unify thread name + + public static S spin(Function serverFactory) { +@@ -1703,6 +1705,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + for (final Entity entity : level.getEntityLookup().getAllCopy()) { // Paper - rewrite chunk system + if (entity.isRemoved()) { +@@ -1714,6 +1728,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Sat, 2 Mar 2024 18:22:15 -0500 Subject: [PATCH] Improve Purpur AFK system -TODO - Dreeam: Configurable afk title time - AFK command & command cooldown AFK title message @@ -21,7 +19,7 @@ index 95c84e0f83d056ee080061cd495c95a328814469..a5784aa215522c4666139a8eac3711c9 org.purpurmc.purpur.command.DemoCommand.register(this.dispatcher); // Purpur org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 9b97d5ca67c0e53f318a54465708e21ae906e994..0e772d847d9a9b4000bcb9547f07663f17d9f2a4 100644 +index 9b97d5ca67c0e53f318a54465708e21ae906e994..2a76960ebd0270ab5a6f850dc7b0b1a6c2cde572 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -2370,6 +2370,8 @@ public class ServerPlayer extends Player { @@ -33,25 +31,36 @@ index 9b97d5ca67c0e53f318a54465708e21ae906e994..0e772d847d9a9b4000bcb9547f07663f @Override public void setAfk(boolean afk) { -@@ -2407,6 +2409,9 @@ public class ServerPlayer extends Player { +@@ -2407,6 +2409,20 @@ public class ServerPlayer extends Player { String prefix = (split.length > 0 ? split[0] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix, ""); String suffix = (split.length > 1 ? split[1] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, ""); if (afk) { -+ net.kyori.adventure.title.Title tile = net.kyori.adventure.title.Title.title(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.afkTitleAway), net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.afkSubTitleAway), net.kyori.adventure.title.Title.Times.times(net.kyori.adventure.util.Ticks.duration(10), net.kyori.adventure.util.Ticks.duration(70), net.kyori.adventure.util.Ticks.duration(20))); -+ getBukkitEntity().showTitle(tile); ++ String[] rawTitle = org.purpurmc.purpur.PurpurConfig.afkTitleAway.split(":"); ++ if (rawTitle.length == 5) { ++ String title = rawTitle[0]; ++ String subTitle = rawTitle[1]; ++ long fadeInTicks = Long.parseLong(rawTitle[2]); ++ long stayTicks = Long.parseLong(rawTitle[3]); ++ long fadeOutTicks = Long.parseLong(rawTitle[4]); ++ net.kyori.adventure.title.Title tile = net.kyori.adventure.title.Title.title(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(title), net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(subTitle), net.kyori.adventure.title.Title.Times.times(net.kyori.adventure.util.Ticks.duration(fadeInTicks), net.kyori.adventure.util.Ticks.duration(stayTicks), net.kyori.adventure.util.Ticks.duration(fadeOutTicks))); ++ getBukkitEntity().showTitle(tile); ++ } else { ++ LOGGER.error("You put wrong format of afk-title-away in PurpurConfig, it should look like AFK:You are now AFK...:10:70:20"); ++ LOGGER.error("'Title:Sub Title:Title Fade In Ticks:Title Stay Ticks:Title Fade Out Ticks', split with :"); ++ } + getBukkitEntity().setPlayerListName(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix + prefix + scoreboardName + suffix + org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, true); } else { getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix, true); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index a0abb0182aa6166b1d2702aa9964132889dc9d86..2c630eddcacee445f44beeefa842e90aff75c0a6 100644 +index a0abb0182aa6166b1d2702aa9964132889dc9d86..6f38bd7a7c6e7bb8ade7b79756ab0afded6add99 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2254,8 +2254,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2254,8 +2254,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } -+ private final Map cooldown = new java.util.concurrent.ConcurrentHashMap<>(); // Purpur ++ public static final Map afkCooldown = new java.util.concurrent.ConcurrentHashMap<>(); // Purpur + @Override public void handleChatCommand(ServerboundChatCommandPacket packet) { @@ -62,36 +71,41 @@ index a0abb0182aa6166b1d2702aa9964132889dc9d86..2c630eddcacee445f44beeefa842e90a + if (org.purpurmc.purpur.PurpurConfig.afkCommandCooldown > 0) { + UUID uuid = player.getUUID(); + long currentTime = System.nanoTime(); -+ if (cooldown.containsKey(uuid) && (currentTime - cooldown.get(uuid)) / 1000000000 <= org.purpurmc.purpur.PurpurConfig.afkCommandCooldown) { ++ if (afkCooldown.containsKey(uuid) && (currentTime - afkCooldown.get(uuid)) / 1_000_000_000 <= org.purpurmc.purpur.PurpurConfig.afkCommandCooldown) { + String msg = org.purpurmc.purpur.PurpurConfig.afkCooldown; + if (msg != null && !msg.isEmpty()) -+ player.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(msg.replace("%time%", String.valueOf(org.purpurmc.purpur.PurpurConfig.afkCommandCooldown - (currentTime - cooldown.get(uuid)) / 1000000000)))); ++ player.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(msg.replace("%time%", String.valueOf(org.purpurmc.purpur.PurpurConfig.afkCommandCooldown - (currentTime - afkCooldown.get(uuid)) / 1_000_000_000)))); + return; + } else { -+ cooldown.put(uuid, currentTime); ++ afkCooldown.put(uuid, currentTime); + } -+ // Dreeam - is this necessary? -+ /* -+ if (cooldown.size() > 200) { -+ cooldown = new java.util.concurrent.ConcurrentHashMap<>(); -+ } -+ */ + } + } + // Purpur end this.tryHandleChat(packet.command(), () -> { // CraftBukkit start - SPIGOT-7346: Prevent disconnected players from executing commands if (this.player.hasDisconnected()) { +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index b87fa81ccee6792b3a202b2c193299dbd2cce112..471933d0e676f600233c7c726c22b866bd4b2f57 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -623,6 +623,7 @@ public abstract class PlayerList { + org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(entityplayer); // Leaves - protocol + // Paper end - Fix kick event leave message not being sent + org.purpurmc.purpur.task.BossBarTask.removeFromAll(entityplayer.getBukkitEntity()); // Purpur ++ net.minecraft.server.network.ServerGamePacketListenerImpl.afkCooldown.remove(entityplayer.getBukkitEntity().getUniqueId()); // Puprur + ServerLevel worldserver = entityplayer.serverLevel(); + + entityplayer.awardStat(Stats.LEAVE_GAME); diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index ecd3f2c3dde43082809851f2e71d18c5d7926ed8..af5eebca926ba5e4bbec8e25da5013fd3e491dbd 100644 +index ecd3f2c3dde43082809851f2e71d18c5d7926ed8..cfdab5174f5ac523cde457c0cee5a172bb53e0e0 100644 --- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -176,9 +176,13 @@ public class PurpurConfig { +@@ -176,9 +176,12 @@ public class PurpurConfig { public static String cannotRideMob = "You cannot mount that mob"; public static String afkBroadcastAway = "%s is now AFK"; public static String afkBroadcastBack = "%s is no longer AFK"; -+ public static String afkTitleAway = "AFK"; -+ public static String afkSubTitleAway = "You are now AFK..."; ++ public static String afkTitleAway = "AFK:You are now AFK...:10:70:20"; public static boolean afkBroadcastUseDisplayName = false; public static String afkTabListPrefix = "[AFK] "; public static String afkTabListSuffix = ""; @@ -100,12 +114,11 @@ index ecd3f2c3dde43082809851f2e71d18c5d7926ed8..af5eebca926ba5e4bbec8e25da5013fd public static String creditsCommandOutput = "%s has been shown the end credits"; public static String demoCommandOutput = "%s has been shown the demo screen"; public static String pingCommandOutput = "%s's ping is %sms"; -@@ -195,9 +199,13 @@ public class PurpurConfig { +@@ -195,9 +198,12 @@ public class PurpurConfig { cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack); + afkTitleAway = getString("settings.messages.afk-title-away", afkTitleAway); -+ afkSubTitleAway = getString("settings.messages.afk-sub-title-away", afkSubTitleAway); afkBroadcastUseDisplayName = getBoolean("settings.messages.afk-broadcast-use-display-name", afkBroadcastUseDisplayName); afkTabListPrefix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix))); afkTabListSuffix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-suffix", afkTabListSuffix))); diff --git a/patches/server/0067-Virtual-Thread-for-async-scheduler.patch b/patches/server/0068-Virtual-Thread-for-async-scheduler.patch similarity index 100% rename from patches/server/0067-Virtual-Thread-for-async-scheduler.patch rename to patches/server/0068-Virtual-Thread-for-async-scheduler.patch diff --git a/patches/server/0068-Mirai-Configurable-chat-message-signatures.patch b/patches/server/0069-Mirai-Configurable-chat-message-signatures.patch similarity index 98% rename from patches/server/0068-Mirai-Configurable-chat-message-signatures.patch rename to patches/server/0069-Mirai-Configurable-chat-message-signatures.patch index 1c1744f8..705cd478 100644 --- a/patches/server/0068-Mirai-Configurable-chat-message-signatures.patch +++ b/patches/server/0069-Mirai-Configurable-chat-message-signatures.patch @@ -117,10 +117,10 @@ index 392a8ce9c36c5d464df3a7d6a75737e19c22bdbb..3754ea28fca1fbcd72866942d72c3567 if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index b87fa81ccee6792b3a202b2c193299dbd2cce112..88633fce3052621358a82f18340be620690cdca6 100644 +index 471933d0e676f600233c7c726c22b866bd4b2f57..e7f83ed096257ad8906b3398a7bcb80a787dfa5a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1533,7 +1533,7 @@ public abstract class PlayerList { +@@ -1534,7 +1534,7 @@ public abstract class PlayerList { // Paper end boolean flag = this.verifyChatTrusted(message); @@ -129,7 +129,7 @@ index b87fa81ccee6792b3a202b2c193299dbd2cce112..88633fce3052621358a82f18340be620 OutgoingChatMessage outgoingchatmessage = OutgoingChatMessage.create(message); boolean flag1 = false; -@@ -1562,6 +1562,7 @@ public abstract class PlayerList { +@@ -1563,6 +1563,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public diff --git a/patches/server/0069-Block-log4j-rce-exploit-in-chat.patch b/patches/server/0070-Block-log4j-rce-exploit-in-chat.patch similarity index 92% rename from patches/server/0069-Block-log4j-rce-exploit-in-chat.patch rename to patches/server/0070-Block-log4j-rce-exploit-in-chat.patch index 599b53b6..5d2b720b 100644 --- a/patches/server/0069-Block-log4j-rce-exploit-in-chat.patch +++ b/patches/server/0070-Block-log4j-rce-exploit-in-chat.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Block log4j rce exploit in chat diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 2c630eddcacee445f44beeefa842e90aff75c0a6..ea1383691d57bfe9da958b6071bdb936fed322d6 100644 +index 6f38bd7a7c6e7bb8ade7b79756ab0afded6add99..9546f79db7ab0a247cc658640e861e96eb1c0ace 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2444,6 +2444,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2438,6 +2438,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void tryHandleChat(String s, Runnable runnable, boolean sync) { // CraftBukkit @@ -17,7 +17,7 @@ index 2c630eddcacee445f44beeefa842e90aff75c0a6..ea1383691d57bfe9da958b6071bdb936 if (ServerGamePacketListenerImpl.isChatMessageIllegal(s)) { this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales -@@ -2475,6 +2477,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2469,6 +2471,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/server/0070-Cache-player-profileResult.patch b/patches/server/0071-Cache-player-profileResult.patch similarity index 100% rename from patches/server/0070-Cache-player-profileResult.patch rename to patches/server/0071-Cache-player-profileResult.patch diff --git a/patches/server/0071-Prevent-change-non-editable-sign-warning-spam-in-con.patch b/patches/server/0072-Prevent-change-non-editable-sign-warning-spam-in-con.patch similarity index 100% rename from patches/server/0071-Prevent-change-non-editable-sign-warning-spam-in-con.patch rename to patches/server/0072-Prevent-change-non-editable-sign-warning-spam-in-con.patch diff --git a/patches/server/0072-Matter-Secure-Seed.patch b/patches/server/0073-Matter-Secure-Seed.patch similarity index 99% rename from patches/server/0072-Matter-Secure-Seed.patch rename to patches/server/0073-Matter-Secure-Seed.patch index b219e7c4..a20ac3b1 100644 --- a/patches/server/0072-Matter-Secure-Seed.patch +++ b/patches/server/0073-Matter-Secure-Seed.patch @@ -47,7 +47,7 @@ index 307a7596024528ad194eb01d6468aff1f5fe02cf..c873c85643ce21d7362673af311e9609 return GsonHelper.parse(!s1.isEmpty() ? s1 : "{}"); }, new JsonObject()), (String) this.get("level-type", (s1) -> { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 9cc83985e3222fdfd32359aab17d6b27bb96870d..50fad3d6c5872b52b59e4b714cf5fb09d6be5629 100644 +index 1a90f1eb0682a307dfab63a5694dadd0f29ab77b..31d789e6559bc72c699f1be5457230fb640be045 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -44,6 +44,10 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp diff --git a/patches/server/0073-Matter-Seed-Command.patch b/patches/server/0074-Matter-Seed-Command.patch similarity index 100% rename from patches/server/0073-Matter-Seed-Command.patch rename to patches/server/0074-Matter-Seed-Command.patch diff --git a/patches/server/0074-Ignore-terminal-provider-warning.patch b/patches/server/0075-Ignore-terminal-provider-warning.patch similarity index 100% rename from patches/server/0074-Ignore-terminal-provider-warning.patch rename to patches/server/0075-Ignore-terminal-provider-warning.patch diff --git a/patches/server/0075-Fix-console-freeze-above-JAVA-22.patch b/patches/server/0076-Fix-console-freeze-above-JAVA-22.patch similarity index 100% rename from patches/server/0075-Fix-console-freeze-above-JAVA-22.patch rename to patches/server/0076-Fix-console-freeze-above-JAVA-22.patch diff --git a/patches/server/0076-Faster-Random-Generator.patch b/patches/server/0077-Faster-Random-Generator.patch similarity index 100% rename from patches/server/0076-Faster-Random-Generator.patch rename to patches/server/0077-Faster-Random-Generator.patch diff --git a/patches/server/0077-Don-t-save-primed-tnt-entity.patch b/patches/server/0078-Don-t-save-primed-tnt-entity.patch similarity index 100% rename from patches/server/0077-Don-t-save-primed-tnt-entity.patch rename to patches/server/0078-Don-t-save-primed-tnt-entity.patch diff --git a/patches/server/0078-Don-t-save-falling-block-entity.patch b/patches/server/0079-Don-t-save-falling-block-entity.patch similarity index 100% rename from patches/server/0078-Don-t-save-falling-block-entity.patch rename to patches/server/0079-Don-t-save-falling-block-entity.patch diff --git a/patches/server/0079-Configurable-connection-message.patch b/patches/server/0080-Configurable-connection-message.patch similarity index 97% rename from patches/server/0079-Configurable-connection-message.patch rename to patches/server/0080-Configurable-connection-message.patch index ad228bf5..38ab2f5a 100644 --- a/patches/server/0079-Configurable-connection-message.patch +++ b/patches/server/0080-Configurable-connection-message.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Configurable connection message diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 88633fce3052621358a82f18340be620690cdca6..4d4dc824ccf185623105566d8ece9e43027c94d6 100644 +index e7f83ed096257ad8906b3398a7bcb80a787dfa5a..7c8e9c3c00d7941f2a87b7175ffe2281f31da205 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -28,6 +28,7 @@ import java.util.function.Predicate; @@ -34,7 +34,7 @@ index 88633fce3052621358a82f18340be620690cdca6..4d4dc824ccf185623105566d8ece9e43 joinMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(jm); // Paper - Adventure this.server.getPlayerList().broadcastSystemMessage(joinMessage, false); // Paper - Adventure } -@@ -633,7 +634,7 @@ public abstract class PlayerList { +@@ -634,7 +635,7 @@ public abstract class PlayerList { entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper - Inventory close reason } @@ -43,7 +43,7 @@ index 88633fce3052621358a82f18340be620690cdca6..4d4dc824ccf185623105566d8ece9e43 this.cserver.getPluginManager().callEvent(playerQuitEvent); entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); -@@ -1706,4 +1707,29 @@ public abstract class PlayerList { +@@ -1707,4 +1708,29 @@ public abstract class PlayerList { public boolean isAllowCommandsForAllPlayers() { return this.allowCommandsForAllPlayers; } diff --git a/patches/server/0081-Remove-stream-in-BlockBehaviour-cache-blockstate.patch b/patches/server/0081-Remove-stream-in-BlockBehaviour-cache-blockstate.patch new file mode 100644 index 00000000..3fbb4ba0 --- /dev/null +++ b/patches/server/0081-Remove-stream-in-BlockBehaviour-cache-blockstate.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Fri, 7 Jun 2024 17:43:43 +0800 +Subject: [PATCH] Remove stream in BlockBehaviour cache blockstate + + +diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +index 031fc626d2075cbe0941fecc188406712ab9953f..999d1ef61de1423f804ecdee586d5335acf5e6e5 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java ++++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +@@ -1374,7 +1374,7 @@ public abstract class BlockBehaviour implements FeatureElement { + @Nullable + final VoxelShape[] occlusionShapes; + protected final VoxelShape collisionShape; +- protected final boolean largeCollisionShape; ++ protected boolean largeCollisionShape; // Leaf - not final + private final boolean[] faceSturdy; + protected final boolean isCollisionShapeFullBlock; + +@@ -1406,9 +1406,14 @@ public abstract class BlockBehaviour implements FeatureElement { + if (!this.collisionShape.isEmpty() && state.hasOffsetFunction()) { + throw new IllegalStateException(String.format(Locale.ROOT, "%s has a collision shape and an offset type, but is not marked as dynamicShape in its properties.", BuiltInRegistries.BLOCK.getKey(block))); + } else { +- this.largeCollisionShape = Arrays.stream(Direction.Axis.values()).anyMatch((enumdirection_enumaxis) -> { +- return this.collisionShape.min(enumdirection_enumaxis) < 0.0D || this.collisionShape.max(enumdirection_enumaxis) > 1.0D; +- }); ++ // Leaf start - Remove stream ++ for (Direction.Axis axis : Direction.Axis.values()) { ++ if (this.collisionShape.min(axis) < 0.0D || this.collisionShape.max(axis) > 1.0D) { ++ this.largeCollisionShape = true; ++ break; ++ } ++ } ++ // Leaf end - Remove stream + this.faceSturdy = new boolean[BlockBehaviour.BlockStateBase.Cache.DIRECTIONS.length * BlockBehaviour.BlockStateBase.Cache.SUPPORT_TYPE_COUNT]; + Direction[] aenumdirection1 = BlockBehaviour.BlockStateBase.Cache.DIRECTIONS; + int k = aenumdirection1.length; diff --git a/patches/server/0043-Fix-tracker-NPE.patch b/patches/server/0082-Tracking-Optimize-Use-thread-safe-Collection.patch similarity index 59% rename from patches/server/0043-Fix-tracker-NPE.patch rename to patches/server/0082-Tracking-Optimize-Use-thread-safe-Collection.patch index 99969663..e7524946 100644 --- a/patches/server/0043-Fix-tracker-NPE.patch +++ b/patches/server/0082-Tracking-Optimize-Use-thread-safe-Collection.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> -Date: Wed, 2 Aug 2023 16:14:12 +0800 -Subject: [PATCH] Fix tracker NPE +Date: Thu, 23 May 2024 21:28:02 +0800 +Subject: [PATCH] Tracking Optimize: Use thread-safe Collection diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 822604900ccfe18d8e73c746af2d3d0fc36a2734..5e95d84c37d2d36d62a0b5b3f55bf28bd40bf7ee 100644 +index a8821f031d85ca66f96aece7c179c40ee96fb90f..29780ed86e938ea1f9e6405e5dee84b09abe3ac0 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -244,7 +244,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -13,33 +13,50 @@ index 822604900ccfe18d8e73c746af2d3d0fc36a2734..5e95d84c37d2d36d62a0b5b3f55bf28b // Paper end // Paper start - optimise chunk tick iteration - public final it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet needsChangeBroadcasting = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); -+ public final Set needsChangeBroadcasting = Sets.newConcurrentHashSet(); // Leaf - Fix tracker NPE ++ public final Set needsChangeBroadcasting = Sets.newConcurrentHashSet(); // Leaf - Use thread-safe collection public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap = new gg.pufferfish.pufferfish.util.AsyncPlayerAreaMap(this.pooledLinkedPlayerHashSets); // Pufferfish // Paper end - optimise chunk tick iteration diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index e769e8d8e853b2731d85b75d273b029fd08861fa..6e19dc2d167e47ead14aba57bb2ae2fa5eb2282a 100644 +index 31d789e6559bc72c699f1be5457230fb640be045..700b8713e41982aa9e1f1ae54eb850a31d3ace52 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -640,7 +640,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -644,7 +644,7 @@ public class ServerChunkCache extends ChunkSource { // Paper - optimise chunk tick iteration // Paper start - optimise chunk tick iteration if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { - it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -+ List copy = new java.util.ArrayList<>(this.chunkMap.needsChangeBroadcasting); // Leaf - Fix tracker NPE ++ List copy = new java.util.ArrayList<>(this.chunkMap.needsChangeBroadcasting); // Leaf - Use thread-safe collection this.chunkMap.needsChangeBroadcasting.clear(); for (ChunkHolder holder : copy) { holder.broadcastChanges(holder.getFullChunkNowUnchecked()); // LevelChunks are NEVER unloaded +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index 5a17ccd4a620f17c6434f457244ae2b790e2f34e..d57c6b9d9b37d94829c01f63977ad2caca110dfd 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -436,7 +436,7 @@ public class ServerEntity { + + if (!set.isEmpty()) { + // Leaf start - petal - sync +- final Set copy = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(set); ++ final Set copy = com.google.common.collect.Sets.newConcurrentHashSet(set); + ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> { + // CraftBukkit start - Send scaled max health + if (this.entity instanceof ServerPlayer) { diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index 894082d9a8e2aa05f86948bfd335090f37a4ba07..679f3295d3e6cf6fa8ff535d60b39ad5fa771b5d 100644 +index 894082d9a8e2aa05f86948bfd335090f37a4ba07..9d16bcfb64885d8f23df8effd44f35bb3a0fa2e4 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -@@ -20,7 +20,7 @@ import org.slf4j.Logger; +@@ -19,8 +19,10 @@ import org.slf4j.Logger; + public class AttributeMap { private static final Logger LOGGER = LogUtils.getLogger(); - private final Map, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>(); +- private final Map, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>(); - private final Set dirtyAttributes = new ObjectOpenHashSet<>(); -+ private final Set dirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); // Leaf - Fix tracker NPE ++ // Leaf start - Use thread-safe collection ++ private final Map, AttributeInstance> attributes = com.google.common.collect.Maps.newConcurrentMap(); ++ private final Set dirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); ++ // Leaf end - Use thread-safe collection private final AttributeSupplier supplier; private final java.util.function.Function, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations private final net.minecraft.world.entity.LivingEntity entity; // Purpur diff --git a/patches/server/0083-Tracking-Optimize-Reduce-expensive-iteration.patch b/patches/server/0083-Tracking-Optimize-Reduce-expensive-iteration.patch new file mode 100644 index 00000000..b171da7b --- /dev/null +++ b/patches/server/0083-Tracking-Optimize-Reduce-expensive-iteration.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Thu, 23 May 2024 21:28:02 +0800 +Subject: [PATCH] Tracking Optimize: Reduce expensive iteration + + +diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java +index 29780ed86e938ea1f9e6405e5dee84b09abe3ac0..4c23012c07d91b804ed72bfa4ee953dfad7a7a96 100644 +--- a/src/main/java/net/minecraft/server/level/ChunkMap.java ++++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +@@ -1173,6 +1173,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + return; + } + // Leaf end - petal ++ ++ if (net.minecraft.server.MinecraftServer.getServer().getPlayerList().players.isEmpty()) return; // Leaf - Don't update since the server is empty ++ + for (TrackedEntity tracker : this.entityMap.values()) { + // update tracker entry + tracker.updatePlayers(tracker.entity.getPlayersInTrackRange()); +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index d57c6b9d9b37d94829c01f63977ad2caca110dfd..c2db18cbb1230588e6b1783dc51c69ed3ccd2e34 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -449,7 +449,7 @@ public class ServerEntity { + // Leaf end - petal + } + +- set.clear(); ++ ((LivingEntity) this.entity).getAttributes().clearDirtyAttributes(); // Leaf + } + + } +diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +index 9d16bcfb64885d8f23df8effd44f35bb3a0fa2e4..9c06b3f76ca9d4f270399d983f1f31c5152de96d 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java ++++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +@@ -21,7 +21,7 @@ public class AttributeMap { + private static final Logger LOGGER = LogUtils.getLogger(); + // Leaf start - Use thread-safe collection + private final Map, AttributeInstance> attributes = com.google.common.collect.Maps.newConcurrentMap(); +- private final Set dirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); ++ private Set dirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); // Leaf - no final + // Leaf end - Use thread-safe collection + private final AttributeSupplier supplier; + private final java.util.function.Function, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations +@@ -49,6 +49,12 @@ public class AttributeMap { + return this.dirtyAttributes; + } + ++ // Leaf start - Reduce expensive clear() iteration ++ public void clearDirtyAttributes() { ++ this.dirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); ++ } ++ // Leaf end - Reduce expensive clear() iteration ++ + public Collection getSyncableAttributes() { + return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(attribute.getAttribute().value()))).collect(Collectors.toList()); // Purpur + } diff --git a/patches/unapplied/server/0084-Tracking-Optimize-reduce-ArmorStand.patch b/patches/unapplied/server/0084-Tracking-Optimize-reduce-ArmorStand.patch new file mode 100644 index 00000000..9986c4b7 --- /dev/null +++ b/patches/unapplied/server/0084-Tracking-Optimize-reduce-ArmorStand.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Thu, 23 May 2024 23:03:10 +0800 +Subject: [PATCH] Tracking Optimize: reduce ArmorStand + + +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index dced0a22e924838b13edd0c24a7d3fb3de9242d6..05d94bdc6f9c8baafa392fa3e8f2221df999277c 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -1437,7 +1437,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + return; + }*/ // Paper - comment out EAR 2 + // Spigot end +- final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); ++ boolean isActive = shouldActive(entity); // Leaf - Reduce entity tick + entity.setOldPosAndRot(); + + ++entity.tickCount; +@@ -1465,7 +1465,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { + if (passenger instanceof Player || this.entityTickList.contains(passenger)) { + // Paper - EAR 2 +- final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); ++ final boolean isActive = shouldActive(passenger); // Leaf - Reduce entity tick + passenger.setOldPosAndRot(); + ++passenger.tickCount; + // Paper start - EAR 2 +@@ -1492,6 +1492,12 @@ public class ServerLevel extends Level implements WorldGenLevel { + } + } + ++ // Leaf start - Reduce entity tick ++ private boolean shouldActive(Entity entity) { ++ return entity instanceof net.minecraft.world.entity.decoration.ArmorStand ? entity.level().paperConfig().entities.armorStands.tick : org.spigotmc.ActivationRange.checkIfActive(entity); ++ } ++ // Leaf end - Reduce entity tick ++ + @Override + public boolean mayInteract(Player player, BlockPos pos) { + return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos); +diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java +index 37e35606e3f47325db4da5deeff02aad9d541e87..b3fa485dbf96a5b691f423d004bbe0ff7bde4f9a 100644 +--- a/src/main/java/org/spigotmc/ActivationRange.java ++++ b/src/main/java/org/spigotmc/ActivationRange.java +@@ -147,6 +147,13 @@ public class ActivationRange + */ + public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config) + { ++ // Leaf start - Reduce ArmorStand tick ++ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand ++ && !entity.level().paperConfig().entities.armorStands.tick) { ++ return false; ++ } ++ // Leaf end - Reduce ArmorStand tick ++ + if ( ( entity.activationType == ActivationType.MISC && config.miscActivationRange <= 0 ) + || ( entity.activationType == ActivationType.RAIDER && config.raiderActivationRange <= 0 ) + || ( entity.activationType == ActivationType.ANIMAL && config.animalActivationRange <= 0 ) +@@ -233,12 +240,18 @@ public class ActivationRange + // Paper start + java.util.List entities = world.getEntities((Entity)null, ActivationRange.maxBB, null); + boolean tickMarkers = world.paperConfig().entities.markers.tick; // Paper - Configurable marker ticking ++ boolean tickArmorStands = world.paperConfig().entities.armorStands.tick; // Leaf - Reduce entity tick + for (Entity entity : entities) { + // Paper start - Configurable marker ticking + if (!tickMarkers && entity instanceof net.minecraft.world.entity.Marker) { + continue; + } + // Paper end - Configurable marker ticking ++ // Leaf start - Reduce entity tick ++ if (!tickArmorStands && entity instanceof net.minecraft.world.entity.decoration.ArmorStand) { ++ continue; ++ } ++ // Leaf end - Reduce entity tick + ActivationRange.activateEntity(entity); + + // Pufferfish start diff --git a/patches/unapplied/server/0085-Tracking-Optimize-Skip-redundant-useless-packets.patch b/patches/unapplied/server/0085-Tracking-Optimize-Skip-redundant-useless-packets.patch new file mode 100644 index 00000000..866a7ed2 --- /dev/null +++ b/patches/unapplied/server/0085-Tracking-Optimize-Skip-redundant-useless-packets.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Fri, 24 May 2024 19:03:02 +0800 +Subject: [PATCH] Tracking Optimize: Skip redundant useless packets + + +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index c2db18cbb1230588e6b1783dc51c69ed3ccd2e34..71a7b36f7ab1d0743591495a45d8a153cee138e8 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -418,23 +418,34 @@ public class ServerEntity { + // Paper end + } + ++ // Leaf start - Tracking Optimize - Skip redundant useless packets ++ private List> lastSendDirtyData = new ArrayList<>(); ++ private Set lastSendDirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(); ++ // Leaf end - Tracking Optimize - Skip redundant useless packets + private void sendDirtyEntityData() { + SynchedEntityData datawatcher = this.entity.getEntityData(); + List> list = datawatcher.packDirty(); + + if (list != null) { + this.trackedDataValues = datawatcher.getNonDefaultValues(); ++ // Leaf start - Tracking Optimize - Skip redundant useless packets ++ if (!lastSendDirtyData.equals(list)) { + // Leaf start - petal - sync + ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> + this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list)) + ); + // Leaf end - petal ++ lastSendDirtyData = new ArrayList<>(list); ++ } ++ // Leaf end - Tracking Optimize - Skip redundant useless packets + } + + if (this.entity instanceof LivingEntity) { + Set set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes(); + + if (!set.isEmpty()) { ++ // Leaf start - Tracking Optimize - Skip redundant useless packets ++ if (!lastSendDirtyAttributes.equals(set)) { + // Leaf start - petal - sync + final Set copy = com.google.common.collect.Sets.newConcurrentHashSet(set); + ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> { +@@ -447,6 +458,9 @@ public class ServerEntity { + + }); + // Leaf end - petal ++ lastSendDirtyAttributes = com.google.common.collect.Sets.newConcurrentHashSet(set); ++ } ++ // Leaf end - Tracking Optimize - Skip redundant useless packets + } + + ((LivingEntity) this.entity).getAttributes().clearDirtyAttributes(); // Leaf