summaryrefslogtreecommitdiff
path: root/indra/newview/llgroupmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llgroupmgr.cpp')
-rw-r--r--[-rwxr-xr-x]indra/newview/llgroupmgr.cpp326
1 files changed, 215 insertions, 111 deletions
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 86f9da6318..7545112ab9 100755..100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -41,7 +41,6 @@
#include "llui.h"
#include "message.h"
#include "roles_constants.h"
-#include "llhttpclient.h"
#include "lltransactiontypes.h"
#include "llstatusbar.h"
#include "lleconomy.h"
@@ -53,6 +52,7 @@
#include "lltrans.h"
#include "llviewerregion.h"
#include <boost/regex.hpp>
+#include "llcorehttputil.h"
#if LL_MSVC
#pragma warning(push)
@@ -239,7 +239,8 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) :
mRoleMemberDataComplete(false),
mGroupPropertiesDataComplete(false),
mPendingRoleMemberRequest(false),
- mAccessTime(0.0f)
+ mAccessTime(0.0f),
+ mPendingBanRequest(false)
{
mMemberVersion.generate();
}
@@ -761,16 +762,77 @@ void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id)
mBanList.erase(ban_id);
}
+void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
+{
+ if (!mMemberDataComplete ||
+ !mRoleDataComplete ||
+ !(mRoleMemberDataComplete && mMembers.size()))
+ {
+ LL_WARNS() << "No Role-Member data yet, setting ban request to pending." << LL_ENDL;
+ mPendingBanRequest = true;
+ mPendingBanMemberID = participant_uuid;
+
+ if (!mMemberDataComplete || !mMembers.size())
+ {
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mID);
+ }
+
+ if (!mRoleDataComplete)
+ {
+ LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mID);
+ }
+
+ return;
+ }
+
+ LLGroupMgrGroupData::member_list_t::iterator mi = mMembers.find((participant_uuid));
+ if (mi == mMembers.end())
+ {
+ if (!mPendingBanRequest)
+ {
+ mPendingBanRequest = true;
+ mPendingBanMemberID = participant_uuid;
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mID); // member isn't in members list, request reloading
+ }
+ else
+ {
+ mPendingBanRequest = false;
+ }
+
+ return;
+ }
+
+ mPendingBanRequest = false;
+
+ LLGroupMemberData* member_data = (*mi).second;
+ if (member_data && member_data->isInRole(mOwnerRole))
+ {
+ return; // can't ban group owner
+ }
+ std::vector<LLUUID> ids;
+ ids.push_back(participant_uuid);
+ LLGroupBanData ban_data;
+ createBanEntry(participant_uuid, ban_data);
+ LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mID, LLGroupMgr::BAN_CREATE, ids);
+ LLGroupMgr::getInstance()->sendGroupMemberEjects(mID, ids);
+ LLGroupMgr::getInstance()->sendGroupMembersRequest(mID);
+ LLSD args;
+ std::string name;
+ gCacheName->getFullName(participant_uuid, name);
+ args["AVATAR_NAME"] = name;
+ args["GROUP_NAME"] = mName;
+ LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
+}
//
// LLGroupMgr
//
-LLGroupMgr::LLGroupMgr()
+LLGroupMgr::LLGroupMgr():
+ mMemberRequestInFlight(false)
{
- mLastGroupMembersRequestFrame = 0;
}
LLGroupMgr::~LLGroupMgr()
@@ -991,6 +1053,11 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
{
LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;
+ if (!msg)
+ {
+ LL_ERRS() << "Can't access the messaging system" << LL_ENDL;
+ return;
+ }
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
if (gAgent.getID() != agent_id)
@@ -1245,6 +1312,11 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
group_datap->mChanged = TRUE;
LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_MEMBER_DATA);
+
+ if (group_datap->mPendingBanRequest)
+ {
+ group_datap->banMemberById(group_datap->mPendingBanMemberID);
+ }
}
// static
@@ -1861,49 +1933,94 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
group_datap->mMemberVersion.generate();
}
-
-// Responder class for capability group management
-class GroupBanDataResponder : public LLHTTPClient::Responder
+void LLGroupMgr::getGroupBanRequestCoro(std::string url, LLUUID groupId)
{
-public:
- GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false);
- virtual ~GroupBanDataResponder() {}
- virtual void httpSuccess();
- virtual void httpFailure();
-private:
- LLUUID mGroupID;
- BOOL mForceRefresh;
-};
+ 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);
-GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) :
- mGroupID(gropup_id),
- mForceRefresh(force_refresh)
-{}
+ std::string finalUrl = url + "?group_id=" + groupId.asString();
-void GroupBanDataResponder::httpFailure()
-{
- LL_WARNS("GrpMgr") << "Error receiving group member data [status:"
- << mStatus << "]: " << mContent << LL_ENDL;
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("GrpMgr") << "Error receiving group member data " << LL_ENDL;
+ return;
+ }
+
+ if (result.has("ban_list"))
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ // group ban data received
+ processGroupBanRequest(result);
+ }
}
-void GroupBanDataResponder::httpSuccess()
+void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID groupId,
+ U32 action, uuid_vec_t banList, bool update)
{
- if (mContent.has("ban_list"))
- {
- // group ban data received
- LLGroupMgr::processGroupBanRequest(mContent);
- }
- else if (mForceRefresh)
- {
- // no ban data received, refreshing data after successful operation
- LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID);
- }
+ 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::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions);
+
+ httpOptions->setFollowRedirects(false);
+
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+
+
+ std::string finalUrl = url + "?group_id=" + groupId.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)
+ {
+ banEntry = (*it);
+ postData["ban_ids"].append(banEntry);
+ }
+
+ LL_WARNS() << "post: " << ll_pretty_print_sd(postData) << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, finalUrl, postData, httpOptions, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("GrpMgr") << "Error posting group member data " << LL_ENDL;
+ return;
+ }
+
+ if (result.has("ban_list"))
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ // group ban data received
+ processGroupBanRequest(result);
+ }
+
+ if (update)
+ {
+ getGroupBanRequestCoro(url, groupId);
+ }
}
void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type,
const LLUUID& group_id,
U32 ban_action, /* = BAN_NO_ACTION */
- const std::vector<LLUUID> ban_list) /* = std::vector<LLUUID>() */
+ const std::vector<LLUUID> &ban_list) /* = std::vector<LLUUID>() */
{
LLViewerRegion* currentRegion = gAgent.getRegion();
if(!currentRegion)
@@ -1925,37 +2042,27 @@ void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type,
{
return;
}
- cap_url += "?group_id=" + group_id.asString();
- LLSD body = LLSD::emptyMap();
- body["ban_action"] = (LLSD::Integer)(ban_action & ~BAN_UPDATE);
- // Add our list of potential banned residents to the list
- body["ban_ids"] = LLSD::emptyArray();
- LLSD ban_entry;
-
- uuid_vec_t::const_iterator iter = ban_list.begin();
- for(;iter != ban_list.end(); ++iter)
- {
- ban_entry = (*iter);
- body["ban_ids"].append(ban_entry);
- }
+ U32 action = ban_action & ~BAN_UPDATE;
+ bool update = ((ban_action & BAN_UPDATE) == BAN_UPDATE);
- LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE);
- switch(request_type)
- {
- case REQUEST_GET:
- LLHTTPClient::get(cap_url, grp_ban_responder);
- break;
- case REQUEST_POST:
- LLHTTPClient::post(cap_url, body, grp_ban_responder);
- break;
- case REQUEST_PUT:
- case REQUEST_DEL:
- break;
- }
+ switch (request_type)
+ {
+ case REQUEST_GET:
+ LLCoros::instance().launch("LLGroupMgr::getGroupBanRequestCoro",
+ boost::bind(&LLGroupMgr::getGroupBanRequestCoro, this, cap_url, group_id));
+ break;
+ case REQUEST_POST:
+ LLCoros::instance().launch("LLGroupMgr::postGroupBanRequestCoro",
+ boost::bind(&LLGroupMgr::postGroupBanRequestCoro, this, cap_url, group_id,
+ action, ban_list, update));
+ break;
+ case REQUEST_PUT:
+ case REQUEST_DEL:
+ break;
+ }
}
-
void LLGroupMgr::processGroupBanRequest(const LLSD& content)
{
// Did we get anything in content?
@@ -1993,45 +2100,42 @@ void LLGroupMgr::processGroupBanRequest(const LLSD& content)
LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST);
}
+void LLGroupMgr::groupMembersRequestCoro(std::string url, LLUUID groupId)
+{
+ 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;
-// Responder class for capability group management
-class GroupMemberDataResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(GroupMemberDataResponder);
-public:
- GroupMemberDataResponder() {}
- virtual ~GroupMemberDataResponder() {}
+ LLSD postData = LLSD::emptyMap();
+ postData["group_id"] = groupId;
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
- LLSD mMemberData;
-};
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData, httpOpts);
-void GroupMemberDataResponder::httpFailure()
-{
- LL_WARNS("GrpMgr") << "Error receiving group member data "
- << dumpResponse() << LL_ENDL;
-}
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-void GroupMemberDataResponder::httpSuccess()
-{
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- LLGroupMgr::processCapGroupMembersRequest(content);
-}
+ 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;
+}
-// static
void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
{
+ static U32 lastGroupMemberRequestFrame = 0;
+
// Have we requested the information already this frame?
- if(mLastGroupMembersRequestFrame == gFrameCount)
+ if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
return;
LLViewerRegion* currentRegion = gAgent.getRegion();
@@ -2060,20 +2164,13 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
return;
}
- // Post to our service. Add a body containing the group_id.
- LLSD body = LLSD::emptyMap();
- body["group_id"] = group_id;
-
- LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
-
- // This could take a while to finish, timeout after 5 minutes.
- LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300);
+ lastGroupMemberRequestFrame = gFrameCount;
- mLastGroupMembersRequestFrame = gFrameCount;
+ LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",
+ boost::bind(&LLGroupMgr::groupMembersRequestCoro, this, cap_url, group_id));
}
-// static
void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
{
// Did we get anything in content?
@@ -2083,20 +2180,27 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
return;
}
- // If we have no members, there's no reason to do anything else
- S32 num_members = content["member_count"];
- if(num_members < 1)
- return;
-
LLUUID group_id = content["group_id"].asUUID();
- LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
+ LLGroupMgrGroupData* group_datap = getGroupData(group_id);
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 member_list = content["members"];
@@ -2184,7 +2288,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
// TODO:
// Refactor to reduce multiple calls for data we already have.
if(group_datap->mTitles.size() < 1)
- LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
+ sendGroupTitlesRequest(group_id);
group_datap->mMemberDataComplete = true;
@@ -2193,11 +2297,11 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete)
{
group_datap->mPendingRoleMemberRequest = false;
- LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
+ sendGroupRoleMembersRequest(group_id);
}
group_datap->mChanged = TRUE;
- LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
+ notifyObservers(GC_MEMBER_DATA);
}