diff --git a/extensions/extensions.pyproj b/extensions/extensions.pyproj index 127cbc8..177f469 100644 --- a/extensions/extensions.pyproj +++ b/extensions/extensions.pyproj @@ -20,14 +20,19 @@ false + + + + + - + - + @@ -65,7 +70,7 @@ - + @@ -80,20 +85,16 @@ - - - - - - - + + + + + + - + - - - @@ -103,8 +104,8 @@ - - + + @@ -112,7 +113,14 @@ + + + + + + + @@ -124,28 +132,26 @@ - + - + - + - - - - Code - - + + + + @@ -178,7 +184,7 @@ - + @@ -191,7 +197,7 @@ - + @@ -208,7 +214,7 @@ - + @@ -218,18 +224,18 @@ Code - - + + - - - - - + + + + + - - + + @@ -237,17 +243,17 @@ - - - - + + + + - - + + diff --git a/extensions/sn_better_target_monitor/content.xml b/extensions/sn_better_target_monitor/content.xml index 1353f36..70a56b0 100644 --- a/extensions/sn_better_target_monitor/content.xml +++ b/extensions/sn_better_target_monitor/content.xml @@ -2,9 +2,9 @@ diff --git a/extensions/sn_better_target_monitor/ui.xml b/extensions/sn_better_target_monitor/ui.xml new file mode 100644 index 0000000..61203cd --- /dev/null +++ b/extensions/sn_better_target_monitor/ui.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/extensions/sn_better_target_monitor/lua/Target_Monitor.lua b/extensions/sn_better_target_monitor/ui/Target_Monitor.lua similarity index 99% rename from extensions/sn_better_target_monitor/lua/Target_Monitor.lua rename to extensions/sn_better_target_monitor/ui/Target_Monitor.lua index 6e3c8e8..847ad52 100644 --- a/extensions/sn_better_target_monitor/lua/Target_Monitor.lua +++ b/extensions/sn_better_target_monitor/ui/Target_Monitor.lua @@ -1,4 +1,4 @@ - +Lua_Loader.define("extensions.sn_better_target_monitor.lua.Target_Monitor",function(require) ------------------------------------------------------------------------------ --[[ The high level of the monitor is handled in monitors.lua. @@ -1764,7 +1764,6 @@ function L.Get_X3_Class(macroclass, purpose, shiptype) end ------------------------------------------------------------------------------ -L.Init_TargetMonitor() --[[ @@ -1830,4 +1829,5 @@ end ]] -return L \ No newline at end of file +return L,L.Init_TargetMonitor +end) \ No newline at end of file diff --git a/extensions/sn_better_target_monitor/lua_interface.txt b/extensions/sn_better_target_monitor/ui/lua_interface.lua similarity index 50% rename from extensions/sn_better_target_monitor/lua_interface.txt rename to extensions/sn_better_target_monitor/ui/lua_interface.lua index b853a32..cdef3b3 100644 --- a/extensions/sn_better_target_monitor/lua_interface.txt +++ b/extensions/sn_better_target_monitor/ui/lua_interface.lua @@ -5,5 +5,7 @@ path will be maintained between github development files and steam style release files. ]] - -return require("extensions.sn_better_target_monitor.lua.Target_Monitor") \ No newline at end of file +Lua_Loader.define("extensions.sn_better_target_monitor.lua_interface",function(require) + -- TODO: Need to determine if we need to Init this + return require("extensions.sn_better_target_monitor.lua.Target_Monitor") +end) \ No newline at end of file diff --git a/extensions/sn_extra_game_options/ui.xml b/extensions/sn_extra_game_options/ui.xml new file mode 100644 index 0000000..c117f5c --- /dev/null +++ b/extensions/sn_extra_game_options/ui.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/extensions/sn_extra_game_options/lua/Custom_Options.lua b/extensions/sn_extra_game_options/ui/Custom_Options.lua similarity index 99% rename from extensions/sn_extra_game_options/lua/Custom_Options.lua rename to extensions/sn_extra_game_options/ui/Custom_Options.lua index 0412907..29727f7 100644 --- a/extensions/sn_extra_game_options/lua/Custom_Options.lua +++ b/extensions/sn_extra_game_options/ui/Custom_Options.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_extra_game_options.lua.Custom_Options",function(require) --[[ This module implements a custom options menu entry, separate from the general api, for changing various behaviors of interest. @@ -1321,4 +1322,5 @@ L.Init_Hide_Modified() ------------------------------------------------------------------------------ -- Final init. -L.Init() \ No newline at end of file +return nil,L.Init +) \ No newline at end of file diff --git a/extensions/sn_hotkey_collection/ui.xml b/extensions/sn_hotkey_collection/ui.xml new file mode 100644 index 0000000..21b3116 --- /dev/null +++ b/extensions/sn_hotkey_collection/ui.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/extensions/sn_hotkey_collection/lua/Hotkeys.lua b/extensions/sn_hotkey_collection/ui/Hotkeys.lua similarity index 98% rename from extensions/sn_hotkey_collection/lua/Hotkeys.lua rename to extensions/sn_hotkey_collection/ui/Hotkeys.lua index dd15f53..a9b8ba3 100644 --- a/extensions/sn_hotkey_collection/lua/Hotkeys.lua +++ b/extensions/sn_hotkey_collection/ui/Hotkeys.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_hotkey_collection.lua.Hotkeys",function(require) --[[ Lua side of hotkey api, for doing things only lua can do. ]] @@ -213,4 +214,5 @@ function L.Reset_Zoom() end -- Final init. -L.Init() \ No newline at end of file +return nil,L.Init +) \ No newline at end of file diff --git a/extensions/sn_measure_fps/ui.xml b/extensions/sn_measure_fps/ui.xml new file mode 100644 index 0000000..bdc9541 --- /dev/null +++ b/extensions/sn_measure_fps/ui.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/extensions/sn_measure_fps/lua/Measure_FPS.lua b/extensions/sn_measure_fps/ui/Measure_FPS.lua similarity index 86% rename from extensions/sn_measure_fps/lua/Measure_FPS.lua rename to extensions/sn_measure_fps/ui/Measure_FPS.lua index 899392d..1f30702 100644 --- a/extensions/sn_measure_fps/lua/Measure_FPS.lua +++ b/extensions/sn_measure_fps/ui/Measure_FPS.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_measure_fps.lua.Measure_FPS",function(require) --[[ Bounces fps sample data back to md. ]] @@ -29,6 +30,5 @@ function L.Get_Sample() }) end -Init() - -return \ No newline at end of file +return nil,Init +) \ No newline at end of file diff --git a/extensions/sn_measure_perf/ui.xml b/extensions/sn_measure_perf/ui.xml new file mode 100644 index 0000000..109e88f --- /dev/null +++ b/extensions/sn_measure_perf/ui.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/extensions/sn_measure_perf/lua/Measure_Perf.lua b/extensions/sn_measure_perf/ui/Measure_Perf.lua similarity index 97% rename from extensions/sn_measure_perf/lua/Measure_Perf.lua rename to extensions/sn_measure_perf/ui/Measure_Perf.lua index 775fce4..610f33a 100644 --- a/extensions/sn_measure_perf/lua/Measure_Perf.lua +++ b/extensions/sn_measure_perf/ui/Measure_Perf.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_better_target_monitor.lua.Target_Monitor",function(require) --[[ Lua side of performance profiling. ]] @@ -33,7 +34,6 @@ function L.Bounce_Test(_, count) end -Init() --[[ @@ -144,4 +144,5 @@ Test_Init() -return \ No newline at end of file +return nil,Init +) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua_interface.txt b/extensions/sn_mod_support_apis/lua_interface.txt deleted file mode 100644 index 4738754..0000000 --- a/extensions/sn_mod_support_apis/lua_interface.txt +++ /dev/null @@ -1,13 +0,0 @@ ---[[ -Lightweight lua wrapper on some exported api functions. -Other extensions using these lua apis should 'require' this file, as its -path will be maintained between github development files and steam style -release files. -]] - -local L = {} -L.Library = require("extensions.sn_mod_support_apis.lua.Library") -L.Pipes = require("extensions.sn_mod_support_apis.lua.named_pipes.Pipes") -L.Time = require("extensions.sn_mod_support_apis.lua.time.Interface") - -return L \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/md/Simple_Menu_API.xml b/extensions/sn_mod_support_apis/md/Simple_Menu_API.xml index ec658a0..a6c7794 100644 --- a/extensions/sn_mod_support_apis/md/Simple_Menu_API.xml +++ b/extensions/sn_mod_support_apis/md/Simple_Menu_API.xml @@ -178,6 +178,9 @@ Complex properties: + diff --git a/extensions/sn_mod_support_apis/ui.xml b/extensions/sn_mod_support_apis/ui.xml new file mode 100644 index 0000000..89cc64d --- /dev/null +++ b/extensions/sn_mod_support_apis/ui.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extensions/sn_mod_support_apis/lua/Library.lua b/extensions/sn_mod_support_apis/ui/Library.lua similarity index 98% rename from extensions/sn_mod_support_apis/lua/Library.lua rename to extensions/sn_mod_support_apis/ui/Library.lua index 8a1fde1..c808926 100644 --- a/extensions/sn_mod_support_apis/lua/Library.lua +++ b/extensions/sn_mod_support_apis/ui/Library.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.Library",function(require) --[[ Library functions to be shared across apis. @@ -266,4 +267,5 @@ function FIFO.Is_Empty (fifo) end -return L \ No newline at end of file +return L +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/ui/Lua_Loader.lua b/extensions/sn_mod_support_apis/ui/Lua_Loader.lua new file mode 100644 index 0000000..ee23c78 --- /dev/null +++ b/extensions/sn_mod_support_apis/ui/Lua_Loader.lua @@ -0,0 +1,323 @@ +--[[ +Simple api for loading in mod lua files, and for accessing ui userdata. +This works around a bug in the x4 ui.xml style lua loading which fails +to initialize the globals table. + +Usage is kept simple: + When the ui reloads or a game is loaded, a ui event is raised. + User MD code will set up a cue to trigger on this event and signal to + lua which file to load. + Lua will then "require" the file, effectively loading it into the game. + +This lua file is itself included by modding an official ui.xml. Lua added +in this way is imported correctly into X4, though there are limited +official ui.xml files which can be modified in this way. + + +Example from MD: + + + + + + + + + + +Here, the cue name can be anything, and the param is the specific +path to the lua file to load, without extension. +The file extension may be ".lua" or ".txt", where the latter may be +needed to distribute lua files through steam workshop. +The lua file needs to be loose, not packed in a cat/dat. + +When a loading is complete, a message is printed to the debuglog, and +a ui signal is raised. The "control" field will be "Loaded " followed +by the original file_path. This can be used to set up loading +dependencies, so that one lua file only loads after a prior one. + +Example dependency condition: + + + + + + +This api also provides for saving data into the uidata.xml file. +All such saved data is in the __MOD_USERDATA global table. +Each individual mod should add a unique key to this table, and save its +data under that key. Nested tables are supported. +Care should be used in the top level key, to avoid cross-mod conflicts. + +To enable early loading of the Userdata handler, this will also support +an early ready signal, which resolves before the normal ready. +- On reloadui or md signalling Priority_Signal, send Priority_Ready. +- Next frame, md cues which listen to this may signal to load their lua. +- Md side will see Priority_Ready, and send Signal. +- Back end of frame, priority lua files load, and api signals standard Ready. +- Next frame, md cues which listen to Ready may signal to load their lua. + +TODO: allow for more md arguments, including specifying dependendencies +which are resolved at this level (eg. store and delay the require until +all dependencies are met). +]] + +Lua_Loader = {} + +local modules = { + +} + +local function Send_Priority_Ready() + --DebugError("LUA Loader API: Signalling 'Lua_Loader, Priority_Ready'") + -- Send a ui signal, telling all md cues to rerun. + AddUITriggeredEvent("Lua_Loader", "Priority_Ready") +end + +local function Send_Ready() + --DebugError("LUA Loader API: Signalling 'Lua_Loader, Ready'") + -- Send a ui signal, telling all md cues to rerun. + AddUITriggeredEvent("Lua_Loader", "Ready") +end + +local function IsWhitelistedInProtectedUI(name) + return name == "ffi" or name == "utf8" +end + +local function IsReserved(name) + return name ~= nil and type(name) == "string" and (name == "bit" or name == "Color" or name == "coroutine" or name == "debug" or name == "ffi" or name == "math" or name == "Matrix" or name == "package" or name == "Rotation" or name == "string" or name == "table" or name == "utf8" or name == "Vector" or name == "_G" or string.find(name, "^jit%.")) +end + +local function Lua_Loader_Require_Helper(name, methodName, requestorName) + if type(name) ~= "string" then + error("Invalid call to "..methodName..". Given name must be a string but is '"..type(name).."''") + end + if requestorName ~= nil and type(requestorName) ~= "string" then + error("Invalid call to "..methodName..". Given requestorName must be nil or a string but is '"..type(requestorName).."''") + end + + local module = modules[name] + if module == nil then + return false + end + + local status = module.status + + if status ~= "defined" then + if status == "executing" then + if requestorName == nil and type(requestorName) == "string" then + error("Invalid call to "..methodName..". Cyclical dependency detected in '"..requestorName.."' and '"..name.."''") + end + elseif status == "faulted" then + error("Failed to require the module '"..name.."' as it encountered an error whilst being defined.\n"..module.exports) + end + + error("Invalid call to "..methodName..". Required module whilst is was being defined '"..name.."''") + end + + local moduleInit = module.init + + return true,module.exports,module.init +end + +local function on_Load_Lua_File(_, file_path) + -- First look for our modules + local success,exports,init = Lua_Loader_Require_Helper(file_path, "Lua_Loader.Load") + + if success then + if init ~= nil and type(init) == "function" then + init() + end + else + local localPackage = package + local packagePath = nil + + -- When Protected UI is enabled it seems that the `package` global is nil, but we want the actual error from require as it might be something else. + if localPackage ~= nil then + local packagePath = localPackage.path + + local customPackagePath = "?.txt" + ---- Removing the debug message; if a user really wants to know, + ---- they can listen to the ui event. + --DebugError("LUA Loader API: loading "..file_path..", package path:"..customPackagePath) + + -- Since lua files cannot be distributed with steam workshop stuff, + -- but txt can, use a trick to change the package search path to + -- also look for txt files (which can be put on steam). + -- This is done on every load, since the package.path was observed to + -- get reset after Init runs (noticed in x4 3.3hf1). + localPackage.path = customPackagePath + end + + success, exports = pcall(baseRequire, file_path) + + -- Restore package.path to the original value + if localPackage ~= nil then + localPackage.path = packagePath + elseif not IsWhitelistedInProtectedUI(name) and success and exports == nil then + local protectedUIError = "require(\""..file_path.."\") : Only whitelisted modules are allowed in Protected UI Mode." + DebugError("If you see the following error, then a lua file for a mod has filed to load:\n"..protectedUIError.."\n\nIf you're confident about the source of ALL of your mods then you will need to disable Protected UI Mode for this mod to function.\n\nAdvice for mod developers: You need to load your mod via 'ui.xml' and update your lua files to using Lua_Loader.define(\""..file_path.."\", function(require)\n ...\nend)") + end + + if not success then + error(exports) + end + + -- Removing the debug message; if a user really wants to know, + -- they can listen to the ui event. + --DebugError("LUA Loader API: loaded "..file_path..", package path:"..customPackagePath) + + -- Generic signal that the load completed, for use when there + -- are inter-lua dependencies (to control loading order). + end + + AddUITriggeredEvent("Lua_Loader", "Loaded "..file_path) +end + +local function Init() + --DebugError("LUA Loader API: Running Init()") + -- Hook up an md->lua signal. + RegisterEvent("Lua_Loader.Load", on_Load_Lua_File) + + -- Listen to md side timing on when to send Ready signals. + -- Priority ready is triggered on game start/load. + RegisterEvent("Lua_Loader.Send_Priority_Ready", Send_Priority_Ready) + RegisterEvent("Lua_Loader.Send_Ready", Send_Ready) + + -- Also call the function once on ui reload itself, to catch /reloadui + -- commands while the md is running. + -- Only triggers priority ready; md will then signal Send_Ready for + -- the second part. + Send_Priority_Ready() +end + +Lua_Loader.IsReserved = IsReserved +Lua_Loader.IsWhitelistedInProtectedUI = IsWhitelistedInProtectedUI + +function Lua_Loader.require(name) + local success,exports,init = Lua_Loader_Require_Helper(name, "Lua_Loader.require()") + + if init == nil then + init = function() + end + end + + return success,exports,init +end + +local baseRequire = require +require = function(name) + local success,exports,init = Lua_Loader_Require_Helper(name, "Lua_Loader.require()") + + if not success then + return baseRequire(name) + end + + if init ~= nil and type(init) == "function" then + init() + end + + return exports +end + +function Lua_Loader.define(name, moduleFunction) + if type(name) ~= "string" then + error("Invalid call to Lua_Loader.define(). Given name must be a string but is '"..type(name).."''") + end + if type(moduleFunction) ~= "function" then + error("Invalid call to Lua_Loader.define(). Given moduleFunction must be a function but is '"..type(moduleFunction).."''") + end + + local module = modules[name] + + if module ~= nil then + DebugError("Redefining the module '"..name.."'") + elseif package ~= nil then + if IsReserved(name) then + DebugError("Redefining the build-in module '"..name.."'") + end + elseif IsWhitelistedInProtectedUI(name) then + DebugError("Redefining the build-in module '"..name.."'") + end + + module = { + status = "executing", + exports = nil, + init = nil, + } + + modules[name] = module + + local ambientName = name + + local dependencies = nil + local moduleFunctionRan = false + + local function moduleRequire(name) + if moduleFunctionRan then + error("Invalid call to require() function in Lua_Loader.define(function(require). Call to moduleRequire method outside of define in '"..ambientName.."''") + end + + local success,exports,init = Lua_Loader_Require_Helper(name, "require() function in Lua_Loader.define(function(require)", ambientName) + + if not success then + return baseRequire(name) + end + + if module.status == "executing" and init ~= nil and type(init) == "function" then + dependencies = dependencies or {} + table.insert(dependencies, init) + end + + return exports,init + end + + local success, exports, initFunction = pcall(moduleFunction, moduleRequire) + + -- Prevent future 'require' from attempting to update the dependency list. + module.status = "executed" + + if not success then + module.status = "faulted" + module.exports = exports + error("Failed to define module '"..name.."' due because of the following error: "..exports) + end + + if initFunction ~= nil and type(initFunction) ~= "function" then + local err = "Invalid call to Lua_Loader.define(). Second return must be nil or the init function but is '"..type(initFunction).."''" + module.status = "faulted" + module.exports = err + error("Failed to define module '"..name.."' due because of the following error: "..err) + end + + local init = nil + + if type(initFunction) == "function" or dependencies ~= nil then + local initialized = false + + init = function() + if not initialized then + if dependencies ~= nil then + for _, dependencyInit in ipairs(dependencies) do + dependencyInit() + end + end + if initFunction ~= nil and type(initFunction) == "function" then + initFunction() + end + initialized = true + end + end + end + + module.exports = exports + module.init = init + module.status = "defined" + + return exports,init +end + +-- This script kicks everything off, so we actually need to run its init now. +Init() diff --git a/extensions/sn_mod_support_apis/ui/OnlineGetUserItemsPatch.lua b/extensions/sn_mod_support_apis/ui/OnlineGetUserItemsPatch.lua new file mode 100644 index 0000000..e1b2942 --- /dev/null +++ b/extensions/sn_mod_support_apis/ui/OnlineGetUserItemsPatch.lua @@ -0,0 +1,9 @@ +local ego_OnlineGetUserItems = OnlineGetUserItems + +-- For some reason, this function returns `nil` in certain cases, which causes a bunch of scripts to start breaking when the interact menu code is injected. +-- Inspection of uses of `OnlineGetUserItems` show that no code seems to check for a `nil` value so it's likely not important that it returns `nil`. +function OnlineGetUserItems( ... ) + local values = {ego_OnlineGetUserItems(...)} + values[1] = values[1] or {} + return unpack(values) +end diff --git a/extensions/sn_mod_support_apis/lua/Text.lua b/extensions/sn_mod_support_apis/ui/Text.lua similarity index 86% rename from extensions/sn_mod_support_apis/lua/Text.lua rename to extensions/sn_mod_support_apis/ui/Text.lua index 9c823a1..a98ea9d 100644 --- a/extensions/sn_mod_support_apis/lua/Text.lua +++ b/extensions/sn_mod_support_apis/ui/Text.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.Text",function(require) --[[ Wrapper for various text lookups from the t files, using ReadText. Standardizes the text names for code management, and maybe even speeds @@ -23,4 +24,5 @@ extension_options = readtext( new, 1000), } -return T \ No newline at end of file +return T +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/ui/addons/ego_debug/Lua_Loader.lua b/extensions/sn_mod_support_apis/ui/addons/ego_debug/Lua_Loader.lua deleted file mode 100644 index 365f91f..0000000 --- a/extensions/sn_mod_support_apis/ui/addons/ego_debug/Lua_Loader.lua +++ /dev/null @@ -1,117 +0,0 @@ ---[[ -Simple api for loading in mod lua files, and for accessing ui userdata. -This works around a bug in the x4 ui.xml style lua loading which fails -to initialize the globals table. - -Usage is kept simple: - When the ui reloads or a game is loaded, a ui event is raised. - User MD code will set up a cue to trigger on this event and signal to - lua which file to load. - Lua will then "require" the file, effectively loading it into the game. - -This lua file is itself included by modding an official ui.xml. Lua added -in this way is imported correctly into X4, though there are limited -official ui.xml files which can be modified in this way. - - -Example from MD: - - - - - - - - - - -Here, the cue name can be anything, and the param is the specific -path to the lua file to load, without extension. -The file extension may be ".lua" or ".txt", where the latter may be -needed to distribute lua files through steam workshop. -The lua file needs to be loose, not packed in a cat/dat. - -When a loading is complete, a message is printed to the debuglog, and -a ui signal is raised. The "control" field will be "Loaded " followed -by the original file_path. This can be used to set up loading -dependencies, so that one lua file only loads after a prior one. - -Example dependency condition: - - - - - - -This api also provides for saving data into the uidata.xml file. -All such saved data is in the __MOD_USERDATA global table. -Each individual mod should add a unique key to this table, and save its -data under that key. Nested tables are supported. -Care should be used in the top level key, to avoid cross-mod conflicts. - -To enable early loading of the Userdata handler, this will also support -an early ready signal, which resolves before the normal ready. -- On reloadui or md signalling Priority_Signal, send Priority_Ready. -- Next frame, md cues which listen to this may signal to load their lua. -- Md side will see Priority_Ready, and send Signal. -- Back end of frame, priority lua files load, and api signals standard Ready. -- Next frame, md cues which listen to Ready may signal to load their lua. - -TODO: allow for more md arguments, including specifying dependendencies -which are resolved at this level (eg. store and delay the require until -all dependencies are met). -]] - -local function Send_Priority_Ready() - --DebugError("LUA Loader API: Signalling 'Lua_Loader, Priority_Ready'") - -- Send a ui signal, telling all md cues to rerun. - AddUITriggeredEvent("Lua_Loader", "Priority_Ready") -end - -local function Send_Ready() - --DebugError("LUA Loader API: Signalling 'Lua_Loader, Ready'") - -- Send a ui signal, telling all md cues to rerun. - AddUITriggeredEvent("Lua_Loader", "Ready") -end - -local function on_Load_Lua_File(_, file_path) - - -- Since lua files cannot be distributed with steam workshop stuff, - -- but txt can, use a trick to change the package search path to - -- also look for txt files (which can be put on steam). - -- This is done on every load, since the package.path was observed to - -- get reset after Init runs (noticed in x4 3.3hf1). - if not string.find(package.path, "?.txt;") then - package.path = "?.txt;"..package.path - end - - require(file_path) - -- Removing the debug message; if a user really wants to know, - -- they can listen to the ui event. - --DebugError("LUA Loader API: loaded "..file_path) - - -- Generic signal that the load completed, for use when there - -- are inter-lua dependencies (to control loading order). - AddUITriggeredEvent("Lua_Loader", "Loaded "..file_path) -end - -local function Init() - --DebugError("LUA Loader API: Running Init()") - -- Hook up an md->lua signal. - RegisterEvent("Lua_Loader.Load", on_Load_Lua_File) - - -- Listen to md side timing on when to send Ready signals. - -- Priority ready is triggered on game start/load. - RegisterEvent("Lua_Loader.Send_Priority_Ready", Send_Priority_Ready) - RegisterEvent("Lua_Loader.Send_Ready", Send_Ready) - - -- Also call the function once on ui reload itself, to catch /reloadui - -- commands while the md is running. - -- Only triggers priority ready; md will then signal Send_Ready for - -- the second part. - Send_Priority_Ready() -end - -Init() \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/ui/addons/ego_debug/ui.xml b/extensions/sn_mod_support_apis/ui/addons/ego_debug/ui.xml deleted file mode 100644 index d7cf139..0000000 --- a/extensions/sn_mod_support_apis/ui/addons/ego_debug/ui.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/extensions/sn_mod_support_apis/lua/c_library/winpipe.lua b/extensions/sn_mod_support_apis/ui/c_library/winpipe.lua similarity index 88% rename from extensions/sn_mod_support_apis/lua/c_library/winpipe.lua rename to extensions/sn_mod_support_apis/ui/c_library/winpipe.lua index 4d39485..cbc3aec 100644 --- a/extensions/sn_mod_support_apis/lua/c_library/winpipe.lua +++ b/extensions/sn_mod_support_apis/ui/c_library/winpipe.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.c_library.winpipe",function(require) --[[ Wrapper for loading the winpipe dll file. @@ -35,7 +36,7 @@ This is that wrapper. -- Check if this is running on Windows. -- First character in package.config is the separator, which -- is backslash on windows. -if package.config:sub(1,1) == "\\" then +if package ~= nil and package.config:sub(1,1) == "\\" then -- Note: as of x4 3.3 hotfix 1 (beta), the jit and lua dll are changed -- such that the winpipe dll doesn't work between versions. @@ -55,14 +56,14 @@ if package.config:sub(1,1) == "\\" then if string.find(GetVersionString(), "406216") then -- <= 3.3 release dll. return package.loadlib( - ".\\extensions\\sn_mod_support_apis\\lua\\c_library\\winpipe_64_pre3p3hf1.dll", + ".\\extensions\\sn_mod_support_apis\\ui\\c_library\\winpipe_64_pre3p3hf1.dll", "luaopen_winpipe")() else -- 3.3 hf1 dll. return package.loadlib( - ".\\extensions\\sn_mod_support_apis\\lua\\c_library\\winpipe_64.dll", + ".\\extensions\\sn_mod_support_apis\\ui\\c_library\\winpipe_64.dll", "luaopen_winpipe")() end end - +end) diff --git a/extensions/sn_mod_support_apis/lua/c_library/winpipe_64.dll b/extensions/sn_mod_support_apis/ui/c_library/winpipe_64.dll similarity index 100% rename from extensions/sn_mod_support_apis/lua/c_library/winpipe_64.dll rename to extensions/sn_mod_support_apis/ui/c_library/winpipe_64.dll diff --git a/extensions/sn_mod_support_apis/lua/c_library/winpipe_64_pre3p3hf1.dll b/extensions/sn_mod_support_apis/ui/c_library/winpipe_64_pre3p3hf1.dll similarity index 100% rename from extensions/sn_mod_support_apis/lua/c_library/winpipe_64_pre3p3hf1.dll rename to extensions/sn_mod_support_apis/ui/c_library/winpipe_64_pre3p3hf1.dll diff --git a/extensions/sn_mod_support_apis/lua/chat_window/Interface.lua b/extensions/sn_mod_support_apis/ui/chat_window/Interface.lua similarity index 98% rename from extensions/sn_mod_support_apis/lua/chat_window/Interface.lua rename to extensions/sn_mod_support_apis/ui/chat_window/Interface.lua index fdbe6ba..4b4f4bf 100644 --- a/extensions/sn_mod_support_apis/lua/chat_window/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/chat_window/Interface.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.chat_window.Interface",function(require) --[[ Lua interface between md and the chat window. Primary goal is to intercept chat text and pass it back to md, with some @@ -290,4 +291,5 @@ function L.rebuildWindowOutput() end -- Removed. TODO: overhaul for changes made in 6.0+. ---L.Init() \ No newline at end of file +return nil--,L.Init +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/hotkey/Interface.lua b/extensions/sn_mod_support_apis/ui/hotkey/Interface.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/hotkey/Interface.lua rename to extensions/sn_mod_support_apis/ui/hotkey/Interface.lua index b42e16a..3edb446 100644 --- a/extensions/sn_mod_support_apis/lua/hotkey/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/hotkey/Interface.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.hotkey.Interface",function(require) --[[ Lua side of the hotkey api. This primarily aims to interface tightly with the egosoft menu system, @@ -931,7 +932,6 @@ end --end -Init() --[[ @@ -1103,4 +1103,8 @@ Possibly adding new keys: - Add a custom section title. - Call menu.displayControlRow() for each new key, matching args. b) patch menu.remapInput to catch user assignments. -]] \ No newline at end of file +]] + +return nil,Init + +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/interact_menu/Interface.lua b/extensions/sn_mod_support_apis/ui/interact_menu/Interface.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/interact_menu/Interface.lua rename to extensions/sn_mod_support_apis/ui/interact_menu/Interface.lua index 064bf45..c0844c4 100644 --- a/extensions/sn_mod_support_apis/lua/interact_menu/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/interact_menu/Interface.lua @@ -1,4 +1,4 @@ - +Lua_Loader.define("extensions.sn_mod_support_apis.lua.interact_menu.Interface",function(require) --[[ Module for adding new context menu actions. Note: not dependent on the simple menu flow directly, except for @@ -863,4 +863,5 @@ function L.Interact_Callback(keep_open, ret_table) end -L.Init() \ No newline at end of file +return nil,L.Init +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/ui/lua_interface.lua b/extensions/sn_mod_support_apis/ui/lua_interface.lua new file mode 100644 index 0000000..daad8dc --- /dev/null +++ b/extensions/sn_mod_support_apis/ui/lua_interface.lua @@ -0,0 +1,15 @@ +--[[ +Lightweight lua wrapper on some exported api functions. +Other extensions using these lua apis should 'require' this file, as its +path will be maintained between github development files and steam style +release files. +]] + +Lua_Loader.define("extensions.sn_mod_support_apis.lua_interface",function(require) + -- TODO: Need to determine if we need to Init this + return { + Library = require("extensions.sn_mod_support_apis.lua.Library"), + Pipes = require("extensions.sn_mod_support_apis.lua.named_pipes.Pipes"), + Time = require("extensions.sn_mod_support_apis.lua.time.Interface"), + } +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/named_pipes/Interface.lua b/extensions/sn_mod_support_apis/ui/named_pipes/Interface.lua similarity index 98% rename from extensions/sn_mod_support_apis/lua/named_pipes/Interface.lua rename to extensions/sn_mod_support_apis/ui/named_pipes/Interface.lua index 1223698..58e2972 100644 --- a/extensions/sn_mod_support_apis/lua/named_pipes/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/named_pipes/Interface.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.named_pipes.Interface",function(require) --[[ MD to Lua Pipe API @@ -203,9 +204,6 @@ function L.Process_Command() end --- Finalize initial setup. -Init() - - -- On require(), just return the Pipes functions to other lua modules. -return Pipes \ No newline at end of file +return Pipes, Init +end) diff --git a/extensions/sn_mod_support_apis/lua/named_pipes/Library.lua b/extensions/sn_mod_support_apis/ui/named_pipes/Library.lua similarity index 94% rename from extensions/sn_mod_support_apis/lua/named_pipes/Library.lua rename to extensions/sn_mod_support_apis/ui/named_pipes/Library.lua index 65cdb5e..ef33ae6 100644 --- a/extensions/sn_mod_support_apis/lua/named_pipes/Library.lua +++ b/extensions/sn_mod_support_apis/ui/named_pipes/Library.lua @@ -1,4 +1,4 @@ - +Lua_Loader.define("extensions.sn_mod_support_apis.lua.named_pipes.Library",function(require) -- Table holding lib functions to be returned, or lib params that can -- be modified. local L = { @@ -56,4 +56,5 @@ end --end -return L \ No newline at end of file +return L +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/named_pipes/Pipes.lua b/extensions/sn_mod_support_apis/ui/named_pipes/Pipes.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/named_pipes/Pipes.lua rename to extensions/sn_mod_support_apis/ui/named_pipes/Pipes.lua index 71c7a39..6cba3a1 100644 --- a/extensions/sn_mod_support_apis/lua/named_pipes/Pipes.lua +++ b/extensions/sn_mod_support_apis/ui/named_pipes/Pipes.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.named_pipes.Pipes",function(require) --[[ Functionality for opening, reading, writing to pipes. @@ -850,4 +851,5 @@ end -- Pass all local functions back on require() for now. -- TODO: maybe be selective. -return L \ No newline at end of file +return L +end) diff --git a/extensions/sn_mod_support_apis/lua/simple_menu/Interface.lua b/extensions/sn_mod_support_apis/ui/simple_menu/Interface.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/simple_menu/Interface.lua rename to extensions/sn_mod_support_apis/ui/simple_menu/Interface.lua index 4eef7cf..8fe8fd0 100644 --- a/extensions/sn_mod_support_apis/lua/simple_menu/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/simple_menu/Interface.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.simple_menu.Interface",function(require) --[[ Top level of the lua side of the simple menu api. Interfaces with MD script commands which will populate the menu and @@ -921,6 +922,6 @@ Standalone_Menu.onSelectElement = L.onSelectElement --- Init once everything is ready. -Init() +return nil,Init +end) diff --git a/extensions/sn_mod_support_apis/lua/simple_menu/Library.lua b/extensions/sn_mod_support_apis/ui/simple_menu/Library.lua similarity index 98% rename from extensions/sn_mod_support_apis/lua/simple_menu/Library.lua rename to extensions/sn_mod_support_apis/ui/simple_menu/Library.lua index 71577fd..72c899d 100644 --- a/extensions/sn_mod_support_apis/lua/simple_menu/Library.lua +++ b/extensions/sn_mod_support_apis/ui/simple_menu/Library.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.simple_menu.Library",function(require) --[[ Misc functions split off into a library file. Mostly string or table processing. @@ -234,5 +235,5 @@ function L.Fix_Bool_Args(args, defaults) end end - -return L \ No newline at end of file +return L +end) diff --git a/extensions/sn_mod_support_apis/lua/simple_menu/Options_Menu.lua b/extensions/sn_mod_support_apis/ui/simple_menu/Options_Menu.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/simple_menu/Options_Menu.lua rename to extensions/sn_mod_support_apis/ui/simple_menu/Options_Menu.lua index 2a455a1..a238185 100644 --- a/extensions/sn_mod_support_apis/lua/simple_menu/Options_Menu.lua +++ b/extensions/sn_mod_support_apis/ui/simple_menu/Options_Menu.lua @@ -1,4 +1,4 @@ - +Lua_Loader.define("extensions.sn_mod_support_apis.lua.simple_menu.Options_Menu",function(require) --[[ Interface into the ego options menu. @@ -349,9 +349,6 @@ local function Init_Gameoptions_Link() -- May require another monkey patch. end --- Run the above immediately. -Init_Gameoptions_Link() - -- Register a custom options submenu provided by user. function menu.Register_Options_Menu(args) -- Verify the id appears unique, at least among registered submenus. @@ -625,11 +622,6 @@ function menu.Handle_Delayed_Display() menu_data.frame:display() end - -return menu - - - --[[ Old development notes: @@ -743,4 +735,7 @@ After having trouble getting submenus to be selected. Thoughts: the main data table to be scrollable. Monkeypatching viewCreated may be the only reliable way to handle this. -]] \ No newline at end of file +]] + +return menu,Init_Gameoptions_Link +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/simple_menu/Standalone_Menu.lua b/extensions/sn_mod_support_apis/ui/simple_menu/Standalone_Menu.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/simple_menu/Standalone_Menu.lua rename to extensions/sn_mod_support_apis/ui/simple_menu/Standalone_Menu.lua index 8a0be11..f53f373 100644 --- a/extensions/sn_mod_support_apis/lua/simple_menu/Standalone_Menu.lua +++ b/extensions/sn_mod_support_apis/ui/simple_menu/Standalone_Menu.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.simple_menu.Standalone_Menu",function (require) --[[ Methods specific to the standalone menu. ]] @@ -451,8 +452,5 @@ function menu.onUpdate() menu.infoFrame:update() end - - -Init() - -return menu \ No newline at end of file +return menu,Init +end) diff --git a/extensions/sn_mod_support_apis/lua/simple_menu/Tables.lua b/extensions/sn_mod_support_apis/ui/simple_menu/Tables.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/simple_menu/Tables.lua rename to extensions/sn_mod_support_apis/ui/simple_menu/Tables.lua index d859c0f..5d0126f 100644 --- a/extensions/sn_mod_support_apis/lua/simple_menu/Tables.lua +++ b/extensions/sn_mod_support_apis/ui/simple_menu/Tables.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.simple_menu.Tables",function(require) --[[ Container for data tables, shared by other active modules. ]] @@ -644,7 +645,7 @@ local function Widget_Init() end end -Widget_Init() -- Export tables. -return T \ No newline at end of file +return T,Widget_Init +end) diff --git a/extensions/sn_mod_support_apis/lua/time/Interface.lua b/extensions/sn_mod_support_apis/ui/time/Interface.lua similarity index 99% rename from extensions/sn_mod_support_apis/lua/time/Interface.lua rename to extensions/sn_mod_support_apis/ui/time/Interface.lua index 9c2c8b4..4f79b8d 100644 --- a/extensions/sn_mod_support_apis/lua/time/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/time/Interface.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.time.Interface",function(require) --[[ This module adds real time support accessible from md. @@ -543,7 +544,5 @@ function E.Unregister_NewFrame_Callback(callback) end end - -Init() - -return E \ No newline at end of file +return E,Init +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/time/Pipe_Time.lua b/extensions/sn_mod_support_apis/ui/time/Pipe_Time.lua similarity index 95% rename from extensions/sn_mod_support_apis/lua/time/Pipe_Time.lua rename to extensions/sn_mod_support_apis/ui/time/Pipe_Time.lua index cccb914..983305f 100644 --- a/extensions/sn_mod_support_apis/lua/time/Pipe_Time.lua +++ b/extensions/sn_mod_support_apis/ui/time/Pipe_Time.lua @@ -1,3 +1,4 @@ +local module = Lua_Loader.define("extensions.sn_mod_support_apis.lua.time.Pipe_Time",function(require) --[[ Python pipe interface functions. Split into a separate file so that the pipe api can import the general @@ -79,5 +80,5 @@ function L.Toc(_, id) ) end - -Init() \ No newline at end of file +return nil,Init +end) \ No newline at end of file diff --git a/extensions/sn_mod_support_apis/lua/userdata/Interface.lua b/extensions/sn_mod_support_apis/ui/userdata/Interface.lua similarity index 90% rename from extensions/sn_mod_support_apis/lua/userdata/Interface.lua rename to extensions/sn_mod_support_apis/ui/userdata/Interface.lua index 0af698e..c3eb1be 100644 --- a/extensions/sn_mod_support_apis/lua/userdata/Interface.lua +++ b/extensions/sn_mod_support_apis/ui/userdata/Interface.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_mod_support_apis.lua.userdata.Interface",function(require) --[[ Support for accessing userdata from uidata.xml, stored in the __MOD_USERDATA global table. @@ -28,21 +29,27 @@ local L = { function L.Init() -- Initial copy of userdata to the md blackboard. - L.player_id = ConvertStringTo64Bit(tostring(ffi.C.GetPlayerID())) + local player_id = ConvertStringTo64Bit(tostring(ffi.C.GetPlayerID())) + + if player_id == 0 then + player_id = nil + end + + L.player_id = player_id -- If userdata is empty, and the player blackboard has data, then leave -- it in place, as a minor safety against the game deleting userdata, -- utilizing data from the savegame as a backup. if next(__MOD_USERDATA) == nil then -- Look up what the md has stored. - local md_userdata = GetNPCBlackboard(L.player_id, "$__MOD_USERDATA") + local md_userdata = GetNPCBlackboard(player_id, "$__MOD_USERDATA") -- If something, copy it back. if md_userdata ~= nil then __MOD_USERDATA = md_userdata end end --DebugError("Copying __MOD_USERDATA to player blackboard") - SetNPCBlackboard(L.player_id, "$__MOD_USERDATA", __MOD_USERDATA) + SetNPCBlackboard(player_id, "$__MOD_USERDATA", __MOD_USERDATA) -- Listen for md Userdata update signal. RegisterEvent("Userdata.Update", L.Userdata_Update) @@ -120,9 +127,10 @@ function L.Write_Userdata(owner, key, value) --SetNPCBlackboard(L.player_id, "$__MOD_USERDATA", __MOD_USERDATA) end -L.Init() - -return { +local exports = { Read_Userdata = L.Read_Userdata, Write_Userdata = L.Write_Userdata, -} \ No newline at end of file +} +return exports, L.Init + +end) \ No newline at end of file diff --git a/extensions/sn_script_profiler/ui.xml b/extensions/sn_script_profiler/ui.xml new file mode 100644 index 0000000..2f66536 --- /dev/null +++ b/extensions/sn_script_profiler/ui.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/extensions/sn_script_profiler/lua/Script_Profiler.lua b/extensions/sn_script_profiler/ui/Script_Profiler.lua similarity index 99% rename from extensions/sn_script_profiler/lua/Script_Profiler.lua rename to extensions/sn_script_profiler/ui/Script_Profiler.lua index f8b020e..cd63a63 100644 --- a/extensions/sn_script_profiler/lua/Script_Profiler.lua +++ b/extensions/sn_script_profiler/ui/Script_Profiler.lua @@ -1,3 +1,4 @@ +Lua_Loader.define("extensions.sn_script_profiler.lua.Script_Profiler",function(require) --[[ Lua side of performance profiling. @@ -336,4 +337,5 @@ function L.Deformat_Time(time_string) end -Init() +return nil,Init +) \ No newline at end of file