From d404645303d3817a42493268a6de8253cb7cddb2 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Sat, 13 Jul 2024 21:18:42 +1000 Subject: [PATCH] join queue: fix 2 bugs that could result in too many players on a team Join(): when a client queued for red, then a blue player left the team, then a client (re)joined blue, the client queued for red was joined too (stacking red team). Fixed by only joining queued players in Join() when teams are currently balanced (the unbalanced cases are handled by TeamBalance_QueuedPlayersTagIn()). ClientKill_Now_TeamChange(): when all queued client(s) chose specific team(s) and the last client (which skips the queue and triggers the joins) chose autoselect from the team selection UI, it was possible they were assigned the same team as one of the queued clients. Fixed by deferring the autoselect to Join() when needed/possible. --- qcsrc/server/client.qc | 3 ++- qcsrc/server/clientkill.qc | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index 0a4a08502..749bbf8c4 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -2043,7 +2043,8 @@ void Join(entity this, bool queued_join) TRANSMUTE(Player, this); - if(queued_join) + if(queued_join + && TeamBalance_AreEqual(this, true)) // if a player couldn't tag in for balance, don't join them here as it would cause a stack { // First we must put queued player(s) in their team(s) (they chose first). FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this && it.wants_join, diff --git a/qcsrc/server/clientkill.qc b/qcsrc/server/clientkill.qc index b8f128a33..21df2319c 100644 --- a/qcsrc/server/clientkill.qc +++ b/qcsrc/server/clientkill.qc @@ -19,7 +19,16 @@ void ClientKill_Now_TeamChange(entity this) { if (this.killindicator_teamchange == -1) { - TeamBalance_JoinBestTeam(this); + if (this.team > 0) + // ensure team is valid immediately so ClientKill_Now() -> Damage() can update score without error + TeamBalance_JoinBestTeam(this); + else + { + // defer autoselect to Join(), after any queued players were joined to avoid 2 players on same team + // when the first player(s) chose specific teams and the last player chose autoselect (they skip the queue) + this.team = -1; + this.team_selected = -1; // don't stop at ShowTeamSelection() + } } else if (this.killindicator_teamchange == -2) { -- 2.39.2