diff --git a/plugins/player_sync/module/player_sync.lua b/plugins/player_sync/module/player_sync.lua index cfbe533e..7d5cfcbb 100644 --- a/plugins/player_sync/module/player_sync.lua +++ b/plugins/player_sync/module/player_sync.lua @@ -334,6 +334,19 @@ function player_sync.check_players_in_cutscene() end end +-- Whether a join should take the stored data: there is some, and this save hasn't synced the player in that epoch at that +-- generation or newer with every component synced here now. A player without a record here has nothing to keep. +local function download_needed(player_record, acquire_response, script_data) + return acquire_response.has_data + and ( + not player_record + or not player_record.sync + or (player_record.epoch or 0) ~= (acquire_response.epoch or 0) + or acquire_response.generation > player_record.generation + or serialize.newly_synced(player_record.components, script_data.components) + ) +end + function player_sync.sync_player(acquire_response) local player = assert(game.get_player(acquire_response.player_name)) @@ -356,14 +369,15 @@ function player_sync.sync_player(acquire_response) -- now. The generation alone isn't enough: a controller that crashed before saving it restarts at the last saved -- generation, and another instance's upload can then reuse the same number with other data. Otherwise the copy -- goes, and the join carries on as if it had never come: today's download or failure dialog, never the restart - -- path below, which only sees a different generation. + -- path below, which only sees a different generation. A copy this save doesn't need goes too, keeping the local + -- data: an upload from an instance with older data can take the generation this save already holds. for _, downloads in ipairs({ script_data.finished_downloads, script_data.active_downloads }) do local record = downloads[acquire_response.player_name] - if record and record.prefetch and not ( + if record and record.prefetch and (not ( acquire_response.status == "acquired" and record.generation == acquire_response.generation and record.token == acquire_response.token and serialize.same_components(record.components, script_data.components) - ) then + ) or not download_needed(script_data.players[acquire_response.player_name], acquire_response, script_data)) then downloads[acquire_response.player_name] = nil end end @@ -458,15 +472,7 @@ function player_sync.sync_player(acquire_response) end local stale = (player_record.epoch or 0) ~= epoch - if - acquire_response.has_data - and ( - not player_record.sync - or stale - or acquire_response.generation > player_record.generation - or serialize.newly_synced(player_record.components, script_data.components) - ) - then + if download_needed(player_record, acquire_response, script_data) then player_sync.initiate_inventory_download(player, player_record, acquire_response.generation, epoch) else