Correcting earlier misconception. This new check routine keeps up the exemption until the players location is updated to something other then the FROM location of the portal event. The minecraft bug is that the from location dominates even in the new world, and only after a delay (which can last for, in some cases, a second or more) is the players location updated to the portal event TO location. This check adapts for that, maintaining an exemption until the players location is updated to something other then the portal event FROM location, or the check period ends.

This commit is contained in:
Daniel Boston 2016-06-16 22:25:08 -04:00
parent 116718e1a2
commit bc36bcbee3
2 changed files with 11 additions and 10 deletions

View File

@ -48,7 +48,8 @@ public class BorderCheckTask implements Runnable
* In 1.9, there is a significant delay between teleportation event and when the player's location is actually updated.
* However, the player world is updated immediately. This disconnection causes the regular checkPlayer to
* incorrectly test the player's prior-world location against the new-world location during that amorphous
* in-between period.
* in-between period. Basically, this checks for the location to actually update, e.g. to be different from the
* "from" location of the portal event.
*
* This function allows a configurable recheck to let Minecraft "catch up" the player's <i>real</i> location.
*
@ -59,11 +60,11 @@ public class BorderCheckTask implements Runnable
* this check gracefully.
*
* @param player The player who is being exempted.
* @param world The world the player is supposedly now in.
* @param prior the location the player has come from
* @param maxDelay The <i>maximum</i> ticks to spend exempting this player
* @param recheckDelay The ticks to wait inbetween rechecks.
*/
public static void timedPlayerExemption(final Player player, final String world, final long maxDelay, final long recheckDelay) {
public static void timedPlayerExemption(final Player player, final Location prior, final long maxDelay, final long recheckDelay) {
// Check for existing watch; cancel if one exists.
BukkitRunnable alreadyWatching = handlingPlayers.get(player.getName().toLowerCase());
@ -100,9 +101,9 @@ public class BorderCheckTask implements Runnable
}
// Are we still stuck between worlds?
Location loc = player.getLocation();
World worldObj = loc.getWorld();
if (world.equals(worldObj.getName())) {
Location current = player.getLocation();
if (current.getBlockX() != prior.getBlockX() && current.getBlockY() != prior.getBlockY() &&
current.getBlockZ() != prior.getBlockZ()) {
// No, we made it!
this.cancel();
handlingPlayers.remove(playerName);
@ -112,9 +113,9 @@ public class BorderCheckTask implements Runnable
}
if (Config.Debug()) {
Config.log("Based on teleport " + playerName + " is in " + world +
" but Minecraft still thinks they are in " + worldObj.getName() +
". Checking again in " + recheckDelay);
Config.log("Based on teleport " + playerName +
" has moved, but Minecraft still has them at old location " +
prior.toString() + ". Checking again in " + recheckDelay);
}
}
};

View File

@ -52,7 +52,7 @@ public class WBListener implements Listener
event.setTo(newLoc);
}
BorderCheckTask.timedPlayerExemption(event.getPlayer(), event.getTo().getWorld().getName(),
BorderCheckTask.timedPlayerExemption(event.getPlayer(), event.getFrom().clone(),
Config.getMaxExemptionTicks(), Config.getPortalRecheckTicks());
}