From e90be2ca576c590d3c8e81a3aebcb74a0a6c2d03 Mon Sep 17 00:00:00 2001 From: RebeccaNod1 Date: Thu, 2 Oct 2025 13:41:52 -0500 Subject: [PATCH] feat: Add traditional inventory-based updater system - Traditional_Updater.lsl copies scripts from its own inventory - Uses llRemoteLoadScriptPin with script names (not content) - Follows proven Second Life updater patterns - Includes inventory verification system - Lists all 17 required Peril Dice scripts - Should work reliably unlike HTTP-based approach --- Traditional_Updater.lsl | 248 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 Traditional_Updater.lsl diff --git a/Traditional_Updater.lsl b/Traditional_Updater.lsl new file mode 100644 index 0000000..e4191c5 --- /dev/null +++ b/Traditional_Updater.lsl @@ -0,0 +1,248 @@ +// ==================================================================== +// Traditional Peril Dice Updater - Inventory-Based Script Copying +// ==================================================================== +// This script goes in an updater box that contains all the updated scripts +// in its inventory. It copies scripts from its inventory to the target game. +// +// SETUP: +// 1. Copy all updated LSL scripts into this updater box's inventory +// 2. User rezzes updater box near their Peril Dice game +// 3. User touches their game -> "Check for Updates" -> "Install Update" +// 4. Updater copies scripts from its inventory to their game +// 5. User deletes updater box when finished +// ==================================================================== + +string UPDATER_VERSION = "2.8.8"; +integer UPDATER_CHANNEL = -7723847; + +// Update state +key targetGameKey = NULL_KEY; +integer updatePin = 0; +list scriptList = []; +integer currentScriptIndex = 0; +string currentOperation = ""; + +// Script names that should be in this updater's inventory +list REQUIRED_SCRIPTS = [ + // Root prim scripts (Link 1) + "Main_Controller_Linkset", + "Game_Manager", + "Controller_Memory", + "Controller_MessageHandler", + "Player_RegistrationManager", + "Player_DialogHandler", + "NumberPicker_DialogHandler", + "Floater_Manager", + "Roll_ConfettiModule", + "Bot_Manager", + "Game_Calculator", + "Verbose_Logger", + "System_Debugger", + "Update_Receiver", + // Other link scripts + "Game_Scoreboard_Manager_Linkset", // Link 12 + "Leaderboard_Communication_Linkset", // Link 35 + "XyzzyText_Dice_Bridge_Linkset", // Link 83 + "xyzzy_Master_script" // Links 35-82 (we'll copy this multiple times) +]; + +// Memory reporting +reportMemoryUsage(string scriptName) { + integer memory = llGetUsedMemory(); + integer freeMemory = llGetFreeMemory(); + float memoryPercent = (float)memory / (memory + freeMemory) * 100.0; + llOwnerSay("📊 " + scriptName + ": " + (string)memory + " bytes used (" + + llGetSubString((string)memoryPercent, 0, 4) + "% memory)"); +} + +// Check which scripts are available in inventory +checkInventory() { + integer totalScripts = 0; + integer availableScripts = 0; + + llOwnerSay("📋 Checking updater inventory..."); + + integer i; + for (i = 0; i < llGetListLength(REQUIRED_SCRIPTS); i++) { + string scriptName = llList2String(REQUIRED_SCRIPTS, i); + totalScripts++; + + if (llGetInventoryType(scriptName) == INVENTORY_SCRIPT) { + availableScripts++; + llOwnerSay("✅ " + scriptName + " - Ready"); + } else { + llOwnerSay("❌ " + scriptName + " - MISSING"); + } + } + + llOwnerSay("📊 Inventory Status: " + (string)availableScripts + "/" + (string)totalScripts + " scripts available"); + + if (availableScripts == totalScripts) { + llOwnerSay("✅ All required scripts present - updater ready!"); + } else { + llOwnerSay("⚠️ Missing scripts - please add them to updater inventory"); + } +} + +// Start the update process +startUpdate(key gameKey, integer pin) { + targetGameKey = gameKey; + updatePin = pin; + currentOperation = "updating"; + currentScriptIndex = 0; + + // Build script list for this specific update + scriptList = []; + + // Add all available scripts + integer i; + for (i = 0; i < llGetListLength(REQUIRED_SCRIPTS); i++) { + string scriptName = llList2String(REQUIRED_SCRIPTS, i); + if (llGetInventoryType(scriptName) == INVENTORY_SCRIPT) { + scriptList += [scriptName]; + } + } + + llOwnerSay("🔄 Starting update process..."); + llOwnerSay("📊 Installing " + (string)llGetListLength(scriptList) + " scripts"); + + // Start with first script + installNextScript(); +} + +// Install next script in the queue +installNextScript() { + if (currentScriptIndex >= llGetListLength(scriptList)) { + // Update complete! + completeUpdate(); + return; + } + + string scriptName = llList2String(scriptList, currentScriptIndex); + + llOwnerSay("📝 Installing " + scriptName + " (" + (string)(currentScriptIndex + 1) + + "/" + (string)llGetListLength(scriptList) + ")"); + + // Use llRemoteLoadScriptPin to copy script from our inventory to target + llRemoteLoadScriptPin(targetGameKey, scriptName, updatePin, TRUE, 0); + + llOwnerSay("✅ Copied " + scriptName + " to target game"); + + // Move to next script + currentScriptIndex++; + llSetTimerEvent(2.0); // Brief pause between installations +} + +// Complete the update process +completeUpdate() { + llOwnerSay("🎉 Update installation complete!"); + llOwnerSay("📊 Successfully installed " + (string)llGetListLength(scriptList) + " scripts"); + + // Notify target game + if (targetGameKey != NULL_KEY) { + llRegionSayTo(targetGameKey, UPDATER_CHANNEL, "UPDATE_COMPLETE|" + UPDATER_VERSION); + } + + // Reset state + currentOperation = ""; + targetGameKey = NULL_KEY; + updatePin = 0; + scriptList = []; + currentScriptIndex = 0; + + llOwnerSay("💡 Update complete! You can now delete this updater box."); + llSetText("🎉 Update Complete!\nYou can delete this updater box\nThank you for updating!", + <0.2, 1.0, 0.2>, 1.0); +} + +// Handle update errors +handleUpdateError(string error) { + llOwnerSay("❌ Update failed: " + error); + + // Notify target game of failure + if (targetGameKey != NULL_KEY) { + llRegionSayTo(targetGameKey, UPDATER_CHANNEL, "UPDATE_FAILED|" + error); + } + + // Reset state + currentOperation = ""; + targetGameKey = NULL_KEY; + updatePin = 0; + scriptList = []; + currentScriptIndex = 0; +} + +default { + state_entry() { + reportMemoryUsage("Traditional Peril Dice Updater"); + llOwnerSay("🔄 Traditional Peril Dice Updater v" + UPDATER_VERSION); + llOwnerSay("📦 Inventory-based script copying system"); + llOwnerSay("👆 Touch your Peril Dice game and select 'Check for Updates'"); + + // Check our inventory + checkInventory(); + + // Listen for update requests + llListen(UPDATER_CHANNEL, "", NULL_KEY, ""); + + // Set helpful text + llSetText("🔄 Peril Dice Updater v" + UPDATER_VERSION + "\n" + + "Traditional inventory-based system\n" + + "Touch your game, not this updater", <0.2, 1.0, 0.2>, 1.0); + } + + on_rez(integer start_param) { + llResetScript(); + } + + listen(integer channel, string name, key id, string message) { + if (channel != UPDATER_CHANNEL) return; + + list parts = llParseString2List(message, ["|"], []); + string command = llList2String(parts, 0); + + if (command == "UPDATE_REQUEST") { + string version = llList2String(parts, 1); + integer pin = (integer)llList2String(parts, 2); + + llOwnerSay("📨 Update request from " + name + " (current: " + version + ", PIN: " + (string)pin + ")"); + + if (currentOperation != "") { + llRegionSayTo(id, UPDATER_CHANNEL, "UPDATE_BUSY|Another update in progress"); + return; + } + + // Start the update process + startUpdate(id, pin); + llRegionSayTo(id, UPDATER_CHANNEL, "UPDATE_STARTING|" + UPDATER_VERSION); + } + else if (command == "PING_UPDATER") { + // Respond to updater detection pings + llRegionSayTo(id, UPDATER_CHANNEL, "UPDATER_AVAILABLE|" + UPDATER_VERSION); + } + } + + timer() { + // Continue with next script installation + if (currentOperation == "updating") { + installNextScript(); + } + llSetTimerEvent(0.0); + } + + touch_start(integer total_number) { + key toucher = llDetectedKey(0); + + if (currentOperation == "updating") { + llOwnerSay("⏳ Update in progress for " + llKey2Name(targetGameKey)); + llOwnerSay("📊 Installing script " + (string)(currentScriptIndex + 1) + + " of " + (string)llGetListLength(scriptList)); + } else { + llOwnerSay("🔄 Traditional Peril Dice Updater v" + UPDATER_VERSION); + llOwnerSay("📦 Ready to update Peril Dice games using inventory scripts"); + llOwnerSay("👆 Touch your Peril Dice game (not this updater) and select 'Check for Updates'"); + llOwnerSay("📋 Checking inventory..."); + checkInventory(); + } + } +} \ No newline at end of file