123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788 |
- /**
- * @file llfloaterscriptqueue.cpp
- * @brief LLFloaterScriptQueue class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- /**
- *
- * Implementation of the script queue which keeps an array of object
- * UUIDs and manipulates all of the scripts on each of them.
- *
- */
- #include "llviewerprecompiledheaders.h"
- #include <utility>
- #include "llfloaterscriptqueue.h"
- #include "llbutton.h"
- #include "lldir.h"
- #include "llexperiencecache.h"
- #include "llscrolllistctrl.h"
- #include "lluictrlfactory.h"
- #include "lluistring.h"
- #include "llagent.h"
- #include "llchat.h"
- #include "llfloaterchat.h"
- #include "llselectmgr.h"
- #include "llviewerassetupload.h"
- #include "llviewercontrol.h"
- #include "llviewerobjectlist.h"
- #include "llviewerregion.h"
- #include "llviewerstats.h"
- struct LLScriptQueueData
- {
- LLUUID mQueueID;
- LLUUID mTaskId;
- LLPointer<LLInventoryItem> mItem;
- LLHost mHost;
- LLUUID mExperienceId;
- std::string mExperiencename;
- LLScriptQueueData(const LLUUID& q_id, const LLUUID& task_id,
- LLInventoryItem* item, const LLHost& host)
- : mQueueID(q_id),
- mTaskId(task_id),
- mItem(new LLInventoryItem(item)),
- mHost(host)
- {
- }
- };
- // NOTE: minor specialization of LLScriptAssetUpload: it does not require a
- // buffer (and does not save a buffer to the cache) and it finds the compile
- // queue floater and displays a compiling message.
- class LLQueuedScriptAssetUpload final : public LLScriptAssetUpload
- {
- protected:
- LOG_CLASS(LLQueuedScriptAssetUpload);
- public:
- LLQueuedScriptAssetUpload(const LLUUID& task_id, const LLUUID& item_id,
- const LLUUID& asset_id, TargetType_t target_type,
- bool running, const std::string& script_name,
- const LLUUID& queue_id, const LLUUID& exp_id,
- task_uploaded_cb_t finish)
- : LLScriptAssetUpload(task_id, item_id, target_type, running, exp_id,
- // *TODO: provide a proper failed_cb_t callback.
- LLStringUtil::null, finish, failed_cb_t()),
- mScriptName(script_name),
- mQueueId(queue_id)
- {
- setAssetId(asset_id);
- }
- LLSD prepareUpload() override
- {
- // NOTE: the parent class (LLScriptAssetUpload) will attempt to save
- // the script buffer into to the cache. Since the resource is already
- // in the cache we do not want to do that. Just put a compiling message
- // in the window and move on.
- LLFloaterCompileQueue* queue;
- queue = (LLFloaterCompileQueue*)LLFloaterScriptQueue::findInstance(mQueueId);
- if (queue)
- {
- std::string message = queue->getString("compiling") + " ";
- queue->logMessage(message + mScriptName);
- }
- return LLSD().with("success", LLSD::Boolean(true));
- }
- private:
- void setScriptName(const std::string& name) { mScriptName = name; }
- private:
- LLUUID mQueueId;
- std::string mScriptName;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // Class LLFloaterScriptQueue
- ///////////////////////////////////////////////////////////////////////////////
- //static
- LLFloaterScriptQueue::instances_map_t LLFloaterScriptQueue::sInstances;
- LLFloaterScriptQueue::LLFloaterScriptQueue(const std::string& title,
- const std::string& verb)
- : LLFloater("script queue"),
- mDone(false)
- {
- mID.generate();
- sInstances[mID] = this;
- LLUICtrlFactory::getInstance()->buildFloater(this,
- "floater_script_queue.xml");
- setTitle(getString(title));
- mVerb = getString(verb);
- }
- //virtual
- LLFloaterScriptQueue::~LLFloaterScriptQueue()
- {
- sInstances.erase(mID);
- }
- //virtual
- bool LLFloaterScriptQueue::postBuild()
- {
- mCloseBtn = getChild<LLButton>("close");
- mCloseBtn->setClickedCallback(onCloseBtn, this);
- mCloseBtn->setEnabled(false);
- mMessages = getChild<LLScrollListCtrl>("queue output");
- return true;
- }
- // Finds an instance by Id. Returns NULL if it does not exist.
- //static
- LLFloaterScriptQueue* LLFloaterScriptQueue::findInstance(const LLUUID& id)
- {
- instances_map_t::iterator it = sInstances.find(id);
- return it != sInstances.end() ? it->second : NULL;
- }
- void LLFloaterScriptQueue::logMessage(const std::string& message)
- {
- mMessages->addCommentText(message);
- }
- void LLFloaterScriptQueue::requestInventory(LLViewerObject* objectp)
- {
- if (objectp && !hasRegisteredListener(objectp))
- {
- registerVOInventoryListener(objectp, NULL);
- requestVOInventory(objectp);
- }
- }
- // This is the callback method for the viewer object currently being worked on.
- //virtual
- void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* objectp,
- LLInventoryObject::object_list_t* inv,
- S32, void*)
- {
- if (!objectp)
- {
- return;
- }
- llinfos << "Processing object " << objectp->getID() << llendl;
- removeVOInventoryListener(objectp);
- if (inv && objectp->getID() == mCurrentObjectID)
- {
- llinfos << "Processing object " << mCurrentObjectID << llendl;
- handleInventory(objectp, inv);
- }
- else
- {
- // No inventory for the current primitive: move to the next.
- llinfos << "No inventory for " << mCurrentObjectID << llendl;
- nextObject();
- }
- }
- //static
- void LLFloaterScriptQueue::onCloseBtn(void* user_data)
- {
- LLFloaterScriptQueue* self = (LLFloaterScriptQueue*)user_data;
- self->close();
- }
- bool LLFloaterScriptQueue::start()
- {
- // Note: we add all the selected objects, be them flagged as scripted or
- // not, because this info is received asynchronously from the server and
- // may not yet be known to the viewer, especially in child primitives. We
- // therefore need to retreive the inventory for each and every selected
- // primitive.
- LLObjectSelectionHandle object_selection = gSelectMgr.getSelection();
- for (LLObjectSelection::valid_iterator
- iter = object_selection->valid_begin(),
- end = object_selection->valid_end();
- iter != end; ++iter)
- {
- LLSelectNode* obj = *iter;
- if (!obj) continue; // Paranoia
- LLViewerObject* vobj = obj->getObject();
- if (!vobj || vobj->isDead())
- {
- // Object gone or soon gone !
- continue;
- }
- LLUUID id = vobj->getID();
- if (obj->mCreationDate == 0)
- {
- llwarns << "Object skipped due to missing information from the server. Id: "
- << id << llendl;
- }
- else if (vobj->permModify())
- {
- llinfos << "Adding object id: " << id << llendl;
- mObjectIDs.emplace_back(id);
- }
- }
- LLUIString starting = getString("starting");
- starting.setArg("[VERB]", mVerb);
- starting.setArg("[ITEMS]", llformat("%d", mObjectIDs.size()));
- logMessage(starting.getString());
- return startQueue();
- }
- bool LLFloaterScriptQueue::nextObject()
- {
- bool successful_start = false;
- do
- {
- mCurrentObjectID.setNull();
- S32 count = mObjectIDs.size();
- llinfos << count << " objects left to process." << llendl;
- if (count > 0)
- {
- mCurrentObjectID = mObjectIDs.back();
- mObjectIDs.pop_back();
- LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
- if (obj && !obj->isDead())
- {
- llinfos << "Requesting inventory for " << mCurrentObjectID
- << llendl;
- requestInventory(obj);
- successful_start = true;
- }
- else
- {
- llinfos << "Removed dead object id: " << mCurrentObjectID
- << llendl;
- mCurrentObjectID.setNull();
- }
- }
- llinfos << "Operation "
- << (successful_start ? "successful" : "unsuccessful")
- << llendl;
- }
- while (mObjectIDs.size() > 0 && !successful_start);
- if (isDone() && !mDone)
- {
- mDone = true;
- logMessage(getString("done"));
- mCloseBtn->setEnabled(true);
- }
- return successful_start;
- }
- //virtual
- bool LLFloaterScriptQueue::startQueue()
- {
- return nextObject();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Class LLFloaterCompileQueue
- ///////////////////////////////////////////////////////////////////////////////
- //static
- LLFloaterCompileQueue* LLFloaterCompileQueue::create(bool mono)
- {
- LLFloaterCompileQueue* self = new LLFloaterCompileQueue();
- self->mMono = mono;
- return self;
- }
- LLFloaterCompileQueue::LLFloaterCompileQueue()
- : LLFloaterScriptQueue("compile_title", "compile_verb")
- {
- }
- void LLFloaterCompileQueue::experienceIdsReceived(const LLSD& content)
- {
- for (LLSD::array_const_iterator it = content.beginArray(),
- end = content.endArray();
- it != end; ++it)
- {
- mExperienceIds.emplace(it->asUUID());
- }
- nextObject();
- }
- bool LLFloaterCompileQueue::hasExperience(const LLUUID& id) const
- {
- return mExperienceIds.count(id) != 0;
- }
- void LLFloaterCompileQueue::handleInventory(LLViewerObject* objectp,
- LLInventoryObject::object_list_t* inv)
- {
- if (!objectp || !inv) return;
- // Find all of the LSL, leaving off duplicates. We will remove all matching
- // asset UUIDs on compilation success.
- typedef std::multimap<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map;
- uuid_item_map asset_item_map;
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- LLAssetType::EType type = (*it)->getType();
- if (type == LLAssetType::AT_LSL_TEXT ||
- type == LLAssetType::AT_SCRIPT) // Legacy scripts
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- // Check permissions before allowing the user to retrieve data.
- if (item->getPermissions().allowModifyBy(gAgentID, gAgent.getGroupID()) &&
- item->getPermissions().allowCopyBy(gAgentID, gAgent.getGroupID()))
- {
- LLPointer<LLViewerInventoryItem> script =
- new LLViewerInventoryItem(item);
- mCurrentScripts.emplace_back(std::move(script));
- asset_item_map.emplace(item->getAssetUUID(), item);
- }
- }
- }
- if (asset_item_map.empty())
- {
- // There is no script in this object. Move on.
- nextObject();
- }
- else
- {
- LLViewerRegion* regionp = objectp->getRegion();
- if (!regionp)
- {
- // No region associated with this object !... Move on.
- llwarns << "NULL region for object: " << objectp->getID()
- << ". Skipping." << llendl;
- nextObject();
- return;
- }
- const std::string& url = regionp->getCapability("GetMetadata");
- LLExperienceCache* expcache = LLExperienceCache::getInstance();
- // Request all of the assets.
- for (uuid_item_map::iterator iter = asset_item_map.begin(),
- end = asset_item_map.end();
- iter != end; ++iter)
- {
- LLInventoryItem* itemp = iter->second;
- LLScriptQueueData* datap =
- new LLScriptQueueData(getID(), objectp->getID(), itemp,
- regionp->getHost());
- if (!url.empty())
- {
- expcache->fetchAssociatedExperience(itemp->getParentUUID(),
- itemp->getUUID(), url,
- boost::bind(LLFloaterCompileQueue::requestAsset,
- datap, _1));
- }
- else
- {
- requestAsset(datap, LLSD());
- }
- }
- }
- }
- //static
- void LLFloaterCompileQueue::requestAsset(LLScriptQueueData* datap,
- const LLSD& experience)
- {
- if (!datap || !gAssetStoragep) return;
- LLFloaterCompileQueue* queue =
- (LLFloaterCompileQueue*)LLFloaterScriptQueue::findInstance(datap->mQueueID);
- if (!queue)
- {
- delete datap;
- return;
- }
- if (experience.has(LLExperienceCache::EXPERIENCE_ID))
- {
- datap->mExperienceId=experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
- if (!queue->hasExperience(datap->mExperienceId))
- {
- LLUIString skipping = queue->getString("skipping");
- skipping.setArg("[SCRIPT]", datap->mItem->getName());
- skipping.setArg("[EXP]",
- experience[LLExperienceCache::NAME].asString());
- queue->logMessage(skipping.getString());
- queue->removeItemByItemID(datap->mItem->getUUID());
- delete datap;
- return;
- }
- }
- gAssetStoragep->getInvItemAsset(datap->mHost, gAgentID, gAgentSessionID,
- datap->mItem->getPermissions().getOwner(),
- datap->mTaskId, datap->mItem->getUUID(),
- datap->mItem->getAssetUUID(),
- datap->mItem->getType(),
- scriptArrived, (void*)datap);
- }
- //static
- void LLFloaterCompileQueue::finishLSLUpload(LLUUID item_id, LLUUID task_id,
- LLUUID new_asset_id, LLSD response,
- std::string script_name,
- LLUUID queue_id)
- {
- std::string message;
- LLFloaterCompileQueue* queue =
- (LLFloaterCompileQueue*)LLFloaterScriptQueue::findInstance(queue_id);
- if (queue)
- {
- // Bytecode save completed
- if (response["compiled"])
- {
- message = "Compilation of \"" + script_name + "\" succeeded.";
- queue->logMessage(message);
- llinfos << message << llendl;
- }
- else
- {
- LLSD compile_errors = response["errors"];
- for (LLSD::array_const_iterator line = compile_errors.beginArray(),
- endl = compile_errors.endArray();
- line != endl; ++line)
- {
- std::string str = line->asString();
- str.erase(std::remove(str.begin(), str.end(), '\n'),
- str.end());
- queue->logMessage(message);
- }
- llinfos << response["errors"] << llendl;
- }
- queue->removeItemByItemID(item_id);
- }
- }
- // This is the callback for when each script arrives
- //static
- void LLFloaterCompileQueue::scriptArrived(const LLUUID& asset_id,
- LLAssetType::EType type,
- void* user_data, S32 status,
- LLExtStat)
- {
- LLScriptQueueData* data = (LLScriptQueueData*)user_data;
- if (!data) return;
- std::string buffer;
- std::string script_name = data->mItem->getName();
- LLFloaterCompileQueue* queue =
- (LLFloaterCompileQueue*)LLFloaterScriptQueue::findInstance(data->mQueueID);
- if (queue && status == 0)
- {
- LLViewerObject* object = gObjectList.findObject(data->mTaskId);
- if (!object)
- {
- llwarns << "Object " << data->mTaskId
- << " is gone. Skipping script." << llendl;
- return;
- }
- LLViewerRegion* regionp = object->getRegion();
- if (!regionp)
- {
- llwarns << "NULL region for object: " << object->getID()
- << ". Skipping script." << llendl;
- return;
- }
-
- const std::string& url = regionp->getCapability("UpdateScriptTask");
- if (url.empty())
- {
- llwarns << "Missing UpdateScriptTask capability for region of object "
- << object->getID() << ". Skipping script." << llendl;
- return;
- }
- LLBufferedAssetUploadInfo::task_uploaded_cb_t proc =
- boost::bind(&LLFloaterCompileQueue::finishLSLUpload, _1, _2, _3,
- _4, script_name, queue->getID());
- LLResourceUploadInfo::ptr_t
- info(new LLQueuedScriptAssetUpload(data->mTaskId,
- data->mItem->getUUID(),
- asset_id,
- queue->mMono ? LLScriptAssetUpload::MONO
- : LLScriptAssetUpload::LSL2,
- true, script_name,
- queue->getID(),
- data->mExperienceId, proc));
- LLViewerAssetUpload::enqueueInventoryUpload(url, info);
- }
- else
- {
- gViewerStats.incStat(LLViewerStats::ST_DOWNLOAD_FAILED);
- if (status == LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE)
- {
- buffer = queue->getString("not_found") + " " + script_name;
- }
- else if (status == LL_ERR_INSUFFICIENT_PERMISSIONS)
- {
- buffer = queue->getString("bad_perm") + " " + script_name;
- }
- else
- {
- buffer = queue->getString("failure") + " " + script_name;
- }
- llwarns << "Problem downloading script: " << script_name << llendl;
- if (gSavedSettings.getBool("ScriptErrorsAsChat"))
- {
- LLChat chat(buffer);
- LLFloaterChat::addChat(chat);
- }
- if (queue)
- {
- queue->removeItemByItemID(data->mItem->getUUID());
- }
- }
- if (queue && buffer.size() > 0)
- {
- queue->logMessage(buffer);
- }
- delete data;
- }
- void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id)
- {
- for (size_t i = 0; i < mCurrentScripts.size(); )
- {
- if (mCurrentScripts[i]->getUUID() == asset_id)
- {
- vector_replace_with_last(mCurrentScripts,
- mCurrentScripts.begin() + i);
- }
- else
- {
- ++i;
- }
- }
- if (mCurrentScripts.empty())
- {
- nextObject();
- }
- }
- bool LLFloaterCompileQueue::startQueue()
- {
- const std::string& url =
- gAgent.getRegionCapability("GetCreatorExperiences");
- if (!url.empty())
- {
- LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t
- succ = boost::bind(&LLFloaterCompileQueue::processExperienceIdResults,
- _1, getID());
- LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t
- fail = boost::bind(&LLFloaterCompileQueue::processExperienceIdResults,
- LLSD(), getID());
- LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(url, succ, fail);
- return true;
- }
- return nextObject();
- }
- //static
- void LLFloaterCompileQueue::processExperienceIdResults(LLSD result,
- LLUUID queue_id)
- {
- LLFloaterCompileQueue* self =
- (LLFloaterCompileQueue*)LLFloaterScriptQueue::findInstance(queue_id);
- if (self)
- {
- self->experienceIdsReceived(result["experience_ids"]);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Class LLFloaterResetQueue
- ///////////////////////////////////////////////////////////////////////////////
- //static
- LLFloaterResetQueue* LLFloaterResetQueue::create()
- {
- return new LLFloaterResetQueue();
- }
- LLFloaterResetQueue::LLFloaterResetQueue()
- : LLFloaterScriptQueue("reset_title", "reset_verb")
- {
- }
- void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv)
- {
- // find all of the lsl, leaving off duplicates. We'll remove all matching
- // asset uuids on compilation success.
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
- if (object)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- logMessage(getString("resetting") + " " + item->getName());
- LLMessageSystem* msg = gMessageSystemp;
- msg->newMessageFast(_PREHASH_ScriptReset);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
- msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
- msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
- msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
- msg->sendReliable(object->getRegion()->getHost());
- }
- }
- }
- nextObject();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Class LLFloaterRunQueue
- ///////////////////////////////////////////////////////////////////////////////
- //static
- LLFloaterRunQueue* LLFloaterRunQueue::create()
- {
- return new LLFloaterRunQueue();
- }
- LLFloaterRunQueue::LLFloaterRunQueue()
- : LLFloaterScriptQueue("run_title", "run_verb")
- {
- }
- void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv)
- {
- // find all of the LSL, leaving off duplicates. We will remove all matching
- // asset uuids on compilation success.
- for (LLInventoryObject::object_list_t::const_iterator it = inv->begin(),
- end = inv->end();
- it != end; ++it)
- {
- if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
- if (object)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- logMessage(getString("running") + " " + item->getName());
- LLMessageSystem* msg = gMessageSystemp;
- msg->newMessageFast(_PREHASH_SetScriptRunning);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
- msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
- msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
- msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
- msg->addBoolFast(_PREHASH_Running, true);
- msg->sendReliable(object->getRegion()->getHost());
- }
- }
- }
- nextObject();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Class LLFloaterStopQueue
- ///////////////////////////////////////////////////////////////////////////////
- //static
- LLFloaterStopQueue* LLFloaterStopQueue::create()
- {
- return new LLFloaterStopQueue();
- }
- LLFloaterStopQueue::LLFloaterStopQueue()
- : LLFloaterScriptQueue("stop_title", "stop_verb")
- {
- }
- void LLFloaterStopQueue::handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv)
- {
- // find all of the lsl, leaving off duplicates. We'll remove
- // all matching asset uuids on compilation success.
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- if ((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
- if (object)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)*it);
- logMessage(getString("stopping") + " " + item->getName());
- LLMessageSystem* msg = gMessageSystemp;
- msg->newMessageFast(_PREHASH_SetScriptRunning);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
- msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
- msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
- msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
- msg->addBoolFast(_PREHASH_Running, false);
- msg->sendReliable(object->getRegion()->getHost());
- }
- }
- }
- nextObject();
- }
|