All pastes #1297711 Raw Edit

Playerbot.patch

public diff v1 · immutable
#1297711 ·published 2009-01-01 18:02 UTC
rendered paste body
Allows players to log in their other characters as bots on same account and order their bots to do their bidding.diff -r b8345ca16d48 src/game/CharacterHandler.cpp--- a/src/game/CharacterHandler.cpp	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/CharacterHandler.cpp	Thu Jan 01 10:42:07 2009 -0500@@ -115,6 +115,25 @@                 return;             }             session->HandlePlayerLogin((LoginQueryHolder*)holder);+        }+        void HandlePlayerBotLoginCallback(QueryResult * /*dummy*/, SqlQueryHolder * holder)+        {+            if (!holder) return;++            LoginQueryHolder* lqh = (LoginQueryHolder*) holder;++            WorldSession *session = sWorld.FindSession(lqh->GetAccountId());++            if (! session)+            {+                delete holder;+                return;+            }++            WorldSession *botSession = new WorldSession(lqh->GetAccountId(), NULL, 0, true, 0, LOCALE_enUS);+            botSession->m_Address = "bot";+            botSession->HandlePlayerLogin(lqh);+            (session->m_playerBots)[lqh->GetGuid()] = botSession->_player;         } } chrHandler; @@ -1087,3 +1106,23 @@     data << uint64(guid);     SendPacket(&data); }++Player* WorldSession::GetPlayerBot(uint64 playerGuid)+{+    PlayerBotMap::const_iterator it = m_playerBots.find(playerGuid);+    return (it == m_playerBots.end()) ? 0 : it->second;+}++void WorldSession::AddPlayerBot(uint64 playerGuid)+{+    // has bot already been added?+    if (GetPlayerBot(playerGuid) != 0) return;++    LoginQueryHolder *holder = new LoginQueryHolder(GetAccountId(), playerGuid);+    if(!holder->Initialize())+    {+        delete holder;                                      // delete all unprocessed queries+        return;+    }+    CharacterDatabase.DelayQueryHolder(&chrHandler, &CharacterHandler::HandlePlayerBotLoginCallback, holder);+}diff -r b8345ca16d48 src/game/Chat.cpp--- a/src/game/Chat.cpp	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/Chat.cpp	Thu Jan 01 10:42:07 2009 -0500@@ -143,7 +143,7 @@ 		{ "modify",         SEC_GAMEMASTER,     false, &ChatHandler::HandleWpModifyCommand,            "", NULL }, 		{ "event",			SEC_GAMEMASTER,     false, &ChatHandler::HandleWpEventCommand,				"", NULL }, 		{ "unload",			SEC_GAMEMASTER,     false, &ChatHandler::HandleWpUnLoadPathCommand,		"", NULL },-		+ 		{ NULL,             0,                  false, NULL,                                           "", NULL }     }; @@ -529,11 +529,11 @@         { "event",          SEC_GAMEMASTER,     false, NULL,                                           "", eventCommandTable },         { "gobject",        SEC_GAMEMASTER,     false, NULL,                                           "", gobjectCommandTable },         { "honor",          SEC_GAMEMASTER,     false, NULL,                                           "", honorCommandTable },-        + 		//wp commands 		{ "path",           SEC_GAMEMASTER,     false, NULL,                                           "", wpCommandTable },         { "loadpath",		SEC_ADMINISTRATOR,  false, &ChatHandler::HandleReloadAllPaths,			   "", NULL },-	+ 		{ "quest",          SEC_ADMINISTRATOR,  false, NULL,                                           "", questCommandTable },         { "reload",         SEC_ADMINISTRATOR,  true,  NULL,                                           "", reloadCommandTable },         { "list",           SEC_ADMINISTRATOR,  true,  NULL,                                           "", listCommandTable },@@ -548,7 +548,7 @@          { "aura",           SEC_ADMINISTRATOR,  false, &ChatHandler::HandleAuraCommand,                "", NULL },         { "unaura",         SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnAuraCommand,              "", NULL },-        { "nameannounce",   SEC_MODERATOR,      false, &ChatHandler::HandleNameAnnounceCommand,        "", NULL }, +        { "nameannounce",   SEC_MODERATOR,      false, &ChatHandler::HandleNameAnnounceCommand,        "", NULL },         { "gmnameannounce", SEC_MODERATOR,      false, &ChatHandler::HandleGMNameAnnounceCommand,      "", NULL },         { "announce",       SEC_MODERATOR,      true,  &ChatHandler::HandleAnnounceCommand,            "", NULL },         { "gmannounce",     SEC_MODERATOR,      true,  &ChatHandler::HandleGMAnnounceCommand,          "", NULL },@@ -616,14 +616,16 @@         { "sendmessage",    SEC_ADMINISTRATOR,  true,  &ChatHandler::HandleSendMessageCommand,         "", NULL },         { "playall",        SEC_ADMINISTRATOR,  false, &ChatHandler::HandlePlayAllCommand,             "", NULL },         { "repairitems",    SEC_GAMEMASTER,     false, &ChatHandler::HandleRepairitemsCommand,         "", NULL },-        { "freeze",         SEC_ADMINISTRATOR,  false, &ChatHandler::HandleFreezeCommand,              "", NULL }, -        { "unfreeze",       SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnFreezeCommand,            "", NULL }, -        { "listfreeze",     SEC_ADMINISTRATOR,  false, &ChatHandler::HandleListFreezeCommand,          "", NULL }, -        { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand,   "", NULL }, +        { "freeze",         SEC_ADMINISTRATOR,  false, &ChatHandler::HandleFreezeCommand,              "", NULL },+        { "unfreeze",       SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnFreezeCommand,            "", NULL },+        { "listfreeze",     SEC_ADMINISTRATOR,  false, &ChatHandler::HandleListFreezeCommand,          "", NULL },+        { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand,   "", NULL },         { "possess",        SEC_ADMINISTRATOR,  false, &ChatHandler::HandlePossessCommand,             "", NULL },         { "unpossess",      SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnPossessCommand,           "", NULL },         { "bindsight",      SEC_ADMINISTRATOR,  false, &ChatHandler::HandleBindSightCommand,           "", NULL },         { "unbindsight",    SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnbindSightCommand,         "", NULL },++        { "bot",            SEC_PLAYER,         false, &ChatHandler::HandlePlayerbotCommand,           "", NULL },          { NULL,             0,                  false, NULL,                                           "", NULL }     };diff -r b8345ca16d48 src/game/Chat.h--- a/src/game/Chat.h	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/Chat.h	Thu Jan 01 10:42:07 2009 -0500@@ -72,7 +72,7 @@         int ParseCommands(const char* text);          virtual char const* GetName() const;-		+     protected:         explicit ChatHandler() : m_session(NULL) {}      // for CLI subclass @@ -406,7 +406,7 @@          bool HandleResetAllCommand(const char * args); -		+ 		// GM ticket command handlers 		bool HandleGMTicketListCommand(const char* args); 		bool HandleGMTicketListOnlineCommand(const char* args);@@ -428,7 +428,7 @@         bool HandlePasswordCommand(const char* args);         bool HandleLockAccountCommand(const char* args);         bool HandleRespawnCommand(const char* args);-                + 		//New Wp Commands 		bool HandleWpAddCommand(const char* args);         bool HandleWpLoadPathCommand(const char* args);@@ -481,6 +481,8 @@         bool HandleBindSightCommand(const char* args);         bool HandleUnbindSightCommand(const char* args); +        bool HandlePlayerbotCommand(const char* args);+         Player*   getSelectedPlayer();         Creature* getSelectedCreature();         Unit*     getSelectedUnit();@@ -503,7 +505,7 @@         void SetSentErrorMessage(bool val){ sentErrorMessage = val;};     private:         WorldSession * m_session;                           // != NULL for chat command call and NULL for CLI command-		+         // common global flag         static bool load_command_table;         bool sentErrorMessage;diff -r b8345ca16d48 src/game/Level0.cpp--- a/src/game/Level0.cpp	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/Level0.cpp	Thu Jan 01 10:42:07 2009 -0500@@ -23,6 +23,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "World.h"+#include "ObjectMgr.h" #include "Player.h" #include "Opcodes.h" #include "Chat.h"@@ -265,3 +266,38 @@ 	PSendSysMessage(LANG_MOTD_CURRENT, sWorld.GetMotd()); 	return true; }++bool ChatHandler::HandlePlayerbotCommand(const char* args)+{+    if (!*args)+    {+        SendSysMessage(LANG_USE_BOL);+        return true;+    }++    char *cmd = strtok ((char*)args, " ");+    char *charname = strtok (NULL, " ");++    if (!cmd || !charname)+        return false;++    std::string cmdStr = cmd;+    std::string charnameStr = charname;++    uint64 guid = objmgr.GetPlayerGUIDByName(charnameStr.c_str());+    if(!guid)+    {+        SendSysMessage(LANG_PLAYER_NOT_FOUND);+        SetSentErrorMessage(true);+        return false;+    }++    if (cmdStr == "add" || cmdStr == "login") {+        m_session->AddPlayerBot(guid);+    }+    else if (cmdStr == "remove" || cmdStr == "logout") {+        m_session->LogoutPlayerBot(guid, true);+    }++    return true;+}diff -r b8345ca16d48 src/game/Player.cpp--- a/src/game/Player.cpp	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/Player.cpp	Thu Jan 01 10:42:07 2009 -0500@@ -268,7 +268,7 @@     m_divider = 0;      m_ExtraFlags = 0;-   +     // players always accept     if(GetSession()->GetSecurity() == SEC_PLAYER)         SetAcceptWhispers(true);@@ -6173,7 +6173,7 @@         {             // Check if allowed to receive it in current map             uint8 MapType = sWorld.getConfig(CONFIG_PVP_TOKEN_MAP_TYPE);-            if( (MapType == 1 && !InBattleGround() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP)) +            if( (MapType == 1 && !InBattleGround() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))                 || (MapType == 2 && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))                 || (MapType == 3 && !InBattleGround()) )                 return true;@@ -7963,7 +7963,7 @@                     data << uint32(2474)  << uint32(50);  //: ally / horde slider percentage, 100 for ally, 0 for horde  // show only in direct vicinity!                     data << uint32(2473)  << uint32(0);   //: ally / horde slider display                                // show only in direct vicinity!                     data << uint32(0x9a8) << uint32(0x0);           // 20 // show the neutral stadium icon      // 2472-                    data << uint32(0x9a7) << uint32(0x0);           // 21 // show the ally stadium icon         // 2471 +                    data << uint32(0x9a7) << uint32(0x0);           // 21 // show the ally stadium icon         // 2471                     data << uint32(0x9a6) << uint32(0x1);           // 22 // show the horde stadium icon        // 2470                 }             }@@ -8056,7 +8056,7 @@                     data << uint32(0x9e1) << uint32(0x0);           // 10 //2529                     data << uint32(0x9e0) << uint32(0x0);           // 11                     data << uint32(0x9df) << uint32(0x0);           // 12-                    data << uint32(0xa5d) << uint32(0x1);           // 13 //2653 +                    data << uint32(0xa5d) << uint32(0x1);           // 13 //2653                     data << uint32(0xa5c) << uint32(0x0);           // 14 //2652 east beacon neutral                     data << uint32(0xa5b) << uint32(0x1);           // 15 horde                     data << uint32(0xa5a) << uint32(0x0);           // 16 ally@@ -8072,7 +8072,7 @@                     data << uint32(0xa00) << uint32(0x0);           // 26 // 2560                     data << uint32(0x9ff) << uint32(0x1);           // 27                     data << uint32(0x9fe) << uint32(0x0);           // 28-                    data << uint32(0x9fd) << uint32(0x0);           // 29 +                    data << uint32(0x9fd) << uint32(0x0);           // 29                     data << uint32(0x9fc) << uint32(0x1);           // 30                     data << uint32(0x9fb) << uint32(0x0);           // 31                     data << uint32(0xa62) << uint32(0x0);           // 32 // 2658@@ -15453,7 +15453,7 @@     // save pet (hunter pet level and experience and all type pets health/mana).     if(Pet* pet = GetPet())         pet->SavePetToDB(PET_SAVE_AS_CURRENT);-        +     //to prevent access to DB we should cache some data, which is used very often     CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());     if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players@@ -16286,6 +16286,43 @@         language = LANG_UNIVERSAL;                          // whispers should always be readable      Player *rPlayer = objmgr.GetPlayer(receiver);++    if (rPlayer->GetSession()->GetRemoteAddress() == "bot")+    {+    	// if message is not from the player controlling the bot, auto reply and ignore+    	if (!(rPlayer->GetSession()->GetAccountId() == GetSession()->GetAccountId()))+    	{+    		WorldPacket data(SMSG_MESSAGECHAT, 200);+    		WorldSession* masterSession = sWorld.FindSession(rPlayer->GetSession()->GetAccountId());+    		std::string msg = "I can't talk to you. Please speak to my master ";+    		msg += masterSession->GetPlayerName();+    		rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, msg, language);+    		GetSession()->SendPacket(&data);+    	}+    	else if (text == "follow")+    	{+    		rPlayer->GetMotionMaster()->Clear();+    		float angle = (float) (M_PI - (M_PI / urand(1,50))); // generates random float between 0 number less then 3.14+    		float dist = (float) urand(1,6); // generates random float between 1 and 6+    		rPlayer->GetMotionMaster()->MoveFollow(this, dist, angle);+    	}+    	else if (text == "stay")+    	{+    		rPlayer->GetMotionMaster()->Clear();+    	}+    	else if (text == "assist")+    	{+    		rPlayer->Attack(getAttackerForHelper(), true);+    	}+    	else+    	{+    		WorldPacket data(SMSG_MESSAGECHAT, 200);+    		std::string msg = "Sorry master. Please speak in terms I can understand such as: follow, stay, assist";+    		rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, msg, language);+    		GetSession()->SendPacket(&data);+    	}+    	return;+    }      // when player you are whispering to is dnd, he cannot receive your message, unless you are in gm mode     if(!rPlayer->isDND() || isGameMaster())@@ -19041,7 +19078,7 @@     // Remove any previous possession from the target     if (target->isPossessedByPlayer())         ((Player*)target->GetCharmer())->RemovePossess(false);-    else if (target->isCharmed()) +    else if (target->isCharmed())         target->UncharmSelf();  // Target isn't possessed, but charmed; uncharm before possessing      // Remove our previous possession@@ -19180,13 +19217,13 @@                     target->GetMotionMaster()->Clear();                     target->GetMotionMaster()->MoveTargetedHome();                 }-            } +            }             else             {                 target->GetMotionMaster()->Clear();                 target->GetMotionMaster()->MoveTargetedHome();             }-            +             // Add high amount of threat on the player             if(attack)                 target->AddThreat(this, 1000000.0f);diff -r b8345ca16d48 src/game/WorldSession.cpp--- a/src/game/WorldSession.cpp	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/WorldSession.cpp	Thu Jan 01 10:42:07 2009 -0500@@ -241,6 +241,13 @@ /// %Log the player out void WorldSession::LogoutPlayer(bool Save) {+    // log out any PlayerBots owned in this WorldSession+    PlayerBotMap::const_iterator it = m_playerBots.begin();+    for(PlayerBotMap::const_iterator itr = m_playerBots.begin(); itr != m_playerBots.end(); ++itr) {+    	uint64 guid = itr->first;+    	LogoutPlayerBot(guid, Save);+    }+     // finish pending transfers before starting the logout     while(_player && _player->IsBeingTeleported())         HandleMoveWorldportAckOpcode();@@ -324,7 +331,8 @@         ///- Reset the online field in the account table         // no point resetting online in character table here as Player::SaveToDB() will set it to 1 since player has not been removed from world at this stage         //No SQL injection as AccountID is uint32-        loginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = '%u'", GetAccountId());+        if (m_Address != "bot")+        	loginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = '%u'", GetAccountId());          ///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members         Guild *guild = objmgr.GetGuildById(_player->GetGuildId());@@ -396,6 +404,9 @@         _player->CleanupsBeforeDelete();                    // do some cleanup before deleting to prevent crash at crossreferences to already deleted data          sSocialMgr.RemovePlayerSocial (_player->GetGUIDLow ());++        uint32 guid = _player->GetGUIDLow();+         delete _player;         _player = NULL; @@ -405,8 +416,7 @@          ///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline         //No SQL injection as AccountId is uint32-        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",-            GetAccountId());+        CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid);         sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );     } @@ -525,3 +535,17 @@         SendPacket(&packet);     } }++void WorldSession::LogoutPlayerBot(uint64 guid, bool Save)+{+    Player* botPlayerPtr = GetPlayerBot(guid);++    if (botPlayerPtr)+    {+        WorldSession * botWorldSessionPtr = botPlayerPtr->m_session;+        botPlayerPtr = NULL;+        m_playerBots.erase(guid);	// deletes bot player ptr inside this WorldSession PlayerBotMap+        botWorldSessionPtr->LogoutPlayer(Save); // this will delete the bot Player object+        delete botWorldSessionPtr;  // finally delete the bot's WorldSession+    }+}diff -r b8345ca16d48 src/game/WorldSession.h--- a/src/game/WorldSession.h	Thu Jan 01 09:22:46 2009 -0500+++ b/src/game/WorldSession.h	Thu Jan 01 10:42:07 2009 -0500@@ -75,6 +75,10 @@     public:         WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expansion, time_t mute_time, LocaleConstant locale);         ~WorldSession();++        void AddPlayerBot(uint64 guid);+        void LogoutPlayerBot(uint64 guid, bool Save);+        Player* GetPlayerBot(uint64 guid);          bool PlayerLoading() const { return m_playerLoading; }         bool PlayerLogout() const { return m_playerLogout; }@@ -275,7 +279,7 @@ 		 void HandleGMTicketDeleteOpcode(WorldPacket& recvPacket); 		 void HandleGMTicketGetTicketOpcode(WorldPacket& recvPacket); 		 void HandleGMTicketSystemStatusOpcode(WorldPacket& recvPacket);-		+         //void HandleGMSurveySubmit(WorldPacket& recvPacket);          void HandleTogglePvP(WorldPacket& recvPacket);@@ -653,6 +657,9 @@         int m_sessionDbLocaleIndex;         uint32 m_latency; +        typedef UNORDERED_MAP<uint64, Player*> PlayerBotMap;+        PlayerBotMap m_playerBots;+         ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _recvQueue; }; #endif