diff --git a/config.lua b/config.lua index 8141d7d1..95398b29 100644 --- a/config.lua +++ b/config.lua @@ -365,10 +365,6 @@ global.config = { -- enables the redmew settings GUI redmew_settings = { enabled = true - }, - -- enables syncing settings to the server - redmew_settings_sync = { - enabled = true } } diff --git a/control.lua b/control.lua index 11b81a03..8011be44 100644 --- a/control.lua +++ b/control.lua @@ -26,6 +26,7 @@ require 'features.server_commands' -- If missing, will cause other feature modules to fail require 'features.player_create' require 'features.rank_system' +require 'features.redmew_settings_sync' -- Feature modules -- Each can be disabled safely @@ -95,9 +96,6 @@ end if config.player_quick_bars.enabled then require 'features.player_quick_bars' end -if config.redmew_settings_sync.enabled then - require 'features.redmew_settings_sync' -end -- GUIs -- The order determines the order they appear from left to right. diff --git a/features/gui/redmew_settings.lua b/features/gui/redmew_settings.lua index 0ce18c13..dcccccbc 100644 --- a/features/gui/redmew_settings.lua +++ b/features/gui/redmew_settings.lua @@ -1,11 +1,9 @@ local Gui = require 'utils.gui' -local Token = require 'utils.token' local Event = require 'utils.event' -local Server = require 'features.server' local Toast = require 'features.gui.toast' local Settings = require 'utils.redmew_settings' +local SettingsSync = require 'features.redmew_settings_sync' local Color = require 'resources.color_presets' - local pairs = pairs local main_button_name = Gui.uid_name() @@ -14,31 +12,6 @@ local main_frame_name = Gui.uid_name() local Public = {} -local on_player_settings_get = Token.register(function (data) - local player = game.get_player(data.key) - - if not player or not player.valid then - return - end - - local button = player.gui.top[main_button_name] - button.enabled = true - button.tooltip = {'redmew_settings_gui.tooltip'} - - if data.cancelled then - return - end - - local settings = data.value - - if settings ~= nil then - local player_index = player.index - for key, value in pairs(settings) do - Settings.set(player_index, key, value) - end - end -end) - local function player_created(event) local player = game.get_player(event.player_index) if not player or not player.valid then @@ -69,8 +42,6 @@ local function player_joined(event) local button = player.gui.top[main_button_name] button.tooltip = {'redmew_settings_gui.tooltip_loading'} button.enabled = false - - Server.try_get_data_timeout('player_settings', player.name, on_player_settings_get, 30) end local function get_element_value(element) @@ -208,7 +179,7 @@ local function save_changes(event) return end - for name, value in pairs (values) do + for name, value in pairs(values) do Settings.set(player_index, name, value) end @@ -221,6 +192,12 @@ local function save_changes(event) end end +local function synced_from_server(event) + local button = event.player.gui.top[main_button_name] + button.tooltip = {'redmew_settings_gui.tooltip'} + button.enabled = true +end + Gui.on_custom_close(main_frame_name, function(event) Gui.destroy(event.element) end) @@ -231,5 +208,6 @@ Gui.on_click(main_button_name, toggle) Gui.on_click(save_changes_button_name, save_changes) Event.add(defines.events.on_player_created, player_created) Event.add(defines.events.on_player_joined_game, player_joined) +Event.add(SettingsSync.events.on_synced_from_server, synced_from_server) return Public diff --git a/features/redmew_settings_sync.lua b/features/redmew_settings_sync.lua index 6d1d54dc..6160cfe7 100644 --- a/features/redmew_settings_sync.lua +++ b/features/redmew_settings_sync.lua @@ -5,11 +5,34 @@ local Schedule = require 'utils.task' local Server = require 'features.server' local Settings = require 'utils.redmew_settings' local set_timeout_in_ticks = Schedule.set_timeout_in_ticks +local pairs = pairs +local raise_event = script.raise_event local Public = {} +Public.events = { + --- Triggered when the settings are synced back from the server + -- Event { + -- player = player + -- } + on_synced_to_server = Event.generate_event_name('on_synced_to_server'), + + --- Triggered when the settings are synced back from the server + --- keeps track of whether or not it's cancelled + -- Event { + -- player = player + -- cancelled = cancelled + -- } + on_synced_from_server = Event.generate_event_name('on_synced_from_server'), +} + + local memory = { + -- when already scheduled, no new schedules have to be added sync_scheduled = false, + + -- when locked it won't schedule anything to prevent recursion syncing back to server + locked = false, } local do_sync_settings_to_server -- token @@ -17,10 +40,6 @@ local do_sync_settings_to_server -- token Global.register(memory, function (tbl) memory = tbl end) local function schedule_sync_to_server(player_index) - if memory.sync_scheduled then - return - end - set_timeout_in_ticks(1, do_sync_settings_to_server, { player_index = player_index }) @@ -39,11 +58,14 @@ do_sync_settings_to_server = Token.register(function(params) -- mark it as updated memory.sync_scheduled = false + + raise_event(Public.events.on_synced_to_server, { + player = player + }) end) local function setting_set(event) - if memory.sync_scheduled then - -- no need to determine if something should be set, already scheduled + if memory.locked or memory.sync_scheduled then return end @@ -56,6 +78,49 @@ local function setting_set(event) schedule_sync_to_server(setting.player_index) end +local on_player_settings_get = Token.register(function (data) + local player = game.get_player(data.key) + if not player or not player.valid then + return + end + + if data.cancelled then + raise_event(Public.events.on_synced_from_server, { + player = player, + cancelled = true + }) + return + end + + local settings = data.value + + if settings ~= nil then + -- temporarily lock the sync so it won't sync from server to client to server + -- as this would cause recursion + memory.locked = true + local player_index = player.index + for key, value in pairs(settings) do + Settings.set(player_index, key, value) + end + memory.locked = false + end + + raise_event(Public.events.on_synced_from_server, { + player = player, + cancelled = false + }) +end) + +local function player_joined(event) + local player = game.get_player(event.player_index) + if not player or not player.valid then + return + end + + Server.try_get_data_timeout('player_settings', player.name, on_player_settings_get, 30) +end + Event.add(Settings.events.on_setting_set, setting_set); +Event.add(defines.events.on_player_joined_game, player_joined) return Public