Avoid NPE race when computing the TechHider hidden region

getHiddenRegion looked the player up in FightTeam.players twice (team,
then FightPlayer) on netty threads. A concurrent reset or removePlayer
made the second lookup return null, the NPE was swallowed by the global
filter and the packet was dropped. Resolve the FightPlayer once and
derive team and canEntern from it.
This commit is contained in:
2026-10-27 09:28:05 +01:00
parent 4943682a66
commit 8381cacdf8
@@ -25,6 +25,7 @@ import de.steamwar.fightsystem.events.BoardingEvent;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
import de.steamwar.fightsystem.events.TeamSpawnEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
@@ -178,12 +179,13 @@ public class TechHiderWrapper extends StateDependent implements Listener {
private Region getHiddenRegion(Player player) {
if (Config.isReferee(player)) return Region.EMPTY;
FightTeam team = Fight.getPlayerTeam(player);
if (team == null) return Config.ArenaRegion;
// Single lookup: runs on netty threads, the player can leave the team at any time
FightPlayer fightPlayer = Fight.getFightPlayer(player);
if (fightPlayer == null) return Config.ArenaRegion;
if (team.canPlayerEntern(player)) return Region.EMPTY;
if (fightPlayer.canEntern()) return Region.EMPTY;
return Fight.getOpposite(team).getExtendRegion();
return Fight.getOpposite(fightPlayer.getTeam()).getExtendRegion();
}
private Stream<BlockState> getWaterloggedBlockStates() {