1
0
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:
Lynn 2019-05-28 21:04:30 +02:00
parent a5703fa2bb
commit 1cd19c69e7
9 changed files with 274 additions and 159 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
View 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
},
}

View File

@ -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'
}

View File

@ -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)