Example #1
0
void LLFloaterAvatarList::updateAvatarList()
{
	if (sInstance != this) return;

	//llinfos << "radar refresh: updating map" << llendl;

	// Check whether updates are enabled
	LLCheckboxCtrl* check = getChild<LLCheckboxCtrl>("update_enabled_cb");
	if (check && !check->getValue())
	{
		mUpdate = FALSE;
		refreshTracker();
		return;
	}
	else
	{
		mUpdate = TRUE;
	}

	LLVector3d mypos = gAgent.getPositionGlobal();

	{
		std::vector<LLUUID> avatar_ids;
		std::vector<LLUUID> sorted_avatar_ids;
		std::vector<LLVector3d> positions;

		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, mypos, F32_MAX);

		sorted_avatar_ids = avatar_ids;
		std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end());

		for (std::vector<LLCharacter*>::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter)
		{
			LLUUID avid = (*iter)->getID();

			if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid))
			{
				avatar_ids.push_back(avid);
			}
		}

		size_t i;
		size_t count = avatar_ids.size();

		for (i = 0; i < count; ++i)
		{
			std::string name;
			std::string first;
			std::string last;
			const LLUUID &avid = avatar_ids[i];

			LLVector3d position;
			LLViewerObject *obj = gObjectList.findObject(avid);

			if (obj)
			{
				LLVOAvatar* avatarp = dynamic_cast<LLVOAvatar*>(obj);

				if (avatarp == NULL)
				{
					continue;
				}

				// Skip if avatar is dead(what's that?)
				// or if the avatar is ourselves.
				if (avatarp->isDead() || avatarp->isSelf())
				{
					continue;
				}

				// Get avatar data
				position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition());
				name = avatarp->getFullname();

				// Apparently, sometimes the name comes out empty, with a " " name. This is because
				// getFullname concatenates first and last name with a " " in the middle.
				// This code will avoid adding a nameless entry to the list until it acquires a name.

				//duped for lower section
				if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0))
				{
					if (gCacheName->getName(avid, first, last))
					{
						name = first + " " + last;
					}
					else
					{
						continue;
					}
				}

				if (avid.isNull())
				{
					//llinfos << "Key empty for avatar " << name << llendl;
					continue;
				}

				if (mAvatars.count(avid) > 0)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					mAvatars[avid].setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0);
				}
				else
				{
					// Avatar not there yet, add it
					LLAvatarListEntry entry(avid, name, position);
					mAvatars[avid] = entry;
				}
			}
			else
			{
				if (i < positions.size())
				{
					position = positions[i];
				}
				else
				{
					continue;
				}

				if (gCacheName->getName(avid, first, last))
				{
					name = first + " " + last;
				}
				else
				{
					//name = gCacheName->getDefaultName();
					continue; //prevent (Loading...)
				}

				if (mAvatars.count(avid) > 0)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					mAvatars[avid].setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0);
				}
				else
				{
					LLAvatarListEntry entry(avid, name, position);
					mAvatars[avid] = entry;
				}
			}
		}
	}
	
//	llinfos << "radar refresh: done" << llendl;

	expireAvatarList();
	refreshAvatarList();
	refreshTracker();
}
void LLFloaterAvatarList::updateAvatarList()
{
	if (sInstance != this) return;

	//llinfos << "radar refresh: updating map" << llendl;

	// Check whether updates are enabled
	LLCheckboxCtrl* check = getChild<LLCheckboxCtrl>("update_enabled_cb");
	if (check && !check->getValue())
	{
		mUpdate = FALSE;
		refreshTracker();
		return;
	}
	else
	{
		mUpdate = TRUE;
	}

	LLVector3d mypos = gAgent.getPositionGlobal();

	{
		std::vector<LLUUID> avatar_ids;
		std::vector<LLUUID> sorted_avatar_ids;
		std::vector<LLVector3d> positions;

		LLWorld::instance().getAvatars(&avatar_ids, &positions, mypos, F32_MAX);

		sorted_avatar_ids = avatar_ids;
		std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end());

		for (std::vector<LLCharacter*>::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter)
		{
			LLUUID avid = (*iter)->getID();

			if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid))
			{
				avatar_ids.push_back(avid);
			}
		}

		size_t i;
		size_t count = avatar_ids.size();
		
		bool announce = gSavedSettings.getBOOL("RadarChatKeys");
		std::queue<LLUUID> announce_keys;

		for (i = 0; i < count; ++i)
		{
			std::string name;
			std::string first;
			std::string last;
			const LLUUID &avid = avatar_ids[i];

			LLVector3d position;
			LLVOAvatar* avatarp = gObjectList.findAvatar(avid);

			if (avatarp)
			{
				// Skip if avatar is dead(what's that?)
				// or if the avatar is ourselves.
				// or if the avatar is a dummy
				if (avatarp->isDead() || avatarp->isSelf() || avatarp->mIsDummy)
				{
					continue;
				}

				// Get avatar data
				position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition());
				name = avatarp->getFullname();
			
				// [Ansariel: Display name support]
				LLAvatarName avatar_name;
				if (LLAvatarNameCache::get(avatarp->getID(), &avatar_name))
				{
				    static const LLCachedControl<S32> phoenix_name_system("PhoenixNameSystem", 0);
					switch (phoenix_name_system)
					{
						case 0 : name = avatar_name.getLegacyName(); break;
						case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break;
						case 2 : name = avatar_name.mDisplayName; break;
						default : name = avatar_name.getLegacyName(); break;
					}

					first = avatar_name.mLegacyFirstName;
					last = avatar_name.mLegacyLastName;
				}
				else continue;
				// [/Ansariel: Display name support]

				//duped for lower section
				if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0))
				{
					if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::get above...
					{
						continue;
					}
				}

				if (avid.isNull())
				{
					//llinfos << "Key empty for avatar " << name << llendl;
					continue;
				}

				if (mAvatars.count(avid) > 0)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					mAvatars[avid].setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0);
				}
				else
				{
					// Avatar not there yet, add it
					LLAvatarListEntry entry(avid, name, position);
					if(announce && avatarp->getRegion() == gAgent.getRegion())
						announce_keys.push(avid);
					mAvatars[avid] = entry;
				}
			}
			else
			{
				if (i < positions.size())
				{
					position = positions[i];
				}
				else
				{
					continue;
				}

				if (!gCacheName->getFullName(avid, name))
				{
					//name = gCacheName->getDefaultName();
					continue; //prevent (Loading...)
				}

				if (mAvatars.count(avid) > 0)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					mAvatars[avid].setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0);
				}
				else
				{
					LLAvatarListEntry entry(avid, name, position);
					if(announce && gAgent.getRegion()->pointInRegionGlobal(position))
						announce_keys.push(avid);
					mAvatars[avid] = entry;
				}
			}
		}
		//let us send the keys in a more timely fashion
		if(announce && !announce_keys.empty())
                {
			std::ostringstream ids;
			int transact_num = (int)gFrameCount;
			int num_ids = 0;
			while(!announce_keys.empty())
			{
				LLUUID id = announce_keys.front();
				announce_keys.pop();

				ids << "," << id.asString();
				++num_ids;

				if(ids.tellp() > 200)
				{
				        gMessageSystem->newMessage("ScriptDialogReply");
				        gMessageSystem->nextBlock("AgentData");
				        gMessageSystem->addUUID("AgentID", gAgent.getID());
				        gMessageSystem->addUUID("SessionID", gAgent.getSessionID());
				        gMessageSystem->nextBlock("Data");
				        gMessageSystem->addUUID("ObjectID", gAgent.getID());
				        gMessageSystem->addS32("ChatChannel", -777777777);
				        gMessageSystem->addS32("ButtonIndex", 1);
				        gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str());
				        gAgent.sendReliableMessage();

				        num_ids = 0;
				        ids.seekp(0);
				        ids.str("");
				}
			}
			if(num_ids > 0)
			{
				gMessageSystem->newMessage("ScriptDialogReply");
				gMessageSystem->nextBlock("AgentData");
				gMessageSystem->addUUID("AgentID", gAgent.getID());
				gMessageSystem->addUUID("SessionID", gAgent.getSessionID());
				gMessageSystem->nextBlock("Data");
				gMessageSystem->addUUID("ObjectID", gAgent.getID());
				gMessageSystem->addS32("ChatChannel", -777777777);
				gMessageSystem->addS32("ButtonIndex", 1);
				gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str());
				gAgent.sendReliableMessage();
			}
                }
	}
	
