mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-29 20:16:38 +09:00
Moved Files Around
This commit is contained in:
@@ -1,298 +0,0 @@
|
||||
--- Command system that allows middle ware and auto validation of command arguments.
|
||||
-- @module ExpGamingCore.Command@4.0.0
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
-- @alias commands
|
||||
|
||||
local Game = require('FactorioStdLib.Game')
|
||||
local Color = require('FactorioStdLib.Color')
|
||||
|
||||
--- Used as an error constant for validation
|
||||
-- @field commands.error
|
||||
-- @usage return commands.error, 'err message'
|
||||
-- @usage return commands.error('err message')
|
||||
commands.error = setmetatable({},{__call=function(...) return ... end})
|
||||
commands._add_command = commands.add_command
|
||||
local commandDataStore = {}
|
||||
local middleware = {}
|
||||
|
||||
--- Used to add middle ware to the command handler, functions should return true or false
|
||||
-- @tparam function callback function(player,commandName,event) should return true to allow next middle ware to run
|
||||
function commands.add_middleware(callback) if not is_type(callback,'function') then error('Callback is not a function',2) return end table.insert(middleware,callback) end
|
||||
|
||||
--- Index of all command data
|
||||
-- @field commands.data
|
||||
-- @usage commands.command_name -- returns command data
|
||||
-- @usage commands.data -- returns all data
|
||||
-- @tparam ?string|table|event key the command that will be returned: string is the name, table is the command data, event is event from add_command
|
||||
-- @treturn table the command data
|
||||
setmetatable(commands,{
|
||||
__index=function(tbl,key) return is_type(key,'table') and (key.command and rawget(commandDataStore,key.name) or key) or key == 'data' and commandDataStore or rawget(commandDataStore,key) end
|
||||
})
|
||||
|
||||
--- Collection of functions that can be used to validate inputs
|
||||
-- @table commands.validate
|
||||
-- @usage commands.validate[type](value,event,...)
|
||||
-- @tparam string type the type that the value should be
|
||||
-- @param value the value that will be tested
|
||||
-- @param ... any other data that can be passed to the function
|
||||
-- @return[1] the validated value
|
||||
-- @return[2] error constant
|
||||
-- @return[2] the err message
|
||||
-- @field __comment replace _ with - the ldoc did not like me using - in the names
|
||||
-- @field string basically does nothing but a type filed is required
|
||||
-- @field string_inf same as string but is infinite in length, must be last arg
|
||||
-- @field string_len same as string but can define a max length
|
||||
-- @field number converts the input into a number
|
||||
-- @field number_int converts the input to a number and floors it
|
||||
-- @field number_range allows a number in a range min < X <= max
|
||||
-- @field number_range allows a number in a range after it has been floored min < math.floor(X) <= max
|
||||
-- @field player converts the input into a valid player
|
||||
-- @field player_online converts the input to a player if the player is online
|
||||
-- @field player_alive converts the input to a player if the player is online and alive
|
||||
-- @field player_role converts the input to a player if the player is a lower rank than the user or if the person is not admin and the user is
|
||||
-- @field player_role-online converts the input to a player if the player is a lower rank than the user and online
|
||||
-- @field player_role_alive converts the input to a player if the player is a lower rank than the user and online and alive
|
||||
commands.validate = {
|
||||
['boolean']=function(value) value = value.lower() if value == 'true' or value == 'yes' or value == 'y' or value == '1' then return true else return false end end,
|
||||
['string']=function(value) return tostring(value) end,
|
||||
['string-inf']=function(value) return tostring(value) end,
|
||||
['string-list']=function(value,event,list)
|
||||
local rtn = tostring(value) and table.includes(list,tostring(value)) and tostring(value) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-string-list',table.concat(list,', ')} end return rtn end,
|
||||
['string-len']=function(value,event,max)
|
||||
local rtn = tostring(value) and tostring(value):len() <= max and tostring(value) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-string-len',max} end return rtn end,
|
||||
['number']=function(value)
|
||||
local rtn = tonumber(value) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-number'} end return rtn end,
|
||||
['number-int']=function(value)
|
||||
local rtn = tonumber(value) and math.floor(tonumber(value)) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-number'} end return rtn end,
|
||||
['number-range']=function(value,event,min,max)
|
||||
local rtn = tonumber(value) and tonumber(value) > min and tonumber(value) <= max and tonumber(value) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-number-range',min,max} end return rtn end,
|
||||
['number-range-int']=function(value,event,min,max)
|
||||
local rtn = tonumber(value) and math.floor(tonumber(value)) > min and math.floor(tonumber(value)) <= max and math.floor(tonumber(value)) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-number-range',min,max} end return rtn end,
|
||||
['player']=function(value)
|
||||
local rtn = Game.get_player(value) or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-player',value} end return rtn end,
|
||||
['player-online']=function(value)
|
||||
local player,err = commands.validate['player'](value)
|
||||
if err then return commands.error(err) end
|
||||
local rtn = player.connected and player or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-player-online'} end return rtn end,
|
||||
['player-alive']=function(value)
|
||||
local player,err = commands.validate['player-online'](value)
|
||||
if err then return commands.error(err) end
|
||||
local rtn = player.character and player.character.health > 0 and player or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-player-alive'} end return rtn end,
|
||||
['player-rank']=function(value,event)
|
||||
local player,err = commands.validate['player'](value)
|
||||
if err then return commands.error(err) end
|
||||
local rtn = player.admin and Game.get_player(event).admin and player or nil
|
||||
if not rtn then return commands.error{'expcore-commands.error-player-rank'} end return rtn end,
|
||||
['player-rank-online']=function(value)
|
||||
local player,err = commands.validate['player-online'](value)
|
||||
if err then return commands.error(err) end
|
||||
local player,err = commands.validate['player-rank'](player)
|
||||
if err then return commands.error(err) end return player end,
|
||||
['player-rank-alive']=function(value)
|
||||
local player,err = commands.validate['player-alive'](value)
|
||||
if err then return commands.error(err) end
|
||||
local player,err = commands.validate['player-rank'](player)
|
||||
if err then return commands.error(err) end return player end,
|
||||
}
|
||||
--- Adds a function to the validation list
|
||||
-- @tparam string name the name of the validation
|
||||
-- @tparam function callback function(value,event) which returns either the value to be used or commands.error{'error-message'}
|
||||
function commands.add_validation(name,callback) if not is_type(callback,'function') then error('Callback is not a function',2) return end commands.validate[name]=callback end
|
||||
|
||||
--- Returns the inputs of this command as a formated string
|
||||
-- @usage commands.format_inputs('interface') -- returns <code> (if you have ExpGamingCore.Server)
|
||||
-- @tparam ?string|table|event command the command to get the inputs of
|
||||
-- @treturn string the formated string for the inputs
|
||||
function commands.format_inputs(command)
|
||||
command = commands[command]
|
||||
if not is_type(command,'table') then error('Command is not valid',2) end
|
||||
local rtn = ''
|
||||
for name,data in pairs(command.inputs) do
|
||||
if data[1] == false then rtn=rtn..string.format('[%s] ',name)
|
||||
else rtn=rtn..string.format('<%s> ',name) end
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Used to validate the arguments of a command, will understand strings with "" as a single param else spaces divede the params
|
||||
-- @usage commands.validate_args(event) -- returns args table
|
||||
-- @tparam table event this is the event created by add_command not on_console_command
|
||||
-- @treturn[1] table the args for this command
|
||||
-- @return[2] command.error
|
||||
-- @treturn string the error that happend while parsing the args
|
||||
function commands.validate_args(event)
|
||||
local command = commands[event.name]
|
||||
if not is_type(command,'table') then error('Command not valid',2) end
|
||||
local rtn = {}
|
||||
local count = 0
|
||||
local count_opt = 0
|
||||
for _,data in pairs(command.inputs) do count = count + 1 if data[1] == false then count_opt = count_opt + 1 end end
|
||||
-- checks that there is some args given if there is meant to be
|
||||
if not event.parameter then
|
||||
if count == count_opt then return rtn
|
||||
else return commands.error('invalid-inputs') end
|
||||
end
|
||||
-- splits the args into words so that it can be used to assign values
|
||||
local words = string.split(event.parameter,' ')
|
||||
local index = 0
|
||||
for _,word in pairs(words) do
|
||||
index = index+1
|
||||
if not word then break end
|
||||
local pos, _pos = word:find('"')
|
||||
local hasSecond = pos and word:find('"',pos+1) or nil
|
||||
while not hasSecond and pos and pos == _pos do
|
||||
local next = table.remove(words,index+1)
|
||||
if not next then return commands.error('invalid-parse') end
|
||||
words[index] = words[index]..' '..next
|
||||
_pos = words[index]:find('"',pos+1)
|
||||
end
|
||||
end
|
||||
-- assigns the values from the words to the args
|
||||
index = 0
|
||||
for name,data in pairs(command.inputs) do
|
||||
index = index+1
|
||||
local arg = words[index]
|
||||
if not arg and data[1] then return commands.error('invalid-inputs') end
|
||||
if data[2] == 'string-inf' then rtn[name] = table.concat(words,' ',index) break end
|
||||
local valid = is_type(data[2],'function') and data[2] or commands.validate[data[2]] or error('Invalid validation ("'..tostring(data[2])..'") for command: "'..command.name..'/'..name..'"')
|
||||
local temp_tbl = table.deepcopy(data) table.remove(temp_tbl,1) table.remove(temp_tbl,1)
|
||||
local value, err = valid(arg,event,unpack(temp_tbl))
|
||||
if value == commands.error then return value, err end
|
||||
rtn[name] = is_type(value,'string') and value:gsub('"','') or value
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Used to return all the commands a player can use
|
||||
-- @usage get_commands(1) -- return table of command data for each command that the player can use
|
||||
-- @tparam ?index|name|player| player the player to test as
|
||||
-- @treturn table a table containg all the commands the player can use
|
||||
function commands.get_commands(player)
|
||||
player = Game.get_player(player)
|
||||
local commands = {}
|
||||
if not player then return error('Invalid player',2) end
|
||||
for name,data in pairs(commandDataStore) do
|
||||
if #middleware > 0 then for _,callback in pairs(middleware) do
|
||||
local success, err = pcall(callback,player,name,data)
|
||||
if not success then error(err)
|
||||
elseif err then table.insert(commands,data) end
|
||||
end elseif data.default_admin_only == true and player.admin then table.insert(commands,data) end
|
||||
end
|
||||
return commands
|
||||
end
|
||||
|
||||
local function logMessage(player_name,command,message,args)
|
||||
game.write_file('commands.log',
|
||||
game.tick
|
||||
..' Player: "'..player_name..'"'
|
||||
..' '..message..': "'..command.name..'"'
|
||||
..' With args of: '..table.tostring(args)
|
||||
..'\n'
|
||||
, true, 0)
|
||||
end
|
||||
|
||||
--- Used to call the custom commands
|
||||
-- @usage You dont its an internal command
|
||||
-- @tparam table command the event rasied by the command
|
||||
local function run_custom_command(command)
|
||||
local data = commands.data[command.name]
|
||||
local player = Game.get_player(command) or SERVER
|
||||
-- runs all middle ware if any, if there is no middle where then it relies on .default_admin_only
|
||||
if #middleware > 0 then for _,callback in pairs(middleware) do
|
||||
local success, err = pcall(callback,player,command.name,command)
|
||||
if not success then error(err)
|
||||
elseif not err then
|
||||
player_return({'expcore-commands.command-fail',{'expcore-commands.unauthorized'}},defines.textcolor.crit)
|
||||
logMessage(player.name,command,'Failed to use command (Unauthorized)',commands.validate_args(command))
|
||||
game.player.play_sound{path='utility/cannot_build'}
|
||||
return
|
||||
end
|
||||
end elseif data.default_admin_only == true and player and not player.admin then
|
||||
player_return({'expcore-commands.command-fail',{'expcore-commands.unauthorized'}},defines.textcolor.crit)
|
||||
logMessage(player.name,command,'Failed to use command (Unauthorized)',commands.validate_args(command))
|
||||
game.player.play_sound{path='utility/cannot_build'}
|
||||
return
|
||||
end
|
||||
-- gets the args for the command
|
||||
local args, err = commands.validate_args(command)
|
||||
if args == commands.error then
|
||||
if is_type(err,'table') then table.insert(err,command.name) table.insert(err,commands.format_inputs(data))
|
||||
player_return({'expcore-commands.command-fail',err},defines.textcolor.high) else player_return({'expcore-commands.command-fail',{'expcore-commands.invalid-inputs',command.name,commands.format_inputs(data)}},defines.textcolor.high) end
|
||||
logMessage(player.name,command,'Failed to use command (Invalid Args)',args)
|
||||
player.play_sound{path='utility/deconstruct_big'}
|
||||
return
|
||||
end
|
||||
-- runs the command
|
||||
local success, err = pcall(data.callback,command,args)
|
||||
if not success then error(err) end
|
||||
if err ~= commands.error then player_return({'expcore-commands.command-ran'},defines.textcolor.info) end
|
||||
logMessage(player.name,command,'Used command',args)
|
||||
end
|
||||
|
||||
--- Used to define commands
|
||||
-- @usage --see examples in file
|
||||
-- @tparam string name the name of the command
|
||||
-- @tparam[opt='No Description'] string description the description of the command
|
||||
-- @tparam[opt=an infinite string] table inputs a table of the inputs to be used, last index being true makes the last parameter open ended (longer than one word)
|
||||
-- @tparam function callback the function to call on the event
|
||||
commands.add_command = function(name, description, inputs, callback)
|
||||
if commands[name] then error('That command is already registered',2) end
|
||||
if not is_type(name,'string') then error('Command name has not been given') end
|
||||
if not is_type(callback,'function') or not is_type(inputs,'table') then
|
||||
if is_type(inputs,'function') then commands._add_command(name,description,inputs)
|
||||
else error('Invalid args given to add_command') end
|
||||
end
|
||||
verbose('Created Command: '..name)
|
||||
-- test for string and then test for locale string
|
||||
description = is_type(description,'string') and description
|
||||
or is_type(description,'table') and is_type(description[1],'string') and string.find(description[1],'.+[.].+') and {description,''}
|
||||
or 'No Description'
|
||||
inputs = is_type(inputs,'table') and inputs or {['param']={false,'string-inf'}}
|
||||
commandDataStore[name] = {
|
||||
name=name,
|
||||
description=description,
|
||||
inputs=inputs,
|
||||
callback=callback,
|
||||
admin_only=false
|
||||
}
|
||||
local help = is_type(description,'string') and commands.format_inputs(name)..'- '..description
|
||||
or is_type(description,'table') and is_type(description[1],'string') and string.find(description[1],'.+[.].+') and {description,commands.format_inputs(name)..'- '}
|
||||
or commands.format_inputs(name)
|
||||
commandDataStore[name].help = help
|
||||
commands._add_command(name,help,function(...)
|
||||
local success, err = Manager.sandbox(run_custom_command,{},...)
|
||||
if not success then error(err) end
|
||||
end)
|
||||
return commandDataStore[name]
|
||||
end
|
||||
|
||||
return commands
|
||||
|
||||
--[[
|
||||
command example
|
||||
|
||||
**locale file**
|
||||
[foo]
|
||||
description=__1__ this is a command
|
||||
|
||||
**control.lua**
|
||||
commands.add_command('foo',{'foo.description'},{
|
||||
['player']={true,'player'}, -- a required arg that must be a valid player
|
||||
['number']={true,'number-range',0,10}, -- a required arg that must be a number 0<X<=10
|
||||
['pwd']={true,function(value,event) if value == 'password123' then return true else return commands.error('Invalid Password') end} -- a required arg pwd that has custom validation
|
||||
['reason']={false,'string-inf'} -- an optional arg that is and infinite length (useful for reasons)
|
||||
},function(event,args)
|
||||
args.player.print(args.number)
|
||||
if args.reasons then args.player.print(args.reason) end
|
||||
end)
|
||||
]]
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "ExpGamingCore.Command",
|
||||
"version": "4.0.0",
|
||||
"description": "A better command handler than the base game.",
|
||||
"location": "FSM_ARCHIVE",
|
||||
"keywords": [
|
||||
"Library",
|
||||
"Lib",
|
||||
"ExpGaming",
|
||||
"Core",
|
||||
"Commands"
|
||||
],
|
||||
"dependencies": {
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"FactorioStdLib.Color": "^0.8.0",
|
||||
"FactorioStdLib.Game": "^0.8.0"
|
||||
},
|
||||
"collection": "ExpGamingCore@4.0.0",
|
||||
"submodules": {}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
-- defines for groups
|
||||
Group{
|
||||
name='Admin',
|
||||
disallow={
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group'
|
||||
}
|
||||
}
|
||||
|
||||
Group{
|
||||
name='HiMember',
|
||||
disallow={
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group'
|
||||
}
|
||||
}
|
||||
|
||||
Group{
|
||||
name='Member',
|
||||
disallow={
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group',
|
||||
'set_auto_launch_rocket',
|
||||
'change_programmable_speaker_alert_parameters',
|
||||
'drop_item'
|
||||
}
|
||||
}
|
||||
|
||||
Group{
|
||||
name='User',
|
||||
disallow={
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group',
|
||||
'set_auto_launch_rocket',
|
||||
'change_programmable_speaker_alert_parameters',
|
||||
'drop_item',
|
||||
'build_terrain',
|
||||
'remove_cables',
|
||||
'launch_rocket',
|
||||
'reset_assembling_machine',
|
||||
'cancel_research'
|
||||
}
|
||||
}
|
||||
|
||||
Group{
|
||||
name='Jail',
|
||||
disallow={
|
||||
'set_allow_commands',
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group',
|
||||
'open_character_gui',
|
||||
'begin_mining',
|
||||
'start_walking',
|
||||
'player_leave_game',
|
||||
'open_blueprint_library_gui',
|
||||
'build_item',
|
||||
'use_item',
|
||||
'select_item',
|
||||
'rotate_entity',
|
||||
'open_train_gui',
|
||||
'open_train_station_gui',
|
||||
'open_gui',
|
||||
'open_item',
|
||||
'deconstruct',
|
||||
'build_rail',
|
||||
'cancel_research',
|
||||
'start_research',
|
||||
'set_train_stopped',
|
||||
'select_gun',
|
||||
'open_technology_gui',
|
||||
'open_trains_gui',
|
||||
'edit_custom_tag',
|
||||
'craft',
|
||||
'setup_assembling_machine',
|
||||
}
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
--- Adds a system to manage and auto-create permission groups.
|
||||
-- @module ExpGamingCore@Group
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
-- @alias Group
|
||||
|
||||
-- Module Require
|
||||
local Game = require('FactorioStdLib.Game')
|
||||
|
||||
-- Module Define
|
||||
local module_verbose = false
|
||||
|
||||
--- Used as an interface for factorio permissions groups
|
||||
-- @type Group
|
||||
-- @field _prototype the prototype of this class
|
||||
-- @field groups a table of all groups, includes auto complete on the indexing
|
||||
local _GroupSelfRef
|
||||
local Group = {
|
||||
_prototype = {},
|
||||
groups = setmetatable({},{
|
||||
__index=table.autokey,
|
||||
__newindex=function(tbl,key,value)
|
||||
rawset(tbl,key,_GroupSelfRef.define(value))
|
||||
end
|
||||
}),
|
||||
on_init = function()
|
||||
if loaded_modules['ExpGamingCore.Server'] then require('ExpGamingCore.Server') end
|
||||
end,
|
||||
on_post = function(self)
|
||||
-- creates a root role that the server can use
|
||||
self{name='Root',disallow={}}
|
||||
-- loads the groups in config
|
||||
require(module_path..'/config',{Group=self})
|
||||
end
|
||||
}
|
||||
_GroupSelfRef=Group
|
||||
|
||||
-- Function Define
|
||||
|
||||
--- Defines a new instance of a group
|
||||
-- @usage Group.define{name='foo',disallow={'edit_permission_group','delete_permission_group','add_permission_group'}} -- returns new group
|
||||
-- @usage Group{name='foo',disallow={'edit_permission_group','delete_permission_group','add_permission_group'}} -- returns new group
|
||||
-- @tparam table obj contains string name and table disallow of defines.input_action
|
||||
-- @treturn Group the group which has been made
|
||||
function Group.define(obj)
|
||||
if not type_error(game,nil,'Cant define Group during runtime.') then return end
|
||||
if not type_error(obj.name,'string','Group creation is invalid: group.name is not a string') then return end
|
||||
if not type_error(obj.disallow,'table','Group creation is invalid: group.disallow is not a table') then return end
|
||||
verbose('Created Group: '..obj.name)
|
||||
setmetatable(obj,{__index=function(tbl,key) return Group._prototype[key] or game and game.permissions.get_group(tbl.name)[key] or nil end})
|
||||
obj.connected_players = setmetatable({self=obj},Group._prototype.connected_players_mt)
|
||||
rawset(Group.groups,obj.name,obj)
|
||||
return obj
|
||||
end
|
||||
|
||||
--- Used to get the group of a player or the group by name
|
||||
-- @usage Group.get('foo') -- returns group foo
|
||||
-- @usage Group.get(player) -- returns group of player
|
||||
-- @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)
|
||||
if is_type(mixed,'table') and mixed.name then mixed = mixed.name end
|
||||
if game and Game.get_player(mixed) then mixed = Game.get_player(mixed).permission_group.name end
|
||||
local rtn = Group.groups[mixed]
|
||||
if not rtn and game and is_type(mixed,'string') and game.permissions.get_group(mixed) then
|
||||
rtn = setmetatable({disallow={},name=mixed},{
|
||||
__index=function(tbl,key) return Group._prototype[key] or game and game.permissions.get_group(tbl.name)[key] or nil end
|
||||
})
|
||||
rtn.connected_players = setmetatable({self=rtn},Group._prototype.connected_players_mt)
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Used to place a player into a group
|
||||
-- @usage Group.assign(player,group)
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer player the player to assign the group to
|
||||
-- @tparam ?string|LuaPermissionGroup the group to add the player to
|
||||
-- @treturn boolean was the player assigned
|
||||
function Group.assign(player,group)
|
||||
player = Game.get_player(player)
|
||||
if not player then error('Invalid player #1 given to Group.assign.',2) return end
|
||||
group = Group.get(group)
|
||||
if not group then error('Invalid group #2 given to Group.assign.',2) return end
|
||||
return group:add_player(player)
|
||||
end
|
||||
|
||||
--- Used to get the factorio permission group linked to this group
|
||||
-- @usage group:get_raw() -- returns LuaPermissionGroup of this group
|
||||
-- @treturn LuaPermissionGroup the factorio group linked to this group
|
||||
function Group._prototype:get_raw()
|
||||
if not self_test(self,'group','get_raw') then return end
|
||||
local _group = game.permissions.get_group(self.name)
|
||||
if not _group or _group.valid == false then error('No permissions group found, please to not remove groups with /permissions',2) return end
|
||||
return setmetatable({},{__index=_group})
|
||||
end
|
||||
|
||||
--- Used to add a player to this group
|
||||
-- @usage group:add_player(player) -- returns true if added
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer player the player to add to the group
|
||||
-- @treturn boolean if the player was added
|
||||
function Group._prototype:add_player(player)
|
||||
if not self_test(self,'group','add_player') then return end
|
||||
player = Game.get_player(player)
|
||||
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
|
||||
|
||||
--- Used to remove a player from this group
|
||||
-- @usage group:remove_player(player) -- returns true if removed
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer player the player to remove from the group
|
||||
-- @treturn boolean if the player was removed
|
||||
function Group._prototype:remove_player(player)
|
||||
if not self_test(self,'group','remove_player') then return end
|
||||
player = Game.get_player(player)
|
||||
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
|
||||
|
||||
--- Gets all players in this group
|
||||
-- @usage group:get_players() -- returns table of players
|
||||
-- @usage group.players -- returns table of players
|
||||
-- @usage group.connected_players -- returns table of online players
|
||||
-- @tparam[opt=false] boolean online if true returns only online players
|
||||
-- @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
|
||||
return online and rtn or raw_group.players
|
||||
end
|
||||
|
||||
-- this is used to create a connected_players table
|
||||
Group._prototype.connected_players_mt = {
|
||||
__call=function(tbl) return tbl.self:get_players(true) end,
|
||||
__pairs=function(self)
|
||||
local players = self.self:get_players(true)
|
||||
local function next_pair(tbl,key)
|
||||
local k, v = next(players, key)
|
||||
if v then return k,v end
|
||||
end
|
||||
return next_pair, players, nil
|
||||
end,
|
||||
__ipairs=function(self)
|
||||
local players = self.self:get_players(true)
|
||||
local function next_pair(tbl,key)
|
||||
local k, v = next(players, key)
|
||||
if v then return k,v end
|
||||
end
|
||||
return next_pair, players, nil
|
||||
end
|
||||
}
|
||||
|
||||
--- Prints a message or value to all online players in this group
|
||||
-- @usage group.print('Hello, World!')
|
||||
-- @param rtn any value you wish to print, string not required
|
||||
-- @param colour the colour to print the message in
|
||||
-- @treturn number the number of players who received 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
|
||||
return ctn
|
||||
end
|
||||
|
||||
-- Event Handlers Define
|
||||
|
||||
-- creates all permission groups and links them
|
||||
Event.add('on_init',function()
|
||||
for name,group in pairs(Group.groups) do
|
||||
local _group = game.permissions.create_group(name)
|
||||
verbose('Created Permission Group: '..name)
|
||||
local count = 0
|
||||
for _,to_remove in pairs(group.disallow) do
|
||||
count=count+1
|
||||
_group.set_allows_action(defines.input_action[to_remove],false)
|
||||
end
|
||||
verbose('Disalowed '..count..' input actions.')
|
||||
end
|
||||
end)
|
||||
|
||||
-- Module Return
|
||||
-- calling will attempt to define a new group
|
||||
return setmetatable(Group,{__call=function(tbl,...) tbl.define(...) end})
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "ExpGamingCore.Group",
|
||||
"version": "4.0.0",
|
||||
"description": "Adds a system to manage and auto-create permission groups.",
|
||||
"location": "FSM_ARCHIVE",
|
||||
"keywords": [
|
||||
"Groups",
|
||||
"ExpGaming",
|
||||
"System",
|
||||
"Management",
|
||||
"Manage",
|
||||
"Permissions"
|
||||
],
|
||||
"dependencies": {
|
||||
"FactorioStdLib": "^0.8.0",
|
||||
"ExpGamingCore.Server": "?^4.0.0",
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Game": "^0.8.0"
|
||||
},
|
||||
"collection": "ExpGamingCore@4.0.0",
|
||||
"submodules": {}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
-- the two below are used internally by the role system and should not be REMOVED, name must be kept the same and used at least once
|
||||
Role.add_flag('is_default') -- this must be included in at least one role
|
||||
Role.add_flag('is_root',function(player,state)
|
||||
if state then game.print('--- !!!ALERT!!! --- '..player.name..' has been given a role with ROOT ACCESS --- !!!ALERT!!! ---') end
|
||||
if player.character then player.character.destructible = not state end
|
||||
end) -- the SERVER role will have root but you may assign this to other roles
|
||||
-- the two below are ised internally by the role system and should not be RENAMED, name must be kept the same but does not need to be used
|
||||
Role.add_flag('block_auto_promote') -- is not required but name is used internally to block time based promotions
|
||||
Role.add_flag('is_antiroot',function(player,state) if player.character then player.character.destructible = not state end end) -- not required but setting true will disallow everything for that role
|
||||
-- all below are not required and are not used internally
|
||||
Role.add_flag('is_admin',function(player,state) player.admin = state end) -- highly recommenced but not required
|
||||
Role.add_flag('is_spectator',function(player,state) player.spectator = state end)
|
||||
Role.add_flag('is_jail',function(player,state) if player.character then player.character.active = not state end end)
|
||||
Role.add_flag('allow_afk_kick')
|
||||
Role.add_flag('is_donator')
|
||||
Role.add_flag('is_timed')
|
||||
Role.add_flag('is_verified')
|
||||
Role.add_flag('not_reportable')
|
||||
|
||||
-- Root
|
||||
Role{
|
||||
name='Root',
|
||||
short_hand='Root',
|
||||
tag='[Root]',
|
||||
group='Root',
|
||||
colour={r=255,b=255,g=255},
|
||||
is_root=true,
|
||||
is_admin=true,
|
||||
is_spectator=true,
|
||||
not_reportable=true,
|
||||
allow={}
|
||||
}
|
||||
Role{
|
||||
name='Community Manager',
|
||||
short_hand='Com Mngr',
|
||||
tag='[Com Mngr]',
|
||||
group='Root',
|
||||
colour={r=150,g=68,b=161},
|
||||
is_admin=true,
|
||||
is_spectator=true,
|
||||
is_donator=true,
|
||||
not_reportable=true,
|
||||
allow={}
|
||||
}
|
||||
Role{
|
||||
name='Developer',
|
||||
short_hand='Dev',
|
||||
tag='[Dev]',
|
||||
group='Root',
|
||||
colour={r=179,g=125,b=46},
|
||||
is_admin=true,
|
||||
is_spectator=true,
|
||||
is_donator=true,
|
||||
not_reportable=true,
|
||||
allow={
|
||||
['interface']=true,
|
||||
['cheat-mode']=true
|
||||
}
|
||||
}
|
||||
|
||||
-- Admin
|
||||
Role{
|
||||
name='Administrator',
|
||||
short_hand='Admin',
|
||||
tag='[Admin]',
|
||||
group='Admin',
|
||||
colour={r=233,g=63,b=233},
|
||||
is_admin=true,
|
||||
is_spectator=true,
|
||||
is_verified=true,
|
||||
not_reportable=true,
|
||||
allow={
|
||||
['game-settings']=true,
|
||||
['always-warp']=true,
|
||||
['admin-items']=true
|
||||
}
|
||||
}
|
||||
Role{
|
||||
name='Moderator',
|
||||
short_hand='Mod',
|
||||
tag='[Mod]',
|
||||
group='Admin',
|
||||
colour={r=0,g=170,b=0},
|
||||
is_admin=true,
|
||||
is_spectator=true,
|
||||
is_verified=true,
|
||||
not_reportable=true,
|
||||
allow={
|
||||
['set-home']=true,
|
||||
['home']=true,
|
||||
['return']=true,
|
||||
['bonus']=true,
|
||||
['announcements']=true,
|
||||
['rank-changer']=true,
|
||||
}
|
||||
}
|
||||
Role{
|
||||
name='Trainee',
|
||||
short_hand='TrMod',
|
||||
tag='[TrMod]',
|
||||
group='Admin',
|
||||
colour={r=0,g=196,b=137},
|
||||
is_spectator=true,
|
||||
is_verified=true,
|
||||
not_reportable=true,
|
||||
allow={
|
||||
['go-to']=true,
|
||||
['bring']=true,
|
||||
['set-home']=false,
|
||||
['home']=false,
|
||||
['return']=false,
|
||||
['bonus']=false,
|
||||
['admin-commands']=true,
|
||||
['warn']=true,
|
||||
['temp-ban']=true,
|
||||
['clear-warnings']=true,
|
||||
['clear-reports']=true,
|
||||
['clear-all']=true,
|
||||
['clear-inv']=true,
|
||||
}
|
||||
}
|
||||
|
||||
-- High Member
|
||||
Role{
|
||||
name='Sponsor',
|
||||
short_hand='Spon',
|
||||
tag='[Sponsor]',
|
||||
group='HiMember',
|
||||
colour={r=247,g=246,b=54},
|
||||
is_spectator=true,
|
||||
is_donator=true,
|
||||
allow={}
|
||||
}
|
||||
Role{
|
||||
name='Pay to Win',
|
||||
short_hand='P2W',
|
||||
tag='[P2W]',
|
||||
group='HiMember',
|
||||
colour={r=238,g=172,b=44},
|
||||
is_donator=true,
|
||||
allow={
|
||||
['jail']=true,
|
||||
['unjail']=true,
|
||||
['bonus']=true,
|
||||
['bonus-respawn']=true
|
||||
}
|
||||
}
|
||||
Role{
|
||||
name='Donator',
|
||||
short_hand='Don',
|
||||
tag='[Donator]',
|
||||
group='HiMember',
|
||||
colour={r=230,g=99,b=34},
|
||||
is_donator=true,
|
||||
allow_afk_kick=true,
|
||||
allow={
|
||||
['set-home']=true,
|
||||
['home']=true,
|
||||
['return']=true,
|
||||
}
|
||||
}
|
||||
Role{
|
||||
name='Partner',
|
||||
short_hand='Part',
|
||||
tag='[Partner]',
|
||||
group='HiMember',
|
||||
colour={r=140,g=120,b=200},
|
||||
allow_afk_kick=false,
|
||||
is_spectator=true,
|
||||
allow={
|
||||
['global-chat']=true,
|
||||
}
|
||||
}
|
||||
Role{
|
||||
name='Veteran',
|
||||
short_hand='Vet',
|
||||
tag='[Veteran]',
|
||||
group='HiMember',
|
||||
colour={r=140,g=120,b=200},
|
||||
is_timed=true,
|
||||
is_verified=true,
|
||||
allow_afk_kick=true,
|
||||
time=600, -- 10 hours
|
||||
allow={
|
||||
['tree-decon']=true,
|
||||
['create-poll']=true,
|
||||
['repair']=true
|
||||
}
|
||||
}
|
||||
|
||||
-- Member
|
||||
Role{
|
||||
name='Member',
|
||||
short_hand='Mem',
|
||||
tag='[Member]',
|
||||
group='Member',
|
||||
colour={r=24,g=172,b=188},
|
||||
is_verified=true,
|
||||
allow_afk_kick=true,
|
||||
allow={
|
||||
['edit-tasklist']=true,
|
||||
['make-warp']=true,
|
||||
['nuke']=true,
|
||||
['verified']=true
|
||||
}
|
||||
}
|
||||
Role{
|
||||
name='Regular',
|
||||
short_hand='Reg',
|
||||
tag='[Regular]',
|
||||
group='Member',
|
||||
colour={r=79,g=155,b=163},
|
||||
allow_afk_kick=true,
|
||||
is_timed=true,
|
||||
time=180, -- 3 hours
|
||||
allow={
|
||||
['kill']=true,
|
||||
['decon']=true,
|
||||
['capsules']=true
|
||||
}
|
||||
}
|
||||
|
||||
-- Guest
|
||||
Role{
|
||||
name='Guest',
|
||||
short_hand='',
|
||||
tag='',
|
||||
group='User',
|
||||
colour={r=185,g=187,b=160},
|
||||
allow_afk_kick=true,
|
||||
is_default=true,
|
||||
allow={
|
||||
['player-list']=true,
|
||||
['readme']=true,
|
||||
['rockets']=true,
|
||||
['science']=true,
|
||||
['tasklist']=true,
|
||||
['report']=true,
|
||||
['warp-list']=true,
|
||||
['polls']=true,
|
||||
['tag']=true,
|
||||
['tag-clear']=true,
|
||||
['report']=true
|
||||
}
|
||||
}
|
||||
|
||||
-- Jail
|
||||
Role{
|
||||
name='Jail',
|
||||
short_hand='Jail',
|
||||
tag='[Jail]',
|
||||
group='Jail',
|
||||
colour={r=50,g=50,b=50},
|
||||
is_jail=true,
|
||||
is_antiroot=true,
|
||||
block_auto_promote=true,
|
||||
allow={}
|
||||
}
|
||||
|
||||
Role.order = {
|
||||
'Root',
|
||||
'Community Manager',
|
||||
'Developer',
|
||||
'Administrator',
|
||||
'Moderator',
|
||||
'Trainee',
|
||||
'Sponsor',
|
||||
'Pay to Win',
|
||||
'Donator',
|
||||
'Partner',
|
||||
'Veteran',
|
||||
'Member',
|
||||
'Regular',
|
||||
'Guest',
|
||||
'Jail'
|
||||
}
|
||||
|
||||
Role.set_preassign{
|
||||
["cooldude2606"]={"Developer","Admin","Mod"},
|
||||
["aldldl"]={"Sponsor","Admin","Donator","Sponsor","Member","Mod"},
|
||||
["arty714"]={"Admin","Community Manager","Member","Mod"},
|
||||
["drahc_pro"]={"Admin","Member","Mod"},
|
||||
["mark9064"]={"Admin","Member","Mod"}
|
||||
}
|
||||
@@ -1,532 +0,0 @@
|
||||
--- Adds roles where a player can have more than one role
|
||||
-- @module ExpGamingCore.Role@4.0.0
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
-- @alias Role
|
||||
|
||||
-- Module Require
|
||||
local Group = require('ExpGamingCore.Group')
|
||||
local Game = require('FactorioStdLib.Game')
|
||||
|
||||
-- Local Variables
|
||||
local role_change_event_id = script.generate_event_name('on_role_change')
|
||||
local RoleGlobal
|
||||
|
||||
-- Module Define
|
||||
local _RoleSelfReference
|
||||
local module_verbose = false
|
||||
local Role = {
|
||||
_prototype={},
|
||||
order={},
|
||||
flags={},
|
||||
actions={},
|
||||
preassign={},
|
||||
meta={times={},groups={},count=0},
|
||||
roles=setmetatable({},{
|
||||
__index=table.autokey,
|
||||
__newindex=function(tbl,key,value)
|
||||
rawset(tbl,key,_RoleSelfReference.define(value))
|
||||
end
|
||||
}),
|
||||
on_init=function(self)
|
||||
if loaded_modules['ExpGamingCore.Server'] then require('ExpGamingCore.Server').add_module_to_interface('Role','ExpGamingCore.Role') end
|
||||
if loaded_modules['ExpGamingCore.Command'] then require(module_path..'/src/commands',{self=self}) end
|
||||
if loaded_modules['ExpGamingCore.Sync'] then require(module_path..'/src/sync',{self=self,RoleGlobal=RoleGlobal}) end
|
||||
end,
|
||||
on_post=function(self)
|
||||
-- creates a server role with root access
|
||||
self.meta.server = self{name='SERVER',group='Root',is_root=true,allow={}}
|
||||
-- loads the roles in config
|
||||
require(module_path..'/config',{Role=self})
|
||||
self.order[0] = 'SERVER'
|
||||
-- joins role allows into a chain
|
||||
local previous
|
||||
for index,role_name in pairs(self.order) do
|
||||
local role = self.get(role_name)
|
||||
if not role then error('Invalid role name in order listing: '..role_name) return end
|
||||
if role.is_default then self.meta.default = role end
|
||||
if role.is_timed then self.meta.times[role.name] = {index,role.time*3600} end
|
||||
if not self.meta.groups[role.group.name] then self.meta.groups[role.group.name] = {lowest=index,highest=index} end
|
||||
if self.meta.groups[role.group.name].highest > index then self.meta.groups[role.group.name].highest = index end
|
||||
if self.meta.groups[role.group.name].lowest < index then self.meta.groups[role.group.name].lowest = index end
|
||||
if previous then setmetatable(previous.allow,{__index=role.allow}) end
|
||||
self.meta.count = self.meta.count+1
|
||||
role.index = index
|
||||
previous = role
|
||||
end
|
||||
if previous then setmetatable(previous.allow,{__index=function(tbl,key) return false end})
|
||||
else error('Invalid roles, no roles to load.') end
|
||||
end
|
||||
}
|
||||
_RoleSelfReference=Role
|
||||
|
||||
-- Global Define
|
||||
local global = {
|
||||
change_cache_length=15,
|
||||
changes={},
|
||||
latest_change={},
|
||||
preassign={},
|
||||
players={},
|
||||
roles={}
|
||||
}
|
||||
Global.register(global,function(tbl) RoleGlobal = tbl end)
|
||||
|
||||
-- Function Define
|
||||
|
||||
--- Used to set default roles for players who join
|
||||
-- @usage Role.set_preassign{name={roles}}
|
||||
function Role.set_preassign(tbl) if game then global.preassign = tbl else Role.preassign = tbl end end
|
||||
|
||||
--- Defines a new instance of a role
|
||||
-- @usage Role.define{name='Root',short_hand='Root',tag='[Root]',group='Root',colour={r=255,b=255,g=255},is_root=true,allow={}} -- returns new role
|
||||
-- @usage Role{name='Root',short_hand='Root',tag='[Root]',group='Root',colour={r=255,b=255,g=255},is_root=true,allow={}} -- returns new role
|
||||
-- @tparam table obj contains the strings: name,short_hand,tag a table called allow a table called colour and a pointer to a permission group
|
||||
-- @treturn Role the role which has been made
|
||||
function Role.define(obj)
|
||||
if not type_error(game,nil,'Cant define Role during runtime.') then return end
|
||||
if not type_error(obj.name,'string','Role creation is invalid: role.name is not a string') then return end
|
||||
if not is_type(obj.short_hand,'string') then obj.short_hand = obj.name:sub(1,3) end
|
||||
if not is_type(obj.tag,'string') then obj.tag = '['..obj.short_hand..']' end
|
||||
if not is_type(obj.colour,'table') then obj.colour = {r=255,b=255,g=255} end
|
||||
if not type_error(obj.allow,'table','Role creation is invalid: role.allow is not a table') then return end
|
||||
obj.group = Group.get(obj.group)
|
||||
if not type_error(obj.group,'table','Role creation is invalid: role.group is invalid') then return end
|
||||
if obj.time and not type_error(obj.time,'number','Role creation is invalid: role.time is not a number') then return end
|
||||
verbose('Created Role: '..obj.name)
|
||||
setmetatable(obj,{__index=Role._prototype})
|
||||
obj.connected_players = setmetatable({self=obj,connected=true},Role._prototype.players_mt)
|
||||
obj.players = setmetatable({self=obj},Role._prototype.players_mt)
|
||||
rawset(Role.roles,obj.name,obj)
|
||||
table.insert(Role.order,obj.name)
|
||||
return obj
|
||||
end
|
||||
|
||||
--- Used to get the role of a player or the role by name
|
||||
-- @usage Role.get('foo') -- returns group foo
|
||||
-- @usage Role.get(player) -- returns group of player
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer|string mixed can either be the name of the role or a player identifier
|
||||
-- @treturn table the group which was found or nil
|
||||
function Role.get(mixed,forceIsRole)
|
||||
local player = game and Game.get_player(mixed)
|
||||
if player == SERVER then return {Role.meta.server} end
|
||||
if not forceIsRole and 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.group then return mixed
|
||||
elseif is_type(mixed,'string') then return Role.roles[mixed]
|
||||
elseif is_type(mixed,'number') then
|
||||
for _,role in pairs(Role.roles) do
|
||||
if role.index == mixed then return role end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Used to place a player into a role(s)
|
||||
-- @usage Role.assign(player,'Root')
|
||||
-- @usage Role.assign(player,{'Root','Foo'})
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer player the player to assign the role to
|
||||
-- @tparam ?string|role|table the role to add the player to, if its a table then it will act recursively though the table
|
||||
-- @tparam[opt='<server>'] ?LuaPlayer|pointerToPlayer by_player the player who assigned the roles to the player
|
||||
-- @tparam[opt] table batch this is used internally to prevent multiple event calls, contains {role_index_in_batch,batch}
|
||||
-- @treturn boolean was the player assigned the roles
|
||||
function Role.assign(player,role,by_player,batch)
|
||||
player = Game.get_player(player)
|
||||
if not player then error('Invalid player #1 given to Role.assign.',2) return end
|
||||
verbose('Assigning Roles: '..serpent.line(role)..' to: '..player.name)
|
||||
-- this loops over a table of role if given; will return if ipairs returns, else will assume it was meant to be a role and error
|
||||
if is_type(role,'table') and not role.name then
|
||||
local ctn = 0
|
||||
for n,_role in ipairs(role) do ctn=ctn+1 Role.assign(player,_role,by_player,{n,role}) end
|
||||
if ctn > 0 then if not batch then table.insert(global.changes[player.index],{'assign',role}) global.latest_change = {player.index,'assign',role} end return end
|
||||
end
|
||||
role = Role.get(role)
|
||||
if not role then error('Invalid role #2 given to Role.assign.',2) return end
|
||||
-- this acts as a way to prevent the global table getting too full
|
||||
if not global.changes[player.index] then global.changes[player.index]={} end
|
||||
if #global.changes[player.index] > global.change_cache_length then table.remove(global.changes[player.index],1) end
|
||||
if not batch then table.insert(global.changes[player.index],{'assign',role.name}) global.latest_change = {player.index,'assign',role.name} end
|
||||
return role:add_player(player,by_player,batch)
|
||||
end
|
||||
|
||||
--- Used to remove a player from a role(s)
|
||||
-- @usage Role.unassign(player,'Root')
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer player the player to unassign the role to
|
||||
-- @tparam ?string|role|table role the role to remove the player from, if its a table then it will act recursively though the table
|
||||
-- @tparam[opt='<server>'] ?LuaPlayer|pointerToPlayer by_player the player who unassigned the roles from the player
|
||||
-- @tparam[opt] table batch this is used internally to prevent multiple event calls
|
||||
-- @treturn boolean was the player unassigned the roles
|
||||
function Role.unassign(player,role,by_player,batch)
|
||||
player = Game.get_player(player)
|
||||
if not player then error('Invalid player #1 given to Role.unassign.',2) return end
|
||||
verbose('Assigning Roles: '..serpent.line(role)..' to: '..player.name)
|
||||
-- this loops over a table of role if given; will return if ipairs returns, else will assume it was meant to be a role and error
|
||||
if is_type(role,'table') and not role.name then
|
||||
local ctn = 0
|
||||
for n,_role in ipairs(role) do ctn=ctn+1 Role.unassign(player,_role,by_player,{n,role}) end
|
||||
if ctn > 0 then if not batch then table.insert(global.changes[player.index],{'unassign',role}) global.latest_change = {player.index,'unassign',role} end return end
|
||||
end
|
||||
role = Role.get(role)
|
||||
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 prevent the global table getting too full
|
||||
if #global.changes[player.index] > global.change_cache_length then table.remove(global.changes[player.index],1) end
|
||||
if not batch then table.insert(global.changes[player.index],{'unassign',role.name}) global.latest_change = {player.index,'unassign',role.name} end
|
||||
return role:remove_player(player,by_player,batch)
|
||||
end
|
||||
|
||||
--- Returns the highest role given in a list, if a player is passed then it returns the highest role of the player
|
||||
-- @usage Role.get_highest{'Root','Admin','Mod'} -- returns Root (given that root is highest)
|
||||
-- @usage Role.get_highest(player) -- returns the players highest role
|
||||
-- @tparam ?table|LuaPlayer|pointerToPlayer options table of options or a player
|
||||
-- @treturn role the highest role given in the options
|
||||
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 #1 to Role.get_highest, options is not a table of roles.') then return end
|
||||
local highest_index = -1
|
||||
local highest
|
||||
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
|
||||
end
|
||||
|
||||
--- Uses the change cache to revert changes to players roles
|
||||
-- @usage Role.revert(player) -- reverts the last change to the players roles
|
||||
-- @tparam ?LuaPlayer|pointerToPlayer player the player to revert the changes of
|
||||
-- @tparam[opt] ?LuaPlayer|pointerToPlayer the player who preformed the role revert
|
||||
-- @tparam[opt=1] count the number of reverts to do, if 0 all changes cached are reverted
|
||||
-- @treturn number the number of changes that occurred
|
||||
function Role.revert(player,by_player,count)
|
||||
player = Game.get_player(player)
|
||||
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
|
||||
count = count or 1
|
||||
local ctn = 0
|
||||
if count > #changes or count == 0 then count = #changes end
|
||||
for i = 1,count do
|
||||
local change = table.remove(changes)
|
||||
if not change then break end
|
||||
local batch = is_type(change[2],'table') and change[2] or {change[2]}
|
||||
if change[1] == 'assign' then Role.unassign(player,change[2],by_player,batch) end
|
||||
if change[1] == 'unassign' then Role.assign(player,change[2],by_player,batch) end
|
||||
ctn=ctn+1
|
||||
end
|
||||
return ctn
|
||||
end
|
||||
|
||||
--- Adds a flag which can be set on roles; these flags act as a quick way to access general role changes
|
||||
-- @usage Role.add_flag('is_admin',function(player,state) player.admin = state end) -- the function is passed player and if the flag is true or false
|
||||
-- @tparam string flag the name of the flag that is being added
|
||||
-- @tparam[opt] function callback the function(player,state) which is called when a player loses or gains a flag, if nil no function is called
|
||||
function Role.add_flag(flag,callback)
|
||||
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
|
||||
|
||||
--- Checks if a player or role has the requested flag, if player all roles of player are checked (true has priority)
|
||||
-- @usage Role.has_flag(role,'is_admin') -- returns true if this role has is_admin set
|
||||
-- @tparam role|LuaPlayer|pointerToPlayer mixed the player or role that will be tested
|
||||
-- @tparam string flag the flag to test for
|
||||
-- @treturn boolean if the flag was true or false, false if nil
|
||||
function Role.has_flag(mixed,flag)
|
||||
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 #1 to Role.has_flag, mixed is not a role or player.') then return end
|
||||
if #roles > 0 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
|
||||
return false
|
||||
end
|
||||
|
||||
--- Adds a action to be used by the role system
|
||||
-- @usage Role.add_action('foo')
|
||||
-- @tparam string action the name of the action that will be added
|
||||
function Role.add_action(action)
|
||||
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
|
||||
|
||||
--- Checks if a player or role is allowed the requested action, if player all roles of player are checked (true has priority)
|
||||
-- @usage Role.allowed(role,'foo') -- returns true if this role is allowed 'foo'
|
||||
-- @tparam ?role|LuaPlayer|pointerToPlayer mixed the player or role that will be tested
|
||||
-- @tparam string action the action to test for
|
||||
-- @treturn boolean if the action is allowed for the player or role
|
||||
function Role.allowed(mixed,action)
|
||||
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 #1 to Role.allowed, mixed is not a role or player.') then return end
|
||||
if #roles > 0 then for _,role in pairs(roles) do
|
||||
if role:allowed(action) then return true end
|
||||
end elseif roles:allowed(action) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Prints to all roles and players of those roles which are greater than the given role (or if inv then all below)
|
||||
-- @usage Role.print('Admin','Hello, World!') -- returns the number of players who received the message
|
||||
-- @tparam ?role|string role the role which acts as the turning point of the print (always included regardless of inv value)
|
||||
-- @param rtn the value that will be returned to the players
|
||||
-- @tparam[opt] table colour the colour that you want the message printed in
|
||||
-- @tparam[opt=false] boolean inv true to print to roles below, false to print to roles above
|
||||
-- @treturn number the number of players who received the message
|
||||
function Role.print(role,rtn,colour,inv)
|
||||
role = Role.get(role,true)
|
||||
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 message = inv and {'ExpGamingCore-Role.default-print',rtn} or {'ExpGamingCore-Role.print',role.name,rtn}
|
||||
local change = inv and 1 or -1
|
||||
local ctn = 0
|
||||
local i = role.index
|
||||
while true do
|
||||
local _role = Role.get(i,true)
|
||||
if not _role then break end
|
||||
ctn=ctn+_role:print(message,colour)
|
||||
i=i+change
|
||||
end
|
||||
return ctn
|
||||
end
|
||||
|
||||
--- Prints all registered roles and there important information (debug)
|
||||
-- @tparam[opt] ?role|string the role to print the info of, if nil then all roles are printed in order of power
|
||||
-- @tparam[opt=game.player] ?LuaPlayer|pointerToPlayer the player to print the info to, default the player who ran command
|
||||
function Role.debug_output(role,player)
|
||||
player = Game.get_player(player) or game.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
|
||||
role = Role.get(role)
|
||||
if not type_error(role,'table','Invalid argument #1 to Role.print, role is invalid.') then return end
|
||||
_output(role)
|
||||
else for index,_role in pairs(Role.roles) do _output(_role) end end
|
||||
end
|
||||
|
||||
--- Used to test if a role has a flag set
|
||||
-- @usage role:has_flag('is_admin') -- returns true if the role has the flag 'is_admin'
|
||||
-- @tparam string flag the flag to test for
|
||||
-- @treturn boolean true if the flag is set else false
|
||||
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 #1 to role:has_flag, flag is not a string.') then return end
|
||||
return self[flag] or false
|
||||
end
|
||||
|
||||
--- Used to test if a role is allowed an action
|
||||
-- @usage role:allowed('foo') -- returns true if the role is allowed 'foo'
|
||||
-- @tparam string action the action to test for
|
||||
-- @treturn boolean true if the action is allowed else false
|
||||
function Role._prototype:allowed(action)
|
||||
if not self_test(self,'role','allowed') then return end
|
||||
if not type_error(action,'string','Invalid argument #1 to role:allowed, action is not a string.') then return end
|
||||
if self.is_antiroot then return false end
|
||||
return self.allow[action] or self.is_root or false -- still include is_root exception flag
|
||||
end
|
||||
|
||||
--- Returns the players who have this role
|
||||
-- @usage role:get_player() -- returns table of players
|
||||
-- @usage role.players -- returns table of players
|
||||
-- @usage role.connected_players -- returns table of online players
|
||||
-- @tparam[opt] boolean online if true only returns online players
|
||||
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 #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
|
||||
if self.is_default then if online then return game.connected_players else return game.players end end
|
||||
local rtn = {}
|
||||
for _,player_index in pairs(global.roles[self.name]) do
|
||||
local player = game.players[player_index]
|
||||
if player and not online or player.connected then table.insert(rtn,player) end
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
-- this is used to create a connected_players table
|
||||
Role._prototype.players_mt = {
|
||||
__call=function(tbl) return tbl.self:get_players(tbl.connected) end,
|
||||
__pairs=function(tbl)
|
||||
local players = tbl.self:get_players(tbl.connected)
|
||||
local function next_pair(tbl,key)
|
||||
local k, v = next(players, key)
|
||||
if v then return k,v end
|
||||
end
|
||||
return next_pair, players, nil
|
||||
end,
|
||||
__ipairs=function(tbl)
|
||||
local players = tbl.self:get_players(tbl.connected)
|
||||
local function next_pair(tbl,key)
|
||||
local k, v = next(players, key)
|
||||
if v then return k,v end
|
||||
end
|
||||
return next_pair, players, nil
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
--- Prints a message to all players who have this role
|
||||
-- @usage role:print('Hello, World!') -- returns number of players who received the message
|
||||
-- @param rtn the message to print to the players
|
||||
-- @tparam[opt] table colour the colour to print the message in
|
||||
-- @treturn number the number of players who received the message
|
||||
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 #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
|
||||
end
|
||||
|
||||
--- Returns a table that describes all the permissions and which this role is allowed
|
||||
-- @usage role:get_permissions() -- returns table of permissions
|
||||
-- @treturn table a table of permissions, only includes ones which were defined with Role.add_action
|
||||
function Role._prototype:get_permissions()
|
||||
if not self_test(self,'role','get_permissions') then return end
|
||||
local rtn = {}
|
||||
for _,action in pairs(Role.actions) do rtn[action] = self:allowed(action) end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Adds a player to this role (players can have more than one role)
|
||||
-- @usage role:add_player(player)
|
||||
-- @tparam ?LuaPlayer|PointerToPlayer player the player to add
|
||||
-- @tparam[opt] ?LuaPlayer|PointerToPlayer by_player the player who ran the command
|
||||
-- @tparam[opt] table batch this is used internally to prevent multiple event calls
|
||||
function Role._prototype:add_player(player,by_player,batch)
|
||||
if not self_test(self,'role','add_player') then return end
|
||||
player = Game.get_player(player)
|
||||
if not player then error('Invalid player #1 given to role:add_player.',2) return end
|
||||
by_player = Game.get_player(by_player) or SERVER
|
||||
if not global.roles[self.name] then global.roles[self.name] = {} end
|
||||
if not global.players[player.index] then global.players[player.index] = {} end
|
||||
local highest = Role.get_highest(player) or Role.meta.default
|
||||
for _,player_index in pairs(global.roles[self.name]) do if player_index == player.index then return end end
|
||||
table.insert(global.roles[self.name],player.index)
|
||||
table.insert(global.players[player.index],self.name)
|
||||
script.raise_event(role_change_event_id,{
|
||||
name=role_change_event_id,
|
||||
tick=game.tick,
|
||||
player_index=player.index,
|
||||
by_player_index=by_player.index,
|
||||
old_highest=highest.name,
|
||||
role_name=self.name,
|
||||
batch=batch and batch[2] or {self.name},
|
||||
batch_index=batch and batch[1] or 1,
|
||||
effect='assign'
|
||||
})
|
||||
end
|
||||
|
||||
--- Removes a player from this role (players can have more than one role)
|
||||
-- @usage role:remove_player(player)
|
||||
-- @tparam ?LuaPlayer|PointerToPlayer player the player to remove
|
||||
-- @tparam[opt] ?LuaPlayer|PointerToPlayer by_player the player who ran the command
|
||||
-- @tparam[opt] table batch this is used internally to prevent multiple event calls
|
||||
function Role._prototype:remove_player(player,by_player,batch)
|
||||
if not self_test(self,'role','add_player') then return end
|
||||
player = Game.get_player(player)
|
||||
if not player then error('Invalid player #1 given to role:remove_player.',2) return end
|
||||
by_player = Game.get_player(by_player) or SERVER
|
||||
if not global.roles[self.name] then global.roles[self.name] = {} end
|
||||
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)
|
||||
for _index,role_name in pairs(global.players[player.index]) do if role_name == self.name then index=_index break end end
|
||||
table.remove(global.players[player.index],index)
|
||||
script.raise_event(role_change_event_id,{
|
||||
name=role_change_event_id,
|
||||
tick=game.tick,
|
||||
player_index=player.index,
|
||||
by_player_index=by_player.index,
|
||||
old_highest=highest.name,
|
||||
role_name=self.name,
|
||||
batch=batch and batch[2] or {self.name},
|
||||
batch_index=batch and batch[1] or 1,
|
||||
effect='unassign'
|
||||
})
|
||||
end
|
||||
|
||||
-- Event Handlers Define
|
||||
Event.add(role_change_event_id,function(event)
|
||||
-- variable init
|
||||
local player = Game.get_player(event)
|
||||
local by_player = Game.get_player(event.by_player_index) or SERVER
|
||||
local role = Role.get(event.role_name)
|
||||
local highest = Role.get_highest(player)
|
||||
if not highest then Role.meta.default:add_player(player) highest = Role.meta.default end
|
||||
-- gets the flags the player currently has
|
||||
for flag,callback in pairs(Role.flags) do if is_type(callback,'function') then callback(player,Role.has_flag(player,flag)) end end
|
||||
-- assign new tag and group of highest role
|
||||
Group.assign(player,highest.group)
|
||||
local old_highest_tag = Role.get(event.old_highest).tag or ''
|
||||
local start, _end = string.find(player.tag,old_highest_tag,1,true)
|
||||
if start and old_highest_tag ~= highest.tag then player.tag = string.sub(player.tag,0,start-1)..highest.tag..string.sub(player.tag,_end+1) end
|
||||
if not start then player.tag = highest.tag player_return({'ExpGamingCore-Role.tag-reset'},nil,player) end
|
||||
if player.online_time > 60 then
|
||||
-- send a message to other players
|
||||
if event.batch_index == 1 then
|
||||
local names = {}
|
||||
for _,name in pairs(event.batch) do local next_role = Role.get(name) if next_role then table.insert(names,next_role.name) end end
|
||||
if event.effect == 'assign' then
|
||||
if not role.is_jail then player.play_sound{path='utility/achievement_unlocked'} end
|
||||
game.print{'ExpGamingCore-Role.default-print',{'ExpGamingCore-Role.assign',player.name,table.concat(names,', '),by_player.name}}
|
||||
else
|
||||
player.play_sound{path='utility/game_lost'}
|
||||
game.print{'ExpGamingCore-Role.default-print',{'ExpGamingCore-Role.unassign',player.name,table.concat(names,', '),by_player.name}}
|
||||
end
|
||||
end
|
||||
-- log change to file
|
||||
game.write_file('role-change.json',
|
||||
table.json({
|
||||
tick=game.tick,
|
||||
effect=event.effect,
|
||||
role_name=role.name,
|
||||
player_name=player.name,
|
||||
by_player_name=by_player.name,
|
||||
play_time=player.online_time,
|
||||
highest_role_name=highest.name,
|
||||
old_highest=event.highest,
|
||||
batch_count=#event.batch,
|
||||
batch_index=event.batch_index
|
||||
})..'\n'
|
||||
, true, 0)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_created,function(event)
|
||||
local player = Game.get_player(event)
|
||||
local highest = Role.get_highest(player) or Role.meta.default
|
||||
Group.assign(player,highest.group)
|
||||
player.tag=highest.tag
|
||||
if global.preassign[player.name:lower()] then Role.assign(player,global.preassign[player.name:lower()]) end
|
||||
if Role.preassign[player.name:lower()] then Role.assign(player,Role.preassign[player.name:lower()]) end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_tick,function(event)
|
||||
if game.tick%(3600*5) ~= 0 then return end -- every 5 minutes
|
||||
for _,player in pairs(game.connected_players) do
|
||||
if not Role.has_flag(player,'block_auto_promote') then
|
||||
local highest = Role.get_highest(player)
|
||||
for role_name, time in pairs(Role.meta.times) do
|
||||
if highest.index > time[1] and (player.online_time) > time[2] then Role.assign(player,role_name) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Module Return
|
||||
-- calling will attempt to define a new role
|
||||
return setmetatable(Role,{__call=function(tbl,...) return tbl.define(...) end})
|
||||
@@ -1,6 +0,0 @@
|
||||
[ExpGamingCore-Role]
|
||||
default-print=[Everyone]: __1__
|
||||
print=[__1__]: __2__
|
||||
assign=__1__ was assigned to __2__ by __3__
|
||||
unassign=__1__ was unassigned from __2__ by __3__
|
||||
tag-reset=Your Tag was reset due to a role change
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "ExpGamingCore.Role",
|
||||
"version": "4.0.0",
|
||||
"description": "Adds roles where a player can have more than one role",
|
||||
"location": "FSM_ARCHIVE",
|
||||
"keywords": [
|
||||
"Role",
|
||||
"Ranks",
|
||||
"Permissions",
|
||||
"Alowed",
|
||||
"Admin"
|
||||
],
|
||||
"dependencies": {
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"FactorioStdLib.Game": "^0.8.0",
|
||||
"ExpGamingCore.Group": "^4.0.0",
|
||||
"ExpGamingCore.Server": "?^4.0.0",
|
||||
"ExpGamingCore.Command": "?^4.0.0",
|
||||
"ExpGamingCore.Sync": "?^4.0.0"
|
||||
},
|
||||
"collection": "ExpGamingCore@4.0.0",
|
||||
"submodules": {}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
local Role = self
|
||||
|
||||
commands.add_validation('player-rank',function(value,event)
|
||||
local player,err = commands.validate['player'](value)
|
||||
if err then return commands.error(err) end
|
||||
local rtn = Role.get_highest(player).index > Role.get_highest(event).index and player or player.index == event.player_index and player or nil
|
||||
if not rtn then return commands.error{'ExpGamingCore_Command.error-player-rank'} end return rtn
|
||||
end)
|
||||
|
||||
commands.add_validation('player-rank-online',function(value,event)
|
||||
local player,err = commands.validate['player-online'](value)
|
||||
if err then return commands.error(err) end
|
||||
local player,err = commands.validate['player-rank'](player)
|
||||
if err then return commands.error(err) end
|
||||
return player
|
||||
end)
|
||||
|
||||
commands.add_validation('player-rank-alive',function(value,event)
|
||||
local player,err = commands.validate['player-alive'](value)
|
||||
if err then return commands.error(err) end
|
||||
local player,err = commands.validate['player-rank'](player,event)
|
||||
if err then return commands.error(err) end
|
||||
return player
|
||||
end)
|
||||
|
||||
commands.add_middleware(function(player,command_name,event)
|
||||
return Role.allowed(player,command_name)
|
||||
end)
|
||||
@@ -1,82 +0,0 @@
|
||||
local Role = self
|
||||
local RoleGlobal = RoleGlobal
|
||||
local Sync = require('ExpGamingCore.Sync')
|
||||
local Game = require('FactorioStdLib.Game')
|
||||
local Color = require('FactorioStdLib.Color')
|
||||
|
||||
-- just to hard reset the role sync
|
||||
function Sync.set_roles(...)
|
||||
Role.set_preassign(...)
|
||||
end
|
||||
|
||||
-- used to assign the role if the player is online, or add to the the preassign
|
||||
function Sync.assign_role(player_name,roles,by_player_name)
|
||||
if not game then return end
|
||||
local preassign = RoleGlobal.preassign
|
||||
local player_roles = preassign[player_name]
|
||||
if Game.get_player(player_name) then Role.assign(player_name,roles,by_player_name)
|
||||
else
|
||||
if not is_type(roles,'table') then roles = {roles} end
|
||||
if not player_roles then preassign[player_name] = roles return end
|
||||
for _,role_name in pairs(roles) do
|
||||
if not table.includes(player_roles,role_name) then table.insert(player_roles,role_name) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- used to unassign the role if the player is online, or removes the preassign
|
||||
function Sync.unassign_role(player_name,roles,by_player_name)
|
||||
if not game then return end
|
||||
local preassign = RoleGlobal.preassign
|
||||
local player_roles = preassign[player_name]
|
||||
if Game.get_player(player_name) then Role.unassign(player_name,roles,by_player_name)
|
||||
else
|
||||
if not is_type(roles,'table') then roles = {roles} end
|
||||
if not player_roles then preassign[player_name] = nil return end
|
||||
for _,role_name in pairs(roles) do
|
||||
local index = table.index(player_roles,role_name)
|
||||
if index then table.remove(player_roles,index) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Sync.add_update('roles',function()
|
||||
if not game then return {'Offline'} end
|
||||
local _rtn = {}
|
||||
for _,role in pairs(Role.roles) do
|
||||
local players = role:get_players()
|
||||
local _players = {}
|
||||
for k,player in pairs(players) do _players[k] = player.name end
|
||||
local online = role:get_players(true)
|
||||
local _online = {}
|
||||
for k,player in pairs(online) do _online[k] = player.name end
|
||||
_rtn[role.name] = {players=_players,online=_online,n_players=#_players,n_online=#_online}
|
||||
end
|
||||
return _rtn
|
||||
end)
|
||||
|
||||
-- Adds a caption to the info gui that shows the rank given to the player
|
||||
if Sync.add_to_gui then
|
||||
Sync.add_to_gui(function(player)
|
||||
local names = {}
|
||||
for _,role in pairs(Role.get(player)) do table.insert(names,role.name) end
|
||||
return 'You have been assigned the roles: '..table.concat(names,', ')
|
||||
end)
|
||||
end
|
||||
|
||||
-- adds a discord emit for rank changing
|
||||
Event.add('on_role_change',function(event)
|
||||
local role = Role.get(event.role_name)
|
||||
local player = Game.get_player(event)
|
||||
local by_player = Game.get_player(event.by_player_index) or SERVER
|
||||
if role.is_jail and RoleGlobal.last_change[1] ~= player.index then
|
||||
Sync.emit_embedded{
|
||||
title='Player Jail',
|
||||
color=Color.to_hex(defines.textcolor.med),
|
||||
description='There was a player jailed.',
|
||||
['Player:']='<<inline>>'..player.name,
|
||||
['By:']='<<inline>>'..by_player.name,
|
||||
['Reason:']='No Reason'
|
||||
}
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user