From 7517895b6f5c7c478954b246b55ca0b013562a09 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Wed, 15 Nov 2023 22:29:32 -0500 Subject: [PATCH] Fix various crashes and bugs in group code --- indra/newview/llgroupmgr.cpp | 30 ++++++++++++++----------- indra/newview/llgroupmgr.h | 34 ++++++++++++++++++++++++++--- indra/newview/llpanelgrouproles.cpp | 17 +++++++++++++-- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 1792af64f97..ca9f210f677 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -250,8 +250,12 @@ BOOL LLGroupMgrGroupData::getRoleData(const LLUUID& role_id, LLRoleData& role_da role_list_t::const_iterator rit = mRoles.find(role_id); if (rit != mRoles.end()) { - role_data = (*rit).second->getRoleData(); - return TRUE; + auto& role_datap = rit->second; + if (role_datap) + { + role_data = role_datap->getRoleData(); + return TRUE; + } } // This role must not exist. @@ -1451,11 +1455,11 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) { LLGroupMgrGroupData* group_datap = NULL; - group_map_t::iterator existing_group = LLGroupMgr::getInstance()->mGroups.find(id); - if (existing_group == LLGroupMgr::getInstance()->mGroups.end()) + group_map_t::iterator existing_group = mGroups.find(id); + if (existing_group == mGroups.end()) { group_datap = new LLGroupMgrGroupData(id); - LLGroupMgr::getInstance()->addGroup(group_datap); + addGroup(group_datap); } else { @@ -1472,8 +1476,8 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) bool LLGroupMgr::hasPendingPropertyRequest(const LLUUID & id) { - properties_request_map_t::iterator existing_req = LLGroupMgr::getInstance()->mPropRequests.find(id); - if (existing_req != LLGroupMgr::getInstance()->mPropRequests.end()) + properties_request_map_t::iterator existing_req = mPropRequests.find(id); + if (existing_req != mPropRequests.end()) { if (gFrameTime - existing_req->second < MIN_GROUP_PROPERTY_REQUEST_FREQ) { @@ -1481,7 +1485,7 @@ bool LLGroupMgr::hasPendingPropertyRequest(const LLUUID & id) } else { - LLGroupMgr::getInstance()->mPropRequests.erase(existing_req); + mPropRequests.erase(existing_req); } } return false; @@ -1489,7 +1493,7 @@ bool LLGroupMgr::hasPendingPropertyRequest(const LLUUID & id) void LLGroupMgr::addPendingPropertyRequest(const LLUUID& id) { - LLGroupMgr::getInstance()->mPropRequests.insert_or_assign(id, gFrameTime); + mPropRequests.insert_or_assign(id, gFrameTime); } void LLGroupMgr::notifyObservers(LLGroupChange gc) @@ -1579,12 +1583,12 @@ void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id) // This will happen when we get the reply //LLGroupMgrGroupData* group_datap = createGroupData(group_id); - if (LLGroupMgr::getInstance()->hasPendingPropertyRequest(group_id)) + if (hasPendingPropertyRequest(group_id)) { LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest suppressed repeat for " << group_id << LL_ENDL; return; } - LLGroupMgr::getInstance()->addPendingPropertyRequest(group_id); + addPendingPropertyRequest(group_id); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_GroupProfileRequest); @@ -1926,7 +1930,7 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, for (LLGroupMemberData::role_list_t::iterator rit = member_data->roleBegin(); rit != member_data->roleEnd(); ++rit) { - if ((*rit).first.notNull() && (*rit).second != 0) + if ((*rit).first.notNull() && (*rit).second != nullptr) { (*rit).second->removeMember(ejected_member_id); } @@ -2213,7 +2217,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) // Set mMemberDataComplete for correct handling of empty responses. See MAINT-5237 group_datap->mMemberDataComplete = true; group_datap->mChanged = TRUE; - LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); + notifyObservers(GC_MEMBER_DATA); return; } diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 2fac45ece7d..4fc56a9b4da 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -77,7 +77,7 @@ class LLGroupMemberData friend class LLGroupMgrGroupData; public: - typedef boost::unordered_flat_map<LLUUID, LLGroupRoleData*> role_list_t; + typedef boost::unordered_map<LLUUID,LLGroupRoleData*> role_list_t; LLGroupMemberData(const LLUUID& id, S32 contribution, @@ -102,8 +102,6 @@ friend class LLGroupMgrGroupData; BOOL isInRole(const LLUUID& role_id) { return (mRolesList.find(role_id) != mRolesList.end()); } - const role_list_t& getRoles() { return mRolesList; } - LLUUID mID; S32 mContribution; U64 mAgentPowers; @@ -117,6 +115,36 @@ struct LLRoleData { LLRoleData() : mRolePowers(0), mChangeType(RC_UPDATE_NONE) { } + LLRoleData(const LLRoleData& rd) + { + *this = rd; + } + + LLRoleData(LLRoleData&& rd) + { + *this = std::move(rd); + } + + LLRoleData& operator=(const LLRoleData& rd) + { + mRoleName = rd.mRoleName; + mRoleTitle = rd.mRoleTitle; + mRoleDescription = rd.mRoleDescription; + mRolePowers = rd.mRolePowers; + mChangeType = rd.mChangeType; + return *this; + }; + + LLRoleData& operator=(LLRoleData&& rd) noexcept + { + mRoleName = std::move(rd.mRoleName); + mRoleTitle = std::move(rd.mRoleTitle); + mRoleDescription = std::move(rd.mRoleDescription); + mRolePowers = rd.mRolePowers; + mChangeType = rd.mChangeType; + return *this; + }; + std::string mRoleName; std::string mRoleTitle; std::string mRoleDescription; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 3cef4c00102..c3721ddfa0c 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -423,6 +423,10 @@ void LLPanelGroupRoles::setGroupID(const LLUUID& id) if ( button ) button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); + button = getChild<LLButton>("export_list"); + if (button) + button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_VISIBLE_IN_DIR)); + if(mSubTabContainer) mSubTabContainer->selectTab(1); group_roles_tab->mFirstOpen = TRUE; @@ -1089,7 +1093,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() else { // This could happen if changes are not synced right on sub-panel change. - LL_WARNS() << "No group role data for " << iter->second->getID() << LL_ENDL; + LL_WARNS() << "No group role data for " << iter->first << LL_ENDL; } } mAssignedRolesList->setEnabled(TRUE); @@ -1815,6 +1819,15 @@ void LLPanelGroupMembersSubTab::updateMembers() mMembersList->deleteAllItems(); } + for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + } + mAvatarNameCacheConnections.clear(); + LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); LLTimer update_time; @@ -2403,7 +2416,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect() mSelectedRole = item->getUUID(); buildMembersList(); - mCopyRoleButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE)); + mCopyRoleButton->setEnabled((gdatap->mRoles.size() < (U32)MAX_ROLES) && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE)); can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_DELETE); mDeleteRoleButton->setEnabled(can_delete); -- GitLab