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

Generated on Thu Jul 1 06:08:20 2010 for Second Life Viewer by  doxygen 1.4.7