aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--patches/server/0018-Paper-Metrics.patch10
-rw-r--r--patches/server/1031-Add-feature-patch-hook-for-overrides.patch290
-rw-r--r--patches/server/1032-DataComponent-API.patch (renamed from patches/server/1031-DataComponent-API.patch)0
-rw-r--r--patches/server/1033-Properly-resend-entities.patch (renamed from patches/server/1050-Properly-resend-entities.patch)16
-rw-r--r--patches/server/1034-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch (renamed from patches/server/1032-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch)0
-rw-r--r--patches/server/1035-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch (renamed from patches/server/1033-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch)13
-rw-r--r--patches/server/1036-Optimize-Network-Manager-and-add-advanced-packet-sup.patch (renamed from patches/server/1034-Optimize-Network-Manager-and-add-advanced-packet-sup.patch)0
-rw-r--r--patches/server/1037-Allow-Saving-of-Oversized-Chunks.patch (renamed from patches/server/1035-Allow-Saving-of-Oversized-Chunks.patch)0
-rw-r--r--patches/server/1038-Flat-bedrock-generator-settings.patch (renamed from patches/server/1036-Flat-bedrock-generator-settings.patch)0
-rw-r--r--patches/server/1039-Entity-Activation-Range-2.0.patch (renamed from patches/server/1037-Entity-Activation-Range-2.0.patch)6
-rw-r--r--patches/server/1040-Anti-Xray.patch (renamed from patches/server/1038-Anti-Xray.patch)123
-rw-r--r--patches/server/1041-Use-Velocity-compression-and-cipher-natives.patch (renamed from patches/server/1039-Use-Velocity-compression-and-cipher-natives.patch)0
-rw-r--r--patches/server/1042-Optimize-Collision-to-not-load-chunks.patch (renamed from patches/server/1040-Optimize-Collision-to-not-load-chunks.patch)2
-rw-r--r--patches/server/1043-Optimize-GoalSelector-Goal.Flag-Set-operations.patch (renamed from patches/server/1041-Optimize-GoalSelector-Goal.Flag-Set-operations.patch)0
-rw-r--r--patches/server/1044-Optimize-Hoppers.patch (renamed from patches/server/1042-Optimize-Hoppers.patch)0
-rw-r--r--patches/server/1045-Optimize-Voxel-Shape-Merging.patch (renamed from patches/server/1043-Optimize-Voxel-Shape-Merging.patch)0
-rw-r--r--patches/server/1046-Optimize-Bit-Operations-by-inlining.patch (renamed from patches/server/1044-Optimize-Bit-Operations-by-inlining.patch)0
-rw-r--r--patches/server/1047-Remove-streams-from-hot-code.patch (renamed from patches/server/1045-Remove-streams-from-hot-code.patch)0
-rw-r--r--patches/server/1048-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch (renamed from patches/server/1046-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch)0
-rw-r--r--patches/server/1049-Fix-entity-type-tags-suggestions-in-selectors.patch (renamed from patches/server/1047-Fix-entity-type-tags-suggestions-in-selectors.patch)0
-rw-r--r--patches/server/1050-Handle-Oversized-block-entities-in-chunks.patch (renamed from patches/server/1048-Handle-Oversized-block-entities-in-chunks.patch)0
-rw-r--r--patches/server/1051-Check-distance-in-entity-interactions.patch (renamed from patches/server/1049-Check-distance-in-entity-interactions.patch)2
-rw-r--r--patches/server/1052-optimize-dirt-and-snow-spreading.patch (renamed from patches/server/1051-optimize-dirt-and-snow-spreading.patch)0
-rw-r--r--patches/server/1053-Optimise-getChunkAt-calls-for-loaded-chunks.patch (renamed from patches/server/1052-Optimise-getChunkAt-calls-for-loaded-chunks.patch)0
-rw-r--r--patches/server/1054-Rewrite-dataconverter-system.patch (renamed from patches/server/1053-Rewrite-dataconverter-system.patch)0
-rw-r--r--patches/server/1055-Moonrise-optimisation-patches.patch (renamed from patches/server/1054-Moonrise-optimisation-patches.patch)99
-rw-r--r--patches/server/1056-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch (renamed from patches/server/1055-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch)0
-rw-r--r--patches/server/1057-Improved-Watchdog-Support.patch (renamed from patches/server/1056-Improved-Watchdog-Support.patch)18
-rw-r--r--patches/server/1058-Detail-more-information-in-watchdog-dumps.patch (renamed from patches/server/1057-Detail-more-information-in-watchdog-dumps.patch)0
-rw-r--r--patches/server/1059-Entity-load-save-limit-per-chunk.patch (renamed from patches/server/1058-Entity-load-save-limit-per-chunk.patch)0
-rw-r--r--patches/server/1060-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch (renamed from patches/server/1059-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch)0
-rw-r--r--patches/server/1061-Improve-performance-of-mass-crafts.patch (renamed from patches/server/1060-Improve-performance-of-mass-crafts.patch)0
-rw-r--r--patches/server/1062-Incremental-chunk-and-player-saving.patch (renamed from patches/server/1061-Incremental-chunk-and-player-saving.patch)0
-rw-r--r--patches/server/1063-Optimise-general-POI-access.patch (renamed from patches/server/1062-Optimise-general-POI-access.patch)0
-rw-r--r--patches/server/1064-Fix-entity-tracker-desync-when-new-players-are-added.patch (renamed from patches/server/1063-Fix-entity-tracker-desync-when-new-players-are-added.patch)0
-rw-r--r--patches/server/1065-Lag-compensation-ticks.patch (renamed from patches/server/1064-Lag-compensation-ticks.patch)0
-rw-r--r--patches/server/1066-Optimise-collision-checking-in-player-move-packet-ha.patch (renamed from patches/server/1065-Optimise-collision-checking-in-player-move-packet-ha.patch)0
-rw-r--r--patches/server/1067-Optional-per-player-mob-spawns.patch (renamed from patches/server/1066-Optional-per-player-mob-spawns.patch)0
-rw-r--r--patches/server/1068-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch (renamed from patches/server/1067-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch)0
-rw-r--r--patches/server/1069-Eigencraft-redstone-implementation.patch (renamed from patches/server/1068-Eigencraft-redstone-implementation.patch)0
-rw-r--r--patches/server/1070-Add-Alternate-Current-redstone-implementation.patch (renamed from patches/server/1069-Add-Alternate-Current-redstone-implementation.patch)0
-rw-r--r--patches/server/1071-Implement-chunk-view-API.patch48
-rw-r--r--patches/server/1071-Improve-exact-choice-recipe-ingredients.patch (renamed from patches/server/1070-Improve-exact-choice-recipe-ingredients.patch)0
-rw-r--r--patches/server/1072-Implement-chunk-view-API.patch51
44 files changed, 445 insertions, 233 deletions
diff --git a/patches/server/0018-Paper-Metrics.patch b/patches/server/0018-Paper-Metrics.patch
index 9ad0f5d70e..fbc1a647d0 100644
--- a/patches/server/0018-Paper-Metrics.patch
+++ b/patches/server/0018-Paper-Metrics.patch
@@ -15,10 +15,10 @@ decisions on behalf of the project.
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
new file mode 100644
-index 0000000000000000000000000000000000000000..6aaed8e8bf8c721fc834da5c76ac72a4c3e92458
+index 0000000000000000000000000000000000000000..8f62879582195d8ae4f64bd23f752fa133b1c973
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
-@@ -0,0 +1,678 @@
+@@ -0,0 +1,682 @@
+package com.destroystokyo.paper;
+
+import net.minecraft.server.MinecraftServer;
@@ -113,7 +113,11 @@ index 0000000000000000000000000000000000000000..6aaed8e8bf8c721fc834da5c76ac72a4
+ * Starts the Scheduler which submits our data every 30 minutes.
+ */
+ private void startSubmitting() {
-+ final Runnable submitTask = this::submitData;
++ final Runnable submitTask = () -> {
++ if (!MinecraftServer.getServer().hasStopped()) {
++ submitData();
++ }
++ };
+
+ // Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
+ // bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay.
diff --git a/patches/server/1031-Add-feature-patch-hook-for-overrides.patch b/patches/server/1031-Add-feature-patch-hook-for-overrides.patch
new file mode 100644
index 0000000000..d565c289b2
--- /dev/null
+++ b/patches/server/1031-Add-feature-patch-hook-for-overrides.patch
@@ -0,0 +1,290 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Nassim Jahnke <[email protected]>
+Date: Thu, 5 Dec 2024 13:00:22 +0100
+Subject: [PATCH] Add feature patch hook for overrides
+
+
+diff --git a/src/main/java/io/papermc/paper/FeatureHooks.java b/src/main/java/io/papermc/paper/FeatureHooks.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..cfd47bcdcdaae3829563fdb6fd80ad3c01c3115d
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/FeatureHooks.java
+@@ -0,0 +1,72 @@
++package io.papermc.paper;
++
++import io.papermc.paper.command.PaperSubcommand;
++import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
++import it.unimi.dsi.fastutil.longs.LongSet;
++import it.unimi.dsi.fastutil.longs.LongSets;
++import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
++import it.unimi.dsi.fastutil.objects.ObjectSet;
++import it.unimi.dsi.fastutil.objects.ObjectSets;
++import java.util.List;
++import java.util.Map;
++import java.util.Set;
++import net.minecraft.core.Registry;
++import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
++import net.minecraft.server.level.ServerPlayer;
++import net.minecraft.world.level.ChunkPos;
++import net.minecraft.world.level.Level;
++import net.minecraft.world.level.biome.Biome;
++import net.minecraft.world.level.block.Block;
++import net.minecraft.world.level.block.Blocks;
++import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.chunk.LevelChunk;
++import net.minecraft.world.level.chunk.LevelChunkSection;
++import net.minecraft.world.level.chunk.PalettedContainer;
++import org.bukkit.Chunk;
++import org.bukkit.World;
++
++public final class FeatureHooks {
++
++ public static void initChunkTaskScheduler(final boolean useParallelGen) {
++ }
++
++ public static void registerPaperCommands(final Map<Set<String>, PaperSubcommand> commands) {
++ }
++
++ public static LevelChunkSection createSection(final Registry<Biome> biomeRegistry, final Level level, final ChunkPos chunkPos, final int chunkSection) {
++ return new LevelChunkSection(biomeRegistry);
++ }
++
++ public static void sendChunkRefreshPackets(final List<ServerPlayer> playersInRange, final LevelChunk chunk) {
++ final ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, chunk.level.getLightEngine(), null, null);
++ for (final ServerPlayer player : playersInRange) {
++ if (player.connection == null) continue;
++
++ player.connection.send(refreshPacket);
++ }
++ }
++
++ public static PalettedContainer<BlockState> emptyPalettedBlockContainer() {
++ return new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
++ }
++
++ public static Set<Long> getSentChunkKeys(final ServerPlayer player) {
++ final LongSet keys = new LongOpenHashSet();
++ player.getChunkTrackingView().forEach(pos -> keys.add(pos.longKey));
++ return LongSets.unmodifiable(keys);
++ }
++
++ public static Set<Chunk> getSentChunks(final ServerPlayer player) {
++ final ObjectSet<Chunk> chunks = new ObjectOpenHashSet<>();
++ final World world = player.serverLevel().getWorld();
++ player.getChunkTrackingView().forEach(pos -> {
++ final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey);
++ chunks.add(chunk);
++ });
++ return ObjectSets.unmodifiable(chunks);
++ }
++
++ public static boolean isChunkSent(final ServerPlayer player, final long chunkKey) {
++ return player.getChunkTrackingView().contains(new ChunkPos(chunkKey));
++ }
++}
+diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
+index 46bf42d5ea9e7b046f962531c5962d287cf44a41..8d0471153893ad3a82eb5aa03713b8bd9d8da43d 100644
+--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
++++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
+@@ -1,5 +1,6 @@
+ package io.papermc.paper.command;
+
++import io.papermc.paper.FeatureHooks;
+ import io.papermc.paper.command.subcommands.*;
+ import it.unimi.dsi.fastutil.Pair;
+ import java.util.ArrayList;
+@@ -42,6 +43,7 @@ public final class PaperCommand extends Command {
+ commands.put(Set.of("dumpitem"), new DumpItemCommand());
+ commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand());
+ commands.put(Set.of("dumplisteners"), new DumpListenersCommand());
++ FeatureHooks.registerPaperCommands(commands);
+
+ return commands.entrySet().stream()
+ .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
+diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+index 2d2ff826354670fef356e241d939080c9ed3fd4a..088b8fe5d144807f4da1e85b2fa34dfd21286f8c 100644
+--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
++++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+@@ -1,6 +1,7 @@
+ package io.papermc.paper.configuration;
+
+ import com.mojang.logging.LogUtils;
++import io.papermc.paper.FeatureHooks;
+ import io.papermc.paper.configuration.constraint.Constraints;
+ import io.papermc.paper.configuration.type.number.DoubleOr;
+ import io.papermc.paper.configuration.type.number.IntOr;
+@@ -217,6 +218,22 @@ public class GlobalConfiguration extends ConfigurationPart {
+ @PostProcess
+ private void postProcess() {
+ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads);
++ String newChunkSystemGenParallelism = this.genParallelism;
++ if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) {
++ newChunkSystemGenParallelism = "true";
++ }
++
++ final boolean useParallelGen;
++ if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled")
++ || newChunkSystemGenParallelism.equalsIgnoreCase("true")) {
++ useParallelGen = true;
++ } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled")
++ || newChunkSystemGenParallelism.equalsIgnoreCase("false")) {
++ useParallelGen = false;
++ } else {
++ throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]");
++ }
++ FeatureHooks.initChunkTaskScheduler(useParallelGen);
+ }
+ }
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+index bfc8b87941578e8f52f7cd9035776b7db5ab2221..f3ab07e44e2e912ea66c6148cfdb2a4a528741b2 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit;
+ import com.google.common.base.Preconditions;
+ import com.google.common.base.Predicates;
+ import com.mojang.serialization.Codec;
++import io.papermc.paper.FeatureHooks;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Objects;
+@@ -56,7 +57,7 @@ public class CraftChunk implements Chunk {
+ private final ServerLevel worldServer;
+ private final int x;
+ private final int z;
+- private static final PalettedContainer<net.minecraft.world.level.block.state.BlockState> emptyBlockIDs = new PalettedContainer<>(net.minecraft.world.level.block.Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
++ private static final PalettedContainer<net.minecraft.world.level.block.state.BlockState> emptyBlockIDs = FeatureHooks.emptyPalettedBlockContainer();
+ private static final byte[] FULL_LIGHT = new byte[2048];
+ private static final byte[] EMPTY_LIGHT = new byte[2048];
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+index 6370b780af5043f32d07346ea4dd7f23c819f7a0..5b64111bc8baca45ecc7bfa384e5f8a004163a0b 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+@@ -2718,7 +2718,7 @@ public final class CraftServer implements Server {
+ public ChunkGenerator.ChunkData createChunkData(World world) {
+ Preconditions.checkArgument(world != null, "World cannot be null");
+ ServerLevel handle = ((CraftWorld) world).getHandle();
+- return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME));
++ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME), world);
+ }
+
+ @Override
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+index 73b0438908894bdd64835f21290250c88625a41a..ca62105a0ff0aa69385cbf2018f8fe6a4bb69fd4 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+@@ -5,6 +5,7 @@ import com.google.common.base.Predicates;
+ import com.google.common.collect.ImmutableList;
+ import com.google.common.collect.ImmutableMap;
+ import com.mojang.datafixers.util.Pair;
++import io.papermc.paper.FeatureHooks;
+ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
+ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
+ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+@@ -511,12 +512,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+ List<ServerPlayer> playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false);
+ if (playersInRange.isEmpty()) return;
+
+- ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null);
+- for (ServerPlayer player : playersInRange) {
+- if (player.connection == null) continue;
+-
+- player.connection.send(refreshPacket);
+- }
++ FeatureHooks.sendChunkRefreshPackets(playersInRange, chunk);
+ });
+ });
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+index 58b485c4cfd2ced26a7178aa4380d66c0250b014..d5dc10cf9440f2394e6548c6a3e0160df13c9cae 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+@@ -6,6 +6,7 @@ import com.google.common.io.BaseEncoding;
+ import com.mojang.authlib.GameProfile;
+ import com.mojang.datafixers.util.Pair;
+ import io.netty.buffer.Unpooled;
++import io.papermc.paper.FeatureHooks;
+ import it.unimi.dsi.fastutil.shorts.ShortArraySet;
+ import it.unimi.dsi.fastutil.shorts.ShortSet;
+ import java.io.ByteArrayOutputStream;
+@@ -3489,27 +3490,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+ @Override
+ public Set<java.lang.Long> 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 FeatureHooks.getSentChunkKeys(this.getHandle());
+ }
+
+ @Override
+ public Set<org.bukkit.Chunk> getSentChunks() {
+ org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
+- final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<org.bukkit.Chunk> chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>();
+- final org.bukkit.World world = this.getWorld();
+- 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);
++ return FeatureHooks.getSentChunks(this.getHandle());
+ }
+
+ @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 FeatureHooks.isChunkSent(this.getHandle(), chunkKey);
+ }
+ // Paper end
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
+index e7f7a246e9c03e676dadfee59de87b8b2ac55ba3..719fe4cbe96c12c281bcbc7909b35310bbf650a5 100644
+--- a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
++++ b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
+@@ -1,5 +1,6 @@
+ package org.bukkit.craftbukkit.generator;
+
++import io.papermc.paper.FeatureHooks;
+ import java.util.HashSet;
+ import java.util.Set;
+ import net.minecraft.core.BlockPos;
+@@ -27,8 +28,15 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData {
+ private final Registry<net.minecraft.world.level.biome.Biome> biomes;
+ private Set<BlockPos> tiles;
+ private final Set<BlockPos> lights = new HashSet<>();
++ private final org.bukkit.World world;
+
++ @Deprecated @io.papermc.paper.annotation.DoNotUse
+ public OldCraftChunkData(int minHeight, int maxHeight, Registry<net.minecraft.world.level.biome.Biome> biomes) {
++ this(minHeight, maxHeight, biomes, null);
++ }
++
++ public OldCraftChunkData(int minHeight, int maxHeight, Registry<net.minecraft.world.level.biome.Biome> biomes, org.bukkit.World world) {
++ this.world = world;
+ this.minHeight = minHeight;
+ this.maxHeight = maxHeight;
+ this.biomes = biomes;
+@@ -176,7 +184,7 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData {
+ int offset = (y - this.minHeight) >> 4;
+ LevelChunkSection section = this.sections[offset];
+ if (create && section == null) {
+- this.sections[offset] = section = new LevelChunkSection(this.biomes);
++ this.sections[offset] = section = FeatureHooks.createSection(this.biomes, this.world instanceof org.bukkit.craftbukkit.CraftWorld ? ((org.bukkit.craftbukkit.CraftWorld) this.world).getHandle() : null, null, offset + (this.minHeight >> 4)); // Paper - Anti-Xray - Add parameters
+ }
+ return section;
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
+index 256a131781721c86dd6cdbc329335964570cbe8c..503a31b4efc8920a11bc1db03f81aab6439ceb23 100644
+--- a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
++++ b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
+@@ -5,7 +5,7 @@ import org.bukkit.map.MapCursor;
+
+ public class RenderData {
+
+- public final byte[] buffer;
++ public byte[] buffer;
+ public final ArrayList<MapCursor> cursors;
+
+ public RenderData() {
diff --git a/patches/server/1031-DataComponent-API.patch b/patches/server/1032-DataComponent-API.patch
index 2493615d74..2493615d74 100644
--- a/patches/server/1031-DataComponent-API.patch
+++ b/patches/server/1032-DataComponent-API.patch
diff --git a/patches/server/1050-Properly-resend-entities.patch b/patches/server/1033-Properly-resend-entities.patch
index d9186c61a6..d9f2145430 100644
--- a/patches/server/1050-Properly-resend-entities.patch
+++ b/patches/server/1033-Properly-resend-entities.patch
@@ -57,10 +57,10 @@ index 02bf2705ca1c99023a83a22d92e1962181102297..0f99733660f91280e4c6262cf75b3c9c
final EntityDataAccessor<T> accessor;
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
-index fdba8a7344760c5903f838d0e0d65edef23262bb..504c996220b278c194c93e001a3b326d549868ec 100644
+index 0d168d15d9adeb90a183d4a847931cbf2281a5c7..55f73502a9be74dcd53714491b84810609f4fe8e 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
-@@ -567,6 +567,7 @@ public class ServerPlayerGameMode {
+@@ -565,6 +565,7 @@ public class ServerPlayerGameMode {
}
// Paper end - extend Player Interact cancellation
player.getBukkitEntity().updateInventory(); // SPIGOT-2867
@@ -68,7 +68,7 @@ index fdba8a7344760c5903f838d0e0d65edef23262bb..504c996220b278c194c93e001a3b326d
return (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS;
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition);
-@@ -617,6 +618,11 @@ public class ServerPlayerGameMode {
+@@ -615,6 +616,11 @@ public class ServerPlayerGameMode {
return enuminteractionresult;
} else {
@@ -102,7 +102,7 @@ index cfad5925f7d6b9970e8abef981b67e805bf1866a..8cae479d7b299ff4215c80fa2bbebf41
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 4efdd8f0ca73b59eb90abfe1fadbcb34d845fcd4..c68040a59fa8aa9b8b9f1e0b4fdded565ea592d9 100644
+index af209a95b3f83e9c2c3f6473e3be7ca4414ebf40..eb9783d22d13d2dbf204d2ce953e17e1f3cab762 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -396,7 +396,7 @@ public abstract class PlayerList {
@@ -134,10 +134,10 @@ index 4efdd8f0ca73b59eb90abfe1fadbcb34d845fcd4..c68040a59fa8aa9b8b9f1e0b4fdded56
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0deb12c9b5397695a363b9bb598843ed2b6e396c..7496260370adc6f627288637c53a652d27a6cd84 100644
+index 9865fb52bcee1dd4dd068e69e45cd85fbcbe9060..8ac4fe3f94baa47f1b95d9f8a6a84fad2504e573 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -601,13 +601,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -598,13 +598,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// CraftBukkit start
public void refreshEntityData(ServerPlayer to) {
@@ -186,10 +186,10 @@ index 0deb12c9b5397695a363b9bb598843ed2b6e396c..7496260370adc6f627288637c53a652d
public boolean equals(Object object) {
return object instanceof Entity ? ((Entity) object).id == this.id : false;
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index 44b63480923c068889972278adfffd0552d691c2..d54f6f1f8ef4df5233478d6341f3181e8c1baace 100644
+index bef31f70ed9bc9f4bea62dda2339b7a281485dce..e7092ec3e22a1236d8cb183859a2597ab0245631 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -4075,6 +4075,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
+@@ -4067,6 +4067,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
}
diff --git a/patches/server/1032-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/1034-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
index 4e08c4e606..4e08c4e606 100644
--- a/patches/server/1032-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
+++ b/patches/server/1034-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
diff --git a/patches/server/1033-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/1035-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
index 4981fc8cb7..73fea5a3cb 100644
--- a/patches/server/1033-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
+++ b/patches/server/1035-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
@@ -122,16 +122,3 @@ index 2d5e7380e8a14cbc01ba48cd05deccc0c7f53430..ae321b3b8d98e42ef07fd1f0f738c1a2
for (org.bukkit.map.MapCursor cursor : render.cursors) {
if (cursor.isVisible()) {
icons.add(new MapDecoration(CraftMapCursor.CraftType.bukkitToMinecraftHolder(cursor.getType()), cursor.getX(), cursor.getY(), cursor.getDirection(), Optional.ofNullable(PaperAdventure.asVanilla(cursor.caption()))));
-diff --git a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
-index 256a131781721c86dd6cdbc329335964570cbe8c..5768cd512ec166f1e8d1f4a28792015347297c3f 100644
---- a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
-+++ b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
-@@ -5,7 +5,7 @@ import org.bukkit.map.MapCursor;
-
- public class RenderData {
-
-- public final byte[] buffer;
-+ public byte[] buffer; // Paper
- public final ArrayList<MapCursor> cursors;
-
- public RenderData() {
diff --git a/patches/server/1034-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/1036-Optimize-Network-Manager-and-add-advanced-packet-sup.patch
index 964b69d8d4..964b69d8d4 100644
--- a/patches/server/1034-Optimize-Network-Manager-and-add-advanced-packet-sup.patch
+++ b/patches/server/1036-Optimize-Network-Manager-and-add-advanced-packet-sup.patch
diff --git a/patches/server/1035-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/1037-Allow-Saving-of-Oversized-Chunks.patch
index 0b77f00d70..0b77f00d70 100644
--- a/patches/server/1035-Allow-Saving-of-Oversized-Chunks.patch
+++ b/patches/server/1037-Allow-Saving-of-Oversized-Chunks.patch
diff --git a/patches/server/1036-Flat-bedrock-generator-settings.patch b/patches/server/1038-Flat-bedrock-generator-settings.patch
index 5084ca1e6b..5084ca1e6b 100644
--- a/patches/server/1036-Flat-bedrock-generator-settings.patch
+++ b/patches/server/1038-Flat-bedrock-generator-settings.patch
diff --git a/patches/server/1037-Entity-Activation-Range-2.0.patch b/patches/server/1039-Entity-Activation-Range-2.0.patch
index 184cf71959..41cc88a799 100644
--- a/patches/server/1037-Entity-Activation-Range-2.0.patch
+++ b/patches/server/1039-Entity-Activation-Range-2.0.patch
@@ -87,7 +87,7 @@ index b98b8d42fb95185551a4559ce22abad33e000d33..5d6f135f3d1b845e289d20d566e1b544
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 9865fb52bcee1dd4dd068e69e45cd85fbcbe9060..5d8ea207cd5a2e3d608bc01922d4430e0bb60f32 100644
+index 8ac4fe3f94baa47f1b95d9f8a6a84fad2504e573..c85e0cc09d7dfe9221665c13211d381b07f10a54 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -421,6 +421,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -99,7 +99,7 @@ index 9865fb52bcee1dd4dd068e69e45cd85fbcbe9060..5d8ea207cd5a2e3d608bc01922d4430e
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
// Paper start - Entity origin API
@javax.annotation.Nullable
-@@ -1010,6 +1012,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -1042,6 +1044,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} else {
this.wasOnFire = this.isOnFire();
if (type == MoverType.PISTON) {
@@ -108,7 +108,7 @@ index 9865fb52bcee1dd4dd068e69e45cd85fbcbe9060..5d8ea207cd5a2e3d608bc01922d4430e
movement = this.limitPistonMovement(movement);
if (movement.equals(Vec3.ZERO)) {
return;
-@@ -1024,6 +1028,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -1056,6 +1060,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.stuckSpeedMultiplier = Vec3.ZERO;
this.setDeltaMovement(Vec3.ZERO);
}
diff --git a/patches/server/1038-Anti-Xray.patch b/patches/server/1040-Anti-Xray.patch
index 2d38c2b972..ad4fd2c07d 100644
--- a/patches/server/1038-Anti-Xray.patch
+++ b/patches/server/1040-Anti-Xray.patch
@@ -1000,6 +1000,48 @@ index 0000000000000000000000000000000000000000..80a2dfb266ae1221680a7b24fee2f7e2
+ chunkPacketBlockControllerAntiXray.obfuscate(this);
+ }
+}
+diff --git a/src/main/java/io/papermc/paper/FeatureHooks.java b/src/main/java/io/papermc/paper/FeatureHooks.java
+index cfd47bcdcdaae3829563fdb6fd80ad3c01c3115d..a6779295bff446ee79e7c9d41e405447becc2966 100644
+--- a/src/main/java/io/papermc/paper/FeatureHooks.java
++++ b/src/main/java/io/papermc/paper/FeatureHooks.java
+@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.longs.LongSets;
+ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+ import it.unimi.dsi.fastutil.objects.ObjectSet;
+ import it.unimi.dsi.fastutil.objects.ObjectSets;
++import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+@@ -34,20 +35,25 @@ public final class FeatureHooks {
+ }
+
+ public static LevelChunkSection createSection(final Registry<Biome> biomeRegistry, final Level level, final ChunkPos chunkPos, final int chunkSection) {
+- return new LevelChunkSection(biomeRegistry);
++ return new LevelChunkSection(biomeRegistry, level, chunkPos, chunkSection); // Paper - Anti-Xray - Add parameters
+ }
+
+ public static void sendChunkRefreshPackets(final List<ServerPlayer> playersInRange, final LevelChunk chunk) {
+- final ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, chunk.level.getLightEngine(), null, null);
++ // Paper start - Anti-Xray
++ final Map<Object, ClientboundLevelChunkWithLightPacket> refreshPackets = new HashMap<>();
+ for (final ServerPlayer player : playersInRange) {
+ if (player.connection == null) continue;
+
+- player.connection.send(refreshPacket);
++ final Boolean shouldModify = chunk.getLevel().chunkPacketBlockController.shouldModify(player, chunk);
++ player.connection.send(refreshPackets.computeIfAbsent(shouldModify, s -> { // Use connection to prevent creating firing event
++ return new ClientboundLevelChunkWithLightPacket(chunk, chunk.level.getLightEngine(), null, null, (Boolean) s);
++ }));
+ }
++ // Paper end - Anti-Xray
+ }
+
+ public static PalettedContainer<BlockState> emptyPalettedBlockContainer() {
+- return new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
++ return new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); // Paper - Anti-Xray - Add preset block states
+ }
+
+ public static Set<Long> getSentChunkKeys(final ServerPlayer player) {
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
index ccc8c32c27c19cb0f0b581ca6693cfa737cb1de1..3c1cad5c2b34047cec44734ba4e8348cabec6f80 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
@@ -1117,7 +1159,7 @@ index 5d6f135f3d1b845e289d20d566e1b54440231365..6c71ef3c7430623900a7021f853d2bb5
this.convertable = convertable_conversionsession;
this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile());
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
-index 0d168d15d9adeb90a183d4a847931cbf2281a5c7..fdba8a7344760c5903f838d0e0d65edef23262bb 100644
+index 55f73502a9be74dcd53714491b84810609f4fe8e..504c996220b278c194c93e001a3b326d549868ec 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -48,7 +48,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
@@ -1157,7 +1199,7 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a9528127
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent();
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index af209a95b3f83e9c2c3f6473e3be7ca4414ebf40..4efdd8f0ca73b59eb90abfe1fadbcb34d845fcd4 100644
+index eb9783d22d13d2dbf204d2ce953e17e1f3cab762..c68040a59fa8aa9b8b9f1e0b4fdded565ea592d9 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -426,7 +426,7 @@ public abstract class PlayerList {
@@ -1584,80 +1626,3 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..4bc7fa3324e9af3abce2acf960c7b065
}
// CraftBukkit end
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-index bfc8b87941578e8f52f7cd9035776b7db5ab2221..028174f712ea9605f22243b76c3f5dd6da76b57f 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-@@ -56,7 +56,7 @@ public class CraftChunk implements Chunk {
- private final ServerLevel worldServer;
- private final int x;
- private final int z;
-- private static final PalettedContainer<net.minecraft.world.level.block.state.BlockState> emptyBlockIDs = new PalettedContainer<>(net.minecraft.world.level.block.Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
-+ private static final PalettedContainer<net.minecraft.world.level.block.state.BlockState> emptyBlockIDs = new PalettedContainer<>(net.minecraft.world.level.block.Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); // Paper - Anti-Xray - Add preset block states
- private static final byte[] FULL_LIGHT = new byte[2048];
- private static final byte[] EMPTY_LIGHT = new byte[2048];
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 6370b780af5043f32d07346ea4dd7f23c819f7a0..ef836e1a6481775263bdbe3668febd577ac96aec 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -2718,7 +2718,7 @@ public final class CraftServer implements Server {
- public ChunkGenerator.ChunkData createChunkData(World world) {
- Preconditions.checkArgument(world != null, "World cannot be null");
- ServerLevel handle = ((CraftWorld) world).getHandle();
-- return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME));
-+ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
- }
-
- @Override
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 73b0438908894bdd64835f21290250c88625a41a..2ead4edd2e6298ea3c22490e91319c64752815fc 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -511,11 +511,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- List<ServerPlayer> playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false);
- if (playersInRange.isEmpty()) return;
-
-- ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null);
-+ // Paper start - Anti-Xray bypass
-+ final Map<Object, ClientboundLevelChunkWithLightPacket> refreshPackets = new HashMap<>();
- for (ServerPlayer player : playersInRange) {
- if (player.connection == null) continue;
-
-- player.connection.send(refreshPacket);
-+ Boolean shouldModify = chunk.getLevel().chunkPacketBlockController.shouldModify(player, chunk);
-+ player.connection.send(refreshPackets.computeIfAbsent(shouldModify, s -> { // Use connection to prevent creating firing event
-+ return new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null, (Boolean) s);
-+ }));
-+ // Paper end - Anti-Xray bypass
- }
- });
- });
-diff --git a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
-index e7f7a246e9c03e676dadfee59de87b8b2ac55ba3..03eb35d5c67f125c44cf46595c93d124ac7892b8 100644
---- a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
-+++ b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
-@@ -27,8 +27,13 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData {
- private final Registry<net.minecraft.world.level.biome.Biome> biomes;
- private Set<BlockPos> tiles;
- private final Set<BlockPos> lights = new HashSet<>();
-+ // Paper start - Anti-Xray - Add parameters
-+ private final org.bukkit.World world;
-
-- public OldCraftChunkData(int minHeight, int maxHeight, Registry<net.minecraft.world.level.biome.Biome> biomes) {
-+ @Deprecated @io.papermc.paper.annotation.DoNotUse public OldCraftChunkData(int minHeight, int maxHeight, Registry<net.minecraft.world.level.biome.Biome> biomes) { this(minHeight, maxHeight, biomes, null); }
-+ public OldCraftChunkData(int minHeight, int maxHeight, Registry<net.minecraft.world.level.biome.Biome> biomes, org.bukkit.World world) {
-+ this.world = world;
-+ // Paper end
- this.minHeight = minHeight;
- this.maxHeight = maxHeight;
- this.biomes = biomes;
-@@ -176,7 +181,7 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData {
- int offset = (y - this.minHeight) >> 4;
- LevelChunkSection section = this.sections[offset];
- if (create && section == null) {
-- this.sections[offset] = section = new LevelChunkSection(this.biomes);
-+ this.sections[offset] = section = new LevelChunkSection(this.biomes, this.world instanceof org.bukkit.craftbukkit.CraftWorld ? ((org.bukkit.craftbukkit.CraftWorld) this.world).getHandle() : null, null, offset + (this.minHeight >> 4)); // Paper - Anti-Xray - Add parameters
- }
- return section;
- }
diff --git a/patches/server/1039-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/1041-Use-Velocity-compression-and-cipher-natives.patch
index 4fe3d49978..4fe3d49978 100644
--- a/patches/server/1039-Use-Velocity-compression-and-cipher-natives.patch
+++ b/patches/server/1041-Use-Velocity-compression-and-cipher-natives.patch
diff --git a/patches/server/1040-Optimize-Collision-to-not-load-chunks.patch b/patches/server/1042-Optimize-Collision-to-not-load-chunks.patch
index 1ae5b2022c..809208a26a 100644
--- a/patches/server/1040-Optimize-Collision-to-not-load-chunks.patch
+++ b/patches/server/1042-Optimize-Collision-to-not-load-chunks.patch
@@ -14,7 +14,7 @@ movement will load only the chunk the player enters anyways and avoids loading
massive amounts of surrounding chunks due to large AABB lookups.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 5d8ea207cd5a2e3d608bc01922d4430e0bb60f32..0deb12c9b5397695a363b9bb598843ed2b6e396c 100644
+index c85e0cc09d7dfe9221665c13211d381b07f10a54..7496260370adc6f627288637c53a652d27a6cd84 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -259,6 +259,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
diff --git a/patches/server/1041-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/1043-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
index 04866c7805..04866c7805 100644
--- a/patches/server/1041-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
+++ b/patches/server/1043-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
diff --git a/patches/server/1042-Optimize-Hoppers.patch b/patches/server/1044-Optimize-Hoppers.patch
index 28044def80..28044def80 100644
--- a/patches/server/1042-Optimize-Hoppers.patch
+++ b/patches/server/1044-Optimize-Hoppers.patch
diff --git a/patches/server/1043-Optimize-Voxel-Shape-Merging.patch b/patches/server/1045-Optimize-Voxel-Shape-Merging.patch
index 52246713b3..52246713b3 100644
--- a/patches/server/1043-Optimize-Voxel-Shape-Merging.patch
+++ b/patches/server/1045-Optimize-Voxel-Shape-Merging.patch
diff --git a/patches/server/1044-Optimize-Bit-Operations-by-inlining.patch b/patches/server/1046-Optimize-Bit-Operations-by-inlining.patch
index 63fe402931..63fe402931 100644
--- a/patches/server/1044-Optimize-Bit-Operations-by-inlining.patch
+++ b/patches/server/1046-Optimize-Bit-Operations-by-inlining.patch
diff --git a/patches/server/1045-Remove-streams-from-hot-code.patch b/patches/server/1047-Remove-streams-from-hot-code.patch
index e6f8c4dd49..e6f8c4dd49 100644
--- a/patches/server/1045-Remove-streams-from-hot-code.patch
+++ b/patches/server/1047-Remove-streams-from-hot-code.patch
diff --git a/patches/server/1046-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/1048-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
index b32ebf6b4e..b32ebf6b4e 100644
--- a/patches/server/1046-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
+++ b/patches/server/1048-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
diff --git a/patches/server/1047-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/1049-Fix-entity-type-tags-suggestions-in-selectors.patch
index 365ed610f6..365ed610f6 100644
--- a/patches/server/1047-Fix-entity-type-tags-suggestions-in-selectors.patch
+++ b/patches/server/1049-Fix-entity-type-tags-suggestions-in-selectors.patch
diff --git a/patches/server/1048-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/1050-Handle-Oversized-block-entities-in-chunks.patch
index d3283fd63f..d3283fd63f 100644
--- a/patches/server/1048-Handle-Oversized-block-entities-in-chunks.patch
+++ b/patches/server/1050-Handle-Oversized-block-entities-in-chunks.patch
diff --git a/patches/server/1049-Check-distance-in-entity-interactions.patch b/patches/server/1051-Check-distance-in-entity-interactions.patch
index 05295df130..7e7ea01bc1 100644
--- a/patches/server/1049-Check-distance-in-entity-interactions.patch
+++ b/patches/server/1051-Check-distance-in-entity-interactions.patch
@@ -17,7 +17,7 @@ index eb6a589280a433d915ad7c035b7ec4ddafb162a0..38ffa1c4c204f73746c4b87127de92b6
};
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index bef31f70ed9bc9f4bea62dda2339b7a281485dce..44b63480923c068889972278adfffd0552d691c2 100644
+index e7092ec3e22a1236d8cb183859a2597ab0245631..d54f6f1f8ef4df5233478d6341f3181e8c1baace 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1467,7 +1467,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
diff --git a/patches/server/1051-optimize-dirt-and-snow-spreading.patch b/patches/server/1052-optimize-dirt-and-snow-spreading.patch
index bdf5b94547..bdf5b94547 100644
--- a/patches/server/1051-optimize-dirt-and-snow-spreading.patch
+++ b/patches/server/1052-optimize-dirt-and-snow-spreading.patch
diff --git a/patches/server/1052-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/server/1053-Optimise-getChunkAt-calls-for-loaded-chunks.patch
index a18ef75e66..a18ef75e66 100644
--- a/patches/server/1052-Optimise-getChunkAt-calls-for-loaded-chunks.patch
+++ b/patches/server/1053-Optimise-getChunkAt-calls-for-loaded-chunks.patch
diff --git a/patches/server/1053-Rewrite-dataconverter-system.patch b/patches/server/1054-Rewrite-dataconverter-system.patch
index 63a36045f0..63a36045f0 100644
--- a/patches/server/1053-Rewrite-dataconverter-system.patch
+++ b/patches/server/1054-Rewrite-dataconverter-system.patch
diff --git a/patches/server/1054-Moonrise-optimisation-patches.patch b/patches/server/1055-Moonrise-optimisation-patches.patch
index 71f20bc7d9..4e0e6b9a0b 100644
--- a/patches/server/1054-Moonrise-optimisation-patches.patch
+++ b/patches/server/1055-Moonrise-optimisation-patches.patch
@@ -22763,19 +22763,32 @@ index 0000000000000000000000000000000000000000..689ce367164e79e0426eeecb81dbbc52
+
+ private SaveUtil() {}
+}
-diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
-index 46bf42d5ea9e7b046f962531c5962d287cf44a41..362765d977aaa1996f9cef3404c0676d7bbddf38 100644
---- a/src/main/java/io/papermc/paper/command/PaperCommand.java
-+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
-@@ -42,6 +42,8 @@ public final class PaperCommand extends Command {
- commands.put(Set.of("dumpitem"), new DumpItemCommand());
- commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand());
- commands.put(Set.of("dumplisteners"), new DumpListenersCommand());
+diff --git a/src/main/java/io/papermc/paper/FeatureHooks.java b/src/main/java/io/papermc/paper/FeatureHooks.java
+index a6779295bff446ee79e7c9d41e405447becc2966..efc7f4071655201c59c912e9c84e35a8da66e34c 100644
+--- a/src/main/java/io/papermc/paper/FeatureHooks.java
++++ b/src/main/java/io/papermc/paper/FeatureHooks.java
+@@ -1,6 +1,8 @@
+ package io.papermc.paper;
+
+ import io.papermc.paper.command.PaperSubcommand;
++import io.papermc.paper.command.subcommands.ChunkDebugCommand;
++import io.papermc.paper.command.subcommands.FixLightCommand;
+ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+ import it.unimi.dsi.fastutil.longs.LongSet;
+ import it.unimi.dsi.fastutil.longs.LongSets;
+@@ -29,9 +31,12 @@ import org.bukkit.World;
+ public final class FeatureHooks {
+
+ public static void initChunkTaskScheduler(final boolean useParallelGen) {
++ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(useParallelGen); // Paper - Chunk system
+ }
+
+ public static void registerPaperCommands(final Map<Set<String>, PaperSubcommand> commands) {
+ commands.put(Set.of("fixlight"), new FixLightCommand()); // Paper - rewrite chunk system
+ commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // Paper - rewrite chunk system
+ }
- return commands.entrySet().stream()
- .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
+ public static LevelChunkSection createSection(final Registry<Biome> biomeRegistry, final Level level, final ChunkPos chunkPos, final int chunkSection) {
diff --git a/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..2dca7afbd93cfbb8686f336fcd3b45dd01fba0fc
@@ -23181,34 +23194,6 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14
+ sender.getBukkitEntity().sendMessage(text().color(BLUE).append(text("Relighting "), text(pending[0], DARK_AQUA), text(" chunks")));
+ }
+}
-diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
-index 2d2ff826354670fef356e241d939080c9ed3fd4a..17e23ca4dd2bbfba49ea00aa2b719a95feb931be 100644
---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
-+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
-@@ -217,6 +217,23 @@ public class GlobalConfiguration extends ConfigurationPart {
- @PostProcess
- private void postProcess() {
- ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads);
-+
-+ String newChunkSystemGenParallelism = this.genParallelism;
-+ if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) {
-+ newChunkSystemGenParallelism = "true";
-+ }
-+
-+ boolean useParallelGen;
-+ if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled")
-+ || newChunkSystemGenParallelism.equalsIgnoreCase("true")) {
-+ useParallelGen = true;
-+ } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled")
-+ || newChunkSystemGenParallelism.equalsIgnoreCase("false")) {
-+ useParallelGen = false;
-+ } else {
-+ throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]");
-+ }
-+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(useParallelGen);
- }
- }
-
diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java
new file mode 100644
index 0000000000000000000000000000000000000000..8424cf9d4617b4732d44cc460d25b04481068989
@@ -36033,10 +36018,10 @@ index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2
for (SavedTick<T> savedTick : this.pendingTicks) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-index 028174f712ea9605f22243b76c3f5dd6da76b57f..2dd38f40c8c0b48b12ffe557ceeed69213066a6a 100644
+index f3ab07e44e2e912ea66c6148cfdb2a4a528741b2..c2bffe3450ee9f768e00a23ec09df74d7a06d49b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-@@ -82,6 +82,12 @@ public class CraftChunk implements Chunk {
+@@ -83,6 +83,12 @@ public class CraftChunk implements Chunk {
}
public ChunkAccess getHandle(ChunkStatus chunkStatus) {
@@ -36049,7 +36034,7 @@ index 028174f712ea9605f22243b76c3f5dd6da76b57f..2dd38f40c8c0b48b12ffe557ceeed692
ChunkAccess chunkAccess = this.worldServer.getChunk(this.x, this.z, chunkStatus);
// SPIGOT-7332: Get unwrapped extension
-@@ -116,60 +122,12 @@ public class CraftChunk implements Chunk {
+@@ -117,60 +123,12 @@ public class CraftChunk implements Chunk {
@Override
public boolean isEntitiesLoaded() {
@@ -36113,7 +36098,7 @@ index 028174f712ea9605f22243b76c3f5dd6da76b57f..2dd38f40c8c0b48b12ffe557ceeed692
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index ef836e1a6481775263bdbe3668febd577ac96aec..ac8af406180bc680d46e8edc3da0fc2e5211345a 100644
+index 5b64111bc8baca45ecc7bfa384e5f8a004163a0b..97b5d6ba2b19a7c730730c74175a29157aed1840 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1448,7 +1448,7 @@ public final class CraftServer implements Server {
@@ -36144,10 +36129,10 @@ index ef836e1a6481775263bdbe3668febd577ac96aec..ac8af406180bc680d46e8edc3da0fc2e
// Paper start - Adventure
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 2ead4edd2e6298ea3c22490e91319c64752815fc..a9f7ac8d1f5e184687d53ab3e8b348bb7f4f2ba0 100644
+index ca62105a0ff0aa69385cbf2018f8fe6a4bb69fd4..92d9f0ea8f7810ae20d3996f49aefa539b4bcb69 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -506,10 +506,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -507,15 +507,17 @@ public class CraftWorld extends CraftRegionAccessor implements World {
ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
if (playerChunk == null) return false;
@@ -36163,19 +36148,15 @@ index 2ead4edd2e6298ea3c22490e91319c64752815fc..a9f7ac8d1f5e184687d53ab3e8b348bb
- if (playersInRange.isEmpty()) return;
+ if (playersInRange.isEmpty()) return true; // Paper - chunk system
- // Paper start - Anti-Xray bypass
- final Map<Object, ClientboundLevelChunkWithLightPacket> refreshPackets = new HashMap<>();
-@@ -522,8 +526,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- }));
- // Paper end - Anti-Xray bypass
- }
+ FeatureHooks.sendChunkRefreshPackets(playersInRange, chunk);
- });
- });
+-
+ // Paper - chunk system
-
return true;
}
-@@ -627,20 +630,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+
+@@ -618,20 +620,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public Collection<Plugin> getPluginChunkTickets(int x, int z) {
DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager;
@@ -36197,7 +36178,7 @@ index 2ead4edd2e6298ea3c22490e91319c64752815fc..a9f7ac8d1f5e184687d53ab3e8b348bb
}
@Override
-@@ -648,7 +639,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -639,7 +629,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
Map<Plugin, ImmutableList.Builder<Chunk>> ret = new HashMap<>();
DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager;
@@ -36206,7 +36187,7 @@ index 2ead4edd2e6298ea3c22490e91319c64752815fc..a9f7ac8d1f5e184687d53ab3e8b348bb
long chunkKey = chunkTickets.getLongKey();
SortedArraySet<Ticket<?>> tickets = chunkTickets.getValue();
-@@ -1351,12 +1342,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1342,12 +1332,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public int getViewDistance() {
@@ -36221,7 +36202,7 @@ index 2ead4edd2e6298ea3c22490e91319c64752815fc..a9f7ac8d1f5e184687d53ab3e8b348bb
}
public BlockMetadataStore getBlockMetadata() {
-@@ -2495,17 +2486,20 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2486,17 +2476,20 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setSimulationDistance(final int simulationDistance) {
@@ -36246,10 +36227,10 @@ index 2ead4edd2e6298ea3c22490e91319c64752815fc..a9f7ac8d1f5e184687d53ab3e8b348bb
// Paper start - implement pointers
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 58b485c4cfd2ced26a7178aa4380d66c0250b014..4365fd116767b9aba8759d8b3083995fd0c460de 100644
+index d5dc10cf9440f2394e6548c6a3e0160df13c9cae..20f64850cb42d986358f01ffcdb42187e1684bca 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -3526,7 +3526,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -3519,7 +3519,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setViewDistance(final int viewDistance) {
@@ -36260,7 +36241,7 @@ index 58b485c4cfd2ced26a7178aa4380d66c0250b014..4365fd116767b9aba8759d8b3083995f
}
@Override
-@@ -3536,7 +3538,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -3529,7 +3531,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setSimulationDistance(final int simulationDistance) {
@@ -36271,7 +36252,7 @@ index 58b485c4cfd2ced26a7178aa4380d66c0250b014..4365fd116767b9aba8759d8b3083995f
}
@Override
-@@ -3546,7 +3550,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -3539,7 +3543,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setSendViewDistance(final int viewDistance) {
diff --git a/patches/server/1055-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/1056-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch
index c155a5cca2..c155a5cca2 100644
--- a/patches/server/1055-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch
+++ b/patches/server/1056-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch
diff --git a/patches/server/1056-Improved-Watchdog-Support.patch b/patches/server/1057-Improved-Watchdog-Support.patch
index 9fe5c21791..150860a96e 100644
--- a/patches/server/1056-Improved-Watchdog-Support.patch
+++ b/patches/server/1057-Improved-Watchdog-Support.patch
@@ -40,24 +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.
-diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
-index 6aaed8e8bf8c721fc834da5c76ac72a4c3e92458..4b002e8b75d117b726b0de274a76d3596fce015b 100644
---- a/src/main/java/com/destroystokyo/paper/Metrics.java
-+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
-@@ -92,7 +92,12 @@ public class Metrics {
- * Starts the Scheduler which submits our data every 30 minutes.
- */
- private void startSubmitting() {
-- final Runnable submitTask = this::submitData;
-+ final Runnable submitTask = () -> {
-+ if (MinecraftServer.getServer().hasStopped()) {
-+ return;
-+ }
-+ submitData();
-+ };
-
- // Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
- // bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay.
diff --git a/src/main/java/io/papermc/paper/util/LogManagerShutdownThread.java b/src/main/java/io/papermc/paper/util/LogManagerShutdownThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..183e141d0c13190c6905dc4510d891992afef878
diff --git a/patches/server/1057-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1058-Detail-more-information-in-watchdog-dumps.patch
index b5f4025bad..b5f4025bad 100644
--- a/patches/server/1057-Detail-more-information-in-watchdog-dumps.patch
+++ b/patches/server/1058-Detail-more-information-in-watchdog-dumps.patch
diff --git a/patches/server/1058-Entity-load-save-limit-per-chunk.patch b/patches/server/1059-Entity-load-save-limit-per-chunk.patch
index e69171236b..e69171236b 100644
--- a/patches/server/1058-Entity-load-save-limit-per-chunk.patch
+++ b/patches/server/1059-Entity-load-save-limit-per-chunk.patch
diff --git a/patches/server/1059-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/1060-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
index 5c9944447a..5c9944447a 100644
--- a/patches/server/1059-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
+++ b/patches/server/1060-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
diff --git a/patches/server/1060-Improve-performance-of-mass-crafts.patch b/patches/server/1061-Improve-performance-of-mass-crafts.patch
index 57f901bc5f..57f901bc5f 100644
--- a/patches/server/1060-Improve-performance-of-mass-crafts.patch
+++ b/patches/server/1061-Improve-performance-of-mass-crafts.patch
diff --git a/patches/server/1061-Incremental-chunk-and-player-saving.patch b/patches/server/1062-Incremental-chunk-and-player-saving.patch
index d0f88ba05d..d0f88ba05d 100644
--- a/patches/server/1061-Incremental-chunk-and-player-saving.patch
+++ b/patches/server/1062-Incremental-chunk-and-player-saving.patch
diff --git a/patches/server/1062-Optimise-general-POI-access.patch b/patches/server/1063-Optimise-general-POI-access.patch
index 79a34afd5a..79a34afd5a 100644
--- a/patches/server/1062-Optimise-general-POI-access.patch
+++ b/patches/server/1063-Optimise-general-POI-access.patch
diff --git a/patches/server/1063-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1064-Fix-entity-tracker-desync-when-new-players-are-added.patch
index b8cbd694c2..b8cbd694c2 100644
--- a/patches/server/1063-Fix-entity-tracker-desync-when-new-players-are-added.patch
+++ b/patches/server/1064-Fix-entity-tracker-desync-when-new-players-are-added.patch
diff --git a/patches/server/1064-Lag-compensation-ticks.patch b/patches/server/1065-Lag-compensation-ticks.patch
index e066509147..e066509147 100644
--- a/patches/server/1064-Lag-compensation-ticks.patch
+++ b/patches/server/1065-Lag-compensation-ticks.patch
diff --git a/patches/server/1065-Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/1066-Optimise-collision-checking-in-player-move-packet-ha.patch
index 317ca38fea..317ca38fea 100644
--- a/patches/server/1065-Optimise-collision-checking-in-player-move-packet-ha.patch
+++ b/patches/server/1066-Optimise-collision-checking-in-player-move-packet-ha.patch
diff --git a/patches/server/1066-Optional-per-player-mob-spawns.patch b/patches/server/1067-Optional-per-player-mob-spawns.patch
index 16376dd6f8..16376dd6f8 100644
--- a/patches/server/1066-Optional-per-player-mob-spawns.patch
+++ b/patches/server/1067-Optional-per-player-mob-spawns.patch
diff --git a/patches/server/1067-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/1068-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch
index 57ae223711..57ae223711 100644
--- a/patches/server/1067-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch
+++ b/patches/server/1068-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch
diff --git a/patches/server/1068-Eigencraft-redstone-implementation.patch b/patches/server/1069-Eigencraft-redstone-implementation.patch
index 8ea799e5f8..8ea799e5f8 100644
--- a/patches/server/1068-Eigencraft-redstone-implementation.patch
+++ b/patches/server/1069-Eigencraft-redstone-implementation.patch
diff --git a/patches/server/1069-Add-Alternate-Current-redstone-implementation.patch b/patches/server/1070-Add-Alternate-Current-redstone-implementation.patch
index 740ec46169..740ec46169 100644
--- a/patches/server/1069-Add-Alternate-Current-redstone-implementation.patch
+++ b/patches/server/1070-Add-Alternate-Current-redstone-implementation.patch
diff --git a/patches/server/1071-Implement-chunk-view-API.patch b/patches/server/1071-Implement-chunk-view-API.patch
deleted file mode 100644
index b324cf7b6e..0000000000
--- a/patches/server/1071-Implement-chunk-view-API.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Flo0 <[email protected]>
-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 4365fd116767b9aba8759d8b3083995fd0c460de..84c494ca81b8f58604b372ac7236147776817a4f 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -3489,27 +3489,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
- @Override
- public Set<java.lang.Long> 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<org.bukkit.Chunk> getSentChunks() {
- org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
-- final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<org.bukkit.Chunk> 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<org.bukkit.Chunk> 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/1070-Improve-exact-choice-recipe-ingredients.patch b/patches/server/1071-Improve-exact-choice-recipe-ingredients.patch
index 88c45348a2..88c45348a2 100644
--- a/patches/server/1070-Improve-exact-choice-recipe-ingredients.patch
+++ b/patches/server/1071-Improve-exact-choice-recipe-ingredients.patch
diff --git a/patches/server/1072-Implement-chunk-view-API.patch b/patches/server/1072-Implement-chunk-view-API.patch
new file mode 100644
index 0000000000..7e6fbf27c8
--- /dev/null
+++ b/patches/server/1072-Implement-chunk-view-API.patch
@@ -0,0 +1,51 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Flo0 <[email protected]>
+Date: Thu, 5 Dec 2024 12:15:07 +0100
+Subject: [PATCH] Implement chunk view API
+
+
+diff --git a/src/main/java/io/papermc/paper/FeatureHooks.java b/src/main/java/io/papermc/paper/FeatureHooks.java
+index efc7f4071655201c59c912e9c84e35a8da66e34c..e41ceed2b11e24ae512c162f0f4465278ce207bc 100644
+--- a/src/main/java/io/papermc/paper/FeatureHooks.java
++++ b/src/main/java/io/papermc/paper/FeatureHooks.java
+@@ -3,8 +3,8 @@ package io.papermc.paper;
+ import io.papermc.paper.command.PaperSubcommand;
+ import io.papermc.paper.command.subcommands.ChunkDebugCommand;
+ import io.papermc.paper.command.subcommands.FixLightCommand;
++import it.unimi.dsi.fastutil.longs.LongIterator;
+ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+-import it.unimi.dsi.fastutil.longs.LongSet;
+ import it.unimi.dsi.fastutil.longs.LongSets;
+ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+ import it.unimi.dsi.fastutil.objects.ObjectSet;
+@@ -62,22 +62,21 @@ public final class FeatureHooks {
+ }
+
+ public static Set<Long> getSentChunkKeys(final ServerPlayer player) {
+- final LongSet keys = new LongOpenHashSet();
+- player.getChunkTrackingView().forEach(pos -> keys.add(pos.longKey));
+- return LongSets.unmodifiable(keys);
++ return LongSets.unmodifiable(player.moonrise$getChunkLoader().getSentChunksRaw().clone());
+ }
+
+ public static Set<Chunk> getSentChunks(final ServerPlayer player) {
+- final ObjectSet<Chunk> chunks = new ObjectOpenHashSet<>();
++ final LongOpenHashSet rawChunkKeys = player.moonrise$getChunkLoader().getSentChunksRaw();
++ final ObjectSet<org.bukkit.Chunk> chunks = new ObjectOpenHashSet<>(rawChunkKeys.size());
+ final World world = player.serverLevel().getWorld();
+- player.getChunkTrackingView().forEach(pos -> {
+- final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey);
+- chunks.add(chunk);
+- });
++ final LongIterator iter = player.moonrise$getChunkLoader().getSentChunksRaw().longIterator();
++ while (iter.hasNext()) {
++ chunks.add(world.getChunkAt(iter.nextLong(), false));
++ }
+ return ObjectSets.unmodifiable(chunks);
+ }
+
+ public static boolean isChunkSent(final ServerPlayer player, final long chunkKey) {
+- return player.getChunkTrackingView().contains(new ChunkPos(chunkKey));
++ return player.moonrise$getChunkLoader().getSentChunksRaw().contains(chunkKey);
+ }
+ }