From e547f76d6f6cd92a725400992ce9182b93e6af07 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Feb 2019 22:03:33 +0000 Subject: [PATCH] Well I tried this is going to need a refactor ;-; --- container.lua | 78 ++++++++++++++++++++++++++++++++++++++++++++--- control.lua | 83 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 151 insertions(+), 10 deletions(-) diff --git a/container.lua b/container.lua index 5a4e93f2..256dfff2 100644 --- a/container.lua +++ b/container.lua @@ -10,6 +10,7 @@ local Container = { --tableToString=serpent.line }, _raw={}, -- any values that are replaced by handlers are moved here + _loaded={}, defines={ errorLoad='ERRLOAD', -- error when loading a file errorNotFound='ERRNOTFOUND', -- error when file not found @@ -18,7 +19,7 @@ local Container = { logDebug=2, -- longer logs of debugging logEvents=3, -- logs which take place very often such as frequent event triggers if no other filters logVerbose=4, -- basically a log of any thing useful - logMax=5 -- what ever is left to log weather you see a current need or not + logAll=5 -- what ever is left to log weather you see a current need or not }, -- to prevent desyncs during on_load any change to the following must be updated -- example: runtime change to logLevel must be applied during on_load to avoid desyncs @@ -46,7 +47,7 @@ function Container.error(...) if Container.safeError then Container.stdout('ERROR',...) else Container.stderr(...) end end function Container.stderr(type,...) - local msg = 'ERROR: '..type + local msg = 'ERROR: '..tostring(type) for _,value in pairs({...}) do msg = msg..' '..Container.tostring(value) end @@ -106,11 +107,60 @@ function Container.tostring(value) end end +--- Sandboxs a function into the container and the given env, will load upvalues if provied in the given env +-- @usage container:sandbox(print,{},'hello from the sandbox') +-- @tparam callback function the function that will be run in the sandbox +-- @tparam env table the env which the function will run in, place upvalues in this table +-- @param[opt] any args you want to pass to the function +-- @treturn boolean did the function run without error +-- @treturn string|table returns error message or the returns from the function +-- @treturn table returns back the env as new values may have been saved +function Container.sandbox(callback,env,...) + -- creates a sandbox env which will later be loaded onto _G + local sandbox_env = setmetatable(env,{ + __index=function(tbl,key) + return rawget(_G,key) + end + }) + sandbox_env._ENV = sandbox_env + sandbox_env._MT_G = getmetatable(_G) + -- sets any upvalues on the callback + local i = 1 + while true do + local name, value = debug.getupvalue(callback,i) + if not name then break end + if not value and sandbox_env[name] then + debug.setupvalue(callback,i,sandbox_env[name]) + end + i=i+1 + end + -- adds the sandbox to _G + setmetatable(_G,{__index=sandbox_env,__newindex=sandbox_env}) + local rtn = {pcall(callback,...)} + local success = table.remove(rtn,1) + setmetatable(_G,_MT_G) + -- returns values from the callback, if error then it returns the error + if success then return success, rtn, sandbox_env + else return success, rtn[1], sandbox_env end +end + function Container.loadFile(filePath) + if Container._loaded[filePath] then return Container._loaded[filePath] end local success,file = pcall(require,filePath) - if not success then return Container.error(Container.defines.errorLoad,file) end - if not file then return Container.error(Container.defines.errorNotFound) end + if not success then return Container.error(Container.defines.errorLoad,filePath,file) end + -- if the file was not found then it returns an error from require which does not trip pcall, tested for here + if Container.type(file,'string') and file:find('no such file') then + -- tries with modules. appended to the front of the path and .control on the end + local success,_file = pcall(require,'modules.'..filePath..'.control') + if not success then return Container.error(Container.defines.errorLoad,filePath,_file) end + -- again tests for the error not caught by pcall + if Container.type(_file,'string') and _file:find('no such file') then return Container.error(Container.defines.errorNotFound,filePath) end + Container.log(Container.defines.logDebug,'Loaded file:',filePath) + Container._loaded[filePath] = _file + return _file + end Container.log(Container.defines.logDebug,'Loaded file:',filePath) + Container._loaded[filePath] = file return file end @@ -139,4 +189,24 @@ function Container.loadFiles() end end +function Container.initFiles() + Container.log(Container.defines.logAlways,'Initiating Container Files') + for filePath,file in pairs(Container._loaded) do + if file.on_init then + file.on_init() + Container.log(Container.defines.logDebug,'Initiated file:',filePath) + end + end +end + +function Container.postFiles() + Container.log(Container.defines.logAlways,'POSTing Container Files') + for filePath,file in pairs(Container._loaded) do + if file.on_post then + file.on_post() + Container.log(Container.defines.logDebug,'POSTed file:',filePath) + end + end +end + return Container \ No newline at end of file diff --git a/control.lua b/control.lua index 3b4fbc77..29962032 100644 --- a/control.lua +++ b/control.lua @@ -1,4 +1,4 @@ --- not_luadoc=true +--[[ not_luadoc=true function _log(...) log(...) end -- do not remove this is used for smaller verbose lines Manager = require("FactorioSoftmodManager") Manager.setVerbose{ @@ -12,21 +12,92 @@ Manager.setVerbose{ output=Manager._verbose -- can be: can be: print || log || other function } Manager() -- can be Manager.loadModules() if called else where +]] ---[[ require 'utils.data_stages' -local Container = require 'container' +Container = require 'container' +Container.debug=false +Container.logLevel=Container.defines.logAll +Container.safeError=true Container.handlers = { + require=function(path,env,...) + env = env or {} + local success, rtn, sandbox_env = Container.sandbox(_R.require,env,path,...) + return rtn + end, Event='utils.event', Global='utils.global', - error=error, + --error=error, logging=function(...) log(...) end, tableToString=serpent.line } Container.loadHandlers() Container.files = { - 'modules.test' + 'AdvancedStartingItems', + 'ChatPopup', + 'DamagePopup', + 'DeathMarkers', + 'DeconControl', + 'ExpGamingAdmin', + 'ExpGamingBot', + 'ExpGamingCommands', + 'ExpGamingCore', + 'ExpGamingInfo', + 'ExpGamingLib', + 'ExpGamingPlayer', + 'FactorioStdLib', + 'GameSettingsGui', + 'GuiAnnouncements', + 'PlayerAutoColor', + 'SpawnArea', + 'WarpPoints', + 'WornPaths', + 'ExpGamingAdmin.Gui', + 'ExpGamingAdmin.Ban', + 'ExpGamingAdmin.Reports', + 'ExpGamingAdmin.ClearInventory', + 'ExpGamingAdmin.TempBan', + 'ExpGamingAdmin.Teleport', + 'ExpGamingAdmin.Commands', + 'ExpGamingAdmin.Jail', + 'ExpGamingAdmin.Warnings', + 'ExpGamingAdmin.Kick', + 'ExpGamingBot.autoMessage', + 'ExpGamingBot.discordAlerts', + 'ExpGamingBot.autoChat', + 'ExpGamingCommands.cheatMode', + 'ExpGamingCommands.repair', + 'ExpGamingCommands.tags', + 'ExpGamingCommands.home', + 'ExpGamingCore.Command', + 'ExpGamingCommands.teleport', + 'ExpGamingCommands.bonus', + 'ExpGamingCommands.kill', + 'ExpGamingCore.Server', + 'ExpGamingCore.Gui', + 'ExpGamingInfo.Science', + 'ExpGamingPlayer.playerList', + 'ExpGamingCore.Sync', + 'ExpGamingCore.Role', + 'ExpGamingInfo.Readme', + 'ExpGamingInfo.Rockets', + 'ExpGamingCore.Group', + 'ExpGamingInfo.Tasklist', + 'ExpGamingPlayer.playerInfo', + 'ExpGamingPlayer.afkKick', + 'FactorioStdLib.Table', + 'ExpGamingPlayer.polls', + 'FactorioStdLib.Color', + 'FactorioStdLib.Game', + 'FactorioStdLib.String', + 'ExpGamingPlayer.inventorySearch', + 'ExpGamingCore.Gui.center', + 'ExpGamingCore.Gui.popup', + 'ExpGamingCore.Gui.toolbar', + 'ExpGamingCore.Gui.left', + 'ExpGamingCore.Gui.inputs' } Container.loadFiles() -]] \ No newline at end of file +Container.initFiles() +Container.postFiles() \ No newline at end of file