diff --git a/patches/server/0047-Ensure-commands-are-not-ran-async.patch b/patches/server/0047-Ensure-commands-are-not-ran-async.patch index 23f388d11..2b9b71074 100644 --- a/patches/server/0047-Ensure-commands-are-not-ran-async.patch +++ b/patches/server/0047-Ensure-commands-are-not-ran-async.patch @@ -14,7 +14,7 @@ big slowdown in execution but throwing an exception at same time to raise awaren that it is happening so that plugin authors can fix their code to stop executing commands async. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9b47d8ab57c3b290173247ba25ad7668f3529903..28c4e16e202876e58447b1f766619e3cee329aaa 100644 +index 9b47d8ab57c3b290173247ba25ad7668f3529903..6f99b1b54fe893240143282563cb59e6c9cd4122 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1871,6 +1871,29 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser @@ -24,8 +24,8 @@ index 9b47d8ab57c3b290173247ba25ad7668f3529903..28c4e16e202876e58447b1f766619e3c + // Paper Start + if (!org.spigotmc.AsyncCatcher.shuttingDown && !org.bukkit.Bukkit.isPrimaryThread()) { + final String fCommandLine = s; -+ MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine); -+ MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); ++ LOGGER.error("Command Dispatched Async: " + fCommandLine); ++ LOGGER.error("Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); + Waitable wait = new Waitable() { + @Override + protected Object evaluate() { diff --git a/patches/server/0070-Use-a-Shared-Random-for-Entities.patch b/patches/server/0070-Use-a-Shared-Random-for-Entities.patch index 505022ba2..3d805466e 100644 --- a/patches/server/0070-Use-a-Shared-Random-for-Entities.patch +++ b/patches/server/0070-Use-a-Shared-Random-for-Entities.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Use a Shared Random for Entities Reduces memory usage and provides ensures more randomness, Especially since a lot of garbage entity objects get created. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 78fd9e84e24b163b4918ba0580abca18806f4988..f12e282dc4683d0430b9dba552757c4da5dee988 100644 +index 78fd9e84e24b163b4918ba0580abca18806f4988..8e746391d6e3393a19e0f0cb3b28b6722df55510 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -155,6 +155,21 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i @@ -19,7 +19,7 @@ index 78fd9e84e24b163b4918ba0580abca18806f4988..f12e282dc4683d0430b9dba552757c4d + @Override + public synchronized void setSeed(long seed) { + if (locked) { -+ LogManager.getLogger().error("Ignoring setSeed on Entity.SHARED_RANDOM", new Throwable()); ++ LOGGER.error("Ignoring setSeed on Entity.SHARED_RANDOM", new Throwable()); + } else { + super.setSeed(seed); + locked = true; diff --git a/patches/server/0184-Player.setPlayerProfile-API.patch b/patches/server/0184-Player.setPlayerProfile-API.patch index cac4d119b..ea73455dd 100644 --- a/patches/server/0184-Player.setPlayerProfile-API.patch +++ b/patches/server/0184-Player.setPlayerProfile-API.patch @@ -24,7 +24,7 @@ index d3462cdc5eee37cedbff80f35d5b9c51e8dcd1da..5ebc450432805d52457b9f8ff1e2b198 playerName = gameProfile.getName(); uniqueId = gameProfile.getId(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6eaf970663bf5de9ea30db879e135c5e06238b41..e1d81be0a7ad66fc77c89563fd4e814ce80e24a7 100644 +index 6eaf970663bf5de9ea30db879e135c5e06238b41..0895b09a6fa52697ad36b6de84bc3ba3c6ceef3a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -72,6 +72,7 @@ import net.minecraft.world.entity.ai.attributes.Attributes; @@ -129,7 +129,7 @@ index 6eaf970663bf5de9ea30db879e135c5e06238b41..e1d81be0a7ad66fc77c89563fd4e814c + + //Respawn the player then update their position and selected slot + ServerLevel worldserver = handle.getLevel(); -+ connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(worldserver.dimensionType(), worldserver.dimension(), BiomeManager.obfuscateSeed(worldserver.getSeed()), handle.gameMode.getGameModeForPlayer(), handle.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), true)); ++ connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(worldserver.dimensionTypeRegistration(), worldserver.dimension(), BiomeManager.obfuscateSeed(worldserver.getSeed()), handle.gameMode.getGameModeForPlayer(), handle.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), true)); + handle.onUpdateAbilities(); + connection.send(new net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), java.util.Collections.emptySet(), 0, false)); + net.minecraft.server.MinecraftServer.getServer().getPlayerList().sendAllPlayerInfo(handle); diff --git a/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch b/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch index 736fc64b7..77cc4faad 100644 --- a/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch +++ b/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch @@ -161,7 +161,7 @@ index 0fda52841b5e1643efeda92106124998abc4e0aa..fe79c0add4f7cb18d487c5bb9415c40c public static Timing getTickList(ServerLevel worldserver, String timingsType) { diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index d9114c5fa141c37270398100db6bb2a8a8e4ed1e..7cec7a377d64dd00ea6fb8f82af489d4bf3bf572 100644 +index 62671d6c04f973594a6ca95446774c4b5a78a575..7682300eec0d097798c1bd68de519513c438fd17 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -1,5 +1,6 @@ @@ -300,18 +300,18 @@ index 0000000000000000000000000000000000000000..5af0ac3d9e87c06053e65433060f1577 +} diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java new file mode 100644 -index 0000000000000000000000000000000000000000..a630a84b60b4517e3bc330d4983b914bd064efa4 +index 0000000000000000000000000000000000000000..ab583855d46e2adc56e503f191bdb523c2afdd91 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java @@ -0,0 +1,606 @@ +package com.destroystokyo.paper.io; + ++import com.mojang.logging.LogUtils; +import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.storage.RegionFile; -+import org.apache.logging.log4j.Logger; ++import org.slf4j.Logger; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; @@ -343,7 +343,7 @@ index 0000000000000000000000000000000000000000..a630a84b60b4517e3bc330d4983b914b + */ +public final class PaperFileIOThread extends QueueExecutorThread { + -+ public static final Logger LOGGER = MinecraftServer.LOGGER; ++ public static final Logger LOGGER = LogUtils.getLogger(); + public static final CompoundTag FAILURE_VALUE = new CompoundTag(); + + public static final class Holder { @@ -362,7 +362,7 @@ index 0000000000000000000000000000000000000000..a630a84b60b4517e3bc330d4983b914b + this.setName("Paper RegionFile IO Thread"); + this.setPriority(Thread.NORM_PRIORITY - 1); // we keep priority close to normal because threads can wait on us + this.setUncaughtExceptionHandler((final Thread unused, final Throwable thr) -> { -+ LOGGER.fatal("Uncaught exception thrown from IO thread, report this!", thr); ++ LOGGER.error("Uncaught exception thrown from IO thread, report this!", thr); + }); + } + @@ -717,7 +717,7 @@ index 0000000000000000000000000000000000000000..a630a84b60b4517e3bc330d4983b914b + if (throwable instanceof ThreadDeath) { + throw (ThreadDeath)throwable; + } -+ LOGGER.fatal("Failed to execute general task on IO thread " + IOUtil.genericToString(this.run), throwable); ++ LOGGER.error("Failed to execute general task on IO thread " + IOUtil.genericToString(this.run), throwable); + } + } + } @@ -816,7 +816,7 @@ index 0000000000000000000000000000000000000000..a630a84b60b4517e3bc330d4983b914b + if (thr instanceof ThreadDeath) { + throw (ThreadDeath)thr; + } -+ LOGGER.fatal("Failed to read chunk data for task: " + this.toString(), thr); ++ LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); + // fall through to complete with null data + } + read.readFuture.complete(compound); @@ -874,7 +874,7 @@ index 0000000000000000000000000000000000000000..a630a84b60b4517e3bc330d4983b914b + if (thr instanceof ThreadDeath) { + throw (ThreadDeath)thr; + } -+ LOGGER.fatal("Failed to write chunk data for task: " + this.toString(), thr); ++ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); + failedWrite = true; + } + @@ -1216,14 +1216,14 @@ index 0000000000000000000000000000000000000000..24fe40c14cc50f8357a9c7a7493140fd +} diff --git a/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java new file mode 100644 -index 0000000000000000000000000000000000000000..64b772dc1ed857ccd6999591f89dd89aface0649 +index 0000000000000000000000000000000000000000..f1b940704400266e6df186139b57ec72ae314448 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java @@ -0,0 +1,254 @@ +package com.destroystokyo.paper.io; + -+import net.minecraft.server.MinecraftServer; -+import org.apache.logging.log4j.Logger; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; @@ -1231,7 +1231,7 @@ index 0000000000000000000000000000000000000000..64b772dc1ed857ccd6999591f89dd89a + +public class QueueExecutorThread extends Thread { + -+ private static final Logger LOGGER = MinecraftServer.LOGGER; ++ private static final Logger LOGGER = LogUtils.getLogger(); + + protected final PrioritizedTaskQueue queue; + protected final long spinWaitTime; @@ -1342,7 +1342,7 @@ index 0000000000000000000000000000000000000000..64b772dc1ed857ccd6999591f89dd89a + if (throwable instanceof ThreadDeath) { + throw (ThreadDeath)throwable; + } -+ LOGGER.fatal("Exception thrown from prioritized runnable task in thread '" + this.getName() + "': " + IOUtil.genericToString(task), throwable); ++ LOGGER.error("Exception thrown from prioritized runnable task in thread '" + this.getName() + "': " + IOUtil.genericToString(task), throwable); + } + } + @@ -1783,7 +1783,7 @@ index 0000000000000000000000000000000000000000..058fb5a41565e6ce2acbd1f4d071a1b8 +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..db6f8ac2ae068d5bc2ec2d587ab625c4956f6947 +index 0000000000000000000000000000000000000000..abf62796cfbfa61392b0776b28eb6bfc284053c1 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java @@ -0,0 +1,505 @@ @@ -1876,16 +1876,16 @@ index 0000000000000000000000000000000000000000..db6f8ac2ae068d5bc2ec2d587ab625c4 + public static void dumpAllChunkLoadInfo() { + ChunkInfo[] chunks = getChunkInfos(); + if (chunks.length > 0) { -+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk wait task info below: "); ++ PaperFileIOThread.LOGGER.error("Chunk wait task info below: "); + + for (final ChunkInfo chunkInfo : chunks) { + final long key = IOUtil.getCoordinateKey(chunkInfo.chunkX, chunkInfo.chunkZ); + final ChunkLoadTask loadTask = chunkInfo.world.asyncChunkTaskManager.chunkLoadTasks.get(key); + final ChunkSaveTask saveTask = chunkInfo.world.asyncChunkTaskManager.chunkSaveTasks.get(key); + -+ PaperFileIOThread.LOGGER.log(Level.ERROR, chunkInfo.chunkX + "," + chunkInfo.chunkZ + " in '" + chunkInfo.world.getWorld().getName() + ":"); -+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Load Task - " + (loadTask == null ? "none" : loadTask.toString())); -+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Save Task - " + (saveTask == null ? "none" : saveTask.toString())); ++ PaperFileIOThread.LOGGER.error(chunkInfo.chunkX + "," + chunkInfo.chunkZ + " in '" + chunkInfo.world.getWorld().getName() + ":"); ++ PaperFileIOThread.LOGGER.error("Load Task - " + (loadTask == null ? "none" : loadTask.toString())); ++ PaperFileIOThread.LOGGER.error("Save Task - " + (saveTask == null ? "none" : saveTask.toString())); + // log current status of chunk to indicate whether we're waiting on generation or loading + ChunkHolder chunkHolder = chunkInfo.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(key); + @@ -1908,14 +1908,14 @@ index 0000000000000000000000000000000000000000..db6f8ac2ae068d5bc2ec2d587ab625c4 + seenChunks.add(chunkHolder); + String indentStr = StringUtils.repeat(" ", indent); + if (chunkHolder == null) { -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder - null for (" + x +"," + z +")"); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Holder - null for (" + x +"," + z +")"); + } else { + ChunkAccess chunk = chunkHolder.getLastAvailable(); + ChunkStatus holderStatus = chunkHolder.getChunkHolderStatus(); -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder - non-null"); -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getStatus().toString())); -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Ticket Status - " + ChunkHolder.getStatus(chunkHolder.getTicketLevel())); -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString())); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Holder - non-null"); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getStatus().toString())); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Ticket Status - " + ChunkHolder.getStatus(chunkHolder.getTicketLevel())); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString())); + } + } + @@ -2877,7 +2877,7 @@ index 0d536d72ac918fbd403397ff369d10143ee9c204..be677d437d17b74c6188ce1bd5fc6fdc private final String name; private final Comparator comparator; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 62fda1dd8d560a8e16118e9d1b044ef59c0e5b02..d0adb066fcea5636c88be838fb5eff79306c5f4a 100644 +index 8a1da2b1e667420df97e432b5a5fd9563cadda91..f1d2c9274f4968adab689a08c86bea7a16b76b39 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -716,6 +716,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser @@ -3612,7 +3612,7 @@ index 65b7a4dc767a3fd5c4d0c00f4a4aaa8e04d13f13..5dea397fc7f11db39385c1711364a311 @Override public PersistentDataContainer getPersistentDataContainer() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index e496a346b12497e5e0834e0bc523c2221b45cab7..16f2479de2c330b17c9ef6f3bee8e4ade5b66d15 100644 +index 20c753f5819652430e4fe7b9e3fd4a4b16fc3647..8e6ae581c714c1fec6b1cdc1c26b83772573ab27 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -15,6 +15,7 @@ import net.minecraft.network.chat.Component; diff --git a/patches/server/0263-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch b/patches/server/0263-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch index 28e1552e6..62b297eaf 100644 --- a/patches/server/0263-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch +++ b/patches/server/0263-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement an API for CanPlaceOn and CanDestroy NBT values diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 2244a3c61f4effd365ed5fc010ecd1a4858b53a8..a7e53dcc2769148a8a74db999666bb40aad94720 100644 +index 2244a3c61f4effd365ed5fc010ecd1a4858b53a8..4b48f4e1b2d69a18be0e9d83d52bc4f58b1f5bd9 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -83,6 +83,12 @@ import org.bukkit.persistence.PersistentDataContainer; @@ -253,7 +253,7 @@ index 2244a3c61f4effd365ed5fc010ecd1a4858b53a8..a7e53dcc2769148a8a74db999666bb40 // Paper end CraftMetaCompass.LODESTONE_DIMENSION.NBT, CraftMetaCompass.LODESTONE_POS.NBT, -@@ -1480,4 +1623,146 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1480,4 +1623,148 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } // Paper end @@ -356,9 +356,11 @@ index 2244a3c61f4effd365ed5fc010ecd1a4858b53a8..a7e53dcc2769148a8a74db999666bb40 + return null; + } + -+ net.minecraft.resources.ResourceLocation key; ++ net.minecraft.resources.ResourceLocation key = null; + if (isTag) { -+ key = blockParser.getTag(); ++ if (blockParser.getTag() != null) { ++ key = blockParser.getTag().location(); ++ } + } else { + key = blockParser.id; + } diff --git a/patches/server/0312-Entity-getEntitySpawnReason.patch b/patches/server/0312-Entity-getEntitySpawnReason.patch index 2cebcd9b4..7386fa6dd 100644 --- a/patches/server/0312-Entity-getEntitySpawnReason.patch +++ b/patches/server/0312-Entity-getEntitySpawnReason.patch @@ -35,7 +35,7 @@ index b494d7fc864a2fa734c73c2c4d433e288bccfb26..840bfcea9347b50b422eb7a325a1be43 }); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1f1442e62c089ef9a922bbee91fc841771e7777f..a896b0b671d0c57de49c8f5e937e6218cbdc7a1e 100644 +index c15c86a0cbb08a0770b88a2f5e2c656a6b79157f..7396e86b750e326653b82ca28ae3bffee3f99344 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -70,6 +70,8 @@ import net.minecraft.world.InteractionHand; @@ -74,7 +74,7 @@ index 1f1442e62c089ef9a922bbee91fc841771e7777f..a896b0b671d0c57de49c8f5e937e6218 + try { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName); + } catch (Exception ignored) { -+ LogManager.getLogger().error("Unknown SpawnReason " + spawnReasonName + " for " + this); ++ LOGGER.error("Unknown SpawnReason " + spawnReasonName + " for " + this); + } + } + if (spawnReason == null) { @@ -105,7 +105,7 @@ index 1c76a59eb25148bf2523e9d68cc165b6cd3e1d23..fafbc8601ba3378b86c660f947e23ec2 // Spigot Start if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 16f2479de2c330b17c9ef6f3bee8e4ade5b66d15..c066be9b92d73de66ee3f1ef6aa8910de4589210 100644 +index 8e6ae581c714c1fec6b1cdc1c26b83772573ab27..b732d9de71e5799969852a22f22e860637f7d64e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1238,5 +1238,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0405-Load-Chunks-for-Login-Asynchronously.patch b/patches/server/0405-Load-Chunks-for-Login-Asynchronously.patch index 84904bbaf..c17acc7d9 100644 --- a/patches/server/0405-Load-Chunks-for-Login-Asynchronously.patch +++ b/patches/server/0405-Load-Chunks-for-Login-Asynchronously.patch @@ -37,7 +37,7 @@ index be677d437d17b74c6188ce1bd5fc6fdc228fd92f..78fbb4c3e52e900956ae0811aaf934c8 public static final TicketType UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); public static final TicketType PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e9fbbe197b991276111cad87fadde8d1077a7062..2859db2809a3d789b8246dd76f313e304d979e0f 100644 +index 1353b0192f54a9419b853168307727307e4cee76..782501e6663fde112700c4ca8ccba073e45dd23a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -220,6 +220,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser @@ -96,7 +96,7 @@ index 4c06e62e967f28eb844d74237948834e61daeab0..0af65f1698e4ee9d94724f19b0abd61c 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 e7904870da5134b397f93c4de29d804775830947..a36d582b8fdd99eba423fbeb8f46f0dd226d3523 100644 +index e7904870da5134b397f93c4de29d804775830947..e9470af5a168f54c78383553ca634e77ae2a4cf5 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -40,6 +40,7 @@ import net.minecraft.network.protocol.Packet; @@ -164,7 +164,7 @@ index e7904870da5134b397f93c4de29d804775830947..a36d582b8fdd99eba423fbeb8f46f0dd + 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; -+ distanceManager.addTicketAtLevel(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong()); ++ distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong()); + worldserver1.getChunkSource().runDistanceManagerUpdates(); + worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { + net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); diff --git a/patches/server/0470-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/patches/server/0470-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index 45483ebb7..cf7dfabe7 100644 --- a/patches/server/0470-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/patches/server/0470-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -23,7 +23,7 @@ Chunks in front of the player have higher priority, to help with fast traveling players keep up with their movement. diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java -index db6f8ac2ae068d5bc2ec2d587ab625c4956f6947..057968ccce588072662666fef145669d63490791 100644 +index abf62796cfbfa61392b0776b28eb6bfc284053c1..4c78ad72e7e788fbc0c57834a2c89bfa70e1f872 100644 --- a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java @@ -106,7 +106,7 @@ public final class ChunkTaskManager { @@ -36,18 +36,18 @@ index db6f8ac2ae068d5bc2ec2d587ab625c4956f6947..057968ccce588072662666fef145669d static void dumpChunkInfo(Set seenChunks, ChunkHolder chunkHolder, int x, int z, int indent, int maxDepth) { @@ -127,6 +127,31 @@ public final class ChunkTaskManager { - PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getStatus().toString())); - PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Ticket Status - " + ChunkHolder.getStatus(chunkHolder.getTicketLevel())); - PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString())); + PaperFileIOThread.LOGGER.error(indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getStatus().toString())); + PaperFileIOThread.LOGGER.error(indentStr + "Chunk Ticket Status - " + ChunkHolder.getStatus(chunkHolder.getTicketLevel())); + PaperFileIOThread.LOGGER.error(indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString())); + // Paper start -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Priority - " + chunkHolder.queueLevel); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Holder Priority - " + chunkHolder.queueLevel); + + if (!chunkHolder.neighbors.isEmpty()) { + if (indent >= maxDepth) { -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Neighbors: (Can't show, too deeply nested)"); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Neighbors: (Can't show, too deeply nested)"); + return; + } -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Neighbors: "); ++ PaperFileIOThread.LOGGER.error(indentStr + "Chunk Neighbors: "); + for (ChunkHolder neighbor : chunkHolder.neighbors.keySet()) { + ChunkStatus status = neighbor.getChunkHolderStatus(); + if (status != null && status.isOrAfter(ChunkHolder.getStatus(neighbor.getTicketLevel()))) { @@ -56,10 +56,10 @@ index db6f8ac2ae068d5bc2ec2d587ab625c4956f6947..057968ccce588072662666fef145669d + int nx = neighbor.pos.x; + int nz = neighbor.pos.z; + if (seenChunks.contains(neighbor)) { -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + " " + nx + "," + nz + " in " + chunkHolder.getWorld().getWorld().getName() + " (CIRCULAR)"); ++ PaperFileIOThread.LOGGER.error(indentStr + " " + nx + "," + nz + " in " + chunkHolder.getWorld().getWorld().getName() + " (CIRCULAR)"); + continue; + } -+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + " " + nx + "," + nz + " in " + chunkHolder.getWorld().getWorld().getName() + ":"); ++ PaperFileIOThread.LOGGER.error(indentStr + " " + nx + "," + nz + " in " + chunkHolder.getWorld().getWorld().getName() + ":"); + dumpChunkInfo(seenChunks, neighbor, nx, nz, indent + 1, maxDepth); + } + } @@ -1112,7 +1112,7 @@ index 8770fe0db46b01e8b608637df4f1a669a3f4cdde..3c1698ba0d3bc412ab957777d9b5211d private final String name; private final Comparator comparator; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index c154f5e7708dbb19cf1b1a546bb209d386ef52d4..78270cdd1e8f371f951d317f6cf438069e81c958 100644 +index aa9d32a4c86aade43f91c78ae1179119d12e9a88..d5e5e0a80c1a3dd5823e9975062856b6d0ef3ae1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -175,6 +175,7 @@ public abstract class PlayerList { @@ -1126,7 +1126,7 @@ index c154f5e7708dbb19cf1b1a546bb209d386ef52d4..78270cdd1e8f371f951d317f6cf43806 @@ -289,8 +290,8 @@ public abstract class PlayerList { net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap; net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager; - distanceManager.addTicketAtLevel(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong()); + distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong()); - worldserver1.getChunkSource().runDistanceManagerUpdates(); - worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { + worldserver1.getChunkSource().markAreaHighPriority(pos, 28, 3); // Paper - Chunk priority @@ -1135,7 +1135,7 @@ index c154f5e7708dbb19cf1b1a546bb209d386ef52d4..78270cdd1e8f371f951d317f6cf43806 if (updatingChunk != null) { return updatingChunk.getEntityTickingChunkFuture(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a702a53f588ddd9f748f55973cd3782734aafc51..e18b2855791002a20f5afaa87cbfb36023ba4b7f 100644 +index 85c818c6c4a56065699de9f4675240de54a5a1df..5ec5e5256e81e1cb61897f3c6f63f482a56a92d9 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -231,7 +231,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i @@ -1194,7 +1194,7 @@ index 7bb753f498b10be32726771250dca7e15338d8d1..3741dc458bf78be17144528ef0414848 net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null); if (chunk != null) addTicket(x, z); // Paper diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0a9d519596b074fd88fc3594d673189ef2c5e3d9..6ae1b3e95783a0692a72a3754edb1850cd2dc83a 100644 +index 7c406649f112e1b449d07d180c7f2d63b170f2ed..199e0635f4d1ba247624131e8c9fac8b06754c51 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -927,6 +927,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0637-More-World-API.patch b/patches/server/0637-More-World-API.patch index 7b0b96730..26e43326d 100644 --- a/patches/server/0637-More-World-API.patch +++ b/patches/server/0637-More-World-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] More World API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 5f77172bcd7c250d33a9ecbd40dbf70f370dcc9e..fc7f17f05ef5457cce545424b19537c9d3e9bf01 100644 +index 5f77172bcd7c250d33a9ecbd40dbf70f370dcc9e..addc12d30bf58459b7d54bdc8ad97eff231c6419 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1966,6 +1966,65 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -21,7 +21,7 @@ index 5f77172bcd7c250d33a9ecbd40dbf70f370dcc9e..fc7f17f05ef5457cce545424b19537c9 + @Override + public Location locateNearestBiome(Location origin, Biome biome, int radius, int step) { + BlockPos originPos = new BlockPos(origin.getX(), origin.getY(), origin.getZ()); -+ BlockPos nearest = getHandle().findNearestBiome(CraftBlock.biomeToBiomeBase(getHandle().registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY), biome), originPos, radius, step); ++ BlockPos nearest = getHandle().findNearestBiome( holder -> holder.is(CraftNamespacedKey.toMinecraft(biome.getKey())), originPos, radius, step).getFirst(); + return (nearest == null) ? null : new Location(this, nearest.getX(), nearest.getY(), nearest.getZ()); + } + @@ -62,7 +62,7 @@ index 5f77172bcd7c250d33a9ecbd40dbf70f370dcc9e..fc7f17f05ef5457cce545424b19537c9 + + @Override + public Collection getInfiniburn() { -+ return com.google.common.collect.Sets.newHashSet(com.google.common.collect.Iterators.transform(getHandle().dimensionType().infiniburn().getValues().iterator(), CraftMagicNumbers::getMaterial)); ++ return com.google.common.collect.Sets.newHashSet(com.google.common.collect.Iterators.transform(net.minecraft.core.Registry.BLOCK.getTagOrEmpty(this.getHandle().dimensionType().infiniburn()).iterator(), blockHolder -> CraftMagicNumbers.getMaterial(blockHolder.value()))); + } + + @Override diff --git a/patches/server/0658-Fix-and-optimise-world-force-upgrading.patch b/patches/server/0658-Fix-and-optimise-world-force-upgrading.patch index 831d531ac..ffaa5bdd5 100644 --- a/patches/server/0658-Fix-and-optimise-world-force-upgrading.patch +++ b/patches/server/0658-Fix-and-optimise-world-force-upgrading.patch @@ -30,10 +30,10 @@ easy to add threading, so I did. diff --git a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java new file mode 100644 -index 0000000000000000000000000000000000000000..748e6923338d40d67e31251e9ab6001674963690 +index 0000000000000000000000000000000000000000..ca4e9acb4b7beb739546954d0aa02461559a28c8 --- /dev/null +++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -@@ -0,0 +1,211 @@ +@@ -0,0 +1,209 @@ +package io.papermc.paper.world; + +import com.mojang.datafixers.DataFixer; @@ -70,7 +70,6 @@ index 0000000000000000000000000000000000000000..748e6923338d40d67e31251e9ab60016 + private static final Logger LOGGER = LogManager.getLogger(); + + private final ResourceKey dimensionType; -+ private final ResourceKey worldKey; + private final String worldName; + private final File worldDir; + private final ExecutorService threadPool; @@ -78,10 +77,9 @@ index 0000000000000000000000000000000000000000..748e6923338d40d67e31251e9ab60016 + private final Optional>> generatorKey; + private final boolean removeCaches; + -+ public ThreadedWorldUpgrader(final ResourceKey dimensionType, final ResourceKey worldKey, final String worldName, final File worldDir, final int threads, ++ public ThreadedWorldUpgrader(final ResourceKey dimensionType, final String worldName, final File worldDir, final int threads, + final DataFixer dataFixer, final Optional>> generatorKey, final boolean removeCaches) { + this.dimensionType = dimensionType; -+ this.worldKey = worldKey; + this.worldName = worldName; + this.worldDir = worldDir; + this.threadPool = Executors.newFixedThreadPool(Math.max(1, threads), new ThreadFactory() { @@ -246,7 +244,7 @@ index 0000000000000000000000000000000000000000..748e6923338d40d67e31251e9ab60016 + } +} diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 69dc1271be0a3f3f2fb4ce15981ed25d24dce785..04359306ba6a117e447966e04ef1376b6e2d7e99 100644 +index 69dc1271be0a3f3f2fb4ce15981ed25d24dce785..1e0d261439255091a6f61485c0747231fbd5b1db 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -15,6 +15,7 @@ import java.nio.file.Path; @@ -262,10 +260,10 @@ index 69dc1271be0a3f3f2fb4ce15981ed25d24dce785..04359306ba6a117e447966e04ef1376b // Paper end + // Paper start - fix and optimise world upgrading -+ public static void convertWorldButItWorks(net.minecraft.resources.ResourceKey dimensionType, net.minecraft.resources.ResourceKey worldKey, net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess worldSession, ++ public static void convertWorldButItWorks(net.minecraft.resources.ResourceKey dimensionType, net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess worldSession, + DataFixer dataFixer, Optional>> generatorKey, boolean removeCaches) { + int threads = Runtime.getRuntime().availableProcessors() * 3 / 8; -+ final ThreadedWorldUpgrader worldUpgrader = new ThreadedWorldUpgrader(dimensionType, worldKey, worldSession.getLevelId(), worldSession.levelPath.toFile(), threads, dataFixer, generatorKey, removeCaches); ++ final ThreadedWorldUpgrader worldUpgrader = new ThreadedWorldUpgrader(dimensionType, worldSession.getLevelId(), worldSession.levelPath.toFile(), threads, dataFixer, generatorKey, removeCaches); + worldUpgrader.convert(); + } + // Paper end - fix and optimise world upgrading @@ -274,7 +272,7 @@ index 69dc1271be0a3f3f2fb4ce15981ed25d24dce785..04359306ba6a117e447966e04ef1376b Main.LOGGER.info("Forcing world upgrade! {}", session.getLevelId()); // CraftBukkit WorldUpgrader worldupgrader = new WorldUpgrader(session, dataFixer, generatorOptions, eraseCache); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 824d90b541355d711a170ff8e163a894ba17ff00..4def5f9189cffd11ce23fc974fbf1102f9c1d57c 100644 +index 824d90b541355d711a170ff8e163a894ba17ff00..e91c9caff8d789031f93fb5b3bd17599eb0b5c33 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -557,11 +557,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop ChunkMap.MAX_CHUNK_DISTANCE && level > ChunkMap.MAX_CHUNK_DISTANCE) { return holder; } else { @@ -49,14 +49,14 @@ index be8303e64e481e37a6ab25ee99c4008037670303..77f17937e90c9b12839f0e64131aa24b } }; diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index c97692440f4f0403714cdd7d1fba5496e324b40c..755537ca7b83a08357a59e00a6ef35107b0696e9 100644 +index c97692440f4f0403714cdd7d1fba5496e324b40c..718c89f421637d623a92e5167397870562593a04 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -816,6 +816,7 @@ public class ServerChunkCache extends ChunkSource { public boolean runDistanceManagerUpdates() { if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority -+ if (this.chunkMap.unloadingPlayerChunk) { net.minecraft.server.MinecraftServer.LOGGER.fatal("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper ++ if (this.chunkMap.unloadingPlayerChunk) { LOGGER.error("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap(); diff --git a/patches/server/0742-Prevent-unload-calls-removing-tickets-for-sync-loads.patch b/patches/server/0742-Prevent-unload-calls-removing-tickets-for-sync-loads.patch index 8a78c56d8..ef1dd7758 100644 --- a/patches/server/0742-Prevent-unload-calls-removing-tickets-for-sync-loads.patch +++ b/patches/server/0742-Prevent-unload-calls-removing-tickets-for-sync-loads.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent unload() calls removing tickets for sync loads diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 755537ca7b83a08357a59e00a6ef35107b0696e9..7771fd7c7918aa4852371dc88d46163c168f020e 100644 +index 718c89f421637d623a92e5167397870562593a04..adab778c11ef11cb57418675a98129afb01ec06e 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -721,6 +721,8 @@ public class ServerChunkCache extends ChunkSource { @@ -26,7 +26,7 @@ index 755537ca7b83a08357a59e00a6ef35107b0696e9..7771fd7c7918aa4852371dc88d46163c // CraftBukkit end this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair); + identifier = Long.valueOf(this.syncLoadCounter++); // Paper - prevent plugin unloads from removing our ticket -+ this.distanceManager.addTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Paper - prevent plugin unloads from removing our ticket ++ this.distanceManager.addTicket(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Paper - prevent plugin unloads from removing our ticket if (isUrgent) this.distanceManager.markUrgent(chunkcoordintpair); // Paper - Chunk priority if (this.chunkAbsent(playerchunk, l)) { ProfilerFiller gameprofilerfiller = this.level.getProfiler(); @@ -34,7 +34,7 @@ index 755537ca7b83a08357a59e00a6ef35107b0696e9..7771fd7c7918aa4852371dc88d46163c playerchunk = this.getVisibleChunkIfPresent(k); gameprofilerfiller.pop(); if (this.chunkAbsent(playerchunk, l)) { -+ this.distanceManager.removeTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Paper ++ this.distanceManager.removeTicket(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Paper throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("No chunk holder after ticket has been added")); } } @@ -46,7 +46,7 @@ index 755537ca7b83a08357a59e00a6ef35107b0696e9..7771fd7c7918aa4852371dc88d46163c + // Paper start - prevent plugin unloads from removing our ticket + if (create && !currentlyUnloading) { + future.thenAcceptAsync((either) -> { -+ ServerChunkCache.this.distanceManager.removeTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); ++ ServerChunkCache.this.distanceManager.removeTicket(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); + }, ServerChunkCache.this.mainThreadProcessor); + } + // Paper end - prevent plugin unloads from removing our ticket diff --git a/patches/server/0750-Do-not-copy-visible-chunks.patch b/patches/server/0750-Do-not-copy-visible-chunks.patch index 6b5f5cee4..8bb08bcd3 100644 --- a/patches/server/0750-Do-not-copy-visible-chunks.patch +++ b/patches/server/0750-Do-not-copy-visible-chunks.patch @@ -35,7 +35,7 @@ index b3516862d796c2d9fcc1c67a6073445403d73088..b61abf227a04b4565c2525e5f469db30 List allChunks = new ArrayList<>(visibleChunks.values()); List players = world.players; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 6a9f9d93be96bd27be5ac3a7d2e142fda2f45efa..09e2d5bd3ab14a2c43547313394bf1167168d6cc 100644 +index 245ce32ee7b35a07c47c31772208eccf35c85a33..6f2f3f036b983a34a50b43522c30b3ba0ef555d2 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -123,9 +123,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -81,6 +81,18 @@ index 6a9f9d93be96bd27be5ac3a7d2e142fda2f45efa..09e2d5bd3ab14a2c43547313394bf116 } protected IntSupplier getChunkQueueLevel(long pos) { +@@ -686,9 +693,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + }; + + stringbuilder.append("Updating:").append(System.lineSeparator()); +- this.updatingChunkMap.values().forEach(consumer); ++ this.updatingChunks.getUpdatingValuesCopy().forEach(consumer); // Paper + stringbuilder.append("Visible:").append(System.lineSeparator()); +- this.visibleChunkMap.values().forEach(consumer); ++ this.updatingChunks.getVisibleValuesCopy().forEach(consumer); // Paper + CrashReport crashreport = CrashReport.forThrowable(exception, "Chunk loading"); + CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk loading"); + @@ -739,7 +746,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end } @@ -108,6 +120,15 @@ index 6a9f9d93be96bd27be5ac3a7d2e142fda2f45efa..09e2d5bd3ab14a2c43547313394bf116 } } +@@ -873,7 +880,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + 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() || !this.updatingChunks.getUpdatingValuesCopy().isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper + } + + private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more @@ -888,7 +895,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider while (longiterator.hasNext()) { // Spigot long j = longiterator.nextLong(); @@ -166,7 +187,7 @@ index 6a9f9d93be96bd27be5ac3a7d2e142fda2f45efa..09e2d5bd3ab14a2c43547313394bf116 while (objectbidirectionaliterator.hasNext()) { Entry entry = (Entry) objectbidirectionaliterator.next(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b3f447e77619a7a0954a7709f36ad22678fce5f4..71eb9d86738db8eb79ec5dc5574ea9afa934da62 100644 +index 225cdb651775bcc601982ba33b1f5d01aefd9e2a..2420bc805923094d4d7422e69c20ed5de23777de 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -160,7 +160,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0755-Distance-manager-tick-timings.patch b/patches/server/0755-Distance-manager-tick-timings.patch index 4902ee8af..69c8bf095 100644 --- a/patches/server/0755-Distance-manager-tick-timings.patch +++ b/patches/server/0755-Distance-manager-tick-timings.patch @@ -19,13 +19,13 @@ index eada966d7f108a6081be7a848f5c1dfcb1eed676..a977f7483f37df473096b2234dc1308b public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks"); diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index be59f4ec068947fbb78ae8b140527bb417395860..469bc5f71a72217514c0496977de33e2fa4d391e 100644 +index b73f49b9bf49dc2a08aa8ffece675df41c077412..5271cc135e636961fc1248f6b98bb122ab3391e6 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -831,6 +831,7 @@ public class ServerChunkCache extends ChunkSource { public boolean runDistanceManagerUpdates() { if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority - if (this.chunkMap.unloadingPlayerChunk) { net.minecraft.server.MinecraftServer.LOGGER.fatal("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper + if (this.chunkMap.unloadingPlayerChunk) { LOGGER.error("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper + co.aikar.timings.MinecraftTimings.distanceManagerTick.startTiming(); try { // Paper - add timings for distance manager boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap(); diff --git a/patches/server/0817-Allow-delegation-to-vanilla-chunk-gen.patch b/patches/server/0817-Allow-delegation-to-vanilla-chunk-gen.patch index a0c4e5811..fd3b04204 100644 --- a/patches/server/0817-Allow-delegation-to-vanilla-chunk-gen.patch +++ b/patches/server/0817-Allow-delegation-to-vanilla-chunk-gen.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow delegation to vanilla chunk gen diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index c1b79f21bff6f9f83f06c338a67f9a942f75da68..14f0b550bdbe42c67456e54d88289f0de56ca04e 100644 +index 492f398a1c2dbe7b821dd40be1c1c6952f056c3a..fba20c4228a34d4c956ce2a440eb6e495182f8f2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2305,6 +2305,107 @@ public final class CraftServer implements Server { +@@ -2305,6 +2305,90 @@ public final class CraftServer implements Server { return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), world); // Paper - Anti-Xray - Add parameters } @@ -26,24 +26,6 @@ index c1b79f21bff6f9f83f06c338a67f9a942f75da68..14f0b550bdbe42c67456e54d88289f0d + net.minecraft.world.level.chunk.ChunkStatus.LIGHT + ); + -+ @net.minecraft.MethodsReturnNonnullByDefault -+ private static final class PaperEmptyLevelChunk extends net.minecraft.world.level.chunk.EmptyLevelChunk { -+ private final net.minecraft.world.level.biome.Biome biome; -+ -+ public PaperEmptyLevelChunk(net.minecraft.world.level.Level world, net.minecraft.world.level.ChunkPos pos) { -+ super(world, pos); -+ this.biome = this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); -+ } -+ -+ @Override -+ public net.minecraft.world.level.biome.Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { -+ return this.biome; -+ } -+ -+ @Override -+ public void markPosForPostprocessing(BlockPos pos) {} -+ } -+ + @Override + @Deprecated(forRemoval = true) + public ChunkGenerator.ChunkData createVanillaChunkData(World world, int x, int z) { @@ -79,7 +61,8 @@ index c1b79f21bff6f9f83f06c338a67f9a942f75da68..14f0b550bdbe42c67456e54d88289f0d + if (xx == chunkPos.x && zz == chunkPos.z) { + chunks.add(protoChunk); + } else { -+ final net.minecraft.world.level.chunk.ChunkAccess chunk = new PaperEmptyLevelChunk(serverLevel, new net.minecraft.world.level.ChunkPos(xx, zz)); ++ final Holder biomeHolder = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); ++ final net.minecraft.world.level.chunk.ChunkAccess chunk = new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, new net.minecraft.world.level.ChunkPos(xx, zz), biomeHolder); + chunks.add(chunk); + } + } diff --git a/patches/server/0820-Actually-unload-POI-data.patch b/patches/server/0820-Actually-unload-POI-data.patch index 7a790c1ec..3ad8dbd20 100644 --- a/patches/server/0820-Actually-unload-POI-data.patch +++ b/patches/server/0820-Actually-unload-POI-data.patch @@ -10,7 +10,7 @@ This patch also prevents the saving/unloading of POI data when world saving is disabled. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 0120480bc569f84d9036b90fd0c0f2f33c9c6a9f..a0075aed85fc51cc48e01ecf2b187b04078fb488 100644 +index ccfd00591da304aa03ea2f10e809c11213db6e0f..b75b218733fd5f171bb0290d5fb0248c17737030 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -848,6 +848,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -22,7 +22,7 @@ index 0120480bc569f84d9036b90fd0c0f2f33c9c6a9f..a0075aed85fc51cc48e01ecf2b187b04 this.updatingChunks.queueUpdate(pos, holder); // Paper - Don't copy this.modified = true; @@ -997,7 +998,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - 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() || !this.updatingChunks.getUpdatingValuesCopy().isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper } - private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more diff --git a/patches/server/0861-Add-GameEvent-tags.patch b/patches/server/0861-Add-GameEvent-tags.patch index 7ee9115b3..74cb5fcbb 100644 --- a/patches/server/0861-Add-GameEvent-tags.patch +++ b/patches/server/0861-Add-GameEvent-tags.patch @@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..d5d3c66afb408026513ac436eb1f4fdd + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 640cfb7cf792e2e61417cc93627b43db8dc9bcc9..b858ac57ff2b802a8eeec731cfd932ee266bff17 100644 +index 3b7b4a578346a162afbeb5781633c163d0c46177..197668e1b8487ed5463d457c8738ba70813cace1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -97,6 +97,7 @@ import net.minecraft.world.level.biome.BiomeSource; @@ -52,7 +52,7 @@ index 640cfb7cf792e2e61417cc93627b43db8dc9bcc9..b858ac57ff2b802a8eeec731cfd932ee import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.PatrolSpawner; import net.minecraft.world.level.levelgen.PhantomSpawner; -@@ -2553,6 +2554,12 @@ public final class CraftServer implements Server { +@@ -2536,6 +2537,12 @@ public final class CraftServer implements Server { Preconditions.checkArgument(clazz == org.bukkit.entity.EntityType.class, "Entity type namespace must have entity type"); return (org.bukkit.Tag) new CraftEntityTag(Registry.ENTITY_TYPE, TagKey.create(Registry.ENTITY_TYPE_REGISTRY, key)); @@ -65,7 +65,7 @@ index 640cfb7cf792e2e61417cc93627b43db8dc9bcc9..b858ac57ff2b802a8eeec731cfd932ee default: throw new IllegalArgumentException(); } -@@ -2582,6 +2589,13 @@ public final class CraftServer implements Server { +@@ -2565,6 +2572,13 @@ public final class CraftServer implements Server { Registry> entityTags = Registry.ENTITY_TYPE; return entityTags.getTags().map(pair -> (org.bukkit.Tag) new CraftEntityTag(entityTags, pair.getFirst())).collect(ImmutableList.toImmutableList()); diff --git a/patches/server/0862-Replace-player-chunk-loader-system.patch b/patches/server/0862-Replace-player-chunk-loader-system.patch index e6238d216..88029c87b 100644 --- a/patches/server/0862-Replace-player-chunk-loader-system.patch +++ b/patches/server/0862-Replace-player-chunk-loader-system.patch @@ -1381,7 +1381,7 @@ index 36b6e7295cf7484675c8c2b9624c1f6fea7aed1d..38db3905f47fefb5c958fa24aef2313e public CompletableFuture> getOrScheduleFuture(ChunkStatus targetStatus, ChunkMap chunkStorage) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index a0075aed85fc51cc48e01ecf2b187b04078fb488..becb3fb122ead85875958aa20de34b7f0ad7e371 100644 +index b75b218733fd5f171bb0290d5fb0248c17737030..bac41c30a0405815465edb81c7552d61defc9c6a 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -217,6 +217,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1632,7 +1632,7 @@ index a0075aed85fc51cc48e01ecf2b187b04078fb488..becb3fb122ead85875958aa20de34b7f double d2 = d0 * d0; boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player); diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 005d75c93387a8c34a9ff7413ba09cb1ae788a74..1c8020435ab8eb5fec68dc5bf473650f2658bdac 100644 +index 005d75c93387a8c34a9ff7413ba09cb1ae788a74..d428da9060693db4e60d456b370d7b4db7bc6792 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -50,8 +50,8 @@ public abstract class DistanceManager { @@ -1785,6 +1785,21 @@ index 005d75c93387a8c34a9ff7413ba09cb1ae788a74..1c8020435ab8eb5fec68dc5bf473650f public void removeTicketsOnClosing() { ImmutableSet> immutableset = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.LIGHT); +@@ -559,12 +558,12 @@ public abstract class DistanceManager { + if (!immutableset.contains(ticket.getType())) { + iterator.remove(); + flag = true; +- this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket); ++ // this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket); // Paper - no longer used + } + } + + if (flag) { +- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false); ++ // this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false); // Paper - no longer used + } + + if (((SortedArraySet) entry.getValue()).isEmpty()) { @@ -643,6 +642,7 @@ public abstract class DistanceManager { } } @@ -1800,7 +1815,7 @@ index 005d75c93387a8c34a9ff7413ba09cb1ae788a74..1c8020435ab8eb5fec68dc5bf473650f + */ // Paper - replace old loader system } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index ef5321f230f66383e3760bf97e7eca1be3a5b02e..96cdb8746b404e7080f7f53da14d49e596dddc75 100644 +index cd6eb305f4d36be923f6c5f0dd85e449d0f94c8f..5793154c0deca7fc570bbe858c6bea0d640db941 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -851,17 +851,10 @@ public class ServerChunkCache extends ChunkSource { @@ -1903,7 +1918,7 @@ index b4d20c06a19e021317cff64a9789f0579b5f921d..e74c13e7aaa144fcd07036de70e80beb + public final int getViewDistance() { throw new UnsupportedOperationException("Use PlayerChunkLoader"); } // Paper - placeholder } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 0766abd7334bc76b57fd509c8890701704aa217c..d14b079ae53628c9bf9a7c261f0b195c7351c2e6 100644 +index fae67931849eb0c19598def9f538c7971c36c575..f5852341161b0d632e22af9b3e625ca1e786bd63 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -271,7 +271,7 @@ public abstract class PlayerList { @@ -2082,7 +2097,7 @@ index a141071966428315484480831a58f02a2b0bc025..d4ce71d98c5071cd3567c772a0853ca8 @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 72df27de006121fe21d1cc4c5f50dbc4a23fc505..f9f7a8ee1a9cd4709924ee403a487bcce9bd0ffb 100644 +index 2e8e066ca3f57cfb9d11cbc620d038cea9dd2b64..f20a6d82ac983f7c0239fb9daff8f726c4bed0dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2218,37 +2218,55 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -2149,7 +2164,7 @@ index 72df27de006121fe21d1cc4c5f50dbc4a23fc505..f9f7a8ee1a9cd4709924ee403a487bcc // Spigot end diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d309d9f0b54e2a966ccfbb780359bb8e68d15ee3..ef841a5ea1f634e87e5437faf83dc00efd590106 100644 +index a00f65bd14d242ead4d6460e0cc912a54ea58e63..4e20735837d1b854f3a605d2cf2cf1159fc6b3b4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -528,35 +528,80 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0871-Custom-Potion-Mixes.patch b/patches/server/0871-Custom-Potion-Mixes.patch index af6176c58..3e22e5b04 100644 --- a/patches/server/0871-Custom-Potion-Mixes.patch +++ b/patches/server/0871-Custom-Potion-Mixes.patch @@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..6b0bed550763f34e18c9e92f9a47ec0c + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 66588f83024286efd04d408993113397d8bd1cfa..df0200600a3371ebc1974ef1219b06e46ef46424 100644 +index f60120f788bdd1e1a159b87c18655d9e00920c89..0a0bc8c45cb70073cb94dee25b5e54fb98bf9c8e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2060,6 +2060,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop