Update all code styles

This commit is contained in:
Cooldude2606
2024-09-28 01:56:54 +01:00
parent 5e2a62ab27
commit 292c1a1b68
194 changed files with 9817 additions and 9703 deletions

View File

@@ -191,9 +191,9 @@ local trace = debug.traceback
local Commands = {
--- Constant values used by the command system
defines = {
error = 'CommandError',
unauthorized = 'CommandErrorUnauthorized',
success = 'CommandSuccess'
error = "CommandError",
unauthorized = "CommandErrorUnauthorized",
success = "CommandSuccess",
},
--- An array of all custom commands that are registered
commands = {},
@@ -243,7 +243,7 @@ Commands.remove_authenticator(admin_authenticator)
]]
function Commands.remove_authenticator(authenticator)
if type(authenticator) == 'number' then
if type(authenticator) == "number" then
-- If a number is passed then it is assumed to be the index
if Commands.authenticators[authenticator] then
Commands.authenticators[authenticator] = nil
@@ -281,15 +281,15 @@ function Commands.authorize(player, command_name)
-- This is the reject function given to authenticators
local failure_message
local function reject(message)
failure_message = message or {'expcore-commands.unauthorized'}
failure_message = message or { "expcore-commands.unauthorized" }
return Commands.defines.unauthorized
end
-- This is the internal error function used when an authenticator errors
local function authenticator_error(err)
log('[ERROR] Authorization failed: '..trace(err))
log("[ERROR] Authorization failed: " .. trace(err))
if Commands.authorization_failure_on_error then
return reject('Internal Error')
return reject("Internal Error")
end
end
@@ -298,7 +298,7 @@ function Commands.authorize(player, command_name)
-- player: LuaPlayer, command: string, flags: table, reject: function(error_message: string)
local _, rtn = xpcall(authenticator, authenticator_error, player, command_name, command_data.flags, reject)
if rtn == false or rtn == Commands.defines.unauthorized or rtn == reject or failure_message ~= nil then
if failure_message == nil then failure_message = {'expcore-commands.unauthorized'} end
if failure_message == nil then failure_message = { "expcore-commands.unauthorized" } end
return false, failure_message
end
end
@@ -370,7 +370,10 @@ end)
function Commands.parse(name, input, player, reject, ...)
if not Commands.parsers[name] then return end
local success, rtn = pcall(Commands.parsers[name], input, player, reject, ...)
if not success then error(rtn, 2) return end
if not success then
error(rtn, 2)
return
end
if not rtn or rtn == Commands.defines.error then return end
return rtn
end
@@ -398,6 +401,7 @@ function Commands.get(player)
allowed[name] = command_data
end
end
return allowed
end
@@ -420,12 +424,13 @@ function Commands.search(keyword, player)
-- Loops over custom commands
for name, command_data in pairs(custom_commands) do
-- combines name help and aliases into one message to be searched
local search = string.format('%s %s %s %s', name, command_data.help, command_data.searchable_description, table.concat(command_data.aliases, ' '))
local search = string.format("%s %s %s %s", name, command_data.help, command_data.searchable_description, table.concat(command_data.aliases, " "))
if search:lower():match(keyword) then
matches[name] = command_data
end
end
-- Loops over the names of game commands
for name, description in pairs(commands.game_commands) do
if name:lower():match(keyword) then
@@ -433,11 +438,12 @@ function Commands.search(keyword, player)
matches[name] = {
name = name,
help = description,
description = '',
aliases = {}
description = "",
aliases = {},
}
end
end
return matches
end
@@ -458,16 +464,16 @@ function Commands.new_command(name, help, descr)
local command = setmetatable({
name = name,
help = help,
searchable_description = descr or '',
callback = function() Commands.internal_error(false, name, 'No callback registered') end,
searchable_description = descr or "",
callback = function() Commands.internal_error(false, name, "No callback registered") end,
auto_concat = false,
min_param_count = 0,
max_param_count = 0,
flags = {}, -- stores flags that can be used by auth
flags = {}, -- stores flags that can be used by auth
aliases = {}, -- stores aliases to this command
params = {}, -- [param_name] = {optional: boolean, default: any, parse: function, parse_args: table}
params = {}, -- [param_name] = {optional: boolean, default: any, parse: function, parse_args: table}
}, {
__index = Commands._prototype
__index = Commands._prototype,
})
Commands.commands[name] = command
return command
@@ -491,17 +497,17 @@ end)
]]
function Commands._prototype:add_param(name, optional, parse, ...)
local parse_args = {...}
if type(optional) ~= 'boolean' then
parse_args = {parse, ...}
local parse_args = { ... }
if type(optional) ~= "boolean" then
parse_args = { parse, ... }
parse = optional
optional = false
end
self.params[name] = {
optional = optional,
parse = parse or function(string) return string end,
parse_args = parse_args
optional = optional,
parse = parse or function(string) return string end,
parse_args = parse_args,
}
self.max_param_count = self.max_param_count + 1
@@ -532,6 +538,7 @@ function Commands._prototype:set_defaults(defaults)
self.params[name].default = value
end
end
return self
end
@@ -562,9 +569,10 @@ command:add_alias('name', 'rname')
]]
function Commands._prototype:add_alias(...)
local start_index = #self.aliases
for index, alias in ipairs{...} do
self.aliases[start_index+index] = alias
for index, alias in ipairs{ ... } do
self.aliases[start_index + index] = alias
end
return self
end
@@ -600,14 +608,15 @@ function Commands._prototype:register(callback)
self.callback = callback
-- Generates a description to be used
local description = ''
local description = ""
for param_name, param_details in pairs(self.params) do
if param_details.optional then
description = string.format('%s [%s]', description, param_name)
description = string.format("%s [%s]", description, param_name)
else
description = string.format('%s <%s>', description, param_name)
description = string.format("%s <%s>", description, param_name)
end
end
self.description = description
-- Last resort error handler for commands
@@ -622,7 +631,7 @@ function Commands._prototype:register(callback)
end
-- Registers the command under its own name
local help = {'expcore-commands.command-help', description, self.help}
local help = { "expcore-commands.command-help", description, self.help }
commands.add_command(self.name, help, command_callback)
-- Adds any aliases that it has
@@ -650,7 +659,7 @@ return 'Your message has been printed'
]]
function Commands.success(value)
if value ~= nil then player_return(value) end
player_return({'expcore-commands.command-ran'}, 'cyan')
player_return({ "expcore-commands.command-ran" }, "cyan")
return Commands.defines.success
end
@@ -675,11 +684,11 @@ return Commands.error('The player you selected is offline')
]]
function Commands.error(error_message, play_sound)
error_message = error_message or ''
player_return({'expcore-commands.command-fail', error_message}, 'orange_red')
error_message = error_message or ""
player_return({ "expcore-commands.command-fail", error_message }, "orange_red")
if play_sound ~= false then
play_sound = play_sound or 'utility/wire_pickup'
if game.player then game.player.play_sound{path=play_sound} end
play_sound = play_sound or "utility/wire_pickup"
if game.player then game.player.play_sound{ path = play_sound } end
end
return Commands.defines.error
end
@@ -700,22 +709,22 @@ end
]]
function Commands.internal_error(success, command_name, error_message)
if not success then
Commands.error('Internal Error, Please contact an admin', 'utility/cannot_build')
log{'expcore-commands.command-error-log-format', command_name, error_message}
Commands.error("Internal Error, Please contact an admin", "utility/cannot_build")
log{ "expcore-commands.command-error-log-format", command_name, error_message }
end
return not success
end
--- Logs command usage to file
local function command_log(player, command, comment, params, raw, details)
local player_name = player and player.name or '<Server>'
write_json('log/commands.log', {
player_name = player_name,
local player_name = player and player.name or "<Server>"
write_json("log/commands.log", {
player_name = player_name,
command_name = command.name,
comment = comment,
details = details,
params = params,
raw = raw
comment = comment,
details = details,
params = params,
raw = raw,
})
end
@@ -733,46 +742,46 @@ function Commands.run_command(command_event)
-- Check if the player is allowed to use the command
local authorized, auth_fail = Commands.authorize(player, command_data.name)
if not authorized then
command_log(player, command_data, 'Failed Auth', {}, command_event.parameter)
Commands.error(auth_fail, 'utility/cannot_build')
command_log(player, command_data, "Failed Auth", {}, command_event.parameter)
Commands.error(auth_fail, "utility/cannot_build")
return
end
-- Check for parameter being nil
if command_data.min_param_count > 0 and not command_event.parameter then
command_log(player, command_data, 'No Params Given', {}, command_event.parameter)
Commands.error{'expcore-commands.invalid-inputs', command_data.name, command_data.description}
command_log(player, command_data, "No Params Given", {}, command_event.parameter)
Commands.error{ "expcore-commands.invalid-inputs", command_data.name, command_data.description }
return
end
-- Extract quoted arguments
local raw_input = command_event.parameter or ''
local raw_input = command_event.parameter or ""
local quote_params = {}
local input_string = raw_input:gsub('"[^"]-"', function(word)
local no_spaces = word:gsub('%s', '%%s')
local no_spaces = word:gsub("%s", "%%s")
quote_params[no_spaces] = word:sub(2, -2)
return ' '..no_spaces..' '
return " " .. no_spaces .. " "
end)
-- Extract unquoted arguments
local raw_params = {}
local last_index = 0
local param_number = 0
for word in input_string:gmatch('%S+') do
for word in input_string:gmatch("%S+") do
param_number = param_number + 1
if param_number > command_data.max_param_count then
-- there are too many params given to the command
if not command_data.auto_concat then
-- error as they should not be more
command_log(player, command_data, 'Invalid Input: Too Many Params', raw_params, raw_input)
Commands.error{'expcore-commands.invalid-inputs', command_data.name, command_data.description}
command_log(player, command_data, "Invalid Input: Too Many Params", raw_params, raw_input)
Commands.error{ "expcore-commands.invalid-inputs", command_data.name, command_data.description }
return
else
-- concat to the last param
if quote_params[word] then
raw_params[last_index] = raw_params[last_index]..' "'..quote_params[word]..'"'
raw_params[last_index] = raw_params[last_index] .. ' "' .. quote_params[word] .. '"'
else
raw_params[last_index] = raw_params[last_index]..' '..word
raw_params[last_index] = raw_params[last_index] .. " " .. word
end
end
else
@@ -790,8 +799,8 @@ function Commands.run_command(command_event)
-- Check the param count
local param_count = #raw_params
if param_count < command_data.min_param_count then
command_log(player, command_data, 'Invalid Input: Not Enough Params', raw_params, raw_input)
Commands.error{'expcore-commands.invalid-inputs', command_data.name, command_data.description}
command_log(player, command_data, "Invalid Input: Not Enough Params", raw_params, raw_input)
Commands.error{ "expcore-commands.invalid-inputs", command_data.name, command_data.description }
return
end
@@ -801,48 +810,46 @@ function Commands.run_command(command_event)
for param_name, param_data in pairs(command_data.params) do
local parse_callback = param_data.parse
-- If its a string this get it from the parser table
if type(parse_callback) == 'string' then
if type(parse_callback) == "string" then
parse_callback = Commands.parsers[parse_callback]
end
-- If its not a function throw and error
if type(parse_callback) ~= 'function' then
Commands.internal_error(false, command_data.name, 'Invalid param parse '..tostring(param_data.parse))
command_log(player, command_data, 'Internal Error: Invalid Param Parse', params, raw_input, tostring(param_data.parse))
if type(parse_callback) ~= "function" then
Commands.internal_error(false, command_data.name, "Invalid param parse " .. tostring(param_data.parse))
command_log(player, command_data, "Internal Error: Invalid Param Parse", params, raw_input, tostring(param_data.parse))
return
end
-- This is the reject function given to parse callbacks
local function reject(error_message)
error_message = error_message or ''
command_log(player, command_data, 'Invalid Param Given', raw_params, input_string)
return Commands.error{'expcore-commands.invalid-param', param_name, error_message}
error_message = error_message or ""
command_log(player, command_data, "Invalid Param Given", raw_params, input_string)
return Commands.error{ "expcore-commands.invalid-param", param_name, error_message }
end
-- input: string, player: LuaPlayer, reject: function, ... extra args
local success, param_parsed = pcall(parse_callback, raw_params[index], player, reject, table.unpack(param_data.parse_args))
if Commands.internal_error(success, command_data.name, param_parsed) then
return command_log(player, command_data, 'Internal Error: Param Parse Fail', params, raw_input, param_parsed)
return command_log(player, command_data, "Internal Error: Param Parse Fail", params, raw_input, param_parsed)
end
if param_data.optional == true and raw_params[index] == nil then
-- If the param is optional and nil then it is set to default
param_parsed = param_data.default
if type(param_parsed) == 'function' then
if type(param_parsed) == "function" then
success, param_parsed = pcall(param_parsed, player)
if Commands.internal_error(success, command_data.name, param_parsed) then
return command_log(player, command_data, 'Internal Error: Default Value Fail', params, raw_input, param_parsed)
return command_log(player, command_data, "Internal Error: Default Value Fail", params, raw_input, param_parsed)
end
end
elseif param_parsed == nil or param_parsed == Commands.defines.error or param_parsed == reject then
-- No value was returned or error was returned, if nil then give generic error
if param_parsed ~= Commands.defines.error then
command_log(player, command_data, 'Invalid Param Given', raw_params, raw_input, param_name)
Commands.error{'expcore-commands.command-error-param-format', param_name, 'please make sure it is the correct type'}
command_log(player, command_data, "Invalid Param Given", raw_params, raw_input, param_name)
Commands.error{ "expcore-commands.command-error-param-format", param_name, "please make sure it is the correct type" }
end
return
end
-- Add the param to the table to be passed to the command callback
@@ -852,19 +859,19 @@ function Commands.run_command(command_event)
-- Run the command
-- player: LuaPlayer, ... command params, raw: string
params[command_data.max_param_count+1] = raw_input
params[command_data.max_param_count + 1] = raw_input
local success, rtn = pcall(command_data.callback, player, table.unpack(params))
if Commands.internal_error(success, command_data.name, rtn) then
return command_log(player, command_data, 'Internal Error: Command Callback Fail', raw_params, command_event.parameter, rtn)
return command_log(player, command_data, "Internal Error: Command Callback Fail", raw_params, command_event.parameter, rtn)
end
-- Give output to the player
if rtn == Commands.defines.error or rtn == Commands.error then
return command_log(player, command_data, 'Custom Error', raw_params, raw_input)
return command_log(player, command_data, "Custom Error", raw_params, raw_input)
elseif rtn ~= Commands.defines.success and rtn ~= Commands.success then
Commands.success(rtn)
end
command_log(player, command_data, 'Success', raw_params, raw_input)
command_log(player, command_data, "Success", raw_params, raw_input)
end
return Commands

View File

@@ -40,7 +40,7 @@ type_error(value, 'number', 'Value must be a number')
]]
function Common.type_error(value, test_type, error_message, level)
level = level and level+1 or 2
level = level and level + 1 or 2
return Common.type_check(value, test_type) or error(error_message, level)
end
@@ -60,6 +60,7 @@ function Common.multi_type_check(value, test_types)
return true
end
end
return false
end
@@ -75,7 +76,7 @@ multi_type_error('foo', {'string', 'table'}, 'Value must be a string or table')
]]
function Common.multi_type_error(value, test_types, error_message, level)
level = level and level+1 or 2
level = level and level + 1 or 2
return Common.mult_type_check(value, test_types) or error(error_message, level)
end
@@ -95,12 +96,12 @@ validate_argument_type(value, 'number', 2, 'repeat_count')
]]
function Common.validate_argument_type(value, test_type, param_number, param_name)
if not Common.test_type(value, test_type) then
local function_name = debug.getinfo(2, 'n').name or '<anon>'
local function_name = debug.getinfo(2, "n").name or "<anon>"
local error_message
if param_name then
error_message = string.format('Bad argument #%d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), test_type)
error_message = string.format("Bad argument #%d to %q; %q is of type %s expected %s", param_number, function_name, param_name, type(value), test_type)
else
error_message = string.format('Bad argument #%d to %q; argument is of type %s expected %s', param_number, function_name, type(value), test_type)
error_message = string.format("Bad argument #%d to %q; argument is of type %s expected %s", param_number, function_name, type(value), test_type)
end
return error(error_message, 3)
end
@@ -123,12 +124,12 @@ validate_argument_type(value, {'string', 'table'}, 2, 'player')
]]
function Common.validate_argument_multi_type(value, test_types, param_number, param_name)
if not Common.multi_type_check(value, test_types) then
local function_name = debug.getinfo(2, 'n').name or '<anon>'
local function_name = debug.getinfo(2, "n").name or "<anon>"
local error_message
if param_name then
error_message = string.format('Bad argument #%2d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), table.concat(test_types, ' or '))
error_message = string.format("Bad argument #%2d to %q; %q is of type %s expected %s", param_number, function_name, param_name, type(value), table.concat(test_types, " or "))
else
error_message = string.format('Bad argument #%2d to %q; argument is of type %s expected %s', param_number, function_name, type(value), table.concat(test_types, ' or '))
error_message = string.format("Bad argument #%2d to %q; argument is of type %s expected %s", param_number, function_name, type(value), table.concat(test_types, " or "))
end
return error(error_message, 3)
end
@@ -139,8 +140,8 @@ end
-- @usage error_if_runtime()
function Common.error_if_runtime()
if package.lifecycle == 8 then
local function_name = debug.getinfo(2, 'n').name or '<anon>'
error(function_name..' can not be called during runtime', 3)
local function_name = debug.getinfo(2, "n").name or "<anon>"
error(function_name .. " can not be called during runtime", 3)
end
end
@@ -171,7 +172,7 @@ local value = Common.resolve_value(self.defaut_value, self)
]]
function Common.resolve_value(value, ...)
return value and type(value) == 'function' and value(...) or value
return value and type(value) == "function" and value(...) or value
end
--- Converts a varible into its boolean value, nil and false return false
@@ -190,8 +191,8 @@ end
--- Returns a string for a number with comma seperators
-- @usage comma_value(input_number)
function Common.comma_value(n) -- credit http://richard.warburton.it
local left, num, right = string.match(n, '^([^%d]*%d)(%d*)(.-)$')
return left .. (num:reverse():gsub('(%d%d%d)', '%1, '):reverse()) .. right
local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$")
return left .. (num:reverse():gsub("(%d%d%d)", "%1, "):reverse()) .. right
end
--[[-- Sets a table element to value while also returning value.
@@ -218,7 +219,7 @@ write_json('dump', tbl)
]]
function Common.write_json(path, tbl)
game.write_file(path, game.table_to_json(tbl)..'\n', true, 0)
game.write_file(path, game.table_to_json(tbl) .. "\n", true, 0)
end
--[[-- Calls a require that will not error if the file is not found
@@ -232,8 +233,11 @@ local Module = opt_require 'expcore.common'
]]
function Common.opt_require(path)
local success, rtn = pcall(require, path)
if success then return rtn
else return nil, rtn end
if success then
return rtn
else
return nil, rtn
end
end
--[[-- Returns a desync safe file path for the current file
@@ -246,7 +250,7 @@ local file_path = get_file_path()
]]
function Common.get_file_path(offset)
offset = offset or 0
return debug.getinfo(offset+2, 'S').short_src:sub(10, -5)
return debug.getinfo(offset + 2, "S").short_src:sub(10, -5)
end
--[[-- Converts a table to an enum
@@ -264,18 +268,21 @@ local colors = enum{
function Common.enum(tbl)
local rtn = {}
for k, v in pairs(tbl) do
if type(k) ~= 'number' then
rtn[v]=k
if type(k) ~= "number" then
rtn[v] = k
end
end
for k, v in pairs(tbl) do
if type(k) == 'number' then
if type(k) == "number" then
table.insert(rtn, v)
end
end
for k, v in pairs(rtn) do
rtn[v]=k
rtn[v] = k
end
return rtn
end
@@ -297,7 +304,7 @@ local key = auto_complete(tbl, "foo", true, true)
]]
function Common.auto_complete(options, input, use_key, rtn_key)
if type(input) ~= 'string' then return end
if type(input) ~= "string" then return end
input = input:lower()
for key, value in pairs(options) do
local check = use_key and key or value
@@ -319,7 +326,7 @@ local player_name = get_actor()
]]
function Common.get_actor(player_name)
return game.player and game.player.name or player_name or '<server>'
return game.player and game.player.name or player_name or "<server>"
end
--[[-- Returns a message with valid chat tags to change its colour
@@ -333,8 +340,8 @@ local message = format_chat_colour('Hello, World!', { r=355, g=100, b=100 })
]]
function Common.format_chat_colour(message, color)
color = color or Colours.white
local color_tag = '[color='..math.round(color.r, 3)..', '..math.round(color.g, 3)..', '..math.round(color.b, 3)..']'
return string.format('%s%s[/color]', color_tag, message)
local color_tag = "[color=" .. math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3) .. "]"
return string.format("%s%s[/color]", color_tag, message)
end
--[[-- Returns a message with valid chat tags to change its colour, using localization
@@ -348,8 +355,8 @@ local message = format_chat_colour_localized('Hello, World!', { r=355, g=100, b=
]]
function Common.format_chat_colour_localized(message, color)
color = color or Colours.white
color = math.round(color.r, 3)..', '..math.round(color.g, 3)..', '..math.round(color.b, 3)
return {'color-tag', color, message}
color = math.round(color.r, 3) .. ", " .. math.round(color.g, 3) .. ", " .. math.round(color.b, 3)
return { "color-tag", color, message }
end
--[[-- Returns the players name in the players color
@@ -363,7 +370,7 @@ local message = format_chat_player_name(game.player, true)
]]
function Common.format_chat_player_name(player, raw_string)
player = Game.get_player_from_any(player)
local player_name = player and player.name or '<Server>'
local player_name = player and player.name or "<Server>"
local player_chat_colour = player and player.chat_color or Colours.white
if raw_string then
return Common.format_chat_colour(player_name, player_chat_colour)
@@ -388,37 +395,41 @@ player_return('Hello, World!', nil, player)
]]
function Common.player_return(value, colour, player)
colour = Common.type_check(colour, 'table') and colour or Colours[colour] ~= Colours.white and Colours[colour] or Colours.white
colour = Common.type_check(colour, "table") and colour or Colours[colour] ~= Colours.white and Colours[colour] or Colours.white
player = player or game.player
-- converts the value to a string
local returnAsString
if Common.type_check(value, 'table') or type(value) == 'userdata' then
if Common.type_check(value.__self, 'userdata') or type(value) == 'userdata' then
if Common.type_check(value, "table") or type(value) == "userdata" then
if Common.type_check(value.__self, "userdata") or type(value) == "userdata" then
-- value is userdata
returnAsString = 'Cant Display Userdata'
elseif Common.type_check(value[1], 'string') and string.find(value[1], '.+[.].+') and not string.find(value[1], '%s') then
returnAsString = "Cant Display Userdata"
elseif Common.type_check(value[1], "string") and string.find(value[1], ".+[.].+") and not string.find(value[1], "%s") then
-- value is a locale string
returnAsString = value
elseif getmetatable(value) ~= nil and not tostring(value):find('table: 0x') then
elseif getmetatable(value) ~= nil and not tostring(value):find("table: 0x") then
-- value has a tostring meta method
returnAsString = tostring(value)
else
-- value is a table
returnAsString = table.inspect(value, {depth=5, indent=' ', newline='\n'})
returnAsString = table.inspect(value, { depth = 5, indent = " ", newline = "\n" })
end
elseif Common.type_check(value, 'function') then
elseif Common.type_check(value, "function") then
-- value is a function
returnAsString = 'Cant Display Functions'
else returnAsString = tostring(value) end
returnAsString = "Cant Display Functions"
else
returnAsString = tostring(value)
end
-- returns to the player or the server
if player then
-- allows any valid player identifier to be used
player = Game.get_player_from_any(player)
if not player then error('Invalid Player given to player_return', 2) end
if not player then error("Invalid Player given to player_return", 2) end
-- plays a nice sound that is different to normal message sound
player.play_sound{path='utility/scenario_message'}
player.play_sound{ path = "utility/scenario_message" }
player.print(returnAsString, colour)
else rcon.print(returnAsString) end
else
rcon.print(returnAsString)
end
end
--[[-- Formats tick into a clean format, denominations from highest to lowest
@@ -444,78 +455,78 @@ local time = format_time(18000, { hours=true, minutes=true, seconds=true, string
function Common.format_time(ticks, options)
-- Sets up the options
options = options or {
days=false,
hours=true,
minutes=true,
seconds=false,
long=false,
time=false,
string=false,
null=false
days = false,
hours = true,
minutes = true,
seconds = false,
long = false,
time = false,
string = false,
null = false,
}
-- Basic numbers that are used in calculations
local max_days, max_hours, max_minutes, max_seconds = ticks/5184000, ticks/216000, ticks/3600, ticks/60
local days, hours = max_days, max_hours-math.floor(max_days)*24
local minutes, seconds = max_minutes-math.floor(max_hours)*60, max_seconds-math.floor(max_minutes)*60
local max_days, max_hours, max_minutes, max_seconds = ticks / 5184000, ticks / 216000, ticks / 3600, ticks / 60
local days, hours = max_days, max_hours - math.floor(max_days) * 24
local minutes, seconds = max_minutes - math.floor(max_hours) * 60, max_seconds - math.floor(max_minutes) * 60
-- Handles overflow of disabled denominations
local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = math.floor(days), math.floor(hours), math.floor(minutes), math.floor(seconds)
if not options.days then
rtn_hours = rtn_hours + rtn_days*24
rtn_hours = rtn_hours + rtn_days * 24
end
if not options.hours then
rtn_minutes = rtn_minutes + rtn_hours*60
rtn_minutes = rtn_minutes + rtn_hours * 60
end
if not options.minutes then
rtn_seconds = rtn_seconds + rtn_minutes*60
rtn_seconds = rtn_seconds + rtn_minutes * 60
end
-- Creates the null time format, does not work with long
if options.null and not options.long then
rtn_days='--'
rtn_hours='--'
rtn_minutes='--'
rtn_seconds='--'
rtn_days = "--"
rtn_hours = "--"
rtn_minutes = "--"
rtn_seconds = "--"
end
-- Format options
local suffix = 'time-symbol-'
local suffix_2 = '-short'
local suffix = "time-symbol-"
local suffix_2 = "-short"
if options.long then
suffix = ''
suffix_2 = ''
suffix = ""
suffix_2 = ""
end
local div = options.string and ' ' or 'time-format.simple-format-tagged'
local div = options.string and " " or "time-format.simple-format-tagged"
if options.time then
div = options.string and ':' or 'time-format.simple-format-div'
div = options.string and ":" or "time-format.simple-format-div"
suffix = false
end
-- Adds formatting
if suffix ~= false then
if options.string then
-- format it as a string
local long = suffix == ''
rtn_days = long and rtn_days..' days' or rtn_days..'d'
rtn_hours = long and rtn_hours..' hours' or rtn_hours..'h'
rtn_minutes = long and rtn_minutes..' minutes' or rtn_minutes..'m'
rtn_seconds = long and rtn_seconds..' seconds' or rtn_seconds..'s'
local long = suffix == ""
rtn_days = long and rtn_days .. " days" or rtn_days .. "d"
rtn_hours = long and rtn_hours .. " hours" or rtn_hours .. "h"
rtn_minutes = long and rtn_minutes .. " minutes" or rtn_minutes .. "m"
rtn_seconds = long and rtn_seconds .. " seconds" or rtn_seconds .. "s"
else
rtn_days = {suffix..'days'..suffix_2, rtn_days}
rtn_hours = {suffix..'hours'..suffix_2, rtn_hours}
rtn_minutes = {suffix..'minutes'..suffix_2, rtn_minutes}
rtn_seconds = {suffix..'seconds'..suffix_2, rtn_seconds}
rtn_days = { suffix .. "days" .. suffix_2, rtn_days }
rtn_hours = { suffix .. "hours" .. suffix_2, rtn_hours }
rtn_minutes = { suffix .. "minutes" .. suffix_2, rtn_minutes }
rtn_seconds = { suffix .. "seconds" .. suffix_2, rtn_seconds }
end
elseif not options.null then
-- weather string or not it has same format
rtn_days = string.format('%02d', rtn_days)
rtn_hours = string.format('%02d', rtn_hours)
rtn_minutes = string.format('%02d', rtn_minutes)
rtn_seconds = string.format('%02d', rtn_seconds)
rtn_days = string.format("%02d", rtn_days)
rtn_hours = string.format("%02d", rtn_hours)
rtn_minutes = string.format("%02d", rtn_minutes)
rtn_seconds = string.format("%02d", rtn_seconds)
end
-- The final return is construed
local rtn
local append = function(dom, value)
if dom and options.string then
rtn = rtn and rtn..div..value or value
rtn = rtn and rtn .. div .. value or value
elseif dom then
rtn = rtn and {div, rtn, value} or value
rtn = rtn and { div, rtn, value } or value
end
end
append(options.days, rtn_days)
@@ -542,51 +553,52 @@ copy_items_stack(game.player.get_main_inventory().get_contents())
]]
function Common.copy_items_stack(items, surface, position, radius, chest_type)
chest_type = chest_type or 'iron-chest'
surface = surface or game.surfaces[1]
if position and type(position) ~= 'table' then return end
if type(items) ~= 'table' then return end
-- Finds all entities of the given type
local p = position or {x=0, y=0}
local r = radius or 32
local entities = surface.find_entities_filtered{area={{p.x-r, p.y-r}, {p.x+r, p.y+r}}, name=chest_type} or {}
local count = #entities
local current = 1
-- Makes a new empty chest when it is needed
local function make_new_chest()
local pos = surface.find_non_colliding_position(chest_type, position, 32, 1)
local chest = surface.create_entity{name=chest_type, position=pos, force='neutral'}
table.insert(entities, chest)
count = count + 1
return chest
end
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
if count == 0 then return make_new_chest() end
if chest.get_inventory(defines.inventory.chest).can_insert(item) then
-- If the item can be inserted then the chest is returned
current = current+1
if current > count then current = 1 end
return chest
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
-- Inserts the items into the chests
local last_chest
for i=1,#items do
local item = items[i]
if item.valid_for_read then
local chest = next_chest(item)
if not chest or not chest.valid then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y)) end
chest.insert(item)
last_chest = chest
end
end
return last_chest
chest_type = chest_type or "iron-chest"
surface = surface or game.surfaces[1]
if position and type(position) ~= "table" then return end
if type(items) ~= "table" then return end
-- Finds all entities of the given type
local p = position or { x = 0, y = 0 }
local r = radius or 32
local entities = surface.find_entities_filtered{ area = { { p.x - r, p.y - r }, { p.x + r, p.y + r } }, name = chest_type } or {}
local count = #entities
local current = 1
-- Makes a new empty chest when it is needed
local function make_new_chest()
local pos = surface.find_non_colliding_position(chest_type, position, 32, 1)
local chest = surface.create_entity{ name = chest_type, position = pos, force = "neutral" }
table.insert(entities, chest)
count = count + 1
return chest
end
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
if count == 0 then return make_new_chest() end
if chest.get_inventory(defines.inventory.chest).can_insert(item) then
-- If the item can be inserted then the chest is returned
current = current + 1
if current > count then current = 1 end
return chest
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
-- Inserts the items into the chests
local last_chest
for i = 1, #items do
local item = items[i]
if item.valid_for_read then
local chest = next_chest(item)
if not chest or not chest.valid then return error(string.format("Cant move item %s to %s{%s, %s} no valid chest in radius", item.name, surface.name, p.x, p.y)) end
chest.insert(item)
last_chest = chest
end
end
return last_chest
end
--[[-- Moves items to the position and stores them in the closest entity of the type given
@@ -603,23 +615,23 @@ move_items_stack(game.player.get_main_inventory())
]]
function Common.move_items_stack(items, surface, position, radius, chest_type)
chest_type = chest_type or 'steel-chest'
surface = surface or game.surfaces[1]
chest_type = chest_type or "steel-chest"
surface = surface or game.surfaces[1]
if position and type(position) ~= 'table' then
if position and type(position) ~= "table" then
return
end
if type(items) ~= 'table' then
if type(items) ~= "table" then
return
end
-- Finds all entities of the given type
local p = position or {x=0, y=0}
local r = radius or 32
local entities = surface.find_entities_filtered{area={{p.x - r, p.y - r}, {p.x + r, p.y + r}}, name={chest_type, 'iron-chest'}} or {}
local count = #entities
local current = 0
-- Finds all entities of the given type
local p = position or { x = 0, y = 0 }
local r = radius or 32
local entities = surface.find_entities_filtered{ area = { { p.x - r, p.y - r }, { p.x + r, p.y + r } }, name = { chest_type, "iron-chest" } } or {}
local count = #entities
local current = 0
local last_entity = nil
-- ipairs does not work on LuaInventory
@@ -664,7 +676,7 @@ function Common.move_items_stack(items, surface, position, radius, chest_type)
]]
local pos = surface.find_non_colliding_position(chest_type, p, r, 1, true)
last_entity = surface.create_entity{name=chest_type, position=pos, force='neutral'}
last_entity = surface.create_entity{ name = chest_type, position = pos, force = "neutral" }
count = count + 1
entities[count] = last_entity
@@ -675,63 +687,63 @@ function Common.move_items_stack(items, surface, position, radius, chest_type)
end
--[[
-- Makes a new empty chest when it is needed
local function make_new_chest()
local pos = surface.find_non_colliding_position(chest_type, position, 32, 1)
local chest = surface.create_entity{name=chest_type, position=pos, force='neutral'}
table.insert(entities, chest)
count = count + 1
-- Makes a new empty chest when it is needed
local function make_new_chest()
local pos = surface.find_non_colliding_position(chest_type, position, 32, 1)
local chest = surface.create_entity{name=chest_type, position=pos, force='neutral'}
table.insert(entities, chest)
count = count + 1
return chest
end
return chest
end
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
-- Function used to round robin the items into all chests
local function next_chest(item)
local chest = entities[current]
if count == 0 then
if count == 0 then
return make_new_chest()
end
if chest.get_inventory(defines.inventory.chest).can_insert(item) then
-- If the item can be inserted then the chest is returned
current = current + 1
if current > count then
if chest.get_inventory(defines.inventory.chest).can_insert(item) then
-- If the item can be inserted then the chest is returned
current = current + 1
if current > count then
current = 1
end
return chest
return chest
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
else
-- Other wise it is removed from the list
table.remove(entities, current)
count = count - 1
end
end
-- Inserts the items into the chests
local last_chest
-- Inserts the items into the chests
local last_chest
for i=1,#items do
local item = items[i]
for i=1,#items do
local item = items[i]
if item.valid_for_read then
local chest = next_chest(item)
local chest = next_chest(item)
if not chest or not chest.valid then
if not chest or not chest.valid then
return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y))
end
local empty_stack = chest.get_inventory(defines.inventory.chest).find_empty_stack(item.name)
local empty_stack = chest.get_inventory(defines.inventory.chest).find_empty_stack(item.name)
if not empty_stack then
return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius', item.name, surface.name, p.x, p.y))
end
empty_stack.transfer_stack(item)
last_chest = chest
end
end
empty_stack.transfer_stack(item)
last_chest = chest
end
end
return last_chest
]]
@@ -753,34 +765,34 @@ print_grid_value(0, game.player.surface, { x=0, y=0 })
]]
function Common.print_grid_value(value, surface, position, scale, offset, immutable)
local is_string = type(value) == 'string'
local is_string = type(value) == "string"
local color = Colours.white
local text = value
if type(immutable) ~= 'boolean' then
if type(immutable) ~= "boolean" then
immutable = false
end
if not is_string then
scale = scale or 1
offset = offset or 0
position = {x = position.x + offset, y = position.y + offset}
local r = math.clamp(-value/scale, 0, 1)
local g = math.clamp(1-math.abs(value)/scale, 0, 1)
local b = math.clamp(value/scale, 0, 1)
position = { x = position.x + offset, y = position.y + offset }
local r = math.clamp(-value / scale, 0, 1)
local g = math.clamp(1 - math.abs(value) / scale, 0, 1)
local b = math.clamp(value / scale, 0, 1)
color = { r = r, g = g, b = b}
color = { r = r, g = g, b = b }
-- round at precision of 2
text = math.floor(100 * value) * 0.01
if (0 == text) then
text = '0.00'
text = "0.00"
end
end
if not immutable then
local text_entity = surface.find_entity('flying-text', position)
local text_entity = surface.find_entity("flying-text", position)
if text_entity then
text_entity.text = text
@@ -790,10 +802,10 @@ function Common.print_grid_value(value, surface, position, scale, offset, immuta
end
surface.create_entity{
name = 'flying-text',
name = "flying-text",
color = color,
text = text,
position = position
position = position,
}.active = false
end
@@ -805,7 +817,7 @@ clear_flying_text(game.player.surface)
]]
function Common.clear_flying_text(surface)
local entities = surface.find_entities_filtered{name ='flying-text'}
local entities = surface.find_entities_filtered{ name = "flying-text" }
for _, entity in pairs(entities) do
if entity and entity.valid then
entity.destroy()

