mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-01-05 22:53:39 +02:00
Replaced command for player and chat colors
This commit is contained in:
parent
a5703fa2bb
commit
1cd19c69e7
@ -276,9 +276,6 @@ global.config = {
|
||||
donator_commands = {
|
||||
enabled = true
|
||||
},
|
||||
player_colors = {
|
||||
enabled = true
|
||||
},
|
||||
-- adds a command to generate a popup dialog box for players to see, useful for important announcements
|
||||
popup = {
|
||||
enabled = true
|
||||
|
@ -27,6 +27,7 @@ require 'features.server_commands'
|
||||
require 'features.player_create'
|
||||
require 'features.rank_system'
|
||||
require 'features.redmew_settings_sync'
|
||||
require 'features.player_colors'
|
||||
|
||||
-- Feature modules
|
||||
-- Each can be disabled safely
|
||||
@ -60,9 +61,6 @@ end
|
||||
if config.nuke_control.enabled then
|
||||
require 'features.nuke_control'
|
||||
end
|
||||
if config.player_colors.enabled then
|
||||
require 'features.player_colors'
|
||||
end
|
||||
if config.reactor_meltdown.enabled then
|
||||
require 'features.reactor_meltdown'
|
||||
end
|
||||
|
@ -123,7 +123,7 @@ local function draw_main_frame(center, player)
|
||||
label_style.height = 35
|
||||
label_style.vertical_align = 'center'
|
||||
|
||||
local value = Settings.get(player_index, name)
|
||||
local value = Settings.toScalar(name, Settings.get(player_index, name))
|
||||
local input_container = setting_grid.add({type = 'flow'})
|
||||
local input_container_style = input_container.style
|
||||
input_container_style.height = 35
|
||||
@ -238,7 +238,8 @@ local function setting_set(event)
|
||||
return
|
||||
end
|
||||
|
||||
local element_data = data[event.setting_name]
|
||||
local setting_name = event.setting_name
|
||||
local element_data = data[setting_name]
|
||||
|
||||
if not element_data then
|
||||
return
|
||||
@ -249,8 +250,8 @@ local function setting_set(event)
|
||||
-- for some reason it has been removed already
|
||||
return
|
||||
end
|
||||
set_element_value(input, event.new_value)
|
||||
element_data.previous_value = event.old_value
|
||||
set_element_value(input, Settings.toScalar(setting_name, event.new_value))
|
||||
element_data.previous_value = Settings.toScalar(setting_name, event.old_value)
|
||||
end
|
||||
|
||||
Gui.on_custom_close(main_frame_name, function(event)
|
||||
|
@ -1,84 +1,75 @@
|
||||
local Event = require 'utils.event'
|
||||
local Command = require 'utils.command'
|
||||
local Server = require 'features.server'
|
||||
local Token = require 'utils.token'
|
||||
local Utils = require 'utils.core'
|
||||
local Ranks = require 'resources.ranks'
|
||||
local Settings = require 'utils.redmew_settings'
|
||||
|
||||
local serialize = serpent.line
|
||||
local player_color_name = 'player-color'
|
||||
local player_chat_color_name = 'player-chat-color'
|
||||
Settings.register(player_color_name, Settings.types.color, nil, 'player_colors.player_color_setting_label')
|
||||
Settings.register(player_chat_color_name, Settings.types.color, nil, 'player_colors.player_chat_color_setting_label')
|
||||
|
||||
local Public = {}
|
||||
|
||||
local color_callback =
|
||||
Token.register(
|
||||
function(data)
|
||||
local key = data.key
|
||||
local value = data.value
|
||||
if not value then
|
||||
return
|
||||
end
|
||||
local player = game.players[key]
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
player.chat_color = value.chat_color
|
||||
player.color = value.color
|
||||
end
|
||||
)
|
||||
-- left in for migration purposes, remove at a later point
|
||||
local color_callback = Token.register(function(data)
|
||||
local key = data.key
|
||||
local value = data.value
|
||||
|
||||
if not value then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.players[key]
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
Settings.set(player.index, player_color_name, value.color)
|
||||
Settings.set(player.index, player_chat_color_name, value.chat_color)
|
||||
|
||||
end)
|
||||
|
||||
local function setting_set(event)
|
||||
local value = event.new_value
|
||||
if not value then
|
||||
return
|
||||
end
|
||||
|
||||
local setting_name = event.setting_name
|
||||
if setting_name ~= player_color_name and setting_name ~= player_chat_color_name then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if setting_name == player_color_name then
|
||||
player.color = value
|
||||
end
|
||||
|
||||
if setting_name == player_chat_color_name then
|
||||
player.chat_color = value
|
||||
end
|
||||
end
|
||||
|
||||
local function player_joined_game(event)
|
||||
local player_index = event.player_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
-- already migrated
|
||||
if Settings.get(player_index, player_color_name) then
|
||||
return
|
||||
end
|
||||
|
||||
--- Attempts to retrieve and get the saved color of a LuaPlayer
|
||||
function Public.recall_player_color(player)
|
||||
Server.try_get_data('colors', player.name, color_callback)
|
||||
end
|
||||
|
||||
--- Assigns LuaPlayer random RGB values for color and player_color and returns the RGB table.
|
||||
function Public.set_random_color(player)
|
||||
return {
|
||||
chat_color = Utils.set_and_return(player, 'chat_color', Utils.random_RGB()),
|
||||
color = Utils.set_and_return(player, 'color', Utils.random_RGB())
|
||||
}
|
||||
end
|
||||
|
||||
Command.add(
|
||||
'redmew-color',
|
||||
{
|
||||
description = {'command_description.redmew_color'},
|
||||
arguments = {'set-reset-random'},
|
||||
required_rank = Ranks.regular
|
||||
},
|
||||
function(args, player)
|
||||
local player_name = player.name
|
||||
local arg = args['set-reset-random']
|
||||
if arg == 'set' then
|
||||
local data = {
|
||||
color = player.color,
|
||||
chat_color = player.chat_color
|
||||
}
|
||||
Server.set_data('colors', player_name, data)
|
||||
player.print({'player_colors.color_saved'})
|
||||
Utils.print_except({'player_colors.color_saved_advert', player_name})
|
||||
elseif arg == 'reset' then
|
||||
Server.set_data('colors', player_name, nil)
|
||||
player.print({'player_colors.color_reset'})
|
||||
elseif arg == 'random' then
|
||||
local color_data = Public.set_random_color(player)
|
||||
player.print({'player_colors.color_random', serialize(color_data)})
|
||||
else
|
||||
player.print({'player_colors.fail_wrong_argument'})
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_joined_game,
|
||||
function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
Public.recall_player_color(player)
|
||||
end
|
||||
)
|
||||
Event.add(defines.events.on_player_joined_game, player_joined_game)
|
||||
Event.add(Settings.events.on_setting_set, setting_set)
|
||||
|
||||
return Public
|
||||
|
@ -80,6 +80,8 @@ color_saved_advert=__1__ has saved their color server-side for future maps. You
|
||||
color_reset=Your saved color (if you had one) has been removed.
|
||||
color_random=Your color has been changed to: __1__
|
||||
fail_wrong_argument=Only set, reset, and random are accepted arguments
|
||||
player_color_setting_label=Character color
|
||||
player_chat_color_setting_label=Chat color
|
||||
|
||||
[performance]
|
||||
fail_wrong_argument=Scale must be a valid number ranging from 0.05 to 1
|
||||
|
@ -29,8 +29,10 @@ print_admins=__1__(ADMIN) __2__: __3__
|
||||
[gui_util]
|
||||
button_tooltip=Shows / hides the Redmew Gui buttons.
|
||||
|
||||
|
||||
[redmew_settings_util]
|
||||
fraction_invalid_value=fraction setting type requires the input to be a valid number between 0 and 1.
|
||||
string_invalid_value=string setting type requires the input to be either a valid string or something that can be converted to a string.
|
||||
boolean_invalid_value=boolean setting type requires the input to be either a boolean, number or string that can be transformed to a boolean.
|
||||
color_invalid_string_value=color setting type requires the input to be either a valid preset such as "red" or "green", or a valid "r g b" or "r g b a" value.
|
||||
color_invalid_table_value=color setting type with a table requires a valid {r, g, b} or {r, g, b, a} table with these keys.
|
||||
invalid_color_value=color setting type only supports strings or tables as value type.
|
||||
|
161
resources/setting_types.lua
Normal file
161
resources/setting_types.lua
Normal file
@ -0,0 +1,161 @@
|
||||
local Color = require 'resources.color_presets'
|
||||
local type = type
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local gmatch = string.gmatch
|
||||
local pairs = pairs
|
||||
local concat = table.concat
|
||||
local size = table.size
|
||||
|
||||
local color_key_table = {'r', 'g', 'b', 'a'}
|
||||
|
||||
local function raw(input)
|
||||
return input
|
||||
end
|
||||
|
||||
--- Contains a set of callables that will attempt to sanitize and transform the input
|
||||
--- sanitizer = takes any raw input and converts it to the final value used and stored
|
||||
--- to_string = takes stored input and converts it to its string representation
|
||||
return {
|
||||
fraction = {
|
||||
toScalar = raw,
|
||||
sanitizer = function (input)
|
||||
input = tonumber(input)
|
||||
|
||||
if input == nil then
|
||||
return false, {'redmew_settings_util.fraction_invalid_value'}
|
||||
end
|
||||
|
||||
if input < 0 then
|
||||
input = 0
|
||||
end
|
||||
|
||||
if input > 1 then
|
||||
input = 1
|
||||
end
|
||||
|
||||
return true, input
|
||||
end
|
||||
},
|
||||
string = {
|
||||
toScalar = raw,
|
||||
sanitizer = function (input)
|
||||
if input == nil then
|
||||
return true, ''
|
||||
end
|
||||
|
||||
local input_type = type(input)
|
||||
if input_type == 'string' then
|
||||
return true, input
|
||||
end
|
||||
|
||||
if input_type == 'number' or input_type == 'boolean' then
|
||||
return true, tostring(input)
|
||||
end
|
||||
|
||||
return false, {'redmew_settings_util.string_invalid_value'}
|
||||
end
|
||||
},
|
||||
boolean = {
|
||||
toScalar = raw,
|
||||
sanitizer = function (input)
|
||||
local input_type = type(input)
|
||||
|
||||
if input_type == 'boolean' then
|
||||
return true, input
|
||||
end
|
||||
|
||||
if input_type == 'string' then
|
||||
if input == '0' or input == '' or input == 'false' or input == 'no' then
|
||||
return true, false
|
||||
end
|
||||
if input == '1' or input == 'true' or input == 'yes' then
|
||||
return true, true
|
||||
end
|
||||
|
||||
return true, tonumber(input) ~= nil
|
||||
end
|
||||
|
||||
if input_type == 'number' then
|
||||
return true, input ~= 0
|
||||
end
|
||||
|
||||
return false, {'redmew_settings_util.boolean_invalid_value'}
|
||||
end
|
||||
},
|
||||
color = {
|
||||
toScalar = function (input)
|
||||
if type(input) ~= 'table' then
|
||||
return ''
|
||||
end
|
||||
|
||||
local out = {}
|
||||
local i = 0
|
||||
for _, value in pairs(input) do
|
||||
i = i + 1
|
||||
out[i] = value
|
||||
end
|
||||
|
||||
return concat(out, ' ')
|
||||
end,
|
||||
--- accepts either a table or a string
|
||||
--- string must be in an "r g b" or "r g b a" format
|
||||
--- optionally a preset name may be given instead (from resources/color_presets.lua)
|
||||
--- table must contain the "r", "g" and "b" keys and may optionally contain an "a" key
|
||||
--- the output will always be a valid color table for Factorio
|
||||
sanitizer = function (input)
|
||||
if input == nil or input == '' then
|
||||
return true, nil
|
||||
end
|
||||
|
||||
local input_type = type(input)
|
||||
|
||||
if input_type == 'string' then
|
||||
local color = Color[input]
|
||||
if color and tonumber(input) == nil then
|
||||
-- we have some numeric keys in there
|
||||
return true, color
|
||||
end
|
||||
|
||||
local data = {}
|
||||
local index = 0
|
||||
for value in gmatch(input, '%S+') do
|
||||
index = index + 1
|
||||
if index < 5 then
|
||||
value = tonumber(value)
|
||||
if value == nil or value < 0 or value > 255 then
|
||||
return false, {'redmew_settings_util.color_invalid_string_value'}
|
||||
end
|
||||
|
||||
data[color_key_table[index]] = value
|
||||
end
|
||||
end
|
||||
|
||||
if size(data) < 3 then
|
||||
return false, {'redmew_settings_util.color_invalid_string_value'}
|
||||
end
|
||||
|
||||
return true, data
|
||||
end
|
||||
|
||||
if input_type == 'table' then
|
||||
if size(input) > 4 or not input.r or not input.g or not input.b then
|
||||
return false, {'redmew_settings_util.color_invalid_table_value'}
|
||||
end
|
||||
|
||||
local data = {
|
||||
r = input.r,
|
||||
g = input.g,
|
||||
b = input.b
|
||||
}
|
||||
if input.a then
|
||||
data.a = input.a
|
||||
end
|
||||
|
||||
return true, data
|
||||
end
|
||||
|
||||
return false, {'redmew_settings_util.invalid_color_value'}
|
||||
end
|
||||
},
|
||||
}
|
@ -15,6 +15,8 @@ local next = next
|
||||
local serialize = serpent.line
|
||||
local gmatch = string.gmatch
|
||||
local get_rank_name = Rank.get_rank_name
|
||||
local pairs = pairs
|
||||
local pcall = pcall
|
||||
|
||||
local Command = {}
|
||||
|
||||
@ -24,12 +26,11 @@ local deprecated_command_alternatives = {
|
||||
['tpplayer'] = 'tp <player>',
|
||||
['tppos'] = 'tp',
|
||||
['tpmode'] = 'tp mode',
|
||||
['color-redmew'] = 'redmew-color'
|
||||
}
|
||||
|
||||
local notify_on_commands = {
|
||||
['version'] = 'RedMew has a version as well, accessible via /redmew-version',
|
||||
['color'] = 'RedMew allows color saving and a color randomizer: check out /redmew-color',
|
||||
['color'] = 'You can also use the Redmew Settings (gear icon) to set the character and chat colors, this will be synchronized to all Redmew servers',
|
||||
['ban'] = 'In case your forgot: please remember to include a message on how to appeal a ban'
|
||||
}
|
||||
|
||||
|
@ -1,80 +1,29 @@
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local type = type
|
||||
local error = error
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local pairs = pairs
|
||||
local format = string.format
|
||||
local tostring = tostring
|
||||
local type = type
|
||||
local raise_event = script.raise_event
|
||||
|
||||
--- Contains a set of callables that will attempt to sanitize and transform the input
|
||||
local settings_type = {
|
||||
fraction = function (input)
|
||||
input = tonumber(input)
|
||||
|
||||
if input == nil then
|
||||
return false, {'redmew_settings_util.fraction_invalid_value'}
|
||||
end
|
||||
|
||||
if input < 0 then
|
||||
input = 0
|
||||
end
|
||||
|
||||
if input > 1 then
|
||||
input = 1
|
||||
end
|
||||
|
||||
return true, input
|
||||
end,
|
||||
string = function (input)
|
||||
if input == nil then
|
||||
return true, ''
|
||||
end
|
||||
|
||||
local input_type = type(input)
|
||||
if input_type == 'string' then
|
||||
return true, input
|
||||
end
|
||||
|
||||
if input_type == 'number' or input_type == 'boolean' then
|
||||
return true, tostring(input)
|
||||
end
|
||||
|
||||
return false, {'redmew_settings_util.string_invalid_value'}
|
||||
end,
|
||||
boolean = function (input)
|
||||
local input_type = type(input)
|
||||
|
||||
if input_type == 'boolean' then
|
||||
return true, input
|
||||
end
|
||||
|
||||
if input_type == 'string' then
|
||||
if input == '0' or input == '' or input == 'false' or input == 'no' then
|
||||
return true, false
|
||||
end
|
||||
if input == '1' or input == 'true' or input == 'yes' then
|
||||
return true, true
|
||||
end
|
||||
|
||||
return true, tonumber(input) ~= nil
|
||||
end
|
||||
|
||||
if input_type == 'number' then
|
||||
return true, input ~= 0
|
||||
end
|
||||
|
||||
return false, {'redmew_settings_util.boolean_invalid_value'}
|
||||
end,
|
||||
}
|
||||
|
||||
local settings_type = require 'resources.setting_types'
|
||||
local settings = {}
|
||||
local memory = {}
|
||||
local raw_callback_setting = {
|
||||
callback = function (input)
|
||||
return true, input
|
||||
end
|
||||
local missing_setting = {
|
||||
data_transformation = {
|
||||
toScalar = function(input)
|
||||
if type(input) ~= 'table' then
|
||||
return input
|
||||
end
|
||||
|
||||
return tostring(input)
|
||||
end,
|
||||
sanitizer = function (input)
|
||||
return true, input
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
Global.register(memory, function (tbl) memory = tbl end)
|
||||
@ -94,7 +43,7 @@ Public.events = {
|
||||
on_setting_set = Event.generate_event_name('on_setting_set'),
|
||||
}
|
||||
|
||||
Public.types = {fraction = 'fraction', string = 'string', boolean = 'boolean'}
|
||||
Public.types = {fraction = 'fraction', string = 'string', boolean = 'boolean', color = 'color'}
|
||||
|
||||
---Register a specific setting with a sensitization setting type.
|
||||
---
|
||||
@ -118,15 +67,15 @@ function Public.register(name, setting_type, default, localisation_key)
|
||||
error(format('Trying to register setting for "%s" while it has already been registered.', name), 2)
|
||||
end
|
||||
|
||||
local callback = settings_type[setting_type]
|
||||
if not callback then
|
||||
error(format('Trying to register setting for "%s" with type "%s" while this type does not exist.', name, setting_type), 2)
|
||||
local data_transformation = settings_type[setting_type]
|
||||
if not data_transformation then
|
||||
error(format('Trying to register data_transformation for "%s" with type "%s" while this type does not exist.', name, setting_type), 2)
|
||||
end
|
||||
|
||||
local setting = {
|
||||
type = setting_type,
|
||||
default = default,
|
||||
callback = callback,
|
||||
data_transformation = data_transformation,
|
||||
localised_string = localisation_key and {localisation_key} or name,
|
||||
}
|
||||
|
||||
@ -144,7 +93,7 @@ function Public.validate(name, value)
|
||||
return format('Setting "%s" does not exist.', name)
|
||||
end
|
||||
|
||||
local success, sanitized_value = setting.callback(value)
|
||||
local success, sanitized_value = setting.data_transformation.sanitizer(value)
|
||||
|
||||
if not success then
|
||||
return sanitized_value
|
||||
@ -163,10 +112,10 @@ end
|
||||
function Public.set(player_index, name, value)
|
||||
local setting = settings[name]
|
||||
if not setting then
|
||||
setting = raw_callback_setting
|
||||
setting = missing_setting
|
||||
end
|
||||
|
||||
local success, sanitized_value = setting.callback(value)
|
||||
local success, sanitized_value = setting.data_transformation.sanitizer(value)
|
||||
|
||||
if not success then
|
||||
error(format('Setting "%s" failed: %s', name, sanitized_value), 2)
|
||||
@ -217,6 +166,19 @@ function Public.get(player_index, name)
|
||||
return player_setting
|
||||
end
|
||||
|
||||
---Returns the string representation of a given value based on a setting name.
|
||||
---
|
||||
---@param name string
|
||||
---@param raw_value any
|
||||
function Public.toScalar(name, raw_value)
|
||||
local setting = settings[name]
|
||||
if not setting then
|
||||
setting = missing_setting
|
||||
end
|
||||
|
||||
return setting.data_transformation.toScalar(raw_value)
|
||||
end
|
||||
|
||||
---Returns a table of all settings for a given player in a key => value setup
|
||||
---@param player_index number
|
||||
function Public.all(player_index)
|
||||
|
Loading…
Reference in New Issue
Block a user