From 900e3eacd263000429536d32cc8e1cb2dd393c82 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 13 Aug 2026 17:04:47 +0300 Subject: [PATCH 1/2] Add PlayerPrepareTeleportEvent --- .../player/PlayerPrepareTeleportEvent.java | 81 +++++++++++++++++++ .../craftbukkit/entity/CraftPlayer.java | 7 ++ 2 files changed, 88 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java new file mode 100644 index 000000000000..77adcc73882b --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java @@ -0,0 +1,81 @@ +package io.papermc.paper.event.player; + +import io.papermc.paper.entity.TeleportFlag; +import java.util.Set; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; + +/** + * Event that is fired before attempting to teleport a player (Allows for pre-teleport handling, such as dismounting passengers if teleporting cross-worlds etc.) + *

+ * After the handling of this event, the player will attempt to teleport to the given location. + */ +@NullMarked +public class PlayerPrepareTeleportEvent extends PlayerEvent { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Location to; + private final PlayerTeleportEvent.TeleportCause cause; + private final Set teleportFlags; + + @ApiStatus.Internal + public PlayerPrepareTeleportEvent(final Player player, Location to, PlayerTeleportEvent.TeleportCause cause, Set teleportFlags) { + super(player); + this.to = to; + this.cause = cause; + this.teleportFlags = teleportFlags; + } + + /** + * Gets the location this player is teleporting to + * + * @return A copy of the Location the player is teleporting to + */ + public Location getTo() { + return this.to.clone(); + } + + /** + * Gets the location this player is teleporting from + * + * @return A copy of the Location the player is moving from + */ + public Location getFrom() { + return this.getPlayer().getLocation(); + } + + /** + * Returns the relative teleportation flags used in this teleportation. + * This determines which axis the player will not lose their velocity in. + * + * @return an immutable set of relative teleportation flags + */ + public @Unmodifiable Set getRelativeTeleportationFlags() { + return this.teleportFlags; + } + + /** + * Gets the cause of this teleportation event + * + * @return Cause of the event + */ + public PlayerTeleportEvent.TeleportCause getCause() { + return this.cause; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 596338c7c9b3..44bd4c4e40a2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -18,6 +18,7 @@ import io.papermc.paper.entity.LookAnchor; import io.papermc.paper.entity.PaperPlayerGiveResult; import io.papermc.paper.entity.PlayerGiveResult; +import io.papermc.paper.event.player.PlayerPrepareTeleportEvent; import io.papermc.paper.math.Angle; import io.papermc.paper.math.Position; import io.papermc.paper.util.MCUtil; @@ -1316,6 +1317,12 @@ protected boolean teleport0(Location location, org.bukkit.event.player.PlayerTel if (this.getHandle().connection == null) { return false; } + + // Paper start - Add PlayerPrepareTeleportEvent + final PlayerPrepareTeleportEvent playerPrepareTeleportEvent = new PlayerPrepareTeleportEvent(this, location, cause, Set.of(flags)); + this.server.getPluginManager().callEvent(playerPrepareTeleportEvent); + // Paper end - Add PlayerPrepareTeleportEvent + // Minecraft does not currently support teleporting players between worlds with passengers. // It causes them to be dismounted, and causes weird behavior. if (location.getWorld() != this.getWorld() && this.getHandle().isVehicle()) { From 374c1950b2240981a090181e633f671bb0cd3123 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 13 Aug 2026 17:18:04 +0300 Subject: [PATCH 2/2] Added PlayerPrepareTeleportEvent overloads --- .../player/PlayerPrepareTeleportEvent.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java index 77adcc73882b..6c14fa51bd9e 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPrepareTeleportEvent.java @@ -1,6 +1,7 @@ package io.papermc.paper.event.player; import io.papermc.paper.entity.TeleportFlag; +import java.util.Collections; import java.util.Set; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -25,6 +26,22 @@ public class PlayerPrepareTeleportEvent extends PlayerEvent { private final PlayerTeleportEvent.TeleportCause cause; private final Set teleportFlags; + @ApiStatus.Internal + public PlayerPrepareTeleportEvent(final Player player, Location to) { + super(player); + this.to = to; + this.cause = PlayerTeleportEvent.TeleportCause.PLUGIN; + this.teleportFlags = Collections.emptySet(); + } + + @ApiStatus.Internal + public PlayerPrepareTeleportEvent(final Player player, Location to, PlayerTeleportEvent.TeleportCause cause) { + super(player); + this.to = to; + this.cause = cause; + this.teleportFlags = Collections.emptySet(); + } + @ApiStatus.Internal public PlayerPrepareTeleportEvent(final Player player, Location to, PlayerTeleportEvent.TeleportCause cause, Set teleportFlags) { super(player);