Shiny new name cache.

This commit is contained in:
Shyotl
2011-07-15 00:21:38 -05:00
parent ce064f5af2
commit 7e0ee6bb71
52 changed files with 932 additions and 742 deletions

View File

@@ -25,10 +25,6 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
/*
Ported to Phoenix by Wolfspirit Magic.
*/
#include "linden_common.h"
#include "llavatarname.h"
@@ -52,7 +48,7 @@ LLAvatarName::LLAvatarName()
mLegacyFirstName(),
mLegacyLastName(),
mIsDisplayNameDefault(false),
mIsDummy(false),
mIsTemporaryName(false),
mExpires(F64_MAX),
mNextUpdate(0.0)
{ }
@@ -94,21 +90,16 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
std::string LLAvatarName::getCompleteName(bool linefeed) const
{
std::string name;
if (!mUsername.empty())
if (mUsername.empty() || mIsDisplayNameDefault)
// If the display name feature is off
// OR this particular display name is defaulted (i.e. based on user name),
// then display only the easier to read instance of the person's name.
{
if (linefeed)
{
name = mDisplayName + "\n(" + mUsername + ")";
}
else
{
name = mDisplayName + " (" + mUsername + ")";
}
name = mDisplayName;
}
else
{
// ...display names are off, legacy name is in mDisplayName
name = mDisplayName;
name = mDisplayName + (linefeed ? "\n(" : "(") + mUsername + ")";
}
return name;
}

View File

@@ -79,7 +79,7 @@ public:
// Under error conditions, we may insert "dummy" records with
// names like "???" into caches as placeholders. These can be
// shown in UI, but are not serialized.
bool mIsDummy;
bool mIsTemporaryName;
// Names can change, so need to keep track of when name was
// last checked.

View File

@@ -25,10 +25,6 @@
* $/LicenseInfo$
*/
/*
Ported to Phoenix by Wolfspirit Magic.
*/
#include "linden_common.h"
#include "llavatarnamecache.h"
@@ -91,8 +87,11 @@ namespace LLAvatarNameCache
// only need per-frame timing resolution
LLFrameTimer sRequestTimer;
// Periodically clean out expired entries from the cache
//LLFrameTimer sEraseExpiredTimer;
/// Maximum time an unrefreshed cache entry is allowed
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
/// Time when unrefreshed cached names were checked last
static F64 sLastExpireCheck;
//-----------------------------------------------------------------------
// Internal methods
@@ -107,10 +106,11 @@ namespace LLAvatarNameCache
void requestNamesViaCapability();
// agent_id/group_id, first_name, last_name, is_group, user_data
// Legacy name system callback
void legacyNameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
void legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
bool is_group
);
void requestNamesViaLegacy();
@@ -124,9 +124,10 @@ namespace LLAvatarNameCache
const LLAvatarName& av_name);
// Is a request in-flight over the network?
bool isRequestPending(const LLUUID& agent_id);
// Erase expired names from cache
void eraseExpired();
void eraseUnrefreshed();
bool expirationFromCacheControl(LLSD headers, F64 *expires);
}
@@ -196,6 +197,7 @@ public:
{
// Pull expiration out of headers if available
F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mHeaders);
F64 now = LLFrameTimer::getTotalSeconds();
LLSD agents = content["agents"];
LLSD::array_const_iterator it = agents.beginArray();
@@ -216,118 +218,91 @@ public:
av_name.mDisplayName = av_name.mUsername;
}
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " "
<< "user '" << av_name.mUsername << "' "
<< "display '" << av_name.mDisplayName << "' "
<< "expires in " << expires - now << " seconds"
<< LL_ENDL;
// cache it and fire signals
LLAvatarNameCache::processName(agent_id, av_name, true);
}
// Same logic as error response case
LLSD unresolved_agents = content["bad_ids"];
if (unresolved_agents.size() > 0)
S32 num_unresolved = unresolved_agents.size();
if (num_unresolved > 0)
{
const std::string DUMMY_NAME("\?\?\?");
LLAvatarName av_name;
av_name.mUsername = DUMMY_NAME;
av_name.mDisplayName = DUMMY_NAME;
av_name.mIsDisplayNameDefault = false;
av_name.mIsDummy = true;
av_name.mExpires = expires;
LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; "
<< "expires in " << expires - now << " seconds"
<< LL_ENDL;
it = unresolved_agents.beginArray();
for ( ; it != unresolved_agents.endArray(); ++it)
{
const LLUUID& agent_id = *it;
// cache it and fire signals
// Wolfspirit: Do not use ??? as username. Try to get a username out of the old legacy name
std::string oldname;
gCacheName->getFullName(agent_id, oldname);
LLStringUtil::toLower(oldname);
LLStringUtil::replaceString(oldname," ",".");
LLStringUtil::replaceString(oldname,".resident","");
av_name.mUsername = oldname;
LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result "
<< "failed id " << agent_id
<< LL_ENDL;
LLAvatarNameCache::processName(agent_id, av_name, true);
LLAvatarNameCache::handleAgentError(agent_id);
}
}
}
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
<< LLAvatarNameCache::sCache.size() << " cached names"
<< LL_ENDL;
}
/*virtual*/ void error(U32 status, const std::string& reason)
{
// We're going to construct a dummy record and cache it for a while,
// either briefly for a 503 Service Unavailable, or longer for other
// errors.
F64 retry_timestamp = errorRetryTimestamp(status);
// If there's an error, it might be caused by PeopleApi,
// or when loading textures on startup and using a very slow
// network, this query may time out.
// What we should do depends on whether or not we have a cached name
LL_WARNS("AvNameCache") << "LLAvatarNameResponder::error " << status << " " << reason
<< LL_ENDL;
// *NOTE: "??" starts trigraphs in C/C++, escape the question marks.
const std::string DUMMY_NAME("\?\?\?");
LLAvatarName av_name;
av_name.mUsername = DUMMY_NAME;
av_name.mDisplayName = DUMMY_NAME;
av_name.mIsDisplayNameDefault = false;
av_name.mIsDummy = true;
av_name.mExpires = retry_timestamp;
// Add dummy records for all agent IDs in this request
// Add dummy records for any agent IDs in this request that we do not have cached already
std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();
for ( ; it != mAgentIDs.end(); ++it)
{
const LLUUID& agent_id = *it;
// cache it and fire signals
// Wolfspirit: Do not use ??? as username. Try to get a username out of the old legacy name
std::string oldname;
gCacheName->getFullName(agent_id, oldname);
LLStringUtil::toLower(oldname);
LLStringUtil::replaceString(oldname," ",".");
LLStringUtil::replaceString(oldname,".resident","");
av_name.mUsername = oldname;
LLAvatarNameCache::processName(agent_id, av_name, true);
}
}
// Return time to retry a request that generated an error, based on
// error type and headers. Return value is seconds-since-epoch.
F64 errorRetryTimestamp(S32 status)
{
F64 now = LLFrameTimer::getTotalSeconds();
// Retry-After takes priority
LLSD retry_after = mHeaders["retry-after"];
if (retry_after.isDefined())
{
// We only support the delta-seconds type
S32 delta_seconds = retry_after.asInteger();
if (delta_seconds > 0)
{
// ...valid delta-seconds
return now + F64(delta_seconds);
}
}
// If no Retry-After, look for Cache-Control max-age
F64 expires = 0.0;
if (LLAvatarNameCache::expirationFromCacheControl(mHeaders, &expires))
{
return expires;
}
// No information in header, make a guess
if (status == 503)
{
// ...service unavailable, retry soon
const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
return now + SERVICE_UNAVAILABLE_DELAY;
}
else
{
// ...other unexpected error
const F64 DEFAULT_DELAY = 3600.0; // 1 hour
return now + DEFAULT_DELAY;
LLAvatarNameCache::handleAgentError(agent_id);
}
}
};
// Provide some fallback for agents that return errors
void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
{
std::map<LLUUID,LLAvatarName>::iterator existing = sCache.find(agent_id);
if (existing == sCache.end())
{
// there is no existing cache entry, so make a temporary name from legacy
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
<< agent_id << LL_ENDL;
gCacheName->get(agent_id, false, // legacy compatibility
boost::bind(&LLAvatarNameCache::legacyNameCallback,
_1, _2, _3));
}
else
{
// we have a chached (but probably expired) entry - since that would have
// been returned by the get method, there is no need to signal anyone
// Clear this agent from the pending list
LLAvatarNameCache::sPendingQueue.erase(agent_id);
const LLAvatarName& av_name = existing->second;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
<< agent_id
<< "user '" << av_name.mUsername << "' "
<< "display '" << av_name.mDisplayName << "' "
<< "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
<< LL_ENDL;
}
}
void LLAvatarNameCache::processName(const LLUUID& agent_id,
const LLAvatarName& av_name,
bool add_to_cache)
@@ -336,12 +311,12 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id,
{
// sCache[agent_id] = av_name;
// [SL:KB] - Patch: Agent-DisplayNames | Checked: 2010-12-28 (Catznip-2.4.0h) | Added: Catznip-2.4.0h
// Don't replace existing entries with dummies
cache_t::iterator itName = (av_name.mIsDummy) ? sCache.find(agent_id) : sCache.end();
if (sCache.end() != itName)
itName->second.mExpires = av_name.mExpires;
else
sCache[agent_id] = av_name;
// Don't replace existing entries with dummies
cache_t::iterator itName = (av_name.mIsTemporaryName) ? sCache.find(agent_id) : sCache.end();
if (sCache.end() != itName)
itName->second.mExpires = av_name.mExpires;
else
sCache[agent_id] = av_name;
// [/SL:KB]
}
@@ -377,6 +352,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
std::vector<LLUUID> agent_ids;
agent_ids.reserve(128);
U32 ids = 0;
ask_queue_t::const_iterator it = sAskQueue.begin();
for ( ; it != sAskQueue.end(); ++it)
{
@@ -387,11 +363,13 @@ void LLAvatarNameCache::requestNamesViaCapability()
// ...starting new request
url += sNameLookupURL;
url += "?ids=";
ids = 1;
}
else
{
// ...continuing existing request
url += "&ids=";
ids++;
}
url += agent_id.asString();
agent_ids.push_back(agent_id);
@@ -401,7 +379,9 @@ void LLAvatarNameCache::requestNamesViaCapability()
if (url.size() > NAME_URL_SEND_THRESHOLD)
{
//llinfos << "requestNames " << url << llendl;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
<< ids << " ids"
<< LL_ENDL;
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
url.clear();
agent_ids.clear();
@@ -410,7 +390,9 @@ void LLAvatarNameCache::requestNamesViaCapability()
if (!url.empty())
{
//llinfos << "requestNames " << url << llendl;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
<< ids << " ids"
<< LL_ENDL;
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
url.clear();
agent_ids.clear();
@@ -419,18 +401,25 @@ void LLAvatarNameCache::requestNamesViaCapability()
// We've moved all asks to the pending request queue
sAskQueue.clear();
}
void LLAvatarNameCache::legacyNameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
bool is_group)
{
std::string full_name = first + " " +last;
// Construct a dummy record for this name. By convention, SLID is blank
// Never expires, but not written to disk, so lasts until end of session.
LLAvatarName av_name;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
<< "agent " << agent_id << " "
<< "full name '" << full_name << "'"
<< ( is_group ? " [group]" : "" )
<< LL_ENDL;
buildLegacyName(full_name, &av_name);
// Don't add to cache, the data already exists in the legacy name system
// cache and we don't want or need duplicate storage, because keeping the
// two copies in sync is complex.
processName(id, av_name, false);
processName(agent_id, av_name, false);
}
void LLAvatarNameCache::requestNamesViaLegacy()
@@ -446,7 +435,11 @@ void LLAvatarNameCache::requestNamesViaLegacy()
// invoked below. This should never happen in practice.
sPendingQueue[agent_id] = now;
gCacheName->get(agent_id, false, legacyNameCallback);
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
gCacheName->get(agent_id, false, // legacy compatibility
boost::bind(&LLAvatarNameCache::legacyNameCallback,
_1, _2, _3));
}
// We've either answered immediately or moved all asks to the
@@ -482,21 +475,24 @@ void LLAvatarNameCache::importFile(std::istream& istr)
av_name.fromLLSD( it->second );
sCache[agent_id] = av_name;
}
// entries may have expired since we last ran the viewer, just
// clean them out now
eraseExpired();
llinfos << "loaded " << sCache.size() << llendl;
LL_INFOS("AvNameCache") << "loaded " << sCache.size() << LL_ENDL;
// Some entries may have expired since the cache was stored,
// but they will be flushed in the first call to eraseUnrefreshed
// from LLAvatarNameResponder::idle
}
void LLAvatarNameCache::exportFile(std::ostream& ostr)
{
LLSD agents;
F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME;
cache_t::const_iterator it = sCache.begin();
for ( ; it != sCache.end(); ++it)
{
const LLUUID& agent_id = it->first;
const LLAvatarName& av_name = it->second;
if (!av_name.mIsDummy)
// Do not write temporary or expired entries to the stored cache
if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)
{
// key must be a string
agents[agent_id.asString()] = av_name.asLLSD();
@@ -531,36 +527,26 @@ void LLAvatarNameCache::idle()
// return;
//}
// Must be large relative to above
// No longer deleting expired entries, just re-requesting in the get
// this way first synchronous get call on an expired entry won't return
// legacy name. LF
//const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
//if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
//{
// eraseExpired();
//}
if (sAskQueue.empty())
if (!sAskQueue.empty())
{
return;
if (useDisplayNames())
{
requestNamesViaCapability();
}
else
{
// ...fall back to legacy name cache system
requestNamesViaLegacy();
}
}
if (useDisplayNames())
{
requestNamesViaCapability();
}
else
{
// ...fall back to legacy name cache system
requestNamesViaLegacy();
}
// erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
eraseUnrefreshed();
}
bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
{
bool isPending = false;
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
pending_queue_t::const_iterator it = sPendingQueue.find(agent_id);
@@ -568,26 +554,38 @@ bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
{
// in the list of requests in flight, retry if too old
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
return it->second > expire_time;
isPending = (it->second > expire_time);
}
return false;
return isPending;
}
void LLAvatarNameCache::eraseExpired()
void LLAvatarNameCache::eraseUnrefreshed()
{
F64 now = LLFrameTimer::getTotalSeconds();
cache_t::iterator it = sCache.begin();
for (cache_t::iterator it = sCache.begin(); it != sCache.end();)
{
const LLAvatarName& av_name = it->second;
if (av_name.mExpires < now)
{
sCache.erase(it++);
}
else
{
++it;
}
F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME;
if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed)
{
sLastExpireCheck = now;
for (cache_t::iterator it = sCache.begin(); it != sCache.end();)
{
const LLAvatarName& av_name = it->second;
if (av_name.mExpires < max_unrefreshed)
{
const LLUUID& agent_id = it->first;
LL_DEBUGS("AvNameCache") << agent_id
<< " user '" << av_name.mUsername << "' "
<< "expired " << now - av_name.mExpires << " secs ago"
<< LL_ENDL;
sCache.erase(it++);
}
else
{
++it;
}
}
LL_INFOS("AvNameCache") << sCache.size() << " cached avatar names" << LL_ENDL;
}
}
@@ -598,8 +596,11 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
av_name->mUsername = "";
av_name->mDisplayName = full_name;
av_name->mIsDisplayNameDefault = true;
av_name->mIsDummy = true;
av_name->mExpires = F64_MAX;
av_name->mIsTemporaryName = true;
av_name->mExpires = F64_MAX; // not used because these are not cached
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
<< full_name
<< LL_ENDL;
// [Ansariel/Henri]
// Why ain't those set? In case of disabled display names
@@ -632,6 +633,9 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
{
if (!isRequestPending(agent_id))
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
<< "refresh agent " << agent_id
<< LL_ENDL;
sAskQueue.insert(agent_id);
}
}
@@ -641,7 +645,6 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
}
else
{
// ...use legacy names cache
std::string full_name;
if (gCacheName->getFullName(agent_id, full_name))
@@ -654,6 +657,9 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
if (!isRequestPending(agent_id))
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
<< "queue request for agent " << agent_id
<< LL_ENDL;
sAskQueue.insert(agent_id);
}
@@ -800,6 +806,8 @@ F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers)
bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)
{
bool fromCacheControl = false;
F64 now = LLFrameTimer::getTotalSeconds();
// Allow the header to override the default
LLSD cache_control_header = headers["cache-control"];
if (cache_control_header.isDefined())
@@ -808,12 +816,16 @@ bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)
std::string cache_control = cache_control_header.asString();
if (max_age_from_cache_control(cache_control, &max_age))
{
F64 now = LLFrameTimer::getTotalSeconds();
*expires = now + (F64)max_age;
return true;
fromCacheControl = true;
}
}
return false;
LL_DEBUGS("AvNameCache")
<< ( fromCacheControl ? "expires based on cache control " : "default expiration " )
<< "in " << *expires - now << " seconds"
<< LL_ENDL;
return fromCacheControl;
}

