mirror of
https://github.com/garbagemule/MobArena.git
synced 2024-11-23 02:55:46 +01:00
Guard against teleporting back to the arena on death.
The /back command in Essentials - and similar commands from other plugins that allow you to warp back to your location of death - makes it possible to re-enter the arena after dying.
This commit builds upon the "leaving players" of commit 02f75d0e7f
and introduces a more general notion of players being "moved". The arena is "moving" a player if the player is being teleported somewhere by MobArena (to any arena warp), and in this case, all teleports of a player are permitted. This takes care of the cases where MobArena "might be doing it". The rest of the cases are due to commands, plugins, ender pearls, etc., and they are a little easier to deal with separately. The new logic is more straightforward and should prevent most exploits and permit most legit warp cases.
This (hopefully) fixes #313.
This commit is contained in:
parent
37de1e66e9
commit
31aa4c15a1
@ -97,6 +97,7 @@ public class ArenaImpl implements Arena
|
||||
private Map<Player,PlayerData> playerData = new HashMap<>();
|
||||
|
||||
private Set<Player> arenaPlayers, lobbyPlayers, readyPlayers, specPlayers, deadPlayers;
|
||||
private Set<Player> movingPlayers;
|
||||
private Set<Player> leavingPlayers;
|
||||
private Set<Player> randoms;
|
||||
|
||||
@ -165,6 +166,7 @@ public class ArenaImpl implements Arena
|
||||
this.specPlayers = new HashSet<>();
|
||||
this.deadPlayers = new HashSet<>();
|
||||
this.randoms = new HashSet<>();
|
||||
this.movingPlayers = new HashSet<>();
|
||||
this.leavingPlayers = new HashSet<>();
|
||||
|
||||
// Classes, items and permissions
|
||||
@ -518,7 +520,9 @@ public class ArenaImpl implements Arena
|
||||
System.out.println("[MobArena] Invincibility glitch attempt stopped!");
|
||||
}
|
||||
|
||||
movingPlayers.add(p);
|
||||
p.teleport(region.getArenaWarp());
|
||||
movingPlayers.remove(p);
|
||||
p.setAllowFlight(false);
|
||||
p.setFlying(false);
|
||||
//movePlayerToLocation(p, region.getArenaWarp());
|
||||
@ -663,6 +667,11 @@ public class ArenaImpl implements Arena
|
||||
return false;
|
||||
}
|
||||
|
||||
if (movingPlayers.contains(p)) {
|
||||
return false;
|
||||
}
|
||||
movingPlayers.add(p);
|
||||
|
||||
// Announce globally (must happen before moving player)
|
||||
if (settings.getBoolean("global-join-announce", false)) {
|
||||
if (lobbyPlayers.isEmpty()) {
|
||||
@ -710,6 +719,7 @@ public class ArenaImpl implements Arena
|
||||
}
|
||||
}
|
||||
|
||||
movingPlayers.remove(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -785,6 +795,11 @@ public class ArenaImpl implements Arena
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMoving(Player p) {
|
||||
return movingPlayers.contains(p) || leavingPlayers.contains(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaving(Player p) {
|
||||
return leavingPlayers.contains(p);
|
||||
@ -878,11 +893,17 @@ public class ArenaImpl implements Arena
|
||||
|
||||
@Override
|
||||
public void playerSpec(Player p, Location loc) {
|
||||
if (movingPlayers.contains(p)) {
|
||||
return;
|
||||
}
|
||||
movingPlayers.add(p);
|
||||
|
||||
storePlayerData(p, loc);
|
||||
MAUtils.sitPets(p);
|
||||
movePlayerToSpec(p);
|
||||
|
||||
messenger.tell(p, Msg.SPEC_PLAYER_SPECTATE);
|
||||
movingPlayers.remove(p);
|
||||
}
|
||||
|
||||
private void spawnPets() {
|
||||
|
@ -1173,44 +1173,54 @@ public class ArenaListener
|
||||
return TeleportResponse.IDGAF;
|
||||
}
|
||||
|
||||
Location to = event.getTo();
|
||||
Location from = event.getFrom();
|
||||
Player p = event.getPlayer();
|
||||
|
||||
/*
|
||||
* Players that are being moved around by the arena are always allowed
|
||||
* to teleport. They stay in this "moving" state only during the actual
|
||||
* transition and are removed from that state as soon as the transition
|
||||
* is complete.
|
||||
*/
|
||||
if (arena.isMoving(p) || p.hasPermission("mobarena.admin.teleport")) {
|
||||
return TeleportResponse.ALLOW;
|
||||
}
|
||||
|
||||
Location to = event.getTo();
|
||||
Location from = event.getFrom();
|
||||
|
||||
/*
|
||||
* At this point we're looking at warping of players that are either in
|
||||
* the arena - but not in the "moving" state - or not in the arena. The
|
||||
* tricky bit here is to figure out the edge cases. This is essentially
|
||||
* a matter of players "teleporting on their own" (or with assistance
|
||||
* from other plugins).
|
||||
*/
|
||||
if (region.contains(from)) {
|
||||
// Players with proper admin permission can warp out
|
||||
if (p.hasPermission("mobarena.admin.teleport")) {
|
||||
if (region.contains(to)) {
|
||||
// Inside -> inside
|
||||
if (!arena.inArena(p)) {
|
||||
arena.getMessenger().tell(p, Msg.WARP_TO_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
}
|
||||
return TeleportResponse.ALLOW;
|
||||
} else {
|
||||
// Inside -> outside
|
||||
if (arena.getAllPlayers().contains(p)) {
|
||||
arena.getMessenger().tell(p, Msg.WARP_FROM_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
}
|
||||
return TeleportResponse.IDGAF;
|
||||
}
|
||||
|
||||
// Players not in the arena are free to warp out.
|
||||
if (!arena.inArena(p) && !arena.inLobby(p) && !arena.inSpec(p)) {
|
||||
return TeleportResponse.ALLOW;
|
||||
} else {
|
||||
if (region.contains(to)) {
|
||||
// Outside -> inside
|
||||
arena.getMessenger().tell(p, Msg.WARP_TO_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
} else {
|
||||
// Outside -> outside
|
||||
return TeleportResponse.IDGAF;
|
||||
}
|
||||
|
||||
// Covers the case in which both locations are in the arena.
|
||||
if (region.contains(to) || region.isWarp(to) || to.equals(arena.getPlayerEntry(p))) {
|
||||
return TeleportResponse.ALLOW;
|
||||
}
|
||||
|
||||
arena.getMessenger().tell(p, Msg.WARP_FROM_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
}
|
||||
else if (region.contains(to)) {
|
||||
// Players with proper admin permission can warp in
|
||||
if (p.hasPermission("mobarena.admin.teleport")) {
|
||||
return TeleportResponse.ALLOW;
|
||||
}
|
||||
|
||||
if (region.isWarp(from) || region.isWarp(to) || to.equals(arena.getPlayerEntry(p))) {
|
||||
return TeleportResponse.ALLOW;
|
||||
}
|
||||
|
||||
arena.getMessenger().tell(p, Msg.WARP_TO_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
}
|
||||
|
||||
return TeleportResponse.IDGAF;
|
||||
}
|
||||
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
|
@ -154,6 +154,8 @@ public interface Arena
|
||||
|
||||
boolean playerLeave(Player p);
|
||||
|
||||
boolean isMoving(Player p);
|
||||
|
||||
boolean isLeaving(Player p);
|
||||
|
||||
void playerDeath(Player p);
|
||||
|
Loading…
Reference in New Issue
Block a user