diff options
Diffstat (limited to 'linden/indra/newview/panelradar.cpp')
-rw-r--r-- | linden/indra/newview/panelradar.cpp | 968 |
1 files changed, 968 insertions, 0 deletions
diff --git a/linden/indra/newview/panelradar.cpp b/linden/indra/newview/panelradar.cpp new file mode 100644 index 0000000..487767d --- /dev/null +++ b/linden/indra/newview/panelradar.cpp | |||
@@ -0,0 +1,968 @@ | |||
1 | /** | ||
2 | * @file panelradar.cpp | ||
3 | * @brief PanelRadar class (list of nearby agents) | ||
4 | * | ||
5 | * Copyright (c) 2009, McCabe Maxsted, Jacek Antonelli, Dale Glass | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided to you | ||
8 | * under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in | ||
10 | * this distribution, or online at | ||
11 | * http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
12 | * | ||
13 | * There are special exceptions to the terms and conditions of the GPL as | ||
14 | * it is applied to this Source Code. View the full text of the exception | ||
15 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
16 | * online at | ||
17 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "panelradar.h" | ||
31 | |||
32 | #include "llagent.h" | ||
33 | #include "llchat.h" | ||
34 | #include "llfloateravatarinfo.h" | ||
35 | #include "llfloaterchat.h" | ||
36 | #include "llfloaterfriends.h" | ||
37 | #include "llfloatergroupinvite.h" | ||
38 | #include "llfloatergroups.h" | ||
39 | #include "llfloaterreporter.h" | ||
40 | #include "llimview.h" | ||
41 | #include "llmutelist.h" | ||
42 | #include "llparcel.h" | ||
43 | #include "llregionposition.h" | ||
44 | #include "roles_constants.h" | ||
45 | #include "llscrolllistctrl.h" | ||
46 | #include "lltracker.h" | ||
47 | #include "lluictrlfactory.h" | ||
48 | #include "llviewerobjectlist.h" | ||
49 | #include "llviewermenu.h" | ||
50 | #include "llviewermessage.h" | ||
51 | #include "llviewerparcelmgr.h" | ||
52 | #include "llviewerregion.h" | ||
53 | #include "llviewerwindow.h" | ||
54 | #include "llvoavatar.h" | ||
55 | #include "llworld.h" | ||
56 | |||
57 | |||
58 | PanelRadar::PanelRadar() | ||
59 | : | ||
60 | LLPanel(), | ||
61 | mSelectedAvatar(LLUUID::null) | ||
62 | { | ||
63 | LLUICtrlFactory::getInstance()->buildPanel(this, "panel_radar.xml"); | ||
64 | |||
65 | mChatAvatars.clear(); | ||
66 | mTypingAvatars.clear(); | ||
67 | } | ||
68 | |||
69 | |||
70 | BOOL PanelRadar::postBuild() | ||
71 | { | ||
72 | mRadarList = getChild<LLScrollListCtrl>("RadarList"); | ||
73 | childSetCommitCallback("RadarList", onList, this); | ||
74 | mRadarList->setDoubleClickCallback(onClickIM); | ||
75 | |||
76 | childSetFocusChangedCallback("near_me_range", onRangeChange, this); | ||
77 | |||
78 | childSetAction("im_btn", onClickIM, this); | ||
79 | childSetAction("profile_btn", onClickProfile, this); | ||
80 | childSetAction("offer_teleport_btn", onClickOfferTeleport, this); | ||
81 | childSetAction("track_btn", onClickTrack, this); | ||
82 | childSetAction("invite_btn", onClickInvite, this); | ||
83 | childSetAction("add_btn", onClickAddFriend, this); | ||
84 | childSetAction("freeze_btn", onClickFreeze, this); | ||
85 | childSetAction("eject_btn", onClickEject, this); | ||
86 | childSetAction("mute_btn", onClickMute, this); | ||
87 | childSetAction("unmute_btn", onClickUnmute, this); | ||
88 | childSetAction("ar_btn", onClickAR, this); | ||
89 | childSetAction("estate_eject_btn", onClickEjectFromEstate, this); | ||
90 | |||
91 | setDefaultBtn("im_btn"); | ||
92 | |||
93 | populateRadar(); | ||
94 | |||
95 | return TRUE; | ||
96 | } | ||
97 | |||
98 | |||
99 | PanelRadar::~PanelRadar() | ||
100 | { | ||
101 | } | ||
102 | |||
103 | |||
104 | //static | ||
105 | bool PanelRadar::isImpDev(LLUUID agent_id) | ||
106 | { | ||
107 | // We use strings here as avatar keys change across grids. | ||
108 | // Feel free to add/remove yourself. | ||
109 | std::string agent_name = getSelectedName(agent_id); | ||
110 | if (agent_name == "McCabe Maxsted" || | ||
111 | agent_name == "Jacek Antonelli" || | ||
112 | agent_name == "Armin Weatherwax") | ||
113 | { | ||
114 | return true; | ||
115 | } | ||
116 | return false; | ||
117 | } | ||
118 | |||
119 | |||
120 | void PanelRadar::populateRadar() | ||
121 | { | ||
122 | if (!mUpdate || !getVisible()) | ||
123 | { | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | if (visibleItemsSelected()) | ||
128 | { | ||
129 | mSelectedAvatar = mRadarList->getFirstSelected()->getUUID(); | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | mSelectedAvatar.setNull(); | ||
134 | } | ||
135 | |||
136 | S32 scroll_pos = mRadarList->getScrollPos(); | ||
137 | |||
138 | // clear count | ||
139 | std::stringstream avatar_count; | ||
140 | avatar_count.str(""); | ||
141 | |||
142 | // find what avatars you can see | ||
143 | F32 range = gSavedSettings.getF32("NearMeRange"); | ||
144 | LLVector3d current_pos = gAgent.getPositionGlobal(); | ||
145 | std::vector<LLUUID> avatar_ids; | ||
146 | std::vector<LLVector3d> positions; | ||
147 | LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); | ||
148 | |||
149 | LLSD element; | ||
150 | |||
151 | mRadarList->deleteAllItems(); | ||
152 | |||
153 | if (!avatar_ids.empty()) | ||
154 | { | ||
155 | for (U32 i=0; i<avatar_ids.size(); i++) | ||
156 | { | ||
157 | if (avatar_ids[i] == gAgent.getID() || | ||
158 | avatar_ids[i].isNull()) | ||
159 | { | ||
160 | continue; | ||
161 | } | ||
162 | |||
163 | // Add to list only if we get their name | ||
164 | std::string fullname = getSelectedName(avatar_ids[i]); | ||
165 | if (!fullname.empty()) | ||
166 | { | ||
167 | bool notify_chat = gSavedSettings.getBOOL("MiniMapNotifyChatRange"); | ||
168 | bool notify_sim = gSavedSettings.getBOOL("MiniMapNotifySimRange"); | ||
169 | // [RLVa:KB] - Alternate: Imprudence-1.2.0 | ||
170 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
171 | { | ||
172 | fullname = gRlvHandler.getAnonym(fullname); | ||
173 | notify_chat = false; | ||
174 | notify_sim = false; | ||
175 | } | ||
176 | // [/RLVa:KB] | ||
177 | |||
178 | // check if they're in certain ranges and notify user if we've enabled that | ||
179 | LLVector3d temp = positions[i]; | ||
180 | if (positions[i].mdV[VZ] == 0.0f) // LL only sends height value up to 1024m, try to work around it | ||
181 | { | ||
182 | LLViewerObject *av_obj = gObjectList.findObject(avatar_ids[i]); | ||
183 | if (av_obj != NULL && av_obj->isAvatar()) | ||
184 | { | ||
185 | LLVOAvatar* avatarp = (LLVOAvatar*)av_obj; | ||
186 | if (avatarp != NULL) | ||
187 | { | ||
188 | temp = avatarp->getPositionGlobal(); | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | F64 distance = dist_vec(temp, current_pos); | ||
193 | // we round for accuracy when avs tp in | ||
194 | std::string dist_string = llformat("%.1f", llround((F32)distance, 0.1f)); | ||
195 | |||
196 | /*llinfos << "Avatar :" << fullname << " Position: " << positions[i] << " Your Position: " | ||
197 | << current_pos << " Distance: " << distance << llendl;*/ | ||
198 | |||
199 | if (notify_chat) | ||
200 | { | ||
201 | if (distance < 20.0f) | ||
202 | { | ||
203 | if (!isInChatList(avatar_ids[i])) | ||
204 | { | ||
205 | addToChatList(avatar_ids[i], dist_string); | ||
206 | } | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | if (isInChatList(avatar_ids[i])) | ||
211 | { | ||
212 | removeFromChatList(avatar_ids[i]); | ||
213 | } | ||
214 | } | ||
215 | updateChatList(avatar_ids); | ||
216 | } | ||
217 | else if (!mChatAvatars.empty()) | ||
218 | { | ||
219 | mChatAvatars.clear(); | ||
220 | } | ||
221 | |||
222 | if (notify_sim) | ||
223 | { | ||
224 | if (!isInChatList(avatar_ids[i]) && !getInSimAvList(avatar_ids[i])) | ||
225 | { | ||
226 | LLViewerObject *av_obj = gObjectList.findObject(avatar_ids[i]); | ||
227 | if (av_obj != NULL && av_obj->isAvatar()) | ||
228 | { | ||
229 | LLVOAvatar* avatarp = (LLVOAvatar*)av_obj; | ||
230 | if (avatarp != NULL) | ||
231 | { | ||
232 | if (avatarp->getRegion() == gAgent.getRegion()) | ||
233 | { | ||
234 | addToSimAvList(avatar_ids[i], dist_string); | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | updateSimAvList(avatar_ids); | ||
240 | } | ||
241 | else if (!mSimAvatars.empty()) | ||
242 | { | ||
243 | mSimAvatars.clear(); | ||
244 | } | ||
245 | |||
246 | // only display avatars in range | ||
247 | if (distance <= range) | ||
248 | { | ||
249 | // append typing string | ||
250 | std::string typing = ""; | ||
251 | if (isTyping(avatar_ids[i])) | ||
252 | { | ||
253 | typing = getString("is_typing")+ " "; | ||
254 | } | ||
255 | |||
256 | std::string mute_text = LLMuteList::getInstance()->isMuted(avatar_ids[i]) ? getString("is_muted") : ""; | ||
257 | element["id"] = avatar_ids[i]; | ||
258 | element["columns"][0]["column"] = "avatar_name"; | ||
259 | element["columns"][0]["type"] = "text"; | ||
260 | element["columns"][0]["value"] = typing + fullname + " " + mute_text; | ||
261 | element["columns"][1]["column"] = "avatar_distance"; | ||
262 | element["columns"][1]["type"] = "text"; | ||
263 | element["columns"][1]["value"] = dist_string+"m"; | ||
264 | |||
265 | mRadarList->addElement(element, ADD_BOTTOM); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | |||
270 | mRadarList->sortItems(); | ||
271 | mRadarList->setScrollPos(scroll_pos); | ||
272 | if (mSelectedAvatar.notNull()) | ||
273 | { | ||
274 | mRadarList->selectByID(mSelectedAvatar); | ||
275 | } | ||
276 | avatar_count << (int)avatar_ids.size(); | ||
277 | } | ||
278 | else | ||
279 | { | ||
280 | mTypingAvatars.clear(); | ||
281 | mRadarList->addCommentText(getString("no_one_near"), ADD_TOP); | ||
282 | avatar_count << "0"; | ||
283 | } | ||
284 | |||
285 | childSetText("lblAvatarCount", avatar_count.str()); | ||
286 | |||
287 | toggleButtons(); | ||
288 | |||
289 | //llinfos << "mSelectedAvatar: " << mSelectedAvatar.asString() << llendl; | ||
290 | } | ||
291 | |||
292 | |||
293 | void PanelRadar::updateChatList(std::vector<LLUUID> agent_ids) | ||
294 | { | ||
295 | std::set<LLUUID>::iterator it; | ||
296 | std::vector<LLUUID>::iterator result; | ||
297 | for (it = mChatAvatars.begin(); it != mChatAvatars.end(); ) | ||
298 | { | ||
299 | result = find(agent_ids.begin(), agent_ids.end(), *it); | ||
300 | if (result == agent_ids.end()) | ||
301 | { | ||
302 | mChatAvatars.erase(it++); | ||
303 | } | ||
304 | else | ||
305 | { | ||
306 | it++; | ||
307 | } | ||
308 | } | ||
309 | } | ||
310 | |||
311 | |||
312 | bool PanelRadar::isInChatList(LLUUID agent_id) | ||
313 | { | ||
314 | if (mChatAvatars.count(agent_id) > 0) | ||
315 | { | ||
316 | return true; | ||
317 | } | ||
318 | return false; | ||
319 | } | ||
320 | |||
321 | |||
322 | void PanelRadar::addToChatList(LLUUID agent_id, std::string distance) | ||
323 | { | ||
324 | mChatAvatars.insert(agent_id); | ||
325 | LLChat chat; | ||
326 | |||
327 | LLUIString notify = getString("entering_chat_range"); | ||
328 | notify.setArg("[NAME]", getSelectedName(agent_id)); | ||
329 | notify.setArg("[DISTANCE]", distance); | ||
330 | |||
331 | chat.mText = notify; | ||
332 | chat.mSourceType = CHAT_SOURCE_SYSTEM; | ||
333 | LLFloaterChat::addChat(chat, FALSE, FALSE); | ||
334 | } | ||
335 | |||
336 | |||
337 | void PanelRadar::removeFromChatList(LLUUID agent_id) | ||
338 | { | ||
339 | // Do we want to add a notice? | ||
340 | mChatAvatars.erase(agent_id); | ||
341 | } | ||
342 | |||
343 | |||
344 | bool PanelRadar::isTyping(LLUUID agent_id) | ||
345 | { | ||
346 | if (mTypingAvatars.count(agent_id) > 0) | ||
347 | { | ||
348 | return true; | ||
349 | } | ||
350 | return false; | ||
351 | } | ||
352 | |||
353 | |||
354 | void PanelRadar::updateTypingList(LLUUID agent_id, bool remove) | ||
355 | { | ||
356 | if (remove) | ||
357 | { | ||
358 | if (isTyping(agent_id)) | ||
359 | { | ||
360 | mTypingAvatars.erase(agent_id); | ||
361 | } | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | mTypingAvatars.insert(agent_id); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | |||
370 | void PanelRadar::updateSimAvList(std::vector<LLUUID> agent_ids) | ||
371 | { | ||
372 | std::set<LLUUID>::iterator it; | ||
373 | std::vector<LLUUID>::iterator result; | ||
374 | for (it = mSimAvatars.begin(); it != mSimAvatars.end(); ) | ||
375 | { | ||
376 | result = find(agent_ids.begin(), agent_ids.end(), *it); | ||
377 | if (result == agent_ids.end()) | ||
378 | { | ||
379 | mSimAvatars.erase(it++); | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | it++; | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | |||
388 | |||
389 | void PanelRadar::addToSimAvList(LLUUID agent_id, std::string distance) | ||
390 | { | ||
391 | mSimAvatars.insert(agent_id); | ||
392 | LLChat chat; | ||
393 | |||
394 | LLUIString notify = getString("entering_sim_range"); | ||
395 | notify.setArg("[NAME]", getSelectedName(agent_id)); | ||
396 | notify.setArg("[DISTANCE]", distance); | ||
397 | |||
398 | chat.mText = notify; | ||
399 | chat.mSourceType = CHAT_SOURCE_SYSTEM; | ||
400 | LLFloaterChat::addChat(chat, FALSE, FALSE); | ||
401 | } | ||
402 | |||
403 | |||
404 | bool PanelRadar::getInSimAvList(LLUUID agent_id) | ||
405 | { | ||
406 | if (mSimAvatars.count(agent_id) > 0) | ||
407 | { | ||
408 | return true; | ||
409 | } | ||
410 | return false; | ||
411 | } | ||
412 | |||
413 | |||
414 | void PanelRadar::toggleButtons() | ||
415 | { | ||
416 | BOOL enable = FALSE; | ||
417 | BOOL enable_unmute = FALSE; | ||
418 | BOOL enable_track = FALSE; | ||
419 | BOOL enable_estate = FALSE; | ||
420 | BOOL enable_friend = FALSE; | ||
421 | if (childHasFocus("RadarPanel")) | ||
422 | { | ||
423 | enable = mSelectedAvatar.notNull() ? visibleItemsSelected() : FALSE; | ||
424 | enable_unmute = mSelectedAvatar.notNull() ? LLMuteList::getInstance()->isMuted(mSelectedAvatar) : FALSE; | ||
425 | enable_track = gAgent.isGodlike() || is_agent_mappable(mSelectedAvatar); | ||
426 | enable_estate = isKickable(mSelectedAvatar); | ||
427 | enable_friend = !is_agent_friend(mSelectedAvatar); | ||
428 | } | ||
429 | else | ||
430 | { | ||
431 | mRadarList->deselect(); | ||
432 | } | ||
433 | |||
434 | childSetEnabled("im_btn", enable); | ||
435 | childSetEnabled("profile_btn", enable); | ||
436 | childSetEnabled("offer_teleport_btn", enable); | ||
437 | childSetEnabled("track_btn", enable_track); | ||
438 | childSetEnabled("invite_btn", enable); | ||
439 | childSetEnabled("add_btn", enable); | ||
440 | childSetEnabled("freeze_btn", enable_estate); | ||
441 | childSetEnabled("eject_btn", enable_estate); | ||
442 | childSetEnabled("mute_btn", enable); | ||
443 | childSetEnabled("ar_btn", enable); | ||
444 | childSetEnabled("estate_eject_btn", enable_estate); | ||
445 | |||
446 | if (enable_unmute) | ||
447 | { | ||
448 | childSetVisible("mute_btn", false); | ||
449 | childSetEnabled("unmute_btn", true); | ||
450 | childSetVisible("unmute_btn", true); | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | childSetVisible("mute_btn", true); | ||
455 | childSetVisible("unmute_btn", false); | ||
456 | } | ||
457 | |||
458 | // [RLVa:KB] - Imprudence-1.2.0 | ||
459 | // Bit clumsy, but this way the RLV stuff is in its own separate | ||
460 | // block and keeps the code above clean - Kitty | ||
461 | if ( (rlv_handler_t::isEnabled()) && (mSelectedAvatar.notNull()) ) | ||
462 | { | ||
463 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
464 | { | ||
465 | childSetEnabled("im_btn", FALSE); | ||
466 | childSetEnabled("profile_btn", FALSE); | ||
467 | childSetEnabled("invite_btn", FALSE); | ||
468 | childSetEnabled("add_btn", FALSE); | ||
469 | childSetEnabled("mute_btn", FALSE); | ||
470 | childSetEnabled("unmute_btn", FALSE); | ||
471 | } | ||
472 | |||
473 | // Even though the avie is in the same sim (so they already know | ||
474 | // where we are) the tp would just get blocked by different code | ||
475 | // so it's actually less confusing to the user if we just disable | ||
476 | // the teleport button here so they'll at least have a visual cue | ||
477 | BOOL rlv_enable_tp = (!gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) || (gRlvHandler.isException(RLV_BHVR_TPLURE, mSelectedAvatar)); | ||
478 | if ( (rlv_enable_tp) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
479 | { | ||
480 | const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(mSelectedAvatar); | ||
481 | if ( ((!pBuddyInfo) || (!pBuddyInfo->isOnline()) || (!pBuddyInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))) ) | ||
482 | rlv_enable_tp = FALSE; | ||
483 | } | ||
484 | childSetEnabled("offer_teleport_btn", rlv_enable_tp); | ||
485 | } | ||
486 | // [/RLVa:KB] | ||
487 | } | ||
488 | |||
489 | |||
490 | BOOL PanelRadar::isKickable(const LLUUID &agent_id) | ||
491 | { | ||
492 | if (agent_id.notNull()) | ||
493 | { | ||
494 | LLViewerObject* av_obj = gObjectList.findObject(agent_id); | ||
495 | if (av_obj != NULL && av_obj->isAvatar()) | ||
496 | { | ||
497 | LLVOAvatar* avatar = (LLVOAvatar*)av_obj; | ||
498 | LLViewerRegion* region = avatar->getRegion(); | ||
499 | if (region) | ||
500 | { | ||
501 | const LLVector3& pos = avatar->getPositionRegion(); | ||
502 | const LLVector3d& pos_global = avatar->getPositionGlobal(); | ||
503 | if (LLWorld::getInstance()->positionRegionValidGlobal(pos_global)) | ||
504 | { | ||
505 | LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel(); | ||
506 | LLViewerParcelMgr::getInstance()->deselectLand(); | ||
507 | |||
508 | BOOL new_value = (region != NULL); | ||
509 | |||
510 | if (new_value) | ||
511 | { | ||
512 | new_value = region->isOwnedSelf(pos); | ||
513 | if (!new_value || region->isOwnedGroup(pos)) | ||
514 | { | ||
515 | new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN); | ||
516 | } | ||
517 | } | ||
518 | return new_value; | ||
519 | } | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | return FALSE; | ||
524 | } | ||
525 | |||
526 | |||
527 | // static | ||
528 | void PanelRadar::onList(LLUICtrl* ctrl, void* user_data) | ||
529 | { | ||
530 | PanelRadar* self = (PanelRadar*)user_data; | ||
531 | if (self) | ||
532 | { | ||
533 | self->toggleButtons(); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | |||
538 | BOOL PanelRadar::visibleItemsSelected() const | ||
539 | { | ||
540 | if (mRadarList->getFirstSelectedIndex() >= 0) | ||
541 | { | ||
542 | return TRUE; | ||
543 | } | ||
544 | return FALSE; | ||
545 | } | ||
546 | |||
547 | |||
548 | // static | ||
549 | void PanelRadar::onRangeChange(LLFocusableElement* focus, void* user_data) | ||
550 | { | ||
551 | PanelRadar* self = (PanelRadar*)user_data; | ||
552 | if (self) | ||
553 | { | ||
554 | self->mUpdate = !(self->childHasFocus("near_me_range")); | ||
555 | } | ||
556 | } | ||
557 | |||
558 | |||
559 | LLUUID PanelRadar::getSelected() | ||
560 | { | ||
561 | return mSelectedAvatar; | ||
562 | } | ||
563 | |||
564 | |||
565 | |||
566 | // | ||
567 | // Avatar tab | ||
568 | // | ||
569 | |||
570 | // static | ||
571 | void PanelRadar::onClickIM(void* user_data) | ||
572 | { | ||
573 | PanelRadar* self = (PanelRadar*) user_data; | ||
574 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
575 | if (item != NULL) | ||
576 | { | ||
577 | LLUUID agent_id = item->getUUID(); | ||
578 | gIMMgr->setFloaterOpen(TRUE); | ||
579 | gIMMgr->addSession(getSelectedName(agent_id), IM_NOTHING_SPECIAL, agent_id); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | |||
584 | // static | ||
585 | void PanelRadar::onClickProfile(void* user_data) | ||
586 | { | ||
587 | PanelRadar* self = (PanelRadar*) user_data; | ||
588 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
589 | if (item != NULL) | ||
590 | { | ||
591 | LLUUID agent_id = item->getUUID(); | ||
592 | LLFloaterAvatarInfo::show(agent_id); | ||
593 | } | ||
594 | } | ||
595 | |||
596 | |||
597 | // static | ||
598 | void PanelRadar::onClickOfferTeleport(void* user_data) | ||
599 | { | ||
600 | PanelRadar* self = (PanelRadar*) user_data; | ||
601 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
602 | if (item != NULL) | ||
603 | { | ||
604 | LLUUID agent_id = item->getUUID(); | ||
605 | handle_lure(agent_id); | ||
606 | } | ||
607 | } | ||
608 | |||
609 | |||
610 | // static | ||
611 | void PanelRadar::onClickTrack(void* user_data) | ||
612 | { | ||
613 | PanelRadar* self = (PanelRadar*) user_data; | ||
614 | LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); | ||
615 | |||
616 | if (LLTracker::TRACKING_AVATAR == tracking_status) | ||
617 | { | ||
618 | LLTracker::stopTracking(NULL); | ||
619 | } | ||
620 | else | ||
621 | { | ||
622 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
623 | if (item != NULL) | ||
624 | { | ||
625 | LLUUID agent_id = item->getUUID(); | ||
626 | LLTracker::trackAvatar(agent_id, getSelectedName(agent_id)); | ||
627 | } | ||
628 | } | ||
629 | } | ||
630 | |||
631 | |||
632 | // static | ||
633 | void PanelRadar::onClickInvite(void* user_data) | ||
634 | { | ||
635 | PanelRadar* self = (PanelRadar*) user_data; | ||
636 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
637 | if (item != NULL) | ||
638 | { | ||
639 | LLUUID agent_id = item->getUUID(); | ||
640 | LLFloaterGroupPicker* widget; | ||
641 | widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); | ||
642 | if (widget) | ||
643 | { | ||
644 | widget->center(); | ||
645 | widget->setPowersMask(GP_MEMBER_INVITE); | ||
646 | widget->setSelectCallback(callback_invite_to_group, (void *)&agent_id); | ||
647 | } | ||
648 | } | ||
649 | } | ||
650 | |||
651 | |||
652 | // static | ||
653 | void PanelRadar::callback_invite_to_group(LLUUID group_id, void *user_data) | ||
654 | { | ||
655 | std::vector<LLUUID> agent_ids; | ||
656 | agent_ids.push_back(*(LLUUID *)user_data); | ||
657 | |||
658 | LLFloaterGroupInvite::showForGroup(group_id, &agent_ids); | ||
659 | } | ||
660 | |||
661 | |||
662 | // static | ||
663 | void PanelRadar::onClickAddFriend(void* user_data) | ||
664 | { | ||
665 | PanelRadar* self = (PanelRadar*) user_data; | ||
666 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
667 | if (item != NULL) | ||
668 | { | ||
669 | LLUUID agent_id = item->getUUID(); | ||
670 | LLPanelFriends::requestFriendshipDialog(agent_id, getSelectedName(agent_id)); | ||
671 | } | ||
672 | } | ||
673 | |||
674 | |||
675 | |||
676 | // | ||
677 | // Estate tab | ||
678 | // | ||
679 | |||
680 | //static | ||
681 | std::string PanelRadar::getSelectedName(const LLUUID &agent_id) | ||
682 | { | ||
683 | std::string agent_name; | ||
684 | if(gCacheName->getFullName(agent_id, agent_name) && agent_name != " ") | ||
685 | { | ||
686 | return agent_name; | ||
687 | } | ||
688 | return LLStringUtil::null; | ||
689 | } | ||
690 | |||
691 | |||
692 | //static | ||
693 | void PanelRadar::callbackFreeze(S32 option, void *user_data) | ||
694 | { | ||
695 | PanelRadar *self = (PanelRadar*)user_data; | ||
696 | |||
697 | if ( option == 0 ) | ||
698 | { | ||
699 | sendFreeze(self->mSelectedAvatar, true); | ||
700 | } | ||
701 | else if ( option == 1 ) | ||
702 | { | ||
703 | sendFreeze(self->mSelectedAvatar, false); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | |||
708 | //static | ||
709 | void PanelRadar::callbackEject(S32 option, void *user_data) | ||
710 | { | ||
711 | PanelRadar *self = (PanelRadar*)user_data; | ||
712 | |||
713 | if ( option == 0 ) | ||
714 | { | ||
715 | sendEject(self->mSelectedAvatar, false); | ||
716 | } | ||
717 | else if ( option == 1 ) | ||
718 | { | ||
719 | sendEject(self->mSelectedAvatar, true); | ||
720 | } | ||
721 | } | ||
722 | |||
723 | |||
724 | //static | ||
725 | void PanelRadar::callbackEjectFromEstate(S32 option, void *user_data) | ||
726 | { | ||
727 | PanelRadar *self = (PanelRadar*)user_data; | ||
728 | |||
729 | if ( option == 0 ) | ||
730 | { | ||
731 | cmdEstateEject(self->mSelectedAvatar); | ||
732 | } | ||
733 | else if ( option == 1 ) | ||
734 | { | ||
735 | cmdEstateBan(self->mSelectedAvatar); | ||
736 | } | ||
737 | } | ||
738 | |||
739 | |||
740 | void PanelRadar::onClickFreeze(void *user_data) | ||
741 | { | ||
742 | PanelRadar *self = (PanelRadar*)user_data; | ||
743 | LLStringUtil::format_map_t args; | ||
744 | LLSD payload; | ||
745 | args["[AVATAR_NAME]"] = getSelectedName(self->mSelectedAvatar); | ||
746 | gViewerWindow->alertXml("FreezeAvatarFullname", args, callbackFreeze, user_data); | ||
747 | } | ||
748 | |||
749 | |||
750 | //static | ||
751 | void PanelRadar::onClickEject(void *user_data) | ||
752 | { | ||
753 | PanelRadar *self = (PanelRadar*)user_data; | ||
754 | LLStringUtil::format_map_t args; | ||
755 | LLSD payload; | ||
756 | args["AVATAR_NAME"] = getSelectedName(self->mSelectedAvatar); | ||
757 | gViewerWindow->alertXml("EjectAvatarFullName", args, callbackEject, user_data); | ||
758 | } | ||
759 | |||
760 | |||
761 | //static | ||
762 | void PanelRadar::onClickMute(void *user_data) | ||
763 | { | ||
764 | PanelRadar *self = (PanelRadar*)user_data; | ||
765 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
766 | if (item != NULL) | ||
767 | { | ||
768 | LLUUID agent_id = item->getUUID(); | ||
769 | std::string agent_name = getSelectedName(agent_id); | ||
770 | if (LLMuteList::getInstance()->isMuted(agent_id)) | ||
771 | { | ||
772 | //LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
773 | //LLMuteList::getInstance()->remove(mute); | ||
774 | //LLFloaterMute::getInstance()->selectMute(agent_id); | ||
775 | } | ||
776 | else | ||
777 | { | ||
778 | LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
779 | LLMuteList::getInstance()->add(mute); | ||
780 | } | ||
781 | } | ||
782 | } | ||
783 | |||
784 | |||
785 | //static | ||
786 | void PanelRadar::onClickUnmute(void *user_data) | ||
787 | { | ||
788 | PanelRadar *self = (PanelRadar*)user_data; | ||
789 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
790 | if (item != NULL) | ||
791 | { | ||
792 | LLUUID agent_id = item->getUUID(); | ||
793 | std::string agent_name = getSelectedName(agent_id); | ||
794 | if (LLMuteList::getInstance()->isMuted(agent_id)) | ||
795 | { | ||
796 | LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
797 | LLMuteList::getInstance()->remove(mute); | ||
798 | //LLFloaterMute::getInstance()->selectMute(agent_id); | ||
799 | } | ||
800 | else | ||
801 | { | ||
802 | //LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
803 | //LLMuteList::getInstance()->add(mute); | ||
804 | } | ||
805 | } | ||
806 | } | ||
807 | |||
808 | |||
809 | //static | ||
810 | void PanelRadar::onClickEjectFromEstate(void *user_data) | ||
811 | { | ||
812 | PanelRadar *self = (PanelRadar*)user_data; | ||
813 | LLStringUtil::format_map_t args; | ||
814 | LLSD payload; | ||
815 | args["EVIL_USER"] = getSelectedName(self->mSelectedAvatar); | ||
816 | gViewerWindow->alertXml("EstateKickUser", args, callbackEjectFromEstate, user_data); | ||
817 | } | ||
818 | |||
819 | |||
820 | //static | ||
821 | void PanelRadar::onClickAR(void *user_data) | ||
822 | { | ||
823 | PanelRadar *self = (PanelRadar*)user_data; | ||
824 | LLUUID agent_id = self->mSelectedAvatar; | ||
825 | |||
826 | if (agent_id.notNull()) | ||
827 | { | ||
828 | LLFloaterReporter::showFromObject(agent_id); | ||
829 | } | ||
830 | } | ||
831 | |||
832 | |||
833 | // static | ||
834 | void PanelRadar::cmdEstateEject(const LLUUID &avatar) | ||
835 | { | ||
836 | sendEstateMessage("teleporthomeuser", avatar); | ||
837 | } | ||
838 | |||
839 | |||
840 | // static | ||
841 | void PanelRadar::cmdEstateBan(const LLUUID &avatar) | ||
842 | { | ||
843 | sendEstateMessage("teleporthomeuser", avatar); // Kick first, just to be sure | ||
844 | sendEstateBan(avatar); | ||
845 | } | ||
846 | |||
847 | |||
848 | // static | ||
849 | void PanelRadar::sendFreeze(const LLUUID& avatar_id, bool freeze) | ||
850 | { | ||
851 | U32 flags = 0x0; | ||
852 | if (!freeze) | ||
853 | { | ||
854 | // unfreeze | ||
855 | flags |= 0x1; | ||
856 | } | ||
857 | |||
858 | LLMessageSystem* msg = gMessageSystem; | ||
859 | LLViewerObject* avatar = gObjectList.findObject(avatar_id); | ||
860 | |||
861 | if (avatar) | ||
862 | { | ||
863 | msg->newMessage("FreezeUser"); | ||
864 | msg->nextBlock("AgentData"); | ||
865 | msg->addUUID("AgentID", gAgent.getID()); | ||
866 | msg->addUUID("SessionID", gAgent.getSessionID()); | ||
867 | msg->nextBlock("Data"); | ||
868 | msg->addUUID("TargetID", avatar_id ); | ||
869 | msg->addU32("Flags", flags ); | ||
870 | msg->sendReliable( avatar->getRegion()->getHost() ); | ||
871 | } | ||
872 | } | ||
873 | |||
874 | |||
875 | // static | ||
876 | void PanelRadar::sendEject(const LLUUID& avatar_id, bool ban) | ||
877 | { | ||
878 | LLMessageSystem* msg = gMessageSystem; | ||
879 | LLViewerObject* avatar = gObjectList.findObject(avatar_id); | ||
880 | |||
881 | if (avatar) | ||
882 | { | ||
883 | U32 flags = 0x0; | ||
884 | if ( ban ) | ||
885 | { | ||
886 | // eject and add to ban list | ||
887 | flags |= 0x1; | ||
888 | } | ||
889 | |||
890 | msg->newMessage("EjectUser"); | ||
891 | msg->nextBlock("AgentData"); | ||
892 | msg->addUUID("AgentID", gAgent.getID() ); | ||
893 | msg->addUUID("SessionID", gAgent.getSessionID() ); | ||
894 | msg->nextBlock("Data"); | ||
895 | msg->addUUID("TargetID", avatar_id ); | ||
896 | msg->addU32("Flags", flags ); | ||
897 | msg->sendReliable( avatar->getRegion()->getHost() ); | ||
898 | } | ||
899 | } | ||
900 | |||
901 | |||
902 | // static | ||
903 | void PanelRadar::sendEstateMessage(const char* request, const LLUUID &target) | ||
904 | { | ||
905 | |||
906 | LLMessageSystem* msg = gMessageSystem; | ||
907 | LLUUID invoice; | ||
908 | |||
909 | // This seems to provide an ID so that the sim can say which request it's | ||
910 | // replying to. I think this can be ignored for now. | ||
911 | invoice.generate(); | ||
912 | |||
913 | llinfos << "Sending estate request '" << request << "'" << llendl; | ||
914 | msg->newMessage("EstateOwnerMessage"); | ||
915 | msg->nextBlockFast(_PREHASH_AgentData); | ||
916 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
917 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
918 | msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used | ||
919 | msg->nextBlock("MethodData"); | ||
920 | msg->addString("Method", request); | ||
921 | msg->addUUID("Invoice", invoice); | ||
922 | |||
923 | // Agent id | ||
924 | msg->nextBlock("ParamList"); | ||
925 | msg->addString("Parameter", gAgent.getID().asString().c_str()); | ||
926 | |||
927 | // Target | ||
928 | msg->nextBlock("ParamList"); | ||
929 | msg->addString("Parameter", target.asString().c_str()); | ||
930 | |||
931 | msg->sendReliable(gAgent.getRegion()->getHost()); | ||
932 | } | ||
933 | |||
934 | |||
935 | // static | ||
936 | void PanelRadar::sendEstateBan(const LLUUID& agent) | ||
937 | { | ||
938 | LLUUID invoice; | ||
939 | U32 flags = ESTATE_ACCESS_BANNED_AGENT_ADD; | ||
940 | |||
941 | invoice.generate(); | ||
942 | |||
943 | LLMessageSystem* msg = gMessageSystem; | ||
944 | msg->newMessage("EstateOwnerMessage"); | ||
945 | msg->nextBlockFast(_PREHASH_AgentData); | ||
946 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
947 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
948 | msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used | ||
949 | |||
950 | msg->nextBlock("MethodData"); | ||
951 | msg->addString("Method", "estateaccessdelta"); | ||
952 | msg->addUUID("Invoice", invoice); | ||
953 | |||
954 | char buf[MAX_STRING]; /* Flawfinder: ignore*/ | ||
955 | gAgent.getID().toString(buf); | ||
956 | msg->nextBlock("ParamList"); | ||
957 | msg->addString("Parameter", buf); | ||
958 | |||
959 | snprintf(buf, MAX_STRING, "%u", flags); /* Flawfinder: ignore */ | ||
960 | msg->nextBlock("ParamList"); | ||
961 | msg->addString("Parameter", buf); | ||
962 | |||
963 | agent.toString(buf); | ||
964 | msg->nextBlock("ParamList"); | ||
965 | msg->addString("Parameter", buf); | ||
966 | |||
967 | gAgent.sendReliableMessage(); | ||
968 | } | ||