Fix invincible ghost character creation on first join

Inventory sync will now wait intil the player has a character.
This means sync won't happen ex during respawn animations
or freeplay intro cutscenes.
This commit is contained in:
Daniel committed 2021-07-12 23:28:16 +02:00
1 parent 4027a4f310
commit 1a1b4fb0d2
3 files changed
+37 -15

No files matched your search

@@ -2,7 +2,8 @@
When a player leaves the game, serialize their inventory and upload it to the master.
When a player joins the game, send a request to the master server for the players inventory.
When a player joins the game, wait until they have a character, then send a request to
the master server for the players inventory.
When the master sends an inventory, parse it and give it to the player.
If the master responds that its a new player, show a welcome message.
@@ -31,6 +32,7 @@ inventory_sync.events[clusterio_api.events.on_server_startup] = function(event)
download_start_tick = {},
saved_crafting_queue = {},
download_cache = {},
players_waiting_for_download = {},
}
end
end
@@ -47,8 +49,15 @@ end
-- Download inventory from master
inventory_sync.events[defines.events.on_player_joined_game] = function(event)
local playerIndex = event.player_index
inventory_sync.initiate_inventory_download(playerIndex)
-- Add player to download queue. Inventory won't be downloaded before the player has a character
global.inventory_sync.players_waiting_for_download[game.get_player(event.player_index).name] = true
-- Don't wait for on_nth_tick if not required
inventory_sync.check_player_character_before_download()
end
inventory_sync.on_nth_tick = {}
inventory_sync.on_nth_tick[33] = function(event)
inventory_sync.check_player_character_before_download()
end
-- Upload inventory when a player leaves the game. Triggers on restart after crash if player was online during crash.
@@ -60,15 +69,30 @@ inventory_sync.events[defines.events.on_pre_player_left_game] = function(event)
end
local player_index = event.player_index
inventory_sync.upload_inventory(player_index)
global.inventory_sync.download_cache[player_index] = "" -- Clear cache to avoid leaking memory to people quitting during download
local player = game.get_player(player_index)
-- Avoid uploading for unsynced players (due to not having a character, ex during freeplay cutscene)
if global.inventory_sync.players_waiting_for_download[player.name] == nil then
inventory_sync.upload_inventory(player_index)
global.inventory_sync.download_cache[player_index] = "" -- Clear cache to avoid leaking memory to people quitting during download
end
global.inventory_sync.players_waiting_for_download[player.name] = nil
end
function inventory_sync.initiate_inventory_download(playerIndex)
local player = game.get_player(playerIndex)
function inventory_sync.check_player_character_before_download()
-- Check if players waiting for download have a valid character
for name in pairs(global.inventory_sync.players_waiting_for_download) do
local player = game.get_player(name)
if player.character ~= nil then
global.inventory_sync.players_waiting_for_download[name] = nil
inventory_sync.initiate_inventory_download(player)
end
end
end
function inventory_sync.initiate_inventory_download(player)
player.print("Initiating inventory download...")
global.inventory_sync.download_start_tick[player.name] = game.tick
global.inventory_sync.download_cache[playerIndex] = ""
global.inventory_sync.download_cache[player.name] = ""
clusterio_api.send_json("inventory_sync_download", {
player_name = player.name
})
@@ -2,14 +2,16 @@ local clusterio_api = require("modules/clusterio/api")
local serialize = require("modules/clusterio/serialize")
local inventories = require("modules/inventory_sync/define_player_inventories")
local save_crafts = require("modules/inventory_sync/save_crafts")
local ensure_character = require("modules/inventory_sync/ensure_character")
local player_stat_keys = require("modules/inventory_sync/define_player_stat_keys")
function upload_inventory(playerIndex)
local player = game.get_player(playerIndex)
-- Force player to have a character to prevent access errors
ensure_character(player)
if player.character == nil then
-- Panic!
log("ERROR: Player "..player.name.." quit without a character. Inventory not uploaded")
return false
end
local serialized_player = {
name = player.name,
@@ -1,13 +1,9 @@
local ensure_character = require("modules/inventory_sync/ensure_character")
local function welcome_new_player(player_name)
local player = game.get_player(player_name)
if player == nil then return end
player.print("Welcome to the server!")
player.print("Your inventory will be automatically synchronized between servers in this cluster.")
player.print("To improve sync performance, please avoid storing blueprints in your inventory.")
ensure_character(player)
end
return welcome_new_player