Advertisement
Guest User

Untitled

a guest
Jan 26th, 2020
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.21 KB | None | 0 0
  1. local chestPrefix="actuallyadditions:giantchestmedium_"
  2. local prefix="$"
  3. local prefixPattern="^%"..prefix
  4. local inputInterval=5
  5. local warnInterval=60
  6. local feederInterval=4
  7. local channel=1
  8.  
  9. local autoFeeder=false
  10. local cachedSlot=false
  11. local index={}
  12. local modem=peripheral.wrap("back")
  13. local modules=peripheral.wrap("manipulator_1")
  14. local inputChest=peripheral.wrap("minecraft:ender chest_0")
  15. local inv
  16. repeat
  17.     local success,result=pcall(modules.getInventory)
  18.     inv=result
  19.     if not success then sleep(10) end
  20. until success
  21. local totalStorage=0
  22. local usedStorage=0
  23. local lastFullWarning=os.clock()-warnInterval-1
  24. local yieldTime=os.clock()
  25. modem.open(channel)
  26.  
  27. local function yield()
  28.     if os.clock()-yieldTime>2 then
  29.         os.queueEvent("yield")
  30.         os.pullEvent()
  31.         yieldTime=os.clock()
  32.     end
  33. end
  34.  
  35. function slots()
  36.     return "Slots used: "..usedStorage.."/"..totalStorage
  37. end
  38.  
  39. function refreshIndex()
  40.     index={}
  41.     local indexLookup={}
  42.     totalStorage=0
  43.     usedStorage=0
  44.     local inventoryList=inputChest.getTransferLocations()
  45.     for _,chest in pairs(inventoryList) do
  46.         if chest:match(chestPrefix) then
  47.             totalStorage=totalStorage+peripheral.call(chest,"size")
  48.             local chestID=chest:gsub(chestPrefix,"")
  49.             local chestList=peripheral.call(chest,"list")
  50.             if chestList then
  51.                 for slot,_ in pairs(chestList) do
  52.                     usedStorage=usedStorage+1
  53.                     local slotMeta=peripheral.call(chest,"getItemMeta",slot)
  54.                     local name=slotMeta.displayName.." - "..slotMeta.name
  55.                     if not indexLookup[name] then
  56.                         indexLookup[name]=#index+1
  57.                     end
  58.                     if not index[indexLookup[name]] then
  59.                         index[indexLookup[name]]={
  60.                             name=name,
  61.                             slots={},
  62.                             count=0
  63.                         }
  64.                     end
  65.                     local indexEntry=index[indexLookup[name]]
  66.                     if not indexEntry.slots[chestID] then
  67.                         indexEntry.slots[chestID]={}
  68.                     end
  69.                     table.insert(indexEntry.slots[chestID],slot)
  70.                     indexEntry.count=indexEntry.count+slotMeta.count
  71.                     yield()
  72.                 end
  73.             end
  74.         end
  75.     end
  76.     if usedStorage<totalStorage then
  77.         lastFullWarning=os.clock()-warnInterval-1
  78.     end
  79. end
  80.  
  81. function search(term)
  82.     modules.tell("Search results for "..term..":")
  83.     local found=0
  84.     if term~="" then
  85.         for id,entry in ipairs(index) do
  86.             if entry.name:lower():match(term:lower()) then
  87.                 modules.tell("[ "..id.." ]  "..entry.name.." ("..entry.count..")")
  88.                 found=found+1
  89.             end
  90.         end
  91.     end
  92.     if found==0 then
  93.         modules.tell("No results found.")
  94.     end
  95. end
  96.  
  97. function list()
  98.     modules.tell("Item list:")
  99.     for id,entry in ipairs(index) do
  100.         modules.tell("[ "..id.." ]  "..entry.name.." ("..entry.count..")")
  101.     end
  102.     modules.tell(slots())
  103. end
  104.  
  105. function transfer(id, num)
  106.     local transferred=0
  107.     local entry=index[id]
  108.     for chestID,slots in pairs(entry.slots) do
  109.         local toRemove={}
  110.         for slotID,slot in pairs(slots) do
  111.             local item=peripheral.call(chestPrefix..chestID,"getItemMeta",slot)
  112.             if item and item.count<=num-transferred then
  113.                 transferred=transferred+inv.pullItems(chestPrefix..chestID,slot)
  114.                 table.insert(toRemove,slotID)
  115.             elseif item then
  116.                 transferred=transferred+inv.pullItems(chestPrefix..chestID,slot,num-transferred)
  117.             end
  118.             if transferred==num then break end
  119.             yield()
  120.         end
  121.         for k,v in pairs(toRemove) do
  122.             table.remove(slots,v)
  123.         end
  124.         if transferred==num then break end
  125.     end
  126.     local displayName=entry.name:gsub(" %- %S+$","")
  127.     entry.count=entry.count-transferred
  128.     modules.tell("Transferred "..transferred.." "..displayName.." ("..entry.count.." remaining).")
  129.     if entry.count==0 then table.remove(index,id) end
  130. end
  131.  
  132. modules.capture(prefixPattern)
  133.  
  134. modules.tell("")
  135. modules.tell("CC System loading...")
  136. print("Indexing...")
  137. refreshIndex()
  138. print("Done indexing.")
  139. print(slots())
  140. modules.tell("CC System is online.")
  141. modules.tell(slots())
  142.  
  143. parallel.waitForAny(
  144.     function()
  145.         while true do
  146.             local _,message,pattern,_,_=os.pullEvent("chat_capture")
  147.             if pattern==prefixPattern then
  148.                 modules.tell("")
  149.                 if message:match(prefixPattern.."reboot") then
  150.                     -- reboot
  151.                     modules.tell("Rebooting.")
  152.                     shell.run("reboot")
  153.                 elseif message:match(prefixPattern.."feeder") then
  154.                     -- feeder
  155.                     autoFeeder=not autoFeeder
  156.                     if autoFeeder then
  157.                         modules.tell("Auto-feeder enabled.")
  158.                     else
  159.                         modules.tell("Auto-feeder disabled.")
  160.                     end
  161.                 elseif message:match(prefixPattern.."g") then
  162.                     -- get
  163.                     local num=message:match(prefixPattern.."%S+ .+ (%d+)$") or ""
  164.                     local term=message:match(prefixPattern.."%S+ (.+) "..num.."$") or message:match(prefixPattern.."%S+ (.+)$") or ""
  165.                     if num=="" then num=1 end
  166.                     num=tonumber(num)
  167.                     if term:gsub("[%d%s]","")=="" then
  168.                         -- id
  169.                         term=tonumber(term)
  170.                         if index[term] then
  171.                             transfer(term,num)
  172.                         else
  173.                             modules.tell("No items found with id "..term.."!")
  174.                         end
  175.                     else
  176.                         -- search
  177.                         local results={}
  178.                         for id,entry in ipairs(index) do
  179.                             if entry.name:lower():match(term:lower()) then
  180.                                 table.insert(results,id)
  181.                             end
  182.                         end
  183.                         if #results==0 then
  184.                             modules.tell("No items found matching the name "..term.."!")
  185.                         elseif #results==1 then
  186.                             transfer(results[1],num)
  187.                         else
  188.                             modules.tell("Multiple items found matching the name "..term..":")
  189.                             for _,id in ipairs(results) do
  190.                                 local entry=index[id]
  191.                                 modules.tell("[ "..id.." ]  "..entry.name.." ("..entry.count..")")
  192.                             end
  193.                             modules.tell("Type id of desired item, or anything else to cancel.")
  194.                             modules.capture(".")
  195.                             local _,choice,_,_,_=os.pullEvent("chat_capture")
  196.                             choice=tonumber(choice)
  197.                             if index[choice] then
  198.                                 transfer(choice,num)
  199.                             else
  200.                                 modules.tell("Cancelled.")
  201.                             end
  202.                             modules.uncapture(".")
  203.                         end
  204.                     end
  205.                 elseif message:match(prefixPattern.."s") then
  206.                     -- search
  207.                     local term=message:match(prefixPattern.."%S+ (.+)$") or ""
  208.                     search(term)
  209.                 elseif message:match(prefixPattern.."r") then
  210.                     -- re-index
  211.                     modules.tell("Re-indexing...")
  212.                     refreshIndex()
  213.                     modules.tell("Done re-indexing.")
  214.                     modules.tell(slots())
  215.                 elseif message:match(prefixPattern.."l") then
  216.                     -- list
  217.                     list()
  218.                 elseif message:match(prefixPattern.."f") then
  219.                     -- free
  220.                     modules.tell(slots())
  221.                 elseif message:match(prefixPattern.."h") then
  222.                     -- help menu
  223.                     modules.tell("Commands:")
  224.                     modules.tell(prefix.."h(elp) - show this menu")
  225.                     modules.tell(prefix.."s(earch) <search term> - list items matching search term, in the form [ id ]  name - id_name (num)")
  226.                     modules.tell(prefix.."g(et) <id / name> [count] - get count (default: 1) items from the system, matching the id or name")
  227.                     modules.tell(prefix.."r(efresh) - refresh the item index (you shouldn't need to do this in most cases)")
  228.                     modules.tell(prefix.."l(ist) - list all items in the system, in the form [ id ]  name - id_name (num)")
  229.                     modules.tell(prefix.."f(ree) - show how many slots in the system are full")
  230.                     modules.tell(prefix.."reboot - reboot the system")
  231.                     modules.tell(prefix.."feeder - toggle the auto-feeder")
  232.                 else
  233.                     modules.tell("Command "..message:match(prefixPattern.."%S+").." not found.")
  234.                 end
  235.             end
  236.         end
  237.     end,
  238.     function()
  239.         while true do
  240.             local itemList=inputChest.list()
  241.             if next(itemList)~=nil and os.clock()-lastFullWarning>warnInterval then
  242.                 local transferredItems=false
  243.                 for slot,item in pairs(itemList) do
  244.                     local count=item.count
  245.                     local transferred=0
  246.                     for _,entry in ipairs(index) do
  247.                         if entry.name:match(item.name) then
  248.                             for id,_ in pairs(entry.slots) do
  249.                                 transferred=transferred+inputChest.pushItems(chestPrefix..id,slot)
  250.                                 if transferred>=count then
  251.                                     break
  252.                                 end
  253.                             end
  254.                             break
  255.                         end
  256.                     end
  257.                     if transferred<count then
  258.                         local inventoryList=inputChest.getTransferLocations()
  259.                         for _,chest in pairs(inventoryList) do
  260.                             if chest:match(chestPrefix) then
  261.                                 transferred=transferred+inputChest.pushItems(chest,slot)
  262.                                 if transferred>=count then
  263.                                     break
  264.                                 end
  265.                             end
  266.                         end
  267.                     end
  268.                     if transferred<count then
  269.                         lastFullWarning=os.clock()
  270.                         modules.tell("")
  271.                         modules.tell("WARNING: storage is full!")
  272.                         modules.tell(slots())
  273.                         print()
  274.                         print("WARNING: storage is full!")
  275.                         print(slots())
  276.                     end
  277.                     if transferred>0 and not transferredItems then
  278.                         transferredItems=true
  279.                     end
  280.                 end
  281.                 if transferredItems then
  282.                     refreshIndex()
  283.                 end
  284.             end
  285.             sleep(inputInterval)
  286.         end
  287.     end,
  288.     function()
  289.         while true do
  290.             local _,_,sendChannel,replyChannel,message,_=os.pullEvent("modem_message")
  291.             if message=="slots" then
  292.                 modem.transmit(replyChannel,channel,slots())
  293.             end
  294.         end
  295.     end,
  296.     function()
  297.         while true do
  298.             if autoFeeder then
  299.                 local data=modules.getMetaOwner()
  300.                 while data.food.hungry do
  301.                     local item
  302.                     if cachedSlot then
  303.                         local slotItem=inv.getItem(cachedSlot)
  304.                         if slotItem and slotItem.consume then
  305.                             item=slotItem
  306.                         else
  307.                             cachedSlot=nil
  308.                         end
  309.                     end
  310.                     if not item then
  311.                         for slot,meta in pairs(inv.list()) do
  312.                             local slotItem=inv.getItem(slot)
  313.                             if slotItem and slotItem.consume then
  314.                                 item=slotItem
  315.                                 cachedSlot=slot
  316.                                 break
  317.                             end
  318.                         end
  319.                     end
  320.                     if item then
  321.                         item.consume()
  322.                     end
  323.                     data=modules.getMetaOwner()
  324.                 end
  325.             end
  326.             sleep(feederInterval)
  327.         end
  328.     end,
  329.     function()
  330.         while true do
  331.             local success,_=pcall(modules.getInventory)
  332.             if not success then
  333.                 shell.run("reboot")
  334.             end
  335.             sleep(10)
  336.         end
  337.     end
  338. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement