From 799d1d595505acaa7f05a6d92db5f8f2d258f53e Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 8 Apr 2024 16:55:26 +0300
Subject: Add script termination option to 'Lua Scripts' floater

---
 indra/newview/llfloaterluascripts.cpp                   |  6 ++++++
 indra/newview/llfloaterluascripts.h                     |  1 +
 indra/newview/llluamanager.cpp                          | 16 ++++++++++++++++
 indra/newview/llluamanager.h                            |  5 ++++-
 indra/newview/skins/default/xui/en/menu_lua_scripts.xml |  8 ++++++++
 5 files changed, 35 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterluascripts.cpp b/indra/newview/llfloaterluascripts.cpp
index bd845a97d6..8f6ccc50fa 100644
--- a/indra/newview/llfloaterluascripts.cpp
+++ b/indra/newview/llfloaterluascripts.cpp
@@ -45,6 +45,11 @@ LLFloaterLUAScripts::LLFloaterLUAScripts(const LLSD &key)
     { 
         gViewerWindow->getWindow()->openFolder(mTargetFolderPath);
     });
+    mCommitCallbackRegistrar.add("Script.Terminate", [this](LLUICtrl*, const LLSD &userdata) 
+    { 
+        LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close", "coro", mCoroName));
+        LLLUAmanager::terminateScript(mCoroName);
+    });
 }
 
 
@@ -113,6 +118,7 @@ void LLFloaterLUAScripts::onScrollListRightClicked(LLUICtrl *ctrl, S32 x, S32 y)
         if (menu)
         {
             mTargetFolderPath = std::filesystem::path((item->getColumn(1)->getValue().asString())).parent_path().string();
+            mCoroName = item->getValue().asString();
             menu->show(x, y);
             LLMenuGL::showPopup(this, menu, x, y);
         }
diff --git a/indra/newview/llfloaterluascripts.h b/indra/newview/llfloaterluascripts.h
index 548bbd10f6..c7c888b55a 100644
--- a/indra/newview/llfloaterluascripts.h
+++ b/indra/newview/llfloaterluascripts.h
@@ -47,6 +47,7 @@ private:
     std::unique_ptr<LLTimer> mUpdateTimer;
     LLScrollListCtrl* mScriptList;
     std::string mTargetFolderPath;
+    std::string mCoroName;
 
     LLHandle<LLContextMenu> mContextMenuHandle;
 };
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index 1d55313813..35a73aaabe 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -49,6 +49,7 @@
 #include <vector>
 
 std::map<std::string, std::string> LLLUAmanager::sScriptNames;
