mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-02 13:07:06 +01:00
4af62f6d1d
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: 2d009e64 Update SnakeYAML javadoc link b4fd213c Switch Player#updateInventory deprecation for internal API annotation CraftBukkit Changes: f3b2b2210 SPIGOT-7376: Exception with getBlockData when hasBlockData is false 725545630 SPIGOT-7375: Fix crash breeding certain entities b9873b0d4 Update Brigadier version with fix 68b320562 SPIGOT-7266: Found typo in CraftBukkit package 98b4d2ff8 SPIGOT-7372, SPIGOT-7373: Signs can't be edited, issues with SignChangeEvent 5f7bd4d78 SPIGOT-7371: Sign does not open edit text on placement b4cf99d24 SPIGOT-7371: Fix editing signs with API a2b6c2744 PR-1200: Implement open sign by side a345bb940 SPIGOT-7368: Downgrade SpecialSource version Spigot Changes: 723951c3 Rebuild patches b655c57d Drop old collision API deprecated since 1.9.4 55b0fed4 Rebuild patches
215 lines
12 KiB
Diff
215 lines
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 41784e46737a4a22aee53df4d4bdf170850b7a75..4b2ff9527d6af588a4947c6eea66eee89f888aaa 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
|