Brought over LLAvatarPropertiesProcessor, and updated relevant floaters to utilize it. (Mainly in the avatar properties floaters)
This commit is contained in:
@@ -128,6 +128,7 @@ set(viewer_SOURCE_FILES
|
||||
llassetuploadqueue.cpp
|
||||
llattachmentsmgr.cpp
|
||||
llaudiosourcevo.cpp
|
||||
llavatarpropertiesprocessor.cpp
|
||||
llbox.cpp
|
||||
llbuildnewviewsscheduler.cpp
|
||||
llcallbacklist.cpp
|
||||
@@ -612,6 +613,7 @@ set(viewer_HEADER_FILES
|
||||
llassetuploadqueue.h
|
||||
llattachmentsmgr.h
|
||||
llaudiosourcevo.h
|
||||
llavatarpropertiesprocessor.h
|
||||
llbox.h
|
||||
llbuildnewviewsscheduler.h
|
||||
llcallbacklist.h
|
||||
|
||||
692
indra/newview/llavatarpropertiesprocessor.cpp
Normal file
692
indra/newview/llavatarpropertiesprocessor.cpp
Normal file
@@ -0,0 +1,692 @@
|
||||
/**
|
||||
* @file llavatarpropertiesprocessor.cpp
|
||||
* @brief LLAvatarPropertiesProcessor class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
|
||||
// Viewer includes
|
||||
#include "llagent.h"
|
||||
#include "llviewergenericmessage.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llavatarconstants.h" // AVATAR_TRANSACTED, etc.
|
||||
#include "lldate.h"
|
||||
#include "lltrans.h"
|
||||
#include "llui.h" // LLUI::getLanguage()
|
||||
#include "message.h"
|
||||
|
||||
LLAvatarPropertiesProcessor::LLAvatarPropertiesProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
LLAvatarPropertiesProcessor::~LLAvatarPropertiesProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
|
||||
{
|
||||
// Check if that observer is already in mObservers for that avatar_id
|
||||
observer_multimap_t::iterator it;
|
||||
|
||||
// IAN BUG this should update the observer's UUID if this is a dupe - sent to PE
|
||||
it = mObservers.find(avatar_id);
|
||||
while (it != mObservers.end())
|
||||
{
|
||||
if (it->second == observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
mObservers.insert(std::pair<LLUUID, LLAvatarPropertiesObserver*>(avatar_id, observer));
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
|
||||
{
|
||||
if (!observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
observer_multimap_t::iterator it;
|
||||
it = mObservers.find(avatar_id);
|
||||
while (it != mObservers.end())
|
||||
{
|
||||
if (it->second == observer)
|
||||
{
|
||||
mObservers.erase(it);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
|
||||
{
|
||||
// Suppress duplicate requests while waiting for a response from the network
|
||||
if (isPendingRequest(avatar_id, type))
|
||||
{
|
||||
// waiting for a response, don't re-request
|
||||
return;
|
||||
}
|
||||
// indicate we're going to make a request
|
||||
addPendingRequest(avatar_id, type);
|
||||
|
||||
std::vector<std::string> strings;
|
||||
strings.push_back( avatar_id.asString() );
|
||||
send_generic_message(method, strings);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
if (isPendingRequest(avatar_id, APT_PROPERTIES))
|
||||
{
|
||||
// waiting for a response, don't re-request
|
||||
return;
|
||||
}
|
||||
// indicate we're going to make a request
|
||||
addPendingRequest(avatar_id, APT_PROPERTIES);
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
|
||||
msg->nextBlockFast( _PREHASH_AgentData);
|
||||
msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
std::string name;
|
||||
gCacheName->getFullName(avatar_id, name);
|
||||
llinfos << "Sending avatarpicksrequest for " << avatar_id << " ("<<name<<")" << llendl;
|
||||
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
sendGenericRequest(avatar_id, APT_NOTES, "avatarnotesrequest");
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarGroupsRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
sendGenericRequest(avatar_id, APT_GROUPS, "avatargroupsrequest");
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarTexturesRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
sendGenericRequest(avatar_id, APT_TEXTURES, "avatartexturesrequest");
|
||||
// No response expected.
|
||||
removePendingRequest(avatar_id, APT_TEXTURES);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarClassifiedsRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
sendGenericRequest(avatar_id, APT_CLASSIFIEDS, "avatarclassifiedsrequest");
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props)
|
||||
{
|
||||
if (!gAgent.isInitialized() || (gAgent.getID() == LLUUID::null))
|
||||
{
|
||||
llwarns << "Sending avatarinfo update DENIED - invalid agent" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
llinfos << "Sending avatarinfo update" << llendl;
|
||||
|
||||
// This value is required by sendAvatarPropertiesUpdate method.
|
||||
//A profile should never be mature. (From the original code)
|
||||
BOOL mature = FALSE;
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast (_PREHASH_AvatarPropertiesUpdate);
|
||||
msg->nextBlockFast (_PREHASH_AgentData);
|
||||
msg->addUUIDFast (_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast (_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast (_PREHASH_PropertiesData);
|
||||
|
||||
msg->addUUIDFast (_PREHASH_ImageID, avatar_props->image_id);
|
||||
msg->addUUIDFast (_PREHASH_FLImageID, avatar_props->fl_image_id);
|
||||
msg->addStringFast (_PREHASH_AboutText, avatar_props->about_text);
|
||||
msg->addStringFast (_PREHASH_FLAboutText, avatar_props->fl_about_text);
|
||||
|
||||
msg->addBOOL(_PREHASH_AllowPublish, avatar_props->allow_publish);
|
||||
msg->addBOOL(_PREHASH_MaturePublish, mature);
|
||||
msg->addString(_PREHASH_ProfileURL, avatar_props->profile_url);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarInterestsUpdate(const LLAvatarInterestsInfo* interests_props)
|
||||
{
|
||||
if (!gAgent.isInitialized() || (gAgent.getID() == LLUUID::null))
|
||||
{
|
||||
llwarns << "Sending avatarinfo update DENIED - invalid agent" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
msg->newMessage(_PREHASH_AvatarInterestsUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast(_PREHASH_PropertiesData);
|
||||
msg->addU32Fast( _PREHASH_WantToMask, interests_props->want_to_mask);
|
||||
msg->addStringFast( _PREHASH_WantToText, interests_props->want_to_text);
|
||||
msg->addU32Fast( _PREHASH_SkillsMask, interests_props->skills_mask);
|
||||
msg->addStringFast( _PREHASH_SkillsText, interests_props->skills_text);
|
||||
msg->addString( _PREHASH_LanguagesText, interests_props->languages_text);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
//static
|
||||
std::string LLAvatarPropertiesProcessor::accountType(const LLAvatarData* avatar_data)
|
||||
{
|
||||
// If you have a special account, like M Linden ("El Jefe!")
|
||||
// return an untranslated "special" string
|
||||
if (!avatar_data->caption_text.empty())
|
||||
{
|
||||
return avatar_data->caption_text;
|
||||
}
|
||||
const char* const ACCT_TYPE[] = {
|
||||
"AcctTypeResident",
|
||||
"AcctTypeTrial",
|
||||
"AcctTypeCharterMember",
|
||||
"AcctTypeEmployee"
|
||||
};
|
||||
U8 caption_max = (U8)LL_ARRAY_SIZE(ACCT_TYPE)-1;
|
||||
U8 caption_index = llclamp(avatar_data->caption_index, (U8)0, caption_max);
|
||||
return LLTrans::getString(ACCT_TYPE[caption_index]);
|
||||
}
|
||||
|
||||
//static
|
||||
std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_data)
|
||||
{
|
||||
// Special accounts like M Linden don't have payment info revealed.
|
||||
if (!avatar_data->caption_text.empty()) return "";
|
||||
|
||||
// Linden employees don't have payment info revealed
|
||||
const S32 LINDEN_EMPLOYEE_INDEX = 3;
|
||||
if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return "";
|
||||
|
||||
BOOL transacted = (avatar_data->flags & AVATAR_TRANSACTED);
|
||||
BOOL identified = (avatar_data->flags & AVATAR_IDENTIFIED);
|
||||
// Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations
|
||||
//BOOL age_verified = (avatar_data->flags & AVATAR_AGEVERIFIED);
|
||||
|
||||
const char* payment_text;
|
||||
if(transacted)
|
||||
{
|
||||
payment_text = "PaymentInfoUsed";
|
||||
}
|
||||
else if (identified)
|
||||
{
|
||||
payment_text = "PaymentInfoOnFile";
|
||||
}
|
||||
else
|
||||
{
|
||||
payment_text = "NoPaymentInfoOnFile";
|
||||
}
|
||||
return LLTrans::getString(payment_text);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarData avatar_data;
|
||||
std::string birth_date;
|
||||
|
||||
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, avatar_data.agent_id);
|
||||
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, avatar_data.avatar_id);
|
||||
msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_ImageID, avatar_data.image_id);
|
||||
msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_FLImageID, avatar_data.fl_image_id);
|
||||
msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_PartnerID, avatar_data.partner_id);
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_AboutText, avatar_data.about_text);
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_FLAboutText, avatar_data.fl_about_text);
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_BornOn, birth_date);
|
||||
msg->getString( _PREHASH_PropertiesData, _PREHASH_ProfileURL, avatar_data.profile_url);
|
||||
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_Flags, avatar_data.flags);
|
||||
|
||||
|
||||
//LLDateUtil::dateFromPDTString(avatar_data.born_on, birth_date);
|
||||
avatar_data.born_on = birth_date;
|
||||
avatar_data.caption_index = 0;
|
||||
|
||||
S32 charter_member_size = 0;
|
||||
charter_member_size = msg->getSize(_PREHASH_PropertiesData, _PREHASH_CharterMember);
|
||||
if(1 == charter_member_size)
|
||||
{
|
||||
msg->getBinaryData(_PREHASH_PropertiesData, _PREHASH_CharterMember, &avatar_data.caption_index, 1);
|
||||
}
|
||||
else if(1 < charter_member_size)
|
||||
{
|
||||
msg->getString(_PREHASH_PropertiesData, _PREHASH_CharterMember, avatar_data.caption_text);
|
||||
}
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES);
|
||||
self->notifyObservers(avatar_data.avatar_id,&avatar_data,APT_PROPERTIES);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarInterestsInfo avatar_interests;
|
||||
|
||||
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, avatar_interests.agent_id);
|
||||
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, avatar_interests.avatar_id );
|
||||
|
||||
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, avatar_interests.want_to_mask );
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, avatar_interests.want_to_text );
|
||||
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, avatar_interests.skills_mask );
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, avatar_interests.skills_text );
|
||||
msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, avatar_interests.languages_text );
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
//This message isn't requested.. it just comes as a consequence of AvatarPropertiesRequest.
|
||||
//self->removePendingRequest(avatar_interests.avatar_id, APT_INTERESTS);
|
||||
self->notifyObservers(avatar_interests.avatar_id,&avatar_interests,APT_INTERESTS);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarClassifieds classifieds;
|
||||
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, classifieds.agent_id);
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, classifieds.target_id);
|
||||
|
||||
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
|
||||
|
||||
for(int n = 0; n < block_count; ++n)
|
||||
{
|
||||
LLAvatarClassifieds::classified_data data;
|
||||
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, data.classified_id, n);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_Name, data.name, n);
|
||||
|
||||
classifieds.classifieds_list.push_back(data);
|
||||
}
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(classifieds.target_id, APT_CLASSIFIEDS);
|
||||
self->notifyObservers(classifieds.target_id,&classifieds,APT_CLASSIFIEDS);
|
||||
//LLPanelAvatarClassified => LLPanelAvatar
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarClassifiedInfo c_info;
|
||||
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, c_info.agent_id);
|
||||
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, c_info.classified_id);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_CreatorID, c_info.creator_id);
|
||||
msg->getU32(_PREHASH_Data, _PREHASH_CreationDate, c_info.creation_date);
|
||||
msg->getU32(_PREHASH_Data, _PREHASH_ExpirationDate, c_info.expiration_date);
|
||||
msg->getU32(_PREHASH_Data, _PREHASH_Category, c_info.category);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_Name, c_info.name);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_Desc, c_info.description);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_ParcelID, c_info.parcel_id);
|
||||
msg->getU32(_PREHASH_Data, _PREHASH_ParentEstate, c_info.parent_estate);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, c_info.snapshot_id);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_SimName, c_info.sim_name);
|
||||
msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, c_info.pos_global);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_ParcelName, c_info.parcel_name);
|
||||
msg->getU8(_PREHASH_Data, _PREHASH_ClassifiedFlags, c_info.flags);
|
||||
msg->getS32(_PREHASH_Data, _PREHASH_PriceForListing, c_info.price_for_listing);
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(c_info.creator_id, APT_CLASSIFIED_INFO);
|
||||
self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO);
|
||||
}
|
||||
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarNotes avatar_notes;
|
||||
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_notes.agent_id);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_TargetID, avatar_notes.target_id);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_Notes, avatar_notes.notes);
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(avatar_notes.target_id, APT_NOTES);
|
||||
self->notifyObservers(avatar_notes.target_id,&avatar_notes,APT_NOTES);
|
||||
//LLPanelAvatar
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarPicks avatar_picks;
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
|
||||
|
||||
std::string name;
|
||||
gCacheName->getFullName(avatar_picks.target_id, name);
|
||||
|
||||
llinfos << "Got reply for " << avatar_picks.target_id << ": (" << name << ")" << llendl;
|
||||
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
|
||||
for (int block = 0; block < block_count; ++block)
|
||||
{
|
||||
LLUUID pick_id;
|
||||
std::string pick_name;
|
||||
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block);
|
||||
|
||||
llinfos << "\t" << pick_id << ": " << pick_name << llendl;
|
||||
avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name));
|
||||
}
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(avatar_picks.target_id, APT_PICKS);
|
||||
self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS);
|
||||
//LLPanelAvatar
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLPickData pick_data;
|
||||
|
||||
// Extract the agent id and verify the message is for this
|
||||
// client.
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, pick_data.agent_id );
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_data.pick_id);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_CreatorID, pick_data.creator_id);
|
||||
|
||||
// ** top_pick should be deleted, not being used anymore - angela
|
||||
msg->getBOOL(_PREHASH_Data, _PREHASH_TopPick, pick_data.top_pick);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_ParcelID, pick_data.parcel_id);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_Name, pick_data.name);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_Desc, pick_data.desc);
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, pick_data.snapshot_id);
|
||||
|
||||
msg->getString(_PREHASH_Data, _PREHASH_User, pick_data.user_name);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_OriginalName, pick_data.original_name);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_SimName, pick_data.sim_name);
|
||||
msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, pick_data.pos_global);
|
||||
|
||||
msg->getS32(_PREHASH_Data, _PREHASH_SortOrder, pick_data.sort_order);
|
||||
msg->getBOOL(_PREHASH_Data, _PREHASH_Enabled, pick_data.enabled);
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// don't need to remove pending request as we don't track pick info
|
||||
self->notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarGroups avatar_groups;
|
||||
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_groups.agent_id );
|
||||
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_groups.avatar_id );
|
||||
|
||||
S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
|
||||
for(S32 i = 0; i < group_count; ++i)
|
||||
{
|
||||
LLAvatarGroups::LLGroupData group_data;
|
||||
|
||||
msg->getU64( _PREHASH_GroupData, _PREHASH_GroupPowers, group_data.group_powers, i );
|
||||
msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupTitle, group_data.group_title, i );
|
||||
msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupID, group_data.group_id, i);
|
||||
msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group_data.group_name, i );
|
||||
msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupInsigniaID, group_data.group_insignia_id, i );
|
||||
|
||||
avatar_groups.group_list.push_back(group_data);
|
||||
}
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
self->removePendingRequest(avatar_groups.avatar_id, APT_GROUPS);
|
||||
self->notifyObservers(avatar_groups.avatar_id,&avatar_groups,APT_GROUPS);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type)
|
||||
{
|
||||
// Copy the map (because observers may delete themselves when updated?)
|
||||
LLAvatarPropertiesProcessor::observer_multimap_t observers = mObservers;
|
||||
|
||||
observer_multimap_t::iterator oi = observers.begin();
|
||||
observer_multimap_t::iterator end = observers.end();
|
||||
for (; oi != end; ++oi)
|
||||
{
|
||||
// only notify observers for the same agent, or if the observer
|
||||
// didn't know the agent ID and passed a NULL id.
|
||||
const LLUUID &agent_id = oi->first;
|
||||
if (agent_id == id || agent_id.isNull())
|
||||
{
|
||||
oi->second->processProperties(data,type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32 rights)
|
||||
{
|
||||
if(!avatar_id.isNull())
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
// setup message header
|
||||
msg->newMessageFast(_PREHASH_GrantUserRights);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlockFast(_PREHASH_Rights);
|
||||
msg->addUUID(_PREHASH_AgentRelated, avatar_id);
|
||||
msg->addS32(_PREHASH_RelatedRights, rights);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendNotes(const LLUUID& avatar_id, const std::string notes)
|
||||
{
|
||||
if(!avatar_id.isNull())
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
// setup message header
|
||||
msg->newMessageFast(_PREHASH_AvatarNotesUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addUUID(_PREHASH_TargetID, avatar_id);
|
||||
msg->addString(_PREHASH_Notes, notes);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id )
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage(_PREHASH_PickDelete);
|
||||
msg->nextBlock(_PREHASH_AgentData);
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlock(_PREHASH_Data);
|
||||
msg->addUUID(_PREHASH_PickID, pick_id);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
//LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
|
||||
//LLAgentPicksInfo::getInstance()->decrementNumberOfPicks();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_id)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessage(_PREHASH_ClassifiedDelete);
|
||||
|
||||
msg->nextBlock(_PREHASH_AgentData);
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlock(_PREHASH_Data);
|
||||
msg->addUUID(_PREHASH_ClassifiedID, classified_id);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
|
||||
{
|
||||
if (!new_pick) return;
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessage(_PREHASH_PickInfoUpdate);
|
||||
msg->nextBlock(_PREHASH_AgentData);
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlock(_PREHASH_Data);
|
||||
msg->addUUID(_PREHASH_PickID, new_pick->pick_id);
|
||||
msg->addUUID(_PREHASH_CreatorID, new_pick->creator_id);
|
||||
|
||||
//legacy var need to be deleted
|
||||
msg->addBOOL(_PREHASH_TopPick, FALSE);
|
||||
|
||||
// fills in on simulator if null
|
||||
msg->addUUID(_PREHASH_ParcelID, new_pick->parcel_id);
|
||||
msg->addString(_PREHASH_Name, new_pick->name);
|
||||
msg->addString(_PREHASH_Desc, new_pick->desc);
|
||||
msg->addUUID(_PREHASH_SnapshotID, new_pick->snapshot_id);
|
||||
msg->addVector3d(_PREHASH_PosGlobal, new_pick->pos_global);
|
||||
|
||||
// Only top picks have a sort order
|
||||
msg->addS32(_PREHASH_SortOrder, 0);
|
||||
|
||||
msg->addBOOL(_PREHASH_Enabled, new_pick->enabled);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
//LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data)
|
||||
{
|
||||
if(!c_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessage(_PREHASH_ClassifiedInfoUpdate);
|
||||
|
||||
msg->nextBlock(_PREHASH_AgentData);
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlock(_PREHASH_Data);
|
||||
msg->addUUID(_PREHASH_ClassifiedID, c_data->classified_id);
|
||||
msg->addU32(_PREHASH_Category, c_data->category);
|
||||
msg->addString(_PREHASH_Name, c_data->name);
|
||||
msg->addString(_PREHASH_Desc, c_data->description);
|
||||
msg->addUUID(_PREHASH_ParcelID, c_data->parcel_id);
|
||||
msg->addU32(_PREHASH_ParentEstate, 0);
|
||||
msg->addUUID(_PREHASH_SnapshotID, c_data->snapshot_id);
|
||||
msg->addVector3d(_PREHASH_PosGlobal, c_data->pos_global);
|
||||
msg->addU8(_PREHASH_ClassifiedFlags, c_data->flags);
|
||||
msg->addS32(_PREHASH_PriceForListing, c_data->price_for_listing);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id)
|
||||
{
|
||||
// Must ask for a pick based on the creator id because
|
||||
// the pick database is distributed to the inventory cluster. JC
|
||||
std::vector<std::string> request_params;
|
||||
request_params.push_back(creator_id.asString() );
|
||||
request_params.push_back(pick_id.asString() );
|
||||
send_generic_message("pickinforequest", request_params);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendClassifiedInfoRequest(const LLUUID& classified_id)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessage(_PREHASH_ClassifiedInfoRequest);
|
||||
msg->nextBlock(_PREHASH_AgentData);
|
||||
|
||||
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlock(_PREHASH_Data);
|
||||
msg->addUUID(_PREHASH_ClassifiedID, classified_id);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
|
||||
{
|
||||
timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
|
||||
timestamp_map_t::iterator it = mRequestTimestamps.find(key);
|
||||
|
||||
// Is this a new request?
|
||||
if (it == mRequestTimestamps.end()) return false;
|
||||
|
||||
// We found a request, check if it has timed out
|
||||
U32 now = time(NULL);
|
||||
const U32 REQUEST_EXPIRE_SECS = 5;
|
||||
U32 expires = it->second + REQUEST_EXPIRE_SECS;
|
||||
|
||||
// Request is still pending if it hasn't expired yet
|
||||
// *NOTE: Expired requests will accumulate in this map, but they are rare,
|
||||
// the data is small, and they will be updated if the same data is
|
||||
// re-requested
|
||||
return (now < expires);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::addPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
|
||||
{
|
||||
timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
|
||||
U32 now = time(NULL);
|
||||
// Add or update existing (expired) request
|
||||
mRequestTimestamps[ key ] = now;
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::removePendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
|
||||
{
|
||||
timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
|
||||
mRequestTimestamps.erase(key);
|
||||
}
|
||||
291
indra/newview/llavatarpropertiesprocessor.h
Normal file
291
indra/newview/llavatarpropertiesprocessor.h
Normal file
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* @file llavatarpropertiesprocessor.h
|
||||
* @brief LLAvatatIconCtrl base class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLAVATARPROPERTIESPROCESSOR_H
|
||||
#define LL_LLAVATARPROPERTIESPROCESSOR_H
|
||||
|
||||
#include "lluuid.h"
|
||||
#include "llsingleton.h"
|
||||
#include "v3dmath.h" // LLVector3d
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
*TODO Vadim: This needs some refactoring:
|
||||
- Remove EAvatarProcessorType in favor of separate observers, derived from a common parent (to get rid of void*).
|
||||
*/
|
||||
|
||||
class LLMessageSystem;
|
||||
|
||||
enum EAvatarProcessorType
|
||||
{
|
||||
APT_PROPERTIES,
|
||||
APT_NOTES,
|
||||
APT_GROUPS,
|
||||
APT_PICKS,
|
||||
APT_PICK_INFO,
|
||||
APT_TEXTURES,
|
||||
APT_CLASSIFIEDS,
|
||||
APT_CLASSIFIED_INFO,
|
||||
APT_INTERESTS
|
||||
};
|
||||
|
||||
struct LLAvatarData
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID avatar_id; //target id
|
||||
LLUUID image_id;
|
||||
LLUUID fl_image_id;
|
||||
LLUUID partner_id;
|
||||
std::string about_text;
|
||||
std::string fl_about_text;
|
||||
std::string born_on;
|
||||
std::string profile_url;
|
||||
U8 caption_index;
|
||||
std::string caption_text;
|
||||
U32 flags;
|
||||
BOOL allow_publish;
|
||||
};
|
||||
|
||||
struct LLAvatarPicks
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID target_id; //target id
|
||||
|
||||
typedef std::pair<LLUUID,std::string> pick_data_t;
|
||||
typedef std::list< pick_data_t> picks_list_t;
|
||||
picks_list_t picks_list;
|
||||
};
|
||||
|
||||
struct LLPickData
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID pick_id;
|
||||
LLUUID creator_id;
|
||||
BOOL top_pick;
|
||||
LLUUID parcel_id;
|
||||
std::string name;
|
||||
std::string desc;
|
||||
LLUUID snapshot_id;
|
||||
LLVector3d pos_global;
|
||||
S32 sort_order;
|
||||
BOOL enabled;
|
||||
|
||||
//used only in read requests
|
||||
std::string user_name;
|
||||
std::string original_name;
|
||||
std::string sim_name;
|
||||
|
||||
//used only in write (update) requests
|
||||
LLUUID session_id;
|
||||
|
||||
};
|
||||
|
||||
struct LLAvatarNotes
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID target_id; //target id
|
||||
std::string notes;
|
||||
};
|
||||
|
||||
struct LLAvatarGroups
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID avatar_id; //target id
|
||||
BOOL list_in_profile;
|
||||
|
||||
struct LLGroupData;
|
||||
typedef std::list<LLGroupData> group_list_t;
|
||||
|
||||
group_list_t group_list;
|
||||
|
||||
struct LLGroupData
|
||||
{
|
||||
U64 group_powers;
|
||||
BOOL accept_notices;
|
||||
std::string group_title;
|
||||
LLUUID group_id;
|
||||
std::string group_name;
|
||||
LLUUID group_insignia_id;
|
||||
};
|
||||
};
|
||||
|
||||
struct LLAvatarClassifieds
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID target_id;
|
||||
|
||||
struct classified_data;
|
||||
typedef std::list<classified_data> classifieds_list_t;
|
||||
|
||||
classifieds_list_t classifieds_list;
|
||||
|
||||
struct classified_data
|
||||
{
|
||||
LLUUID classified_id;
|
||||
std::string name;
|
||||
};
|
||||
};
|
||||
|
||||
struct LLAvatarClassifiedInfo
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID classified_id;
|
||||
LLUUID creator_id;
|
||||
U32 creation_date;
|
||||
U32 expiration_date;
|
||||
U32 category;
|
||||
std::string name;
|
||||
std::string description;
|
||||
LLUUID parcel_id;
|
||||
U32 parent_estate;
|
||||
LLUUID snapshot_id;
|
||||
std::string sim_name;
|
||||
LLVector3d pos_global;
|
||||
std::string parcel_name;
|
||||
U8 flags;
|
||||
S32 price_for_listing;
|
||||
};
|
||||
|
||||
struct LLAvatarInterestsInfo
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID avatar_id; //target id
|
||||
U32 want_to_mask;
|
||||
std::string want_to_text;
|
||||
U32 skills_mask;
|
||||
std::string skills_text;
|
||||
std::string languages_text;
|
||||
};
|
||||
|
||||
class LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
virtual ~LLAvatarPropertiesObserver() {}
|
||||
virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
|
||||
};
|
||||
|
||||
class LLAvatarPropertiesProcessor
|
||||
: public LLSingleton<LLAvatarPropertiesProcessor>
|
||||
{
|
||||
public:
|
||||
|
||||
LLAvatarPropertiesProcessor();
|
||||
virtual ~LLAvatarPropertiesProcessor();
|
||||
|
||||
void addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
|
||||
|
||||
void removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
|
||||
|
||||
// Request various types of avatar data. Duplicate requests will be
|
||||
// suppressed while waiting for a response from the network.
|
||||
void sendAvatarPropertiesRequest(const LLUUID& avatar_id);
|
||||
void sendAvatarPicksRequest(const LLUUID& avatar_id);
|
||||
void sendAvatarNotesRequest(const LLUUID& avatar_id);
|
||||
void sendAvatarGroupsRequest(const LLUUID& avatar_id);
|
||||
void sendAvatarTexturesRequest(const LLUUID& avatar_id);
|
||||
void sendAvatarClassifiedsRequest(const LLUUID& avatar_id);
|
||||
|
||||
// Duplicate pick info requests are not suppressed.
|
||||
void sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id);
|
||||
|
||||
void sendClassifiedInfoRequest(const LLUUID& classified_id);
|
||||
|
||||
void sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props);
|
||||
void sendAvatarInterestsUpdate(const LLAvatarInterestsInfo* interests_props);
|
||||
|
||||
void sendPickInfoUpdate(const LLPickData* new_pick);
|
||||
|
||||
void sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data);
|
||||
|
||||
void sendFriendRights(const LLUUID& avatar_id, S32 rights);
|
||||
|
||||
void sendNotes(const LLUUID& avatar_id, const std::string notes);
|
||||
|
||||
void sendPickDelete(const LLUUID& pick_id);
|
||||
|
||||
void sendClassifiedDelete(const LLUUID& classified_id);
|
||||
|
||||
// Returns translated, human readable string for account type, such
|
||||
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
|
||||
static std::string accountType(const LLAvatarData* avatar_data);
|
||||
|
||||
// Returns translated, human readable string for payment info, such
|
||||
// as "Payment Info on File" or "Payment Info Used".
|
||||
// Used for profiles, inspectors.
|
||||
static std::string paymentInfo(const LLAvatarData* avatar_data);
|
||||
|
||||
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processAvatarClassifiedsReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processClassifiedInfoReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processAvatarNotesReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processAvatarPicksReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processPickInfoReply(LLMessageSystem* msg, void**);
|
||||
|
||||
protected:
|
||||
|
||||
void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
|
||||
|
||||
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
|
||||
|
||||
// Is there a pending, not timed out, request for this avatar's data?
|
||||
// Use this to suppress duplicate requests for data when a request is
|
||||
// pending.
|
||||
bool isPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type);
|
||||
|
||||
// Call this when a request has been sent
|
||||
void addPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type);
|
||||
|
||||
// Call this when the reply to the request is received
|
||||
void removePendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type);
|
||||
|
||||
typedef void* (*processor_method_t)(LLMessageSystem*);
|
||||
static processor_method_t getProcessor(EAvatarProcessorType type);
|
||||
|
||||
protected:
|
||||
|
||||
typedef std::multimap<LLUUID, LLAvatarPropertiesObserver*> observer_multimap_t;
|
||||
|
||||
observer_multimap_t mObservers;
|
||||
|
||||
// Keep track of pending requests for data by avatar id and type.
|
||||
// Maintain a timestamp for each request so a request that receives no reply
|
||||
// does not block future requests forever.
|
||||
// Map avatar_id+request_type -> U32 timestamp in seconds
|
||||
typedef std::map< std::pair<LLUUID, EAvatarProcessorType>, U32> timestamp_map_t;
|
||||
timestamp_map_t mRequestTimestamps;
|
||||
};
|
||||
|
||||
#endif // LL_LLAVATARPROPERTIESPROCESSOR_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@
|
||||
#include "v3dmath.h"
|
||||
#include "lluuid.h"
|
||||
#include "llmediactrl.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
|
||||
class LLAvatarName;
|
||||
class LLButton;
|
||||
@@ -68,30 +69,29 @@ enum EOnlineStatus
|
||||
// Base class for all sub-tabs inside the avatar profile. Many of these
|
||||
// panels need to keep track of the parent panel (to get the avatar id)
|
||||
// and only request data from the database when they are first drawn. JC
|
||||
class LLPanelAvatarTab : public LLPanel
|
||||
class LLPanelAvatarTab : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
LLPanelAvatarTab(const std::string& name, const LLRect &rect,
|
||||
LLPanelAvatar* panel_avatar);
|
||||
|
||||
virtual ~LLPanelAvatarTab();
|
||||
|
||||
// Calls refresh() once per frame when panel is visible
|
||||
/*virtual*/ void draw();
|
||||
|
||||
LLPanelAvatar* getPanelAvatar() const { return mPanelAvatar; }
|
||||
|
||||
void setAvatarID(const LLUUID& avatar_id);
|
||||
|
||||
void setDataRequested(bool requested) { mDataRequested = requested; }
|
||||
bool isDataRequested() const { return mDataRequested; }
|
||||
|
||||
// If the data for this tab has not yet been requested,
|
||||
// send the request. Used by tabs that are filled in only
|
||||
// when they are first displayed.
|
||||
// type is one of "avatarnotesrequest", "avatarpicksrequest",
|
||||
// or "avatarclassifiedsrequest"
|
||||
void sendAvatarProfileRequestIfNeeded(const std::string& method);
|
||||
|
||||
private:
|
||||
LLPanelAvatar* mPanelAvatar;
|
||||
bool mDataRequested;
|
||||
protected:
|
||||
LLUUID mAvatarID;
|
||||
};
|
||||
|
||||
|
||||
@@ -101,6 +101,9 @@ public:
|
||||
LLPanelAvatarFirstLife(const std::string& name, const LLRect &rect, LLPanelAvatar* panel_avatar);
|
||||
|
||||
/*virtual*/ BOOL postBuild(void);
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
static void onClickImage( void *userdata);
|
||||
|
||||
|
||||
@@ -117,6 +120,8 @@ public:
|
||||
/*virtual*/ BOOL postBuild(void);
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
static void onClickImage( void *userdata);
|
||||
static void onClickFriends( void *userdata);
|
||||
static void onDoubleClickGroup(void* userdata);
|
||||
@@ -150,6 +155,8 @@ public:
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
void enableControls(BOOL own_avatar);
|
||||
|
||||
void setWebURL(std::string url);
|
||||
@@ -177,6 +184,8 @@ public:
|
||||
|
||||
/*virtual*/ BOOL postBuild(void);
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
void enableControls(BOOL own_avatar);
|
||||
void setWantSkills(U32 want_to_mask, const std::string& want_to_text,
|
||||
U32 skills_mask, const std::string& skills_text,
|
||||
@@ -204,6 +213,8 @@ public:
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type){}
|
||||
|
||||
void clearControls();
|
||||
|
||||
static void onCommitNotes(LLUICtrl* field, void* userdata);
|
||||
@@ -219,6 +230,8 @@ public:
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
// If can close, return TRUE. If cannot close, pop save/discard dialog
|
||||
// and return FALSE.
|
||||
BOOL canClose();
|
||||
@@ -230,10 +243,6 @@ public:
|
||||
// Delete all the classified sub-panels from the tab container
|
||||
void deleteClassifiedPanels();
|
||||
|
||||
// Unpack the outline of classified for this avatar (count, names, but not
|
||||
// actual data).
|
||||
void processAvatarClassifiedReply(LLMessageSystem* msg, void**);
|
||||
|
||||
private:
|
||||
static void onClickNew(void* data);
|
||||
static void onClickDelete(void* data);
|
||||
@@ -252,14 +261,11 @@ public:
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
// Delete all the pick sub-panels from the tab container
|
||||
void deletePickPanels();
|
||||
|
||||
// Unpack the outline of picks for this avatar (count, names, but not
|
||||
// actual data).
|
||||
void processAvatarPicksReply(LLMessageSystem* msg, void**);
|
||||
void processAvatarClassifiedReply(LLMessageSystem* msg, void**);
|
||||
|
||||
private:
|
||||
static void onClickNew(void* data);
|
||||
static void onClickDelete(void* data);
|
||||
@@ -276,7 +282,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class LLPanelAvatar : public LLPanel
|
||||
class LLPanelAvatar : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -285,6 +291,8 @@ public:
|
||||
|
||||
/*virtual*/ BOOL postBuild(void);
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
// If can close, return TRUE. If cannot close, pop save/discard dialog
|
||||
// and return FALSE.
|
||||
BOOL canClose();
|
||||
@@ -318,13 +326,6 @@ public:
|
||||
BOOL haveData() { return mHaveProperties && mHaveStatistics; }
|
||||
BOOL isEditable() const { return mAllowEdit; }
|
||||
|
||||
static void processAvatarPropertiesReply(LLMessageSystem *msg, void **);
|
||||
static void processAvatarInterestsReply(LLMessageSystem *msg, void **);
|
||||
static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
|
||||
static void processAvatarNotesReply(LLMessageSystem *msg, void **);
|
||||
static void processAvatarPicksReply(LLMessageSystem *msg, void **);
|
||||
static void processAvatarClassifiedReply(LLMessageSystem *msg, void **);
|
||||
|
||||
static void onClickTrack( void *userdata);
|
||||
static void onClickIM( void *userdata);
|
||||
static void onClickGroupInvite( void *userdata);
|
||||
@@ -369,6 +370,8 @@ public:
|
||||
LLPanelAvatarFirstLife* mPanelFirstLife;
|
||||
LLPanelAvatarWeb* mPanelWeb;
|
||||
|
||||
std::list<LLPanelAvatarTab*> mAvatarPanelList;
|
||||
|
||||
LLDropTarget* mDropTarget;
|
||||
|
||||
// Teen users are not allowed to see or enter data into the first life page,
|
||||
|
||||
@@ -213,12 +213,21 @@ LLPanelClassified::LLPanelClassified(bool in_finder, bool from_search)
|
||||
|
||||
LLPanelClassified::~LLPanelClassified()
|
||||
{
|
||||
if(mCreatorID.notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this);
|
||||
}
|
||||
sAllPanels.remove(this);
|
||||
}
|
||||
|
||||
|
||||
void LLPanelClassified::reset()
|
||||
{
|
||||
if(mCreatorID.notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this);
|
||||
}
|
||||
|
||||
mClassifiedID.setNull();
|
||||
mCreatorID.setNull();
|
||||
mParcelID.setNull();
|
||||
@@ -322,6 +331,82 @@ BOOL LLPanelClassified::postBuild()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelClassified::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if(APT_CLASSIFIED_INFO == type)
|
||||
{
|
||||
lldebugs << "processClassifiedInfoReply()" << llendl;
|
||||
|
||||
LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
|
||||
if(c_info && mClassifiedID == c_info->classified_id)
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this);
|
||||
|
||||
// "Location text" is actually the original
|
||||
// name that owner gave the parcel, and the location.
|
||||
std::string location_text = c_info->parcel_name;
|
||||
|
||||
if (!location_text.empty())
|
||||
location_text.append(", ");
|
||||
|
||||
S32 region_x = llround((F32)c_info->pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
|
||||
S32 region_y = llround((F32)c_info->pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
|
||||
S32 region_z = llround((F32)c_info->pos_global.mdV[VZ]);
|
||||
|
||||
std::string buffer = llformat("%s (%d, %d, %d)", c_info->sim_name.c_str(), region_x, region_y, region_z);
|
||||
location_text.append(buffer);
|
||||
|
||||
//BOOL enabled = is_cf_enabled(flags);
|
||||
|
||||
time_t tim = c_info->creation_date;
|
||||
tm *now=localtime(&tim);
|
||||
|
||||
|
||||
// Found the panel, now fill in the information
|
||||
mClassifiedID = c_info->classified_id;
|
||||
mCreatorID = c_info->creator_id;
|
||||
mParcelID = c_info->parcel_id;
|
||||
mPriceForListing = c_info->price_for_listing;
|
||||
mSimName = c_info->sim_name;
|
||||
mPosGlobal = c_info->pos_global;
|
||||
|
||||
// Update UI controls
|
||||
mNameEditor->setText(c_info->name);
|
||||
mDescEditor->setText(c_info->description);
|
||||
mSnapshotCtrl->setImageAssetID(c_info->snapshot_id);
|
||||
mLocationEditor->setText(location_text);
|
||||
mLocationChanged = false;
|
||||
|
||||
mCategoryCombo->setCurrentByIndex(c_info->category - 1);
|
||||
|
||||
mMatureCombo->setCurrentByIndex(is_cf_mature(c_info->flags) ? MATURE_CONTENT : PG_CONTENT);
|
||||
|
||||
if (mAutoRenewCheck)
|
||||
{
|
||||
mAutoRenewCheck->set(is_cf_auto_renew(c_info->flags));
|
||||
}
|
||||
|
||||
std::string datestr;
|
||||
timeStructToFormattedString(now, gSavedSettings.getString("ShortDateFormat"), datestr);
|
||||
LLStringUtil::format_map_t string_args;
|
||||
string_args["[DATE]"] = datestr;
|
||||
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
||||
string_args["[AMT]"] = llformat("%d", c_info->price_for_listing);
|
||||
childSetText("classified_info_text", getString("ad_placed_paid", string_args));
|
||||
|
||||
// If we got data from the database, we know the listing is paid for.
|
||||
mPaidFor = TRUE;
|
||||
|
||||
mUpdateBtn->setLabel(getString("update_txt"));
|
||||
|
||||
resetDirty();
|
||||
|
||||
// I don't know if a second call is deliberate or a bad merge, so I'm leaving it here.
|
||||
resetDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLPanelClassified::titleIsValid()
|
||||
{
|
||||
// Disallow leading spaces, punctuation, etc. that screw up
|
||||
@@ -488,19 +573,13 @@ std::string LLPanelClassified::getClassifiedName()
|
||||
|
||||
void LLPanelClassified::sendClassifiedInfoRequest()
|
||||
{
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
if (mClassifiedID != mRequestedID)
|
||||
{
|
||||
msg->newMessageFast(_PREHASH_ClassifiedInfoRequest);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addUUIDFast(_PREHASH_ClassifiedID, mClassifiedID);
|
||||
gAgent.sendReliableMessage();
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver(mCreatorID, this);
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(mClassifiedID);
|
||||
|
||||
mDataRequested = TRUE;
|
||||
|
||||
mRequestedID = mClassifiedID;
|
||||
|
||||
// While we're at it let's get the stats from the new table if that
|
||||
@@ -517,9 +596,10 @@ void LLPanelClassified::sendClassifiedInfoRequest()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLPanelClassified::sendClassifiedInfoUpdate()
|
||||
{
|
||||
LLAvatarClassifiedInfo c_data;
|
||||
|
||||
// If we don't have a classified id yet, we'll need to generate one,
|
||||
// otherwise we'll keep overwriting classified_id 00000 in the database.
|
||||
if (mClassifiedID.isNull())
|
||||
@@ -528,180 +608,24 @@ void LLPanelClassified::sendClassifiedInfoUpdate()
|
||||
mClassifiedID.generate();
|
||||
}
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
c_data.agent_id = gAgent.getID();
|
||||
c_data.classified_id = mClassifiedID;
|
||||
c_data.category = mCategoryCombo->getCurrentIndex() + 1;
|
||||
c_data.name = mNameEditor->getText();
|
||||
c_data.description = mDescEditor->getText();
|
||||
c_data.parcel_id = mParcelID;
|
||||
c_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
|
||||
c_data.pos_global = mPosGlobal;
|
||||
BOOL auto_renew = mAutoRenewCheck && mAutoRenewCheck->get();
|
||||
c_data.flags = pack_classified_flags_request(auto_renew, false, mMatureCombo->getCurrentIndex() == MATURE_CONTENT, false);
|
||||
c_data.price_for_listing = mPriceForListing;
|
||||
c_data.parent_estate = 0; //probably not required.
|
||||
|
||||
msg->newMessageFast(_PREHASH_ClassifiedInfoUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addUUIDFast(_PREHASH_ClassifiedID, mClassifiedID);
|
||||
// TODO: fix this
|
||||
U32 category = mCategoryCombo->getCurrentIndex() + 1;
|
||||
msg->addU32Fast(_PREHASH_Category, category);
|
||||
msg->addStringFast(_PREHASH_Name, mNameEditor->getText());
|
||||
msg->addStringFast(_PREHASH_Desc, mDescEditor->getText());
|
||||
|
||||
// fills in on simulator if null
|
||||
msg->addUUIDFast(_PREHASH_ParcelID, mParcelID);
|
||||
// fills in on simulator if null
|
||||
msg->addU32Fast(_PREHASH_ParentEstate, 0);
|
||||
msg->addUUIDFast(_PREHASH_SnapshotID, mSnapshotCtrl->getImageAssetID());
|
||||
msg->addVector3dFast(_PREHASH_PosGlobal, mPosGlobal);
|
||||
BOOL mature = mMatureCombo->getCurrentIndex() == MATURE_CONTENT;
|
||||
BOOL auto_renew = FALSE;
|
||||
if (mAutoRenewCheck)
|
||||
{
|
||||
auto_renew = mAutoRenewCheck->get();
|
||||
}
|
||||
// These flags doesn't matter here.
|
||||
const bool adult_enabled = false;
|
||||
const bool is_pg = false;
|
||||
U8 flags = pack_classified_flags_request(auto_renew, is_pg, mature, adult_enabled);
|
||||
msg->addU8Fast(_PREHASH_ClassifiedFlags, flags);
|
||||
msg->addS32("PriceForListing", mPriceForListing);
|
||||
gAgent.sendReliableMessage();
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
|
||||
|
||||
mDirty = false;
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void LLPanelClassified::processClassifiedInfoReply(LLMessageSystem *msg, void **)
|
||||
{
|
||||
lldebugs << "processClassifiedInfoReply()" << llendl;
|
||||
// Extract the agent id and verify the message is for this
|
||||
// client.
|
||||
LLUUID agent_id;
|
||||
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
|
||||
if (agent_id != gAgent.getID())
|
||||
{
|
||||
llwarns << "Agent ID mismatch in processClassifiedInfoReply"
|
||||
<< llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID classified_id;
|
||||
msg->getUUIDFast(_PREHASH_Data, _PREHASH_ClassifiedID, classified_id);
|
||||
|
||||
LLUUID creator_id;
|
||||
msg->getUUIDFast(_PREHASH_Data, _PREHASH_CreatorID, creator_id);
|
||||
|
||||
LLUUID parcel_id;
|
||||
msg->getUUIDFast(_PREHASH_Data, _PREHASH_ParcelID, parcel_id);
|
||||
|
||||
std::string name;
|
||||
msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name);
|
||||
|
||||
std::string desc;
|
||||
msg->getStringFast(_PREHASH_Data, _PREHASH_Desc, desc);
|
||||
|
||||
LLUUID snapshot_id;
|
||||
msg->getUUIDFast(_PREHASH_Data, _PREHASH_SnapshotID, snapshot_id);
|
||||
|
||||
// "Location text" is actually the original
|
||||
// name that owner gave the parcel, and the location.
|
||||
std::string location_text;
|
||||
|
||||
msg->getStringFast(_PREHASH_Data, _PREHASH_ParcelName, location_text);
|
||||
if (!location_text.empty())
|
||||
{
|
||||
location_text.append(", ");
|
||||
}
|
||||
|
||||
std::string sim_name;
|
||||
msg->getStringFast(_PREHASH_Data, _PREHASH_SimName, sim_name);
|
||||
|
||||
LLVector3d pos_global;
|
||||
msg->getVector3dFast(_PREHASH_Data, _PREHASH_PosGlobal, pos_global);
|
||||
|
||||
S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
|
||||
S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
|
||||
S32 region_z = llround((F32)pos_global.mdV[VZ]);
|
||||
|
||||
std::string buffer = llformat("%s (%d, %d, %d)", sim_name.c_str(), region_x, region_y, region_z);
|
||||
location_text.append(buffer);
|
||||
|
||||
U8 flags;
|
||||
msg->getU8Fast(_PREHASH_Data, _PREHASH_ClassifiedFlags, flags);
|
||||
//BOOL enabled = is_cf_enabled(flags);
|
||||
bool mature = is_cf_mature(flags);
|
||||
bool auto_renew = is_cf_auto_renew(flags);
|
||||
|
||||
U32 date = 0;
|
||||
msg->getU32Fast(_PREHASH_Data, _PREHASH_CreationDate, date);
|
||||
time_t tim = date;
|
||||
tm *now=localtime(&tim);
|
||||
|
||||
// future use
|
||||
U32 expiration_date = 0;
|
||||
msg->getU32("Data", "ExpirationDate", expiration_date);
|
||||
|
||||
U32 category = 0;
|
||||
msg->getU32Fast(_PREHASH_Data, _PREHASH_Category, category);
|
||||
|
||||
S32 price_for_listing = 0;
|
||||
msg->getS32("Data", "PriceForListing", price_for_listing);
|
||||
|
||||
// Look up the panel to fill in
|
||||
for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
|
||||
{
|
||||
LLPanelClassified* self = *iter;
|
||||
// For top picks, must match pick id
|
||||
if (self->mClassifiedID != classified_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found the panel, now fill in the information
|
||||
self->mClassifiedID = classified_id;
|
||||
self->mCreatorID = creator_id;
|
||||
self->mParcelID = parcel_id;
|
||||
self->mPriceForListing = price_for_listing;
|
||||
self->mSimName.assign(sim_name);
|
||||
self->mPosGlobal = pos_global;
|
||||
|
||||
// Update UI controls
|
||||
self->mNameEditor->setText(name);
|
||||
self->mDescEditor->setText(desc);
|
||||
self->mSnapshotCtrl->setImageAssetID(snapshot_id);
|
||||
self->mLocationEditor->setText(location_text);
|
||||
self->mLocationChanged = false;
|
||||
|
||||
self->mCategoryCombo->setCurrentByIndex(category - 1);
|
||||
if(mature)
|
||||
{
|
||||
self->mMatureCombo->setCurrentByIndex(MATURE_CONTENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->mMatureCombo->setCurrentByIndex(PG_CONTENT);
|
||||
}
|
||||
if (self->mAutoRenewCheck)
|
||||
{
|
||||
self->mAutoRenewCheck->set(auto_renew);
|
||||
}
|
||||
|
||||
std::string datestr;
|
||||
timeStructToFormattedString(now, gSavedSettings.getString("ShortDateFormat"), datestr);
|
||||
LLStringUtil::format_map_t string_args;
|
||||
string_args["[DATE]"] = datestr;
|
||||
string_args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
|
||||
string_args["[AMT]"] = llformat("%d", price_for_listing);
|
||||
self->childSetText("classified_info_text", self->getString("ad_placed_paid", string_args));
|
||||
|
||||
// If we got data from the database, we know the listing is paid for.
|
||||
self->mPaidFor = TRUE;
|
||||
|
||||
self->mUpdateBtn->setLabel(self->getString("update_txt"));
|
||||
|
||||
self->resetDirty();
|
||||
|
||||
// I don't know if a second call is deliberate or a bad merge, so I'm leaving it here.
|
||||
self->resetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelClassified::draw()
|
||||
{
|
||||
refresh();
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#ifndef LL_LLPANELCLASSIFIED_H
|
||||
#define LL_LLPANELCLASSIFIED_H
|
||||
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llpanel.h"
|
||||
#include "llclassifiedinfo.h"
|
||||
#include "v3dmath.h"
|
||||
@@ -55,7 +56,7 @@ class LLTextureCtrl;
|
||||
class LLUICtrl;
|
||||
class LLMessageSystem;
|
||||
|
||||
class LLPanelClassified : public LLPanel
|
||||
class LLPanelClassified : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
LLPanelClassified(bool in_finder, bool from_search);
|
||||
@@ -69,6 +70,8 @@ public:
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
void apply();
|
||||
|
||||
// If can close, return TRUE. If cannot close, pop save/discard dialog
|
||||
@@ -98,8 +101,6 @@ public:
|
||||
void sendClassifiedInfoUpdate();
|
||||
void resetDirty();
|
||||
|
||||
static void processClassifiedInfoReply(LLMessageSystem* msg, void**);
|
||||
|
||||
// Confirmation dialogs flow in this order
|
||||
bool confirmMature(const LLSD& notification, const LLSD& response);
|
||||
void gotMature();
|
||||
|
||||
@@ -112,12 +112,20 @@ LLPanelPick::LLPanelPick(BOOL top_pick)
|
||||
|
||||
LLPanelPick::~LLPanelPick()
|
||||
{
|
||||
if(mDataRequested && !mDataReceived)
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this);
|
||||
}
|
||||
sAllPanels.remove(this);
|
||||
}
|
||||
|
||||
|
||||
void LLPanelPick::reset()
|
||||
{
|
||||
if(mDataRequested && !mDataReceived)
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this);
|
||||
}
|
||||
mPickID.setNull();
|
||||
mCreatorID.setNull();
|
||||
mParcelID.setNull();
|
||||
@@ -178,6 +186,72 @@ BOOL LLPanelPick::postBuild()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelPick::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if(APT_PICK_INFO != type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLPickData* pick_info = static_cast<LLPickData*>(data);
|
||||
//llassert_always(pick_info->creator_id != gAgent.getID());
|
||||
//llassert_always(mCreatorID != gAgent.getID());
|
||||
if(!pick_info
|
||||
|| pick_info->creator_id != mCreatorID
|
||||
|| pick_info->pick_id != mPickID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mCreatorID, this);
|
||||
|
||||
// "Location text" is actually the owner name, the original
|
||||
// name that owner gave the parcel, and the location.
|
||||
std::string location_text = pick_info->user_name + ", ";
|
||||
|
||||
if (!pick_info->original_name.empty())
|
||||
{
|
||||
location_text.append(pick_info->original_name);
|
||||
location_text.append(", ");
|
||||
}
|
||||
|
||||
location_text.append(pick_info->sim_name);
|
||||
location_text.append(" ");
|
||||
|
||||
//Fix for location text importing - RK
|
||||
for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
|
||||
{
|
||||
LLPanelPick* self = *iter;
|
||||
if(!self->mImporting) self->mLocationText = location_text;
|
||||
else location_text = self->mLocationText;
|
||||
self->mImporting = false;
|
||||
}
|
||||
|
||||
S32 region_x = llround((F32)pick_info->pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
|
||||
S32 region_y = llround((F32)pick_info->pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
|
||||
S32 region_z = llround((F32)pick_info->pos_global.mdV[VZ]);
|
||||
|
||||
location_text.append(llformat("(%d, %d, %d)", region_x, region_y, region_z));
|
||||
|
||||
mDataReceived = TRUE;
|
||||
|
||||
// Found the panel, now fill in the information
|
||||
mPickID = pick_info->pick_id;
|
||||
mCreatorID = pick_info->creator_id;
|
||||
mParcelID = pick_info->parcel_id;
|
||||
mSimName = pick_info->sim_name;
|
||||
mPosGlobal = pick_info->pos_global;
|
||||
|
||||
// Update UI controls
|
||||
mNameEditor->setText(pick_info->name);
|
||||
mDescEditor->setText(pick_info->desc);
|
||||
mSnapshotCtrl->setImageAssetID(pick_info->snapshot_id);
|
||||
mLocationEditor->setText(location_text);
|
||||
mEnabledCheck->set(pick_info->enabled);
|
||||
|
||||
mSortOrderEditor->setText(llformat("%d", pick_info->sort_order));
|
||||
|
||||
}
|
||||
|
||||
// Fill in some reasonable defaults for a new pick.
|
||||
void LLPanelPick::initNewPick()
|
||||
@@ -307,12 +381,9 @@ std::string LLPanelPick::getPickName()
|
||||
|
||||
void LLPanelPick::sendPickInfoRequest()
|
||||
{
|
||||
// Must ask for a pick based on the creator id because
|
||||
// the pick database is distributed to the inventory cluster. JC
|
||||
std::vector<std::string> strings;
|
||||
strings.push_back( mCreatorID.asString() );
|
||||
strings.push_back( mPickID.asString() );
|
||||
send_generic_message("pickinforequest", strings);
|
||||
//llassert_always(mCreatorID != gAgent.getID());
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver(mCreatorID, this);
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(mCreatorID, mPickID);
|
||||
|
||||
mDataRequested = TRUE;
|
||||
}
|
||||
@@ -320,6 +391,8 @@ void LLPanelPick::sendPickInfoRequest()
|
||||
|
||||
void LLPanelPick::sendPickInfoUpdate()
|
||||
{
|
||||
LLPickData pick_data;
|
||||
|
||||
// If we don't have a pick id yet, we'll need to generate one,
|
||||
// otherwise we'll keep overwriting pick_id 00000 in the database.
|
||||
if (mPickID.isNull())
|
||||
@@ -327,146 +400,29 @@ void LLPanelPick::sendPickInfoUpdate()
|
||||
mPickID.generate();
|
||||
}
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
pick_data.agent_id = gAgent.getID();
|
||||
pick_data.session_id = gAgent.getSessionID();
|
||||
pick_data.pick_id = mPickID;
|
||||
pick_data.creator_id = gAgent.getID();
|
||||
|
||||
msg->newMessage("PickInfoUpdate");
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("Data");
|
||||
msg->addUUID("PickID", mPickID);
|
||||
msg->addUUID("CreatorID", mCreatorID);
|
||||
msg->addBOOL("TopPick", mTopPick);
|
||||
// fills in on simulator if null
|
||||
msg->addUUID("ParcelID", mParcelID);
|
||||
msg->addString("Name", mNameEditor->getText());
|
||||
msg->addString("Desc", mDescEditor->getText());
|
||||
msg->addUUID("SnapshotID", mSnapshotCtrl->getImageAssetID());
|
||||
msg->addVector3d("PosGlobal", mPosGlobal);
|
||||
|
||||
// Only top picks have a sort order
|
||||
S32 sort_order;
|
||||
if (mTopPick)
|
||||
{
|
||||
sort_order = atoi(mSortOrderEditor->getText().c_str());
|
||||
}
|
||||
//legacy var need to be deleted
|
||||
pick_data.top_pick = mTopPick;
|
||||
pick_data.parcel_id = mParcelID;
|
||||
pick_data.name = mNameEditor->getText();
|
||||
pick_data.desc = mDescEditor->getText();
|
||||
pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
|
||||
pick_data.pos_global = mPosGlobal;
|
||||
if(mTopPick)
|
||||
pick_data.sort_order = atoi(mSortOrderEditor->getText().c_str());
|
||||
else
|
||||
{
|
||||
sort_order = 0;
|
||||
}
|
||||
msg->addS32("SortOrder", sort_order);
|
||||
msg->addBOOL("Enabled", mEnabledCheck->get());
|
||||
gAgent.sendReliableMessage();
|
||||
pick_data.sort_order = 0;
|
||||
|
||||
pick_data.enabled = mEnabledCheck->get();
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data);
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void LLPanelPick::processPickInfoReply(LLMessageSystem *msg, void **)
|
||||
{
|
||||
// Extract the agent id and verify the message is for this
|
||||
// client.
|
||||
LLUUID agent_id;
|
||||
msg->getUUID("AgentData", "AgentID", agent_id );
|
||||
if (agent_id != gAgent.getID())
|
||||
{
|
||||
llwarns << "Agent ID mismatch in processPickInfoReply"
|
||||
<< llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID pick_id;
|
||||
msg->getUUID("Data", "PickID", pick_id);
|
||||
|
||||
LLUUID creator_id;
|
||||
msg->getUUID("Data", "CreatorID", creator_id);
|
||||
|
||||
BOOL top_pick;
|
||||
msg->getBOOL("Data", "TopPick", top_pick);
|
||||
|
||||
LLUUID parcel_id;
|
||||
msg->getUUID("Data", "ParcelID", parcel_id);
|
||||
|
||||
std::string name;
|
||||
msg->getString("Data", "Name", name);
|
||||
|
||||
std::string desc;
|
||||
msg->getString("Data", "Desc", desc);
|
||||
|
||||
LLUUID snapshot_id;
|
||||
msg->getUUID("Data", "SnapshotID", snapshot_id);
|
||||
|
||||
// "Location text" is actually the owner name, the original
|
||||
// name that owner gave the parcel, and the location.
|
||||
std::string location_text;
|
||||
msg->getString("Data", "User", location_text);
|
||||
location_text.append(", ");
|
||||
|
||||
std::string original_name;
|
||||
msg->getString("Data", "OriginalName", original_name);
|
||||
if (!original_name.empty())
|
||||
{
|
||||
location_text.append(original_name);
|
||||
location_text.append(", ");
|
||||
}
|
||||
|
||||
std::string sim_name;
|
||||
msg->getString("Data", "SimName", sim_name);
|
||||
location_text.append(sim_name);
|
||||
location_text.append(" ");
|
||||
|
||||
//Fix for location text importing - RK
|
||||
for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
|
||||
{
|
||||
LLPanelPick* self = *iter;
|
||||
if(!self->mImporting) self->mLocationText = location_text;
|
||||
else location_text = self->mLocationText;
|
||||
self->mImporting = false;
|
||||
}
|
||||
|
||||
LLVector3d pos_global;
|
||||
msg->getVector3d("Data", "PosGlobal", pos_global);
|
||||
|
||||
S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
|
||||
S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
|
||||
S32 region_z = llround((F32)pos_global.mdV[VZ]);
|
||||
|
||||
location_text.append(llformat("(%d, %d, %d)", region_x, region_y, region_z));
|
||||
|
||||
S32 sort_order;
|
||||
msg->getS32("Data", "SortOrder", sort_order);
|
||||
|
||||
BOOL enabled;
|
||||
msg->getBOOL("Data", "Enabled", enabled);
|
||||
|
||||
// Look up the panel to fill in
|
||||
for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
|
||||
{
|
||||
LLPanelPick* self = *iter;
|
||||
// For top picks, must match pick id
|
||||
if (self->mPickID != pick_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
self->mDataReceived = TRUE;
|
||||
|
||||
// Found the panel, now fill in the information
|
||||
self->mPickID = pick_id;
|
||||
self->mCreatorID = creator_id;
|
||||
self->mParcelID = parcel_id;
|
||||
self->mSimName.assign(sim_name);
|
||||
self->mPosGlobal = pos_global;
|
||||
|
||||
// Update UI controls
|
||||
self->mNameEditor->setText(std::string(name));
|
||||
self->mDescEditor->setText(std::string(desc));
|
||||
self->mSnapshotCtrl->setImageAssetID(snapshot_id);
|
||||
self->mLocationEditor->setText(location_text);
|
||||
self->mEnabledCheck->set(enabled);
|
||||
|
||||
self->mSortOrderEditor->setText(llformat("%d", sort_order));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPick::draw()
|
||||
{
|
||||
@@ -611,6 +567,9 @@ void LLPanelPick::onCommitAny(LLUICtrl* ctrl, void* data)
|
||||
{
|
||||
LLPanelPick* self = (LLPanelPick*)data;
|
||||
|
||||
if(self->mCreatorID != gAgent.getID())
|
||||
return;
|
||||
|
||||
// have we received up to date data for this pick?
|
||||
if (self->mDataReceived)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "llpanel.h"
|
||||
#include "v3dmath.h"
|
||||
#include "lluuid.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
|
||||
class LLButton;
|
||||
class LLCheckBoxCtrl;
|
||||
@@ -52,7 +53,7 @@ class LLUICtrl;
|
||||
class LLMessageSystem;
|
||||
class AIFilePicker;
|
||||
|
||||
class LLPanelPick : public LLPanel
|
||||
class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
LLPanelPick(BOOL top_pick);
|
||||
@@ -66,6 +67,8 @@ public:
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
// Setup a new pick, including creating an id, giving a sane
|
||||
// initial position, etc.
|
||||
void initNewPick();
|
||||
@@ -91,8 +94,6 @@ public:
|
||||
void sendPickInfoRequest();
|
||||
void sendPickInfoUpdate();
|
||||
|
||||
static void processPickInfoReply(LLMessageSystem* msg, void**);
|
||||
|
||||
protected:
|
||||
static void onClickTeleport(void* data);
|
||||
static void onClickMap(void* data);
|
||||
|
||||
@@ -3617,20 +3617,20 @@ void register_viewer_callbacks(LLMessageSystem* msg)
|
||||
LLViewerParcelMgr::processParcelDwellReply);
|
||||
|
||||
msg->setHandlerFunc("AvatarPropertiesReply",
|
||||
LLPanelAvatar::processAvatarPropertiesReply);
|
||||
&LLAvatarPropertiesProcessor::processAvatarPropertiesReply);
|
||||
msg->setHandlerFunc("AvatarInterestsReply",
|
||||
LLPanelAvatar::processAvatarInterestsReply);
|
||||
&LLAvatarPropertiesProcessor::processAvatarInterestsReply);
|
||||
msg->setHandlerFunc("AvatarGroupsReply",
|
||||
LLPanelAvatar::processAvatarGroupsReply);
|
||||
&LLAvatarPropertiesProcessor::processAvatarGroupsReply);
|
||||
// ratings deprecated
|
||||
//msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
|
||||
// LLPanelAvatar::processAvatarStatisticsReply);
|
||||
msg->setHandlerFunc("AvatarNotesReply",
|
||||
LLPanelAvatar::processAvatarNotesReply);
|
||||
&LLAvatarPropertiesProcessor::processAvatarNotesReply);
|
||||
msg->setHandlerFunc("AvatarPicksReply",
|
||||
LLPanelAvatar::processAvatarPicksReply);
|
||||
&LLAvatarPropertiesProcessor::processAvatarPicksReply);
|
||||
msg->setHandlerFunc("AvatarClassifiedReply",
|
||||
LLPanelAvatar::processAvatarClassifiedReply);
|
||||
&LLAvatarPropertiesProcessor::processAvatarClassifiedsReply);
|
||||
|
||||
msg->setHandlerFuncFast(_PREHASH_CreateGroupReply,
|
||||
LLGroupMgr::processCreateGroupReply);
|
||||
@@ -3704,8 +3704,9 @@ void register_viewer_callbacks(LLMessageSystem* msg)
|
||||
msg->setHandlerFunc("MapItemReply", LLWorldMap::processMapItemReply);
|
||||
|
||||
msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply);
|
||||
msg->setHandlerFunc("PickInfoReply", LLPanelPick::processPickInfoReply);
|
||||
msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
|
||||
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
|
||||
//msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
|
||||
msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
|
||||
msg->setHandlerFunc("ParcelInfoReply", LLPanelPlace::processParcelInfoReply);
|
||||
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
|
||||
msg->setHandlerFunc("LoadURL", process_load_url);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "llagentcamera.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llanimationstates.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lldrawpoolavatar.h"
|
||||
#include "lldriverparam.h"
|
||||
@@ -7936,9 +7937,7 @@ bool LLVOAvatar::sendAvatarTexturesRequest()
|
||||
bool sent = false;
|
||||
if (mRuthTimer.getElapsedTimeF32() > DERUTHING_TIMEOUT_SECONDS)
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
strings.push_back(getID().asString());
|
||||
send_generic_message("avatartexturesrequest", strings);
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
|
||||
mRuthTimer.reset();
|
||||
sent = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user