+std::set<std::string> LLLUAmanager::sTerminationList;
 
 lua_function(sleep, "sleep(seconds): pause the running coroutine")
 {
@@ -188,6 +189,21 @@ void LLLUAmanager::runScriptFile(const std::string &filename, script_result_fn r
             // A script_finished_fn is used to initialize the LuaState.
             // It will be called when the LuaState is destroyed.
             LuaState L(finished_cb);
+
+            static int index = 0;
+            lua_callbacks(L)->interrupt = [](lua_State *L, int gc)
+            {
+                if (gc >= 0)
+                    return;
+               
+                std::set<std::string> scripts = LLLUAmanager::getTerminationList();
+                std::string coro = LLCoros::getName();
+                if (scripts.find(coro) != scripts.end()) 
+                {
+                    sTerminationList.erase(coro);
+                    lluau::error(L, "Script was terminated");
+                }
+            };
             std::string text{std::istreambuf_iterator<char>(in_file), {}};
             auto [count, result] = L.expr(filename, text);
             if (result_cb)
diff --git a/indra/newview/llluamanager.h b/indra/newview/llluamanager.h
index fe4db22fca..d671719bc4 100644
--- a/indra/newview/llluamanager.h
+++ b/indra/newview/llluamanager.h
@@ -85,9 +85,12 @@ public:
     static void runScriptOnLogin();
 
     static const std::map<std::string, std::string> getScriptNames() { return sScriptNames; }
+    static std::set<std::string> getTerminationList() { return sTerminationList; }
+    static void terminateScript(std::string& coro_name) { sTerminationList.insert(coro_name); }
 
  private:
-    static std::map<std::string, std::string> sScriptNames;
+   static std::map<std::string, std::string> sScriptNames;
+   static std::set<std::string> sTerminationList;
 };
 
 class LLRequireResolver
diff --git a/indra/newview/skins/default/xui/en/menu_lua_scripts.xml b/indra/newview/skins/default/xui/en/menu_lua_scripts.xml
index 8f718abe17..645fee405d 100644
--- a/indra/newview/skins/default/xui/en/menu_lua_scripts.xml
+++ b/indra/newview/skins/default/xui/en/menu_lua_scripts.xml
@@ -8,4 +8,12 @@
     <menu_item_call.on_click
      function="Script.OpenFolder" />
   </menu_item_call>
+  <menu_item_separator/>
+  <menu_item_call
+   label="Terminate script"
+   layout="topleft"
+   name="terminate">
+    <menu_item_call.on_click
+     function="Script.Terminate" />
+   </menu_item_call>
 </context_menu>
-- 
cgit v1.2.3


From e6aa6d22a107161b0bf08a45e9a90e749a824d9b Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Tue, 9 Apr 2024 22:37:34 +0300
Subject: mac build fix - remove unused variable

---
 indra/newview/llluamanager.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index 35a73aaabe..344ab1bb99 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -190,7 +190,6 @@ void LLLUAmanager::runScriptFile(const std::string &filename, script_result_fn r
             // It will be called when the LuaState is destroyed.
             LuaState L(finished_cb);
 
-            static int index = 0;
             lua_callbacks(L)->interrupt = [](lua_State *L, int gc)
             {
                 if (gc >= 0)
-- 
cgit v1.2.3


From 396ae60e1528515d0cbdfc4290b24ccb172998c8 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 12 Apr 2024 19:28:29 +0300
Subject: 'Lua Scripts' floater clean up

---
 indra/newview/llfloaterluascripts.cpp | 16 +++++++++++-----
 indra/newview/llfloaterluascripts.h   |  2 --
 indra/newview/llluamanager.cpp        |  8 ++++----
 3 files changed, 15 insertions(+), 11 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterluascripts.cpp b/indra/newview/llfloaterluascripts.cpp
index 8f6ccc50fa..30353a7210 100644
--- a/indra/newview/llfloaterluascripts.cpp
+++ b/indra/newview/llfloaterluascripts.cpp
@@ -43,12 +43,20 @@ LLFloaterLUAScripts::LLFloaterLUAScripts(const LLSD &key)
 {
     mCommitCallbackRegistrar.add("Script.OpenFolder", [this](LLUICtrl*, const LLSD &userdata) 
     { 
-        gViewerWindow->getWindow()->openFolder(mTargetFolderPath);
+        if (mScriptList->hasSelectedItem())
+        {
+            std::string target_folder_path = std::filesystem::path((mScriptList->getFirstSelected()->getColumn(1)->getValue().asString())).parent_path().string();
+            gViewerWindow->getWindow()->openFolder(target_folder_path);
+        }
     });
     mCommitCallbackRegistrar.add("Script.Terminate", [this](LLUICtrl*, const LLSD &userdata) 
     { 
-        LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close", "coro", mCoroName));
-        LLLUAmanager::terminateScript(mCoroName);
+        if (mScriptList->hasSelectedItem())
+        {
+            std::string coro_name = mScriptList->getSelectedValue();
+            LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close", "coro", coro_name));
+            LLLUAmanager::terminateScript(coro_name);
+        }
     });
 }
 
@@ -117,8 +125,6 @@ void LLFloaterLUAScripts::onScrollListRightClicked(LLUICtrl *ctrl, S32 x, S32 y)
         auto menu = mContextMenuHandle.get();
         if (menu)
         {
-            mTargetFolderPath = std::filesystem::path((item->getColumn(1)->getValue().asString())).parent_path().string();
-            mCoroName = item->getValue().asString();
             menu->show(x, y);
             LLMenuGL::showPopup(this, menu, x, y);
         }
diff --git a/indra/newview/llfloaterluascripts.h b/indra/newview/llfloaterluascripts.h
index c7c888b55a..932c5c78dd 100644
--- a/indra/newview/llfloaterluascripts.h
+++ b/indra/newview/llfloaterluascripts.h
@@ -46,8 +46,6 @@ private:
 
     std::unique_ptr<LLTimer> mUpdateTimer;
     LLScrollListCtrl* mScriptList;
-    std::string mTargetFolderPath;
-    std::string mCoroName;
 
     LLHandle<LLContextMenu> mContextMenuHandle;
 };
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index 344ab1bb99..853ed5a634 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -192,14 +192,14 @@ void LLLUAmanager::runScriptFile(const std::string &filename, script_result_fn r
 
             lua_callbacks(L)->interrupt = [](lua_State *L, int gc)
             {
+                // skip if we're interrupting only for garbage collection
                 if (gc >= 0)
                     return;
                
-                std::set<std::string> scripts = LLLUAmanager::getTerminationList();
-                std::string coro = LLCoros::getName();
-                if (scripts.find(coro) != scripts.end()) 
+                auto it = sTerminationList.find(LLCoros::getName());
+                if (it != sTerminationList.end()) 
                 {
-                    sTerminationList.erase(coro);
+                    sTerminationList.erase(it);
                     lluau::error(L, "Script was terminated");
                 }
             };
-- 
cgit v1.2.3