geforkt von Mirrors/Paper
2873869bb1
Signs no longer have a specific isEdiable state, the entire API in this regard needs updating/deprecation. The boolean field is completely gone, replaced by a uuid (which will need a new setEditingPlayer(UUID) method on the Sign interface), and the current upstream implementation of setEdiable simply flips the is_waxed state. This patch is hence not needed as it neither allows editing (which will be redone in a later patch) nor is required to copy the is_waxed boolean flag as it lives in the signs compound tag and is covered by applyTo.
216 Zeilen
12 KiB
Diff
216 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 791f04d75f4d942bc0ef8d04ef4a401161acdc1c..d74d9493bb6fd4677aa3244b4b1b26d02f6b5b86 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -1707,11 +1707,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 c6fc526db6943f6466d6504feff63715e35a0eb2..f04c50a76f3589181dd4502d630a93c4dff3a95a 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 6b61a80407cc5ba580d7c95e5bf2146d177b1b4a..ce83330c4ebd81247f2b4c4f2693265810237d7a 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -1233,13 +1233,100 @@ 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();
|
|
+ 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();
|
|
@@ -1252,7 +1339,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
return false;
|
|
}
|
|
|
|
- if (entity.isVehicle()) {
|
|
+ if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API
|
|
return false;
|
|
}
|
|
|
|
@@ -1270,7 +1357,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()) {
|
|
@@ -1286,13 +1373,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
|