View File

@@ -85,10 +85,11 @@ namespace LLAvatarNameCache
void setForceDisplayNames(bool force);
// [/RLVa:KB]
bool isRequestPending(const LLUUID& agent_id);
void erase(const LLUUID& agent_id);
/// Provide some fallback for agents that return errors
void handleAgentError(const LLUUID& agent_id);
// Force a re-fetch of the most recent data, but keep the current
// data in cache
void fetch(const LLUUID& agent_id);

View File

@@ -43,10 +43,7 @@
#include "lluuid.h"
#include "message.h"
// Constants
static const std::string CN_WAITING("(Loading...)"); // *TODO: translate
static const std::string CN_NOBODY("(nobody)"); // *TODO: translate
static const std::string CN_NONE("(none)"); // *TODO: translate
#include <boost/regex.hpp>
// llsd serialization constants
static const std::string AGENTS("agents");
@@ -65,6 +62,7 @@ const S32 CN_FILE_VERSION = 2;
// Globals
LLCacheName* gCacheName = NULL;
std::map<std::string, std::string> LLCacheName::sCacheName;
/// ---------------------------------------------------------------------------
/// class LLCacheNameEntry
@@ -84,6 +82,8 @@ public:
};
LLCacheNameEntry::LLCacheNameEntry()
: mIsGroup(false),
mCreateTime(0)
{
}
@@ -92,17 +92,19 @@ class PendingReply
{
public:
LLUUID mID;
LLCacheNameCallback mCallback;
LLCacheNameSignal mSignal;
LLHost mHost;
void* mData;
PendingReply(const LLUUID& id, LLCacheNameCallback callback, void* data = NULL)
: mID(id), mCallback(callback), mData(data)
{ }
PendingReply(const LLUUID& id, const LLHost& host)
: mID(id), mCallback(0), mHost(host)
{ }
: mID(id), mHost(host)
{
}
boost::signals2::connection setCallback(const LLCacheNameCallback& cb)
{
return mSignal.connect(cb);
}
void done() { mID.setNull(); }
bool isDone() const { return mID.isNull() != FALSE; }
};
@@ -126,7 +128,7 @@ private:
};
ReplySender::ReplySender(LLMessageSystem* msg)
: mMsg(msg), mPending(false)
: mMsg(msg), mPending(false), mCurrIsGroup(false)
{ }
ReplySender::~ReplySender()
@@ -187,10 +189,10 @@ void ReplySender::flush()
typedef std::set<LLUUID> AskQueue;
typedef std::vector<PendingReply> ReplyQueue;
typedef std::list<PendingReply*> ReplyQueue;
typedef std::map<LLUUID,U32> PendingQueue;
typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
typedef std::vector<LLCacheNameCallback> Observers;
typedef std::map<std::string, LLUUID> ReverseCache;
class LLCacheName::Impl
{
@@ -200,7 +202,9 @@ public:
Cache mCache;
// the map of UUIDs to names
ReverseCache mReverseCache;
// map of names to UUIDs
AskQueue mAskNameQueue;
AskQueue mAskGroupQueue;
// UUIDs to ask our upstream host about
@@ -211,13 +215,18 @@ public:
ReplyQueue mReplyQueue;
// requests awaiting replies from us
Observers mObservers;
LLCacheNameSignal mSignal;
LLFrameTimer mProcessTimer;
Impl(LLMessageSystem* msg);
~Impl();
BOOL getName(const LLUUID& id, std::string& first, std::string& last);
boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback);
void addPending(const LLUUID& id, const LLHost& host);
void processPendingAsks();
void processPendingReplies();
void sendRequest(const char* msg_name, const AskQueue& queue);
@@ -231,8 +240,6 @@ public:
static void handleUUIDNameReply(LLMessageSystem* msg, void** userdata);
static void handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userdata);
static void handleUUIDGroupNameReply(LLMessageSystem* msg, void** userdata);
void notifyObservers(const LLUUID& id, const std::string& first, const std::string& last, BOOL group);
};
@@ -247,6 +254,9 @@ LLCacheName::LLCacheName(LLMessageSystem* msg)
LLCacheName::LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host)
: impl(* new Impl(msg))
{
sCacheName["waiting"] = "(Loading...)";
sCacheName["nobody"] = "(nobody)";
sCacheName["none"] = "(none)";
setUpstream(upstream_host);
}
@@ -272,54 +282,34 @@ LLCacheName::Impl::Impl(LLMessageSystem* msg)
LLCacheName::Impl::~Impl()
{
for_each(mCache.begin(), mCache.end(), DeletePairedPointer());
for_each(mReplyQueue.begin(), mReplyQueue.end(), DeletePointer());
}
boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback)
{
PendingReply* reply = new PendingReply(id, LLHost());
boost::signals2::connection res = reply->setCallback(callback);
mReplyQueue.push_back(reply);
return res;
}
void LLCacheName::Impl::addPending(const LLUUID& id, const LLHost& host)
{
PendingReply* reply = new PendingReply(id, host);
mReplyQueue.push_back(reply);
}
void LLCacheName::setUpstream(const LLHost& upstream_host)
{
impl.mUpstreamHost = upstream_host;
}
void LLCacheName::addObserver(LLCacheNameCallback callback)
boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& callback)
{
impl.mObservers.push_back(callback);
}
void LLCacheName::removeObserver(LLCacheNameCallback callback)
{
Observers::iterator it = impl.mObservers.begin();
Observers::iterator end = impl.mObservers.end();
for ( ; it != end; ++it)
{
const LLCacheNameCallback& cb = (*it);
if (cb == callback)
{
impl.mObservers.erase(it);
return;
}
}
}
void LLCacheName::cancelCallback(const LLUUID& id, LLCacheNameCallback callback, void* user_data)
{
ReplyQueue::iterator it = impl.mReplyQueue.begin();
ReplyQueue::iterator end = impl.mReplyQueue.end();
for(; it != end; ++it)
{
const PendingReply& reply = (*it);
if ((callback == reply.mCallback)
&& (id == reply.mID)
&& (user_data == reply.mData) )
{
impl.mReplyQueue.erase(it);
return;
}
}
return impl.mSignal.connect(callback);
}
#if 0
void LLCacheName::importFile(LLFILE* fp)
{
S32 count = 0;
@@ -396,11 +386,12 @@ void LLCacheName::importFile(LLFILE* fp)
llinfos << "LLCacheName loaded " << count << " names" << llendl;
}
#endif
bool LLCacheName::importFile(std::istream& istr)
{
LLSD data;
if(LLSDSerialize::fromXML(data, istr) < 1)
if(LLSDSerialize::fromXMLDocument(data, istr) < 1)
return false;
// We'll expire entries more than a week old
@@ -426,6 +417,9 @@ bool LLCacheName::importFile(std::istream& istr)
entry->mFirstName = agent[FIRST].asString();
entry->mLastName = agent[LAST].asString();
impl.mCache[id] = entry;
std::string fullname = buildFullName(entry->mFirstName, entry->mLastName);
impl.mReverseCache[fullname] = id;
++count;
}
llinfos << "LLCacheName loaded " << count << " agent names" << llendl;
@@ -446,6 +440,7 @@ bool LLCacheName::importFile(std::istream& istr)
entry->mCreateTime = ctime;
entry->mGroupName = group[NAME].asString();
impl.mCache[id] = entry;
impl.mReverseCache[entry->mGroupName] = id;
++count;
}
llinfos << "LLCacheName loaded " << count << " group names" << llendl;
@@ -488,16 +483,16 @@ void LLCacheName::exportFile(std::ostream& ostr)
}
BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& last)
BOOL LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last)
{
if(id.isNull())
{
first = CN_NOBODY;
first = sCacheName["nobody"];
last.clear();
return FALSE;
return TRUE;
}
LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id );
LLCacheNameEntry* entry = get_ptr_in_map(mCache, id );
if (entry)
{
first = entry->mFirstName;
@@ -506,32 +501,42 @@ BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& las
}
else
{
first = CN_WAITING;
first = sCacheName["waiting"];
last.clear();
if (!impl.isRequestPending(id))
if (!isRequestPending(id))
{
impl.mAskNameQueue.insert(id);
mAskNameQueue.insert(id);
}
return FALSE;
}
}
// static
void LLCacheName::localizeCacheName(std::string key, std::string value)
{
if (key!="" && value!= "" )
sCacheName[key]=value;
else
llwarns<< " Error localizing cache key " << key << " To "<< value<<llendl;
}
BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname)
{
std::string first_name, last_name;
BOOL res = getName(id, first_name, last_name);
if(res)
fullname = first_name + " " + last_name;
BOOL res = impl.getName(id, first_name, last_name);
fullname = buildFullName(first_name, last_name);
return res;
}
BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
{
if(id.isNull())
{
group = CN_NONE;
return FALSE;
group = sCacheName["none"];
return TRUE;
}
LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache,id);
@@ -551,7 +556,7 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
}
else
{
group = CN_WAITING;
group = sCacheName["waiting"];
if (!impl.isRequestPending(id))
{
impl.mAskGroupQueue.insert(id);
@@ -560,27 +565,151 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
}
}
// TODO: Make the cache name callback take a SINGLE std::string,
// not a separate first and last name.
void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callback, void* user_data)
BOOL LLCacheName::getUUID(const std::string& first, const std::string& last, LLUUID& id)
{
std::string full_name = buildFullName(first, last);
return getUUID(full_name, id);
}
BOOL LLCacheName::getUUID(const std::string& full_name, LLUUID& id)
{
ReverseCache::iterator iter = impl.mReverseCache.find(full_name);
if (iter != impl.mReverseCache.end())
{
id = iter->second;
return TRUE;
}
else
{
return FALSE;
}
}
//static
std::string LLCacheName::buildFullName(const std::string& first, const std::string& last)
{
std::string fullname = first;
if (!last.empty()
&& last != "Resident")
{
fullname += ' ';
fullname += last;
}
return fullname;
}
//static
std::string LLCacheName::cleanFullName(const std::string& full_name)
{
return full_name.substr(0, full_name.find(" Resident"));
}
//static
std::string LLCacheName::buildUsername(const std::string& full_name)
{
// rare, but handle hard-coded error names returned from server
if (full_name == "(\?\?\?) (\?\?\?)")
{
return "(\?\?\?)";
}
std::string::size_type index = full_name.find(' ');
if (index != std::string::npos)
{
std::string username;
username = full_name.substr(0, index);
std::string lastname = full_name.substr(index+1);
if (lastname != "Resident")
{
username = username + "." + lastname;
}
LLStringUtil::toLower(username);
return username;
}
// if the input wasn't a correctly formatted legacy name just return it unchanged
return full_name;
}
//static
std::string LLCacheName::buildLegacyName(const std::string& complete_name)
{
//boost::regexp was showing up in the crashreporter, so doing
//painfully manual parsing using substr. LF
S32 open_paren = complete_name.rfind(" (");
S32 close_paren = complete_name.rfind(')');
if (open_paren != std::string::npos &&
close_paren == complete_name.length()-1)
{
S32 length = close_paren - open_paren - 2;
std::string legacy_name = complete_name.substr(open_paren+2, length);
if (legacy_name.length() > 0)
{
std::string cap_letter = legacy_name.substr(0, 1);
LLStringUtil::toUpper(cap_letter);
legacy_name = cap_letter + legacy_name.substr(1);
S32 separator = legacy_name.find('.');
if (separator != std::string::npos)
{
std::string last_name = legacy_name.substr(separator+1);
legacy_name = legacy_name.substr(0, separator);
if (last_name.length() > 0)
{
cap_letter = last_name.substr(0, 1);
LLStringUtil::toUpper(cap_letter);
legacy_name = legacy_name + " " + cap_letter + last_name.substr(1);
}
}
return legacy_name;
}
}
return complete_name;
}
// This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer.
// The reason it is a slot is so that the legacy get() function below can bind an old callback
// and pass it as a slot. The reason it isn't a boost::function is so that trackable behavior
// doesn't get lost. As a result, we have to bind the slot to a signal to call it, even when
// we call it immediately. -Steve
// NOTE: Even though passing first and last name is a bit of extra overhead, it eliminates the
// potential need for any parsing should any code need to handle first and last name independently.
boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback)
{
boost::signals2::connection res;
if(id.isNull())
{
callback(id, CN_NOBODY, "", is_group, user_data);
return;
LLCacheNameSignal signal;
signal.connect(callback);
signal(id, sCacheName["nobody"], is_group);
return res;
}
LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id );
if (entry)
{
LLCacheNameSignal signal;
signal.connect(callback);
// id found in map therefore we can call the callback immediately.
if (entry->mIsGroup)
{
callback(id, entry->mGroupName, "", entry->mIsGroup, user_data);
signal(id, entry->mGroupName, entry->mIsGroup);
}
else
{
callback(id, entry->mFirstName, entry->mLastName, entry->mIsGroup, user_data);
std::string fullname =
buildFullName(entry->mFirstName, entry->mLastName);
signal(id, fullname, entry->mIsGroup);
}
}
else
@@ -597,16 +726,29 @@ void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callb
impl.mAskNameQueue.insert(id);
}
}
impl.mReplyQueue.push_back(PendingReply(id, callback, user_data));
res = impl.addPending(id, callback);
}
return res;
}
boost::signals2::connection LLCacheName::getGroup(const LLUUID& group_id,
const LLCacheNameCallback& callback)
{
return get(group_id, true, callback);
}
boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data)
{
return get(id, is_group, boost::bind(callback, _1, _2, _3, user_data));
}
// <edit>
BOOL LLCacheName::getIfThere(const LLUUID& id, std::string& fullname, BOOL& is_group)
bool LLCacheName::getIfThere(const LLUUID& id, std::string& fullname, BOOL& is_group)
{
if(id.isNull())
{
fullname = "";
return FALSE;
return false;
}
LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id );
@@ -621,10 +763,10 @@ BOOL LLCacheName::getIfThere(const LLUUID& id, std::string& fullname, BOOL& is_g
fullname = entry->mFirstName + " " + entry->mLastName;
}
is_group = entry->mIsGroup;
return TRUE;
return true;
}
fullname = "";
return FALSE;
return false;
}
// </edit>
void LLCacheName::processPending()
@@ -695,7 +837,7 @@ void LLCacheName::dump()
{
llinfos
<< iter->first << " = "
<< entry->mFirstName << " " << entry->mLastName
<< buildFullName(entry->mFirstName, entry->mLastName)
<< " @ " << entry->mCreateTime
<< llendl;
}
@@ -710,16 +852,27 @@ void LLCacheName::dumpStats()
<< " AskGroup=" << impl.mAskGroupQueue.size()
<< " Pending=" << impl.mPendingQueue.size()
<< " Reply=" << impl.mReplyQueue.size()
<< " Observers=" << impl.mObservers.size()
// << " Observers=" << impl.mSignal.size()
<< llendl;
}
void LLCacheName::clear()
{
for_each(impl.mCache.begin(), impl.mCache.end(), DeletePairedPointer());
impl.mCache.clear();
}
//static
std::string LLCacheName::getDefaultName()
{
return CN_WAITING;
return sCacheName["waiting"];
}
//static
std::string LLCacheName::getDefaultLastName()
{
return "Resident";
}
void LLCacheName::Impl::processPendingAsks()
{
sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue);
@@ -730,50 +883,51 @@ void LLCacheName::Impl::processPendingAsks()
void LLCacheName::Impl::processPendingReplies()
{
ReplyQueue::iterator it = mReplyQueue.begin();
ReplyQueue::iterator end = mReplyQueue.end();
// First call all the callbacks, because they might send messages.
for(; it != end; ++it)
for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it)
{
LLCacheNameEntry* entry = get_ptr_in_map(mCache, it->mID);
PendingReply* reply = *it;
LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID);
if(!entry) continue;
if (it->mCallback)
if (!entry->mIsGroup)
{
if (!entry->mIsGroup)
{
(it->mCallback)(it->mID,
entry->mFirstName, entry->mLastName,
FALSE, it->mData);
}
else {
(it->mCallback)(it->mID,
entry->mGroupName, "",
TRUE, it->mData);
}
std::string fullname =
LLCacheName::buildFullName(entry->mFirstName, entry->mLastName);
(reply->mSignal)(reply->mID, fullname, false);
}
else
{
(reply->mSignal)(reply->mID, entry->mGroupName, true);
}
}
// Forward on all replies, if needed.
ReplySender sender(mMsg);
for (it = mReplyQueue.begin(); it != end; ++it)
for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it)
{
LLCacheNameEntry* entry = get_ptr_in_map(mCache, it->mID);
PendingReply* reply = *it;
LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID);
if(!entry) continue;
if (it->mHost.isOk())
if (reply->mHost.isOk())
{
sender.send(it->mID, *entry, it->mHost);
sender.send(reply->mID, *entry, reply->mHost);
}
it->done();
reply->done();
}
for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); )
{
ReplyQueue::iterator curit = it++;
PendingReply* reply = *curit;
if (reply->isDone())
{
delete reply;
mReplyQueue.erase(curit);
}
}
mReplyQueue.erase(
remove_if(mReplyQueue.begin(), mReplyQueue.end(),
std::mem_fun_ref(&PendingReply::isDone)),
mReplyQueue.end());
}
@@ -811,18 +965,6 @@ void LLCacheName::Impl::sendRequest(
}
}
void LLCacheName::Impl::notifyObservers(const LLUUID& id,
const std::string& first, const std::string& last, BOOL is_group)
{
for (Observers::const_iterator i = mObservers.begin(),
end = mObservers.end();
i != end;
++i)
{
(**i)(id, first, last, is_group, NULL);
}
}
bool LLCacheName::Impl::isRequestPending(const LLUUID& id)
{
U32 now = (U32)time(NULL);
@@ -889,7 +1031,7 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
}
}
mReplyQueue.push_back(PendingReply(id, fromHost));
addPending(id, fromHost);
}
}
}
@@ -927,11 +1069,32 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
if (!isGroup)
{
notifyObservers(id, entry->mFirstName, entry->mLastName, FALSE);
// NOTE: Very occasionally the server sends down a full name
// in the first name field with an empty last name, for example,
// first = "Ladanie1 Resident", last = "".
// I cannot reproduce this, nor can I find a bug in the server code.
// Ensure "Resident" does not appear via cleanFullName, because
// buildFullName only checks last name. JC
std::string full_name;
if (entry->mLastName.empty())
{
full_name = cleanFullName(entry->mFirstName);
//fix what we are putting in the cache
entry->mFirstName = full_name;
entry->mLastName = "Resident";
}
else
{
full_name = LLCacheName::buildFullName(entry->mFirstName, entry->mLastName);
}
mSignal(id, full_name, false);
mReverseCache[full_name] = id;
}
else
{
notifyObservers(id, entry->mGroupName, "", TRUE);
mSignal(id, entry->mGroupName, true);
mReverseCache[entry->mGroupName] = id;
}
}
}

