llcallingcard.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #if LL_WINDOWS
00035 #pragma warning( disable : 4800 ) // performance warning in <functional>
00036 #endif
00037 
00038 #include "llcallingcard.h"
00039 
00040 #include <vector>
00041 #include <algorithm>
00042 //#include <iterator>
00043 
00044 #include "indra_constants.h"
00045 #include "llcachename.h"
00046 #include "llstl.h"
00047 #include "lltimer.h"
00048 #include "lluuid.h"
00049 #include "message.h"
00050 
00051 #include "llagent.h"
00052 #include "llbutton.h"
00053 //#include "llinventory.h"
00054 #include "llinventorymodel.h"
00055 #include "llnotify.h"
00056 #include "llresmgr.h"
00057 #include "llimview.h"
00058 #include "llviewercontrol.h"
00059 #include "llviewernetwork.h"
00060 #include "llviewerobjectlist.h"
00061 #include "llviewerwindow.h"
00062 #include "llvoavatar.h"
00063 #include "llimview.h"
00064 #include "llimpanel.h"
00065 
00069 
00070 class LLTrackingData
00071 {
00072 public:
00073         LLTrackingData(const LLUUID& avatar_id, const std::string& name);
00074         bool haveTrackingInfo();
00075         void setTrackedCoarseLocation(const LLVector3d& global_pos);
00076         void agentFound(const LLUUID& prey,
00077                                         const LLVector3d& estimated_global_pos);
00078         
00079 public:
00080         LLUUID mAvatarID;
00081         LLString mName;
00082         LLVector3d mGlobalPositionEstimate;
00083         bool mHaveInfo;
00084         bool mHaveCoarseInfo;
00085         LLTimer mCoarseLocationTimer;
00086         LLTimer mUpdateTimer;
00087         LLTimer mAgentGone;
00088 };
00089 
00090 const F32 COARSE_FREQUENCY = 2.2f;
00091 const F32 FIND_FREQUENCY = 29.7f;       // This results in a database query, so cut these back
00092 const F32 OFFLINE_SECONDS = FIND_FREQUENCY + 8.0f;
00093 
00094 // static
00095 LLAvatarTracker LLAvatarTracker::sInstance;
00096 
00097 /*
00098 class LLAvatarTrackerInventoryObserver : public LLInventoryObserver
00099 {
00100 public:
00101         LLAvatarTrackerInventoryObserver(LLAvatarTracker* at) :
00102                 mAT(at) {}
00103         virtual ~LLAvatarTrackerInventoryObserver() {}
00104         virtual void changed(U32 mask);
00105 protected:
00106         LLAvatarTracker* mAT;
00107 };
00108 */
00109 
00110 /*
00111 void LLAvatarTrackerInventoryObserver::changed(U32 mask)
00112 {
00113         // if there's a calling card change, just do it.
00114         if((mask & LLInventoryObserver::CALLING_CARD) != 0)
00115         {
00116                 mAT->inventoryChanged();
00117         }
00118 }
00119 */
00120 
00124 
00125 LLAvatarTracker::LLAvatarTracker() :
00126         mTrackingData(NULL),
00127         mTrackedAgentValid(false),
00128         //mInventory(NULL),
00129         //mInventoryObserver(NULL),
00130         mModifyMask(0x0)        
00131 {
00132 }
00133 
00134 LLAvatarTracker::~LLAvatarTracker()
00135 {
00136         deleteTrackingData();
00137         std::for_each(mObservers.begin(), mObservers.end(), DeletePointer());
00138         std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer());
00139 }
00140 
00141 void LLAvatarTracker::track(const LLUUID& avatar_id, const std::string& name)
00142 {
00143         deleteTrackingData();
00144         mTrackedAgentValid = false;
00145         mTrackingData = new LLTrackingData(avatar_id, name);
00146         findAgent();
00147 
00148         // We track here because findAgent() is called on a timer (for now).
00149         if(avatar_id.notNull())
00150         {
00151                 LLMessageSystem* msg = gMessageSystem;
00152                 msg->newMessageFast(_PREHASH_TrackAgent);
00153                 msg->nextBlockFast(_PREHASH_AgentData);
00154                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00155                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00156                 msg->nextBlockFast(_PREHASH_TargetData);
00157                 msg->addUUIDFast(_PREHASH_PreyID, avatar_id);
00158                 gAgent.sendReliableMessage();
00159         }
00160 }
00161 
00162 void LLAvatarTracker::untrack(const LLUUID& avatar_id)
00163 {
00164         if (mTrackingData && mTrackingData->mAvatarID == avatar_id)
00165         {
00166                 deleteTrackingData();
00167                 mTrackedAgentValid = false;
00168                 LLMessageSystem* msg = gMessageSystem;
00169                 msg->newMessageFast(_PREHASH_TrackAgent);
00170                 msg->nextBlockFast(_PREHASH_AgentData);
00171                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00172                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00173                 msg->nextBlockFast(_PREHASH_TargetData);
00174                 msg->addUUIDFast(_PREHASH_PreyID, LLUUID::null);
00175                 gAgent.sendReliableMessage();
00176         }
00177 }
00178 
00179 void LLAvatarTracker::setTrackedCoarseLocation(const LLVector3d& global_pos)
00180 {
00181         if(mTrackingData)
00182         {
00183                 mTrackingData->setTrackedCoarseLocation(global_pos);
00184         }
00185 }
00186 
00187 bool LLAvatarTracker::haveTrackingInfo()
00188 {
00189         if(mTrackingData)
00190         {
00191                 return mTrackingData->haveTrackingInfo();
00192         }
00193         return false;
00194 }
00195 
00196 LLVector3d LLAvatarTracker::getGlobalPos()
00197 {
00198         if(!mTrackedAgentValid || !mTrackingData) return LLVector3d();
00199         LLVector3d global_pos;
00200         
00201         LLViewerObject* object = gObjectList.findObject(mTrackingData->mAvatarID);
00202         if(object && !object->isDead())
00203         {
00204                 global_pos = object->getPositionGlobal();
00205                 // HACK - for making the tracker point above the avatar's head
00206                 // rather than its groin
00207                 global_pos.mdV[VZ] += 0.7f * ((LLVOAvatar *)object)->mBodySize.mV[VZ];
00208 
00209                 mTrackingData->mGlobalPositionEstimate = global_pos;
00210         }
00211         else
00212         {
00213                 global_pos = mTrackingData->mGlobalPositionEstimate;
00214         }
00215 
00216         return global_pos;
00217 }
00218 
00219 void LLAvatarTracker::getDegreesAndDist(F32& rot,
00220                                                                                 F64& horiz_dist,
00221                                                                                 F64& vert_dist)
00222 {
00223         if(!mTrackingData) return;
00224 
00225         LLVector3d global_pos;
00226 
00227         LLViewerObject* object = gObjectList.findObject(mTrackingData->mAvatarID);
00228         if(object && !object->isDead())
00229         {
00230                 global_pos = object->getPositionGlobal();
00231                 mTrackingData->mGlobalPositionEstimate = global_pos;
00232         }
00233         else
00234         {
00235                 global_pos = mTrackingData->mGlobalPositionEstimate;
00236         }
00237         LLVector3d to_vec = global_pos - gAgent.getPositionGlobal();
00238         horiz_dist = sqrt(to_vec.mdV[VX] * to_vec.mdV[VX] + to_vec.mdV[VY] * to_vec.mdV[VY]);
00239         vert_dist = to_vec.mdV[VZ];
00240         rot = F32(RAD_TO_DEG * atan2(to_vec.mdV[VY], to_vec.mdV[VX]));
00241 }
00242 
00243 const LLString& LLAvatarTracker::getName()
00244 {
00245         if(mTrackingData)
00246         {
00247                 return mTrackingData->mName;
00248         }
00249         else
00250         {
00251                 return LLString::null;
00252         }
00253 }
00254 
00255 const LLUUID& LLAvatarTracker::getAvatarID()
00256 {
00257         if(mTrackingData)
00258         {
00259                 return mTrackingData->mAvatarID;
00260         }
00261         else
00262         {
00263                 return LLUUID::null;
00264         }
00265 }
00266 
00267 S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
00268 {
00269         using namespace std;
00270 
00271         U32 new_buddy_count = 0;
00272         std::string first,last;
00273         LLUUID agent_id;
00274         for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr)
00275         {
00276                 agent_id = (*itr).first;
00277                 buddy_map_t::const_iterator existing_buddy = mBuddyInfo.find(agent_id);
00278                 if(existing_buddy == mBuddyInfo.end())
00279                 {
00280                         ++new_buddy_count;
00281                         mBuddyInfo[agent_id] = (*itr).second;
00282                         gCacheName->getName(agent_id, first, last);
00283                         mModifyMask |= LLFriendObserver::ADD;
00284                         lldebugs << "Added buddy " << agent_id
00285                                         << ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline")
00286                                         << ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo()
00287                                         << ", FROM: " << mBuddyInfo[agent_id]->getRightsGrantedFrom()
00288                                         << llendl;
00289                 }
00290                 else
00291                 {
00292                         LLRelationship* e_r = (*existing_buddy).second;
00293                         LLRelationship* n_r = (*itr).second;
00294                         llwarns << "!! Add buddy for existing buddy: " << agent_id
00295                                         << " [" << (e_r->isOnline() ? "Online" : "Offline") << "->" << (n_r->isOnline() ? "Online" : "Offline")
00296                                         << ", " <<  e_r->getRightsGrantedTo() << "->" << n_r->getRightsGrantedTo()
00297                                         << ", " <<  e_r->getRightsGrantedTo() << "->" << n_r->getRightsGrantedTo()
00298                                         << "]" << llendl;
00299                 }
00300         }
00301         notifyObservers();
00302         
00303         return new_buddy_count;
00304 }
00305 
00306 
00307 void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const
00308 {
00309         buddy_map_t::const_iterator it = mBuddyInfo.begin();
00310         buddy_map_t::const_iterator end = mBuddyInfo.end();
00311         for(; it != end; ++it)
00312         {
00313                 buddies[(*it).first] = (*it).second;
00314         }
00315 }
00316 
00317 void LLAvatarTracker::terminateBuddy(const LLUUID& id)
00318 {
00319         lldebugs << "LLAvatarTracker::terminateBuddy()" << llendl;
00320         LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id);
00321         if(!buddy) return;
00322         mBuddyInfo.erase(id);
00323         LLMessageSystem* msg = gMessageSystem;
00324         msg->newMessage("TerminateFriendship");
00325         msg->nextBlock("AgentData");
00326         msg->addUUID("AgentID", gAgent.getID());
00327         msg->addUUID("SessionID", gAgent.getSessionID());
00328         msg->nextBlock("ExBlock");
00329         msg->addUUID("OtherID", id);
00330         gAgent.sendReliableMessage();
00331         mModifyMask |= LLFriendObserver::REMOVE;
00332         delete buddy;
00333 }
00334 
00335 // get all buddy info
00336 const LLRelationship* LLAvatarTracker::getBuddyInfo(const LLUUID& id) const
00337 {
00338         if(id.isNull()) return NULL;
00339         return get_ptr_in_map(mBuddyInfo, id);
00340 }
00341 
00342 // online status
00343 void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
00344 {
00345         LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
00346         if(info)
00347         {
00348                 info->online(is_online);
00349                 mModifyMask |= LLFriendObserver::ONLINE;
00350                 lldebugs << "Set buddy " << id << (is_online ? " Online" : " Offline") << llendl;
00351         }
00352         else
00353         {
00354                 llwarns << "!! No buddy info found for " << id 
00355                                 << ", setting to " << (is_online ? "Online" : "Offline") << llendl;
00356         }
00357 }
00358 
00359 bool LLAvatarTracker::isBuddyOnline(const LLUUID& id) const
00360 {
00361         LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
00362         if(info)
00363         {
00364                 return info->isOnline();
00365         }
00366         return false;
00367 }
00368 
00369 // empowered status
00370 void LLAvatarTracker::setBuddyEmpowered(const LLUUID& id, bool is_empowered)
00371 {
00372         LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
00373         if(info)
00374         {
00375                 info->grantRights(LLRelationship::GRANT_MODIFY_OBJECTS, 0);
00376                 mModifyMask |= LLFriendObserver::POWERS;
00377         }
00378 }
00379 
00380 bool LLAvatarTracker::isBuddyEmpowered(const LLUUID& id) const
00381 {
00382         LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
00383         if(info)
00384         {
00385                 return info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
00386         }
00387         return false;
00388 }
00389 
00390 void LLAvatarTracker::empower(const LLUUID& id, bool grant)
00391 {
00392         // wrapper for ease of use in some situations.
00393         buddy_map_t list;
00394         /*
00395         list.insert(id);
00396         empowerList(list, grant);
00397         */
00398 }
00399 
00400 void LLAvatarTracker::empowerList(const buddy_map_t& list, bool grant)
00401 {
00402         llwarns << "LLAvatarTracker::empowerList() not implemented." << llendl;
00403 /*
00404         LLMessageSystem* msg = gMessageSystem;
00405         const char* message_name;
00406         const char* block_name;
00407         const char* field_name;
00408         if(grant)
00409         {
00410                 message_name = _PREHASH_GrantModification;
00411                 block_name = _PREHASH_EmpoweredBlock;
00412                 field_name = _PREHASH_EmpoweredID;
00413         }
00414         else
00415         {
00416                 message_name = _PREHASH_RevokeModification;
00417                 block_name = _PREHASH_RevokedBlock;
00418                 field_name = _PREHASH_RevokedID;
00419         }
00420 
00421         std::string name;
00422         gAgent.buildFullnameAndTitle(name);
00423 
00424         bool start_new_message = true;
00425         buddy_list_t::const_iterator it = list.begin();
00426         buddy_list_t::const_iterator end = list.end();
00427         for(; it != end; ++it)
00428         {
00429                 if(NULL == get_ptr_in_map(mBuddyInfo, (*it))) continue;
00430                 setBuddyEmpowered((*it), grant);
00431                 if(start_new_message)
00432                 {
00433                         start_new_message = false;
00434                         msg->newMessageFast(message_name);
00435                         msg->nextBlockFast(_PREHASH_AgentData);
00436                         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00437                         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00438                         msg->addStringFast(_PREHASH_GranterName, name);
00439                 }
00440                 msg->nextBlockFast(block_name);
00441                 msg->addUUIDFast(field_name, (*it));
00442                 if(msg->isSendFullFast(block_name))
00443                 {
00444                         start_new_message = true;
00445                         gAgent.sendReliableMessage();
00446                 }
00447         }
00448         if(!start_new_message)
00449         {
00450                 gAgent.sendReliableMessage();
00451         }
00452 */
00453 }
00454 
00455 void LLAvatarTracker::deleteTrackingData()
00456 {
00457         //make sure mTrackingData never points to freed memory
00458         LLTrackingData* tmp = mTrackingData;
00459         mTrackingData = NULL;
00460         delete tmp;
00461 }
00462 
00463 void LLAvatarTracker::findAgent()
00464 {
00465         if (!mTrackingData) return;
00466         if (mTrackingData->mAvatarID.isNull()) return;
00467         LLMessageSystem* msg = gMessageSystem;
00468         msg->newMessageFast(_PREHASH_FindAgent); // Request
00469         msg->nextBlockFast(_PREHASH_AgentBlock);
00470         msg->addUUIDFast(_PREHASH_Hunter, gAgentID);
00471         msg->addUUIDFast(_PREHASH_Prey, mTrackingData->mAvatarID);
00472         msg->addU32Fast(_PREHASH_SpaceIP, 0); // will get filled in by simulator
00473         msg->nextBlockFast(_PREHASH_LocationBlock);
00474         const F64 NO_LOCATION = 0.0;
00475         msg->addF64Fast(_PREHASH_GlobalX, NO_LOCATION);
00476         msg->addF64Fast(_PREHASH_GlobalY, NO_LOCATION);
00477         gAgent.sendReliableMessage();
00478 }
00479 
00480 void LLAvatarTracker::addObserver(LLFriendObserver* observer)
00481 {
00482         if(observer)
00483         {
00484                 mObservers.push_back(observer);
00485         }
00486 }
00487 
00488 void LLAvatarTracker::removeObserver(LLFriendObserver* observer)
00489 {
00490         mObservers.erase(
00491                 std::remove(mObservers.begin(), mObservers.end(), observer),
00492                 mObservers.end());
00493 }
00494 
00495 void LLAvatarTracker::notifyObservers()
00496 {
00497         observer_list_t observers(mObservers);
00498         observer_list_t::iterator it = observers.begin();
00499         observer_list_t::iterator end = observers.end();
00500         for(; it != end; ++it)
00501         {
00502                 (*it)->changed(mModifyMask);
00503         }
00504         mModifyMask = LLFriendObserver::NONE;
00505 }
00506 
00507 void LLAvatarTracker::applyFunctor(LLRelationshipFunctor& f)
00508 {
00509         buddy_map_t::iterator it = mBuddyInfo.begin();
00510         buddy_map_t::iterator end = mBuddyInfo.end();
00511         for(; it != end; ++it)
00512         {
00513                 f((*it).first, (*it).second);
00514         }
00515 }
00516 
00517 void LLAvatarTracker::registerCallbacks(LLMessageSystem* msg)
00518 {
00519         msg->setHandlerFuncFast(_PREHASH_FindAgent, processAgentFound);
00520         msg->setHandlerFuncFast(_PREHASH_OnlineNotification,
00521                                                 processOnlineNotification);
00522         msg->setHandlerFuncFast(_PREHASH_OfflineNotification,
00523                                                 processOfflineNotification);
00524         //msg->setHandlerFuncFast(_PREHASH_GrantedProxies,
00525         //                                      processGrantedProxies);
00526         msg->setHandlerFunc("TerminateFriendship", processTerminateFriendship);
00527         msg->setHandlerFunc(_PREHASH_ChangeUserRights, processChangeUserRights);
00528 }
00529 
00530 // static
00531 void LLAvatarTracker::processAgentFound(LLMessageSystem* msg, void**)
00532 {
00533         LLUUID id;
00534 
00535         
00536         msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_Hunter, id);
00537         msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_Prey, id);
00538         // *FIX: should make sure prey id matches.
00539         LLVector3d estimated_global_pos;
00540         msg->getF64Fast(_PREHASH_LocationBlock, _PREHASH_GlobalX,
00541                                  estimated_global_pos.mdV[VX]);
00542         msg->getF64Fast(_PREHASH_LocationBlock, _PREHASH_GlobalY,
00543                                  estimated_global_pos.mdV[VY]);
00544         LLAvatarTracker::instance().agentFound(id, estimated_global_pos);
00545 }
00546 
00547 void LLAvatarTracker::agentFound(const LLUUID& prey,
00548                                                                  const LLVector3d& estimated_global_pos)
00549 {
00550         if(!mTrackingData) return;
00551         //if we get a valid reply from the server, that means the agent
00552         //is our friend and mappable, so enable interest list based updates
00553         LLAvatarTracker::instance().setTrackedAgentValid(true);
00554         mTrackingData->agentFound(prey, estimated_global_pos);
00555 }
00556 
00557 //      static
00558 void LLAvatarTracker::processOnlineNotification(LLMessageSystem* msg, void**)
00559 {
00560         lldebugs << "LLAvatarTracker::processOnlineNotification()" << llendl;
00561         instance().processNotify(msg, true);
00562 }
00563 
00564 //      static
00565 void LLAvatarTracker::processOfflineNotification(LLMessageSystem* msg, void**)
00566 {
00567         lldebugs << "LLAvatarTracker::processOfflineNotification()" << llendl;
00568         instance().processNotify(msg, false);
00569 }
00570 
00571 void LLAvatarTracker::processChange(LLMessageSystem* msg)
00572 {
00573         S32 count = msg->getNumberOfBlocksFast(_PREHASH_Rights);
00574         LLUUID agent_id, agent_related;
00575         S32 new_rights;
00576         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
00577         for(int i = 0; i < count; ++i)
00578         {
00579                 msg->getUUIDFast(_PREHASH_Rights, _PREHASH_AgentRelated, agent_related, i);
00580                 msg->getS32Fast(_PREHASH_Rights,_PREHASH_RelatedRights, new_rights, i);
00581                 if(agent_id == gAgent.getID())
00582                 {
00583                         if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
00584                         {
00585                                 (mBuddyInfo[agent_related])->setRightsTo(new_rights);
00586                         }
00587                 }
00588                 else
00589                 {
00590                         if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
00591                         {
00592                                 if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^  new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
00593                                 {
00594                                         std::string first, last;
00595                                         LLStringBase<char>::format_map_t args;
00596                                         if(gCacheName->getName(agent_id, first, last))
00597                                         {
00598                                                 args["[FIRST_NAME]"] = first;
00599                                                 args["[LAST_NAME]"] = last;     
00600                                         }
00601                                         if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)
00602                                         {
00603                                                 gViewerWindow->alertXml("GrantedModifyRights",args);
00604                                         }
00605                                         else
00606                                         {
00607                                                 gViewerWindow->alertXml("RevokedModifyRights",args);
00608                                         }
00609                                 }
00610                                 (mBuddyInfo[agent_id])->setRightsFrom(new_rights);
00611                         }
00612                 }
00613         }
00614         mModifyMask |= LLFriendObserver::POWERS;
00615 
00616         notifyObservers();
00617 }
00618 
00619 void LLAvatarTracker::processChangeUserRights(LLMessageSystem* msg, void**)
00620 {
00621         lldebugs << "LLAvatarTracker::processChangeUserRights()" << llendl;
00622         instance().processChange(msg);
00623 }
00624 
00625 void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
00626 {
00627         S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock);
00628         BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification");
00629 
00630         lldebugs << "Received " << count << " online notifications **** " << llendl;
00631         if(count > 0)
00632         {
00633                 LLUUID agent_id;
00634                 const LLRelationship* info = NULL;
00635                 LLUUID tracking_id;
00636                 if(mTrackingData)
00637                 {
00638                         tracking_id = mTrackingData->mAvatarID;
00639                 }
00640                 BOOL notify = FALSE;
00641                 LLString::format_map_t args;
00642                 for(S32 i = 0; i < count; ++i)
00643                 {
00644                         msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i);
00645                         info = getBuddyInfo(agent_id);
00646                         if(info)
00647                         {
00648                                 setBuddyOnline(agent_id,online);
00649                                 if(chat_notify)
00650                                 {
00651                                         std::string first, last;
00652                                         if(gCacheName->getName(agent_id, first, last))
00653                                         {
00654                                                 notify = TRUE;
00655                                                 args["[FIRST]"] = first;
00656                                                 args["[LAST]"] = last;
00657                                         }
00658                                 }
00659                         }
00660                         else
00661                         {
00662                                 llwarns << "Received online notification for unknown buddy: " 
00663                                         << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << llendl;
00664                         }
00665 
00666                         if(tracking_id == agent_id)
00667                         {
00668                                 // we were tracking someone who went offline
00669                                 deleteTrackingData();
00670                         }
00671                         // *TODO: get actual inventory id
00672                         gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null);
00673                 }
00674                 if(notify)
00675                 {
00676                         // Popup a notify box with online status of this agent
00677                         LLNotifyBox::showXml(online ? "FriendOnline" : "FriendOffline", args);
00678 
00679                         // If there's an open IM session with this agent, send a notification there too.
00680                         LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id);
00681                         LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
00682                         if (floater)
00683                         {
00684                                 LLUIString notifyMsg = LLNotifyBox::getTemplateMessage((online ? "FriendOnline" : "FriendOffline"),args);
00685                                 if (!notifyMsg.empty())
00686                                         floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor"));
00687                         }
00688                 }
00689 
00690                 mModifyMask |= LLFriendObserver::ONLINE;
00691                 instance().notifyObservers();
00692                 gInventory.notifyObservers();
00693         }
00694 }
00695 
00696 void LLAvatarTracker::formFriendship(const LLUUID& id)
00697 {
00698         if(id.notNull())
00699         {
00700                 LLRelationship* buddy_info = get_ptr_in_map(instance().mBuddyInfo, id);
00701                 if(!buddy_info)
00702                 {
00703                         LLAvatarTracker& at = LLAvatarTracker::instance();
00704                         //The default for relationship establishment is to have both parties
00705                         //visible online to each other.
00706                         buddy_info = new LLRelationship(LLRelationship::GRANT_ONLINE_STATUS,LLRelationship::GRANT_ONLINE_STATUS, false);
00707                         at.mBuddyInfo[id] = buddy_info;
00708                         at.mModifyMask |= LLFriendObserver::ADD;
00709                         at.notifyObservers();
00710                 }
00711         }
00712 }
00713 
00714 void LLAvatarTracker::processTerminateFriendship(LLMessageSystem* msg, void**)
00715 {
00716         LLUUID id;
00717         msg->getUUID("ExBlock", "OtherID", id);
00718         if(id.notNull())
00719         {
00720                 LLAvatarTracker& at = LLAvatarTracker::instance();
00721                 LLRelationship* buddy = get_ptr_in_map(at.mBuddyInfo, id);
00722                 if(!buddy) return;
00723                 at.mBuddyInfo.erase(id);
00724                 at.mModifyMask |= LLFriendObserver::REMOVE;
00725                 delete buddy;
00726                 at.notifyObservers();
00727         }
00728 }
00729 
00733 
00734 LLTrackingData::LLTrackingData(const LLUUID& avatar_id, const std::string& name)
00735 :       mAvatarID(avatar_id),
00736         mHaveInfo(false),
00737         mHaveCoarseInfo(false)
00738 {
00739         mCoarseLocationTimer.setTimerExpirySec(COARSE_FREQUENCY);
00740         mUpdateTimer.setTimerExpirySec(FIND_FREQUENCY);
00741         mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
00742         if(!name.empty())
00743         {
00744                 mName = name;
00745         }
00746 }
00747 
00748 void LLTrackingData::agentFound(const LLUUID& prey,
00749                                                                 const LLVector3d& estimated_global_pos)
00750 {
00751         if(prey != mAvatarID)
00752         {
00753                 llwarns << "LLTrackingData::agentFound() - found " << prey
00754                                 << " but looking for " << mAvatarID << llendl;
00755         }
00756         mHaveInfo = true;
00757         mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
00758         mGlobalPositionEstimate = estimated_global_pos;
00759 }
00760 
00761 bool LLTrackingData::haveTrackingInfo()
00762 {
00763         LLViewerObject* object = gObjectList.findObject(mAvatarID);
00764         if(object && !object->isDead())
00765         {
00766                 mCoarseLocationTimer.checkExpirationAndReset(COARSE_FREQUENCY);
00767                 mUpdateTimer.setTimerExpirySec(FIND_FREQUENCY);
00768                 mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
00769                 mHaveInfo = true;
00770                 return true;
00771         }
00772         if(mHaveCoarseInfo &&
00773            !mCoarseLocationTimer.checkExpirationAndReset(COARSE_FREQUENCY))
00774         {
00775                 // if we reach here, then we have a 'recent' coarse update
00776                 mUpdateTimer.setTimerExpirySec(FIND_FREQUENCY);
00777                 mAgentGone.setTimerExpirySec(OFFLINE_SECONDS);
00778                 return true;
00779         }
00780         if(mUpdateTimer.checkExpirationAndReset(FIND_FREQUENCY))
00781         {
00782                 LLAvatarTracker::instance().findAgent();
00783                 mHaveCoarseInfo = false;
00784         }
00785         if(mAgentGone.checkExpirationAndReset(OFFLINE_SECONDS))
00786         {
00787                 mHaveInfo = false;
00788                 mHaveCoarseInfo = false;
00789         }
00790         return mHaveInfo;
00791 }
00792 
00793 void LLTrackingData::setTrackedCoarseLocation(const LLVector3d& global_pos)
00794 {
00795         mCoarseLocationTimer.setTimerExpirySec(COARSE_FREQUENCY);
00796         mGlobalPositionEstimate = global_pos;
00797         mHaveInfo = true;
00798         mHaveCoarseInfo = true;
00799 }
00800 
00802 // various buddy functors
00804 
00805 bool LLCollectProxyBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
00806 {
00807         if(buddy->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS))
00808         {
00809                 mProxy.insert(buddy_id);
00810         }
00811         return true;
00812 }
00813 
00814 bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
00815 {
00816         gCacheName->getName(buddy_id, mFirst, mLast);
00817         std::ostringstream fullname;
00818         fullname << mFirst << " " << mLast;
00819         buddy_map_t::value_type value(fullname.str(), buddy_id);
00820         if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))
00821         {
00822                 mMappable.insert(value);
00823         }
00824         return true;
00825 }
00826 
00827 bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
00828 {
00829         gCacheName->getName(buddy_id, mFirst, mLast);
00830         std::ostringstream fullname;
00831         fullname << mFirst << " " << mLast;
00832         buddy_map_t::value_type value(fullname.str(), buddy_id);
00833         if(buddy->isOnline())
00834         {
00835                 mOnline.insert(value);
00836         }
00837         return true;
00838 }
00839 
00840 bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
00841 {
00842         gCacheName->getName(buddy_id, mFirst, mLast);
00843         std::ostringstream fullname;
00844         fullname << mFirst << " " << mLast;
00845         buddy_map_t::value_type value(fullname.str(), buddy_id);
00846         if(buddy->isOnline())
00847         {
00848                 mOnline.insert(value);
00849         }
00850         else
00851         {
00852                 mOffline.insert(value);
00853         }
00854         return true;
00855 }
00856 
00857 

Generated on Fri May 16 08:33:15 2008 for SecondLife by  doxygen 1.5.5