mirror of
https://github.com/essentials/Essentials.git
synced 2025-10-01 16:46:51 +02:00
Essentials API cleanup and teleport possession fixing. (UNSTABLE)
This commit is contained in:
@@ -10,12 +10,9 @@ import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
|
||||
public class Teleport implements Runnable, ITeleport
|
||||
public class Teleport implements ITeleport
|
||||
{
|
||||
private static final double MOVE_CONSTANT = 0.3;
|
||||
|
||||
|
||||
private class Target
|
||||
public class Target
|
||||
{
|
||||
private final Location location;
|
||||
private final String name;
|
||||
@@ -42,155 +39,40 @@ public class Teleport implements Runnable, ITeleport
|
||||
return location;
|
||||
}
|
||||
}
|
||||
private final IUser user;
|
||||
private String teleportUserName;
|
||||
private int teleTimer = -1;
|
||||
private long started; // time this task was initiated
|
||||
private long tpdelay; // how long to delay the teleport
|
||||
private int health;
|
||||
// note that I initially stored a clone of the location for reference, but...
|
||||
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
|
||||
// so, the X/Y/Z values are stored instead and rounded off
|
||||
private long initX;
|
||||
private long initY;
|
||||
private long initZ;
|
||||
private Target teleportTarget;
|
||||
private boolean respawn;
|
||||
private boolean canMove;
|
||||
private Trade chargeFor;
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
private TeleportCause cause;
|
||||
|
||||
private void initTimer(long delay, Target target, Trade chargeFor, TeleportCause cause)
|
||||
{
|
||||
initTimer(delay, user, target, chargeFor, cause, false);
|
||||
}
|
||||
|
||||
private void initTimer(long delay, IUser teleportUser, Target target, Trade chargeFor, TeleportCause cause, boolean respawn)
|
||||
{
|
||||
this.started = System.currentTimeMillis();
|
||||
this.tpdelay = delay;
|
||||
this.health = teleportUser.getHealth();
|
||||
this.initX = Math.round(teleportUser.getLocation().getX() * MOVE_CONSTANT);
|
||||
this.initY = Math.round(teleportUser.getLocation().getY() * MOVE_CONSTANT);
|
||||
this.initZ = Math.round(teleportUser.getLocation().getZ() * MOVE_CONSTANT);
|
||||
this.teleportUserName = teleportUser.getName();
|
||||
this.teleportTarget = target;
|
||||
this.chargeFor = chargeFor;
|
||||
this.cause = cause;
|
||||
this.respawn = respawn;
|
||||
|
||||
this.canMove = user.isAuthorized("essentials.teleport.timer.move");
|
||||
|
||||
teleTimer = ess.scheduleSyncRepeatingTask(this, 20, 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
||||
if (user == null || !user.isOnline() || user.getLocation() == null)
|
||||
{
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
IUser teleportUser = ess.getUser(this.teleportUserName);
|
||||
|
||||
if (teleportUser == null || !teleportUser.isOnline())
|
||||
{
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final Location currLocation = teleportUser.getLocation();
|
||||
if (currLocation == null)
|
||||
{
|
||||
cancel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canMove
|
||||
&& (Math.round(currLocation.getX() * MOVE_CONSTANT) != initX
|
||||
|| Math.round(currLocation.getY() * MOVE_CONSTANT) != initY
|
||||
|| Math.round(currLocation.getZ() * MOVE_CONSTANT) != initZ
|
||||
|| teleportUser.getHealth() < health))
|
||||
{
|
||||
// user moved, cancel teleport
|
||||
cancel(true);
|
||||
return;
|
||||
}
|
||||
|
||||
health = teleportUser.getHealth(); // in case user healed, then later gets injured
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now > started + tpdelay)
|
||||
{
|
||||
try
|
||||
{
|
||||
cooldown(false);
|
||||
teleportUser.sendMessage(_("teleportationCommencing"));
|
||||
try
|
||||
{
|
||||
if (respawn)
|
||||
{
|
||||
teleportUser.getTeleport().respawn(cause);
|
||||
}
|
||||
else
|
||||
{
|
||||
teleportUser.getTeleport().now(teleportTarget, cause);
|
||||
}
|
||||
cancel(false);
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.charge(user);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
ess.showError(user.getBase(), ex, "teleport");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
user.sendMessage(_("cooldownWithMessage", ex.getMessage()));
|
||||
if (user != teleportUser)
|
||||
{
|
||||
teleportUser.sendMessage(_("cooldownWithMessage", ex.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private TimedTeleport timedTeleport;
|
||||
|
||||
public Teleport(IUser user, IEssentials ess)
|
||||
{
|
||||
this.user = user;
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
public void cooldown(boolean check) throws Exception
|
||||
{
|
||||
final Calendar time = new GregorianCalendar();
|
||||
if (user.getLastTeleportTimestamp() > 0)
|
||||
if (teleportOwner.getLastTeleportTimestamp() > 0)
|
||||
{
|
||||
// Take the current time, and remove the delay from it.
|
||||
final double cooldown = ess.getSettings().getTeleportCooldown();
|
||||
final Calendar earliestTime = new GregorianCalendar();
|
||||
earliestTime.add(Calendar.SECOND, -(int)cooldown);
|
||||
earliestTime.add(Calendar.MILLISECOND, -(int)((cooldown * 1000.0) % 1000.0));
|
||||
// This value contains the most recent time a teleport could have been used that would allow another use.
|
||||
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
|
||||
final long earliestLong = earliestTime.getTimeInMillis();
|
||||
|
||||
// When was the last teleport used?
|
||||
final Long lastTime = user.getLastTeleportTimestamp();
|
||||
// When was the last teleportPlayer used?
|
||||
final Long lastTime = teleportOwner.getLastTeleportTimestamp();
|
||||
|
||||
if (lastTime > time.getTimeInMillis())
|
||||
{
|
||||
// This is to make sure time didn't get messed up on last kit use.
|
||||
// This is to make sure time didn't get messed up on last teleportPlayer use.
|
||||
// If this happens, let's give the user the benifit of the doubt.
|
||||
user.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
return;
|
||||
}
|
||||
else if (lastTime > earliestLong && !user.isAuthorized("essentials.teleport.cooldown.bypass"))
|
||||
else if (lastTime > earliestLong && !teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass"))
|
||||
{
|
||||
time.setTimeInMillis(lastTime);
|
||||
time.add(Calendar.SECOND, (int)cooldown);
|
||||
@@ -201,132 +83,10 @@ public class Teleport implements Runnable, ITeleport
|
||||
// if justCheck is set, don't update lastTeleport; we're just checking
|
||||
if (!check)
|
||||
{
|
||||
user.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
}
|
||||
}
|
||||
|
||||
//If we need to cancel a pending teleport call this method
|
||||
public void cancel(boolean notifyUser)
|
||||
{
|
||||
if (teleTimer == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
ess.getServer().getScheduler().cancelTask(teleTimer);
|
||||
if (notifyUser)
|
||||
{
|
||||
user.sendMessage(_("pendingTeleportCancelled"));
|
||||
if (teleportUserName != null && !teleportUserName.equals(user.getName()))
|
||||
{
|
||||
ess.getUser(teleportUserName).sendMessage(_("pendingTeleportCancelled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
teleTimer = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
|
||||
@Override
|
||||
public void now(Location loc, boolean cooldown, TeleportCause cause) throws Exception
|
||||
{
|
||||
if (cooldown)
|
||||
{
|
||||
cooldown(false);
|
||||
}
|
||||
now(new Target(loc), cause);
|
||||
}
|
||||
|
||||
public void now(Player entity, boolean cooldown, TeleportCause cause) throws Exception
|
||||
{
|
||||
if (cooldown)
|
||||
{
|
||||
cooldown(false);
|
||||
}
|
||||
now(new Target(entity), cause);
|
||||
}
|
||||
|
||||
private void now(Target target, TeleportCause cause) throws Exception
|
||||
{
|
||||
cancel(false);
|
||||
user.setLastLocation();
|
||||
user.getBase().teleport(Util.getSafeDestination(target.getLocation()), cause);
|
||||
}
|
||||
|
||||
//The teleport function is used when you want to normally teleport someone to a location or player.
|
||||
//This method is nolonger used internally and will be removed.
|
||||
@Deprecated
|
||||
public void teleport(Location loc, Trade chargeFor) throws Exception
|
||||
{
|
||||
teleport(loc, chargeFor, TeleportCause.PLUGIN);
|
||||
}
|
||||
|
||||
public void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
teleport(new Target(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
public void teleport(Player entity, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
teleport(new Target(entity), chargeFor, cause);
|
||||
}
|
||||
|
||||
private void teleport(Target target, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.isAffordableFor(user);
|
||||
}
|
||||
cooldown(true);
|
||||
if (delay <= 0 || user.isAuthorized("essentials.teleport.timer.bypass"))
|
||||
{
|
||||
cooldown(false);
|
||||
now(target, cause);
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.charge(user);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(user, delay);
|
||||
initTimer((long)(delay * 1000.0), target, chargeFor, cause);
|
||||
}
|
||||
|
||||
//The teleportToMe function is a wrapper used to handle teleporting players to them, like /tphere
|
||||
public void teleportToMe(User otherUser, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
Target target = new Target(user);
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.isAffordableFor(user);
|
||||
}
|
||||
cooldown(true);
|
||||
if (delay <= 0 || user.isAuthorized("essentials.teleport.timer.bypass"))
|
||||
{
|
||||
cooldown(false);
|
||||
otherUser.getTeleport().now(target, cause);
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.charge(user);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(otherUser, delay);
|
||||
initTimer((long)(delay * 1000.0), otherUser, target, chargeFor, cause, false);
|
||||
}
|
||||
|
||||
private void warnUser(final IUser user, final double delay)
|
||||
{
|
||||
Calendar c = new GregorianCalendar();
|
||||
@@ -335,38 +95,133 @@ public class Teleport implements Runnable, ITeleport
|
||||
user.sendMessage(_("dontMoveMessage", Util.formatDateDiff(c.getTimeInMillis())));
|
||||
}
|
||||
|
||||
//The respawn function is a wrapper used to handle tp fallback, on /jail and /home
|
||||
public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception
|
||||
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
|
||||
@Override
|
||||
public void now(Location loc, boolean cooldown, TeleportCause cause) throws Exception
|
||||
{
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.isAffordableFor(user);
|
||||
}
|
||||
cooldown(true);
|
||||
if (delay <= 0 || user.isAuthorized("essentials.teleport.timer.bypass"))
|
||||
if (cooldown)
|
||||
{
|
||||
cooldown(false);
|
||||
respawn(cause);
|
||||
}
|
||||
now(teleportOwner, new Target(loc), cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void now(Player entity, boolean cooldown, TeleportCause cause) throws Exception
|
||||
{
|
||||
if (cooldown)
|
||||
{
|
||||
cooldown(false);
|
||||
}
|
||||
now(teleportOwner, new Target(entity), cause);
|
||||
}
|
||||
|
||||
protected void now(IUser teleportee, Target target, TeleportCause cause) throws Exception
|
||||
{
|
||||
cancel(false);
|
||||
teleportee.setLastLocation();
|
||||
teleportee.getBase().teleport(Util.getSafeDestination(target.getLocation()), cause);
|
||||
}
|
||||
|
||||
//The teleportPlayer function is used when you want to normally teleportPlayer someone to a location or player.
|
||||
//This method is nolonger used internally and will be removed.
|
||||
@Deprecated
|
||||
public void teleport(Location loc, Trade chargeFor) throws Exception
|
||||
{
|
||||
teleport(loc, chargeFor, TeleportCause.PLUGIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
teleport(teleportOwner, new Target(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Player entity, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
teleport(teleportOwner, new Target(entity), chargeFor, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleportPlayer(IUser teleportee, Location loc, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
teleport(teleportee, new Target(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleportPlayer(IUser teleportee, Player entity, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
teleport(teleportee, new Target(entity), chargeFor, cause);
|
||||
}
|
||||
|
||||
private void teleport(IUser teleportee, Target target, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
cooldown(true);
|
||||
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportee.isAuthorized("essentials.teleport.timer.bypass"))
|
||||
{
|
||||
cooldown(false);
|
||||
now(teleportee, target, cause);
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.charge(user);
|
||||
chargeFor.charge(teleportOwner);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(user, delay);
|
||||
initTimer((long)(delay * 1000.0), user, null, chargeFor, cause, true);
|
||||
warnUser(teleportee, delay);
|
||||
initTimer((long)(delay * 1000.0), teleportee, target, chargeFor, cause, false);
|
||||
}
|
||||
|
||||
public void respawn(TeleportCause cause) throws Exception
|
||||
//The teleportToMe function is a wrapper used to handle teleporting players to them, like /tphere
|
||||
@Override
|
||||
public void teleportToMe(IUser otherUser, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
final Player player = user.getBase();
|
||||
Target target = new Target(teleportOwner);
|
||||
teleport(otherUser, target, chargeFor, cause);
|
||||
}
|
||||
|
||||
//The respawn function is a wrapper used to handle tp fallback, on /jail and /home
|
||||
@Override
|
||||
public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
cooldown(true);
|
||||
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass"))
|
||||
{
|
||||
cooldown(false);
|
||||
respawnNow(teleportOwner, cause);
|
||||
if (chargeFor != null)
|
||||
{
|
||||
chargeFor.charge(teleportOwner);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportOwner, delay);
|
||||
initTimer((long)(delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
|
||||
}
|
||||
|
||||
protected void respawnNow(IUser teleportee, TeleportCause cause) throws Exception
|
||||
{
|
||||
final Player player = teleportee.getBase();
|
||||
Location bed = player.getBedSpawnLocation();
|
||||
if (bed != null)
|
||||
{
|
||||
now(new Target(bed), cause);
|
||||
now(teleportee, new Target(bed), cause);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -376,33 +231,52 @@ public class Teleport implements Runnable, ITeleport
|
||||
}
|
||||
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
|
||||
ess.getServer().getPluginManager().callEvent(pre);
|
||||
now(new Target(pre.getRespawnLocation()), cause);
|
||||
now(teleportee, new Target(pre.getRespawnLocation()), cause);
|
||||
}
|
||||
}
|
||||
|
||||
//The warp function is a wrapper used to teleport a player to a /warp
|
||||
public void warp(String warp, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
//The warp function is a wrapper used to teleportPlayer a player to a /warp
|
||||
@Override
|
||||
public void warp(IUser teleportee, String warp, Trade chargeFor, TeleportCause cause) throws Exception
|
||||
{
|
||||
Location loc = ess.getWarps().getWarp(warp);
|
||||
user.sendMessage(_("warpingTo", warp));
|
||||
teleport(new Target(loc), chargeFor, cause);
|
||||
teleportee.sendMessage(_("warpingTo", warp));
|
||||
teleport(teleportee, new Target(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
//The back function is a wrapper used to teleport a player /back to their previous location.
|
||||
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
|
||||
@Override
|
||||
public void back(Trade chargeFor) throws Exception
|
||||
{
|
||||
teleport(new Target(user.getLastLocation()), chargeFor, TeleportCause.COMMAND);
|
||||
teleport(teleportOwner, new Target(teleportOwner.getLastLocation()), chargeFor, TeleportCause.COMMAND);
|
||||
}
|
||||
|
||||
//This function is used to throw a user back after a jail sentence
|
||||
@Override
|
||||
public void back() throws Exception
|
||||
{
|
||||
now(new Target(user.getLastLocation()), TeleportCause.COMMAND);
|
||||
now(teleportOwner, new Target(teleportOwner.getLastLocation()), TeleportCause.COMMAND);
|
||||
}
|
||||
|
||||
//This function handles teleporting to /home
|
||||
@Override
|
||||
public void home(Location loc, Trade chargeFor) throws Exception
|
||||
{
|
||||
teleport(new Target(loc), chargeFor, TeleportCause.COMMAND);
|
||||
teleport(teleportOwner, new Target(loc), chargeFor, TeleportCause.COMMAND);
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
private void cancel(boolean notifyUser)
|
||||
{
|
||||
if (timedTeleport != null)
|
||||
{
|
||||
timedTeleport.cancelTimer(notifyUser);
|
||||
timedTeleport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimer(long delay, IUser teleportUser, Target target, Trade chargeFor, TeleportCause cause, boolean respawn)
|
||||
{
|
||||
timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user