Files
SingularityViewer/indra/newview/llfloatertopobjects.cpp

651 lines
19 KiB
C++

/**
* @file llfloatertopobjects.cpp
* @brief Shows top colliders, top scripts, etc.
*
* $LicenseInfo:firstyear=2005&license=viewergpl$
*
* Copyright (c) 2005-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatertopobjects.h"
#include "message.h"
#include "llfontgl.h"
#include "llagent.h"
#include "llavataractions.h"
#include "llbutton.h"
#include "llfloatergodtools.h"
#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llscrolllistctrl.h"
#include "lllineeditor.h"
#include "lltextbox.h"
#include "lltracker.h"
#include "llviewermessage.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "llagentcamera.h"
#include "llviewerobjectlist.h"
void cmdline_printchat(std::string message);
LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
// Globals
// const U32 TIME_STR_LENGTH = 30;
// static
void LLFloaterTopObjects::show()
{
if (sInstance)
{
sInstance->setVisibleAndFrontmost();
return;
}
sInstance = new LLFloaterTopObjects();
LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml");
sInstance->center();
}
LLFloaterTopObjects::LLFloaterTopObjects()
: LLFloater(std::string("top_objects")),
mInitialized(FALSE),
mtotalScore(0.f)
{
sInstance = this;
}
LLFloaterTopObjects::~LLFloaterTopObjects()
{
sInstance = NULL;
}
// virtual
BOOL LLFloaterTopObjects::postBuild()
{
LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list");
if (objects_list)
{
objects_list->setCommitCallback(boost::bind(&LLFloaterTopObjects::onCommitObjectsList,_1,this));
objects_list->setDoubleClickCallback(boost::bind(&LLFloaterTopObjects::onDoubleClickObjectsList,this));
objects_list->setFocus(true);
objects_list->setCommitOnSelectionChange(TRUE);
}
childSetAction("show_beacon_btn", onClickShowBeacon, this);
setDefaultBtn("show_beacon_btn");
childSetAction("return_selected_btn", onReturnSelected, this);
childSetAction("return_all_btn", onReturnAll, this);
childSetAction("disable_selected_btn", onDisableSelected, this);
childSetAction("disable_all_btn", onDisableAll, this);
childSetAction("refresh_btn", onRefresh, this);
childSetAction("lagwarning", onLagWarningBtn, this);
childSetAction("profile", onProfileBtn, this);
childSetAction("kick", onKickBtn, this);
childSetAction("tpto", onTPBtn, this);
childSetAction("filter_object_btn", onGetByObjectNameClicked, this);
childSetAction("filter_owner_btn", onGetByOwnerNameClicked, this);
/*
LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
if (line_editor)
{
line_editor->setCommitOnFocusLost(FALSE);
line_editor->setCommitCallback(onGetByOwnerName, this);
}
line_editor = getChild<LLLineEditor>("object_name_editor");
if (line_editor)
{
line_editor->setCommitOnFocusLost(FALSE);
line_editor->setCommitCallback(onGetByObjectName, this);
}*/
mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
mFlags = 0;
mFilter.clear();
return TRUE;
}
void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data)
{
// Make sure dialog is on screen
show();
sInstance->handleReply(msg, data);
//HACK: for some reason sometimes top scripts originally comes back
//with no results even though they're there
if (!sInstance->mObjectListIDs.size() && !sInstance->mInitialized)
{
sInstance->onRefresh(NULL);
sInstance->mInitialized = TRUE;
}
}
void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
{
U32 request_flags;
U32 total_count;
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags);
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count);
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ReportType, mCurrentMode);
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("objects_list");
S32 block_count = msg->getNumberOfBlocks("ReportData");
for (S32 block = 0; block < block_count; ++block)
{
U32 task_local_id;
U32 time_stamp = 0;
LLUUID task_id;
F32 location_x, location_y, location_z;
F32 score;
std::string name_buf;
std::string owner_buf;
F32 mono_score = 0.f;
bool have_extended_data = false;
S32 public_urls = 0;
msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationX, location_x, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationY, location_y, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_LocationZ, location_z, block);
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
if(msg->has("DataExtended"))
{
have_extended_data = true;
msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
msg->getF32("DataExtended", "MonoScore", mono_score, block);
msg->getS32(_PREHASH_ReportData,"PublicURLs",public_urls,block);
}
LLSD element;
element["id"] = task_id;
element["object_name"] = name_buf;
element["owner_name"] = owner_buf;
element["columns"][0]["column"] = "score";
element["columns"][0]["value"] = llformat("%0.3f", score);
element["columns"][0]["font"] = "SANSSERIF";
element["columns"][1]["column"] = "name";
element["columns"][1]["value"] = name_buf;
element["columns"][1]["font"] = "SANSSERIF";
if (name_buf == owner_buf)
{
element["columns"][1]["color"] = LLColor4::red.getValue();
}
element["columns"][2]["column"] = "owner";
element["columns"][2]["value"] = owner_buf;
element["columns"][2]["font"] = "SANSSERIF";
element["columns"][3]["column"] = "location";
element["columns"][3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
element["columns"][3]["font"] = "SANSSERIF";
element["columns"][4]["column"] = "time";
element["columns"][4]["value"] = formatted_time((time_t)time_stamp);
element["columns"][4]["font"] = "SANSSERIF";
if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS
&& have_extended_data)
{
element["columns"][5]["column"] = "mono_time";
element["columns"][5]["value"] = llformat("%0.3f", mono_score);
element["columns"][5]["font"] = "SANSSERIF";
element["columns"][6]["column"] = "URLs";
element["columns"][6]["value"] = llformat("%d", public_urls);
element["columns"][6]["font"] = "SANSSERIF";
}
list->addElement(element);
mObjectListData.append(element);
mObjectListIDs.push_back(task_id);
mtotalScore += score;
}
if (total_count == 0 && list->getItemCount() == 0)
{
list->setCommentText(getString("none_descriptor"));
}
else
{
list->selectFirstItem();
}
if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS)
{
setTitle(getString("top_scripts_title"));
list->setColumnLabel("score", getString("scripts_score_label"));
list->setColumnLabel("mono_time", getString("scripts_mono_time_label"));
LLUIString format = getString("top_scripts_text");
format.setArg("[COUNT]", llformat("%d", total_count));
format.setArg("[TIME]", llformat("%0.1f", mtotalScore));
childSetValue("title_text", LLSD(format));
}
else
{
setTitle(getString("top_colliders_title"));
list->setColumnLabel("score", getString("colliders_score_label"));
list->setColumnLabel("mono_time", "");
LLUIString format = getString("top_colliders_text");
format.setArg("[COUNT]", llformat("%d", total_count));
childSetValue("title_text", LLSD(format));
}
}
// static
void LLFloaterTopObjects::onCommitObjectsList(LLUICtrl* ctrl, void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->updateSelectionInfo();
}
void LLFloaterTopObjects::updateSelectionInfo()
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLUUID object_id = list->getCurrentID();
if (object_id.isNull()) return;
std::string object_id_string = object_id.asString();
childSetValue("id_editor", LLSD(object_id_string));
childSetValue("object_name_editor", list->getFirstSelected()->getColumn(1)->getValue().asString());
childSetValue("owner_name_editor", list->getFirstSelected()->getColumn(2)->getValue().asString());
}
// static
void LLFloaterTopObjects::onDoubleClickObjectsList(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->showBeacon();
self->lookAtAvatar();
}
void LLFloaterTopObjects::lookAtAvatar()
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
LLUUID taskid = first_selected->getUUID();
LLVOAvatar* voavatar = gObjectList.findAvatar(taskid);
if(voavatar)
{
gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
gAgentCamera.changeCameraToThirdPerson();
gAgentCamera.setFocusGlobal(voavatar->getPositionGlobal(),taskid);
gAgentCamera.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal()
+ LLVector3d(3.5,1.35,0.75) * voavatar->getRotation(),
voavatar->getPositionGlobal(),
taskid );
}
}
// static
void LLFloaterTopObjects::onClickShowBeacon(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
if (!self) return;
self->showBeacon();
}
void LLFloaterTopObjects::doToObjects(int action, bool all)
{
LLMessageSystem *msg = gMessageSystem;
LLViewerRegion* region = gAgent.getRegion();
if (!region) return;
LLCtrlListInterface *list = childGetListInterface("objects_list");
if (!list || list->getItemCount() == 0) return;
std::vector<LLUUID>::iterator id_itor;
bool start_message = true;
for (id_itor = mObjectListIDs.begin(); id_itor != mObjectListIDs.end(); ++id_itor)
{
LLUUID task_id = *id_itor;
if (!all && !list->isSelected(task_id))
{
// Selected only
continue;
}
if (start_message)
{
if (action == ACTION_RETURN)
{
msg->newMessageFast(_PREHASH_ParcelReturnObjects);
}
else
{
msg->newMessageFast(_PREHASH_ParcelDisableObjects);
}
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_ParcelData);
msg->addS32Fast(_PREHASH_LocalID, -1); // Whole region
msg->addS32Fast(_PREHASH_ReturnType, RT_NONE);
start_message = false;
}
msg->nextBlockFast(_PREHASH_TaskIDs);
msg->addUUIDFast(_PREHASH_TaskID, task_id);
if (msg->isSendFullFast(_PREHASH_TaskIDs))
{
msg->sendReliable(region->getHost());
start_message = true;
}
}
if (!start_message)
{
msg->sendReliable(region->getHost());
}
}
//static
bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
sInstance->doToObjects(ACTION_RETURN, true);
}
return false;
}
void LLFloaterTopObjects::onReturnAll(void* data)
{
LLNotificationsUtil::add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
}
void LLFloaterTopObjects::onReturnSelected(void* data)
{
sInstance->doToObjects(ACTION_RETURN, false);
}
void LLFloaterTopObjects::onLagWarningBtn(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->onLagWarning(data);
}
void LLFloaterTopObjects::onLagWarning(void* data)
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
LLUUID taskid = first_selected->getUUID();
std::string name = first_selected->getColumn(1)->getValue().asString();
std::string score = first_selected->getColumn(0)->getValue().asString();
std::istringstream stm;
stm.str(score);
F32 f_score;
stm >> f_score;
F32 percentage = 100.f * (f_score / 22);
std::string message = llformat(
"Hello %s, you are receiving this automated message because you are wearing heavily scripted attachments/HUDs, "
"causing excessive script lag (%5.2f ms, that's ca. %5.2f%% of the region's resources.)\n\n"
"Please remove resizer scripts or attachments to reduce your script time, thank you.",
name.c_str(),
(F32)f_score,
(F32)percentage
);
std::string my_name;
gAgent.buildFullname(my_name);
cmdline_printchat(llformat("Script time warning sent to %s: (%5.2f ms)",
name.c_str(),(F32)f_score));
send_improved_im(LLUUID(taskid),
my_name,
message,
IM_ONLINE,
IM_NOTHING_SPECIAL,
LLUUID::null,
NO_TIMESTAMP,
(U8*)EMPTY_BINARY_BUCKET,
EMPTY_BINARY_BUCKET_SIZE);
}
void LLFloaterTopObjects::onProfileBtn(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->onProfile(data);
}
void LLFloaterTopObjects::onProfile(void* data)
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
LLAvatarActions::showProfile(first_selected->getUUID());
}
void LLFloaterTopObjects::onKickBtn(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->onKick(data);
}
void LLFloaterTopObjects::onKick(void* data)
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
LLUUID taskid = first_selected->getUUID();
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("EstateOwnerMessage");
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
msg->nextBlock("MethodData");
msg->addString("Method", "kickestate");
msg->addUUID("Invoice", LLUUID::null);
msg->nextBlock("ParamList");
msg->addString("Parameter", taskid.asString().c_str());
msg->sendReliable(gAgent.getRegionHost());
}
void LLFloaterTopObjects::onTPBtn(void* data)
{
LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
self->onTP(data);
}
void LLFloaterTopObjects::onTP(void* data)
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
std::string name = first_selected->getColumn(1)->getValue().asString();
std::string pos_string = first_selected->getColumn(3)->getValue().asString();
F32 x, y, z;
S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
if (matched != 3) return;
LLVector3 pos_agent(x, y, z);
LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
gAgent.teleportViaLocation( pos_global );
}
//static
bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
sInstance->doToObjects(ACTION_DISABLE, true);
}
return false;
}
void LLFloaterTopObjects::onDisableAll(void* data)
{
LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
}
void LLFloaterTopObjects::onDisableSelected(void* data)
{
sInstance->doToObjects(ACTION_DISABLE, false);
}
//static
void LLFloaterTopObjects::clearList()
{
LLCtrlListInterface *list = sInstance->childGetListInterface("objects_list");
if (list)
{
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
sInstance->mObjectListData.clear();
sInstance->mObjectListIDs.clear();
sInstance->mtotalScore = 0.f;
}
//static
void LLFloaterTopObjects::onRefresh(void* data)
{
U32 mode = STAT_REPORT_TOP_SCRIPTS;
U32 flags = 0;
std::string filter = "";
if (sInstance)
{
mode = sInstance->mCurrentMode;
flags = sInstance->mFlags;
filter = sInstance->mFilter;
sInstance->clearList();
}
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LandStatRequest);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
msg->nextBlockFast(_PREHASH_RequestData);
msg->addU32Fast(_PREHASH_ReportType, mode);
msg->addU32Fast(_PREHASH_RequestFlags, flags);
msg->addStringFast(_PREHASH_Filter, filter);
msg->addS32Fast(_PREHASH_ParcelLocalID, 0);
msg->sendReliable(gAgent.getRegionHost());
if (sInstance)
{
sInstance->mFilter.clear();
sInstance->mFlags = 0;
}
}
void LLFloaterTopObjects::onGetByObjectName(LLUICtrl* ctrl, void* data)
{
if (sInstance)
{
sInstance->mFlags = STAT_FILTER_BY_OBJECT;
sInstance->mFilter = sInstance->childGetText("object_name_editor");
onRefresh(NULL);
}
}
void LLFloaterTopObjects::onGetByOwnerName(LLUICtrl* ctrl, void* data)
{
if (sInstance)
{
sInstance->mFlags = STAT_FILTER_BY_OWNER;
sInstance->mFilter = sInstance->childGetText("owner_name_editor");
onRefresh(NULL);
}
}
void LLFloaterTopObjects::showBeacon()
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
if (!list) return;
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
std::string name = first_selected->getColumn(1)->getValue().asString();
std::string pos_string = first_selected->getColumn(3)->getValue().asString();
F32 x, y, z;
S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
if (matched != 3) return;
LLVector3 pos_agent(x, y, z);
LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
std::string tooltip("");
LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM);
}