From e433824c54488808d3f34b0d600a10ed06b9ef5c Mon Sep 17 00:00:00 2001 From: Lyberta Date: Tue, 28 Nov 2017 12:20:05 +0300 Subject: [PATCH] Hardening of several teamplay functions. --- qcsrc/common/teams.qh | 36 ++++++++++++++++ qcsrc/server/bot/default/bot.qc | 2 +- qcsrc/server/client.qc | 8 ++-- qcsrc/server/teamplay.qc | 75 ++++++++++++++++++++++----------- qcsrc/server/teamplay.qh | 2 +- 5 files changed, 92 insertions(+), 31 deletions(-) diff --git a/qcsrc/common/teams.qh b/qcsrc/common/teams.qh index 1f8a603dd..57d644c04 100644 --- a/qcsrc/common/teams.qh +++ b/qcsrc/common/teams.qh @@ -125,6 +125,42 @@ float Team_ColorToTeam(string team_color) return -1; } +/// \brief Returns whether team is valid. +/// \param[in] team_ Team to check. +/// \return True if team is valid, false otherwise. +bool Team_IsValidTeam(int team_) +{ + switch (team_) + { + case NUM_TEAM_1: + case NUM_TEAM_2: + case NUM_TEAM_3: + case NUM_TEAM_4: + { + return true; + } + } + return false; +} + +/// \brief Returns whether team number is valid. +/// \param[in] number Team number to check. +/// \return True if team number is valid, false otherwise. +bool Team_IsValidNumber(int number) +{ + switch (number) + { + case 1: + case 2: + case 3: + case 4: + { + return true; + } + } + return false; +} + float Team_NumberToTeam(float number) { switch(number) diff --git a/qcsrc/server/bot/default/bot.qc b/qcsrc/server/bot/default/bot.qc index f8ddd0c63..6ea375c08 100644 --- a/qcsrc/server/bot/default/bot.qc +++ b/qcsrc/server/bot/default/bot.qc @@ -438,7 +438,7 @@ void bot_clientconnect(entity this) else if(this.bot_forced_team==4) this.team = NUM_TEAM_4; else - JoinBestTeam(this, false, true); + JoinBestTeam(this, true); havocbot_setupbot(this); } diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index d7b9a7ae0..ed7c36a37 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -507,7 +507,7 @@ void PutPlayerInServer(entity this) accuracy_resend(this); if (this.team < 0) - JoinBestTeam(this, false, true); + JoinBestTeam(this, true); entity spot = SelectSpawnPoint(this, false); if (!spot) { @@ -875,7 +875,7 @@ void ClientKill_Now_TeamChange(entity this) { if(this.killindicator_teamchange == -1) { - JoinBestTeam( this, false, true ); + JoinBestTeam( this, true ); } else if(this.killindicator_teamchange == -2) { @@ -1187,7 +1187,7 @@ void ClientConnect(entity this) { int id = this.playerid; this.playerid = 0; // silent - JoinBestTeam(this, false, false); // if the team number is valid, keep it + JoinBestTeam(this, false); // if the team number is valid, keep it this.playerid = id; } @@ -2000,7 +2000,7 @@ void Join(entity this) if(!this.team_selected) if(autocvar_g_campaign || autocvar_g_balance_teams) - JoinBestTeam(this, false, true); + JoinBestTeam(this, true); if(autocvar_g_campaign) campaign_bots_may_start = true; diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index fd73969cb..00cf58e26 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -545,6 +545,14 @@ void GetTeamCounts(entity ignore) bool IsTeamSmallerThanTeam(int team_a, int team_b, entity player, bool use_score) { + if (!Team_IsValidNumber(team_a)) + { + LOG_FATALF("IsTeamSmallerThanTeam: team_a is invalid: %f", team_a); + } + if (!Team_IsValidNumber(team_b)) + { + LOG_FATALF("IsTeamSmallerThanTeam: team_b is invalid: %f", team_b); + } if (team_a == team_b) { return false; @@ -642,6 +650,14 @@ bool IsTeamSmallerThanTeam(int team_a, int team_b, entity player, bool IsTeamEqualToTeam(int team_a, int team_b, entity player, bool use_score) { + if (!Team_IsValidNumber(team_a)) + { + LOG_FATALF("IsTeamEqualToTeam: team_a is invalid: %f", team_a); + } + if (!Team_IsValidNumber(team_b)) + { + LOG_FATALF("IsTeamEqualToTeam: team_b is invalid: %f", team_b); + } if (team_a == team_b) { return true; @@ -837,53 +853,56 @@ int FindSmallestTeam(entity player, float ignore_player) return RandomSelection_chosen_float; } -int JoinBestTeam(entity this, bool only_return_best, bool force_best_team) +void JoinBestTeam(entity this, bool force_best_team) { // don't join a team if we're not playing a team game if (!teamplay) { - return 0; + return; } // find out what teams are available CheckAllowedTeams(this); - // if we don't care what team he ends up on, put him on whatever team he entered as. - // if he's not on a valid team, then let other code put him on the smallest team + // if we don't care what team they ends up on, put them on whatever team they entered as. + // if they're not on a valid team, then let other code put them on the smallest team if (!force_best_team) { int selected_team; - if( c1 >= 0 && this.team == NUM_TEAM_1) + if ((c1 >= 0) && (this.team == NUM_TEAM_1)) + { selected_team = this.team; - else if(c2 >= 0 && this.team == NUM_TEAM_2) + } + else if ((c2 >= 0) && (this.team == NUM_TEAM_2)) + { selected_team = this.team; - else if(c3 >= 0 && this.team == NUM_TEAM_3) + } + else if ((c3 >= 0) && (this.team == NUM_TEAM_3)) + { selected_team = this.team; - else if(c4 >= 0 && this.team == NUM_TEAM_4) + } + else if ((c4 >= 0) && (this.team == NUM_TEAM_4)) + { selected_team = this.team; + } else + { selected_team = -1; + } if (selected_team > 0) { - if (!only_return_best) - { - SetPlayerTeamSimple(this, selected_team); - - // when JoinBestTeam is called by client.qc/ClientKill_Now_TeamChange the players team is -1 and thus skipped - // when JoinBestTeam is called by client.qc/ClientConnect the player_id is 0 the log attempt is rejected - LogTeamchange(this.playerid, this.team, 99); - } - return selected_team; + SetPlayerTeamSimple(this, selected_team); + LogTeamchange(this.playerid, this.team, 99); + return; } - // otherwise end up on the smallest team (handled below) } - - int best_team = FindSmallestTeam(this, true); - if (only_return_best || this.bot_forced_team) + // otherwise end up on the smallest team (handled below) + if (this.bot_forced_team) { - return best_team; + return; } + int best_team = FindSmallestTeam(this, true); best_team = Team_NumberToTeam(best_team); if (best_team == -1) { @@ -893,12 +912,11 @@ int JoinBestTeam(entity this, bool only_return_best, bool force_best_team) TeamchangeFrags(this); SetPlayerTeamSimple(this, best_team); LogTeamchange(this.playerid, this.team, 2); // log auto join - if (!IS_BOT_CLIENT(this)) + if ((old_team != -1) && !IS_BOT_CLIENT(this)) { AutoBalanceBots(old_team, Team_TeamToNumber(best_team)); } KillPlayerForTeamChange(this); - return best_team; } void SV_ChangeTeam(entity this, float _color) @@ -978,8 +996,15 @@ void SV_ChangeTeam(entity this, float _color) void AutoBalanceBots(int source_team, int destination_team) { - if ((source_team == -1) || (destination_team == -1)) + if (!Team_IsValidNumber(source_team)) + { + LOG_WARNF("AutoBalanceBots: Source team is invalid: %f", source_team); + return; + } + if (!Team_IsValidNumber(destination_team)) { + LOG_WARNF("AutoBalanceBots: Destination team is invalid: %f", + destination_team); return; } if (!autocvar_g_balance_teams || diff --git a/qcsrc/server/teamplay.qh b/qcsrc/server/teamplay.qh index 1813db04d..7c4ebe77b 100644 --- a/qcsrc/server/teamplay.qh +++ b/qcsrc/server/teamplay.qh @@ -107,7 +107,7 @@ int FindBestTeams(entity player, bool use_score); // NOTE: Assumes CheckAllowedTeams has already been called! int FindSmallestTeam(entity player, float ignore_player); -int JoinBestTeam(entity this, bool only_return_best, bool force_best_team); +void JoinBestTeam(entity this, bool force_best_team); /// \brief Auto balances bots in teams after the player has changed team. /// \param[in] source_team Previous team of the player (1, 2, 3, 4). -- 2.39.2