View File

@@ -33,12 +33,21 @@
#ifndef LL_LLCACHENAME_H
#define LL_LLCACHENAME_H
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
class LLMessageSystem;
class LLHost;
class LLUUID;
// agent_id/group_id, first_name, last_name, is_group, user_data
typedef void (*LLCacheNameCallback)(const LLUUID&, const std::string&, const std::string&, BOOL, void*);
typedef boost::signals2::signal<void (const LLUUID& id,
const std::string& name,
bool is_group)> LLCacheNameSignal;
typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
// Old callback with user data for compatability
typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*);
// Here's the theory:
// If you request a name that isn't in the cache, it returns "waiting"
@@ -59,25 +68,44 @@ public:
// for simulators, this is the data server
void setUpstream(const LLHost& upstream_host);
void addObserver(LLCacheNameCallback callback);
void removeObserver(LLCacheNameCallback callback);
void cancelCallback(const LLUUID& id, LLCacheNameCallback callback, void* user_data = NULL);
boost::signals2::connection addObserver(const LLCacheNameCallback& callback);
// janky old format. Remove after a while. Phoenix. 2008-01-30
#if 0
void importFile(LLFILE* fp);
#endif
// storing cache on disk; for viewer, in name.cache
bool importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
// If available, copies the first and last name into the strings provided.
// first must be at least DB_FIRST_NAME_BUF_SIZE characters.
// last must be at least DB_LAST_NAME_BUF_SIZE characters.
// If available, copies name ("bobsmith123" or "James Linden") into string
// If not available, copies the string "waiting".
// Returns TRUE iff available.
BOOL getName(const LLUUID& id, std::string& first, std::string& last);
BOOL getFullName(const LLUUID& id, std::string& fullname);
BOOL getFullName(const LLUUID& id, std::string& full_name);
// Reverse lookup of UUID from name
BOOL getUUID(const std::string& first, const std::string& last, LLUUID& id);
BOOL getUUID(const std::string& fullname, LLUUID& id);
// IDEVO Temporary code
// Clean up new-style "bobsmith123 Resident" names to "bobsmith123" for display
static std::string buildFullName(const std::string& first, const std::string& last);
// Clean up legacy "bobsmith123 Resident" to "bobsmith123"
// If name does not contain "Resident" returns it unchanged.
static std::string cleanFullName(const std::string& full_name);
// Converts a standard legacy name to a username
// "bobsmith123 Resident" -> "bobsmith"
// "Random Linden" -> "random.linden"
static std::string buildUsername(const std::string& name);
// Converts a complete display name to a legacy name
// if possible, otherwise returns the input
// "Alias (random.linden)" -> "Random Linden"
// "Something random" -> "Something random"
static std::string buildLegacyName(const std::string& name);
// If available, this method copies the group name into the string
// provided. The caller must allocate at least
@@ -89,16 +117,19 @@ public:
// If the data is currently available, may call the callback immediatly
// otherwise, will request the data, and will call the callback when
// available. There is no garuntee the callback will ever be called.
void get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callback, void* user_data = NULL);
boost::signals2::connection get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback);
// <edit>
BOOL getIfThere(const LLUUID& id, std::string& fullname, BOOL& is_group);
// </edit>
//<edit>
bool getIfThere(const LLUUID& id, std::string& fullname, BOOL& is_group);
//</edit>
// Convenience method for looking up a group name, so you can
// tell the difference between avatar lookup and group lookup
// in global searches
boost::signals2::connection getGroup(const LLUUID& group_id, const LLCacheNameCallback& callback);
// LEGACY
void getName(const LLUUID& id, LLCacheNameCallback callback, void* user_data = NULL)
{ get(id, FALSE, callback, user_data); }
boost::signals2::connection get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data);
// This method needs to be called from time to time to send out
// requests.
void processPending();
@@ -109,9 +140,16 @@ public:
// Debugging
void dump(); // Dumps the contents of the cache
void dumpStats(); // Dumps the sizes of the cache and associated queues.
void clear(); // Deletes all entries from the cache
static std::string getDefaultName();
// Returns "Resident", the default last name for SLID-based accounts
// that have no last name.
static std::string getDefaultLastName();
static void localizeCacheName(std::string key, std::string value);
static std::map<std::string, std::string> sCacheName;
private:
class Impl;

