From aa08956431e2d5c12e40916dd6080d684f783a21 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Tue, 19 Dec 2023 23:40:24 -0800 Subject: [PATCH] Split Position from Location type hierarchy --- ...osition-from-Location-type-hierarchy.patch | 51 ++++++++ .../api/0488-adapt-to-Position-change.patch | 33 +++++ ...osition-from-Location-type-hierarchy.patch | 116 ++++++++++++++++++ .../1058-adapt-to-Position-change.patch | 68 ++++++++++ test-plugin/build.gradle.kts | 7 +- .../io/papermc/testplugin/TestPlugin.java | 21 ++++ 6 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 patches/api/0487-Split-Position-from-Location-type-hierarchy.patch create mode 100644 patches/api/0488-adapt-to-Position-change.patch create mode 100644 patches/server/1057-Split-Position-from-Location-type-hierarchy.patch create mode 100644 patches/server/1058-adapt-to-Position-change.patch diff --git a/patches/api/0487-Split-Position-from-Location-type-hierarchy.patch b/patches/api/0487-Split-Position-from-Location-type-hierarchy.patch new file mode 100644 index 0000000000..a116b0849a --- /dev/null +++ b/patches/api/0487-Split-Position-from-Location-type-hierarchy.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 19 Dec 2023 23:39:49 -0800 +Subject: [PATCH] Split Position from Location type hierarchy + + +diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java +index 65618b6b3c950fb27707f243a766511d6cd3aab4..0c82941c045ddede59da69f865f27b3e4a0f5a12 100644 +--- a/src/main/java/org/bukkit/Location.java ++++ b/src/main/java/org/bukkit/Location.java +@@ -30,7 +30,7 @@ import org.bukkit.entity.Player; + * magnitude than 360 are valid, but may be normalized to any other equivalent + * representation by the implementation. + */ +-public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition { // Paper ++public class Location implements Cloneable, ConfigurationSerializable/*, io.papermc.paper.math.FinePosition*/ { // Paper + private Reference world; + private double x; + private double y; +@@ -1156,29 +1156,8 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm + } + + // Paper - add Position +- @Override +- public double x() { +- return this.getX(); +- } +- +- @Override +- public double y() { +- return this.getY(); +- } +- +- @Override +- public double z() { +- return this.getZ(); +- } +- +- @Override +- public boolean isFinite() { +- return io.papermc.paper.math.FinePosition.super.isFinite() && Float.isFinite(this.getYaw()) && Float.isFinite(this.getPitch()); +- } +- +- @Override +- public @NotNull Location toLocation(@NotNull World world) { +- return new Location(world, this.x(), this.y(), this.z(), this.getYaw(), this.getPitch()); ++ public io.papermc.paper.math.@NotNull Position asPosition() { ++ return io.papermc.paper.math.Position.fine(this); + } + // Paper end + } diff --git a/patches/api/0488-adapt-to-Position-change.patch b/patches/api/0488-adapt-to-Position-change.patch new file mode 100644 index 0000000000..bb83651f97 --- /dev/null +++ b/patches/api/0488-adapt-to-Position-change.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Thu, 21 Dec 2023 19:11:23 -0800 +Subject: [PATCH] adapt to Position change + +will be squashed into original patches + +diff --git a/src/main/java/org/bukkit/RegionAccessor.java b/src/main/java/org/bukkit/RegionAccessor.java +index eb33e8e671972aa308ad75a7ce9aa9ac526f470f..292f40d4ab849f786d9034dd4d8e4f829e439f97 100644 +--- a/src/main/java/org/bukkit/RegionAccessor.java ++++ b/src/main/java/org/bukkit/RegionAccessor.java +@@ -133,7 +133,7 @@ public interface RegionAccessor extends Keyed { // Paper + */ + @NotNull + default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull Location location) { +- return getFluidData(location.blockX(), location.blockY(), location.blockZ()); ++ return getFluidData(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + // Paper end + +diff --git a/src/main/java/org/bukkit/block/Sign.java b/src/main/java/org/bukkit/block/Sign.java +index 340e3adcc57227f2e570826681ea81b9159805de..47d89b1fe4cc9cb2720d0a3572320e08e8ca5aba 100644 +--- a/src/main/java/org/bukkit/block/Sign.java ++++ b/src/main/java/org/bukkit/block/Sign.java +@@ -214,7 +214,7 @@ public interface Sign extends TileState, Colorable { + * @return the side it is facing + */ + default @NotNull Side getInteractableSideFor(org.bukkit.entity.@NotNull Entity entity) { +- return this.getInteractableSideFor(entity.getLocation()); ++ return this.getInteractableSideFor(entity.getLocation().asPosition()); + } + + /** diff --git a/patches/server/1057-Split-Position-from-Location-type-hierarchy.patch b/patches/server/1057-Split-Position-from-Location-type-hierarchy.patch new file mode 100644 index 0000000000..741ca4f830 --- /dev/null +++ b/patches/server/1057-Split-Position-from-Location-type-hierarchy.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 19 Dec 2023 23:40:01 -0800 +Subject: [PATCH] Split Position from Location type hierarchy + + +diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/PaperClassloaderBytecodeModifier.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/PaperClassloaderBytecodeModifier.java +index d7a789af72e5a1ef5e42c7e855897b65fdeda805..f0383c6df4d8ce15f2e04bf589e0c9524e07befb 100644 +--- a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/PaperClassloaderBytecodeModifier.java ++++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/PaperClassloaderBytecodeModifier.java +@@ -3,6 +3,7 @@ package io.papermc.paper.plugin.entrypoint.classloader.bytecode; + import com.google.common.collect.Iterators; + import io.papermc.paper.plugin.configuration.PluginMeta; + import io.papermc.paper.plugin.entrypoint.classloader.ClassloaderBytecodeModifier; ++import io.papermc.paper.plugin.entrypoint.classloader.bytecode.versions.API_1_21_1; + import java.util.Iterator; + import java.util.LinkedHashMap; + import java.util.List; +@@ -15,6 +16,7 @@ import org.objectweb.asm.Opcodes; + public class PaperClassloaderBytecodeModifier implements ClassloaderBytecodeModifier { + + private static final Map> MODIFIERS = Util.make(new LinkedHashMap<>(), map -> { ++ map.put(API_1_21_1.API_VERSION, List.of(API_1_21_1::new)); + }); + + private final Map> constructedModifiers = MODIFIERS.entrySet().stream() +diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/versions/API_1_21_1.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/versions/API_1_21_1.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fc8e26c1b024f5bde160a91b23a6adc233fc947f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/bytecode/versions/API_1_21_1.java +@@ -0,0 +1,84 @@ ++package io.papermc.paper.plugin.entrypoint.classloader.bytecode.versions; ++ ++import io.papermc.asm.rules.RewriteRule; ++import io.papermc.asm.rules.builder.ConfiguredRuleFactory; ++import io.papermc.asm.rules.builder.matcher.method.targeted.TargetedMethodMatcher; ++import io.papermc.paper.event.world.StructuresLocateEvent; ++import io.papermc.paper.math.Position; ++import io.papermc.paper.plugin.entrypoint.classloader.bytecode.VersionedClassloaderBytecodeModifier; ++import java.lang.constant.ClassDesc; ++import java.lang.reflect.Method; ++import java.util.List; ++import java.util.Set; ++import org.bukkit.Bukkit; ++import org.bukkit.Location; ++import org.bukkit.RegionAccessor; ++import org.bukkit.Server; ++import org.bukkit.World; ++import org.bukkit.block.SculkCatalyst; ++import org.bukkit.block.Sign; ++import org.bukkit.boss.DragonBattle; ++import org.bukkit.craftbukkit.util.ApiVersion; ++import org.bukkit.entity.Player; ++import org.bukkit.generator.LimitedRegion; ++ ++import static io.papermc.asm.rules.RewriteRule.chain; ++import static io.papermc.asm.util.DescriptorUtils.desc; ++ ++public class API_1_21_1 extends VersionedClassloaderBytecodeModifier { ++ ++ public static final ApiVersion API_VERSION = ApiVersion.getOrCreateVersion("1.21.1"); ++ ++ private static final ClassDesc POSITION = desc(Position.class); ++ ++ private static final Method POSITION_FUZZY_HANDLER; ++ ++ static { ++ try { ++ POSITION_FUZZY_HANDLER = API_1_21_1.class.getDeclaredMethod("toPos", Object.class); ++ } catch (final NoSuchMethodException throwable) { ++ throw new RuntimeException(throwable); ++ } ++ } ++ ++ // for removing FinePosition from superclasses of Location ++ private static ConfiguredRuleFactory.Factory locationSplit(final String... methods) { ++ return rf -> rf.changeParamFuzzy( ++ Position.class, ++ POSITION_FUZZY_HANDLER, ++ TargetedMethodMatcher.builder() ++ .match(List.of(methods)) ++ .targetParam(POSITION) ++ .build() ++ ); ++ } ++ ++ public API_1_21_1(final int api) { ++ super(api); ++ } ++ ++ @Override ++ protected RewriteRule createRule() { ++ return chain( ++ this.createSplitRule() ++ ); ++ } ++ ++ private RewriteRule createSplitRule() { ++ // For all methods with Position parameters prior to the removal of Position from Location type hierarchy ++ return chain( ++ this.forOwnerClasses(Set.of(Bukkit.class, Server.class), locationSplit("isOwnedByCurrentRegion")), ++ this.forOwnerClasses(Set.of(RegionAccessor.class, World.class, LimitedRegion.class), locationSplit("getFluidData")), ++ this.forOwnerClass(World.class, locationSplit("hasStructureAt", "isPositionLoaded", "rayTraceEntities", "rayTraceBlocks", "rayTrace")), ++ this.forOwnerClass(SculkCatalyst.class, locationSplit("bloom")), ++ this.forOwnerClass(Sign.class, locationSplit("getInteractableSideFor")), ++ this.forOwnerClass(DragonBattle.class, locationSplit("spawnNewGateway")), ++ this.forOwnerClass(Player.class, locationSplit("lookAt")), ++ this.forOwnerClass(StructuresLocateEvent.Result.class, locationSplit("")) ++ ); ++ } ++ ++ public static Position toPos(final Object object) { // for split rule ++ return object instanceof final Location loc ? loc.asPosition() : (Position) object; ++ } ++} diff --git a/patches/server/1058-adapt-to-Position-change.patch b/patches/server/1058-adapt-to-Position-change.patch new file mode 100644 index 0000000000..60f75a9af9 --- /dev/null +++ b/patches/server/1058-adapt-to-Position-change.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Thu, 21 Dec 2023 19:11:06 -0800 +Subject: [PATCH] adapt to Position change + +will be squashed into original patches + +diff --git a/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java +index 479bc32241ebadf8bbc1080b601f61391ad37fa4..8830b6a8b10845a8bc4f751d7ec6d2987b0fa580 100644 +--- a/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java ++++ b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java +@@ -65,7 +65,7 @@ public class PaperFluidData implements FluidData { + @Override + public float computeHeight(@NotNull final Location location) { + Preconditions.checkArgument(location.getWorld() != null, "Cannot compute height on world-less location"); +- return this.state.getHeight(((CraftWorld) location.getWorld()).getHandle(), MCUtil.toBlockPos(location)); ++ return this.state.getHeight(((CraftWorld) location.getWorld()).getHandle(), MCUtil.toBlockPosition(location)); + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index ffd284f0e25c6f20672f7225aafd37e6c87ccf03..2cc1069e3657977f67ac356038b6fecafafd4c45 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -1175,7 +1175,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + @Override + public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) { + // Paper start - Add predicate for blocks when raytracing +- return this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, null); ++ return this.rayTraceBlocks(start.asPosition(), direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, null); + } + + @Override +@@ -1206,7 +1206,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + @Override + public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate filter) { + // Paper start - Add predicate for blocks when raytracing +- return this.rayTrace(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, raySize, filter, null); ++ return this.rayTrace(start.asPosition(), direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, raySize, filter, null); + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java +index 7b7b89e67d53ed70efae714192c5fa32977f3d9c..594fdeb10d384b0fbe967693b93e83c5c3847e09 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java +@@ -87,7 +87,7 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem + this.getHandle().setPodium(null); + } else { + org.apache.commons.lang.Validate.isTrue(location.getWorld() == null || location.getWorld().equals(getWorld()), "You cannot set a podium in a different world to where the dragon is"); +- this.getHandle().setPodium(io.papermc.paper.util.MCUtil.toBlockPos(location)); ++ this.getHandle().setPodium(io.papermc.paper.util.MCUtil.toBlockPos(location.asPosition())); + } + } + // Paper end - Allow changing the EnderDragon podium +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index a0d5082590ee03060f0dbb4770d196efc316c328..17ca20d64fdc28db3ed7c74e5456e207fd7ae7c0 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1352,7 +1352,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + org.bukkit.util.Vector direction = targetLocation.getDirection(); + direction.multiply(9999999); // We need to move the target block.. FAR out + targetLocation.add(direction); +- this.lookAt(targetLocation, io.papermc.paper.entity.LookAnchor.EYES); ++ this.lookAt(targetLocation.asPosition(), io.papermc.paper.entity.LookAnchor.EYES); + // Paper end + } + diff --git a/test-plugin/build.gradle.kts b/test-plugin/build.gradle.kts index 9f7d9da599..7c01fdd0b1 100644 --- a/test-plugin/build.gradle.kts +++ b/test-plugin/build.gradle.kts @@ -1,7 +1,12 @@ version = "1.0.0-SNAPSHOT" +repositories { + maven("https://repo.papermc.io/repository/maven-public/") +} + dependencies { - compileOnly(project(":paper-api")) + compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT") + // compileOnly(project(":paper-api")) } tasks.processResources { diff --git a/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java b/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java index 671c37fa40..d6d4e79f7c 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java @@ -1,6 +1,13 @@ package io.papermc.testplugin; +import io.papermc.paper.event.player.ChatEvent; +import io.papermc.paper.event.world.StructuresLocateEvent; +import java.util.function.BiFunction; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.generator.structure.Structure; import org.bukkit.plugin.java.JavaPlugin; public final class TestPlugin extends JavaPlugin implements Listener { @@ -10,6 +17,20 @@ public final class TestPlugin extends JavaPlugin implements Listener { this.getServer().getPluginManager().registerEvents(this, this); // io.papermc.testplugin.brigtests.Registration.registerViaOnEnable(this); + this.test(new Location(null, 0, 0, 0)); + } + + @EventHandler + public void onChat(ChatEvent event) { + this.test(event.getPlayer().getLocation()); + } + + private void test(Location loc) { + final BiFunction biFunction = StructuresLocateEvent.Result::new; + final StructuresLocateEvent.Result resultByConstructor = new StructuresLocateEvent.Result(loc, Structure.FORTRESS); + System.out.println(resultByConstructor.position()); + final StructuresLocateEvent.Result result = biFunction.apply(loc, Structure.FORTRESS); + System.out.println(result.position()); } }