//	llinfos << "radar refresh: done" << llendl;

	expireAvatarList();
	refreshAvatarList();
	refreshTracker();
}
//---------------------------------------------------------------------------
// Singu Note: We could clean a lot of this up by creating derived classes for Notifications and NotificationTips.
LLNotifyBox::LLNotifyBox(LLNotificationPtr notification)
	:	LLPanel(notification->getName(), LLRect(), BORDER_NO),
		LLEventTimer(notification->getExpiration() == LLDate() 
			? LLDate(LLDate::now().secondsSinceEpoch() + (F64)gSavedSettings.getF32("NotifyTipDuration")) 
			: notification->getExpiration()),
		LLInstanceTracker<LLNotifyBox, LLUUID>(notification->getID()),
	  mNotification(notification),
	  mIsTip(notification->getType() == "notifytip"),
	  mAnimating(gNotifyBoxView->getChildCount() == 0), // Only animate first window
	  mNextBtn(NULL),
	  mNumOptions(0),
	  mNumButtons(0),
	  mAddedDefaultBtn(false),
	  mUserInputBox(NULL)
{
	std::string edit_text_name;
	std::string edit_text_contents;

	// setup paramaters
	const std::string& message(notification->getMessage());

	// initialize
	setFocusRoot(!mIsTip);

	// caution flag can be set explicitly by specifying it in the
	// notification payload, or it can be set implicitly if the
	// notify xml template specifies that it is a caution
	//
	// tip-style notification handle 'caution' differently -
	// they display the tip in a different color
	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;

	LLNotificationFormPtr form(notification->getForm());

	mNumOptions = form->getNumElements();
		  
	bool is_textbox = form->getElement("message").isDefined();

	bool layout_script_dialog(notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
	LLRect rect = mIsTip ? getNotifyTipRect(message)
		   		  		 : getNotifyRect(is_textbox ? 10 : mNumOptions, layout_script_dialog, mIsCaution);
	if ((form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE || form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE))
		rect.mBottom -= BTN_HEIGHT;
	setRect(rect);
	setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
	setBackgroundVisible(FALSE);
	setBackgroundOpaque(TRUE);

	const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32);
	const S32 BOTTOM = (S32)sFont->getLineHeight();
	S32 x = HPAD + HPAD;
	S32 y = TOP;

	auto icon = new LLIconCtrl(std::string("icon"), LLRect(x, y, x+32, TOP-32), mIsTip ? "notify_tip_icon.tga" : mIsCaution ? "notify_caution_icon.tga" : "notify_box_icon.tga");

	icon->setMouseOpaque(FALSE);
	addChild(icon);

	x += HPAD + HPAD + 32;

	// add a caution textbox at the top of a caution notification
	if (mIsCaution && !mIsTip)
	{
		S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD;
		auto caution_box = new LLTextBox(
			std::string("caution_box"), 
			LLRect(x, y, getRect().getWidth() - 2, caution_height), 
			LLStringUtil::null, 
			sFont, 
			FALSE);

		caution_box->setFontStyle(LLFontGL::BOLD);
		caution_box->setColor(gColors.getColor("NotifyCautionWarnColor"));
		caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor"));
		caution_box->setBorderVisible(FALSE);
		caution_box->setWrappedText(notification->getMessage());
		
		addChild(caution_box);

		// adjust the vertical position of the next control so that 
		// it appears below the caution textbox
		y = y - caution_height;
	}
	else
	{
		const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);

		// Tokenization on \n is handled by LLTextBox

		const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;  // For script dialogs: add space for title.

		auto text = new LLTextEditor(std::string("box"), LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), MAX_LENGTH, LLStringUtil::null, sFont, FALSE, true);
		text->setWordWrap(TRUE);
		text->setMouseOpaque(TRUE);
		text->setBorderVisible(FALSE);
		text->setTakesNonScrollClicks(TRUE);
		text->setHideScrollbarForShortDocs(TRUE);
		text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually 
															// rendered under the text box, therefore we want 
															// the actual text box to be transparent

		auto text_color = gColors.getColor(mIsCaution && mIsTip ? "NotifyCautionWarnColor" : "NotifyTextColor");
		text->setReadOnlyFgColor(text_color); //sets caution text color for tip notifications
		if (!mIsCaution) // We could do some extra color math here to determine if bg's too close to link color, but let's just cross with the link color instead
			text->setLinkColor(new LLColor4(lerp(text_color, gSavedSettings.getColor4("HTMLLinkColor"), 0.4f)));
		text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard)
		text->appendText(message,false,false,nullptr,!layout_script_dialog); // Now we can set the text, since colors have been set.
		addChild(text);
	}

	if (mIsTip)
	{
		chat_notification(mNotification);
	}
	else
	{
		mNextBtn = new LLButton(std::string("next"),
						   LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD),
						   std::string("notify_next.png"),
						   std::string("notify_next.png"),
						   LLStringUtil::null,
						   boost::bind(&LLNotifyBox::moveToBack, this, true),
						   sFont);
		mNextBtn->setScaleImage(TRUE);
		mNextBtn->setToolTip(LLTrans::getString("next"));
		addChild(mNextBtn);

		for (S32 i = 0; i < mNumOptions; i++)
		{
			LLSD form_element = form->getElement(i);
			std::string element_type = form_element["type"].asString();
			if (element_type == "button") 
			{
				addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean(), layout_script_dialog);
			}
			else if (element_type == "input") 
			{
				edit_text_contents = form_element["value"].asString();
				edit_text_name = form_element["name"].asString();
			}
		}

		if (is_textbox)
		{
			S32 button_rows = layout_script_dialog ? 2 : 1;

			LLRect input_rect;
			input_rect.setOriginAndSize(x, BOTTOM_PAD + button_rows * (BTN_HEIGHT + VPAD),
										3 * 80 + 4 * HPAD, button_rows * (BTN_HEIGHT + VPAD) + BTN_HEIGHT);

			mUserInputBox = new LLTextEditor(edit_text_name, input_rect, 254,
											 edit_text_contents, sFont, FALSE);
			mUserInputBox->setBorderVisible(TRUE);
			mUserInputBox->setTakesNonScrollClicks(TRUE);
			mUserInputBox->setHideScrollbarForShortDocs(TRUE);
			mUserInputBox->setWordWrap(TRUE);
			mUserInputBox->setTabsToNextField(FALSE);
			mUserInputBox->setCommitOnFocusLost(FALSE);
			mUserInputBox->setAcceptCallingCardNames(FALSE);
			mUserInputBox->setHandleEditKeysDirectly(TRUE);

			addChild(mUserInputBox, -1);
		}
		else
		{
			setIsChrome(TRUE);
		}

		if (mNumButtons == 0)
		{
			addButton("OK", "OK", false, true, layout_script_dialog);
			mAddedDefaultBtn = true;
		}

		std::string check_title;
		if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
		{
			check_title = LLNotificationTemplates::instance().getGlobalString("skipnexttime");
		}
		else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
		{
			check_title = LLNotificationTemplates::instance().getGlobalString("alwayschoose");
		}
		if (!check_title.empty())
		{
			const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF);
			S32 line_height = llfloor(font->getLineHeight() + 0.99f);

			// Extend dialog for "check next time"
			S32 max_msg_width = getRect().getWidth() - HPAD * 9;
			S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16;
			max_msg_width = llmax(max_msg_width, check_width);

			S32 msg_x = (getRect().getWidth() - max_msg_width) / 2;

			LLRect check_rect;
			check_rect.setOriginAndSize(msg_x, BOTTOM_PAD + BTN_HEIGHT + VPAD*2 + (BTN_HEIGHT + VPAD) * (mNumButtons / 3),
				max_msg_width, line_height);

			LLCheckboxCtrl* check = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font,
				// Lambda abuse.
				[this](LLUICtrl* ctrl, const LLSD& param)
				{
						this->mNotification->setIgnored(ctrl->getValue());
				});
			check->setEnabledColor(LLUI::sColorsGroup->getColor(mIsCaution ? "AlertCautionTextColor" : "AlertTextColor"));
			if (mIsCaution)
			{
				check->setButtonColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
			}
			addChild(check);
		}
		
		if (++sNotifyBoxCount <= 0)
			LL_WARNS() << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << LL_ENDL;
		// If this is the only notify box, don't show the next button
		else if (sNotifyBoxCount == 1 && mNextBtn)
			mNextBtn->setVisible(false);
	}
}
BOOL FloaterAvatarList::tick()
{
	if(!gDisconnected)
	{

		LLCheckboxCtrl* check = getChild<LLCheckboxCtrl>("update_enabled_cb");

		if(check && check->getValue())
		{
			//UPDATES//
			LLVector3d agent_pos = gAgent.getPositionGlobal();
			std::vector<LLUUID> avatar_ids;
			std::vector<LLUUID> sorted_avatar_ids;
			std::vector<LLVector3d> positions;

			LLWorld::instance().getAvatars(&avatar_ids, &positions,agent_pos);

			sorted_avatar_ids = avatar_ids;
			std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end());

			for(std::vector<LLCharacter*>::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter)
			{
				LLUUID avid = (*iter)->getID();

				if(!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid))
				{
					avatar_ids.push_back(avid);
				}
			}

			int i = 0;
			int len = avatar_ids.size();
			for(i = 0; i < len; i++)
			{
				LLUUID &avid = avatar_ids[i];
				if(avid != gAgent.getID())
				{

					std::string name;
					std::string first;
					std::string last;
					LLVector3d position;
					LLViewerObject *obj = gObjectList.findObject(avid);

					bool same_region = false;

					bool in_draw = false;

					if(obj)
					{
						LLVOAvatar* avatarp = dynamic_cast<LLVOAvatar*>(obj);

						if (avatarp == NULL)
						{
							continue;
						}
						if (avatarp->isDead())
						{
							continue;
						}
						position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition());

						in_draw = true;

						same_region = avatarp->getRegion() == gAgent.getRegion();

					}else
					{
						if( i < (int)positions.size())
						{
							position = positions[i];
						}
						else
						{
							continue;
						}

						same_region = gAgent.getRegion()->pointInRegionGlobal(position);
					}
					if(gCacheName->getName(avid, first, last))
					{
						name = first + " " + last;
					}
					else
					{
						continue;//name = LLCacheName::getDefaultName();
					}

					
					if (mAvatars.find(avid) == mAvatars.end())
					{
						avatar_entry new_entry;
						new_entry.id = avid;
						new_entry.is_linden = (strcmp(last.c_str(),"Linden") == 0 || strcmp(last.c_str(),"Tester") == 0) ? true : false;
						mAvatars[avid] = new_entry;
						if(gSavedSettings.getBOOL("EmeraldRadarChatKeys"))
						{
							gMessageSystem->newMessage("ScriptDialogReply");
							gMessageSystem->nextBlock("AgentData");
							gMessageSystem->addUUID("AgentID", gAgent.getID());
							gMessageSystem->addUUID("SessionID", gAgent.getSessionID());
							gMessageSystem->nextBlock("Data");
							gMessageSystem->addUUID("ObjectID", gAgent.getID());
							gMessageSystem->addS32("ChatChannel", gSavedSettings.getS32("EmeraldRadarChatKeysChannel"));
							gMessageSystem->addS32("ButtonIndex", 1);
							gMessageSystem->addString("ButtonLabel",llformat("%d,%d,", gFrameCount, 1) + avid.asString());
							gAgent.sendReliableMessage();
						}
					}
					avatar_entry* entry = &(mAvatars[avid]);
					entry->name = name;
					entry->position = position;
					entry->same_region = same_region;
					entry->last_update_frame = gFrameCount;
					entry->last_update_sec.reset();

					bool in_chat = (position - agent_pos).magVec() < 20.0f;

					
					chat_alerts(entry,same_region, in_draw, in_chat);

					if(entry->last_in_sim != same_region)
					{
						LLViewerRegion* regionp = gAgent.getRegion();
						if(sInstance->mEstateMemoryBans.find(regionp) != sInstance->mEstateMemoryBans.end())
						{
							std::set<LLUUID> *mem = &mEstateMemoryBans[regionp];
							if(mem->find(avid) != mem->end())
							{
								cmdline_printchat("Enforcing memory ban.");
								execEstateKick(avid);
							}
						}
					}
					entry->last_in_sim = same_region;
					entry->last_in_draw = in_draw;
					entry->last_in_chat = in_chat;
				}
			}
			//END UPDATES//


			//EXPIRE//
			std::map<LLUUID, avatar_entry>::iterator iter;
			std::queue<LLUUID> delete_queue;

			
			for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
			{
				//avatar_entry *entry = &iter->second;
				
				F32 aged = iter->second.last_update_sec.getElapsedTimeF32();
				if ( aged > CLEANUP_TIMEOUT )
				{
					LLUUID av_id = iter->first;
					delete_queue.push(av_id);
				}
				else if(iter->second.last_update_frame != gFrameCount)
					if(iter->second.last_update_frame != -1)
					{
						LLUUID av_id = iter->first;
						chat_alerts(&iter->second,false, false, false);
						iter->second.last_in_sim = false;
						iter->second.last_in_draw = false;
						iter->second.last_in_chat = false;
						iter->second.last_update_frame = -1;
						if(gSavedSettings.getBOOL("EmeraldRadarChatKeys"))
						{
							gMessageSystem->newMessage("ScriptDialogReply");
							gMessageSystem->nextBlock("AgentData");
							gMessageSystem->addUUID("AgentID", gAgent.getID());
							gMessageSystem->addUUID("SessionID", gAgent.getSessionID());
							gMessageSystem->nextBlock("Data");
							gMessageSystem->addUUID("ObjectID", gAgent.getID());
							gMessageSystem->addS32("ChatChannel", gSavedSettings.getS32("EmeraldRadarChatKeysChannel"));
							gMessageSystem->addS32("ButtonIndex", 1);
							gMessageSystem->addString("ButtonLabel",llformat("%d,%d,", gFrameCount, 0) + av_id.asString());
							gAgent.sendReliableMessage();
						}
					}
			}

			while(!delete_queue.empty())
			{
				mAvatars.erase(delete_queue.front());
				delete_queue.pop();
			}
			//END EXPIRE//


			//DRAW//
			if (sInstance->getVisible())
			{
				LLCheckboxCtrl* fetch_data = getChild<LLCheckboxCtrl>("fetch_avdata_enabled_cb");
				BOOL fetching = fetch_data->getValue();

				LLDynamicArray<LLUUID> selected = mAvatarList->getSelectedIDs();
				S32 scrollpos = mAvatarList->getScrollPos();

				mAvatarList->deleteAllItems();

				std::map<LLUUID, avatar_entry>::iterator iter;

				for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
				{

					
					
					LLUUID av_id;

					av_id = iter->first;
					avatar_entry *entry = &iter->second;

					//llinfos << entry->last_update_sec.getElapsedSeconds() << llendl;
					if(entry->last_update_sec.getElapsedTimeF32() < 5.0f)
					{
						LLSD element;

						if(entry->has_info == false && fetching && last_av_req.getElapsedTimeF32() > MIN_REQUEST_INTERVAL)
						{
							F32 now = entry->lifetime.getElapsedTimeF32();
							F32 diff = now - entry->last_info_req;
							bool requested = entry->info_requested();
							if(diff > entry->request_timeout || !requested)
							{
								
								if(requested && entry->request_timeout < 256.0f)entry->request_timeout *= 2.0f;

								last_av_req.reset();

								entry->last_info_req = entry->lifetime.getElapsedTimeF32();


								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, av_id);
								gAgent.sendReliableMessage();

							}
						}


						LLVector3d delta = entry->position - agent_pos;
						F32 distance = (F32)delta.magVec();
						delta.mdV[VZ] = 0.0f;
						//F32 side_distance = (F32)delta.magVec();

						if(av_id.isNull())continue;

						element["id"] = av_id;

						std::string icon = "";

						if(entry->is_linden)
						{
							element["columns"][LIST_AVATAR_NAME]["font-style"] = "BOLD";
						}

						element["columns"][LIST_AVATAR_NAME]["column"] = "avatar_name";
						element["columns"][LIST_AVATAR_NAME]["type"] = "text";
						element["columns"][LIST_AVATAR_NAME]["value"] = entry->name;
						element["columns"][LIST_AVATAR_NAME]["color"] = gColors.getColor("DefaultListText").getValue();

						element["columns"][LIST_DISTANCE]["column"] = "distance";
						element["columns"][LIST_DISTANCE]["type"] = "text";
						
						if(entry->position.mdV[VZ] == 0.0)
						{
							static F32 *sRenderFarClip = rebind_llcontrol<F32>("RenderFarClip",&gSavedSettings,true);
							element["columns"][LIST_DISTANCE]["value"] = llformat("> %d", S32(*sRenderFarClip) );
						}else
						{
							element["columns"][LIST_DISTANCE]["value"] = llformat("%.2f", distance);
						}

						LLColor4 dist_color;

						static LLColor4U *sAvatarListTextDistNormalRange = rebind_llcontrol<LLColor4U>("AvatarListTextDistNormalRange",&gColors,true);
						static LLColor4U *sAvatarListTextDistShoutRange = rebind_llcontrol<LLColor4U>("AvatarListTextDistShoutRange",&gColors,true);
						static LLColor4U *sAvatarListTextDistOver = rebind_llcontrol<LLColor4U>("AvatarListTextDistOver",&gColors,true);

						if(distance <= 20.0f)dist_color = LLColor4(*sAvatarListTextDistNormalRange);
						else if(distance > 20.0f && distance <= 96.0f)dist_color = LLColor4(*sAvatarListTextDistShoutRange);
						else dist_color = LLColor4(*sAvatarListTextDistOver);

						element["columns"][LIST_DISTANCE]["color"] = dist_color.getValue();


						if(entry->has_info)
						{
							static F32 *sEmeraldAvatarAgeAlertDays = rebind_llcontrol<F32>("EmeraldAvatarAgeAlertDays",&gSavedSettings,true);
							if(entry->account_age < *sEmeraldAvatarAgeAlertDays && entry->age_alerted == false)
							{
								entry->age_alerted = true;
							}
							element["columns"][LIST_AGE]["column"] = "age";
							element["columns"][LIST_AGE]["type"] = "text";
							element["columns"][LIST_AGE]["value"] = llformat("%d",entry->account_age);

							LLColor4 age_color;

							static LLColor4U *sAvatarListTextAgeYoung = rebind_llcontrol<LLColor4U>("AvatarListTextAgeYoung",&gColors,true);
							static LLColor4U *sAvatarListTextAgeNormal = rebind_llcontrol<LLColor4U>("AvatarListTextAgeNormal",&gColors,true);

							if ( entry->account_age <= 7 )age_color = LLColor4(*sAvatarListTextAgeYoung);
							else age_color = LLColor4(*sAvatarListTextAgeNormal);

							element["columns"][LIST_AGE]["color"] = age_color.getValue();
						}

						element["columns"][LIST_SIM]["column"] = "samesim";
						element["columns"][LIST_SIM]["type"] = "text";

						icon = "";
						if(entry->last_update_sec.getElapsedTimeF32() < 0.5)
						{
							if(entry->same_region)
							{
								icon = "account_id_green.tga";
							}
						}else
						{
							icon = "avatar_gone.tga";
						}
							
						if (!icon.empty() )
						{	
							element["columns"][LIST_SIM].erase("color");
							element["columns"][LIST_SIM]["type"] = "icon";
							element["columns"][LIST_SIM]["value"] = icon;
						}

						icon = "";

						if(!entry->has_info)
						{
							if(entry->info_requested())
							{
								if(entry->request_timeout < 256.0f) icon = "info_fetching.tga";
								else icon = "info_error.tga";
							}else icon = "info_unknown.tga";
						}else
						{
							switch(entry->agent_info.payment)
							{
							case PAYMENT_NONE:
								break;
							case PAYMENT_ON_FILE:
								icon = "payment_info_filled.tga";
								break;
							case PAYMENT_USED:
								icon = "payment_info_used.tga";
								break;
							case PAYMENT_LINDEN:
								// confusingly named icon, maybe use something else
								icon = "icon_top_pick.tga";
								break;
							}
						}
						element["columns"][LIST_PAYMENT]["column"] = "payment_data";
						element["columns"][LIST_PAYMENT]["type"] = "text";
						if ( !icon.empty() )
						{
							element["columns"][LIST_PAYMENT]["type"] = "icon";
							element["columns"][LIST_PAYMENT]["value"] =  icon;
						}

						S32 seentime = (S32)entry->lifetime.getElapsedTimeF32();
						S32 hours = (S32)(seentime / (60*60));
						S32 mins = (S32)((seentime - hours*(60*60)) / 60);
						S32 secs = (S32)((seentime - hours*(60*60) - mins*60));

						element["columns"][LIST_TIME]["column"] = "time";
						element["columns"][LIST_TIME]["type"] = "text";
						element["columns"][LIST_TIME]["color"] = gColors.getColor("DefaultListText").getValue();
						element["columns"][LIST_TIME]["value"] = llformat("%d:%02d:%02d", hours,mins,secs);




						element["columns"][LIST_CLIENT]["column"] = "client";
						element["columns"][LIST_CLIENT]["type"] = "text";

						static LLColor4U *sAvatarNameColor = rebind_llcontrol<LLColor4U>("AvatarNameColor",&gColors,true);
						static LLColor4U *sScrollUnselectedColor = rebind_llcontrol<LLColor4U>("ScrollUnselectedColor",&gColors,true);

						LLColor4 avatar_name_color = LLColor4(*sAvatarNameColor);
						std::string client;
						LLVOAvatar *av = (LLVOAvatar*)gObjectList.findObject(av_id);
						if(av)
						{
							LLVOAvatar::resolveClient(avatar_name_color, client, av);
							if(client == "")
							{
								avatar_name_color = LLColor4(*sScrollUnselectedColor);
								client = "?";
							}
							element["columns"][LIST_CLIENT]["value"] = client.c_str();
						}
						else
						{
							element["columns"][LIST_CLIENT]["value"] = "Out Of Range";
							avatar_name_color = LLColor4(*sScrollUnselectedColor);
						}

						avatar_name_color = (avatar_name_color * 0.5) + (LLColor4(*sScrollUnselectedColor) * 0.5);

						element["columns"][LIST_CLIENT]["color"] = avatar_name_color.getValue();

						mAvatarList->addElement(element, ADD_BOTTOM);
					}
				}
				mAvatarList->sortItems();
				mAvatarList->selectMultiple(selected);
				mAvatarList->setScrollPos(scrollpos);
			}
			//END DRAW//
		}
	}

	if( mTracking && LLTracker::getTrackedPositionGlobal().isExactlyZero() )
	{
		// trying to track an avatar, but tracker stopped tracking		
		if ( mAvatars.find(mTrackedAvatar) != mAvatars.end() && !mTrackByLocation)
		{
			mTrackByLocation = TRUE;
		}
		else
		{
			LLTracker::stopTracking(NULL);
			mTracking = FALSE;
		}
	}

	if ( mTracking && mTrackByLocation)
	{
		std::string name = mAvatars[mTrackedAvatar].name;
		std::string tooltip = "Tracking last known position";
		name += " (near)";
		LLTracker::trackLocation(mAvatars[mTrackedAvatar].position,name, tooltip);
	}

	return FALSE;
}
void LLFloaterAvatarList::updateAvatarList()
{
	//llinfos << "radar refresh: updating map" << llendl;

	// Check whether updates are enabled
	LLCheckboxCtrl* check = getChild<LLCheckboxCtrl>("update_enabled_cb");
	if (check && !check->getValue())
	{
		mUpdate = FALSE;
		refreshTracker();
		return;
	}
	else
	{
		mUpdate = TRUE;
	}
	//moved to pipeline to prevent a crash
	//gPipeline.forAllVisibleDrawables(updateParticleActivity);


	//todo: make this less of a hacked up copypasta from dales 1.18.
	if(gAudiop != NULL)
	{
		LLAudioEngine::source_map::iterator iter;
		for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter)
		{
			LLAudioSource *sourcep = iter->second;
			LLUUID uuid = sourcep->getOwnerID();
			LLAvatarListEntry *ent = getAvatarEntry(uuid);
			if ( ent )
			{
				ent->setActivity(LLAvatarListEntry::ACTIVITY_SOUND);
			}
		}
	}

	LLVector3d mypos = gAgent.getPositionGlobal();

	{
		std::vector<LLUUID> avatar_ids;
		std::vector<LLUUID> sorted_avatar_ids;
		std::vector<LLVector3d> positions;

		LLWorld::instance().getAvatars(&avatar_ids, &positions, mypos, F32_MAX);

		sorted_avatar_ids = avatar_ids;
		std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end());

		BOOST_FOREACH(std::vector<LLCharacter*>::value_type& iter, LLCharacter::sInstances)
		{
			LLUUID avid = iter->getID();

			if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid))
			{
				avatar_ids.push_back(avid);
			}
		}

		size_t i;
		size_t count = avatar_ids.size();

		static LLCachedControl<bool> announce(gSavedSettings, "RadarChatKeys");
		std::queue<LLUUID> announce_keys;

		for (i = 0; i < count; ++i)
		{
			std::string name;
			const LLUUID &avid = avatar_ids[i];

			LLVector3d position;
			LLVOAvatar* avatarp = gObjectList.findAvatar(avid);

			if (avatarp)
			{
				// Skip if avatar is dead(what's that?)
				// or if the avatar is ourselves.
				// or if the avatar is a dummy
				if (avatarp->isDead() || avatarp->isSelf() || avatarp->mIsDummy)
				{
					continue;
				}

				// Get avatar data
				position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition());
				name = avatarp->getFullname();

				if (!LLAvatarNameCache::getPNSName(avatarp->getID(), name))
					continue;

				//duped for lower section
				if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0))
				{
					if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::getPNSName above...
					{
						continue;
					}
				}

				if (avid.isNull())
				{
					//llinfos << "Key empty for avatar " << name << llendl;
					continue;
				}

				LLAvatarListEntry* entry = getAvatarEntry(avid);
				if (entry)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					entry->setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0);
					if(avatarp->isTyping())entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING);
				}
				else
				{
					// Avatar not there yet, add it
					if(announce && avatarp->getRegion() == gAgent.getRegion())
						announce_keys.push(avid);
					mAvatars.push_back(LLAvatarListEntryPtr(new LLAvatarListEntry(avid, name, position)));
				}
			}
			else
			{
				if (i < positions.size())
				{
					position = positions[i];
				}
				else
				{
					continue;
				}

				if (!LLAvatarNameCache::getPNSName(avid, name))
				{
					//name = gCacheName->getDefaultName();
					continue; //prevent (Loading...)
				}

				LLAvatarListEntry* entry = getAvatarEntry(avid);
				if (entry)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0);
				}
				else
				{
					if(announce && gAgent.getRegion()->pointInRegionGlobal(position))
						announce_keys.push(avid);
					mAvatars.push_back(LLAvatarListEntryPtr(new LLAvatarListEntry(avid, name, position)));
				}
			}
		}
		//let us send the keys in a more timely fashion
		if (announce && !announce_keys.empty())
		{
			// NOTE: This fragment is repeated in sendKey
			std::ostringstream ids;
			int transact_num = (int)gFrameCount;
			int num_ids = 0;
			while(!announce_keys.empty())
			{
				LLUUID id = announce_keys.front();
				announce_keys.pop();

				ids << "," << id.asString();
				++num_ids;

				if (ids.tellp() > 200)
				{
					send_keys_message(transact_num, num_ids, ids.str());

					num_ids = 0;
					ids.seekp(0);
					ids.str("");
				}
			}
			if (num_ids > 0)
				send_keys_message(transact_num, num_ids, ids.str());
		}
	}
