diff --git a/src/me/ryanhamshire/GriefPrevention/CheckForPortalTrapTask.java b/src/me/ryanhamshire/GriefPrevention/CheckForPortalTrapTask.java index 7cc030a..885dd2b 100644 --- a/src/me/ryanhamshire/GriefPrevention/CheckForPortalTrapTask.java +++ b/src/me/ryanhamshire/GriefPrevention/CheckForPortalTrapTask.java @@ -36,19 +36,25 @@ class CheckForPortalTrapTask implements Runnable public CheckForPortalTrapTask(Player player, Location location) { this.player = player; - this.returnLocation = location; + this.returnLocation = location; } @Override public void run() { - //if player has logged out, do nothing - if(!this.player.isOnline()) return; + //if player has logged out, do nothing + if(!player.isOnline()) return; - //otherwise if still standing in a portal frame, teleport him back through + //if still standing in a portal frame, teleport him back through if(this.player.getLocation().getBlock().getType() == Material.PORTAL) { this.player.teleport(this.returnLocation); } + + //otherwise, note that he 'escaped' the portal frame + else + { + PlayerEventHandler.portalReturnMap.remove(player.getUniqueId()); + } } } diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerData.java b/src/me/ryanhamshire/GriefPrevention/PlayerData.java index 218970c..59551b4 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerData.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerData.java @@ -146,7 +146,7 @@ public class PlayerData //true when the player's IP address was counted against the re-use limit when he joined boolean ipLimited = false; - + //whether or not this player is "in" pvp combat public boolean inPvpCombat() { diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index 308289e..ce21e6f 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -893,6 +893,17 @@ class PlayerEventHandler implements Listener //create a thread to load ignore information new IgnoreLoaderThread(playerID, playerData.ignoredPlayers).start(); + + //is he possibly stuck in a portal frame? + Location returnLocation = PlayerEventHandler.portalReturnMap.get(player.getUniqueId()); + if(returnLocation != null) + { + PlayerEventHandler.portalReturnMap.remove(player.getUniqueId()); + if(player.getLocation().getBlock().getType() == Material.PORTAL) + { + player.teleport(returnLocation); + } + } } //when a player spawns, conditionally apply temporary pvp protection @@ -1075,6 +1086,9 @@ class PlayerEventHandler implements Listener } } + //remember where players teleport from (via portals) in case they're trapped at the destination + static ConcurrentHashMap portalReturnMap = new ConcurrentHashMap(); + //when a player teleports via a portal @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) void onPlayerPortal(PlayerPortalEvent event) @@ -1092,6 +1106,7 @@ class PlayerEventHandler implements Listener //FEATURE: when players get trapped in a nether portal, send them back through to the other side CheckForPortalTrapTask task = new CheckForPortalTrapTask(player, event.getFrom()); GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 200L); + portalReturnMap.put(player.getUniqueId(), event.getFrom()); //FEATURE: if the player teleporting doesn't have permission to build a nether portal and none already exists at the destination, cancel the teleportation if(GriefPrevention.instance.config_claims_portalsRequirePermission) @@ -1102,6 +1117,7 @@ class PlayerEventHandler implements Listener if(event.getPortalTravelAgent().getCanCreatePortal()) { //hypothetically find where the portal would be created if it were + //this is VERY expensive for the cpu, so this feature is off by default TravelAgent agent = event.getPortalTravelAgent(); agent.setCanCreatePortal(false); destination = agent.findOrCreate(destination);