diff options
45 files changed, 1512 insertions, 1510 deletions
diff --git a/patches/server/0008-MC-Utils.patch b/patches/server/0008-MC-Utils.patch index de1b60d845..3f7ecbecda 100644 --- a/patches/server/0008-MC-Utils.patch +++ b/patches/server/0008-MC-Utils.patch @@ -989,7 +989,7 @@ index 0000000000000000000000000000000000000000..190c5f0b02a3d99054704ae1afbffb34 +} diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java new file mode 100644 -index 0000000000000000000000000000000000000000..c89f6986eda5a132a948732ea1b6923370685317 +index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9690e967d --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java @@ -0,0 +1,453 @@ @@ -1000,7 +1000,7 @@ index 0000000000000000000000000000000000000000..c89f6986eda5a132a948732ea1b69233 +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.ChunkPos; +import javax.annotation.Nullable; @@ -1448,7 +1448,7 @@ index 0000000000000000000000000000000000000000..c89f6986eda5a132a948732ea1b69233 +} diff --git a/src/main/java/com/destroystokyo/paper/util/misc/DistanceTrackingAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/DistanceTrackingAreaMap.java new file mode 100644 -index 0000000000000000000000000000000000000000..eacec5074ab1237986635c6cb19a4d34a89d4d3f +index 0000000000000000000000000000000000000000..896c3ff7ddb07f1f6f05f90e1e3fe7fb615071d4 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/misc/DistanceTrackingAreaMap.java @@ -0,0 +1,175 @@ @@ -1456,7 +1456,7 @@ index 0000000000000000000000000000000000000000..eacec5074ab1237986635c6cb19a4d34 + +import io.papermc.paper.util.IntegerUtil; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.world.level.ChunkPos; + +/** @author Spottedleaf */ @@ -1990,13 +1990,13 @@ index 0000000000000000000000000000000000000000..e51104e65a07b6ea7bbbcbb6afb066ef +} diff --git a/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java new file mode 100644 -index 0000000000000000000000000000000000000000..d0c77068e9a53d1b8bbad0f3f6b420d6bc85f8c8 +index 0000000000000000000000000000000000000000..a743703502cea333bd4231b6557de50e8eaf81eb --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java @@ -0,0 +1,85 @@ +package com.destroystokyo.paper.util.pooled; + -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import org.apache.commons.lang3.mutable.MutableInt; + +import java.util.ArrayDeque; @@ -2172,7 +2172,7 @@ index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a } diff --git a/src/main/java/io/papermc/paper/chunk/SingleThreadChunkRegionManager.java b/src/main/java/io/papermc/paper/chunk/SingleThreadChunkRegionManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..0b71cf7a462d25c3e4f910e09a37270ce9bc7776 +index 0000000000000000000000000000000000000000..a5f706d6f716b2a463ae58adcde69d9e665c7733 --- /dev/null +++ b/src/main/java/io/papermc/paper/chunk/SingleThreadChunkRegionManager.java @@ -0,0 +1,477 @@ @@ -2182,7 +2182,7 @@ index 0000000000000000000000000000000000000000..0b71cf7a462d25c3e4f910e09a37270c +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import java.util.ArrayList; @@ -2653,6 +2653,306 @@ index 0000000000000000000000000000000000000000..0b71cf7a462d25c3e4f910e09a37270c + + } +} +diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8a5e93961dac4d87c81c0e70b6f4124a1f1d2556 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +@@ -0,0 +1,294 @@ ++package io.papermc.paper.chunk.system; ++ ++import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import com.destroystokyo.paper.util.SneakyThrow; ++import com.mojang.datafixers.util.Either; ++import com.mojang.logging.LogUtils; ++import io.papermc.paper.util.CoordinateUtils; ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.ChunkMap; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.server.level.TicketType; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.ChunkStatus; ++import net.minecraft.world.level.chunk.LevelChunk; ++import org.bukkit.Bukkit; ++import org.slf4j.Logger; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.concurrent.CompletableFuture; ++import java.util.function.Consumer; ++ ++public final class ChunkSystem { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { ++ scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ } ++ ++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { ++ level.chunkSource.mainThreadProcessor.execute(run); ++ } ++ ++ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, ++ final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, ++ final Consumer<ChunkAccess> onComplete) { ++ if (gen) { ++ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); ++ return; ++ } ++ scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { ++ if (chunk == null) { ++ onComplete.accept(null); ++ } else { ++ if (chunk.getStatus().isOrAfter(toStatus)) { ++ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); ++ } else { ++ onComplete.accept(null); ++ } ++ } ++ }); ++ } ++ ++ static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); ++ ++ private static long chunkLoadCounter = 0L; ++ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, ++ final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) { ++ if (!Bukkit.isPrimaryThread()) { ++ scheduleChunkTask(level, chunkX, chunkZ, () -> { ++ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); ++ }, priority); ++ return; ++ } ++ ++ final int minLevel = 33 + ChunkStatus.getDistance(toStatus); ++ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; ++ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); ++ ++ if (addTicket) { ++ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); ++ } ++ level.chunkSource.runDistanceManagerUpdates(); ++ ++ final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> { ++ try { ++ if (onComplete != null) { ++ onComplete.accept(chunk); ++ } ++ } catch (final ThreadDeath death) { ++ throw death; ++ } catch (final Throwable thr) { ++ LOGGER.error("Exception handling chunk load callback", thr); ++ SneakyThrow.sneaky(thr); ++ } finally { ++ if (addTicket) { ++ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); ++ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); ++ } ++ } ++ }; ++ ++ final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ if (holder == null || holder.getTicketLevel() > minLevel) { ++ loadCallback.accept(null); ++ return; ++ } ++ ++ final CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> loadFuture = holder.getOrScheduleFuture(toStatus, level.chunkSource.chunkMap); ++ ++ if (loadFuture.isDone()) { ++ loadCallback.accept(loadFuture.join().left().orElse(null)); ++ return; ++ } ++ ++ loadFuture.whenCompleteAsync((final Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { ++ if (thr != null) { ++ loadCallback.accept(null); ++ return; ++ } ++ loadCallback.accept(either.left().orElse(null)); ++ }, (final Runnable r) -> { ++ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ }); ++ } ++ ++ public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, ++ final ChunkHolder.FullChunkStatus toStatus, final boolean addTicket, ++ final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) { ++ if (toStatus == ChunkHolder.FullChunkStatus.INACCESSIBLE) { ++ throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); ++ } ++ ++ if (!Bukkit.isPrimaryThread()) { ++ scheduleChunkTask(level, chunkX, chunkZ, () -> { ++ scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); ++ }, priority); ++ return; ++ } ++ ++ final int minLevel = 33 - (toStatus.ordinal() - 1); ++ final int radius = toStatus.ordinal() - 1; ++ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; ++ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); ++ ++ if (addTicket) { ++ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); ++ } ++ level.chunkSource.runDistanceManagerUpdates(); ++ ++ final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> { ++ try { ++ if (onComplete != null) { ++ onComplete.accept(chunk); ++ } ++ } catch (final ThreadDeath death) { ++ throw death; ++ } catch (final Throwable thr) { ++ LOGGER.error("Exception handling chunk load callback", thr); ++ SneakyThrow.sneaky(thr); ++ } finally { ++ if (addTicket) { ++ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); ++ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); ++ } ++ } ++ }; ++ ++ final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ if (holder == null || holder.getTicketLevel() > minLevel) { ++ loadCallback.accept(null); ++ return; ++ } ++ ++ final CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> tickingState; ++ switch (toStatus) { ++ case BORDER: { ++ tickingState = holder.getFullChunkFuture(); ++ break; ++ } ++ case TICKING: { ++ tickingState = holder.getTickingChunkFuture(); ++ break; ++ } ++ case ENTITY_TICKING: { ++ tickingState = holder.getEntityTickingChunkFuture(); ++ break; ++ } ++ default: { ++ throw new IllegalStateException("Cannot reach here"); ++ } ++ } ++ ++ if (tickingState.isDone()) { ++ loadCallback.accept(tickingState.join().left().orElse(null)); ++ return; ++ } ++ ++ tickingState.whenCompleteAsync((final Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { ++ if (thr != null) { ++ loadCallback.accept(null); ++ return; ++ } ++ loadCallback.accept(either.left().orElse(null)); ++ }, (final Runnable r) -> { ++ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ }); ++ } ++ ++ public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) { ++ return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); ++ } ++ ++ public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) { ++ return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); ++ } ++ ++ public static int getVisibleChunkHolderCount(final ServerLevel level) { ++ return level.chunkSource.chunkMap.visibleChunkMap.size(); ++ } ++ ++ public static int getUpdatingChunkHolderCount(final ServerLevel level) { ++ return level.chunkSource.chunkMap.updatingChunkMap.size(); ++ } ++ ++ public static boolean hasAnyChunkHolders(final ServerLevel level) { ++ return getUpdatingChunkHolderCount(level) != 0; ++ } ++ ++ public static void onEntityPreAdd(final ServerLevel level, final Entity entity) { ++ ++ } ++ ++ public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) { ++ final ChunkMap chunkMap = level.chunkSource.chunkMap; ++ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) { ++ chunkMap.regionManagers.get(index).addChunk(holder.pos.x, holder.pos.z); ++ } ++ } ++ ++ public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { ++ final ChunkMap chunkMap = level.chunkSource.chunkMap; ++ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) { ++ chunkMap.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z); ++ } ++ } ++ ++ public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ chunk.playerChunk = holder; ++ } ++ ++ public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ ++ } ++ ++ public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { ++ chunk.level.getChunkSource().tickingChunks.add(chunk); ++ } ++ ++ public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { ++ chunk.level.getChunkSource().tickingChunks.remove(chunk); ++ } ++ ++ public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { ++ chunk.level.getChunkSource().entityTickingChunks.add(chunk); ++ } ++ ++ public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { ++ chunk.level.getChunkSource().entityTickingChunks.remove(chunk); ++ } ++ ++ public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { ++ return level.chunkSource.chunkMap.getUnloadingChunkHolder(chunkX, chunkZ); ++ } ++ ++ public static int getSendViewDistance(final ServerPlayer player) { ++ return getLoadViewDistance(player); ++ } ++ ++ public static int getLoadViewDistance(final ServerPlayer player) { ++ final ServerLevel level = player.getLevel(); ++ if (level == null) { ++ return Bukkit.getViewDistance() + 1; ++ } ++ return level.chunkSource.chunkMap.getEffectiveViewDistance() + 1; ++ } ++ ++ public static int getTickViewDistance(final ServerPlayer player) { ++ final ServerLevel level = player.getLevel(); ++ if (level == null) { ++ return Bukkit.getSimulationDistance(); ++ } ++ return level.chunkSource.chunkMap.distanceManager.getSimulationDistance(); ++ } ++ ++ private ChunkSystem() { ++ throw new RuntimeException(); ++ } ++} diff --git a/src/main/java/io/papermc/paper/util/CachedLists.java b/src/main/java/io/papermc/paper/util/CachedLists.java new file mode 100644 index 0000000000000000000000000000000000000000..be668387f65a633c6ac497fca632a4767a1bf3a2 @@ -3154,6 +3454,524 @@ index 0000000000000000000000000000000000000000..cea9c098ade00ee87b8efc8164ab72f5 + return this.sum; + } +} +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9798a1010120125039cbf226a0e3679cc92f92c7 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -0,0 +1,512 @@ ++package io.papermc.paper.util; ++ ++import com.google.common.util.concurrent.ThreadFactoryBuilder; ++import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; ++import java.lang.ref.Cleaner; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.ClipContext; ++import net.minecraft.world.level.Level; ++import org.apache.commons.lang.exception.ExceptionUtils; ++import org.bukkit.Location; ++import org.bukkit.block.BlockFace; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.util.Waitable; ++import org.spigotmc.AsyncCatcher; ++ ++import javax.annotation.Nonnull; ++import javax.annotation.Nullable; ++import java.util.List; ++import java.util.Queue; ++import java.util.concurrent.CompletableFuture; ++import java.util.concurrent.ExecutionException; ++import java.util.concurrent.LinkedBlockingQueue; ++import java.util.concurrent.ThreadPoolExecutor; ++import java.util.concurrent.TimeUnit; ++import java.util.concurrent.TimeoutException; ++import java.util.concurrent.atomic.AtomicBoolean; ++import java.util.function.BiConsumer; ++import java.util.function.Consumer; ++import java.util.function.Supplier; ++ ++public final class MCUtil { ++ public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor( ++ 0, 2, 60L, TimeUnit.SECONDS, ++ new LinkedBlockingQueue<>(), ++ new ThreadFactoryBuilder() ++ .setNameFormat("Paper Async Task Handler Thread - %1$d") ++ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) ++ .build() ++ ); ++ public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor( ++ 1, 1, 0L, TimeUnit.SECONDS, ++ new LinkedBlockingQueue<>(), ++ new ThreadFactoryBuilder() ++ .setNameFormat("Paper Object Cleaner") ++ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) ++ .build() ++ ); ++ ++ public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE); ++ ++ ++ public static Runnable once(Runnable run) { ++ AtomicBoolean ran = new AtomicBoolean(false); ++ return () -> { ++ if (ran.compareAndSet(false, true)) { ++ run.run(); ++ } ++ }; ++ } ++ ++ public static <T> Runnable once(List<T> list, Consumer<T> cb) { ++ return once(() -> { ++ list.forEach(cb); ++ }); ++ } ++ ++ private static Runnable makeCleanerCallback(Runnable run) { ++ return once(() -> cleanerExecutor.execute(run)); ++ } ++ ++ /** ++ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky! ++ * @param obj ++ * @param run ++ * @return ++ */ ++ public static Runnable registerCleaner(Object obj, Runnable run) { ++ // Wrap callback in its own method above or the lambda will leak object ++ Runnable cleaner = makeCleanerCallback(run); ++ CleanerHolder.CLEANER.register(obj, cleaner); ++ return cleaner; ++ } ++ ++ private static final class CleanerHolder { ++ private static final Cleaner CLEANER = Cleaner.create(); ++ } ++ ++ /** ++ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky! ++ * @param obj ++ * @param list ++ * @param cleaner ++ * @param <T> ++ * @return ++ */ ++ public static <T> Runnable registerListCleaner(Object obj, List<T> list, Consumer<T> cleaner) { ++ return registerCleaner(obj, () -> { ++ list.forEach(cleaner); ++ list.clear(); ++ }); ++ } ++ ++ /** ++ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky! ++ * @param obj ++ * @param resource ++ * @param cleaner ++ * @param <T> ++ * @return ++ */ ++ public static <T> Runnable registerCleaner(Object obj, T resource, java.util.function.Consumer<T> cleaner) { ++ return registerCleaner(obj, () -> cleaner.accept(resource)); ++ } ++ ++ public static List<ChunkPos> getSpiralOutChunks(BlockPos blockposition, int radius) { ++ List<ChunkPos> list = com.google.common.collect.Lists.newArrayList(); ++ ++ list.add(new ChunkPos(blockposition.getX() >> 4, blockposition.getZ() >> 4)); ++ for (int r = 1; r <= radius; r++) { ++ int x = -r; ++ int z = r; ++ ++ // Iterates the edge of half of the box; then negates for other half. ++ while (x <= r && z > -r) { ++ list.add(new ChunkPos((blockposition.getX() + (x << 4)) >> 4, (blockposition.getZ() + (z << 4)) >> 4)); ++ list.add(new ChunkPos((blockposition.getX() - (x << 4)) >> 4, (blockposition.getZ() - (z << 4)) >> 4)); ++ ++ if (x < r) { ++ x++; ++ } else { ++ z--; ++ } ++ } ++ } ++ return list; ++ } ++ ++ public static int fastFloor(double x) { ++ int truncated = (int)x; ++ return x < (double)truncated ? truncated - 1 : truncated; ++ } ++ ++ public static int fastFloor(float x) { ++ int truncated = (int)x; ++ return x < (double)truncated ? truncated - 1 : truncated; ++ } ++ ++ public static float normalizeYaw(float f) { ++ float f1 = f % 360.0F; ++ ++ if (f1 >= 180.0F) { ++ f1 -= 360.0F; ++ } ++ ++ if (f1 < -180.0F) { ++ f1 += 360.0F; ++ } ++ ++ return f1; ++ } ++ ++ /** ++ * Quickly generate a stack trace for current location ++ * ++ * @return Stacktrace ++ */ ++ public static String stack() { ++ return ExceptionUtils.getFullStackTrace(new Throwable()); ++ } ++ ++ /** ++ * Quickly generate a stack trace for current location with message ++ * ++ * @param str ++ * @return Stacktrace ++ */ ++ public static String stack(String str) { ++ return ExceptionUtils.getFullStackTrace(new Throwable(str)); ++ } ++ ++ public static long getCoordinateKey(final BlockPos blockPos) { ++ return ((long)(blockPos.getZ() >> 4) << 32) | ((blockPos.getX() >> 4) & 0xFFFFFFFFL); ++ } ++ ++ public static long getCoordinateKey(final Entity entity) { ++ return ((long)(MCUtil.fastFloor(entity.getZ()) >> 4) << 32) | ((MCUtil.fastFloor(entity.getX()) >> 4) & 0xFFFFFFFFL); ++ } ++ ++ public static long getCoordinateKey(final ChunkPos pair) { ++ return ((long)pair.z << 32) | (pair.x & 0xFFFFFFFFL); ++ } ++ ++ public static long getCoordinateKey(final int x, final int z) { ++ return ((long)z << 32) | (x & 0xFFFFFFFFL); ++ } ++ ++ public static int getCoordinateX(final long key) { ++ return (int)key; ++ } ++ ++ public static int getCoordinateZ(final long key) { ++ return (int)(key >>> 32); ++ } ++ ++ public static int getChunkCoordinate(final double coordinate) { ++ return MCUtil.fastFloor(coordinate) >> 4; ++ } ++ ++ public static int getBlockCoordinate(final double coordinate) { ++ return MCUtil.fastFloor(coordinate); ++ } ++ ++ public static long getBlockKey(final int x, final int y, final int z) { ++ return ((long)x & 0x7FFFFFF) | (((long)z & 0x7FFFFFF) << 27) | ((long)y << 54); ++ } ++ ++ public static long getBlockKey(final BlockPos pos) { ++ return ((long)pos.getX() & 0x7FFFFFF) | (((long)pos.getZ() & 0x7FFFFFF) << 27) | ((long)pos.getY() << 54); ++ } ++ ++ public static long getBlockKey(final Entity entity) { ++ return getBlockKey(getBlockCoordinate(entity.getX()), getBlockCoordinate(entity.getY()), getBlockCoordinate(entity.getZ())); ++ } ++ ++ // assumes the sets have the same comparator, and if this comparator is null then assume T is Comparable ++ public static <T> void mergeSortedSets(final java.util.function.Consumer<T> consumer, final java.util.Comparator<? super T> comparator, final java.util.SortedSet<T>...sets) { ++ final ObjectRBTreeSet<T> all = new ObjectRBTreeSet<>(comparator); ++ // note: this is done in log(n!) ~ nlogn time. It could be improved if it were to mimic what mergesort does. ++ for (java.util.SortedSet<T> set : sets) { ++ if (set != null) { ++ all.addAll(set); ++ } ++ } ++ all.forEach(consumer); ++ } ++ ++ private MCUtil() {} ++ ++ public static final java.util.concurrent.Executor MAIN_EXECUTOR = (run) -> { ++ if (!isMainThread()) { ++ MinecraftServer.getServer().execute(run); ++ } else { ++ run.run(); ++ } ++ }; ++ ++ public static <T> CompletableFuture<T> ensureMain(CompletableFuture<T> future) { ++ return future.thenApplyAsync(r -> r, MAIN_EXECUTOR); ++ } ++ ++ public static <T> void thenOnMain(CompletableFuture<T> future, Consumer<T> consumer) { ++ future.thenAcceptAsync(consumer, MAIN_EXECUTOR); ++ } ++ public static <T> void thenOnMain(CompletableFuture<T> future, BiConsumer<T, Throwable> consumer) { ++ future.whenCompleteAsync(consumer, MAIN_EXECUTOR); ++ } ++ ++ public static boolean isMainThread() { ++ return MinecraftServer.getServer().isSameThread(); ++ } ++ ++ public static org.bukkit.scheduler.BukkitTask scheduleTask(int ticks, Runnable runnable) { ++ return scheduleTask(ticks, runnable, null); ++ } ++ ++ public static org.bukkit.scheduler.BukkitTask scheduleTask(int ticks, Runnable runnable, String taskName) { ++ return MinecraftServer.getServer().server.getScheduler().scheduleInternalTask(runnable, ticks, taskName); ++ } ++ ++ public static void processQueue() { ++ Runnable runnable; ++ Queue<Runnable> processQueue = getProcessQueue(); ++ while ((runnable = processQueue.poll()) != null) { ++ try { ++ runnable.run(); ++ } catch (Exception e) { ++ MinecraftServer.LOGGER.error("Error executing task", e); ++ } ++ } ++ } ++ public static <T> T processQueueWhileWaiting(CompletableFuture <T> future) { ++ try { ++ if (isMainThread()) { ++ while (!future.isDone()) { ++ try { ++ return future.get(1, TimeUnit.MILLISECONDS); ++ } catch (TimeoutException ignored) { ++ processQueue(); ++ } ++ } ++ } ++ return future.get(); ++ } catch (Exception e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ public static void ensureMain(Runnable run) { ++ ensureMain(null, run); ++ } ++ /** ++ * Ensures the target code is running on the main thread ++ * @param reason ++ * @param run ++ * @return ++ */ ++ public static void ensureMain(String reason, Runnable run) { ++ if (!isMainThread()) { ++ if (reason != null) { ++ MinecraftServer.LOGGER.warn("Asynchronous " + reason + "!", new IllegalStateException()); ++ } ++ getProcessQueue().add(run); ++ return; ++ } ++ run.run(); ++ } ++ ++ private static Queue<Runnable> getProcessQueue() { ++ return MinecraftServer.getServer().processQueue; ++ } ++ ++ public static <T> T ensureMain(Supplier<T> run) { ++ return ensureMain(null, run); ++ } ++ /** ++ * Ensures the target code is running on the main thread ++ * @param reason ++ * @param run ++ * @param <T> ++ * @return ++ */ ++ public static <T> T ensureMain(String reason, Supplier<T> run) { ++ if (!isMainThread()) { ++ if (reason != null) { ++ MinecraftServer.LOGGER.warn("Asynchronous " + reason + "! Blocking thread until it returns ", new IllegalStateException()); ++ } ++ Waitable<T> wait = new Waitable<T>() { ++ @Override ++ protected T evaluate() { ++ return run.get(); ++ } ++ }; ++ getProcessQueue().add(wait); ++ try { ++ return wait.get(); ++ } catch (InterruptedException | ExecutionException e) { ++ MinecraftServer.LOGGER.warn("Encountered exception", e); ++ } ++ return null; ++ } ++ return run.get(); ++ } ++ ++ /** ++ * Calculates distance between 2 entities ++ * @param e1 ++ * @param e2 ++ * @return ++ */ ++ public static double distance(Entity e1, Entity e2) { ++ return Math.sqrt(distanceSq(e1, e2)); ++ } ++ ++ ++ /** ++ * Calculates distance between 2 block positions ++ * @param e1 ++ * @param e2 ++ * @return ++ */ ++ public static double distance(BlockPos e1, BlockPos e2) { ++ return Math.sqrt(distanceSq(e1, e2)); ++ } ++ ++ /** ++ * Gets the distance between 2 positions ++ * @param x1 ++ * @param y1 ++ * @param z1 ++ * @param x2 ++ * @param y2 ++ * @param z2 ++ * @return ++ */ ++ public static double distance(double x1, double y1, double z1, double x2, double y2, double z2) { ++ return Math.sqrt(distanceSq(x1, y1, z1, x2, y2, z2)); ++ } ++ ++ /** ++ * Get's the distance squared between 2 entities ++ * @param e1 ++ * @param e2 ++ * @return ++ */ ++ public static double distanceSq(Entity e1, Entity e2) { ++ return distanceSq(e1.getX(),e1.getY(),e1.getZ(), e2.getX(),e2.getY(),e2.getZ()); ++ } ++ ++ /** ++ * Gets the distance sqaured between 2 block positions ++ * @param pos1 ++ * @param pos2 ++ * @return ++ */ ++ public static double distanceSq(BlockPos pos1, BlockPos pos2) { ++ return distanceSq(pos1.getX(), pos1.getY(), pos1.getZ(), pos2.getX(), pos2.getY(), pos2.getZ()); ++ } ++ ++ /** ++ * Gets the distance squared between 2 positions ++ * @param x1 ++ * @param y1 ++ * @param z1 ++ * @param x2 ++ * @param y2 ++ * @param z2 ++ * @return ++ */ ++ public static double distanceSq(double x1, double y1, double z1, double x2, double y2, double z2) { ++ return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2); ++ } ++ ++ /** ++ * Converts a NMS World/BlockPosition to Bukkit Location ++ * @param world ++ * @param x ++ * @param y ++ * @param z ++ * @return ++ */ ++ public static Location toLocation(Level world, double x, double y, double z) { ++ return new Location(world.getWorld(), x, y, z); ++ } ++ ++ /** ++ * Converts a NMS World/BlockPosition to Bukkit Location ++ * @param world ++ * @param pos ++ * @return ++ */ ++ public static Location toLocation(Level world, BlockPos pos) { ++ return new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); ++ } ++ ++ /** ++ * Converts an NMS entity's current location to a Bukkit Location ++ * @param entity ++ * @return ++ */ ++ public static Location toLocation(Entity entity) { ++ return new Location(entity.getCommandSenderWorld().getWorld(), entity.getX(), entity.getY(), entity.getZ()); ++ } ++ ++ public static org.bukkit.block.Block toBukkitBlock(Level world, BlockPos pos) { ++ return world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ } ++ ++ public static BlockPos toBlockPosition(Location loc) { ++ return new BlockPos(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); ++ } ++ ++ public static boolean isEdgeOfChunk(BlockPos pos) { ++ final int modX = pos.getX() & 15; ++ final int modZ = pos.getZ() & 15; ++ return (modX == 0 || modX == 15 || modZ == 0 || modZ == 15); ++ } ++ ++ /** ++ * Posts a task to be executed asynchronously ++ * @param run ++ */ ++ public static void scheduleAsyncTask(Runnable run) { ++ asyncExecutor.execute(run); ++ } ++ ++ @Nonnull ++ public static ServerLevel getNMSWorld(@Nonnull org.bukkit.World world) { ++ return ((CraftWorld) world).getHandle(); ++ } ++ ++ public static ServerLevel getNMSWorld(@Nonnull org.bukkit.entity.Entity entity) { ++ return getNMSWorld(entity.getWorld()); ++ } ++ ++ public static BlockFace toBukkitBlockFace(Direction enumDirection) { ++ switch (enumDirection) { ++ case DOWN: ++ return BlockFace.DOWN; ++ case UP: ++ return BlockFace.UP; ++ case NORTH: ++ return BlockFace.NORTH; ++ case SOUTH: ++ return BlockFace.SOUTH; ++ case WEST: ++ return BlockFace.WEST; ++ case EAST: ++ return BlockFace.EAST; ++ default: ++ return null; ++ } ++ } ++ ++ public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) { ++ return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status); ++ } ++} diff --git a/src/main/java/io/papermc/paper/util/StackWalkerUtil.java b/src/main/java/io/papermc/paper/util/StackWalkerUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..f7114d5b8f2f93f62883e24da29afaf9f74ee1a6 @@ -3881,7 +4699,7 @@ index 0000000000000000000000000000000000000000..470402573bc31106d5a63e415b958fb7 +} diff --git a/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java b/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java new file mode 100644 -index 0000000000000000000000000000000000000000..4d3dc8fba51bf5c0dceb06744781d1df2bbf2df6 +index 0000000000000000000000000000000000000000..808d1449ac44ae86a650932365081fbaf178d141 --- /dev/null +++ b/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java @@ -0,0 +1,718 @@ @@ -3893,7 +4711,7 @@ index 0000000000000000000000000000000000000000..4d3dc8fba51bf5c0dceb06744781d1df +import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue; +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; + +public final class Delayed8WayDistancePropagator2D { + @@ -4673,825 +5491,8 @@ index 207f1c1fc9d4451d27047bb8362bded8cd53e32f..021a26a6b1c258deffc26c035ab52a4e if (packet.isSkippable()) { throw new SkipPacketException(var10); } else { -diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c59fca05484c30b28e883f5b5dde0362f294b517 ---- /dev/null -+++ b/src/main/java/net/minecraft/server/ChunkSystem.java -@@ -0,0 +1,294 @@ -+package net.minecraft.server; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.destroystokyo.paper.util.SneakyThrow; -+import com.mojang.datafixers.util.Either; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.util.CoordinateUtils; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.TicketType; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.ChunkStatus; -+import net.minecraft.world.level.chunk.LevelChunk; -+import org.bukkit.Bukkit; -+import org.slf4j.Logger; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.concurrent.CompletableFuture; -+import java.util.function.Consumer; -+ -+public final class ChunkSystem { -+ -+ private static final Logger LOGGER = LogUtils.getLogger(); -+ -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { -+ scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { -+ level.chunkSource.mainThreadProcessor.execute(run); -+ } -+ -+ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, -+ final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, -+ final Consumer<ChunkAccess> onComplete) { -+ if (gen) { -+ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ return; -+ } -+ scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { -+ if (chunk == null) { -+ onComplete.accept(null); -+ } else { -+ if (chunk.getStatus().isOrAfter(toStatus)) { -+ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ } else { -+ onComplete.accept(null); -+ } -+ } -+ }); -+ } -+ -+ static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); -+ -+ private static long chunkLoadCounter = 0L; -+ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, -+ final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) { -+ if (!Bukkit.isPrimaryThread()) { -+ scheduleChunkTask(level, chunkX, chunkZ, () -> { -+ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ }, priority); -+ return; -+ } -+ -+ final int minLevel = 33 + ChunkStatus.getDistance(toStatus); -+ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -+ -+ if (addTicket) { -+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -+ } -+ level.chunkSource.runDistanceManagerUpdates(); -+ -+ final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> { -+ try { -+ if (onComplete != null) { -+ onComplete.accept(chunk); -+ } -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr) { -+ LOGGER.error("Exception handling chunk load callback", thr); -+ SneakyThrow.sneaky(thr); -+ } finally { -+ if (addTicket) { -+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); -+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -+ } -+ } -+ }; -+ -+ final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (holder == null || holder.getTicketLevel() > minLevel) { -+ loadCallback.accept(null); -+ return; -+ } -+ -+ final CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> loadFuture = holder.getOrScheduleFuture(toStatus, level.chunkSource.chunkMap); -+ -+ if (loadFuture.isDone()) { -+ loadCallback.accept(loadFuture.join().left().orElse(null)); -+ return; -+ } -+ -+ loadFuture.whenCompleteAsync((final Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { -+ if (thr != null) { -+ loadCallback.accept(null); -+ return; -+ } -+ loadCallback.accept(either.left().orElse(null)); -+ }, (final Runnable r) -> { -+ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -+ }); -+ } -+ -+ public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, -+ final ChunkHolder.FullChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) { -+ if (toStatus == ChunkHolder.FullChunkStatus.INACCESSIBLE) { -+ throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); -+ } -+ -+ if (!Bukkit.isPrimaryThread()) { -+ scheduleChunkTask(level, chunkX, chunkZ, () -> { -+ scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ }, priority); -+ return; -+ } -+ -+ final int minLevel = 33 - (toStatus.ordinal() - 1); -+ final int radius = toStatus.ordinal() - 1; -+ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -+ -+ if (addTicket) { -+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -+ } -+ level.chunkSource.runDistanceManagerUpdates(); -+ -+ final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> { -+ try { -+ if (onComplete != null) { -+ onComplete.accept(chunk); -+ } -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr) { -+ LOGGER.error("Exception handling chunk load callback", thr); -+ SneakyThrow.sneaky(thr); -+ } finally { -+ if (addTicket) { -+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); -+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -+ } -+ } -+ }; -+ -+ final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (holder == null || holder.getTicketLevel() > minLevel) { -+ loadCallback.accept(null); -+ return; -+ } -+ -+ final CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> tickingState; -+ switch (toStatus) { -+ case BORDER: { -+ tickingState = holder.getFullChunkFuture(); -+ break; -+ } -+ case TICKING: { -+ tickingState = holder.getTickingChunkFuture(); -+ break; -+ } -+ case ENTITY_TICKING: { -+ tickingState = holder.getEntityTickingChunkFuture(); -+ break; -+ } -+ default: { -+ throw new IllegalStateException("Cannot reach here"); -+ } -+ } -+ -+ if (tickingState.isDone()) { -+ loadCallback.accept(tickingState.join().left().orElse(null)); -+ return; -+ } -+ -+ tickingState.whenCompleteAsync((final Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { -+ if (thr != null) { -+ loadCallback.accept(null); -+ return; -+ } -+ loadCallback.accept(either.left().orElse(null)); -+ }, (final Runnable r) -> { -+ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -+ }); -+ } -+ -+ public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) { -+ return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); -+ } -+ -+ public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) { -+ return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); -+ } -+ -+ public static int getVisibleChunkHolderCount(final ServerLevel level) { -+ return level.chunkSource.chunkMap.visibleChunkMap.size(); -+ } -+ -+ public static int getUpdatingChunkHolderCount(final ServerLevel level) { -+ return level.chunkSource.chunkMap.updatingChunkMap.size(); -+ } -+ -+ public static boolean hasAnyChunkHolders(final ServerLevel level) { -+ return getUpdatingChunkHolderCount(level) != 0; -+ } -+ -+ public static void onEntityPreAdd(final ServerLevel level, final Entity entity) { -+ -+ } -+ -+ public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) { -+ final ChunkMap chunkMap = level.chunkSource.chunkMap; -+ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) { -+ chunkMap.regionManagers.get(index).addChunk(holder.pos.x, holder.pos.z); -+ } -+ } -+ -+ public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { -+ final ChunkMap chunkMap = level.chunkSource.chunkMap; -+ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) { -+ chunkMap.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z); -+ } -+ } -+ -+ public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.playerChunk = holder; -+ } -+ -+ public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) { -+ -+ } -+ -+ public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().tickingChunks.add(chunk); -+ } -+ -+ public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().tickingChunks.remove(chunk); -+ } -+ -+ public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().entityTickingChunks.add(chunk); -+ } -+ -+ public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().entityTickingChunks.remove(chunk); -+ } -+ -+ public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { -+ return level.chunkSource.chunkMap.getUnloadingChunkHolder(chunkX, chunkZ); -+ } -+ -+ public static int getSendViewDistance(final ServerPlayer player) { -+ return getLoadViewDistance(player); -+ } -+ -+ public static int getLoadViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.getLevel(); -+ if (level == null) { -+ return Bukkit.getViewDistance() + 1; -+ } -+ return level.chunkSource.chunkMap.getEffectiveViewDistance() + 1; -+ } -+ -+ public static int getTickViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.getLevel(); -+ if (level == null) { -+ return Bukkit.getSimulationDistance(); -+ } -+ return level.chunkSource.chunkMap.distanceManager.getSimulationDistance(); -+ } -+ -+ private ChunkSystem() { -+ throw new RuntimeException(); -+ } -+} -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9db975e84609956b2206076e30f17a350adb77d6 ---- /dev/null -+++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -0,0 +1,511 @@ -+package net.minecraft.server; -+ -+import com.google.common.util.concurrent.ThreadFactoryBuilder; -+import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; -+import java.lang.ref.Cleaner; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.Direction; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.ClipContext; -+import net.minecraft.world.level.Level; -+import org.apache.commons.lang.exception.ExceptionUtils; -+import org.bukkit.Location; -+import org.bukkit.block.BlockFace; -+import org.bukkit.craftbukkit.CraftWorld; -+import org.bukkit.craftbukkit.util.Waitable; -+import org.spigotmc.AsyncCatcher; -+ -+import javax.annotation.Nonnull; -+import javax.annotation.Nullable; -+import java.util.List; -+import java.util.Queue; -+import java.util.concurrent.CompletableFuture; -+import java.util.concurrent.ExecutionException; -+import java.util.concurrent.LinkedBlockingQueue; -+import java.util.concurrent.ThreadPoolExecutor; -+import java.util.concurrent.TimeUnit; -+import java.util.concurrent.TimeoutException; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.function.BiConsumer; -+import java.util.function.Consumer; -+import java.util.function.Supplier; -+ -+public final class MCUtil { -+ public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor( -+ 0, 2, 60L, TimeUnit.SECONDS, -+ new LinkedBlockingQueue<>(), -+ new ThreadFactoryBuilder() -+ .setNameFormat("Paper Async Task Handler Thread - %1$d") -+ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) -+ .build() -+ ); -+ public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor( -+ 1, 1, 0L, TimeUnit.SECONDS, -+ new LinkedBlockingQueue<>(), -+ new ThreadFactoryBuilder() -+ .setNameFormat("Paper Object Cleaner") -+ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) -+ .build() -+ ); -+ -+ public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE); -+ -+ -+ public static Runnable once(Runnable run) { -+ AtomicBoolean ran = new AtomicBoolean(false); -+ return () -> { -+ if (ran.compareAndSet(false, true)) { -+ run.run(); -+ } -+ }; -+ } -+ -+ public static <T> Runnable once(List<T> list, Consumer<T> cb) { -+ return once(() -> { -+ list.forEach(cb); -+ }); -+ } -+ -+ private static Runnable makeCleanerCallback(Runnable run) { -+ return once(() -> cleanerExecutor.execute(run)); -+ } -+ -+ /** -+ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky! -+ * @param obj -+ * @param run -+ * @return -+ */ -+ public static Runnable registerCleaner(Object obj, Runnable run) { -+ // Wrap callback in its own method above or the lambda will leak object -+ Runnable cleaner = makeCleanerCallback(run); -+ CleanerHolder.CLEANER.register(obj, cleaner); -+ return cleaner; -+ } -+ -+ private static final class CleanerHolder { -+ private static final Cleaner CLEANER = Cleaner.create(); -+ } -+ -+ /** -+ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky! -+ * @param obj -+ * @param list -+ * @param cleaner -+ * @param <T> -+ * @return -+ */ -+ public static <T> Runnable registerListCleaner(Object obj, List<T> list, Consumer<T> cleaner) { -+ return registerCleaner(obj, () -> { -+ list.forEach(cleaner); -+ list.clear(); -+ }); -+ } -+ -+ /** -+ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky! -+ * @param obj -+ * @param resource -+ * @param cleaner -+ * @param <T> -+ * @return -+ */ -+ public static <T> Runnable registerCleaner(Object obj, T resource, java.util.function.Consumer<T> cleaner) { -+ return registerCleaner(obj, () -> cleaner.accept(resource)); -+ } -+ -+ public static List<ChunkPos> getSpiralOutChunks(BlockPos blockposition, int radius) { -+ List<ChunkPos> list = com.google.common.collect.Lists.newArrayList(); -+ -+ list.add(new ChunkPos(blockposition.getX() >> 4, blockposition.getZ() >> 4)); -+ for (int r = 1; r <= radius; r++) { -+ int x = -r; -+ int z = r; -+ -+ // Iterates the edge of half of the box; then negates for other half. -+ while (x <= r && z > -r) { -+ list.add(new ChunkPos((blockposition.getX() + (x << 4)) >> 4, (blockposition.getZ() + (z << 4)) >> 4)); -+ list.add(new ChunkPos((blockposition.getX() - (x << 4)) >> 4, (blockposition.getZ() - (z << 4)) >> 4)); -+ -+ if (x < r) { -+ x++; -+ } else { -+ z--; -+ } -+ } -+ } -+ return list; -+ } -+ -+ public static int fastFloor(double x) { -+ int truncated = (int)x; -+ return x < (double)truncated ? truncated - 1 : truncated; -+ } -+ -+ public static int fastFloor(float x) { -+ int truncated = (int)x; -+ return x < (double)truncated ? truncated - 1 : truncated; -+ } -+ -+ public static float normalizeYaw(float f) { -+ float f1 = f % 360.0F; -+ -+ if (f1 >= 180.0F) { -+ f1 -= 360.0F; -+ } -+ -+ if (f1 < -180.0F) { -+ f1 += 360.0F; -+ } -+ -+ return f1; -+ } -+ -+ /** -+ * Quickly generate a stack trace for current location -+ * -+ * @return Stacktrace -+ */ -+ public static String stack() { -+ return ExceptionUtils.getFullStackTrace(new Throwable()); -+ } -+ -+ /** -+ * Quickly generate a stack trace for current location with message -+ * -+ * @param str -+ * @return Stacktrace -+ */ -+ public static String stack(String str) { -+ return ExceptionUtils.getFullStackTrace(new Throwable(str)); -+ } -+ -+ public static long getCoordinateKey(final BlockPos blockPos) { -+ return ((long)(blockPos.getZ() >> 4) << 32) | ((blockPos.getX() >> 4) & 0xFFFFFFFFL); -+ } -+ -+ public static long getCoordinateKey(final Entity entity) { -+ return ((long)(MCUtil.fastFloor(entity.getZ()) >> 4) << 32) | ((MCUtil.fastFloor(entity.getX()) >> 4) & 0xFFFFFFFFL); -+ } -+ -+ public static long getCoordinateKey(final ChunkPos pair) { -+ return ((long)pair.z << 32) | (pair.x & 0xFFFFFFFFL); -+ } -+ -+ public static long getCoordinateKey(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public static int getCoordinateX(final long key) { -+ return (int)key; -+ } -+ -+ public static int getCoordinateZ(final long key) { -+ return (int)(key >>> 32); -+ } -+ -+ public static int getChunkCoordinate(final double coordinate) { -+ return MCUtil.fastFloor(coordinate) >> 4; -+ } -+ -+ public static int getBlockCoordinate(final double coordinate) { -+ return MCUtil.fastFloor(coordinate); -+ } -+ -+ public static long getBlockKey(final int x, final int y, final int z) { -+ return ((long)x & 0x7FFFFFF) | (((long)z & 0x7FFFFFF) << 27) | ((long)y << 54); -+ } -+ -+ public static long getBlockKey(final BlockPos pos) { -+ return ((long)pos.getX() & 0x7FFFFFF) | (((long)pos.getZ() & 0x7FFFFFF) << 27) | ((long)pos.getY() << 54); -+ } -+ -+ public static long getBlockKey(final Entity entity) { -+ return getBlockKey(getBlockCoordinate(entity.getX()), getBlockCoordinate(entity.getY()), getBlockCoordinate(entity.getZ())); -+ } -+ -+ // assumes the sets have the same comparator, and if this comparator is null then assume T is Comparable -+ public static <T> void mergeSortedSets(final java.util.function.Consumer<T> consumer, final java.util.Comparator<? super T> comparator, final java.util.SortedSet<T>...sets) { -+ final ObjectRBTreeSet<T> all = new ObjectRBTreeSet<>(comparator); -+ // note: this is done in log(n!) ~ nlogn time. It could be improved if it were to mimic what mergesort does. -+ for (java.util.SortedSet<T> set : sets) { -+ if (set != null) { -+ all.addAll(set); -+ } -+ } -+ all.forEach(consumer); -+ } -+ -+ private MCUtil() {} -+ -+ public static final java.util.concurrent.Executor MAIN_EXECUTOR = (run) -> { -+ if (!isMainThread()) { -+ MinecraftServer.getServer().execute(run); -+ } else { -+ run.run(); -+ } -+ }; -+ -+ public static <T> CompletableFuture<T> ensureMain(CompletableFuture<T> future) { -+ return future.thenApplyAsync(r -> r, MAIN_EXECUTOR); -+ } -+ -+ public static <T> void thenOnMain(CompletableFuture<T> future, Consumer<T> consumer) { -+ future.thenAcceptAsync(consumer, MAIN_EXECUTOR); -+ } -+ public static <T> void thenOnMain(CompletableFuture<T> future, BiConsumer<T, Throwable> consumer) { -+ future.whenCompleteAsync(consumer, MAIN_EXECUTOR); -+ } -+ -+ public static boolean isMainThread() { -+ return MinecraftServer.getServer().isSameThread(); -+ } -+ -+ public static org.bukkit.scheduler.BukkitTask scheduleTask(int ticks, Runnable runnable) { -+ return scheduleTask(ticks, runnable, null); -+ } -+ -+ public static org.bukkit.scheduler.BukkitTask scheduleTask(int ticks, Runnable runnable, String taskName) { -+ return MinecraftServer.getServer().server.getScheduler().scheduleInternalTask(runnable, ticks, taskName); -+ } -+ -+ public static void processQueue() { -+ Runnable runnable; -+ Queue<Runnable> processQueue = getProcessQueue(); -+ while ((runnable = processQueue.poll()) != null) { -+ try { -+ runnable.run(); -+ } catch (Exception e) { -+ MinecraftServer.LOGGER.error("Error executing task", e); -+ } -+ } -+ } -+ public static <T> T processQueueWhileWaiting(CompletableFuture <T> future) { -+ try { -+ if (isMainThread()) { -+ while (!future.isDone()) { -+ try { -+ return future.get(1, TimeUnit.MILLISECONDS); -+ } catch (TimeoutException ignored) { -+ processQueue(); -+ } -+ } -+ } -+ return future.get(); -+ } catch (Exception e) { -+ throw new RuntimeException(e); -+ } -+ } -+ -+ public static void ensureMain(Runnable run) { -+ ensureMain(null, run); -+ } -+ /** -+ * Ensures the target code is running on the main thread -+ * @param reason -+ * @param run -+ * @return -+ */ -+ public static void ensureMain(String reason, Runnable run) { -+ if (!isMainThread()) { -+ if (reason != null) { -+ MinecraftServer.LOGGER.warn("Asynchronous " + reason + "!", new IllegalStateException()); -+ } -+ getProcessQueue().add(run); -+ return; -+ } -+ run.run(); -+ } -+ -+ private static Queue<Runnable> getProcessQueue() { -+ return MinecraftServer.getServer().processQueue; -+ } -+ -+ public static <T> T ensureMain(Supplier<T> run) { -+ return ensureMain(null, run); -+ } -+ /** -+ * Ensures the target code is running on the main thread -+ * @param reason -+ * @param run -+ * @param <T> -+ * @return -+ */ -+ public static <T> T ensureMain(String reason, Supplier<T> run) { -+ if (!isMainThread()) { -+ if (reason != null) { -+ MinecraftServer.LOGGER.warn("Asynchronous " + reason + "! Blocking thread until it returns ", new IllegalStateException()); -+ } -+ Waitable<T> wait = new Waitable<T>() { -+ @Override -+ protected T evaluate() { -+ return run.get(); -+ } -+ }; -+ getProcessQueue().add(wait); -+ try { -+ return wait.get(); -+ } catch (InterruptedException | ExecutionException e) { -+ MinecraftServer.LOGGER.warn("Encountered exception", e); -+ } -+ return null; -+ } -+ return run.get(); -+ } -+ -+ /** -+ * Calculates distance between 2 entities -+ * @param e1 -+ * @param e2 -+ * @return -+ */ -+ public static double distance(Entity e1, Entity e2) { -+ return Math.sqrt(distanceSq(e1, e2)); -+ } -+ -+ -+ /** -+ * Calculates distance between 2 block positions -+ * @param e1 -+ * @param e2 -+ * @return -+ */ -+ public static double distance(BlockPos e1, BlockPos e2) { -+ return Math.sqrt(distanceSq(e1, e2)); -+ } -+ -+ /** -+ * Gets the distance between 2 positions -+ * @param x1 -+ * @param y1 -+ * @param z1 -+ * @param x2 -+ * @param y2 -+ * @param z2 -+ * @return -+ */ -+ public static double distance(double x1, double y1, double z1, double x2, double y2, double z2) { -+ return Math.sqrt(distanceSq(x1, y1, z1, x2, y2, z2)); -+ } -+ -+ /** -+ * Get's the distance squared between 2 entities -+ * @param e1 -+ * @param e2 -+ * @return -+ */ -+ public static double distanceSq(Entity e1, Entity e2) { -+ return distanceSq(e1.getX(),e1.getY(),e1.getZ(), e2.getX(),e2.getY(),e2.getZ()); -+ } -+ -+ /** -+ * Gets the distance sqaured between 2 block positions -+ * @param pos1 -+ * @param pos2 -+ * @return -+ */ -+ public static double distanceSq(BlockPos pos1, BlockPos pos2) { -+ return distanceSq(pos1.getX(), pos1.getY(), pos1.getZ(), pos2.getX(), pos2.getY(), pos2.getZ()); -+ } -+ -+ /** -+ * Gets the distance squared between 2 positions -+ * @param x1 -+ * @param y1 -+ * @param z1 -+ * @param x2 -+ * @param y2 -+ * @param z2 -+ * @return -+ */ -+ public static double distanceSq(double x1, double y1, double z1, double x2, double y2, double z2) { -+ return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2); -+ } -+ -+ /** -+ * Converts a NMS World/BlockPosition to Bukkit Location -+ * @param world -+ * @param x -+ * @param y -+ * @param z -+ * @return -+ */ -+ public static Location toLocation(Level world, double x, double y, double z) { -+ return new Location(world.getWorld(), x, y, z); -+ } -+ -+ /** -+ * Converts a NMS World/BlockPosition to Bukkit Location -+ * @param world -+ * @param pos -+ * @return -+ */ -+ public static Location toLocation(Level world, BlockPos pos) { -+ return new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); -+ } -+ -+ /** -+ * Converts an NMS entity's current location to a Bukkit Location -+ * @param entity -+ * @return -+ */ -+ public static Location toLocation(Entity entity) { -+ return new Location(entity.getCommandSenderWorld().getWorld(), entity.getX(), entity.getY(), entity.getZ()); -+ } -+ -+ public static org.bukkit.block.Block toBukkitBlock(Level world, BlockPos pos) { -+ return world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ } -+ -+ public static BlockPos toBlockPosition(Location loc) { -+ return new BlockPos(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); -+ } -+ -+ public static boolean isEdgeOfChunk(BlockPos pos) { -+ final int modX = pos.getX() & 15; -+ final int modZ = pos.getZ() & 15; -+ return (modX == 0 || modX == 15 || modZ == 0 || modZ == 15); -+ } -+ -+ /** -+ * Posts a task to be executed asynchronously -+ * @param run -+ */ -+ public static void scheduleAsyncTask(Runnable run) { -+ asyncExecutor.execute(run); -+ } -+ -+ @Nonnull -+ public static ServerLevel getNMSWorld(@Nonnull org.bukkit.World world) { -+ return ((CraftWorld) world).getHandle(); -+ } -+ -+ public static ServerLevel getNMSWorld(@Nonnull org.bukkit.entity.Entity entity) { -+ return getNMSWorld(entity.getWorld()); -+ } -+ -+ public static BlockFace toBukkitBlockFace(Direction enumDirection) { -+ switch (enumDirection) { -+ case DOWN: -+ return BlockFace.DOWN; -+ case UP: -+ return BlockFace.UP; -+ case NORTH: -+ return BlockFace.NORTH; -+ case SOUTH: -+ return BlockFace.SOUTH; -+ case WEST: -+ return BlockFace.WEST; -+ case EAST: -+ return BlockFace.EAST; -+ default: -+ return null; -+ } -+ } -+ -+ public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) { -+ return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status); -+ } -+} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 80a3c56fb5e73c09c542b17aac952fb63081a662..805a1773d55e2551911e5b8e69052e23f630359b 100644 +index 80a3c56fb5e73c09c542b17aac952fb63081a662..d7ece1ae4e9c97935de96eafd6d22cded1f8aa42 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -282,6 +282,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -5506,8 +5507,8 @@ index 80a3c56fb5e73c09c542b17aac952fb63081a662..805a1773d55e2551911e5b8e69052e23 MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1); } // Spigot start -+ MCUtil.asyncExecutor.shutdown(); // Paper -+ try { MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper ++ io.papermc.paper.util.MCUtil.asyncExecutor.shutdown(); // Paper ++ try { io.papermc.paper.util.MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper + } catch (java.lang.InterruptedException ignored) {} // Paper if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { MinecraftServer.LOGGER.info("Saving usercache.json"); @@ -5542,7 +5543,7 @@ index 80a3c56fb5e73c09c542b17aac952fb63081a662..805a1773d55e2551911e5b8e69052e23 } catch (Throwable throwable) { // Spigot Start diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c9a0115d8 100644 +index f902b1f7062fc2c81e0ce43e8b8599192469e57c..74d1ae0104e8d0795df50f00317fd860de4f112e 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -52,9 +52,9 @@ public class ChunkHolder { @@ -5693,7 +5694,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c + if (left.isPresent() && ChunkHolder.this.fullChunkCreateCount == expectCreateCount) { + LevelChunk fullChunk = either.left().get(); + ChunkHolder.this.isFullChunkReady = true; -+ net.minecraft.server.ChunkSystem.onChunkBorder(fullChunk, this); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(fullChunk, this); + } + }); this.updateChunkToSave(this.fullChunkFuture, "full"); @@ -5702,7 +5703,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c if (flag2 && !flag3) { + // Paper start + if (this.isFullChunkReady) { -+ net.minecraft.server.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().left().get(), this); // Paper ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().left().get(), this); // Paper + } + // Paper end this.fullChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); @@ -5721,7 +5722,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c + either.ifLeft(chunk -> { + // note: Here is a very good place to add callbacks to logic waiting on this. + ChunkHolder.this.isTickingReady = true; -+ net.minecraft.server.ChunkSystem.onChunkTicking(chunk, this); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(chunk, this); + }); + }); + // Paper end @@ -5732,7 +5733,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c - this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); + // Paper start + if (this.isTickingReady) { -+ net.minecraft.server.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().left().get(), this); // Paper ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().left().get(), this); // Paper + } + // Paper end + this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage @@ -5747,7 +5748,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c + this.entityTickingChunkFuture.thenAccept(either -> { + either.ifLeft(chunk -> { + ChunkHolder.this.isEntityTickingReady = true; -+ net.minecraft.server.ChunkSystem.onChunkEntityTicking(chunk, this); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(chunk, this); + }); + }); + // Paper end @@ -5758,7 +5759,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c - this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); + // Paper start + if (this.isEntityTickingReady) { -+ net.minecraft.server.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().left().get(), this); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().left().get(), this); + } + // Paper end + this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage @@ -5785,14 +5786,14 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c + // Paper end } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70a8650f25 100644 +index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..5095519f9bd009a4d5af49d5b42c5795114411a2 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -63,6 +63,7 @@ import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket; import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; import net.minecraft.network.protocol.game.DebugPackets; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.network.ServerPlayerConnection; import net.minecraft.util.CsvOutput; @@ -5884,10 +5885,10 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 stringbuilder.append("Updating:").append(System.lineSeparator()); - this.updatingChunkMap.values().forEach(consumer); -+ net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).forEach(consumer); // Paper ++ io.papermc.paper.chunk.system.ChunkSystem.getUpdatingChunkHolders(this.level).forEach(consumer); // Paper stringbuilder.append("Visible:").append(System.lineSeparator()); - this.visibleChunkMap.values().forEach(consumer); -+ net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).forEach(consumer); // Paper ++ io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(consumer); // Paper CrashReport crashreport = CrashReport.forThrowable(exception, "Chunk loading"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk loading"); @@ -5896,7 +5897,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 } else { holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this); + // Paper start -+ net.minecraft.server.ChunkSystem.onChunkHolderCreate(this.level, holder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderCreate(this.level, holder); + // Paper end } @@ -5911,7 +5912,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 protected void saveAllChunks(boolean flush) { if (flush) { - List<ChunkHolder> list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); -+ List<ChunkHolder> list = (List) net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper ++ List<ChunkHolder> list = (List) io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper MutableBoolean mutableboolean = new MutableBoolean(); do { @@ -5920,7 +5921,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 this.flushWorker(); } else { - this.visibleChunkMap.values().forEach(this::saveChunkIfNeeded); -+ net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); ++ io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); } } @@ -5929,7 +5930,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 public boolean hasWork() { - return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); -+ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || net.minecraft.server.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper ++ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || io.papermc.paper.chunk.system.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper } private void processUnloads(BooleanSupplier shouldKeepTicking) { @@ -5946,7 +5947,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 int l = 0; - ObjectIterator objectiterator = this.visibleChunkMap.values().iterator(); -+ Iterator objectiterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper ++ Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { @@ -5958,7 +5959,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 + // Paper start + boolean removed; + if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -+ net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); + // Paper end if (ichunkaccess instanceof LevelChunk) { ((LevelChunk) ichunkaccess).setLoaded(false); @@ -5969,7 +5970,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong()); - } + } else if (removed) { // Paper start -+ net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); + } // Paper end } @@ -5979,7 +5980,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 this.viewDistance = j; this.distanceManager.updatePlayerTickets(this.viewDistance + 1); - ObjectIterator objectiterator = this.updatingChunkMap.values().iterator(); -+ Iterator objectiterator = net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper ++ Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper while (objectiterator.hasNext()) { ChunkHolder playerchunk = (ChunkHolder) objectiterator.next(); @@ -5988,7 +5989,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 public int size() { - return this.visibleChunkMap.size(); -+ return net.minecraft.server.ChunkSystem.getVisibleChunkHolderCount(this.level); // Paper ++ return io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolderCount(this.level); // Paper } public DistanceManager getDistanceManager() { @@ -5997,14 +5998,14 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70 protected Iterable<ChunkHolder> getChunks() { - return Iterables.unmodifiableIterable(this.visibleChunkMap.values()); -+ return Iterables.unmodifiableIterable(net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level)); // Paper ++ return Iterables.unmodifiableIterable(io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level)); // Paper } void dumpChunks(Writer writer) throws IOException { CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer); TickingTracker tickingtracker = this.distanceManager.tickingTracker(); - ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator(); -+ Iterator<ChunkHolder> objectbidirectionaliterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper ++ Iterator<ChunkHolder> objectbidirectionaliterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper while (objectbidirectionaliterator.hasNext()) { - Entry<ChunkHolder> entry = (Entry) objectbidirectionaliterator.next(); @@ -6097,7 +6098,7 @@ index 6c98676827ceb6999f340fa2b06a0b3e1cb4cae2..fbe62a31ab199d83a1db0a4e0b1a8138 while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index ce88976db29b9e9524dbe45b16721ef90afb692b..1a8c5ce3ecce9cbbc8496ea3882b18c297964e33 100644 +index ce88976db29b9e9524dbe45b16721ef90afb692b..359de6697ec69f68fe79a691c7306d4c0e42fd58 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -50,6 +50,7 @@ import net.minecraft.world.level.storage.LevelStorageSource; @@ -6186,21 +6187,21 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..1a8c5ce3ecce9cbbc8496ea3882b18c2 + long chunkFutureAwaitCounter; // Paper - private -> package private + + public void getEntityTickingChunkAsync(int x, int z, java.util.function.Consumer<LevelChunk> onLoad) { -+ net.minecraft.server.ChunkSystem.scheduleTickingState( ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleTickingState( + this.level, x, z, ChunkHolder.FullChunkStatus.ENTITY_TICKING, true, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad + ); + } + + public void getTickingChunkAsync(int x, int z, java.util.function.Consumer<LevelChunk> onLoad) { -+ net.minecraft.server.ChunkSystem.scheduleTickingState( ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleTickingState( + this.level, x, z, ChunkHolder.FullChunkStatus.TICKING, true, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad + ); + } + + public void getFullChunkAsync(int x, int z, java.util.function.Consumer<LevelChunk> onLoad) { -+ net.minecraft.server.ChunkSystem.scheduleTickingState( ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleTickingState( + this.level, x, z, ChunkHolder.FullChunkStatus.BORDER, true, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad + ); @@ -6224,7 +6225,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..1a8c5ce3ecce9cbbc8496ea3882b18c2 + return; + } + -+ net.minecraft.server.ChunkSystem.scheduleChunkLoad( ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad( + this.level, chunkX, chunkZ, ChunkHolder.getStatus(ticketLevel), true, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, consumer + ); @@ -6261,7 +6262,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..1a8c5ce3ecce9cbbc8496ea3882b18c2 + return; + } + -+ this.getChunkAtAsynchronously(chunkX, chunkZ, net.minecraft.server.MCUtil.getTicketLevelFor(ChunkStatus.EMPTY), (ChunkAccess chunk) -> { ++ this.getChunkAtAsynchronously(chunkX, chunkZ, io.papermc.paper.util.MCUtil.getTicketLevelFor(ChunkStatus.EMPTY), (ChunkAccess chunk) -> { + if (chunk == null) { + throw new IllegalStateException("Chunk cannot be null"); + } @@ -6404,7 +6405,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..1a8c5ce3ecce9cbbc8496ea3882b18c2 ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index aa396df025115c7fd866cbc63a44c2c17abfde84..b2f79a0c9caa6783816afc36531c94378e832cb7 100644 +index aa396df025115c7fd866cbc63a44c2c17abfde84..6e2cd39d4ca7466bbb480d0d9331f644ccda62cd 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -168,6 +168,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -6503,7 +6504,7 @@ index aa396df025115c7fd866cbc63a44c2c17abfde84..b2f79a0c9caa6783816afc36531c9437 + + for (int cx = minChunkX; cx <= maxChunkX; ++cx) { + for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { -+ net.minecraft.server.ChunkSystem.scheduleChunkLoad( ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad( + this, cx, cz, net.minecraft.world.level.chunk.ChunkStatus.FULL, true, priority, consumer + ); + } @@ -7265,7 +7266,7 @@ index 9668a960dbd3b4ff3c0635df2fb7cc1af289d235..603111a52346f678aba0fd66b010d8f3 public BlockState getBlockState(BlockPos pos) { int i = pos.getY(); diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -index dfd1afc57664dd18c11f8a2547616074ccc55690..ab7eadf2fc4c4598fa89068332eaaf9a8e0a100f 100644 +index dfd1afc57664dd18c11f8a2547616074ccc55690..21e1d86bd287c5e90db43c9c0247d6b7ee1425ae 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java @@ -90,6 +90,18 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A @@ -7277,7 +7278,7 @@ index dfd1afc57664dd18c11f8a2547616074ccc55690..ab7eadf2fc4c4598fa89068332eaaf9a + // I don't want to know why this is a generic type. + Entity entityCasted = (Entity)entity; + boolean wasRemoved = entityCasted.isRemoved(); -+ net.minecraft.server.ChunkSystem.onEntityPreAdd((net.minecraft.server.level.ServerLevel)entityCasted.level, entityCasted); ++ io.papermc.paper.chunk.system.ChunkSystem.onEntityPreAdd((net.minecraft.server.level.ServerLevel)entityCasted.level, entityCasted); + if (!wasRemoved && entityCasted.isRemoved()) { + // removed by callback + return false; @@ -7288,7 +7289,7 @@ index dfd1afc57664dd18c11f8a2547616074ccc55690..ab7eadf2fc4c4598fa89068332eaaf9a return false; } else { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..6d9469d577dcbb9d5b5b703cf47c8863e0b43b13 100644 +index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..452bd97c699261623bf504ee3a177f8f4df97d11 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -234,8 +234,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -7297,7 +7298,7 @@ index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..6d9469d577dcbb9d5b5b703cf47c8863 public Chunk[] getLoadedChunks() { - Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = this.world.getChunkSource().chunkMap.visibleChunkMap; - return chunks.values().stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new); -+ List<ChunkHolder> chunks = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.world); // Paper ++ List<ChunkHolder> chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world); // Paper + return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new); } @@ -7333,7 +7334,7 @@ index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..6d9469d577dcbb9d5b5b703cf47c8863 + + java.util.concurrent.CompletableFuture<Chunk> ret = new java.util.concurrent.CompletableFuture<>(); + -+ net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { + net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { + net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; + ret.complete(chunk == null ? null : chunk.getBukkitChunk()); diff --git a/patches/server/0014-Starlight.patch b/patches/server/0014-Starlight.patch index c9ef4a631b..b0b2e367cc 100644 --- a/patches/server/0014-Starlight.patch +++ b/patches/server/0014-Starlight.patch @@ -4348,7 +4348,7 @@ index b3a58bf4b654e336826dc04da9e2f80ff8b9a9a7..c9a2ac696f7cefc8b0715f53db3fc541 .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) diff --git a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..450bd95218852174cfbc88d4517e17daee5ffd5f +index 0000000000000000000000000000000000000000..7784d72ddd6db00c674e22759c00c430222c4b85 --- /dev/null +++ b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java @@ -0,0 +1,115 @@ @@ -4357,7 +4357,7 @@ index 0000000000000000000000000000000000000000..450bd95218852174cfbc88d4517e17da +import io.papermc.paper.command.PaperSubcommand; +import java.util.ArrayDeque; +import java.util.Deque; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerLevel; @@ -4468,7 +4468,7 @@ index 0000000000000000000000000000000000000000..450bd95218852174cfbc88d4517e17da + } +} diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 0873134f1f6de0c372ba28b89a20302c9a0115d8..86c33f029ae56fcace51b69763202be9f8bc5f44 100644 +index fa800bb4fbbd553ca2a70ba9717546f1415bfc0e..27e1880c4b74a36391f66b1126a92a8b7789c069 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -55,7 +55,7 @@ public class ChunkHolder { @@ -4481,7 +4481,7 @@ index 0873134f1f6de0c372ba28b89a20302c9a0115d8..86c33f029ae56fcace51b69763202be9 private final DebugBuffer<ChunkHolder.ChunkSaveDebug> chunkToSaveHistory; public int oldTicketLevel; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 2a9e5fb8164f79b0f9c1cb5497216e51f9df3454..cbd4e749574c55c6e52f42b62dd6da8cfcca97f9 100644 +index 47a07a372f1e160c0da2c3e8d59ec42166edaf8b..4850ca166a664e2f4b2f28188f72b18812c302f0 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -128,7 +128,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -4507,7 +4507,7 @@ index fbe62a31ab199d83a1db0a4e0b1a813824e6f2c2..d38ad1b1eee92a6dbd2b79b4fcdb8959 while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 5b238e41ffa3e374b52ee955cb39087571c6ffc2..3fb8d2626a1ef097c05fa5810bc1e051b4a6ad44 100644 +index 5b238e41ffa3e374b52ee955cb39087571c6ffc2..275b7f7dd36a2073a3eb9f89f4c832839e5aa9af 100644 --- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java +++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java @@ -23,6 +23,17 @@ import net.minecraft.world.level.chunk.LightChunkGetter; @@ -4581,7 +4581,7 @@ index 5b238e41ffa3e374b52ee955cb39087571c6ffc2..3fb8d2626a1ef097c05fa5810bc1e051 + + final Long id = Long.valueOf(this.relightCounter++); + -+ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().addTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, net.minecraft.server.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), id); ++ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().addTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, io.papermc.paper.util.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), id); + ticketIds.put(chunkPos, id); + + ++totalChunks; @@ -4592,7 +4592,7 @@ index 5b238e41ffa3e374b52ee955cb39087571c6ffc2..3fb8d2626a1ef097c05fa5810bc1e051 + chunkLightCallback.accept(chunkPos); + ((java.util.concurrent.Executor)((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().mainThreadProcessor).execute(() -> { + ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().chunkMap.getUpdatingChunkIfPresent(chunkPos.toLong()).broadcast(new net.minecraft.network.protocol.game.ClientboundLightUpdatePacket(chunkPos, ThreadedLevelLightEngine.this, null, null, true), false); -+ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().removeTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, net.minecraft.server.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), ticketIds.get(chunkPos)); ++ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().removeTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, io.papermc.paper.util.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), ticketIds.get(chunkPos)); + }); + }, onComplete); + }); diff --git a/patches/server/0016-Rewrite-chunk-system.patch b/patches/server/0016-Rewrite-chunk-system.patch index 74a4470d3a..7e3c8d8b1a 100644 --- a/patches/server/0016-Rewrite-chunk-system.patch +++ b/patches/server/0016-Rewrite-chunk-system.patch @@ -1303,7 +1303,7 @@ index 0000000000000000000000000000000000000000..99f49b5625cf51d6c97640553cf5c420 +} diff --git a/src/main/java/io/papermc/paper/chunk/PlayerChunkLoader.java b/src/main/java/io/papermc/paper/chunk/PlayerChunkLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..dd501e83d991e45598509134fab05bafc1904953 +index 0000000000000000000000000000000000000000..0b060183429f4c72ec767075538477b4302bbf0d --- /dev/null +++ b/src/main/java/io/papermc/paper/chunk/PlayerChunkLoader.java @@ -0,0 +1,1128 @@ @@ -1322,7 +1322,7 @@ index 0000000000000000000000000000000000000000..dd501e83d991e45598509134fab05baf +import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket; +import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; +import net.minecraft.network.protocol.game.ClientboundSetSimulationDistancePacket; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.*; +import net.minecraft.util.Mth; @@ -2435,9 +2435,241 @@ index 0000000000000000000000000000000000000000..dd501e83d991e45598509134fab05baf + } + } +} +diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +index 8a5e93961dac4d87c81c0e70b6f4124a1f1d2556..0dc94dec1317b3f86d38074c6cbe41ab828cab1d 100644 +--- a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java ++++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +@@ -31,191 +31,41 @@ public final class ChunkSystem { + } + + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { +- level.chunkSource.mainThreadProcessor.execute(run); ++ level.chunkTaskScheduler.scheduleChunkTask(chunkX, chunkZ, run, priority); // Paper - rewrite chunk system + } + + public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, + final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, + final Consumer<ChunkAccess> onComplete) { +- if (gen) { +- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- return; +- } +- scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { +- if (chunk == null) { +- onComplete.accept(null); +- } else { +- if (chunk.getStatus().isOrAfter(toStatus)) { +- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- } else { +- onComplete.accept(null); +- } +- } +- }); ++ level.chunkTaskScheduler.scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system + } + +- static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); +- +- private static long chunkLoadCounter = 0L; ++ // Paper - rewrite chunk system + public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, + final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) { +- if (!Bukkit.isPrimaryThread()) { +- scheduleChunkTask(level, chunkX, chunkZ, () -> { +- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- }, priority); +- return; +- } +- +- final int minLevel = 33 + ChunkStatus.getDistance(toStatus); +- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; +- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); +- +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- level.chunkSource.runDistanceManagerUpdates(); +- +- final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> { +- try { +- if (onComplete != null) { +- onComplete.accept(chunk); +- } +- } catch (final ThreadDeath death) { +- throw death; +- } catch (final Throwable thr) { +- LOGGER.error("Exception handling chunk load callback", thr); +- SneakyThrow.sneaky(thr); +- } finally { +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); +- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- } +- }; +- +- final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (holder == null || holder.getTicketLevel() > minLevel) { +- loadCallback.accept(null); +- return; +- } +- +- final CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> loadFuture = holder.getOrScheduleFuture(toStatus, level.chunkSource.chunkMap); +- +- if (loadFuture.isDone()) { +- loadCallback.accept(loadFuture.join().left().orElse(null)); +- return; +- } +- +- loadFuture.whenCompleteAsync((final Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { +- if (thr != null) { +- loadCallback.accept(null); +- return; +- } +- loadCallback.accept(either.left().orElse(null)); +- }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); +- }); ++ level.chunkTaskScheduler.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system + } + + public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, + final ChunkHolder.FullChunkStatus toStatus, final boolean addTicket, + final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) { +- if (toStatus == ChunkHolder.FullChunkStatus.INACCESSIBLE) { +- throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); +- } +- +- if (!Bukkit.isPrimaryThread()) { +- scheduleChunkTask(level, chunkX, chunkZ, () -> { +- scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- }, priority); +- return; +- } +- +- final int minLevel = 33 - (toStatus.ordinal() - 1); +- final int radius = toStatus.ordinal() - 1; +- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; +- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); +- +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- level.chunkSource.runDistanceManagerUpdates(); +- +- final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> { +- try { +- if (onComplete != null) { +- onComplete.accept(chunk); +- } +- } catch (final ThreadDeath death) { +- throw death; +- } catch (final Throwable thr) { +- LOGGER.error("Exception handling chunk load callback", thr); +- SneakyThrow.sneaky(thr); +- } finally { +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); +- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- } +- }; +- +- final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (holder == null || holder.getTicketLevel() > minLevel) { +- loadCallback.accept(null); +- return; +- } +- +- final CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> tickingState; +- switch (toStatus) { +- case BORDER: { +- tickingState = holder.getFullChunkFuture(); +- break; +- } +- case TICKING: { +- tickingState = holder.getTickingChunkFuture(); +- break; +- } +- case ENTITY_TICKING: { +- tickingState = holder.getEntityTickingChunkFuture(); +- break; +- } +- default: { +- throw new IllegalStateException("Cannot reach here"); +- } +- } +- +- if (tickingState.isDone()) { +- loadCallback.accept(tickingState.join().left().orElse(null)); +- return; +- } +- +- tickingState.whenCompleteAsync((final Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { +- if (thr != null) { +- loadCallback.accept(null); +- return; +- } +- loadCallback.accept(either.left().orElse(null)); +- }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); +- }); ++ level.chunkTaskScheduler.scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system + } + + public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) { +- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); ++ return level.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders(); // Paper - rewrite chunk system + } + + public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) { +- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); ++ return level.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders(); // Paper - rewrite chunk system + } + + public static int getVisibleChunkHolderCount(final ServerLevel level) { +- return level.chunkSource.chunkMap.visibleChunkMap.size(); ++ return level.chunkTaskScheduler.chunkHolderManager.size(); // Paper - rewrite chunk system + } + + public static int getUpdatingChunkHolderCount(final ServerLevel level) { +- return level.chunkSource.chunkMap.updatingChunkMap.size(); ++ return level.chunkTaskScheduler.chunkHolderManager.size(); // Paper - rewrite chunk system + } + + public static boolean hasAnyChunkHolders(final ServerLevel level) { +@@ -269,23 +119,15 @@ public final class ChunkSystem { + } + + public static int getSendViewDistance(final ServerPlayer player) { +- return getLoadViewDistance(player); ++ return io.papermc.paper.chunk.PlayerChunkLoader.getSendViewDistance(player); + } + + public static int getLoadViewDistance(final ServerPlayer player) { +- final ServerLevel level = player.getLevel(); +- if (level == null) { +- return Bukkit.getViewDistance() + 1; +- } +- return level.chunkSource.chunkMap.getEffectiveViewDistance() + 1; ++ return io.papermc.paper.chunk.PlayerChunkLoader.getLoadViewDistance(player); + } + + public static int getTickViewDistance(final ServerPlayer player) { +- final ServerLevel level = player.getLevel(); +- if (level == null) { +- return Bukkit.getSimulationDistance(); +- } +- return level.chunkSource.chunkMap.distanceManager.getSimulationDistance(); ++ return io.papermc.paper.chunk.PlayerChunkLoader.getTickViewDistance(player); + } + + private ChunkSystem() { diff --git a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..7d37b2b02dd64acdac7e5981bebcf988e2f5a7c1 +index 0000000000000000000000000000000000000000..c37adf64ad6133a8d79bfad4a852a6a7e284b6d3 --- /dev/null +++ b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java @@ -0,0 +1,839 @@ @@ -2453,7 +2685,7 @@ index 0000000000000000000000000000000000000000..7d37b2b02dd64acdac7e5981bebcf988 +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import net.minecraft.core.BlockPos; -+import net.minecraft.server.ChunkSystem; ++import io.papermc.paper.chunk.system.ChunkSystem; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerLevel; @@ -5248,7 +5480,7 @@ index 0000000000000000000000000000000000000000..fb42d776f15f735fb59e972e00e2b512 +} diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..d220507e1a432883d3092720e3634e8d1d961dbe +index 0000000000000000000000000000000000000000..7a513a6fd8caa61e0444b38daa0ff20d9475220e --- /dev/null +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java @@ -0,0 +1,1190 @@ @@ -5277,7 +5509,7 @@ index 0000000000000000000000000000000000000000..d220507e1a432883d3092720e3634e8d +import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; +import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; +import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.ChunkSystem; ++import io.papermc.paper.chunk.system.ChunkSystem; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; @@ -7247,7 +7479,7 @@ index 0000000000000000000000000000000000000000..322675a470eacbf0e5452f4009c643f2 +} diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java new file mode 100644 -index 0000000000000000000000000000000000000000..c43c62fb22a26e4e3f5df4001f1b3e65d3833833 +index 0000000000000000000000000000000000000000..84cc9397237fa0c17aa1012dfb5683c90eb6d3b8 --- /dev/null +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java @@ -0,0 +1,780 @@ @@ -7264,7 +7496,7 @@ index 0000000000000000000000000000000000000000..c43c62fb22a26e4e3f5df4001f1b3e65 +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.ReportedException; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; @@ -11321,7 +11553,7 @@ index c9a2ac696f7cefc8b0715f53db3fc541f26b62f6..1e9105cf5ab2ff0ee847fafd00b41e1b .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) 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..628c549b1436c3de75071ecd6182a9beadd4840b +index 0000000000000000000000000000000000000000..a6fb7ae77d7cad2243e28a33718e4631f65697fa --- /dev/null +++ b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java @@ -0,0 +1,264 @@ @@ -11336,7 +11568,7 @@ index 0000000000000000000000000000000000000000..628c549b1436c3de75071ecd6182a9be +import java.util.Collections; +import java.util.List; +import java.util.Locale; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerLevel; @@ -11432,7 +11664,7 @@ index 0000000000000000000000000000000000000000..628c549b1436c3de75071ecd6182a9be + int ticking = 0; + int entityTicking = 0; + -+ for (final ChunkHolder chunk : net.minecraft.server.ChunkSystem.getVisibleChunkHolders(world)) { ++ for (final ChunkHolder chunk : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(world)) { + if (chunk.getFullChunkNowUnchecked() == null) { + continue; + } @@ -11589,6 +11821,153 @@ index 0000000000000000000000000000000000000000..628c549b1436c3de75071ecd6182a9be + } + +} +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index 9798a1010120125039cbf226a0e3679cc92f92c7..3a0e4934af1f1c711e55ed6f439241364b7448f4 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -1,16 +1,29 @@ + package io.papermc.paper.util; + + import com.google.common.util.concurrent.ThreadFactoryBuilder; ++import com.google.gson.JsonArray; ++import com.google.gson.JsonObject; ++import com.google.gson.internal.Streams; ++import com.google.gson.stream.JsonWriter; ++import com.mojang.datafixers.util.Either; + import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; + import java.lang.ref.Cleaner; ++import it.unimi.dsi.fastutil.objects.ReferenceArrayList; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.ChunkMap; ++import net.minecraft.server.level.DistanceManager; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.server.level.Ticket; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.level.ChunkPos; + import net.minecraft.world.level.ClipContext; + import net.minecraft.world.level.Level; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.ChunkStatus; + import org.apache.commons.lang.exception.ExceptionUtils; + import org.bukkit.Location; + import org.bukkit.block.BlockFace; +@@ -20,8 +33,11 @@ import org.spigotmc.AsyncCatcher; + + import javax.annotation.Nonnull; + import javax.annotation.Nullable; ++import java.io.*; ++import java.nio.charset.StandardCharsets; + import java.util.List; + import java.util.Queue; ++import java.util.Set; + import java.util.concurrent.CompletableFuture; + import java.util.concurrent.ExecutionException; + import java.util.concurrent.LinkedBlockingQueue; +@@ -506,6 +522,100 @@ public final class MCUtil { + } + } + ++ public static ChunkStatus getChunkStatus(ChunkHolder chunk) { ++ return chunk.getChunkHolderStatus(); ++ } ++ ++ public static void dumpChunks(File file, boolean watchdog) throws IOException { ++ file.getParentFile().mkdirs(); ++ file.createNewFile(); ++ ReferenceArrayList<org.bukkit.World> worlds = new ReferenceArrayList<>(org.bukkit.Bukkit.getWorlds()); ++ ReferenceArrayList<org.bukkit.World> loadedWorlds = new ReferenceArrayList<>(worlds); ++ JsonObject data = new JsonObject(); ++ ++ data.addProperty("server-version", org.bukkit.Bukkit.getVersion()); ++ data.addProperty("data-version", 1); ++ ++ { ++ JsonArray players = new JsonArray(); ++ data.add("all-players", players); ++ List<ServerPlayer> playerList = MinecraftServer.getServer().getPlayerList().players; ++ for (ServerPlayer player : playerList) { ++ JsonObject playerData = new JsonObject(); ++ players.add(playerData); ++ ++ Level playerWorld = player.getLevel(); ++ org.bukkit.World craftWorld = playerWorld.getWorld(); ++ Entity.RemovalReason removalReason = player.getRemovalReason(); ++ ++ playerData.addProperty("name", player.getScoreboardName()); ++ playerData.addProperty("x", player.getX()); ++ playerData.addProperty("y", player.getY()); ++ playerData.addProperty("z", player.getZ()); ++ playerData.addProperty("world", playerWorld == null ? "null world" : craftWorld.getName()); ++ playerData.addProperty("removalReason", removalReason == null ? "null" : removalReason.name()); ++ ++ if (!worlds.contains(craftWorld)) { ++ worlds.add(craftWorld); ++ } ++ } ++ } ++ ++ JsonArray chunkWaitInformation = new JsonArray(); ++ data.add("chunk-wait-infos", chunkWaitInformation); ++ ++ for (io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.ChunkInfo chunkInfo : io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.getChunkInfos()) { ++ chunkWaitInformation.add(chunkInfo.toString()); ++ } ++ ++ JsonArray worldsData = new JsonArray(); ++ ++ for (org.bukkit.World bukkitWorld : worlds) { ++ JsonObject worldData = new JsonObject(); ++ ++ ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle(); ++ List<ServerPlayer> players = world.players; ++ ++ worldData.addProperty("is-loaded", loadedWorlds.contains(bukkitWorld)); ++ worldData.addProperty("name", world.getWorld().getName()); ++ worldData.addProperty("view-distance", world.getChunkSource().chunkMap.playerChunkManager.getTargetNoTickViewDistance()); // Paper - replace chunk loader system ++ worldData.addProperty("tick-view-distance", world.getChunkSource().chunkMap.playerChunkManager.getTargetTickViewDistance()); // Paper - replace chunk loader system ++ worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory); ++ worldData.addProperty("keep-spawn-loaded-range", world.paperConfig().spawn.keepSpawnLoadedRange * 16); ++ ++ JsonArray playersData = new JsonArray(); ++ ++ for (ServerPlayer player : players) { ++ JsonObject playerData = new JsonObject(); ++ ++ playerData.addProperty("name", player.getScoreboardName()); ++ playerData.addProperty("x", player.getX()); ++ playerData.addProperty("y", player.getY()); ++ playerData.addProperty("z", player.getZ()); ++ ++ playersData.add(playerData); ++ } ++ ++ worldData.add("players", playersData); ++ worldData.add("chunk-data", watchdog ? world.chunkTaskScheduler.chunkHolderManager.getDebugJsonForWatchdog() : world.chunkTaskScheduler.chunkHolderManager.getDebugJson()); ++ worldsData.add(worldData); ++ } ++ ++ data.add("worlds", worldsData); ++ ++ StringWriter stringWriter = new StringWriter(); ++ JsonWriter jsonWriter = new JsonWriter(stringWriter); ++ jsonWriter.setIndent(" "); ++ jsonWriter.setLenient(false); ++ Streams.write(data, jsonWriter); ++ ++ String fileData = stringWriter.toString(); ++ ++ try (PrintStream out = new PrintStream(new FileOutputStream(file), false, StandardCharsets.UTF_8)) { ++ out.print(fileData); ++ } ++ } ++ + public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) { + return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status); + } diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java index d59885ee9c8b29d5bac34dce0597e345e5358c77..fc57850b80303fcade89ca95794f63910404a407 100644 --- a/src/main/java/io/papermc/paper/util/TickThread.java @@ -12316,384 +12695,6 @@ index a5e438a834826161c52ca9db57d234d9ff80a591..b8bc1b9b8e8a33df90a963f9f9769292 } @Override -diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java -index c59fca05484c30b28e883f5b5dde0362f294b517..0c6534e64ef023cf613f2c5407c7598c6ed81bc6 100644 ---- a/src/main/java/net/minecraft/server/ChunkSystem.java -+++ b/src/main/java/net/minecraft/server/ChunkSystem.java -@@ -31,191 +31,41 @@ public final class ChunkSystem { - } - - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { -- level.chunkSource.mainThreadProcessor.execute(run); -+ level.chunkTaskScheduler.scheduleChunkTask(chunkX, chunkZ, run, priority); // Paper - rewrite chunk system - } - - public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, - final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, - final Consumer<ChunkAccess> onComplete) { -- if (gen) { -- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- return; -- } -- scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { -- if (chunk == null) { -- onComplete.accept(null); -- } else { -- if (chunk.getStatus().isOrAfter(toStatus)) { -- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- } else { -- onComplete.accept(null); -- } -- } -- }); -+ level.chunkTaskScheduler.scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system - } - -- static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); -- -- private static long chunkLoadCounter = 0L; -+ // Paper - rewrite chunk system - public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, - final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) { -- if (!Bukkit.isPrimaryThread()) { -- scheduleChunkTask(level, chunkX, chunkZ, () -> { -- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- }, priority); -- return; -- } -- -- final int minLevel = 33 + ChunkStatus.getDistance(toStatus); -- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -- -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- level.chunkSource.runDistanceManagerUpdates(); -- -- final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> { -- try { -- if (onComplete != null) { -- onComplete.accept(chunk); -- } -- } catch (final ThreadDeath death) { -- throw death; -- } catch (final Throwable thr) { -- LOGGER.error("Exception handling chunk load callback", thr); -- SneakyThrow.sneaky(thr); -- } finally { -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); -- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- } -- }; -- -- final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (holder == null || holder.getTicketLevel() > minLevel) { -- loadCallback.accept(null); -- return; -- } -- -- final CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> loadFuture = holder.getOrScheduleFuture(toStatus, level.chunkSource.chunkMap); -- -- if (loadFuture.isDone()) { -- loadCallback.accept(loadFuture.join().left().orElse(null)); -- return; -- } -- -- loadFuture.whenCompleteAsync((final Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { -- if (thr != null) { -- loadCallback.accept(null); -- return; -- } -- loadCallback.accept(either.left().orElse(null)); -- }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -- }); -+ level.chunkTaskScheduler.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system - } - - public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, - final ChunkHolder.FullChunkStatus toStatus, final boolean addTicket, - final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) { -- if (toStatus == ChunkHolder.FullChunkStatus.INACCESSIBLE) { -- throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); -- } -- -- if (!Bukkit.isPrimaryThread()) { -- scheduleChunkTask(level, chunkX, chunkZ, () -> { -- scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- }, priority); -- return; -- } -- -- final int minLevel = 33 - (toStatus.ordinal() - 1); -- final int radius = toStatus.ordinal() - 1; -- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -- -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- level.chunkSource.runDistanceManagerUpdates(); -- -- final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> { -- try { -- if (onComplete != null) { -- onComplete.accept(chunk); -- } -- } catch (final ThreadDeath death) { -- throw death; -- } catch (final Throwable thr) { -- LOGGER.error("Exception handling chunk load callback", thr); -- SneakyThrow.sneaky(thr); -- } finally { -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); -- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- } -- }; -- -- final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (holder == null || holder.getTicketLevel() > minLevel) { -- loadCallback.accept(null); -- return; -- } -- -- final CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> tickingState; -- switch (toStatus) { -- case BORDER: { -- tickingState = holder.getFullChunkFuture(); -- break; -- } -- case TICKING: { -- tickingState = holder.getTickingChunkFuture(); -- break; -- } -- case ENTITY_TICKING: { -- tickingState = holder.getEntityTickingChunkFuture(); -- break; -- } -- default: { -- throw new IllegalStateException("Cannot reach here"); -- } -- } -- -- if (tickingState.isDone()) { -- loadCallback.accept(tickingState.join().left().orElse(null)); -- return; -- } -- -- tickingState.whenCompleteAsync((final Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> { -- if (thr != null) { -- loadCallback.accept(null); -- return; -- } -- loadCallback.accept(either.left().orElse(null)); -- }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -- }); -+ level.chunkTaskScheduler.scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system - } - - public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) { -- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); -+ return level.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders(); // Paper - rewrite chunk system - } - - public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) { -- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); -+ return level.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders(); // Paper - rewrite chunk system - } - - public static int getVisibleChunkHolderCount(final ServerLevel level) { -- return level.chunkSource.chunkMap.visibleChunkMap.size(); -+ return level.chunkTaskScheduler.chunkHolderManager.size(); // Paper - rewrite chunk system - } - - public static int getUpdatingChunkHolderCount(final ServerLevel level) { -- return level.chunkSource.chunkMap.updatingChunkMap.size(); -+ return level.chunkTaskScheduler.chunkHolderManager.size(); // Paper - rewrite chunk system - } - - public static boolean hasAnyChunkHolders(final ServerLevel level) { -@@ -269,23 +119,15 @@ public final class ChunkSystem { - } - - public static int getSendViewDistance(final ServerPlayer player) { -- return getLoadViewDistance(player); -+ return io.papermc.paper.chunk.PlayerChunkLoader.getSendViewDistance(player); - } - - public static int getLoadViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.getLevel(); -- if (level == null) { -- return Bukkit.getViewDistance() + 1; -- } -- return level.chunkSource.chunkMap.getEffectiveViewDistance() + 1; -+ return io.papermc.paper.chunk.PlayerChunkLoader.getLoadViewDistance(player); - } - - public static int getTickViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.getLevel(); -- if (level == null) { -- return Bukkit.getSimulationDistance(); -- } -- return level.chunkSource.chunkMap.distanceManager.getSimulationDistance(); -+ return io.papermc.paper.chunk.PlayerChunkLoader.getTickViewDistance(player); - } - - private ChunkSystem() { -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 9db975e84609956b2206076e30f17a350adb77d6..f99929c0c5652dedf94b7e34ba599cedf5daf508 100644 ---- a/src/main/java/net/minecraft/server/MCUtil.java -+++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -1,15 +1,28 @@ - package net.minecraft.server; - - import com.google.common.util.concurrent.ThreadFactoryBuilder; -+import com.google.gson.JsonArray; -+import com.google.gson.JsonObject; -+import com.google.gson.internal.Streams; -+import com.google.gson.stream.JsonWriter; -+import com.mojang.datafixers.util.Either; - import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; - import java.lang.ref.Cleaner; -+import it.unimi.dsi.fastutil.objects.ReferenceArrayList; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.DistanceManager; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.Ticket; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.ClipContext; - import net.minecraft.world.level.Level; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.ChunkStatus; - import org.apache.commons.lang.exception.ExceptionUtils; - import org.bukkit.Location; - import org.bukkit.block.BlockFace; -@@ -19,8 +32,11 @@ import org.spigotmc.AsyncCatcher; - - import javax.annotation.Nonnull; - import javax.annotation.Nullable; -+import java.io.*; -+import java.nio.charset.StandardCharsets; - import java.util.List; - import java.util.Queue; -+import java.util.Set; - import java.util.concurrent.CompletableFuture; - import java.util.concurrent.ExecutionException; - import java.util.concurrent.LinkedBlockingQueue; -@@ -505,6 +521,100 @@ public final class MCUtil { - } - } - -+ public static ChunkStatus getChunkStatus(ChunkHolder chunk) { -+ return chunk.getChunkHolderStatus(); -+ } -+ -+ public static void dumpChunks(File file, boolean watchdog) throws IOException { -+ file.getParentFile().mkdirs(); -+ file.createNewFile(); -+ ReferenceArrayList<org.bukkit.World> worlds = new ReferenceArrayList<>(org.bukkit.Bukkit.getWorlds()); -+ ReferenceArrayList<org.bukkit.World> loadedWorlds = new ReferenceArrayList<>(worlds); -+ JsonObject data = new JsonObject(); -+ -+ data.addProperty("server-version", org.bukkit.Bukkit.getVersion()); -+ data.addProperty("data-version", 1); -+ -+ { -+ JsonArray players = new JsonArray(); -+ data.add("all-players", players); -+ List<ServerPlayer> playerList = MinecraftServer.getServer().getPlayerList().players; -+ for (ServerPlayer player : playerList) { -+ JsonObject playerData = new JsonObject(); -+ players.add(playerData); -+ -+ Level playerWorld = player.getLevel(); -+ org.bukkit.World craftWorld = playerWorld.getWorld(); -+ Entity.RemovalReason removalReason = player.getRemovalReason(); -+ -+ playerData.addProperty("name", player.getScoreboardName()); -+ playerData.addProperty("x", player.getX()); -+ playerData.addProperty("y", player.getY()); -+ playerData.addProperty("z", player.getZ()); -+ playerData.addProperty("world", playerWorld == null ? "null world" : craftWorld.getName()); -+ playerData.addProperty("removalReason", removalReason == null ? "null" : removalReason.name()); -+ -+ if (!worlds.contains(craftWorld)) { -+ worlds.add(craftWorld); -+ } -+ } -+ } -+ -+ JsonArray chunkWaitInformation = new JsonArray(); -+ data.add("chunk-wait-infos", chunkWaitInformation); -+ -+ for (io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.ChunkInfo chunkInfo : io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.getChunkInfos()) { -+ chunkWaitInformation.add(chunkInfo.toString()); -+ } -+ -+ JsonArray worldsData = new JsonArray(); -+ -+ for (org.bukkit.World bukkitWorld : worlds) { -+ JsonObject worldData = new JsonObject(); -+ -+ ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle(); -+ List<ServerPlayer> players = world.players; -+ -+ worldData.addProperty("is-loaded", loadedWorlds.contains(bukkitWorld)); -+ worldData.addProperty("name", world.getWorld().getName()); -+ worldData.addProperty("view-distance", world.getChunkSource().chunkMap.playerChunkManager.getTargetNoTickViewDistance()); // Paper - replace chunk loader system -+ worldData.addProperty("tick-view-distance", world.getChunkSource().chunkMap.playerChunkManager.getTargetTickViewDistance()); // Paper - replace chunk loader system -+ worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory); -+ worldData.addProperty("keep-spawn-loaded-range", world.paperConfig().spawn.keepSpawnLoadedRange * 16); -+ -+ JsonArray playersData = new JsonArray(); -+ -+ for (ServerPlayer player : players) { -+ JsonObject playerData = new JsonObject(); -+ -+ playerData.addProperty("name", player.getScoreboardName()); -+ playerData.addProperty("x", player.getX()); -+ playerData.addProperty("y", player.getY()); -+ playerData.addProperty("z", player.getZ()); -+ -+ playersData.add(playerData); -+ } -+ -+ worldData.add("players", playersData); -+ worldData.add("chunk-data", watchdog ? world.chunkTaskScheduler.chunkHolderManager.getDebugJsonForWatchdog() : world.chunkTaskScheduler.chunkHolderManager.getDebugJson()); -+ worldsData.add(worldData); -+ } -+ -+ data.add("worlds", worldsData); -+ -+ StringWriter stringWriter = new StringWriter(); -+ JsonWriter jsonWriter = new JsonWriter(stringWriter); -+ jsonWriter.setIndent(" "); -+ jsonWriter.setLenient(false); -+ Streams.write(data, jsonWriter); -+ -+ String fileData = stringWriter.toString(); -+ -+ try (PrintStream out = new PrintStream(new FileOutputStream(file), false, StandardCharsets.UTF_8)) { -+ out.print(fileData); -+ } -+ } -+ - public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) { - return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status); - } diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java index 4dd3af1416cbdad330365a19ad664079f3598c15..45db9f1b1d19319e7f92bd4e61be9ea9b06dd5e5 100644 --- a/src/main/java/net/minecraft/server/Main.java @@ -12707,7 +12708,7 @@ index 4dd3af1416cbdad330365a19ad664079f3598c15..45db9f1b1d19319e7f92bd4e61be9ea9 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, config.get(), ops.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::new); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53be6189d3fa6a65a09996683913fbbf5133dcb7..317cd6f68c2368b2f70dfb809db3e418de040f05 100644 +index 2b2b71f3963e66fa0d2683b10581b1a38c774549..0d2114be30df99c5b50f82def97b0a44e797e573 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -287,7 +287,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -12856,7 +12857,7 @@ index 53be6189d3fa6a65a09996683913fbbf5133dcb7..317cd6f68c2368b2f70dfb809db3e418 public boolean isDebugging() { diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index c905602d23cdf3af1de7ab4419f11856b07da2ba..fa1ab9974859c75075f3090e36e0de58dda3e8e6 100644 +index c905602d23cdf3af1de7ab4419f11856b07da2ba..48745f950a35ead81abb3f4cb56f4a3397c74cac 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -406,7 +406,34 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -12877,7 +12878,7 @@ index c905602d23cdf3af1de7ab4419f11856b07da2ba..fa1ab9974859c75075f3090e36e0de58 + "chunks-" + java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(java.time.LocalDateTime.now()) + ".txt"); + sender.sendMessage(net.kyori.adventure.text.Component.text("Writing chunk information dump to " + file, net.kyori.adventure.text.format.NamedTextColor.GREEN)); + try { -+ net.minecraft.server.MCUtil.dumpChunks(file, true); ++ io.papermc.paper.util.MCUtil.dumpChunks(file, true); + sender.sendMessage(net.kyori.adventure.text.Component.text("Successfully written chunk information!", net.kyori.adventure.text.format.NamedTextColor.GREEN)); + } catch (Throwable thr) { + MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr); @@ -12895,7 +12896,7 @@ index c905602d23cdf3af1de7ab4419f11856b07da2ba..fa1ab9974859c75075f3090e36e0de58 } diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d82851c00a 100644 +index a7feddc31da0870faa3d32a7108282e9e9143180..2ba3bb4e5670ece798a8882801a856d82851c00a 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -50,17 +50,12 @@ public class ChunkHolder { @@ -13339,7 +13340,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 - if (left.isPresent() && ChunkHolder.this.fullChunkCreateCount == expectCreateCount) { - LevelChunk fullChunk = either.left().get(); - ChunkHolder.this.isFullChunkReady = true; -- net.minecraft.server.ChunkSystem.onChunkBorder(fullChunk, this); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(fullChunk, this); - } - }); - this.updateChunkToSave(this.fullChunkFuture, "full"); @@ -13348,7 +13349,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 - if (flag2 && !flag3) { - // Paper start - if (this.isFullChunkReady) { -- net.minecraft.server.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().left().get(), this); // Paper +- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().left().get(), this); // Paper - } - // Paper end - this.fullChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); @@ -13368,7 +13369,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 - either.ifLeft(chunk -> { - // note: Here is a very good place to add callbacks to logic waiting on this. - ChunkHolder.this.isTickingReady = true; -- net.minecraft.server.ChunkSystem.onChunkTicking(chunk, this); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(chunk, this); - }); - }); - // Paper end @@ -13378,7 +13379,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 - if (flag4 && !flag5) { - // Paper start - if (this.isTickingReady) { -- net.minecraft.server.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().left().get(), this); // Paper +- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().left().get(), this); // Paper - } - // Paper end - this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage @@ -13399,7 +13400,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 - this.entityTickingChunkFuture.thenAccept(either -> { - either.ifLeft(chunk -> { - ChunkHolder.this.isEntityTickingReady = true; -- net.minecraft.server.ChunkSystem.onChunkEntityTicking(chunk, this); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(chunk, this); - }); - }); - // Paper end @@ -13409,7 +13410,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 - if (flag6 && !flag7) { - // Paper start - if (this.isEntityTickingReady) { -- net.minecraft.server.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().left().get(), this); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().left().get(), this); - } - // Paper end - this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage @@ -13509,7 +13510,7 @@ index 86c33f029ae56fcace51b69763202be9f8bc5f44..2ba3bb4e5670ece798a8882801a856d8 // Paper end } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7f6113f6a 100644 +index 1fa6d7ba1c04f9f4773f9303cc220d75415a56fb..82f5316ee44edd64f23178edc9b47f3be8dc39ca 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -122,10 +122,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -13783,7 +13784,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 - } else { - holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this); - // Paper start -- net.minecraft.server.ChunkSystem.onChunkHolderCreate(this.level, holder); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderCreate(this.level, holder); - // Paper end - } - @@ -13818,7 +13819,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 protected void saveAllChunks(boolean flush) { - if (flush) { -- List<ChunkHolder> list = (List) net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper +- List<ChunkHolder> list = (List) io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper - MutableBoolean mutableboolean = new MutableBoolean(); - - do { @@ -13847,7 +13848,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 - }); - this.flushWorker(); - } else { -- net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); +- io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); - } - + this.level.chunkTaskScheduler.chunkHolderManager.saveAllChunks(flush, false, false); // Paper - rewrite chunk system @@ -13871,7 +13872,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 } public boolean hasWork() { -- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || net.minecraft.server.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper +- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || io.papermc.paper.chunk.system.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -13901,7 +13902,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 - } - - int l = 0; -- Iterator objectiterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper +- Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper - - while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { - if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { @@ -13923,7 +13924,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 - // Paper start - boolean removed; - if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -- net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); - // Paper end - if (ichunkaccess instanceof LevelChunk) { - ((LevelChunk) ichunkaccess).setLoaded(false); @@ -13941,7 +13942,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 - this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null); - this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong()); - } else if (removed) { // Paper start -- net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder); +- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); - } // Paper end - - } @@ -14295,7 +14296,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 this.viewDistance = j; - this.distanceManager.updatePlayerTickets(this.viewDistance + 1); -- Iterator objectiterator = net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper +- Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper - - while (objectiterator.hasNext()) { - ChunkHolder playerchunk = (ChunkHolder) objectiterator.next(); @@ -14333,7 +14334,7 @@ index cbd4e749574c55c6e52f42b62dd6da8cfcca97f9..13814643e28e36c72173d0d62b9271a7 void dumpChunks(Writer writer) throws IOException { - CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer); - TickingTracker tickingtracker = this.distanceManager.tickingTracker(); -- Iterator<ChunkHolder> objectbidirectionaliterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper +- Iterator<ChunkHolder> objectbidirectionaliterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper - - while (objectbidirectionaliterator.hasNext()) { - ChunkHolder playerchunk = objectbidirectionaliterator.next(); // Paper @@ -14990,7 +14991,7 @@ index d38ad1b1eee92a6dbd2b79b4fcdb8959cdb4007d..ffa1e457decf8502c3283352bf5be94d + */ // Paper - rewrite chunk system } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 8c99e9d1cc1abf5a425846eb4edd52bf38aa2f75..b3cff10fece84839fe85feb297fafbcd4a02d838 100644 +index 203bca8839a9c1c0fd8171d3a17d0a55086f20a1..39d96933e2d922e377df866367057f1991471c8d 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -366,7 +366,7 @@ public class ServerChunkCache extends ChunkSource { @@ -15017,7 +15018,7 @@ index 8c99e9d1cc1abf5a425846eb4edd52bf38aa2f75..b3cff10fece84839fe85feb297fafbcd + priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL; + } + -+ net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.level, x, z, gen, ChunkStatus.FULL, true, priority, (chunk) -> { ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.level, x, z, gen, ChunkStatus.FULL, true, priority, (chunk) -> { + if (chunk == null) { + ret.complete(ChunkHolder.UNLOADED_CHUNK); + } else { @@ -15304,7 +15305,7 @@ index 8c99e9d1cc1abf5a425846eb4edd52bf38aa2f75..b3cff10fece84839fe85feb297fafbcd } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 99d44faab5b5da244fdc170c73d73723c174c8fd..7c709be5d43bcd45064c79e84d5b2fff0b3d0cfe 100644 +index b24b68aad942401815548fa49b968a7bf1f7939d..c5cc5e2c235b46f15d120b6aa5f71410d535a486 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -190,7 +190,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -15666,7 +15667,7 @@ index 99d44faab5b5da244fdc170c73d73723c174c8fd..7c709be5d43bcd45064c79e84d5b2fff private final class EntityCallbacks implements LevelCallback<Entity> { diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 3fb8d2626a1ef097c05fa5810bc1e051b4a6ad44..63d1a121a97a8dbc9b640d21580b084898a232bf 100644 +index 275b7f7dd36a2073a3eb9f89f4c832839e5aa9af..660693c6dc0ef86f4013df980b6d0c11c03e46cd 100644 --- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java +++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java @@ -36,15 +36,14 @@ import net.minecraft.world.level.chunk.ChunkStatus; @@ -16194,7 +16195,7 @@ index 1a44c98b69398ba5dcb4115f0e8fdcf3f62fd920..1a2ee5824c6af6b548e7006d583b73f4 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index db4fa7355b1f834d0f8a0710c1c583dded184613..8938e04ffab2d31e64b80879d21d9f1eb90c20bb 100644 +index db4fa7355b1f834d0f8a0710c1c583dded184613..a98f4315b82919e4d90d74f5cd0e6f21e49353dc 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java @@ -38,12 +38,28 @@ import net.minecraft.world.level.chunk.storage.SectionStorage; @@ -16328,8 +16329,8 @@ index db4fa7355b1f834d0f8a0710c1c583dded184613..8938e04ffab2d31e64b80879d21d9f1e + } + + public void onUnload(long coordinate) { // Paper - rewrite chunk system -+ int chunkX = net.minecraft.server.MCUtil.getCoordinateX(coordinate); -+ int chunkZ = net.minecraft.server.MCUtil.getCoordinateZ(coordinate); ++ int chunkX = io.papermc.paper.util.MCUtil.getCoordinateX(coordinate); ++ int chunkZ = io.papermc.paper.util.MCUtil.getCoordinateZ(coordinate); + io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); + for (int section = this.levelHeightAccessor.getMinSection(); section < this.levelHeightAccessor.getMaxSection(); ++section) { + long sectionPos = SectionPos.asLong(chunkX, section, chunkZ); @@ -16674,7 +16675,7 @@ index e6240f891e396d91e31b02fdf3084be77e9d6697..00cb9dafc711607f28529ea9afbcdb49 public int getIndex() { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index e75ec8f6aa597b5f3048d6269fba45eef057bc71..6a84e7524a246e234116a37349f30e01411e6787 100644 +index e75ec8f6aa597b5f3048d6269fba45eef057bc71..0e2a15d623e5ff5c34252e4b714713a6a670e755 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -183,6 +183,43 @@ public class LevelChunk extends ChunkAccess { @@ -16764,7 +16765,7 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..6a84e7524a246e234116a37349f30e01 + // the chunk load event // -> stays here + // any entity add to world events // -> in FULL status + this.loadCallback(); -+ net.minecraft.server.ChunkSystem.onChunkBorder(this, chunkHolder.vanillaChunkHolder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(this, chunkHolder.vanillaChunkHolder); + } + + public void onChunkUnload(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { @@ -16774,25 +16775,25 @@ index e75ec8f6aa597b5f3048d6269fba45eef057bc71..6a84e7524a246e234116a37349f30e01 + // any entity add to world events // -> goes into the unload logic, it will completely explode + // etc later + this.unloadCallback(); -+ net.minecraft.server.ChunkSystem.onChunkNotBorder(this, chunkHolder.vanillaChunkHolder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this, chunkHolder.vanillaChunkHolder); + } + + public void onChunkTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { + this.postProcessGeneration(); + this.level.startTickingChunk(this); -+ net.minecraft.server.ChunkSystem.onChunkTicking(this, chunkHolder.vanillaChunkHolder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(this, chunkHolder.vanillaChunkHolder); + } + + public void onChunkNotTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ net.minecraft.server.ChunkSystem.onChunkNotTicking(this, chunkHolder.vanillaChunkHolder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this, chunkHolder.vanillaChunkHolder); + } + + public void onChunkEntityTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ net.minecraft.server.ChunkSystem.onChunkEntityTicking(this, chunkHolder.vanillaChunkHolder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(this, chunkHolder.vanillaChunkHolder); + } + + public void onChunkNotEntityTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ net.minecraft.server.ChunkSystem.onChunkNotEntityTicking(this, chunkHolder.vanillaChunkHolder); ++ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this, chunkHolder.vanillaChunkHolder); + } + // Paper end - new load callbacks + @@ -17758,7 +17759,7 @@ index eb5c7e15366ee5902d8c754a1e9daec50d26fb17..2103081cf6a8db00d78618340eef5140 // Paper start diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 9a6820b10e4164cc38d269853b5c2a49175cb890..e2c051dd0d639ba28da0f62d06259fcf0d3244ce 100644 +index e3d0a82387dfdcf65f1b07fd8ae2132be6e6d18f..fe2f5364e526cfe9e25760301165934b7fbbdd85 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -314,10 +314,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0079-EntityPathfindEvent.patch b/patches/server/0079-EntityPathfindEvent.patch index 8567351f04..4e0de3f713 100644 --- a/patches/server/0079-EntityPathfindEvent.patch +++ b/patches/server/0079-EntityPathfindEvent.patch @@ -63,7 +63,7 @@ index 27b072943328aca4489a9565bda700e7e7dcbb6a..f0248d839255763005ba333b0bfcf691 private int getSurfaceY() { diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index eaf1653b14e5fdacae38abe75260a64d0ffbfc1d..30f58f1829d1b500ee49b543e3c15e5bfe63fade 100644 +index eaf1653b14e5fdacae38abe75260a64d0ffbfc1d..b6b6106ad2105c19273dc9f983fabd6573d35e5a 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -108,7 +108,13 @@ public abstract class PathNavigation { @@ -115,7 +115,7 @@ index eaf1653b14e5fdacae38abe75260a64d0ffbfc1d..30f58f1829d1b500ee49b543e3c15e5b + boolean copiedSet = false; + for (BlockPos possibleTarget : positions) { + if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(), -+ net.minecraft.server.MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) { ++ io.papermc.paper.util.MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) { + if (!copiedSet) { + copiedSet = true; + positions = new java.util.HashSet<>(positions); diff --git a/patches/server/0094-LootTable-API-Replenishable-Lootables-Feature.patch b/patches/server/0094-LootTable-API-Replenishable-Lootables-Feature.patch index 1bd3ae7f40..bea608329e 100644 --- a/patches/server/0094-LootTable-API-Replenishable-Lootables-Feature.patch +++ b/patches/server/0094-LootTable-API-Replenishable-Lootables-Feature.patch @@ -415,13 +415,13 @@ index 0000000000000000000000000000000000000000..e5ea9f27a1936ed9e329e74317c91c5d +} diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java new file mode 100644 -index 0000000000000000000000000000000000000000..3377b86c337d0234bbb9b0349e4034a7cd450a97 +index 0000000000000000000000000000000000000000..9cfa5d36a6991067a3866e0d437749fafcc0158e --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java @@ -0,0 +1,65 @@ +package com.destroystokyo.paper.loottable; + -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity; +import org.bukkit.Bukkit; @@ -485,7 +485,7 @@ index 0000000000000000000000000000000000000000..3377b86c337d0234bbb9b0349e4034a7 + } +} diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 233c8950816521be5a9d099c29c99d0a421d30e4..77652939ccb3191c29b919170a06ef451b3fd74f 100644 +index dd5e9dc310f30c008f0c8c60ac4305160261bad9..a6b5527e97e8a5b2eeca762477a7b695223a0d4d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -232,6 +232,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { diff --git a/patches/server/0097-Async-GameProfileCache-saving.patch b/patches/server/0097-Async-GameProfileCache-saving.patch index e0d7f93e3f..7a9b7d0bed 100644 --- a/patches/server/0097-Async-GameProfileCache-saving.patch +++ b/patches/server/0097-Async-GameProfileCache-saving.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Async GameProfileCache saving diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7755d79e0dc01e8464f4ffda46db6dbde033aac4..f1d4a7a9e74adc18e18b2df960794ec8c05ce340 100644 +index e24bd9c2be84dd11bf109e65ea4e1e577fe647ca..f438056c74dd24142bd94b505160711d0f94a5d5 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -926,7 +926,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -18,7 +18,7 @@ index 7755d79e0dc01e8464f4ffda46db6dbde033aac4..f1d4a7a9e74adc18e18b2df960794ec8 // Spigot end io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 4dc5a5888f0180e1490597e43956e8e80981f8b9..6c856dee201d84285283504aad8cf959e88b1c52 100644 +index 528bf80bdd786b13b3c46eaf922bf6870865f040..f3c65b5f4a0cc3bc0004cc6f8cc974a87a1123bb 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -247,7 +247,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -31,7 +31,7 @@ index 4dc5a5888f0180e1490597e43956e8e80981f8b9..6c856dee201d84285283504aad8cf959 if (!OldUsersConverter.serverReadyAfterUserconversion(this)) { diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index d246563021c32127e570809f4d849b6a156f4dc6..2249beff3200c5dab1e81bd3d10f2c3bf1e7dbc9 100644 +index d246563021c32127e570809f4d849b6a156f4dc6..225e15d686675e21969c4210fa38fef58d920355 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -127,7 +127,7 @@ public class GameProfileCache { @@ -76,7 +76,7 @@ index d246563021c32127e570809f4d849b6a156f4dc6..2249beff3200c5dab1e81bd3d10f2c3b + // Paper start + }; + if (asyncSave) { -+ net.minecraft.server.MCUtil.scheduleAsyncTask(save); ++ io.papermc.paper.util.MCUtil.scheduleAsyncTask(save); + } else { + save.run(); + } diff --git a/patches/server/0115-Prevent-Pathfinding-out-of-World-Border.patch b/patches/server/0115-Prevent-Pathfinding-out-of-World-Border.patch index 6feb089d75..50b980ec70 100644 --- a/patches/server/0115-Prevent-Pathfinding-out-of-World-Border.patch +++ b/patches/server/0115-Prevent-Pathfinding-out-of-World-Border.patch @@ -13,7 +13,7 @@ by adding code to all overrides in: to return BLOCKED if it is outside the world border. diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 30f58f1829d1b500ee49b543e3c15e5bfe63fade..64cbff139ee8ccf5cdfe7c3d97fa69d8244becb2 100644 +index b6b6106ad2105c19273dc9f983fabd6573d35e5a..185f0bce91f03dfe9a37412710aa7319a15f57ff 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -156,7 +156,7 @@ public abstract class PathNavigation { @@ -22,6 +22,6 @@ index 30f58f1829d1b500ee49b543e3c15e5bfe63fade..64cbff139ee8ccf5cdfe7c3d97fa69d8 for (BlockPos possibleTarget : positions) { - if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(), + if (!this.mob.getCommandSenderWorld().getWorldBorder().isWithinBounds(possibleTarget) || !new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(), // Paper - don't path out of world border - net.minecraft.server.MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) { + io.papermc.paper.util.MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) { if (!copiedSet) { copiedSet = true; diff --git a/patches/server/0124-PlayerTeleportEndGatewayEvent.patch b/patches/server/0124-PlayerTeleportEndGatewayEvent.patch index 65f98958b1..378f2e4756 100644 --- a/patches/server/0124-PlayerTeleportEndGatewayEvent.patch +++ b/patches/server/0124-PlayerTeleportEndGatewayEvent.patch @@ -6,14 +6,14 @@ Subject: [PATCH] PlayerTeleportEndGatewayEvent Allows you to access the Gateway being used in a teleport event diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index 0a792513ac71df24aa8ea4e5d47caad07c22c65e..8a65d379a67630967d07d97fdc528838453763a9 100644 +index 0a792513ac71df24aa8ea4e5d47caad07c22c65e..575e9ced37b6b865de342d305af2c5762ae6fcb9 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java @@ -11,6 +11,7 @@ import net.minecraft.data.worldgen.features.EndFeatures; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; diff --git a/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch index a2c225e44e..4ec316d03a 100644 --- a/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch @@ -20,7 +20,7 @@ index 64b763d6dc695e9cb9dd381deb5609e4902713dd..1954a93a1f566c1c79cdc2e0eb1b4114 private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList(); private boolean tickingBlockEntities; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e2c051dd0d639ba28da0f62d06259fcf0d3244ce..a75f4a1ecfe2790d727f5dda792c5ab4bb45554e 100644 +index fe2f5364e526cfe9e25760301165934b7fbbdd85..2636ef8f827b30315693f1b406debcdea0716170 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -152,6 +152,56 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -43,7 +43,7 @@ index e2c051dd0d639ba28da0f62d06259fcf0d3244ce..a75f4a1ecfe2790d727f5dda792c5ab4 + public int getTileEntityCount() { + // We don't use the full world tile entity list, so we must iterate chunks + int size = 0; -+ for (ChunkHolder playerchunk : net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.world)) { ++ for (ChunkHolder playerchunk : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world)) { + net.minecraft.world.level.chunk.LevelChunk chunk = playerchunk.getTickingChunk(); + if (chunk == null) { + continue; @@ -62,7 +62,7 @@ index e2c051dd0d639ba28da0f62d06259fcf0d3244ce..a75f4a1ecfe2790d727f5dda792c5ab4 + public int getChunkCount() { + int ret = 0; + -+ for (ChunkHolder chunkHolder : net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.world)) { ++ for (ChunkHolder chunkHolder : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world)) { + if (chunkHolder.getTickingChunk() != null) { + ++ret; + } diff --git a/patches/server/0126-Enforce-Sync-Player-Saves.patch b/patches/server/0126-Enforce-Sync-Player-Saves.patch index b13a65c6ac..db22ab7995 100644 --- a/patches/server/0126-Enforce-Sync-Player-Saves.patch +++ b/patches/server/0126-Enforce-Sync-Player-Saves.patch @@ -7,14 +7,14 @@ Saving players async is extremely dangerous. This will force it to main the same way we handle async chunk loads. diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 0d0b04775dc36c1749d8f19f5c8d2b9dd9bb5a1e..acb3d75f0777eab5aa117679d2328c22f46cf823 100644 +index 0d0b04775dc36c1749d8f19f5c8d2b9dd9bb5a1e..730f30b6ee5230cde784b7f0a2b20699968f7e15 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1042,11 +1042,13 @@ public abstract class PlayerList { } public void saveAll() { -+ net.minecraft.server.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main ++ io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main MinecraftTimings.savePlayers.startTiming(); // Paper for (int i = 0; i < this.players.size(); ++i) { - this.save((ServerPlayer) this.players.get(i)); diff --git a/patches/server/0142-Basic-PlayerProfile-API.patch b/patches/server/0142-Basic-PlayerProfile-API.patch index cba9be0438..cd3cc22296 100644 --- a/patches/server/0142-Basic-PlayerProfile-API.patch +++ b/patches/server/0142-Basic-PlayerProfile-API.patch @@ -554,19 +554,19 @@ index 0000000000000000000000000000000000000000..7ac27392a8647ef7d0dc78efe78703e9 + + @NotNull GameProfile buildGameProfile(); +} -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index c9e169a6dca4dd8fe6e27a23deb410664a5d4466..e98276943e1690572b8f7bc54a259aa8340bae41 100644 ---- a/src/main/java/net/minecraft/server/MCUtil.java -+++ b/src/main/java/net/minecraft/server/MCUtil.java +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index 3a0e4934af1f1c711e55ed6f439241364b7448f4..4c5ed3de410c740bcaca37d84b153af6a482bf89 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java @@ -1,5 +1,7 @@ - package net.minecraft.server; + package io.papermc.paper.util; +import com.destroystokyo.paper.profile.CraftPlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -@@ -24,6 +26,7 @@ import net.minecraft.world.level.Level; +@@ -25,6 +27,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; import org.apache.commons.lang.exception.ExceptionUtils; @@ -574,7 +574,7 @@ index c9e169a6dca4dd8fe6e27a23deb410664a5d4466..e98276943e1690572b8f7bc54a259aa8 import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.CraftWorld; -@@ -371,6 +374,10 @@ public final class MCUtil { +@@ -372,6 +375,10 @@ public final class MCUtil { return run.get(); } @@ -599,7 +599,7 @@ index 45db9f1b1d19319e7f92bd4e61be9ea9b06dd5e5..151b13e257c09fc5c4bbccfc388b15ad String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName); LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath()); diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index 2a0cf0a8a79c09566c598197fc6f8c447d4bbd72..5e3bc0590e59770490b1c6c818d99be054214a8a 100644 +index 4038bb76339d43f18770624bd7fecc79b8d7f2a9..2456edc11b29a92b1648937cd3dd6a9a05706803 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -136,6 +136,17 @@ public class GameProfileCache { diff --git a/patches/server/0150-ProfileWhitelistVerifyEvent.patch b/patches/server/0150-ProfileWhitelistVerifyEvent.patch index 70f413bfcc..150f0aa174 100644 --- a/patches/server/0150-ProfileWhitelistVerifyEvent.patch +++ b/patches/server/0150-ProfileWhitelistVerifyEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ProfileWhitelistVerifyEvent diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index f86d3dfcc19f6f9383d21044f61aa5246cf1f9e5..399735c923cfd52bd7b67beb9b974585ab507ca9 100644 +index 07a6b3e74600489f1076a73b3f02ad95891b22e7..808fd17a60c63ef96e702b0ffc9801f58bd0bde2 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -621,9 +621,9 @@ public abstract class PlayerList { @@ -33,7 +33,7 @@ index f86d3dfcc19f6f9383d21044f61aa5246cf1f9e5..399735c923cfd52bd7b67beb9b974585 + boolean isOp = this.ops.contains(gameprofile); + boolean isWhitelisted = !this.doWhiteList || isOp || this.whitelist.contains(gameprofile); + final com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent event; -+ event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(net.minecraft.server.MCUtil.toBukkit(gameprofile), this.doWhiteList, isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage); ++ event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(io.papermc.paper.util.MCUtil.toBukkit(gameprofile), this.doWhiteList, isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage); + event.callEvent(); + if (!event.isWhitelisted()) { + if (loginEvent != null) { diff --git a/patches/server/0168-AsyncTabCompleteEvent.patch b/patches/server/0168-AsyncTabCompleteEvent.patch index ddced42488..c55d2a5b56 100644 --- a/patches/server/0168-AsyncTabCompleteEvent.patch +++ b/patches/server/0168-AsyncTabCompleteEvent.patch @@ -89,7 +89,7 @@ index e40eeb5e04d96fb55283ded82cea0a5539a2fad5..90bd5c1a010a3a9d24328e5c71905360 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 7013b11fc0cd5fbb5a7e62be45d84d54d3052237..ca6bb66e8ba1e17f025b82091910ca223185ad3b 100644 +index 7013b11fc0cd5fbb5a7e62be45d84d54d3052237..bbf9550e7a7c78e961160ef09466e5f962172b6c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2086,7 +2086,7 @@ public final class CraftServer implements Server { @@ -97,7 +97,7 @@ index 7013b11fc0cd5fbb5a7e62be45d84d54d3052237..ca6bb66e8ba1e17f025b82091910ca22 } - TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers); -+ TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? net.minecraft.server.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), new BlockPos(pos)) : null); // Paper ++ TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? io.papermc.paper.util.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), new BlockPos(pos)) : null); // Paper this.getPluginManager().callEvent(tabEvent); return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions(); diff --git a/patches/server/0173-PreCreatureSpawnEvent.patch b/patches/server/0173-PreCreatureSpawnEvent.patch index 69bfbb5b34..3ad4668bab 100644 --- a/patches/server/0173-PreCreatureSpawnEvent.patch +++ b/patches/server/0173-PreCreatureSpawnEvent.patch @@ -15,7 +15,7 @@ instead and save a lot of server resources. See: https://github.com/PaperMC/Paper/issues/917 diff --git a/src/main/java/net/minecraft/util/SpawnUtil.java b/src/main/java/net/minecraft/util/SpawnUtil.java -index f4d1a3e861a8727d7f3efd75c0e83cc9418fa9bd..4f2952cb39be3644e81ae627b748b7916eed2304 100644 +index f4d1a3e861a8727d7f3efd75c0e83cc9418fa9bd..3fb910fadde4875c39523779ad24f381e45b6ab6 100644 --- a/src/main/java/net/minecraft/util/SpawnUtil.java +++ b/src/main/java/net/minecraft/util/SpawnUtil.java @@ -19,10 +19,10 @@ public class SpawnUtil { @@ -41,7 +41,7 @@ index f4d1a3e861a8727d7f3efd75c0e83cc9418fa9bd..4f2952cb39be3644e81ae627b748b791 + + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; + event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( -+ net.minecraft.server.MCUtil.toLocation(worldserver, blockposition), ++ io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition), + type, + reason + ); @@ -59,7 +59,7 @@ index f4d1a3e861a8727d7f3efd75c0e83cc9418fa9bd..4f2952cb39be3644e81ae627b748b791 if (t0 != null) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 2db27f5e3e3c1bb0502c055f78c4a81eb00fcf1b..4b8024f8f62caaa417de6798522c2beb98e00fc4 100644 +index 2db27f5e3e3c1bb0502c055f78c4a81eb00fcf1b..fdefccfa07227f315259f636076e36a120c72917 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -347,6 +347,20 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> { @@ -71,7 +71,7 @@ index 2db27f5e3e3c1bb0502c055f78c4a81eb00fcf1b..4b8024f8f62caaa417de6798522c2beb + if (type != null) { + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; + event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( -+ net.minecraft.server.MCUtil.toLocation(worldserver, blockposition), ++ io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition), + type, + spawnReason + ); @@ -97,7 +97,7 @@ index 25cd8a4101cf44955d95924c9794c238ddde2901..f957c0aca36b7228ac3a33ca04c948b1 } } diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index ac767d107ea0d856f3f8caccfe6f79b14e933005..ffb7a0b7c1ae53e1340f2cdb7840ee2c89982dbe 100644 +index ac767d107ea0d856f3f8caccfe6f79b14e933005..c41c1fa8085f502363c8273cd9fce1cf1743fe71 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -124,6 +124,27 @@ public abstract class BaseSpawner { @@ -112,7 +112,7 @@ index ac767d107ea0d856f3f8caccfe6f79b14e933005..ffb7a0b7c1ae53e1340f2cdb7840ee2c + if (type != null) { + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; + event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( -+ net.minecraft.server.MCUtil.toLocation(world, d0, d1, d2), ++ io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2), + type, + org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER + ); @@ -129,7 +129,7 @@ index ac767d107ea0d856f3f8caccfe6f79b14e933005..ffb7a0b7c1ae53e1340f2cdb7840ee2c Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> { entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot()); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index c6ba7427b53398ddc8f0c942a810fad6e24561b4..08340299538f1adacddc6d5022482a5307c06f78 100644 +index c6ba7427b53398ddc8f0c942a810fad6e24561b4..c41390f5b9260bcfb843460904e1315695a1a972 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -212,7 +212,13 @@ public final class NaturalSpawner { @@ -160,7 +160,7 @@ index c6ba7427b53398ddc8f0c942a810fad6e24561b4..08340299538f1adacddc6d5022482a53 + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(entitytypes).getPath()); + if (type != null) { + event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( -+ net.minecraft.server.MCUtil.toLocation(world, pos), ++ io.papermc.paper.util.MCUtil.toLocation(world, pos), + type, SpawnReason.NATURAL + ); + if (!event.callEvent()) { diff --git a/patches/server/0234-Add-TNTPrimeEvent.patch b/patches/server/0234-Add-TNTPrimeEvent.patch index 95c3a89f2f..805a9b3806 100644 --- a/patches/server/0234-Add-TNTPrimeEvent.patch +++ b/patches/server/0234-Add-TNTPrimeEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add TNTPrimeEvent diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 1709126f0853edc6bece6f31d7c65a5f8955683a..6495b0421cab1b067b9483cc448222705c15578c 100644 +index 6eada8313e468e4ea851094976ac98c11710fb45..3f854bea2e6be82c7ad12b4d13064de8baec55c7 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java @@ -532,6 +532,11 @@ public class EnderDragon extends Mob implements Enemy { @@ -21,7 +21,7 @@ index 1709126f0853edc6bece6f31d7c65a5f8955683a..6495b0421cab1b067b9483cc44822270 this.level.removeBlock(blockposition, false); diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java -index 037902b3addd34dfc6b751ca225373a06c2d6a89..2188cfc34ab4bd67fac9aedd861a597c137a5c40 100644 +index 037902b3addd34dfc6b751ca225373a06c2d6a89..69903bad7b3e143b73b20624c06909458564396c 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -290,12 +290,19 @@ public class FireBlock extends BaseFireBlock { @@ -36,7 +36,7 @@ index 037902b3addd34dfc6b751ca225373a06c2d6a89..2188cfc34ab4bd67fac9aedd861a597c if (block instanceof TntBlock) { + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition); ++ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, blockposition); + if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) { + return; + } @@ -46,7 +46,7 @@ index 037902b3addd34dfc6b751ca225373a06c2d6a89..2188cfc34ab4bd67fac9aedd861a597c } } diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java -index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..355448a08cca780f4f0b95e2abcdc87eb61de6dc 100644 +index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..dd0707bc0a9daf3cd5441a82e9d3502b53d2d0bf 100644 --- a/src/main/java/net/minecraft/world/level/block/TntBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java @@ -38,6 +38,11 @@ public class TntBlock extends Block { @@ -54,7 +54,7 @@ index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..355448a08cca780f4f0b95e2abcdc87e if (!oldState.is(state.getBlock())) { if (world.hasNeighborSignal(pos)) { + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);; ++ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);; + if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) + return; + // Paper end @@ -66,7 +66,7 @@ index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..355448a08cca780f4f0b95e2abcdc87e public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { if (world.hasNeighborSignal(pos)) { + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);; ++ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);; + if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) + return; + // Paper end @@ -78,7 +78,7 @@ index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..355448a08cca780f4f0b95e2abcdc87e public void wasExploded(Level world, BlockPos pos, Explosion explosion) { if (!world.isClientSide) { + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos); ++ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos); + org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null; + if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) + return; @@ -91,7 +91,7 @@ index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..355448a08cca780f4f0b95e2abcdc87e return super.use(state, world, pos, player, hand, hit); } else { + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos); ++ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos); + if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) + return InteractionResult.FAIL; + // Paper end @@ -103,7 +103,7 @@ index 9fcad0eb55a4a91a89ab8bce1f22d91127a94fb2..355448a08cca780f4f0b95e2abcdc87e } // CraftBukkit end + // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition); ++ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, blockposition); + if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) { + return; + } diff --git a/patches/server/0249-Add-PhantomPreSpawnEvent.patch b/patches/server/0249-Add-PhantomPreSpawnEvent.patch index f4862ce10d..2f3dcd5f86 100644 --- a/patches/server/0249-Add-PhantomPreSpawnEvent.patch +++ b/patches/server/0249-Add-PhantomPreSpawnEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PhantomPreSpawnEvent diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index c436476b3ec442b40a7ff122e6d3947a47ae163b..84400bb44d5deb7c79295a83c4c3c6aac88f3175 100644 +index c068eddb08898681735e483df5b9c36f5fef3878..0e96e9d7e4d636f4222f60cec556663f506c3906 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java @@ -171,6 +171,11 @@ public class Phantom extends FlyingMob implements Enemy { @@ -48,14 +48,14 @@ index c436476b3ec442b40a7ff122e6d3947a47ae163b..84400bb44d5deb7c79295a83c4c3c6aa CIRCLE, SWOOP; diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index 573490a7c95746c3d372d258b2e592241258f6cf..e9d25aef08103ccdbc6a35c3ab67c1d921e9f45d 100644 +index 573490a7c95746c3d372d258b2e592241258f6cf..0dbb0c4d038379c6ffdae8528d98431e98faeb93 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -3,6 +3,7 @@ package net.minecraft.world.level.levelgen; import java.util.Iterator; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.ServerStatsCounter; diff --git a/patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch b/patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch index b9856e2e2e..e65b5a68ca 100644 --- a/patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch +++ b/patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch @@ -4,11 +4,11 @@ Date: Mon, 3 Sep 2018 18:20:03 -0500 Subject: [PATCH] Add ray tracing methods to LivingEntity -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index e98276943e1690572b8f7bc54a259aa8340bae41..c9b43d077727c22a9eca738e9a75e7f1a6a5a9ee 100644 ---- a/src/main/java/net/minecraft/server/MCUtil.java -+++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -509,6 +509,18 @@ public final class MCUtil { +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index 4c5ed3de410c740bcaca37d84b153af6a482bf89..e9e1b9e4f487acad02e871c002f3d099c87766fb 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -510,6 +510,18 @@ public final class MCUtil { return getNMSWorld(entity.getWorld()); } @@ -56,7 +56,7 @@ index 30983979f3501c693c7d1f96c47d9cfa1eaa243a..28a49c15c078b7afe1d3c9693c548f6a public int getShieldBlockingDelay() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 04829ced2048b07aa4b2dcf98a601d1fdd9431fb..40e777b859151d036ac7ec4e71ed896df4cd689b 100644 +index 04829ced2048b07aa4b2dcf98a601d1fdd9431fb..6c5cb2e5fb1f5bb7eb05a465a24d62e1dad57b93 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -200,6 +200,28 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @@ -66,22 +66,22 @@ index 04829ced2048b07aa4b2dcf98a601d1fdd9431fb..40e777b859151d036ac7ec4e71ed896d + // Paper start + @Override + public Block getTargetBlock(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) { -+ net.minecraft.world.phys.HitResult rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); ++ net.minecraft.world.phys.HitResult rayTrace = getHandle().getRayTrace(maxDistance, io.papermc.paper.util.MCUtil.getNMSFluidCollisionOption(fluidMode)); + return !(rayTrace instanceof net.minecraft.world.phys.BlockHitResult) ? null : org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().level, ((net.minecraft.world.phys.BlockHitResult)rayTrace).getBlockPos()); + } + + @Override + public org.bukkit.block.BlockFace getTargetBlockFace(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) { -+ net.minecraft.world.phys.HitResult rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); -+ return !(rayTrace instanceof net.minecraft.world.phys.BlockHitResult) ? null : net.minecraft.server.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection()); ++ net.minecraft.world.phys.HitResult rayTrace = getHandle().getRayTrace(maxDistance, io.papermc.paper.util.MCUtil.getNMSFluidCollisionOption(fluidMode)); ++ return !(rayTrace instanceof net.minecraft.world.phys.BlockHitResult) ? null : io.papermc.paper.util.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection()); + } + + @Override + public com.destroystokyo.paper.block.TargetBlockInfo getTargetBlockInfo(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) { -+ net.minecraft.world.phys.HitResult rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); ++ net.minecraft.world.phys.HitResult rayTrace = getHandle().getRayTrace(maxDistance, io.papermc.paper.util.MCUtil.getNMSFluidCollisionOption(fluidMode)); + return !(rayTrace instanceof net.minecraft.world.phys.BlockHitResult) ? null : + new com.destroystokyo.paper.block.TargetBlockInfo(org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().level, ((net.minecraft.world.phys.BlockHitResult)rayTrace).getBlockPos()), -+ net.minecraft.server.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection())); ++ io.papermc.paper.util.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection())); + } + // Paper end + diff --git a/patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch b/patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch index d823af9154..7e49a60f5f 100644 --- a/patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch +++ b/patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch @@ -12,20 +12,20 @@ Shulkers) may need to be changed in order for it to re-save properly No more crashing though. -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index c9b43d077727c22a9eca738e9a75e7f1a6a5a9ee..99f56658c70f99592fb40c9df0ce3e47053d1bd5 100644 ---- a/src/main/java/net/minecraft/server/MCUtil.java -+++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -13,6 +13,8 @@ import java.lang.ref.Cleaner; - import it.unimi.dsi.fastutil.objects.ReferenceArrayList; +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index e9e1b9e4f487acad02e871c002f3d099c87766fb..e63dc33250831428c2cef34e02238600231fb815 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -14,6 +14,8 @@ import it.unimi.dsi.fastutil.objects.ReferenceArrayList; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; + import net.minecraft.server.MinecraftServer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.DistanceManager; -@@ -540,6 +542,21 @@ public final class MCUtil { +@@ -541,6 +543,21 @@ public final class MCUtil { } } @@ -48,7 +48,7 @@ index c9b43d077727c22a9eca738e9a75e7f1a6a5a9ee..99f56658c70f99592fb40c9df0ce3e47 return chunk.getChunkHolderStatus(); } diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java -index a0728e95251e8110bcecd00512c7a266fe120794..da504702bc9423774b35dff792d2dbe7fc270fe3 100644 +index a0728e95251e8110bcecd00512c7a266fe120794..7dac559fd35e7ba646b84bb28315001375723643 100644 --- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java +++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java @@ -72,7 +72,7 @@ public abstract class BaseCommandBlock implements CommandSource { @@ -56,12 +56,12 @@ index a0728e95251e8110bcecd00512c7a266fe120794..da504702bc9423774b35dff792d2dbe7 this.successCount = nbt.getInt("SuccessCount"); if (nbt.contains("CustomName", 8)) { - this.setName(Component.Serializer.fromJson(nbt.getString("CustomName"))); -+ this.setName(net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt)); // Paper - Catch ParseException ++ this.setName(io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt)); // Paper - Catch ParseException } if (nbt.contains("TrackOutput", 1)) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java -index 601cf7b9aa4b3483a2134a2db0d617ed8938ea48..c6ce5dc5dafc15f1f12b0ea4c9d55325f6a76529 100644 +index 601cf7b9aa4b3483a2134a2db0d617ed8938ea48..cef6a9795b289b791db29f9018585e5912634b39 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java @@ -98,7 +98,7 @@ public class BannerBlockEntity extends BlockEntity implements Nameable { @@ -69,12 +69,12 @@ index 601cf7b9aa4b3483a2134a2db0d617ed8938ea48..c6ce5dc5dafc15f1f12b0ea4c9d55325 super.load(nbt); if (nbt.contains("CustomName", 8)) { - this.name = Component.Serializer.fromJson(nbt.getString("CustomName")); -+ this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException ++ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException } this.itemPatterns = nbt.getList("Patterns", 10); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -index a34ae15cd4048bda965fd1449c75f3bd8f0e530b..adf67868eef7d578b7858a5afd54e37ea0d5102f 100644 +index a34ae15cd4048bda965fd1449c75f3bd8f0e530b..f1b5a7e29d2a94c18c0d06b066b8cfbccabbc0a1 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java @@ -30,7 +30,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co @@ -82,12 +82,12 @@ index a34ae15cd4048bda965fd1449c75f3bd8f0e530b..adf67868eef7d578b7858a5afd54e37e this.lockKey = LockCode.fromTag(nbt); if (nbt.contains("CustomName", 8)) { - this.name = Component.Serializer.fromJson(nbt.getString("CustomName")); -+ this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException ++ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index 0c699c08ef85ca3339ada5c869b571581092a11d..349b89dd4d34b92d1077ddadb30c36642fd85622 100644 +index 0c699c08ef85ca3339ada5c869b571581092a11d..12bb07ba7bcb37a26c0492e045b42289bfec70db 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -365,7 +365,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider { @@ -95,12 +95,12 @@ index 0c699c08ef85ca3339ada5c869b571581092a11d..349b89dd4d34b92d1077ddadb30c3664 // CraftBukkit end if (nbt.contains("CustomName", 8)) { - this.name = Component.Serializer.fromJson(nbt.getString("CustomName")); -+ this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException ++ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException } this.lockKey = LockCode.fromTag(nbt); diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java -index 3a8bdb788b07b0a8cda3d4b872ede52ca9a005c4..2341a5a249d455628165fc6ba508fc6d70c3dbfb 100644 +index 3a8bdb788b07b0a8cda3d4b872ede52ca9a005c4..65e1381bb2d10bd212463feb602c60f8fdb9ade1 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java @@ -42,7 +42,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable @@ -108,7 +108,7 @@ index 3a8bdb788b07b0a8cda3d4b872ede52ca9a005c4..2341a5a249d455628165fc6ba508fc6d super.load(nbt); if (nbt.contains("CustomName", 8)) { - this.name = Component.Serializer.fromJson(nbt.getString("CustomName")); -+ this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException ++ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException } } diff --git a/patches/server/0267-PreSpawnerSpawnEvent.patch b/patches/server/0267-PreSpawnerSpawnEvent.patch index ad93f9fbae..a6c42252d0 100644 --- a/patches/server/0267-PreSpawnerSpawnEvent.patch +++ b/patches/server/0267-PreSpawnerSpawnEvent.patch @@ -9,7 +9,7 @@ SpawnerSpawnEvent gets called instead of the CreatureSpawnEvent for spawners. diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index ffb7a0b7c1ae53e1340f2cdb7840ee2c89982dbe..0be0c7a323277093a6f8e476048eb9ee8712cbc9 100644 +index c41c1fa8085f502363c8273cd9fce1cf1743fe71..92e3bb8b59d79cbe79fa55a7db443bd7a1957914 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -130,11 +130,11 @@ public abstract class BaseSpawner { @@ -20,10 +20,10 @@ index ffb7a0b7c1ae53e1340f2cdb7840ee2c89982dbe..0be0c7a323277093a6f8e476048eb9ee - event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( + com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event; + event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent( - net.minecraft.server.MCUtil.toLocation(world, d0, d1, d2), + io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2), type, - org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER -+ net.minecraft.server.MCUtil.toLocation(world, pos) ++ io.papermc.paper.util.MCUtil.toLocation(world, pos) ); if (!event.callEvent()) { flag = true; diff --git a/patches/server/0268-Add-LivingEntity-getTargetEntity.patch b/patches/server/0268-Add-LivingEntity-getTargetEntity.patch index 2842a11a1c..4d7cddef82 100644 --- a/patches/server/0268-Add-LivingEntity-getTargetEntity.patch +++ b/patches/server/0268-Add-LivingEntity-getTargetEntity.patch @@ -56,7 +56,7 @@ index 1189ddcab5011d34a66356cde561fe7e2cecbfdd..8155421080761734c519042e1c24dd2e public int getShieldBlockingDelay() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 40e777b859151d036ac7ec4e71ed896df4cd689b..fb92f55ae3c8c54edce7565b27fb84f50ee85702 100644 +index 6c5cb2e5fb1f5bb7eb05a465a24d62e1dad57b93..bfa6b088f87117015791dc4ab25d8e8cf4c4cf28 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -1,5 +1,6 @@ @@ -68,7 +68,7 @@ index 40e777b859151d036ac7ec4e71ed896df4cd689b..fb92f55ae3c8c54edce7565b27fb84f5 import java.util.ArrayList; @@ -220,6 +221,33 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { new com.destroystokyo.paper.block.TargetBlockInfo(org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().level, ((net.minecraft.world.phys.BlockHitResult)rayTrace).getBlockPos()), - net.minecraft.server.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection())); + io.papermc.paper.util.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection())); } + + public Entity getTargetEntity(int maxDistance, boolean ignoreBlocks) { diff --git a/patches/server/0270-Turtle-API.patch b/patches/server/0270-Turtle-API.patch index 1bc6544713..9b44db2ee4 100644 --- a/patches/server/0270-Turtle-API.patch +++ b/patches/server/0270-Turtle-API.patch @@ -18,7 +18,7 @@ index e3983370c09e3e3445c4557fcca50dd25f29cba0..6efba52c2e5d7811ee329ed22c1c76f7 private final int searchRange; private final int verticalSearchRange; diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 37125ffe47fcd5fe93ab62ad8a46e8188f362436..69c98c2cb2fd8f149a39bbddcbfe0c5c5adc3904 100644 +index 37125ffe47fcd5fe93ab62ad8a46e8188f362436..0cea2eacfe3264a9b3500dc3a6a19d21d74d54e9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -480,14 +480,17 @@ public class Turtle extends Animal { @@ -26,7 +26,7 @@ index 37125ffe47fcd5fe93ab62ad8a46e8188f362436..69c98c2cb2fd8f149a39bbddcbfe0c5c if (!this.turtle.isInWater() && this.isReachedTarget()) { if (this.turtle.layEggCounter < 1) { - this.turtle.setLayingEgg(true); -+ this.turtle.setLayingEgg(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), net.minecraft.server.MCUtil.toLocation(this.turtle.level, this.getTargetPosition())).callEvent()); // Paper ++ this.turtle.setLayingEgg(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level, this.getTargetPosition())).callEvent()); // Paper } else if (this.turtle.layEggCounter > this.adjustedTickDelay(200)) { Level world = this.turtle.level; @@ -34,7 +34,7 @@ index 37125ffe47fcd5fe93ab62ad8a46e8188f362436..69c98c2cb2fd8f149a39bbddcbfe0c5c - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1)).isCancelled()) { + // Paper start + int eggCount = this.turtle.random.nextInt(4) + 1; -+ com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), net.minecraft.server.MCUtil.toLocation(this.turtle.level, this.blockPos.above()), eggCount); ++ com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level, this.blockPos.above()), eggCount); + if (layEggEvent.callEvent() && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount())).isCancelled()) { world.playSound((Player) null, blockposition, SoundEvents.TURTLE_LAY_EGG, SoundSource.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F); - world.setBlock(this.blockPos.above(), (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1), 3); @@ -52,7 +52,7 @@ index 37125ffe47fcd5fe93ab62ad8a46e8188f362436..69c98c2cb2fd8f149a39bbddcbfe0c5c @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java -index 96462a29551c301d3c80029cab2bec3839914237..318f7bc921283ad83daebbf6080821cdc53b2257 100644 +index 96462a29551c301d3c80029cab2bec3839914237..a14d0a688b9054988b5c86c94738e4aaca9f9cfd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java @@ -34,4 +34,31 @@ public class CraftTurtle extends CraftAnimals implements Turtle { @@ -63,12 +63,12 @@ index 96462a29551c301d3c80029cab2bec3839914237..318f7bc921283ad83daebbf6080821cd + // Paper start + @Override + public org.bukkit.Location getHome() { -+ return net.minecraft.server.MCUtil.toLocation(getHandle().getLevel(), getHandle().getHomePos()); ++ return io.papermc.paper.util.MCUtil.toLocation(getHandle().getLevel(), getHandle().getHomePos()); + } + + @Override + public void setHome(org.bukkit.Location location) { -+ getHandle().setHomePos(net.minecraft.server.MCUtil.toBlockPosition(location)); ++ getHandle().setHomePos(io.papermc.paper.util.MCUtil.toBlockPosition(location)); + } + + @Override diff --git a/patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch index fdb06e3b52..6534fddcb2 100644 --- a/patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -11,8 +11,28 @@ server threads Allow usage of a single thread executor by not using ForkJoin so single core CPU's. +diff --git a/src/main/java/io/papermc/paper/util/ServerWorkerThread.java b/src/main/java/io/papermc/paper/util/ServerWorkerThread.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b60f59cf5cc8eb84a6055b7861857dece7f2501b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/util/ServerWorkerThread.java +@@ -0,0 +1,14 @@ ++package io.papermc.paper.util; ++ ++import java.util.concurrent.atomic.AtomicInteger; ++import net.minecraft.Util; ++ ++public class ServerWorkerThread extends Thread { ++ private static final AtomicInteger threadId = new AtomicInteger(1); ++ public ServerWorkerThread(Runnable target, String poolName, int prioritityModifier) { ++ super(target, "Worker-" + poolName + "-" + threadId.getAndIncrement()); ++ setPriority(Thread.NORM_PRIORITY+prioritityModifier); // Deprioritize over main ++ this.setDaemon(true); ++ this.setUncaughtExceptionHandler(Util::onThreadException); ++ } ++} diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 336a26733b5bf73455f8ec10347c1e08b8e866f7..4fce18c52c8144460ebf0c1e336dce712d796cc6 100644 +index 336a26733b5bf73455f8ec10347c1e08b8e866f7..0773447354542925826369625f21e26aa30ebff4 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -79,8 +79,8 @@ public class Util { @@ -43,7 +63,7 @@ index 336a26733b5bf73455f8ec10347c1e08b8e866f7..4fce18c52c8144460ebf0c1e336dce71 } else { - executorService = new ForkJoinPool(i, (forkJoinPool) -> { - ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(forkJoinPool) { -+ executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<Runnable>(), target -> new net.minecraft.server.ServerWorkerThread(target, s, priorityModifier)); ++ executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<Runnable>(), target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier)); + } + /* @Override @@ -58,7 +78,7 @@ index 336a26733b5bf73455f8ec10347c1e08b8e866f7..4fce18c52c8144460ebf0c1e336dce71 return executorService; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index afce3acc552df092636b205964e06b399b7db8e2..5e1a0ab40d9d03844c6e0b962bb15d3b4b40d229 100644 +index 25aac194eb486a5b8707aa0a655fd8259ad7409c..6afa9ab5cb864ff286341582d6d70648d8a86efb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -306,6 +306,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -69,23 +89,3 @@ index afce3acc552df092636b205964e06b399b7db8e2..5e1a0ab40d9d03844c6e0b962bb15d3b thread.start(); return s0; } -diff --git a/src/main/java/net/minecraft/server/ServerWorkerThread.java b/src/main/java/net/minecraft/server/ServerWorkerThread.java -new file mode 100644 -index 0000000000000000000000000000000000000000..480129f430da33157342becb9d3b010f9f7c5edd ---- /dev/null -+++ b/src/main/java/net/minecraft/server/ServerWorkerThread.java -@@ -0,0 +1,14 @@ -+package net.minecraft.server; -+ -+import java.util.concurrent.atomic.AtomicInteger; -+import net.minecraft.Util; -+ -+public class ServerWorkerThread extends Thread { -+ private static final AtomicInteger threadId = new AtomicInteger(1); -+ public ServerWorkerThread(Runnable target, String poolName, int prioritityModifier) { -+ super(target, "Worker-" + poolName + "-" + threadId.getAndIncrement()); -+ setPriority(Thread.NORM_PRIORITY+prioritityModifier); // Deprioritize over main -+ this.setDaemon(true); -+ this.setUncaughtExceptionHandler(Util::onThreadException); -+ } -+} diff --git a/patches/server/0295-BlockDestroyEvent.patch b/patches/server/0295-BlockDestroyEvent.patch index 507652f6ac..f4735fc41c 100644 --- a/patches/server/0295-BlockDestroyEvent.patch +++ b/patches/server/0295-BlockDestroyEvent.patch @@ -11,14 +11,14 @@ floating in the air. This can replace many uses of BlockPhysicsEvent diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 9ed8117afa4eb1ff9e7403d3ab92a9e6cb0fab73..1a474fb88dc1447fb754e8ad936ab6add470359c 100644 +index 9ed8117afa4eb1ff9e7403d3ab92a9e6cb0fab73..699df824d2e9fe8b6f6a1ccc8ae7c818c84204cb 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -28,6 +28,7 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerLevel; diff --git a/patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 0d594b9746..3e0c602933 100644 --- a/patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -28,7 +28,7 @@ and then catch exceptions and close if they fire. Part of this commit was authored by: Spottedleaf diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index dd9c03611e410e601ba4a7769474fada8c28c104..a283cce82069bf5dfd64229d102a19dfda158daf 100644 +index dd9c03611e410e601ba4a7769474fada8c28c104..be571be69b5c3df41531b6c8c7be467afaa4dc55 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -115,6 +115,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -115,7 +115,7 @@ index dd9c03611e410e601ba4a7769474fada8c28c104..a283cce82069bf5dfd64229d102a19df + } + packet.onPacketDispatch(getPlayer()); + if (connected && (InnerUtil.canSendImmediate(this, packet) || ( -+ net.minecraft.server.MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() && ++ io.papermc.paper.util.MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() && + (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty()) + ))) { this.sendPacket(packet, callbacks); @@ -194,7 +194,7 @@ index dd9c03611e410e601ba4a7769474fada8c28c104..a283cce82069bf5dfd64229d102a19df + if (!isConnected()) { + return true; + } -+ if (net.minecraft.server.MCUtil.isMainThread()) { ++ if (io.papermc.paper.util.MCUtil.isMainThread()) { + return processQueue(); + } else if (isPending) { + // Should only happen during login/status stages diff --git a/patches/server/0318-Configurable-Keep-Spawn-Loaded-range-per-world.patch b/patches/server/0318-Configurable-Keep-Spawn-Loaded-range-per-world.patch index 700270f158..b1bbb41122 100644 --- a/patches/server/0318-Configurable-Keep-Spawn-Loaded-range-per-world.patch +++ b/patches/server/0318-Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Configurable Keep Spawn Loaded range per world This lets you disable it for some worlds and lower it for others. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f9a96a11764b66709a0d74122f9ecc06d0365a93..d6ca6ef7262e25620aceda589d21363193c70310 100644 +index 412380f4bfe8a2d50090904124242e8b2c7bfa1b..1a21f7e590aaeca131256dd7079b9546710ca9ad 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -729,31 +729,34 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -64,14 +64,14 @@ index f9a96a11764b66709a0d74122f9ecc06d0365a93..d6ca6ef7262e25620aceda589d213631 // CraftBukkit start // this.updateMobSpawningFlags(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 84eeb8787c389a3c66b23d567f6c2ebe9644a1ce..a9acb6bd32609489e7442188209f3b7c771eb52f 100644 +index 798ddd562f7dcf97f24cc356742d31befb9eef3e..f7e965d1764f7431eaf2673c7bb0a26a1406207a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -64,6 +64,7 @@ import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket; import net.minecraft.network.protocol.game.ClientboundSoundPacket; import net.minecraft.network.protocol.game.DebugPackets; import net.minecraft.resources.ResourceKey; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerScoreboard; import net.minecraft.server.level.progress.ChunkProgressListener; @@ -200,7 +200,7 @@ index 4d2348df25410a0b5364eec066880326d6667dad..286aad3205ef8a9e21a47ef07893844f this.maxCount = i * i; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 8a8993ff7ec450416ef16941079ee0ac3078767b..a4fc3e4f13b359e3a33b867e4bd200265e020226 100644 +index 5e16798c836d46d08d42a27c549dbdc119803966..919ea3ee6be9877938f9f7743b74b737793bae1d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1346,15 +1346,21 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0321-Fix-World-isChunkGenerated-calls.patch b/patches/server/0321-Fix-World-isChunkGenerated-calls.patch index 973a7c6ae7..8ddbdd16bb 100644 --- a/patches/server/0321-Fix-World-isChunkGenerated-calls.patch +++ b/patches/server/0321-Fix-World-isChunkGenerated-calls.patch @@ -8,7 +8,7 @@ This patch also adds a chunk status cache on region files (note that its only purpose is to cache the status on DISK) diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index d1af0aca0237ee86acd86fea3255ddeadc3db0d6..06b5fecb37621f66780a396774a37292675d90ac 100644 +index b6034a7f6748a87669326e1bcfde351757e88234..b13111521e7ffc9fc3cbcf22d6aff7b18560e469 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -659,9 +659,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -84,7 +84,7 @@ index d1af0aca0237ee86acd86fea3255ddeadc3db0d6..06b5fecb37621f66780a396774a37292 + } + + public ChunkAccess getUnloadingChunk(int chunkX, int chunkZ) { -+ ChunkHolder chunkHolder = net.minecraft.server.ChunkSystem.getUnloadingChunkHolder(this.level, chunkX, chunkZ); ++ ChunkHolder chunkHolder = io.papermc.paper.chunk.system.ChunkSystem.getUnloadingChunkHolder(this.level, chunkX, chunkZ); + return chunkHolder == null ? null : chunkHolder.getAvailableChunkNow(); + } + // Paper end @@ -156,7 +156,7 @@ index 5a25664a15643ff148db47caad4f53376b55168e..7bfb0716964af5ee300150d500c97e8f } catch (Throwable throwable) { if (dataoutputstream != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index a4fc3e4f13b359e3a33b867e4bd200265e020226..37efb3305b4f740d9092c2a253b93f1925ee75d5 100644 +index f3235c80c6eecdeade88ddafaf39c52beadda684..7ff5943949aea15d7b8a48f01ce8e8cb98c78532 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -299,9 +299,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0333-Duplicate-UUID-Resolve-Option.patch b/patches/server/0333-Duplicate-UUID-Resolve-Option.patch index 1bdfb97dc5..830567f338 100644 --- a/patches/server/0333-Duplicate-UUID-Resolve-Option.patch +++ b/patches/server/0333-Duplicate-UUID-Resolve-Option.patch @@ -32,10 +32,10 @@ But for those who are ok with leaving this inconsistent behavior, you may use WA It is recommended you regenerate the entities, as these were legit entities, and deserve your love. -diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java -index 0c6534e64ef023cf613f2c5407c7598c6ed81bc6..d38beb8183470a48c4c927b78fbed243eebcfe71 100644 ---- a/src/main/java/net/minecraft/server/ChunkSystem.java -+++ b/src/main/java/net/minecraft/server/ChunkSystem.java +diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +index 0dc94dec1317b3f86d38074c6cbe41ab828cab1d..0e45a340ae534caf676b7f9d0adcbcee5829925e 100644 +--- a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java ++++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java @@ -73,7 +73,17 @@ public final class ChunkSystem { } @@ -56,7 +56,7 @@ index 0c6534e64ef023cf613f2c5407c7598c6ed81bc6..d38beb8183470a48c4c927b78fbed243 public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 06b5fecb37621f66780a396774a37292675d90ac..67823979209f9b8a3f44cd21baca667457ef110a 100644 +index b13111521e7ffc9fc3cbcf22d6aff7b18560e469..d97e017289783cd8795e055616dd5931bb6147cd 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -522,6 +522,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0351-implement-optional-per-player-mob-spawns.patch b/patches/server/0351-implement-optional-per-player-mob-spawns.patch index b75773f8f5..7d77e64308 100644 --- a/patches/server/0351-implement-optional-per-player-mob-spawns.patch +++ b/patches/server/0351-implement-optional-per-player-mob-spawns.patch @@ -252,7 +252,7 @@ index 0000000000000000000000000000000000000000..11de56afaf059b00fa5bec293516bcdc + } +} diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 3f1bd5e0efa72e8805fcf74f20c0d46f67cfde6b..638d768393c507ff855c7b517434b61736f680d1 100644 +index ec352a1916bea3893173375cfeaf84fc1c3cc52a..7b6a35026978485b676ea92324d3290ad9da3705 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -145,6 +145,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -269,7 +269,7 @@ index 3f1bd5e0efa72e8805fcf74f20c0d46f67cfde6b..638d768393c507ff855c7b517434b617 // Note: players need to be explicitly added to distance maps before they can be updated + // Paper start - per player mob spawning + if (this.playerMobDistanceMap != null) { -+ this.playerMobDistanceMap.add(player, chunkX, chunkZ, net.minecraft.server.ChunkSystem.getTickViewDistance(player)); ++ this.playerMobDistanceMap.add(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); + } + // Paper end - per player mob spawning } @@ -291,7 +291,7 @@ index 3f1bd5e0efa72e8805fcf74f20c0d46f67cfde6b..638d768393c507ff855c7b517434b617 this.playerChunkManager.updatePlayer(player); // Paper - replace chunk loader + // Paper start - per player mob spawning + if (this.playerMobDistanceMap != null) { -+ this.playerMobDistanceMap.update(player, chunkX, chunkZ, net.minecraft.server.ChunkSystem.getTickViewDistance(player)); ++ this.playerMobDistanceMap.update(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); + } + // Paper end - per player mob spawning } @@ -338,7 +338,7 @@ index 3f1bd5e0efa72e8805fcf74f20c0d46f67cfde6b..638d768393c507ff855c7b517434b617 double d0 = (double) SectionPos.sectionToBlockCoord(pos.x, 8); double d1 = (double) SectionPos.sectionToBlockCoord(pos.z, 8); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 70077d3f359944e2df29198ae156be477ebc278d..2d0a8668d1828fe085631079798a36374a0d4844 100644 +index 3a2cacbbba15d48428147842590851a57b3f3df7..8b8c8970e1d478edc3a0231556bf92f8263392c1 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -692,7 +692,18 @@ public class ServerChunkCache extends ChunkSource { @@ -386,7 +386,7 @@ index 9cae5379d60c8d20ae6966850f7f13640742f9b7..f2808d62c15c586dff0313e6d27ef92d // Yes, this doesn't match Vanilla, but it's the best we can do for now. diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index eb4d06cb115f9b923b0441c341523d0df0392049..9fdaf0aecb3c850be63ae9aae0879cb5584c5472 100644 +index 3b8ea490e7b8bd1a6df624e4eb5c7edccaeb800f..25256c422a3274ed75c9a9cd20fbbb709c8b298e 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -69,6 +69,12 @@ public final class NaturalSpawner { diff --git a/patches/server/0375-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0375-Optimize-Collision-to-not-load-chunks.patch index 1296dd9549..d6a997eaf1 100644 --- a/patches/server/0375-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0375-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/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 6e585b79bf2eccc6bfc98d7cdc05efea699d4e2f..78c2872ed6f696053a03e8c37995f4c2f67a9aa6 100644 +index c7ec290b712cf509ce53d5ef3a6785bb15cabbb6..3f2abd13dfcb45601fd3e333626e24ee036706fd 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -797,6 +797,7 @@ public abstract class PlayerList { @@ -26,7 +26,7 @@ index 6e585b79bf2eccc6bfc98d7cdc05efea699d4e2f..78c2872ed6f696053a03e8c37995f4c2 entityplayer1.setPos(entityplayer1.getX(), entityplayer1.getY() + 1.0D, entityplayer1.getZ()); } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 904015183bbaa3ac3976e3d81a7968ebb18c0c41..7326d892f40447b716c93efe2f01fbbb67d6b942 100644 +index e3075bbf737905c3a61ce900fc525d4ed9484b79..5de420c0a2f0881abb03c16b2621d081ef7ad4fd 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -236,6 +236,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -38,7 +38,7 @@ index 904015183bbaa3ac3976e3d81a7968ebb18c0c41..7326d892f40447b716c93efe2f01fbbb public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper diff --git a/src/main/java/net/minecraft/world/level/BlockCollisions.java b/src/main/java/net/minecraft/world/level/BlockCollisions.java -index 8390ce194ccc692139c0e870c16a7fb76ac8ba68..95e22c91bc701785f4804e5d4e0a6b420b9830fd 100644 +index 8390ce194ccc692139c0e870c16a7fb76ac8ba68..be578f14146b0184d5419d5b961c5d681f9ba7a3 100644 --- a/src/main/java/net/minecraft/world/level/BlockCollisions.java +++ b/src/main/java/net/minecraft/world/level/BlockCollisions.java @@ -66,22 +66,41 @@ public class BlockCollisions extends AbstractIterator<VoxelShape> { @@ -57,7 +57,7 @@ index 8390ce194ccc692139c0e870c16a7fb76ac8ba68..95e22c91bc701785f4804e5d4e0a6b42 } + // Paper start - ensure we don't load chunks + final @Nullable Entity source = this.context instanceof net.minecraft.world.phys.shapes.EntityCollisionContext entityContext ? entityContext.getEntity() : null; -+ boolean far = source != null && net.minecraft.server.MCUtil.distanceSq(source.getX(), y, source.getZ(), x, y, z) > 14; ++ boolean far = source != null && io.papermc.paper.util.MCUtil.distanceSq(source.getX(), y, source.getZ(), x, y, z) > 14; + this.pos.set(x, y, z); - BlockGetter blockGetter = this.getChunk(i, k); diff --git a/patches/server/0387-Load-Chunks-for-Login-Asynchronously.patch b/patches/server/0387-Load-Chunks-for-Login-Asynchronously.patch index 38078f50e3..75ce446f87 100644 --- a/patches/server/0387-Load-Chunks-for-Login-Asynchronously.patch +++ b/patches/server/0387-Load-Chunks-for-Login-Asynchronously.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Load Chunks for Login Asynchronously diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 5a2797104d43d5981fe0d4599c0abbbf8658f153..c0e17bbf04723da76ea6952d9558dd4d34b00f6c 100644 +index 7cc21dab89dcb50ee4034e1e39b6a27478fd983b..652d30ce735aa265db848ca73a48d7b0b143103b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -170,6 +170,7 @@ import org.bukkit.event.world.GenericGameEvent; @@ -103,7 +103,7 @@ index 6fd0e5a97d0ed9155b12dac94c075e1225a22e93..c16cb8ebe28987f1630fe659dfa43726 try { ServerPlayer entityplayer1 = this.server.getPlayerList().getPlayerForLogin(this.gameProfile, s); // CraftBukkit - add player reference diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 1096e24835194f20425f75228cafe62adebc2282..f37787b9d018a624b509612729f18ca077b55f55 100644 +index 36aef2836246a33b879b3da3e988539f8615efc5..f5705346debdc940e5b5b3b54a140e3dc0228cb0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -139,6 +139,7 @@ public abstract class PlayerList { @@ -166,7 +166,7 @@ index 1096e24835194f20425f75228cafe62adebc2282..f37787b9d018a624b509612729f18ca0 + final net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ); + net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap; + net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager; -+ net.minecraft.server.ChunkSystem.scheduleTickingState( ++ io.papermc.paper.chunk.system.ChunkSystem.scheduleTickingState( + worldserver1, chunkX, chunkZ, net.minecraft.server.level.ChunkHolder.FullChunkStatus.ENTITY_TICKING, true, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHEST, + (chunk) -> { @@ -266,7 +266,7 @@ index 1096e24835194f20425f75228cafe62adebc2282..f37787b9d018a624b509612729f18ca0 Iterator iterator = list.iterator(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b92dff790cfe699c3e6a036f1377c3052373fe05..237127907c3c8ddcd16bdc9645e84a2d0b922440 100644 +index a2750cba8540caa9f12f5d5179b51f7753d38bba..e5c5a514e6b7bdf663d33074557e34372f18ea77 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1219,7 +1219,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/0415-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch b/patches/server/0415-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch index 90f095a707..a4f92249c6 100644 --- a/patches/server/0415-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch +++ b/patches/server/0415-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimize anyPlayerCloseEnoughForSpawning to use distance maps Use a distance map to find the players in range quickly diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index b550f302b1bb6ef92987c8c3431b94c3ba3a091d..2add24517d38708a84e7f8ec25fbe9c62309375e 100644 +index 2ba3bb4e5670ece798a8882801a856d82851c00a..a61f55ed1fbe5aac5289014cb95cb6950b4c77fa 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -83,16 +83,29 @@ public class ChunkHolder { @@ -15,7 +15,7 @@ index b550f302b1bb6ef92987c8c3431b94c3ba3a091d..2add24517d38708a84e7f8ec25fbe9c6 public void onChunkAdd() { - + // Paper start - optimise anyPlayerCloseEnoughForSpawning -+ long key = net.minecraft.server.MCUtil.getCoordinateKey(this.pos); ++ long key = io.papermc.paper.util.MCUtil.getCoordinateKey(this.pos); + this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key); + this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key); + // Paper end - optimise anyPlayerCloseEnoughForSpawning @@ -42,7 +42,7 @@ index b550f302b1bb6ef92987c8c3431b94c3ba3a091d..2add24517d38708a84e7f8ec25fbe9c6 this.newChunkHolder = newChunkHolder; // Paper - rewrite chunk system this.chunkToSaveHistory = null; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 8dce24ae70057115feff193a1307eb2437e16773..50e9d29b5a0ea6d11a44c41c49d6f52bc464e6e2 100644 +index 999a675dd42c37b27e40d1a32b77641188b8d432..63536642f005b6936734397e2347c504084f3f6c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -152,12 +152,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -69,7 +69,7 @@ index 8dce24ae70057115feff193a1307eb2437e16773..50e9d29b5a0ea6d11a44c41c49d6f52b + this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - per player mob spawning if (this.playerMobDistanceMap != null) { - this.playerMobDistanceMap.add(player, chunkX, chunkZ, net.minecraft.server.ChunkSystem.getTickViewDistance(player)); + this.playerMobDistanceMap.add(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); @@ -168,6 +180,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider void removePlayerFromDistanceMaps(ServerPlayer player) { this.playerChunkManager.removePlayer(player); // Paper - replace chunk loader @@ -88,7 +88,7 @@ index 8dce24ae70057115feff193a1307eb2437e16773..50e9d29b5a0ea6d11a44c41c49d6f52b + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - per player mob spawning if (this.playerMobDistanceMap != null) { - this.playerMobDistanceMap.update(player, chunkX, chunkZ, net.minecraft.server.ChunkSystem.getTickViewDistance(player)); + this.playerMobDistanceMap.update(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); @@ -267,6 +284,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.regionManagers.add(this.dataRegionManager); // Paper end @@ -262,7 +262,7 @@ index d3c3db919e9b0507e8543313d9028394e5163673..52cba8f68d274cce106304aef1249a95 public String getDebugStatus() { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 60264feb656861d5a9474fe4285ac69d8d12269e..44766ea7e5dd8f8411b52cf259187d7557cc0c23 100644 +index 8a20fa6d1c357f6d9787032c31dd0d0f80bd74be..67bcda3e1d343b59dd1842f5eb982a71859d4d7b 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -657,6 +657,37 @@ public class ServerChunkCache extends ChunkSource { @@ -292,8 +292,8 @@ index 60264feb656861d5a9474fe4285ac69d8d12269e..44766ea7e5dd8f8411b52cf259187d75 + } + + int range = Math.min(event.getSpawnRadius(), 32); // limit to max view distance -+ int chunkX = net.minecraft.server.MCUtil.getChunkCoordinate(player.getX()); -+ int chunkZ = net.minecraft.server.MCUtil.getChunkCoordinate(player.getZ()); ++ int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX()); ++ int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); + + playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); + player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning diff --git a/patches/server/0416-Use-distance-map-to-optimise-entity-tracker.patch b/patches/server/0416-Use-distance-map-to-optimise-entity-tracker.patch index 0f18b0a606..e77a5566d5 100644 --- a/patches/server/0416-Use-distance-map-to-optimise-entity-tracker.patch +++ b/patches/server/0416-Use-distance-map-to-optimise-entity-tracker.patch @@ -6,13 +6,13 @@ Subject: [PATCH] Use distance map to optimise entity tracker Use the distance map to find candidate players for tracking. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index a25ef2f2362b6f9b0cc8bfb33b6da66dc0f59347..e75b72d7bb51e50b46e639fbff4d9a01533f50c8 100644 +index 63536642f005b6936734397e2347c504084f3f6c..ed6e0a186dba26bee5ebcc02120c24ecb38d6892 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -66,6 +66,7 @@ import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; import net.minecraft.network.protocol.game.DebugPackets; - import net.minecraft.server.MCUtil; + import io.papermc.paper.util.MCUtil; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.network.ServerPlayerConnection; @@ -42,7 +42,7 @@ index a25ef2f2362b6f9b0cc8bfb33b6da66dc0f59347..e75b72d7bb51e50b46e639fbff4d9a01 void addPlayerToDistanceMaps(ServerPlayer player) { this.playerChunkManager.addPlayer(player); // Paper - replace chunk loader @@ -175,6 +193,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.playerMobDistanceMap.add(player, chunkX, chunkZ, net.minecraft.server.ChunkSystem.getTickViewDistance(player)); + this.playerMobDistanceMap.add(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); } // Paper end - per player mob spawning + // Paper start - use distance map to optimise entity tracker @@ -50,7 +50,7 @@ index a25ef2f2362b6f9b0cc8bfb33b6da66dc0f59347..e75b72d7bb51e50b46e639fbff4d9a01 + com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; + int trackRange = this.entityTrackerTrackRanges[i]; + -+ trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, net.minecraft.server.ChunkSystem.getSendViewDistance(player))); ++ trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player))); + } + // Paper end - use distance map to optimise entity tracker } @@ -69,7 +69,7 @@ index a25ef2f2362b6f9b0cc8bfb33b6da66dc0f59347..e75b72d7bb51e50b46e639fbff4d9a01 void updateMaps(ServerPlayer player) { @@ -202,6 +233,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.playerMobDistanceMap.update(player, chunkX, chunkZ, net.minecraft.server.ChunkSystem.getTickViewDistance(player)); + this.playerMobDistanceMap.update(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); } // Paper end - per player mob spawning + // Paper start - use distance map to optimise entity tracker @@ -77,7 +77,7 @@ index a25ef2f2362b6f9b0cc8bfb33b6da66dc0f59347..e75b72d7bb51e50b46e639fbff4d9a01 + com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; + int trackRange = this.entityTrackerTrackRanges[i]; + -+ trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, net.minecraft.server.ChunkSystem.getSendViewDistance(player))); ++ trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player))); + } + // Paper end - use distance map to optimise entity tracker } @@ -287,14 +287,14 @@ index a25ef2f2362b6f9b0cc8bfb33b6da66dc0f59347..e75b72d7bb51e50b46e639fbff4d9a01 return object instanceof ChunkMap.TrackedEntity ? ((ChunkMap.TrackedEntity) object).entity.getId() == this.entity.getId() : false; } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 32623f90a5bc4fb6fe99897c682ef4f55f056dea..6a86125c6f6daa0a443601db4fea19531225ad33 100644 +index 32623f90a5bc4fb6fe99897c682ef4f55f056dea..26c8b19d484032f5d0935ba8672a3121a3197d67 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -57,6 +57,7 @@ import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; diff --git a/patches/server/0436-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/server/0436-Add-Plugin-Tickets-to-API-Chunk-Methods.patch index a7cfa15425..966d383561 100644 --- a/patches/server/0436-Add-Plugin-Tickets-to-API-Chunk-Methods.patch +++ b/patches/server/0436-Add-Plugin-Tickets-to-API-Chunk-Methods.patch @@ -22,7 +22,7 @@ wants it to collect even faster, they can restore that setting back to 1 instead Not adding it to .getType() though to keep behavior consistent with vanilla for performance reasons. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 262d550e739928fc5f203432138fdcaf6ccb8ddb..007b85cfda82d245ae336efc26aa38ad2f6d2c28 100644 +index 4c6c9aa8b3305f5ab4f7b8d356e860da169fb1db..2aab13270af76bcc1b62787e9910d23d5ab56add 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -360,7 +360,7 @@ public final class CraftServer implements Server { @@ -44,7 +44,7 @@ index 262d550e739928fc5f203432138fdcaf6ccb8ddb..007b85cfda82d245ae336efc26aa38ad this.printSaveWarning = false; console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 414522b641cd866822c13a753cc623c463004fd6..d83ea6113d3f2f7aaeac6e09473282434ec2fc67 100644 +index c3703933598ee96d856a18dcc0932061959c9791..20a08c79d4577d0eb36ab413b36811c828f4f084 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -282,8 +282,21 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -64,7 +64,7 @@ index 414522b641cd866822c13a753cc623c463004fd6..d83ea6113d3f2f7aaeac6e0947328243 + + // Paper start + private void addTicket(int x, int z) { -+ net.minecraft.server.MCUtil.MAIN_EXECUTOR.execute(() -> world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE)); // Paper ++ io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE)); // Paper } + // Paper end @@ -112,7 +112,7 @@ index 414522b641cd866822c13a753cc623c463004fd6..d83ea6113d3f2f7aaeac6e0947328243 return true; // Paper end @@ -2148,6 +2164,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { + io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; + if (chunk != null) addTicket(x, z); // Paper diff --git a/patches/server/0437-incremental-chunk-and-player-saving.patch b/patches/server/0437-incremental-chunk-and-player-saving.patch index 0a9cdfbda3..f7bce0f362 100644 --- a/patches/server/0437-incremental-chunk-and-player-saving.patch +++ b/patches/server/0437-incremental-chunk-and-player-saving.patch @@ -5,7 +5,7 @@ Subject: [PATCH] incremental chunk and player saving diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 1c39e141a392d96548f5ac62fb279ed1f105677d..922475997902dcc85ae42f351ace15e82b5aa638 100644 +index dda33bd52d9c527c37f67b829010c27dba4b667a..e42b12839faab0c040495b00368b107b35b93283 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -864,7 +864,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -53,7 +53,7 @@ index 1c39e141a392d96548f5ac62fb279ed1f105677d..922475997902dcc85ae42f351ace15e8 // Paper start - move executeAll() into full server tick timing try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 44766ea7e5dd8f8411b52cf259187d7557cc0c23..fa7801158b68eaa12d6322c9c0def9de37f03814 100644 +index 018ccef6f9157e95f957915736db61cde920f788..ac1c500fce8c4abbb8ed82908607fe5ded4ee727 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -601,6 +601,15 @@ public class ServerChunkCache extends ChunkSource { @@ -73,7 +73,7 @@ index 44766ea7e5dd8f8411b52cf259187d7557cc0c23..fa7801158b68eaa12d6322c9c0def9de public void close() throws IOException { // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 8cc266e25d25d154158b36e456804ac80a47364e..7ef0eaa6fffae02c3c27313f05eab5ae1558e948 100644 +index cfe370d1cf1b9ce11896a6aa2071eafd4bf64d27..43f668f96aef2c537f4d3fc7913967cebafb3a43 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1122,6 +1122,37 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -127,7 +127,7 @@ index 582b9595aa06dd6787fd84c0ea0058c890f84c33..02bb4ecdc6797d1c5bccc64cc235fe63 private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; public ServerGamePacketListenerImpl connection; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index f37787b9d018a624b509612729f18ca077b55f55..b0120df807a61db21da04324644fbd71a285f461 100644 +index 9aebe7dca9f5085a821f52653fe349aa6c8d2ca1..d75a3e54599c52f510d9dc31c3e44fd9b6fe5b80 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -569,6 +569,7 @@ public abstract class PlayerList { @@ -147,7 +147,7 @@ index f37787b9d018a624b509612729f18ca077b55f55..b0120df807a61db21da04324644fbd71 + } + + public void saveAll(int interval) { - net.minecraft.server.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main + io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main MinecraftTimings.savePlayers.startTiming(); // Paper + int numSaved = 0; + long now = MinecraftServer.currentTick; diff --git a/patches/server/0470-Add-BellRingEvent.patch b/patches/server/0470-Add-BellRingEvent.patch index e6528721cf..6b5fdae03d 100644 --- a/patches/server/0470-Add-BellRingEvent.patch +++ b/patches/server/0470-Add-BellRingEvent.patch @@ -7,14 +7,14 @@ Add a new event, BellRingEvent, to trigger whenever a player rings a village bell. Passes along the bell block and the player who rang it. diff --git a/src/main/java/net/minecraft/world/level/block/BellBlock.java b/src/main/java/net/minecraft/world/level/block/BellBlock.java -index a4da6418c17e145333aa5efe427826ba53293e4d..14002e1f67e3dce421584c01e8f91769509638b7 100644 +index a4da6418c17e145333aa5efe427826ba53293e4d..3dfbc517e8867029b9821ec605dffb1ae476260a 100644 --- a/src/main/java/net/minecraft/world/level/block/BellBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BellBlock.java @@ -3,6 +3,7 @@ package net.minecraft.world.level.block; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -+import net.minecraft.server.MCUtil; ++import io.papermc.paper.util.MCUtil; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.stats.Stats; diff --git a/patches/server/0519-Add-PlayerShearBlockEvent.patch b/patches/server/0519-Add-PlayerShearBlockEvent.patch index 4004036b95..ad60c8efb4 100644 --- a/patches/server/0519-Add-PlayerShearBlockEvent.patch +++ b/patches/server/0519-Add-PlayerShearBlockEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerShearBlockEvent diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -index 8dff119fa83e44d71b10bb3ea6e5f4e886a48c9c..1aaab26c59bb9255955aff34ea1d057b88152768 100644 +index 8dff119fa83e44d71b10bb3ea6e5f4e886a48c9c..dd51ea83935028a083c9cf368e6826fa32c00462 100644 --- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java @@ -113,7 +113,7 @@ public class BeehiveBlock extends BaseEntityBlock { @@ -22,7 +22,7 @@ index 8dff119fa83e44d71b10bb3ea6e5f4e886a48c9c..1aaab26c59bb9255955aff34ea1d057b if (itemstack.is(Items.SHEARS)) { + // Paper start - Add PlayerShearBlockEvent -+ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), net.minecraft.server.MCUtil.toBukkitBlock(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (hand == InteractionHand.OFF_HAND ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND), new java.util.ArrayList<>()); ++ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (hand == InteractionHand.OFF_HAND ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND), new java.util.ArrayList<>()); + event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.HONEYCOMB, 3))); + if (!event.callEvent()) { + return InteractionResult.PASS; @@ -39,7 +39,7 @@ index 8dff119fa83e44d71b10bb3ea6e5f4e886a48c9c..1aaab26c59bb9255955aff34ea1d057b entityhuman1.broadcastBreakEvent(hand); }); diff --git a/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java b/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java -index 0e8cbe7a465edc31b78b7e47a928435f9c2b6bd9..f998598a34315389dd74b82e4b9c8448f0aae253 100644 +index 0e8cbe7a465edc31b78b7e47a928435f9c2b6bd9..4568d1659dda897de5f6c2059629a4718d401e63 100644 --- a/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java @@ -27,13 +27,24 @@ public class PumpkinBlock extends StemGrownBlock { @@ -47,7 +47,7 @@ index 0e8cbe7a465edc31b78b7e47a928435f9c2b6bd9..f998598a34315389dd74b82e4b9c8448 if (itemStack.is(Items.SHEARS)) { if (!world.isClientSide) { + // Paper start - Add PlayerShearBlockEvent -+ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), net.minecraft.server.MCUtil.toBukkitBlock(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (hand == InteractionHand.OFF_HAND ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND), new java.util.ArrayList<>()); ++ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (hand == InteractionHand.OFF_HAND ? org.bukkit.inventory.EquipmentSlot.OFF_HAND : org.bukkit.inventory.EquipmentSlot.HAND), new java.util.ArrayList<>()); + event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.PUMPKIN_SEEDS, 4))); + if (!event.callEvent()) { + return InteractionResult.PASS; diff --git a/patches/server/0556-Add-StructuresLocateEvent.patch b/patches/server/0556-Add-StructuresLocateEvent.patch index 42d31007ce..f7bf54d7de 100644 --- a/patches/server/0556-Add-StructuresLocateEvent.patch +++ b/patches/server/0556-Add-StructuresLocateEvent.patch @@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..423bf87ebda7ea266dc7b48cbfadbc85 + } +} diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 6e2185bbaac889d51a54ec97907da3b1faa465c4..50b9c2fbe3a5c12a43b4711d678ed2398dbdee58 100644 +index 6e2185bbaac889d51a54ec97907da3b1faa465c4..c35bf0709e83e05c2135d7a5c98bf44c48d0c31f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -295,6 +295,26 @@ public abstract class ChunkGenerator { @@ -81,7 +81,7 @@ index 6e2185bbaac889d51a54ec97907da3b1faa465c4..50b9c2fbe3a5c12a43b4711d678ed239 public Pair<BlockPos, Holder<Structure>> findNearestMapStructure(ServerLevel world, HolderSet<Structure> structures, BlockPos center, int radius, boolean skipReferencedStructures) { + // Paper start - StructureLocateEvent + final org.bukkit.World bukkitWorld = world.getWorld(); -+ final org.bukkit.Location origin = net.minecraft.server.MCUtil.toLocation(world, center); ++ final org.bukkit.Location origin = io.papermc.paper.util.MCUtil.toLocation(world, center); + final var paperRegistry = io.papermc.paper.registry.PaperRegistry.getRegistry(io.papermc.paper.registry.RegistryKey.CONFIGURED_STRUCTURE_REGISTRY); + final List<io.papermc.paper.world.structure.ConfiguredStructure> configuredStructures = new ArrayList<>(); + paperRegistry.convertToApi(structures, configuredStructures::add, false); // gracefully handle missing api, use tests to check (or exclude) @@ -91,9 +91,9 @@ index 6e2185bbaac889d51a54ec97907da3b1faa465c4..50b9c2fbe3a5c12a43b4711d678ed239 + return null; + } + if (event.getResult() != null) { -+ return Pair.of(net.minecraft.server.MCUtil.toBlockPosition(event.getResult().position()), paperRegistry.getMinecraftHolder(event.getResult().configuredStructure())); ++ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPosition(event.getResult().position()), paperRegistry.getMinecraftHolder(event.getResult().configuredStructure())); + } -+ center = net.minecraft.server.MCUtil.toBlockPosition(event.getOrigin()); ++ center = io.papermc.paper.util.MCUtil.toBlockPosition(event.getOrigin()); + radius = event.getRadius(); + skipReferencedStructures = event.shouldFindUnexplored(); + structures = HolderSet.direct(paperRegistry::getMinecraftHolder, event.getConfiguredStructures()); diff --git a/patches/server/0646-Add-BellRevealRaiderEvent.patch b/patches/server/0646-Add-BellRevealRaiderEvent.patch index 587e0f0400..416490bb3d 100644 --- a/patches/server/0646-Add-BellRevealRaiderEvent.patch +++ b/patches/server/0646-Add-BellRevealRaiderEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BellRevealRaiderEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java -index feaad48e9bbc1e658324ef9e1e7e73aca0b3bf48..b9d2c38e80924f52dcf76ec1042d2d746e77ffc6 100644 +index feaad48e9bbc1e658324ef9e1e7e73aca0b3bf48..648d8f3e72e30aacf68eb073a1ac30f8ec29503c 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java @@ -138,7 +138,7 @@ public class BellBlockEntity extends BlockEntity { @@ -25,7 +25,7 @@ index feaad48e9bbc1e658324ef9e1e7e73aca0b3bf48..b9d2c38e80924f52dcf76ec1042d2d74 + // Paper start + private static void glow(LivingEntity entity) { glow(entity, null); } + private static void glow(LivingEntity entity, @javax.annotation.Nullable BlockPos pos) { -+ if (pos != null && !new io.papermc.paper.event.block.BellRevealRaiderEvent(entity.level.getWorld().getBlockAt(net.minecraft.server.MCUtil.toLocation(entity.level, pos)), entity.getBukkitEntity()).callEvent()) return; ++ if (pos != null && !new io.papermc.paper.event.block.BellRevealRaiderEvent(entity.level.getWorld().getBlockAt(io.papermc.paper.util.MCUtil.toLocation(entity.level, pos)), entity.getBukkitEntity()).callEvent()) return; + // Paper end entity.addEffect(new MobEffectInstance(MobEffects.GLOWING, 60)); } diff --git a/patches/server/0657-Missing-Entity-Behavior-API.patch b/patches/server/0657-Missing-Entity-Behavior-API.patch index 08e11a769d..4b391ea8d6 100644 --- a/patches/server/0657-Missing-Entity-Behavior-API.patch +++ b/patches/server/0657-Missing-Entity-Behavior-API.patch @@ -70,7 +70,7 @@ index 5ffae9d3be22b5e78645da57a6bd0e7350749ef1..9aec9f80c564fa3ae03e445423d9e50a public Llama(EntityType<? extends Llama> type, Level world) { super(type, world); diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index 1fc862a3b5d40a45cf91703051bcfb06ec1b177a..02d7cd9cd27ff9254c3e99e3e94309a8cb8b243d 100644 +index 0d36a903b7aa8d26232e6edcb0fdbba1defde660..d4d7830ab5b9944c38a301a0e2a2150063adf229 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java @@ -84,6 +84,11 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @@ -225,7 +225,7 @@ index 254d4f2e45d7c8f572a4368eccd84560d4d0d836..299ab868252c8f326e3a56e878c9ee23 + // Paper end - Horse API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java -index 3b960a832df1fe496ea036962083f1ac507a7db7..ee5534972a2b26402f29b146d1f3da69052672b0 100644 +index 3b960a832df1fe496ea036962083f1ac507a7db7..8f25bb253c2b22e1964afeae705901e926432ef0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java @@ -33,4 +33,25 @@ public class CraftBat extends CraftAmbient implements Bat { @@ -240,14 +240,14 @@ index 3b960a832df1fe496ea036962083f1ac507a7db7..ee5534972a2b26402f29b146d1f3da69 + return null; + } + -+ return net.minecraft.server.MCUtil.toLocation(this.getHandle().getLevel(), pos); ++ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().getLevel(), pos); + } + + @Override + public void setTargetLocation(org.bukkit.Location location) { + net.minecraft.core.BlockPos pos = null; + if (location != null) { -+ pos = net.minecraft.server.MCUtil.toBlockPosition(location); ++ pos = io.papermc.paper.util.MCUtil.toBlockPosition(location); + } + + this.getHandle().targetPosition = pos; @@ -663,7 +663,7 @@ index ff9f711b83a8ea1bf4135751a9ba865224bce787..1f6dcad764240e15083731d017f9bb1c @Override public boolean isRolling() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java -index dce23f3878b1588c26b6116d80e597d08070edbc..eaa0358051c4ac32cc7e6a45039374dd5c036fa2 100644 +index dce23f3878b1588c26b6116d80e597d08070edbc..5a8fd2910204550537c04ae8754b50f70a445bb1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java @@ -50,5 +50,25 @@ public class CraftPhantom extends CraftFlying implements Phantom { @@ -678,14 +678,14 @@ index dce23f3878b1588c26b6116d80e597d08070edbc..eaa0358051c4ac32cc7e6a45039374dd + return null; + } + -+ return net.minecraft.server.MCUtil.toLocation(this.getHandle().getLevel(), pos); ++ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().getLevel(), pos); + } + + @Override + public void setAnchorLocation(org.bukkit.Location location) { + net.minecraft.core.BlockPos pos = null; + if (location != null) { -+ pos = net.minecraft.server.MCUtil.toBlockPosition(location); ++ pos = io.papermc.paper.util.MCUtil.toBlockPosition(location); + } + + this.getHandle().anchorPoint = pos; @@ -884,7 +884,7 @@ index 8a0a905f6701c6e94cbbf15793788350958fb728..2a74e6ecb4f57bc6879b37f7bc067541 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java -index fa7107593b20e0151d8d67104e4a92dcc697d461..d3618b2fd698552b2331f1114654b3339f3f066f 100644 +index fa7107593b20e0151d8d67104e4a92dcc697d461..ec6bbac3462ebe289b69f7a116802e34658b09c5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java @@ -55,5 +55,25 @@ public class CraftWanderingTrader extends CraftAbstractVillager implements Wande @@ -899,14 +899,14 @@ index fa7107593b20e0151d8d67104e4a92dcc697d461..d3618b2fd698552b2331f1114654b333 + return null; + } + -+ return net.minecraft.server.MCUtil.toLocation(this.getHandle().getLevel(), pos); ++ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().getLevel(), pos); + } + + @Override + public void setWanderingTowards(org.bukkit.Location location) { + net.minecraft.core.BlockPos pos = null; + if (location != null) { -+ pos = net.minecraft.server.MCUtil.toBlockPosition(location); ++ pos = io.papermc.paper.util.MCUtil.toBlockPosition(location); + } + + this.getHandle().wanderTarget = pos; diff --git a/patches/server/0661-Fix-commands-from-signs-not-firing-command-events.patch b/patches/server/0661-Fix-commands-from-signs-not-firing-command-events.patch index c66c6d829d..67844b2f67 100644 --- a/patches/server/0661-Fix-commands-from-signs-not-firing-command-events.patch +++ b/patches/server/0661-Fix-commands-from-signs-not-firing-command-events.patch @@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..01a2bc1feec808790bb93618ce46adb9 + } +} diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 831db5ee21938d71e99bf9d17b92a6ca15531740..def4fdd2c7e4f925fa128692a744e5d10ae0203a 100644 +index 831db5ee21938d71e99bf9d17b92a6ca15531740..58599ead28c25a76d9f41d2d29ee8024c9afdccd 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java @@ -40,6 +40,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C @@ -79,7 +79,7 @@ index 831db5ee21938d71e99bf9d17b92a6ca15531740..def4fdd2c7e4f925fa128692a744e5d1 + if (org.spigotmc.SpigotConfig.logCommands) { + LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command); + } -+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(player.getBukkitEntity(), command, new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), (org.bukkit.block.Sign) net.minecraft.server.MCUtil.toBukkitBlock(this.level, this.worldPosition).getState()); ++ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(player.getBukkitEntity(), command, new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), (org.bukkit.block.Sign) io.papermc.paper.util.MCUtil.toBukkitBlock(this.level, this.worldPosition).getState()); + if (!event.callEvent()) { + return false; + } diff --git a/patches/server/0677-Add-PlayerSetSpawnEvent.patch b/patches/server/0677-Add-PlayerSetSpawnEvent.patch index 4f372eda86..909d181d2f 100644 --- a/patches/server/0677-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0677-Add-PlayerSetSpawnEvent.patch @@ -32,7 +32,7 @@ index ce1c7512cc368e196ae94ee22c6a228c975b4980..1e41de9523c5fa3b9cfced798a5c35a2 String string = resourceKey.location().toString(); if (targets.size() == 1) { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index a02b02c71ac6dddcccb10a6aa7993337ed04b829..18f67094f0ce0902963a118744f9fd48f53273c8 100644 +index a02b02c71ac6dddcccb10a6aa7993337ed04b829..3fdb52e31e4e845ddf61fc3695c0c85362eab708 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -1272,7 +1272,7 @@ public class ServerPlayer extends Player { @@ -58,7 +58,7 @@ index a02b02c71ac6dddcccb10a6aa7993337ed04b829..18f67094f0ce0902963a118744f9fd48 + boolean willNotify = false; if (pos != null) { boolean flag2 = pos.equals(this.respawnPosition) && dimension.equals(this.respawnDimension); -+ spawnLoc = net.minecraft.server.MCUtil.toLocation(this.getServer().getLevel(dimension), pos); ++ spawnLoc = io.papermc.paper.util.MCUtil.toLocation(this.getServer().getLevel(dimension), pos); + spawnLoc.setYaw(angle); + willNotify = sendMessage && !flag2; + } @@ -68,7 +68,7 @@ index a02b02c71ac6dddcccb10a6aa7993337ed04b829..18f67094f0ce0902963a118744f9fd48 + } + if (event.getLocation() != null) { + dimension = event.getLocation().getWorld() != null ? ((CraftWorld) event.getLocation().getWorld()).getHandle().dimension() : dimension; -+ pos = net.minecraft.server.MCUtil.toBlockPosition(event.getLocation()); ++ pos = io.papermc.paper.util.MCUtil.toBlockPosition(event.getLocation()); + angle = (float) event.getLocation().getYaw(); + forced = event.isForced(); + // Paper end @@ -89,7 +89,7 @@ index a02b02c71ac6dddcccb10a6aa7993337ed04b829..18f67094f0ce0902963a118744f9fd48 public void trackChunk(ChunkPos chunkPos, Packet<?> chunkDataPacket) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 627cf258312e5dc7a129286de6dcb4c028f846ac..456031783aa902c8fd40050aa2b8d051b996d71d 100644 +index f0fe73f53d26ed8a527d0791a41ca0c9773319ca..3b583f3070cecf1e9c751c9a80592aadb8376ba4 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -902,13 +902,13 @@ public abstract class PlayerList { diff --git a/patches/server/0693-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/server/0693-Add-methods-to-find-targets-for-lightning-strikes.patch index e8d2853750..c586250bee 100644 --- a/patches/server/0693-Add-methods-to-find-targets-for-lightning-strikes.patch +++ b/patches/server/0693-Add-methods-to-find-targets-for-lightning-strikes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add methods to find targets for lightning strikes diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 6b1124ee45b40b49fdbf7e5d3b0349986112afc4..0070f82f7725f584a177464cc8dc543b7a5c78e1 100644 +index 56afb3c6a0c575e793e6c30cfb42596fcb83dd4f..c0dd56bc2eb8cdcf8a7dc20904f5a33f4a90f8a2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -815,6 +815,11 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -29,7 +29,7 @@ index 6b1124ee45b40b49fdbf7e5d3b0349986112afc4..0070f82f7725f584a177464cc8dc543b blockposition1 = blockposition1.above(2); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b6aefca1ef13ddbe4f79b91cfed4fbc109b89475..5a3e498776a35770a19535751f9dfcc1573035d7 100644 +index cad1d4be462a53567dc56472f90d9aacdf82be99..31659cf6decac7cb83b83b09a17eaf91be656b53 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -686,6 +686,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -39,8 +39,8 @@ index b6aefca1ef13ddbe4f79b91cfed4fbc109b89475..5a3e498776a35770a19535751f9dfcc1 + // Paper start + @Override + public Location findLightningRod(Location location) { -+ return this.world.findLightningRod(net.minecraft.server.MCUtil.toBlockPosition(location)) -+ .map(blockPos -> net.minecraft.server.MCUtil.toLocation(this.world, blockPos) ++ return this.world.findLightningRod(io.papermc.paper.util.MCUtil.toBlockPosition(location)) ++ .map(blockPos -> io.papermc.paper.util.MCUtil.toLocation(this.world, blockPos) + // get the actual rod pos + .subtract(0, 1, 0)) + .orElse(null); @@ -48,8 +48,8 @@ index b6aefca1ef13ddbe4f79b91cfed4fbc109b89475..5a3e498776a35770a19535751f9dfcc1 + + @Override + public Location findLightningTarget(Location location) { -+ final BlockPos pos = this.world.findLightningTargetAround(net.minecraft.server.MCUtil.toBlockPosition(location), true); -+ return pos == null ? null : net.minecraft.server.MCUtil.toLocation(this.world, pos); ++ final BlockPos pos = this.world.findLightningTargetAround(io.papermc.paper.util.MCUtil.toBlockPosition(location), true); ++ return pos == null ? null : io.papermc.paper.util.MCUtil.toLocation(this.world, pos); + } + // Paper end + diff --git a/patches/server/0710-Allow-controlled-flushing-for-network-manager.patch b/patches/server/0710-Allow-controlled-flushing-for-network-manager.patch index a88de7918e..39d52d0a18 100644 --- a/patches/server/0710-Allow-controlled-flushing-for-network-manager.patch +++ b/patches/server/0710-Allow-controlled-flushing-for-network-manager.patch @@ -9,7 +9,7 @@ This patch will be used to optimise out flush calls in later patches. diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 2f38d04b369b345c89f85cee32081df8baf4239f..13ab14b1fb3acfd245fbab35f84f5c30c97ed855 100644 +index 02cab94e208303a738adebaffe5929703d8bf0b3..af5d81778bf0dd3f227d64faeb814f2b234e7332 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -121,6 +121,39 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -53,7 +53,7 @@ index 2f38d04b369b345c89f85cee32081df8baf4239f..13ab14b1fb3acfd245fbab35f84f5c30 this.receiving = side; } @@ -286,7 +319,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { - net.minecraft.server.MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() && + io.papermc.paper.util.MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() && (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty()) ))) { - this.sendPacket(packet, callbacks); diff --git a/patches/server/0733-Optimise-nearby-player-lookups.patch b/patches/server/0733-Optimise-nearby-player-lookups.patch index 9cde1dc358..7a0d38249a 100644 --- a/patches/server/0733-Optimise-nearby-player-lookups.patch +++ b/patches/server/0733-Optimise-nearby-player-lookups.patch @@ -9,7 +9,7 @@ since the penalty of a map lookup could outweigh the benefits of searching less players (as it basically did in the outside range patch). diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index dcb1318a3e676598f3b64279da77aa1170a94c42..10a5762e3d5540e24839f82ea875b4daeb9f0603 100644 +index e11ec87e8007979a1c6932b414bcd70c10db746c..bc46479fd0622a90fd98ac88f92b2840a22a2d04 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -93,6 +93,12 @@ public class ChunkHolder { @@ -39,7 +39,7 @@ index dcb1318a3e676598f3b64279da77aa1170a94c42..10a5762e3d5540e24839f82ea875b4da // Paper end diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 134274a7e36f14d855f659df37e0ba24d93fdad7..2a7cdaabbb772520ced0eb1dcd827bd93ebbc59b 100644 +index 0abcc48cea5f0ca99d9ad5b753cc0c5bc91e97d9..43466ce2b9ce583a5af067937ce9c47f7635f56d 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -152,6 +152,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -56,7 +56,7 @@ index 134274a7e36f14d855f659df37e0ba24d93fdad7..2a7cdaabbb772520ced0eb1dcd827bd9 // Paper start - distance maps private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); @@ -204,6 +210,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, net.minecraft.server.ChunkSystem.getSendViewDistance(player))); + trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player))); } // Paper end - use distance map to optimise entity tracker + this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn @@ -72,7 +72,7 @@ index 134274a7e36f14d855f659df37e0ba24d93fdad7..2a7cdaabbb772520ced0eb1dcd827bd9 if (this.playerMobDistanceMap != null) { this.playerMobDistanceMap.remove(player); @@ -244,6 +252,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, net.minecraft.server.ChunkSystem.getSendViewDistance(player))); + trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player))); } // Paper end - use distance map to optimise entity tracker + this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn @@ -104,7 +104,7 @@ index 134274a7e36f14d855f659df37e0ba24d93fdad7..2a7cdaabbb772520ced0eb1dcd827bd9 protected ChunkGenerator generator() { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 60d354bce53b5101dc986d0c35d82ac9dbbbd016..2112b7aef36054c9854c13cc5e9fb4c05bf18c6e 100644 +index 195c50c7ba10b784c372046d956b54fccf684812..48c5a62ea9c0441fa14300aff4dab44cc26090c5 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -442,6 +442,84 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -226,7 +226,7 @@ index b9685fa96bb59b4b080ffd0ac53e4c5581aaeb8b..fffa6ba329b38433a1df51df339df652 if (entityhuman != null) { double d0 = entityhuman.distanceToSqr((Entity) this); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index aa90454e70e5c25eb331ceb212df3128d64b1567..c1a3bcc8d9df2bf25a9c73faeac84652756d430a 100644 +index b5fd3a9b58fb56db92d579d307edc99bbe344c79..09c2d318330e03d0230a82b30985bba3a4231615 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -205,6 +205,69 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -300,7 +300,7 @@ index aa90454e70e5c25eb331ceb212df3128d64b1567..c1a3bcc8d9df2bf25a9c73faeac84652 public abstract ResourceKey<LevelStem> getTypeKey(); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index e0b6f7da138776be2892821b32a099c2d0e45038..df83b6f0e217eec4c9e9707be0030c129fdeb545 100644 +index edd32b6d5a96a6fffe641a23c27921e6dcf37a54..272bdc088f440cf94850dff6e626331b4b5d6539 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -259,7 +259,7 @@ public final class NaturalSpawner { @@ -322,7 +322,7 @@ index e0b6f7da138776be2892821b32a099c2d0e45038..df83b6f0e217eec4c9e9707be0030c12 private static Boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) { // Paper diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 07eeea03796cd6330a9788ef357cf307a02b4ace..258d00692fa50e0932747a7a2f0ddae5ab659040 100644 +index 97a1972b8e4359b4327fa0b0ac1fb82966122a27..6c31e246b49dfa2447f3179b744b0b3842d1509e 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -269,6 +269,98 @@ public class LevelChunk extends ChunkAccess { diff --git a/patches/server/0804-Dolphin-API.patch b/patches/server/0804-Dolphin-API.patch index 4bb12a6785..7b62597b9e 100644 --- a/patches/server/0804-Dolphin-API.patch +++ b/patches/server/0804-Dolphin-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Dolphin API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java -index 938e141f161acf5de5d3361382b514caea02c6fb..75919bf87b6f5cad06ca76888e284e2548594f00 100644 +index 938e141f161acf5de5d3361382b514caea02c6fb..c1db88ceb65eb81c542171fc5465224ef613ce3b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java @@ -24,4 +24,34 @@ public class CraftDolphin extends CraftWaterMob implements Dolphin { @@ -35,11 +35,11 @@ index 938e141f161acf5de5d3361382b514caea02c6fb..75919bf87b6f5cad06ca76888e284e25 + + @Override + public org.bukkit.Location getTreasureLocation() { -+ return net.minecraft.server.MCUtil.toLocation(this.getHandle().level, this.getHandle().getTreasurePos()); ++ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().level, this.getHandle().getTreasurePos()); + } + + @Override + public void setTreasureLocation(org.bukkit.Location location) { -+ this.getHandle().setTreasurePos(net.minecraft.server.MCUtil.toBlockPosition(location)); ++ this.getHandle().setTreasurePos(io.papermc.paper.util.MCUtil.toBlockPosition(location)); + } } |