From d5a92535829560333cd6f8c7683a58b1ac935242 Mon Sep 17 00:00:00 2001 From: jeefo Date: Fri, 19 Jan 2024 21:35:00 +0300 Subject: [PATCH] fix: refactoring mistake with square distances (ref #506 #495) fix: bot glibc dependency when SIMD is disabled fakeping: allow to disable ping average ping calculation from human players (controllable via yb_count_players_for_fakeping) --- ext/crlib | 2 +- src/combat.cpp | 5 +--- src/support.cpp | 66 +++++++++++++++++++++++++++---------------------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/ext/crlib b/ext/crlib index 07c5413..72b32ac 160000 --- a/ext/crlib +++ b/ext/crlib @@ -1 +1 @@ -Subproject commit 07c54138879ea360913a594b3c11557361e20fed +Subproject commit 72b32ac851400c6abb2332299d42f62b871620dd diff --git a/src/combat.cpp b/src/combat.cpp index 632b57a..883efb9 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -627,7 +627,7 @@ bool Bot::isFriendInLineOfFire (float distance) { } const auto friendDistanceSq = client.ent->v.origin.distanceSq (pev->origin); - if (friendDistanceSq <= distanceSq && util.getShootingCone (ent (), client.ent->v.origin) > friendDistanceSq / (friendDistanceSq + cr::sqrf (1089.0f))) { + if (friendDistanceSq <= distanceSq && util.getShootingCone (ent (), client.ent->v.origin) > friendDistanceSq / (friendDistanceSq + cr::sqrf (33.0f))) { return true; } } @@ -975,9 +975,6 @@ void Bot::fireWeapons () { // or if friend in line of fire, stop this too but do not update shoot time if (isFriendInLineOfFire (distance)) { - m_fightStyle = Fight::Strafe; - m_lastFightStyleCheck = game.time (); - return; } int selectId = Weapon::Knife, selectIndex = 0, choosenWeapon = 0; diff --git a/src/support.cpp b/src/support.cpp index 073df3b..a440d25 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -11,6 +11,7 @@ ConVar cv_display_welcome_text ("display_welcome_text", "1", "Enables or disable ConVar cv_enable_query_hook ("enable_query_hook", "0", "Enables or disables fake server queries response, that shows bots as real players in server browser."); ConVar cv_breakable_health_limit ("breakable_health_limit", "500.0", "Specifies the maximum health of breakable object, that bot will consider to destroy.", true, 1.0f, 3000.0); ConVar cv_enable_fake_steamids ("enable_fake_steamids", "0", "Allows or disallows bots to return fake steam id."); +ConVar cv_count_players_for_fakeping ("count_players_for_fakeping", "1", "Count player pings when calculating average ping for bots. If no, some random ping chosen for bots."); BotSupport::BotSupport () { m_needToSendWelcome = false; @@ -430,38 +431,45 @@ void BotSupport::syncCalculatePings () { Twin average { 0, 0 }; int numHumans = 0; - // first get average ping on server, and store real client pings - for (auto &client : m_clients) { - if (!(client.flags & ClientFlags::Used) || isFakeClient (client.ent)) { - continue; + // only count player pings if we're allowed to + if (cv_count_players_for_fakeping.bool_ ()) { + // first get average ping on server, and store real client pings + for (auto &client : m_clients) { + if (!(client.flags & ClientFlags::Used) || isFakeClient (client.ent)) { + continue; + } + int ping, loss; + engfuncs.pfnGetPlayerStats (client.ent, &ping, &loss); + + // @note: for those who asking on a email, we CAN call pfnGetPlayerStats hl-engine function in a separate thread + // since the function doesn't modify anything inside engine, so race-condition and crash isn't viable situation + // it's just fills ping and loss from engine structures, the only way to cause crash in separate thread + // is to call it with a invalid ``client`` pointer (on goldsrc), thus causing Con_Printf which is not compatible with + // multi-threaded environment + // + // see: + // https://github.com/dreamstalker/rehlds/blob/a680f18ee1e7eb8c39fbdc45682163ca9477d783/rehlds/engine/pr_cmds.cpp#L2735C15-L2735C32 + // https://github.com/fwgs/xash3d-fwgs/blob/f5b9826fd9bbbdc5293c1ff522de11ce28d3c9f2/engine/server/sv_game.c#L4443 + + // store normal client ping + client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg.get (8, 16)); // getting player ping sometimes fails + ++numHumans; + + average.first += ping; + average.second += loss; } - int ping, loss; - engfuncs.pfnGetPlayerStats (client.ent, &ping, &loss); - // @note: for those who asking on a email, we CAN call pfnGetPlayerStats hl-engine function in a separate thread - // since the function doesn't modify anything inside engine, so race-condition and crash isn't viable situation - // it's just fills ping and loss from engine structures, the only way to cause crash in separate thread - // is to call it with a invalid ``client`` pointer (on goldsrc), thus causing Con_Printf which is not compatible with - // multi-threaded environment - // - // see: - // https://github.com/dreamstalker/rehlds/blob/a680f18ee1e7eb8c39fbdc45682163ca9477d783/rehlds/engine/pr_cmds.cpp#L2735C15-L2735C32 - // https://github.com/fwgs/xash3d-fwgs/blob/f5b9826fd9bbbdc5293c1ff522de11ce28d3c9f2/engine/server/sv_game.c#L4443 - - // store normal client ping - client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg.get (8, 16)); // getting player ping sometimes fails - ++numHumans; - - average.first += ping; - average.second += loss; - } - - if (numHumans > 0) { - average.first /= numHumans; - average.second /= numHumans; + if (numHumans > bots.getBotCount () / 4) { + average.first /= numHumans; + average.second /= numHumans; + } + else { + average.first = rg.get (10, 20); + average.second = rg.get (5, 10); + } } else { - average.first = rg.get (30, 40); + average.first = rg.get (10, 20); average.second = rg.get (5, 10); } @@ -484,7 +492,7 @@ void BotSupport::syncCalculatePings () { if (botPing < 2) { botPing = rg.get (10, 23); } - else if (botPing > 300) { + else if (botPing > 100) { botPing = rg.get (30, 40); } client.ping = getPingBitmask (client.ent, botLoss, botPing);