Ignore leave events for spectators.
Spectators produce leave events, but they won't have a join event that matches the leave event they produce. This is because spectators either joined _as_ spectators (spectating doesn't produce join events), or they _transitioned_ into the spectator state after _dying_ in the session (in which case they already produced a death event that "cements" the player session). This fixes an edge case problem that occurs when a spectator produces a leave event while exactly one player is currently in the lobby. In this case, the leave event triggers a session deletion, since the leave event logic "thinks" the leave event is triggered by the player in the lobby. It would be possible to prevent that problem with additional checks in the leave event logic, but the underlying problem really is that leave events produced by spectators shouldn't be recorded or reacted to in any way, shape, or form, as they are not relevant to the stats (leave times are only really relevant if the leave event happens _during_ a session, which this change does not affect).
This commit is contained in:
@@ -88,6 +88,10 @@ public class SessionListener implements Listener {
|
||||
Arena arena = event.getArena();
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (arena.inSpec(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Session session = sessionStore.getByArena(arena);
|
||||
if (session == null) {
|
||||
log.warning("Unexpected leave event for non-existent session of arena " + arena.getSlug());
|
||||
|
||||
@@ -110,10 +110,23 @@ class SessionListenerTest {
|
||||
verify(session).playerReady(player, className);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoresPlayerLeaveForSpectators() {
|
||||
Player player = mock(Player.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.inSpec(player)).thenReturn(true);
|
||||
ArenaPlayerLeaveEvent event = new ArenaPlayerLeaveEvent(player, arena);
|
||||
|
||||
subject.on(event);
|
||||
|
||||
verifyNoInteractions(sessionStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
void logsWarningIfPlayerLeavesInNonExistentSession() {
|
||||
Player player = mock(Player.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
when(arena.inSpec(player)).thenReturn(false);
|
||||
when(sessionStore.getByArena(arena)).thenReturn(null);
|
||||
ArenaPlayerLeaveEvent event = new ArenaPlayerLeaveEvent(player, arena);
|
||||
|
||||
@@ -127,6 +140,7 @@ class SessionListenerTest {
|
||||
Player player = mock(Player.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
Session session = mock(Session.class);
|
||||
when(arena.inSpec(player)).thenReturn(false);
|
||||
when(arena.isRunning()).thenReturn(false);
|
||||
when(arena.getPlayersInLobby()).thenReturn(Collections.singleton(player));
|
||||
when(sessionStore.getByArena(arena)).thenReturn(session);
|
||||
@@ -142,6 +156,7 @@ class SessionListenerTest {
|
||||
Player player = mock(Player.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
Session session = mock(Session.class);
|
||||
when(arena.inSpec(player)).thenReturn(false);
|
||||
when(arena.isRunning()).thenReturn(false);
|
||||
when(arena.getPlayersInLobby()).thenReturn(Collections.singleton(player));
|
||||
when(sessionStore.getByArena(arena)).thenReturn(session);
|
||||
@@ -158,6 +173,7 @@ class SessionListenerTest {
|
||||
Player other = mock(Player.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
Session session = mock(Session.class);
|
||||
when(arena.inSpec(player)).thenReturn(false);
|
||||
when(arena.isRunning()).thenReturn(false);
|
||||
when(arena.getPlayersInLobby()).thenReturn(new HashSet<>(Arrays.asList(player, other)));
|
||||
when(sessionStore.getByArena(arena)).thenReturn(session);
|
||||
@@ -173,6 +189,7 @@ class SessionListenerTest {
|
||||
Player player = mock(Player.class);
|
||||
Arena arena = mock(Arena.class);
|
||||
Session session = mock(Session.class);
|
||||
when(arena.inSpec(player)).thenReturn(false);
|
||||
when(arena.isRunning()).thenReturn(true);
|
||||
when(sessionStore.getByArena(arena)).thenReturn(session);
|
||||
ArenaPlayerLeaveEvent event = new ArenaPlayerLeaveEvent(player, arena);
|
||||
|
||||
Reference in New Issue
Block a user