View File

@@ -61,7 +61,7 @@ public:
LLMeanCollisionData(LLMeanCollisionData *mcd)
: mVictim(mcd->mVictim), mPerp(mcd->mPerp), mTime(mcd->mTime), mType(mcd->mType), mMag(mcd->mMag),
mFirstName(mcd->mFirstName), mLastName(mcd->mLastName)
mFullName(mcd->mFullName)
{
}
@@ -95,8 +95,7 @@ public:
time_t mTime;
EMeanCollisionType mType;
F32 mMag;
std::string mFirstName;
std::string mLastName;
std::string mFullName;
};

View File

@@ -310,12 +310,6 @@ void JCFloaterAreaSearch::results()
sInstance->mLastUpdateTimer.reset();
}
// static
void JCFloaterAreaSearch::callbackLoadOwnerName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
{
results();
}
// static
void JCFloaterAreaSearch::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data)
{
@@ -335,8 +329,8 @@ void JCFloaterAreaSearch::processObjectPropertiesFamily(LLMessageSystem* msg, vo
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, details->group_id);
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, details->name);
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, details->desc);
gCacheName->get(details->owner_id, FALSE, callbackLoadOwnerName);
gCacheName->get(details->group_id, TRUE, callbackLoadOwnerName);
gCacheName->get(details->owner_id, false, boost::bind(&JCFloaterAreaSearch::results));
gCacheName->get(details->group_id, true, boost::bind(&JCFloaterAreaSearch::results));
//llinfos << "Got info for " << (exists ? "requested" : "unknown") << " object " << object_id << llendl;
}
}

View File

@@ -61,7 +61,6 @@ public:
static void results();
static void toggle();
static JCFloaterAreaSearch* getInstance() { return sInstance; }
static void callbackLoadOwnerName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
static void processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data);
private:

View File

@@ -33,7 +33,6 @@
#include "llviewerprecompiledheaders.h"
#include "llappviewer.h"
#include "llprimitive.h"
#include "hippogridmanager.h"
#include "hippolimits.h"
@@ -79,12 +78,16 @@
#include "llfirstuse.h"
#include "llrender.h"
#include "llfont.h"
#include "llimagej2c.h"
#include "llvocache.h"
#include "llweb.h"
#include "llsecondlifeurls.h"
// Linden library includes
#include "llavatarnamecache.h"
#include "lldiriterator.h"
#include "llimagej2c.h"
#include "llprimitive.h"
#include <boost/bind.hpp>
#if LL_WINDOWS
@@ -117,7 +120,6 @@
#include "lltoolmgr.h"
#include "llassetstorage.h"
#include "llpolymesh.h"
#include "llcachename.h"
#include "llaudioengine.h"
#include "llstreamingaudio.h"
#include "llviewermenu.h"
@@ -181,8 +183,6 @@
#include "llviewerthrottle.h"
#include "llparcel.h"
#include "lldiriterator.h"
#include "llavatarnamecache.h"
#include "llinventoryview.h"
#include "llcommandlineparser.h"
@@ -1257,10 +1257,7 @@ bool LLAppViewer::cleanup()
LLPolyMesh::freeAllMeshes();
LLAvatarNameCache::cleanupClass();
delete gCacheName;
gCacheName = NULL;
LLStartUp::cleanupNameCache();
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
@@ -3455,12 +3452,14 @@ void LLAppViewer::loadNameCache()
// Try to load from the legacy format. This should go away after a
// while. Phoenix 2008-01-30
#if 0
LLFILE* name_cache_fp = LLFile::fopen(name_cache, "r"); // Flawfinder: ignore
if (name_cache_fp)
{
gCacheName->importFile(name_cache_fp);
fclose(name_cache_fp);
}
#endif
}
void LLAppViewer::saveNameCache()
@@ -3658,9 +3657,6 @@ void LLAppViewer::idle()
{
LLFastTimer t(LLFastTimer::FTM_NETWORK);
// Phoenix: Wolfspirit: Prepare the namecache.
idleNameCache();
////////////////////////////////////////////////
//
// Network processing
@@ -3668,6 +3664,7 @@ void LLAppViewer::idle()
// NOTE: Starting at this point, we may still have pointers to "dead" objects
// floating throughout the various object lists.
//
idleNameCache();
gFrameStats.start(LLFrameStats::IDLE_NETWORK);
stop_glerror();
@@ -4012,11 +4009,9 @@ void LLAppViewer::idleNameCache()
if (had_capability != have_capability)
{
// name tags are persistant on screen, so make sure they refresh
//LLVOAvatar::invalidateNameTags();
LLVOAvatar::invalidateNameTags(); //Should this be commented out?
}
// Phoenix: Wolfspirit: Check if we are using Display Names and set it. Then idle the cache.
LLAvatarNameCache::idle();
}
@@ -4081,8 +4076,6 @@ void LLAppViewer::idleNetwork()
{
LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK); // decode
// deal with any queued name requests and replies.
gCacheName->processPending();
llpushcallstacks ;
LLTimer check_message_timer;
// Read all available packets from network

View File

