mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
The scenario no longer sends its components with the download request. The instance strips the download by its own config and sends the components it used with the first chunk. If they differ from the ones the scenario started the download with, because the config changed in between, the scenario restarts the download. A pending download is now marked with sync_in_progress instead of clearing dirty while spectating, and it is set for every download rather than only when inventories are synced. Uploads are skipped while it is set, so a player who leaves during a download with inventories off no longer uploads their stale state. SyncComponent names the components in the Lua annotations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
154 lines
4.5 KiB
Lua
154 lines
4.5 KiB
Lua
local ensure_character = require("modules/player_sync/ensure_character")
|
|
local get_script_data = require("modules/player_sync/get_script_data")
|
|
|
|
local dialog_failed_download = {}
|
|
|
|
--- @param player LuaPlayer
|
|
--- @param acquire_response table
|
|
function dialog_failed_download.create(player, acquire_response)
|
|
if player.gui.screen.dialog_failed_download then
|
|
player.gui.screen.dialog_failed_download.destroy()
|
|
end
|
|
|
|
local frame = player.gui.screen.add {
|
|
name = "dialog_failed_download",
|
|
type = "frame",
|
|
direction = "vertical",
|
|
}
|
|
|
|
local titlebar = frame.add {
|
|
type = "flow",
|
|
}
|
|
titlebar.drag_target = frame
|
|
|
|
local title_caption = "Player sync download failed"
|
|
if acquire_response.status == "busy" then
|
|
title_caption = "Inventory is in use on " .. acquire_response.message
|
|
end
|
|
|
|
local title = titlebar.add {
|
|
type = "label",
|
|
style = "frame_title",
|
|
caption = title_caption,
|
|
}
|
|
title.drag_target = frame
|
|
|
|
local filler = titlebar.add {
|
|
type = "empty-widget",
|
|
style = "draggable_space_header",
|
|
}
|
|
filler.style.horizontally_stretchable = true
|
|
filler.style.right_margin = 4
|
|
filler.style.height = 24
|
|
filler.drag_target = frame
|
|
|
|
local content = frame.add {
|
|
name = "player_sync_failed_download_content",
|
|
type = "frame",
|
|
direction = "vertical",
|
|
style = "inside_shallow_frame_with_padding",
|
|
}
|
|
content.style.width = 400
|
|
|
|
local reason
|
|
if acquire_response.status == "timeout" then
|
|
reason = "Timed out fetching inventory from the controller."
|
|
|
|
elseif acquire_response.status == "busy" then
|
|
reason =
|
|
"Your synced inventory is in in use on " .. acquire_response.message .. ". " ..
|
|
"If you are logged in there you will have to log out there before you can sync the inventory here. " ..
|
|
"If you just logged out from there it might take some time before the inventory is available."
|
|
|
|
elseif acquire_response.status == "error" then
|
|
reason = "Error fetching inventory from the controller: " .. acquire_response.message .. "."
|
|
|
|
else
|
|
reason = "Unknown status " .. acquire_response.status .. " fetching inventory from the controller."
|
|
end
|
|
|
|
local p1 = content.add {
|
|
type = "label",
|
|
caption = reason
|
|
}
|
|
p1.style.single_line = false
|
|
|
|
local p2 = content.add {
|
|
type = "label",
|
|
caption =
|
|
"You may choose to retry fetching the inventory or play with a temporary inventory which will be merged " ..
|
|
"with your synced inventory the next time you join this server."
|
|
,
|
|
}
|
|
p2.style.single_line = false
|
|
p2.style.top_margin = 8
|
|
|
|
local dialog_row = frame.add {
|
|
type = "flow",
|
|
}
|
|
dialog_row.style.top_margin = 8
|
|
dialog_row.drag_target = frame
|
|
|
|
local abort = dialog_row.add {
|
|
name = "player_sync_failed_download_abort",
|
|
type = "button",
|
|
style = "back_button",
|
|
caption = "Use temporary inventory",
|
|
tooltip = "Items you obtain here will be merged with your synced inventory the next time you join this server.",
|
|
}
|
|
|
|
local dialog_filler = dialog_row.add {
|
|
type = "empty-widget",
|
|
style = "draggable_space_header",
|
|
}
|
|
dialog_filler.style.horizontally_stretchable = true
|
|
dialog_filler.style.right_margin = 4
|
|
dialog_filler.style.height = 28
|
|
dialog_filler.drag_target = frame
|
|
|
|
local retry = dialog_row.add {
|
|
name = "player_sync_failed_download_retry",
|
|
type = "button",
|
|
style = "forward_button",
|
|
caption = "Retry",
|
|
}
|
|
|
|
frame.force_auto_center()
|
|
player.opened = frame
|
|
end
|
|
|
|
dialog_failed_download.events = {
|
|
[defines.events.on_gui_click] = function(event)
|
|
if not event.element.valid then
|
|
return
|
|
end
|
|
|
|
if event.element.name == "player_sync_failed_download_abort" then
|
|
-- Give the player a character and let them play with that
|
|
local player = assert(game.get_player(event.player_index))
|
|
ensure_character(player)
|
|
local player_sync = get_script_data()
|
|
player.gui.screen.dialog_failed_download.destroy()
|
|
player_sync.players[player.name].dirty = true
|
|
player_sync.players[player.name].sync = false
|
|
player_sync.players[player.name].sync_in_progress = false
|
|
player_sync.players[player.name].local_controller = nil
|
|
|
|
elseif event.element.name == "player_sync_failed_download_retry" then
|
|
-- Retry acquiring the player from the controller
|
|
local player = assert(game.get_player(event.player_index))
|
|
player_sync.acquire(player)
|
|
player.gui.screen.dialog_failed_download.destroy()
|
|
end
|
|
end,
|
|
|
|
[defines.events.on_player_left_game] = function(event)
|
|
local player = assert(game.get_player(event.player_index))
|
|
if player.gui.screen.dialog_failed_download then
|
|
player.gui.screen.dialog_failed_download.destroy()
|
|
end
|
|
end,
|
|
}
|
|
|
|
return dialog_failed_download
|