From c2234505f303f9cd72c0153c7cfc5cdb4405e8cb Mon Sep 17 00:00:00 2001 From: Matthew Date: Wed, 2 Jan 2019 08:42:18 -0500 Subject: [PATCH] Implement server-side color saving (#566) * Implement server-side color saving * Add set_and_return to core utils --- config.lua | 1 + features/donator_messages.lua | 16 ++++++- features/player_colors.lua | 87 +++++++++++++++++++++++++++++++---- features/player_create.lua | 6 +++ utils/command.lua | 17 +++++-- utils/core.lua | 14 ++++++ 6 files changed, 128 insertions(+), 13 deletions(-) diff --git a/config.lua b/config.lua index eaf3af3f..8b0e85c2 100644 --- a/config.lua +++ b/config.lua @@ -185,6 +185,7 @@ global.config = { free_item_logging = { enabled = true, }, + -- adds ability to save and restore player colors player_colors = { enabled = true, }, diff --git a/features/donator_messages.lua b/features/donator_messages.lua index 42e9bf43..34915b28 100644 --- a/features/donator_messages.lua +++ b/features/donator_messages.lua @@ -1,6 +1,19 @@ local Game = require 'utils.game' local Event = require 'utils.event' local UserGroups = require 'features.user_groups' +local Task = require 'utils.schedule' +local Token = require 'utils.token' + +local print_after_timeout = + Token.register( + function(data) + local player = data.player + if not player.valid then + return + end + game.print(data.message, player.chat_color) + end +) local function player_joined(event) local player = Game.get_player_by_index(event.player_index) @@ -13,7 +26,8 @@ local function player_joined(event) return end - game.print(table.concat({'*** ', message, ' ***'}), player.chat_color) + message = table.concat({'*** ', message, ' ***'}) + Task.set_timeout_in_ticks(60, print_after_timeout, {player = player, message = message}) end Event.add(defines.events.on_player_joined_game, player_joined) diff --git a/features/player_colors.lua b/features/player_colors.lua index b42ea52b..9e332080 100644 --- a/features/player_colors.lua +++ b/features/player_colors.lua @@ -1,21 +1,90 @@ local Event = require 'utils.event' local Game = require 'utils.game' -local player_colors = require 'resources.player_colors' +local Command = require 'utils.command' +local Server = require 'features.server' +local Token = require 'utils.token' +local Utils = require 'utils.core' + +local serialize = serpent.line + +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 +) + +--- 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 + +--- Saves the player's color to the server +local function save_color(player_name, value) + Server.set_data('colors', player_name, value) +end + +Command.add( + 'color-redmew', + { + description = 'Set will save your current color for future maps. Reset will erase your saved color. Random will give you a random color.', + arguments = {'set-reset-random'}, + admin_only = false, + regular_only = true, + allowed_by_server = false, + allowed_by_player = true + }, + function(args, player) + local player_name = player.name + if args['set-reset-random'] == 'set' then + local data = { + color = player.color, + chat_color = player.chat_color, + } + save_color(player_name, data) + player.print('Your color has been saved. Any time you join a redmew server your color will automatically be set.') + elseif args['set-reset-random'] == 'reset' then + save_color(player_name, nil) + player.print('Your saved color (if you had one) has been removed.') + elseif args['set-reset-random'] == 'random' then + local color_data = Public.set_random_color(player) + player.print('Your color has been changed to: ' .. serialize(color_data)) + else + player.print('Only set, reset, and random are accepted arguments') + end + end +) Event.add( - defines.events.on_player_created, + defines.events.on_player_joined_game, function(event) local player = Game.get_player_by_index(event.player_index) if not player or not player.valid then return end - local color_data = player_colors[player.name] - if not color_data then - return - end - - player.color = color_data.color - player.chat_color = color_data.chat_color or color_data.color + Public.recall_player_color(player) end ) + +return Public diff --git a/features/player_create.lua b/features/player_create.lua index 2ac616ea..4056f329 100644 --- a/features/player_create.lua +++ b/features/player_create.lua @@ -3,6 +3,8 @@ local Game = require 'utils.game' local Event = require 'utils.event' local Global = require 'utils.global' local Info = require 'features.gui.info' +local UserGroups = require 'features.user_groups' + local get_random_weighted = table.get_random_weighted local memory = { @@ -54,6 +56,10 @@ local function player_created(event) end end + if _DEBUG and player.admin then + UserGroups.add_regular(player.name) + end + if _CHEATS then player.cheat_mode = true local cheats = config.cheats diff --git a/utils/command.lua b/utils/command.lua index 915f6e7b..3a3e68e9 100644 --- a/utils/command.lua +++ b/utils/command.lua @@ -1,4 +1,5 @@ require 'utils.table' +local UserGroups = require 'features.user_groups' local insert = table.insert local format = string.format @@ -12,6 +13,7 @@ local option_names = { ['description'] = 'A description of the command', ['arguments'] = 'A table of arguments, example: {"foo", "bar"} would map the first 2 arguments to foo and bar', ['default_values'] = 'A default value for a given argument when omitted, example: {bar = false}', + ['regular_only'] = 'Set this to true if only regulars may execute this command', ['admin_only'] = 'Set this to true if only admins may execute this command', ['debug_only'] = 'Set this to true if it should only be registered when _DEBUG is true', ['allowed_by_server'] = 'Set to true if the server (host) may execute this command', @@ -42,10 +44,11 @@ end --- description = 'A description of the command', --- arguments = {'foo', 'bar'}, -- maps arguments to these names in the given sequence --- default_values = {bar = false}, -- gives a default value to 'bar' when omitted +--- regular_only = true, -- defaults to false --- admin_only = true, -- defaults to false --- debug_only = false, -- only registers it if _DEBUG is set to true when false ---- allowed_by_server = false -- lets the server execute this, defaults to false ---- allowed_by_player = true -- lets players execute this, defaults to true +--- allowed_by_server = false, -- lets the server execute this, defaults to false +--- allowed_by_player = true, -- lets players execute this, defaults to true --- log_command = true, -- defaults to false unless admin only, then always true --- capture_excess_arguments = true, defaults to false, captures excess arguments in the last argument, useful for sentences ---} @@ -62,6 +65,7 @@ function Command.add(command_name, options, callback) local description = options.description or '[Undocumented command]' local arguments = options.arguments or {} local default_values = options.default_values or {} + local regular_only = options.regular_only or false local admin_only = options.admin_only or false local debug_only = options.debug_only or false local capture_excess_arguments = options.capture_excess_arguments or false @@ -107,6 +111,8 @@ function Command.add(command_name, options, callback) extra = ' (Server Only)' elseif allowed_by_player and admin_only then extra = ' (Admin Only)' + elseif allowed_by_player and regular_only then + extra = ' (Regulars Only)' end commands.add_command(command_name, argument_list .. description .. extra, function (command) @@ -129,7 +135,12 @@ function Command.add(command_name, options, callback) end if admin_only and not player.admin then - print(format("The command '%s' requires an admin to be be executed", command_name)) + print(format("The command '%s' requires admin status to be be executed.", command_name)) + return + end + + if regular_only and not UserGroups.is_regular(player_name) then + print(format("The command '%s' is not available to guests.", command_name)) return end end diff --git a/utils/core.lua b/utils/core.lua index f9e00e3c..f9f7dea9 100644 --- a/utils/core.lua +++ b/utils/core.lua @@ -177,6 +177,20 @@ function Module.random_RGB() return {r = random(0, 255), g = random(0, 255), b = random(0, 255)} end +--- Sets a table element to value while also returning value. +-- @param tbl table to change the element of +-- @param key string +-- @param value nil|boolean|number|string|table to set the element to +-- @return value +function Module.set_and_return(tbl, key, value) + tbl[key] = value + return value +end + +function Module.random_RGB() + return {r = random(0, 255), g = random(0, 255), b = random(0, 255)} +end + -- add utility functions that exist in base factorio/util require 'util'