Files
factorio-clusterio/plugins/player_sync/module/download_inventory.lua
T
bbassieandClaude Opus 5.5 0e559cf000 Allow inventory sync components to be turned off per instance
Adds an inventory_sync.sync_<component> instance config field for the
controller, force, appearance, inventories, logistics, quick bar,
settings and recipe notifications. All default to on, which keeps the
current behaviour.

A component which is off on an instance is left alone there and its
fields are not stored from that instance. The controller merges each
upload with the stored data using the uploading instance's config, the
instance strips the fields from downloads before sending them over RCON,
and the scenario is told the enabled set on start and when it changes so
it can skip serializing them and skip the steps which replace the
character.

The controller is only synced together with the inventories, as switching
controller can destroy the character holding them. Without the controller
synced the player gets back the controller they had on the instance, only
character inventories move between instances, and a player without a
character keeps their inventory.

Closes #968

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:25:06 +00:00

82 lines
2.6 KiB
Lua

local progress_dialog = require("modules/player_sync/gui/progress_dialog")
local ensure_character = require("modules/player_sync/ensure_character")
local restore_position = require("modules/player_sync/restore_position")
local get_script_data = require("modules/player_sync/get_script_data")
local serialize = require("modules/player_sync/serialize")
local function download_inventory(player_name, data, number, total)
local player = game.get_player(player_name)
if player == nil then
rcon.print("Player " .. player_name .. " does not exist")
return
end
local script_data = get_script_data()
local record = script_data.active_downloads[player_name]
if record == nil then
rcon.print("No active download is in progress for " .. player_name)
return
end
local player_record = script_data.players[player_name]
if record.restart then
rcon.print("Restarting outdated download")
player_sync.initiate_inventory_download(player, player_record, record.generation)
return
end
if total == 0 then
-- Download was requested but the player had no data stored.
log("ERROR: Player sync failed, got empty player data for " .. player.name .. " from the controller")
player.print("ERROR: Player sync failed, got empty player data from the controller")
progress_dialog.remove(player)
-- Give the player a character and pretend that's the synced player data
if serialize.syncs(script_data.components, "inventories") then
ensure_character(player)
end
player_record.local_controller = nil
-- Restore player position and driving state
restore_position(player, record)
script_data.active_downloads[player_name] = nil
player_record.dirty = player.connected
player_record.sync = true
player_record.generation = record.generation
return
end
record.data = record.data .. data
-- Show progress in console
-- player.print("Downloaded "..(number + 1).."/"..total.." parts")
if number ~= total then
-- Show progress in GUI
progress_dialog.display(player, number, total)
-- Update activity to indicate this session is still going
record.last_active = game.ticks_played
return
end
-- Download is complete
progress_dialog.remove(player)
-- Remove download session and store finished download
script_data.active_downloads[player_name] = nil
script_data.finished_downloads[player_name] = record
local ticks = game.ticks_played - record.started
player.print("Imported player data in " .. ticks .. " ticks")
log("Imported player data for " .. player_name .. " in " .. ticks .. " ticks")
if player.connected then
player_sync.finish_download(player, record)
end
end
return download_inventory