feat: Entity#teleportAsync method with TeleportFlags (#10371)

* feat: Entity#teleportAsync method with TeleportFlags

* use method-local class

---------

Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
This commit is contained in:
Bridge
2024-04-06 22:38:37 +02:00
parent 68e86d7297
commit 7de6922d21
13 changed files with 100 additions and 84 deletions

View File

@@ -71,6 +71,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Let the server handle cross world teleports
if (location.getWorld() != null && !location.getWorld().equals(this.getWorld())) {
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
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()
{
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java