llcallingcard.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:25k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llcallingcard.cpp
  3.  * @brief Implementation of the LLPreviewCallingCard class
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #if LL_WINDOWS
  34. #pragma warning( disable : 4800 ) // performance warning in <functional>
  35. #endif
  36. #include "llcallingcard.h"
  37. #include <vector>
  38. #include <algorithm>
  39. //#include <iterator>
  40. #include "indra_constants.h"
  41. #include "llcachename.h"
  42. #include "llstl.h"
  43. #include "lltimer.h"
  44. #include "lluuid.h"
  45. #include "message.h"
  46. #include "llagent.h"
  47. #include "llbutton.h"
  48. #include "llinventoryobserver.h"
  49. #include "llinventorymodel.h"
  50. #include "llnotifications.h"
  51. #include "llnotificationsutil.h"
  52. #include "llresmgr.h"
  53. #include "llslurl.h"
  54. #include "llimview.h"
  55. #include "llviewercontrol.h"
  56. #include "llviewernetwork.h"
  57. #include "llviewerobjectlist.h"
  58. #include "llviewerwindow.h"
  59. #include "llvoavatar.h"
  60. #include "llavataractions.h"
  61. ///----------------------------------------------------------------------------
  62. /// Local function declarations, constants, enums, and typedefs
  63. ///----------------------------------------------------------------------------
  64. class LLTrackingData
  65. {
  66. public:
  67. LLTrackingData(const LLUUID& avatar_id, const std::string& name);
  68. bool haveTrackingInfo();
  69. void setTrackedCoarseLocation(const LLVector3d& global_pos);
  70. void agentFound(const LLUUID& prey,
  71. const LLVector3d& estimated_global_pos);
  72. public:
  73. LLUUID mAvatarID;
  74. std::string mName;
  75. LLVector3d mGlobalPositionEstimate;
  76. bool mHaveInfo;
  77. bool mHaveCoarseInfo;
  78. LLTimer mCoarseLocationTimer;
  79. LLTimer mUpdateTimer;
  80. LLTimer mAgentGone;
  81. };
  82. const F32 COARSE_FREQUENCY = 2.2f;
  83. const F32 FIND_FREQUENCY = 29.7f; // This results in a database query, so cut these back
  84. const F32 OFFLINE_SECONDS = FIND_FREQUENCY + 8.0f;
  85. // static
  86. LLAvatarTracker LLAvatarTracker::sInstance;
  87. ///----------------------------------------------------------------------------
  88. /// Class LLAvatarTracker
  89. ///----------------------------------------------------------------------------
  90. LLAvatarTracker::LLAvatarTracker() :
  91. mTrackingData(NULL),
  92. mTrackedAgentValid(false),
  93. //mInventory(NULL),
  94. //mInventoryObserver(NULL),
  95. mModifyMask(0x0)
  96. {
  97. }
  98. LLAvatarTracker::~LLAvatarTracker()
  99. {
  100. deleteTrackingData();
  101. std::for_each(mObservers.begin(), mObservers.end(), DeletePointer());
  102. std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer());
  103. }
  104. void LLAvatarTracker::track(const LLUUID& avatar_id, const std::string& name)
  105. {
  106. deleteTrackingData();
  107. mTrackedAgentValid = false;
  108. mTrackingData = new LLTrackingData(avatar_id, name);
  109. findAgent();
  110. // We track here because findAgent() is called on a timer (for now).
  111. if(avatar_id.notNull())
  112. {
  113. LLMessageSystem* msg = gMessageSystem;
  114. msg->newMessageFast(_PREHASH_TrackAgent);
  115. msg->nextBlockFast(_PREHASH_AgentData);
  116. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  117. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  118. msg->nextBlockFast(_PREHASH_TargetData);
  119. msg->addUUIDFast(_PREHASH_PreyID, avatar_id);
  120. gAgent.sendReliableMessage();
  121. }
  122. }
  123. void LLAvatarTracker::untrack(const LLUUID& avatar_id)
  124. {
  125. if (mTrackingData && mTrackingData->mAvatarID == avatar_id)
  126. {
  127. deleteTrackingData();
  128. mTrackedAgentValid = false;
  129. LLMessageSystem* msg = gMessageSystem;
  130. msg->newMessageFast(_PREHASH_TrackAgent);
  131. msg->nextBlockFast(_PREHASH_AgentData);
  132. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  133. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  134. msg->nextBlockFast(_PREHASH_TargetData);
  135. msg->addUUIDFast(_PREHASH_PreyID, LLUUID::null);
  136. gAgent.sendReliableMessage();
  137. }
  138. }
  139. void LLAvatarTracker::setTrackedCoarseLocation(const LLVector3d& global_pos)
  140. {
  141. if(mTrackingData)
  142. {
  143. mTrackingData->setTrackedCoarseLocation(global_pos);
  144. }
  145. }
  146. bool LLAvatarTracker::haveTrackingInfo()
  147. {
  148. if(mTrackingData)
  149. {
  150. return mTrackingData->haveTrackingInfo();
  151. }
  152. return false;
  153. }
  154. LLVector3d LLAvatarTracker::getGlobalPos()
  155. {
  156. if(!mTrackedAgentValid || !mTrackingData) return LLVector3d();
  157. LLVector3d global_pos;
  158. LLViewerObject* object = gObjectList.findObject(mTrackingData->mAvatarID);
  159. if(object && !object->isDead())
  160. {
  161. global_pos = object->getPositionGlobal();
  162. // HACK - for making the tracker point above the avatar's head
  163. // rather than its groin
  164. global_pos.mdV[VZ] += 0.7f * ((LLVOAvatar *)object)->mBodySize.mV[VZ];
  165. mTrackingData->mGlobalPositionEstimate = global_pos;
  166. }
  167. else
  168. {
  169. global_pos = mTrackingData->mGlobalPositionEstimate;
  170. }
  171. return global_pos;
  172. }
  173. void LLAvatarTracker::getDegreesAndDist(F32& rot,
  174. F64& horiz_dist,
  175. F64& vert_dist)
  176. {
  177. if(!mTrackingData) return;
  178. LLVector3d global_pos;
  179. LLViewerObject* object = gObjectList.findObject(mTrackingData->mAvatarID);
  180. if(object && !object->isDead())
  181. {
  182. global_pos = object->getPositionGlobal();
  183. mTrackingData->mGlobalPositionEstimate = global_pos;
  184. }
  185. else
  186. {
  187. global_pos = mTrackingData->mGlobalPositionEstimate;
  188. }
  189. LLVector3d to_vec = global_pos - gAgent.getPositionGlobal();
  190. horiz_dist = sqrt(to_vec.mdV[VX] * to_vec.mdV[VX] + to_vec.mdV[VY] * to_vec.mdV[VY]);
  191. vert_dist = to_vec.mdV[VZ];
  192. rot = F32(RAD_TO_DEG * atan2(to_vec.mdV[VY], to_vec.mdV[VX]));
  193. }
  194. const std::string& LLAvatarTracker::getName()
  195. {
  196. if(mTrackingData)
  197. {
  198. return mTrackingData->mName;
  199. }
  200. else
  201. {
  202. return LLStringUtil::null;
  203. }
  204. }
  205. const LLUUID& LLAvatarTracker::getAvatarID()
  206. {
  207. if(mTrackingData)
  208. {
  209. return mTrackingData->mAvatarID;
  210. }
  211. else
  212. {
  213. return LLUUID::null;
  214. }
  215. }
  216. S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
  217. {
  218. using namespace std;
  219. U32 new_buddy_count = 0;
  220. std::string first,last;
  221. LLUUID agent_id;
  222. for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr)
  223. {
  224. agent_id = (*itr).first;
  225. buddy_map_t::const_iterator existing_buddy = mBuddyInfo.find(agent_id);
  226. if(existing_buddy == mBuddyInfo.end())
  227. {
  228. ++new_buddy_count;
  229. mBuddyInfo[agent_id] = (*itr).second;
  230. gCacheName->getName(agent_id, first, last);
  231. addChangedMask(LLFriendObserver::ADD, agent_id);
  232. lldebugs << "Added buddy " << agent_id
  233. << ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline")
  234. << ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo()
  235. << ", FROM: " << mBuddyInfo[agent_id]->getRightsGrantedFrom()
  236. << llendl;
  237. }
  238. else
  239. {
  240. LLRelationship* e_r = (*existing_buddy).second;
  241. LLRelationship* n_r = (*itr).second;
  242. llwarns << "!! Add buddy for existing buddy: " << agent_id
  243. << " [" << (e_r->isOnline() ? "Online" : "Offline") << "->" << (n_r->isOnline() ? "Online" : "Offline")
  244. << ", " <<  e_r->getRightsGrantedTo() << "->" << n_r->getRightsGrantedTo()
  245. << ", " <<  e_r->getRightsGrantedTo() << "->" << n_r->getRightsGrantedTo()
  246. << "]" << llendl;
  247. }
  248. }
  249. notifyObservers();
  250. return new_buddy_count;
  251. }
  252. void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const
  253. {
  254. buddy_map_t::const_iterator it = mBuddyInfo.begin();
  255. buddy_map_t::const_iterator end = mBuddyInfo.end();
  256. for(; it != end; ++it)
  257. {
  258. buddies[(*it).first] = (*it).second;
  259. }
  260. }
  261. void LLAvatarTracker::terminateBuddy(const LLUUID& id)
  262. {
  263. lldebugs << "LLAvatarTracker::terminateBuddy()" << llendl;
  264. LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id);
  265. if(!buddy) return;
  266. mBuddyInfo.erase(id);
  267. LLMessageSystem* msg = gMessageSystem;
  268. msg->newMessage("TerminateFriendship");
  269. msg->nextBlock("AgentData");
  270. msg->addUUID("AgentID", gAgent.getID());
  271. msg->addUUID("SessionID", gAgent.getSessionID());
  272. msg->nextBlock("ExBlock");
  273. msg->addUUID("OtherID", id);
  274. gAgent.sendReliableMessage();
  275.  
  276. addChangedMask(LLFriendObserver::REMOVE, id);
  277. delete buddy;
  278. }
  279. // get all buddy info
  280. const LLRelationship* LLAvatarTracker::getBuddyInfo(const LLUUID& id) const
  281. {
  282. if(id.isNull()) return NULL;
  283. return get_ptr_in_map(mBuddyInfo, id);
  284. }
  285. bool LLAvatarTracker::isBuddy(const LLUUID& id) const
  286. {
  287. LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
  288. return (info != NULL);
  289. }
  290. // online status
  291. void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
  292. {
  293. LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
  294. if(info)
  295. {
  296. info->online(is_online);
  297. addChangedMask(LLFriendObserver::ONLINE, id);
  298. lldebugs << "Set buddy " << id << (is_online ? " Online" : " Offline") << llendl;
  299. }
  300. else
  301. {
  302. llwarns << "!! No buddy info found for " << id 
  303. << ", setting to " << (is_online ? "Online" : "Offline") << llendl;
  304. }
  305. }
  306. bool LLAvatarTracker::isBuddyOnline(const LLUUID& id) const
  307. {
  308. LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
  309. if(info)
  310. {
  311. return info->isOnline();
  312. }
  313. return false;
  314. }
  315. // empowered status
  316. void LLAvatarTracker::setBuddyEmpowered(const LLUUID& id, bool is_empowered)
  317. {
  318. LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
  319. if(info)
  320. {
  321. info->grantRights(LLRelationship::GRANT_MODIFY_OBJECTS, 0);
  322. mModifyMask |= LLFriendObserver::POWERS;
  323. }
  324. }
  325. bool LLAvatarTracker::isBuddyEmpowered(const LLUUID& id) const
  326. {
  327. LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
  328. if(info)
  329. {
  330. return info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
  331. }
  332. return false;
  333. }
  334. void LLAvatarTracker::empower(const LLUUID& id, bool grant)
  335. {
  336. // wrapper for ease of use in some situations.
  337. buddy_map_t list;
  338. /*
  339. list.insert(id);
  340. empowerList(list, grant);
  341. */
  342. }
  343. void LLAvatarTracker::empowerList(const buddy_map_t& list, bool grant)
  344. {
  345. llwarns << "LLAvatarTracker::empowerList() not implemented." << llendl;
  346. /*
  347. LLMessageSystem* msg = gMessageSystem;
  348. const char* message_name;
  349. const char* block_name;
  350. const char* field_name;
  351. if(grant)
  352. {
  353. message_name = _PREHASH_GrantModification;
  354. block_name = _PREHASH_EmpoweredBlock;
  355. field_name = _PREHASH_EmpoweredID;
  356. }
  357. else
  358. {
  359. message_name = _PREHASH_RevokeModification;
  360. block_name = _PREHASH_RevokedBlock;
  361. field_name = _PREHASH_RevokedID;
  362. }
  363. std::string name;
  364. gAgent.buildFullnameAndTitle(name);
  365. bool start_new_message = true;
  366. buddy_list_t::const_iterator it = list.begin();
  367. buddy_list_t::const_iterator end = list.end();
  368. for(; it != end; ++it)
  369. {
  370. if(NULL == get_ptr_in_map(mBuddyInfo, (*it))) continue;
  371. setBuddyEmpowered((*it), grant);
  372. if(start_new_message)
  373. {
  374. start_new_message = false;
  375. msg->newMessageFast(message_name);
  376. msg->nextBlockFast(_PREHASH_AgentData);
  377. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  378. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  379. msg->addStringFast(_PREHASH_GranterName, name);
  380. }
  381. msg->nextBlockFast(block_name);
  382. msg->addUUIDFast(field_name, (*it));
  383. if(msg->isSendFullFast(block_name))
  384. {
  385. start_new_message = true;
  386. gAgent.sendReliableMessage();
  387. }
  388. }
  389. if(!start_new_message)
  390. {
  391. gAgent.sendReliableMessage();
  392. }
  393. */
  394. }
  395. void LLAvatarTracker::deleteTrackingData()
  396. {
  397. //make sure mTrackingData never points to freed memory
  398. LLTrackingData* tmp = mTrackingData;
  399. mTrackingData = NULL;
  400. delete tmp;
  401. }
  402. void LLAvatarTracker::findAgent()
  403. {
  404. if (!mTrackingData) return;
  405. if (mTrackingData->mAvatarID.isNull()) return;
  406. LLMessageSystem* msg = gMessageSystem;
  407. msg->newMessageFast(_PREHASH_FindAgent); // Request
  408. msg->nextBlockFast(_PREHASH_AgentBlock);
  409. msg->addUUIDFast(_PREHASH_Hunter, gAgentID);
  410. msg->addUUIDFast(_PREHASH_Prey, mTrackingData->mAvatarID);
  411. msg->addU32Fast(_PREHASH_SpaceIP, 0); // will get filled in by simulator
  412. msg->nextBlockFast(_PREHASH_LocationBlock);
  413. const F64 NO_LOCATION = 0.0;
  414. msg->addF64Fast(_PREHASH_GlobalX, NO_LOCATION);
  415. msg->addF64Fast(_PREHASH_GlobalY, NO_LOCATION);
  416. gAgent.sendReliableMessage();
  417. }
  418. void LLAvatarTracker::addObserver(LLFriendObserver* observer)
  419. {
  420. if(observer)
  421. {
  422. mObservers.push_back(observer);
  423. }
  424. }
  425. void LLAvatarTracker::removeObserver(LLFriendObserver* observer)
  426. {
  427. mObservers.erase(
  428. std::remove(mObservers.begin(), mObservers.end(), observer),
  429. mObservers.end());
  430. }
  431. void LLAvatarTracker::notifyObservers()
  432. {
  433. observer_list_t observers(mObservers);
  434. observer_list_t::iterator it = observers.begin();
  435. observer_list_t::iterator end = observers.end();
  436. for(; it != end; ++it)
  437. {
  438. (*it)->changed(mModifyMask);
  439. }
  440. for (changed_buddy_t::iterator it = mChangedBuddyIDs.begin(); it != mChangedBuddyIDs.end(); it++)
  441. {
  442. notifyParticularFriendObservers(*it);
  443. }
  444. mModifyMask = LLFriendObserver::NONE;
  445. mChangedBuddyIDs.clear();
  446. }
  447. void LLAvatarTracker::addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer)
  448. {
  449. if (buddy_id.notNull() && observer)
  450. mParticularFriendObserverMap[buddy_id].insert(observer);
  451. }
  452. void LLAvatarTracker::removeParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer)
  453. {
  454. if (buddy_id.isNull() || !observer)
  455. return;
  456.     observer_map_t::iterator obs_it = mParticularFriendObserverMap.find(buddy_id);
  457.     if(obs_it == mParticularFriendObserverMap.end())
  458.         return;
  459.     obs_it->second.erase(observer);
  460.     // purge empty sets from the map
  461.     if (obs_it->second.size() == 0)
  462.      mParticularFriendObserverMap.erase(obs_it);
  463. }
  464. void LLAvatarTracker::notifyParticularFriendObservers(const LLUUID& buddy_id)
  465. {
  466.     observer_map_t::iterator obs_it = mParticularFriendObserverMap.find(buddy_id);
  467.     if(obs_it == mParticularFriendObserverMap.end())
  468.         return;
  469.     // Notify observers interested in buddy_id.
  470.     observer_set_t& obs = obs_it->second;
  471.     for (observer_set_t::iterator ob_it = obs.begin(); ob_it != obs.end(); ob_it++)
  472.     {
  473.         (*ob_it)->changed(mModifyMask);
  474.     }
  475. }
  476. // store flag for change
  477. // and id of object change applies to
  478. void LLAvatarTracker::addChangedMask(U32 mask, const LLUUID& referent)
  479. mModifyMask |= mask; 
  480. if (referent.notNull())
  481. {
  482. mChangedBuddyIDs.insert(referent);
  483. }
  484. }
  485. void LLAvatarTracker::applyFunctor(LLRelationshipFunctor& f)
  486. {
  487. buddy_map_t::iterator it = mBuddyInfo.begin();
  488. buddy_map_t::iterator end = mBuddyInfo.end();
  489. for(; it != end; ++it)
  490. {
  491. f((*it).first, (*it).second);
  492. }
  493. }
  494. void LLAvatarTracker::registerCallbacks(LLMessageSystem* msg)
  495. {
  496. msg->setHandlerFuncFast(_PREHASH_FindAgent, processAgentFound);
  497. msg->setHandlerFuncFast(_PREHASH_OnlineNotification,
  498. processOnlineNotification);
  499. msg->setHandlerFuncFast(_PREHASH_OfflineNotification,
  500. processOfflineNotification);
  501. //msg->setHandlerFuncFast(_PREHASH_GrantedProxies,
  502. // processGrantedProxies);
  503. msg->setHandlerFunc("TerminateFriendship", processTerminateFriendship);
  504. msg->setHandlerFunc(_PREHASH_ChangeUserRights, processChangeUserRights);
  505. }
  506. // static
  507. void LLAvatarTracker::processAgentFound(LLMessageSystem* msg, void**)
  508. {
  509. LLUUID id;
  510. msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_Hunter, id);
  511. msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_Prey, id);
  512. // *FIX: should make sure prey id matches.
  513. LLVector3d estimated_global_pos;
  514. msg->getF64Fast(_PREHASH_LocationBlock, _PREHASH_GlobalX,
  515.  estimated_global_pos.mdV[VX]);
  516. msg->getF64Fast(_PREHASH_LocationBlock, _PREHASH_GlobalY,
  517.  estimated_global_pos.mdV[VY]);
  518. LLAvatarTracker::instance().agentFound(id, estimated_global_pos);
  519. }
  520. void LLAvatarTracker::agentFound(const LLUUID& prey,
  521.  const LLVector3d& estimated_global_pos)
  522. {
  523. if(!mTrackingData) return;
  524. //if we get a valid reply from the server, that means the agent
  525. //is our friend and mappable, so enable interest list based updates
  526. LLAvatarTracker::instance().setTrackedAgentValid(true);
  527. mTrackingData->agentFound(prey, estimated_global_pos);
  528. }
  529. //  static
  530. void LLAvatarTracker::processOnlineNotification(LLMessageSystem* msg, void**)
  531. {
  532. lldebugs << "LLAvatarTracker::processOnlineNotification()" << llendl;
  533. instance().processNotify(msg, true);
  534. }
  535. //  static
  536. void LLAvatarTracker::processOfflineNotification(LLMessageSystem* msg, void**)
  537. {
  538. lldebugs << "LLAvatarTracker::processOfflineNotification()" << llendl;
  539. instance().processNotify(msg, false);
  540. }
  541. void LLAvatarTracker::processChange(LLMessageSystem* msg)
  542. {
  543. S32 count = msg->getNumberOfBlocksFast(_PREHASH_Rights);
  544. LLUUID agent_id, agent_related;
  545. S32 new_rights;
  546. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
  547. for(int i = 0; i < count; ++i)
  548. {
  549. msg->getUUIDFast(_PREHASH_Rights, _PREHASH_AgentRelated, agent_related, i);
  550. msg->getS32Fast(_PREHASH_Rights,_PREHASH_RelatedRights, new_rights, i);
  551. if(agent_id == gAgent.getID())
  552. {
  553. if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
  554. {
  555. (mBuddyInfo[agent_related])->setRightsTo(new_rights);
  556. }
  557. }
  558. else
  559. {
  560. if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
  561. {
  562. if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^  new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
  563. {
  564. std::string name;
  565. LLSD args;
  566. if(gCacheName->getFullName(agent_id, name))
  567. {
  568. args["NAME"] = name;
  569. }
  570. LLSD payload;
  571. payload["from_id"] = agent_id;
  572. if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)
  573. {
  574. LLNotificationsUtil::add("GrantedModifyRights",args, payload);
  575. }
  576. else
  577. {
  578. LLNotificationsUtil::add("RevokedModifyRights",args, payload);
  579. }
  580. }
  581. (mBuddyInfo[agent_id])->setRightsFrom(new_rights);
  582. }
  583. }
  584. }
  585. addChangedMask(LLFriendObserver::POWERS, agent_id);
  586. notifyObservers();
  587. }
  588. void LLAvatarTracker::processChangeUserRights(LLMessageSystem* msg, void**)
  589. {
  590. lldebugs << "LLAvatarTracker::processChangeUserRights()" << llendl;
  591. instance().processChange(msg);
  592. }
  593. void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
  594. {
  595. S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock);
  596. BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification");
  597. lldebugs << "Received " << count << " online notifications **** " << llendl;
  598. if(count > 0)
  599. {
  600. LLUUID agent_id;
  601. const LLRelationship* info = NULL;
  602. LLUUID tracking_id;
  603. if(mTrackingData)
  604. {
  605. tracking_id = mTrackingData->mAvatarID;
  606. }
  607. BOOL notify = FALSE;
  608. LLSD args;
  609. LLSD payload;
  610. for(S32 i = 0; i < count; ++i)
  611. {
  612. msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i);
  613. payload["FROM_ID"] = agent_id;
  614. info = getBuddyInfo(agent_id);
  615. if(info)
  616. {
  617. setBuddyOnline(agent_id,online);
  618. if(chat_notify)
  619. {
  620. std::string first, last;
  621. if(gCacheName->getName(agent_id, first, last))
  622. {
  623. notify = TRUE;
  624. args["FIRST"] = first;
  625. args["LAST"] = last;
  626. }
  627. }
  628. }
  629. else
  630. {
  631. llwarns << "Received online notification for unknown buddy: " 
  632. << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << llendl;
  633. }
  634. if(tracking_id == agent_id)
  635. {
  636. // we were tracking someone who went offline
  637. deleteTrackingData();
  638. }
  639. // *TODO: get actual inventory id
  640. gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null);
  641. }
  642. if(notify)
  643. {
  644. // Popup a notify box with online status of this agent
  645. LLNotificationPtr notification;
  646. if (online)
  647. {
  648. notification =
  649. LLNotificationsUtil::add("FriendOnline",
  650.  args,
  651.  payload.with("respond_on_mousedown", TRUE),
  652.  boost::bind(&LLAvatarActions::startIM, agent_id));
  653. }
  654. else
  655. {
  656. notification =
  657. LLNotificationsUtil::add("FriendOffline", args, payload);
  658. }
  659. // If there's an open IM session with this agent, send a notification there too.
  660. LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id);
  661. std::string notify_msg = notification->getMessage();
  662. LLIMModel::instance().proccessOnlineOfflineNotification(session_id, notify_msg);
  663. }
  664. mModifyMask |= LLFriendObserver::ONLINE;
  665. instance().notifyObservers();
  666. gInventory.notifyObservers();
  667. }
  668. }
  669. void LLAvatarTracker::formFriendship(const LLUUID& id)
  670. {
  671. if(id.notNull())
  672. {
  673. LLRelationship* buddy_info = get_ptr_in_map(instance().mBuddyInfo, id);
  674. if(!buddy_info)
  675. {
  676. LLAvatarTracker& at = LLAvatarTracker::instance();
  677. //The default for relationship establishment is to have both parties
  678. //visible online to each other.
  679. buddy_info = new LLRelationship(LLRelationship::GRANT_ONLINE_STATUS,LLRelationship::GRANT_ONLINE_STATUS, false);
  680. at.mBuddyInfo[id] = buddy_info;
  681. at.addChangedMask(LLFriendObserver::ADD, id);
  682. at.notifyObservers();
  683. }
  684. }
  685. }
  686. void LLAvatarTracker::processTerminateFriendship(LLMessageSystem* msg, void**)
  687. {
  688. LLUUID id;
  689. msg->getUUID("ExBlock", "OtherID", id);
  690. if(id.notNull())
  691. {
  692. LLAvatarTracker& at = LLAvatarTracker::instance();
  693. LLRelationship* buddy = get_ptr_in_map(at.mBuddyInfo, id);
  694. if(!buddy) return;
  695. at.mBuddyInfo.erase(id);
  696. at.addChangedMask(LLFriendObserver::REMOVE, id);
  697. delete buddy;
  698. at.notifyObservers();
  699. }
  700. }
  701. ///----------------------------------------------------------------------------
  702. /// Tracking Data
  703. ///----------------------------------------------------------------------------
  704. LLTrackingData::LLTrackingData(const LLUUID& avatar_id, const std::string& name)
  705. : mAvatarID(avatar_id),
  706. mHaveInfo(false),
  707. mHaveCoarseInfo(false)
  708. {
  709. mCoarseLocationTimer.setTimerExpirySec(COARSE_FREQUENCY);
  710. mUpdateTimer.setTimerExpirySec(FIND_FREQUENCY);
  711. mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
  712. if(!name.empty())
  713. {
  714. mName = name;
  715. }
  716. }
  717. void LLTrackingData::agentFound(const LLUUID& prey,
  718. const LLVector3d& estimated_global_pos)
  719. {
  720. if(prey != mAvatarID)
  721. {
  722. llwarns << "LLTrackingData::agentFound() - found " << prey
  723. << " but looking for " << mAvatarID << llendl;
  724. }
  725. mHaveInfo = true;
  726. mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
  727. mGlobalPositionEstimate = estimated_global_pos;
  728. }
  729. bool LLTrackingData::haveTrackingInfo()
  730. {
  731. LLViewerObject* object = gObjectList.findObject(mAvatarID);
  732. if(object && !object->isDead())
  733. {
  734. mCoarseLocationTimer.checkExpirationAndReset(COARSE_FREQUENCY);
  735. mUpdateTimer.setTimerExpirySec(FIND_FREQUENCY);
  736. mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
  737. mHaveInfo = true;
  738. return true;
  739. }
  740. if(mHaveCoarseInfo &&
  741.    !mCoarseLocationTimer.checkExpirationAndReset(COARSE_FREQUENCY))
  742. {
  743. // if we reach here, then we have a 'recent' coarse update
  744. mUpdateTimer.setTimerExpirySec(FIND_FREQUENCY);
  745. mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
  746. return true;
  747. }
  748. if(mUpdateTimer.checkExpirationAndReset(FIND_FREQUENCY))
  749. {
  750. LLAvatarTracker::instance().findAgent();
  751. mHaveCoarseInfo = false;
  752. }
  753. if(mAgentGone.checkExpirationAndReset(OFFLINE_SECONDS))
  754. {
  755. mHaveInfo = false;
  756. mHaveCoarseInfo = false;
  757. }
  758. return mHaveInfo;
  759. }
  760. void LLTrackingData::setTrackedCoarseLocation(const LLVector3d& global_pos)
  761. {
  762. mCoarseLocationTimer.setTimerExpirySec(COARSE_FREQUENCY);
  763. mGlobalPositionEstimate = global_pos;
  764. mHaveInfo = true;
  765. mHaveCoarseInfo = true;
  766. }
  767. ///----------------------------------------------------------------------------
  768. // various buddy functors
  769. ///----------------------------------------------------------------------------
  770. bool LLCollectProxyBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
  771. {
  772. if(buddy->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS))
  773. {
  774. mProxy.insert(buddy_id);
  775. }
  776. return true;
  777. }
  778. bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
  779. {
  780. gCacheName->getName(buddy_id, mFirst, mLast);
  781. std::ostringstream fullname;
  782. fullname << mFirst << " " << mLast;
  783. buddy_map_t::value_type value(fullname.str(), buddy_id);
  784. if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))
  785. {
  786. mMappable.insert(value);
  787. }
  788. return true;
  789. }
  790. bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
  791. {
  792. gCacheName->getName(buddy_id, mFirst, mLast);
  793. std::ostringstream fullname;
  794. fullname << mFirst << " " << mLast;
  795. buddy_map_t::value_type value(fullname.str(), buddy_id);
  796. if(buddy->isOnline())
  797. {
  798. mOnline.insert(value);
  799. }
  800. return true;
  801. }
  802. bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
  803. {
  804. gCacheName->getName(buddy_id, mFirst, mLast);
  805. std::ostringstream fullname;
  806. fullname << mFirst << " " << mLast;
  807. buddy_map_t::value_type value(fullname.str(), buddy_id);
  808. if(buddy->isOnline())
  809. {
  810. mOnline.insert(value);
  811. }
  812. else
  813. {
  814. mOffline.insert(value);
  815. }
  816. return true;
  817. }