From 66cb880754c72ea79f9abde4128fefa6d89a13ca Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 21 May 2024 08:21:28 -0700 Subject: [PATCH] Remove ThreadedWorldUpgrader patch The patch does not implement Vanilla forceUpgrade behavior. Specifically, poi/entity conversion and regionfile recreation. The Vanilla force upgrader is also no longer broken by CB, so the bug fixes from this patch are not relevant anymore. --- ...> 1025-API-for-checking-sent-chunks.patch} | 2 +- ...x-and-optimise-world-force-upgrading.patch | 395 ------------------ ...-for-mobs-immune-to-default-effects.patch} | 0 ... => 1027-Deep-clone-nbt-tags-in-PDC.patch} | 0 ...028-Support-old-UUID-format-for-NBT.patch} | 0 ...29-Fix-shield-disable-inconsistency.patch} | 2 +- ...ch => 1030-Write-SavedData-IO-async.patch} | 22 +- ...removed-data-components-in-ItemMeta.patch} | 0 ...-experimental-improved-give-command.patch} | 0 ...-Large-Packets-disconnecting-client.patch} | 0 ...emFlags.patch => 1034-Fix-ItemFlags.patch} | 0 ...et-damage-reduction-inconsistencies.patch} | 0 ...-handling-of-LivingEntity-actuallyH.patch} | 2 +- ...e-checking-handled-tags-in-itemmeta.patch} | 0 ...atch => 1038-General-ItemMeta-fixes.patch} | 0 ...39-Expose-hasColor-to-leather-armor.patch} | 0 ...-API-to-get-player-ha-proxy-address.patch} | 2 +- ....patch => 1041-More-Chest-Block-API.patch} | 0 ...ta-component-type-on-encoding-error.patch} | 0 ...r-desync-when-new-players-are-added.patch} | 0 ...=> 1044-Brigadier-based-command-API.patch} | 10 +- ... => 1045-Fix-issues-with-Recipe-API.patch} | 0 22 files changed, 10 insertions(+), 425 deletions(-) rename patches/server/{1026-API-for-checking-sent-chunks.patch => 1025-API-for-checking-sent-chunks.patch} (96%) delete mode 100644 patches/server/1025-Fix-and-optimise-world-force-upgrading.patch rename patches/server/{1027-Add-config-for-mobs-immune-to-default-effects.patch => 1026-Add-config-for-mobs-immune-to-default-effects.patch} (100%) rename patches/server/{1028-Deep-clone-nbt-tags-in-PDC.patch => 1027-Deep-clone-nbt-tags-in-PDC.patch} (100%) rename patches/server/{1029-Support-old-UUID-format-for-NBT.patch => 1028-Support-old-UUID-format-for-NBT.patch} (100%) rename patches/server/{1030-Fix-shield-disable-inconsistency.patch => 1029-Fix-shield-disable-inconsistency.patch} (93%) rename patches/server/{1031-Write-SavedData-IO-async.patch => 1030-Write-SavedData-IO-async.patch} (89%) rename patches/server/{1032-Don-t-lose-removed-data-components-in-ItemMeta.patch => 1031-Don-t-lose-removed-data-components-in-ItemMeta.patch} (100%) rename patches/server/{1033-Add-experimental-improved-give-command.patch => 1032-Add-experimental-improved-give-command.patch} (100%) rename patches/server/{1034-Handle-Large-Packets-disconnecting-client.patch => 1033-Handle-Large-Packets-disconnecting-client.patch} (100%) rename patches/server/{1035-Fix-ItemFlags.patch => 1034-Fix-ItemFlags.patch} (100%) rename patches/server/{1036-Fix-helmet-damage-reduction-inconsistencies.patch => 1035-Fix-helmet-damage-reduction-inconsistencies.patch} (100%) rename patches/server/{1037-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch => 1036-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch} (94%) rename patches/server/{1038-improve-checking-handled-tags-in-itemmeta.patch => 1037-improve-checking-handled-tags-in-itemmeta.patch} (100%) rename patches/server/{1039-General-ItemMeta-fixes.patch => 1038-General-ItemMeta-fixes.patch} (100%) rename patches/server/{1040-Expose-hasColor-to-leather-armor.patch => 1039-Expose-hasColor-to-leather-armor.patch} (100%) rename patches/server/{1041-Added-API-to-get-player-ha-proxy-address.patch => 1040-Added-API-to-get-player-ha-proxy-address.patch} (97%) rename patches/server/{1042-More-Chest-Block-API.patch => 1041-More-Chest-Block-API.patch} (100%) rename patches/server/{1043-Print-data-component-type-on-encoding-error.patch => 1042-Print-data-component-type-on-encoding-error.patch} (100%) rename patches/server/{1044-Fix-entity-tracker-desync-when-new-players-are-added.patch => 1043-Fix-entity-tracker-desync-when-new-players-are-added.patch} (100%) rename patches/server/{1045-Brigadier-based-command-API.patch => 1044-Brigadier-based-command-API.patch} (99%) rename patches/server/{1046-Fix-issues-with-Recipe-API.patch => 1045-Fix-issues-with-Recipe-API.patch} (100%) diff --git a/patches/server/1026-API-for-checking-sent-chunks.patch b/patches/server/1025-API-for-checking-sent-chunks.patch similarity index 96% rename from patches/server/1026-API-for-checking-sent-chunks.patch rename to patches/server/1025-API-for-checking-sent-chunks.patch index a08ada1670..01ec0b2993 100644 --- a/patches/server/1026-API-for-checking-sent-chunks.patch +++ b/patches/server/1025-API-for-checking-sent-chunks.patch @@ -21,7 +21,7 @@ index ee58c67cb2bd78159cce19ec75f13dc6168a0e7a..149cfb0587299f72fcfddf395fb71b70 // TODO rebase into util patch diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6f8999df04e6ad4d4d52e87b05a187f586d60c74..a9aa3dca65aca86cf535d6616f5d5db3e1e8fc8b 100644 +index 2d373be107a610522db9b3ce8ae446b848d92580..84ed5dc8c82e28aa93fa0440d90ddb44dc5f3d40 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3446,6 +3446,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/1025-Fix-and-optimise-world-force-upgrading.patch b/patches/server/1025-Fix-and-optimise-world-force-upgrading.patch deleted file mode 100644 index ce0b75bfbb..0000000000 --- a/patches/server/1025-Fix-and-optimise-world-force-upgrading.patch +++ /dev/null @@ -1,395 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 20 May 2021 07:02:22 -0700 -Subject: [PATCH] Fix and optimise world force upgrading - -The WorldUpgrader class was incorrectly modified by -CB. It will store an IChunkLoader instance for all -dimension types in the world, but obviously with how -CB shifts around worlds only one dimension type exists -per world. But this would be OK if CB did this -change correctly. All IChunkLoader instances -will point to the same regionfiles. And all -IChunkLoader instances are going to be read from. - -This problem hasn't really been reported because -it relies on the persistent legacy data to be converted -as well to cause corruption. Why? Because the legacy -data is also shared, it will result in different -outputs from conversion (as once conversion for legacy -persistent data takes place, it is REMOVED - so the next -convert will _not_ have the data). Which means different -sizes on disk. Which means different regionfile sector -allocations. Which means there are 3 different possible -regionfile sector allocations in memory, and none of them -are going to be correct. - -I've fixed this by writing a world upgrader suited to -CB's changes to world folder format. It was brain dead -easy to add threading, so I did. - -== AT == -public net.minecraft.util.worldupdate.WorldUpgrader REGEX - -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..e049fbe4038aaea896f45b11ce9ce8f05922c898 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -@@ -0,0 +1,222 @@ -+package io.papermc.paper.world; -+ -+import com.mojang.datafixers.DataFixer; -+import com.mojang.serialization.MapCodec; -+import net.minecraft.SharedConstants; -+import net.minecraft.core.RegistryAccess; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.resources.ResourceKey; -+import net.minecraft.util.worldupdate.WorldUpgrader; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.chunk.ChunkGenerator; -+import net.minecraft.world.level.chunk.storage.ChunkStorage; -+import net.minecraft.world.level.chunk.storage.RegionFileStorage; -+import net.minecraft.world.level.chunk.storage.RegionStorageInfo; -+import net.minecraft.world.level.dimension.LevelStem; -+import net.minecraft.world.level.storage.DimensionDataStorage; -+import net.minecraft.world.level.storage.LevelStorageSource; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+import java.io.File; -+import java.io.IOException; -+import java.text.DecimalFormat; -+import java.util.Optional; -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; -+import java.util.concurrent.ThreadFactory; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.function.Supplier; -+ -+public class ThreadedWorldUpgrader { -+ -+ private static final Logger LOGGER = LogManager.getLogger(); -+ -+ private final ResourceKey dimensionType; -+ private final String worldName; -+ private final File worldDir; -+ private final ExecutorService threadPool; -+ private final DataFixer dataFixer; -+ private final RegistryAccess registryLookup; -+ private final Optional>> generatorKey; -+ private final boolean removeCaches; -+ private final boolean recreateRegionFiles; // TODO -+ -+ public ThreadedWorldUpgrader(final ResourceKey dimensionType, final String worldName, final File worldDir, final int threads, -+ final DataFixer dataFixer, final RegistryAccess registryLookup, final Optional>> generatorKey, -+ final boolean removeCaches, final boolean recreateRegionFiles) { -+ this.dimensionType = dimensionType; -+ this.worldName = worldName; -+ this.worldDir = worldDir; -+ this.threadPool = Executors.newFixedThreadPool(Math.max(1, threads), new ThreadFactory() { -+ private final AtomicInteger threadCounter = new AtomicInteger(); -+ -+ @Override -+ public Thread newThread(final Runnable run) { -+ final Thread ret = new Thread(run); -+ -+ ret.setName("World upgrader thread for world " + ThreadedWorldUpgrader.this.worldName + " #" + this.threadCounter.getAndIncrement()); -+ ret.setUncaughtExceptionHandler((thread, throwable) -> { -+ LOGGER.fatal("Error upgrading world", throwable); -+ }); -+ -+ return ret; -+ } -+ }); -+ this.dataFixer = dataFixer; -+ this.registryLookup = registryLookup; -+ this.generatorKey = generatorKey; -+ this.removeCaches = removeCaches; -+ this.recreateRegionFiles = recreateRegionFiles; -+ } -+ -+ public void convert() { -+ final File worldFolder = LevelStorageSource.getStorageFolder(this.worldDir.toPath(), this.dimensionType).toFile(); -+ final DimensionDataStorage worldPersistentData = new DimensionDataStorage(new File(worldFolder, "data"), this.dataFixer, this.registryLookup); -+ -+ final File regionFolder = new File(worldFolder, "region"); -+ -+ LOGGER.info("Force upgrading {}", this.worldName); -+ LOGGER.info("Counting regionfiles for {}", this.worldName); -+ final File[] regionFiles = regionFolder.listFiles((final File dir, final String name) -> { -+ return WorldUpgrader.REGEX.matcher(name).matches(); -+ }); -+ if (regionFiles == null) { -+ LOGGER.info("Found no regionfiles to convert for world {}", this.worldName); -+ return; -+ } -+ LOGGER.info("Found {} regionfiles to convert", regionFiles.length); -+ LOGGER.info("Starting conversion now for world {}", this.worldName); -+ -+ // Only used for profiling, let's fill it anyways just in case -+ final RegionStorageInfo storageInfo = new RegionStorageInfo( -+ this.worldName, -+ ResourceKey.create(Registries.DIMENSION, this.dimensionType.location()), -+ "region" -+ ); -+ -+ final WorldInfo info = new WorldInfo(() -> worldPersistentData, -+ new ChunkStorage(storageInfo, regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey); -+ -+ long expectedChunks = (long)regionFiles.length * (32L * 32L); -+ -+ for (final File regionFile : regionFiles) { -+ final ChunkPos regionPos = RegionFileStorage.getRegionFileCoordinates(regionFile.toPath()); -+ if (regionPos == null) { -+ expectedChunks -= (32L * 32L); -+ continue; -+ } -+ -+ this.threadPool.execute(new ConvertTask(info, regionPos.x >> 5, regionPos.z >> 5)); -+ } -+ this.threadPool.shutdown(); -+ -+ final DecimalFormat format = new DecimalFormat("#0.00"); -+ -+ final long start = System.nanoTime(); -+ -+ while (!this.threadPool.isTerminated()) { -+ final long current = info.convertedChunks.get(); -+ -+ LOGGER.info("{}% completed ({} / {} chunks)...", format.format((double)current / (double)expectedChunks * 100.0), current, expectedChunks); -+ -+ try { -+ Thread.sleep(1000L); -+ } catch (final InterruptedException ignore) {} -+ } -+ -+ final long end = System.nanoTime(); -+ -+ try { -+ info.loader.close(); -+ } catch (final IOException ex) { -+ LOGGER.fatal("Failed to close chunk loader", ex); -+ } -+ LOGGER.info("Completed conversion. Took {}s, {} out of {} chunks needed to be converted/modified ({}%)", -+ (int)Math.ceil((end - start) * 1.0e-9), info.modifiedChunks.get(), expectedChunks, format.format((double)info.modifiedChunks.get() / (double)expectedChunks * 100.0)); -+ } -+ -+ private static final class WorldInfo { -+ -+ public final Supplier persistentDataSupplier; -+ public final ChunkStorage loader; -+ public final boolean removeCaches; -+ public final ResourceKey worldKey; -+ public final Optional>> generatorKey; -+ public final AtomicLong convertedChunks = new AtomicLong(); -+ public final AtomicLong modifiedChunks = new AtomicLong(); -+ -+ private WorldInfo(final Supplier persistentDataSupplier, final ChunkStorage loader, final boolean removeCaches, -+ final ResourceKey worldKey, Optional>> generatorKey) { -+ this.persistentDataSupplier = persistentDataSupplier; -+ this.loader = loader; -+ this.removeCaches = removeCaches; -+ this.worldKey = worldKey; -+ this.generatorKey = generatorKey; -+ } -+ } -+ -+ private static final class ConvertTask implements Runnable { -+ -+ private final WorldInfo worldInfo; -+ private final int regionX; -+ private final int regionZ; -+ -+ public ConvertTask(final WorldInfo worldInfo, final int regionX, final int regionZ) { -+ this.worldInfo = worldInfo; -+ this.regionX = regionX; -+ this.regionZ = regionZ; -+ } -+ -+ @Override -+ public void run() { -+ final int regionCX = this.regionX << 5; -+ final int regionCZ = this.regionZ << 5; -+ -+ final Supplier persistentDataSupplier = this.worldInfo.persistentDataSupplier; -+ final ChunkStorage loader = this.worldInfo.loader; -+ final boolean removeCaches = this.worldInfo.removeCaches; -+ final ResourceKey worldKey = this.worldInfo.worldKey; -+ -+ for (int cz = regionCZ; cz < (regionCZ + 32); ++cz) { -+ for (int cx = regionCX; cx < (regionCX + 32); ++cx) { -+ final ChunkPos chunkPos = new ChunkPos(cx, cz); -+ try { -+ // no need to check the coordinate of the chunk, the regionfilecache does that for us -+ -+ CompoundTag chunkNBT = (loader.read(chunkPos).join()).orElse(null); -+ -+ if (chunkNBT == null) { -+ continue; -+ } -+ -+ final int versionBefore = ChunkStorage.getVersion(chunkNBT); -+ -+ chunkNBT = loader.upgradeChunkTag(worldKey, persistentDataSupplier, chunkNBT, this.worldInfo.generatorKey, chunkPos, null); -+ -+ boolean modified = versionBefore < SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -+ -+ if (removeCaches) { -+ final CompoundTag level = chunkNBT.getCompound("Level"); -+ modified |= level.contains("Heightmaps"); -+ level.remove("Heightmaps"); -+ modified |= level.contains("isLightOn"); -+ level.remove("isLightOn"); -+ } -+ -+ if (modified) { -+ this.worldInfo.modifiedChunks.getAndIncrement(); -+ loader.write(chunkPos, chunkNBT); -+ } -+ } catch (final Exception ex) { -+ LOGGER.error("Error upgrading chunk {}", chunkPos, ex); -+ } finally { -+ this.worldInfo.convertedChunks.getAndIncrement(); -+ } -+ } -+ } -+ } -+ } -+} -diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 244a19ecd0234fa1d7a6ecfea20751595688605d..5443013060b62e3bfcc51cddca96d1c0bc59fe72 100644 ---- a/src/main/java/net/minecraft/server/Main.java -+++ b/src/main/java/net/minecraft/server/Main.java -@@ -392,6 +392,15 @@ public class Main { - return new WorldLoader.InitConfig(worldloader_d, Commands.CommandSelection.DEDICATED, serverPropertiesHandler.functionPermissionLevel); - } - -+ // Paper start - fix and optimise world upgrading -+ public static void convertWorldButItWorks(net.minecraft.resources.ResourceKey dimensionType, net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess worldSession, -+ DataFixer dataFixer, RegistryAccess registryLookup, Optional>> generatorKey, boolean removeCaches, boolean recreateRegionFiles) { -+ int threads = Runtime.getRuntime().availableProcessors() * 3 / 8; -+ final io.papermc.paper.world.ThreadedWorldUpgrader worldUpgrader = new io.papermc.paper.world.ThreadedWorldUpgrader(dimensionType, worldSession.getLevelId(), worldSession.levelDirectory.path().toFile(), threads, dataFixer, registryLookup, generatorKey, removeCaches, recreateRegionFiles); -+ worldUpgrader.convert(); -+ } -+ // Paper end - fix and optimise world upgrading -+ - public static void forceUpgrade(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, boolean eraseCache, BooleanSupplier continueCheck, RegistryAccess dynamicRegistryManager, boolean recreateRegionFiles) { - Main.LOGGER.info("Forcing world upgrade! {}", session.getLevelId()); // CraftBukkit - WorldUpgrader worldupgrader = new WorldUpgrader(session, dataFixer, dynamicRegistryManager, eraseCache, recreateRegionFiles); -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0408d5d54fef7767ecf70e70686ad520d890ff26..f525a8735e5cf5eb1278e2a3002ac81d9fff7b1a 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -596,11 +596,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -- return true; -- }, iregistrycustom_dimension, this.options.has("recreateRegionFiles")); -- } -+ // Paper - fix and optimise world upgrading; move down - - PrimaryLevelData iworlddataserver = worlddata; - boolean flag = worlddata.isDebugWorld(); -@@ -615,6 +611,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop worldKey = ResourceKey.create(Registries.DIMENSION, dimensionKey.location()); - - if (dimensionKey == LevelStem.OVERWORLD) { -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 0a8eeebb2d702ebcefd9f26cc0f41d1eab497902..b4ef3ad2c17168085372f1fe46809f02d9dfe74a 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -178,6 +178,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions - public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here - -+ // Paper start - fix and optimise world upgrading -+ // copied from below -+ public static ResourceKey getDimensionKey(DimensionType manager) { -+ return ((org.bukkit.craftbukkit.CraftServer)org.bukkit.Bukkit.getServer()).getHandle().getServer().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.DIMENSION_TYPE).getResourceKey(manager).orElseThrow(() -> { -+ return new IllegalStateException("Unregistered dimension type: " + manager); -+ }); -+ } -+ // Paper end - fix and optimise world upgrading -+ - public CraftWorld getWorld() { - return this.world; - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -index 249705ec1b8b692ef1d7fec34a04918afe6486bc..f6e3b745fc417354380d4a969f83aee430bad785 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -@@ -69,6 +69,29 @@ public class RegionFileStorage implements AutoCloseable { - } - - // Paper start -+ @Nullable -+ public static ChunkPos getRegionFileCoordinates(Path file) { -+ String fileName = file.getFileName().toString(); -+ if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) { -+ return null; -+ } -+ -+ String[] split = fileName.split("\\."); -+ -+ if (split.length != 4) { -+ return null; -+ } -+ -+ try { -+ int x = Integer.parseInt(split[1]); -+ int z = Integer.parseInt(split[2]); -+ -+ return new ChunkPos(x << 5, z << 5); -+ } catch (NumberFormatException ex) { -+ return null; -+ } -+ } -+ - public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) { - return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ())); - } -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8e0b0e4b177f1bcf23e174dfca6eaa0f7203a95a..b63dc96d2b387bd0a6bd3c703853b40a337bb33f 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1361,9 +1361,7 @@ public final class CraftServer implements Server { - worlddata.checkName(name); - worlddata.setModdedInfo(this.console.getServerModName(), this.console.getModdedStatus().shouldReportAsModified()); - -- if (this.console.options.has("forceUpgrade")) { -- net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), this.console.options.has("eraseCache"), () -> true, iregistrycustom_dimension, this.console.options.has("recreateRegionFiles")); -- } -+ // Paper - fix and optimise world upgrading; move down - - long j = BiomeManager.obfuscateSeed(worlddata.worldGenOptions().seed()); // Paper - use world seed - List list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata)); -@@ -1374,6 +1372,13 @@ public final class CraftServer implements Server { - biomeProvider = generator.getDefaultBiomeProvider(worldInfo); - } - -+ // Paper start - fix and optimise world upgrading -+ if (this.console.options.has("forceUpgrade")) { -+ net.minecraft.server.Main.convertWorldButItWorks( -+ actualDimension, worldSession, DataFixers.getDataFixer(), iregistrycustom_dimension, worlddimension.generator().getTypeNameForDataFixer(), this.console.options.has("eraseCache"), this.console.options.has("recreateRegionFiles") -+ ); -+ } -+ // Paper end - fix and optimise world upgrading - ResourceKey worldKey; - String levelName = this.getServer().getProperties().levelName; - if (name.equals(levelName + "_nether")) { diff --git a/patches/server/1027-Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/1026-Add-config-for-mobs-immune-to-default-effects.patch similarity index 100% rename from patches/server/1027-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/server/1026-Add-config-for-mobs-immune-to-default-effects.patch diff --git a/patches/server/1028-Deep-clone-nbt-tags-in-PDC.patch b/patches/server/1027-Deep-clone-nbt-tags-in-PDC.patch similarity index 100% rename from patches/server/1028-Deep-clone-nbt-tags-in-PDC.patch rename to patches/server/1027-Deep-clone-nbt-tags-in-PDC.patch diff --git a/patches/server/1029-Support-old-UUID-format-for-NBT.patch b/patches/server/1028-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/server/1029-Support-old-UUID-format-for-NBT.patch rename to patches/server/1028-Support-old-UUID-format-for-NBT.patch diff --git a/patches/server/1030-Fix-shield-disable-inconsistency.patch b/patches/server/1029-Fix-shield-disable-inconsistency.patch similarity index 93% rename from patches/server/1030-Fix-shield-disable-inconsistency.patch rename to patches/server/1029-Fix-shield-disable-inconsistency.patch index 757be91657..bcc617a146 100644 --- a/patches/server/1030-Fix-shield-disable-inconsistency.patch +++ b/patches/server/1029-Fix-shield-disable-inconsistency.patch @@ -8,7 +8,7 @@ it will not disable the shield if the attacker is holding an axe item. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ca242ba1312263ec095fa2850dc0f02351e844ab..2338e41fde55559249d5f212697235e789b20b2a 100644 +index d6a7642697c08bcdc69b4f1d4475f0532e131b80..a1a72712e9acd4023c4b6832e5ec09dcc3676b6e 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2341,7 +2341,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/1031-Write-SavedData-IO-async.patch b/patches/server/1030-Write-SavedData-IO-async.patch similarity index 89% rename from patches/server/1031-Write-SavedData-IO-async.patch rename to patches/server/1030-Write-SavedData-IO-async.patch index 365011d581..66e24700a5 100644 --- a/patches/server/1031-Write-SavedData-IO-async.patch +++ b/patches/server/1030-Write-SavedData-IO-async.patch @@ -5,26 +5,6 @@ Subject: [PATCH] Write SavedData IO async Co-Authored-By: Shane Freeder -diff --git a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -index e049fbe4038aaea896f45b11ce9ce8f05922c898..7f6d1ccd147e5593412567bb2934ce5662da7ef0 100644 ---- a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -+++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -@@ -110,6 +110,15 @@ public class ThreadedWorldUpgrader { - } - - this.threadPool.execute(new ConvertTask(info, regionPos.x >> 5, regionPos.z >> 5)); -+ // Paper start - Write SavedData IO async -+ this.threadPool.execute(() -> { -+ try { -+ worldPersistentData.close(); -+ } catch (IOException exception) { -+ LOGGER.error("Failed to close persistent world data", exception); -+ } -+ }); -+ // Paper end - Write SavedData IO async - } - this.threadPool.shutdown(); - diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index 36caf354634d6675a3f1ec6829f4778e1d0623bc..b99f50604bafecbc68835974c9ed0caa91911a40 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -81,7 +61,7 @@ index aab652174a8175765cad548f7c61ce353ca74803..ca56a0b596976448da6bb2a0e82b3d5c public List getEntities(EntityTypeTest filter, Predicate predicate) { diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index 639f72618a7c22fa94effa9d0406b97fffc64cb5..3e582c49069f2a820ba3baac03917493877d9875 100644 +index ffbb3bf9ff3fc968ef69d4f889b0baf7e8ab691b..954d468459fe167ede0e7fca5b9f99da565d59e1 100644 --- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java +++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java @@ -116,7 +116,13 @@ public class WorldUpgrader { diff --git a/patches/server/1032-Don-t-lose-removed-data-components-in-ItemMeta.patch b/patches/server/1031-Don-t-lose-removed-data-components-in-ItemMeta.patch similarity index 100% rename from patches/server/1032-Don-t-lose-removed-data-components-in-ItemMeta.patch rename to patches/server/1031-Don-t-lose-removed-data-components-in-ItemMeta.patch diff --git a/patches/server/1033-Add-experimental-improved-give-command.patch b/patches/server/1032-Add-experimental-improved-give-command.patch similarity index 100% rename from patches/server/1033-Add-experimental-improved-give-command.patch rename to patches/server/1032-Add-experimental-improved-give-command.patch diff --git a/patches/server/1034-Handle-Large-Packets-disconnecting-client.patch b/patches/server/1033-Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/server/1034-Handle-Large-Packets-disconnecting-client.patch rename to patches/server/1033-Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/server/1035-Fix-ItemFlags.patch b/patches/server/1034-Fix-ItemFlags.patch similarity index 100% rename from patches/server/1035-Fix-ItemFlags.patch rename to patches/server/1034-Fix-ItemFlags.patch diff --git a/patches/server/1036-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/1035-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 100% rename from patches/server/1036-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/server/1035-Fix-helmet-damage-reduction-inconsistencies.patch diff --git a/patches/server/1037-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/1036-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 94% rename from patches/server/1037-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/server/1036-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch index e471865c85..84ae9df20b 100644 --- a/patches/server/1037-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch +++ b/patches/server/1036-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Revert to vanilla handling of LivingEntity#actuallyHurt diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 2338e41fde55559249d5f212697235e789b20b2a..517e10c3d8b1549cd30fd0e7cf2bcb35e88eb8ed 100644 +index a1a72712e9acd4023c4b6832e5ec09dcc3676b6e..ef0f118aecf0893e45cb9423a677d7e42496324b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2226,7 +2226,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/1038-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/1037-improve-checking-handled-tags-in-itemmeta.patch similarity index 100% rename from patches/server/1038-improve-checking-handled-tags-in-itemmeta.patch rename to patches/server/1037-improve-checking-handled-tags-in-itemmeta.patch diff --git a/patches/server/1039-General-ItemMeta-fixes.patch b/patches/server/1038-General-ItemMeta-fixes.patch similarity index 100% rename from patches/server/1039-General-ItemMeta-fixes.patch rename to patches/server/1038-General-ItemMeta-fixes.patch diff --git a/patches/server/1040-Expose-hasColor-to-leather-armor.patch b/patches/server/1039-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/server/1040-Expose-hasColor-to-leather-armor.patch rename to patches/server/1039-Expose-hasColor-to-leather-armor.patch diff --git a/patches/server/1041-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/1040-Added-API-to-get-player-ha-proxy-address.patch similarity index 97% rename from patches/server/1041-Added-API-to-get-player-ha-proxy-address.patch rename to patches/server/1040-Added-API-to-get-player-ha-proxy-address.patch index 364197b03e..a9b47406aa 100644 --- a/patches/server/1041-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/server/1040-Added-API-to-get-player-ha-proxy-address.patch @@ -35,7 +35,7 @@ index 52f537b7bfbdeaad9d17c0e88a1ed1c8925a833f..8aff5129f85ab5729b3da2e465871be6 } else { super.channelRead(ctx, msg); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a9aa3dca65aca86cf535d6616f5d5db3e1e8fc8b..561a7a8e96e2d91bbb87fe6230e94b5f38073d27 100644 +index 84ed5dc8c82e28aa93fa0440d90ddb44dc5f3d40..7e6116963d835d4606ef3d93b69d3e44b61288e1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -273,6 +273,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/1042-More-Chest-Block-API.patch b/patches/server/1041-More-Chest-Block-API.patch similarity index 100% rename from patches/server/1042-More-Chest-Block-API.patch rename to patches/server/1041-More-Chest-Block-API.patch diff --git a/patches/server/1043-Print-data-component-type-on-encoding-error.patch b/patches/server/1042-Print-data-component-type-on-encoding-error.patch similarity index 100% rename from patches/server/1043-Print-data-component-type-on-encoding-error.patch rename to patches/server/1042-Print-data-component-type-on-encoding-error.patch diff --git a/patches/server/1044-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1043-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 100% rename from patches/server/1044-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/server/1043-Fix-entity-tracker-desync-when-new-players-are-added.patch diff --git a/patches/server/1045-Brigadier-based-command-API.patch b/patches/server/1044-Brigadier-based-command-API.patch similarity index 99% rename from patches/server/1045-Brigadier-based-command-API.patch rename to patches/server/1044-Brigadier-based-command-API.patch index 638a5b18f4..61d00aaac5 100644 --- a/patches/server/1045-Brigadier-based-command-API.patch +++ b/patches/server/1044-Brigadier-based-command-API.patch @@ -2154,7 +2154,7 @@ index 982b2bab27e3d55d0ba07060862c0c3183ad91b0..5fa8a3343ffc11e82c20b78a73205fd8 Component component = message.resolveComponent(commandSourceStack); CommandSigningContext commandSigningContext = commandSourceStack.getSigningContext(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f525a8735e5cf5eb1278e2a3002ac81d9fff7b1a..dbc86b8d4d2af6e5f7e678f2bb77fd39b85c04c5 100644 +index 0408d5d54fef7767ecf70e70686ad520d890ff26..0ed42fa899721f83b598db05be1b5f321af3614a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -299,7 +299,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -2195,7 +2195,7 @@ index f525a8735e5cf5eb1278e2a3002ac81d9fff7b1a..dbc86b8d4d2af6e5f7e678f2bb77fd39 this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -2320,8 +2322,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop