From 8f638b6a664431b520f3ff8d08cc9ee9046be6ba Mon Sep 17 00:00:00 2001 From: BeardBear <138500494+BeardBear33@users.noreply.github.com> Date: Tue, 30 Dec 2025 21:13:36 +0100 Subject: [PATCH] Add secure login handling for playerbots (#1953) Introduces PlayerbotsSecureLoginServerScript to handle secure login scenarios for playerbots. Ensures that if a playerbot is already online when a login is attempted, it is properly logged out before allowing the new session. Registers the new script in the Playerbots initialization. --- src/Playerbots.cpp | 3 ++ src/PlayerbotsSecureLogin.cpp | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/PlayerbotsSecureLogin.cpp diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp index 66e74201..e69c46bd 100644 --- a/src/Playerbots.cpp +++ b/src/Playerbots.cpp @@ -502,6 +502,8 @@ public: void OnBattlegroundEnd(Battleground* bg, TeamId /*winnerTeam*/) override { bgStrategies.erase(bg->GetInstanceID()); } }; +void AddPlayerbotsSecureLoginScripts(); + void AddPlayerbotsScripts() { new PlayerbotsDatabaseScript(); @@ -511,6 +513,7 @@ void AddPlayerbotsScripts() new PlayerbotsWorldScript(); new PlayerbotsScript(); new PlayerBotsBGScript(); + AddPlayerbotsSecureLoginScripts(); AddSC_playerbots_commandscript(); } diff --git a/src/PlayerbotsSecureLogin.cpp b/src/PlayerbotsSecureLogin.cpp new file mode 100644 index 00000000..aa5d103d --- /dev/null +++ b/src/PlayerbotsSecureLogin.cpp @@ -0,0 +1,82 @@ +#include "ScriptMgr.h" +#include "Opcodes.h" +#include "Player.h" +#include "ObjectAccessor.h" + +#include "Playerbots.h" + +namespace +{ + static Player* FindOnlineAltbotByGuid(ObjectGuid guid) + { + if (!guid) + return nullptr; + + Player* p = ObjectAccessor::FindPlayer(guid); + if (!p) + return nullptr; + + PlayerbotAI* ai = GET_PLAYERBOT_AI(p); + if (!ai || ai->IsRealPlayer()) + return nullptr; + + return p; + } + + static void ForceLogoutViaPlayerbotHolder(Player* target) + { + if (!target) + return; + + PlayerbotAI* ai = GET_PLAYERBOT_AI(target); + if (!ai) + return; + + if (Player* master = ai->GetMaster()) + { + if (PlayerbotMgr* mgr = GET_PLAYERBOT_MGR(master)) + { + mgr->LogoutPlayerBot(target->GetGUID()); + return; + } + } + + if (sRandomPlayerbotMgr) + { + sRandomPlayerbotMgr->LogoutPlayerBot(target->GetGUID()); + return; + } + } +} + +class PlayerbotsSecureLoginServerScript : public ServerScript +{ +public: + PlayerbotsSecureLoginServerScript() + : ServerScript("PlayerbotsSecureLoginServerScript", { SERVERHOOK_CAN_PACKET_RECEIVE }) {} + + bool CanPacketReceive(WorldSession* /*session*/, WorldPacket& packet) override + { + if (packet.GetOpcode() != CMSG_PLAYER_LOGIN) + return true; + + auto const oldPos = packet.rpos(); + ObjectGuid loginGuid; + packet >> loginGuid; + packet.rpos(oldPos); + + if (!loginGuid) + return true; + + Player* existingAltbot = FindOnlineAltbotByGuid(loginGuid); + if (existingAltbot) + ForceLogoutViaPlayerbotHolder(existingAltbot); + + return true; + } +}; + +void AddPlayerbotsSecureLoginScripts() +{ + new PlayerbotsSecureLoginServerScript(); +}