diff --git a/FactorioSoftmodManager.lua b/FactorioSoftmodManager.lua index 21f51194..e4a67bd6 100644 --- a/FactorioSoftmodManager.lua +++ b/FactorioSoftmodManager.lua @@ -331,17 +331,9 @@ Manager.loadModules = setmetatable({}, -- if you prefere module_exports can be used rather than returning the module if type(tbl[module_name]) == 'nil' then -- if it is a new module then creat the new index - if string.find(module_name,'GlobalLib') then - Manager.verbose('Extracting GlobalLib: '..module_name) - -- if it is named GlobalLib then it will be auto extracted into _G - if sandbox.module_exports and type(sandbox.module_exports) == 'table' - then for key,value in pairs(sandbox.module_exports) do _G[key] = value end - else for key,value in pairs(table.remove(module,1)) do _G[key] = value end end - else - if sandbox.module_exports and type(sandbox.module_exports) == 'table' - then tbl[module_name] = sandbox.module_exports - else tbl[module_name] = table.remove(module,1) end - end + if sandbox.module_exports and type(sandbox.module_exports) == 'table' + then tbl[module_name] = sandbox.module_exports + else tbl[module_name] = table.remove(module,1) end elseif type(tbl[module_name]) == 'table' then -- if this module adds onto an existing one then append the keys if sandbox.module_exports and type(sandbox.module_exports) == 'table' @@ -362,6 +354,7 @@ Manager.loadModules = setmetatable({}, end -- if there is a module by this name in _G ex table then it will be indexed to the new module if rawget(_G,module_name) and type(tbl[module_name]) == 'table' then setmetatable(rawget(_G,module_name),{__index=tbl[module_name]}) end + if type(tbl[module_name]) == 'table' then tbl[module_name]._module_path = path tbl[module_name]._module_name = module_name end else Manager.verbose('Failed load: "'..module_name..'"; path: '..path..' ('..module..')','errorCaught') for event_name,callbacks in pairs(Manager.event) do Manager.verbose('Removed Event Handler: "'..module_name..'/'..Manager.event.names[event_name],'eventRegistered') callbacks[module_name] = nil end @@ -488,6 +481,7 @@ Manager.error = setmetatable({ end, __index=function(tbl,key) -- this allows the __error_handler to be called from many different names + if type(key) ~= 'string' then return end if key:lower() == 'addhandler' or key:lower() == 'sethandler' or key:lower() == 'handler' or key:lower() == 'register' then return rawget(tbl,'__error_handler') else rawget(tbl,'__error_call')('Invalid index for error handler; please use build in methods.') end end, diff --git a/modules/ExpGamingCore/Server/control.lua b/modules/ExpGamingCore/Server/control.lua index a4a1e49f..e5bc89ea 100644 --- a/modules/ExpGamingCore/Server/control.lua +++ b/modules/ExpGamingCore/Server/control.lua @@ -271,8 +271,11 @@ function Server._thread:create(obj) local obj = obj or {} setmetatable(obj,{__index=Server._thread}) obj.uuid = tostring(Server.uuid) - obj._env = get_env() - obj._env.obj = nil -- provents infinte recusion + obj._env = get_upvalues(2) + obj._env._modules = {} + for name,value in pairs(obj._env) do if value._module_name and loaded_modules[value._module_name] == value then obj._env._modules[name] = value._module_name obj._env[name] = nil end end + obj._env._env = true + obj._env._ENV = nil -- provents infinte recusion local name = obj.name or 'Anon' verbose('Created new thread: '..name..' ('..obj.uuid..')') return obj @@ -480,7 +483,7 @@ end) script.on_event(-2,function(event) -- sets up metatable again so that threads contiune to work - for uuid,thread in pairs(Server.threads) do setmetatable(thread,{__index=Server._thread}) end + for uuid,thread in pairs(Server.threads) do setmetatable(thread,{__index=Server._thread}) setmetatable(thread._env,{__index=function(tbl,key) if rawget(tbl,'_modules') and tbl._modules[key] then return require(tbl._modules[key]) end end}) end end) function Server:on_init() diff --git a/modules/ExpGamingLib/control.lua b/modules/ExpGamingLib/control.lua index c08eb40c..392f76e9 100644 --- a/modules/ExpGamingLib/control.lua +++ b/modules/ExpGamingLib/control.lua @@ -28,11 +28,11 @@ function ExpLib.get_env(level) local level = level and level+1 or 2 local env = setmetatable({},{__index=_G}) while true do - if not debug.getinfo(level) or debug.getinfo(level).namewhat == 'global' then break end + if not debug.getinfo(level) then break end local i = 1 while true do local name, value = debug.getlocal(level,i) - if not name then break else env[name] = value end + if not name or _G[name] == value then break else env[name] = value end i=i+1 end level=level+1 @@ -40,6 +40,23 @@ function ExpLib.get_env(level) return env end +--- Used to get the current ENV with all _G keys removed; useful when saving function to global +-- @usage get_env() returns current ENV with _G keys removed +-- @treturn table the env table with _G keys removed +-- @warning does not work from console +function ExpLib.get_upvalues(level) + local level = level and level+1 or 2 + local func = debug.getinfo(level).func + local upvalues = setmetatable({},{__index=_G}) + local i = 1 + while true do + local name, value = debug.getupvalue(func,i) + if not name then break else upvalues[name] = value end + i=i+1 + end + return upvalues +end + --- Creats a table that will act like a string and a function -- @usage add_metatable({},function) -- returns table -- @tparam table tbl the table that will have its metatable set