diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/llfloaterscriptlimits.cpp | |
parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) |
Fix line endlings
Diffstat (limited to 'indra/newview/llfloaterscriptlimits.cpp')
-rw-r--r-- | indra/newview/llfloaterscriptlimits.cpp | 1882 |
1 files changed, 941 insertions, 941 deletions
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 71ee10bf4a..1f4e95c229 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -1,941 +1,941 @@ -/**
- * @file llfloaterscriptlimits.cpp
- * @author Gabriel Lee
- * @brief Implementation of the region info and controls floater and panels.
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llfloaterscriptlimits.h"
-
-// library includes
-#include "llavatarnamecache.h"
-#include "llsdutil.h"
-#include "llsdutil_math.h"
-#include "message.h"
-
-#include "llagent.h"
-#include "llfloateravatarpicker.h"
-#include "llfloaterland.h"
-#include "llfloaterreg.h"
-#include "llregionhandle.h"
-#include "llscrolllistctrl.h"
-#include "llscrolllistitem.h"
-#include "llparcel.h"
-#include "lltabcontainer.h"
-#include "lltracker.h"
-#include "lltrans.h"
-#include "llviewercontrol.h"
-#include "lluictrlfactory.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llviewerwindow.h"
-#include "llcorehttputil.h"
-
-///----------------------------------------------------------------------------
-/// LLFloaterScriptLimits
-///----------------------------------------------------------------------------
-
-// debug switches, won't work in release
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-
-// dump responder replies to LL_INFOS() for debugging
-//#define DUMP_REPLIES_TO_LLINFOS
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-#include "llsdserialize.h"
-#include "llwindow.h"
-#endif
-
-// use fake LLSD responses to check the viewer side is working correctly
-// I'm syncing this with the server side efforts so hopfully we can keep
-// the to-ing and fro-ing between the two teams to a minimum
-//#define USE_FAKE_RESPONSES
-
-#ifdef USE_FAKE_RESPONSES
-const S32 FAKE_NUMBER_OF_URLS = 329;
-const S32 FAKE_AVAILABLE_URLS = 731;
-const S32 FAKE_AMOUNT_OF_MEMORY = 66741;
-const S32 FAKE_AVAILABLE_MEMORY = 895577;
-#endif
-
-#endif
-
-const S32 SIZE_OF_ONE_KB = 1024;
-
-LLFloaterScriptLimits::LLFloaterScriptLimits(const LLSD& seed)
- : LLFloater(seed)
-{
-}
-
-bool LLFloaterScriptLimits::postBuild()
-{
- mTab = getChild<LLTabContainer>("scriptlimits_panels");
-
- if(!mTab)
- {
- LL_WARNS() << "Error! couldn't get scriptlimits_panels, aborting Script Information setup" << LL_ENDL;
- return false;
- }
-
- // contruct the panel
- LLPanelScriptLimitsRegionMemory* panel_memory = new LLPanelScriptLimitsRegionMemory;
- mInfoPanels.push_back(panel_memory);
- panel_memory->buildFromFile( "panel_script_limits_region_memory.xml");
- mTab->addTabPanel(panel_memory);
- mTab->selectTab(0);
- return true;
-}
-
-LLFloaterScriptLimits::~LLFloaterScriptLimits()
-{
-}
-
-// public
-void LLFloaterScriptLimits::refresh()
-{
- for(info_panels_t::iterator iter = mInfoPanels.begin();
- iter != mInfoPanels.end(); ++iter)
- {
- (*iter)->refresh();
- }
-}
-
-///----------------------------------------------------------------------------
-// Base class for panels
-///----------------------------------------------------------------------------
-
-LLPanelScriptLimitsInfo::LLPanelScriptLimitsInfo()
- : LLPanel()
-{
-}
-
-
-// virtual
-bool LLPanelScriptLimitsInfo::postBuild()
-{
- refresh();
- return true;
-}
-
-// virtual
-void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr)
-{
-}
-
-///----------------------------------------------------------------------------
-// Memory Panel
-///----------------------------------------------------------------------------
-
-LLPanelScriptLimitsRegionMemory::~LLPanelScriptLimitsRegionMemory()
-{
- if(!mParcelId.isNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- mParcelId.setNull();
- }
-};
-
-bool LLPanelScriptLimitsRegionMemory::getLandScriptResources()
-{
- if (!gAgent.getRegion()) return false;
-
- LLSD body;
- std::string url = gAgent.getRegion()->getCapability("LandResources");
- if (!url.empty())
- {
- LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro",
- boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro, this, url));
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro(std::string url)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptResourcesCoro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
- LLSD postData;
-
- postData["parcel_id"] = mParcelId;
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- LL_WARNS() << "Failed to get script resource info" << LL_ENDL;
- return;
- }
-
- // We could retrieve these sequentially inline from this coroutine. But
- // since the original code retrieved them in parallel I'll spawn two
- // coroutines to do the retrieval.
-
- // The summary service:
- if (result.has("ScriptResourceSummary"))
- {
- std::string urlResourceSummary = result["ScriptResourceSummary"].asString();
- LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro",
- boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro, this, urlResourceSummary));
- }
-
- if (result.has("ScriptResourceDetails"))
- {
- std::string urlResourceDetails = result["ScriptResourceDetails"].asString();
- LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro",
- boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro, this, urlResourceDetails));
- }
-
-
-}
-
-void LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro(std::string url)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptSummaryCoro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- LL_WARNS() << "Unable to retrieve script summary." << LL_ENDL;
- return;
- }
-
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
- if (!instance)
- {
- LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
- return;
- }
-
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if (!tab)
- {
- LL_WARNS() << "Unable to access script limits tab" << LL_ENDL;
- return;
- }
-
- LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
- if (!panelMemory)
- {
- LL_WARNS() << "Unable to get memory panel." << LL_ENDL;
- return;
- }
-
- panelMemory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
-
- LLButton* btn = panelMemory->getChild<LLButton>("refresh_list_btn");
- if (btn)
- {
- btn->setEnabled(true);
- }
-
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- panelMemory->setRegionSummary(result);
-
-}
-
-void LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro(std::string url)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptDetailsCoro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- LL_WARNS() << "Unable to retrieve script details." << LL_ENDL;
- return;
- }
-
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-
- if (!instance)
- {
- LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
- return;
- }
-
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if (!tab)
- {
- LL_WARNS() << "Unable to access script limits tab" << LL_ENDL;
- return;
- }
-
- LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
-
- if (!panelMemory)
- {
- LL_WARNS() << "Unable to get memory panel." << LL_ENDL;
- return;
- }
-
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- panelMemory->setRegionDetails(result);
-}
-
-void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data)
-{
- if(!getLandScriptResources())
- {
- std::string msg_error = LLTrans::getString("ScriptLimitsRequestError");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_error));
- }
- else
- {
- std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
- }
-}
-
-void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id)
-{
- if (!parcel_id.isNull())
- {
- if(!mParcelId.isNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- mParcelId.setNull();
- }
- mParcelId = parcel_id;
- LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this);
- LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id);
- }
- else
- {
- std::string msg_error = LLTrans::getString("ScriptLimitsRequestError");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_error));
- }
-}
-
-// virtual
-void LLPanelScriptLimitsRegionMemory::setErrorStatus(S32 status, const std::string& reason)
-{
- LL_WARNS() << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<LL_ENDL;
-}
-
-// callback from the name cache with an owner name to add to the list
-void LLPanelScriptLimitsRegionMemory::onAvatarNameCache(
- const LLUUID& id,
- const LLAvatarName& av_name)
-{
- onNameCache(id, av_name.getUserName());
-}
-
-// callback from the name cache with an owner name to add to the list
-void LLPanelScriptLimitsRegionMemory::onNameCache(
- const LLUUID& id,
- const std::string& full_name)
-{
- LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
- if(!list)
- {
- return;
- }
-
- std::string name = LLCacheName::buildUsername(full_name);
-
- std::vector<LLSD>::iterator id_itor;
- for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
- {
- LLSD element = *id_itor;
- if(element["owner_id"].asUUID() == id)
- {
- LLScrollListItem* item = list->getItem(element["id"].asUUID());
-
- if(item)
- {
- item->getColumn(3)->setValue(LLSD(name));
- element["columns"][3]["value"] = name;
- }
- }
- }
-}
-
-void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
-{
- LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
-
- if(!list)
- {
- LL_WARNS() << "Error getting the scripts_list control" << LL_ENDL;
- return;
- }
-
- S32 number_parcels = content["parcels"].size();
-
- LLStringUtil::format_map_t args_parcels;
- args_parcels["[PARCELS]"] = llformat ("%d", number_parcels);
- std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels);
- getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_parcels));
-
- uuid_vec_t names_requested;
-
- // This makes the assumption that all objects will have the same set
- // of attributes, ie they will all have, or none will have locations
- // This is a pretty safe assumption as it's reliant on server version.
- bool has_locations = false;
- bool has_local_ids = false;
-
- for(S32 i = 0; i < number_parcels; i++)
- {
- std::string parcel_name = content["parcels"][i]["name"].asString();
- S32 number_objects = content["parcels"][i]["objects"].size();
-
- S32 local_id = 0;
- if(content["parcels"][i].has("local_id"))
- {
- // if any locations are found flag that we can use them and turn on the highlight button
- has_local_ids = true;
- local_id = content["parcels"][i]["local_id"].asInteger();
- }
-
- for(S32 j = 0; j < number_objects; j++)
- {
- S32 size = content["parcels"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB;
-
- S32 urls = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger();
-
- std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString();
- LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID();
- LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID();
- // This field may not be sent by all server versions, but it's OK if
- // it uses the LLSD default of false
- bool is_group_owned = content["parcels"][i]["objects"][j]["is_group_owned"].asBoolean();
-
- F32 location_x = 0.0f;
- F32 location_y = 0.0f;
- F32 location_z = 0.0f;
-
- if(content["parcels"][i]["objects"][j].has("location"))
- {
- // if any locations are found flag that we can use them and turn on the highlight button
- LLVector3 vec = ll_vector3_from_sd(content["parcels"][i]["objects"][j]["location"]);
- has_locations = true;
- location_x = vec.mV[0];
- location_y = vec.mV[1];
- location_z = vec.mV[2];
- }
-
- std::string owner_buf;
-
- // in the future the server will give us owner names, so see if we're there yet:
- if(content["parcels"][i]["objects"][j].has("owner_name"))
- {
- owner_buf = content["parcels"][i]["objects"][j]["owner_name"].asString();
- }
- // ...and if not use the slightly more painful method of disovery:
- else
- {
- bool name_is_cached;
- if (is_group_owned)
- {
- name_is_cached = gCacheName->getGroupName(owner_id, owner_buf);
- }
- else
- {
- LLAvatarName av_name;
- name_is_cached = LLAvatarNameCache::get(owner_id, &av_name);
- owner_buf = av_name.getUserName();
- owner_buf = LLCacheName::buildUsername(owner_buf);
- }
- if(!name_is_cached)
- {
- if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end())
- {
- names_requested.push_back(owner_id);
- if (is_group_owned)
- {
- gCacheName->getGroup(owner_id,
- boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
- this, _1, _2));
- }
- else
- {
- LLAvatarNameCache::get(owner_id,
- boost::bind(&LLPanelScriptLimitsRegionMemory::onAvatarNameCache,
- this, _1, _2));
- }
- }
- }
- }
-
- LLScrollListItem::Params item_params;
- item_params.value = task_id;
-
- LLScrollListCell::Params cell_params;
- cell_params.font = LLFontGL::getFontSansSerif();
- // Start out right justifying numeric displays
- cell_params.font_halign = LLFontGL::RIGHT;
-
- cell_params.column = "size";
- cell_params.value = size;
- item_params.columns.add(cell_params);
-
- cell_params.column = "urls";
- cell_params.value = urls;
- item_params.columns.add(cell_params);
-
- cell_params.font_halign = LLFontGL::LEFT;
- // The rest of the columns are text to left justify them
- cell_params.column = "name";
- cell_params.value = name_buf;
- item_params.columns.add(cell_params);
-
- cell_params.column = "owner";
- cell_params.value = owner_buf;
- item_params.columns.add(cell_params);
-
- cell_params.column = "parcel";
- cell_params.value = parcel_name;
- item_params.columns.add(cell_params);
-
- cell_params.column = "location";
- cell_params.value = has_locations
- ? llformat("<%0.0f, %0.0f, %0.0f>", location_x, location_y, location_z)
- : "";
- item_params.columns.add(cell_params);
-
- list->addRow(item_params);
-
- LLSD element;
- element["owner_id"] = owner_id;
-
- element["id"] = task_id;
- element["local_id"] = local_id;
- mObjectListItems.push_back(element);
- }
- }
-
- if (has_locations)
- {
- LLButton* btn = getChild<LLButton>("highlight_btn");
- if(btn)
- {
- btn->setVisible(true);
- }
- }
-
- if (has_local_ids)
- {
- LLButton* btn = getChild<LLButton>("return_btn");
- if(btn)
- {
- btn->setVisible(true);
- }
- }
-
- // save the structure to make object return easier
- mContent = content;
-}
-
-void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content)
-{
- if(content["summary"]["used"][0]["type"].asString() == std::string("memory"))
- {
- mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
- mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB;
- mGotParcelMemoryUsed = true;
- }
- else if(content["summary"]["used"][1]["type"].asString() == std::string("memory"))
- {
- mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
- mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB;
- mGotParcelMemoryUsed = true;
- }
- else
- {
- LL_WARNS() << "summary doesn't contain memory info" << LL_ENDL;
- return;
- }
-
- if(content["summary"]["used"][0]["type"].asString() == std::string("urls"))
- {
- mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger();
- mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger();
- mGotParcelURLsUsed = true;
- }
- else if(content["summary"]["used"][1]["type"].asString() == std::string("urls"))
- {
- mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger();
- mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger();
- mGotParcelURLsUsed = true;
- }
- else
- {
- LL_WARNS() << "summary doesn't contain urls info" << LL_ENDL;
- return;
- }
-
- if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0))
- {
- LLStringUtil::format_map_t args_parcel_memory;
- args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed);
- std::string translate_message = "ScriptLimitsMemoryUsedSimple";
-
- if (0 < mParcelMemoryMax)
- {
- S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed;
-
- args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax);
- args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available);
- translate_message = "ScriptLimitsMemoryUsed";
- }
-
- std::string msg_parcel_memory = LLTrans::getString(translate_message, args_parcel_memory);
- getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_parcel_memory));
- }
-
- if((mParcelURLsUsed >= 0) && (mParcelURLsMax >= 0))
- {
- S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed;
-
- LLStringUtil::format_map_t args_parcel_urls;
- args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed);
- args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax);
- args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available);
- std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls);
- getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_parcel_urls));
- }
-}
-
-bool LLPanelScriptLimitsRegionMemory::postBuild()
-{
- childSetAction("refresh_list_btn", onClickRefresh, this);
- childSetAction("highlight_btn", onClickHighlight, this);
- childSetAction("return_btn", onClickReturn, this);
-
- std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
-
- LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
- if(!list)
- {
- return false;
- }
- list->setCommitCallback(boost::bind(&LLPanelScriptLimitsRegionMemory::checkButtonsEnabled, this));
- checkButtonsEnabled();
-
- //set all columns to resizable mode even if some columns will be empty
- for(S32 column = 0; column < list->getNumColumns(); column++)
- {
- LLScrollListColumn* columnp = list->getColumn(column);
- columnp->mHeader->setHasResizableElement(true);
- }
-
- return StartRequestChain();
-}
-
-bool LLPanelScriptLimitsRegionMemory::StartRequestChain()
-{
- LLUUID region_id;
-
- LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
- if(!instance)
- {
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
- //might have to do parent post build here
- //if not logic below could use early outs
- return false;
- }
- LLParcel* parcel = instance->getCurrentSelectedParcel();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
-
- if ((region) && (parcel))
- {
- LLUUID current_region_id = gAgent.getRegion()->getRegionID();
- LLVector3 parcel_center = parcel->getCenterpoint();
-
- region_id = region->getRegionID();
-
- if(region_id != current_region_id)
- {
- std::string msg_wrong_region = LLTrans::getString("ScriptLimitsRequestWrongRegion");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_wrong_region));
- return false;
- }
-
- LLVector3d pos_global = region->getCenterGlobal();
-
- LLSD body;
- std::string url = region->getCapability("RemoteParcelRequest");
- if (!url.empty())
- {
- LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
- region_id, parcel_center, pos_global, getObserverHandle());
- }
- else
- {
- LL_WARNS() << "Can't get parcel info for script information request" << region_id
- << ". Region: " << region->getName()
- << " does not support RemoteParcelRequest" << LL_ENDL;
-
- std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
- }
- }
- else
- {
- std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestNoParcelSelected");
- getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting));
- }
-
- return LLPanelScriptLimitsInfo::postBuild();
-}
-
-void LLPanelScriptLimitsRegionMemory::clearList()
-{
- LLCtrlListInterface *list = childGetListInterface("scripts_list");
-
- if (list)
- {
- list->operateOnAll(LLCtrlListInterface::OP_DELETE);
- }
-
- mGotParcelMemoryUsed = false;
- mGotParcelMemoryMax = false;
- mGotParcelURLsUsed = false;
- mGotParcelURLsMax = false;
-
- LLStringUtil::format_map_t args_parcel_memory;
- std::string msg_empty_string("");
- getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_empty_string));
- getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_empty_string));
- getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string));
-
- mObjectListItems.clear();
- checkButtonsEnabled();
-}
-
-void LLPanelScriptLimitsRegionMemory::checkButtonsEnabled()
-{
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list");
- getChild<LLButton>("highlight_btn")->setEnabled(list->getNumSelected() > 0);
- getChild<LLButton>("return_btn")->setEnabled(list->getNumSelected() > 0);
-}
-
-// static
-void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata)
-{
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
- if(instance)
- {
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if(tab)
- {
- LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
- if(panel_memory)
- {
- //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer!
- //turn the button off, then turn it on when we get a response
- LLButton* btn = panel_memory->getChild<LLButton>("refresh_list_btn");
- if(btn)
- {
- btn->setEnabled(false);
- }
- panel_memory->clearList();
-
- panel_memory->StartRequestChain();
- }
- }
- return;
- }
- else
- {
- LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << LL_ENDL;
- return;
- }
-}
-
-void LLPanelScriptLimitsRegionMemory::showBeacon()
-{
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list");
- if (!list) return;
-
- LLScrollListItem* first_selected = list->getFirstSelected();
- if (!first_selected) return;
-
- std::string name = first_selected->getColumn(2)->getValue().asString();
- std::string pos_string = first_selected->getColumn(5)->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);
-}
-
-// static
-void LLPanelScriptLimitsRegionMemory::onClickHighlight(void* userdata)
-{
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
- if(instance)
- {
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if(tab)
- {
- LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
- if(panel)
- {
- panel->showBeacon();
- }
- }
- return;
- }
- else
- {
- LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << LL_ENDL;
- return;
- }
-}
-
-void LLPanelScriptLimitsRegionMemory::returnObjectsFromParcel(S32 local_id)
-{
- LLMessageSystem *msg = gMessageSystem;
-
- LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
-
- LLCtrlListInterface *list = childGetListInterface("scripts_list");
- if (!list || list->getItemCount() == 0) return;
-
- std::vector<LLSD>::iterator id_itor;
-
- bool start_message = true;
-
- for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
- {
- LLSD element = *id_itor;
- if (!list->isSelected(element["id"].asUUID()))
- {
- // Selected only
- continue;
- }
-
- if(element["local_id"].asInteger() != local_id)
- {
- // Not the parcel we are looking for
- continue;
- }
-
- if (start_message)
- {
- msg->newMessageFast(_PREHASH_ParcelReturnObjects);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ParcelData);
- msg->addS32Fast(_PREHASH_LocalID, element["local_id"].asInteger());
- msg->addU32Fast(_PREHASH_ReturnType, RT_LIST);
- start_message = false;
- }
-
- msg->nextBlockFast(_PREHASH_TaskIDs);
- msg->addUUIDFast(_PREHASH_TaskID, element["id"].asUUID());
-
- if (msg->isSendFullFast(_PREHASH_TaskIDs))
- {
- msg->sendReliable(region->getHost());
- start_message = true;
- }
- }
-
- if (!start_message)
- {
- msg->sendReliable(region->getHost());
- }
-}
-
-void LLPanelScriptLimitsRegionMemory::returnObjects()
-{
- if(!mContent.has("parcels"))
- {
- return;
- }
-
- S32 number_parcels = mContent["parcels"].size();
-
- // a message per parcel containing all objects to be returned from that parcel
- for(S32 i = 0; i < number_parcels; i++)
- {
- S32 local_id = 0;
- if(mContent["parcels"][i].has("local_id"))
- {
- local_id = mContent["parcels"][i]["local_id"].asInteger();
- returnObjectsFromParcel(local_id);
- }
- }
-
- onClickRefresh(NULL);
-}
-
-
-// static
-void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata)
-{
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
- if(instance)
- {
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if(tab)
- {
- LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
- if(panel)
- {
- panel->returnObjects();
- }
- }
- return;
- }
- else
- {
- LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << LL_ENDL;
- return;
- }
-}
-
+/** + * @file llfloaterscriptlimits.cpp + * @author Gabriel Lee + * @brief Implementation of the region info and controls floater and panels. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterscriptlimits.h" + +// library includes +#include "llavatarnamecache.h" +#include "llsdutil.h" +#include "llsdutil_math.h" +#include "message.h" + +#include "llagent.h" +#include "llfloateravatarpicker.h" +#include "llfloaterland.h" +#include "llfloaterreg.h" +#include "llregionhandle.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "llparcel.h" +#include "lltabcontainer.h" +#include "lltracker.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "lluictrlfactory.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llcorehttputil.h" + +///---------------------------------------------------------------------------- +/// LLFloaterScriptLimits +///---------------------------------------------------------------------------- + +// debug switches, won't work in release +#ifndef LL_RELEASE_FOR_DOWNLOAD + +// dump responder replies to LL_INFOS() for debugging +//#define DUMP_REPLIES_TO_LLINFOS + +#ifdef DUMP_REPLIES_TO_LLINFOS +#include "llsdserialize.h" +#include "llwindow.h" +#endif + +// use fake LLSD responses to check the viewer side is working correctly +// I'm syncing this with the server side efforts so hopfully we can keep +// the to-ing and fro-ing between the two teams to a minimum +//#define USE_FAKE_RESPONSES + +#ifdef USE_FAKE_RESPONSES +const S32 FAKE_NUMBER_OF_URLS = 329; +const S32 FAKE_AVAILABLE_URLS = 731; +const S32 FAKE_AMOUNT_OF_MEMORY = 66741; +const S32 FAKE_AVAILABLE_MEMORY = 895577; +#endif + +#endif + +const S32 SIZE_OF_ONE_KB = 1024; + +LLFloaterScriptLimits::LLFloaterScriptLimits(const LLSD& seed) + : LLFloater(seed) +{ +} + +bool LLFloaterScriptLimits::postBuild() +{ + mTab = getChild<LLTabContainer>("scriptlimits_panels"); + + if(!mTab) + { + LL_WARNS() << "Error! couldn't get scriptlimits_panels, aborting Script Information setup" << LL_ENDL; + return false; + } + + // contruct the panel + LLPanelScriptLimitsRegionMemory* panel_memory = new LLPanelScriptLimitsRegionMemory; + mInfoPanels.push_back(panel_memory); + panel_memory->buildFromFile( "panel_script_limits_region_memory.xml"); + mTab->addTabPanel(panel_memory); + mTab->selectTab(0); + return true; +} + +LLFloaterScriptLimits::~LLFloaterScriptLimits() +{ +} + +// public +void LLFloaterScriptLimits::refresh() +{ + for(info_panels_t::iterator iter = mInfoPanels.begin(); + iter != mInfoPanels.end(); ++iter) + { + (*iter)->refresh(); + } +} + +///---------------------------------------------------------------------------- +// Base class for panels +///---------------------------------------------------------------------------- + +LLPanelScriptLimitsInfo::LLPanelScriptLimitsInfo() + : LLPanel() +{ +} + + +// virtual +bool LLPanelScriptLimitsInfo::postBuild() +{ + refresh(); + return true; +} + +// virtual +void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr) +{ +} + +///---------------------------------------------------------------------------- +// Memory Panel +///---------------------------------------------------------------------------- + +LLPanelScriptLimitsRegionMemory::~LLPanelScriptLimitsRegionMemory() +{ + if(!mParcelId.isNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); + mParcelId.setNull(); + } +}; + +bool LLPanelScriptLimitsRegionMemory::getLandScriptResources() +{ + if (!gAgent.getRegion()) return false; + + LLSD body; + std::string url = gAgent.getRegion()->getCapability("LandResources"); + if (!url.empty()) + { + LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro", + boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro, this, url)); + return true; + } + else + { + return false; + } +} + +void LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptResourcesCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD postData; + + postData["parcel_id"] = mParcelId; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Failed to get script resource info" << LL_ENDL; + return; + } + + // We could retrieve these sequentially inline from this coroutine. But + // since the original code retrieved them in parallel I'll spawn two + // coroutines to do the retrieval. + + // The summary service: + if (result.has("ScriptResourceSummary")) + { + std::string urlResourceSummary = result["ScriptResourceSummary"].asString(); + LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro", + boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro, this, urlResourceSummary)); + } + + if (result.has("ScriptResourceDetails")) + { + std::string urlResourceDetails = result["ScriptResourceDetails"].asString(); + LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro", + boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro, this, urlResourceDetails)); + } + + +} + +void LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptSummaryCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Unable to retrieve script summary." << LL_ENDL; + return; + } + + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); + if (!instance) + { + LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL; + return; + } + + LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); + if (!tab) + { + LL_WARNS() << "Unable to access script limits tab" << LL_ENDL; + return; + } + + LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if (!panelMemory) + { + LL_WARNS() << "Unable to get memory panel." << LL_ENDL; + return; + } + + panelMemory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string(""))); + + LLButton* btn = panelMemory->getChild<LLButton>("refresh_list_btn"); + if (btn) + { + btn->setEnabled(true); + } + + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + panelMemory->setRegionSummary(result); + +} + +void LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptDetailsCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Unable to retrieve script details." << LL_ENDL; + return; + } + + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); + + if (!instance) + { + LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL; + return; + } + + LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); + if (!tab) + { + LL_WARNS() << "Unable to access script limits tab" << LL_ENDL; + return; + } + + LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + + if (!panelMemory) + { + LL_WARNS() << "Unable to get memory panel." << LL_ENDL; + return; + } + + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + panelMemory->setRegionDetails(result); +} + +void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data) +{ + if(!getLandScriptResources()) + { + std::string msg_error = LLTrans::getString("ScriptLimitsRequestError"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_error)); + } + else + { + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting)); + } +} + +void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id) +{ + if (!parcel_id.isNull()) + { + if(!mParcelId.isNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); + mParcelId.setNull(); + } + mParcelId = parcel_id; + LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); + } + else + { + std::string msg_error = LLTrans::getString("ScriptLimitsRequestError"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_error)); + } +} + +// virtual +void LLPanelScriptLimitsRegionMemory::setErrorStatus(S32 status, const std::string& reason) +{ + LL_WARNS() << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<LL_ENDL; +} + +// callback from the name cache with an owner name to add to the list +void LLPanelScriptLimitsRegionMemory::onAvatarNameCache( + const LLUUID& id, + const LLAvatarName& av_name) +{ + onNameCache(id, av_name.getUserName()); +} + +// callback from the name cache with an owner name to add to the list +void LLPanelScriptLimitsRegionMemory::onNameCache( + const LLUUID& id, + const std::string& full_name) +{ + LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + if(!list) + { + return; + } + + std::string name = LLCacheName::buildUsername(full_name); + + std::vector<LLSD>::iterator id_itor; + for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) + { + LLSD element = *id_itor; + if(element["owner_id"].asUUID() == id) + { + LLScrollListItem* item = list->getItem(element["id"].asUUID()); + + if(item) + { + item->getColumn(3)->setValue(LLSD(name)); + element["columns"][3]["value"] = name; + } + } + } +} + +void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) +{ + LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + + if(!list) + { + LL_WARNS() << "Error getting the scripts_list control" << LL_ENDL; + return; + } + + S32 number_parcels = content["parcels"].size(); + + LLStringUtil::format_map_t args_parcels; + args_parcels["[PARCELS]"] = llformat ("%d", number_parcels); + std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels); + getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_parcels)); + + uuid_vec_t names_requested; + + // This makes the assumption that all objects will have the same set + // of attributes, ie they will all have, or none will have locations + // This is a pretty safe assumption as it's reliant on server version. + bool has_locations = false; + bool has_local_ids = false; + + for(S32 i = 0; i < number_parcels; i++) + { + std::string parcel_name = content["parcels"][i]["name"].asString(); + S32 number_objects = content["parcels"][i]["objects"].size(); + + S32 local_id = 0; + if(content["parcels"][i].has("local_id")) + { + // if any locations are found flag that we can use them and turn on the highlight button + has_local_ids = true; + local_id = content["parcels"][i]["local_id"].asInteger(); + } + + for(S32 j = 0; j < number_objects; j++) + { + S32 size = content["parcels"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; + + S32 urls = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger(); + + std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString(); + LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID(); + LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); + // This field may not be sent by all server versions, but it's OK if + // it uses the LLSD default of false + bool is_group_owned = content["parcels"][i]["objects"][j]["is_group_owned"].asBoolean(); + + F32 location_x = 0.0f; + F32 location_y = 0.0f; + F32 location_z = 0.0f; + + if(content["parcels"][i]["objects"][j].has("location")) + { + // if any locations are found flag that we can use them and turn on the highlight button + LLVector3 vec = ll_vector3_from_sd(content["parcels"][i]["objects"][j]["location"]); + has_locations = true; + location_x = vec.mV[0]; + location_y = vec.mV[1]; + location_z = vec.mV[2]; + } + + std::string owner_buf; + + // in the future the server will give us owner names, so see if we're there yet: + if(content["parcels"][i]["objects"][j].has("owner_name")) + { + owner_buf = content["parcels"][i]["objects"][j]["owner_name"].asString(); + } + // ...and if not use the slightly more painful method of disovery: + else + { + bool name_is_cached; + if (is_group_owned) + { + name_is_cached = gCacheName->getGroupName(owner_id, owner_buf); + } + else + { + LLAvatarName av_name; + name_is_cached = LLAvatarNameCache::get(owner_id, &av_name); + owner_buf = av_name.getUserName(); + owner_buf = LLCacheName::buildUsername(owner_buf); + } + if(!name_is_cached) + { + if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) + { + names_requested.push_back(owner_id); + if (is_group_owned) + { + gCacheName->getGroup(owner_id, + boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, + this, _1, _2)); + } + else + { + LLAvatarNameCache::get(owner_id, + boost::bind(&LLPanelScriptLimitsRegionMemory::onAvatarNameCache, + this, _1, _2)); + } + } + } + } + + LLScrollListItem::Params item_params; + item_params.value = task_id; + + LLScrollListCell::Params cell_params; + cell_params.font = LLFontGL::getFontSansSerif(); + // Start out right justifying numeric displays + cell_params.font_halign = LLFontGL::RIGHT; + + cell_params.column = "size"; + cell_params.value = size; + item_params.columns.add(cell_params); + + cell_params.column = "urls"; + cell_params.value = urls; + item_params.columns.add(cell_params); + + cell_params.font_halign = LLFontGL::LEFT; + // The rest of the columns are text to left justify them + cell_params.column = "name"; + cell_params.value = name_buf; + item_params.columns.add(cell_params); + + cell_params.column = "owner"; + cell_params.value = owner_buf; + item_params.columns.add(cell_params); + + cell_params.column = "parcel"; + cell_params.value = parcel_name; + item_params.columns.add(cell_params); + + cell_params.column = "location"; + cell_params.value = has_locations + ? llformat("<%0.0f, %0.0f, %0.0f>", location_x, location_y, location_z) + : ""; + item_params.columns.add(cell_params); + + list->addRow(item_params); + + LLSD element; + element["owner_id"] = owner_id; + + element["id"] = task_id; + element["local_id"] = local_id; + mObjectListItems.push_back(element); + } + } + + if (has_locations) + { + LLButton* btn = getChild<LLButton>("highlight_btn"); + if(btn) + { + btn->setVisible(true); + } + } + + if (has_local_ids) + { + LLButton* btn = getChild<LLButton>("return_btn"); + if(btn) + { + btn->setVisible(true); + } + } + + // save the structure to make object return easier + mContent = content; +} + +void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content) +{ + if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) + { + mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotParcelMemoryUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) + { + mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotParcelMemoryUsed = true; + } + else + { + LL_WARNS() << "summary doesn't contain memory info" << LL_ENDL; + return; + } + + if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) + { + mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); + mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger(); + mGotParcelURLsUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) + { + mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); + mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger(); + mGotParcelURLsUsed = true; + } + else + { + LL_WARNS() << "summary doesn't contain urls info" << LL_ENDL; + return; + } + + if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0)) + { + LLStringUtil::format_map_t args_parcel_memory; + args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); + std::string translate_message = "ScriptLimitsMemoryUsedSimple"; + + if (0 < mParcelMemoryMax) + { + S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; + + args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); + args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); + translate_message = "ScriptLimitsMemoryUsed"; + } + + std::string msg_parcel_memory = LLTrans::getString(translate_message, args_parcel_memory); + getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_parcel_memory)); + } + + if((mParcelURLsUsed >= 0) && (mParcelURLsMax >= 0)) + { + S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed; + + LLStringUtil::format_map_t args_parcel_urls; + args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); + args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax); + args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available); + std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls); + getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_parcel_urls)); + } +} + +bool LLPanelScriptLimitsRegionMemory::postBuild() +{ + childSetAction("refresh_list_btn", onClickRefresh, this); + childSetAction("highlight_btn", onClickHighlight, this); + childSetAction("return_btn", onClickReturn, this); + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting)); + + LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); + if(!list) + { + return false; + } + list->setCommitCallback(boost::bind(&LLPanelScriptLimitsRegionMemory::checkButtonsEnabled, this)); + checkButtonsEnabled(); + + //set all columns to resizable mode even if some columns will be empty + for(S32 column = 0; column < list->getNumColumns(); column++) + { + LLScrollListColumn* columnp = list->getColumn(column); + columnp->mHeader->setHasResizableElement(true); + } + + return StartRequestChain(); +} + +bool LLPanelScriptLimitsRegionMemory::StartRequestChain() +{ + LLUUID region_id; + + LLFloaterLand* instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land"); + if(!instance) + { + getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string(""))); + //might have to do parent post build here + //if not logic below could use early outs + return false; + } + LLParcel* parcel = instance->getCurrentSelectedParcel(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + + if ((region) && (parcel)) + { + LLUUID current_region_id = gAgent.getRegion()->getRegionID(); + LLVector3 parcel_center = parcel->getCenterpoint(); + + region_id = region->getRegionID(); + + if(region_id != current_region_id) + { + std::string msg_wrong_region = LLTrans::getString("ScriptLimitsRequestWrongRegion"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_wrong_region)); + return false; + } + + LLVector3d pos_global = region->getCenterGlobal(); + + LLSD body; + std::string url = region->getCapability("RemoteParcelRequest"); + if (!url.empty()) + { + LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url, + region_id, parcel_center, pos_global, getObserverHandle()); + } + else + { + LL_WARNS() << "Can't get parcel info for script information request" << region_id + << ". Region: " << region->getName() + << " does not support RemoteParcelRequest" << LL_ENDL; + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting)); + } + } + else + { + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestNoParcelSelected"); + getChild<LLUICtrl>("loading_text")->setValue(LLSD(msg_waiting)); + } + + return LLPanelScriptLimitsInfo::postBuild(); +} + +void LLPanelScriptLimitsRegionMemory::clearList() +{ + LLCtrlListInterface *list = childGetListInterface("scripts_list"); + + if (list) + { + list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + mGotParcelMemoryUsed = false; + mGotParcelMemoryMax = false; + mGotParcelURLsUsed = false; + mGotParcelURLsMax = false; + + LLStringUtil::format_map_t args_parcel_memory; + std::string msg_empty_string(""); + getChild<LLUICtrl>("memory_used")->setValue(LLSD(msg_empty_string)); + getChild<LLUICtrl>("urls_used")->setValue(LLSD(msg_empty_string)); + getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string)); + + mObjectListItems.clear(); + checkButtonsEnabled(); +} + +void LLPanelScriptLimitsRegionMemory::checkButtonsEnabled() +{ + LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); + getChild<LLButton>("highlight_btn")->setEnabled(list->getNumSelected() > 0); + getChild<LLButton>("return_btn")->setEnabled(list->getNumSelected() > 0); +} + +// static +void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); + if(instance) + { + LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel_memory) + { + //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer! + //turn the button off, then turn it on when we get a response + LLButton* btn = panel_memory->getChild<LLButton>("refresh_list_btn"); + if(btn) + { + btn->setEnabled(false); + } + panel_memory->clearList(); + + panel_memory->StartRequestChain(); + } + } + return; + } + else + { + LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << LL_ENDL; + return; + } +} + +void LLPanelScriptLimitsRegionMemory::showBeacon() +{ + LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); + if (!list) return; + + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + + std::string name = first_selected->getColumn(2)->getValue().asString(); + std::string pos_string = first_selected->getColumn(5)->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); +} + +// static +void LLPanelScriptLimitsRegionMemory::onClickHighlight(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); + if(instance) + { + LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel) + { + panel->showBeacon(); + } + } + return; + } + else + { + LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << LL_ENDL; + return; + } +} + +void LLPanelScriptLimitsRegionMemory::returnObjectsFromParcel(S32 local_id) +{ + LLMessageSystem *msg = gMessageSystem; + + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + LLCtrlListInterface *list = childGetListInterface("scripts_list"); + if (!list || list->getItemCount() == 0) return; + + std::vector<LLSD>::iterator id_itor; + + bool start_message = true; + + for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) + { + LLSD element = *id_itor; + if (!list->isSelected(element["id"].asUUID())) + { + // Selected only + continue; + } + + if(element["local_id"].asInteger() != local_id) + { + // Not the parcel we are looking for + continue; + } + + if (start_message) + { + msg->newMessageFast(_PREHASH_ParcelReturnObjects); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, element["local_id"].asInteger()); + msg->addU32Fast(_PREHASH_ReturnType, RT_LIST); + start_message = false; + } + + msg->nextBlockFast(_PREHASH_TaskIDs); + msg->addUUIDFast(_PREHASH_TaskID, element["id"].asUUID()); + + if (msg->isSendFullFast(_PREHASH_TaskIDs)) + { + msg->sendReliable(region->getHost()); + start_message = true; + } + } + + if (!start_message) + { + msg->sendReliable(region->getHost()); + } +} + +void LLPanelScriptLimitsRegionMemory::returnObjects() +{ + if(!mContent.has("parcels")) + { + return; + } + + S32 number_parcels = mContent["parcels"].size(); + + // a message per parcel containing all objects to be returned from that parcel + for(S32 i = 0; i < number_parcels; i++) + { + S32 local_id = 0; + if(mContent["parcels"][i].has("local_id")) + { + local_id = mContent["parcels"][i]["local_id"].asInteger(); + returnObjectsFromParcel(local_id); + } + } + + onClickRefresh(NULL); +} + + +// static +void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); + if(instance) + { + LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + if(panel) + { + panel->returnObjects(); + } + } + return; + } + else + { + LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << LL_ENDL; + return; + } +} + |