From a92ca63ca9da45641e0e534eb101c0ffaf0e94e2 Mon Sep 17 00:00:00 2001 From: MD <1917406+md678685@users.noreply.github.com> Date: Wed, 8 Jul 2020 19:51:00 +0100 Subject: [PATCH] Replace UserTeleportEvent with more sane events (#3192) This PR replaces UserTeleportEvent with two new teleport events called at different stages: - TeleportWarmupEvent; called before a user's teleport warmup begins and allows plugins to skip it or prevent a teleportation - PreTeleportEvent; called after the warmup completes but before any safety checks are carried out This is a **breaking change** as it removes UserTeleportEvent, but the previous event isn't useful or descriptive in its current form and was only recently introduced, so it's unlikely that many plugins already depend on this. Closes #2506. --- .../earth2me/essentials/AsyncTeleport.java | 27 +++++++- .../src/com/earth2me/essentials/Teleport.java | 27 +++++++- .../ess3/api/events/UserTeleportEvent.java | 58 ---------------- .../api/events/teleport/PreTeleportEvent.java | 31 +++++++++ .../api/events/teleport/TeleportEvent.java | 67 +++++++++++++++++++ .../events/teleport/TeleportWarmupEvent.java | 52 ++++++++++++++ 6 files changed, 200 insertions(+), 62 deletions(-) delete mode 100644 Essentials/src/net/ess3/api/events/UserTeleportEvent.java create mode 100644 Essentials/src/net/ess3/api/events/teleport/PreTeleportEvent.java create mode 100644 Essentials/src/net/ess3/api/events/teleport/TeleportEvent.java create mode 100644 Essentials/src/net/ess3/api/events/teleport/TeleportWarmupEvent.java diff --git a/Essentials/src/com/earth2me/essentials/AsyncTeleport.java b/Essentials/src/com/earth2me/essentials/AsyncTeleport.java index 8d3acaf09..43cf1dd8d 100644 --- a/Essentials/src/com/earth2me/essentials/AsyncTeleport.java +++ b/Essentials/src/com/earth2me/essentials/AsyncTeleport.java @@ -8,8 +8,9 @@ import io.papermc.lib.PaperLib; import net.ess3.api.IEssentials; import net.ess3.api.IUser; import net.ess3.api.InvalidWorldException; -import net.ess3.api.events.UserTeleportEvent; import net.ess3.api.events.UserWarpEvent; +import net.ess3.api.events.teleport.PreTeleportEvent; +import net.ess3.api.events.teleport.TeleportWarmupEvent; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -157,7 +158,7 @@ public class AsyncTeleport implements IAsyncTeleport { protected void nowAsync(IUser teleportee, ITarget target, TeleportCause cause, CompletableFuture future) { cancel(false); - UserTeleportEvent event = new UserTeleportEvent(teleportee, cause, target.getLocation()); + PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; @@ -245,6 +246,13 @@ public class AsyncTeleport implements IAsyncTeleport { private void teleport(IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause, CompletableFuture future) { double delay = ess.getSettings().getTeleportDelay(); + TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + delay = event.getDelay(); + Trade cashCharge = chargeFor; if (chargeFor != null) { @@ -285,6 +293,13 @@ public class AsyncTeleport implements IAsyncTeleport { private void teleportOther(IUser teleporter, IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause, CompletableFuture future) { double delay = ess.getSettings().getTeleportDelay(); + TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + delay = event.getDelay(); + Trade cashCharge = chargeFor; if (teleporter != null && chargeFor != null) { @@ -329,6 +344,14 @@ public class AsyncTeleport implements IAsyncTeleport { @Override public void respawn(Trade chargeFor, TeleportCause cause, CompletableFuture future) { double delay = ess.getSettings().getTeleportDelay(); + + TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + delay = event.getDelay(); + if (chargeFor != null) { chargeFor.isAffordableFor(teleportOwner, future); if (future.isCompletedExceptionally()) { diff --git a/Essentials/src/com/earth2me/essentials/Teleport.java b/Essentials/src/com/earth2me/essentials/Teleport.java index d458c140f..0400f8201 100644 --- a/Essentials/src/com/earth2me/essentials/Teleport.java +++ b/Essentials/src/com/earth2me/essentials/Teleport.java @@ -6,8 +6,9 @@ import io.papermc.lib.PaperLib; import net.ess3.api.IEssentials; import net.ess3.api.ITeleport; import net.ess3.api.IUser; -import net.ess3.api.events.UserTeleportEvent; import net.ess3.api.events.UserWarpEvent; +import net.ess3.api.events.teleport.PreTeleportEvent; +import net.ess3.api.events.teleport.TeleportWarmupEvent; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -134,7 +135,7 @@ public class Teleport implements ITeleport { cancel(false); Location loc = target.getLocation(); - UserTeleportEvent event = new UserTeleportEvent(teleportee, cause, loc); + PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; @@ -217,6 +218,13 @@ public class Teleport implements ITeleport { private void teleport(IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception { double delay = ess.getSettings().getTeleportDelay(); + TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + delay = event.getDelay(); + Trade cashCharge = chargeFor; if (chargeFor != null) { @@ -248,6 +256,13 @@ public class Teleport implements ITeleport { private void teleportOther(IUser teleporter, IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception { double delay = ess.getSettings().getTeleportDelay(); + TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + delay = event.getDelay(); + Trade cashCharge = chargeFor; if (teleporter != null && chargeFor != null) { @@ -283,6 +298,14 @@ public class Teleport implements ITeleport { @Deprecated public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception { double delay = ess.getSettings().getTeleportDelay(); + + TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + delay = event.getDelay(); + if (chargeFor != null) { chargeFor.isAffordableFor(teleportOwner); } diff --git a/Essentials/src/net/ess3/api/events/UserTeleportEvent.java b/Essentials/src/net/ess3/api/events/UserTeleportEvent.java deleted file mode 100644 index cd9ae33de..000000000 --- a/Essentials/src/net/ess3/api/events/UserTeleportEvent.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.ess3.api.events; - -import net.ess3.api.IUser; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; -/** - * Called when the player teleports - */ -public class UserTeleportEvent extends Event implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - - private IUser user; - private TeleportCause cause; - private Location target; - private boolean cancelled = false; - - public UserTeleportEvent(IUser user, TeleportCause cause, Location target) { - super(!Bukkit.isPrimaryThread()); - this.user = user; - this.cause = cause; - this.target = target; - } - - public IUser getUser() { - return user; - } - - public TeleportCause getTeleportCause() { - return cause; - } - - public Location getLocation() { - return target; - } - - @Override - public boolean isCancelled() { - return cancelled; - } - - @Override - public void setCancelled(boolean b) { - cancelled = b; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/Essentials/src/net/ess3/api/events/teleport/PreTeleportEvent.java b/Essentials/src/net/ess3/api/events/teleport/PreTeleportEvent.java new file mode 100644 index 000000000..357c20119 --- /dev/null +++ b/Essentials/src/net/ess3/api/events/teleport/PreTeleportEvent.java @@ -0,0 +1,31 @@ +package net.ess3.api.events.teleport; + +import com.earth2me.essentials.ITarget; +import net.ess3.api.IUser; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerTeleportEvent; + +/** + * Called before a player is teleported. + *

+ * Note that this is called after any warmup has been performed but before teleport safety checks are performed. + * Cancelling this event will cancel the teleport without warning the user. + */ +public class PreTeleportEvent extends TeleportEvent { + + private static final HandlerList handlers = new HandlerList(); + + public PreTeleportEvent(IUser teleportee, PlayerTeleportEvent.TeleportCause cause, ITarget target) { + super(teleportee, cause, target); + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + +} diff --git a/Essentials/src/net/ess3/api/events/teleport/TeleportEvent.java b/Essentials/src/net/ess3/api/events/teleport/TeleportEvent.java new file mode 100644 index 000000000..761a1a6e2 --- /dev/null +++ b/Essentials/src/net/ess3/api/events/teleport/TeleportEvent.java @@ -0,0 +1,67 @@ +package net.ess3.api.events.teleport; + +import com.earth2me.essentials.ITarget; +import net.ess3.api.IUser; +import org.bukkit.Bukkit; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerTeleportEvent; + +public abstract class TeleportEvent extends Event implements Cancellable { + + private final IUser teleporter; + private final IUser teleportee; + private final PlayerTeleportEvent.TeleportCause cause; + private final ITarget target; + private boolean cancelled = false; + + TeleportEvent(IUser teleporter, IUser teleportee, PlayerTeleportEvent.TeleportCause cause, ITarget target) { + super(!Bukkit.isPrimaryThread()); + this.teleporter = teleporter; + this.teleportee = teleportee; + this.cause = cause; + this.target = target; + } + + TeleportEvent(IUser teleportee, PlayerTeleportEvent.TeleportCause cause, ITarget target) { + this(teleportee, teleportee, cause, target); + } + + /** + * @return The user that initiated the teleportation, or null if unknown + */ + public IUser getTeleporter() { + return teleporter; + } + + /** + * @return The user to be teleported + */ + public IUser getTeleportee() { + return teleportee; + } + + /** + * @return The reason for teleportation + */ + public PlayerTeleportEvent.TeleportCause getTeleportCause() { + return cause; + } + + /** + * @return The target to teleport to, or null if unknown at this stage (such as a forced respawn) + */ + public ITarget getTarget() { + return target; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + cancelled = b; + } +} diff --git a/Essentials/src/net/ess3/api/events/teleport/TeleportWarmupEvent.java b/Essentials/src/net/ess3/api/events/teleport/TeleportWarmupEvent.java new file mode 100644 index 000000000..92f60992c --- /dev/null +++ b/Essentials/src/net/ess3/api/events/teleport/TeleportWarmupEvent.java @@ -0,0 +1,52 @@ +package net.ess3.api.events.teleport; + +import com.earth2me.essentials.ITarget; +import net.ess3.api.IUser; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerTeleportEvent; + +/** + * Called when a command starts a player's teleport warmup. + *

+ * Cancelling this event will prevent the user from teleporting, and any previously pending teleport will commence rather than being cancelled. + * To skip the warmup delay, see {@link #setDelay(double)}. + */ +public class TeleportWarmupEvent extends TeleportEvent { + + private static final HandlerList handlers = new HandlerList(); + + private double delay; + + public TeleportWarmupEvent(IUser teleporter, IUser teleportee, PlayerTeleportEvent.TeleportCause cause, ITarget target, double delay) { + super(teleporter, teleportee, cause, target); + this.delay = delay; + } + + public TeleportWarmupEvent(IUser teleportee, PlayerTeleportEvent.TeleportCause cause, ITarget target, double delay) { + super(teleportee, cause, target); + this.delay = delay; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + /** + * @return The warmup delay, in seconds. + */ + public double getDelay() { + return delay; + } + + /** + * @param delay The warmup delay, in seconds. Set this to 0 to skip the warmup delay. + */ + public void setDelay(double delay) { + this.delay = delay; + } +}