Improved the entry/exit flags so that it's harder to break it. Thanks to Siriuo.

This commit is contained in:
sk89q 2011-06-26 16:29:28 -07:00
parent 0fa43ee287
commit 258fbc8870
2 changed files with 53 additions and 1 deletions

View File

@ -22,6 +22,7 @@
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import org.bukkit.World;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
@ -153,8 +154,12 @@ public static class PlayerFlagState {
public String lastGreeting;
public String lastFarewell;
public Boolean lastExitAllowed = null;
public Boolean notifiedForEnter = false;
public Boolean notifiedForLeave = false;
public Boolean notifiedForEnter = false;
public World lastWorld;
public int lastBlockX;
public int lastBlockY;
public int lastBlockZ;
}
}

View File

@ -133,6 +133,7 @@ public void onPlayerLogin(PlayerLoginEvent event) {
@Override
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
@ -171,6 +172,15 @@ public void onPlayerJoin(PlayerJoinEvent event) {
if (plugin.inGroup(player, "wg-amphibious")) {
cfg.enableAmphibiousMode(player);
}
if (wcfg.useRegions) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
Location loc = player.getLocation();
state.lastWorld = loc.getWorld();
state.lastBlockX = loc.getBlockX();
state.lastBlockY = loc.getBlockY();
state.lastBlockZ = loc.getBlockZ();
}
}
/**
@ -179,8 +189,41 @@ public void onPlayerJoin(PlayerJoinEvent event) {
@Override
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// This is to make the enter/exit flags accurate -- move events are not
// sent constantly, so it is possible to move just a little enough to
// not trigger the event and then rejoin so that you are then considered
// outside the border. This should work around that.
if (wcfg.useRegions) {
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
if (state.lastWorld != null && !hasBypass) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Location loc = player.getLocation();
Vector pt = new Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (state.lastExitAllowed == null) {
state.lastExitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
}
if (!state.lastExitAllowed || !set.allows(DefaultFlag.ENTRY, localPlayer)) {
// Only if we have the last location cached
if (state.lastWorld.equals(world)) {
Location newLoc = new Location(world, state.lastBlockX + 0.5,
state.lastBlockY, state.lastBlockZ + 0.5);
player.teleport(newLoc);
}
}
}
}
cfg.forgetPlayer(plugin.wrapPlayer(player));
plugin.forgetPlayer(player);
}
@ -320,6 +363,10 @@ public void onPlayerMove(PlayerMoveEvent event) {
state.notifiedForEnter = notifyEnter;
state.notifiedForLeave = notifyLeave;
state.lastExitAllowed = exitAllowed;
state.lastWorld = event.getTo().getWorld();
state.lastBlockX = event.getTo().getBlockX();
state.lastBlockY = event.getTo().getBlockY();
state.lastBlockZ = event.getTo().getBlockZ();
}
}
}