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