summaryrefslogtreecommitdiff
path: root/indra/newview/llgroupmgr.cpp
diff options
context:
space:
mode:
authorAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2024-07-23 10:45:57 +0200
committerGuru <alexandrgproductengine@lindenlab.com>2024-07-24 16:58:25 +0200
commitaaa5caeca89cb08f785fec1785d8edeca6eda0ae (patch)
tree34563ca873300f07f8a3533e64a8a58a386fc116 /indra/newview/llgroupmgr.cpp
parent57e78ed43b61864a6b8a54df95d8823daaeb5fe8 (diff)
#1318 Pagination in the Group Interface
Diffstat (limited to 'indra/newview/llgroupmgr.cpp')
-rw-r--r--indra/newview/llgroupmgr.cpp248
1 files changed, 128 insertions, 120 deletions
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 1057bc25e0..090ed7b0e2 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -806,7 +806,7 @@ void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
mPendingBanRequest = false;
- LLGroupMemberData* member_data = (*mi).second;
+ LLGroupMemberData* member_data = mi->second;
if (member_data && member_data->isInRole(mOwnerRole))
{
return; // can't ban group owner
@@ -832,8 +832,7 @@ void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
// LLGroupMgr
//
-LLGroupMgr::LLGroupMgr():
- mMemberRequestInFlight(false)
+LLGroupMgr::LLGroupMgr()
{
}
@@ -968,11 +967,11 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
if (!group_datap || (group_datap->mMemberRequestID != request_id))
{
- LL_WARNS() << "processGroupMembersReply: Received incorrect (stale?) group or request id" << LL_ENDL;
+ LL_WARNS() << "Received incorrect (stale?) group or request id" << LL_ENDL;
return;
}
- msg->getS32(_PREHASH_GroupData, "MemberCount", group_datap->mMemberCount );
+ msg->getS32Fast(_PREHASH_GroupData, _PREHASH_MemberCount, group_datap->mMemberCount);
if (group_datap->mMemberCount > 0)
{
@@ -987,12 +986,12 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
{
LLUUID member_id;
- msg->getUUIDFast(_PREHASH_MemberData, _PREHASH_AgentID, member_id, i );
- msg->getS32(_PREHASH_MemberData, _PREHASH_Contribution, contribution, i);
- msg->getU64(_PREHASH_MemberData, "AgentPowers", agent_powers, i);
+ msg->getUUIDFast(_PREHASH_MemberData, _PREHASH_AgentID, member_id, i);
+ msg->getS32Fast(_PREHASH_MemberData, _PREHASH_Contribution, contribution, i);
+ msg->getU64Fast(_PREHASH_MemberData, _PREHASH_AgentPowers, agent_powers, i);
msg->getStringFast(_PREHASH_MemberData, _PREHASH_OnlineStatus, online_status, i);
- msg->getString(_PREHASH_MemberData, "Title", title, i);
- msg->getBOOL(_PREHASH_MemberData,"IsOwner",is_owner,i);
+ msg->getStringFast(_PREHASH_MemberData, _PREHASH_Title, title, i);
+ msg->getBOOLFast(_PREHASH_MemberData, _PREHASH_IsOwner, is_owner, i);
if (member_id.notNull())
{
@@ -1037,7 +1036,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
group_datap->mMemberVersion.generate();
- if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount)
+ if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount)
{
group_datap->mMemberDataComplete = true;
group_datap->mMemberRequestID.setNull();
@@ -1678,13 +1677,12 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
if (group_datap->mRoleMembersRequestID.isNull())
{
// Don't send the request if we don't have all the member or role data
- if (!group_datap->isMemberDataComplete()
- || !group_datap->isRoleDataComplete())
+ if (!group_datap->isMemberDataComplete() || !group_datap->isRoleDataComplete())
{
// *TODO: KLW FIXME: Should we start a member or role data request?
LL_INFOS("GrpMgr") << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")
- << " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N")
- << " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << LL_ENDL;
+ << ", MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N")
+ << ", RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << LL_ENDL;
group_datap->mPendingRoleMemberRequest = true;
return;
}
@@ -1984,14 +1982,14 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
group_datap->mMemberVersion.generate();
}
-void LLGroupMgr::getGroupBanRequestCoro(std::string url, LLUUID groupId)
+void LLGroupMgr::getGroupBanRequestCoro(std::string url, LLUUID group_id)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- std::string finalUrl = url + "?group_id=" + groupId.asString();
+ std::string finalUrl = url + "?group_id=" + group_id.asString();
LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl);
@@ -2012,8 +2010,8 @@ void LLGroupMgr::getGroupBanRequestCoro(std::string url, LLUUID groupId)
}
}
-void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID groupId,
- U32 action, uuid_vec_t banList, bool update)
+void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID group_id,
+ U32 action, uuid_vec_t ban_list, bool update)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
@@ -2026,20 +2024,16 @@ void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID groupId,
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
-
- std::string finalUrl = url + "?group_id=" + groupId.asString();
+ std::string finalUrl = url + "?group_id=" + group_id.asString();
LLSD postData = LLSD::emptyMap();
postData["ban_action"] = (LLSD::Integer)action;
// Add our list of potential banned residents to the list
postData["ban_ids"] = LLSD::emptyArray();
- LLSD banEntry;
- uuid_vec_t::const_iterator it = banList.begin();
- for (; it != banList.end(); ++it)
+ for (const LLUUID& ban_id : ban_list)
{
- banEntry = (*it);
- postData["ban_ids"].append(banEntry);
+ postData["ban_ids"].append(ban_id);
}
LL_WARNS() << "post: " << ll_pretty_print_sd(postData) << LL_ENDL;
@@ -2064,7 +2058,7 @@ void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID groupId,
if (update)
{
- getGroupBanRequestCoro(url, groupId);
+ getGroupBanRequestCoro(url, group_id);
}
}
@@ -2151,55 +2145,66 @@ void LLGroupMgr::processGroupBanRequest(const LLSD& content)
LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST);
}
-void LLGroupMgr::groupMembersRequestCoro(std::string url, LLUUID groupId)
+void LLGroupMgr::groupMembersRequestCoro(std::string url, LLUUID group_id, U32 page_size, U32 page_start, std::string sort_column)
{
+ LL_INFOS("GrpMgr") << "group_id: '" << group_id << "', sort_column: '" << sort_column << "', page_size: " << page_size << ", page_start: " << page_start << LL_ENDL;
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
-
- mMemberRequestInFlight = true;
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
LLSD postData = LLSD::emptyMap();
- postData["group_id"] = groupId;
+ postData["group_id"] = group_id;
+ if (page_size)
+ {
+ postData["page_size"] = LLSD::Integer(page_size);
+ if (page_start)
+ {
+ postData["page_start"] = LLSD::Integer(page_start);
+ }
+ if (!sort_column.empty())
+ {
+ postData["sort_column"] = sort_column;
+ }
+ }
- LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData, httpOpts);
+ LLSD response = httpAdapter->postAndSuspend(httpRequest, url, postData, httpOpts);
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ mMemberRequestInFlight = false;
+
+ LLSD httpResults = response.get(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
LL_WARNS("GrpMgr") << "Error receiving group member data " << LL_ENDL;
- mMemberRequestInFlight = false;
return;
}
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- LLGroupMgr::processCapGroupMembersRequest(result);
- mMemberRequestInFlight = false;
+ response.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ processCapGroupMembersResponse(response, page_size, page_start, sort_column);
}
-void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
+void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id, U32 page_size, U32 page_start, const std::string& sort_column)
{
static U32 lastGroupMemberRequestFrame = 0;
// Have we requested the information already this frame?
// Todo: make this per group, we can invite to one group and simultaneously be checking another one
- if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
+ if ((lastGroupMemberRequestFrame == gFrameCount) || mMemberRequestInFlight)
return;
LLViewerRegion* currentRegion = gAgent.getRegion();
// Thank you FS:Ansariel!
- if(!currentRegion)
+ if (!currentRegion)
{
LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL;
return;
}
// Check to make sure we have our capabilities
- if(!currentRegion->capabilitiesReceived())
+ if (!currentRegion->capabilitiesReceived())
{
LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL;
return;
@@ -2209,9 +2214,9 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
std::string cap_url = currentRegion->getCapability("GroupMemberData");
// Thank you FS:Ansariel!
- if(cap_url.empty())
+ if (cap_url.empty())
{
- LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL;
+ LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL;
sendGroupMembersRequest(group_id);
return;
}
@@ -2221,120 +2226,121 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
lastGroupMemberRequestFrame = gFrameCount;
- LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",
- boost::bind(&LLGroupMgr::groupMembersRequestCoro, this, cap_url, group_id));
-}
+ mMemberRequestInFlight = true;
+ LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro", [&]()
+ {
+ groupMembersRequestCoro(cap_url, group_id, page_size, page_start, sort_column);
+ });
+}
-void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
+void LLGroupMgr::processCapGroupMembersResponse(const LLSD& response, U32 page_size, U32 page_start, const std::string& sort_column)
{
+ LLUUID group_id = response["group_id"].asUUID();
+ LL_INFOS("GrpMgr") << "group_id: '" << group_id << "', sort_column: '" << sort_column << "', page_size: " << page_size << ", page_start: " << page_start << LL_ENDL;
+
// Did we get anything in content?
- if(!content.size())
+ if (!response.size())
{
- LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL;
+ LL_INFOS("GrpMgr") << "No group member data received." << LL_ENDL;
return;
}
- LLUUID group_id = content["group_id"].asUUID();
-
LLGroupMgrGroupData* group_datap = getGroupData(group_id);
- if(!group_datap)
+ if (!group_datap)
{
LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL;
return;
}
- // If we have no members, there's no reason to do anything else
- S32 num_members = content["member_count"];
- if (num_members < 1)
- {
- LL_INFOS("GrpMgr") << "Received empty group members list for group id: " << group_id.asString() << LL_ENDL;
- // 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);
- return;
- }
-
- group_datap->mMemberCount = num_members;
+ LLSD members = response["members"];
+ LLSD titles = response["titles"];
+ LLSD defaults = response["defaults"];
- LLSD member_list = content["members"];
- LLSD titles = content["titles"];
- LLSD defaults = content["defaults"];
-
- std::string online_status;
- std::string title;
- S32 contribution;
- U64 member_powers;
- // If this is changed to a bool, make sure to change the LLGroupMemberData constructor
- bool is_owner;
+ size_t members_before = group_datap->mMembers.size();
+ size_t members_loaded = members.size();
// Compute this once, rather than every time.
- U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16);
+ std::string default_title = titles.size() ? titles[0].asString() : LLStringUtil::null;
+ U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16);
- LLSD::map_const_iterator member_iter_start = member_list.beginMap();
- LLSD::map_const_iterator member_iter_end = member_list.endMap();
- for( ; member_iter_start != member_iter_end; ++member_iter_start)
+ auto members_end = members.endMap();
+ for (auto it = members.beginMap(); it != members_end; ++it)
{
// Reset defaults
- online_status = "unknown";
- title = titles[0].asString();
- contribution = 0;
- member_powers = default_powers;
- is_owner = false;
+ std::string online_status = "unknown";
+ std::string title = default_title;
+ U64 member_powers = default_powers;
+ S32 donated_square_meters = 0;
+ bool is_owner = false;
- const LLUUID member_id(member_iter_start->first);
- LLSD member_info = member_iter_start->second;
+ const LLUUID member_id(it->first);
+ LLSD member_info = it->second;
- if(member_info.has("last_login"))
+ if (member_info.has("last_login"))
{
online_status = member_info["last_login"].asString();
- if(online_status == "Online")
+ if (online_status == "Online")
+ {
online_status = LLTrans::getString("group_member_status_online");
+ }
else
+ {
formatDateString(online_status);
+ }
}
- if(member_info.has("title"))
+ if (member_info.has("title"))
+ {
title = titles[member_info["title"].asInteger()].asString();
+ }
- if(member_info.has("powers"))
+ if (member_info.has("powers"))
+ {
member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16);
+ }
- if(member_info.has("donated_square_meters"))
- contribution = member_info["donated_square_meters"];
+ if (member_info.has("donated_square_meters"))
+ {
+ donated_square_meters = member_info["donated_square_meters"];
+ }
- if(member_info.has("owner"))
+ if (member_info.has("owner"))
+ {
is_owner = true;
+ }
LLGroupMemberData* data = new LLGroupMemberData(member_id,
- contribution,
- member_powers,
- title,
- online_status,
- is_owner);
-
- LLGroupMemberData* member_old = group_datap->mMembers[member_id];
- if (member_old && group_datap->mRoleMemberDataComplete)
- {
- LLGroupMemberData::role_list_t::iterator rit = member_old->roleBegin();
- LLGroupMemberData::role_list_t::iterator end = member_old->roleEnd();
+ donated_square_meters, member_powers, title, online_status, is_owner);
- for ( ; rit != end; ++rit)
+ if (group_datap->mRoleMemberDataComplete)
+ {
+ if (LLGroupMemberData* member_old = group_datap->mMembers[member_id])
{
- data->addRole((*rit).first,(*rit).second);
+ auto role_end = member_old->roleEnd();
+ for (auto role_it = member_old->roleBegin(); role_it != role_end; ++role_it)
+ {
+ data->addRole(role_it->first, role_it->second);
+ }
+ }
+ else
+ {
+ group_datap->mRoleMemberDataComplete = false;
}
- }
- else
- {
- group_datap->mRoleMemberDataComplete = false;
}
group_datap->mMembers[member_id] = data;
}
+ group_datap->mMemberCount = (S32)group_datap->mMembers.size();
+ group_datap->mMemberDataComplete = true;
+ group_datap->mMemberRequestID.setNull();
group_datap->mMemberVersion.generate();
+ LL_INFOS("GrpMgr") << "members before: " << members_before
+ << ", members loaded: " << members_loaded
+ << ", members now: " << group_datap->mMemberCount << LL_ENDL;
+
// Technically, we have this data, but to prevent completely overhauling
// this entire system (it would be nice, but I don't have the time),
// I'm going to be dumb and just call services I most likely don't need
@@ -2342,12 +2348,16 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
//
// TODO:
// Refactor to reduce multiple calls for data we already have.
- if(group_datap->mTitles.size() < 1)
+ if (group_datap->mTitles.size() < 1)
+ {
sendGroupTitlesRequest(group_id);
+ }
+ if (page_size && members_loaded >= page_size)
+ {
+ sendCapGroupMembersRequest(group_id, page_size, (U32)group_datap->mMemberCount, sort_column);
+ }
- group_datap->mMemberDataComplete = true;
- group_datap->mMemberRequestID.setNull();
// Make the role-member data request
if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete)
{
@@ -2357,10 +2367,8 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
group_datap->mChanged = true;
notifyObservers(GC_MEMBER_DATA);
-
}
-
void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
{
LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL;
@@ -2379,9 +2387,11 @@ void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id)
{
LL_DEBUGS("GrpMgr") << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL;
- LLGroupMgrGroupData* group_datap = getGroupData(group_id);
- if (group_datap) group_datap->cancelRoleChanges();
+ if (LLGroupMgrGroupData* group_datap = getGroupData(group_id))
+ {
+ group_datap->cancelRoleChanges();
+ }
}
//static
@@ -2503,5 +2513,3 @@ void LLGroupMgr::debugClearAllGroups(void*)
LLGroupMgr::getInstance()->clearGroups();
LLGroupMgr::parseRoleActions("role_actions.xml");
}
-
-