Reimplement core method for crafting_queue sync

* New method avoids all dataloss and prefectly replicates the queue
* Made proper description in readme
* Added packages to make lerna build happy
* Added reference to main readme
This commit is contained in:
Daniel committed 2021-07-12 22:05:54 +02:00
1 parent 87218e4803
commit a4a667ef06
7 files changed
+91 -43

No files matched your search

@@ -34,7 +34,7 @@ inventory_sync.events[defines.events.on_player_joined_game] = function(event)
end
-- Upload inventory when a player leaves the game. Triggers on restart after crash if player was online during crash.
inventory_sync.events[defines.events.on_player_left_game] = function(event)
inventory_sync.events[defines.events.on_pre_player_left_game] = function(event)
local playerIndex = event.player_index
inventory_sync.uploadInventory(playerIndex)
global.download_cache[playerIndex] = "" -- Clear cache to avoid leaking memory to people quitting during download
@@ -3,33 +3,28 @@ function load_crafting_queue(crafting_queue, player)
local inventory = player.get_main_inventory()
-- Give player some more inventory space to avoid duplicating items
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 100
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
-- Add items to inventory
for _, item in pairs(crafting_queue.ingredients) do
inventory.insert(item)
end
-- Load crafting queue
for _, queueItem in pairs(crafting_queue) do
for _, queueItem in pairs(crafting_queue.crafting_queue) do
local recipe = game.recipe_prototypes[queueItem.recipe]
game.print("Crafting "..queueItem.recipe)
-- Add items to inventory
for _, item in pairs(recipe.ingredients) do
local count = math.floor(item.amount * queueItem.count / math.max(recipe.main_product.amount, 1))
if count > 0 then
inventory.insert({
name = item.name,
count = count,
})
end
end
-- game.print("Crafting "..queueItem.recipe)
-- Start crafting (consume items)
player.begin_crafting {
count = queueItem.count,
recipe = queueItem.recipe,
silent = true, -- Fail silently if items are missing
-- silent = true, -- Fail silently if items are missing
}
end
-- Remove extra inventory slots
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 100
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 1000
end
return load_crafting_queue
+65 -24
View File
@@ -9,46 +9,87 @@ function save_crafts(event)
return
end
-- Serialize crafting queue
if player.crafting_queue == nil then
player.print("You can't save nothing, you silly goose")
return
end
for _, queueItem in pairs(player.crafting_queue) do
crafting_queue[queueItem.index] = {
count = queueItem.count,
recipe = queueItem.recipe,
}
end
-- Give player some more inventory space to avoid duplicating items
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 100
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
-- Save current items
local inventory = player.get_main_inventory()
local old_items = inventory.get_contents()
-- Cancel old crafts to get the items back
while player.crafting_queue_size > 0 do
local old_queue = player.crafting_queue
local queueItem = player.crafting_queue[1]
local recipe = game.recipe_prototypes[queueItem.recipe]
-- Cancel craft
player.cancel_crafting {
index = 1,
count = 1,
}
-- Remove ingredients from inventory
for _, item in pairs(recipe.ingredients) do
local inventory = player.get_main_inventory()
inventory.remove({
name = item.name,
count = item.amount,
local rightmost_right_index = 0 -- 0 indexed since it is subtractive in a 1 indexed language
local new_queue = player.crafting_queue
while
new_queue ~= nil and
new_queue[#new_queue - rightmost_right_index] ~= nil and
new_queue[#new_queue - rightmost_right_index].count >= old_queue[#old_queue - rightmost_right_index].count
do
rightmost_right_index = rightmost_right_index + 1
end
local oldItem = old_queue[#old_queue - rightmost_right_index]
local newItem = nil
if new_queue ~= nil then
newItem = new_queue[#new_queue - rightmost_right_index]
end
-- Figure out how many items to add to queue
local added = oldItem.count
if newItem ~= nil then
added = oldItem.count - newItem.count
if oldItem.recipe ~= newItem.recipe then
log("ERROR: Old item "..oldItem.recipe.." is not equal "..newItem.recipe)
end
end
-- If the last item we added was of the same type, merge them in the queue
if #crafting_queue > 0 and crafting_queue[#crafting_queue].recipe == oldItem.recipe then
crafting_queue[#crafting_queue].count = crafting_queue[#crafting_queue].count + added
else
-- If the last item was of a different type, add a new item to the queue
table.insert(crafting_queue, {
recipe = oldItem.recipe,
count = added,
})
end
game.print("Canceled craft "..recipe.name)
-- game.print("Saved craft "..oldItem.recipe)
end
-- Find amount of items added and remove from inventory
local new_items = inventory.get_contents()
local difference = {}
for k,v in pairs(new_items) do
local old_count = old_items[k]
local diff = v
if old_count ~= nil then
diff = diff - old_count
end
if diff > 0 then
local ingredient = {
name = k,
count = diff,
}
inventory.remove(ingredient)
table.insert(difference, ingredient)
end
end
-- Remove extra inventory slots
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 100
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 1000
global["saved_crafting_queue_"..player.name] = crafting_queue
global["saved_crafting_queue_"..player.name] = {
crafting_queue = crafting_queue,
ingredients = difference,
}
end
end
@@ -1,6 +1,7 @@
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")
function upload_inventory(playerIndex)
local player = game.players[playerIndex]
@@ -68,7 +69,8 @@ function upload_inventory(playerIndex)
end
end
-- Serialize crafting queue saved by /csc or /save-crafts
-- Serialize crafting queue saved by /csc or /save-crafts OR automatically
save_crafts({player_index = player.name})
serialized_player.crafting_queue = global["saved_crafting_queue_"..player.name]
if serialized_player.crafting_queue == nil then
serialized_player.crafting_queue = {}