From 7cae13b8004226dbd5ee5921f85c7cf788db7368 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 22 Sep 2018 00:29:29 +0100 Subject: [PATCH] Completed ExpGamingCore.Roles --- FactorioSoftmodManager.lua | 9 ++- modules/ExpGamingCore/Group/control.lua | 13 +-- modules/ExpGamingCore/Role/config.lua | 1 + modules/ExpGamingCore/Role/control.lua | 102 ++++++++++++------------ modules/index.lua | 1 + 5 files changed, 68 insertions(+), 58 deletions(-) diff --git a/FactorioSoftmodManager.lua b/FactorioSoftmodManager.lua index 94017ed8..52cbab0b 100644 --- a/FactorioSoftmodManager.lua +++ b/FactorioSoftmodManager.lua @@ -223,7 +223,8 @@ Manager.sandbox = setmetatable({ verbose=Manager.verbose, loaded_modules={}, -- this is over riden later module_verbose=false, - module_exports=false + module_exports=false, + _no_error_in_sandbox=true },{ __metatable=false, __index=ReadOnlyManager, @@ -443,14 +444,14 @@ Manager.error = setmetatable({ -- if the error constant is given crash game if err == rawget(tbl,'__error_const') then Manager.verbose('Force Stop','errorCaught') rawget(tbl,'__error_call')('Force Stop',2) end -- other wise treat the call as if its been passed an err string - Manager.verbose('An error has occurred: '..err,'errorCaught') + if _G._no_error_in_sandbox and ReadOnlyManager.currentState == 'moduleEnv' then else Manager.verbose('An error has occurred: '..err,'errorCaught') end if #tbl > 0 then -- there is at least one error handler loaded; loops over the error handlers for handler_name,callback in pairs(tbl) do local success, err = pcall(callback,err,...) if not success then Manager.verbose('Error handler: "'..handler_name..'" failed to run ('..err..')','errorCaught') end -- if the error constant is returned from the handler then crash the game - if err == rawget(tbl,'__error_const') then Manager.verbose('Force Stop by: '..handler_name,'errorCaught') rawget(tbl,'__error_call')('Force Stop by: '..handler_name) end + if err == rawget(tbl,'__error_const') then Manager.verbose('Force Stop by: '..handler_name,'errorCaught') rawset(tbl,'__crash',true) rawget(tbl,'__error_call')('Force Stop by: '..handler_name) end end elseif game then -- there are no handlers loaded so it will print to the game if loaded @@ -459,8 +460,10 @@ Manager.error = setmetatable({ else -- all else fails it will crash the game with the error code Manager.verbose('No error handlers loaded; Game not loaded; Forced crash: '..err,'errorCaught') + rawset(tbl,'__crash',true) rawget(tbl,'__error_call')(err,2) end + rawget(tbl,'__error_call')(err,2) end, __index=function(tbl,key) -- this allows the __error_handler to be called from many different names diff --git a/modules/ExpGamingCore/Group/control.lua b/modules/ExpGamingCore/Group/control.lua index 0b4a8583..d5ae3464 100644 --- a/modules/ExpGamingCore/Group/control.lua +++ b/modules/ExpGamingCore/Group/control.lua @@ -54,7 +54,8 @@ end -- @tparam ?LuaPlayer|pointerToPlayer|string mixed can either be the name or raw group of a group or a player indenifier -- @treturn table the group which was found or nil function Group.get(mixed) - local player = Game.get_player(mixed) + local player = game and Game.get_player(mixed) + if is_type(mixed,'table') and mixed._raw_group then return mixed end if player then mixed = player.permission_group.name end if is_type(mixed,'table') and mixed.__self and mixed.name then mixed = mixed.name end return Group.groups[mixed] or game.permissions.get_group(mixed) and setmetatable({disallow={},name=mixed,_raw_group=game.permissions.get_group(mixed)},{ @@ -69,9 +70,9 @@ end -- @treturn boolean was the player assigned function Group.assign(player,group) local player = Game.get_player(player) - if not player then error('Invalid player given to Group.assign.',2) return end + if not player then error('Invalid player #1 given to Group.assign.',2) return end local group = Group.get(group) - if not group then error('Invalid group given to Group.assign.',2) return end + if not group then error('Invalid group #2 given to Group.assign.',2) return end return group:add_player(player) end @@ -91,7 +92,7 @@ end function Group._prototype:add_player(player) if not self_test(self,'group','add_player') then return end local player = Game.get_player(player) - if not player then error('Invalid player given to group.add_player.',2) return end + if not player then error('Invalid player #1 given to group.add_player.',2) return end local raw_group = self:get_raw() return raw_group.add_player(player) end @@ -103,7 +104,7 @@ end function Group._prototype:remove_player(player) if not self_test(self,'group','remove_player') then return end local player = Game.get_player(player) - if not player then error('Invalid player given to group.remove_player.',2) return end + if not player then error('Invalid player #1 given to group.remove_player.',2) return end local raw_group = self:get_raw() return raw_group.remove_player(player) end @@ -114,6 +115,7 @@ end -- @treturn table table of players function Group._prototype:get_players(online) if not self_test(self,'group','get_players') then return end + if online and not type_error(online,'boolean','Invalid argument #1 to group:get_players, online is not a boolean.') then return end local raw_group = self:get_raw() local rtn = {} if online then for _,player in pairs(raw_group.players) do if player.connected then table.insert(rtn,player) end end end @@ -127,6 +129,7 @@ end -- @treturn number the number of players who recived the message function Group._prototype:print(rtn,colour) if not self_test(self,'group','print') then return end + if colour and not type_error(colour,'table','Invalid argument #2 to group:print, colour is not a table.') then return end local players = self:get_players() local ctn = 0 for _,player in pairs(players) do if player.connected then player_return(rtn,colour,player) ctn=ctn+1 end end diff --git a/modules/ExpGamingCore/Role/config.lua b/modules/ExpGamingCore/Role/config.lua index 4670c818..05e3dca4 100644 --- a/modules/ExpGamingCore/Role/config.lua +++ b/modules/ExpGamingCore/Role/config.lua @@ -13,6 +13,7 @@ Role{ is_root=true, is_admin=true, is_spectator=true, + is_default=true, allow={} } diff --git a/modules/ExpGamingCore/Role/control.lua b/modules/ExpGamingCore/Role/control.lua index fc784238..042013f7 100644 --- a/modules/ExpGamingCore/Role/control.lua +++ b/modules/ExpGamingCore/Role/control.lua @@ -26,7 +26,7 @@ local Role = { end }), on_init=function() - --code + if loaded_modules['ExpGamingCore.Server@^4.0.0'] then require('ExpGamingCore.Server@^4.0.0').add_module_to_interface('Role','ExpGamingCore.Role') end end, on_post=function(self) -- loads the roles in config @@ -41,7 +41,8 @@ local Role = { role.index = index previous = role end - setmetatable(previous.allow,{__index=function(tbl,key) return false end}) + if previous then setmetatable(previous.allow,{__index=function(tbl,key) return false end}) + else error('Invalid roles, no roles to load.') end end } @@ -74,20 +75,20 @@ end -- gets all roles of a user or a role by name function Role.get(mixed) - local player = Game.get_player(mixed) + local player = game and Game.get_player(mixed) if player then local rtn = {} if not global.players[player.index] then return Role.meta.default and {Role.meta.default} or {} end for _,role in pairs(global.players[player.index]) do table.insert(rtn,Role.get(role)) end return rtn - elseif is_type(mixed,'table') and mixed.role_name then return Roles.roles[mixed.role_name] - elseif is_type(mixed,'string') then return Roles.roles[mixed] end + elseif is_type(mixed,'table') and mixed.group then return mixed + elseif is_type(mixed,'string') then return Role.roles[mixed] end end -- gives a player a role by name or a table of roles function Role.assign(player,role,no_log) local player = Game.get_player(player) - if not player then error('Invalid player given to Role.assign.',2) return end + if not player then error('Invalid player #1 given to Role.assign.',2) return end -- this loops over a table of role if given; will return if ipairs returns, else will asume it was ment to be a role and error if is_type(role,'table') and not role.name then local ctn = 0 @@ -95,7 +96,7 @@ function Role.assign(player,role,no_log) if ctn > 0 then if not no_log then table.insert(global.changes[player.index],{'assign',role.name}) end return end end local role = Role.get(role) - if not role then error('Invalid role given to Role.assign.',2) return end + if not role then error('Invalid role #2 given to Role.assign.',2) return end -- this acts as a way to provent the global table getting too full if not global.changes[player.index] then global.changes[player.index]={} end if #global.changes[player.index] > 20 then table.remove(global.changes[player.index],1) end @@ -106,7 +107,7 @@ end -- removes a player from a role by name or a table of roles function Role.unassign(player,role,no_log) local player = Game.get_player(player) - if not player then error('Invalid player given to Role.unassign.',2) return end + if not player then error('Invalid player #1 given to Role.unassign.',2) return end -- this loops over a table of role if given; will return if ipairs returns, else will asume it was ment to be a role and error if is_type(role,'table') and not role.name then local ctn = 0 @@ -114,7 +115,7 @@ function Role.unassign(player,role,no_log) if ctn > 0 then if not no_log then table.insert(global.changes[player.index],{'unassign',role.name}) end return end end local role = Role.get(role) - if not role then error('Invalid role given to Role.unassign.',2) return end + if not role then error('Invalid role #2 given to Role.unassign.',2) return end if not global.changes[player.index] then global.changes[player.index]={} end -- this acts as a way to provent the global table getting too full if #global.changes[player.index] > 20 then table.remove(global.changes[player.index],1) end @@ -126,11 +127,12 @@ end function Role.get_highest(options) local player = Game.get_player(options) if player then options = Role.get(player) end - if not type_error(options,'table','Invalid argument to Role.highest, options is not a table of roles.') then return end + if not type_error(options,'table','Invalid argument #1 to Role.highest, options is not a table of roles.') then return end local highest_index = -1 local highest - for _,role in pairs(options) do - local role = Role.get(role) + for _,role_name in pairs(options) do + local role = Role.get(role_name) + if not role then error('Invalid role inside options: '..serpent.line(role_name)) return end if highest_index == -1 or role.index < highest_index then highest_index,highest = role.index,role end end return highest @@ -139,8 +141,8 @@ end -- reverts the last change to a user's roles function Role.revert(player,count) local player = Game.get_player(player) - if not player then error('Invalid player given to Role.revert.',2) return end - if count and not type_error(count,'number','Invalid argument to Role.revert, count is not a number.') then return end + if not player then error('Invalid player #1 given to Role.revert.',2) return end + if count and not type_error(count,'number','Invalid argument #2 to Role.revert, count is not a number.') then return end local changes = global.changes[player.index] or {} if #changes == 0 then error('Player has no role changes logged, can not revert.') end local count = count or 1 @@ -160,17 +162,17 @@ end -- all the flags a player has are combined with true as pirority -- example Role.add_flag('is_admin',function(player,state) player.admin = state end) function Role.add_flag(flag,callback) - if not type_error(flag,'string','Invalid argument to Role.add_flag, flag is not a string.') then return end - if callback and not type_error(callback,'function','Invalid argument to Role.add_flag, callback is not a function.') then return end + if not type_error(flag,'string','Invalid argument #1 to Role.add_flag, flag is not a string.') then return end + if callback and not type_error(callback,'function','Invalid argument #2 to Role.add_flag, callback is not a function.') then return end verbose('Added flag: '..flag) Role.flags[flag] = callback or true end -- tests if mixed (either player or role) has the requested flag function Role.has_flag(mixed,flag) - if not type_error(flag,'string','Invalid argument to Role.has_flag, flag is not a string.') then return end + if not type_error(flag,'string','Invalid argument #2 to Role.has_flag, flag is not a string.') then return end local roles = Role.get(mixed) - if not type_error(roles,'table','Invalid argument to Role.has_flag, mixed is not a role or player.') then return end + if not type_error(roles,'table','Invalid argument #1 to Role.has_flag, mixed is not a role or player.') then return end if #roles then for _,role in pairs(roles) do if role:has_flag(flag) then return true end end elseif roles:has_flag(flag) then return true end @@ -180,33 +182,33 @@ end -- allows a table to be made that includes all possible actions and thus can test who is allowed -- used purly as a way to loop over all actions function Role.add_action(action) - if not type_error(action,'string','Invalid argument to Role.add_action, action is not a string.') then return end + if not type_error(action,'string','Invalid argument #1 to Role.add_action, action is not a string.') then return end verbose('Added action: '..action) table.insert(Role.actions,action) end -- returns if mixed (either player or role) is allowed to do this action function Role.allowed(mixed,action) - if not type_error(action,'string','Invalid argument to Role.allowed, action is not a string.') then return end + if not type_error(action,'string','Invalid argument #2 to Role.allowed, action is not a string.') then return end local roles = Role.get(mixed) - if not type_error(roles,'table','Invalid argument to Role.allowed, mixed is not a role or player.') then return end + if not type_error(roles,'table','Invalid argument #1 to Role.allowed, mixed is not a role or player.') then return end if #roles then for _,role in pairs(roles) do - if role:allowed(flag) then return true end - end elseif roles:allowed(flag) then return true end + if role:allowed(action) then return true end + end elseif roles:allowed(action) then return true end return false end -- prints to this role and all below it or above if inv function Role.print(role,rtn,colour,inv) - local role = Role.get(mixed) - if not type_error(roles,'table','Invalid argument to Role.print, role is invalid.') then return end - if colour and not type_error(colour,'table','Invalid argument to Role.print, colour is not a table.') then return end - if inv and not type_error(inv,'boolean','Invalid argument to Role.print, inv is not a boolean.') then return end + local role = Role.get(role) + if not type_error(role,'table','Invalid argument #1 to Role.print, role is invalid.') then return end + if colour and not type_error(colour,'table','Invalid argument #3 to Role.print, colour is not a table.') then return end + if inv and not type_error(inv,'boolean','Invalid argument #4 to Role.print, inv is not a boolean.') then return end local print = inv or false local ctn = 0 - for index,role_name in pairs(Role.roles) do - if print then ctn=ctn+Role.roles[role_name]:print(rtn,colour) end - if role_name == role.name then if print then break else print = true end end + for index,_role in pairs(Role.roles) do + if print or _role == role then ctn=ctn+_role:print(rtn,colour) end + if _role == role then if print then break else print = true end end end return ctn end @@ -214,38 +216,38 @@ end -- outputs all roles for debug purposes function Role.debug_output(role,player) local player = Game.get_player(player) or game.player - if not player then error('Invalid player given to Role.debug_output.',2) return end - local function _output(role) - local flags = {};for flag in pairs(Role.flags) do if role:has_flag(flag) then table.insert(flags,flag) end end - local rtn = string.format('%s) %q %s > Group: %q Time: %s Flags: %s', - role.index,role.name,role.tag,role.group,tostring(role.time),table.concat(flags,',')) - player_return(rtn,role.colour,player) + if not player then error('Invalid player #2 given to Role.debug_output.',2) return end + local function _output(_role) + local flags = {};for flag in pairs(Role.flags) do if _role:has_flag(flag) then table.insert(flags,flag) end end + local rtn = string.format('%s) %q-%q || Tag: %s Short Hand: %q Time: %s Flags: %s', + _role.index,_role.group.name,_role.name,_role.tag,_role.short_hand,tostring(_role.time),table.concat(flags,', ')) + player_return(rtn,_role.colour,player) end if role then local role = Role.get(mixed) - if not type_error(roles,'table','Invalid argument to Role.print, role is invalid.') then return end + if not type_error(roles,'table','Invalid argument #1 to Role.print, role is invalid.') then return end _output(role) - else for index,role_name in pairs(Role.roles) do _output(Role.roles[role_name]) end end + else for index,_role in pairs(Role.roles) do _output(_role) end end end -- returns true if this role has this flag set function Role._prototype:has_flag(flag) if not self_test(self,'role','has_flag') then return end - if not type_error(flag,'string','Invalid argument to role:has_flag, flag is not a string.') then return end + if not type_error(flag,'string','Invalid argument #1 to role:has_flag, flag is not a string.') then return end return self[flag] or false end -- returns true if the rank is allowed, indexing with metatables for inheraitance function Role._prototype:allowed(action) if not self_test(self,'role','allowed') then return end - if not type_error(action,'string','Invalid argument to role:allowed, action is not a string.') then return end - return self.allowed[action] or self.is_root or false -- still include is_root exception flag + if not type_error(action,'string','Invalid argument #1 to role:allowed, action is not a string.') then return end + return self.allow[action] or self.is_root or false -- still include is_root exception flag end -- gets the players in this role and online only if online is true function Role._prototype:get_players(online) if not self_test(self,'role','get_players') then return end - if online and not type_error(online,'boolean','Invalid argument to role:get_players, online is not a boolean.') then return end + if online and not type_error(online,'boolean','Invalid argument #1 to role:get_players, online is not a boolean.') then return end if not global.roles[self.name] then global.roles[self.name] = {} end local rtn = {} for _,player_index in pairs(global.roles[self.name]) do @@ -258,7 +260,7 @@ end -- prints a message to all players with this role function Role._prototype:print(rtn,colour) if not self_test(self,'role','print') then return end - if colour and not type_error(colour,'table','Invalid argument to Role.print, colour is not a table.') then return end + if colour and not type_error(colour,'table','Invalid argument #2 to Role.print, colour is not a table.') then return end local ctn = 0 for _,player in pairs(self:get_players(true)) do ctn=ctn+1 player_return(rtn,colour,player) end return ctn @@ -276,12 +278,12 @@ end function Role._prototype:add_player(player,by_player) if not self_test(self,'role','add_player') then return end local player = Game.get_player(player) - if not player then error('Invalid player given to role:add_player.',2) return end + if not player then error('Invalid player #1 given to role:add_player.',2) return end local by_player = Game.get_player(by_player) if not by_player then by_player = {name='',index=0} end if not global.roles[self.name] then global.roles[self.name] = {} end - if not global.players[player.index] then global.roles[player.index] = {} end - local highest = Role.get_highest(player) + if not global.players[player.index] then global.players[player.index] = {} end + local highest = Role.get_highest(player) or Role.meta.default table.insert(global.roles[self.name],player.index) table.insert(global.players[player.index],self.name) script.raise_event(role_change_event_id,{ @@ -299,11 +301,11 @@ end function Role._prototype:remove_player(player,by_player) if not self_test(self,'role','add_player') then return end local player = Game.get_player(player) - if not player then error('Invalid player given to role:remove_player.',2) return end + if not player then error('Invalid player #1 given to role:remove_player.',2) return end local by_player = Game.get_player(by_player) or {name='',index=0} if not global.roles[self.name] then global.roles[self.name] = {} end - if not global.players[player.index] then global.roles[player.index] = {} end - local highest = Role.get_highest(player) + if not global.players[player.index] then global.players[player.index] = {} end + local highest = Role.get_highest(player) or Role.meta.default local index = 0 for _index,player_index in pairs(global.roles[self.name]) do if player_index == player.index then index=_index break end end table.remove(global.roles[self.name],index) @@ -325,7 +327,7 @@ script.on_event(role_change_event_id,function(event) -- varible init local player = Game.get_player(event) local by_player = Game.get_player(event.by_player_index) or {name='',index=0} - local role = Role.get(event) + local role = Role.get(event.role_name) local highest = Role.get_highest(player) -- assign new tag and group of highest role Group.assign(player,highest.group) diff --git a/modules/index.lua b/modules/index.lua index 84e0b35f..ffe4caf3 100644 --- a/modules/index.lua +++ b/modules/index.lua @@ -50,4 +50,5 @@ return { ['ChatPopup@4.0.0']='./modules/ChatPopup', ['DamagePopup@4.0.0']='./modules/DamagePopup', ['ExpGamingCore.Group@4.0.0']='./modules/ExpGamingCore/Group', + ['ExpGamingCore.Role@4.0.0']='./modules/ExpGamingCore/Role', } \ No newline at end of file