diff options
| author | Rider Linden <rider@lindenlab.com> | 2026-02-06 11:01:23 -0800 |
|---|---|---|
| committer | Rider Linden <rider@lindenlab.com> | 2026-02-06 11:01:23 -0800 |
| commit | ecdb63651e4d94a8323d22114bb5db09c8078d61 (patch) | |
| tree | 7d5f0e11e9427ecc5b8a3c4138345c4df6b53dbf | |
| parent | 5a49c9c2ddc7fd15c2333c0b3c85aaeee20ee896 (diff) | |
Allow viewer to specify what default script it wants to use, either by language ID or by supplying an inventory item as a template.
| -rw-r--r-- | indra/newview/llpanelcontents.cpp | 105 | ||||
| -rw-r--r-- | indra/newview/llpreviewscript.h | 4 | ||||
| -rw-r--r-- | indra/newview/lltooldraganddrop.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerinventory.cpp | 64 | ||||
| -rw-r--r-- | indra/newview/llviewerinventory.h | 6 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 21 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 10 | ||||
| -rw-r--r-- | scripts/messages/message_template.msg | 5 | ||||
| -rw-r--r-- | scripts/messages/message_template.msg.sha1 | 2 |
9 files changed, 57 insertions, 162 deletions
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index bc99899c27..2f060ac2e6 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -221,19 +221,6 @@ void LLPanelContents::clearContents() // Static functions // -// See below comment in `onClickNewScript()` about this hack :( -static const std::string DEFAULT_SLUA_SCRIPT = R"( -function LLEvents.touch_start(detected) - ll.Say(0, "Touched.") -end - -local function main() - print("Hello, Avatar!") -end - -main() -)"; - // static void LLPanelContents::onClickNewScript(void *userdata) { @@ -254,20 +241,9 @@ void LLPanelContents::onClickNewScript(void *userdata) std::string desc; LLViewerAssetType::generateDescriptionFor(LLAssetType::AT_LSL_TEXT, desc); - // -------------------------------------------------------------------------------------------------- - // Begin hack - // - // The current state of the server doesn't allow specifying a default script template, - // so we have to update its code immediately after creation instead. - // - // Moreover, _PREHASH_RezScript has more complex server-side logic than _PREHASH_CreateInventoryItem, - // which changes the item's attributes, such as its name and UUID. The simplest way to mitigate this - // is to create a temporary item in the user's inventory, modify it as in create_inventory_item()'s - // callback, and then call _PREHASH_RezScript to move it into the object's inventory. - // - // This temporary workaround should be removed after a server-side fix. - // See https://github.com/secondlife/viewer/issues/3731 for more information. - // + U8 script_language = LANG_ID_LSL; + LLUUID template_id; + LLViewerRegion* region = object->getRegion(); if (region && region->simulatorFeaturesReceived()) { @@ -275,78 +251,11 @@ void LLPanelContents::onClickNewScript(void *userdata) region->getSimulatorFeatures(simulatorFeatures); if (simulatorFeatures["LuaScriptsEnabled"].asBoolean()) { - if (std::string::size_type pos = desc.find("lsl2"); pos != std::string::npos) - { - desc.replace(pos, 4, "SLua"); - } - - auto scriptCreationCallback = [object](const LLUUID& inv_item) - { - if (!inv_item.isNull()) - { - LLViewerInventoryItem* item = gInventory.getItem(inv_item); - if (item) - { - auto scriptUploadFinished = [object, item](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) - { - LLPointer<LLViewerInventoryItem> new_script = new LLViewerInventoryItem(item); - object->saveScript(new_script, true, true); - - // Delete the temporary item from the user's inventory after rezzing it in the object's inventory - ms_sleep(50); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RemoveInventoryItem); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_InventoryData); - msg->addUUIDFast(_PREHASH_ItemID, item->getUUID()); - gAgent.sendReliableMessage(); - - gInventory.deleteObject(item->getUUID()); - gInventory.notifyObservers(); - }; - - std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); - if (!url.empty()) - { - LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLScriptAssetUpload>( - item->getUUID(), - "luau", - DEFAULT_SLUA_SCRIPT, - scriptUploadFinished, - nullptr)); - - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); - } - } - } - }; - LLPointer<LLBoostFuncInventoryCallback> cb = new LLBoostFuncInventoryCallback(scriptCreationCallback); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_CreateInventoryItem); - msg->nextBlock(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlock(_PREHASH_InventoryBlock); - msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb)); - msg->addUUIDFast(_PREHASH_FolderID, gInventory.getRootFolderID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLTransactionID::tnull); - msg->addU32Fast(_PREHASH_NextOwnerMask, PERM_MOVE | PERM_TRANSFER); - msg->addS8Fast(_PREHASH_Type, LLAssetType::AT_LSL_TEXT); - msg->addS8Fast(_PREHASH_InvType, LLInventoryType::IT_LSL); - msg->addU8Fast(_PREHASH_WearableType, NO_INV_SUBTYPE); - msg->addStringFast(_PREHASH_Name, "New Script"); - msg->addStringFast(_PREHASH_Description, desc); - - gAgent.sendReliableMessage(); - return; + script_language = LANG_ID_LUA; } } - // - // End hack - // -------------------------------------------------------------------------------------------------- + // *TODO* Get a template ID and script_language based on user preferences. Template ID is the inventory item UUID of a script + // in the user's inventory that is used as a template for new scripts. LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem( @@ -361,7 +270,7 @@ void LLPanelContents::onClickNewScript(void *userdata) LLSaleInfo::DEFAULT, LLInventoryItemFlags::II_FLAGS_NONE, time_corrected()); - object->saveScript(new_item, true, true); + object->saveScript(new_item, true, true, script_language, template_id); std::string name = new_item->getName(); diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index a85837065e..909e2183c2 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -24,8 +24,7 @@ * $/LicenseInfo$ */ -#ifndef LL_LLPREVIEWSCRIPT_H -#define LL_LLPREVIEWSCRIPT_H +#pragma once #include "llpreview.h" #include "lltabcontainer.h" @@ -377,4 +376,3 @@ private: std::string mObjectName; }; -#endif // LL_LLPREVIEWSCRIPT_H diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 5e2d91d31e..87329d204b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1828,7 +1828,7 @@ void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj, } } } - hit_obj->saveScript(new_script, active, true); + hit_obj->saveScript(new_script, active, true, 0, LLUUID::null); if (gFloaterTools) { gFloaterTools->dirty(); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 4d91b7675d..1b80573a1a 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1016,19 +1016,6 @@ void set_default_permissions(LLViewerInventoryItem* item, std::string perm_type) } } -// See below comment in `create_script_cb()` about this hack :( -static const std::string DEFAULT_SLUA_SCRIPT = R"( -function LLEvents.touch_start(detected) - ll.Say(0, "Touched.") -end - -local function main() - print("Hello, Avatar!") -end - -main() -)"; - void create_script_cb(const LLUUID& inv_item) { if (!inv_item.isNull()) @@ -1036,40 +1023,6 @@ void create_script_cb(const LLUUID& inv_item) LLViewerInventoryItem* item = gInventory.getItem(inv_item); if (item) { - // ------------------------------------------------------------------------------------ - // Begin hack - // - // The current state of the server doesn't allow specifying a default script template, - // so we have to update its code immediately after creation instead. - // - // This temporary workaround should be removed after a server-side fix. - // See https://github.com/secondlife/viewer/issues/3731 for more information. - // - LLViewerRegion* region = gAgent.getRegion(); - if (region && region->simulatorFeaturesReceived()) - { - LLSD simulatorFeatures; - region->getSimulatorFeatures(simulatorFeatures); - if (simulatorFeatures["LuaScriptsEnabled"].asBoolean()) - { - std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); - if (!url.empty()) - { - LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLScriptAssetUpload>( - item->getUUID(), - "luau", - DEFAULT_SLUA_SCRIPT, - nullptr, - nullptr)); - - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); - } - } - } - // - // End hack - // ------------------------------------------------------------------------------------ - set_default_permissions(item, "Scripts"); // item was just created, update even if permissions did not changed @@ -1763,6 +1716,7 @@ void create_new_item(const std::string& name, std::function<void(const LLUUID&)> created_cb = nullptr) { std::string desc; + U8 subtype = NO_INV_SUBTYPE; LLViewerAssetType::generateDescriptionFor(asset_type, desc); next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER; @@ -1774,6 +1728,20 @@ void create_new_item(const std::string& name, { cb = new LLBoostFuncInventoryCallback(create_script_cb); next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Scripts"); + + LLViewerRegion* region = gAgent.getRegion(); + if (region && region->simulatorFeaturesReceived()) + { + // *TODO* Setting the subtype for the script will cause the server to select + // either the LSL or Lau default script. We should perhaps allow the user to + // select which type of script they want to create. + LLSD simulatorFeatures; + region->getSimulatorFeatures(simulatorFeatures); + if (simulatorFeatures["LuaScriptsEnabled"].asBoolean()) + { + subtype = LANG_ID_LUA; + } + } break; } @@ -1816,7 +1784,7 @@ void create_new_item(const std::string& name, desc, asset_type, inv_type, - NO_INV_SUBTYPE, + subtype, next_owner_perm, cb); } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index a42bdaa2b0..4147efe3a9 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -42,6 +42,10 @@ class LLViewerInventoryCategory; class LLInventoryCallback; class LLAvatarName; +constexpr U8 NO_INV_SUBTYPE{ 0 }; +constexpr U8 LANG_ID_LSL = 0; +constexpr U8 LANG_ID_LUA = 1; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLViewerInventoryItem // @@ -359,8 +363,6 @@ public: extern LLInventoryCallbackManager gInventoryCallbacks; -const U8 NO_INV_SUBTYPE{ 0 }; - // *TODO: Find a home for these void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, const LLUUID& parent, const LLTransactionID& transaction_id, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 0f4cbdd25c..a07c64f252 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2762,10 +2762,14 @@ void LLViewerObject::doUpdateInventory( // save a script, which involves removing the old one, and rezzing // in the new one. This method should be called with the asset id // of the new and old script AFTER the bytecode has been saved. -void LLViewerObject::saveScript( - const LLViewerInventoryItem* item, - bool active, - bool is_new) +// When creating a new script, the asset should be null. The server +// will create the new script based on the script_language (LSL or Lua) +// If a template_id is provided, the new script will be a copy of that item. +// +// *IMPORTANT* If template_id is provided, it must be the ITEM ID of a +// copy/mod-able script in the user's inventory. +void LLViewerObject::saveScript(const LLViewerInventoryItem* item, + bool active, bool is_new, U8 script_language, const LLUUID& template_id) { /* * XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the @@ -2794,6 +2798,15 @@ void LLViewerObject::saveScript( msg->addBOOLFast(_PREHASH_Enabled, enabled); msg->nextBlockFast(_PREHASH_InventoryBlock); task_item->packMessage(msg); + + // This is a completely new script (no asset id) + if (task_item->getAssetUUID().isNull()) + { + msg->nextBlock("NewScriptInfo"); + msg->addU8("Type", script_language); + msg->addUUID("TemplateID", template_id); + } + msg->sendReliable(mRegionp->getHost()); // do the internal logic diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index cccf59a319..271c35836f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -25,8 +25,7 @@ * $/LicenseInfo$ */ -#ifndef LL_LLVIEWEROBJECT_H -#define LL_LLVIEWEROBJECT_H +#pragma once #include <map> #include <unordered_map> @@ -549,7 +548,10 @@ public: // save a script, which involves removing the old one, and rezzing // in the new one. This method should be called with the asset id // of the new and old script AFTER the bytecode has been saved. - void saveScript(const LLViewerInventoryItem* item, bool active, bool is_new); + // If is_new is true, then we are saving a new script. In this case, + // template_id will be used by the simulator and the new script will be a copy of that script + // asset, otherwise script_language will request the correct generic starting script. + void saveScript(const LLViewerInventoryItem* item, bool active, bool is_new, U8 script_language, const LLUUID& template_id); // move an inventory item out of the task and into agent // inventory. This operation is based on messaging. No permissions @@ -1102,5 +1104,3 @@ public: virtual void updateDrawable(bool force_damped); }; - -#endif diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 40ba2cc6b6..d3d60ea584 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -6818,6 +6818,11 @@ version 2.0 { CreationDate S32 } { CRC U32 } } + { + NewScriptInfo Variable + { Type U8 } + { TemplateID LLUUID } + } } // Create inventory diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1 index baa4f3f12b..745eec1971 100644 --- a/scripts/messages/message_template.msg.sha1 +++ b/scripts/messages/message_template.msg.sha1 @@ -1 +1 @@ -aaecaf01b6954c156662f572dc3ecaf26de0ca67
\ No newline at end of file +2244732a49f7b3fa00694b9870d5d6d3dc0c5cb2
\ No newline at end of file |
