Hull kept a set of affected players that was only filled by a join
listener active in the Schem states, so spectators joining earlier were
never hidden from the hull. The set was also a plain HashSet read on
netty threads, where a racing lookup meant "not hidden".
Invert it into a concurrent set of viewers (referees, own team, boarded
players); everyone else is hidden by default.
- Hull: viewer UUID set with addViewer/removeViewer/forgetViewer, a
null player counts as hidden
- Hull: entities are hidden/shown when they enter/leave the hull for all
non-viewer online players; uncovered blocks go to non-viewers
- HullHider: join/quit handled in a listener active in every state; quit
clears the viewer entry
- HullHider: TeamDeathEvent re-hides the enemy hull and resends its chunks
- FightPlayer: stop the enter countdown before firing TeamDeathEvent so
listeners see canEntern() == false
Chat is now handled entirely by VelocityCore through channels with
separate readers and writers (Global, Local/Fight, Blue/Red fight team,
Team, ServerTeam, Alert and 1:1 direct messages). Each player has a
saved default channel; messages from other channels are tagged with
the channel name, and every default change is announced.
- /global, /local, /tc, /stc, /msg and /r switch the default channel
when called without a message
- /chat <channel> switches, /chat <channel> join|leave toggles reading
(saved); moderators can join arenas by name and write with
/chat <channel> msg <text>
- '+' sends from global to local and from local/fight to the fight team
- Referees write yellow in the fight chat
- Subservers no longer receive chat; arenas get a record-only
ChatRecordPacket so replays keep their chat
- Remove the chat listeners of SpigotCore, FightSystem, MissileWars,
TowerRun and TNTLeague
Closes#460, #129