/** * @file llfloatermyscripts.cpp * @brief LLFloaterMyScripts class implementation. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2019, 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 "llfloatermyscripts.h" #include "llagent.h" #include "llcorehttputil.h" #include "llcoros.h" #include "lleventcoro.h" #include "llfloaterreg.h" #include "llscrolllistctrl.h" #include "lltrans.h" #include "llviewerregion.h" constexpr S32 SIZE_OF_ONE_KB = 1024; LLFloaterMyScripts::LLFloaterMyScripts(const LLSD& seed) : LLFloater(seed), mGotAttachmentMemoryUsed(false), mAttachmentDetailsRequested(false), mAttachmentMemoryMax(0), mAttachmentMemoryUsed(0), mGotAttachmentURLsUsed(false), mAttachmentURLsMax(0), mAttachmentURLsUsed(0) { } bool LLFloaterMyScripts::postBuild() { childSetAction("refresh_list_btn", onClickRefresh, this); std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); getChild("loading_text")->setValue(LLSD(msg_waiting)); mAttachmentDetailsRequested = requestAttachmentDetails(); return true; } // virtual void LLFloaterMyScripts::onOpen(const LLSD& key) { if (!mAttachmentDetailsRequested) { mAttachmentDetailsRequested = requestAttachmentDetails(); } LLFloater::onOpen(key); } bool LLFloaterMyScripts::requestAttachmentDetails() { if (!gAgent.getRegion()) return false; LLSD body; std::string url = gAgent.getRegion()->getCapability("AttachmentResources"); if (!url.empty()) { LLCoros::instance().launch("LLFloaterMyScripts::getAttachmentLimitsCoro", boost::bind(&LLFloaterMyScripts::getAttachmentLimitsCoro, this, url)); return true; } else { return false; } } void LLFloaterMyScripts::getAttachmentLimitsCoro(std::string url) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", 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 attachment limits." << LL_ENDL; return; } LLFloaterMyScripts* instance = LLFloaterReg::getTypedInstance("my_scripts"); if (!instance) { LL_WARNS() << "Failed to get LLFloaterMyScripts instance" << LL_ENDL; return; } instance->getChild("loading_text")->setValue(LLSD(std::string(""))); LLButton* btn = instance->getChild("refresh_list_btn"); if (btn) { btn->setEnabled(true); } result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); instance->setAttachmentDetails(result); } void LLFloaterMyScripts::setAttachmentDetails(LLSD content) { LLScrollListCtrl *list = getChild("scripts_list"); if(!list) { return; } S32 number_attachments = static_cast(content["attachments"].size()); for(int i = 0; i < number_attachments; i++) { std::string humanReadableLocation = ""; if(content["attachments"][i].has("location")) { std::string actualLocation = content["attachments"][i]["location"]; humanReadableLocation = LLTrans::getString(actualLocation.c_str()); } S32 number_objects = static_cast(content["attachments"][i]["objects"].size()); for(int j = 0; j < number_objects; j++) { LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID(); S32 size = 0; if(content["attachments"][i]["objects"][j]["resources"].has("memory")) { size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; } S32 urls = 0; if(content["attachments"][i]["objects"][j]["resources"].has("urls")) { urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger(); } std::string name = content["attachments"][i]["objects"][j]["name"].asString(); LLSD element; element["id"] = task_id; element["columns"][0]["column"] = "size"; element["columns"][0]["value"] = llformat("%d", size); element["columns"][0]["font"] = "SANSSERIF"; element["columns"][0]["halign"] = LLFontGL::RIGHT; element["columns"][1]["column"] = "urls"; element["columns"][1]["value"] = llformat("%d", urls); element["columns"][1]["font"] = "SANSSERIF"; element["columns"][1]["halign"] = LLFontGL::RIGHT; element["columns"][2]["column"] = "name"; element["columns"][2]["value"] = name; element["columns"][2]["font"] = "SANSSERIF"; element["columns"][3]["column"] = "location"; element["columns"][3]["value"] = humanReadableLocation; element["columns"][3]["font"] = "SANSSERIF"; list->addElement(element); } } setAttachmentSummary(content); getChild("loading_text")->setValue(LLSD(std::string(""))); LLButton* btn = getChild("refresh_list_btn"); if(btn) { btn->setEnabled(true); } } void LLFloaterMyScripts::clearList() { LLCtrlListInterface *list = childGetListInterface("scripts_list"); if (list) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); } std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); getChild("loading_text")->setValue(LLSD(msg_waiting)); } void LLFloaterMyScripts::setAttachmentSummary(LLSD content) { if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) { mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; mGotAttachmentMemoryUsed = true; } else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) { mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; mGotAttachmentMemoryUsed = true; } else { LL_WARNS() << "attachment details don't contain memory summary info" << LL_ENDL; return; } if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) { mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger(); mGotAttachmentURLsUsed = true; } else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) { mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger(); mGotAttachmentURLsUsed = true; } else { LL_WARNS() << "attachment details don't contain urls summary info" << LL_ENDL; return; } if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) { LLStringUtil::format_map_t args_attachment_memory; args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); std::string translate_message = "ScriptLimitsMemoryUsedSimple"; if (0 < mAttachmentMemoryMax) { S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); translate_message = "ScriptLimitsMemoryUsed"; } getChild("memory_used")->setValue(LLTrans::getString(translate_message, args_attachment_memory)); } if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) { S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed; LLStringUtil::format_map_t args_attachment_urls; args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed); args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax); args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available); std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls); getChild("urls_used")->setValue(LLSD(msg_attachment_urls)); } } // static void LLFloaterMyScripts::onClickRefresh(void* userdata) { LLFloaterMyScripts* instance = LLFloaterReg::getTypedInstance("my_scripts"); if(instance) { LLButton* btn = instance->getChild("refresh_list_btn"); //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 if(btn) { btn->setEnabled(false); } instance->clearList(); instance->mAttachmentDetailsRequested = instance->requestAttachmentDetails(); } else { LL_WARNS() << "could not find LLFloaterMyScripts instance after refresh button clicked" << LL_ENDL; } }