Example #6
0
LLPanelDebug::LLPanelDebug(const std::string& name, const LLRect& rect)
:	LLPanel(name, rect)
{
	LLCheckboxCtrl* check = NULL;
	LLSliderCtrl *sliderctrl = NULL;

	const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );

	const S32 HPAD = 10;
	const S32 VPAD = 4;

	const S32 TOP_PAD = 10;

	// alignment "rulers" for buttons
	const S32 SEGMENT_WIDTH = 128;
	const S32 LEFT = HPAD;
	const S32 RULER1 = LEFT + SEGMENT_WIDTH + 30;
	const S32 RULER2 = RULER1 + HPAD;
	const S32 RIGHT = RULER2 + SEGMENT_WIDTH;
	const S32 LABEL_OFFSET = 60;

	S32 cur_y = rect.getHeight() - TOP_PAD;

	sliderctrl = new LLSliderCtrl(std::string("Drop Shadow Floater"),
								  LLRect( LEFT, cur_y, RIGHT, cur_y - SLIDERCTRL_HEIGHT ),
								  std::string("Drop Shadow Floater"),
								  font,
								  LABEL_OFFSET,
								  RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH,
								  TRUE,
								  TRUE,
								  FALSE,
								  NULL, NULL,
								  (F32)gSavedSettings.getS32("DropShadowFloater"), 
								  0.f, 10.f, 1.0f, 
								  std::string("DropShadowFloater"));
	sliderctrl->setFollowsTop();
	sliderctrl->setFollowsLeft();
	addChild(sliderctrl);
	cur_y -= VPAD + SLIDERCTRL_HEIGHT;

	sliderctrl = new LLSliderCtrl(std::string("Drop Shadow Button"),
								  LLRect( LEFT, cur_y, RIGHT, cur_y - SLIDERCTRL_HEIGHT ),
								  std::string("Drop Shadow Button"),
								  font,
								  LABEL_OFFSET,
								  RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH,
								  TRUE,
								  TRUE,
								  FALSE,
								  NULL, NULL,
								  (F32)gSavedSettings.getS32("DropShadowButton"), 
								  0.f, 10.f, 1.0f, 
								  std::string("DropShadowButton"));
	sliderctrl->setFollowsTop();
	sliderctrl->setFollowsLeft();
	addChild(sliderctrl);
	cur_y -= VPAD + SLIDERCTRL_HEIGHT;

	check = new LLCheckboxCtrl(std::string("left click"),
							   LLRect(LEFT, cur_y, RIGHT, cur_y - 20),
							   std::string("Left Click Shows Menu Unless Interactive"),
							   font,
							   NULL, NULL,
							   gSavedSettings.getBOOL("LeftClickShowMenu"));
	check->setFollows(FOLLOWS_LEFT|FOLLOWS_TOP);
	addChild(check);
	mLeftClickCheck = check;
	cur_y -= VPAD+20;
}
Example #7
0
void LLFloaterAvatarList::updateAvatarList()
{
	if (sInstance != this) return;
	
	#ifdef LL_RRINTERFACE_H //MK
	if (gRRenabled && gAgent.mRRInterface.mContainsShownames)
	{
		close();
	}
#endif //mk

	//llinfos << "radar refresh: updating map" << llendl;

	// Check whether updates are enabled
	LLCheckboxCtrl* check = getChild<LLCheckboxCtrl>("update_enabled_cb");
	if (check && !check->getValue())
	{
		mUpdate = FALSE;
		refreshTracker();
		return;
	}
	else
	{
		mUpdate = TRUE;
	}

	LLVector3d mypos = gAgent.getPositionGlobal();

	{
		std::vector<LLUUID> avatar_ids;
		std::vector<LLUUID> sorted_avatar_ids;
		std::vector<LLVector3d> positions;

		LLWorld::instance().getAvatars(&avatar_ids, &positions, mypos, F32_MAX);

		sorted_avatar_ids = avatar_ids;
		std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end());

		for (std::vector<LLCharacter*>::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter)
		{
			LLUUID avid = (*iter)->getID();

			if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid))
			{
				avatar_ids.push_back(avid);
			}
		}

		size_t i;
		size_t count = avatar_ids.size();
		
		bool announce = gSavedSettings.getBOOL("RadarChatKeys");
		std::queue<LLUUID> announce_keys;

		for (i = 0; i < count; ++i)
		{
			std::string name, first, last;
			const LLUUID &avid = avatar_ids[i];

			LLVector3d position;
			LLViewerObject *obj = gObjectList.findObject(avid);

			if (obj)
			{
				LLVOAvatar* avatarp = dynamic_cast<LLVOAvatar*>(obj);

				if (avatarp == NULL)
				{
					continue;
				}

				// Skip if avatar is dead(what's that?)
				// or if the avatar is ourselves.
				// or if the avatar is a dummy
				if (avatarp->isDead() || avatarp->isSelf() || avatarp->mIsDummy)
				{
					continue;
				}

				// Get avatar data
				position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition());
				name = avatarp->getFullname();

				// Apparently, sometimes the name comes out empty, with a " " name. This is because
				// getFullname concatenates first and last name with a " " in the middle.
				// This code will avoid adding a nameless entry to the list until it acquires a name.

				//duped for lower section
				if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0))
				{
					if (gCacheName->getName(avid, first, last))
					{
						name = first + " " + last;
					}
					else
					{
						continue;
					}
				}
