diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 20:51:58 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-22 20:51:58 +0300 |
commit | 6cc7dd09d5e69cf57e6de7fb568a0ad2693f9c9a (patch) | |
tree | fab23811a5cedc1ebf01479c852ee92ff62b636c /indra/newview/llfloaterscriptlimits.cpp | |
parent | ef8f4819822288e044ea719feb6af7a1f4df4c4e (diff) | |
parent | 7bb5afc11ee5a6af78302a8d76a9a619e2baaab2 (diff) |
Merge pull request #1545 from Ansariel/DRTVWR-600-maint-A
Merge main into DRTVWR-600-maint-a
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 e274b6b954..71ee10bf4a 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;
+ }
+}
+
|