View File

@@ -169,8 +169,8 @@ end)
--- Metatable used on datastores
DatastoreManager.metatable = {
__index = function(self, key) return rawget(self.children, key) or rawget(Datastore, key) end,
__newidnex = function(_, _, _) error('Datastore can not be modified', 2) end,
__call = function(self, ...) return self:get(...) end
__newidnex = function(_, _, _) error("Datastore can not be modified", 2) end,
__call = function(self, ...) return self:get(...) end,
}
--[[-- Make a new datastore connection, if a connection already exists then it is returned
@@ -188,7 +188,7 @@ function DatastoreManager.connect(datastoreName, saveToDisk, autoSave, propagate
if Datastores[datastoreName] then return Datastores[datastoreName] end
if package.lifecycle ~= package.lifecycle_stage.control then
-- Only allow this function to be called during the control stage
error('New datastore connection can not be created during runtime', 2)
error("New datastore connection can not be created during runtime", 2)
end
local new_datastore = {
@@ -202,7 +202,7 @@ function DatastoreManager.connect(datastoreName, saveToDisk, autoSave, propagate
children = {},
metadata = {},
events = {},
data = {}
data = {},
}
Data[datastoreName] = new_datastore.data
@@ -220,7 +220,7 @@ local BarData = Datastore.combine('ExampleData', 'Bar')
]]
function DatastoreManager.combine(datastoreName, subDatastoreName)
local datastore = assert(Datastores[datastoreName], 'Datastore not found '..tostring(datastoreName))
local datastore = assert(Datastores[datastoreName], "Datastore not found " .. tostring(datastoreName))
return datastore:combine(subDatastoreName)
end
@@ -235,27 +235,23 @@ Datastore.ingest('request', 'ExampleData', 'TestKey', 'Foo')
]]
function DatastoreManager.ingest(action, datastoreName, key, valueJson)
local datastore = assert(Datastores[datastoreName], 'Datastore ingest error, Datastore not found '..tostring(datastoreName))
assert(type(action) == 'string', 'Datastore ingest error, Action is not a string got: '..type(action))
assert(type(key) == 'string', 'Datastore ingest error, Key is not a string got: '..type(key))
local datastore = assert(Datastores[datastoreName], "Datastore ingest error, Datastore not found " .. tostring(datastoreName))
assert(type(action) == "string", "Datastore ingest error, Action is not a string got: " .. type(action))
assert(type(key) == "string", "Datastore ingest error, Key is not a string got: " .. type(key))
if action == 'remove' then
if action == "remove" then
datastore:raw_set(key)
elseif action == 'message' then
elseif action == "message" then
local success, value = pcall(game.json_to_table, valueJson)
if not success or value == nil then value = tonumber(valueJson) or valueJson end
datastore:raise_event('on_message', key, value)
elseif action == 'propagate' or action == 'request' then
datastore:raise_event("on_message", key, value)
elseif action == "propagate" or action == "request" then
local success, value = pcall(game.json_to_table, valueJson)
if not success or value == nil then value = tonumber(valueJson) or valueJson end
local old_value = datastore:raw_get(key)
value = datastore:raise_event('on_load', key, value, old_value)
value = datastore:raise_event("on_load", key, value, old_value)
datastore:set(key, value)
end
end
--[[-- Debug, Use to get all datastores, or return debug info on a datastore
@@ -270,7 +266,7 @@ local debug_info = Datastore.debug('ExampleData')
]]
function DatastoreManager.debug(datastoreName)
if not datastoreName then return Datastores end
local datastore = assert(Datastores[datastoreName], 'Datastore not found '..tostring(datastoreName))
local datastore = assert(Datastores[datastoreName], "Datastore not found " .. tostring(datastoreName))
return datastore:debug()
end
@@ -308,11 +304,13 @@ function Datastore:debug()
end
local children = {}
for name in pairs(self.children) do children[#children+1] = name end
for name in pairs(self.children) do children[#children + 1] = name end
if #children > 0 then debug_info.children = children end
local events = {}
for name, handlers in pairs(self.events) do events[name] = #handlers end
if next(events) then debug_info.events = events end
if next(self.metadata) then debug_info.metadata = self.metadata end
@@ -334,7 +332,7 @@ function Datastore:raw_get(key, fromChild)
local data = self.data
if self.parent then
data = self.parent:raw_get(key, true)
key = self.value_name
key = self.value_name
end
local value = data[key]
if value ~= nil then return value end
@@ -360,7 +358,7 @@ function Datastore:raw_set(key, value)
end
end
local function serialize_error(err) error('An error ocurred in a datastore serializer: '..trace(err)) end
local function serialize_error(err) error("An error ocurred in a datastore serializer: " .. trace(err)) end
--[[-- Internal, Return the serialized key
@tparam any rawKey The key that needs to be serialized, if it is already a string then it is returned
@treturn string The key after it has been serialized
@@ -370,8 +368,8 @@ key = self:serialize(key)
]]
function Datastore:serialize(rawKey)
if type(rawKey) == 'string' then return rawKey end
assert(self.serializer, 'Datastore does not have a serializer and received non string key')
if type(rawKey) == "string" then return rawKey end
assert(self.serializer, "Datastore does not have a serializer and received non string key")
local success, key = xpcall(self.serializer, serialize_error, rawKey)
return success and key or nil
end
@@ -389,11 +387,11 @@ self:write_action('save', 'TestKey', 'Foo')
]]
function Datastore:write_action(action, key, value)
local data = {action, self.name, key}
local data = { action, self.name, key }
if value ~= nil then
data[4] = type(value) == 'table' and game.table_to_json(value) or value
data[4] = type(value) == "table" and game.table_to_json(value) or value
end
game.write_file('ext/datastore.out', table.concat(data, ' ')..'\n', true, 0)
game.write_file("ext/datastore.out", table.concat(data, " ") .. "\n", true, 0)
end
----- Datastore Local
@@ -409,7 +407,7 @@ local BarData = ExampleData:combine('Bar')
]]
function Datastore:combine(subDatastoreName)
local new_datastore = DatastoreManager.connect(self.name..'.'..subDatastoreName)
local new_datastore = DatastoreManager.connect(self.name .. "." .. subDatastoreName)
self.children[subDatastoreName] = new_datastore
new_datastore.value_name = subDatastoreName
new_datastore.serializer = self.serializer
@@ -431,7 +429,7 @@ end)
]]
function Datastore:set_serializer(callback)
assert(type(callback) == 'function', 'Callback must be a function')
assert(type(callback) == "function", "Callback must be a function")
self.serializer = callback
end
@@ -501,7 +499,7 @@ function Datastore:set(key, value)
else
self:raw_set(key, value)
end
self:raise_event('on_update', key, value, old_value)
self:raise_event("on_update", key, value, old_value)
if self.auto_save then self:save(key) end
return value
end
@@ -521,7 +519,7 @@ function Datastore:increment(key, delta)
return self:set(key, value + (delta or 1))
end
local function update_error(err) log('An error occurred in datastore update:\n\t'..trace(err)) end
local function update_error(err) log("An error occurred in datastore update:\n\t" .. trace(err)) end
--[[-- Use a function to update the value locally, will trigger on_update then on_save, save_to_disk and auto_save is required for on_save
@tparam any key The key that you want to apply the update to, must be a string unless a serializer is set
@tparam function callback The function that will be used to update the value at this key
@@ -546,7 +544,7 @@ function Datastore:update(key, callback)
elseif raw_value == nil then
self:set(key, value)
else
self:raise_event('on_update', key, value, old_value)
self:raise_event("on_update", key, value, old_value)
if self.auto_save then self:save(key) end
end
end
@@ -563,12 +561,12 @@ function Datastore:remove(key)
key = self:serialize(key)
local old_value = self:raw_get(key)
self:raw_set(key)
self:raise_event('on_update', key, nil, old_value)
if self.save_to_disk then self:write_action('remove', key) end
self:raise_event("on_update", key, nil, old_value)
if self.save_to_disk then self:write_action("remove", key) end
if self.parent and self.parent.auto_save then return self.parent:save(key) end
end
local function filter_error(err) log('An error ocurred in a datastore filter:\n\t'..trace(err)) end
local function filter_error(err) log("An error ocurred in a datastore filter:\n\t" .. trace(err)) end
--[[-- Internal, Used to filter elements from a table
@tparam table tbl The table that will have the filter applied to it
@tparam[opt] function callback The function that will be used as a filter, if none giving then the provided table is returned
@@ -587,6 +585,7 @@ local function filter(tbl, callback)
local success, add = xpcall(callback, filter_error, key, value)
if success and add then rtn[key] = value end
end
return rtn
end
@@ -613,6 +612,7 @@ function Datastore:get_all(callback)
for key, value in pairs(self.parent:get_all()) do
data[key] = value[value_name]
end
return filter(data, callback)
end
end
@@ -635,7 +635,7 @@ function Datastore:update_all(callback)
if success and new_value ~= nil then
self:set(key, new_value)
else
self:raise_event('on_update', key, value, old_value)
self:raise_event("on_update", key, value, old_value)
if self.auto_save then self:save(key) end
end
end
@@ -655,7 +655,7 @@ ExampleData:request('TestKey')
function Datastore:request(key)
if self.parent then return self.parent:request(key) end
key = self:serialize(key)
self:write_action('request', key)
self:write_action("request", key)
end
--[[-- Save a value to an external source, will trigger on_save before data is saved, save_to_disk must be set to true
@@ -670,8 +670,8 @@ function Datastore:save(key)
if self.parent then self.parent:save(key) end
if not self.save_to_disk then return end
key = self:serialize(key)
local value = self:raise_event('on_save', key, copy(self:raw_get(key)))
local action = self.propagate_changes and 'propagate' or 'save'
local value = self:raise_event("on_save", key, copy(self:raw_get(key)))
local action = self.propagate_changes and "propagate" or "save"
self:write_action(action, key, value)
end
@@ -686,7 +686,7 @@ ExampleData:unload('TestKey')
function Datastore:unload(key)
if self.parent then return self.parent:unload(key) end
key = self:serialize(key)
self:raise_event('on_unload', key, copy(self:raw_get(key)))
self:raise_event("on_unload", key, copy(self:raw_get(key)))
self:save(key)
self:raw_set(key)
end
@@ -702,7 +702,7 @@ ExampleData:message('TestKey', 'Foo')
]]
function Datastore:message(key, message)
key = self:serialize(key)
self:write_action('message', key, message)
self:write_action("message", key, message)
end
--[[-- Save all the keys in the datastore, optional filter callback
@@ -746,7 +746,7 @@ end
----- Events
-- @section events
local function event_error(err) log('An error ocurred in a datastore event handler:\n\t'..trace(err)) end
local function event_error(err) log("An error ocurred in a datastore event handler:\n\t" .. trace(err)) end
--[[-- Internal, Raise an event on this datastore
@tparam string event_name The name of the event to raise for this datastore
@tparam string key The key that this event is being raised for
@@ -761,11 +761,11 @@ value = self:raise_event('on_save', key, value)
]]
function Datastore:raise_event(event_name, key, value, old_value, source)
-- Raise the event for the children of this datastore
if source ~= 'child' and next(self.children) then
if type(value) ~= 'table' then value = {} end
if source ~= "child" and next(self.children) then
if type(value) ~= "table" then value = {} end
for value_name, child in pairs(self.children) do
local old_child_value = old_value and old_value[value_name] or nil
value[value_name] = child:raise_event(event_name, key, value[value_name], old_child_value, 'parent')
value[value_name] = child:raise_event(event_name, key, value[value_name], old_child_value, "parent")
end
end
@@ -779,13 +779,13 @@ function Datastore:raise_event(event_name, key, value, old_value, source)
end
-- Raise the event for the parent of this datastore
if source ~= 'parent' and self.parent then
if source ~= "parent" and self.parent then
local parent_value = self.parent:raw_get(key, true)
self.parent:raise_event(event_name, key, parent_value, parent_value, 'child')
self.parent:raise_event(event_name, key, parent_value, parent_value, "child")
end
-- If this is the save event and the table is empty then return nil
if event_name == 'on_save' and next(self.children) and not next(value) then return end
if event_name == "on_save" and next(self.children) and not next(value) then return end
return value
end
@@ -799,12 +799,12 @@ Datastore.on_load = event_factory('on_load')
]]
local function event_factory(event_name)
return function(self, callback)
assert(type(callback) == 'function', 'Handler must be a function')
assert(type(callback) == "function", "Handler must be a function")
local handlers = self.events[event_name]
if not handlers then
self.events[event_name] = { callback }
else
handlers[#handlers+1] = callback
handlers[#handlers + 1] = callback
end
end
end
@@ -817,7 +817,7 @@ ExampleData:on_load(function(key, value)
game.print('Test data loaded for: '..key)
end)
]]
Datastore.on_load = event_factory('on_load')
Datastore.on_load = event_factory("on_load")
--[[-- Register a callback that triggers before data is saved, returned value is saved externally
@tparam function callback The handler that will be registered to the on_load event
@@ -827,7 +827,7 @@ ExampleData:on_save(function(key, value)
game.print('Test data saved for: '..key)
end)
]]
Datastore.on_save = event_factory('on_save')
Datastore.on_save = event_factory("on_save")
--[[-- Register a callback that triggers before data is unloaded, returned value is ignored
@tparam function callback The handler that will be registered to the on_load event
@@ -837,7 +837,7 @@ ExampleData:on_load(function(key, value)
game.print('Test data unloaded for: '..key)
end)
]]
Datastore.on_unload = event_factory('on_unload')
Datastore.on_unload = event_factory("on_unload")
--[[-- Register a callback that triggers when a message is received, returned value is ignored
@tparam function callback The handler that will be registered to the on_load event
@@ -847,7 +847,7 @@ ExampleData:on_message(function(key, value)
game.print('Test data message for: '..key)
end)
]]
Datastore.on_message = event_factory('on_message')
Datastore.on_message = event_factory("on_message")
--[[-- Register a callback that triggers any time a value is changed, returned value is ignored
@tparam function callback The handler that will be registered to the on_load event
@@ -857,7 +857,7 @@ ExampleData:on_update(function(key, value)
game.print('Test data updated for: '..key)
end)
]]
Datastore.on_update = event_factory('on_update')
Datastore.on_update = event_factory("on_update")
----- Module Return
return DatastoreManager

View File

@@ -47,8 +47,8 @@ local servers = External.get_servers()
]]
function External.get_servers()
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
return assert(ext.servers, 'No server list was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
return assert(ext.servers, "No server list was found, please ensure that the external service is running")
end
--[[-- Gets a table of all the servers filtered by name, key is the server id, value is the server details
@@ -60,14 +60,15 @@ local servers = External.get_servers_filtered(public)
]]
function External.get_servers_filtered(search)
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(ext.servers, 'No server list was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
local found_servers = {}
search = search:lower()
for server_id, server in pairs(servers) do
local str = concat{server.name, server.short_name, server.id}
local str = concat{ server.name, server.short_name, server.id }
if str:lower():find(search, 1, true) then found_servers[server_id] = server end
end
return found_servers
end
@@ -79,9 +80,9 @@ local server = External.get_current_server()
]]
function External.get_current_server()
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(ext.servers, 'No server list was found, please ensure that the external service is running')
local server_id = assert(ext.current, 'No current id was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
local server_id = assert(ext.current, "No current id was found, please ensure that the external service is running")
return servers[server_id]
end
@@ -94,8 +95,8 @@ local server = External.get_server_details('eu-01')
]]
function External.get_server_details(server_id)
assert(ext, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(ext.servers, 'No server list was found, please ensure that the external service is running')
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
return servers[server_id]
end
@@ -109,10 +110,10 @@ local status = External.get_server_status('eu-01')
]]
function External.get_server_status(server_id, raw)
assert(var, 'No external data was found, use External.valid() to ensure external data exists.')
local servers = assert(var.status, 'No server status was found, please ensure that the external service is running')
local current = assert(ext.current, 'No current id was found, please ensure that the external service is running')
return not raw and server_id == current and 'Current' or servers[server_id]
assert(var, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(var.status, "No server status was found, please ensure that the external service is running")
local current = assert(ext.current, "No current id was found, please ensure that the external service is running")
return not raw and server_id == current and "Current" or servers[server_id]
end
--[[-- Gets the ups of the current server
@@ -121,8 +122,8 @@ local server_ups = External.get_server_ups()
]]
function External.get_server_ups()
assert(var, 'No external data was found, use External.valid() to ensure external data exists.')
return assert(var.server_ups, 'No server ups was found, please ensure that the external service is running')
assert(var, "No external data was found, use External.valid() to ensure external data exists.")
return assert(var.server_ups, "No server ups was found, please ensure that the external service is running")
end
--[[-- Connect a player to the given server
@@ -138,16 +139,16 @@ External.request_connection(player, 'eu-01', true)
]]
function External.request_connection(player, server_id, self_requested)
local server = { address = server_id, name = 'Unknown Server', description = 'This server is not ran by us, please check the address of the server.' }
local server = { address = server_id, name = "Unknown Server", description = "This server is not ran by us, please check the address of the server." }
if ext and ext.servers and ext.servers[server_id] then server = ext.servers[server_id] end
local message = 'Please press the connect button below to join.'
if not self_requested then message = 'You have been asked to switch to a different server.\n'..message end
local message = "Please press the connect button below to join."
if not self_requested then message = "You have been asked to switch to a different server.\n" .. message end
player.connect_to_server{
address = server.address,
name = '\n[color=orange][font=heading-1]'..server.name..'[/font][/color]\n',
description = server.description..'\n'..message
name = "\n[color=orange][font=heading-1]" .. server.name .. "[/font][/color]\n",
description = server.description .. "\n" .. message,
}
end
--- Module return
return External
return External

View File

@@ -132,13 +132,12 @@ local Roles = _C.opt_require("modules.exp_legacy.expcore.roles")
local Event = _C.opt_require("modules/exp_legacy/utils/event")
if Roles and Event then
Event.add(Roles.events.on_role_assigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
Event.add(Roles.events.on_role_unassigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
Event.add(Roles.events.on_role_assigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
Event.add(Roles.events.on_role_unassigned, function(e)
Gui.update_top_flow(game.get_player(e.player_index))
end)
end
return Gui
return Gui

View File

@@ -12,61 +12,61 @@ local Event = require("modules/exp_legacy/utils/event")
--- Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible
-- @element hide_top_flow
local hide_top_flow =
Gui.element{
type = 'sprite-button',
sprite = 'utility/preset',
style = 'tool_button',
tooltip = {'gui_util.button_tooltip'},
name = Gui.unique_static_name
}
:style{
padding = -2,
width = 18,
height = 36
}
:on_click(function(player, _,_)
Gui.toggle_top_flow(player, false)
end)
Gui.element{
type = "sprite-button",
sprite = "utility/preset",
style = "tool_button",
tooltip = { "gui_util.button_tooltip" },
name = Gui.unique_static_name,
}
:style{
padding = -2,
width = 18,
height = 36,
}
:on_click(function(player, _, _)
Gui.toggle_top_flow(player, false)
end)
Gui.core_defines.hide_top_flow = hide_top_flow
--- Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden
-- @element show_top_flow
local show_top_flow =
Gui.element{
type = 'sprite-button',
sprite = 'utility/preset',
style = 'tool_button',
tooltip = {'gui_util.button_tooltip'},
name = Gui.unique_static_name
}
:style{
padding = -2,
width = 18,
height = 20
}
:on_click(function(player, _,_)
Gui.toggle_top_flow(player, true)
end)
Gui.element{
type = "sprite-button",
sprite = "utility/preset",
style = "tool_button",
tooltip = { "gui_util.button_tooltip" },
name = Gui.unique_static_name,
}
:style{
padding = -2,
width = 18,
height = 20,
}
:on_click(function(player, _, _)
Gui.toggle_top_flow(player, true)
end)
Gui.core_defines.show_top_flow = show_top_flow
--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible
-- @element hide_left_flow
local hide_left_flow =
Gui.element{
type = 'sprite-button',
sprite = 'utility/close_black',
style = 'tool_button',
tooltip = {'expcore-gui.left-button-tooltip'},
name = Gui.unique_static_name
}
:style{
padding = -3,
width = 18,
height = 20
}
:on_click(function(player, _,_)
Gui.hide_left_flow(player)
end)
Gui.element{
type = "sprite-button",
sprite = "utility/close_black",
style = "tool_button",
tooltip = { "expcore-gui.left-button-tooltip" },
name = Gui.unique_static_name,
}
:style{
padding = -3,
width = 18,
height = 20,
}
:on_click(function(player, _, _)
Gui.hide_left_flow(player)
end)
Gui.core_defines.hide_left_flow = hide_left_flow
--- Draw the core elements when a player joins the game
@@ -80,10 +80,10 @@ Event.add(defines.events.on_player_created, function(event)
-- Draw the left flow
local left_flow = Gui.get_left_flow(player)
local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' }
local button_flow = left_flow.add{ type = "flow", name = "gui_core_buttons", direction = "vertical" }
local show_top = show_top_flow(button_flow)
local hide_left = hide_left_flow(button_flow)
show_top.visible = false
hide_left.visible = false
Gui.draw_left_flow(player)
end)
end)

View File

@@ -24,19 +24,19 @@ local alignment = Gui.alignment(element, 'example_center_top_alignment', 'center
]]
Gui.alignment =
Gui.element(function(_, parent, name, _,_)
return parent.add{
name = name or 'alignment',
type = 'flow',
}
end)
:style(function(style, _,_, horizontal_align, vertical_align)
style.padding = {1, 2}
style.vertical_align = vertical_align or 'center'
style.horizontal_align = horizontal_align or 'right'
style.vertically_stretchable = style.vertical_align ~= 'center'
style.horizontally_stretchable = style.horizontal_align ~= 'center'
end)
Gui.element(function(_, parent, name, _, _)
return parent.add{
name = name or "alignment",
type = "flow",
}
end)
:style(function(style, _, _, horizontal_align, vertical_align)
style.padding = { 1, 2 }
style.vertical_align = vertical_align or "center"
style.horizontal_align = horizontal_align or "right"
style.vertically_stretchable = style.vertical_align ~= "center"
style.horizontally_stretchable = style.horizontal_align ~= "center"
end)
--[[-- Draw a scroll pane that has a table inside of it
@element Gui.scroll_table
@@ -51,42 +51,42 @@ local scroll_table = Gui.scroll_table(element, 200, 3)
]]
Gui.scroll_table =
Gui.element(function(_, parent, height, column_count, name)
-- Draw the scroll
local scroll_pane =
parent.add{
name = name or 'scroll',
type = 'scroll-pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto',
style = 'scroll_pane_under_subheader'
Gui.element(function(_, parent, height, column_count, name)
-- Draw the scroll
local scroll_pane =
parent.add{
name = name or "scroll",
type = "scroll-pane",
direction = "vertical",
horizontal_scroll_policy = "never",
vertical_scroll_policy = "auto",
style = "scroll_pane_under_subheader",
}
-- Set the style of the scroll pane
local scroll_style = scroll_pane.style
scroll_style.padding = { 1, 3 }
scroll_style.maximal_height = height
scroll_style.horizontally_stretchable = true
-- Draw the table
local scroll_table =
scroll_pane.add{
type = "table",
name = "table",
column_count = column_count,
}
-- Return the scroll table
return scroll_table
end)
:style{
padding = 0,
cell_padding = 0,
vertical_align = "center",
horizontally_stretchable = true,
}
-- Set the style of the scroll pane
local scroll_style = scroll_pane.style
scroll_style.padding = {1, 3}
scroll_style.maximal_height = height
scroll_style.horizontally_stretchable = true
-- Draw the table
local scroll_table =
scroll_pane.add{
type = 'table',
name = 'table',
column_count = column_count
}
-- Return the scroll table
return scroll_table
end)
:style{
padding = 0,
cell_padding = 0,
vertical_align = 'center',
horizontally_stretchable = true
}
--[[-- Used to add a frame with the header style, has the option for a right alignment flow for buttons
@element Gui.header
@tparam LuaGuiElement parent the parent element to which the header will be added
@@ -105,35 +105,35 @@ local header = Gui.header(
]]
Gui.header =
Gui.element(function(_, parent, caption, tooltip, add_alignment, name, label_name)
-- Draw the header
local header =
parent.add{
name = name or 'header',
type = 'frame',
style = 'subheader_frame'
}
Gui.element(function(_, parent, caption, tooltip, add_alignment, name, label_name)
-- Draw the header
local header =
parent.add{
name = name or "header",
type = "frame",
style = "subheader_frame",
}
-- Change the style of the header
local style = header.style
style.padding = {2, 4}
style.use_header_filler = false
style.horizontally_stretchable = true
-- Change the style of the header
local style = header.style
style.padding = { 2, 4 }
style.use_header_filler = false
style.horizontally_stretchable = true
-- Draw the caption label
if caption then
header.add{
name = label_name or 'header_label',
type = 'label',
style = 'frame_title',
caption = caption,
tooltip = tooltip
}
end
-- Draw the caption label
if caption then
header.add{
name = label_name or "header_label",
type = "label",
style = "frame_title",
caption = caption,
tooltip = tooltip,
}
end
-- Return either the header or the added alignment
return add_alignment and Gui.alignment(header) or header
end)
-- Return either the header or the added alignment
return add_alignment and Gui.alignment(header) or header
end)
--[[-- Used to add a frame with the footer style, has the option for a right alignment flow for buttons
@element Gui.footer
@@ -153,35 +153,35 @@ local footer = Gui.footer(
]]
Gui.footer =
Gui.element(function(_, parent, caption, tooltip, add_alignment, name)
-- Draw the header
local footer =
parent.add{
name = name or 'footer',
type = 'frame',
style = 'subfooter_frame'
}
Gui.element(function(_, parent, caption, tooltip, add_alignment, name)
-- Draw the header
local footer =
parent.add{
name = name or "footer",
type = "frame",
style = "subfooter_frame",
}
-- Change the style of the footer
local style = footer.style
style.padding = {2, 4}
style.use_header_filler = false
style.horizontally_stretchable = true
-- Change the style of the footer
local style = footer.style
style.padding = { 2, 4 }
style.use_header_filler = false
style.horizontally_stretchable = true
-- Draw the caption label
if caption then
footer.add{
name = 'footer_label',
type = 'label',
style = 'frame_title',
caption = caption,
tooltip = tooltip
}
end
-- Draw the caption label
if caption then
footer.add{
name = "footer_label",
type = "label",
style = "frame_title",
caption = caption,
tooltip = tooltip,
}
end
-- Return either the footer or the added alignment
return add_alignment and Gui.alignment(footer) or footer
end)
-- Return either the footer or the added alignment
return add_alignment and Gui.alignment(footer) or footer
end)
--[[-- Used for left frames to give them a nice boarder
@element Gui.container
@@ -194,29 +194,29 @@ local container = Gui.container(parent, 'my_container', 200)
]]
Gui.container =
Gui.element(function(_, parent, name, _)
-- Draw the external container
local frame =
parent.add{
name = name,
type = 'frame'
}
frame.style.horizontally_stretchable = false
Gui.element(function(_, parent, name, _)
-- Draw the external container
local frame =
parent.add{
name = name,
type = "frame",
}
frame.style.horizontally_stretchable = false
-- Return the container
return frame.add{
name = 'container',
type = 'frame',
direction = 'vertical',
style = 'inside_shallow_frame_packed'
}
end)
:style(function(style, element, _,width)
style.vertically_stretchable = false
local frame_style = element.parent.style
frame_style.padding = 2
frame_style.minimal_width = width
end)
-- Return the container
return frame.add{
name = "container",
type = "frame",
direction = "vertical",
style = "inside_shallow_frame_packed",
}
end)
:style(function(style, element, _, width)
style.vertically_stretchable = false
local frame_style = element.parent.style
frame_style.padding = 2
frame_style.minimal_width = width
end)
--[[-- Used to make a solid white bar in a gui
@element Gui.bar
@@ -228,19 +228,22 @@ local bar = Gui.bar(parent, 100)
]]
Gui.bar =
Gui.element(function(_, parent)
return parent.add{
type = 'progressbar',
size = 1,
value = 1
}
end)
:style(function(style, _,width)
style.height = 3
style.color = {r=255, g=255, b=255}
if width then style.width = width
else style.horizontally_stretchable = true end
end)
Gui.element(function(_, parent)
return parent.add{
type = "progressbar",
size = 1,
value = 1,
}
end)
:style(function(style, _, width)
style.height = 3
style.color = { r = 255, g = 255, b = 255 }
if width then
style.width = width
else
style.horizontally_stretchable = true
end
end)
--[[-- Used to make a label which is centered and of a certian size
@element Gui.centered_label
@@ -254,20 +257,20 @@ local label = Gui.centered_label(parent, 100, 'This is centered')
]]
Gui.centered_label =
Gui.element(function(_, parent, width, caption, tooltip)
local label = parent.add{
type = 'label',
caption = caption,
tooltip = tooltip,
}
Gui.element(function(_, parent, width, caption, tooltip)
local label = parent.add{
type = "label",
caption = caption,
tooltip = tooltip,
}
local style = label.style
style.horizontal_align = 'center'
style.single_line = false
style.width = width
local style = label.style
style.horizontal_align = "center"
style.single_line = false
style.width = width
return label
end)
return label
end)
--[[-- Used to make a title which has two bars on either side
@element Gui.title_label
@@ -281,18 +284,18 @@ local label = Gui.centered_label(parent, 100, 'This is centered')
]]
Gui.title_label =
Gui.element(function(_, parent, width, caption, tooltip)
local title_flow = parent.add{ type='flow' }
title_flow.style.vertical_align = 'center'
Gui.element(function(_, parent, width, caption, tooltip)
local title_flow = parent.add{ type = "flow" }
title_flow.style.vertical_align = "center"
Gui.bar(title_flow, width)
local title_label = title_flow.add{
type = 'label',
caption = caption,
tooltip = tooltip,
style = 'frame_title'
}
Gui.bar(title_flow)
Gui.bar(title_flow, width)
local title_label = title_flow.add{
type = "label",
caption = caption,
tooltip = tooltip,
style = "frame_title",
}
Gui.bar(title_flow)
return title_label
end)
return title_label
end)

View File

@@ -88,4 +88,4 @@ function Gui.sprite_style(size, padding, style)
style.height = size
style.width = size
return style
end
end

View File

@@ -4,7 +4,7 @@
]]
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
local mod_gui = require 'mod-gui'
local mod_gui = require "mod-gui"
local hide_left_flow = Gui.core_defines.hide_left_flow.name
@@ -12,7 +12,7 @@ local hide_left_flow = Gui.core_defines.hide_left_flow.name
-- @section leftFlow
-- Triggered when a user changed the visibility of a left flow element by clicking a button
Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click'
Gui.events.on_visibility_changed_by_click = "on_visibility_changed_by_click"
--- Contains the uids of the elements that will shown on the left flow and their join functions
-- @table left_elements
@@ -68,7 +68,7 @@ function Gui.left_toolbar_button(sprite, tooltip, element_define, authenticator)
button:raise_event{
name = Gui.events.on_visibility_changed_by_click,
element = Gui.get_top_element(player, button),
state = Gui.toggle_left_element(player, element_define)
state = Gui.toggle_left_element(player, element_define),
}
end)
@@ -90,8 +90,8 @@ function Gui.inject_left_flow_order(provider)
Gui.get_left_flow_order = provider
local debug_info = debug.getinfo(2, "Sn")
local file_name = debug_info.short_src:sub(10, -5)
local func_name = debug_info.name or ("<anonymous:"..debug_info.linedefined..">")
Gui._left_flow_order_src = file_name..":"..func_name
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
Gui._left_flow_order_src = file_name .. ":" .. func_name
end
--[[-- Draw all the left elements onto the left flow, internal use only with on join
@@ -121,17 +121,17 @@ function Gui.draw_left_flow(player)
end, debug.traceback)
if not draw_success then
log('There as been an error with an element draw function: '..element_define.defined_at..'\n\t'..left_element)
log("There as been an error with an element draw function: " .. element_define.defined_at .. "\n\t" .. left_element)
goto continue
end
-- Check if it should be open by default
local open_on_join = element_define.open_on_join
local visible = type(open_on_join) == 'boolean' and open_on_join or false
if type(open_on_join) == 'function' then
local visible = type(open_on_join) == "boolean" and open_on_join or false
if type(open_on_join) == "function" then
local success, err = xpcall(open_on_join, debug.traceback, player)
if not success then
log('There as been an error with an open on join hander for a gui element:\n\t'..err)
log("There as been an error with an open on join hander for a gui element:\n\t" .. err)
goto continue
end
visible = err
@@ -166,7 +166,7 @@ function Gui.reorder_left_flow(player)
-- Reorder the elements, index 1 is the core ui buttons so +1 is required
for index, element_define in ipairs(flow_order) do
local element = left_flow[element_define.name]
left_flow.swap_children(index+1, element.get_index_in_parent())
left_flow.swap_children(index + 1, element.get_index_in_parent())
end
end
@@ -188,6 +188,7 @@ function Gui.update_left_flow(player)
return true
end
end
hide_button.visible = false
return false
end
@@ -220,7 +221,7 @@ function Gui.hide_left_flow(player)
element_define.toolbar_button:raise_event{
name = Gui.events.on_visibility_changed_by_click,
element = button,
state = false
state = false,
}
end
end
@@ -272,4 +273,4 @@ function Gui.toggle_left_element(player, element_define, state)
Gui.toggle_toolbar_button(player, element_define.toolbar_button, state)
end
return state
end
end

View File

@@ -23,7 +23,7 @@ local Gui = {
--- The prototype used to store the functions of an element define
_prototype_element = {},
--- The prototype metatable applied to new element defines
_mt_element = {}
_mt_element = {},
}
--- Allow access to the element prototype methods
@@ -37,14 +37,14 @@ function Gui._mt_element.__call(self, parent, ...)
-- Asserts to catch common errors
if element then
if self.name and self.name ~= element.name then
error("Static name \""..self.name.."\" expected but got: "..tostring(element.name))
error("Static name \"" .. self.name .. "\" expected but got: " .. tostring(element.name))
end
local event_triggers = element.tags and element.tags.ExpGui_event_triggers
if event_triggers and table.array_contains(event_triggers, self.uid) then
error("Element::triggers_events should not be called on the value you return from the definition")
end
elseif self.name then
error("Static name \""..self.name.."\" expected but no element was returned from the definition")
error("Static name \"" .. self.name .. "\" expected but no element was returned from the definition")
end
-- Register events by default, but allow skipping them
@@ -59,8 +59,8 @@ end
local function get_defined_at(level)
local debug_info = debug.getinfo(level, "Sn")
local file_name = debug_info.short_src:sub(10, -5)
local func_name = debug_info.name or ("<anonymous:"..debug_info.linedefined..">")
return file_name..":"..func_name
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
return file_name .. ":" .. func_name
end
--- Element Define.
@@ -115,19 +115,20 @@ function Gui.element(element_define)
local uid = Gui.uid + 1
Gui.uid = uid
element.uid = uid
Gui.debug_info[uid] = { draw = 'None', style = 'None', events = {} }
Gui.debug_info[uid] = { draw = "None", style = "None", events = {} }
-- Add the definition function
if type(element_define) == 'table' then
if type(element_define) == "table" then
Gui.debug_info[uid].draw = element_define
if element_define.name == Gui.unique_static_name then
element_define.name = "ExpGui_"..tostring(uid)
element_define.name = "ExpGui_" .. tostring(uid)
end
for k, v in pairs(element_define) do
if element[k] == nil then
element[k] = v
end
end
element._draw = function(_, parent)
return parent.add(element_define)
end
@@ -183,7 +184,7 @@ end)
function Gui._prototype_element:style(style_define)
_C.error_if_runtime()
-- Add the definition function
if type(style_define) == 'table' then
if type(style_define) == "table" then
Gui.debug_info[self.uid].style = style_define
self._style = function(style)
for key, value in pairs(style_define) do
@@ -206,7 +207,7 @@ end
function Gui._prototype_element:static_name(name)
_C.error_if_runtime()
if name == Gui.unique_static_name then
self.name = "ExpGui_"..tostring(self.uid)
self.name = "ExpGui_" .. tostring(self.uid)
else
self.name = name
end
@@ -295,7 +296,7 @@ function Gui._prototype_element:raise_event(event)
local success, err = xpcall(handler, debug.traceback, player, element, event)
if not success then
error('There as been an error with an event handler for a gui element:\n\t'..err)
error("There as been an error with an event handler for a gui element:\n\t" .. err)
end
return self
end
@@ -328,84 +329,84 @@ end
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_open(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_open = event_handler_factory(defines.events.on_gui_opened)
--- Called when the player closes the GUI they have open.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_close(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_close = event_handler_factory(defines.events.on_gui_closed)
--- Called when LuaGuiElement is clicked.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_click(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click)
--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_confirmed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed)
--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_checked_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed)
--- Called when LuaGuiElement element value is changed (related to choose element buttons).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_elem_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed)
--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_location_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed)
--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_tab_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed)
--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_selection_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed)
--- Called when LuaGuiElement switch state is changed (related to switches).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_switch_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed)
--- Called when LuaGuiElement text is changed by the player.
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_text_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed)
--- Called when LuaGuiElement slider value is changed (related to the slider element).
-- @tparam function handler the event handler which will be called
-- @usage element_define:on_value_changed(function(event)
-- event.player.print(table.inspect(event))
--end)
-- end)
Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed)
-- Module return