ifdef LL_DISPLAY_NAMES
				std::string display_name = name;
				if (LLAvatarNameCache::useDisplayNames())
				{
					LLAvatarName avatar_name;
					if (LLAvatarNameCache::get(avid, &avatar_name))
					{
						if (LLAvatarNameCache::useDisplayNames() == 2)
						{
							display_name = avatar_name.mDisplayName;
						}
						else
						{
							display_name = avatar_name.getNames();
						}
					}
				}
#endif

				if (avid.isNull())
				{
					//llinfos << "Key empty for avatar " << name << llendl;
					continue;
				}

				if (mAvatars.count(avid) > 0)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					mAvatars[avid].setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0);
				}
				else
				{
					// Avatar not there yet, add it
					LLAvatarListEntry entry(avid, name, position);
					if(announce && avatarp->getRegion() == gAgent.getRegion())
						announce_keys.push(avid);
					mAvatars[avid] = entry;
				}
				
#ifdef LL_DISPLAY_NAMES
				// update avatar display name.
				mAvatars[avid].setDisplayName(display_name);
#endif
			}
			else
			{
				if (i < positions.size())
				{
					position = positions[i];
				}
				else
				{
					continue;
				}

				if (gCacheName->getName(avid, first, last))
				{
					name = first + " " + last;
				}
				else
				{
					//name = gCacheName->getDefaultName();
					continue; //prevent (Loading...)
				}
#ifdef LL_DISPLAY_NAMES
				std::string display_name = name;
				if (LLAvatarNameCache::useDisplayNames())
				{
					LLAvatarName avatar_name;
					if (LLAvatarNameCache::get(avid, &avatar_name))
					{
						if (LLAvatarNameCache::useDisplayNames() == 2)
						{
							display_name = avatar_name.mDisplayName;
						}
						else
						{
							display_name = avatar_name.getNames();
						}
					}
				}
#endif

				if (mAvatars.count(avid) > 0)
				{
					// Avatar already in list, update position
					F32 dist = (F32)(position - mypos).magVec();
					mAvatars[avid].setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0);
				}
				else
				{
					LLAvatarListEntry entry(avid, name, position);
					if(announce && gAgent.getRegion()->pointInRegionGlobal(position))
						announce_keys.push(avid);
					mAvatars[avid] = entry;
				}
				
