From 765ee5eeedb75291113aec307825431678beb68a Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 19 Feb 2018 07:34:43 -0500 Subject: [PATCH] Fix for possible memory leak when spawning bots --- zone/bot.cpp | 24 ++++++++++++++++-------- zone/bot.h | 2 +- zone/bot_command.cpp | 23 ++++++++++++++++++----- zone/bot_database.cpp | 5 ++++- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index b0435dbe4..95ecf7885 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -3053,7 +3053,7 @@ void Bot::Depop() { NPC::Depop(false); } -void Bot::Spawn(Client* botCharacterOwner) { +bool Bot::Spawn(Client* botCharacterOwner) { if(GetBotID() > 0 && _botOwnerCharacterID > 0 && botCharacterOwner && botCharacterOwner->CharacterID() == _botOwnerCharacterID) { // Rename the bot name to make sure that Mob::GetName() matches Mob::GetCleanName() so we dont have a bot named "Jesuschrist001" strcpy(name, GetCleanName()); @@ -3097,7 +3097,11 @@ void Bot::Spawn(Client* botCharacterOwner) { this->SendWearChange(materialFromSlot); } } + + return true; } + + return false; } // Deletes the inventory record for the specified item from the database for this bot. @@ -3246,16 +3250,20 @@ void Bot::LoadAndSpawnAllZonedBots(Client* botOwner) { if(!ActiveBots.empty()) { for(std::list::iterator itr = ActiveBots.begin(); itr != ActiveBots.end(); ++itr) { Bot* activeBot = Bot::LoadBot(*itr); + if (!activeBot) + continue; - if(activeBot) { - activeBot->Spawn(botOwner); - g->UpdatePlayer(activeBot); - // follow the bot owner, not the group leader we just zoned with our owner. - if(g->IsGroupMember(botOwner) && g->IsGroupMember(activeBot)) - activeBot->SetFollowID(botOwner->GetID()); + if (!activeBot->Spawn(botOwner)) { + safe_delete(activeBot); + continue; } - if(activeBot && !botOwner->HasGroup()) + g->UpdatePlayer(activeBot); + // follow the bot owner, not the group leader we just zoned with our owner. + if (g->IsGroupMember(botOwner) && g->IsGroupMember(activeBot)) + activeBot->SetFollowID(botOwner->GetID()); + + if(!botOwner->HasGroup()) database.SetGroupID(activeBot->GetCleanName(), 0, activeBot->GetBotID()); } } diff --git a/zone/bot.h b/zone/bot.h index c69405011..1d38e5f57 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -275,7 +275,7 @@ public: static bool IsValidRaceClassCombo(uint16 r, uint8 c); bool IsValidName(); static bool IsValidName(std::string& name); - void Spawn(Client* botCharacterOwner); + bool Spawn(Client* botCharacterOwner); virtual void SetLevel(uint8 in_level, bool command = false); virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); virtual bool Process(); diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index e94825929..cd5e727d0 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -5049,7 +5049,11 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep) return; } - my_bot->Spawn(c); + if (!my_bot->Spawn(c)) { + c->Message(m_fail, "Failed to spawn bot '%s' (id: %i)", bot_name.c_str(), bot_id); + safe_delete(my_bot); + return; + } static const char* bot_spawn_message[16] = { "A solid weapon is my ally!", // WARRIOR / 'generic' @@ -5805,18 +5809,22 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep) return; } if (!leader_id) { - c->Message(m_fail, "Can not locate bot-group leader id for '%s'", botgroup_name_arg.c_str()); + c->Message(m_fail, "Cannot locate bot-group leader id for '%s'", botgroup_name_arg.c_str()); return; } auto botgroup_leader = Bot::LoadBot(leader_id); if (!botgroup_leader) { - c->Message(m_fail, "Could not spawn bot-group leader for '%s'", botgroup_name_arg.c_str()); + c->Message(m_fail, "Could not load bot-group leader for '%s'", botgroup_name_arg.c_str()); safe_delete(botgroup_leader); return; } - botgroup_leader->Spawn(c); + if (!botgroup_leader->Spawn(c)) { + c->Message(m_fail, "Could not spawn bot-group leader %s for '%s'", botgroup_leader->GetName(), botgroup_name_arg.c_str()); + safe_delete(botgroup_leader); + return; + } Group* group_inst = new Group(botgroup_leader); @@ -5835,7 +5843,12 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep) return; } - botgroup_member->Spawn(c); + if (!botgroup_member->Spawn(c)) { + c->Message(m_fail, "Could not spawn bot '%s' (id: %i)", botgroup_member->GetName(), member_iter); + safe_delete(botgroup_member); + return; + } + Bot::AddBotToGroup(botgroup_member, group_inst); } diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index d8511c54c..4c5aabb82 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -273,7 +273,10 @@ bool BotDatabase::LoadBotID(const uint32 owner_id, const std::string& bot_name, if (!owner_id || bot_name.empty()) return false; - query = StringFormat("SELECT `bot_id` FROM `bot_data` WHERE `name` = '%s' LIMIT 1", bot_name.c_str()); + query = StringFormat( + "SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u' AND `name` = '%s' LIMIT 1", + owner_id, bot_name.c_str() + ); auto results = QueryDatabase(query); if (!results.Success()) return false;