View File

@@ -4,7 +4,7 @@
]]
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
local mod_gui = require 'mod-gui' --- @dep mod-gui
local mod_gui = require "mod-gui" --- @dep mod-gui
local toolbar_button_size = 36
local hide_top_flow = Gui.core_defines.hide_top_flow.name
@@ -14,7 +14,7 @@ local show_top_flow = Gui.core_defines.show_top_flow.name
-- @section topFlow
-- Triggered when a user changed the visibility of a left flow element by clicking a button
Gui.events.on_toolbar_button_toggled = 'on_toolbar_button_toggled'
Gui.events.on_toolbar_button_toggled = "on_toolbar_button_toggled"
--- Contains the uids of the elements that will shown on the top flow and their auth functions
-- @table top_elements
@@ -26,7 +26,7 @@ Gui.top_flow_button_style = mod_gui.button_style
--- The style that should be used for buttons on the top flow when their flow is visible
-- @field Gui.top_flow_button_toggled_style
Gui.top_flow_button_toggled_style = 'menu_button_continue'
Gui.top_flow_button_toggled_style = "menu_button_continue"
--[[-- Styles a top flow button depending on the state given
@tparam LuaGuiElement button the button element to style
@@ -40,7 +40,7 @@ Gui.toolbar_button_style(button, false)
]]
function Gui.toolbar_button_style(button, state, size)
---@cast button LuaGuiElement
--- @cast button LuaGuiElement
if state then
button.style = Gui.top_flow_button_toggled_style
else
@@ -108,8 +108,8 @@ function Gui.inject_top_flow_order(provider)
Gui.get_top_flow_order = provider
local debug_info = debug.getinfo(2, "Sn")
local file_name = debug_info.short_src:sub(10, -5)
local func_name = debug_info.name or ("<anonymous:"..debug_info.linedefined..">")
Gui._top_flow_order_src = file_name..":"..func_name
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
Gui._top_flow_order_src = file_name .. ":" .. func_name
end
--[[-- Updates the visible state of all the elements on the players top flow, uses authenticator
@@ -137,12 +137,12 @@ function Gui.update_top_flow(player)
if not element then
element = element_define(top_flow)
else
top_flow.swap_children(index+1, element.get_index_in_parent())
top_flow.swap_children(index + 1, element.get_index_in_parent())
end
-- Set the visible state
local allowed = element_define.authenticator
if type(allowed) == 'function' then allowed = allowed(player) end
if type(allowed) == "function" then allowed = allowed(player) end
element.visible = allowed or false
-- If its not visible and there is a left element, then hide it
@@ -176,7 +176,7 @@ function Gui.reorder_top_flow(player)
-- Reorder the elements, index 1 is the core ui buttons so +1 is required
for index, element_define in ipairs(flow_order) do
local element = top_flow[element_define.name]
top_flow.swap_children(index+1, element.get_index_in_parent())
top_flow.swap_children(index + 1, element.get_index_in_parent())
end
end
@@ -243,7 +243,7 @@ function Gui.toggle_toolbar_button(player, element_define, state)
name = Gui.events.on_toolbar_button_toggled,
element = toolbar_button,
player = player,
state = state
state = state,
}
return state
end
@@ -262,18 +262,18 @@ end)
]]
function Gui.toolbar_button(sprite, tooltip, authenticator)
return Gui.element{
type = 'sprite-button',
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2
}
:add_to_top_flow(authenticator)
type = "sprite-button",
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name,
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2,
}
:add_to_top_flow(authenticator)
end
--[[-- Creates a toggle button on the top flow with consistent styling
@@ -293,23 +293,23 @@ end)
]]
function Gui.toolbar_toggle_button(sprite, tooltip, authenticator)
local button =
Gui.element{
type = 'sprite-button',
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2
}
:add_to_top_flow(authenticator)
Gui.element{
type = "sprite-button",
sprite = sprite,
tooltip = tooltip,
style = Gui.top_flow_button_style,
name = Gui.unique_static_name,
}
:style{
minimal_width = toolbar_button_size,
height = toolbar_button_size,
padding = -2,
}
:add_to_top_flow(authenticator)
button:on_click(function(player, _, _)
Gui.toggle_toolbar_button(player, button)
end)
return button
end
end

