From 374d9c85ba95f64910c769f4f21f42cc87809298 Mon Sep 17 00:00:00 2001 From: DerEchtePilz <81232921+DerEchtePilz@users.noreply.github.com> Date: Sun, 25 Aug 2024 22:25:13 +0200 Subject: [PATCH] Add a method to reset Lodestone compasses back to normal ones (#11308) --- patches/api/0472-General-ItemMeta-fixes.patch | 40 ++++ .../server/0966-General-ItemMeta-fixes.patch | 223 ++++++++++++++++-- ...oy-placed-blocks-on-the-end-platform.patch | 4 +- 3 files changed, 251 insertions(+), 16 deletions(-) diff --git a/patches/api/0472-General-ItemMeta-fixes.patch b/patches/api/0472-General-ItemMeta-fixes.patch index 43cf0e1a8c..34bd355a54 100644 --- a/patches/api/0472-General-ItemMeta-fixes.patch +++ b/patches/api/0472-General-ItemMeta-fixes.patch @@ -40,6 +40,46 @@ index a6d1dde422de98f178c0c9add99e01203a35e5cb..01ec84248a681180088fb1d7d22b80f8 ItemType.Typed TOTEM_OF_UNDYING = getItemType("totem_of_undying"); ItemType.Typed SHULKER_SHELL = getItemType("shulker_shell"); ItemType.Typed IRON_NUGGET = getItemType("iron_nugget"); +diff --git a/src/main/java/org/bukkit/inventory/meta/CompassMeta.java b/src/main/java/org/bukkit/inventory/meta/CompassMeta.java +index 5040ab6190b41442986d2a734a8e782df0eab2f6..48bac38469ce3c5b2e59ad115375e7e5a2417da7 100644 +--- a/src/main/java/org/bukkit/inventory/meta/CompassMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/CompassMeta.java +@@ -28,7 +28,8 @@ public interface CompassMeta extends ItemMeta { + /** + * Sets the location this lodestone compass will point to. + * +- * @param lodestone new location or null to clear ++ * @param lodestone new location or null to clear the targeted location ++ * @see #clearLodestone() to reset the compass to a normal compass + */ + void setLodestone(@Nullable Location lodestone); + +@@ -49,9 +50,25 @@ public interface CompassMeta extends ItemMeta { + * location. + * + * @param tracked new tracked status ++ * @see #clearLodestone() to reset the compass to a normal compass + */ + void setLodestoneTracked(boolean tracked); + ++ // Paper start - Add more lodestone compass methods ++ /** ++ * Checks if this compass is considered a lodestone compass. ++ * @see #hasLodestone() to check if a position is being tracked ++ * @see #isLodestoneTracked() to check if it verifies the position is a lodestone ++ */ ++ boolean isLodestoneCompass(); ++ ++ /** ++ * Reset this compass to a normal compass, removing any tracked ++ * location. ++ */ ++ void clearLodestone(); ++ // Paper end - Add more lodestone compass methods ++ + @Override + CompassMeta clone(); + } diff --git a/src/main/java/org/bukkit/inventory/meta/Damageable.java b/src/main/java/org/bukkit/inventory/meta/Damageable.java index ff6818b6d9e0207eafdd749928f33aeac3f27191..992f39da07bafe9769effaa7dc6adc018c89329d 100644 --- a/src/main/java/org/bukkit/inventory/meta/Damageable.java diff --git a/patches/server/0966-General-ItemMeta-fixes.patch b/patches/server/0966-General-ItemMeta-fixes.patch index 758fe84ff4..17b7102b0e 100644 --- a/patches/server/0966-General-ItemMeta-fixes.patch +++ b/patches/server/0966-General-ItemMeta-fixes.patch @@ -596,42 +596,237 @@ index 6517ec4933b0eae761fceb117ea1db175755d0b1..299f2f4f143f753f3cd8a020c8e6ae46 return true; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java -index 69a112b3a9726966aecbe687d905fd1a11cfa1e3..6362df65424e53098701b8d54c74b5905648b78a 100644 +index 69a112b3a9726966aecbe687d905fd1a11cfa1e3..ab424926c282fb03eabd1eebd2b7980899ef28e3 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java -@@ -35,7 +35,7 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { - private int lodestoneX; - private int lodestoneY; - private int lodestoneZ; +@@ -31,11 +31,7 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + static final ItemMetaKey LODESTONE_POS_Z = new ItemMetaKey("LodestonePosZ"); + static final ItemMetaKey LODESTONE_TRACKED = new ItemMetaKey("LodestoneTracked"); + +- private ResourceKey lodestoneWorld; +- private int lodestoneX; +- private int lodestoneY; +- private int lodestoneZ; - private boolean tracked = true; -+ private Boolean tracked = null; // Paper - tri-state ++ private LodestoneTracker tracker; // Paper - use LodestoneTracker type CraftMetaCompass(CraftMetaItem meta) { super(meta); -@@ -79,7 +79,7 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { +@@ -43,24 +39,13 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + return; + } + CraftMetaCompass compassMeta = (CraftMetaCompass) meta; +- this.lodestoneWorld = compassMeta.lodestoneWorld; +- this.lodestoneX = compassMeta.lodestoneX; +- this.lodestoneY = compassMeta.lodestoneY; +- this.lodestoneZ = compassMeta.lodestoneZ; +- this.tracked = compassMeta.tracked; ++ this.tracker = compassMeta.tracker; // Paper - use LodestoneTracker type + } + + CraftMetaCompass(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper + getOrEmpty(tag, CraftMetaCompass.LODESTONE_TARGET).ifPresent((lodestoneTarget) -> { +- lodestoneTarget.target().ifPresent((target) -> { +- this.lodestoneWorld = target.dimension(); +- BlockPos pos = target.pos(); +- this.lodestoneX = pos.getX(); +- this.lodestoneY = pos.getY(); +- this.lodestoneZ = pos.getZ(); +- }); +- this.tracked = lodestoneTarget.tracked(); ++ this.tracker = lodestoneTarget; // Paper - use LodestoneTracker type + }); + } + +@@ -68,10 +53,13 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + super(map); + String lodestoneWorldString = SerializableMeta.getString(map, CraftMetaCompass.LODESTONE_POS_WORLD.BUKKIT, true); + if (lodestoneWorldString != null) { +- this.lodestoneWorld = ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(lodestoneWorldString)); +- this.lodestoneX = (Integer) map.get(CraftMetaCompass.LODESTONE_POS_X.BUKKIT); +- this.lodestoneY = (Integer) map.get(CraftMetaCompass.LODESTONE_POS_Y.BUKKIT); +- this.lodestoneZ = (Integer) map.get(CraftMetaCompass.LODESTONE_POS_Z.BUKKIT); ++ // Paper start - use LodestoneTracker type ++ ResourceKey lodestoneWorld = ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(lodestoneWorldString)); ++ int lodestoneX = (Integer) map.get(CraftMetaCompass.LODESTONE_POS_X.BUKKIT); ++ int lodestoneY = (Integer) map.get(CraftMetaCompass.LODESTONE_POS_Y.BUKKIT); ++ int lodestoneZ = (Integer) map.get(CraftMetaCompass.LODESTONE_POS_Z.BUKKIT); ++ this.tracker = new LodestoneTracker(Optional.of(new GlobalPos(lodestoneWorld, new BlockPos(lodestoneX, lodestoneY, lodestoneZ))), true); ++ // Paper end - use LodestoneTracker type + } else { + // legacy + Location lodestone = SerializableMeta.getObject(Location.class, map, CraftMetaCompass.LODESTONE_POS.BUKKIT, true); +@@ -79,21 +67,22 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { this.setLodestone(lodestone); } } - this.tracked = SerializableMeta.getBoolean(map, CraftMetaCompass.LODESTONE_TRACKED.BUKKIT); -+ this.tracked = SerializableMeta.getObjectOptionally(Boolean.class, map, CraftMetaCompass.LODESTONE_TRACKED.BUKKIT, true).orElse(null); // Paper - tri-state ++ // Paper start - use LodestoneTracker type ++ final Optional tracked = SerializableMeta.getObjectOptionally(Boolean.class, map, CraftMetaCompass.LODESTONE_TRACKED.BUKKIT, true); ++ final Optional trackedPos = this.tracker != null ? this.tracker.target() : Optional.empty(); ++ tracked.ifPresent(isTracked -> this.tracker = new LodestoneTracker(trackedPos, isTracked)); ++ // Paper end - use LodestoneTracker type } @Override -@@ -140,12 +140,12 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + void applyToItem(CraftMetaItem.Applicator tag) { + super.applyToItem(tag); + +- Optional target = Optional.empty(); +- if (this.lodestoneWorld != null) { +- target = Optional.of(new GlobalPos(this.lodestoneWorld, new BlockPos(this.lodestoneX, this.lodestoneY, this.lodestoneZ))); +- } +- +- if (target.isPresent() || this.hasLodestoneTracked()) { +- tag.put(CraftMetaCompass.LODESTONE_TARGET, new LodestoneTracker(target, this.tracked)); ++ // Paper start - use LodestoneTracker type ++ if (this.tracker != null) { ++ tag.put(CraftMetaCompass.LODESTONE_TARGET, this.tracker); + } ++ // Paper end - use LodestoneTracker type } - boolean hasLodestoneTracked() { + @Override +@@ -102,7 +91,7 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + } + + boolean isCompassEmpty() { +- return !(this.hasLodestone() || this.hasLodestoneTracked()); ++ return this.tracker == null; // Paper - use LodestoneTracker type + } + + @Override +@@ -113,58 +102,69 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + + @Override + public boolean hasLodestone() { +- return this.lodestoneWorld != null; ++ return this.tracker != null && this.tracker.target().isPresent(); // Paper - use LodestoneTracker type + } + + @Override + public Location getLodestone() { +- if (this.lodestoneWorld == null) { ++ if (this.tracker == null || this.tracker.target().isEmpty()) { // Paper - use LodestoneTracker type + return null; + } +- ServerLevel worldServer = MinecraftServer.getServer().getLevel(this.lodestoneWorld); ++ ServerLevel worldServer = MinecraftServer.getServer().getLevel(this.tracker.target().get().dimension()); // Paper - use LodestoneTracker type + World world = worldServer != null ? worldServer.getWorld() : null; +- return new Location(world, this.lodestoneX, this.lodestoneY, this.lodestoneZ); // world may be null here, if the referenced world is not loaded ++ return org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.tracker.target().get().pos(), world); // world may be null here, if the referenced world is not loaded // Paper - use LodestoneTracker type + } + + @Override + public void setLodestone(Location lodestone) { + Preconditions.checkArgument(lodestone == null || lodestone.getWorld() != null, "world is null"); + if (lodestone == null) { +- this.lodestoneWorld = null; ++ // Paper start - use LodestoneTracker type ++ if (this.tracker != null) { ++ this.tracker = new LodestoneTracker(java.util.Optional.empty(), this.tracker.tracked()); // Paper - use LodestoneTracker type ++ } ++ // Paper end - use LodestoneTracker type + } else { +- this.lodestoneWorld = ((CraftWorld) lodestone.getWorld()).getHandle().dimension(); +- this.lodestoneX = lodestone.getBlockX(); +- this.lodestoneY = lodestone.getBlockY(); +- this.lodestoneZ = lodestone.getBlockZ(); ++ // Paper start - use LodestoneTracker type ++ GlobalPos pos = GlobalPos.of( ++ ((CraftWorld) lodestone.getWorld()).getHandle().dimension(), ++ io.papermc.paper.util.MCUtil.toBlockPosition(lodestone) ++ ); ++ boolean tracked = this.tracker == null || this.tracker.tracked(); ++ this.tracker = new LodestoneTracker(Optional.of(pos), tracked); ++ // Paper end - use LodestoneTracker type + } + } + +- boolean hasLodestoneTracked() { - return !this.tracked; -+ return this.tracked != null; // Paper - tri-state - } - +- } +- @Override public boolean isLodestoneTracked() { - return this.tracked; -+ return this.tracked != null && this.tracked; // Paper - tri-state ++ return this.tracker != null && this.tracker.tracked(); // Paper - use LodestoneTracker type } @Override + public void setLodestoneTracked(boolean tracked) { +- this.tracked = tracked; ++ final Optional trackedPos = this.tracker != null ? this.tracker.target() : Optional.empty(); // Paper - use LodestoneTracker type ++ this.tracker = new LodestoneTracker(trackedPos, tracked); // Paper - use LodestoneTracker type ++ } ++ ++ // Paper start - Add more lodestone compass methods ++ @Override ++ public boolean isLodestoneCompass() { ++ return this.tracker != null; ++ } ++ ++ @Override ++ public void clearLodestone() { ++ this.tracker = null; + } ++ // Paper end - Add more lodestone compass methods + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); +- if (this.hasLodestone()) { +- hash = 73 * hash + this.lodestoneWorld.hashCode(); +- hash = 73 * hash + this.lodestoneX; +- hash = 73 * hash + this.lodestoneY; +- hash = 73 * hash + this.lodestoneZ; +- } +- if (this.hasLodestoneTracked()) { +- hash = 73 * hash + (this.isLodestoneTracked() ? 1231 : 1237); ++ if (this.isLodestoneCompass()) { ++ hash = 73 * hash + this.tracker.hashCode(); // Paper - use LodestoneTracker type + } + + return original != hash ? CraftMetaCompass.class.hashCode() ^ hash : hash; +@@ -178,10 +178,7 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + if (meta instanceof CraftMetaCompass) { + CraftMetaCompass that = (CraftMetaCompass) meta; + +- return (this.hasLodestone() ? that.hasLodestone() && this.lodestoneWorld.equals(that.lodestoneWorld) +- && this.lodestoneX == that.lodestoneX && this.lodestoneY == that.lodestoneY +- && this.lodestoneZ == that.lodestoneZ : !that.hasLodestone()) +- && this.tracked == that.tracked; ++ return java.util.Objects.equals(this.tracker, that.tracker); // Paper - use LodestoneTracker type + } + return true; + } +@@ -195,14 +192,16 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta { + Builder serialize(Builder builder) { + super.serialize(builder); + +- if (this.hasLodestone()) { +- builder.put(CraftMetaCompass.LODESTONE_POS_WORLD.BUKKIT, this.lodestoneWorld.location().toString()); +- builder.put(CraftMetaCompass.LODESTONE_POS_X.BUKKIT, this.lodestoneX); +- builder.put(CraftMetaCompass.LODESTONE_POS_Y.BUKKIT, this.lodestoneY); +- builder.put(CraftMetaCompass.LODESTONE_POS_Z.BUKKIT, this.lodestoneZ); +- } +- if (this.hasLodestoneTracked()) { +- builder.put(CraftMetaCompass.LODESTONE_TRACKED.BUKKIT, this.tracked); ++ if (this.isLodestoneCompass()) { // Paper - use LodestoneTracker type ++ // Paper start - use LodestoneTracker type ++ if (this.tracker.target().isPresent()) { ++ builder.put(CraftMetaCompass.LODESTONE_POS_WORLD.BUKKIT, this.tracker.target().get().dimension().location().toString()); ++ builder.put(CraftMetaCompass.LODESTONE_POS_X.BUKKIT, this.tracker.target().get().pos().getX()); ++ builder.put(CraftMetaCompass.LODESTONE_POS_Y.BUKKIT, this.tracker.target().get().pos().getY()); ++ builder.put(CraftMetaCompass.LODESTONE_POS_Z.BUKKIT, this.tracker.target().get().pos().getZ()); ++ } ++ builder.put(CraftMetaCompass.LODESTONE_TRACKED.BUKKIT, this.tracker.tracked()); ++ // Paper end - use LodestoneTracker type + } + + return builder; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java index 0807c2172c5a4bee675cef265a45a9350e98b880..88ea260fb84a5f8eaab3a23a9a65d0411215a6a1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java diff --git a/patches/server/1053-Properly-destroy-placed-blocks-on-the-end-platform.patch b/patches/server/1053-Properly-destroy-placed-blocks-on-the-end-platform.patch index 94813b1d42..9bbeddc476 100644 --- a/patches/server/1053-Properly-destroy-placed-blocks-on-the-end-platform.patch +++ b/patches/server/1053-Properly-destroy-placed-blocks-on-the-end-platform.patch @@ -12,7 +12,7 @@ platform to be lost. The patch moves the destroy calls and executes them on the actual world access. diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java -index 0bc659a8427b89b5e3211220c55b52eec6a20494..15d0de7b623d874972c67ac34da2718220b6bdf5 100644 +index 0bc659a8427b89b5e3211220c55b52eec6a20494..8aa5445e38622cd7cf4b3e42e9be8760827639fa 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java +++ b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java @@ -44,7 +44,7 @@ public class EndPlatformFeature extends Feature { @@ -20,7 +20,7 @@ index 0bc659a8427b89b5e3211220c55b52eec6a20494..15d0de7b623d874972c67ac34da27182 if (!blockList.getBlockState(blockposition_mutableblockposition1).is(block)) { if (flag) { - blockList.destroyBlock(blockposition_mutableblockposition1, true, (Entity) null); -+ // blockList.destroyBlock(blockposition_mutableblockposition1, true, (Entity) null); // Paper - moved down - cb implementation of LevelAccessor does not support destoryBlock ++ // blockList.destroyBlock(blockposition_mutableblockposition1, true, (Entity) null); // Paper - moved down - cb implementation of LevelAccessor does not support destroyBlock } blockList.setBlock(blockposition_mutableblockposition1, block.defaultBlockState(), 3);