Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local cache = {} -- {["item:id"] = {["periph:id"] = {slot_n,slot_m...}}}
- local mainChest = nil
- local periphs = {} -- {["periph:id"] = true}
- local debug = false
- local function registerChests()
- periphs = {}
- local names = peripheral.getNames()
- for i = 1, #names do
- local name = names[i]
- if peripheral.hasType(name,"inventory") and name ~= mainChest then
- periphs[name] = true
- end
- end
- end
- local function loadCache(file)
- local f = fs.open(file,"r")
- if f == nil then return end
- cache = textutils.unserialise(f.readAll())
- f.close()
- end
- local function saveCache(file)
- local f = fs.open(file,"w")
- f.write(textutils.serialise(cache))
- f.close()
- end
- local function createCache()
- cache = {}
- for i in pairs(periphs) do
- if i ~= mainChest then
- local items = peripheral.call(i, "list")
- for slot, item in pairs(items) do
- cache[item.name] = cache[item.name] or {}
- cache[item.name][i] = cache[item.name][i] or {}
- cache[item.name][i][slot] = true
- end
- end
- end
- end
- local function setMainChest(name)
- if mainChest~=nil then periphs[mainChest]=true end
- mainChest = name
- periphs[name]=nil
- end
- local function pullItem(item, count)
- if item=="" or count==0 or cache[item]==nil then return 0 end
- local main = peripheral.wrap(mainChest)
- local remaining = count
- for periphName,slots in pairs(cache[item]) do
- local items = peripheral.call(periphName, "list")
- for slot in pairs(slots) do
- if slot == nil then break end
- if items[slot].count <= remaining then
- cache[item][periphName][slot]=nil
- local next = next
- if next(cache[item][periphName]) == nil then
- cache[item][periphName] = nil
- if next(cache[item]) == nil then
- cache[item] = nil
- end
- end
- end
- remaining = remaining - main.pullItems(periphName,slot,remaining)
- if remaining <= 0 then return count end
- end
- end
- return count-remaining
- end
- local function pushItemFromSlot(slot,item,count)
- -- this is a helper function and will do nothing if cached slots are full
- local remaining = count
- local main = peripheral.wrap(mainChest)
- for periphName,slots in pairs(cache[item]) do
- for i in pairs(slots) do
- remaining = remaining - main.pushItems(periphName,slot,remaining,i)
- if remaining<=0 then return count end
- end
- end
- return count-remaining
- end
- local function pushItem(item, count)
- if item=="" or count==0 then return 0 end
- local main = peripheral.wrap(mainChest)
- local items = main.list()
- local foundSlots = {}
- local totalFound = 0
- local maxSlot = 0
- cache[item] = cache[item] or {}
- for slot, it in pairs(items) do
- if slot > maxSlot then maxSlot = slot end
- if it.name == item then
- foundSlots[slot] = it.count
- totalFound = totalFound + it.count
- else
- foundSlots[slot] = 0
- end
- end
- if totalFound == 0 then return 0 end
- local toMove = math.min(count, totalFound)
- local remaining = toMove
- local recachePeriphs = {}
- local cachedPeriphs = cache[item] or {}
- for periphName in pairs(cachedPeriphs) do
- for slot = maxSlot, 1, -1 do
- if remaining <= 0 then break end
- local slotCount = foundSlots[slot] or 0
- if slotCount > 0 then
- local pushed = main.pushItems(periphName, slot, remaining)
- if pushed > 0 then
- remaining = remaining - pushed
- foundSlots[slot] = foundSlots[slot] - pushed
- table.insert(recachePeriphs,periphName)
- end
- end
- end
- end
- if remaining > 0 then
- for periphName in pairs(periphs) do
- if not cachedPeriphs[periphName] then
- for slot = maxSlot, 1, -1 do
- if remaining <= 0 then break end
- local slotCount = foundSlots[slot] or 0
- if slotCount > 0 then
- local pushed = main.pushItems(periphName, slot, remaining)
- if pushed > 0 then
- cache[item] = cache[item] or {}
- table.insert(recachePeriphs,periphName)
- remaining = remaining - pushed
- foundSlots[slot] = foundSlots[slot] - pushed
- end
- end
- end
- end
- end
- end
- for i=1,#recachePeriphs do
- local p = recachePeriphs[i]
- local l = peripheral.call(p,"list")
- for slot,it in pairs(l) do
- if it.name==item then
- cache[item][p] = cache[item][p] or {}
- cache[item][p][slot] = true
- end
- end
- end
- return toMove - remaining
- end
- --[[local function pushItem(item, count)
- if item=="" or count==0 then return 0 end
- local main = peripheral.wrap(mainChest)
- local items = main.list()
- local remaining = count
- local cachefull = false
- local keys = {}
- local index = 0
- cache[item] = cache[item] or {}
- for slot,it in pairs(items) do
- if it.name==item then
- if not cachefull then
- local pushed = pushItemFromSlot(slot,item,remaining)
- remaining = remaining - pushed
- if remaining<=0 then return count end
- if pushed==0 then cachefull = true end
- end
- if cachefull then
- index = index + 1
- keys[index] = {slot,it.count}
- end
- end
- end
- local function processPeriph(periphName)
- cache[item][periphName] = cache[item][periphName] or {}
- local chest = peripheral.wrap(periphName)
- local pushed = 1
- while pushed>0 and remaining>0 do
- if index==0 then return count - remaining end
- local slot = keys[index][1]
- pushed = main.pushItems(periphName,slot,remaining)
- if keys[index][2]<=pushed then
- index = index-1
- else
- keys[index][2] = keys[index][2] - pushed
- end
- remaining = remaining - pushed
- end
- local items = chest.list()
- for slot,it in pairs(items) do
- if it.name == item then
- cache[item][periphName][slot] = true
- end
- end
- if remaining==0 then return count end
- end
- for periphName in pairs(cache[item]) do
- local result = processPeriph(periphName)
- if result ~= nil then return result end
- end
- for periphName in pairs(periphs) do
- if cache[item][periphName] == nil then
- local result = processPeriph(periphName)
- if result ~= nil then return result end
- end
- end
- return count - remaining
- end]]
- local function returnItems()
- local l = peripheral.call(mainChest,"list")
- local c = {}
- local a = {}
- for slot,it in pairs(l) do
- c[it.name] = (c[it.name] or 0) + it.count
- end
- for name,count in pairs(c) do
- a[name] = pushItem(name,count)
- end
- return a
- end
- local function getCache()
- return cache,periphs
- end
- local function listItems()
- local keys = {}
- local ln = 0
- for k,v in pairs(cache) do
- ln=ln+1
- keys[ln]=k
- end
- return keys
- end
- local function countItem(item)
- if cache[item]==nil then return 0 end
- local c = 0
- for p,slots in pairs(cache[item]) do
- local items = peripheral.call(p,"list")
- for i in pairs(slots) do
- c=c+items[i].count
- end
- end
- if c == 0 or next(cache[item])==nil then cache[item]=nil end
- return c
- end
- local function listItemsWithCount()
- local l = listItems()
- local counted = {}
- for i=1,#l do
- counted[l[i]] = countItem(l[i])
- end
- return counted
- end
- local function restockMainChest()
- local m = peripheral.wrap(mainChest)
- for slot,item in pairs(m.list()) do
- pullItem(item.name,m.getItemDetail(slot).maxCount-item.count)
- end
- end
- local function sortChest(id)
- local c = peripheral.wrap(id)
- for slot,item in pairs(c.list()) do
- c.pushItems(id,slot)
- end
- end
- local function sortAllChests()
- for i in pairs(periphs) do
- sortChest(i)
- end
- end
- return {returnItems=returnItems,pushItem=pushItem,pullItem=pullItem,
- registerChests=registerChests,createCache=createCache,saveCache=saveCache,
- loadCache=loadCache,getCache=getCache,setDebugMode=setDebugMode,setMainChest=setMainChest,
- listItemsWithCount=listItemsWithCount,countItem=countItem,listItems=listItems,
- restockMainChest=restockMainChest,sortChest=sortChest,sortAllChests=sortAllChests}
Add Comment
Please, Sign In to add comment