From ba0c03af08cf90400d8f2f2e1bfeb5890fb5ad7e Mon Sep 17 00:00:00 2001 From: neckkola <65987027+neckkola@users.noreply.github.com> Date: Mon, 3 Jan 2022 11:52:08 -0400 Subject: [PATCH] Bot Group Work Fixed botid=charid spawn on zone issue Added a group_list update on zone to refresh from database to fix a dangling pointer to a Bot object that was camped but was previously in a group within the zone being entered. Modified Bot::ProcessBotGroupInvite to use the client of the bot when doing the Bot initialization so that a leader can invite another owner's Bot --- zone/bot.cpp | 4 +-- zone/bot_database.cpp | 23 ++++++++-------- zone/groups.cpp | 63 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 74 insertions(+), 16 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 2ac70c6ea..a9545c7e8 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -8596,8 +8596,8 @@ Bot* Bot::GetBotByBotClientOwnerAndBotName(Client* c, std::string botName) { void Bot::ProcessBotGroupInvite(Client* c, std::string botName) { if(c) { - Bot* invitedBot = GetBotByBotClientOwnerAndBotName(c, botName); - + Bot* invitedBot = GetBotByBotClientOwnerAndBotName(entity_list.GetBotByBotName(botName)->GetOwner()->CastToClient(), botName); + //Mitch changed entity from c if(invitedBot && !invitedBot->HasGroup()) { if(!c->IsGrouped()) { Group *g = new Group(c); diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index c419fd355..b05fa7e98 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -2632,19 +2632,20 @@ bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 g { if (!group_id || !owner_id) return false; - + //modified query for usecase of a BOTID sharing a CHARACTERID. + //in this usecase, when the BOTID=CHARACTERID of BOT OWNER, this BOTID would be added to the GROUP query = StringFormat( - "SELECT `charid`" - " FROM `group_id`" - " WHERE `groupid` = '%u'" - " AND `charid` IN (" - " SELECT `bot_id`" - " FROM `bot_data`" - " WHERE `owner_id` = '%u'" - " )", + "SELECT `mob_id` FROM `vw_groups` " + "WHERE `group_id` = '%u' " + "AND `mob_type`='B' " + "AND `mob_id` IN (SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u');" + , group_id, owner_id); + /*query = StringFormat( + "SELECT `charid` FROM `group_id` WHERE `groupid` = '%u'" + " AND `charid` IN (SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u')" + " AND `group_id.name` NOT IN (SELECT `name` FROM `character_data`)", group_id, - owner_id - ); + owner_id);*/ auto results = database.QueryDatabase(query); if (!results.Success()) diff --git a/zone/groups.cpp b/zone/groups.cpp index 13188dcb9..5d44dc5df 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -248,10 +248,24 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte uint32 i = 0; for (i = 0; i < MAX_GROUP_MEMBERS; ++i) { - if(!strcasecmp(membername[i], NewMemberName)) +#ifdef BOTSS + if (newmember->IsBot() && !newmember->HasGroup() && !strcasecmp(membername[i], NewMemberName)) // Mitch + { + //Bot::RemoveBotFromGroup(newmember->CastToBot(), members[0]->GetGroup()); + //Group::DelMember(newmember); + memset(membername[i], 0, 64); + members[i] = nullptr; + } + else if (!strcasecmp(membername[i], NewMemberName)) { return false; } +#else + if (!strcasecmp(membername[i], NewMemberName)) + { + return false; + } +#endif } // Put them in the group @@ -1176,7 +1190,13 @@ void Group::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float } bool Group::LearnMembers() { - std::string query = StringFormat("SELECT name FROM group_id WHERE groupid = %lu", (unsigned long)GetID()); + //std::string query = StringFormat("SELECT name FROM group_id WHERE groupid = %lu", (unsigned long)GetID()); + std::string query = StringFormat("SELECT name FROM group_id " + "WHERE group_id.groupid = %lu AND group_id.name NOT " + "IN(SELECT group_leaders.leadername FROM group_leaders WHERE gid = %lu)" + , (unsigned long)GetID() + , (unsigned long)GetID()); + auto results = database.QueryDatabase(query); if (!results.Success()) return false; @@ -1191,7 +1211,7 @@ bool Group::LearnMembers() { return false; } - int memberIndex = 0; + int memberIndex = 1; //starts at 1 becasuse leader [0] is done specifically for(auto row = results.begin(); row != results.end(); ++row) { if(!row[0]) continue; @@ -1201,7 +1221,24 @@ bool Group::LearnMembers() { memberIndex++; } + // for leader only [0] /Mitch + query = StringFormat("SELECT leadername FROM group_leaders WHERE group_leaders.gid = %lu", (unsigned long)GetID()); + auto results2 = database.QueryDatabase(query); + if (!results2.Success()) + return false; + if (results2.RowCount() == 0) { + LogError( + "Error getting group leader for group [{}]: [{}]", + (unsigned long)GetID(), + results2.ErrorMessage().c_str() + ); + + return false; + } + auto row2 = results2.begin(); + members[0] = nullptr; + strn0cpy(membername[0], row2[0], 64); return true; } @@ -1212,6 +1249,22 @@ void Group::VerifyGroup() { Only called every once in a while (on member re-join for now). */ + // To do + // Reset the membername array to match the group_id database records? + // When doing this manually, it seem to have resolved the issue. + // Only want to do this when the database Name does not match the array + // Could this be done from the LearnGroup method? + // reset the members and membername array for this group + // Mitch + for (int i = 0; i < MAX_GROUP_MEMBERS; i++) { + members[i] = nullptr; + memset(membername[i],'\0',64); + //membername[i][0] == '\0'); + } + // repopulate the membername array from the database to ensure the local zone instance has accurate information + + Group::LearnMembers(); + uint32 i; for (i = 0; i < MAX_GROUP_MEMBERS; i++) { if (membername[i][0] == '\0') { @@ -1231,6 +1284,10 @@ void Group::VerifyGroup() { members[i] = nullptr; continue; } + //if (them == nullptr && members[i] == nullptr) { //fixes a group bug with bots Mitch added Jan 1 2022 + // membername[i][0] = '\0'; + // continue; + //} if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good. #if EQDEBUG >= 5