@@ -97,29 +97,10 @@ const F32 OFFLINE_SECONDS = FIND_FREQUENCY + 8.0f;
// static
LLAvatarTracker LLAvatarTracker::sInstance;
/*
class LLAvatarTrackerInventoryObserver : public LLInventoryObserver
{
public:
LLAvatarTrackerInventoryObserver(LLAvatarTracker* at) :
mAT(at) {}
virtual ~LLAvatarTrackerInventoryObserver() {}
virtual void changed(U32 mask);
protected:
LLAvatarTracker* mAT;
};
*/
/*
void LLAvatarTrackerInventoryObserver::changed(U32 mask)
{
// if there's a calling card change, just do it.
if((mask & LLInventoryObserver::CALLING_CARD) != 0)
{
mAT->inventoryChanged();
}
}
*/
static void on_avatar_name_cache_notify(const LLUUID& agent_id,
const LLAvatarName& av_name,
bool online,
LLSD payload);
///----------------------------------------------------------------------------
/// Class LLAvatarTracker
@@ -272,7 +253,7 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
using namespace std;
U32 new_buddy_count = 0;
std::string first,last;
std::string full_name;
LLUUID agent_id;
for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr)
{
@@ -282,8 +263,9 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
{
++new_buddy_count;
mBuddyInfo[agent_id] = (*itr).second;
gCacheName->getName(agent_id, first, last);
mModifyMask |= LLFriendObserver::ADD;
// IDEVO: is this necessary? name is unused?
gCacheName->getFullName(agent_id, full_name);
addChangedMask(LLFriendObserver::ADD, agent_id);
lldebugs << "Added buddy " << agent_id
<< ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline")
<< ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo()
@@ -331,7 +313,7 @@ void LLAvatarTracker::terminateBuddy(const LLUUID& id)
msg->nextBlock("ExBlock");
msg->addUUID("OtherID", id);
gAgent.sendReliableMessage();
mModifyMask |= LLFriendObserver::REMOVE;
addChangedMask(LLFriendObserver::REMOVE, id);
delete buddy;
}
@@ -342,6 +324,12 @@ const LLRelationship* LLAvatarTracker::getBuddyInfo(const LLUUID& id) const
return get_ptr_in_map(mBuddyInfo, id);
}
bool LLAvatarTracker::isBuddy(const LLUUID& id) const
{
LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
return (info != NULL);
}
// online status
void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
{
@@ -349,7 +337,7 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
if(info)
{
info->online(is_online);
mModifyMask |= LLFriendObserver::ONLINE;
addChangedMask(LLFriendObserver::ONLINE, id);
lldebugs << "Set buddy " << id << (is_online ? " Online" : " Offline") << llendl;
}
else
@@ -504,7 +492,61 @@ void LLAvatarTracker::notifyObservers()
{
(*it)->changed(mModifyMask);
}
for (changed_buddy_t::iterator it = mChangedBuddyIDs.begin(); it != mChangedBuddyIDs.end(); it++)
{
notifyParticularFriendObservers(*it);
}
mModifyMask = LLFriendObserver::NONE;
mChangedBuddyIDs.clear();
}
void LLAvatarTracker::addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer)
{
if (buddy_id.notNull() && observer)
mParticularFriendObserverMap[buddy_id].insert(observer);
}
void LLAvatarTracker::removeParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer)
{
if (buddy_id.isNull() || !observer)
return;
observer_map_t::iterator obs_it = mParticularFriendObserverMap.find(buddy_id);
if(obs_it == mParticularFriendObserverMap.end())
return;
obs_it->second.erase(observer);
// purge empty sets from the map
if (obs_it->second.size() == 0)
mParticularFriendObserverMap.erase(obs_it);
}
void LLAvatarTracker::notifyParticularFriendObservers(const LLUUID& buddy_id)
{
observer_map_t::iterator obs_it = mParticularFriendObserverMap.find(buddy_id);
if(obs_it == mParticularFriendObserverMap.end())
return;
// Notify observers interested in buddy_id.
observer_set_t& obs = obs_it->second;
for (observer_set_t::iterator ob_it = obs.begin(); ob_it != obs.end(); ob_it++)
{
(*ob_it)->changed(mModifyMask);
}
}
// store flag for change
// and id of object change applies to
void LLAvatarTracker::addChangedMask(U32 mask, const LLUUID& referent)
{
mModifyMask |= mask;
if (referent.notNull())
{
mChangedBuddyIDs.insert(referent);
}
}
void LLAvatarTracker::applyFunctor(LLRelationshipFunctor& f)
@@ -609,21 +651,24 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
}
args["NAME"] = fullname;
}
LLSD payload;
payload["from_id"] = agent_id;
if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)
{
LLNotifications::instance().add("GrantedModifyRights",args);
LLNotifications::instance().add("GrantedModifyRights",args, payload);
}
else
{
LLNotifications::instance().add("RevokedModifyRights",args);
LLNotifications::instance().add("RevokedModifyRights",args, payload);
}
}
(mBuddyInfo[agent_id])->setRightsFrom(new_rights);
}
}
}
mModifyMask |= LLFriendObserver::POWERS;
addChangedMask(LLFriendObserver::POWERS, agent_id);
notifyObservers();
}
@@ -648,32 +693,15 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
{
tracking_id = mTrackingData->mAvatarID;
}
BOOL notify = FALSE;
LLSD args;
LLSD payload;
for(S32 i = 0; i < count; ++i)
{
msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i);
payload["FROM_ID"] = agent_id;
info = getBuddyInfo(agent_id);
if(info)
{
setBuddyOnline(agent_id,online);
if(chat_notify)
{
std::string fullname;
LLAvatarName avatar_name;
if (LLAvatarNameCache::get(agent_id, &avatar_name))
{
switch (gSavedSettings.getS32("PhoenixNameSystem"))
{
case 0 : fullname = avatar_name.getLegacyName(); break;
case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break;
case 2 : fullname = avatar_name.mDisplayName; break;
default : fullname = avatar_name.getCompleteName(); break;
}
notify = TRUE;
args["NAME"] = fullname;
}
}
}
else
{
@@ -689,20 +717,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
// *TODO: get actual inventory id
gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null);
}
if(notify)
if(chat_notify)
{
// Popup a notify box with online status of this agent
LLNotificationPtr notification = LLNotifications::instance().add(online ? "FriendOnline" : "FriendOffline", args);
// If there's an open IM session with this agent, send a notification there too.
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id);
LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
if (floater)
{
std::string notifyMsg = notification->getMessage();
if (!notifyMsg.empty())
floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor"));
}
// Look up the name of this agent for the notification
LLAvatarNameCache::get(agent_id,
boost::bind(&on_avatar_name_cache_notify,
_1, _2, online, payload));
}
mModifyMask |= LLFriendObserver::ONLINE;
@@ -711,6 +731,36 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
}
}
static void on_avatar_name_cache_notify(const LLUUID& agent_id,
const LLAvatarName& av_name,
bool online,
LLSD payload)
{
// Popup a notify box with online status of this agent
// Use display name only because this user is your friend
LLSD args;
switch (gSavedSettings.getS32("PhoenixNameSystem"))
{
case 0 : args["NAME"] = av_name.getLegacyName(); break;
case 1 : args["NAME"] = (av_name.mIsDisplayNameDefault ? av_name.mDisplayName : av_name.getCompleteName()); break;
case 2 : args["NAME"] = av_name.mDisplayName; break;
default : args["NAME"] = av_name.getCompleteName(); break;
}
// Popup a notify box with online status of this agent
LLNotificationPtr notification = LLNotifications::instance().add(online ? "FriendOnline" : "FriendOffline", args, payload);
// If there's an open IM session with this agent, send a notification there too.
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id);
LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
if (floater)
{
std::string notifyMsg = notification->getMessage();
if (!notifyMsg.empty())
floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor"));
}
}
void LLAvatarTracker::formFriendship(const LLUUID& id)
{
if(id.notNull())
@@ -723,7 +773,7 @@ void LLAvatarTracker::formFriendship(const LLUUID& id)
//visible online to each other.
buddy_info = new LLRelationship(LLRelationship::GRANT_ONLINE_STATUS,LLRelationship::GRANT_ONLINE_STATUS, false);
at.mBuddyInfo[id] = buddy_info;
at.mModifyMask |= LLFriendObserver::ADD;
at.addChangedMask(LLFriendObserver::ADD, id);
at.notifyObservers();
}
}
@@ -739,7 +789,7 @@ void LLAvatarTracker::processTerminateFriendship(LLMessageSystem* msg, void**)
LLRelationship* buddy = get_ptr_in_map(at.mBuddyInfo, id);
if(!buddy) return;
at.mBuddyInfo.erase(id);
at.mModifyMask |= LLFriendObserver::REMOVE;
at.addChangedMask(LLFriendObserver::REMOVE, id);
delete buddy;
at.notifyObservers();
}
@@ -837,10 +887,9 @@ bool LLCollectProxyBuddies::operator()(const LLUUID& buddy_id, LLRelationship* b
bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
{
gCacheName->getName(buddy_id, mFirst, mLast);
std::ostringstream fullname;
fullname << mFirst << " " << mLast;
buddy_map_t::value_type value(fullname.str(), buddy_id);
LLAvatarName av_name;
LLAvatarNameCache::get( buddy_id, &av_name);
buddy_map_t::value_type value(av_name.mDisplayName, buddy_id);
if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))
{
mMappable.insert(value);
@@ -850,10 +899,8 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship
bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
{
gCacheName->getName(buddy_id, mFirst, mLast);
std::ostringstream fullname;
fullname << mFirst << " " << mLast;
buddy_map_t::value_type value(fullname.str(), buddy_id);
gCacheName->getFullName(buddy_id, mFullName);
buddy_map_t::value_type value(mFullName, buddy_id);
if(buddy->isOnline())
{
mOnline.insert(value);
@@ -863,10 +910,10 @@ bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship*
bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
{
gCacheName->getName(buddy_id, mFirst, mLast);
std::ostringstream fullname;
fullname << mFirst << " " << mLast;
buddy_map_t::value_type value(fullname.str(), buddy_id);
LLAvatarName av_name;
LLAvatarNameCache::get(buddy_id, &av_name);
mFullName = av_name.mDisplayName;
buddy_map_t::value_type value(mFullName, buddy_id);
if(buddy->isOnline())
{
mOnline.insert(value);

View File

@@ -125,6 +125,9 @@ public:
// get full info
const LLRelationship* getBuddyInfo(const LLUUID& id) const;
// Is this person a friend/buddy/calling card holder?
bool isBuddy(const LLUUID& id) const;
// online status
void setBuddyOnline(const LLUUID& id, bool is_online);
bool isBuddyOnline(const LLUUID& id) const;
@@ -147,6 +150,23 @@ public:
void removeObserver(LLFriendObserver* observer);
void notifyObservers();
// Observers interested in updates of a particular avatar.
// On destruction these observers are NOT deleted.
void addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer);
void removeParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer);
void notifyParticularFriendObservers(const LLUUID& buddy_id);
/**
* Stores flag for change and id of object change applies to
*
* This allows outsiders to tell the AvatarTracker if something has
* been changed 'under the hood',
* and next notification will have exact avatar IDs have been changed.
*/
void addChangedMask(U32 mask, const LLUUID& referent);
const std::set<LLUUID>& getChangedIDs() { return mChangedBuddyIDs; }
// Apply the functor to every buddy. Do not actually modify the
// buddy list in the functor or bad things will happen.
void applyFunctor(LLRelationshipFunctor& f);
@@ -154,7 +174,7 @@ public:
static void formFriendship(const LLUUID& friend_id);
void updateFriends();
protected:
void deleteTrackingData();
void agentFound(const LLUUID& prey,
@@ -181,9 +201,16 @@ protected:
buddy_map_t mBuddyInfo;
typedef std::set<LLUUID> changed_buddy_t;
changed_buddy_t mChangedBuddyIDs;
typedef std::vector<LLFriendObserver*> observer_list_t;
observer_list_t mObservers;
typedef std::set<LLFriendObserver*> observer_set_t;
typedef std::map<LLUUID, observer_set_t> observer_map_t;
observer_map_t mParticularFriendObserverMap;
private:
// do not implement
LLAvatarTracker(const LLAvatarTracker&);
@@ -215,8 +242,7 @@ public:
virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy);
typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t;
buddy_map_t mMappable;
std::string mFirst;
std::string mLast;
std::string mFullName;
};
// collect dictionary sorted map of name -> agent_id for every online buddy
@@ -228,8 +254,7 @@ public:
virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy);
typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t;
buddy_map_t mOnline;
std::string mFirst;
std::string mLast;
std::string mFullName;
};
// collect dictionary sorted map of name -> agent_id for every buddy,
@@ -243,8 +268,7 @@ public:
typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t;
buddy_map_t mOnline;
buddy_map_t mOffline;
std::string mFirst;
std::string mLast;
std::string mFullName;
};
#endif // LL_LLCALLINGCARD_H

View File

@@ -449,11 +449,7 @@ void LLFloaterAvatarList::updateAvatarList()
//duped for lower section
if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0))
{
if (gCacheName->getName(avid, first, last))
{
name = first + " " + last;
}
else
if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::get above...
{
continue;
}
@@ -497,11 +493,7 @@ void LLFloaterAvatarList::updateAvatarList()
continue;
}
if (gCacheName->getName(avid, first, last))
{
name = first + " " + last;
}
else
if (!gCacheName->getFullName(avid, name))
{
//name = gCacheName->getDefaultName();
continue; //prevent (Loading...)

View File

@@ -111,7 +111,7 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)
new LLFloaterBump();
}
if (mcd->mFirstName.empty() || list->getItemCount() >= 20)
if (mcd->mFullName.empty() || list->getItemCount() >= 20)
{
return;
}
@@ -152,8 +152,7 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)
// All above action strings are in XML file
LLUIString text = sInstance->getString(action);
text.setArg("[TIME]", time);
text.setArg("[FIRST]", mcd->mFirstName);
text.setArg("[LAST]", mcd->mLastName);
text.setArg("[NAME]", mcd->mFullName);
LLSD row;
row["id"] = mcd->mPerp;

View File

@@ -200,8 +200,7 @@ private:
};
};
static void cacheNameUpdateRefreshesBuyLand(const LLUUID&,
const std::string&, const std::string&, BOOL, void* data)
static void cacheNameUpdateRefreshesBuyLand(const LLUUID& id, const std::string& full_name, bool is_group)
{
LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false);
if (ui)

View File

@@ -188,7 +188,7 @@ void LLFloaterGroupInfo::refreshGroup(const LLUUID& group_id)
}
// static
void LLFloaterGroupInfo::callbackLoadGroupName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
void LLFloaterGroupInfo::callbackLoadGroupName(const LLUUID& id, const std::string& full_name, bool is_group)
{
LLFloaterGroupInfo *fgi = get_if_there(sInstances, id, (LLFloaterGroupInfo*)NULL);
@@ -196,7 +196,7 @@ void LLFloaterGroupInfo::callbackLoadGroupName(const LLUUID& id, const std::stri
{
// Build a new title including the group name.
std::ostringstream title;
title << first << " - " << FLOATER_TITLE;
title << full_name << " - " << FLOATER_TITLE;
fgi->setTitle(title.str());
}
}
@@ -221,8 +221,7 @@ void LLFloaterGroupInfo::showFromUUID(const LLUUID& group_id,
{
// Look up the group name.
// The callback will insert it into the title.
const BOOL is_group = TRUE;
gCacheName->get(group_id, is_group, callbackLoadGroupName, NULL);
gCacheName->get(group_id, true, boost::bind(&callbackLoadGroupName, _1, _2, _3));
}
}

View File

@@ -76,7 +76,7 @@ protected:
LLFloaterGroupInfo(const std::string& name, const LLRect &rect, const std::string& title, const LLUUID& group_id = LLUUID::null, const std::string& tab_name = std::string());
private:
static void callbackLoadGroupName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
static void callbackLoadGroupName(const LLUUID& id, const std::string& full_name, bool is_group);
static std::map<LLUUID, LLFloaterGroupInfo*> sInstances;
LLUUID mGroupID;

View File

@@ -1317,10 +1317,9 @@ bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, co
}
else
{
std::string first, last;
gCacheName->getName(owner_id, first, last);
args["FIRST"] = first;
args["LAST"] = last;
std::string full_name;
gCacheName->getFullName(owner_id, full_name);
args["NAME"] = full_name;
LLNotifications::instance().add("OtherObjectsReturned", args);
}
send_return_objects_message(parcel->getLocalID(), RT_OWNER);

View File

@@ -41,7 +41,6 @@
S32 COL_1_WIDTH = 200;
static std::string sOnlineDescriptor = "*";
static std::string sNameFormat = "[FIRST] [LAST]";
LLFloaterNewIM::LLFloaterNewIM()
{
@@ -69,7 +68,6 @@ BOOL LLFloaterNewIM::postBuild()
llwarns << "LLUICtrlFactory::getNameListByName() returned NULL for 'user_list'" << llendl;
}
sOnlineDescriptor = getString("online_descriptor");
sNameFormat = getString("name_format");
setDefaultBtn("start_btn");
return TRUE;
}
@@ -135,11 +133,8 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on
void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online)
{
std::string first, last;
gCacheName->getName(uuid, first, last);
LLUIString fullname = sNameFormat;
fullname.setArg("[FIRST]", first);
fullname.setArg("[LAST]", last);
std::string fullname;
gCacheName->getFullName(uuid, fullname);
LLSD row;
row["id"] = uuid;

View File

@@ -68,7 +68,7 @@ public:
static void onClickOwner(void* data);
static void onClickMute(void* data);
static void nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
void nameCallback(const LLUUID& id, const std::string& full_name, bool is_group);
private:
LLUUID mObjectID;
@@ -127,7 +127,7 @@ void LLFloaterObjectIMInfo::update(const LLUUID& object_id, const std::string& n
mOwnerID = owner_id;
mOwnerIsGroup = owner_is_group;
if (gCacheName) gCacheName->get(owner_id,owner_is_group,nameCallback,this);
if (gCacheName) gCacheName->get(owner_id,owner_is_group,boost::bind(&LLFloaterObjectIMInfo::nameCallback,this,_1,_2,_3));
}
//static
@@ -178,23 +178,17 @@ void LLFloaterObjectIMInfo::onClickMute(void* data)
}
//static
void LLFloaterObjectIMInfo::nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
void LLFloaterObjectIMInfo::nameCallback(const LLUUID& id, const std::string& full_name, bool is_group)
{
LLFloaterObjectIMInfo* self = (LLFloaterObjectIMInfo*)data;
self->mOwnerName = first;
if (!last.empty())
{
self->mOwnerName += " " + last;
}
mOwnerName = full_name;
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0g
if ( (!is_group) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(id)) )
{
self->mOwnerName = RlvStrings::getAnonym(self->mOwnerName);
mOwnerName = RlvStrings::getAnonym(mOwnerName);
}
// [/RLVa:KB]
self->childSetText("OwnerName",self->mOwnerName);
childSetText("OwnerName", mOwnerName);
}
////////////////////////////////////////////////////////////////////////////

