00001 #include "llviewerprecompiledheaders.h"
00002 #include "llfloatereventlog.h"
00003
00004 #include "llvieweruictrlfactory.h"
00005 #include "llviewerwindow.h"
00006 #include "llscrolllistctrl.h"
00007 #include "viewer.h"
00008 #include "llagent.h"
00009 #include "llpartdata.h"
00010 #include "llfloateravatarinfo.h"
00011 #include "llmutelist.h"
00012 #include "lltracker.h"
00013 #include "llviewerregion.h"
00014 #include "llviewerobject.h"
00015 #include "llviewerpartsource.h"
00016 #include "lltextbox.h"
00017 #include "audioengine.h"
00018 #include <iostream>
00019 #include <vector>
00020 #include <algorithm>
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 LLFloaterEventLog *gFloaterEventLog = NULL;
00048
00049
00050
00051
00052
00053 void LLWorldEvent::incCount(S32 count)
00054 {
00055 if ( mLastFrame != gFrameCount )
00056 {
00057 mAgeTimer.reset();
00058 mDuration += mDurationTimer.getElapsedTimeAndResetF32();
00059 mLastFrame = gFrameCount;
00060 }
00061
00062 mCount += count;
00063 }
00064
00065 LLParticleEvent::LLParticleEvent(const LLPartSysData &data)
00066 {
00067 mTexture = data.mPartImageID;
00068 }
00069
00070 S32 LLParticleEvent::getScore() const
00071 {
00072
00073
00074 F32 bounce_factor = 1.0f;
00075 if ( mPartSysData.mPartData.mFlags & LLPartData::LL_PART_BOUNCE_MASK )
00076 bounce_factor = 1.5f;
00077
00078
00079 return (S32)(mPartSysData.mBurstPartCount *
00080 ( 1 + mPartSysData.mPartData.mMaxAge ) *
00081 ( 1 / mPartSysData.mBurstRate ) *
00082 ( 1 + mPartSysData.mPartData.mStartScale.magVec() +
00083 mPartSysData.mPartData.mEndScale.magVec() ) *
00084 bounce_factor );
00085 }
00086
00087
00088
00089
00090
00091
00092 LLAvatarOwnedEmitter::LLAvatarOwnedEmitter(const LLUUID& id, const LLString& name)
00093 {
00094 mNamePending = false;
00095 setOwner(id, name);
00096
00097 }
00098
00099 void LLAvatarOwnedEmitter::setOwner(const LLUUID &id, const LLString &name)
00100 {
00101 mOwnerID = id;
00102 mOwnerName = name;
00103 }
00104
00105 void LLAvatarOwnedEmitter::update()
00106 {
00107 if ( mOwnerName.empty() && !mNamePending )
00108 {
00109 llinfos << "Requesting name for id " << mOwnerID << llendl;
00110 mNamePending = true;
00111 gCacheName->get( mOwnerID, FALSE, nameLookupCallback, this );
00112 }
00113 }
00114
00115
00116 void LLAvatarOwnedEmitter::nameLookupCallback(const LLUUID&id, const char *first, const char *last, BOOL group, void *userdata)
00117 {
00118 if ( first && last && !id.isNull())
00119 {
00120
00121
00122 LLAvatarOwnedEmitter *em = (LLAvatarOwnedEmitter*)userdata;
00123
00124 LLString name;
00125
00126 name += first;
00127 name += " ";
00128 name += last;
00129
00130 llinfos << "Setting name for id " << em->mOwnerID << " to " << name << llendl;
00131
00132 em->mOwnerName = name;
00133 em->mNamePending = false;
00134 }
00135 }
00136
00137 LLAvatarOwnedEmitter::~LLAvatarOwnedEmitter()
00138 {
00139 if ( mNamePending && gCacheName )
00140 {
00141 gCacheName->cancelCallback( mOwnerID, nameLookupCallback, this );
00142 }
00143 }
00144
00145 LLObjectEmitter::LLObjectEmitter(const LLUUID& id, const LLUUID &owner)
00146 {
00147 mRequestedProperties = false;
00148
00149 setOwner(owner);
00150 setObject(id);
00151 }
00152
00153 LLObjectEmitter::LLObjectEmitter(LLPointer<LLViewerObject> vo)
00154 {
00155 mRequestedProperties = false;
00156 setObject(vo->getID());
00157 setPosition(vo->getPositionGlobal());
00158
00159 if ( vo->isParticleSource() )
00160 {
00161 setOwner(vo->mPartSourcep->getOwnerUUID());
00162 }
00163
00164 requestObjectInfo(vo->getRegion());
00165 }
00166
00167
00168 void LLObjectEmitter::setObject( const LLUUID& id, const LLString &name )
00169 {
00170 if ( id.isNull() )
00171 {
00172 llwarns << "Trying to set object id to null" << llendl;
00173 return;
00174 }
00175 mObjectID = id; mObjectName = name;
00176 }
00177
00178 void LLObjectEmitter::requestObjectInfo(const LLViewerRegion *reg)
00179 {
00180 LLAvatarOwnedEmitter::update();
00181
00182 if ( !mObjectID.isNull() && mObjectName.empty() && !mRequestedProperties )
00183 {
00184 llinfos << "Requesting object data for " << mObjectID << llendl;
00185
00186 mRequestedProperties = true;
00187
00188 LLMessageSystem* msg = gMessageSystem;
00189
00190 msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
00191 msg->nextBlockFast(_PREHASH_AgentData);
00192 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00193 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00194 msg->nextBlockFast(_PREHASH_ObjectData);
00195 msg->addU32Fast(_PREHASH_RequestFlags, 0x0 );
00196 msg->addUUIDFast(_PREHASH_ObjectID, mObjectID );
00197
00198
00199 msg->sendReliable( reg->getHost() );
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209 LLFloaterEventLog::LLFloaterEventLog() : LLFloater("event log")
00210 {
00211
00212 gUICtrlFactory->buildFloater(this, "floater_event_log.xml");
00213
00214
00215 setVisible(FALSE);
00216
00217
00218 mEventList = LLUICtrlFactory::getScrollListByName(this, "event_log");
00219 mSelectedTexture = LLUICtrlFactory::getTexturePickerByName(this, "selected_texture");
00220
00221
00222
00223
00224 mActionButtons[QB_AVATAR_PROFILE] = LLUICtrlFactory::getButtonByName(this, "av_profile_btn");
00225 mActionButtons[QB_AVATAR_KEY] = LLUICtrlFactory::getButtonByName(this, "av_get_key_btn");
00226 mActionButtons[QB_AVATAR_TRACK] = LLUICtrlFactory::getButtonByName(this, "av_track_btn");
00227 mActionButtons[QB_AVATAR_MUTE] = LLUICtrlFactory::getButtonByName(this, "av_mute_btn");
00228 mActionButtons[QB_AVATAR_EJECT] = LLUICtrlFactory::getButtonByName(this, "av_eject_btn");
00229 mActionButtons[QB_AVATAR_LW_GOHOME] = LLUICtrlFactory::getButtonByName(this, "av_luskwood_gohome_btn");
00230 mActionButtons[QB_OBJECT_KEY] = LLUICtrlFactory::getButtonByName(this, "obj_get_key_btn");
00231 mActionButtons[QB_OBJECT_TRACK] = LLUICtrlFactory::getButtonByName(this, "obj_track_btn");
00232 mActionButtons[QB_OBJECT_MUTE] = LLUICtrlFactory::getButtonByName(this, "obj_mute_btn");
00233 mActionButtons[QB_OBJECT_RETURN] = LLUICtrlFactory::getButtonByName(this, "obj_return_btn");
00234 mActionButtons[QB_UUID_BLACKLIST] = LLUICtrlFactory::getButtonByName(this, "uuid_blacklist_btn");
00235 mActionButtons[QB_UUID_WHITELIST] = LLUICtrlFactory::getButtonByName(this, "uuid_whitelist_btn");
00236 mActionButtons[QB_UUID_MUTELIST] = LLUICtrlFactory::getButtonByName(this, "uuid_mutelist_btn");
00237
00238
00239 mActionButtonsType[QB_AVATAR_PROFILE] = QBT_AVATAR;
00240 mActionButtonsType[QB_AVATAR_KEY] = QBT_AVATAR;
00241 mActionButtonsType[QB_AVATAR_TRACK] = QBT_AVATAR;
00242 mActionButtonsType[QB_AVATAR_MUTE] = QBT_AVATAR;
00243 mActionButtonsType[QB_AVATAR_EJECT] = QBT_AVATAR;
00244 mActionButtonsType[QB_AVATAR_LW_GOHOME] = QBT_AVATAR;
00245 mActionButtonsType[QB_OBJECT_KEY] = QBT_OBJECT;
00246 mActionButtonsType[QB_OBJECT_TRACK] = QBT_OBJECT;
00247 mActionButtonsType[QB_OBJECT_MUTE] = QBT_OBJECT;
00248 mActionButtonsType[QB_OBJECT_RETURN] = QBT_OBJECT;
00249 mActionButtonsType[QB_UUID_BLACKLIST] = QBT_UUID;
00250 mActionButtonsType[QB_UUID_WHITELIST] = QBT_UUID;
00251 mActionButtonsType[QB_UUID_MUTELIST] = QBT_UUID;
00252
00253
00254
00255 for(int i=0;i<MAX_INTERESTING_TEXTURES;i++)
00256 {
00257 std::ostringstream o;
00258 o << "hiscore_texture_" << i;
00259 mHiscoreTextures[i] = LLUICtrlFactory::getTexturePickerByName(this, o.str());
00260
00261 o.str(""); o << "hiscore_name_" << i;
00262 mHiscoreNames[i] = LLUICtrlFactory::getTextBoxByName(this, o.str());
00263
00264 o.str(""); o << "hiscore_owner_" << i;
00265 mHiscoreOwners[i] = LLUICtrlFactory::getTextBoxByName(this, o.str());
00266
00267 o.str(""); o << "hiscore_action_" << i;
00268 mHiscoreButtons[i] = LLUICtrlFactory::getButtonByName(this, o.str());
00269
00270 childSetAction(o.str(), onClickQuickButton, mHiscoreButtons[i]);
00271 }
00272
00273
00274 mEventList->setCallbackUserData(this);
00275 mEventList->sortByColumn("score", FALSE);
00276 mEventList->setDoubleClickCallback(onDoubleClick);
00277
00278 childSetAction("av_profile_btn", onClickAvatarProfile, this);
00279 childSetAction("av_get_key_btn", onClickAvatarGetKey, this);
00280 childSetAction("av_track_btn", onClickAvatarTrack, this);
00281 childSetAction("av_mute_btn", onClickAvatarMute, this);
00282 childSetAction("av_eject_btn", onClickAvatarEject, this);
00283 childSetAction("av_luskwood_gohome_btn", onClickAvatarGohomerSendHome, this);
00284
00285 childSetAction("obj_get_key_btn", onClickObjectGetKey, this);
00286 childSetAction("obj_track_btn", onClickObjectTrack, this);
00287 childSetAction("obj_mute_btn", onClickObjectMute, this);
00288 childSetAction("obj_return_btn", onClickObjectReturn, this);
00289
00290
00291 childSetAction("uuid_blacklist_btn", onClickUUIDBlacklist, this);
00292 childSetAction("uuid_whitelist_btn", onClickUUIDWhitelist, this);
00293 childSetAction("uuid_mutelist_btn", onClickUUIDMutelist, this);
00294
00295 LLMessageSystem *msg = gMessageSystem;
00296 msg->addHandlerFuncFast(_PREHASH_ObjectPropertiesFamily, processObjectPropertiesFamily);
00297 msg->addHandlerFuncFast(_PREHASH_ObjectPropertiesFamily, processObjectProperties);
00298
00299 updateControlsState();
00300
00301 }
00302
00303 LLFloaterEventLog::~LLFloaterEventLog()
00304 {
00305 LLMessageSystem *msg = gMessageSystem;
00306 if ( msg )
00307 {
00308 msg->delHandlerFuncFast(_PREHASH_ObjectPropertiesFamily, processObjectPropertiesFamily);
00309 msg->delHandlerFuncFast(_PREHASH_ObjectPropertiesFamily, processObjectProperties);
00310 }
00311 }
00312
00313 void LLFloaterEventLog::show()
00314 {
00315
00316 open();
00317 }
00318
00319 void LLFloaterEventLog::updateControlsState()
00320 {
00321 BOOL row_selected = FALSE;
00322 EVENT_TYPE type = LLFloaterEventLog::EVENT_PARTICLE;
00323
00324 if ( mEventList->getFirstSelected() ) row_selected = TRUE;
00325
00326
00327 childSetVisible("particle_info_container", row_selected && type == LLFloaterEventLog::EVENT_PARTICLE);
00328 childSetEnabled("av_profile_btn", row_selected);
00329 childSetEnabled("av_get_key_btn", row_selected);
00330 childSetEnabled("av_track_btn", row_selected);
00331 childSetEnabled("av_mute_btn", row_selected);
00332 childSetEnabled("av_eject_btn", row_selected);
00333 childSetEnabled("av_luskwood_gohome_btn", row_selected);
00334
00335 childSetEnabled("obj_get_key_btn", row_selected);
00336 childSetEnabled("obj_track_btn", row_selected);
00337 childSetEnabled("obj_mute_btn", row_selected);
00338 childSetEnabled("obj_return_btn", row_selected);
00339
00340 childSetEnabled("uuid_blacklist_btn", row_selected);
00341 childSetEnabled("uuid_whitelist_btn", row_selected);
00342 childSetEnabled("uuid_mutelist_btn", row_selected);
00343 }
00344
00345
00346 void LLFloaterEventLog::toggle(void*) {
00347 if (!gFloaterEventLog) {
00348 llinfos << "No event log!" << llendl;
00349 return;
00350 }
00351
00352 if (gFloaterEventLog->getVisible())
00353 {
00354 gFloaterEventLog->close();
00355 }
00356 else
00357 {
00358 gFloaterEventLog->show();
00359 }
00360 }
00361
00362
00363 BOOL LLFloaterEventLog::visible(void*)
00364 {
00365 return (gFloaterEventLog && gFloaterEventLog->getVisible());
00366 }
00367
00368 void LLFloaterEventLog::logAvatarEvent( const LLUUID &avatar, const LLString &name, LLPointer <LLWorldEvent> ev)
00369 {
00370 logEvent( new LLAvatarEmitter(avatar, name), ev);
00371 }
00372
00373 void LLFloaterEventLog::logObjectEvent( const LLUUID &object, const LLUUID &owner, LLPointer <LLWorldEvent> ev)
00374 {
00375 LLObjectEmitter *em = new LLObjectEmitter(object, owner);
00376 logEvent( em, ev);
00377 }
00378
00379 void LLFloaterEventLog::logEvent( LLPointer<LLEventEmitter> emitter, LLPointer <LLWorldEvent> event)
00380 {
00381 LLUUID id = emitter->getID();
00382
00383 LLPointer<LLEventEmitter> em = getEmitter(id);
00384
00385 if ( !em )
00386 {
00387 em = emitter;
00388 mEmitters[id] = em;
00389 }
00390
00391 LLPointer<LLWorldEvent> ev = em->getEvent(event->getID());
00392 if ( !ev )
00393 {
00394 em->addEvent(event);
00395 ev = event;
00396 }
00397
00398
00399 *ev += *event;
00400 }
00401
00402 void LLFloaterEventLog::logObject( LLPointer<LLViewerObject> vo )
00403 {
00404
00405
00406 if ( !vo->isParticleSource() ) return;
00407
00408 LLUUID emitter_id = vo->getID();
00409
00410 LLPointer<LLEventEmitter> em = getEmitter(emitter_id);
00411 LLPointer<LLWorldEvent> ev;
00412
00413 if ( !em )
00414 {
00415 em = new LLObjectEmitter(vo);
00416 mEmitters[emitter_id] = em;
00417 }
00418
00419
00420
00421 if ( vo->isParticleSource() )
00422 {
00423 ev = em->getEvent( vo->mPartSourcep->mPartSysData.mPartImageID );
00424 if ( ! ev )
00425 {
00426 ev = new LLParticleEvent( vo->mPartSourcep->mPartSysData );
00427 em->addEvent( ev );
00428 }
00429
00430 ev->incCount( vo->mPartSourcep->mPartSysData.mBurstPartCount );
00431
00432 LLParticleEvent *pev = dynamic_cast<LLParticleEvent*>( ev.get() );
00433 if ( pev )
00434 {
00435 pev->setParticleData(vo->mPartSourcep->mPartSysData);
00436 }
00437 }
00438
00439 LLAudioSource *src = vo->getAudioSource( em->getOwnerID() );
00440
00441 if ( src )
00442 {
00443
00444
00445
00446
00447 LLAudioData *data = src->getCurrentData();
00448
00449 if ( data )
00450 {
00451 LLUUID sound_id = data->getID();
00452 ev = em->getEvent( sound_id );
00453
00454 if ( !ev )
00455 {
00456 ev = new LLSoundEvent( sound_id );
00457 em->addEvent( ev );
00458 }
00459 }
00460 }
00461
00462 }
00463
00464
00465 struct DescendingEventSort
00466 {
00467 bool operator()(LLPointer<LLWorldEvent> a, LLPointer<LLWorldEvent> b)
00468 {
00469 return a->getScore() > b->getScore();
00470 }
00471 };
00472
00473 void LLFloaterEventLog::updateList()
00474 {
00475 BOOL show_null = LLUICtrlFactory::getCheckBoxByName(this, "show_null_cb")->getValue();
00476 BOOL show_zero_count = LLUICtrlFactory::getCheckBoxByName(this, "show_zero_count_cb")->getValue();
00477
00478 LLDynamicArray<LLUUID> selected = mEventList->getSelectedIDs();
00479 S32 scrollpos = mEventList->getScrollPos();
00480
00481 U32 max_age = gSavedSettings.getU32("EventLogMaxAge");
00482 U32 max_entries = gSavedSettings.getU32("EventLogMaxEntries");
00483 LLVector3d mypos = gAgent.getPositionGlobal();
00484
00485 mEventList->deleteAllItems();
00486
00487
00488 std::vector< LLPointer<LLWorldEvent> > annoyances;
00489
00490
00491 std::map<LLUUID, LLPointer<LLEventEmitter> >::iterator iter;
00492
00493 for(iter = mEmitters.begin(); iter != mEmitters.end(); iter++)
00494 {
00495 LLPointer<LLEventEmitter> em = iter->second;
00496
00497
00498 LLVector3d delta = em->getPosition() - mypos;
00499 F32 distance = (F32)delta.magVec();
00500
00501
00502
00503 std::map<LLUUID, LLPointer<LLWorldEvent> >::iterator iter_events;
00504 for(iter_events = em->mEvents.begin(); iter_events != em->mEvents.end(); iter_events++)
00505 {
00506 LLPointer<LLWorldEvent> ev = iter_events->second;
00507
00508 if ( ev->getAge() > max_age ) continue;
00509 if ( --max_entries == 0 ) goto too_many_entries;
00510 if ( !show_null && ev->getID().isNull() ) continue;
00511 if ( !show_zero_count && ev->getCount() == 0 ) continue;
00512
00513 ev->checkDuration();
00514
00515 if ( !ev->getID().isNull() && ev->getAge() < 1.0f )
00516 {
00517 annoyances.push_back( ev );
00518 }
00519
00520 LLSD row;
00521
00522 row["id"] = ev->getGlobalID();
00523
00524 row["columns"][LIST_EVENT_ICON]["column"] = "type_icon";
00525 row["columns"][LIST_EVENT_ICON]["type"] = "icon";
00526 row["columns"][LIST_EVENT_ICON]["value"] = ev->getIcon();
00527
00528 row["columns"][LIST_OWNER_NAME]["column"] = "owner_name";
00529 row["columns"][LIST_OWNER_NAME]["type"] = "text";
00530 row["columns"][LIST_OWNER_NAME]["value"] = em->getOwnerName();
00531
00532 row["columns"][LIST_OBJECT_NAME]["column"] = "object_name";
00533 row["columns"][LIST_OBJECT_NAME]["type"] = "text";
00534 row["columns"][LIST_OBJECT_NAME]["value"] = em->getName();
00535
00536 row["columns"][LIST_ID]["column"] = "id";
00537 row["columns"][LIST_ID]["type"] = "text";
00538 row["columns"][LIST_ID]["value"] = ev->getID();
00539
00540 row["columns"][LIST_DISTANCE]["column"] = "distance";
00541 row["columns"][LIST_DISTANCE]["type"] = "text";
00542 row["columns"][LIST_DISTANCE]["value"] = llformat("%.2f", distance);
00543
00544 row["columns"][LIST_COUNT]["column"] = "count";
00545 row["columns"][LIST_COUNT]["type"] = "text";
00546 row["columns"][LIST_COUNT]["value"] = ev->getCount();
00547
00548 row["columns"][LIST_DURATION]["column"] = "duration";
00549 row["columns"][LIST_DURATION]["type"] = "text";
00550 row["columns"][LIST_DURATION]["value"] = llformat("%.2f", ev->getDuration());
00551
00552 row["columns"][LIST_AGE]["column"] = "age";
00553 row["columns"][LIST_AGE]["type"] = "text";
00554 row["columns"][LIST_AGE]["value"] = llformat("%.2f", ev->getAge());
00555
00556 row["columns"][LIST_SCORE]["column"] = "score";
00557 row["columns"][LIST_SCORE]["type"] = "text";
00558 row["columns"][LIST_SCORE]["value"] = ev->getScore();
00559
00560
00561
00562 mEventList->addElement(row, ADD_BOTTOM);
00563 }
00564
00565 em->update();
00566 }
00567
00568 too_many_entries:
00569
00570 mEventList->sort();
00571 mEventList->selectMultiple(selected);
00572 mEventList->setScrollPos(scrollpos);
00573
00574
00575
00576 std::sort(annoyances.begin(), annoyances.end(), DescendingEventSort());
00577 int count = 0;
00578 while( annoyances.size() > count && count < MAX_INTERESTING_TEXTURES)
00579 {
00580 mHiscoreTextures[count]->setImageAssetID( annoyances[count]->getID() );
00581 mHiscoreNames[count]->setText( annoyances[count]->getParent()->getName() );
00582 mHiscoreOwners[count]->setText( annoyances[count]->getParent()->getOwnerName() );
00583 mHiscoreButtons[count]->setEnabled(TRUE);
00584 mHiscoreEvents[count] = annoyances[count];
00585 count++;
00586 }
00587
00588
00589 while( count < MAX_INTERESTING_TEXTURES )
00590 {
00591 mHiscoreTextures[count]->setImageAssetID( LLUUID::null );
00592 mHiscoreNames[count]->setText(LLString(""));
00593 mHiscoreOwners[count]->setText(LLString(""));
00594 mHiscoreButtons[count]->setEnabled(FALSE);
00595 mHiscoreEvents[count] = NULL;
00596 count++;
00597 }
00598
00599 }
00600
00601
00602 void LLFloaterEventLog::updateQuickButtons()
00603 {
00604 S32 action = gSavedSettings.getS32("EventLogQuickAction");
00605 if ( action >= QB_COUNT )
00606 {
00607 llwarns << "Quick action button set to out of range value: " << action << llendl;
00608 return;
00609 }
00610
00611 LLString text = mActionButtons[action]->getLabelSelected();
00612
00613 switch( mActionButtonsType[action] )
00614 {
00615 case QBT_AVATAR: text = "Avatar: " + text; break;
00616 case QBT_OBJECT: text = "Object: " + text; break;
00617 case QBT_UUID: text = "UUID: " + text; break;
00618 }
00619
00620 for(S32 i = 0;i<MAX_INTERESTING_TEXTURES;i++)
00621 {
00622 mHiscoreButtons[i]->setLabel(text);
00623 }
00624 }
00625
00626 void LLFloaterEventLog::updateSelectedEventInfo()
00627 {
00628
00629
00630
00631 LLScrollListItem *selected_item = mEventList->getFirstSelected();
00632 if ( selected_item )
00633 {
00634 LLParticleEvent *pev = dynamic_cast<LLParticleEvent*>( findEventBySelectedID(selected_item->getUUID()).get() );
00635 if ( pev )
00636 {
00637 mSelectedTexture->setImageAssetID( pev->getID() );
00638 LLString pattern;
00639
00640 switch( pev->mPartSysData.mPattern )
00641 {
00642 case LLPartSysData::LL_PART_SRC_PATTERN_DROP: pattern = "DROP"; break;
00643 case LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE: pattern = "EXPLODE"; break;
00644 case LLPartSysData::LL_PART_SRC_PATTERN_ANGLE: pattern = "ANGLE"; break;
00645 case LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE: pattern = "ANGLE_CONE"; break;
00646 case LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY: pattern = "ANGLE_CONE_EMPTY"; break;
00647 default: pattern = "UNKNOWN"; break;
00648 }
00649
00650 childSetTextArg("part_pattern", "[PATTERN]", pattern);
00651 childSetTextArg("part_texture", "[TEXTURE]", pev->getID().asString());
00652 childSetTextArg("part_burst_rate", "[BURST_COUNT]", llformat("%i", (U32)pev->mPartSysData.mBurstPartCount));
00653 childSetTextArg("part_burst_rate", "[BURST_RATE]", llformat("%.3f", pev->mPartSysData.mBurstRate));
00654 childSetTextArg("part_burst_rate", "[PARTICLE_COUNT]", llformat("%.3f", pev->mPartSysData.mBurstPartCount *
00655 (1 / pev->mPartSysData.mBurstRate)) );
00656
00657 childSetTextArg("part_radius", "[RADIUS]", llformat("%.3f", pev->mPartSysData.mBurstRadius));
00658 childSetTextArg("part_angle", "[ANGLE_BEGIN]", llformat("%.3f", pev->mPartSysData.mInnerAngle));
00659 childSetTextArg("part_angle", "[ANGLE_END]", llformat("%.3f", pev->mPartSysData.mOuterAngle));
00660
00661 childSetTextArg("part_speed", "[SPEED_MIN]", llformat("%.3f", pev->mPartSysData.mBurstSpeedMin));
00662 childSetTextArg("part_speed", "[SPEED_MAX]", llformat("%.3f", pev->mPartSysData.mBurstSpeedMax));
00663
00664 childSetTextArg("part_size", "[SCALE_BEGIN]", llformat("<%.3f, %.3f>", pev->mPartSysData.mPartData.mStartScale.mV[VX],
00665 pev->mPartSysData.mPartData.mStartScale.mV[VY]));
00666 childSetTextArg("part_size", "[SCALE_END]", llformat("<%.3f, %.3f>", pev->mPartSysData.mPartData.mEndScale.mV[VX],
00667 pev->mPartSysData.mPartData.mEndScale.mV[VY]));
00668 childSetTextArg("part_color", "[COLOR_BEGIN]", llformat("<%.3f, %.3f, %.3f>", pev->mPartSysData.mPartData.mStartColor.mV[0],
00669 pev->mPartSysData.mPartData.mStartColor.mV[1],
00670 pev->mPartSysData.mPartData.mStartColor.mV[2]));
00671 childSetTextArg("part_color", "[COLOR_END]", llformat("<%.3f, %.3f, %.3f>", pev->mPartSysData.mPartData.mEndColor.mV[0],
00672 pev->mPartSysData.mPartData.mEndColor.mV[1],
00673 pev->mPartSysData.mPartData.mEndColor.mV[2]));
00674 childSetTextArg("part_alpha", "[ALPHA_BEGIN]", llformat("%.3f", pev->mPartSysData.mPartData.mStartColor.mV[3]));
00675 childSetTextArg("part_alpha", "[ALPHA_END]", llformat("%.3f", pev->mPartSysData.mPartData.mEndColor.mV[3]));
00676
00677
00678 LLString flags = "";
00679 U32 f = pev->mPartSysData.mPartData.mFlags;
00680 if ( f & LLPartData::LL_PART_INTERP_COLOR_MASK ) flags += "interp_color ";
00681 if ( f & LLPartData::LL_PART_INTERP_SCALE_MASK ) flags += "interp_size ";
00682 if ( f & LLPartData::LL_PART_BOUNCE_MASK ) flags += "bounce ";
00683 if ( f & LLPartData::LL_PART_WIND_MASK ) flags += "wind ";
00684 if ( f & LLPartData::LL_PART_FOLLOW_SRC_MASK ) flags += "follow_src ";
00685 if ( f & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK ) flags += "follow_vel ";
00686 if ( f & LLPartData::LL_PART_TARGET_POS_MASK ) flags += "target ";
00687 if ( f & LLPartData::LL_PART_TARGET_LINEAR_MASK ) flags += "linear ";
00688 if ( f & LLPartData::LL_PART_EMISSIVE_MASK ) flags += "glow ";
00689 if ( f & LLPartData::LL_PART_BEAM_MASK ) flags += "beam ";
00690 if ( f & LLPartData::LL_PART_DEAD_MASK ) flags += "dead ";
00691
00692 childSetTextArg("part_flags", "[FLAGS]", flags);
00693 }
00694 }
00695
00696 }
00697
00698 void LLFloaterEventLog::updateWindow()
00699 {
00700 if (!LLFloaterEventLog::visible(NULL))
00701 {
00702 return;
00703 }
00704
00705
00706 BOOL enabled = LLUICtrlFactory::getCheckBoxByName(this, "enabled_cb")->getValue();
00707 if ( enabled ) updateList();
00708
00709
00710 updateSelectedEventInfo();
00711 updateControlsState();
00712 updateQuickButtons();
00713 }
00714
00715
00716
00717 void LLFloaterEventLog::processObjectProperties(LLMessageSystem *msg, void **user_data)
00718 {
00719 S32 i;
00720 S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData);
00721 for( i = 0; i < count; i++ )
00722 {
00723 LLUUID id;
00724 char name[DB_INV_ITEM_NAME_BUF_SIZE];
00725
00726
00727 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i);
00728 llinfos << "Processing object data for " << id << llendl;
00729
00730 if ( gFloaterEventLog->mEmitters.count( id ) > 0 )
00731 {
00732 llinfos << "Setting data for " << id << llendl;
00733 LLPointer<LLEventEmitter> em = gFloaterEventLog->mEmitters[id];
00734
00735 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, DB_INV_ITEM_NAME_BUF_SIZE, name, i);
00736
00737 em->setName( name );
00738 }
00739
00740 }
00741 }
00742
00743
00744 void LLFloaterEventLog::processObjectPropertiesFamily(LLMessageSystem *msg, void **user_data)
00745 {
00746
00747 LLUUID id;
00748 U32 request_flags;
00749
00750 char name[DB_INV_ITEM_NAME_BUF_SIZE];
00751
00752
00753 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags );
00754 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id );
00755
00756 llinfos << "Processing object data for " << id << llendl;
00757
00758 if ( gFloaterEventLog->mEmitters.count( id ) > 0 )
00759 {
00760 LLPointer<LLEventEmitter> em = gFloaterEventLog->mEmitters[id];
00761
00762 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, DB_INV_ITEM_NAME_BUF_SIZE, name);
00763
00764 em->setName( name );
00765 }
00766
00767
00768 }
00769
00770 LLPointer<LLEventEmitter> LLFloaterEventLog::findEmitterBySelectedID(const LLUUID &id)
00771 {
00772 std::map<LLUUID, LLPointer<LLEventEmitter> >::iterator iter;
00773 for(iter = mEmitters.begin(); iter != mEmitters.end(); iter++)
00774 {
00775 LLPointer<LLEventEmitter> em = iter->second;
00776
00777 std::map<LLUUID, LLPointer<LLWorldEvent> >::iterator iter_events;
00778 for(iter_events = em->mEvents.begin(); iter_events != em->mEvents.end(); iter_events++)
00779 {
00780 LLPointer<LLWorldEvent> ev = iter_events->second;
00781
00782 if ( ev->getGlobalID() == id )
00783 {
00784 return em;
00785 }
00786 }
00787 }
00788
00789 return NULL;
00790 }
00791
00792 LLPointer<LLWorldEvent> LLFloaterEventLog::findEventBySelectedID(const LLUUID &id)
00793 {
00794 std::map<LLUUID, LLPointer<LLEventEmitter> >::iterator iter;
00795 for(iter = mEmitters.begin(); iter != mEmitters.end(); iter++)
00796 {
00797 LLPointer<LLEventEmitter> em = iter->second;
00798
00799 std::map<LLUUID, LLPointer<LLWorldEvent> >::iterator iter_events;
00800 for(iter_events = em->mEvents.begin(); iter_events != em->mEvents.end(); iter_events++)
00801 {
00802 LLPointer<LLWorldEvent> ev = iter_events->second;
00803
00804 if ( ev->getGlobalID() == id )
00805 {
00806 return ev;
00807 }
00808 }
00809 }
00810
00811 return NULL;
00812 }
00813
00814
00815 void LLFloaterEventLog::onDoubleClick(void *userdata)
00816 {
00817 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00818 LLScrollListItem *item = self->mEventList->getFirstSelected();
00819 LLUUID item_id = item->getUUID();
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 LLPointer<LLEventEmitter> em = self->findEmitterBySelectedID(item_id);
00831 if ( em )
00832 {
00833 gAgent.lookAtObject(em->getID(), CAMERA_POSITION_OBJECT);
00834
00835 }
00836 else
00837 {
00838 llwarns << "Searched the whole list for " << item_id << " but couldn't find it!" << llendl;
00839 }
00840 }
00841
00842
00843
00844 void LLFloaterEventLog::doCommand(avlist_command_t func, bool use_object_id, bool first_only)
00845 {
00846 LLDynamicArray<LLUUID> ids = mEventList->getSelectedIDs();
00847
00848 std::map<LLUUID, S32> seen_ids;
00849
00850
00851 for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
00852 {
00853 LLUUID id = *itr;
00854 LLPointer<LLEventEmitter> pev = findEmitterBySelectedID(id);
00855
00856 if ( pev )
00857 {
00858 LLUUID dest_id;
00859 LLString dest_name;
00860
00861 if ( use_object_id )
00862 {
00863 dest_id = pev->getID();
00864 dest_name = pev->getName();
00865 }
00866 else
00867 {
00868 dest_id = pev->getOwnerID();
00869 dest_name = pev->getOwnerName();
00870 }
00871
00872
00873 if ( seen_ids.count( dest_id ) < 1 )
00874 {
00875 func(dest_id, dest_name);
00876
00877 if ( first_only ) return;
00878 }
00879
00880 seen_ids[dest_id] = 1;
00881 }
00882 }
00883
00884
00885
00886 }
00887
00888
00889 static void cmd_eject(const LLUUID& avatar, const LLString &name) { }
00890 static void cmd_profile(const LLUUID& avatar, const LLString &name) { LLFloaterAvatarInfo::showFromDirectory(avatar); }
00891 static void cmd_mute(const LLUUID&avatar, const LLString &name) { gMuteListp->add(LLMute(avatar, name, LLMute::AGENT)); }
00892 static void cmd_gohome(const LLUUID&avatar, const LLString &name) { gAgent.sendChat("gohome " + name + " " + avatar.asString(), 0, CHAT_TYPE_SHOUT); }
00893 static void cmd_track(const LLUUID&avatar, const LLString &name) { LLTracker::trackAvatar(avatar, name); }
00894 static void cmd_get_key(const LLUUID&avatar, const LLString &name)
00895 {
00896 char buffer[UUID_STR_LENGTH];
00897 avatar.toString(buffer);
00898 gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer));
00899 }
00900
00902
00904
00905
00906 void LLFloaterEventLog::onClickAvatarGohomerSendHome(void *userdata)
00907 {
00908 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00909 self->doCommand(cmd_gohome, false);
00910 }
00911
00912
00913 void LLFloaterEventLog::onClickAvatarGetKey(void *userdata)
00914 {
00915 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00916 self->doCommand(cmd_get_key, false, true);
00917 }
00918
00919
00920 void LLFloaterEventLog::onClickAvatarEject(void *userdata)
00921 {
00922 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00923 self->doCommand(cmd_eject, false);
00924 }
00925
00926
00927 void LLFloaterEventLog::onClickAvatarMute(void *userdata)
00928 {
00929 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00930 self->doCommand(cmd_mute, false);
00931 }
00932
00933
00934 void LLFloaterEventLog::onClickAvatarProfile(void* userdata)
00935 {
00936 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00937 self->doCommand(cmd_profile, false);
00938 }
00939
00940
00941 void LLFloaterEventLog::onClickAvatarTrack(void *userdata)
00942 {
00943 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00944 self->doCommand(cmd_track, false, true);
00945 }
00946
00948
00950
00951
00952 void LLFloaterEventLog::onClickObjectGetKey(void* userdata)
00953 {
00954 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00955 self->doCommand(cmd_get_key, true, true);
00956 }
00957
00958
00959
00960 void LLFloaterEventLog::onClickObjectTrack(void* userdata)
00961 {
00962 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00963 self->doCommand(cmd_track, true, true);
00964 }
00965
00966
00967 void LLFloaterEventLog::onClickObjectMute(void* userdata)
00968 {
00969 LLFloaterEventLog *self = (LLFloaterEventLog*)userdata;
00970 self->doCommand(cmd_mute, true);
00971 }
00972
00973
00974 void LLFloaterEventLog::onClickObjectReturn(void* userdata)
00975 {
00976
00977
00978 llinfos << "not implemented" << llendl;
00979 }
00980
00982
00984
00985
00986 void LLFloaterEventLog::onClickUUIDBlacklist(void* userdata)
00987 {
00988
00989
00990 llinfos << "not implemented" << llendl;
00991 }
00992
00993
00994 void LLFloaterEventLog::onClickUUIDWhitelist(void* userdata)
00995 {
00996
00997
00998 llinfos << "not implemented" << llendl;
00999 }
01000
01001
01002 void LLFloaterEventLog::onClickUUIDMutelist(void* userdata)
01003 {
01004
01005
01006 llinfos << "not implemented" << llendl;
01007 }
01008
01009
01011
01013
01014 void LLFloaterEventLog::onClickQuickButton(void *button)
01015 {
01016 S32 pos = -1;
01017
01018
01019 for(S32 i=0;i<MAX_INTERESTING_TEXTURES;i++)
01020 {
01021 if ( gFloaterEventLog->mHiscoreButtons[i] == button )
01022 {
01023 pos = i;
01024 break;
01025 }
01026 }
01027
01028 if ( pos < 0 )
01029 {
01030 llwarns << "Failed to find myself in the floater!" << llendl;
01031 return;
01032 }
01033
01034
01035 LLPointer<LLWorldEvent> ev = gFloaterEventLog->mHiscoreEvents[pos];
01036 LLPointer<LLEventEmitter> em = ev->getParent();
01037
01038 S32 action = gSavedSettings.getS32("EventLogQuickAction");
01039 switch(action)
01040 {
01041 case QB_AVATAR_PROFILE: cmd_profile( em->getOwnerID(), em->getOwnerName() ); break;
01042 case QB_AVATAR_KEY: cmd_get_key( em->getOwnerID(), em->getOwnerName() ); break;
01043 case QB_AVATAR_TRACK: cmd_track( em->getOwnerID(), em->getOwnerName() ); break;
01044 case QB_AVATAR_MUTE: cmd_mute( em->getOwnerID(), em->getOwnerName() ); break;
01045 case QB_AVATAR_EJECT: cmd_eject( em->getOwnerID(), em->getOwnerName() ); break;
01046 case QB_AVATAR_LW_GOHOME: cmd_gohome( em->getOwnerID(), em->getOwnerName() ); break;
01047 case QB_OBJECT_KEY: cmd_get_key( em->getID(), em->getName() ); break;
01048 case QB_OBJECT_TRACK: cmd_track( em->getID(), em->getName() ); break;
01049 case QB_OBJECT_MUTE: cmd_mute( em->getID(), em->getName() ); break;
01050 case QB_OBJECT_RETURN: llwarns << "Not implemented" << llendl; break;
01051 case QB_UUID_BLACKLIST: llwarns << "Not implemented" << llendl; break;
01052 case QB_UUID_WHITELIST: llwarns << "Not implemented" << llendl; break;
01053 case QB_UUID_MUTELIST: llwarns << "Not implemented" << llendl; break;
01054 default: llwarns << "Unknown action " << action << llendl; break;
01055 }
01056 }
01057