2022-07-22 21:36:43 +02:00
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
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
2024-08-24 11:07:12 +02:00
index 6b95158d7fb6548840ebb7644f2e3f94d4ec5b29..f163c9c47d8eb3668204aa86c44238254dbab6f3 100644
2022-07-22 21:36:43 +02:00
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
2024-08-24 11:07:12 +02:00
@@ -1551,11 +1551,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
2022-07-22 21:36:43 +02:00
return false; // CraftBukkit - Return event status
}
- PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause);
+ // Paper start - Teleport API
2023-03-04 23:07:23 +01:00
+ Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
2023-03-15 00:10:18 +01:00
+ for (RelativeMovement relativeArgument : set) {
2022-07-22 21:36:43 +02:00
+ relativeFlags.add(org.bukkit.craftbukkit.entity.CraftPlayer.toApiRelativeFlag(relativeArgument));
+ }
2023-03-15 00:10:18 +01:00
+ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause, java.util.Set.copyOf(relativeFlags));
2024-01-18 15:56:25 +01:00
+ // Paper end - Teleport API
2022-07-22 21:36:43 +02:00
this.cserver.getPluginManager().callEvent(event);
if (event.isCancelled() || !to.equals(event.getTo())) {
- set.clear(); // Can't relative teleport
2024-01-18 15:56:25 +01:00
+ // set.clear(); // Can't relative teleport // Paper - Teleport API; Now you can!
2022-07-22 21:36:43 +02:00
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
2024-04-24 22:32:38 +02:00
index 113ca1d16cb7650d72f488cdaa9e670d51dc85f0..b6fef2ca5b564c293cb602cb8e300d35dba89b1f 100644
2022-07-22 21:36:43 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#10277)
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:
9a80d38c SPIGOT-336, SPIGOT-3366, SPIGOT-5768, SPIGOT-6409, SPIGOT-6861, PR-722: Add EntityRemoveEvent
258086d9 SPIGOT-7417, PR-967: Add Sign#getTargetSide and Sign#getAllowedEditor
ffaba051 SPIGOT-7584: Add missing Tag.ITEMS_NON_FLAMMABLE_WOOD
CraftBukkit Changes:
98b6c1ac7 SPIGOT-7589 Fix NullPointerException when bans expire
a2736ddb0 SPIGOT-336, SPIGOT-3366, SPIGOT-5768, SPIGOT-6409, SPIGOT-6861, PR-1008: Add EntityRemoveEvent
5bf12cb89 SPIGOT-7565: Throw a more descriptive error message when a developer tries to spawn an entity from a CraftBukkit class
76d95fe7e SPIGOT-7417, PR-1343: Add Sign#getTargetSide and Sign#getAllowedEditor
Spigot Changes:
e9ec5485 Rebuild patches
f1b62e0c Rebuild patches
2024-02-23 14:37:33 +01:00
@@ -219,15 +219,36 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
2022-07-22 21:36:43 +02:00
@Override
public boolean teleport(Location location, TeleportCause cause) {
+ // Paper start - Teleport passenger API
2023-03-04 23:07:23 +01:00
+ return teleport(location, cause, new io.papermc.paper.entity.TeleportFlag[0]);
2022-07-22 21:36:43 +02:00
+ }
+
+ @Override
2023-03-04 23:07:23 +01:00
+ public boolean teleport(Location location, TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
2022-07-22 21:36:43 +02:00
+ // Paper end
Preconditions.checkArgument(location != null, "location cannot be null");
location.checkFinite();
+ // Paper start - Teleport passenger API
2023-03-04 23:07:23 +01:00
+ 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);
2022-07-22 21:36:43 +02:00
+ // Don't allow teleporting between worlds while keeping passengers
2023-03-04 23:07:23 +01:00
+ if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) {
2022-07-22 21:36:43 +02:00
+ return false;
+ }
2023-03-23 22:57:03 +01:00
+
2022-07-22 21:36:43 +02:00
+ // Don't allow to teleport between worlds if remaining on vehicle
+ if (!dismount && this.entity.isPassenger() && location.getWorld() != this.getWorld()) {
+ return false;
+ }
+ // Paper end
2023-03-23 22:57:03 +01:00
- if (this.entity.isVehicle() || this.entity.isRemoved()) {
2022-07-22 21:36:43 +02:00
+ 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())) {
2024-04-24 22:32:38 +02:00
@@ -958,6 +979,39 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
2024-04-06 22:38:37 +02:00
return CraftEntity.perm;
}
+ // Paper start - more teleport API / async chunk API
+ @Override
+ public java.util.concurrent.CompletableFuture<Boolean> teleportAsync(final Location location, final TeleportCause cause, final io.papermc.paper.entity.TeleportFlag... teleportFlags) {
+ Preconditions.checkArgument(location != null, "location");
+ location.checkFinite();
+ Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call.
+
+ net.minecraft.server.level.ServerLevel world = ((CraftWorld)locationClone.getWorld()).getHandle();
+ java.util.concurrent.CompletableFuture<Boolean> ret = new java.util.concurrent.CompletableFuture<>();
+
+ world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()),
+ this instanceof CraftPlayer ? ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER : ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, (list) -> {
+ net.minecraft.server.level.ServerChunkCache chunkProviderServer = world.getChunkSource();
+ for (net.minecraft.world.level.chunk.ChunkAccess chunk : list) {
+ chunkProviderServer.addTicketAtLevel(net.minecraft.server.level.TicketType.POST_TELEPORT, chunk.getPos(), 33, CraftEntity.this.getEntityId());
+ }
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
+ try {
+ ret.complete(CraftEntity.this.teleport(locationClone, cause, teleportFlags) ? Boolean.TRUE : Boolean.FALSE);
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath) {
+ throw (ThreadDeath)throwable;
+ }
+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to teleport entity " + CraftEntity.this, throwable);
+ ret.completeExceptionally(throwable);
+ }
+ });
+ });
+
+ return ret;
+ }
+ // Paper end - more teleport API / async chunk API
+
// Spigot start
private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot()
{
2022-07-22 21:36:43 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
2024-08-24 11:07:12 +02:00
index 6793acbbae09a9bc39f59c029f6b02182ec33a92..898259c35c25ee034c859e210350efc19c559e3b 100644
2022-07-22 21:36:43 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
2024-04-24 22:32:38 +02:00
@@ -1273,13 +1273,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2022-07-22 21:36:43 +02:00
@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();
2023-06-09 04:37:59 +02:00
+ direction.multiply(9999999); // We need to move the target block.. FAR out
2022-07-22 21:36:43 +02:00
+ 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
2023-03-04 23:07:23 +01:00
+ return this.teleport(location, cause, new io.papermc.paper.entity.TeleportFlag[0]);
2022-07-22 21:36:43 +02:00
+ }
+
+ @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;
+ };
+ }
+
2023-03-14 22:35:03 +01:00
+ public static net.minecraft.world.entity.RelativeMovement toNmsRelativeFlag(io.papermc.paper.entity.TeleportFlag.Relative apiFlag) {
2022-07-22 21:36:43 +02:00
+ return switch (apiFlag) {
2023-03-14 22:35:03 +01:00
+ 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;
2022-07-22 21:36:43 +02:00
+ };
+ }
+
2023-03-14 22:35:03 +01:00
+ public static io.papermc.paper.entity.TeleportFlag.Relative toApiRelativeFlag(net.minecraft.world.entity.RelativeMovement nmsFlag) {
2022-07-22 21:36:43 +02:00
+ return switch (nmsFlag) {
2023-03-04 23:07:23 +01:00
+ 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;
2022-07-22 21:36:43 +02:00
+ };
+ }
+
+ @Override
2023-03-04 23:07:23 +01:00
+ public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
2024-01-02 20:42:26 +01:00
+ Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeArguments;
+ Set<io.papermc.paper.entity.TeleportFlag> allFlags;
2023-03-04 23:07:23 +01:00
+ if (flags.length == 0) {
+ relativeArguments = Set.of();
+ allFlags = Set.of();
+ } else {
2024-01-02 20:42:26 +01:00
+ relativeArguments = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
2023-03-04 23:07:23 +01:00
+ allFlags = new HashSet<>();
+ for (io.papermc.paper.entity.TeleportFlag flag : flags) {
2024-01-02 20:42:26 +01:00
+ if (flag instanceof final io.papermc.paper.entity.TeleportFlag.Relative relativeTeleportFlag) {
+ relativeArguments.add(relativeTeleportFlag);
2023-03-04 23:07:23 +01:00
+ }
+ allFlags.add(flag);
+ }
2022-07-22 21:36:43 +02:00
+ }
2023-03-04 23:07:23 +01:00
+ boolean dismount = !allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE);
+ boolean ignorePassengers = allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
2022-07-22 21:36:43 +02:00
+ // 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();
2024-04-24 22:32:38 +02:00
@@ -1292,7 +1380,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
Updated Upstream (Bukkit/CraftBukkit) (#10034)
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:
f29cb801 Separate checkstyle-suppressions file is not required
86f99bbe SPIGOT-7540, PR-946: Add ServerTickManager API
d4119585 SPIGOT-6903, PR-945: Add BlockData#getMapColor
b7a2ed41 SPIGOT-7530, PR-947: Add Player#removeResourcePack
9dd56255 SPIGOT-7527, PR-944: Add WindCharge#explode()
994a6163 Attempt upgrade of resolver libraries
CraftBukkit Changes:
b3b43a6ad Add Checkstyle check for unused imports
13fb3358e SPIGOT-7544: Scoreboard#getEntries() doesn't get entries but class names
3dda99c06 SPIGOT-7540, PR-1312: Add ServerTickManager API
2ab4508c0 SPIGOT-6903, PR-1311: Add BlockData#getMapColor
1dbdbbed4 PR-1238: Remove unnecessary sign ticking
659728d2a MC-264285, SPIGOT-7439, PR-1237: Fix unbreakable flint and steel is completely consumed while igniting creeper
e37e29ce0 Increase outdated build delay
c00438b39 SPIGOT-7530, PR-1313: Add Player#removeResourcePack
492dd80ce SPIGOT-7527, PR-1310: Add WindCharge#explode()
e11fbb9d7 Upgrade MySQL driver
9f3a0bd2a Attempt upgrade of resolver libraries
60d16d7ca PR-1306: Centralize Bukkit and Minecraft entity conversion
Spigot Changes:
06d602e7 Rebuild patches
2023-12-17 03:09:28 +01:00
return false;
2022-07-22 21:36:43 +02:00
}
- if (entity.isVehicle()) {
+ if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API
return false;
}
2024-04-24 22:32:38 +02:00
@@ -1301,7 +1389,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2024-01-02 20:42:26 +01:00
// To = Players new Location if Teleport is Successful
Location to = location;
// Create & Call the Teleport Event.
- PlayerTeleportEvent event = new PlayerTeleportEvent(this, from, to, cause);
+ PlayerTeleportEvent event = new PlayerTeleportEvent(this, from, to, cause, Set.copyOf(relativeArguments)); // Paper - Teleport API
this.server.getPluginManager().callEvent(event);
// Return False to inform the Plugin that the Teleport was unsuccessful/cancelled.
2024-04-24 22:32:38 +02:00
@@ -1310,7 +1398,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2022-07-22 21:36:43 +02:00
}
// 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()) {
2024-04-24 22:32:38 +02:00
@@ -1326,13 +1414,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
2023-03-04 23:07:23 +01:00
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
2024-01-21 19:37:09 +01:00
this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper - Inventory close reason
2023-03-04 23:07:23 +01:00
}
2022-07-22 21:36:43 +02:00
// Check if the fromWorld and toWorld are the same.
if (fromWorld == toWorld) {
- entity.connection.teleport(to);
2024-01-02 20:42:26 +01:00
+ // Paper start - Teleport API
+ final Set<net.minecraft.world.entity.RelativeMovement> nms = java.util.EnumSet.noneOf(net.minecraft.world.entity.RelativeMovement.class);
+ for (final io.papermc.paper.entity.TeleportFlag.Relative bukkit : relativeArguments) {
+ nms.add(toNmsRelativeFlag(bukkit));
+ }
+ entity.connection.internalTeleport(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), nms);
+ // Paper end - Teleport API
2022-07-22 21:36:43 +02:00
} else {
2023-04-10 10:03:36 +02:00
// The respawn reason should never be used if the passed location is non null.
2023-10-27 01:34:58 +02:00
this.server.getHandle().respawn(entity, toWorld, true, to, !toWorld.paperConfig().environment.disableTeleportationSuffocationCheck, null); // Paper