From b52915b54ebf09442e570f3aa0f1ab6b3619ec4e Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 13 Jun 2024 16:45:27 +0200 Subject: [PATCH] Update upstream (Bukkit/CraftBukkit/Spigot) (#10875) 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: 376e37db SPIGOT-7677: Update which entities are marked as spawnable 06c4add3 SPIGOT-7737: Add separate TreeType.MEGA_PINE 19b7caaa SPIGOT-7731: Spawn eggs cannot have damage e585297e PR-1022: Add force option to Player#spawnParticle d26e0094 PR-1018: Add methods to get players seeing specific chunks 8df1ed18 PR-978: Add Material#isCompostable and Material#getCompostChance 4b9b59c7 SPIGOT-7676: Enforce locale parameter in toLowerCase and toUpperCase method calls and always use root locale 8d1e700a PR-1020: Cast instead of using #typed when getting BlockType and ItemType to better work with testing / mocks fa28607a PR-1016: Fix incorrect assumption of Fireball having constant speed 4c6c8586 PR-1015: Add a tool component to ItemMeta 6f6b2123 PR-1014: Add PotionEffectTypeCategory to distinguish between beneficial and harmful effects f511cfe1 PR-1013, SPIGOT-4288, SPIGOT-6202: Add material rerouting in preparation for the switch to ItemType and BlockType def44cbf SPIGOT-7669: Fix typo in ProjectileHitEvent#getHitBlockFace documentation 53fa4f72 PR-1011: Throw an exception if a RecipeChoice is ever supplied air CraftBukkit Changes: ee95e171a SPIGOT-7737: Add separate TreeType.MEGA_PINE 0dae4c62c Fix spawn egg equality check and copy constructor ab59e847c Fix spawn eggs with no entity creating invalid stacks and disconnect creative clients 3b6093b28 SPIGOT-7736: Creative spawn egg use loses components c6b4d5a87 SPIGOT-7731: Spawn eggs cannot have damage 340ccd57f SPIGOT-7735: Fix serialization of player heads with note block sound fd2f41834 SPIGOT-7734: Can't register a custom advancement using unsafe() 02456e2a5 PR-1413: Add force option to Player#spawnParticle 6a61f38b2 SPIGOT-7680: Per-world weather command 58c41cebb PR-1409: Add methods to get players seeing specific chunks 16c976797 PR-1412: Fix shipwreck loot tables not being set for BlockTransformers 7189ba636 PR-1360: Add Material#isCompostable and Material#getCompostChance 900384556 SPIGOT-7676: Enforce locale parameter in toLowerCase and toUpperCase method calls and always use root locale bdb40c5f1 Increase outdated build delay d6607c7dd SPIGOT-7675: Fix FoodComponent config deserialization b148ed332 PR-1406: Fix incorrect assumption of Fireball having constant speed 3ec31ca75 PR-1405: Add a tool component to ItemMeta 5d7d675b9 PR-1404: Add PotionEffectTypeCategory to distinguish between beneficial and harmful effects 960827981 PR-1403, SPIGOT-4288, SPIGOT-6202: Add material rerouting in preparation for the switch to ItemType and BlockType 94e44ec93 PR-1401: Add a config option to accept old keys in registry get calls a43701920 PR-1402: Fix ChunkSnapshot#isSectionEmpty() is always false 87d0a3368 SPIGOT-7668: Move NONE Registry updater to FieldRename to avoid some class loader issues 2ea1e7ac2 PR-1399: Fix regression preventing positive .setDamage value from causing knockback for 0 damage events ba2d49d21 Increase outdated build delay Spigot Changes: fcd94e21 Rebuild patches 342f4939 SPIGOT-7661: Add experimental unload-frozen-chunks option --- .../generator/types/goal/MobGoalNames.java | 5 +- .../papermc/generator/utils/Formatting.java | 2 +- patches/api/Add-Material-Tags.patch | 6 + ...gistryAccess-for-managing-registries.patch | 14 +- patches/api/Fix-upstream-javadocs.patch | 2 +- patches/api/Missing-Entity-API.patch | 35 +---- patches/api/Paper-Plugins.patch | 14 +- ...currency-Improvements-to-Permissions.patch | 4 +- patches/api/Timings-v2.patch | 23 ++- ...-Plugin-Tickets-to-API-Chunk-Methods.patch | 2 +- ...gistryAccess-for-managing-Registries.patch | 37 +++-- .../server/Add-System.out-err-catcher.patch | 2 +- patches/server/Add-basic-Datapack-API.patch | 2 +- .../Add-methods-to-get-translation-keys.patch | 3 +- .../Add-setPlayerProfile-API-for-Skulls.patch | 8 +- patches/server/Add-velocity-warnings.patch | 2 +- patches/server/Adopt-MaterialRerouting.patch | 134 ++++++++++++++++++ patches/server/Adventure.patch | 2 +- patches/server/Build-system-changes.patch | 2 +- ...nvert-legacy-attributes-in-Item-Meta.patch | 2 +- patches/server/Expand-world-key-API.patch | 4 +- .../Expose-server-build-information.patch | 2 +- ...t-isSectionEmpty-int-and-optimize-Pa.patch | 1 + patches/server/Fix-ItemFlags.patch | 12 +- ...r-spawnParticle-x-y-z-precision-loss.patch | 8 +- patches/server/Fix-this-stupid-bullshit.patch | 2 +- patches/server/General-ItemMeta-fixes.patch | 23 +-- .../server/Hook-into-CB-plugin-rewrites.patch | 6 +- patches/server/Implement-Mob-Goal-API.patch | 4 +- patches/server/Missing-Entity-API.patch | 34 +---- patches/server/Paper-Plugins.patch | 2 +- patches/server/Paper-command.patch | 8 +- patches/server/Paper-config-files.patch | 6 +- patches/server/Plugin-remapping.patch | 4 +- ...ion-calls-in-plugins-using-internals.patch | 4 +- ...a-handling-of-LivingEntity-actuallyH.patch | 2 +- patches/server/Rewrite-chunk-system.patch | 4 +- patches/server/Timings-v2.patch | 2 +- ...ve-checking-handled-tags-in-itemmeta.patch | 5 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 42 files changed, 276 insertions(+), 164 deletions(-) create mode 100644 patches/server/Adopt-MaterialRerouting.patch diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java index 2ad5e0ac06..1bd6342f61 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java @@ -120,6 +120,7 @@ import org.bukkit.entity.ZombieVillager; import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -282,8 +283,8 @@ public class MobGoalNames { name = sb.toString(); name = name.replaceFirst("_", ""); - if (flag && !deobfuscationMap.containsKey(name.toLowerCase()) && !ignored.contains(name)) { - System.out.println("need to map " + original + " (" + name.toLowerCase() + ")"); + if (flag && !deobfuscationMap.containsKey(name.toLowerCase(Locale.ROOT)) && !ignored.contains(name)) { + System.out.println("need to map " + original + " (" + name.toLowerCase(Locale.ROOT) + ")"); } // did we rename this key? diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java index a6c88a8a14..9d938f8cb7 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java @@ -12,7 +12,7 @@ public final class Formatting { private static final Pattern ILLEGAL_FIELD_CHARACTERS = Pattern.compile("[.-/]"); public static String formatKeyAsField(String path) { - return ILLEGAL_FIELD_CHARACTERS.matcher(path.toUpperCase(Locale.ENGLISH)).replaceAll("_"); + return ILLEGAL_FIELD_CHARACTERS.matcher(path.toUpperCase(Locale.ROOT)).replaceAll("_"); } public static Comparator ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path); diff --git a/patches/api/Add-Material-Tags.patch b/patches/api/Add-Material-Tags.patch index 68757d6028..3c604aa8d4 100644 --- a/patches/api/Add-Material-Tags.patch +++ b/patches/api/Add-Material-Tags.patch @@ -36,6 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; ++import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + @@ -83,12 +84,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @NotNull + @Override ++ @ApiStatus.Internal + protected Set getAllPossibleValues() { + return Stream.of(Material.values()).collect(Collectors.toSet()); + } + + @Override + @NotNull ++ @ApiStatus.Internal + protected String getName(@NotNull Material value) { + return value.name(); + } @@ -849,6 +852,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.Tag; ++import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; @@ -1018,9 +1022,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @NotNull ++ @ApiStatus.Internal + protected abstract Set getAllPossibleValues(); + + @NotNull ++ @ApiStatus.Internal + protected abstract String getName(@NotNull T value); +} diff --git a/src/main/java/io/papermc/paper/tag/EntitySetTag.java b/src/main/java/io/papermc/paper/tag/EntitySetTag.java diff --git a/patches/api/Add-RegistryAccess-for-managing-registries.patch b/patches/api/Add-RegistryAccess-for-managing-registries.patch index 51d225812e..bdb8d957e1 100644 --- a/patches/api/Add-RegistryAccess-for-managing-registries.patch +++ b/patches/api/Add-RegistryAccess-for-managing-registries.patch @@ -376,12 +376,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 when(instance.getBukkitVersion()).thenReturn("BukkitVersion_" + TestServer.class.getPackage().getImplementationVersion()); - Map, Registry> registers = new HashMap<>(); -- when(instance.getRegistry(any())).then(invocationOnMock -> registers.computeIfAbsent(invocationOnMock.getArgument(0), aClass -> new Registry() { +- when(instance.getRegistry(any())).then(invocationOnMock -> registers.computeIfAbsent(invocationOnMock.getArgument(0), aClass -> new Registry<>() { - private final Map cache = new HashMap<>(); - - @Override - public Keyed get(NamespacedKey key) { -- return cache.computeIfAbsent(key, key2 -> mock(aClass, withSettings().stubOnly())); +- Class theClass; +- // Some registries have extra Typed classes such as BlockType and ItemType. +- // To avoid class cast exceptions during init mock the Typed class. +- // To get the correct class, we just use the field type. +- try { +- theClass = (Class) aClass.getField(key.getKey().toUpperCase(Locale.ROOT).replace('.', '_')).getType(); +- } catch (ClassCastException | NoSuchFieldException e) { +- throw new RuntimeException(e); +- } +- +- return cache.computeIfAbsent(key, key2 -> mock(theClass, withSettings().stubOnly())); - } - - @NotNull diff --git a/patches/api/Fix-upstream-javadocs.patch b/patches/api/Fix-upstream-javadocs.patch index b5d5b5c0a8..4bd61f25a2 100644 --- a/patches/api/Fix-upstream-javadocs.patch +++ b/patches/api/Fix-upstream-javadocs.patch @@ -872,7 +872,7 @@ diff --git a/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java b index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java +++ b/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java -@@ -0,0 +0,0 @@ import org.bukkit.event.block.BlockExpEvent; +@@ -0,0 +0,0 @@ import org.bukkit.material.MaterialData; import org.jetbrains.annotations.NotNull; /** diff --git a/patches/api/Missing-Entity-API.patch b/patches/api/Missing-Entity-API.patch index c6813261b0..28fdc039bb 100644 --- a/patches/api/Missing-Entity-API.patch +++ b/patches/api/Missing-Entity-API.patch @@ -497,51 +497,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/entity/Fireball.java +++ b/src/main/java/org/bukkit/entity/Fireball.java @@ -0,0 +0,0 @@ public interface Fireball extends Projectile, Explosive { - * Sets the direction the fireball should be flying towards. - * The direction vector will be normalized and the default speed will be applied. - *
-- * To also change the speed of the fireball, use {@link #setVelocity(Vector)}. -+ * To also change the acceleration of the fireball, use {@link #setPower(Vector)}. - * Note: that the client may not respect non-default speeds and will therefore - * mispredict the location of the fireball, causing visual stutter. - *
-- * Also Note: that this method and {@link #setVelocity(Vector)} will override each other. -+ * Also Note: that this method and {@link #setPower(Vector)} will override each other. - * - * @param direction the direction this fireball should be flying towards - * @see #setVelocity(Vector) -@@ -0,0 +0,0 @@ public interface Fireball extends Projectile, Explosive { + */ @NotNull - public Vector getDirection(); - -+ // Paper start - Expose power on fireball projectiles -+ /** -+ * {@inheritDoc} -+ *

-+ * Note: For fireball entities, their movement is also controlled by their power. -+ * -+ * @param velocity New velocity to travel with -+ * @see #setPower(Vector) -+ */ -+ @Override -+ public void setVelocity(@NotNull Vector velocity); + Vector getAcceleration(); + ++ // Paper start - Expose power on fireball projectiles + /** + * Sets the power of a fireball. The power determines the direction and magnitude of its acceleration. + * + * @param power the power ++ * @deprecated use #setAcceleration(Vector) instead. + */ ++ @Deprecated + public void setPower(@NotNull Vector power); + + /** + * Gets the power of a fireball. The power determines the direction and magnitude of its acceleration. + * + * @return the power ++ * @deprecated Use #getAcceleration instead. + */ ++ @Deprecated + @NotNull + public Vector getPower(); + // Paper end - Expose power on fireball projectiles -+ } diff --git a/src/main/java/org/bukkit/entity/Fox.java b/src/main/java/org/bukkit/entity/Fox.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/api/Paper-Plugins.patch b/patches/api/Paper-Plugins.patch index 939179798e..af395045ef 100644 --- a/patches/api/Paper-Plugins.patch +++ b/patches/api/Paper-Plugins.patch @@ -1743,7 +1743,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public Permission getPermission(@NotNull String name) { + if (true) {return this.paperPluginManager.getPermission(name);} // Paper - return permissions.get(name.toLowerCase(java.util.Locale.ENGLISH)); + return permissions.get(name.toLowerCase(Locale.ROOT)); } @Override @@ -1755,7 +1755,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Deprecated public void addPermission(@NotNull Permission perm, boolean dirty) { + if (true) {this.paperPluginManager.addPermission(perm); return;} // Paper - This just has a performance implication, use the better api to avoid this. - String name = perm.getName().toLowerCase(java.util.Locale.ENGLISH); + String name = perm.getName().toLowerCase(Locale.ROOT); if (permissions.containsKey(name)) { @@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager { @@ -1775,13 +1775,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void removePermission(@NotNull String name) { + if (true) {this.paperPluginManager.removePermission(name); return;} // Paper - permissions.remove(name.toLowerCase(java.util.Locale.ENGLISH)); + permissions.remove(name.toLowerCase(Locale.ROOT)); } @Override public void recalculatePermissionDefaults(@NotNull Permission perm) { + if (true) {this.paperPluginManager.recalculatePermissionDefaults(perm); return;} // Paper - if (perm != null && permissions.containsKey(perm.getName().toLowerCase(java.util.Locale.ENGLISH))) { + if (perm != null && permissions.containsKey(perm.getName().toLowerCase(Locale.ROOT))) { defaultPerms.get(true).remove(perm); defaultPerms.get(false).remove(perm); @@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager { @@ -1789,7 +1789,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void subscribeToPermission(@NotNull String permission, @NotNull Permissible permissible) { + if (true) {this.paperPluginManager.subscribeToPermission(permission, permissible); return;} // Paper - String name = permission.toLowerCase(java.util.Locale.ENGLISH); + String name = permission.toLowerCase(Locale.ROOT); Map map = permSubs.get(name); @@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager { @@ -1797,7 +1797,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void unsubscribeFromPermission(@NotNull String permission, @NotNull Permissible permissible) { + if (true) {this.paperPluginManager.unsubscribeFromPermission(permission, permissible); return;} // Paper - String name = permission.toLowerCase(java.util.Locale.ENGLISH); + String name = permission.toLowerCase(Locale.ROOT); Map map = permSubs.get(name); @@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager { @@ -1805,7 +1805,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @NotNull public Set getPermissionSubscriptions(@NotNull String permission) { + if (true) {return this.paperPluginManager.getPermissionSubscriptions(permission);} // Paper - String name = permission.toLowerCase(java.util.Locale.ENGLISH); + String name = permission.toLowerCase(Locale.ROOT); Map map = permSubs.get(name); @@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager { diff --git a/patches/api/Performance-Concurrency-Improvements-to-Permissions.patch b/patches/api/Performance-Concurrency-Improvements-to-Permissions.patch index 84495f0b11..9276b65a44 100644 --- a/patches/api/Performance-Concurrency-Improvements-to-Permissions.patch +++ b/patches/api/Performance-Concurrency-Improvements-to-Permissions.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/org/bukkit/permissions/PermissibleBase.java @@ -0,0 +0,0 @@ public class PermissibleBase implements Permissible { - String name = inName.toLowerCase(java.util.Locale.ENGLISH); + String name = inName.toLowerCase(Locale.ROOT); - if (isPermissionSet(name)) { - return permissions.get(name).getValue(); @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class PermissibleBase implements Permissible { - String name = perm.getName().toLowerCase(java.util.Locale.ENGLISH); + String name = perm.getName().toLowerCase(Locale.ROOT); - if (isPermissionSet(name)) { - return permissions.get(name).getValue(); diff --git a/patches/api/Timings-v2.patch b/patches/api/Timings-v2.patch index 8fbe7589bb..a6d09b21ed 100644 --- a/patches/api/Timings-v2.patch +++ b/patches/api/Timings-v2.patch @@ -874,17 +874,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + ), -+ toObjectMapper(input.tileEntityCounts.entrySet(), -+ new Function, JSONPair>() { -+ @NotNull -+ @Override -+ public JSONPair apply(Map.Entry entry) { -+ tileEntityTypeSet.add(entry.getKey()); -+ return pair( -+ String.valueOf(entry.getKey().ordinal()), -+ entry.getValue().count() -+ ); -+ } ++ toObjectMapper( ++ input.tileEntityCounts.entrySet(), ++ entry -> { ++ tileEntityTypeSet.add(entry.getKey()); ++ return pair( ++ String.valueOf(entry.getKey().ordinal()), ++ entry.getValue().count() ++ ); + } + ) + ); @@ -3168,8 +3165,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean register(@NotNull String label, @NotNull String fallbackPrefix, @NotNull Command command) { + command.timings = co.aikar.timings.TimingsManager.getCommandTiming(fallbackPrefix, command); // Paper - label = label.toLowerCase(java.util.Locale.ENGLISH).trim(); - fallbackPrefix = fallbackPrefix.toLowerCase(java.util.Locale.ENGLISH).trim(); + label = label.toLowerCase(Locale.ROOT).trim(); + fallbackPrefix = fallbackPrefix.toLowerCase(Locale.ROOT).trim(); boolean registered = register(label, command, false, fallbackPrefix); @@ -0,0 +0,0 @@ public class SimpleCommandMap implements CommandMap { return false; diff --git a/patches/server/Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/server/Add-Plugin-Tickets-to-API-Chunk-Methods.patch index 8e7f791226..9b7fa1881e 100644 --- a/patches/server/Add-Plugin-Tickets-to-API-Chunk-Methods.patch +++ b/patches/server/Add-Plugin-Tickets-to-API-Chunk-Methods.patch @@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + TicketType.PLUGIN.timeout = Math.min(20, this.configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second this.minimumAPI = ApiVersion.getOrCreateVersion(this.configuration.getString("settings.minimum-api")); this.loadIcon(); - + this.loadCompatibilities(); @@ -0,0 +0,0 @@ public final class CraftServer implements Server { this.console.setMotd(config.motd); this.overrideSpawnLimits(); diff --git a/patches/server/Add-RegistryAccess-for-managing-Registries.patch b/patches/server/Add-RegistryAccess-for-managing-Registries.patch index 7e92bd2be1..0d3171a3be 100644 --- a/patches/server/Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/Add-RegistryAccess-for-managing-Registries.patch @@ -725,37 +725,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME); - } - if (bukkitClass == GameEvent.class) { -- return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, CraftRegistry.NONE); +- return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, FieldRename.NONE); - } - if (bukkitClass == MusicInstrument.class) { -- return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, CraftRegistry.NONE); +- return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, FieldRename.NONE); - } - if (bukkitClass == PotionEffectType.class) { -- return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, CraftRegistry.NONE); +- return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, FieldRename.NONE); - } - if (bukkitClass == Structure.class) { -- return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new, CraftRegistry.NONE); +- return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new, FieldRename.NONE); - } - if (bukkitClass == StructureType.class) { -- return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new, CraftRegistry.NONE); +- return new CraftRegistry<>(StructureType.class, BuiltInRegistries.STRUCTURE_TYPE, CraftStructureType::new, FieldRename.NONE); - } - if (bukkitClass == TrimMaterial.class) { -- return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new, CraftRegistry.NONE); +- return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new, FieldRename.NONE); - } - if (bukkitClass == TrimPattern.class) { -- return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new, CraftRegistry.NONE); +- return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new, FieldRename.NONE); - } - if (bukkitClass == DamageType.class) { -- return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, CraftRegistry.NONE); +- return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, FieldRename.NONE); - } - if (bukkitClass == Wolf.Variant.class) { -- return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, CraftRegistry.NONE); +- return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, FieldRename.NONE); - } - if (bukkitClass == BlockType.class) { -- return new CraftRegistry<>(BlockType.class, registryHolder.registryOrThrow(Registries.BLOCK), CraftBlockType::new, CraftRegistry.NONE); +- return new CraftRegistry<>(BlockType.class, registryHolder.registryOrThrow(Registries.BLOCK), CraftBlockType::new, FieldRename.NONE); - } - if (bukkitClass == ItemType.class) { -- return new CraftRegistry<>(ItemType.class, registryHolder.registryOrThrow(Registries.ITEM), CraftItemType::new, CraftRegistry.NONE); +- return new CraftRegistry<>(ItemType.class, registryHolder.registryOrThrow(Registries.ITEM), CraftItemType::new, FieldRename.NONE); - } - - return null; @@ -829,12 +829,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Enum.valueOf(enumClass, FieldRename.rename(apiVersion, enumClass.getName().replace('.', '/'), name)); } +- @RequireCompatibility("allow-old-keys-in-registry") - public static T get(Registry registry, NamespacedKey namespacedKey) { - // We don't have version-specific changes, so just use current, and don't inject a version - return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT); - } + // Paper start - absolutely not, having this as an expectation for plugin developers opens a huge + // can of worms in the future, especially if mojang comes back and reuses some old key ++ // @RequireCompatibility("allow-old-keys-in-registry") + // public static T get(Registry registry, NamespacedKey namespacedKey) { + // // We don't have version-specific changes, so just use current, and don't inject a version + // return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT); @@ -850,6 +852,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/resources/META-INF/services/io.papermc.paper.registry.RegistryAccess @@ -0,0 +1 @@ +io.papermc.paper.registry.PaperRegistryAccess +diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/resources/configurations/bukkit.yml ++++ b/src/main/resources/configurations/bukkit.yml +@@ -0,0 +0,0 @@ settings: + shutdown-message: Server closed + minimum-api: none + use-map-color-cache: true +- compatibility: +- allow-old-keys-in-registry: false + spawn-limits: + monsters: 70 + animals: 10 diff --git a/src/test/java/io/papermc/paper/registry/LegacyRegistryIdentifierTest.java b/src/test/java/io/papermc/paper/registry/LegacyRegistryIdentifierTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/Add-System.out-err-catcher.patch b/patches/server/Add-System.out-err-catcher.patch index 3fb6ce8444..c7b4c3765a 100644 --- a/patches/server/Add-System.out-err-catcher.patch +++ b/patches/server/Add-System.out-err-catcher.patch @@ -109,7 +109,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 { - public int reloadCount; + public Set activeCompatibilities = Collections.emptySet(); private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper public static Exception excessiveVelEx; // Paper - Velocity warnings + private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper diff --git a/patches/server/Add-basic-Datapack-API.patch b/patches/server/Add-basic-Datapack-API.patch index f5520fcbe9..d457535e1e 100644 --- a/patches/server/Add-basic-Datapack-API.patch +++ b/patches/server/Add-basic-Datapack-API.patch @@ -96,9 +96,9 @@ 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 { - public boolean ignoreVanillaPermissions = false; private final List playerView; public int reloadCount; + public Set activeCompatibilities = Collections.emptySet(); + private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper public static Exception excessiveVelEx; // Paper - Velocity warnings diff --git a/patches/server/Add-methods-to-get-translation-keys.patch b/patches/server/Add-methods-to-get-translation-keys.patch index 47b91c03cf..57b325e173 100644 --- a/patches/server/Add-methods-to-get-translation-keys.patch +++ b/patches/server/Add-methods-to-get-translation-keys.patch @@ -94,6 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 package io.papermc.paper.world; import com.destroystokyo.paper.ClientOption; ++import java.util.Locale; +import java.util.Map; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.contents.TranslatableContents; @@ -175,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Test + public void testBiome() { + for (Map.Entry, Biome> nms : AbstractTestingBase.BIOMES.entrySet()) { -+ org.bukkit.block.Biome bukkit = org.bukkit.block.Biome.valueOf(nms.getKey().location().getPath().toUpperCase()); ++ org.bukkit.block.Biome bukkit = org.bukkit.block.Biome.valueOf(nms.getKey().location().getPath().toUpperCase(Locale.ROOT)); + Assertions.assertEquals(nms.getKey().location().toLanguageKey("biome"), bukkit.translationKey(), "translation key mismatch for " + bukkit); + } + } diff --git a/patches/server/Add-setPlayerProfile-API-for-Skulls.patch b/patches/server/Add-setPlayerProfile-API-for-Skulls.patch index d0a454d80b..507a3a5eae 100644 --- a/patches/server/Add-setPlayerProfile-API-for-Skulls.patch +++ b/patches/server/Add-setPlayerProfile-API-for-Skulls.patch @@ -94,11 +94,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { - Builder serialize(Builder builder) { super.serialize(builder); + if (this.profile != null) { -- return builder.put(CraftMetaSkull.SKULL_OWNER.BUKKIT, new CraftPlayerProfile(this.profile)); -+ return builder.put(CraftMetaSkull.SKULL_OWNER.BUKKIT, new com.destroystokyo.paper.profile.CraftPlayerProfile(this.profile)); // Paper +- builder.put(CraftMetaSkull.SKULL_OWNER.BUKKIT, new CraftPlayerProfile(this.profile)); ++ builder.put(CraftMetaSkull.SKULL_OWNER.BUKKIT, new com.destroystokyo.paper.profile.CraftPlayerProfile(this.profile)); // Paper } + NamespacedKey namespacedKeyNB = this.getNoteBlockSound(); - if (namespacedKeyNB != null) { diff --git a/patches/server/Add-velocity-warnings.patch b/patches/server/Add-velocity-warnings.patch index 61f4903069..989bf40426 100644 --- a/patches/server/Add-velocity-warnings.patch +++ b/patches/server/Add-velocity-warnings.patch @@ -9,9 +9,9 @@ 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 { - public boolean ignoreVanillaPermissions = false; private final List playerView; public int reloadCount; + public Set activeCompatibilities = Collections.emptySet(); + public static Exception excessiveVelEx; // Paper - Velocity warnings static { diff --git a/patches/server/Adopt-MaterialRerouting.patch b/patches/server/Adopt-MaterialRerouting.patch new file mode 100644 index 0000000000..f2878b528a --- /dev/null +++ b/patches/server/Adopt-MaterialRerouting.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Bjarne Koll +Date: Thu, 13 Jun 2024 11:02:36 +0200 +Subject: [PATCH] Adopt MaterialRerouting + +Adopts the paper-api to the material rerouting infrastructure introduced +by upstream. + +diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java ++++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java +@@ -0,0 +0,0 @@ public class MaterialRerouting { + public static void setBlocks(ToolComponent.ToolRule toolRule, Collection blocks) { + toolRule.setBlocks(blocks.stream().map(MaterialRerouting::transformToBlockType).toList()); + } ++ ++ // Paper start - register paper API specific material consumers in rerouting ++ // A lot of these methods do *not* run through MaterialRerouting to avoid the overhead of a system that ++ // currently is an effective noop. ++ // The only downside is that upstream moved the handling of legacy materials into transformFromXType methods. ++ // As such, methods introduced prior to 1.13 need to run through the transformation to make sure legacy material ++ // constants still work. ++ ++ // Utility method for constructing a set from an existing one after mapping each element. ++ private static Set mapSet(final Set input, final java.util.function.Function mapper) { ++ final Set output = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(input.size()); ++ for (final I i : input) { ++ output.add(mapper.apply(i)); ++ } ++ return output; ++ } ++ ++ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/4965) ++ public static org.bukkit.Material getMinecartMaterial(org.bukkit.entity.Minecart minecart, @InjectPluginVersion ApiVersion version) { ++ return minecart.getMinecartMaterial(); ++ } ++ ++ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/4965) ++ public static Material getBoatMaterial(Boat boat, @InjectPluginVersion ApiVersion version) { ++ return boat.getBoatMaterial(); ++ } ++ ++ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/3807) ++ public static Material getType(io.papermc.paper.event.player.PlayerItemCooldownEvent event, @InjectPluginVersion ApiVersion version) { ++ return event.getType(); ++ } ++ ++ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/3850) ++ public static Collection getInfiniburn(World world, @InjectPluginVersion ApiVersion version) { ++ return world.getInfiniburn(); ++ } ++ ++ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192) ++ public static Set getTypes( ++ final com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType slotType, ++ @InjectPluginVersion final ApiVersion apiVersion ++ ) { ++ if (apiVersion.isNewerThanOrSameAs(ApiVersion.FLATTENING)) return slotType.getTypes(); ++ else return mapSet(slotType.getTypes(), MaterialRerouting::transformToItemType); // Needed as pre-flattening is hanled by transformToItemType ++ } ++ ++ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192) ++ @RerouteStatic("com/destroystokyo/paper/event/player/PlayerArmorChangeEvent$SlotType") ++ public static com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType getByMaterial( ++ final Material material ++ ) { ++ return com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.getByMaterial(MaterialRerouting.transformToItemType(material)); ++ } ++ ++ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192) ++ @RerouteStatic("com/destroystokyo/paper/event/player/PlayerArmorChangeEvent$SlotType") ++ public static boolean isEquipable(final Material material) { ++ return com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.isEquipable(MaterialRerouting.transformToItemType(material)); ++ } ++ ++ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1244)1 ++ public static Material getMaterial(final com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState damageState) { ++ return damageState.getMaterial(); ++ } ++ ++ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1244)1 ++ @RerouteStatic("com/destroystokyo/paper/event/block/AnvilDamagedEvent$DamageState") ++ public static com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState getState( ++ final Material material ++ ) { ++ return com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.getState(material); ++ } ++ ++ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/10290) ++ public static ItemStack withType(final ItemStack itemStack, final Material material) { ++ return itemStack.withType(material); ++ } ++ // Paper end - register paper API specific material consumers in rerouting + } +diff --git a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java ++++ b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java +@@ -0,0 +0,0 @@ public class MaterialReroutingTest extends AbstractTestingBase { + .filter(entry -> !entry.getName().endsWith("ItemType.class")) + .filter(entry -> !entry.getName().endsWith("Registry.class")) + .filter(entry -> !entry.getName().startsWith("org/bukkit/material")) ++ // Paper start - types that cannot be translated to ItemType/BlockType ++ .filter(entry -> !entry.getName().equals("com/destroystokyo/paper/MaterialSetTag.class")) ++ // Paper end - types that cannot be translated to ItemType/BlockType + .map(entry -> { + try { + return MaterialReroutingTest.jarFile.getInputStream(entry); +@@ -0,0 +0,0 @@ public class MaterialReroutingTest extends AbstractTestingBase { + continue; + } + } ++ // Paper start - filter out more methods from rerouting test ++ if (methodNode.name.startsWith("lambda$")) continue; ++ if (isInternal(methodNode.invisibleAnnotations)) continue; ++ // Paper end - filter out more methods from rerouting test + + if (!Commodore.rerouteMethods(Collections.emptySet(), MaterialReroutingTest.MATERIAL_METHOD_REROUTE, (methodNode.access & Opcodes.ACC_STATIC) != 0, classNode.name, methodNode.name, methodNode.desc, a -> { })) { + missingReroute.add(methodNode.name + " " + methodNode.desc + " " + methodNode.signature); +@@ -0,0 +0,0 @@ public class MaterialReroutingTest extends AbstractTestingBase { + } + } + ++ // Paper start - filter out more methods from rerouting test ++ private static boolean isInternal(final List annotationNodes) { ++ return annotationNodes != null ++ && annotationNodes.stream().anyMatch(a -> a.desc.equals("Lorg/jetbrains/annotations/ApiStatus$Internal;")); ++ } ++ // Paper end - filter out more methods from rerouting test ++ + @AfterAll + public static void clear() throws IOException { + if (MaterialReroutingTest.jarFile != null) { diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch index 86978a18e4..d0ee9f098d 100644 --- a/patches/server/Adventure.patch +++ b/patches/server/Adventure.patch @@ -5139,7 +5139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); + return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); } + // Paper start diff --git a/patches/server/Build-system-changes.patch b/patches/server/Build-system-changes.patch index 011e7d402a..6cb114801c 100644 --- a/patches/server/Build-system-changes.patch +++ b/patches/server/Build-system-changes.patch @@ -142,7 +142,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -3); + deadline.add(Calendar.DAY_OF_YEAR, -21); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java diff --git a/patches/server/Convert-legacy-attributes-in-Item-Meta.patch b/patches/server/Convert-legacy-attributes-in-Item-Meta.patch index 1d3ee63d40..2c859f5c79 100644 --- a/patches/server/Convert-legacy-attributes-in-Item-Meta.patch +++ b/patches/server/Convert-legacy-attributes-in-Item-Meta.patch @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return null; + } + nms = legacyNMS.getOrDefault(nms, nms); -+ if (!nms.toLowerCase().equals(nms) || nms.indexOf(' ') != -1) { ++ if (!nms.toLowerCase(java.util.Locale.ROOT).equals(nms) || nms.indexOf(' ') != -1) { + return null; + } + return nms; diff --git a/patches/server/Expand-world-key-API.patch b/patches/server/Expand-world-key-API.patch index 7c5ca952cb..4796ce635d 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(Registries.DIMENSION, new ResourceLocation(name.toLowerCase(java.util.Locale.ENGLISH))); -+ worldKey = ResourceKey.create(Registries.DIMENSION, 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(Registries.DIMENSION, new ResourceLocation(name.toLowerCase(Locale.ROOT))); ++ worldKey = ResourceKey.create(Registries.DIMENSION, new net.minecraft.resources.ResourceLocation(creator.key().getNamespace().toLowerCase(java.util.Locale.ROOT), creator.key().getKey().toLowerCase(java.util.Locale.ROOT))); // Paper } // If set to not keep spawn in memory (changed from default) then adjust rule accordingly diff --git a/patches/server/Expose-server-build-information.patch b/patches/server/Expose-server-build-information.patch index d8e55aad30..8076dd2679 100644 --- a/patches/server/Expose-server-build-information.patch +++ b/patches/server/Expose-server-build-information.patch @@ -610,7 +610,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static boolean useConsole = true; @@ -0,0 +0,0 @@ public class Main { - deadline.add(Calendar.DAY_OF_YEAR, -3); + deadline.add(Calendar.DAY_OF_YEAR, -21); if (buildDate.before(deadline.getTime())) { System.err.println("*** Error, this build is outdated ***"); - System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***"); diff --git a/patches/server/Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch b/patches/server/Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch index e169875477..1709ec221c 100644 --- a/patches/server/Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch +++ b/patches/server/Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch @@ -20,6 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - data.put("block_states", ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, cs[i].getStates()).getOrThrow()); - sectionBlockIDs[i] = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, data.getCompound("block_states")).getOrThrow(ChunkSerializer.ChunkReadException::new); +- sectionEmpty[i] = cs[i].hasOnlyAir(); + // Paper start - Fix ChunkSnapshot#isSectionEmpty(int); and remove codec usage + sectionEmpty[i] = cs[i].hasOnlyAir(); // fix sectionEmpty array not being filled + if (!sectionEmpty[i]) { diff --git a/patches/server/Fix-ItemFlags.patch b/patches/server/Fix-ItemFlags.patch index eb914cbcd4..51c8d075b6 100644 --- a/patches/server/Fix-ItemFlags.patch +++ b/patches/server/Fix-ItemFlags.patch @@ -82,11 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Set, Optional>> keys = tag.entrySet(); for (Map.Entry, Optional> key : keys) { @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - - String unhandled = SerializableMeta.getString(map, "unhandled", true); - if (unhandled != null) { -- ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(internal)); -+ ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(unhandled)); // Paper - fix deserializing unhandled tags + ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(unhandled)); try { CompoundTag unhandledTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); - this.unhandledTags.copy(DataComponentPatch.CODEC.parse(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), unhandledTag).result().get()); @@ -123,13 +119,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Overridden boolean isEmpty() { -- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); -+ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper +- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); ++ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper } // Paper start @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - && (this.hasFood() ? that.hasFood() && this.food.equals(that.food) : !that.hasFood()) + && (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool()) && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage()) && (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage()) + && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper diff --git a/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch index 1ec96e1cac..adab390b84 100644 --- a/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch +++ b/patches/server/Fix-Player-spawnParticle-x-y-z-precision-loss.patch @@ -11,9 +11,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override - public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) { -- ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.createParticleParam(particle, data), true, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); -+ ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.createParticleParam(particle, data), true, x, y, z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); // Paper - fix x/y/z precision loss + public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { +- ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.createParticleParam(particle, data), force, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); ++ ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.createParticleParam(particle, data), force, x, y, z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); // Paper - fix x/y/z precision loss this.getHandle().connection.send(packetplayoutworldparticles); - } + diff --git a/patches/server/Fix-this-stupid-bullshit.patch b/patches/server/Fix-this-stupid-bullshit.patch index 2748352d35..7b77f054b4 100644 --- a/patches/server/Fix-this-stupid-bullshit.patch +++ b/patches/server/Fix-this-stupid-bullshit.patch @@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +0,0 @@ public class Main { Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -3); + deadline.add(Calendar.DAY_OF_YEAR, -21); if (buildDate.before(deadline.getTime())) { - System.err.println("*** Error, this build is outdated ***"); + // Paper start - This is some stupid bullshit diff --git a/patches/server/General-ItemMeta-fixes.patch b/patches/server/General-ItemMeta-fixes.patch index f769253cd2..d57c164bc7 100644 --- a/patches/server/General-ItemMeta-fixes.patch +++ b/patches/server/General-ItemMeta-fixes.patch @@ -13,15 +13,6 @@ diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/ja index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder { - } finally { - world.captureBlockStates = false; - } -- DataComponentPatch newData = this.getComponentsPatch(); -+ DataComponentPatch newData = this.components.asPatch(); // Paper - Directly access components as patch instead of getComponentsPatch as said method yields EMPTY on items with count 0 - int newCount = this.getCount(); - this.setCount(oldCount); - this.restorePatch(oldData); @@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder { public void setItem(Item item) { this.bukkitStack = null; // Paper @@ -95,7 +86,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 itemStack.applyComponents(tag.build()); } @@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack { - } + if (itemMeta == null) return true; if (!((CraftMetaItem) itemMeta).isEmpty()) { - CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator(); @@ -902,8 +893,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Overridden boolean isEmpty() { -- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper -+ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasDamage() || this.hasMaxDamage() || this.attributeModifiers != null || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper +- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper ++ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.attributeModifiers != null || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper } // Paper start @@ -1071,8 +1062,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 && (Objects.equals(this.customTag, that.customTag)) && (this.persistentDataContainer.equals(that.persistentDataContainer)) @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - hash = 61 * hash + (this.hasRarity() ? this.rarity.hashCode() : 0); hash = 61 * hash + (this.hasFood() ? this.food.hashCode() : 0); + hash = 61 * hash + (this.hasTool() ? this.tool.hashCode() : 0); hash = 61 * hash + (this.hasDamage() ? this.damage : 0); - hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237); - hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0); @@ -1374,10 +1365,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (meta instanceof CraftMetaSpawnEgg) { CraftMetaSpawnEgg that = (CraftMetaSpawnEgg) meta; -- return this.hasSpawnedType() ? that.hasSpawnedType() && this.spawnedType.equals(that.spawnedType) : !that.hasSpawnedType() -- && this.entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : this.entityTag == null; -+ return (this.hasSpawnedType() ? that.hasSpawnedType() && this.spawnedType.equals(that.spawnedType) : !that.hasSpawnedType()) // Paper -+ && (this.entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : that.entityTag == null); // Paper +- return this.entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : this.entityTag == null; ++ return this.entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : that.entityTag == null; // Paper } return true; } diff --git a/patches/server/Hook-into-CB-plugin-rewrites.patch b/patches/server/Hook-into-CB-plugin-rewrites.patch index 93e52f0c9b..d1b425ee4d 100644 --- a/patches/server/Hook-into-CB-plugin-rewrites.patch +++ b/patches/server/Hook-into-CB-plugin-rewrites.patch @@ -11,9 +11,9 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java -@@ -0,0 +0,0 @@ import java.io.InputStream; - import java.util.ArrayList; +@@ -0,0 +0,0 @@ import java.util.ArrayList; import java.util.Arrays; + import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; @@ -28,8 +28,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import joptsimple.OptionSet; import joptsimple.OptionSpec; @@ -0,0 +0,0 @@ public class Commodore { - public static final List> REROUTES = new ArrayList<>(); // Only used for testing private static final Map FIELD_RENAME_METHOD_REROUTE = Commodore.createReroutes(FieldRename.class); + private static final Map MATERIAL_METHOD_REROUTE = Commodore.createReroutes(MaterialRerouting.class); + // Paper start - Plugin rewrites + private static final Map SEARCH_AND_REMOVE = initReplacementsMap(); diff --git a/patches/server/Implement-Mob-Goal-API.patch b/patches/server/Implement-Mob-Goal-API.patch index 876f012159..2f4ba1229c 100644 --- a/patches/server/Implement-Mob-Goal-API.patch +++ b/patches/server/Implement-Mob-Goal-API.patch @@ -305,8 +305,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + name = sb.toString(); + name = name.replaceFirst("_", ""); + -+ if (flag && !deobfuscationMap.containsKey(name.toLowerCase()) && !ignored.contains(name)) { -+ System.out.println("need to map " + clazz.getName() + " (" + name.toLowerCase() + ")"); ++ if (flag && !deobfuscationMap.containsKey(name.toLowerCase(java.util.Locale.ROOT)) && !ignored.contains(name)) { ++ System.out.println("need to map " + clazz.getName() + " (" + name.toLowerCase(java.util.Locale.ROOT) + ")"); + } + + // did we rename this key? diff --git a/patches/server/Missing-Entity-API.patch b/patches/server/Missing-Entity-API.patch index c2053e97db..0bb77ccef0 100644 --- a/patches/server/Missing-Entity-API.patch +++ b/patches/server/Missing-Entity-API.patch @@ -741,44 +741,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java @@ -0,0 +0,0 @@ public class CraftFireball extends AbstractProjectile implements Fireball { - public void setDirection(Vector direction) { - Preconditions.checkArgument(direction != null, "Vector direction cannot be null"); - if (direction.isZero()) { -- this.setVelocity(direction); -+ this.setPower(direction); // Paper - return; - } - this.getHandle().assignPower(direction.getX(), direction.getY(), direction.getZ()); - this.update(); // SPIGOT-6579 + return new Vector(this.getHandle().xPower, this.getHandle().yPower, this.getHandle().zPower); } -+ // Paper - fix upstream bug where they thought x/y/zPower was velocity -+ + // Paper start - Expose power on fireball projectiles - @Override -- public void setVelocity(Vector velocity) { -- Preconditions.checkArgument(velocity != null, "Vector velocity cannot be null"); -- // SPIGOT-6993: Allow power to be higher / lower than the normalized direction enforced by #setDirection(Vector) -- // Note: Because of MC-80142 the fireball will stutter on the client when setting the velocity to something other than 0 or the normalized vector * 0.1 -- this.getHandle().xPower = velocity.getX(); -- this.getHandle().yPower = velocity.getY(); -- this.getHandle().zPower = velocity.getZ(); -- this.update(); // SPIGOT-6579 ++ @Override + public void setPower(final Vector power) { -+ this.getHandle().xPower = power.getX(); -+ this.getHandle().yPower = power.getY(); -+ this.getHandle().zPower = power.getZ(); -+ this.update(); ++ this.setAcceleration(power); + } + + @Override + public Vector getPower() { -+ return new Vector(this.getHandle().xPower, this.getHandle().yPower, this.getHandle().zPower); - } ++ return this.getAcceleration(); ++ } + // Paper end - Expose power on fireball projectiles - ++ @Override public AbstractHurtingProjectile getHandle() { + return (AbstractHurtingProjectile) this.entity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java diff --git a/patches/server/Paper-Plugins.patch b/patches/server/Paper-Plugins.patch index 7520c4fa63..b95bb91b25 100644 --- a/patches/server/Paper-Plugins.patch +++ b/patches/server/Paper-Plugins.patch @@ -3654,7 +3654,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public void recalculatePermissionDefaults(@NotNull Permission perm) { + // we need a null check here because some plugins for some unknown reason pass null into this? -+ if (perm != null && this.permissions().containsKey(perm.getName().toLowerCase(Locale.ENGLISH))) { ++ if (perm != null && this.permissions().containsKey(perm.getName().toLowerCase(Locale.ROOT))) { + this.defaultPerms().get(true).remove(perm); + this.defaultPerms().get(false).remove(perm); + diff --git a/patches/server/Paper-command.patch b/patches/server/Paper-command.patch index c1dc3e35c2..aeb9335d10 100644 --- a/patches/server/Paper-command.patch +++ b/patches/server/Paper-command.patch @@ -253,7 +253,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + private static @Nullable Pair resolveCommand(String label) { -+ label = label.toLowerCase(Locale.ENGLISH); ++ label = label.toLowerCase(Locale.ROOT); + @Nullable PaperSubcommand subCommand = SUBCOMMANDS.get(label); + if (subCommand == null) { + final @Nullable String command = ALIASES.get(label); @@ -396,15 +396,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + private void listEntities(final CommandSender sender, final String[] args) { + // help -+ if (args.length < 1 || !args[0].toLowerCase(Locale.ENGLISH).equals("list")) { ++ if (args.length < 1 || !args[0].toLowerCase(Locale.ROOT).equals("list")) { + sender.sendMessage(text("Use /paper entity [list] help for more information on a specific command", RED)); + return; + } + -+ if ("list".equals(args[0].toLowerCase(Locale.ENGLISH))) { ++ if ("list".equals(args[0].toLowerCase(Locale.ROOT))) { + String filter = "*"; + if (args.length > 1) { -+ if (args[1].toLowerCase(Locale.ENGLISH).equals("help")) { ++ if (args[1].toLowerCase(Locale.ROOT).equals("help")) { + sender.sendMessage(text("Use /paper entity list [filter] [worldName] to get entity info that matches the optional filter.", RED)); + return; + } diff --git a/patches/server/Paper-config-files.patch b/patches/server/Paper-config-files.patch index 974359051d..a6c4b5c81c 100644 --- a/patches/server/Paper-config-files.patch +++ b/patches/server/Paper-config-files.patch @@ -3752,7 +3752,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ) + .addVersion(26, ConfigurationTransformation.builder().addAction(path("alt-item-despawn-rate", "items", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { + String itemName = path.get(path.size() - 1).toString(); -+ final Optional> item = BuiltInRegistries.ITEM.getHolder(ResourceKey.create(Registries.ITEM, new ResourceLocation(itemName.toLowerCase(Locale.ENGLISH)))); ++ final Optional> item = BuiltInRegistries.ITEM.getHolder(ResourceKey.create(Registries.ITEM, new ResourceLocation(itemName.toLowerCase(Locale.ROOT)))); + if (item.isEmpty()) { + itemName = Material.valueOf(itemName).getKey().getKey(); + } @@ -3784,7 +3784,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Map rebuild = new HashMap<>(); + value.childrenMap().forEach((key, node) -> { + String itemName = key.toString(); -+ final Optional> itemHolder = BuiltInRegistries.ITEM.getHolder(ResourceKey.create(Registries.ITEM, new ResourceLocation(itemName.toLowerCase(Locale.ENGLISH)))); ++ final Optional> itemHolder = BuiltInRegistries.ITEM.getHolder(ResourceKey.create(Registries.ITEM, new ResourceLocation(itemName.toLowerCase(Locale.ROOT)))); + final @Nullable String item; + if (itemHolder.isEmpty()) { + final @Nullable Material bukkitMat = Material.matchMaterial(itemName); @@ -4152,7 +4152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return USE_DEFAULT; + } + try { -+ return new BooleanOrDefault(BooleanUtils.toBoolean(string.toLowerCase(Locale.ENGLISH), "true", "false")); ++ return new BooleanOrDefault(BooleanUtils.toBoolean(string.toLowerCase(Locale.ROOT), "true", "false")); + } catch (IllegalArgumentException ex) { + throw new SerializationException(BooleanOrDefault.class, obj + "(" + type + ") is not a boolean or '" + DEFAULT_VALUE + "'", ex); + } diff --git a/patches/server/Plugin-remapping.patch b/patches/server/Plugin-remapping.patch index fe2a9c7c24..3f7ba83c8f 100644 --- a/patches/server/Plugin-remapping.patch +++ b/patches/server/Plugin-remapping.patch @@ -1346,7 +1346,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ + public static String sha256(final InputStream stream) { + try (stream) { -+ return com.google.common.hash.Hashing.sha256().hashBytes(IOUtils.toByteArray(stream)).toString().toUpperCase(Locale.ENGLISH); ++ return com.google.common.hash.Hashing.sha256().hashBytes(IOUtils.toByteArray(stream)).toString().toUpperCase(Locale.ROOT); + } catch (final IOException ex) { + throw new RuntimeException("Failed to take hash of InputStream", ex); + } @@ -1368,7 +1368,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } catch (final IOException ex) { + throw new RuntimeException("Failed to take hash of file '" + file + "'", ex); + } -+ return hash.toString().toUpperCase(Locale.ENGLISH); ++ return hash.toString().toUpperCase(Locale.ROOT); + } +} diff --git a/src/main/java/io/papermc/paper/util/MappingEnvironment.java b/src/main/java/io/papermc/paper/util/MappingEnvironment.java diff --git a/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch index 8492da8d65..aca029594b 100644 --- a/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch +++ b/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch @@ -649,7 +649,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -0,0 +0,0 @@ public class Commodore { - private static final Map FIELD_RENAME_METHOD_REROUTE = Commodore.createReroutes(FieldRename.class); + private static final Map MATERIAL_METHOD_REROUTE = Commodore.createReroutes(MaterialRerouting.class); // Paper start - Plugin rewrites - private static final Map SEARCH_AND_REMOVE = initReplacementsMap(); @@ -724,5 +724,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public byte[] processClass(PluginDescriptionFile pdf, String path, byte[] clazz) { + if (io.papermc.paper.util.MappingEnvironment.DISABLE_PLUGIN_REWRITING) return clazz; // Paper try { - clazz = Commodore.convert(clazz, pdf.getName(), ApiVersion.getOrCreateVersion(pdf.getAPIVersion())); + clazz = Commodore.convert(clazz, pdf.getName(), ApiVersion.getOrCreateVersion(pdf.getAPIVersion()), ((CraftServer) Bukkit.getServer()).activeCompatibilities); } catch (Exception ex) { diff --git a/patches/server/Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch index 98740f8b2e..352c9b049b 100644 --- a/patches/server/Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch +++ b/patches/server/Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch @@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return true; } else { -- return originalDamage >= 0; +- return originalDamage > 0; + return true; // Paper - return false ONLY if event was cancelled } // CraftBukkit end diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index d27cc844bd..aa474c3865 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -14526,10 +14526,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + -+ final String debugType = args[0].toLowerCase(Locale.ENGLISH); ++ final String debugType = args[0].toLowerCase(Locale.ROOT); + switch (debugType) { + case "chunks" -> { -+ if (args.length >= 2 && args[1].toLowerCase(Locale.ENGLISH).equals("help")) { ++ if (args.length >= 2 && args[1].toLowerCase(Locale.ROOT).equals("help")) { + sender.sendMessage(text("Use /paper debug chunks [world] to dump loaded chunk information to a file", RED)); + break; + } diff --git a/patches/server/Timings-v2.patch b/patches/server/Timings-v2.patch index 483886fccf..f61a23f95d 100644 --- a/patches/server/Timings-v2.patch +++ b/patches/server/Timings-v2.patch @@ -943,7 +943,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + // Paper start + command.set(event.getCommand()); -+ if (event.getCommand().toLowerCase().startsWith("timings") && event.getCommand().toLowerCase().matches("timings (report|paste|get|merged|seperate)")) { ++ if (event.getCommand().toLowerCase(java.util.Locale.ROOT).startsWith("timings") && event.getCommand().toLowerCase(java.util.Locale.ROOT).matches("timings (report|paste|get|merged|seperate)")) { + org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender(); + Waitable waitable = new Waitable<>() { + @Override diff --git a/patches/server/improve-checking-handled-tags-in-itemmeta.patch b/patches/server/improve-checking-handled-tags-in-itemmeta.patch index 4df172de5c..9f8222c16a 100644 --- a/patches/server/improve-checking-handled-tags-in-itemmeta.patch +++ b/patches/server/improve-checking-handled-tags-in-itemmeta.patch @@ -459,6 +459,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - CraftMetaItem.MAX_STACK_SIZE.TYPE, - CraftMetaItem.RARITY.TYPE, - CraftMetaItem.FOOD.TYPE, +- CraftMetaItem.TOOL.TYPE, - CraftMetaItem.DAMAGE.TYPE, - CraftMetaItem.MAX_DAMAGE.TYPE, - CraftMetaItem.CUSTOM_DATA.TYPE, @@ -475,6 +476,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - CraftMetaMap.MAP_ID.TYPE, - CraftMetaPotion.POTION_CONTENTS.TYPE, - CraftMetaSkull.SKULL_PROFILE.TYPE, +- CraftMetaSkull.NOTE_BLOCK_SOUND.TYPE, - CraftMetaSpawnEgg.ENTITY_TAG.TYPE, - CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE, - CraftMetaBook.BOOK_CONTENT.TYPE, @@ -516,6 +518,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + CraftMetaItem.MAX_STACK_SIZE.TYPE, + CraftMetaItem.RARITY.TYPE, + CraftMetaItem.FOOD.TYPE, ++ CraftMetaItem.TOOL.TYPE, + CraftMetaItem.DAMAGE.TYPE, + CraftMetaItem.MAX_DAMAGE.TYPE, + CraftMetaItem.CUSTOM_DATA.TYPE, @@ -677,7 +680,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java @@ -0,0 +0,0 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { - this.updateMaterial(null); // Trigger type population + this.entityTag = egg.entityTag; } - CraftMetaSpawnEgg(DataComponentPatch tag) { diff --git a/work/Bukkit b/work/Bukkit index fa99e752ae..376e37db4b 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit fa99e752ae28e0a294b2def5955645ad74a8a2d3 +Subproject commit 376e37db4b23b1fc18f93d3aeccaa40b8bb16ed2 diff --git a/work/CraftBukkit b/work/CraftBukkit index 4af0f22e8a..ee95e171a0 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 4af0f22e8a2ce40afd554a3d60da4fe093c7debd +Subproject commit ee95e171a0761467c09e0657583a5636d7ae7d3c diff --git a/work/Spigot b/work/Spigot index e2c1eee02c..fcd94e2117 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit e2c1eee02c2e00f71d78c56d6439dafc3af7dfac +Subproject commit fcd94e2117c41a2ff382fc7747bf8776a54d0389