Finished implementing new portal trap improvements #13
Probably will need some testing though
This commit is contained in:
parent
8e7af23a13
commit
a2c9242adc
|
|
@ -30,36 +30,28 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||||
//if that happens, we detect the problem and send them back through the portal.
|
//if that happens, we detect the problem and send them back through the portal.
|
||||||
class CheckForPortalTrapTask extends BukkitRunnable
|
class CheckForPortalTrapTask extends BukkitRunnable
|
||||||
{
|
{
|
||||||
|
GriefPrevention instance;
|
||||||
//player who recently teleported via nether portal
|
//player who recently teleported via nether portal
|
||||||
private Player player;
|
private Player player;
|
||||||
|
|
||||||
//where to send the player back to if he hasn't left the portal frame
|
//where to send the player back to if he hasn't left the portal frame
|
||||||
private Location returnLocation;
|
//private Location returnLocation;
|
||||||
|
|
||||||
public CheckForPortalTrapTask(Player player, Location location)
|
public CheckForPortalTrapTask(Player player, GriefPrevention plugin)
|
||||||
{
|
{
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.returnLocation = location;
|
this.instance = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
//if player has logged out, do nothing
|
//if player has logged out, do nothing
|
||||||
if(!player.isOnline()) return;
|
if(!player.isOnline())
|
||||||
|
|
||||||
Block playerBlock = this.player.getLocation().getBlock();
|
|
||||||
//if still standing in a portal frame, teleport him back through
|
|
||||||
if(GriefPrevention.instance.isPlayerTrappedInPortal(playerBlock))
|
|
||||||
{
|
{
|
||||||
GriefPrevention.instance.rescuePlayerTrappedInPortal(player, returnLocation);
|
instance.portalReturnTaskMap.remove(player.getUniqueId());
|
||||||
}
|
return;
|
||||||
|
|
||||||
//otherwise, note that he 'escaped' the portal frame
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PlayerEventHandler.portalReturnMap.remove(player.getUniqueId());
|
|
||||||
PlayerEventHandler.portalReturnTaskMap.remove(player.getUniqueId());
|
|
||||||
}
|
}
|
||||||
|
instance.rescuePlayerTrappedInPortal(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ import org.bukkit.inventory.PlayerInventory;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
import org.bukkit.util.BlockIterator;
|
import org.bukkit.util.BlockIterator;
|
||||||
|
|
||||||
public class GriefPrevention extends JavaPlugin
|
public class GriefPrevention extends JavaPlugin
|
||||||
|
|
@ -2729,6 +2731,21 @@ public class GriefPrevention extends JavaPlugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(cmd.getName().equalsIgnoreCase("undorescue"))
|
||||||
|
{
|
||||||
|
Location location = dataStore.getPlayerData(player.getUniqueId()).portalTrappedLocation;
|
||||||
|
if (location == null)
|
||||||
|
{
|
||||||
|
//TODO: tell player they were not initially rescued (if necessary?)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//Start a new rescue task in case the player was indeed trapped, but dumbly sent the command anyway
|
||||||
|
startRescueTask(player, player.getLocation());
|
||||||
|
player.teleport(location);
|
||||||
|
dataStore.getPlayerData(player.getUniqueId()).portalTrappedLocation = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3613,11 +3630,50 @@ public class GriefPrevention extends JavaPlugin
|
||||||
|| block.getRelative(BlockFace.SOUTH).getType() == Material.PORTAL;
|
|| block.getRelative(BlockFace.SOUTH).getType() == Material.PORTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location rescuePlayerTrappedInPortal(Player player, Location returnLocation)
|
public void rescuePlayerTrappedInPortal(final Player player)
|
||||||
{
|
{
|
||||||
Location oldLocation = player.getLocation();
|
final Location oldLocation = player.getLocation();
|
||||||
player.teleport(returnLocation);
|
if (!isPlayerTrappedInPortal(oldLocation.getBlock()))
|
||||||
|
{
|
||||||
|
//Note that he 'escaped' the portal frame
|
||||||
|
instance.portalReturnMap.remove(player.getUniqueId());
|
||||||
|
instance.portalReturnTaskMap.remove(player.getUniqueId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Location rescueLocation = portalReturnMap.get(player.getUniqueId());
|
||||||
|
|
||||||
|
if (rescueLocation == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Temporarily store the old location, in case the player wishes to undo the rescue
|
||||||
|
dataStore.getPlayerData(player.getUniqueId()).portalTrappedLocation = oldLocation;
|
||||||
|
|
||||||
|
player.teleport(rescueLocation);
|
||||||
sendMessage(player, TextMode.Info, Messages.RescuedFromPortalTrap);
|
sendMessage(player, TextMode.Info, Messages.RescuedFromPortalTrap);
|
||||||
return oldLocation;
|
portalReturnMap.remove(player.getUniqueId());
|
||||||
|
|
||||||
|
new BukkitRunnable()
|
||||||
|
{
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
if (oldLocation == dataStore.getPlayerData(player.getUniqueId()).portalTrappedLocation)
|
||||||
|
dataStore.getPlayerData(player.getUniqueId()).portalTrappedLocation = null;
|
||||||
|
}
|
||||||
|
}.runTaskLater(this, 600L);
|
||||||
|
}
|
||||||
|
|
||||||
|
//remember where players teleport from (via portals) in case they're trapped at the destination
|
||||||
|
ConcurrentHashMap<UUID, Location> portalReturnMap = new ConcurrentHashMap<UUID, Location>();
|
||||||
|
ConcurrentHashMap<UUID, BukkitTask> portalReturnTaskMap = new ConcurrentHashMap<UUID, BukkitTask>();
|
||||||
|
public void startRescueTask(Player player, Location rescueLocation)
|
||||||
|
{
|
||||||
|
BukkitTask task = new CheckForPortalTrapTask(player, this).runTaskLater(GriefPrevention.instance, 600L);
|
||||||
|
portalReturnMap.put(player.getUniqueId(), rescueLocation);
|
||||||
|
|
||||||
|
//Cancel existing rescue task
|
||||||
|
if (portalReturnTaskMap.containsKey(player.getUniqueId()))
|
||||||
|
portalReturnTaskMap.get(player.getUniqueId()).cancel();
|
||||||
|
portalReturnTaskMap.put(player.getUniqueId(), task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,8 @@ public class PlayerData
|
||||||
//this is an anti-bot strategy.
|
//this is an anti-bot strategy.
|
||||||
Location noChatLocation = null;
|
Location noChatLocation = null;
|
||||||
|
|
||||||
//last sign message, to prevent sign spam
|
//last rescue location, if player was recently rescued (to undo if rescue was unnecessary)
|
||||||
String lastSignMessage = null;
|
Location portalTrappedLocation = null;
|
||||||
|
|
||||||
//ignore list
|
//ignore list
|
||||||
//true means invisible (admin-forced ignore), false means player-created ignore
|
//true means invisible (admin-forced ignore), false means player-created ignore
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ import org.bukkit.util.BlockIterator;
|
||||||
class PlayerEventHandler implements Listener
|
class PlayerEventHandler implements Listener
|
||||||
{
|
{
|
||||||
private DataStore dataStore;
|
private DataStore dataStore;
|
||||||
|
private GriefPrevention instance;
|
||||||
|
|
||||||
//list of temporarily banned ip's
|
//list of temporarily banned ip's
|
||||||
private ArrayList<IpBanInfo> tempBannedIps = new ArrayList<IpBanInfo>();
|
private ArrayList<IpBanInfo> tempBannedIps = new ArrayList<IpBanInfo>();
|
||||||
|
|
@ -100,6 +101,7 @@ class PlayerEventHandler implements Listener
|
||||||
PlayerEventHandler(DataStore dataStore, GriefPrevention plugin)
|
PlayerEventHandler(DataStore dataStore, GriefPrevention plugin)
|
||||||
{
|
{
|
||||||
this.dataStore = dataStore;
|
this.dataStore = dataStore;
|
||||||
|
this.instance = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
//when a player chats, monitor for spam
|
//when a player chats, monitor for spam
|
||||||
|
|
@ -761,16 +763,7 @@ class PlayerEventHandler implements Listener
|
||||||
new IgnoreLoaderThread(playerID, playerData.ignoredPlayers).start();
|
new IgnoreLoaderThread(playerID, playerData.ignoredPlayers).start();
|
||||||
|
|
||||||
//is he possibly stuck in a portal frame?
|
//is he possibly stuck in a portal frame?
|
||||||
Location returnLocation = PlayerEventHandler.portalReturnMap.get(player.getUniqueId());
|
instance.rescuePlayerTrappedInPortal(player);
|
||||||
if(returnLocation != null)
|
|
||||||
{
|
|
||||||
PlayerEventHandler.portalReturnMap.remove(player.getUniqueId());
|
|
||||||
Block playerBlock = player.getLocation().getBlock();
|
|
||||||
if(GriefPrevention.instance.isPlayerTrappedInPortal(playerBlock))
|
|
||||||
{
|
|
||||||
GriefPrevention.instance.rescuePlayerTrappedInPortal(player, returnLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if we're holding a logout message for this player, don't send that or this event's join message
|
//if we're holding a logout message for this player, don't send that or this event's join message
|
||||||
if(GriefPrevention.instance.config_spam_logoutMessageDelaySeconds > 0)
|
if(GriefPrevention.instance.config_spam_logoutMessageDelaySeconds > 0)
|
||||||
|
|
@ -974,10 +967,6 @@ class PlayerEventHandler implements Listener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//remember where players teleport from (via portals) in case they're trapped at the destination
|
|
||||||
static ConcurrentHashMap<UUID, Location> portalReturnMap = new ConcurrentHashMap<UUID, Location>();
|
|
||||||
static ConcurrentHashMap<UUID, BukkitTask> portalReturnTaskMap = new ConcurrentHashMap<UUID, BukkitTask>();
|
|
||||||
|
|
||||||
//when a player teleports via a portal
|
//when a player teleports via a portal
|
||||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||||
void onPlayerPortal(PlayerPortalEvent event)
|
void onPlayerPortal(PlayerPortalEvent event)
|
||||||
|
|
@ -993,13 +982,7 @@ class PlayerEventHandler implements Listener
|
||||||
if(event.getCause() == TeleportCause.NETHER_PORTAL)
|
if(event.getCause() == TeleportCause.NETHER_PORTAL)
|
||||||
{
|
{
|
||||||
//FEATURE: when players get trapped in a nether portal, send them back through to the other side
|
//FEATURE: when players get trapped in a nether portal, send them back through to the other side
|
||||||
BukkitTask task = new CheckForPortalTrapTask(player, event.getFrom()).runTaskLater(GriefPrevention.instance, 600L);
|
instance.startRescueTask(player, event.getFrom());
|
||||||
portalReturnMap.put(player.getUniqueId(), event.getFrom());
|
|
||||||
|
|
||||||
//Cancel existing rescue task
|
|
||||||
if (portalReturnTaskMap.containsKey(player.getUniqueId()))
|
|
||||||
portalReturnTaskMap.get(player.getUniqueId()).cancel();
|
|
||||||
portalReturnTaskMap.put(player.getUniqueId(), task);
|
|
||||||
|
|
||||||
//FEATURE: if the player teleporting doesn't have permission to build a nether portal and none already exists at the destination, cancel the teleportation
|
//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)
|
if(GriefPrevention.instance.config_claims_portalsRequirePermission)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user