bcash8

StorageSys client

Feb 13th, 2021 (edited)
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.59 KB | None | 0 0
  1. hostID = 13
  2. turtleNum = 1
  3. channel = "storageSys:1"
  4. chestSize = 54*64
  5. chestNum = 10*3
  6. chestName = "minecraft:chest"
  7.  
  8. storage = {}
  9. turtPos = {turtleNum,0,0}
  10. que = {}
  11. APK = "APK"
  12.  
  13. function init()
  14. --open rednet--
  15.     if not rednet.isOpen("right") then
  16.          rednet.open("right")
  17.     end
  18.  
  19. --get storage--
  20.      fs.delete("storage")
  21.      if fs.exists("storage") then
  22.           local f = fs.open("storage","r")
  23.           storage = textutils.unserialize(f.readAll())
  24.           f.close()
  25.      else
  26.           save("storage",storage)
  27.      end
  28.      storage = {}
  29. --get que--
  30.      if fs.exists("que") then
  31.           local f = fs.open("que","r")
  32.           que = textutils.unserialize(f.readAll())
  33.           f.close()
  34.      else
  35.           save("que",que)
  36.      end
  37.      que = {}
  38.      
  39. --get location--
  40.      fs.delete("location")
  41.      if fs.exists("location") then
  42.           local data = {}
  43.           local f = fs.open("location","r")
  44.           data = textutils.unserialize(f.readAll())
  45.           f.close()
  46.           if data[1] == true then
  47.                turtPos = data[2]
  48.                print("my pos is: ".. turtPos[2].. " " .. turtPos[3])
  49.           else
  50.                findLocation()
  51.           end
  52.      else
  53.           save("location",{false,turtPos})
  54.           findLocation()
  55.      end
  56. end
  57.  
  58. function getTableSize(t)
  59.      local count = 0
  60.      for k in pairs(t) do
  61.           for b in pairs(t[k].pos) do
  62.                count = count + 1
  63.           end
  64.      end
  65.      return count  
  66. end
  67.  
  68. function waitForResponse(id,tries)
  69.      if not tries then tries =  3 end
  70.      local sndr,msg,m,nTry = nil,nil,nil,0
  71.      
  72.      while nTry < tries do
  73.           if nTry > tries then break end
  74.           sndr,m = rednet.receive(channel,1)
  75.           if m then
  76.              msg = textutils.unserialize(m)
  77.           end
  78.           if sndr == id then
  79.                if msg[1] == APK then
  80.                     return msg
  81.                end
  82.           elseif not sndr then
  83.                 nTry = nTry + 1
  84.           end
  85.           return true
  86.      end
  87. end
  88.  
  89. function findLocation()
  90.      print("Finding Location")
  91.      save("location",{false,turtPos})
  92.      repeat turtle.up() until turtle.detectUp()
  93.      for i=1,4 do
  94.           local e, data = turtle.inspect()
  95.           if data then
  96.                print(data.name)
  97.                if data.name ~= chestName then
  98.                      turtPos = {turtleNum,0,4}
  99.                      break
  100.                end
  101.           end
  102.           turtle.turnRight()
  103.      end
  104.      save("location",{true,turtPos})
  105.      print("location is: ".. turtPos[1].. " "..turtPos[2].." ".. turtPos[3])
  106. end
  107.  
  108. function save(path,data)
  109.      f = fs.open(path,"w")
  110.      f.write(textutils.serialize(data))
  111.      f.close()
  112. end
  113.  
  114. function down()
  115.      while not turtle.down() do end
  116. end
  117.  
  118. function up()
  119.      while not turtle.up() do end
  120. end
  121.  
  122. function goto(start,dest)
  123.      save("location",{false,turtPos})
  124.      local dif = dest[2] - start[2]
  125.      while dif ~= 0 do
  126.           if dif > 0 then
  127.                down()
  128.                dif = dif - 1
  129.           else
  130.                up()
  131.                dif = dif + 1
  132.           end
  133.      end
  134.  
  135.      while start[3] > dest[3] do
  136.           turtle.turnLeft()
  137.           start[3] = start[3] - 1
  138.      end
  139.  
  140.      while start[3] < dest[3] do
  141.           turtle.turnRight()
  142.           start[3] = start[3] + 1
  143.      end
  144.      print("at: "..dest[2].. " ".. dest[3])
  145.      turtPos = dest
  146.      save("location",{true,turtPos})
  147. end
  148.  
  149. function listen()
  150.      while true do
  151.           local e = { os.pullEvent() }
  152.           if e[1] == "rednet_message" then
  153.                if e[3] then
  154.                     local msg = textutils.unserialize(e[3])
  155.                     if msg[1] ~= APK then
  156.                          if msg[1] == "request" then
  157.                           print("[MSG] "..e[2].. " " ..e[3])
  158.                               rednet.send(hostID,textutils.serialize({APK,storage}),channel)
  159.                           print("[SNT] ".. e[3].. " " .. "storage")
  160.                          else
  161.                               rednet.send(e[2],textutils.serialize({APK}),channel)
  162.                               table.insert(que,msg)
  163.                          end
  164.                     end
  165.                end
  166.           elseif e[1] == "timer" then
  167.                if e[2] == "waitForEmpty" then
  168.                     waitForEmpty = false
  169.                end
  170.           end
  171.      end
  172. end
  173.  
  174. function pullItems(name,count,b)
  175.      local r = count%64
  176.      local f = math.floor(count/64)
  177.      for i=1,16 do
  178.           if turtle.getItemCount(i) < 1 then
  179.                turtle.select(i)
  180.                break
  181.           end
  182.      end
  183.      
  184.      for i=1,f do
  185.           turtle.suck(64)
  186.           storage[name].pos[b][4] = storage[name].pos[b][4] - turtle.getItemCount()
  187.           save("storage",storage)
  188.           turtle.dropDown()
  189.      end
  190.      turtle.suck(r)
  191.      storage[name].pos[b][4] = storage[name].pos[b][4] - turtle.getItemCount()
  192.      save("storage",storage)
  193.      turtle.dropDown(r)
  194.      if storage[name].pos[b][4] == 0 then
  195.           table.remove(storage[name].pos,b)
  196.      end
  197.      if storage[name].pos == {} then
  198.           table.remove(storage, name)
  199.      end
  200. end
  201.  
  202. function dropItems(n,c,b)
  203.      print("Dropping: " .. n .. ": "..c)
  204.      for i=1,16 do
  205.           if c <= 0 then break end
  206.           local data = turtle.getItemDetail(i)
  207.           if data then
  208.                if data.name == n then
  209.                     turtle.select(i)
  210.                     if c > data.count then
  211.                          turtle.drop()
  212.                          storage[n].pos[b][4] =  storage[n].pos[b][4] + data.count
  213.      save("storage",storage)
  214.                          c = c - data.count
  215.                     else
  216.                          turtle.drop(c)
  217.                          storage[n].pos[b][4] = storage[n].pos[b][4] + c
  218.                          save("storage",storage)
  219.                          c = 0
  220.                     end
  221.                end
  222.           end
  223.      end
  224.      for l,g in pairs(storage[n].pos) do
  225.          print(l.. " ".. g[3].." ".. g[4])
  226.      end
  227.      
  228. end
  229.  
  230. function retrieveItems(tbl)
  231.      local count = tbl[2]
  232.      local list = {}
  233.      local pullList = {}
  234.      for k,v in pairs(storage) do
  235.           if storage[tbl[1]] then
  236.                for b in pairs(storage[tbl[1]].pos) do
  237.                     table.insert(list,{storage[tbl[1]].pos[b],b})
  238.                end
  239.           end
  240.      end
  241.  
  242.      table.sort(list, function(a,b) return a[4] < b[4] end)
  243.      
  244.      for k,v in pairs(list) do
  245.           if count <= 0 then break end
  246.           if v[1][4] - count > 0 then
  247.                table.insert(pullList,{v,count})
  248.                count = count - count
  249.           else
  250.                table.insert(pullList,{v,v[4]})
  251.                count = count - v[1][4]
  252.           end
  253.      end
  254.  
  255.      for k,v in pairs(pullList) do
  256.           goto(turtPos,pullList[k][1][1])
  257.           pullItems(tbl[1],pullList[k][2],pullList[k][1][2])
  258.      end
  259.      updateHost()
  260. end
  261.  
  262. function checkForItems()
  263. local trys = 0
  264.      while true do
  265.           if trys > 10 then break end
  266.           while turtle.suckUp() do
  267.                trys = 10 - 2
  268.           end
  269.           sleep(0.2)
  270.           trys = trys + 1
  271.      end
  272. storeItems()
  273. end
  274.  
  275. function awaitItems(tbl)
  276.      print(tbl[1].. ": "..tbl[2])
  277.      local msg = textutils.serialize({"s",{turtPos[1],tbl[1],tbl[2]}})
  278.      repeat rednet.send(hostID,msg,channel) until waitForResponse(hostID, 3)
  279.  
  280.      local trys = 0
  281.      while true do
  282.           if trys > 10 then break end
  283.           while turtle.suckUp() do
  284.                trys = 10 - 2
  285.           end
  286.           sleep(0.2)
  287.           trys = trys + 1
  288.      end
  289.  
  290.      storeItems()
  291. end
  292.  
  293. function findChest()
  294.      local list = {}
  295.      local aList = {}
  296.      for k,v in pairs(storage) do
  297.           for b in pairs(storage[k].pos) do
  298.                table.insert(list,{storage[k].pos[b][1],storage[k].pos[b][2],storage[k].pos[b][3]})
  299.           end
  300.      end
  301.  
  302.       for i=1,chestNum do
  303.            local p = {turtPos[1],math.floor(i/3),(i%3)+1}
  304.            table.insert(aList,p)
  305.       end
  306.  
  307.       local space = false
  308.       for k,v in pairs(aList) do
  309.            space = false
  310.            for b,c in pairs(list) do
  311.                 if c == v then
  312.                      space = true
  313.                      break
  314.                 end
  315.            end
  316.            
  317.            if not space then
  318.                 print("Free Chest: "..v[2].. " ".. v[3])
  319.                 table.insert(v,0)
  320.                 return v
  321.            end
  322.       end
  323.       return false
  324. end
  325.  
  326. function storeItems()
  327.  
  328.      for i=1,16 do
  329.          local chestList = {}
  330.          local data,dt = nil
  331.          local c = 0
  332.          data = turtle.getItemDetail(i)
  333.          if data then
  334.              c = c + data.count
  335.  
  336. --check to see if there are more like items--
  337.              for b=i,16 do
  338.                   dt = turtle.getItemDetail(b)
  339.                   if dt then
  340.                        if dt.name == data.name then
  341.                             c = c + dt.count
  342.                        end
  343.                   end
  344.              end
  345.  
  346. --find a chest for items--
  347.              local nm = data.name
  348.              if storage[nm] then
  349.                   for v in pairs(storage[nm].pos) do
  350.                        print(nm.. ": ".. storage[nm].pos[v][2].. " ".. storage[nm].pos[v][3])
  351.                        if storage[nm].pos[v][4] + c <= chestSize then
  352.                             table.insert(chestList,{nm,storage[nm].pos[v],c,v})
  353.                             c = 0
  354.                        else
  355.                             local tmpA = chestSize - storage[nm].pos[v][4]
  356.                             table.insert(chestList, {nm,storage[nm].pos[v],tmpA,v})
  357.                             c = c - tmpA
  358.                        end
  359.                   end
  360.              end
  361.  
  362. --generate new chest--
  363.              if c > 0 then
  364.                   print("Gen Chest: " .. nm .. " "..c)
  365.                   local nxtChest = findChest()
  366.                   if nxtChest then
  367.                        if storage[nm] then
  368.                             storage[nm].pos[#storage[nm].pos + 1] = nxtChest
  369.                        else
  370.                             storage[nm] = {pos={}}
  371.                             storage[nm].pos[1] = nxtChest
  372.                        end
  373.  
  374.                        table.insert(chestList,{nm,nxtChest,c,#storage[nm].pos})
  375.                   else
  376.                        print("No Chest Found")
  377.                        table.insert(chestList,{nm,{-1},c,0})
  378.                   end
  379.              end
  380.              
  381. --move to all chest--
  382.                for k,v in pairs(chestList) do
  383.                     if chestList[k][2][1] >= 0 then
  384.                          goto(turtPos,chestList[k][2])
  385.                          dropItems(chestList[k][1],chestList[k][3],chestList[k][4])
  386.                     else
  387.                          local amt = chestList[k][3]
  388.                          for i=1,16 do
  389.                               local d = turtle.getItemDetail(i)
  390.                               if d then
  391.                                    if d.name == chestList[k][1] then
  392.                                         turtle.select(i)
  393.                                         if amt > 63 then
  394.                                              turtle.dropDown()
  395.                                              amt = amt - d.count
  396.                                         else
  397.                                              turtle.dropDown(amt)
  398.                                              amt = amt - d.count
  399.                                         end
  400.                                    end
  401.                               end
  402.                          end
  403.                     end
  404.                end
  405.               updateHost()
  406.          end
  407.      end
  408. end
  409.  
  410. function updateHost()
  411.      local msg = textutils.serialize({"u",{turtPos[1],storage}})
  412.      repeat rednet.send(hostID,msg,channel) until waitForResponse(hostID,3)
  413. end
  414.  
  415.  
  416. function taskManager()
  417.      while true do
  418.           while que[1] do
  419.               if que[1][1] == "r" then
  420.                    print("retrieve items")
  421.                    retrieveItems(que[1][2])
  422.               elseif que[1][1] == "a" then
  423.                    print("await items")
  424.                    awaitItems(que[1][2])
  425.               elseif que[1][1] == "s" then
  426.                    print("store items")
  427.                    storeItems(que[1][2])
  428.               end
  429.               table.remove(que,1)
  430.               print("que: " .. #que)
  431.           end
  432.           sleep(1)
  433.           checkForItems()
  434.      end
  435. end
  436.  
  437. init()
  438. parallel.waitForAll(listen,taskManager)
Add Comment
Please, Sign In to add comment