00001
00037 #include "llviewerprecompiledheaders.h"
00038
00039 #include "llgroupmgr.h"
00040
00041 #include <vector>
00042 #include <algorithm>
00043
00044 #include "llagent.h"
00045 #include "llui.h"
00046 #include "message.h"
00047 #include "roles_constants.h"
00048 #include "lltransactiontypes.h"
00049 #include "llstatusbar.h"
00050 #include "lleconomy.h"
00051 #include "llviewerwindow.h"
00052 #include "llfloaterdirectory.h"
00053 #include "llfloatergroupinfo.h"
00054 #include "lluictrlfactory.h"
00055
00056
00057 const U32 MAX_CACHED_GROUPS = 10;
00058
00059
00060
00061
00062 LLRoleActionSet::LLRoleActionSet()
00063 : mActionSetData(NULL)
00064 { }
00065
00066 LLRoleActionSet::~LLRoleActionSet()
00067 {
00068 delete mActionSetData;
00069 std::for_each(mActions.begin(), mActions.end(), DeletePointer());
00070 }
00071
00072
00073
00074
00075
00076 LLGroupMemberData::LLGroupMemberData(const LLUUID& id,
00077 S32 contribution,
00078 U64 agent_powers,
00079 const std::string& title,
00080 const std::string& online_status,
00081 BOOL is_owner) :
00082 mID(id),
00083 mContribution(contribution),
00084 mAgentPowers(agent_powers),
00085 mTitle(title),
00086 mOnlineStatus(online_status),
00087 mIsOwner(is_owner)
00088 {
00089 }
00090
00091 LLGroupMemberData::~LLGroupMemberData()
00092 {
00093 }
00094
00095 void LLGroupMemberData::addRole(const LLUUID& role, LLGroupRoleData* rd)
00096 {
00097 mRolesList[role] = rd;
00098 }
00099
00100 bool LLGroupMemberData::removeRole(const LLUUID& role)
00101 {
00102 role_list_t::iterator it = mRolesList.find(role);
00103
00104 if (it != mRolesList.end())
00105 {
00106 mRolesList.erase(it);
00107 return true;
00108 }
00109
00110 return false;
00111 }
00112
00113
00114
00115
00116
00117 LLGroupRoleData::LLGroupRoleData(const LLUUID& role_id,
00118 const std::string& role_name,
00119 const std::string& role_title,
00120 const std::string& role_desc,
00121 const U64 role_powers,
00122 const S32 member_count) :
00123 mRoleID(role_id),
00124 mMemberCount(member_count),
00125 mMembersNeedsSort(FALSE)
00126 {
00127 mRoleData.mRoleName = role_name;
00128 mRoleData.mRoleTitle = role_title;
00129 mRoleData.mRoleDescription = role_desc;
00130 mRoleData.mRolePowers = role_powers;
00131 mRoleData.mChangeType = RC_UPDATE_NONE;
00132 }
00133
00134 LLGroupRoleData::LLGroupRoleData(const LLUUID& role_id,
00135 LLRoleData role_data,
00136 const S32 member_count) :
00137 mRoleID(role_id),
00138 mRoleData(role_data),
00139 mMemberCount(member_count),
00140 mMembersNeedsSort(FALSE)
00141 {
00142
00143 }
00144
00145 LLGroupRoleData::~LLGroupRoleData()
00146 {
00147 }
00148
00149 S32 LLGroupRoleData::getMembersInRole(std::vector<LLUUID> members,
00150 BOOL needs_sort)
00151 {
00152 if (mRoleID.isNull())
00153 {
00154
00155
00156 return members.size();
00157 }
00158
00159
00160 if (mMembersNeedsSort)
00161 {
00162 std::sort(mMemberIDs.begin(), mMemberIDs.end());
00163 mMembersNeedsSort = FALSE;
00164 }
00165 if (needs_sort)
00166 {
00167
00168 std::sort(members.begin(), members.end());
00169 }
00170
00171
00172 S32 max_size = llmin( members.size(), mMemberIDs.size() );
00173 std::vector<LLUUID> in_role( max_size );
00174 std::vector<LLUUID>::iterator in_role_end;
00175 in_role_end = std::set_intersection(mMemberIDs.begin(), mMemberIDs.end(),
00176 members.begin(), members.end(),
00177 in_role.begin());
00178 return in_role_end - in_role.begin();
00179 }
00180
00181 void LLGroupRoleData::addMember(const LLUUID& member)
00182 {
00183 mMembersNeedsSort = TRUE;
00184 mMemberIDs.push_back(member);
00185 }
00186
00187 bool LLGroupRoleData::removeMember(const LLUUID& member)
00188 {
00189 std::vector<LLUUID>::iterator it = std::find(mMemberIDs.begin(),mMemberIDs.end(),member);
00190
00191 if (it != mMemberIDs.end())
00192 {
00193 mMembersNeedsSort = TRUE;
00194 mMemberIDs.erase(it);
00195 return true;
00196 }
00197
00198 return false;
00199 }
00200
00201 void LLGroupRoleData::clearMembers()
00202 {
00203 mMembersNeedsSort = FALSE;
00204 mMemberIDs.clear();
00205 }
00206
00207
00208
00209
00210
00211
00212 LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) :
00213 mID(id),
00214 mShowInList(TRUE),
00215 mOpenEnrollment(FALSE),
00216 mMembershipFee(0),
00217 mAllowPublish(FALSE),
00218 mListInProfile(FALSE),
00219 mMaturePublish(FALSE),
00220 mChanged(FALSE),
00221 mMemberCount(0),
00222 mRoleCount(0),
00223 mReceivedRoleMemberPairs(0),
00224 mMemberDataComplete(FALSE),
00225 mRoleDataComplete(FALSE),
00226 mRoleMemberDataComplete(FALSE),
00227 mGroupPropertiesDataComplete(FALSE),
00228 mPendingRoleMemberRequest(FALSE)
00229 {
00230 }
00231
00232 BOOL LLGroupMgrGroupData::getRoleData(const LLUUID& role_id, LLRoleData& role_data)
00233 {
00234 role_data_map_t::const_iterator it;
00235
00236
00237 it = mRoleChanges.find(role_id);
00238 if (it != mRoleChanges.end())
00239 {
00240 if ((*it).second.mChangeType == RC_DELETE) return FALSE;
00241
00242 role_data = (*it).second;
00243 return TRUE;
00244 }
00245
00246
00247 role_list_t::const_iterator rit = mRoles.find(role_id);
00248 if (rit != mRoles.end())
00249 {
00250 role_data = (*rit).second->getRoleData();
00251 return TRUE;
00252 }
00253
00254
00255 return FALSE;
00256 }
00257
00258
00259 void LLGroupMgrGroupData::setRoleData(const LLUUID& role_id, LLRoleData role_data)
00260 {
00261
00262 role_data_map_t::iterator it;
00263 it = mRoleChanges.find(role_id);
00264 if (it != mRoleChanges.end())
00265 {
00266 if ((*it).second.mChangeType == RC_CREATE)
00267 {
00268 role_data.mChangeType = RC_CREATE;
00269 mRoleChanges[role_id] = role_data;
00270 return;
00271 }
00272 else if ((*it).second.mChangeType == RC_DELETE)
00273 {
00274
00275 return;
00276 }
00277 }
00278
00279
00280 LLRoleData old_role_data;
00281 role_list_t::iterator rit = mRoles.find(role_id);
00282 if (rit != mRoles.end())
00283 {
00284 bool data_change = ( ((*rit).second->mRoleData.mRoleDescription != role_data.mRoleDescription)
00285 || ((*rit).second->mRoleData.mRoleName != role_data.mRoleName)
00286 || ((*rit).second->mRoleData.mRoleTitle != role_data.mRoleTitle) );
00287 bool powers_change = ((*rit).second->mRoleData.mRolePowers != role_data.mRolePowers);
00288
00289 if (!data_change && !powers_change)
00290 {
00291
00292 mRoleChanges.erase(role_id);
00293 return;
00294 }
00295
00296 if (data_change && powers_change)
00297 {
00298 role_data.mChangeType = RC_UPDATE_ALL;
00299 }
00300 else if (data_change)
00301 {
00302 role_data.mChangeType = RC_UPDATE_DATA;
00303 }
00304 else
00305 {
00306 role_data.mChangeType = RC_UPDATE_POWERS;
00307 }
00308
00309 mRoleChanges[role_id] = role_data;
00310 }
00311 else
00312 {
00313 llwarns << "Change being made to non-existant role " << role_id << llendl;
00314 }
00315 }
00316
00317 BOOL LLGroupMgrGroupData::pendingRoleChanges()
00318 {
00319 return (!mRoleChanges.empty());
00320 }
00321
00322
00323 void LLGroupMgrGroupData::createRole(const LLUUID& role_id, LLRoleData role_data)
00324 {
00325 if (mRoleChanges.find(role_id) != mRoleChanges.end())
00326 {
00327 llwarns << "create role for existing role! " << role_id << llendl;
00328 }
00329 else
00330 {
00331 role_data.mChangeType = RC_CREATE;
00332 mRoleChanges[role_id] = role_data;
00333 }
00334 }
00335
00336 void LLGroupMgrGroupData::deleteRole(const LLUUID& role_id)
00337 {
00338 role_data_map_t::iterator it;
00339
00340
00341 it = mRoleChanges.find(role_id);
00342 if (it != mRoleChanges.end()
00343 && (*it).second.mChangeType == RC_CREATE)
00344 {
00345 mRoleChanges.erase(it);
00346 return;
00347 }
00348
00349 LLRoleData rd;
00350 rd.mChangeType = RC_DELETE;
00351 mRoleChanges[role_id] = rd;
00352 }
00353
00354 void LLGroupMgrGroupData::addRolePower(const LLUUID &role_id, U64 power)
00355 {
00356 LLRoleData rd;
00357 if (getRoleData(role_id,rd))
00358 {
00359 rd.mRolePowers |= power;
00360 setRoleData(role_id,rd);
00361 }
00362 else
00363 {
00364 llwarns << "addRolePower: no role data found for " << role_id << llendl;
00365 }
00366 }
00367
00368 void LLGroupMgrGroupData::removeRolePower(const LLUUID &role_id, U64 power)
00369 {
00370 LLRoleData rd;
00371 if (getRoleData(role_id,rd))
00372 {
00373 rd.mRolePowers &= ~power;
00374 setRoleData(role_id,rd);
00375 }
00376 else
00377 {
00378 llwarns << "removeRolePower: no role data found for " << role_id << llendl;
00379 }
00380 }
00381
00382 U64 LLGroupMgrGroupData::getRolePowers(const LLUUID& role_id)
00383 {
00384 LLRoleData rd;
00385 if (getRoleData(role_id,rd))
00386 {
00387 return rd.mRolePowers;
00388 }
00389 else
00390 {
00391 llwarns << "getRolePowers: no role data found for " << role_id << llendl;
00392 return GP_NO_POWERS;
00393 }
00394 }
00395
00396 void LLGroupMgrGroupData::removeData()
00397 {
00398
00399 removeMemberData();
00400 removeRoleData();
00401 }
00402
00403 void LLGroupMgrGroupData::removeMemberData()
00404 {
00405 for (member_list_t::iterator mi = mMembers.begin(); mi != mMembers.end(); ++mi)
00406 {
00407 delete mi->second;
00408 }
00409 mMembers.clear();
00410 mMemberDataComplete = FALSE;
00411 }
00412
00413 void LLGroupMgrGroupData::removeRoleData()
00414 {
00415 for (member_list_t::iterator mi = mMembers.begin(); mi != mMembers.end(); ++mi)
00416 {
00417 LLGroupMemberData* data = mi->second;
00418 if (data)
00419 {
00420 data->clearRoles();
00421 }
00422 }
00423
00424 for (role_list_t::iterator ri = mRoles.begin(); ri != mRoles.end(); ++ri)
00425 {
00426 LLGroupRoleData* data = ri->second;
00427 delete data;
00428 }
00429 mRoles.clear();
00430 mReceivedRoleMemberPairs = 0;
00431 mRoleDataComplete = FALSE;
00432 mRoleMemberDataComplete = FALSE;
00433 }
00434
00435 void LLGroupMgrGroupData::removeRoleMemberData()
00436 {
00437 for (member_list_t::iterator mi = mMembers.begin(); mi != mMembers.end(); ++mi)
00438 {
00439 LLGroupMemberData* data = mi->second;
00440 if (data)
00441 {
00442 data->clearRoles();
00443 }
00444 }
00445
00446 for (role_list_t::iterator ri = mRoles.begin(); ri != mRoles.end(); ++ri)
00447 {
00448 LLGroupRoleData* data = ri->second;
00449 if (data)
00450 {
00451 data->clearMembers();
00452 }
00453 }
00454
00455 mReceivedRoleMemberPairs = 0;
00456 mRoleMemberDataComplete = FALSE;
00457 }
00458
00459 LLGroupMgrGroupData::~LLGroupMgrGroupData()
00460 {
00461 removeData();
00462 }
00463
00464 bool LLGroupMgrGroupData::changeRoleMember(const LLUUID& role_id,
00465 const LLUUID& member_id,
00466 LLRoleMemberChangeType rmc)
00467 {
00468 role_list_t::iterator ri = mRoles.find(role_id);
00469 member_list_t::iterator mi = mMembers.find(member_id);
00470
00471 if (ri == mRoles.end()
00472 || mi == mMembers.end() )
00473 {
00474 if (ri == mRoles.end()) llwarns << "LLGroupMgrGroupData::changeRoleMember couldn't find role " << role_id << llendl;
00475 if (mi == mMembers.end()) llwarns << "LLGroupMgrGroupData::changeRoleMember couldn't find member " << member_id << llendl;
00476 return false;
00477 }
00478
00479 LLGroupRoleData* grd = ri->second;
00480 LLGroupMemberData* gmd = mi->second;
00481
00482 if (!grd || !gmd)
00483 {
00484 llwarns << "LLGroupMgrGroupData::changeRoleMember couldn't get member or role data." << llendl;
00485 return false;
00486 }
00487
00488 if (RMC_ADD == rmc)
00489 {
00490 llinfos << " adding member to role." << llendl;
00491 grd->addMember(member_id);
00492 gmd->addRole(role_id,grd);
00493
00494
00495
00496 gmd->mIsOwner = (role_id == mOwnerRole) ? TRUE : gmd->mIsOwner;
00497 }
00498 else if (RMC_REMOVE == rmc)
00499 {
00500 llinfos << " removing member from role." << llendl;
00501 grd->removeMember(member_id);
00502 gmd->removeRole(role_id);
00503
00504
00505 gmd->mIsOwner = (role_id == mOwnerRole) ? FALSE : gmd->mIsOwner;
00506 }
00507
00508 lluuid_pair role_member;
00509 role_member.first = role_id;
00510 role_member.second = member_id;
00511
00512 change_map_t::iterator it = mRoleMemberChanges.find(role_member);
00513 if (it != mRoleMemberChanges.end())
00514 {
00515
00516 if (it->second.mChange == rmc)
00517 {
00518
00519 llinfos << "Received duplicate change for "
00520 << " role: " << role_id << " member " << member_id
00521 << " change " << (rmc == RMC_ADD ? "ADD" : "REMOVE") << llendl;
00522 }
00523 else
00524 {
00525
00526
00527 if (rmc == RMC_NONE)
00528 {
00529 llwarns << "changeRoleMember: existing entry with 'RMC_NONE' change! This shouldn't happen." << llendl;
00530 LLRoleMemberChange rc(role_id,member_id,rmc);
00531 mRoleMemberChanges[role_member] = rc;
00532 }
00533 else
00534 {
00535 mRoleMemberChanges.erase(it);
00536 }
00537 }
00538 }
00539 else
00540 {
00541 LLRoleMemberChange rc(role_id,member_id,rmc);
00542 mRoleMemberChanges[role_member] = rc;
00543 }
00544
00545 recalcAgentPowers(member_id);
00546
00547 mChanged = TRUE;
00548 return true;
00549 }
00550
00551 void LLGroupMgrGroupData::recalcAllAgentPowers()
00552 {
00553 LLGroupMemberData* gmd;
00554
00555 for (member_list_t::iterator mit = mMembers.begin();
00556 mit != mMembers.end(); ++mit)
00557 {
00558 gmd = mit->second;
00559 if (!gmd) continue;
00560
00561 gmd->mAgentPowers = 0;
00562 for (LLGroupMemberData::role_list_t::iterator it = gmd->mRolesList.begin();
00563 it != gmd->mRolesList.end(); ++it)
00564 {
00565 LLGroupRoleData* grd = (*it).second;
00566 if (!grd) continue;
00567
00568 gmd->mAgentPowers |= grd->mRoleData.mRolePowers;
00569 }
00570 }
00571 }
00572
00573 void LLGroupMgrGroupData::recalcAgentPowers(const LLUUID& agent_id)
00574 {
00575 member_list_t::iterator mi = mMembers.find(agent_id);
00576 if (mi == mMembers.end()) return;
00577
00578 LLGroupMemberData* gmd = mi->second;
00579
00580 if (!gmd) return;
00581
00582 gmd->mAgentPowers = 0;
00583 for (LLGroupMemberData::role_list_t::iterator it = gmd->mRolesList.begin();
00584 it != gmd->mRolesList.end(); ++it)
00585 {
00586 LLGroupRoleData* grd = (*it).second;
00587 if (!grd) continue;
00588
00589 gmd->mAgentPowers |= grd->mRoleData.mRolePowers;
00590 }
00591 }
00592
00593 bool packRoleUpdateMessageBlock(LLMessageSystem* msg,
00594 const LLUUID& group_id,
00595 const LLUUID& role_id,
00596 const LLRoleData& role_data,
00597 bool start_message)
00598 {
00599 if (start_message)
00600 {
00601 msg->newMessage("GroupRoleUpdate");
00602 msg->nextBlock("AgentData");
00603 msg->addUUID("AgentID",gAgent.getID());
00604 msg->addUUID("SessionID",gAgent.getSessionID());
00605 msg->addUUID("GroupID",group_id);
00606 start_message = false;
00607 }
00608
00609 msg->nextBlock("RoleData");
00610 msg->addUUID("RoleID",role_id);
00611 msg->addString("Name", role_data.mRoleName);
00612 msg->addString("Description", role_data.mRoleDescription);
00613 msg->addString("Title", role_data.mRoleTitle);
00614 msg->addU64("Powers", role_data.mRolePowers);
00615 msg->addU8("UpdateType", (U8)role_data.mChangeType);
00616
00617 if (msg->isSendFullFast())
00618 {
00619 gAgent.sendReliableMessage();
00620 start_message = true;
00621 }
00622
00623 return start_message;
00624 }
00625
00626 void LLGroupMgrGroupData::sendRoleChanges()
00627 {
00628
00629 LLGroupRoleData* grd;
00630 role_list_t::iterator role_it;
00631 LLMessageSystem* msg = gMessageSystem;
00632 bool start_message = true;
00633
00634 bool need_role_cleanup = false;
00635 bool need_role_data = false;
00636 bool need_power_recalc = false;
00637
00638
00639 for (role_data_map_t::iterator iter = mRoleChanges.begin();
00640 iter != mRoleChanges.end(); )
00641 {
00642 role_data_map_t::iterator it = iter++;
00643 const LLUUID& role_id = (*it).first;
00644 const LLRoleData& role_data = (*it).second;
00645
00646
00647 role_it = mRoles.find((*it).first);
00648 if ( (mRoles.end() == role_it
00649 && RC_CREATE != role_data.mChangeType)
00650 || (mRoles.end() != role_it
00651 && RC_CREATE == role_data.mChangeType))
00652 {
00653 continue;
00654 }
00655
00656
00657 switch (role_data.mChangeType)
00658 {
00659 case RC_CREATE:
00660 {
00661
00662 grd = new LLGroupRoleData(role_id, role_data, 0);
00663 mRoles[role_id] = grd;
00664 need_role_data = true;
00665 break;
00666 }
00667 case RC_DELETE:
00668 {
00669 LLGroupRoleData* group_role_data = (*role_it).second;
00670 delete group_role_data;
00671 mRoles.erase(role_it);
00672 need_role_cleanup = true;
00673 need_power_recalc = true;
00674 break;
00675 }
00676 case RC_UPDATE_ALL:
00677 case RC_UPDATE_POWERS:
00678 need_power_recalc = true;
00679 case RC_UPDATE_DATA:
00680 default:
00681 {
00682 LLGroupRoleData* group_role_data = (*role_it).second;
00683 group_role_data->setRoleData(role_data);
00684 break;
00685 }
00686 }
00687
00688
00689 start_message = packRoleUpdateMessageBlock(msg,getID(),role_id,role_data,start_message);
00690 }
00691
00692 if (!start_message)
00693 {
00694 gAgent.sendReliableMessage();
00695 }
00696
00697
00698 if (need_role_cleanup)
00699 {
00700 removeRoleMemberData();
00701 }
00702
00703
00704 if (need_role_data)
00705 {
00706 LLGroupMgr::getInstance()->sendGroupRoleDataRequest(getID());
00707 }
00708
00709
00710 mRoleChanges.clear();
00711
00712
00713 if (need_power_recalc)
00714 {
00715 recalcAllAgentPowers();
00716 }
00717 }
00718
00719 void LLGroupMgrGroupData::cancelRoleChanges()
00720 {
00721
00722 mRoleChanges.clear();
00723 }
00724
00725
00726
00727
00728 LLGroupMgr::LLGroupMgr()
00729 {
00730 }
00731
00732 LLGroupMgr::~LLGroupMgr()
00733 {
00734 clearGroups();
00735 }
00736
00737 void LLGroupMgr::clearGroups()
00738 {
00739 std::for_each(mRoleActionSets.begin(), mRoleActionSets.end(), DeletePointer());
00740 mRoleActionSets.clear();
00741 std::for_each(mGroups.begin(), mGroups.end(), DeletePairedPointer());
00742 mGroups.clear();
00743 mObservers.clear();
00744 }
00745
00746 void LLGroupMgr::clearGroupData(const LLUUID& group_id)
00747 {
00748 group_map_t::iterator iter = mGroups.find(group_id);
00749 if (iter != mGroups.end())
00750 {
00751 delete (*iter).second;
00752 mGroups.erase(iter);
00753 }
00754 }
00755
00756 void LLGroupMgr::addObserver(LLGroupMgrObserver* observer)
00757 {
00758 mObservers.insert(std::pair<LLUUID, LLGroupMgrObserver*>(observer->getID(), observer));
00759 }
00760
00761 void LLGroupMgr::removeObserver(LLGroupMgrObserver* observer)
00762 {
00763 if (!observer)
00764 {
00765 return;
00766 }
00767 observer_multimap_t::iterator it;
00768 it = mObservers.find(observer->getID());
00769 while (it != mObservers.end())
00770 {
00771 if (it->second == observer)
00772 {
00773 mObservers.erase(it);
00774 break;
00775 }
00776 else
00777 {
00778 ++it;
00779 }
00780 }
00781 }
00782
00783 LLGroupMgrGroupData* LLGroupMgr::getGroupData(const LLUUID& id)
00784 {
00785 group_map_t::iterator gi = mGroups.find(id);
00786
00787 if (gi != mGroups.end())
00788 {
00789 return gi->second;
00790 }
00791 return NULL;
00792 }
00793
00794
00795 void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
00796 {
00797 lldebugs << "LLGroupMgr::processGroupMembersReply" << llendl;
00798 LLUUID agent_id;
00799 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
00800 if (gAgent.getID() != agent_id)
00801 {
00802 llwarns << "Got group properties reply for another agent!" << llendl;
00803 return;
00804 }
00805
00806 LLUUID group_id;
00807 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id );
00808
00809 LLUUID request_id;
00810 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_RequestID, request_id);
00811
00812 LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->createGroupData(group_id);
00813 if (group_datap->mMemberRequestID != request_id)
00814 {
00815 llwarns << "processGroupMembersReply: Received incorrect (stale?) request id" << llendl;
00816 return;
00817 }
00818
00819 msg->getS32(_PREHASH_GroupData, "MemberCount", group_datap->mMemberCount );
00820
00821 if (group_datap->mMemberCount > 0)
00822 {
00823 S32 contribution = 0;
00824 char online_status[DB_DATETIME_BUF_SIZE];
00825 char title[DB_GROUP_TITLE_BUF_SIZE];
00826 U64 agent_powers = 0;
00827 BOOL is_owner = FALSE;
00828
00829 S32 num_members = msg->getNumberOfBlocksFast(_PREHASH_MemberData);
00830 for (S32 i = 0; i < num_members; i++)
00831 {
00832 LLUUID member_id;
00833
00834 msg->getUUIDFast(_PREHASH_MemberData, _PREHASH_AgentID, member_id, i );
00835 msg->getS32(_PREHASH_MemberData, _PREHASH_Contribution, contribution, i);
00836 msg->getU64(_PREHASH_MemberData, "AgentPowers", agent_powers, i);
00837 msg->getStringFast(_PREHASH_MemberData, _PREHASH_OnlineStatus, DB_DATETIME_BUF_SIZE, online_status, i);
00838 msg->getString(_PREHASH_MemberData, "Title", DB_GROUP_TITLE_BUF_SIZE, title, i);
00839 msg->getBOOL(_PREHASH_MemberData,"IsOwner",is_owner,i);
00840
00841 if (member_id.notNull())
00842 {
00843
00844 LLGroupMemberData* newdata = new LLGroupMemberData(member_id,
00845 contribution,
00846 agent_powers,
00847 std::string(title),
00848 std::string(online_status),
00849 is_owner);
00850 #if LL_DEBUG
00851 LLGroupMgrGroupData::member_list_t::iterator mit = group_datap->mMembers.find(member_id);
00852 if (mit != group_datap->mMembers.end())
00853 {
00854 llinfos << " *** Received duplicate member data for agent " << member_id << llendl;
00855 }
00856 #endif
00857 group_datap->mMembers[member_id] = newdata;
00858 }
00859 else
00860 {
00861 llinfos << "Received null group member data." << llendl;
00862 }
00863 }
00864
00865
00866 if(group_datap->mTitles.size() < 1)
00867 {
00868 LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
00869 }
00870 }
00871
00872 if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount)
00873 {
00874 group_datap->mMemberDataComplete = TRUE;
00875 group_datap->mMemberRequestID.setNull();
00876
00877 if (group_datap->mPendingRoleMemberRequest)
00878 {
00879 group_datap->mPendingRoleMemberRequest = FALSE;
00880 LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID);
00881 }
00882 }
00883
00884 group_datap->mChanged = TRUE;
00885 LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
00886 }
00887
00888
00889 void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
00890 {
00891 lldebugs << "LLGroupMgr::processGroupPropertiesReply" << llendl;
00892 LLUUID agent_id;
00893 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
00894 if (gAgent.getID() != agent_id)
00895 {
00896 llwarns << "Got group properties reply for another agent!" << llendl;
00897 return;
00898 }
00899
00900 LLUUID group_id;
00901 char name[DB_GROUP_NAME_BUF_SIZE];
00902 char charter[DB_GROUP_CHARTER_BUF_SIZE];
00903 BOOL show_in_list = FALSE;
00904 LLUUID founder_id;
00905 U64 powers_mask = GP_NO_POWERS;
00906 S32 money = 0;
00907 char member_title[DB_GROUP_TITLE_BUF_SIZE];
00908 LLUUID insignia_id;
00909 LLUUID owner_role;
00910 U32 membership_fee = 0;
00911 BOOL open_enrollment = FALSE;
00912 S32 num_group_members = 0;
00913 S32 num_group_roles = 0;
00914 BOOL allow_publish = FALSE;
00915 BOOL mature = FALSE;
00916
00917 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id );
00918 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_FounderID, founder_id);
00919 msg->getStringFast(_PREHASH_GroupData, _PREHASH_Name, DB_GROUP_NAME_BUF_SIZE, name );
00920 msg->getStringFast(_PREHASH_GroupData, _PREHASH_Charter, DB_GROUP_CHARTER_BUF_SIZE, charter );
00921 msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_ShowInList, show_in_list );
00922 msg->getStringFast(_PREHASH_GroupData, _PREHASH_MemberTitle, DB_GROUP_TITLE_BUF_SIZE, member_title );
00923 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_InsigniaID, insignia_id );
00924 msg->getU64Fast(_PREHASH_GroupData, _PREHASH_PowersMask, powers_mask );
00925 msg->getU32Fast(_PREHASH_GroupData, _PREHASH_MembershipFee, membership_fee );
00926 msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_OpenEnrollment, open_enrollment );
00927 msg->getS32Fast(_PREHASH_GroupData, _PREHASH_GroupMembershipCount, num_group_members);
00928 msg->getS32(_PREHASH_GroupData, "GroupRolesCount", num_group_roles);
00929 msg->getS32Fast(_PREHASH_GroupData, _PREHASH_Money, money);
00930 msg->getBOOL("GroupData", "AllowPublish", allow_publish);
00931 msg->getBOOL("GroupData", "MaturePublish", mature);
00932 msg->getUUID(_PREHASH_GroupData, "OwnerRole", owner_role);
00933
00934 LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->createGroupData(group_id);
00935
00936 group_datap->mName = name;
00937 group_datap->mCharter = charter;
00938 group_datap->mShowInList = show_in_list;
00939 group_datap->mInsigniaID = insignia_id;
00940 group_datap->mFounderID = founder_id;
00941 group_datap->mMembershipFee = membership_fee;
00942 group_datap->mOpenEnrollment = open_enrollment;
00943 group_datap->mAllowPublish = allow_publish;
00944 group_datap->mMaturePublish = mature;
00945 group_datap->mOwnerRole = owner_role;
00946 group_datap->mMemberCount = num_group_members;
00947 group_datap->mRoleCount = num_group_roles + 1;
00948
00949 group_datap->mGroupPropertiesDataComplete = TRUE;
00950 group_datap->mChanged = TRUE;
00951
00952 LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);
00953 }
00954
00955
00956 void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
00957 {
00958 lldebugs << "LLGroupMgr::processGroupRoleDataReply" << llendl;
00959 LLUUID agent_id;
00960 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
00961 if (gAgent.getID() != agent_id)
00962 {
00963 llwarns << "Got group properties reply for another agent!" << llendl;
00964 return;
00965 }
00966
00967 LLUUID group_id;
00968 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id );
00969
00970 LLUUID request_id;
00971 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_RequestID, request_id);
00972
00973 LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->createGroupData(group_id);
00974 if (group_data->mRoleDataRequestID != request_id)
00975 {
00976 llwarns << "processGroupRoleDataReply: Received incorrect (stale?) request id" << llendl;
00977 return;
00978 }
00979
00980 msg->getS32(_PREHASH_GroupData, "RoleCount", group_data->mRoleCount );
00981
00982 char name[DB_GROUP_NAME_BUF_SIZE];
00983 char title[DB_GROUP_TITLE_BUF_SIZE];
00984 char desc[DB_GROUP_CHARTER_BUF_SIZE];
00985 U64 powers = 0;
00986 U32 member_count = 0;
00987 LLUUID role_id;
00988
00989 U32 num_blocks = msg->getNumberOfBlocks("RoleData");
00990 U32 i = 0;
00991 for (i=0; i< num_blocks; ++i)
00992 {
00993 msg->getUUID("RoleData", "RoleID", role_id, i );
00994
00995 msg->getString("RoleData","Name",DB_GROUP_NAME_BUF_SIZE,name,i);
00996 msg->getString("RoleData","Title",DB_GROUP_TITLE_BUF_SIZE,title,i);
00997 msg->getString("RoleData","Description",DB_GROUP_CHARTER_BUF_SIZE,desc,i);
00998 msg->getU64("RoleData","Powers",powers,i);
00999 msg->getU32("RoleData","Members",member_count,i);
01000
01001 lldebugs << "Adding role data: " << name << " {" << role_id << "}" << llendl;
01002 LLGroupRoleData* rd = new LLGroupRoleData(role_id,name,title,desc,powers,member_count);
01003 group_data->mRoles[role_id] = rd;
01004 }
01005
01006 if (group_data->mRoles.size() == (U32)group_data->mRoleCount)
01007 {
01008 group_data->mRoleDataComplete = TRUE;
01009 group_data->mRoleDataRequestID.setNull();
01010
01011 if (group_data->mPendingRoleMemberRequest)
01012 {
01013 group_data->mPendingRoleMemberRequest = FALSE;
01014 LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_data->mID);
01015 }
01016 }
01017
01018 group_data->mChanged = TRUE;
01019 LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA);
01020 }
01021
01022
01023 void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
01024 {
01025 lldebugs << "LLGroupMgr::processGroupRoleMembersReply" << llendl;
01026 LLUUID agent_id;
01027 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
01028 if (gAgent.getID() != agent_id)
01029 {
01030 llwarns << "Got group properties reply for another agent!" << llendl;
01031 return;
01032 }
01033
01034 LLUUID request_id;
01035 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_RequestID, request_id);
01036
01037 LLUUID group_id;
01038 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
01039
01040 U32 total_pairs;
01041 msg->getU32(_PREHASH_AgentData, "TotalPairs", total_pairs);
01042
01043 LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->createGroupData(group_id);
01044
01045 if (group_data->mRoleMembersRequestID != request_id)
01046 {
01047 llwarns << "processGroupRoleMembersReply: Received incorrect (stale?) role member request id" << llendl;
01048 return;
01049 }
01050
01051 U32 num_blocks = msg->getNumberOfBlocks("MemberData");
01052 U32 i;
01053 LLUUID member_id;
01054 LLUUID role_id;
01055 LLGroupRoleData* rd = NULL;
01056 LLGroupMemberData* md = NULL;
01057
01058 LLGroupMgrGroupData::role_list_t::iterator ri;
01059 LLGroupMgrGroupData::member_list_t::iterator mi;
01060
01061
01062 if (total_pairs > 0)
01063 {
01064 for (i = 0;i < num_blocks; ++i)
01065 {
01066 msg->getUUID("MemberData","RoleID",role_id,i);
01067 msg->getUUID("MemberData","MemberID",member_id,i);
01068
01069 if (role_id.notNull() && member_id.notNull() )
01070 {
01071 rd = NULL;
01072 ri = group_data->mRoles.find(role_id);
01073 if (ri != group_data->mRoles.end())
01074 {
01075 rd = ri->second;
01076 }
01077
01078 md = NULL;
01079 mi = group_data->mMembers.find(member_id);
01080 if (mi != group_data->mMembers.end())
01081 {
01082 md = mi->second;
01083 }
01084
01085 if (rd && md)
01086 {
01087 lldebugs << "Adding role-member pair: " << role_id << ", " << member_id << llendl;
01088 rd->addMember(member_id);
01089 md->addRole(role_id,rd);
01090 }
01091 else
01092 {
01093 if (!rd) llwarns << "Received role data for unkown role " << role_id << " in group " << group_id << llendl;
01094 if (!md) llwarns << "Received role data for unkown member " << member_id << " in group " << group_id << llendl;
01095 }
01096 }
01097 }
01098
01099 group_data->mReceivedRoleMemberPairs += num_blocks;
01100 }
01101
01102 if (group_data->mReceivedRoleMemberPairs == total_pairs)
01103 {
01104
01105 LLGroupRoleData* everyone = group_data->mRoles[LLUUID::null];
01106 if (!everyone)
01107 {
01108 llwarns << "Everyone role not found!" << llendl;
01109 }
01110 else
01111 {
01112 for (LLGroupMgrGroupData::member_list_t::iterator mi = group_data->mMembers.begin();
01113 mi != group_data->mMembers.end(); ++mi)
01114 {
01115 LLGroupMemberData* data = mi->second;
01116 if (data)
01117 {
01118 data->addRole(LLUUID::null,everyone);
01119 }
01120 }
01121 }
01122
01123 group_data->mRoleMemberDataComplete = TRUE;
01124 group_data->mRoleMembersRequestID.setNull();
01125 }
01126
01127 group_data->mChanged = TRUE;
01128 LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_MEMBER_DATA);
01129 }
01130
01131
01132 void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
01133 {
01134 lldebugs << "LLGroupMgr::processGroupTitlesReply" << llendl;
01135 LLUUID agent_id;
01136 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
01137 if (gAgent.getID() != agent_id)
01138 {
01139 llwarns << "Got group properties reply for another agent!" << llendl;
01140 return;
01141 }
01142
01143 LLUUID group_id;
01144 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
01145
01146 LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->createGroupData(group_id);
01147
01148 LLUUID request_id;
01149 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_RequestID, request_id);
01150
01151 if (group_data->mTitlesRequestID != request_id)
01152 {
01153 llwarns << "processGroupTitlesReply: Received incorrect (stale?) title request id" << llendl;
01154 return;
01155 }
01156
01157 char title_buf[DB_GROUP_TITLE_BUF_SIZE];
01158
01159 LLGroupTitle title;
01160
01161 S32 i = 0;
01162 S32 blocks = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
01163 for (i=0; i<blocks; ++i)
01164 {
01165 msg->getString("GroupData","Title",DB_GROUP_TITLE_BUF_SIZE,title_buf,i);
01166 title.mTitle = title_buf;
01167 msg->getUUID("GroupData","RoleID",title.mRoleID,i);
01168 msg->getBOOL("GroupData","Selected",title.mSelected,i);
01169
01170 if (title_buf[0] != '\0')
01171 {
01172 lldebugs << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << llendl;
01173 group_data->mTitles.push_back(title);
01174 }
01175 }
01176
01177 group_data->mChanged = TRUE;
01178 LLGroupMgr::getInstance()->notifyObservers(GC_TITLES);
01179 }
01180
01181
01182 void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data)
01183 {
01184 lldebugs << "processEjectGroupMemberReply" << llendl;
01185 LLUUID group_id;
01186 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
01187 BOOL success;
01188 msg->getBOOLFast(_PREHASH_EjectData, _PREHASH_Success, success);
01189
01190
01191 if (!success)
01192 {
01193 LLFloaterGroupInfo::refreshGroup(group_id);
01194 }
01195 }
01196
01197
01198 void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
01199 {
01200 lldebugs << "processJoinGroupReply" << llendl;
01201 LLUUID group_id;
01202 BOOL success;
01203 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
01204 msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_Success, success);
01205
01206 if (success)
01207 {
01208
01209 gAgent.sendAgentDataUpdateRequest();
01210
01211 LLGroupMgr::getInstance()->clearGroupData(group_id);
01212
01213 LLFloaterGroupInfo::refreshGroup(group_id);
01214
01215 LLFloaterDirectory::refreshGroup(group_id);
01216 }
01217 }
01218
01219
01220 void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data)
01221 {
01222 lldebugs << "processLeaveGroupReply" << llendl;
01223 LLUUID group_id;
01224 BOOL success;
01225 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
01226 msg->getBOOLFast(_PREHASH_GroupData, _PREHASH_Success, success);
01227
01228 if (success)
01229 {
01230
01231 gAgent.sendAgentDataUpdateRequest();
01232
01233 LLGroupMgr::getInstance()->clearGroupData(group_id);
01234
01235 LLFloaterGroupInfo::closeGroup(group_id);
01236
01237 LLFloaterDirectory::refreshGroup(group_id);
01238 }
01239 }
01240
01241
01242 void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
01243 {
01244 LLUUID group_id;
01245 BOOL success;
01246 char message[MAX_STRING];
01247
01248 msg->getUUIDFast(_PREHASH_ReplyData, _PREHASH_GroupID, group_id );
01249
01250 msg->getBOOLFast(_PREHASH_ReplyData, _PREHASH_Success, success );
01251 msg->getStringFast(_PREHASH_ReplyData, _PREHASH_Message, MAX_STRING, message );
01252
01253 if (success)
01254 {
01255
01256 gAgent.sendAgentDataUpdateRequest();
01257
01258
01259
01260
01261 LLGroupData gd;
01262 gd.mAcceptNotices = TRUE;
01263 gd.mListInProfile = TRUE;
01264 gd.mContribution = 0;
01265 gd.mID = group_id;
01266 gd.mName = "new group";
01267 gd.mPowers = GP_ALL_POWERS;
01268
01269 gAgent.mGroups.push_back(gd);
01270
01271 LLFloaterGroupInfo::closeCreateGroup();
01272 LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab");
01273 }
01274 else
01275 {
01276
01277 LLString::format_map_t args;
01278 args["[MESSAGE]"] = message;
01279 gViewerWindow->alertXml("UnableToCreateGroup", args);
01280 }
01281 }
01282
01283 LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id)
01284 {
01285 LLGroupMgrGroupData* group_datap;
01286
01287 group_map_t::iterator existing_group = LLGroupMgr::getInstance()->mGroups.find(id);
01288 if (existing_group == LLGroupMgr::getInstance()->mGroups.end())
01289 {
01290 group_datap = new LLGroupMgrGroupData(id);
01291 LLGroupMgr::getInstance()->addGroup(group_datap);
01292 }
01293 else
01294 {
01295 group_datap = existing_group->second;
01296 }
01297
01298 return group_datap;
01299 }
01300
01301 void LLGroupMgr::notifyObservers(LLGroupChange gc)
01302 {
01303 for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi)
01304 {
01305 if (gi->second->mChanged)
01306 {
01307
01308 observer_multimap_t::iterator oi = mObservers.find(gi->first);
01309 for (; oi != mObservers.end(); ++oi)
01310 {
01311 oi->second->changed(gc);
01312 }
01313 gi->second->mChanged = FALSE;
01314 }
01315 }
01316 }
01317
01318 void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap)
01319 {
01320 if (mGroups.size() > MAX_CACHED_GROUPS)
01321 {
01322
01323 for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end() && mGroups.size() > MAX_CACHED_GROUPS / 2; )
01324 {
01325 observer_multimap_t::iterator oi = mObservers.find(gi->first);
01326 if (oi == mObservers.end())
01327 {
01328
01329 LLGroupMgrGroupData* unobserved_groupp = gi->second;
01330 delete unobserved_groupp;
01331 mGroups.erase(gi++);
01332 }
01333 else
01334 {
01335 ++gi;
01336 }
01337 }
01338 }
01339 mGroups[group_datap->getID()] = group_datap;
01340 }
01341
01342
01343 void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id)
01344 {
01345 lldebugs << "LLGroupMgr::sendGroupPropertiesRequest" << llendl;
01346
01347
01348
01349 LLMessageSystem* msg = gMessageSystem;
01350 msg->newMessage("GroupProfileRequest");
01351 msg->nextBlock("AgentData");
01352 msg->addUUID("AgentID",gAgent.getID());
01353 msg->addUUID("SessionID",gAgent.getSessionID());
01354 msg->nextBlock("GroupData");
01355 msg->addUUID("GroupID",group_id);
01356 gAgent.sendReliableMessage();
01357 }
01358
01359 void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
01360 {
01361 lldebugs << "LLGroupMgr::sendGroupMembersRequest" << llendl;
01362 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01363 if (group_datap->mMemberRequestID.isNull())
01364 {
01365 group_datap->removeMemberData();
01366 group_datap->mMemberRequestID.generate();
01367
01368 LLMessageSystem* msg = gMessageSystem;
01369 msg->newMessage("GroupMembersRequest");
01370 msg->nextBlock("AgentData");
01371 msg->addUUID("AgentID",gAgent.getID());
01372 msg->addUUID("SessionID",gAgent.getSessionID());
01373 msg->nextBlock("GroupData");
01374 msg->addUUID("GroupID",group_id);
01375 msg->addUUID("RequestID",group_datap->mMemberRequestID);
01376 gAgent.sendReliableMessage();
01377 }
01378 }
01379
01380 void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
01381 {
01382 lldebugs << "LLGroupMgr::sendGroupRoleDataRequest" << llendl;
01383 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01384 if (group_datap->mRoleDataRequestID.isNull())
01385 {
01386 group_datap->removeRoleData();
01387 group_datap->mRoleDataRequestID.generate();
01388
01389 LLMessageSystem* msg = gMessageSystem;
01390 msg->newMessage("GroupRoleDataRequest");
01391 msg->nextBlock("AgentData");
01392 msg->addUUID("AgentID",gAgent.getID());
01393 msg->addUUID("SessionID",gAgent.getSessionID());
01394 msg->nextBlock("GroupData");
01395 msg->addUUID("GroupID",group_id);
01396 msg->addUUID("RequestID",group_datap->mRoleDataRequestID);
01397 gAgent.sendReliableMessage();
01398 }
01399 }
01400
01401 void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
01402 {
01403 lldebugs << "LLGroupMgr::sendGroupRoleMembersRequest" << llendl;
01404 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01405
01406 if (group_datap->mRoleMembersRequestID.isNull())
01407 {
01408
01409 if (!group_datap->isMemberDataComplete()
01410 || !group_datap->isRoleDataComplete())
01411 {
01412
01413 llinfos << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")
01414 << " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N")
01415 << " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << llendl;
01416 group_datap->mPendingRoleMemberRequest = TRUE;
01417 return;
01418 }
01419
01420 group_datap->removeRoleMemberData();
01421 group_datap->mRoleMembersRequestID.generate();
01422
01423 LLMessageSystem* msg = gMessageSystem;
01424 msg->newMessage("GroupRoleMembersRequest");
01425 msg->nextBlock("AgentData");
01426 msg->addUUID("AgentID",gAgent.getID());
01427 msg->addUUID("SessionID",gAgent.getSessionID());
01428 msg->nextBlock("GroupData");
01429 msg->addUUID("GroupID",group_id);
01430 msg->addUUID("RequestID",group_datap->mRoleMembersRequestID);
01431 gAgent.sendReliableMessage();
01432 }
01433 }
01434
01435 void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id)
01436 {
01437 lldebugs << "LLGroupMgr::sendGroupTitlesRequest" << llendl;
01438 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01439
01440 group_datap->mTitles.clear();
01441 group_datap->mTitlesRequestID.generate();
01442
01443 LLMessageSystem* msg = gMessageSystem;
01444 msg->newMessage("GroupTitlesRequest");
01445 msg->nextBlock("AgentData");
01446 msg->addUUID("AgentID",gAgent.getID());
01447 msg->addUUID("SessionID",gAgent.getSessionID());
01448 msg->addUUID("GroupID",group_id);
01449 msg->addUUID("RequestID",group_datap->mTitlesRequestID);
01450
01451 gAgent.sendReliableMessage();
01452 }
01453
01454 void LLGroupMgr::sendGroupTitleUpdate(const LLUUID& group_id, const LLUUID& title_role_id)
01455 {
01456 lldebugs << "LLGroupMgr::sendGroupTitleUpdate" << llendl;
01457
01458 LLMessageSystem* msg = gMessageSystem;
01459 msg->newMessage("GroupTitleUpdate");
01460 msg->nextBlock("AgentData");
01461 msg->addUUID("AgentID",gAgent.getID());
01462 msg->addUUID("SessionID",gAgent.getSessionID());
01463 msg->addUUID("GroupID",group_id);
01464 msg->addUUID("TitleRoleID",title_role_id);
01465
01466 gAgent.sendReliableMessage();
01467
01468
01469 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01470 for (std::vector<LLGroupTitle>::iterator iter = group_datap->mTitles.begin();
01471 iter != group_datap->mTitles.end(); ++iter)
01472 {
01473 if (iter->mRoleID == title_role_id)
01474 {
01475 iter->mSelected = TRUE;
01476 }
01477 else if (iter->mSelected)
01478 {
01479 iter->mSelected = FALSE;
01480 }
01481 }
01482 }
01483
01484
01485 void LLGroupMgr::sendCreateGroupRequest(const std::string& name,
01486 const std::string& charter,
01487 U8 show_in_list,
01488 const LLUUID& insignia,
01489 S32 membership_fee,
01490 BOOL open_enrollment,
01491 BOOL allow_publish,
01492 BOOL mature_publish)
01493 {
01494 LLMessageSystem* msg = gMessageSystem;
01495 msg->newMessage("CreateGroupRequest");
01496 msg->nextBlock("AgentData");
01497 msg->addUUID("AgentID",gAgent.getID());
01498 msg->addUUID("SessionID",gAgent.getSessionID());
01499
01500 msg->nextBlock("GroupData");
01501 msg->addString("Name",name);
01502 msg->addString("Charter",charter);
01503 msg->addBOOL("ShowInList",show_in_list);
01504 msg->addUUID("InsigniaID",insignia);
01505 msg->addS32("MembershipFee",membership_fee);
01506 msg->addBOOL("OpenEnrollment",open_enrollment);
01507 msg->addBOOL("AllowPublish",allow_publish);
01508 msg->addBOOL("MaturePublish",mature_publish);
01509
01510 gAgent.sendReliableMessage();
01511 }
01512
01513 void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id)
01514 {
01515 lldebugs << "LLGroupMgr::sendUpdateGroupInfo" << llendl;
01516 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01517
01518 LLMessageSystem* msg = gMessageSystem;
01519
01520 msg->newMessageFast(_PREHASH_UpdateGroupInfo);
01521 msg->nextBlockFast(_PREHASH_AgentData);
01522 msg->addUUIDFast(_PREHASH_AgentID,gAgent.getID());
01523 msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
01524
01525 msg->nextBlockFast(_PREHASH_GroupData);
01526 msg->addUUIDFast(_PREHASH_GroupID,group_datap->getID());
01527 msg->addStringFast(_PREHASH_Charter,group_datap->mCharter);
01528 msg->addBOOLFast(_PREHASH_ShowInList,group_datap->mShowInList);
01529 msg->addUUIDFast(_PREHASH_InsigniaID,group_datap->mInsigniaID);
01530 msg->addS32Fast(_PREHASH_MembershipFee,group_datap->mMembershipFee);
01531 msg->addBOOLFast(_PREHASH_OpenEnrollment,group_datap->mOpenEnrollment);
01532 msg->addBOOLFast(_PREHASH_AllowPublish,group_datap->mAllowPublish);
01533 msg->addBOOLFast(_PREHASH_MaturePublish,group_datap->mMaturePublish);
01534
01535 gAgent.sendReliableMessage();
01536
01537
01538 group_datap->mChanged = TRUE;
01539 notifyObservers(GC_PROPERTIES);
01540 }
01541
01542 void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id)
01543 {
01544 lldebugs << "LLGroupMgr::sendGroupRoleMemberChanges" << llendl;
01545 LLGroupMgrGroupData* group_datap = createGroupData(group_id);
01546
01547 if (group_datap->mRoleMemberChanges.empty()) return;
01548
01549 LLMessageSystem* msg = gMessageSystem;
01550
01551 bool start_message = true;
01552 for (LLGroupMgrGroupData::change_map_t::const_iterator citer = group_datap->mRoleMemberChanges.begin();
01553 citer != group_datap->mRoleMemberChanges.end(); ++citer)
01554 {
01555 if (start_message)
01556 {
01557 msg->newMessage("GroupRoleChanges");
01558 msg->nextBlockFast(_PREHASH_AgentData);
01559 msg->addUUIDFast(_PREHASH_AgentID,gAgent.getID());
01560 msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
01561 msg->addUUIDFast(_PREHASH_GroupID,group_id);
01562 start_message = false;
01563 }
01564 msg->nextBlock("RoleChange");
01565 msg->addUUID("RoleID",citer->second.mRole);
01566 msg->addUUID("MemberID",citer->second.mMember);
01567 msg->addU32("Change",(U32)citer->second.mChange);
01568
01569 if (msg->isSendFullFast())
01570 {
01571 gAgent.sendReliableMessage();
01572 start_message = true;
01573 }
01574 }
01575
01576 if (!start_message)
01577 {
01578 gAgent.sendReliableMessage();
01579 }
01580
01581 group_datap->mRoleMemberChanges.clear();
01582
01583
01584 group_datap->mChanged = TRUE;
01585 notifyObservers(GC_ROLE_MEMBER_DATA);
01586 }
01587
01588
01589 void LLGroupMgr::sendGroupMemberJoin(const LLUUID& group_id)
01590 {
01591 LLMessageSystem *msg = gMessageSystem;
01592
01593 msg->newMessageFast(_PREHASH_JoinGroupRequest);
01594 msg->nextBlockFast(_PREHASH_AgentData);
01595 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
01596 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01597 msg->nextBlockFast(_PREHASH_GroupData);
01598 msg->addUUIDFast(_PREHASH_GroupID, group_id);
01599
01600 gAgent.sendReliableMessage();
01601 }
01602
01603
01604
01605 void LLGroupMgr::sendGroupMemberInvites(const LLUUID& group_id, std::map<LLUUID,LLUUID>& member_role_pairs)
01606 {
01607 bool start_message = true;
01608 LLMessageSystem* msg = gMessageSystem;
01609
01610 for (std::map<LLUUID,LLUUID>::iterator it = member_role_pairs.begin();
01611 it != member_role_pairs.end(); ++it)
01612 {
01613 if (start_message)
01614 {
01615 msg->newMessage("InviteGroupRequest");
01616 msg->nextBlock("AgentData");
01617 msg->addUUID("AgentID",gAgent.getID());
01618 msg->addUUID("SessionID",gAgent.getSessionID());
01619 msg->nextBlock("GroupData");
01620 msg->addUUID("GroupID",group_id);
01621 start_message = false;
01622 }
01623
01624 msg->nextBlock("InviteData");
01625 msg->addUUID("InviteeID",(*it).first);
01626 msg->addUUID("RoleID",(*it).second);
01627
01628 if (msg->isSendFull())
01629 {
01630 gAgent.sendReliableMessage();
01631 start_message = true;
01632 }
01633 }
01634
01635 if (!start_message)
01636 {
01637 gAgent.sendReliableMessage();
01638 }
01639 }
01640
01641
01642 void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
01643 std::vector<LLUUID>& member_ids)
01644 {
01645 bool start_message = true;
01646 LLMessageSystem* msg = gMessageSystem;
01647
01648 LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
01649 if (!group_datap) return;
01650
01651 for (std::vector<LLUUID>::iterator it = member_ids.begin();
01652 it != member_ids.end(); ++it)
01653 {
01654
01655 if ((*it) == gAgent.getID()) continue;
01656
01657
01658 LLGroupMgrGroupData::member_list_t::iterator mit = group_datap->mMembers.find(*it);
01659 if (mit != group_datap->mMembers.end())
01660 {
01661
01662 if (start_message)
01663 {
01664 msg->newMessage("EjectGroupMemberRequest");
01665 msg->nextBlock("AgentData");
01666 msg->addUUID("AgentID",gAgent.getID());
01667 msg->addUUID("SessionID",gAgent.getSessionID());
01668 msg->nextBlock("GroupData");
01669 msg->addUUID("GroupID",group_id);
01670 start_message = false;
01671 }
01672
01673 msg->nextBlock("EjectData");
01674 msg->addUUID("EjecteeID",(*it));
01675
01676 if (msg->isSendFull())
01677 {
01678 gAgent.sendReliableMessage();
01679 start_message = true;
01680 }
01681
01682
01683 for (LLGroupMemberData::role_list_t::iterator rit = (*mit).second->roleBegin();
01684 rit != (*mit).second->roleEnd(); ++rit)
01685 {
01686 if ((*rit).first.notNull())
01687 {
01688 (*rit).second->removeMember(*it);
01689 }
01690 }
01691 delete (*mit).second;
01692 group_datap->mMembers.erase(*it);
01693 }
01694 }
01695
01696 if (!start_message)
01697 {
01698 gAgent.sendReliableMessage();
01699 }
01700 }
01701
01702 void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
01703 {
01704 lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl;
01705 LLGroupMgrGroupData* group_datap = getGroupData(group_id);
01706
01707 if (group_datap && group_datap->pendingRoleChanges())
01708 {
01709 group_datap->sendRoleChanges();
01710
01711
01712 group_datap->mChanged = TRUE;
01713 notifyObservers(GC_ROLE_DATA);
01714 }
01715 }
01716
01717 void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id)
01718 {
01719 lldebugs << "LLGroupMgr::cancelGroupRoleChanges" << llendl;
01720 LLGroupMgrGroupData* group_datap = getGroupData(group_id);
01721
01722 if (group_datap) group_datap->cancelRoleChanges();
01723 }
01724
01725
01726 bool LLGroupMgr::parseRoleActions(const LLString& xml_filename)
01727 {
01728 LLXMLNodePtr root;
01729
01730 BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
01731
01732 if (!success || !root || !root->hasName( "role_actions" ))
01733 {
01734 llerrs << "Problem reading UI role_actions file: " << xml_filename << llendl;
01735 return false;
01736 }
01737
01738 LLXMLNodeList role_list;
01739
01740 root->getChildren("action_set", role_list, false);
01741
01742 for (LLXMLNodeList::iterator role_iter = role_list.begin(); role_iter != role_list.end(); ++role_iter)
01743 {
01744 LLXMLNodePtr action_set = role_iter->second;
01745
01746 LLRoleActionSet* role_action_set = new LLRoleActionSet();
01747 LLRoleAction* role_action_data = new LLRoleAction();
01748
01749
01750 LLString action_set_name;
01751 if (action_set->getAttributeString("name", action_set_name))
01752 {
01753 lldebugs << "Loading action set " << action_set_name << llendl;
01754 role_action_data->mName = action_set_name;
01755 }
01756 else
01757 {
01758 llwarns << "Unable to parse action set with no name" << llendl;
01759 delete role_action_set;
01760 delete role_action_data;
01761 continue;
01762 }
01763
01764 LLString set_description;
01765 if (action_set->getAttributeString("description", set_description))
01766 {
01767 role_action_data->mDescription = set_description;
01768 }
01769
01770 LLString set_longdescription;
01771 if (action_set->getAttributeString("longdescription", set_longdescription))
01772 {
01773 role_action_data->mLongDescription = set_longdescription;
01774 }
01775
01776
01777 U64 set_power_mask = 0;
01778
01779 LLXMLNodeList action_list;
01780 LLXMLNodeList::iterator action_iter;
01781
01782 action_set->getChildren("action", action_list, false);
01783
01784 for (action_iter = action_list.begin(); action_iter != action_list.end(); ++action_iter)
01785 {
01786 LLXMLNodePtr action = action_iter->second;
01787
01788 LLRoleAction* role_action = new LLRoleAction();
01789
01790
01791 LLString action_name;
01792 if (action->getAttributeString("name", action_name))
01793 {
01794 lldebugs << "Loading action " << action_name << llendl;
01795 role_action->mName = action_name;
01796 }
01797 else
01798 {
01799 llwarns << "Unable to parse action with no name" << llendl;
01800 delete role_action;
01801 continue;
01802 }
01803
01804 LLString description;
01805 if (action->getAttributeString("description", description))
01806 {
01807 role_action->mDescription = description;
01808 }
01809
01810 LLString longdescription;
01811 if (action->getAttributeString("longdescription", longdescription))
01812 {
01813 role_action->mLongDescription = longdescription;
01814 }
01815
01816 S32 power_bit = 0;
01817 if (action->getAttributeS32("value", power_bit))
01818 {
01819 if (0 <= power_bit && power_bit < 64)
01820 {
01821 role_action->mPowerBit = 0x1LL << power_bit;
01822 }
01823 }
01824
01825 set_power_mask |= role_action->mPowerBit;
01826
01827 role_action_set->mActions.push_back(role_action);
01828 }
01829
01830 role_action_data->mPowerBit = set_power_mask;
01831 role_action_set->mActionSetData = role_action_data;
01832
01833 LLGroupMgr::getInstance()->mRoleActionSets.push_back(role_action_set);
01834 }
01835 return true;
01836 }
01837
01838
01839 void LLGroupMgr::debugClearAllGroups(void*)
01840 {
01841 LLGroupMgr::getInstance()->clearGroups();
01842 LLGroupMgr::parseRoleActions("role_actions.xml");
01843 }
01844
01845