View File

@@ -2566,10 +2566,8 @@ void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent,
// static
void LLPanelEstateInfo::callbackCacheName(
const LLUUID& id,
const std::string& first,
const std::string& last,
BOOL is_group,
void*)
const std::string& full_name,
bool is_group)
{
LLPanelEstateInfo* self = LLFloaterRegionInfo::getPanelEstate();
if (!self) return;
@@ -2582,7 +2580,7 @@ void LLPanelEstateInfo::callbackCacheName(
}
else
{
name = first + " " + last;
name = full_name;
}
self->setOwnerName(name);
@@ -3081,8 +3079,7 @@ bool LLDispatchEstateUpdateInfo::operator()(
LLUUID owner_id(strings[1]);
regionp->setOwner(owner_id);
// Update estate owner name in UI
const BOOL is_group = FALSE;
gCacheName->get(owner_id, is_group, LLPanelEstateInfo::callbackCacheName);
gCacheName->get(owner_id, false, boost::bind(&LLPanelEstateInfo::callbackCacheName,_1,_2,_3));
U32 estate_id = strtoul(strings[2].c_str(), NULL, 10);
panel->setEstateID(estate_id);

View File

@@ -343,10 +343,8 @@ public:
// llmessage/llcachename.h:LLCacheNameCallback
static void callbackCacheName(
const LLUUID& id,
const std::string& first,
const std::string& last,
BOOL is_group,
void*);
const std::string& full_name,
bool is_group);
protected:
virtual BOOL sendUpdate();

View File

@@ -188,9 +188,6 @@ LLFloaterPay::LLFloaterPay(const std::string& name,
LLFloaterPay::~LLFloaterPay()
{
std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer());
// Clean up if we are still waiting for a name.
gCacheName->cancelCallback(mTargetUUID,onCacheOwnerName,this);
}
// static
@@ -391,7 +388,7 @@ void LLFloaterPay::payDirectly(money_callback callback,
void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)
{
gCacheName->get(target_id, is_group, onCacheOwnerName, (void*)this);
mNameConnection = gCacheName->get(target_id, is_group, boost::bind(&LLFloaterPay::onCacheOwnerName, this, _1, _2, _3));
// Make sure the amount field has focus
@@ -402,29 +399,22 @@ void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)
mTargetIsGroup = is_group;
}
// static
void LLFloaterPay::onCacheOwnerName(const LLUUID& owner_id,
const std::string& firstname,
const std::string& lastname,
BOOL is_group,
void* userdata)
const std::string& full_name,
bool is_group)
{
LLFloaterPay* self = (LLFloaterPay*)userdata;
if (!self) return;
if (is_group)
{
self->childSetVisible("payee_group",true);
self->childSetVisible("payee_resident",false);
childSetVisible("payee_group",true);
childSetVisible("payee_resident",false);
}
else
{
self->childSetVisible("payee_group",false);
self->childSetVisible("payee_resident",true);
childSetVisible("payee_group",false);
childSetVisible("payee_resident",true);
}
self->childSetTextArg("payee_name", "[FIRST]", firstname);
self->childSetTextArg("payee_name", "[LAST]", lastname);
childSetTextArg("payee_name", "[NAME]", full_name);
}
// static

View File

@@ -77,11 +77,7 @@ private:
static void onGive(void* data);
void give(S32 amount);
static void processPayPriceReply(LLMessageSystem* msg, void **userdata);
static void onCacheOwnerName(const LLUUID& owner_id,
const std::string& firstname,
const std::string& lastname,
BOOL is_group,
void* userdata);
void onCacheOwnerName( const LLUUID& owner_id, const std::string& full_name, bool is_group);
void finishPayUI(const LLUUID& target_id, BOOL is_group);
protected:
@@ -98,6 +94,8 @@ protected:
LLSafeHandle<LLObjectSelection> mObjectSelection;
boost::signals2::scoped_connection mNameConnection; //will disconnect on destruction
static S32 sLastAmount;
};

View File

@@ -980,7 +980,7 @@ void LLIMMgr::inviteToSession(
{
if (caller_name.empty())
{
gCacheName->getName(caller_id, onInviteNameLookup, new LLSD(payload));
gCacheName->get(caller_id, true, boost::bind(&LLIMMgr::onInviteNameLookup,_1,_2,_3,payload));
}
else
{
@@ -999,16 +999,13 @@ void LLIMMgr::inviteToSession(
}
//static
void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata)
void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& full_name, bool is_group, LLSD payload)
{
LLSD payload = *(LLSD*)userdata;
delete (LLSD*)userdata;
payload["caller_name"] = first + " " + last;
payload["session_name"] = payload["caller_name"].asString();
payload["caller_name"] = full_name;
payload["session_name"] = full_name;
LLSD args;
args["NAME"] = payload["caller_name"].asString();
args["NAME"] = full_name;
LLNotifications::instance().add(
payload["notify_box_type"].asString(),
@@ -1246,13 +1243,12 @@ void LLIMMgr::noteOfflineUsers(
for(S32 i = 0; i < count; ++i)
{
info = at.getBuddyInfo(ids.get(i));
std::string first, last;
std::string full_name;
if(info && !info->isOnline()
&& gCacheName->getName(ids.get(i), first, last))
&& gCacheName->getFullName(ids.get(i), full_name))
{
LLUIString offline = sOfflineMessage;
offline.setArg("[FIRST]", first);
offline.setArg("[LAST]", last);
offline.setArg("[NAME]", full_name);
floater->addHistoryLine(offline, gSavedSettings.getColor4("SystemChatColor"));
}
}

View File

@@ -205,7 +205,7 @@ private:
void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
static void onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata);
static void onInviteNameLookup(const LLUUID& id, const std::string& full_name, bool is_group, LLSD payload);
private:
std::set<LLHandle<LLFloater> > mFloaters;

View File

@@ -132,9 +132,8 @@ LLMute::LLMute(const LLUUID& id, const std::string& name, EType type, U32 flags)
LLNameValue* lastname = mute_object->getNVPair("LastName");
if (firstname && lastname)
{
mName.assign( firstname->getString() );
mName.append(" ");
mName.append( lastname->getString() );
mName = LLCacheName::buildFullName(
firstname->getString(), lastname->getString());
}
mType = mute_object->isAvatar() ? AGENT : OBJECT;
}
@@ -501,11 +500,8 @@ void LLMuteList::updateRemove(const LLMute& mute)
gAgent.sendReliableMessage();
}
void notify_automute_callback(const LLUUID& agent_id, const std::string& first_name, const std::string& last_name, BOOL is_group, void* user_data)
void notify_automute_callback(const LLUUID& agent_id, const std::string& full_name, bool is_group, LLMuteList::EAutoReason reason)
{
U32 temp_data = (U32) (uintptr_t) user_data;
LLMuteList::EAutoReason reason = (LLMuteList::EAutoReason)temp_data;
std::string notif_name;
switch (reason)
{
@@ -522,8 +518,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n
}
LLSD args;
args["FIRST"] = first_name;
args["LAST"] = last_name;
args["NAME"] = full_name;
LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args);
if (notif_ptr)
@@ -545,7 +540,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n
}
BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, const std::string& first_name, const std::string& last_name)
BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason)
{
BOOL removed = FALSE;
@@ -555,24 +550,17 @@ BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, co
removed = TRUE;
remove(automute);
if (first_name.empty() && last_name.empty())
{
std::string cache_first, cache_last;
if (gCacheName->getName(agent_id, cache_first, cache_last))
std::string full_name;
if (gCacheName->getFullName(agent_id, full_name))
{
// name in cache, call callback directly
notify_automute_callback(agent_id, cache_first, cache_last, FALSE, (void *)reason);
notify_automute_callback(agent_id, full_name, false, reason);
}
else
{
// not in cache, lookup name from cache
gCacheName->get(agent_id, FALSE, notify_automute_callback, (void *)reason);
}
}
else
{
// call callback directly
notify_automute_callback(agent_id, first_name, last_name, FALSE, (void *)reason);
gCacheName->get(agent_id, false,
boost::bind(&notify_automute_callback, _1, _2, _3, reason));
}
}

View File

@@ -107,7 +107,7 @@ public:
// Remove both normal and legacy mutes, for any or all properties.
BOOL remove(const LLMute& mute, U32 flags = 0);
BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason, const std::string& first_name = LLStringUtil::null, const std::string& last_name = LLStringUtil::null);
BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason);
// Name is required to test against legacy text-only mutes.
BOOL isMuted(const LLUUID& id, const std::string& name = LLStringUtil::null, U32 flags = 0) const;
@@ -153,7 +153,13 @@ private:
{
bool operator()(const LLMute& a, const LLMute& b) const
{
return a.mName < b.mName;
std::string name1 = a.mName;
std::string name2 = b.mName;
LLStringUtil::toUpper(name1);
LLStringUtil::toUpper(name2);
return name1 < name2;
}
};
struct compare_by_id

View File

@@ -85,26 +85,16 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group)
setText(name);
}
void LLNameBox::refresh(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group)
void LLNameBox::refresh(const LLUUID& id, const std::string& full_name, bool is_group)
{
if (id == mNameID)
{
std::string name;
if (!is_group)
{
name = firstname + " " + lastname;
}
else
{
name = firstname;
}
setText(name);
setText(full_name);
}
}
void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group)
void LLNameBox::refreshAll(const LLUUID& id, const std::string& full_name, bool is_group)
{
std::set<LLNameBox*>::iterator it;
for (it = LLNameBox::sInstances.begin();
@@ -112,6 +102,6 @@ void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname,
++it)
{
LLNameBox* box = *it;
box->refresh(id, firstname, lastname, is_group);
box->refresh(id, full_name, is_group);
}
}

View File

@@ -52,10 +52,9 @@ public:
void setNameID(const LLUUID& name_id, BOOL is_group);
void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
void refresh(const LLUUID& id, const std::string& full_name, bool is_group);
static void refreshAll(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group);
static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group);
private:
static std::set<LLNameBox*> sInstances;

View File

@@ -100,26 +100,15 @@ void LLNameEditor::setNameID(const LLUUID& name_id, BOOL is_group)
setText(name);
}
void LLNameEditor::refresh(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group)
void LLNameEditor::refresh(const LLUUID& id, const std::string& full_name, bool is_group)
{
if (id == mNameID)
{
std::string name;
if (!is_group)
{
name = firstname + " " + lastname;
}
else
{
name = firstname;
}
setText(name);
setText(full_name);
}
}
void LLNameEditor::refreshAll(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group)
void LLNameEditor::refreshAll(const LLUUID& id, const std::string& full_name, bool is_group)
{
std::set<LLNameEditor*>::iterator it;
for (it = LLNameEditor::sInstances.begin();
@@ -127,7 +116,7 @@ void LLNameEditor::refreshAll(const LLUUID& id, const std::string& firstname,
++it)
{
LLNameEditor* box = *it;
box->refresh(id, firstname, lastname, is_group);
box->refresh(id, full_name, is_group);
}
}

View File

@@ -67,10 +67,9 @@ public:
void setNameID(const LLUUID& name_id, BOOL is_group);
void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
void refresh(const LLUUID& id, const std::string& full_name, bool is_group);
static void refreshAll(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group);
static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group);
// Take/return agent UUIDs

View File

@@ -235,33 +235,24 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
}
// public
void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,
const std::string& last, BOOL is_group)
void LLNameListCtrl::refresh(const LLUUID& agent_id, const std::string& full_name)
{
//llinfos << "LLNameListCtrl::refresh " << id << " '" << first << " "
// << last << "'" << llendl;
std::string fullname;
if (!is_group)
{
fullname = first + " " + last;
}
else
{
fullname = first;
}
// TODO: scan items for that ID, fix if necessary
item_list::iterator iter;
for (iter = getItemList().begin(); iter != getItemList().end(); iter++)
{
LLScrollListItem* item = *iter;
if (item->getUUID() == id)
if (item->getUUID() == agent_id)
{
LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(0);
cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
((LLScrollListText*)cell)->setText( fullname );
LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
if (cell)
{
((LLScrollListText*)cell)->setText( full_name );
}
}
}
@@ -270,8 +261,7 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,
// static
void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& first,
const std::string& last, BOOL is_group)
void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& full_name)
{
std::set<LLNameListCtrl*>::iterator it;
for (it = LLNameListCtrl::sInstances.begin();
@@ -279,7 +269,7 @@ void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& first,
++it)
{
LLNameListCtrl* ctrl = *it;
ctrl->refresh(id, first, last, is_group);
ctrl->refresh(id, full_name);
}
}

View File