View File

@@ -23,28 +23,27 @@ Permission_Groups.new_group('Restricted') -- this defines a new group called "Re
]]
local Game = require("modules.exp_legacy.utils.game") --- @dep utils.game
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
local Async = require("modules/exp_util/async")
local Permissions_Groups = {
groups={}, -- store for the different groups that are created
_prototype={} -- stores functions that are used on group instances
groups = {}, -- store for the different groups that are created
_prototype = {}, -- stores functions that are used on group instances
}
-- Async function to add players to permission groups
local add_to_permission_group_async =
Async.register(function(permission_group, player)
permission_group.add_player(player)
end)
Async.register(function(permission_group, player)
permission_group.add_player(player)
end)
Permissions_Groups.add_to_permission_group_async = add_to_permission_group_async
-- Async function to remove players from permission groups
local remove_from_permission_group_async =
Async.register(function(permission_group, player)
permission_group.remove_player(player)
end)
Async.register(function(permission_group, player)
permission_group.remove_player(player)
end)
Permissions_Groups.remove_from_permission_group_async = remove_from_permission_group_async
--- Getters.
@@ -61,11 +60,11 @@ Groups.new_group('Admin')
]]
function Permissions_Groups.new_group(name)
local group = setmetatable({
name=name,
actions={},
allow_all_actions=true
name = name,
actions = {},
allow_all_actions = true,
}, {
__index= Permissions_Groups._prototype
__index = Permissions_Groups._prototype,
})
Permissions_Groups.groups[name] = group
return group
@@ -149,7 +148,7 @@ group:set_action('toggle_map_editor', false)
function Permissions_Groups._prototype:set_action(action, state)
local input_action = defines.input_action[action]
if input_action == nil then input_action = action end
assert(type(input_action) == 'number', tostring(action)..' is not a valid input action')
assert(type(input_action) == "number", tostring(action) .. " is not a valid input action")
self.actions[input_action] = state
return self
end
@@ -165,12 +164,13 @@ group:allow{
]]
function Permissions_Groups._prototype:allow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in pairs(actions) do
self:set_action(action, true)
end
return self
end
@@ -189,12 +189,13 @@ group:disallow{
]]
function Permissions_Groups._prototype:disallow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in pairs(actions) do
self:set_action(action, false)
end
return self
end
@@ -231,7 +232,7 @@ local allowed = group:is_allowed('write_to_console')
]]
function Permissions_Groups._prototype:is_allowed(action)
if type(action) == 'string' then
if type(action) == "string" then
action = defines.input_action[action]
end
local state = self.actions[action]
@@ -260,6 +261,7 @@ function Permissions_Groups._prototype:create()
for _, action in pairs(defines.input_action) do
group.set_allows_action(action, self:is_allowed(action))
end
return group
end
@@ -347,6 +349,7 @@ function Permissions_Groups._prototype:print(message)
for _, player in pairs(players) do
player.print(message)
end
return #players
end
@@ -355,4 +358,4 @@ Event.on_init(function()
Permissions_Groups.reload_permissions()
end)
return Permissions_Groups
return Permissions_Groups

