bcash8

StorageSystem Server

Feb 13th, 2021 (edited)
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.75 KB | None | 0 0
  1. turts = {15}
  2. redstone = {2}
  3. chestSize = 54*64
  4. chestNum = 10*3
  5. channel = "storageSys:1"
  6.  
  7.  
  8. APK = "APK"
  9. storage = {}
  10. que = {}
  11. waitToEmpty = false
  12. wait = nil
  13.  
  14. function init()
  15.  
  16. --open rednet--
  17.      if not rednet.isOpen("right") then
  18.           rednet.open("right")
  19.      end
  20.      sleep(10)
  21.      for k,v in pairs(redstone) do
  22.           rednet.send(v,"off",channel)
  23.      end
  24. -- call all our turtles and get storage info--
  25.       callTurtles()
  26.      
  27.       return true
  28. end
  29.  
  30. function waitForResponse(id,tries)
  31.      if not tries then tries =  3 end
  32.      local sndr,msg,nTry = nil,nil,0
  33.      
  34.      while true do
  35.           if nTry > tries then break end
  36.           sndr,m = rednet.receive(channel,1)
  37.           if m then
  38.               msg = textutils.unserialize(m)
  39.           end
  40.           if sndr == id then
  41.                if msg[1] == APK then
  42.                     return msg
  43.                end
  44.           elseif not sndr then
  45.                 nTry = nTry + 1
  46.            end
  47.      end
  48.      return true
  49. end
  50.  
  51. function getTableSize(t)
  52.      local count = 0
  53.      for _ in pairs(t) do
  54.           count = count + 1
  55.      end
  56.      return count  
  57. end
  58.  
  59. function callTurtles()
  60.     local req = textutils.serialize({"request"})
  61.     print("Pinging Turtles")
  62.      for i=1,#turts do
  63.           rednet.send(turts[i],req,channel)
  64.           local data = waitForResponse(turts[i],3)
  65.           if data ~= true then
  66.                if data[2] then
  67.                     storage[i] = data[2]
  68.                     print("Recieved Storage from: "..i)
  69.                else
  70.                     print("Couldnt get storage: "..i)
  71.                end
  72.            end
  73.      end
  74.      if #storage == #turts then
  75.           return true
  76.      else
  77.           return false
  78.      end
  79. end
  80.  
  81. function sendItems(tbl)
  82.      turtle.select(1)
  83.      local count = tbl[3]
  84.      rednet.send(redstone[tbl[1]],"on",channel)
  85.      for i=1,16 do
  86.           if count <= 0 then break end
  87.           local data = turtle.getItemDetail(i)
  88.           if data then
  89.                if data.name == tbl[2] then
  90.                     turtle.select(i)
  91.                     if count > 63 then
  92.                          turtle.drop()
  93.                          count = count - data.count
  94.                     else
  95.                          turtle.drop(count)
  96.                          count = count - data.count
  97.                     end
  98.                end
  99.           end
  100.      end
  101.      sleep(3)
  102.      rednet.send(redstone[tbl[1]],"off",channel)
  103. end
  104.  
  105. function retrieveItems(tbl)
  106. local name,count = tbl[2],tbl[3]
  107. local sendList = {}
  108. local list = {}
  109.      for k in pairs(storage) do
  110.           if storage[k][name] then
  111.                for b in pairs(storage[k][name].pos) do
  112.                     table.insert(list,storage[k][name].pos[b])
  113.                end
  114.           end
  115.      end
  116.      table.sort(list, function(a,b) return a[4] < b[4] end)
  117.  
  118.      for k,v in ipairs(list) do
  119.           if count <= 0 then break end
  120.           if v[4] >= count then
  121.                table.insert(sendList,{v[1],count})
  122.                count = 0
  123.           else
  124.                table.insert(sendList,{v[1],v[4]})
  125.                count = count - v[4]
  126.           end
  127.      end
  128.  
  129.      for k,v in pairs(sendList) do
  130.           local msg = textutils.serialize({"r",{name,v[4]}})
  131.                repeat rednet.send(turts[v[1]],msg,channel) until waitForResponse(turts[v[1]],2)
  132.      end
  133.      
  134. end
  135.  
  136. function queryItems(tbl)
  137.      if not tbl[2] then
  138.           msg = textutils.serialize(storage)
  139.      else
  140.           local count = 0
  141.           for k in pairs(storage) do
  142.                if storage[k][tbl[2]] then
  143.                     for b,c in pairs(storage[k][tbl[2]].pos) do
  144.                          count = count + storage[k][tbl[2]].pos[b][4]
  145.                     end
  146.                end
  147.           end
  148.           msg = textutils.serialize({tbl[2],count})
  149.      end
  150.      rednet.send(tbl[1],msg,channel)
  151. end
  152.  
  153. function checkForSpace(name,c)
  154.      local list = {}
  155.      for k in pairs(storage) do
  156.           if storage[k][name] then
  157.                for b in pairs(storage[k][name].pos) do
  158.                     if c <= 0 then return list end
  159.                     if chestSize - storage[k][name].pos[b][4] > c then
  160.                          if not list[k] then
  161.                               list[k] = c
  162.                          else
  163.                               list[k] = list[k] + c
  164.                          end
  165.                          c = 0
  166.                     else
  167.                          local count = chestSize - storage[k][name].pos[b][4]
  168.                          if not list[k] then
  169.                               list[k] = count
  170.                          else
  171.                               list[k] = list[k] + count
  172.                          end
  173.                          c = c - count
  174.                     end
  175.                end
  176.           end
  177.      end
  178.  
  179.      if c > 0 then
  180.           local small = -1
  181.           local prevSmall = math.huge
  182.           for i,v in pairs(storage) do
  183.                local count = 0
  184.                for k,c in pairs(storage[i]) do
  185.                     count = count + getTableSize(storage[i][k].pos)
  186.                end
  187.                if count < prevSmall then
  188.                     prevSmall = count
  189.                     small = i
  190.                end
  191.           end
  192.           if prevSmall >= chestSize*chestNum then
  193.                list["full"]  = c
  194.           else
  195.                if list[small] then
  196.                     list[small] = list[small] + c
  197.                else
  198.                     list[small] = c
  199.                end
  200.           end
  201.           c = 0
  202.      end
  203.      return list
  204. end
  205.  
  206. function prepareTurtle(tbl)
  207.      local list = {}
  208.      
  209.      for k,v in pairs(tbl) do
  210.           list[k] = checkForSpace(k,v)
  211.      end
  212.  
  213.      for k,v in pairs(list) do
  214.           for b in pairs(list[k]) do
  215.                local msg = textutils.serialize({"a",{k,list[k][b]}})
  216.                repeat rednet.send(turts[b],msg,channel) until waitForResponse(turts[b])
  217.           end
  218.      end
  219.      wait = os.startTimer(95)
  220.      waitToEmpty = true
  221. end
  222.  
  223. function checkForItems()
  224.      local list = {}
  225.      
  226.      
  227.      
  228.      if not waitToEmpty then
  229.           if turtle.suckUp() then
  230.                local trys = 0
  231.                while true do
  232.                     if trys > 4 then break end
  233.                     while turtle.suckUp() do end
  234.                     trys = trys + 1
  235.                     sleep(0.5)  
  236.                end
  237.           end
  238.  
  239.           for i=1,16 do
  240.                 local data = turtle.getItemDetail(i)
  241.                 if data then
  242.                      if not list[data.name] then
  243.                           list[data.name] = data.count
  244.                      else
  245.                           list[data.name] = list[data.name] + data.count
  246.                      end
  247.                 end
  248.           end
  249.           prepareTurtle(list)
  250.      else
  251.           for i=1,16 do
  252.                if turtle.getItemCount(i) > 0 then
  253.                     break
  254.                end
  255.                waitToEmpty = false
  256.                os.cancelTimer(wait)
  257.           end
  258.      end
  259. end
  260.  
  261. function updateStorage(tbl)
  262.      storage[tbl[1]] = tbl[2]
  263. end
  264.  
  265. function listen()
  266.      while true do
  267.           e = {}
  268.           e = { os.pullEvent() }
  269.           if e[1] == "rednet_message" then
  270.           if e[2] ~= os.getComputerID() then
  271.                if e[3] then
  272.                   print(e[2].. ": ".. e[3])
  273.                   local msg = textutils.unserialize(e[3])
  274.                   print("[MSG] "..e[2].." " ..msg[1])
  275.                   print(msg[1])
  276.                     if msg[1] ~= APK then
  277.                         if msg[1] == "u" then
  278.                              updateStorage(msg[2])
  279.                         else
  280.                               table.insert(que,msg)
  281.                          end
  282. rednet.send(e[2],textutils.serialize({APK}),channel)
  283.                      end
  284.                 end
  285.           end
  286.           elseif e[1] == "timer" then
  287.                if e[2] == "wait" then
  288.                     waitToEmpty = false
  289.                end
  290.           end
  291.      end
  292. end
  293.  
  294. function taskManager()
  295.      while true do
  296.           while que[1] do
  297.                if que[1][1] == "r" then
  298.                     print("retrieve items")
  299.                     retrieveItems(que[1][2])
  300.                elseif que[1][1] == "s" then
  301.                     print("send Items")
  302.                     sendItems(que[1][2])
  303.                elseif que[1][1] == "q" then
  304.                     print("query items")
  305.                     queryItems(que[1][2])
  306.                end
  307.                table.remove(que ,1)
  308.           end
  309.           checkForItems()
  310.           sleep(1)
  311.      end
  312. end
  313.  
  314. init()
  315.  
  316. while not storage[1] do
  317.      sleep(5)
  318.      callTurtles()
  319. end
  320.  
  321. parallel.waitForAll(listen,taskManager)
Add Comment
Please, Sign In to add comment