ccVault/main.lua

238 lines
6.3 KiB
Lua
Raw Permalink Normal View History

2024-10-16 23:47:54 +02:00
local reindexFreq = 1 -- Per minute (0.5 to index every 2 minutes, ...)
local indexUpdated = false
local items
local outputSlots
local item -- User choice
local count -- User choice
local chests = { peripheral.find("inventory") }
for i, chest in ipairs(chests) do
if peripheral.getName(chest) == settings.get("ccVault.outputInventory") then
table.remove(chests, i)
break
end
end
-- Functions
local getOutputSize
local indexChests
local loadIndex
local getItemNames
local userInput
local indexRefresh
local storageLoop
local transfer
function getOutputSize()
if peripheral.getType(settings.get("ccVault.outputInventory")) == "create:depot" then
outputSlots = 1
else
outputSlots = peripheral.call(settings.get("ccVault.outputInventory"), "size")
end
end
-- Function to populate the index
function indexChests()
while true do
local itemIndex = {}
for _, chest in ipairs(chests) do
for slot, item in pairs(chest.list()) do
if not itemIndex[item.name] then
itemIndex[item.name] = {}
end
table.insert(itemIndex[item.name], { chest = peripheral.getName(chest), slot = slot })
end
end
if fs.exists(settings.get("ccVault.file")) then
local db = fs.open(settings.get("ccVault.file"), "r")
if not db then
printError("Couldn't open index databse!")
else
if textutils.unserializeJSON(db.readAll()) == itemIndex then
db.close()
else
db.close()
db = fs.open(settings.get("ccVault.file"), "w")
if not db then
printError("Couldn't write index databse!")
else
db.write(textutils.serializeJSON(itemIndex))
db.close()
indexUpdated = true
end
end
end
else
local db = fs.open(settings.get("ccVault.file"), "w")
db = fs.open(settings.get("ccVault.file"), "w")
if not db then
printError("Couldn't write index databse!")
else
db.write(textutils.serializeJSON(itemIndex))
db.close()
indexUpdated = true
end
end
sleep(60 / reindexFreq)
end
end
function loadIndex()
local itemIndex
local db = fs.open(settings.get("ccVault.file"), "r")
if not db then
print("Index file not found. It probably wasn't created yet.")
local iCount = 0
write("Waiting until indexing is finished")
while not db do
if iCount >= 3 then
term.setCursorPos(term.getCursorPos[1], 1)
write("Waiting until indexing is finished.")
iCount = 0
else
write(".")
iCount = iCount + 1
end
db = fs.open(settings.get("ccVault.file"), "r")
sleep(5)
end
end
itemIndex = textutils.unserializeJSON(db.readAll())
db.close()
term.clear()
term.setCursorPos(1, 1)
return itemIndex
end
function indexRefresh()
sleep(60 / reindexFreq)
end
function storageLoop()
local itemIndex = loadIndex()
while true do
if indexUpdated then
itemIndex = loadIndex()
indexUpdated = false
end
items = getItemNames(itemIndex)
parallel.waitForAny(userInput, indexRefresh)
if item then
if count == 0 or not count then count = 64 end
transfer(item, count, itemIndex)
item = nil
count = nil
end
term.clear()
term.setCursorPos(1, 1)
end
end
---@param tItem string
---@param maxCount integer
---@param itemIndex table
function transfer(tItem, maxCount, itemIndex)
local transfered = 0
-- Stored item info
local exists = itemIndex[tItem] ~= nil
if exists then
exists = itemIndex[tItem][1]
end
if not exists then
print("Item not found.\nTry to wait for index update.")
sleep(3)
2024-10-16 23:47:54 +02:00
return
end
local sItemInfo = peripheral.call(itemIndex[tItem][1]["chest"], "getItemDetail", itemIndex[tItem][1]["slot"])
if not sItemInfo then
print("Index is out of date!\nWait for index update to resolve this error.")
sleep(3)
2024-10-16 23:47:54 +02:00
return
elseif sItemInfo.count <= 0 then
print("Index is out of date!\nWait for index update to resolve this error.")
sleep(3)
2024-10-16 23:47:54 +02:00
return
elseif not sItemInfo.count then
print("Index is out of date!\nWait for index update to resolve this error.")
sleep(3)
2024-10-16 23:47:54 +02:00
return
end
while transfered < count do
if not itemIndex[tItem][1] then
if transfered > 0 then
print("Not enough of `" .. tItem .. "` was found.\nTransfered only " .. transfered .. ".")
sleep(3)
2024-10-16 23:47:54 +02:00
end
break
end
---@type ccTweaked.peripheral.item
local lastSlot = peripheral.call(settings.get("ccVault.outputInventory"), "getItemDetail", outputSlots)
if lastSlot then
if lastSlot.count > 0 then
print("Output inventory is full!")
sleep(3)
2024-10-16 23:47:54 +02:00
return
end
end
if sItemInfo.name == tItem then
local moved = peripheral.call(itemIndex[tItem][1]["chest"], "pushItems", settings.get("ccVault.outputInventory"),
itemIndex[tItem][1]["slot"],
maxCount)
if moved == sItemInfo.count then
transfered = transfered + moved
table.remove(itemIndex[tItem], 1)
elseif moved == 0 then
if peripheral.call(settings.get("ccVault.outputInventory"), "size") == transfered then
print("Output inventory is full!")
sleep(3)
2024-10-16 23:47:54 +02:00
break
else
table.remove(itemIndex[tItem], 1)
end
elseif not moved then
print("Item not found!")
sleep(3)
2024-10-16 23:47:54 +02:00
break
else
transfered = transfered + moved
end
else
table.remove(itemIndex[tItem], 1)
end
end
end
---@param itemIndex table -- Index table of all the items
---@return table names Table of strings
function getItemNames(itemIndex)
local names = {}
for name, _ in pairs(itemIndex) do
table.insert(names, name)
end
return names
end
---@param items table Table of all item names as strings
function userInput()
local completion = require "cc.completion"
local input = read(nil, nil, function(text) return completion.choice(text, items) end)
if not input then item, count = nil, nil end
input = input .. " "
local parsedInput = {}
for w in input:gmatch("(.-) ") do table.insert(parsedInput, w) end
-- item, count = string.match(input, "([^%s]+) (%d+)")
item = parsedInput[1]
count = tonumber(parsedInput[2])
end
getOutputSize()
parallel.waitForAny(indexChests, storageLoop)