mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-11 23:54:52 +09:00
The toolbar order, favourites, and open panels were saved into exp_legacy's PlayerData, which was never synced, and the file doing so was no longer loaded. When a player leaves, the lua side now sends Gui.toolbar.get_state as json compressed with helpers.encode_string, and the controller stores the string on the player record. When the player joins again the instance plugin sends the stored string over rcon to exp_scenario.player_settings.receive_toolbar, which decodes it and calls Gui.toolbar.set_state. exp_gui builds the toolbar in on_player_joined_game, so it exists by the time the rcon arrives. A string which does not decode, or a state naming buttons which no longer exist, is logged and ignored rather than raising in the game. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.4 KiB
Lua
69 lines
2.4 KiB
Lua
--[[-- Control - Player Settings
|
|
Sends settings of players to the controller, which keeps them between servers
|
|
|
|
The toolbar is sent compressed when a player leaves, the instance plugin
|
|
calls receive_toolbar with it when they join again
|
|
]]
|
|
|
|
local Gui = require("modules/exp_gui")
|
|
local clusterio_api = require("modules/clusterio/api")
|
|
|
|
--- @param event EventData.on_player_joined_game | EventData.on_player_locale_changed
|
|
local function send_locale(event)
|
|
local player = assert(game.get_player(event.player_index))
|
|
clusterio_api.send_json("exp_scenario:locale", { player_name = player.name, locale = player.locale })
|
|
end
|
|
|
|
--- @param event EventData.on_player_left_game
|
|
local function send_toolbar(event)
|
|
local player = assert(game.get_player(event.player_index))
|
|
local success, state = pcall(Gui.toolbar.get_state, player)
|
|
if not success then
|
|
log("[WARNING] Could not read the toolbar of " .. player.name .. ": " .. tostring(state))
|
|
return
|
|
end
|
|
local toolbar = helpers.encode_string(helpers.table_to_json(state))
|
|
clusterio_api.send_json("exp_scenario:toolbar", { player_name = player.name, toolbar = toolbar })
|
|
end
|
|
|
|
--- @param toolbar string
|
|
--- @return Gui.ToolbarState?
|
|
local function decode_toolbar(toolbar)
|
|
local json = helpers.decode_string(toolbar)
|
|
local state = json and helpers.json_to_table(json)
|
|
if type(state) == "table" and type(state.order) == "table" and type(state.open) == "table"
|
|
and type(state.visible) == "boolean" then
|
|
return state --[[@as Gui.ToolbarState]]
|
|
end
|
|
end
|
|
|
|
--- Restore the toolbar of a player, called over rcon by the instance plugin
|
|
--- @param player_name string
|
|
--- @param toolbar string From send_toolbar
|
|
local function receive_toolbar(player_name, toolbar)
|
|
local player = game.get_player(player_name)
|
|
if not player or not player.connected then
|
|
return
|
|
end
|
|
|
|
-- Stored states can name buttons which no longer exist
|
|
local success, err = pcall(function()
|
|
local state = assert(decode_toolbar(toolbar), "invalid toolbar state")
|
|
Gui.toolbar.set_state(player, state)
|
|
end)
|
|
if not success then
|
|
log("[WARNING] Could not restore the toolbar of " .. player_name .. ": " .. tostring(err))
|
|
end
|
|
end
|
|
|
|
local e = defines.events
|
|
|
|
return {
|
|
events = {
|
|
[e.on_player_joined_game] = send_locale,
|
|
[e.on_player_locale_changed] = send_locale,
|
|
[e.on_player_left_game] = send_toolbar,
|
|
},
|
|
receive_toolbar = receive_toolbar,
|
|
}
|