Offer the player a temporary inventory while waiting for master

This commit is contained in:
Daniel committed 2021-07-29 23:55:48 +02:00
1 parent 29917fb85a
commit e63f1246da
8 files changed
+172 -2

No files matched your search

@@ -14,7 +14,10 @@ local clusterio_api = require("modules/clusterio/api")
local add_commands = require("modules/inventory_sync/commands")
local upload_inventory = require("modules/inventory_sync/upload_inventory")
local download_inventory = require("modules/inventory_sync/download_inventory")
local welcome_new_player = require("modules/inventory_sync/welcome_new_player")
local welcome_new_player = require("modules/inventory_sync/gui/welcome_new_player")
local handle_gui_events = require("modules/inventory_sync/gui/handle_gui_events")
local dialog_failed_download = require("modules/inventory_sync/gui/dialog_failed_download")
local clean_dirty_inventory = require("modules/inventory_sync/script/clean_dirty_inventory")
inventory_sync = {}
inventory_sync.welcome_new_player = welcome_new_player
@@ -33,6 +36,7 @@ inventory_sync.events[clusterio_api.events.on_server_startup] = function(event)
saved_crafting_queue = {},
download_cache = {},
players_waiting_for_download = {},
players = {},
}
end
end
@@ -45,8 +49,20 @@ inventory_sync.events[defines.events.on_player_removed] = function(event)
global.inventory_sync.download_start_tick[player.name] = nil
-- Remove stored crafting queue
global.inventory_sync.saved_crafting_queue[player.name] = nil
-- Remove other player data
global.inventory_sync.players[player.name] = nil
end
inventory_sync.events[defines.events.on_player_created] = function(event)
local player = game.get_player(event.player_index)
global.inventory_sync.players[player.name] = {
dirty_inventory = false, -- Player has a temporary non-synced inventory that should be persisted
sync_start_tick = 0, -- To track download failure timeout
}
end
inventory_sync.events[defines.events.on_gui_click] = handle_gui_events
-- Download inventory from master
inventory_sync.events[defines.events.on_player_joined_game] = function(event)
-- Add player to download queue. Inventory won't be downloaded before the player has a character
@@ -57,7 +73,11 @@ end
inventory_sync.on_nth_tick = {}
inventory_sync.on_nth_tick[33] = function(event)
-- Periodically check if player has a character to download to. False in cutscenes.
inventory_sync.check_player_character_before_download()
-- Check if download has failed and we should create a dirty inventory
inventory_sync.check_inventory_download_failed()
end
-- Upload inventory when a player leaves the game. Triggers on restart after crash if player was online during crash.
@@ -97,12 +117,36 @@ function inventory_sync.initiate_inventory_download(player)
player_name = player.name
})
-- Handle dirty inventories. A dirty inventory is a temporary inventory that has been used while waiting
-- for sync. It should be taken care of in some way, like putting it in a corpse or a chest.
if global.inventory_sync.players[player.name].dirty_inventory then
clean_dirty_inventory(player)
end
-- Set player into ghost mode for duration of download
local character = player.character
player.set_controller {
type = defines.controllers.ghost,
}
if character ~= nil then character.destroy() end
-- Start timeout for detecting master connection failure
global.inventory_sync.players[player.name].sync_start_tick = game.tick
end
function inventory_sync.check_inventory_download_failed()
-- Used for letting the master report the inventory download failing, like when the master is offline or an
-- error occurs somewhere in the server code. The player will be returned to a playable state.
for name, data in pairs(global.inventory_sync.players) do
if data.sync_start_tick ~= 0 and data.sync_start_tick <= game.tick - 600 then
-- Stop refreshing timer
data.sync_start_tick = 0
local player = game.get_player(name)
player.print("Inventory download failed due to master connection")
-- Show GUI with option to retry or abort download
dialog_failed_download(player)
end
end
end
return inventory_sync