Apply recipe notification deltas directly in Lua

Review feedback: the download field now always carries the delta and the deserializer applies it against the current state instead of rebuilding the full list first. The previous failed recipe names are passed in so they survive the round trip. The version check moved to the call site.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Fable 5.1 committed 2026-09-11 19:26:38 +00:00
1 parent 1272c0e8e4
commit bb36af08fe
5 files changed
+69 -109

No files matched your search

@@ -17,6 +17,7 @@ local progress_dialog = require("modules/inventory_sync/gui/progress_dialog")
local dialog_failed_download = require("modules/inventory_sync/gui/dialog_failed_download")
local v2_remote_controller = compat.version_ge("2.0.0")
local recipe_notifications_api = compat.version_ge("2.0.67")
-- Returns true if the player is currently in a cutscene
local function is_in_cutscene(player)
@@ -111,14 +112,9 @@ function inventory_sync.deserialize_player(player, finished_record)
-- Deserialize downloaded player data
local serialized_player = compat.json_to_table(finished_record.data)
assert(type(serialized_player) == "table", "wrong type for serialized_player")
if serialized_player.recipe_notifications_delta then
serialized_player.recipe_notifications = serialize.apply_crafting_notification_delta(
assert(finished_record.recipe_notifications, "recipe notification delta without snapshot"),
serialized_player.recipe_notifications_delta
)
serialized_player.recipe_notifications_delta = nil
end
script_data.failed_deserialization[player.name] = serialize.deserialize_player(player, serialized_player)
script_data.failed_deserialization[player.name] = serialize.deserialize_player(
player, serialized_player, script_data.failed_deserialization[player.name]
)
-- Restore player position and driving state
restore_position(player, finished_record)
@@ -449,13 +445,17 @@ function inventory_sync.initiate_inventory_download(player, player_record, gener
script_data.active_downloads[player.name] = record
-- The plugin only sends back what differs from the current notification state
record.recipe_notifications = serialize.crafting_notification_snapshot(
player, script_data.failed_deserialization[player.name]
)
local recipe_notifications
if recipe_notifications_api then
local failed = script_data.failed_deserialization[player.name]
recipe_notifications = serialize.serialize_crafting_notifications(
player, failed and failed.recipe_notifications
)
end
clusterio_api.send_json("inventory_sync_download", {
player_name = player.name,
recipe_notifications = record.recipe_notifications,
recipe_notifications = recipe_notifications,
})
-- If this is a synced player turn them into a spectator while the