Advertisement
promitheus_sal

warehouse

Dec 16th, 2023 (edited)
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.06 KB | Source Code | 0 0
  1.  
  2. STORAGE_ROOT_DIR = "./"
  3. STORAGE_BIN_LIST_FILENAME = "bins.list"
  4. bins = {}
  5. main_bin = ""
  6.  
  7. function logwarn(e)
  8.     print("WARN> "..e)
  9. end
  10.  
  11. function logerr(e)
  12.     print("ERROR> "..e)
  13. end
  14.  
  15. function logverb(e)
  16.     print("VERBOSE> "..e)
  17. end
  18.  
  19. --read bins
  20. for l in io.lines(STORAGE_ROOT_DIR..STORAGE_BIN_LIST_FILENAME) do
  21.     local a,b,c = l:match("^([^;]+);([^;]+);([^;]+)$")
  22.     if bins[b]~=nil then
  23.         logwarn(("Duplicate bin alias detected: key '%s' already declared ('%s'), ignoring new value"):format(b,bins[b]))
  24.     else
  25.         bins[b]={type=a,id=b,val=c}
  26.     end
  27.  
  28.     for id, dat in pairs(bins) do
  29.         if dat.type=="main" then
  30.             if main_bin~="" then
  31.                 logwarn(string.format("Duplicate main bin detected (%s); ignoring new value",main_bin))
  32.             else
  33.                 main_bin = id
  34.             end
  35.         end
  36.     end
  37. end
  38.  
  39. function list_bins(all,type,blacklist,limit)
  40.     local r = {}
  41.     blacklist = blacklist or {}
  42.     limit=limit or 1000000
  43.     if limit==-1 then limit=1000000 end
  44.     for id,dat in pairs(all) do
  45.         if (not blacklist[id]) and (type==dat.type) then
  46.             r[id] = dat
  47.         end
  48.     end
  49.     return r
  50. end
  51.  
  52. function pushItems(from,to,inslot,limit,toslot)
  53.     local r = peripheral.call(from,"pushItems",to,inslot,limit,toslot)
  54.     print(string.format("Moving %d items from '%s' to '%s'",r,from,to))
  55.     return r
  56. end
  57.  
  58. function getInvSize(inv)
  59.     return peripheral.call(inv,"size")
  60. end
  61.  
  62. function listInv(inv)
  63.     return peripheral.call(inv,"list")
  64. end
  65.  
  66. function itemDetails(inv,slot)
  67.     return peripheral.call(inv,"getItem",slot).getMetadata()
  68. end
  69.  
  70. function store_to(from,fromslot,to,limit)
  71.     return pushItems(from.val,to.val,fromslot,limit)
  72. end
  73.  
  74. function store_all_to(from,to,limit)
  75.     local t=0
  76.     limit=limit or 1000000
  77.     if limit==-1 then limit=1000000 end
  78.     for slot,item in pairs(listInv(from)) do
  79.         t=t+pushItems(from.val,to.val,slot,limit-t)
  80.         if t==limit then return limit end
  81.     end
  82.     return t
  83. end
  84.  
  85. function store_to_any(from,fromslot,tolist,limit)
  86.     local t=0
  87.     limit=limit or 1000000
  88.     if limit==-1 then limit=1000000 end
  89.     local l={}
  90.     for id,dat in pairs(tolist) do
  91.         table.insert(l,{id=id,dat=dat})
  92.     end
  93.     for _,e in pairs(l) do
  94.         local dat = e.dat
  95.         t=t+pushItems(from.val,dat.val,fromslot,limit-t)
  96.         if t==limit then return limit end
  97.     end
  98.     return t
  99. end
  100.  
  101. function store_all_to_any(from,tolist,limit)
  102.     limit=limit or 1000000
  103.     if limit==-1 then limit=1000000 end
  104.     local t=0
  105.     for slot,item in pairs(listInv(from.val)) do
  106.         t=t+store_to_any(from,slot,tolist,limit-t)
  107.         if t==limit then return limit end
  108.     end
  109.     return t
  110. end
  111.  
  112. function default_filter(txt)
  113.     return function (det)
  114.         local f = txt:lower()
  115.         local a = det.name:lower():find(f)
  116.         local b = det.displayName:lower():find(f)
  117.         return a or b
  118.     end
  119. end
  120.  
  121. function fetch_from(from,to,filter,limit)
  122.     if type(filter)~="function" then if filter then filter=function() return true end else filter=function() return false end end end
  123.     local t=0
  124.     limit=limit or 1000000
  125.     if limit==-1 then limit=1000000 end
  126.     for slot,item in pairs(listInv(from.val)) do
  127.         if filter(itemDetails(from.val,slot)) then
  128.             t=t+store_to(from,slot,to,limit-t)
  129.         end
  130.         if limit==t then return limit end
  131.     end
  132.     return t
  133. end
  134.  
  135. function fetch_from_any(fromlist,to,filter,limit)
  136.     if type(filter)~="function" then if filter then filter=function() return true end else filter=function() return false end end end
  137.     local t=0
  138.     limit=limit or 1000000
  139.     if limit==-1 then limit=1000000 end
  140.     for id,dat in pairs(fromlist) do
  141.         t=t+fetch_from(dat,to,filter,limit-t)
  142.         if limit==t then return limit end
  143.     end
  144.     return t
  145. end
  146.  
  147. function tokens(str)
  148.     local tok = {}
  149.     local isStr = false
  150.     local cur = ""
  151.     for i=1,#str do
  152.         local nc = str:sub(i,i)
  153.         if nc=="'" then
  154.             isStr = not isStr
  155.         else
  156.             if nc==' ' and not isStr then
  157.                 if cur~='' then
  158.                     table.insert(tok,cur)
  159.                 end
  160.                 cur=''
  161.             else
  162.                 cur=cur..nc
  163.             end
  164.         end
  165.     end
  166.     table.insert(tok,cur)
  167.     return tok
  168. end
  169.  
  170. function exec_command(cmd)
  171.     local tk = tokens(cmd)
  172.     cmd = tk[1]
  173.     if cmd=="storeall" or cmd=='s' then
  174.         print(("Stored %d items."):format(store_all_to_any(bins[main_bin],list_bins(bins,"storage",false))))
  175.     elseif cmd=="fetch" or cmd=='f' then
  176.         print(("Fetched %d x '%s'."):format(fetch_from_any(list_bins(bins,"storage",false),bins[main_bin], default_filter(tk[2]), tonumber(tk[3] or -1)),tk[2]))
  177.     elseif cmd=='moveto' or cmd=='m' then
  178.         local where = tk[2]
  179.         local what = tk[3]
  180.         local limit = tonumber(tk[4])
  181.         print(string.format("Moved %d x '%s' to '%s'.",fetch_from_any(list_bins(bins,"storage",{[where]=true}),bins[where],default_filter(what),limit),what,where))
  182.     elseif cmd=='listbins' or cmd=='lb' then
  183.         print("Listing bins:")
  184.         for id,v in pairs(bins) do
  185.             print(string.format("#'%s': pid=\"%s\" type='%s'",id,v.val,v.type))
  186.         end
  187.     elseif cmd=='main' then
  188.         main_bin = tk[2]
  189.         print("Set '"..tk[2].."' as main bin.")
  190.     elseif cmd=='help' or cmd=='h' then
  191.         print([[
  192. Help:
  193. storeall -> store all items from main bin to any storage
  194. moveto | m <where> <filter> <limit> -> move at most <limit >items that meet <filter> from any storage to <where>
  195. fetch | f <filter> <limit> -> same as "moveto main <filter> <limit>"
  196. main <bin> -> set <bin> as main bin
  197. listbins -> list all bins
  198.         ]])
  199.     elseif cmd=="exit" or cmd=="quit" or cmd=="q" then return false end
  200.     return true
  201. end
  202.  
  203. logverb(string.format("Main bin: %s",main_bin))
  204. logverb("Bins:")
  205. for id,v in pairs(bins) do
  206.     logverb(string.format("%s: type: %s val: %s",id,v.type,v.val))
  207. end
  208.  
  209. while exec_command(io.read('*l')) do end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement