mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 07:24:52 +09:00
Add set_destination remote interface to player_sync
A plugin that moves a player calls remote.call("player_sync",
"set_destination", player_name, instance_id) before connect_to_server.
It only records the destination. Every leave clears it, and a leave
that uploads with reason switching_servers adds it to the upload as
destination_instance_id. The README describes it for plugin authors.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
240180d847
commit
18afae4686
3 files changed
+46
No files matched your search
@@ -83,6 +83,24 @@ function player_sync.set_components(data)
|
||||
get_script_data().components = assert(compat.json_to_table(data))
|
||||
end
|
||||
|
||||
-- For plugins that move players to another instance: remote.call("player_sync", "set_destination", player_name,
|
||||
-- instance_id) just before LuaPlayer.connect_to_server, with the destination's Clusterio instance id. It only records
|
||||
-- it; if the player then leaves to switch servers, the upload carries it and the controller sends the player's data
|
||||
-- on to that instance (README, "Sending player data ahead"). A later call replaces it, and every leave clears it.
|
||||
remote.add_interface("player_sync", {
|
||||
set_destination = function(player_name, instance_id)
|
||||
-- Integers only: table_to_json writes inf and nan bare, which the host can't parse, so the upload carrying it
|
||||
-- would fail on every retry and the session would be lost (inf % 1 and nan % 1 are nan, never 0)
|
||||
if type(instance_id) ~= "number" or instance_id % 1 ~= 0 then
|
||||
return
|
||||
end
|
||||
local player_record = get_script_data().players[player_name]
|
||||
if player_record then
|
||||
player_record.destination = instance_id
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- This function is called internally when a player leaves the game to
|
||||
-- serialize the player for upload.
|
||||
function player_sync.serialize_player(player, player_record)
|
||||
@@ -486,6 +504,9 @@ player_sync.events[defines.events.on_pre_player_left_game] = function(event)
|
||||
local script_data = get_script_data()
|
||||
local player = assert(game.get_player(event.player_index))
|
||||
local player_record = script_data.players[player.name]
|
||||
-- Recorded by set_destination. Every leave clears it; only an uploading switching_servers leave sends it on.
|
||||
local destination = player_record.destination
|
||||
player_record.destination = nil
|
||||
|
||||
-- If player has an active download release our acquisition but let the download continue
|
||||
if script_data.active_downloads[player.name] then
|
||||
@@ -506,6 +527,11 @@ player_sync.events[defines.events.on_pre_player_left_game] = function(event)
|
||||
player.print("ERROR: Serializing player data failed: " .. result)
|
||||
return
|
||||
end
|
||||
-- The controller sends the stored data on to that instance while the client reconnects. In the serialized table,
|
||||
-- so a retried upload (check_active_uploads) carries it too.
|
||||
if destination and event.reason == defines.disconnect_reason.switching_servers then
|
||||
result.destination_instance_id = destination
|
||||
end
|
||||
script_data.active_uploads[player.name] = {
|
||||
serialized = result,
|
||||
last_attempt = game.ticks_played,
|
||||
|
||||
Reference in new issue
Block a user