View File

@@ -48,58 +48,59 @@ local Commands = require("modules.exp_legacy.expcore.commands") --- @dep expcore
require("modules.exp_legacy.config.expcore.command_general_parse") --- @dep config.expcore.command_general_parse
--- Common player data that acts as the root store for player data
local PlayerData = Datastore.connect('PlayerData', true) -- saveToDisk
local PlayerData = Datastore.connect("PlayerData", true) -- saveToDisk
PlayerData:set_serializer(Datastore.name_serializer) -- use player name
--- Store and enum for the data saving preference
local DataSavingPreference = PlayerData:combine('DataSavingPreference')
local PreferenceEnum = { 'All', 'Statistics', 'Settings', 'Required' }
for k,v in ipairs(PreferenceEnum) do PreferenceEnum[v] = k end
DataSavingPreference:set_default('All')
local DataSavingPreference = PlayerData:combine("DataSavingPreference")
local PreferenceEnum = { "All", "Statistics", "Settings", "Required" }
for k, v in ipairs(PreferenceEnum) do PreferenceEnum[v] = k end
DataSavingPreference:set_default("All")
DataSavingPreference:set_metadata{
name = {'expcore-data.preference'},
tooltip = {'expcore-data.preference-tooltip'},
value_tooltip ={'expcore-data.preference-value-tooltip'}
name = { "expcore-data.preference" },
tooltip = { "expcore-data.preference-tooltip" },
value_tooltip = { "expcore-data.preference-value-tooltip" },
}
--- Sets your data saving preference
-- @command set-data-preference
Commands.new_command('set-preference', 'Allows you to set your data saving preference')
:add_param('option', false, 'string-options', PreferenceEnum)
:register(function(player, option)
DataSavingPreference:set(player, option)
return {'expcore-data.set-preference', option}
end)
Commands.new_command("set-preference", "Allows you to set your data saving preference")
:add_param("option", false, "string-options", PreferenceEnum)
:register(function(player, option)
DataSavingPreference:set(player, option)
return { "expcore-data.set-preference", option }
end)
--- Gets your data saving preference
-- @command data-preference
Commands.new_command('preference', 'Shows you what your current data saving preference is')
:register(function(player)
return {'expcore-data.get-preference', DataSavingPreference:get(player)}
end)
Commands.new_command("preference", "Shows you what your current data saving preference is")
:register(function(player)
return { "expcore-data.get-preference", DataSavingPreference:get(player) }
end)
--- Gets your data and writes it to a file
Commands.new_command('save-data', 'Writes all your player data to a file on your computer')
:register(function(player)
player.print{'expcore-data.get-data'}
game.write_file('expgaming_player_data.json', game.table_to_json(PlayerData:get(player, {})), false, player.index)
end)
Commands.new_command("save-data", "Writes all your player data to a file on your computer")
:register(function(player)
player.print{ "expcore-data.get-data" }
game.write_file("expgaming_player_data.json", game.table_to_json(PlayerData:get(player, {})), false, player.index)
end)
--- Async function called after 5 seconds with no player data loaded
local check_data_loaded_async =
Async.register(function(player)
local player_data = PlayerData:get(player)
if not player_data or not player_data.valid then
player.print{'expcore-data.data-failed'}
Datastore.ingest('request', 'PlayerData', player.name, '{"valid":false}')
end
end)
Async.register(function(player)
local player_data = PlayerData:get(player)
if not player_data or not player_data.valid then
player.print{ "expcore-data.data-failed" }
Datastore.ingest("request", "PlayerData", player.name, '{"valid":false}')
end
end)
--- When player data loads tell the player if the load had failed previously
PlayerData:on_load(function(player_name, player_data, existing_data)
if not player_data or player_data.valid == false then return end
if existing_data and existing_data.valid == false then
game.players[player_name].print{'expcore-data.data-restore'}
game.players[player_name].print{ "expcore-data.data-restore" }
end
player_data.valid = true
end)
@@ -122,7 +123,7 @@ end)
--- Display your data preference when your data loads
DataSavingPreference:on_load(function(player_name, dataPreference)
game.players[player_name].print{'expcore-data.get-preference', dataPreference or DataSavingPreference.default}
game.players[player_name].print{ "expcore-data.get-preference", dataPreference or DataSavingPreference.default }
end)
--- Load player data when they join
@@ -139,15 +140,17 @@ Event.add(defines.events.on_player_left_game, function(event)
local player_data = PlayerData:get(player)
if player_data and player_data.valid == true then
PlayerData:unload(player)
else PlayerData:raw_set(player.name) end
else
PlayerData:raw_set(player.name)
end
end)
----- Module Return -----
return {
All = PlayerData, -- Root for all of a players data
Statistics = PlayerData:combine('Statistics'), -- Common place for stats
Settings = PlayerData:combine('Settings'), -- Common place for settings
Required = PlayerData:combine('Required'), -- Common place for required data
Statistics = PlayerData:combine("Statistics"), -- Common place for stats
Settings = PlayerData:combine("Settings"), -- Common place for settings
Required = PlayerData:combine("Required"), -- Common place for required data
DataSavingPreference = DataSavingPreference, -- Stores what data groups will be saved
PreferenceEnum = PreferenceEnum -- Enum for the allowed options for data saving preference
}
PreferenceEnum = PreferenceEnum, -- Enum for the allowed options for data saving preference
}