@@ -72,10 +72,9 @@ public:
void removeNameItem(const LLUUID& agent_id);
void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
void refresh(const LLUUID& agent_id, const std::string& full_name);
static void refreshAll(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group);
static void refreshAll(const LLUUID& id, const std::string& full_name);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,

View File

@@ -396,13 +396,10 @@ void LLPanelGroupInvite::addUsers(std::vector<LLUUID>& agent_ids)
if(avatarp)
{
std::string fullname;
LLSD args;
LLNameValue* nvfirst = avatarp->getNVPair("FirstName");
LLNameValue* nvlast = avatarp->getNVPair("LastName");
if(nvfirst && nvlast)
{
args["FIRST"] = std::string(nvfirst->getString());
args["LAST"] = std::string(nvlast->getString());
fullname = std::string(nvfirst->getString()) + " " + std::string(nvlast->getString());
}
if (!fullname.empty())

View File

@@ -387,7 +387,7 @@ void LLPanelPermissions::refresh()
if(mLabelGroupName)
{
mLabelGroupName->setNameID(LLUUID::null, TRUE);
mLabelGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, TRUE);
mLabelGroupName->refresh(LLUUID::null, LLStringUtil::null, true);
mLabelGroupName->setEnabled(FALSE);
}
}

View File

@@ -279,11 +279,11 @@ void release_start_screen();
void reset_login();
void apply_udp_blacklist(const std::string& csv);
void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group, void* data)
void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group)
{
LLNameListCtrl::refreshAll(id, firstname, lastname, is_group);
LLNameBox::refreshAll(id, firstname, lastname, is_group);
LLNameEditor::refreshAll(id, firstname, lastname, is_group);
LLNameListCtrl::refreshAll(id, full_name);
LLNameBox::refreshAll(id, full_name, is_group);
LLNameEditor::refreshAll(id, full_name, is_group);
// TODO: Actually be intelligent about the refresh.
// For now, just brute force refresh the dialogs.
@@ -2076,21 +2076,7 @@ bool idle_startup()
gXferManager->registerCallbacks(gMessageSystem);
if ( gCacheName == NULL )
{
gCacheName = new LLCacheName(gMessageSystem);
gCacheName->addObserver(callback_cache_name);
// Load stored cache if possible
LLAppViewer::instance()->loadNameCache();
}
// Start cache in not-running state until we figure out if we have
// capabilities for display name lookup
LLAvatarNameCache::initClass(false);
S32 phoenix_name_system = gSavedSettings.getS32("PhoenixNameSystem");
if(phoenix_name_system <= 0 || phoenix_name_system > 2) LLAvatarNameCache::setUseDisplayNames(false);
else LLAvatarNameCache::setUseDisplayNames(true);
LLStartUp::initNameCache();
// *Note: this is where gWorldMap used to be initialized.
@@ -3838,6 +3824,35 @@ void LLStartUp::multimediaInit()
LLViewerParcelMedia::initClass();
}
void LLStartUp::initNameCache()
{
// Can be called multiple times
if ( gCacheName ) return;
gCacheName = new LLCacheName(gMessageSystem);
gCacheName->addObserver(&callback_cache_name);
gCacheName->localizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting"));
gCacheName->localizeCacheName("nobody", LLTrans::getString("AvatarNameNobody"));
gCacheName->localizeCacheName("none", LLTrans::getString("GroupNameNone"));
// Load stored cache if possible
LLAppViewer::instance()->loadNameCache();
// Start cache in not-running state until we figure out if we have
// capabilities for display name lookup
LLAvatarNameCache::initClass(false);
S32 phoenix_name_system = gSavedSettings.getS32("PhoenixNameSystem");
if(phoenix_name_system <= 0 || phoenix_name_system > 2) LLAvatarNameCache::setUseDisplayNames(false);
else LLAvatarNameCache::setUseDisplayNames(true);
}
void LLStartUp::cleanupNameCache()
{
LLAvatarNameCache::cleanupClass();
delete gCacheName;
gCacheName = NULL;
}
bool LLStartUp::dispatchURL()
{
// ok, if we've gotten this far and have a startup URL

View File

@@ -95,6 +95,12 @@ public:
static void multimediaInit();
// Initialize LLViewerMedia multimedia engine.
static void initNameCache();
static void cleanupNameCache();
// outfit_folder_name can be a folder anywhere in your inventory,
// but the name must be a case-sensitive exact match.
// gender_name is either "male" or "female"

View File

@@ -3273,10 +3273,8 @@ class LLAvatarGiveCard : public view_listener_t
LLNameValue* nvlast = dest->getNVPair("LastName");
if(nvfirst && nvlast)
{
args["FIRST"] = nvfirst->getString();
args["LAST"] = nvlast->getString();
old_args["FIRST"] = nvfirst->getString();
old_args["LAST"] = nvlast->getString();
args["NAME"] = std::string(nvfirst->getString()) + " " + nvlast->getString();
old_args["NAME"] = std::string(nvfirst->getString()) + " " + nvlast->getString();
found_name = true;
}
LLViewerRegion* region = dest->getRegion();
@@ -3878,16 +3876,11 @@ void request_friendship(const LLUUID& dest_id)
if(dest && dest->isAvatar())
{
std::string fullname;
LLSD args;
LLNameValue* nvfirst = dest->getNVPair("FirstName");
LLNameValue* nvlast = dest->getNVPair("LastName");
if(nvfirst && nvlast)
{
args["FIRST"] = nvfirst->getString();
args["LAST"] = nvlast->getString();
fullname = nvfirst->getString();
fullname += " ";
fullname += nvlast->getString();
fullname = std::string(nvfirst->getString()) + " " + nvlast->getString();
}
if (!fullname.empty())
{

View File

@@ -193,9 +193,7 @@ extern BOOL gDebugClicks;
void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
bool highlight_offered_object(const LLUUID& obj_id);
bool check_offer_throttle(const std::string& from_name, bool check_only);
void callbackCacheEstateOwnerName(const LLUUID& id,
const std::string& first, const std::string& last,
BOOL is_group, void*);
void callbackCacheEstateOwnerName(const LLUUID& id, const std::string& full_name, bool is_group);
//inventory offer throttle globals
LLFrameTimer gThrottleTimer;
@@ -1090,23 +1088,18 @@ bool highlight_offered_object(const LLUUID& obj_id)
}
void inventory_offer_mute_callback(const LLUUID& blocked_id,
const std::string& first_name,
const std::string& last_name,
BOOL is_group,
void* user_data)
const std::string& full_name,
bool is_group )
{
std::string from_name;
std::string from_name = full_name;
LLMute::EType type;
if (is_group)
{
type = LLMute::GROUP;
from_name = first_name;
}
else
{
type = LLMute::AGENT;
from_name = first_name + " " + last_name;
}
LLMute mute(blocked_id, from_name, type);
@@ -1182,7 +1175,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// * we can't build two messages at once.
if (2 == button)
{
gCacheName->get(mFromID, mFromGroup, inventory_offer_mute_callback, this);
gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3));
}
LLMessageSystem* msg = gMessageSystem;
@@ -1233,11 +1226,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
}
else
{
std::string first_name, last_name;
if (gCacheName->getName(mFromID, first_name, last_name))
std::string full_name;
if (gCacheName->getFullName(mFromID, full_name))
{
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
std::string full_name = first_name + " " + last_name;
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(mFromID)) )
{
full_name = RlvStrings::getAnonym(full_name);
@@ -1521,37 +1513,35 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
// Name cache callbacks don't store userdata, so can't save
// off the LLOfferInfo. Argh.
BOOL name_found = FALSE;
payload["from_id"] = info->mFromID;
args["OBJECTFROMNAME"] = info->mFromName;
args["NAME"] = info->mFromName;
if (info->mFromGroup)
{
std::string group_name;
if (gCacheName->getGroupName(info->mFromID, group_name))
{
args["FIRST"] = group_name;
args["LAST"] = "";
args["NAME"] = group_name;
name_found = TRUE;
}
}
else
{
std::string first_name, last_name;
if (gCacheName->getName(info->mFromID, first_name, last_name))
std::string full_name;
if (gCacheName->getFullName(info->mFromID, full_name))
{
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(info->mFromID)) )
{
first_name = RlvStrings::getAnonym(first_name.append(" ").append(last_name));
last_name.clear();
full_name = RlvStrings::getAnonym(full_name);
}
// [/RLVa:KB]
args["FIRST"] = first_name;
args["LAST"] = last_name;
args["NAME"] = full_name;
name_found = TRUE;
}
}
payload["from_id"] = info->mFromID;
args["OBJECTFROMNAME"] = info->mFromName;
args["NAME"] = info->mFromName;
LLNotification::Params p("ObjectGiveItem");
p.substitutions(args).payload(payload).functor(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
@@ -1705,7 +1695,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
if(chat.mSourceType == CHAT_SOURCE_AGENT)
{
LLSD args;
args["FULL_NAME"] = name;
args["NAME"] = name;
static SH_SpamHandler<LLUUID> avatar_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount");
static SH_SpamHandler<LLUUID> object_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount");
if(d==IM_FROM_TASK||d==IM_GOTO_URL||d==IM_FROM_TASK_AS_ALERT||d==IM_TASK_INVENTORY_OFFERED||d==IM_TASK_INVENTORY_ACCEPTED||d==IM_TASK_INVENTORY_DECLINED)
@@ -2881,9 +2871,8 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
LLNameValue* nvlast = source->getNVPair("LastName");
if (nvfirst && nvlast)
{
args["FIRST"] = nvfirst->getString();
args["LAST"] = nvlast->getString();
source_name = std::string(nvfirst->getString()) + " " + nvlast->getString();
args["NAME"] = source_name;
}
}
@@ -3078,7 +3067,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
if (chatter)
{
LLSD args;
args["FULL_NAME"] = from_name;
args["NAME"] = from_name;
static SH_SpamHandler<LLUUID> avatar_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount");
static SH_SpamHandler<LLUUID> object_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount");
if( (chatter->isAvatar() && avatar_spam_check.isBlocked(from_id,from_id,"BlockedChatterAvatar",args)) ||
@@ -5504,7 +5493,7 @@ void handle_show_mean_events(void *)
LLFloaterBump::show(NULL);
}
void mean_name_callback(const LLUUID &id, const std::string& first, const std::string& last, BOOL always_false, void* data)
void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
{
if (gNoRender)
{
@@ -5526,8 +5515,7 @@ void mean_name_callback(const LLUUID &id, const std::string& first, const std::s
LLMeanCollisionData *mcd = *iter;
if (mcd->mPerp == id)
{
mcd->mFirstName = first;
mcd->mLastName = last;
mcd->mFullName = full_name;
}
}
}
@@ -5581,8 +5569,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
{
LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
gMeanCollisionList.push_front(mcd);
const BOOL is_group = FALSE;
gCacheName->get(perp, is_group, mean_name_callback);
gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));
}
}
}
@@ -6277,8 +6264,10 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
it != notification["payload"]["ids"].endArray();
++it)
{
LLUUID target_id = it->asUUID();
msg->nextBlockFast(_PREHASH_TargetData);
msg->addUUIDFast(_PREHASH_TargetID, it->asUUID());
msg->addUUIDFast(_PREHASH_TargetID, target_id);
}
gAgent.sendReliableMessage();
}
@@ -6529,8 +6518,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)
LLNotificationPtr notification;
if (!first_name.empty())
{
args["FIRST"] = first_name;
args["LAST"] = last_name;
args["NAME"] = LLCacheName::buildFullName(first_name, last_name);
static SH_SpamHandler<std::string> spam_check("SGBlockDialogSpam","SGSpamTime","SGSpamCount");
if(spam_check.isBlocked(first_name + " " + last_name,object_id,"BlockedDialogs",args))
@@ -6577,7 +6565,7 @@ static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", ca
// We've got the name of the person who owns the object hurling the url.
// Display confirmation dialog.
void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group)
{
std::vector<LLSD>::iterator it;
for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
@@ -6590,11 +6578,11 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
std::string owner_name;
if (is_group)
{
owner_name = first + " (group)";
owner_name = full_name + " (group)";
}
else
{
owner_name = first + " " + last;
owner_name = full_name;
}
// For legacy name-only mutes.
@@ -6654,7 +6642,8 @@ void process_load_url(LLMessageSystem* msg, void**)
// Add to list of pending name lookups
gLoadUrlList.push_back(payload);
gCacheName->get(owner_id, owner_is_group, callback_load_url_name);
gCacheName->get(owner_id, owner_is_group,
boost::bind(&callback_load_url_name, _1, _2, _3));
}
@@ -6750,7 +6739,8 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
LLPanelLandCovenant::updateLastModified(last_modified);
LLFloaterBuyLand::updateLastModified(last_modified);
gCacheName->getName(estate_owner_id, callbackCacheEstateOwnerName);
gCacheName->get(estate_owner_id, false,
boost::bind(&callbackCacheEstateOwnerName, _1, _2, _3));
// load the actual covenant asset data
const BOOL high_priority = TRUE;
@@ -6785,8 +6775,8 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
}
void callbackCacheEstateOwnerName(const LLUUID& id,
const std::string& first, const std::string& last,
BOOL is_group, void*)
const std::string& full_name,
bool is_group)
{
std::string name;
@@ -6796,7 +6786,7 @@ void callbackCacheEstateOwnerName(const LLUUID& id,
}
else
{
name = first + " " + last;
name = full_name;
}
LLPanelEstateCovenant::updateEstateOwnerName(name);
LLPanelLandCovenant::updateEstateOwnerName(name);

View File

@@ -1290,6 +1290,22 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
void LLViewerParcelMgr::requestHoverParcelProperties(const LLVector3d& pos)
{
static U32 last_west, last_south;
// only request parcel info if position has changed outside of the
// last parcel grid step
U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS );
if ((west_parcel_step == last_west) && (south_parcel_step == last_south))
{
return;
}
else
{
last_west = west_parcel_step;
last_south = south_parcel_step;
}
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos );
if (!region)
{
@@ -2002,10 +2018,9 @@ void LLViewerParcelMgr::deedLandToGroup()
args["GROUP_NAME"] = group_name;
if(mCurrentParcel->getContributeWithDeed())
{
std::string first_name, last_name;
gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name);
args["FIRST_NAME"] = first_name;
args["LAST_NAME"] = last_name;
std::string full_name;
gCacheName->getFullName(mCurrentParcel->getOwnerID(),full_name);
args["NAME"] = full_name;
LLNotifications::instance().add("DeedLandToGroupWithContribution",args, LLSD(), deedAlertCB);
}
else