#ifdef LL_DISPLAY_NAMES
				// update avatar display name.
				mAvatars[avid].setDisplayName(display_name);
#endif
			}
		}
		//let us send the keys in a more timely fashion
		if(announce && !announce_keys.empty())
                {
			std::ostringstream ids;
			int transact_num = (int)gFrameCount;
			int num_ids = 0;
			while(!announce_keys.empty())
			{
				LLUUID id = announce_keys.front();
				announce_keys.pop();

				ids << "," << id.asString();
				++num_ids;

				if(ids.tellp() > 200)
				{
				        gMessageSystem->newMessage("ScriptDialogReply");
				        gMessageSystem->nextBlock("AgentData");
				        gMessageSystem->addUUID("AgentID", gAgent.getID());
				        gMessageSystem->addUUID("SessionID", gAgent.getSessionID());
				        gMessageSystem->nextBlock("Data");
				        gMessageSystem->addUUID("ObjectID", gAgent.getID());
				        gMessageSystem->addS32("ChatChannel", -777777777);
				        gMessageSystem->addS32("ButtonIndex", 1);
				        gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str());
				        gAgent.sendReliableMessage();

				        num_ids = 0;
				        ids.seekp(0);
				        ids.str("");
				}
			}
			if(num_ids > 0)
			{
				gMessageSystem->newMessage("ScriptDialogReply");
				gMessageSystem->nextBlock("AgentData");
				gMessageSystem->addUUID("AgentID", gAgent.getID());
				gMessageSystem->addUUID("SessionID", gAgent.getSessionID());
				gMessageSystem->nextBlock("Data");
				gMessageSystem->addUUID("ObjectID", gAgent.getID());
				gMessageSystem->addS32("ChatChannel", -777777777);
				gMessageSystem->addS32("ButtonIndex", 1);
				gMessageSystem->addString("ButtonLabel",llformat("%d,%d", transact_num, num_ids) + ids.str());
				gAgent.sendReliableMessage();
			}
                }
	}
	
//	llinfos << "radar refresh: done" << llendl;

	expireAvatarList();
	refreshAvatarList();
	refreshTracker();
}