PageRenderTime 162ms CodeModel.GetById 40ms app.highlight 91ms RepoModel.GetById 20ms app.codeStats 0ms

/indra/newview/llavatarpropertiesprocessor.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 655 lines | 458 code | 118 blank | 79 comment | 39 complexity | 07315086cf44e359de92e94c663f479e MD5 | raw file
  1/** 
  2 * @file llavatarpropertiesprocessor.cpp
  3 * @brief LLAvatarPropertiesProcessor class implementation
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llavatarpropertiesprocessor.h"
 30
 31// Viewer includes
 32#include "llagent.h"
 33#include "llagentpicksinfo.h"
 34#include "lldateutil.h"
 35#include "llviewergenericmessage.h"
 36
 37// Linden library includes
 38#include "llavatarconstants.h"	// AVATAR_TRANSACTED, etc.
 39#include "lldate.h"
 40#include "lltrans.h"
 41#include "llui.h"				// LLUI::getLanguage()
 42#include "message.h"
 43
 44LLAvatarPropertiesProcessor::LLAvatarPropertiesProcessor()
 45{
 46}
 47
 48LLAvatarPropertiesProcessor::~LLAvatarPropertiesProcessor()
 49{
 50}
 51
 52void LLAvatarPropertiesProcessor::addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
 53{
 54	// Check if that observer is already in mObservers for that avatar_id
 55	observer_multimap_t::iterator it;
 56
 57	// IAN BUG this should update the observer's UUID if this is a dupe - sent to PE
 58	it = mObservers.find(avatar_id);
 59	while (it != mObservers.end())
 60	{
 61		if (it->second == observer)
 62		{
 63			return;
 64		}
 65		else
 66		{
 67			++it;
 68		}
 69	}
 70
 71	mObservers.insert(std::pair<LLUUID, LLAvatarPropertiesObserver*>(avatar_id, observer));
 72}
 73
 74void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
 75{
 76	if (!observer)
 77	{
 78		return;
 79	}
 80
 81	observer_multimap_t::iterator it;
 82	it = mObservers.find(avatar_id);
 83	while (it != mObservers.end())
 84	{
 85		if (it->second == observer)
 86		{
 87			mObservers.erase(it);
 88			break;
 89		}
 90		else
 91		{
 92			++it;
 93		}
 94	}
 95}
 96
 97
 98void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
 99{
100	// Suppress duplicate requests while waiting for a response from the network
101	if (isPendingRequest(avatar_id, type))
102	{
103		// waiting for a response, don't re-request
104		return;
105	}
106	// indicate we're going to make a request
107	addPendingRequest(avatar_id, type);
108
109	std::vector<std::string> strings;
110	strings.push_back( avatar_id.asString() );
111	send_generic_message(method, strings);
112}
113
114void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
115{
116	if (isPendingRequest(avatar_id, APT_PROPERTIES))
117	{
118		// waiting for a response, don't re-request
119		return;
120	}
121	// indicate we're going to make a request
122	addPendingRequest(avatar_id, APT_PROPERTIES);
123
124	LLMessageSystem *msg = gMessageSystem;
125
126	msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
127	msg->nextBlockFast( _PREHASH_AgentData);
128	msg->addUUIDFast(   _PREHASH_AgentID, gAgent.getID() );
129	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
130	msg->addUUIDFast(   _PREHASH_AvatarID, avatar_id);
131	gAgent.sendReliableMessage();
132}
133
134void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
135{
136	sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
137}
138
139void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
140{
141	sendGenericRequest(avatar_id, APT_NOTES, "avatarnotesrequest");
142}
143
144void LLAvatarPropertiesProcessor::sendAvatarGroupsRequest(const LLUUID& avatar_id)
145{
146	sendGenericRequest(avatar_id, APT_GROUPS, "avatargroupsrequest");
147}
148
149void LLAvatarPropertiesProcessor::sendAvatarTexturesRequest(const LLUUID& avatar_id)
150{
151	sendGenericRequest(avatar_id, APT_TEXTURES, "avatartexturesrequest");
152	// No response expected.
153	removePendingRequest(avatar_id, APT_TEXTURES);
154}
155
156void LLAvatarPropertiesProcessor::sendAvatarClassifiedsRequest(const LLUUID& avatar_id)
157{
158	sendGenericRequest(avatar_id, APT_CLASSIFIEDS, "avatarclassifiedsrequest");
159}
160
161void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props)
162{
163	if (!gAgent.isInitialized() || (gAgent.getID() == LLUUID::null))
164	{
165		llwarns << "Sending avatarinfo update DENIED - invalid agent" << llendl;
166		return;
167	}
168
169	llinfos << "Sending avatarinfo update" << llendl;
170
171	// This value is required by sendAvatarPropertiesUpdate method.
172	//A profile should never be mature. (From the original code)
173	BOOL mature = FALSE;
174
175	LLMessageSystem *msg = gMessageSystem;
176
177	msg->newMessageFast	(_PREHASH_AvatarPropertiesUpdate);
178	msg->nextBlockFast	(_PREHASH_AgentData);
179	msg->addUUIDFast		(_PREHASH_AgentID,		gAgent.getID() );
180	msg->addUUIDFast		(_PREHASH_SessionID,	gAgent.getSessionID() );
181	msg->nextBlockFast	(_PREHASH_PropertiesData);
182
183	msg->addUUIDFast		(_PREHASH_ImageID,		avatar_props->image_id);
184	msg->addUUIDFast		(_PREHASH_FLImageID,	avatar_props->fl_image_id);
185	msg->addStringFast	(_PREHASH_AboutText,	avatar_props->about_text);
186	msg->addStringFast	(_PREHASH_FLAboutText,	avatar_props->fl_about_text);
187
188	msg->addBOOL(_PREHASH_AllowPublish, avatar_props->allow_publish);
189	msg->addBOOL(_PREHASH_MaturePublish, mature);
190	msg->addString(_PREHASH_ProfileURL, avatar_props->profile_url);
191
192	gAgent.sendReliableMessage();
193}
194
195
196
197//static
198std::string LLAvatarPropertiesProcessor::accountType(const LLAvatarData* avatar_data)
199{
200	// If you have a special account, like M Linden ("El Jefe!")
201	// return an untranslated "special" string
202	if (!avatar_data->caption_text.empty())
203	{
204		return avatar_data->caption_text;
205	}
206	const char* const ACCT_TYPE[] = {
207		"AcctTypeResident",
208		"AcctTypeTrial",
209		"AcctTypeCharterMember",
210		"AcctTypeEmployee"
211	};
212	U8 caption_max = (U8)LL_ARRAY_SIZE(ACCT_TYPE)-1;
213	U8 caption_index = llclamp(avatar_data->caption_index, (U8)0, caption_max);
214	return LLTrans::getString(ACCT_TYPE[caption_index]);
215}
216
217//static
218std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_data)
219{
220	// Special accounts like M Linden don't have payment info revealed.
221	if (!avatar_data->caption_text.empty()) return "";
222
223	// Linden employees don't have payment info revealed
224	const S32 LINDEN_EMPLOYEE_INDEX = 3;
225	if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return "";
226
227	BOOL transacted = (avatar_data->flags & AVATAR_TRANSACTED);
228	BOOL identified = (avatar_data->flags & AVATAR_IDENTIFIED);
229	// Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations
230	//BOOL age_verified = (avatar_data->flags & AVATAR_AGEVERIFIED); 
231
232	const char* payment_text;
233	if(transacted)
234	{
235		payment_text = "PaymentInfoUsed";
236	}
237	else if (identified)
238	{
239		payment_text = "PaymentInfoOnFile";
240	}
241	else
242	{
243		payment_text = "NoPaymentInfoOnFile";
244	}
245	return LLTrans::getString(payment_text);
246}
247
248void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
249{
250	LLAvatarData avatar_data;
251	std::string birth_date;
252
253	msg->getUUIDFast(	_PREHASH_AgentData,			_PREHASH_AgentID, 		avatar_data.agent_id);
254	msg->getUUIDFast(	_PREHASH_AgentData,			_PREHASH_AvatarID, 		avatar_data.avatar_id);
255	msg->getUUIDFast(  	_PREHASH_PropertiesData,	_PREHASH_ImageID,		avatar_data.image_id);
256	msg->getUUIDFast(  	_PREHASH_PropertiesData,	_PREHASH_FLImageID,		avatar_data.fl_image_id);
257	msg->getUUIDFast(	_PREHASH_PropertiesData,	_PREHASH_PartnerID,		avatar_data.partner_id);
258	msg->getStringFast(	_PREHASH_PropertiesData,	_PREHASH_AboutText,		avatar_data.about_text);
259	msg->getStringFast(	_PREHASH_PropertiesData,	_PREHASH_FLAboutText,	avatar_data.fl_about_text);
260	msg->getStringFast(	_PREHASH_PropertiesData,	_PREHASH_BornOn,		birth_date);
261	msg->getString(		_PREHASH_PropertiesData,	_PREHASH_ProfileURL,	avatar_data.profile_url);
262	msg->getU32Fast(	_PREHASH_PropertiesData,	_PREHASH_Flags,			avatar_data.flags);
263
264
265	LLDateUtil::dateFromPDTString(avatar_data.born_on, birth_date);
266	avatar_data.caption_index = 0;
267
268	S32 charter_member_size = 0;
269	charter_member_size = msg->getSize(_PREHASH_PropertiesData, _PREHASH_CharterMember);
270	if(1 == charter_member_size)
271	{
272		msg->getBinaryData(_PREHASH_PropertiesData, _PREHASH_CharterMember, &avatar_data.caption_index, 1);
273	}
274	else if(1 < charter_member_size)
275	{
276		msg->getString(_PREHASH_PropertiesData, _PREHASH_CharterMember, avatar_data.caption_text);
277	}
278	LLAvatarPropertiesProcessor* self = getInstance();
279	// Request processed, no longer pending
280	self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES);
281	self->notifyObservers(avatar_data.avatar_id,&avatar_data,APT_PROPERTIES);
282}
283
284void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* msg, void**)
285{
286/*
287	AvatarInterestsReply is automatically sent by the server in response to the 
288	AvatarPropertiesRequest sent when the panel is opened (in addition to the AvatarPropertiesReply message). 
289	If the interests panel is no longer part of the design (?) we should just register the message 
290	to a handler function that does nothing. 
291	That will suppress the warnings and be compatible with old server versions.
292	WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
293*/
294}
295
296void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
297{
298	LLAvatarClassifieds classifieds;
299
300	msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, classifieds.agent_id);
301	msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, classifieds.target_id);
302
303	S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
304
305	for(int n = 0; n < block_count; ++n)
306	{
307		LLAvatarClassifieds::classified_data data;
308
309		msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, data.classified_id, n);
310		msg->getString(_PREHASH_Data, _PREHASH_Name, data.name, n);
311
312		classifieds.classifieds_list.push_back(data);
313	}
314
315	LLAvatarPropertiesProcessor* self = getInstance();
316	// Request processed, no longer pending
317	self->removePendingRequest(classifieds.target_id, APT_CLASSIFIEDS);
318	self->notifyObservers(classifieds.target_id,&classifieds,APT_CLASSIFIEDS);
319}
320
321void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* msg, void**)
322{
323	LLAvatarClassifiedInfo c_info;
324
325	msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, c_info.agent_id);
326
327	msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, c_info.classified_id);
328	msg->getUUID(_PREHASH_Data, _PREHASH_CreatorID, c_info.creator_id);
329	msg->getU32(_PREHASH_Data, _PREHASH_CreationDate, c_info.creation_date);
330	msg->getU32(_PREHASH_Data, _PREHASH_ExpirationDate, c_info.expiration_date);
331	msg->getU32(_PREHASH_Data, _PREHASH_Category, c_info.category);
332	msg->getString(_PREHASH_Data, _PREHASH_Name, c_info.name);
333	msg->getString(_PREHASH_Data, _PREHASH_Desc, c_info.description);
334	msg->getUUID(_PREHASH_Data, _PREHASH_ParcelID, c_info.parcel_id);
335	msg->getU32(_PREHASH_Data, _PREHASH_ParentEstate, c_info.parent_estate);
336	msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, c_info.snapshot_id);
337	msg->getString(_PREHASH_Data, _PREHASH_SimName, c_info.sim_name);
338	msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, c_info.pos_global);
339	msg->getString(_PREHASH_Data, _PREHASH_ParcelName, c_info.parcel_name);
340	msg->getU8(_PREHASH_Data, _PREHASH_ClassifiedFlags, c_info.flags);
341	msg->getS32(_PREHASH_Data, _PREHASH_PriceForListing, c_info.price_for_listing);
342
343	LLAvatarPropertiesProcessor* self = getInstance();
344	// Request processed, no longer pending
345	self->removePendingRequest(c_info.creator_id, APT_CLASSIFIED_INFO);
346	self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO);
347}
348
349
350void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void**)
351{
352	LLAvatarNotes avatar_notes;
353
354	msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_notes.agent_id);
355	msg->getUUID(_PREHASH_Data, _PREHASH_TargetID, avatar_notes.target_id);
356	msg->getString(_PREHASH_Data, _PREHASH_Notes, avatar_notes.notes);
357
358	LLAvatarPropertiesProcessor* self = getInstance();
359	// Request processed, no longer pending
360	self->removePendingRequest(avatar_notes.target_id, APT_NOTES);
361	self->notifyObservers(avatar_notes.target_id,&avatar_notes,APT_NOTES);
362}
363
364void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
365{
366	LLAvatarPicks avatar_picks;
367	msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
368	msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
369
370	S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
371	for (int block = 0; block < block_count; ++block)
372	{
373		LLUUID pick_id;
374		std::string pick_name;
375
376		msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block);
377		msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block);
378
379		avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name));
380	}
381	LLAvatarPropertiesProcessor* self = getInstance();
382	// Request processed, no longer pending
383	self->removePendingRequest(avatar_picks.target_id, APT_PICKS);
384	self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS);
385}
386
387void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**)
388{
389	LLPickData pick_data;
390
391	// Extract the agent id and verify the message is for this
392	// client.
393	msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, pick_data.agent_id );
394	msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_data.pick_id);
395	msg->getUUID(_PREHASH_Data, _PREHASH_CreatorID, pick_data.creator_id);
396
397	// ** top_pick should be deleted, not being used anymore - angela
398	msg->getBOOL(_PREHASH_Data, _PREHASH_TopPick, pick_data.top_pick);
399	msg->getUUID(_PREHASH_Data, _PREHASH_ParcelID, pick_data.parcel_id);
400	msg->getString(_PREHASH_Data, _PREHASH_Name, pick_data.name);
401	msg->getString(_PREHASH_Data, _PREHASH_Desc, pick_data.desc);
402	msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, pick_data.snapshot_id);
403
404	msg->getString(_PREHASH_Data, _PREHASH_User, pick_data.user_name);
405	msg->getString(_PREHASH_Data, _PREHASH_OriginalName, pick_data.original_name);
406	msg->getString(_PREHASH_Data, _PREHASH_SimName, pick_data.sim_name);
407	msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, pick_data.pos_global);
408
409	msg->getS32(_PREHASH_Data, _PREHASH_SortOrder, pick_data.sort_order);
410	msg->getBOOL(_PREHASH_Data, _PREHASH_Enabled, pick_data.enabled);
411
412	LLAvatarPropertiesProcessor* self = getInstance();
413	// don't need to remove pending request as we don't track pick info
414	self->notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO);
415}
416
417void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, void**)
418{
419	LLAvatarGroups avatar_groups;
420	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_groups.agent_id );
421	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_groups.avatar_id );
422
423	S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
424	for(S32 i = 0; i < group_count; ++i)
425	{
426		LLAvatarGroups::LLGroupData group_data;
427
428		msg->getU64(    _PREHASH_GroupData, _PREHASH_GroupPowers,	group_data.group_powers, i );
429		msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupTitle,	group_data.group_title, i );
430		msg->getUUIDFast(  _PREHASH_GroupData, _PREHASH_GroupID,	group_data.group_id, i);
431		msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName,	group_data.group_name, i );
432		msg->getUUIDFast(  _PREHASH_GroupData, _PREHASH_GroupInsigniaID, group_data.group_insignia_id, i );
433
434		avatar_groups.group_list.push_back(group_data);
435	}
436
437	LLAvatarPropertiesProcessor* self = getInstance();
438	self->removePendingRequest(avatar_groups.avatar_id, APT_GROUPS);
439	self->notifyObservers(avatar_groups.avatar_id,&avatar_groups,APT_GROUPS);
440}
441
442void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type)
443{
444	// Copy the map (because observers may delete themselves when updated?)
445	LLAvatarPropertiesProcessor::observer_multimap_t observers = mObservers;
446
447	observer_multimap_t::iterator oi = observers.begin();
448	observer_multimap_t::iterator end = observers.end();
449	for (; oi != end; ++oi)
450	{
451		// only notify observers for the same agent, or if the observer
452		// didn't know the agent ID and passed a NULL id.
453		const LLUUID &agent_id = oi->first;
454		if (agent_id == id || agent_id.isNull())
455		{
456			oi->second->processProperties(data,type);
457		}
458	}
459}
460
461void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32 rights)
462{
463	if(!avatar_id.isNull())
464	{
465		LLMessageSystem* msg = gMessageSystem;
466
467		// setup message header
468		msg->newMessageFast(_PREHASH_GrantUserRights);
469		msg->nextBlockFast(_PREHASH_AgentData);
470		msg->addUUID(_PREHASH_AgentID, gAgent.getID());
471		msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
472
473		msg->nextBlockFast(_PREHASH_Rights);
474		msg->addUUID(_PREHASH_AgentRelated, avatar_id);
475		msg->addS32(_PREHASH_RelatedRights, rights);
476
477		gAgent.sendReliableMessage();
478	}
479}
480
481void LLAvatarPropertiesProcessor::sendNotes(const LLUUID& avatar_id, const std::string notes)
482{
483	if(!avatar_id.isNull())
484	{
485		LLMessageSystem* msg = gMessageSystem;
486
487		// setup message header
488		msg->newMessageFast(_PREHASH_AvatarNotesUpdate);
489		msg->nextBlockFast(_PREHASH_AgentData);
490		msg->addUUID(_PREHASH_AgentID, gAgent.getID());
491		msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
492
493		msg->nextBlockFast(_PREHASH_Data);
494		msg->addUUID(_PREHASH_TargetID, avatar_id);
495		msg->addString(_PREHASH_Notes, notes);
496
497		gAgent.sendReliableMessage();
498	}
499}
500
501
502void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id )
503{
504	LLMessageSystem* msg = gMessageSystem; 
505	msg->newMessage(_PREHASH_PickDelete);
506	msg->nextBlock(_PREHASH_AgentData);
507	msg->addUUID(_PREHASH_AgentID, gAgent.getID());
508	msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
509	msg->nextBlock(_PREHASH_Data);
510	msg->addUUID(_PREHASH_PickID, pick_id);
511	gAgent.sendReliableMessage();
512
513	LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
514	LLAgentPicksInfo::getInstance()->decrementNumberOfPicks();
515}
516
517void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_id)
518{
519	LLMessageSystem* msg = gMessageSystem; 
520
521	msg->newMessage(_PREHASH_ClassifiedDelete);
522
523	msg->nextBlock(_PREHASH_AgentData);
524	msg->addUUID(_PREHASH_AgentID, gAgent.getID());
525	msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
526
527	msg->nextBlock(_PREHASH_Data);
528	msg->addUUID(_PREHASH_ClassifiedID, classified_id);
529
530	gAgent.sendReliableMessage();
531}
532
533void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
534{
535	if (!new_pick) return;
536
537	LLMessageSystem* msg = gMessageSystem;
538
539	msg->newMessage(_PREHASH_PickInfoUpdate);
540	msg->nextBlock(_PREHASH_AgentData);
541	msg->addUUID(_PREHASH_AgentID, gAgent.getID());
542	msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
543
544	msg->nextBlock(_PREHASH_Data);
545	msg->addUUID(_PREHASH_PickID, new_pick->pick_id);
546	msg->addUUID(_PREHASH_CreatorID, new_pick->creator_id);
547
548	//legacy var need to be deleted
549	msg->addBOOL(_PREHASH_TopPick, FALSE);	
550
551	// fills in on simulator if null
552	msg->addUUID(_PREHASH_ParcelID, new_pick->parcel_id);
553	msg->addString(_PREHASH_Name, new_pick->name);
554	msg->addString(_PREHASH_Desc, new_pick->desc);
555	msg->addUUID(_PREHASH_SnapshotID, new_pick->snapshot_id);
556	msg->addVector3d(_PREHASH_PosGlobal, new_pick->pos_global);
557
558	// Only top picks have a sort order
559	msg->addS32(_PREHASH_SortOrder, 0);
560
561	msg->addBOOL(_PREHASH_Enabled, new_pick->enabled);
562	gAgent.sendReliableMessage();
563
564	LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
565}
566
567void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data)
568{
569	if(!c_data)
570	{
571		return;
572	}
573
574	LLMessageSystem* msg = gMessageSystem;
575
576	msg->newMessage(_PREHASH_ClassifiedInfoUpdate);
577
578	msg->nextBlock(_PREHASH_AgentData);
579	msg->addUUID(_PREHASH_AgentID, gAgent.getID());
580	msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
581
582	msg->nextBlock(_PREHASH_Data);
583	msg->addUUID(_PREHASH_ClassifiedID, c_data->classified_id);
584	msg->addU32(_PREHASH_Category, c_data->category);
585	msg->addString(_PREHASH_Name, c_data->name);
586	msg->addString(_PREHASH_Desc, c_data->description);
587	msg->addUUID(_PREHASH_ParcelID, c_data->parcel_id);
588	msg->addU32(_PREHASH_ParentEstate, 0);
589	msg->addUUID(_PREHASH_SnapshotID, c_data->snapshot_id);
590	msg->addVector3d(_PREHASH_PosGlobal, c_data->pos_global);
591	msg->addU8(_PREHASH_ClassifiedFlags, c_data->flags);
592	msg->addS32(_PREHASH_PriceForListing, c_data->price_for_listing);
593
594	gAgent.sendReliableMessage();
595}
596
597void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id)
598{
599	// Must ask for a pick based on the creator id because
600	// the pick database is distributed to the inventory cluster. JC
601	std::vector<std::string> request_params;
602	request_params.push_back(creator_id.asString() );
603	request_params.push_back(pick_id.asString() );
604	send_generic_message("pickinforequest", request_params);
605}
606
607void LLAvatarPropertiesProcessor::sendClassifiedInfoRequest(const LLUUID& classified_id)
608{
609	LLMessageSystem* msg = gMessageSystem;
610
611	msg->newMessage(_PREHASH_ClassifiedInfoRequest);
612	msg->nextBlock(_PREHASH_AgentData);
613	
614	msg->addUUID(_PREHASH_AgentID, gAgent.getID());
615	msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
616
617	msg->nextBlock(_PREHASH_Data);
618	msg->addUUID(_PREHASH_ClassifiedID, classified_id);
619
620	gAgent.sendReliableMessage();
621}
622
623bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
624{
625	timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
626	timestamp_map_t::iterator it = mRequestTimestamps.find(key);
627
628	// Is this a new request?
629	if (it == mRequestTimestamps.end()) return false;
630
631	// We found a request, check if it has timed out
632	U32 now = time(NULL);
633	const U32 REQUEST_EXPIRE_SECS = 5;
634	U32 expires = it->second + REQUEST_EXPIRE_SECS;
635
636	// Request is still pending if it hasn't expired yet
637	// *NOTE: Expired requests will accumulate in this map, but they are rare,
638	// the data is small, and they will be updated if the same data is
639	// re-requested
640	return (now < expires);
641}
642
643void LLAvatarPropertiesProcessor::addPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
644{
645	timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
646	U32 now = time(NULL);
647	// Add or update existing (expired) request
648	mRequestTimestamps[ key ] = now;
649}
650
651void LLAvatarPropertiesProcessor::removePendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
652{
653	timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
654	mRequestTimestamps.erase(key);
655}