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