diff --git a/patches/server/API-for-checking-sent-chunks.patch b/patches/server/API-for-checking-sent-chunks.patch index 089b388295..445a0431bc 100644 --- a/patches/server/API-for-checking-sent-chunks.patch +++ b/patches/server/API-for-checking-sent-chunks.patch @@ -16,28 +16,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public Set getSentChunkKeys() { + org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks"); -+ return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable( -+ this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().clone() -+ ); ++ final it.unimi.dsi.fastutil.longs.LongOpenHashSet keys = new it.unimi.dsi.fastutil.longs.LongOpenHashSet(); ++ this.getHandle().getChunkTrackingView().forEach(pos -> keys.add(pos.longKey)); ++ return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable(keys); + } + + @Override + public Set getSentChunks() { + org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks"); -+ final it.unimi.dsi.fastutil.longs.LongOpenHashSet rawChunkKeys = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw(); -+ final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(rawChunkKeys.size()); ++ final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(); + final org.bukkit.World world = this.getWorld(); -+ -+ final it.unimi.dsi.fastutil.longs.LongIterator iter = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().longIterator(); -+ while (iter.hasNext()) chunks.add(world.getChunkAt(iter.nextLong(), false)); -+ ++ this.getHandle().getChunkTrackingView().forEach(pos -> { ++ final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey); ++ chunks.add(chunk); ++ }); + return it.unimi.dsi.fastutil.objects.ObjectSets.unmodifiable(chunks); + } + + @Override + public boolean isChunkSent(final long chunkKey) { + org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks"); -+ return this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().contains(chunkKey); ++ return this.getHandle().getChunkTrackingView().contains(new net.minecraft.world.level.ChunkPos(chunkKey)); + } + // Paper end + diff --git a/patches/server/API-to-allow-disallow-tick-sleeping.patch b/patches/server/API-to-allow-disallow-tick-sleeping.patch index bf2d7f3439..2bcb085d0c 100644 --- a/patches/server/API-to-allow-disallow-tick-sleeping.patch +++ b/patches/server/API-to-allow-disallow-tick-sleeping.patch @@ -9,13 +9,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping public static S spin(Function serverFactory) { - ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system + AtomicReference atomicreference = new AtomicReference(); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= 0) { - com.velocitypowered.natives.compression.VelocityCompressor compressor = com.velocitypowered.natives.util.Natives.compress.get().create(io.papermc.paper.configuration.GlobalConfiguration.get().misc.compressionLevel.or(-1)); // Paper - Use Velocity cipher + ChannelHandler channelhandler = this.channel.pipeline().get("decompress"); diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java diff --git a/patches/server/Add-registry-entry-and-builders.patch b/patches/server/Add-registry-entry-and-builders.patch index f3f3fdc2b0..b385809ac7 100644 --- a/patches/server/Add-registry-entry-and-builders.patch +++ b/patches/server/Add-registry-entry-and-builders.patch @@ -3,7 +3,6 @@ From: Bjarne Koll Date: Thu, 13 Jun 2024 23:45:32 +0200 Subject: [PATCH] Add registry entry and builders -Feature patch diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Add-startup-flag-to-disable-gamerule-limits.patch b/patches/server/Add-startup-flag-to-disable-gamerule-limits.patch index c06a806cdc..b7a4dfbbfd 100644 --- a/patches/server/Add-startup-flag-to-disable-gamerule-limits.patch +++ b/patches/server/Add-startup-flag-to-disable-gamerule-limits.patch @@ -5,6 +5,9 @@ Subject: [PATCH] Add startup flag to disable gamerule limits -DPaper.DisableGameRuleLimits=true will disable gamerule limits +== AT == +public net.minecraft.server.level.ChunkLevel ENTITY_TICKING_LEVEL + diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/patches/server/Allow-Saving-of-Oversized-Chunks.patch b/patches/server/Allow-Saving-of-Oversized-Chunks.patch index 707258fab6..6c06181f47 100644 --- a/patches/server/Allow-Saving-of-Oversized-Chunks.patch +++ b/patches/server/Allow-Saving-of-Oversized-Chunks.patch @@ -30,8 +30,6 @@ This fix also maintains compatability if someone switches server jars to one wit this fix, as the data will remain in the oversized file. Once the server returns to a jar with this fix, the data will be restored. -Feature patch - diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java diff --git a/patches/server/Allow-using-old-ender-pearl-behavior.patch b/patches/server/Allow-using-old-ender-pearl-behavior.patch index 41e43a9e8f..c729b39847 100644 --- a/patches/server/Allow-using-old-ender-pearl-behavior.patch +++ b/patches/server/Allow-using-old-ender-pearl-behavior.patch @@ -12,7 +12,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { while (iterator.hasNext()) { ThrownEnderpearl entityenderpearl = (ThrownEnderpearl) iterator.next(); @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (entityenderpearl.isRemoved()) { ServerPlayer.LOGGER.warn("Trying to save removed ender pearl, skipping"); -@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public static long placeEnderPearlTicket(ServerLevel world, ChunkPos chunkPos) { diff --git a/patches/server/Anti-Xray.patch b/patches/server/Anti-Xray.patch index 37110c40d6..c88549b1fe 100644 --- a/patches/server/Anti-Xray.patch +++ b/patches/server/Anti-Xray.patch @@ -3,7 +3,6 @@ From: stonar96 Date: Thu, 25 Nov 2021 13:27:51 +0100 Subject: [PATCH] Anti-Xray -Feature patch diff --git a/src/main/java/com/destroystokyo/paper/antixray/BitStorageReader.java b/src/main/java/com/destroystokyo/paper/antixray/BitStorageReader.java new file mode 100644 diff --git a/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch index d032d86be7..0aa11765a3 100644 --- a/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch +++ b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch @@ -9,8 +9,6 @@ we instead drop the current regionfile header and recalculate - hoping that at least then we don't swap chunks, and maybe recover them all. -Feature patch - diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java diff --git a/patches/server/Bundle-spark.patch b/patches/server/Bundle-spark.patch index 5f097d13b8..07a1f67842 100644 --- a/patches/server/Bundle-spark.patch +++ b/patches/server/Bundle-spark.patch @@ -300,13 +300,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.server.waitForAsyncTasksShutdown(); // Paper - Wait for Async Tasks during shutdown } @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Mon, 2 Aug 2021 10:10:40 +0200 Subject: [PATCH] Check distance in entity interactions -Feature patch diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Detail-more-information-in-watchdog-dumps.patch b/patches/server/Detail-more-information-in-watchdog-dumps.patch index d34fee8fe9..9d5a4deee3 100644 --- a/patches/server/Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/Detail-more-information-in-watchdog-dumps.patch @@ -6,8 +6,6 @@ Subject: [PATCH] Detail more information in watchdog dumps - Dump position, world, velocity, and uuid for currently ticking entities - Dump player name, player uuid, position, and world for packet handling -Feature patch - diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/Connection.java diff --git a/patches/server/Eigencraft-redstone-implementation.patch b/patches/server/Eigencraft-redstone-implementation.patch index a420647d31..87c9d93cc3 100644 --- a/patches/server/Eigencraft-redstone-implementation.patch +++ b/patches/server/Eigencraft-redstone-implementation.patch @@ -17,8 +17,6 @@ A lot of this code is self-contained in a helper class. Aside from making the obvious class/function renames and obfhelpers I didn't need to modify much. Just added Bukkit's event system and took a few liberties with dead code and comment misspellings. -Feature patch - == AT == public net.minecraft.world.level.block.RedStoneWireBlock shouldSignal public net.minecraft.world.level.block.RedStoneWireBlock canSurvive(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/LevelReader;Lnet/minecraft/core/BlockPos;)Z diff --git a/patches/server/Entity-Activation-Range-2.0.patch b/patches/server/Entity-Activation-Range-2.0.patch index 83eaaaf10b..d9a21e0900 100644 --- a/patches/server/Entity-Activation-Range-2.0.patch +++ b/patches/server/Entity-Activation-Range-2.0.patch @@ -13,8 +13,6 @@ Adds water Mobs to activation range config and nerfs fish Adds flying monsters to control ghast and phantoms Adds villagers as separate config -Feature patch - == AT == public net.minecraft.world.entity.Entity isInsidePortal diff --git a/patches/server/Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/Fix-entity-tracker-desync-when-new-players-are-added.patch index 610ec23196..e80eb74101 100644 --- a/patches/server/Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -28,8 +28,6 @@ which is most likely in an unloaded chunk - which means that the client will not tick the entity and thus not lerp the entity from its old position to its new position. -Feature patch - diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java diff --git a/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch index 3a81de94fe..d5c45f7291 100644 --- a/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch @@ -9,8 +9,6 @@ when if this was fixed on the client, that wouldn't be needed. Mojira Issue: https://bugs.mojang.com/browse/MC-235045 -Feature patch - diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java diff --git a/patches/server/Flat-bedrock-generator-settings.patch b/patches/server/Flat-bedrock-generator-settings.patch index 47719b17b4..4d8c54d243 100644 --- a/patches/server/Flat-bedrock-generator-settings.patch +++ b/patches/server/Flat-bedrock-generator-settings.patch @@ -18,8 +18,6 @@ public net.minecraft.world.level.levelgen.SurfaceRules$SurfaceRule Co-authored-by: Noah van der Aa -Feature patch - diff --git a/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java b/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/Handle-Oversized-block-entities-in-chunks.patch b/patches/server/Handle-Oversized-block-entities-in-chunks.patch index 248c7320e8..da2af1a0ea 100644 --- a/patches/server/Handle-Oversized-block-entities-in-chunks.patch +++ b/patches/server/Handle-Oversized-block-entities-in-chunks.patch @@ -6,8 +6,6 @@ Subject: [PATCH] Handle Oversized block entities in chunks Splits out Extra Packets if too many TE's are encountered to prevent creating too large of a packet to sed. -Feature patch - Co-authored-by: Spottedleaf diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java diff --git a/patches/server/Implement-Mob-Goal-API.patch b/patches/server/Implement-Mob-Goal-API.patch index 7c68ba2fc8..636e393c63 100644 --- a/patches/server/Implement-Mob-Goal-API.patch +++ b/patches/server/Implement-Mob-Goal-API.patch @@ -317,7 +317,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static EnumSet vanillaToPaper(Goal goal) { + EnumSet goals = EnumSet.noneOf(GoalType.class); + for (GoalType type : GoalType.values()) { -+ if (goal.getFlags().hasElement(paperToVanilla(type))) { ++ if (goal.hasFlag(paperToVanilla(type))) { + goals.add(type); + } + } @@ -423,7 +423,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + this.setFlags(MobGoalHelper.paperToVanilla(handle.getTypes())); + if (this.getFlags().size() == 0) { -+ this.getFlags().addUnchecked(Flag.UNKNOWN_BEHAVIOR); ++ this.addFlag(Flag.UNKNOWN_BEHAVIOR); + } + } + @@ -587,7 +587,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + CraftMob craftMob = (CraftMob) mob; + Set> goals = new HashSet<>(); + for (WrappedGoal item : getHandle(craftMob, type).getAvailableGoals()) { -+ if (!item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) { ++ if (!item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) { + continue; + } + @@ -610,7 +610,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + continue; + } + for (WrappedGoal item : getHandle(craftMob, internalType).getAvailableGoals()) { -+ if (item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) { ++ if (item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) { + continue; + } + @@ -640,7 +640,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Set> goals = new HashSet<>(); + getHandle(craftMob, type).getAvailableGoals() + .stream().filter(WrappedGoal::isRunning) -+ .filter(item -> item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) ++ .filter(item -> item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) + .forEach(item -> { + if (item.getGoal() instanceof PaperCustomGoal) { + //noinspection unchecked @@ -663,7 +663,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + getHandle(craftMob, internalType).getAvailableGoals() + .stream() + .filter(WrappedGoal::isRunning) -+ .filter(item -> !item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) ++ .filter(item -> !item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) + .forEach(item -> { + if (item.getGoal() instanceof PaperCustomGoal) { + //noinspection unchecked @@ -763,6 +763,23 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +@@ -0,0 +0,0 @@ public abstract class Goal { + return this.flags; + } + ++ // Paper start - Mob Goal API ++ public boolean hasFlag(final Goal.Flag flag) { ++ return this.flags.contains(flag); ++ } ++ ++ public void addFlag(final Goal.Flag flag) { ++ this.flags.add(flag); ++ } ++ // Paper end - Mob Goal API ++ + protected int adjustedTickDelay(int ticks) { + return this.requiresUpdateEveryTick() ? ticks : reducedTickDelay(ticks); + } @@ -0,0 +0,0 @@ public abstract class Goal { return (ServerLevel)world; } diff --git a/patches/server/Implement-chunk-view-API.patch b/patches/server/Implement-chunk-view-API.patch new file mode 100644 index 0000000000..06179987d9 --- /dev/null +++ b/patches/server/Implement-chunk-view-API.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Flo0 +Date: Thu, 5 Dec 2024 12:15:07 +0100 +Subject: [PATCH] Implement chunk view API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + @Override + public Set getSentChunkKeys() { + org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks"); +- final it.unimi.dsi.fastutil.longs.LongOpenHashSet keys = new it.unimi.dsi.fastutil.longs.LongOpenHashSet(); +- this.getHandle().getChunkTrackingView().forEach(pos -> keys.add(pos.longKey)); +- return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable(keys); ++ return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable( ++ this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().clone() ++ ); + } + + @Override + public Set getSentChunks() { + org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks"); +- final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(); ++ final it.unimi.dsi.fastutil.longs.LongOpenHashSet rawChunkKeys = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw(); ++ final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(rawChunkKeys.size()); + final org.bukkit.World world = this.getWorld(); +- this.getHandle().getChunkTrackingView().forEach(pos -> { +- final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey); +- chunks.add(chunk); +- }); ++ ++ final it.unimi.dsi.fastutil.longs.LongIterator iter = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().longIterator(); ++ while (iter.hasNext()) chunks.add(world.getChunkAt(iter.nextLong(), false)); ++ + return it.unimi.dsi.fastutil.objects.ObjectSets.unmodifiable(chunks); + } + + @Override + public boolean isChunkSent(final long chunkKey) { + org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks"); +- return this.getHandle().getChunkTrackingView().contains(new net.minecraft.world.level.ChunkPos(chunkKey)); ++ return this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().contains(chunkKey); + } + // Paper end + diff --git a/patches/server/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index 9ccfc007fb..11b55680e0 100644 --- a/patches/server/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/patches/server/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -12,8 +12,6 @@ custom renderers are in use, defaulting to the much simpler Vanilla system. Additionally, numerous issues to player position tracking on maps has been fixed. -Feature patch - diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/patches/server/Improve-exact-choice-recipe-ingredients.patch b/patches/server/Improve-exact-choice-recipe-ingredients.patch index 5cbea3b54d..be741b29e9 100644 --- a/patches/server/Improve-exact-choice-recipe-ingredients.patch +++ b/patches/server/Improve-exact-choice-recipe-ingredients.patch @@ -6,8 +6,6 @@ Subject: [PATCH] Improve exact choice recipe ingredients Fixes exact choices not working with recipe book clicks and shapeless recipes. -Feature patch - == AT == public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG diff --git a/patches/server/Improve-performance-of-mass-crafts.patch b/patches/server/Improve-performance-of-mass-crafts.patch index 5a67e76ed7..c09f2cf750 100644 --- a/patches/server/Improve-performance-of-mass-crafts.patch +++ b/patches/server/Improve-performance-of-mass-crafts.patch @@ -19,8 +19,6 @@ for each craft, that logic is run 9 times (hence the 64 * 9). The + 64 is from t After this patch, the full iteration over all recipes checking for a match should run once for a full craft to find the initial recipe match. Then that recipe will be checked first for all future recipe match checks. -Feature patch - diff --git a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java diff --git a/patches/server/Improved-Watchdog-Support.patch b/patches/server/Improved-Watchdog-Support.patch index 87fe747b2d..b8c641deb3 100644 --- a/patches/server/Improved-Watchdog-Support.patch +++ b/patches/server/Improved-Watchdog-Support.patch @@ -40,8 +40,6 @@ This is to ensure that if main isn't truely stuck, it's not manipulating state w This also moves all plugins who register "delayed init" tasks to occur just before "Done" so they are properly accounted for and wont trip watchdog on init. -Feature patch - diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java @@ -130,8 +128,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot start public static final int TPS = 20; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping + public volatile Thread shutdownThread; // Paper + public volatile boolean abnormalExit = false; // Paper @@ -191,8 +189,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 throw new IllegalStateException("Failed to initialize server"); } @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Sun, 9 Jun 2019 03:53:22 +0100 Subject: [PATCH] Incremental chunk and player saving -Feature patch diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Item-serialization-as-json.patch b/patches/server/Item-serialization-as-json.patch index a0e792e96e..8d457b2699 100644 --- a/patches/server/Item-serialization-as-json.patch +++ b/patches/server/Item-serialization-as-json.patch @@ -60,10 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + final int dataVersion = data.get("DataVersion").getAsInt(); + final int currentVersion = org.bukkit.craftbukkit.util.CraftMagicNumbers.INSTANCE.getDataVersion(); -+ data = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertJson( -+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, -+ data, false, dataVersion, currentVersion -+ ); ++ data = (com.google.gson.JsonObject) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic<>(com.mojang.serialization.JsonOps.INSTANCE, data), dataVersion, currentVersion).getValue(); + com.mojang.serialization.DynamicOps ops = MinecraftServer.getServer().registryAccess().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE); + return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(ops, data).getOrThrow(IllegalArgumentException::new)); + } diff --git a/patches/server/Lag-compensation-ticks.patch b/patches/server/Lag-compensation-ticks.patch index 2147dbe6ed..a2f30eb99d 100644 --- a/patches/server/Lag-compensation-ticks.patch +++ b/patches/server/Lag-compensation-ticks.patch @@ -7,8 +7,6 @@ Areas affected by lag comepnsation: - Block breaking and destroying - Eating food items -Feature patch - diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch index ae87d4707e..2266b4affa 100644 --- a/patches/server/MC-Utils.patch +++ b/patches/server/MC-Utils.patch @@ -2597,285 +2597,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); + } +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -@@ -0,0 +0,0 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.moonrise.common.list.ReferenceList; -+import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import ca.spottedleaf.moonrise.common.util.MoonriseConstants; -+import ca.spottedleaf.moonrise.common.util.ChunkSystem; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; -+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; -+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; -+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; -+import net.minecraft.core.BlockPos; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.level.ChunkPos; -+import java.util.ArrayList; -+ -+public final class NearbyPlayers { -+ -+ public static enum NearbyMapType { -+ GENERAL, -+ GENERAL_SMALL, -+ GENERAL_REALLY_SMALL, -+ TICK_VIEW_DISTANCE, -+ VIEW_DISTANCE, -+ // Moonrise start - chunk tick iteration -+ SPAWN_RANGE { -+ @Override -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); -+ } -+ -+ @Override -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); -+ } -+ }; -+ // Moonrise end - chunk tick iteration -+ -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } -+ -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } -+ } -+ -+ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); -+ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length; -+ -+ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1; -+ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10; -+ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3; -+ -+ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4); -+ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4); -+ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4); -+ -+ private final ServerLevel world; -+ private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; -+ { -+ for (int i = 0; i < this.directByChunk.length; ++i) { -+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); -+ } -+ } -+ -+ public NearbyPlayers(final ServerLevel world) { -+ this.world = world; -+ } -+ -+ public void addPlayer(final ServerPlayer player) { -+ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES]; -+ if (this.players.putIfAbsent(player, newTrackers) != null) { -+ throw new IllegalStateException("Already have player " + player); -+ } -+ -+ final ChunkPos chunk = player.chunkPosition(); -+ -+ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) { -+ // use 0 for default, will be updated by tickPlayer -+ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0); -+ } -+ -+ // update view distances -+ this.tickPlayer(player); -+ } -+ -+ public void removePlayer(final ServerPlayer player) { -+ final TrackedPlayer[] players = this.players.remove(player); -+ if (players == null) { -+ return; // May be called during teleportation before the player is actually placed -+ } -+ -+ for (final TrackedPlayer tracker : players) { -+ tracker.remove(); -+ } -+ } -+ -+ public void clear() { -+ if (this.players.isEmpty()) { -+ return; -+ } -+ -+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { -+ this.removePlayer(player); -+ } -+ } -+ -+ public void tickPlayer(final ServerPlayer player) { -+ final TrackedPlayer[] players = this.players.get(player); -+ if (players == null) { -+ throw new IllegalStateException("Don't have player " + player); -+ } -+ -+ final ChunkPos chunk = player.chunkPosition(); -+ -+ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE); -+ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE); -+ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE); -+ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player)); -+ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getViewDistance(player)); -+ players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration -+ } -+ -+ public TrackedChunk getChunk(final ChunkPos pos) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public TrackedChunk getChunk(final BlockPos pos) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ -+ public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -+ } -+ -+ public static final class TrackedChunk { -+ -+ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; -+ -+ private final long chunkKey; -+ private final NearbyPlayers nearbyPlayers; -+ private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; -+ private int nonEmptyLists; -+ private long updateCount; -+ -+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { -+ this.chunkKey = chunkKey; -+ this.nearbyPlayers = nearbyPlayers; -+ } -+ -+ public boolean isEmpty() { -+ return this.nonEmptyLists == 0; -+ } -+ -+ public long getUpdateCount() { -+ return this.updateCount; -+ } -+ -+ public ReferenceList getPlayers(final NearbyMapType type) { -+ return this.players[type.ordinal()]; -+ } -+ -+ public void addPlayer(final ServerPlayer player, final NearbyMapType type) { -+ ++this.updateCount; -+ -+ final int idx = type.ordinal(); -+ final ReferenceList list = this.players[idx]; -+ if (list == null) { -+ ++this.nonEmptyLists; -+ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); -+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); -+ players.add(player); -+ return; -+ } -+ -+ if (!list.add(player)) { -+ throw new IllegalStateException("Already contains player " + player); -+ } -+ } -+ -+ public void removePlayer(final ServerPlayer player, final NearbyMapType type) { -+ ++this.updateCount; -+ -+ final int idx = type.ordinal(); -+ final ReferenceList list = this.players[idx]; -+ if (list == null) { -+ throw new IllegalStateException("Does not contain player " + player); -+ } -+ -+ if (!list.remove(player)) { -+ throw new IllegalStateException("Does not contain player " + player); -+ } -+ -+ if (list.size() == 0) { -+ this.players[idx] = null; -+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); -+ --this.nonEmptyLists; -+ } -+ } -+ } -+ -+ private final class TrackedPlayer extends SingleUserAreaMap { -+ -+ private final NearbyMapType type; -+ -+ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) { -+ super(player); -+ this.type = type; -+ } -+ -+ @Override -+ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ final NearbyMapType type = this.type; -+ if (chunk != null) { -+ chunk.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ } else { -+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); -+ NearbyPlayers.this.byChunk.put(chunkKey, created); -+ created.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ -+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; -+ } -+ } -+ -+ @Override -+ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ if (chunk == null) { -+ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); -+ } -+ -+ final NearbyMapType type = this.type; -+ chunk.removePlayer(parameter, type); -+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ -+ if (chunk.isEmpty()) { -+ NearbyPlayers.this.byChunk.remove(chunkKey); -+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); -+ if (chunkData != null) { -+ chunkData.nearbyPlayers = null; -+ } -+ } -+ } -+ } -+} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/Moonrise-optimisation-patches.patch b/patches/server/Moonrise-optimisation-patches.patch index aa5bb963fb..ad8c4e9d97 100644 --- a/patches/server/Moonrise-optimisation-patches.patch +++ b/patches/server/Moonrise-optimisation-patches.patch @@ -17,6 +17,285 @@ Currently includes: See https://github.com/Tuinity/Moonrise +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +@@ -0,0 +0,0 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.MoonriseConstants; ++import ca.spottedleaf.moonrise.common.util.ChunkSystem; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; ++import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; ++import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.level.ChunkPos; ++import java.util.ArrayList; ++ ++public final class NearbyPlayers { ++ ++ public static enum NearbyMapType { ++ GENERAL, ++ GENERAL_SMALL, ++ GENERAL_REALLY_SMALL, ++ TICK_VIEW_DISTANCE, ++ VIEW_DISTANCE, ++ // Moonrise start - chunk tick iteration ++ SPAWN_RANGE { ++ @Override ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); ++ } ++ ++ @Override ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); ++ } ++ }; ++ // Moonrise end - chunk tick iteration ++ ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } ++ ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } ++ } ++ ++ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); ++ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length; ++ ++ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1; ++ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10; ++ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3; ++ ++ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4); ++ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4); ++ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4); ++ ++ private final ServerLevel world; ++ private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; ++ { ++ for (int i = 0; i < this.directByChunk.length; ++i) { ++ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); ++ } ++ } ++ ++ public NearbyPlayers(final ServerLevel world) { ++ this.world = world; ++ } ++ ++ public void addPlayer(final ServerPlayer player) { ++ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES]; ++ if (this.players.putIfAbsent(player, newTrackers) != null) { ++ throw new IllegalStateException("Already have player " + player); ++ } ++ ++ final ChunkPos chunk = player.chunkPosition(); ++ ++ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) { ++ // use 0 for default, will be updated by tickPlayer ++ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0); ++ } ++ ++ // update view distances ++ this.tickPlayer(player); ++ } ++ ++ public void removePlayer(final ServerPlayer player) { ++ final TrackedPlayer[] players = this.players.remove(player); ++ if (players == null) { ++ return; // May be called during teleportation before the player is actually placed ++ } ++ ++ for (final TrackedPlayer tracker : players) { ++ tracker.remove(); ++ } ++ } ++ ++ public void clear() { ++ if (this.players.isEmpty()) { ++ return; ++ } ++ ++ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { ++ this.removePlayer(player); ++ } ++ } ++ ++ public void tickPlayer(final ServerPlayer player) { ++ final TrackedPlayer[] players = this.players.get(player); ++ if (players == null) { ++ throw new IllegalStateException("Don't have player " + player); ++ } ++ ++ final ChunkPos chunk = player.chunkPosition(); ++ ++ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE); ++ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE); ++ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE); ++ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player)); ++ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getViewDistance(player)); ++ players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration ++ } ++ ++ public TrackedChunk getChunk(final ChunkPos pos) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public TrackedChunk getChunk(final BlockPos pos) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } ++ ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } ++ ++ public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); ++ } ++ ++ public static final class TrackedChunk { ++ ++ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; ++ ++ private final long chunkKey; ++ private final NearbyPlayers nearbyPlayers; ++ private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; ++ private int nonEmptyLists; ++ private long updateCount; ++ ++ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { ++ this.chunkKey = chunkKey; ++ this.nearbyPlayers = nearbyPlayers; ++ } ++ ++ public boolean isEmpty() { ++ return this.nonEmptyLists == 0; ++ } ++ ++ public long getUpdateCount() { ++ return this.updateCount; ++ } ++ ++ public ReferenceList getPlayers(final NearbyMapType type) { ++ return this.players[type.ordinal()]; ++ } ++ ++ public void addPlayer(final ServerPlayer player, final NearbyMapType type) { ++ ++this.updateCount; ++ ++ final int idx = type.ordinal(); ++ final ReferenceList list = this.players[idx]; ++ if (list == null) { ++ ++this.nonEmptyLists; ++ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); ++ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); ++ players.add(player); ++ return; ++ } ++ ++ if (!list.add(player)) { ++ throw new IllegalStateException("Already contains player " + player); ++ } ++ } ++ ++ public void removePlayer(final ServerPlayer player, final NearbyMapType type) { ++ ++this.updateCount; ++ ++ final int idx = type.ordinal(); ++ final ReferenceList list = this.players[idx]; ++ if (list == null) { ++ throw new IllegalStateException("Does not contain player " + player); ++ } ++ ++ if (!list.remove(player)) { ++ throw new IllegalStateException("Does not contain player " + player); ++ } ++ ++ if (list.size() == 0) { ++ this.players[idx] = null; ++ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); ++ --this.nonEmptyLists; ++ } ++ } ++ } ++ ++ private final class TrackedPlayer extends SingleUserAreaMap { ++ ++ private final NearbyMapType type; ++ ++ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) { ++ super(player); ++ this.type = type; ++ } ++ ++ @Override ++ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { ++ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ final NearbyMapType type = this.type; ++ if (chunk != null) { ++ chunk.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ } else { ++ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); ++ NearbyPlayers.this.byChunk.put(chunkKey, created); ++ created.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ ++ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; ++ } ++ } ++ ++ @Override ++ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { ++ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ if (chunk == null) { ++ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); ++ } ++ ++ final NearbyMapType type = this.type; ++ chunk.removePlayer(parameter, type); ++ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ ++ if (chunk.isEmpty()) { ++ NearbyPlayers.this.byChunk.remove(chunkKey); ++ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); ++ if (chunkData != null) { ++ chunkData.nearbyPlayers = null; ++ } ++ } ++ } ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java @@ -23847,13 +24126,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public class ChunkLevel { - private static final int FULL_CHUNK_LEVEL = 33; - private static final int BLOCK_TICKING_LEVEL = 32; -- private static final int ENTITY_TICKING_LEVEL = 31; + public static final int FULL_CHUNK_LEVEL = 33; + public static final int BLOCK_TICKING_LEVEL = 32; -+ public static final int ENTITY_TICKING_LEVEL = 31; + public static final int ENTITY_TICKING_LEVEL = 31; private static final ChunkStep FULL_CHUNK_STEP = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL); public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); - public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch index 844e944e51..3f4cd40208 100644 --- a/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch @@ -5,8 +5,6 @@ Subject: [PATCH] Optimise collision checking in player move packet handling Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision -Feature patch - diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java diff --git a/patches/server/Optimise-general-POI-access.patch b/patches/server/Optimise-general-POI-access.patch index 3f3faadbc8..92dfac7dd4 100644 --- a/patches/server/Optimise-general-POI-access.patch +++ b/patches/server/Optimise-general-POI-access.patch @@ -30,8 +30,6 @@ This patch also specifically optimises other areas of code to use PoiAccess. For example, some villager AI and portaling code had to be specifically modified. -Feature patch - diff --git a/src/main/java/io/papermc/paper/util/PoiAccess.java b/src/main/java/io/papermc/paper/util/PoiAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/Optimize-Bit-Operations-by-inlining.patch b/patches/server/Optimize-Bit-Operations-by-inlining.patch index 1a80359190..7d7f2d776f 100644 --- a/patches/server/Optimize-Bit-Operations-by-inlining.patch +++ b/patches/server/Optimize-Bit-Operations-by-inlining.patch @@ -6,8 +6,6 @@ Subject: [PATCH] Optimize Bit Operations by inlining Inline bit operations and reduce instruction count to make these hot operations faster -Feature patch - diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java diff --git a/patches/server/Optimize-Collision-to-not-load-chunks.patch b/patches/server/Optimize-Collision-to-not-load-chunks.patch index 2ef0ecd042..8026cceeb7 100644 --- a/patches/server/Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/Optimize-Collision-to-not-load-chunks.patch @@ -13,8 +13,6 @@ If that serting is not enabled, collisions will be ignored for players, since movement will load only the chunk the player enters anyways and avoids loading massive amounts of surrounding chunks due to large AABB lookups. -Feature patch - diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java diff --git a/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch index efc51bcf16..4200e29c19 100644 --- a/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch +++ b/patches/server/Optimize-GoalSelector-Goal.Flag-Set-operations.patch @@ -6,8 +6,6 @@ Subject: [PATCH] Optimize GoalSelector Goal.Flag Set operations Optimise the stream.anyMatch statement to move to a bitset where we can replace the call with a single bitwise operation. -Feature patch - diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java @@ -58,7 +56,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - remove streams from pathfindergoalselector } - protected int adjustedTickDelay(int ticks) { + // Paper start - Mob Goal API + public boolean hasFlag(final Goal.Flag flag) { +- return this.flags.contains(flag); ++ return this.goalTypes.hasElement(flag); + } + + public void addFlag(final Goal.Flag flag) { +- this.flags.add(flag); ++ this.goalTypes.addUnchecked(flag); + } + // Paper end - Mob Goal API + diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java diff --git a/patches/server/Optimize-Hoppers.patch b/patches/server/Optimize-Hoppers.patch index a80c2ce2b4..3b088a1787 100644 --- a/patches/server/Optimize-Hoppers.patch +++ b/patches/server/Optimize-Hoppers.patch @@ -12,8 +12,6 @@ Subject: [PATCH] Optimize Hoppers * Don't check for Entities with Inventories if the block above us is also occluding (not just Inventoried) * Remove Streams from Item Suck In and restore restore 1.12 AABB checks which is simpler and no voxel allocations (was doing TWO Item Suck ins) -Feature patch - diff --git a/src/main/java/io/papermc/paper/event/inventory/PaperInventoryMoveItemEvent.java b/src/main/java/io/papermc/paper/event/inventory/PaperInventoryMoveItemEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 2065341343..51ccefe733 100644 --- a/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -27,8 +27,6 @@ and then catch exceptions and close if they fire. Part of this commit was authored by: Spottedleaf, sandtechnology -Feature patch - diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/Connection.java diff --git a/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch index 3c4e8c7b52..fabf3cd051 100644 --- a/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch +++ b/patches/server/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch @@ -15,8 +15,6 @@ Optimize collection by creating a list instead of a set of the key and value. This lets us get faster foreach iteration, as well as avoids map lookups on the values when needed. -Feature patch - diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java diff --git a/patches/server/Optimize-Voxel-Shape-Merging.patch b/patches/server/Optimize-Voxel-Shape-Merging.patch index 3fec7c0af3..16a5277743 100644 --- a/patches/server/Optimize-Voxel-Shape-Merging.patch +++ b/patches/server/Optimize-Voxel-Shape-Merging.patch @@ -29,8 +29,6 @@ and compute a deterministic result for the MergerList values. Additionally, this lets us avoid even allocating new objects for this too, further reducing memory usage. -Feature patch - diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java diff --git a/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch index bd61fbe6f3..bfa353b5dd 100644 --- a/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch +++ b/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch @@ -11,8 +11,6 @@ Replace all calls to the new place to the unnecessary forward. Optimize getType and getBlockData to manually inline and optimize the calls -Feature patch - diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/core/Vec3i.java diff --git a/patches/server/Optional-per-player-mob-spawns.patch b/patches/server/Optional-per-player-mob-spawns.patch index e31edf614a..dda7294b2a 100644 --- a/patches/server/Optional-per-player-mob-spawns.patch +++ b/patches/server/Optional-per-player-mob-spawns.patch @@ -3,7 +3,6 @@ From: kickash32 Date: Mon, 19 Aug 2019 01:27:58 +0500 Subject: [PATCH] Optional per player mob spawns -Feature patch diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Properly-resend-entities.patch b/patches/server/Properly-resend-entities.patch index 433a9f10e1..e530407860 100644 --- a/patches/server/Properly-resend-entities.patch +++ b/patches/server/Properly-resend-entities.patch @@ -19,8 +19,6 @@ and so we have to (forcibly) resend them in order for the client to reset their See: https://github.com/PaperMC/Paper/pull/1896 -Feature patch - == AT == public net.minecraft.server.level.ChunkMap$TrackedEntity serverEntity diff --git a/patches/server/Registry-Modification-API.patch b/patches/server/Registry-Modification-API.patch index 5727dcd8c1..e05b588afb 100644 --- a/patches/server/Registry-Modification-API.patch +++ b/patches/server/Registry-Modification-API.patch @@ -3,8 +3,6 @@ From: Jake Potrebic Date: Mon, 27 Feb 2023 18:28:39 -0800 Subject: [PATCH] Registry Modification API -Feature patch - == AT == public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V public net.minecraft.resources.RegistryOps lookupProvider diff --git a/patches/server/Remove-streams-from-hot-code.patch b/patches/server/Remove-streams-from-hot-code.patch index 0fd0282d78..815e75e1bd 100644 --- a/patches/server/Remove-streams-from-hot-code.patch +++ b/patches/server/Remove-streams-from-hot-code.patch @@ -3,8 +3,6 @@ From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Wed, 1 Jul 2020 18:01:49 -0400 Subject: [PATCH] Remove streams from hot code -Feature patch - Co-authored-by: Bjarne Koll Co-authored-by: Spottedleaf diff --git a/patches/server/Rewrite-dataconverter-system.patch b/patches/server/Rewrite-dataconverter-system.patch index 21870a4ec4..f1790227a0 100644 --- a/patches/server/Rewrite-dataconverter-system.patch +++ b/patches/server/Rewrite-dataconverter-system.patch @@ -30625,7 +30625,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping public static S spin(Function serverFactory) { + ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system @@ -30781,6 +30781,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } +@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues { + + final int dataVersion = data.get("DataVersion").getAsInt(); + final int currentVersion = org.bukkit.craftbukkit.util.CraftMagicNumbers.INSTANCE.getDataVersion(); +- data = (com.google.gson.JsonObject) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic<>(com.mojang.serialization.JsonOps.INSTANCE, data), dataVersion, currentVersion).getValue(); ++ data = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertJson( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, ++ data, false, dataVersion, currentVersion ++ ); + com.mojang.serialization.DynamicOps ops = MinecraftServer.getServer().registryAccess().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE); + return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(ops, data).getOrThrow(IllegalArgumentException::new)); + } @@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); diff --git a/patches/server/Use-Velocity-compression-and-cipher-natives.patch b/patches/server/Use-Velocity-compression-and-cipher-natives.patch index a484846a52..b339b20f9b 100644 --- a/patches/server/Use-Velocity-compression-and-cipher-natives.patch +++ b/patches/server/Use-Velocity-compression-and-cipher-natives.patch @@ -3,8 +3,6 @@ From: Andrew Steinborn Date: Mon, 26 Jul 2021 02:15:17 -0400 Subject: [PATCH] Use Velocity compression and cipher natives -Feature patch - == AT == private-f net.minecraft.network.CompressionDecoder inflater diff --git a/patches/server/optimize-dirt-and-snow-spreading.patch b/patches/server/optimize-dirt-and-snow-spreading.patch index 96ce135e74..c13eaa6f09 100644 --- a/patches/server/optimize-dirt-and-snow-spreading.patch +++ b/patches/server/optimize-dirt-and-snow-spreading.patch @@ -3,7 +3,6 @@ From: lukas81298 Date: Fri, 22 Jan 2021 21:50:18 +0100 Subject: [PATCH] optimize dirt and snow spreading -Feature patch diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644