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.
This commit is contained in:
MD 2020-07-08 19:51:00 +01:00 committed by GitHub
parent cbfad7b320
commit a92ca63ca9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 200 additions and 62 deletions

View File

@ -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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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()) {

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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.
* <p>
* 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;
}
}

View File

@ -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;
}
}

View File

@ -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.
* <p>
* 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;
}
}