From 6a3d83f459072c32b39b90bd027bb406818bba5d Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Mon, 4 Jul 2022 16:38:06 +0200
Subject: [PATCH] Updated Upstream (Bukkit/CraftBukkit/Spigot) (#8092)

Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
d41796de SPIGOT-7071: Add Player#stopSound(SoundCategory category)
61dae5b2 SPIGOT-7011, SPIGOT-7065: Overhaul of structures

CraftBukkit Changes:
991aeda12 SPIGOT-1729, SPIGOT-7090: Keep precision in teleportation between worlds
5c9a5f628 SPIGOT-7071: Add Player#stopSound(SoundCategory category)
68f888ded SPIGOT-7011, SPIGOT-7065: Overhaul of structures
0231a3746 Remove outdated build delay.

Spigot Changes:
475f6008 Rebuild patches
8ce1761f Rebuild patches
---
 patches/api/Add-StructuresLocateEvent.patch   |  2 +-
 patches/api/Expand-the-Registry-API.patch     | 36 ---------
 patches/api/More-PotionEffectType-API.patch   |  2 +-
 patches/api/More-World-API.patch              |  2 +-
 patches/server/Add-GameEvent-tags.patch       | 12 +--
 patches/server/Add-PaperRegistry.patch        |  6 +-
 ...d-missing-default-perms-for-commands.patch |  2 +-
 ...llow-delegation-to-vanilla-chunk-gen.patch |  6 +-
 patches/server/Anti-Xray.patch                |  4 +-
 patches/server/Build-system-changes.patch     |  2 +-
 patches/server/Expand-world-key-API.patch     |  6 +-
 ...vanilla-BiomeProvider-from-WorldInfo.patch |  2 +-
 .../Fix-World-locateNearestStructure.patch    | 74 -------------------
 ...m-duplication-issues-and-teleport-is.patch |  2 +-
 .../server/Implement-regenerateChunk.patch    | 10 ++-
 patches/server/More-World-API.patch           |  2 +-
 ...oleAppender-for-console-improvements.patch |  2 +-
 work/Bukkit                                   |  2 +-
 work/CraftBukkit                              |  2 +-
 work/Spigot                                   |  2 +-
 20 files changed, 35 insertions(+), 143 deletions(-)
 delete mode 100644 patches/api/Expand-the-Registry-API.patch
 delete mode 100644 patches/server/Fix-World-locateNearestStructure.patch

diff --git a/patches/api/Add-StructuresLocateEvent.patch b/patches/api/Add-StructuresLocateEvent.patch
index b2fbf4bb27..66a5729ca4 100644
--- a/patches/api/Add-StructuresLocateEvent.patch
+++ b/patches/api/Add-StructuresLocateEvent.patch
@@ -455,7 +455,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Configured structures.
 +     * @see io.papermc.paper.world.structure.ConfiguredStructure
 +     */
-+    Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getUnsafe().registryFor(io.papermc.paper.world.structure.ConfiguredStructure.class);
++    Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
 +    // Paper end
  
      /**
diff --git a/patches/api/Expand-the-Registry-API.patch b/patches/api/Expand-the-Registry-API.patch
deleted file mode 100644
index cf3e1d1300..0000000000
--- a/patches/api/Expand-the-Registry-API.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <jake.m.potrebic@gmail.com>
-Date: Sat, 14 Aug 2021 16:19:03 -0700
-Subject: [PATCH] Expand the Registry API
-
-
-diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/Registry.java
-+++ b/src/main/java/org/bukkit/Registry.java
-@@ -0,0 +0,0 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
-             return Arrays.stream(org.bukkit.potion.PotionEffectType.values()).iterator();
-         }
-     };
-+
-+    /**
-+     * Structure types.
-+     *
-+     * @see StructureType
-+     */
-+    Registry<StructureType> STRUCTURE_TYPE = new Registry<StructureType>() {
-+
-+        @Override
-+        public @Nullable StructureType get(@NotNull NamespacedKey key) {
-+            return StructureType.getStructureTypes().get(key.getKey());
-+        }
-+
-+        @NotNull
-+        @Override
-+        public Iterator<StructureType> iterator() {
-+            return StructureType.getStructureTypes().values().iterator();
-+        }
-+    };
-     // Paper end
- 
-     /**
diff --git a/patches/api/More-PotionEffectType-API.patch b/patches/api/More-PotionEffectType-API.patch
index 661dd040e4..107b226b2c 100644
--- a/patches/api/More-PotionEffectType-API.patch
+++ b/patches/api/More-PotionEffectType-API.patch
@@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
       * @see io.papermc.paper.world.structure.ConfiguredStructure
       */
-     Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getUnsafe().registryFor(io.papermc.paper.world.structure.ConfiguredStructure.class);
+     Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Bukkit.getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class);
 +    /**
 +     * Potion effect types.
 +     *
diff --git a/patches/api/More-World-API.patch b/patches/api/More-World-API.patch
index 9c9c7ab6e8..c848a26b82 100644
--- a/patches/api/More-World-API.patch
+++ b/patches/api/More-World-API.patch
@@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +++ b/src/main/java/org/bukkit/World.java
 @@ -0,0 +0,0 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
      @Nullable
-     public Location locateNearestStructure(@NotNull Location origin, @NotNull StructureType structureType, int radius, boolean findUnexplored);
+     StructureSearchResult locateNearestStructure(@NotNull Location origin, @NotNull Structure structure, int radius, boolean findUnexplored);
  
 +    // Paper start
 +    /**
diff --git a/patches/server/Add-GameEvent-tags.patch b/patches/server/Add-GameEvent-tags.patch
index 979763f4f6..ffc6202965 100644
--- a/patches/server/Add-GameEvent-tags.patch
+++ b/patches/server/Add-GameEvent-tags.patch
@@ -49,15 +49,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-                     return (org.bukkit.Tag<T>) new CraftEntityTag(Registry.ENTITY_TYPE, entityTagKey);
+                     return (org.bukkit.Tag<T>) new CraftEntityTag(net.minecraft.core.Registry.ENTITY_TYPE, entityTagKey);
                  }
              }
 +            // Paper start
 +            case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> {
 +                Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class, "Game Event namespace must have GameEvent type");
-+                TagKey<net.minecraft.world.level.gameevent.GameEvent> gameEventTagKey = TagKey.create(Registry.GAME_EVENT_REGISTRY, key);
-+                if (Registry.GAME_EVENT.isKnownTagName(gameEventTagKey)) {
-+                    return (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(Registry.GAME_EVENT, gameEventTagKey);
++                TagKey<net.minecraft.world.level.gameevent.GameEvent> gameEventTagKey = TagKey.create(net.minecraft.core.Registry.GAME_EVENT_REGISTRY, key);
++                if (net.minecraft.core.Registry.GAME_EVENT.isKnownTagName(gameEventTagKey)) {
++                    return (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(net.minecraft.core.Registry.GAME_EVENT, gameEventTagKey);
 +                }
 +            }
 +            // Paper end
@@ -65,13 +65,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          }
  
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-                 Registry<EntityType<?>> entityTags = Registry.ENTITY_TYPE;
+                 net.minecraft.core.Registry<EntityType<?>> entityTags = net.minecraft.core.Registry.ENTITY_TYPE;
                  return entityTags.getTags().map(pair -> (org.bukkit.Tag<T>) new CraftEntityTag(entityTags, pair.getFirst())).collect(ImmutableList.toImmutableList());
              }
 +            // Paper start
 +            case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> {
 +                Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class);
-+                Registry<net.minecraft.world.level.gameevent.GameEvent> gameEvents = Registry.GAME_EVENT;
++                net.minecraft.core.Registry<net.minecraft.world.level.gameevent.GameEvent> gameEvents = net.minecraft.core.Registry.GAME_EVENT;
 +                return gameEvents.getTags().map(pair -> (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(gameEvents, pair.getFirst())).collect(ImmutableList.toImmutableList());
 +            // Paper end
 +            }
diff --git a/patches/server/Add-PaperRegistry.patch b/patches/server/Add-PaperRegistry.patch
index 2bf6f5d6db..2bad1231e2 100644
--- a/patches/server/Add-PaperRegistry.patch
+++ b/patches/server/Add-PaperRegistry.patch
@@ -227,16 +227,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public abstract class AbstractTestingBase {
          MultiPackResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, Collections.singletonList(new VanillaPackResources(ServerPacksSource.BUILT_IN_METADATA, "minecraft")));
          // add tags and loot tables for unit tests
-         RegistryAccess.Frozen registry = RegistryAccess.builtinCopy().freeze();
+         REGISTRY_CUSTOM = RegistryAccess.builtinCopy().freeze();
 +        // Paper start
 +        try {
 +            java.lang.reflect.Field field = io.papermc.paper.registry.PaperRegistry.class.getDeclaredField("REGISTRY_ACCESS");
 +            field.trySetAccessible();
-+            field.set(null, com.google.common.base.Suppliers.ofInstance(registry));
++            field.set(null, com.google.common.base.Suppliers.ofInstance(REGISTRY_CUSTOM));
 +        } catch (ReflectiveOperationException ex) {
 +            throw new IllegalStateException("Could not reflectively set RegistryAccess in PaperRegistry", ex);
 +        }
 +        // Paper end
          // Register vanilla pack
-         DATA_PACK = ReloadableServerResources.loadResources(resourceManager, registry, Commands.CommandSelection.DEDICATED, 0, MoreExecutors.directExecutor(), MoreExecutors.directExecutor()).join();
+         DATA_PACK = ReloadableServerResources.loadResources(resourceManager, REGISTRY_CUSTOM, Commands.CommandSelection.DEDICATED, 0, MoreExecutors.directExecutor(), MoreExecutors.directExecutor()).join();
          // Bind tags
diff --git a/patches/server/Added-missing-default-perms-for-commands.patch b/patches/server/Added-missing-default-perms-for-commands.patch
index 7bb9f20106..84ed064cb6 100644
--- a/patches/server/Added-missing-default-perms-for-commands.patch
+++ b/patches/server/Added-missing-default-perms-for-commands.patch
@@ -176,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public final class DummyServer implements InvocationHandler {
                          }
                      }
-                 );
+             );
 -            Bukkit.setServer(Proxy.getProxyClass(Server.class.getClassLoader(), Server.class).asSubclass(Server.class).getConstructor(InvocationHandler.class).newInstance(new DummyServer()));
 +            // Paper start - modeled off of TestServer in the API tests module
 +            methods.put(
diff --git a/patches/server/Allow-delegation-to-vanilla-chunk-gen.patch b/patches/server/Allow-delegation-to-vanilla-chunk-gen.patch
index ae56f4dbf9..3bd6d405d6 100644
--- a/patches/server/Allow-delegation-to-vanilla-chunk-gen.patch
+++ b/patches/server/Allow-delegation-to-vanilla-chunk-gen.patch
@@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ 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
+         return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY), world); // Paper - Anti-Xray - Add parameters
      }
  
 +    // Paper start
@@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public ChunkGenerator.ChunkData createVanillaChunkData(World world, int x, int z) {
 +        // do bunch of vanilla shit
 +        final net.minecraft.server.level.ServerLevel serverLevel = ((CraftWorld) world).getHandle();
-+        final Registry<net.minecraft.world.level.biome.Biome> biomeRegistry = serverLevel.getServer().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
++        final net.minecraft.core.Registry<net.minecraft.world.level.biome.Biome> biomeRegistry = serverLevel.getServer().registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY);
 +        final net.minecraft.world.level.chunk.ProtoChunk protoChunk = new net.minecraft.world.level.chunk.ProtoChunk(
 +            new net.minecraft.world.level.ChunkPos(x, z),
 +            net.minecraft.world.level.chunk.UpgradeData.EMPTY,
@@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    if (xx == chunkPos.x && zz == chunkPos.z) {
 +                        chunks.add(protoChunk);
 +                    } else {
-+                        final net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> biomeHolder = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
++                        final net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> biomeHolder = serverLevel.registryAccess().registryOrThrow(net.minecraft.core.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/Anti-Xray.patch b/patches/server/Anti-Xray.patch
index 821894c7d6..adf5ca54a7 100644
--- a/patches/server/Anti-Xray.patch
+++ b/patches/server/Anti-Xray.patch
@@ -1613,8 +1613,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public ChunkGenerator.ChunkData createChunkData(World world) {
          Validate.notNull(world, "World cannot be null");
          ServerLevel handle = ((CraftWorld) world).getHandle();
--        return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY));
-+        return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), world); // Paper - Anti-Xray - Add parameters
+-        return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY));
++        return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY), world); // Paper - Anti-Xray - Add parameters
      }
  
      @Override
diff --git a/patches/server/Build-system-changes.patch b/patches/server/Build-system-changes.patch
index 3ddabd96bb..93639e823b 100644
--- a/patches/server/Build-system-changes.patch
+++ b/patches/server/Build-system-changes.patch
@@ -73,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class Main {
                  }
  
-                 if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
+                 if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
 -                    Date buildDate = new Date(Integer.parseInt(Main.class.getPackage().getImplementationVendor()) * 1000L);
 +                    Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(Main.class.getPackage().getImplementationVendor()); // Paper
  
diff --git a/patches/server/Expand-world-key-API.patch b/patches/server/Expand-world-key-API.patch
index 26f21aabfb..f730e4169e 100644
--- a/patches/server/Expand-world-key-API.patch
+++ b/patches/server/Expand-world-key-API.patch
@@ -45,8 +45,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          } else if (name.equals(levelName + "_the_end")) {
              worldKey = net.minecraft.world.level.Level.END;
          } else {
--            worldKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(name.toLowerCase(java.util.Locale.ENGLISH)));
-+            worldKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, new net.minecraft.resources.ResourceLocation(creator.key().getNamespace().toLowerCase(java.util.Locale.ENGLISH), creator.key().getKey().toLowerCase(java.util.Locale.ENGLISH))); // Paper
+-            worldKey = ResourceKey.create(net.minecraft.core.Registry.DIMENSION_REGISTRY, new ResourceLocation(name.toLowerCase(java.util.Locale.ENGLISH)));
++            worldKey = ResourceKey.create(net.minecraft.core.Registry.DIMENSION_REGISTRY, new net.minecraft.resources.ResourceLocation(creator.key().getNamespace().toLowerCase(java.util.Locale.ENGLISH), creator.key().getKey().toLowerCase(java.util.Locale.ENGLISH))); // Paper
          }
  
          ServerLevel internal = (ServerLevel) new ServerLevel(this.console, console.executor, worldSession, worlddata, worldKey, worlddimension, this.getServer().progressListenerFactory.create(11),
@@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start
 +    @Override
 +    public World getWorld(NamespacedKey worldKey) {
-+        ServerLevel worldServer = console.getLevel(ResourceKey.create(Registry.DIMENSION_REGISTRY, CraftNamespacedKey.toMinecraft(worldKey)));
++        ServerLevel worldServer = console.getLevel(ResourceKey.create(net.minecraft.core.Registry.DIMENSION_REGISTRY, CraftNamespacedKey.toMinecraft(worldKey)));
 +        if (worldServer == null) return null;
 +        return worldServer.getWorld();
 +    }
diff --git a/patches/server/Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/server/Expose-vanilla-BiomeProvider-from-WorldInfo.patch
index 271c438b2b..36ecc64498 100644
--- a/patches/server/Expose-vanilla-BiomeProvider-from-WorldInfo.patch
+++ b/patches/server/Expose-vanilla-BiomeProvider-from-WorldInfo.patch
@@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
 @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
-         Registry<LevelStem> iregistry = worlddata.worldGenSettings().dimensions();
+         net.minecraft.core.Registry<LevelStem> iregistry = worlddata.worldGenSettings().dimensions();
          LevelStem worlddimension = (LevelStem) iregistry.get(actualDimension);
  
 -        WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.typeHolder().value());
diff --git a/patches/server/Fix-World-locateNearestStructure.patch b/patches/server/Fix-World-locateNearestStructure.patch
deleted file mode 100644
index f221ad3dc5..0000000000
--- a/patches/server/Fix-World-locateNearestStructure.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <jake.m.potrebic@gmail.com>
-Date: Tue, 1 Mar 2022 14:12:17 -0800
-Subject: [PATCH] Fix World#locateNearestStructure
-
-1.18.2 switched to TagKeys to reference tags of objects, and this method
-  impl needs to be changed to reflect that
-
-diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/MinecraftServer.java
-+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
-             this.resources.managers.updateRegistryTags(this.registryAccess());
-             io.papermc.paper.registry.PaperRegistry.clearCaches(); // Paper
-             net.minecraft.world.item.alchemy.PotionBrewing.reload(); // Paper
-+            // Paper start - clear cache cause datapacks can add more configured structures
-+            for (ServerLevel level : this.levels.values()) {
-+                level.getWorld().structureCache.clear();
-+            }
-+            // Paper end
-             new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
-             // Paper start
-             if (Thread.currentThread() != this.serverThread) {
-diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
-             if (optional.isEmpty()) {
-                 return null;
-             } else {
--                Pair<BlockPos, Holder<Structure>> pair = this.getChunkSource().getGenerator().findNearestMapStructure(this, (HolderSet) optional.get(), pos, radius, skipReferencedStructures);
-+                // Paper start
-+                return this.findNearestMapFeature(optional.get(), pos, radius, skipReferencedStructures);
-+            }
-+        }
-+    }
-+    public @Nullable BlockPos findNearestMapFeature(HolderSet<Structure> holderSet, BlockPos pos, int radius, boolean skipReferencedStructures) {
-+        {
-+            {
-+                Pair<BlockPos, Holder<Structure>> pair = this.getChunkSource().getGenerator().findNearestMapStructure(this, holderSet, pos, radius, skipReferencedStructures);
-+                // Paper end
- 
-                 return pair != null ? (BlockPos) pair.getFirst() : null;
-             }
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- 
-     }
- 
-+    public final Map<StructureType, List<Holder.Reference<net.minecraft.world.level.levelgen.structure.Structure>>> structureCache = new java.util.HashMap<>(); // Paper
-     @Override
-     public Location locateNearestStructure(Location origin, StructureType structureType, int radius, boolean findUnexplored) {
-         BlockPos originPos = new BlockPos(origin.getX(), origin.getY(), origin.getZ());
--        BlockPos nearest = this.getHandle().findNearestMapStructure(TagKey.create(Registry.STRUCTURE_REGISTRY, CraftNamespacedKey.toMinecraft(structureType.getKey())), originPos, radius, findUnexplored);
-+        // Paper start - fix because you can't just create random TagKeys
-+        if (!this.getHandle().serverLevelData.worldGenSettings().generateStructures()) { // from ServerLevel#findNearestMapStructure
-+            return null;
-+        }
-+        final List<Holder.Reference<net.minecraft.world.level.levelgen.structure.Structure>> features = this.structureCache.computeIfAbsent(structureType, (type) -> {
-+            final Registry<net.minecraft.world.level.levelgen.structure.StructureType<?>> structureFeatureRegistry = this.getHandle().registryAccess().registryOrThrow(Registry.STRUCTURE_TYPE_REGISTRY);
-+            return this.getHandle().registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).holders().filter(holder -> {
-+                return structureType.getKey().equals(CraftNamespacedKey.fromMinecraft(Objects.requireNonNull(structureFeatureRegistry.getKey(holder.value().type()))));
-+            }).toList();
-+        });
-+        BlockPos nearest = this.getHandle().findNearestMapFeature(net.minecraft.core.HolderSet.direct(features), originPos, radius, findUnexplored);
-+        // Paper end
-         return (nearest == null) ? null : new Location(this, nearest.getX(), nearest.getY(), nearest.getZ());
-     }
- 
diff --git a/patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch b/patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch
index 8bc8847053..035de2983c 100644
--- a/patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch
+++ b/patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch
@@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              // CraftBukkit start
 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
      @Nullable
-     public Entity teleportTo(ServerLevel worldserver, BlockPos location) {
+     public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
          // CraftBukkit end
 +        // Paper start - fix bad state entities causing dupes
 +        if (!isAlive() || !valid) {
diff --git a/patches/server/Implement-regenerateChunk.patch b/patches/server/Implement-regenerateChunk.patch
index 5e2f63a908..dafd833637 100644
--- a/patches/server/Implement-regenerateChunk.patch
+++ b/patches/server/Implement-regenerateChunk.patch
@@ -25,6 +25,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -        /*
 -        if (!unloadChunk0(x, z, false)) {
 -            return false;
+-        }
+-
+-        final long chunkKey = ChunkCoordIntPair.pair(x, z);
+-        world.getChunkProvider().unloadQueue.remove(chunkKey);
 +        // Paper start - implement regenerateChunk method
 +        final ServerLevel serverLevel = this.world;
 +        final net.minecraft.server.level.ServerChunkCache serverChunkCache = serverLevel.getChunkSource();
@@ -33,10 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) {
 +            levelChunk.removeBlockEntity(blockPos);
 +            serverLevel.setBlock(blockPos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(), 16);
-         }
- 
--        final long chunkKey = ChunkCoordIntPair.pair(x, z);
--        world.getChunkProvider().unloadQueue.remove(chunkKey);
++        }
++
 +        for (final ChunkStatus chunkStatus : REGEN_CHUNK_STATUSES) {
 +            final List<ChunkAccess> list = new ArrayList<>();
 +            final int range = Math.max(1, chunkStatus.getRange());
diff --git a/patches/server/More-World-API.patch b/patches/server/More-World-API.patch
index 0b060f1f87..7658e9e6a8 100644
--- a/patches/server/More-World-API.patch
+++ b/patches/server/More-World-API.patch
@@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 @@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-         return (nearest == null) ? null : new Location(this, nearest.getX(), nearest.getY(), nearest.getZ());
+         return new CraftStructureSearchResult(CraftStructure.minecraftToBukkit(found.getSecond().value(), this.getHandle().registryAccess()), new Location(this, found.getFirst().getX(), found.getFirst().getY(), found.getFirst().getZ()));
      }
  
 +    // Paper start
diff --git a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
index f4148c923a..89637ac447 100644
--- a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
+++ b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
@@ -301,7 +301,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper
                  }
  
-                 if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
+                 if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
 @@ -0,0 +0,0 @@ public class Main {
                      System.out.println("Unable to read system info");
                  }
diff --git a/work/Bukkit b/work/Bukkit
index d5a777e736..d41796deb5 160000
--- a/work/Bukkit
+++ b/work/Bukkit
@@ -1 +1 @@
-Subproject commit d5a777e7366d73cd126515ae8088c0cf81853de4
+Subproject commit d41796deb5e14fd69558db71324e8feb12a1effa
diff --git a/work/CraftBukkit b/work/CraftBukkit
index 82f757467a..991aeda121 160000
--- a/work/CraftBukkit
+++ b/work/CraftBukkit
@@ -1 +1 @@
-Subproject commit 82f757467a7ba67c9be1ecef9601d49aff754849
+Subproject commit 991aeda1218e72e9237942071e7ea55cc77b541c
diff --git a/work/Spigot b/work/Spigot
index 56be6a8491..475f600885 160000
--- a/work/Spigot
+++ b/work/Spigot
@@ -1 +1 @@
-Subproject commit 56be6a849145345c489133a676c40ae15b27b8c6
+Subproject commit 475f600885a8f58aee83aa7473f37dfe6b8ac3b5