View File

@@ -3782,7 +3782,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
if(LLAvatarNameCache::useDisplayNames() && LLAvatarNameCache::get(getID(), &av_name)) dnhasloaded=true;
std::string usedname;
if(dnhasloaded && !av_name.mIsDisplayNameDefault && !av_name.mIsDummy
if(dnhasloaded && !av_name.mIsDisplayNameDefault && !av_name.mIsTemporaryName
&& av_name.mDisplayName != av_name.getLegacyName())
{
usedname = av_name.mDisplayName;

View File

@@ -6902,16 +6902,15 @@ void LLVoiceClient::notifyFriendObservers()
void LLVoiceClient::lookupName(const LLUUID &id)
{
gCacheName->getName(id, onAvatarNameLookup);
gCacheName->get(id, false, boost::bind(&LLVoiceClient::onAvatarNameLookup,_1,_2));
}
//static
void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data)
void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& full_name)
{
if(gVoiceClient)
{
std::string name = llformat("%s %s", first.c_str(), last.c_str());
gVoiceClient->avatarNameResolved(id, name);
gVoiceClient->avatarNameResolved(id, full_name);
}
}

View File

@@ -461,7 +461,7 @@ static void updatePosition(void);
void removeObserver(LLFriendObserver* observer);
void lookupName(const LLUUID &id);
static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data);
static void onAvatarNameLookup(const LLUUID& id, const std::string& full_name);
void avatarNameResolved(const LLUUID &id, const std::string &name);
typedef std::vector<std::string> deviceList;

View File

@@ -103,10 +103,9 @@ void RlvFloaterBehaviour::refreshAll()
if (strLookup.find("???") == std::string::npos)
strBhvr.assign(itCmd->getBehaviour()).append(":").append(strLookup);
}
else if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idOption))
else if (m_PendingLookup.end() == m_PendingLookup.find(idOption))
{
gCacheName->get(idOption, FALSE, onAvatarNameLookup, this);
m_PendingLookup.push_back(idOption);
m_PendingLookup[idOption] = gCacheName->get(idOption, false, boost::bind(&RlvFloaterBehaviour::onAvatarNameLookup,this,_1));
}
}
@@ -139,10 +138,10 @@ void RlvFloaterBehaviour::onClose(bool fQuitting)
LLFloater::setVisible(FALSE);
gRlvHandler.removeBehaviourObserver(this);
for (std::list<LLUUID>::const_iterator itLookup = m_PendingLookup.begin(); itLookup != m_PendingLookup.end(); ++itLookup)
for (std::map<LLUUID, boost::signals2::connection>::const_iterator itLookup = m_PendingLookup.begin(); itLookup != m_PendingLookup.end(); ++itLookup)
{
gCacheName->cancelCallback(*itLookup, onAvatarNameLookup, this);
itLookup->second.disconnect();
}
m_PendingLookup.clear();
}
@@ -164,15 +163,16 @@ void RlvFloaterBehaviour::changed(const RlvCommand& /*rlvCmd*/, bool /*fInternal
// ============================================================================
void RlvFloaterBehaviour::onAvatarNameLookup(const LLUUID& uuid, const std::string& strFirst, const std::string& strLast, BOOL fGroup, void* pParam)
void RlvFloaterBehaviour::onAvatarNameLookup(const LLUUID& uuid)
{
RlvFloaterBehaviour* pSelf = (RlvFloaterBehaviour*)pParam;
std::map<LLUUID, boost::signals2::connection>::const_iterator itLookup = m_PendingLookup.find(uuid);
if (itLookup != m_PendingLookup.end())
{
itLookup->second.disconnect();
m_PendingLookup.erase(itLookup);
}
std::list<LLUUID>::iterator itLookup = std::find(pSelf->m_PendingLookup.begin(), pSelf->m_PendingLookup.end(), uuid);
if (itLookup != pSelf->m_PendingLookup.end())
pSelf->m_PendingLookup.erase(itLookup);
pSelf->refreshAll();
refreshAll();
}
// ============================================================================

View File

@@ -51,13 +51,14 @@ public:
*/
public:
static void show(void*);
static void onAvatarNameLookup(const LLUUID& uuid, const std::string& strFirst, const std::string& strLast, BOOL fGroup, void* pParam);
void onAvatarNameLookup(const LLUUID& uuid);
protected:
void refreshAll();
private:
RlvFloaterBehaviour(const LLSD& key = LLSD());
std::list<LLUUID> m_PendingLookup;
public:
std::map<LLUUID,boost::signals2::connection> m_PendingLookup; //Have to hold a signal so we can remove it later.
};
// ============================================================================

View File

@@ -11,18 +11,18 @@
None detected
</string>
<string name="bump">
[TIME] [FIRST] [LAST] bumped you
</string>
[TIME] [NAME] bumped you
</string>
<string name="llpushobject">
[TIME] [FIRST] [LAST] pushed you with a script
</string>
[TIME] [NAME] pushed you with a script
</string>
<string name="selected_object_collide">
[TIME] [FIRST] [LAST] hit you with an object
</string>
[TIME] [NAME] hit you with an object
</string>
<string name="scripted_object_collide">
[TIME] [FIRST] [LAST] hit you with a scripted object
</string>
[TIME] [NAME] hit you with a scripted object
</string>
<string name="physical_object_collide">
[TIME] [FIRST] [LAST] hit you with a physical object
</string>
[TIME] [NAME] hit you with a physical object
</string>
</floater>

View File

@@ -11,8 +11,8 @@
You are the only user in this session.
</string>
<string name="offline_message">
[FIRST] [LAST] is offline.
</string>
[NAME] is offline.
</string>
<string name="invite_message">
Click the [BUTTON NAME] button to accept/connect to this voice chat.
</string>

View File

@@ -17,9 +17,6 @@
halign="center" height="20" label="Close" label_selected="Close" left="435"
mouse_opaque="true" name="close_btn" scale_image="true" sound_flags="0"
width="60" />
<string name="name_format">
[FIRST] [LAST]
</string>
<string name="online_descriptor">
(online)
</string>

View File

@@ -31,7 +31,7 @@
bottom="-25" drop_shadow_visible="true" enabled="true" follows="left|top"
font="SansSerif" h_pad="0" halign="left" height="18" left="85"
mouse_opaque="true" name="payee_name" v_pad="0" width="210">
[FIRST] [LAST]
[NAME]
</text>
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-72" drop_shadow_visible="true" enabled="true" follows="left|top"

View File

@@ -19,7 +19,7 @@
bottom="-25" drop_shadow_visible="true" enabled="true" follows="left|top"
font="SansSerif" h_pad="0" halign="left" height="18" left="85"
mouse_opaque="true" name="payee_name" v_pad="0" width="210">
[FIRST] [LAST]
[NAME]
</text>
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-50" drop_shadow_visible="true" enabled="true" follows="left|top"

View File

@@ -2464,7 +2464,7 @@ Deed this [AREA] m² of land to the group &apos;[GROUP_NAME]&apos;?
name="DeedLandToGroupWithContribution"
type="alertmodal">
By deeding this parcel, the group will be required to have and maintain sufficient land use credits.
The deed will include a simultaneous land contribution to the group from &apos;[FIRST_NAME] [LAST_NAME]&apos;.
The deed will include a simultaneous land contribution to the group from &apos;[NAME]&apos;.
The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members.
Deed this [AREA] m² of land to the group &apos;[GROUP_NAME]&apos;?
@@ -5475,7 +5475,7 @@ You cannot remove protected categories.
icon="notifytip.tga"
name="OfferedCard"
type="notifytip">
You have offered a calling card to [FIRST] [LAST]
You have offered a calling card to [NAME]
</notification>
<notification
@@ -5712,7 +5712,7 @@ The objects you own on the selected parcel of land have been returned back to yo
icon="notify.tga"
name="OtherObjectsReturned"
type="notify">
The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory.
The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory.
</notification>
<notification
@@ -6001,7 +6001,7 @@ No valid parcel could be found.
icon="notify.tga"
name="ObjectGiveItem"
type="notify">
An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME].
An object named [OBJECTFROMNAME] owned by [NAME] has given you a [OBJECTTYPE] named [OBJECTNAME].
<form name="form">
<button
index="0"
@@ -6199,7 +6199,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ
icon="notify.tga"
name="OfferCallingCard"
type="notify">
[FIRST] [LAST] is offering their calling card.
[NAME] is offering their calling card.
This will add a bookmark in your inventory so you can quickly IM this resident.
<form name="form">
<button
@@ -6335,7 +6335,7 @@ Grant this request?
icon="notify.tga"
name="ScriptDialog"
type="notify">
[FIRST] [LAST]&apos;s &apos;[TITLE]&apos; (ch[CHANNEL])
[NAME]&apos;s &apos;[TITLE]&apos; (ch[CHANNEL])
[MESSAGE]
<form name="form">
<button
@@ -6363,7 +6363,7 @@ Grant this request?
icon="notify.tga"
name="ScriptTextBoxDialog"
type="notify">
[FIRST] [LAST]&apos;s &apos;[TITLE]&apos;
[NAME]&apos;s &apos;[TITLE]&apos;
[MESSAGE]
<form name="form">
<input name="message">
@@ -6585,21 +6585,21 @@ Click Accept to join the call or Decline to decline the invitation. Click Mute t
icon="notify.tga"
name="AutoUnmuteByIM"
type="notify">
[FIRST] [LAST] was sent an instant message and has been automatically unmuted.
[NAME] was sent an instant message and has been automatically unmuted.
</notification>
<notification
icon="notify.tga"
name="AutoUnmuteByMoney"
type="notify">
[FIRST] [LAST] was given money and has been automatically unmuted.
[NAME] was given money and has been automatically unmuted.
</notification>
<notification
icon="notify.tga"
name="AutoUnmuteByInventory"
type="notify">
[FIRST] [LAST] was offered inventory and has been automatically unmuted.
[NAME] was offered inventory and has been automatically unmuted.
</notification>
<notification
@@ -6941,11 +6941,11 @@ No
For instructions, make a new template in the AO. Use the toolbar to toggle the AO on/off.
</notification>
<notification icon="notifytip.tga" name="BlockedCards" type="notifytip">Blocked calling cards from [FIRST] [LAST] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedDialogs" type="notifytip">Blocking all dialogs from [FIRST] [LAST]'s objects. (Origin: [SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedGeneralAvatar" type="notifytip">Blocked spam from avatar [FULL_NAME] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedCards" type="notifytip">Blocked calling cards from [NAME] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedDialogs" type="notifytip">Blocking all dialogs from [NAME]'s objects. (Origin: [SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedGeneralAvatar" type="notifytip">Blocked spam from avatar [NAME] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedGeneralObjects" type="notifytip">Blocked spam from objects owned by [OWNER] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedChatterAvatar" type="notifytip">Blocked chat-spam from avatar [FULL_NAME] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedChatterAvatar" type="notifytip">Blocked chat-spam from avatar [NAME] ([SOURCE])</notification>
<notification icon="notifytip.tga" name="BlockedChatterObjects" type="notifytip">Blocked chat-spam from objects owned by [OWNER] ([SOURCE])</notification>
<notification