41e6f20420
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: fdff0cd4 PR-869: Add Enderman#teleport and Enderman#teleportTowards dfd86ee7 Improve sendSignChange and related documentation beced2b2 PR-867: Add Player#sendBlockUpdate to send tile entity updates CraftBukkit Changes: ad6d0cffb SPIGOT-7394: Fix another issue with sendSignChange 66c5ce4c7 SPIGOT-7391: Preserve vanilla sign json where not modified by event ae3824f94 PR-1204: Add Enderman#teleport and Enderman#teleportTowards 5863a2eae Fix sendSignChange not working 4a7eadc97 PR-1201: Add Player#sendBlockUpdate to send tile entity updates 789324e30 Work around issue placing decorated pots
217 Zeilen
12 KiB
Diff
217 Zeilen
12 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
|
Date: Sun, 5 Sep 2021 12:15:59 -0400
|
|
Subject: [PATCH] More Teleport API
|
|
|
|
== AT ==
|
|
public net.minecraft.server.network.ServerGamePacketListenerImpl internalTeleport(DDDFFLjava/util/Set;Z)V
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index a8465cf4b21d376b37e88a3f9fd8b6e4360ee775..94c1c276998b76744122f98c18f65a4e8cbccf4d 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -1711,11 +1711,17 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
|
return false; // CraftBukkit - Return event status
|
|
}
|
|
|
|
- PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause);
|
|
+ // Paper start - Teleport API
|
|
+ Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
|
|
+ for (RelativeMovement relativeArgument : set) {
|
|
+ relativeFlags.add(org.bukkit.craftbukkit.entity.CraftPlayer.toApiRelativeFlag(relativeArgument));
|
|
+ }
|
|
+ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause, java.util.Set.copyOf(relativeFlags));
|
|
+ // Paper end
|
|
this.cserver.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled() || !to.equals(event.getTo())) {
|
|
- set.clear(); // Can't relative teleport
|
|
+ //set.clear(); // Can't relative teleport // Paper - Teleport API: Now you can!
|
|
to = event.isCancelled() ? event.getFrom() : event.getTo();
|
|
d0 = to.getX();
|
|
d1 = to.getY();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
index cc72d960d9a5f9481ec2214b1549a344907a68da..94b41e9e3abe9cfbe09af67b03bc841fc009b75c 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
@@ -561,15 +561,36 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
|
|
|
@Override
|
|
public boolean teleport(Location location, TeleportCause cause) {
|
|
+ // Paper start - Teleport passenger API
|
|
+ return teleport(location, cause, new io.papermc.paper.entity.TeleportFlag[0]);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean teleport(Location location, TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
|
|
+ // Paper end
|
|
Preconditions.checkArgument(location != null, "location cannot be null");
|
|
location.checkFinite();
|
|
+ // Paper start - Teleport passenger API
|
|
+ Set<io.papermc.paper.entity.TeleportFlag> flagSet = Set.of(flags);
|
|
+ boolean dismount = !flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE);
|
|
+ boolean ignorePassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
|
|
+ // Don't allow teleporting between worlds while keeping passengers
|
|
+ if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Don't allow to teleport between worlds if remaining on vehicle
|
|
+ if (!dismount && this.entity.isPassenger() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
- if (this.entity.isVehicle() || this.entity.isRemoved()) {
|
|
+ if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API
|
|
return false;
|
|
}
|
|
|
|
// If this entity is riding another entity, we must dismount before teleporting.
|
|
- this.entity.stopRiding();
|
|
+ if (dismount) this.entity.stopRiding(); // Paper - Teleport passenger API
|
|
|
|
// Let the server handle cross world teleports
|
|
if (location.getWorld() != null && !location.getWorld().equals(this.getWorld())) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index 3120f72d2ba93625931da83c1e37678c07bd69cd..65e0a7e7b210107cd8882cc48da796c470b6eec4 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -1203,13 +1203,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
|
|
@Override
|
|
public void setRotation(float yaw, float pitch) {
|
|
- throw new UnsupportedOperationException("Cannot set rotation of players. Consider teleporting instead.");
|
|
+ // Paper start - Teleport API
|
|
+ Location targetLocation = this.getEyeLocation();
|
|
+ targetLocation.setYaw(yaw);
|
|
+ targetLocation.setPitch(pitch);
|
|
+
|
|
+ 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);
|
|
+ // Paper end
|
|
}
|
|
|
|
@Override
|
|
public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) {
|
|
+ // Paper start - Teleport API
|
|
+ return this.teleport(location, cause, new io.papermc.paper.entity.TeleportFlag[0]);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor, @NotNull io.papermc.paper.entity.LookAnchor entityAnchor) {
|
|
+ this.getHandle().lookAt(toNmsAnchor(playerAnchor), ((CraftEntity) entity).getHandle(), toNmsAnchor(entityAnchor));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void lookAt(double x, double y, double z, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor) {
|
|
+ this.getHandle().lookAt(toNmsAnchor(playerAnchor), new Vec3(x, y, z));
|
|
+ }
|
|
+
|
|
+ public static net.minecraft.commands.arguments.EntityAnchorArgument.Anchor toNmsAnchor(io.papermc.paper.entity.LookAnchor nmsAnchor) {
|
|
+ return switch (nmsAnchor) {
|
|
+ case EYES -> net.minecraft.commands.arguments.EntityAnchorArgument.Anchor.EYES;
|
|
+ case FEET -> net.minecraft.commands.arguments.EntityAnchorArgument.Anchor.FEET;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public static io.papermc.paper.entity.LookAnchor toApiAnchor(net.minecraft.commands.arguments.EntityAnchorArgument.Anchor playerAnchor) {
|
|
+ return switch (playerAnchor) {
|
|
+ case EYES -> io.papermc.paper.entity.LookAnchor.EYES;
|
|
+ case FEET -> io.papermc.paper.entity.LookAnchor.FEET;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public static net.minecraft.world.entity.RelativeMovement toNmsRelativeFlag(io.papermc.paper.entity.TeleportFlag.Relative apiFlag) {
|
|
+ return switch (apiFlag) {
|
|
+ case X -> net.minecraft.world.entity.RelativeMovement.X;
|
|
+ case Y -> net.minecraft.world.entity.RelativeMovement.Y;
|
|
+ case Z -> net.minecraft.world.entity.RelativeMovement.Z;
|
|
+ case PITCH -> net.minecraft.world.entity.RelativeMovement.X_ROT;
|
|
+ case YAW -> net.minecraft.world.entity.RelativeMovement.Y_ROT;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public static io.papermc.paper.entity.TeleportFlag.Relative toApiRelativeFlag(net.minecraft.world.entity.RelativeMovement nmsFlag) {
|
|
+ return switch (nmsFlag) {
|
|
+ case X -> io.papermc.paper.entity.TeleportFlag.Relative.X;
|
|
+ case Y -> io.papermc.paper.entity.TeleportFlag.Relative.Y;
|
|
+ case Z -> io.papermc.paper.entity.TeleportFlag.Relative.Z;
|
|
+ case X_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.PITCH;
|
|
+ case Y_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.YAW;
|
|
+ };
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
|
|
+ java.util.Set<net.minecraft.world.entity.RelativeMovement> relativeArguments;
|
|
+ java.util.Set<io.papermc.paper.entity.TeleportFlag> allFlags;
|
|
+ if (flags.length == 0) {
|
|
+ relativeArguments = Set.of();
|
|
+ allFlags = Set.of();
|
|
+ } else {
|
|
+ relativeArguments = java.util.EnumSet.noneOf(net.minecraft.world.entity.RelativeMovement.class);
|
|
+ allFlags = new HashSet<>();
|
|
+ for (io.papermc.paper.entity.TeleportFlag flag : flags) {
|
|
+ if (flag instanceof io.papermc.paper.entity.TeleportFlag.Relative relativeTeleportFlag) {
|
|
+ relativeArguments.add(toNmsRelativeFlag(relativeTeleportFlag));
|
|
+ }
|
|
+ allFlags.add(flag);
|
|
+ }
|
|
+ }
|
|
+ boolean dismount = !allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE);
|
|
+ boolean ignorePassengers = allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
|
|
+ // Paper end - Teleport API
|
|
Preconditions.checkArgument(location != null, "location");
|
|
Preconditions.checkArgument(location.getWorld() != null, "location.world");
|
|
+ // Paper start - Teleport passenger API
|
|
+ // Don't allow teleporting between worlds while keeping passengers
|
|
+ if (ignorePassengers && entity.isVehicle() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Don't allow to teleport between worlds if remaining on vehicle
|
|
+ if (!dismount && entity.isPassenger() && location.getWorld() != this.getWorld()) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
location.checkFinite();
|
|
|
|
ServerPlayer entity = this.getHandle();
|
|
@@ -1222,7 +1310,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
return false;
|
|
}
|
|
|
|
- if (entity.isVehicle()) {
|
|
+ if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API
|
|
return false;
|
|
}
|
|
|
|
@@ -1240,7 +1328,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
}
|
|
|
|
// If this player is riding another entity, we must dismount before teleporting.
|
|
- entity.stopRiding();
|
|
+ if (dismount) entity.stopRiding(); // Paper - Teleport API
|
|
|
|
// SPIGOT-5509: Wakeup, similar to riding
|
|
if (this.isSleeping()) {
|
|
@@ -1256,13 +1344,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle();
|
|
|
|
// Close any foreign inventory
|
|
- if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
|
+ if (this.getHandle().containerMenu != this.getHandle().inventoryMenu && !allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_OPEN_INVENTORY)) { // Paper
|
|
this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper
|
|
}
|
|
|
|
// Check if the fromWorld and toWorld are the same.
|
|
if (fromWorld == toWorld) {
|
|
- entity.connection.teleport(to);
|
|
+ entity.connection.internalTeleport(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), relativeArguments); // Paper - Teleport API
|
|
} else {
|
|
// The respawn reason should never be used if the passed location is non null.
|
|
server.getHandle().respawn(entity, toWorld, true, to, !toWorld.paperConfig().environment.disableTeleportationSuffocationCheck, null); // Paper
|