View File

@@ -119,24 +119,24 @@ local write_json = _C.write_json --- @dep expcore.common
local Roles = {
_prototype = {},
config = {
order = {}, -- Contains the order of the roles, lower index is better
roles = {}, -- Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default
players = {}, -- Contains the roles that players have
auto_assign = {}, -- Contains references to all roles which have auto assign conditions
order = {}, -- Contains the order of the roles, lower index is better
roles = {}, -- Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default
players = {}, -- Contains the roles that players have
auto_assign = {}, -- Contains references to all roles which have auto assign conditions
deferred_roles = {}, -- Contains the roles that are to be assigned to players when they are unjailed
},
events = {
on_role_assigned = script.generate_event_name(),
on_role_assigned = script.generate_event_name(),
on_role_unassigned = script.generate_event_name(),
}
},
}
--- When global is loaded it will have the metatable re-assigned to the roles
Storage.register({
Roles.config.players,
Roles.config.deferred_roles
Roles.config.deferred_roles,
}, function(tbl)
Roles.config.players = tbl[1]
Roles.config.deferred_roles = tbl[2]
@@ -150,12 +150,12 @@ end)
-- this is the raw internal trigger as the other function is called at other times
-- there is a second half called role_update which triggers after the event call, it also is called when a player joins
local function emit_player_roles_updated(player, type, roles, by_player_name, skip_game_print)
by_player_name = by_player_name or game.player and game.player.name or '<server>'
by_player_name = by_player_name or game.player and game.player.name or "<server>"
local by_player = game.players[by_player_name]
local by_player_index = by_player and by_player.index or 0
-- get the event id from the type of emit
local event = Roles.events.on_role_assigned
if type == 'unassign' then
if type == "unassign" then
event = Roles.events.on_role_unassigned
end
-- Get the names of the roles
@@ -163,27 +163,28 @@ local function emit_player_roles_updated(player, type, roles, by_player_name, sk
for index, role in ipairs(roles) do
role_names[index] = role.name
end
-- output to all the different locations: game print, player sound, event trigger and role log
if not skip_game_print then
game.print({'expcore-roles.game-message-'..type, player.name, table.concat(role_names, ', '), by_player_name}, Colours.cyan)
game.print({ "expcore-roles.game-message-" .. type, player.name, table.concat(role_names, ", "), by_player_name }, Colours.cyan)
end
if type == 'assign' then
player.play_sound{path='utility/achievement_unlocked'}
if type == "assign" then
player.play_sound{ path = "utility/achievement_unlocked" }
else
player.play_sound{path='utility/game_lost'}
player.play_sound{ path = "utility/game_lost" }
end
script.raise_event(event, {
name=event,
tick=game.tick,
player_index=player.index,
by_player_index=by_player_index,
roles=role_names
name = event,
tick = game.tick,
player_index = player.index,
by_player_index = by_player_index,
roles = role_names,
})
write_json('log/roles.log', {
player_name=player.name,
by_player_name=by_player_name,
type=type,
roles_changed=role_names
write_json("log/roles.log", {
player_name = player.name,
by_player_name = by_player_name,
type = type,
roles_changed = role_names,
})
end
@@ -195,13 +196,14 @@ game.player.print(Roles.debug())
]]
function Roles.debug()
local output = ''
local output = ""
for index, role_name in ipairs(Roles.config.order) do
local role = Roles.config.roles[role_name]
local color = role.custom_color or Colours.white
color = string.format('[color=%d, %d, %d]', color.r, color.g, color.b)
output = output..string.format('\n%s %s) %s[/color]', color, index, serpent.line(role))
color = string.format("[color=%d, %d, %d]", color.r, color.g, color.b)
output = output .. string.format("\n%s %s) %s[/color]", color, index, serpent.line(role))
end
return output
end
@@ -234,9 +236,10 @@ function Roles.print_to_roles_higher(role, message)
local roles = {}
for index, role_name in ipairs(Roles.config.order) do
if index <= role.index and role_name ~= Roles.config.internal.default then
roles[#roles+1] = role_name
roles[#roles + 1] = role_name
end
end
Roles.print_to_roles(roles, message)
end
@@ -254,9 +257,10 @@ function Roles.print_to_roles_lower(role, message)
local roles = {}
for index, role_name in ipairs(Roles.config.order) do
if index >= role.index and role_name ~= Roles.config.internal.default then
roles[#roles+1] = role_name
roles[#roles + 1] = role_name
end
end
Roles.print_to_roles(roles, message)
end
@@ -296,12 +300,12 @@ local role = Roles.get_role_from_any('Moderator')
]]
function Roles.get_role_from_any(any)
local t_any = type(any)
if t_any == 'number' or tonumber(any) then
if t_any == "number" or tonumber(any) then
any = tonumber(any)
return Roles.get_role_by_order(any)
elseif t_any == 'string' then
elseif t_any == "string" then
return Roles.get_role_by_name(any)
elseif t_any == 'table' then
elseif t_any == "table" then
return Roles.get_role_by_name(any.name)
end
end
@@ -316,13 +320,14 @@ local roles = Roles.get_player_roles(game.player)
]]
function Roles.get_player_roles(player)
player = Game.get_player_from_any(player)
if not player then return {Roles.config.roles[Roles.config.internal.root]} end
if not player then return { Roles.config.roles[Roles.config.internal.root] } end
local roles = Roles.config.players[player.name] or {}
local default = Roles.config.roles[Roles.config.internal.default]
local rtn = {default}
local rtn = { default }
for index, role_name in ipairs(roles) do
rtn[index+1] = Roles.config.roles[role_name]
rtn[index + 1] = Roles.config.roles[role_name]
end
return rtn
end
@@ -343,6 +348,7 @@ function Roles.get_player_highest_role(player)
highest = role
end
end
return highest
end
@@ -370,7 +376,7 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent)
if not player then return end
-- Convert the roles into a table (allows for optional array)
if type(roles) ~= 'table' or roles.name then
if type(roles) ~= "table" or roles.name then
roles = { roles }
end
@@ -394,10 +400,11 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent)
end
else
assign_later[role.name] = {
count = 1, by_player_name = by_player_name or "<server>", silent = silent
count = 1, by_player_name = by_player_name or "<server>", silent = silent,
}
end
end
Roles.config.deferred_roles[valid_player.name] = assign_later
return
end
@@ -407,7 +414,7 @@ function Roles.assign_player(player, roles, by_player_name, skip_checks, silent)
end
if valid_player then
emit_player_roles_updated(valid_player, 'assign', role_objects, by_player_name, silent)
emit_player_roles_updated(valid_player, "assign", role_objects, by_player_name, silent)
end
end
@@ -431,7 +438,7 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
if not player then return end
-- Convert the roles into a table (allows for optional array)
if type(roles) ~= 'table' or roles.name then
if type(roles) ~= "table" or roles.name then
roles = { roles }
end
@@ -456,10 +463,11 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
end
else
assign_later[role.name] = {
count = -1, by_player_name = by_player_name or "<server>", silent = silent
count = -1, by_player_name = by_player_name or "<server>", silent = silent,
}
end
end
Roles.config.deferred_roles[valid_player.name] = assign_later
end
@@ -490,17 +498,20 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
end
end
end
for assign_by_player_name, assign_roles in pairs(assigns) do
if #assign_roles > 0 then emit_player_roles_updated(valid_player, 'assign', assign_roles, assign_by_player_name) end
if #assign_roles > 0 then emit_player_roles_updated(valid_player, "assign", assign_roles, assign_by_player_name) end
end
for unassign_by_player_name, unassign_roles in pairs(unassigns) do
if #unassign_roles > 0 then emit_player_roles_updated(valid_player, 'unassign', unassign_roles, unassign_by_player_name) end
if #unassign_roles > 0 then emit_player_roles_updated(valid_player, "unassign", unassign_roles, unassign_by_player_name) end
end
Roles.config.deferred_roles[player.name] = nil
end
if valid_player and #role_changes > 0 then
emit_player_roles_updated(valid_player, 'unassign', role_changes, by_player_name, silent)
emit_player_roles_updated(valid_player, "unassign", role_changes, by_player_name, silent)
end
end
@@ -518,10 +529,11 @@ Roles.override_player_roles{
}
]]
function Roles.override_player_roles(player_name,roles)
function Roles.override_player_roles(player_name, roles)
local player_roles = Roles.config.players
if not roles then
for k in pairs(player_roles) do player_roles[k] = nil end
for k, new_roles in pairs(player_name) do player_roles[k] = new_roles end
else
Roles.config.players[player_name] = roles
@@ -549,6 +561,7 @@ function Roles.player_has_role(player, search_role)
for _, role in ipairs(roles) do
if role.name == search_role.name then return true end
end
return false
end
@@ -569,6 +582,7 @@ function Roles.player_has_flag(player, flag_name)
return true
end
end
return false
end
@@ -589,6 +603,7 @@ function Roles.player_allowed(player, action)
return true
end
end
return false
end
@@ -616,7 +631,7 @@ function Roles.define_role_order(order)
Roles.config.order = {}
local done = {}
for index, role in ipairs(order) do
if type(role) == 'table' and role.name then
if type(role) == "table" and role.name then
done[role.name] = true
Roles.config.order[index] = role.name
else
@@ -624,22 +639,24 @@ function Roles.define_role_order(order)
Roles.config.order[index] = role
end
end
-- Check no roles were missed
for role_name in pairs(Roles.config.roles) do
if not done[role_name] then
error('Role missing '..role_name..' from role order, all defined roles must be included.', 2)
error("Role missing " .. role_name .. " from role order, all defined roles must be included.", 2)
end
end
-- Re-links roles to they parents as this is called at the end of the config
for index, role_name in pairs(Roles.config.order) do
local role = Roles.config.roles[role_name]
if not role then
error('Role with name '..role_name..' has not beed defined, either define it or remove it from the order list.', 2)
error("Role with name " .. role_name .. " has not beed defined, either define it or remove it from the order list.", 2)
end
role.index = index
local parent = Roles.config.roles[role.parent]
if parent then
setmetatable(role.allowed_actions, {__index=parent.allowed_actions})
setmetatable(role.allowed_actions, { __index = parent.allowed_actions })
end
end
end
@@ -696,14 +713,14 @@ local role = Roles.new_role('Moderator', 'Mod')
]]
function Roles.new_role(name, short_hand)
_C.error_if_runtime()
if Roles.config.roles[name] then return error('Role name is non unique') end
if Roles.config.roles[name] then return error("Role name is non unique") end
local role = setmetatable({
name=name,
short_hand=short_hand or name,
allowed_actions={},
allow_all_actions=false,
flags={}
}, {__index=Roles._prototype})
name = name,
short_hand = short_hand or name,
allowed_actions = {},
allow_all_actions = false,
flags = {},
}, { __index = Roles._prototype })
Roles.config.roles[name] = role
return role
end
@@ -738,12 +755,13 @@ role:allow{
]]
function Roles._prototype:allow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in ipairs(actions) do
self.allowed_actions[action]=true
self.allowed_actions[action] = true
end
return self
end
@@ -759,12 +777,13 @@ role:disallow{
]]
function Roles._prototype:disallow(actions)
if type(actions) ~= 'table' then
actions = {actions}
if type(actions) ~= "table" then
actions = { actions }
end
for _, action in ipairs(actions) do
self.allowed_actions[action]=false
self.allowed_actions[action] = false
end
return self
end
@@ -850,7 +869,7 @@ role:set_custom_color{ r=255, g=100, b=100}
]]
function Roles._prototype:set_custom_color(color)
if type(color) ~= 'table' then
if type(color) ~= "table" then
color = Colours[color]
end
self.custom_color = color
@@ -869,7 +888,7 @@ role:set_permission_group('Admin')
function Roles._prototype:set_permission_group(name, use_factorio_api)
_C.error_if_runtime()
if use_factorio_api then
self.permission_group = {true, name}
self.permission_group = { true, name }
else
local group = Groups.get_group_by_name(name)
if not group then return end
@@ -892,7 +911,7 @@ function Roles._prototype:set_parent(role)
self.parent = role
role = Roles.get_role_from_any(role)
if not role then return self end
setmetatable(self.allowed_actions, {__index=role.allowed_actions})
setmetatable(self.allowed_actions, { __index = role.allowed_actions })
return self
end
@@ -972,13 +991,14 @@ function Roles._prototype:add_player(player, skip_check, skip_event)
for _, role_name in ipairs(player_roles) do
if role_name == self.name then return false end
end
player_roles[#player_roles+1] = self.name
player_roles[#player_roles + 1] = self.name
else
Roles.config.players[player_name] = {self.name}
Roles.config.players[player_name] = { self.name }
end
-- Emits event if required
if valid_player and not skip_event then
emit_player_roles_updated(valid_player, 'assign', {self})
emit_player_roles_updated(valid_player, "assign", { self })
end
return true
end
@@ -1018,13 +1038,14 @@ function Roles._prototype:remove_player(player, skip_check, skip_event)
break
end
end
if #player_roles == 0 then
Roles.config.players[player_name] = nil
end
end
-- Emits event if required
if valid_player and not skip_event then
emit_player_roles_updated(valid_player, 'unassign', {self})
emit_player_roles_updated(valid_player, "unassign", { self })
end
return found
end
@@ -1049,12 +1070,13 @@ function Roles._prototype:get_players(online)
local player = game.players[player_name]
-- Filter by online state if required
if player and (online == nil or player.connected == online) then
players[#players+1] = player
players[#players + 1] = player
end
break
end
end
end
return players
end
@@ -1071,6 +1093,7 @@ function Roles._prototype:print(message)
for _, player in ipairs(players) do
player.print(message)
end
return #players
end
@@ -1082,6 +1105,7 @@ local function role_update(event)
local state = Roles.player_has_flag(player, flag)
async_function(player, state)
end
-- Updates the players permission group
local highest = Roles.get_player_highest_role(player)
if highest.permission_group then
@@ -1114,7 +1138,7 @@ local function auto_assign(event)
if not lookup[role] then
local success, rtn = pcall(condition, player)
if not success then
log{'expcore-roles.error-log-format-assign', role.name, rtn}
log{ "expcore-roles.error-log-format-assign", role.name, rtn }
elseif rtn == true then
ctn = ctn + 1
assigns[ctn] = role
@@ -1139,6 +1163,5 @@ Event.on_nth_tick(3600, function()
end
end)
-- Return Roles
return Roles
return Roles