Advertisement
NanoBob

[OLD] computercraft storage server

Jun 21st, 2016
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.67 KB | None | 0 0
  1. local localChannel=666
  2.  
  3. if fs.exists("event")==false then shell.run("pastebin get L7KYC10V event") end
  4. os.loadAPI("event")
  5.  
  6. if fs.exists("utils")==false then shell.run("pastebin get c4CBkgKV utils") end
  7. os.loadAPI("utils")
  8.  
  9. if fs.exists("data")==false then shell.run("pastebin get 5FpayqrQ data") end
  10. if os.loadAPI("data")==false then error("Failed to load data API") end
  11.  
  12. local taskQue = {}
  13.  
  14. local turtles = {}
  15.  
  16. local craftQue = {}
  17.  
  18. local chests={
  19.     {chest=peripheral.wrap("iron_0"),pos={x=156,y=5,z=260}},
  20.     {chest=peripheral.wrap("iron_1"),pos={x=157,y=5,z=260}},
  21.     {chest=peripheral.wrap("iron_2"),pos={x=158,y=5,z=260}},
  22.     {chest=peripheral.wrap("iron_3"),pos={x=159,y=5,z=260}},
  23.     {chest=peripheral.wrap("iron_4"),pos={x=160,y=5,z=260}},
  24.     {chest=peripheral.wrap("iron_5"),pos={x=161,y=5,z=260}},
  25.     {chest=peripheral.wrap("iron_6"),pos={x=162,y=5,z=260}},
  26.     {chest=peripheral.wrap("iron_7"),pos={x=163,y=5,z=260}},
  27.     {chest=peripheral.wrap("iron_8"),pos={x=164,y=5,z=260}},
  28.     {chest=peripheral.wrap("iron_9"),pos={x=165,y=5,z=260}},
  29. }
  30.  
  31. local rest={x=156,y=7,z=263}
  32.  
  33. local pingLimit = 10
  34. local items={}
  35. local modems={}
  36. local drop={x=160,y=6,z=264}
  37. local turtleTimer = os.startTimer(10)
  38.  
  39. function init()
  40.     modem=peripheral.wrap("back")
  41.     modem.open(localChannel)
  42.     modems["back"]=modem
  43.     modems["wired"]=modem
  44.     wireless=peripheral.wrap("bottom")
  45.     wireless.open(localChannel)
  46.     modems["bottom"]=wireless
  47.     modems["wireless"]=wireless
  48. end
  49. init()
  50.  
  51. function indexItems()
  52.     items={}
  53.     for chestID,chest in pairs(chests) do
  54.         for i,stack in pairs(chest.chest.getAllStacks()) do
  55.             local data=stack.all()
  56.             if items[string.lower(data.display_name)]==nil then
  57.                 items[string.lower(data.display_name)]={[chestID]=data.qty}
  58.             else
  59.                 if items[string.lower(data.display_name)][chestID]==nil then
  60.                     items[string.lower(data.display_name)][chestID]=data.qty
  61.                 else
  62.                     items[string.lower(data.display_name)][chestID]=items[string.lower(data.display_name)][chestID]+data.qty
  63.                 end            
  64.             end
  65.         end
  66.     end
  67. end
  68. indexItems()
  69.  
  70. function getItemCount(name)
  71.     local item=items[string.lower(name)]
  72.     if item==nil then return 0 end
  73.     local count=0
  74.     for chestID,itemCount in pairs(item) do
  75.         count=count+itemCount
  76.     end
  77.     return count
  78. end
  79.  
  80. function getItemPosition(name,count)
  81.     local item=items[string.lower(name)]
  82.     if item==nil then return end
  83.     local positions={}
  84.     if count==0 then
  85.         count=1
  86.     end
  87.     local remainder=count
  88.     for chestID,itemCount in pairs(item) do
  89.         remainder=remainder-itemCount
  90.         positions[#positions+1]={pos=chests[chestID].pos,count=itemCount}
  91.         if remainder<=0 then
  92.             return positions
  93.         end
  94.     end
  95.     return positions
  96. end
  97.  
  98. function getIdleTurtle()
  99.     for id,turtle in pairs(turtles) do
  100.         if turtle.status=="idle" then
  101.             return turtle
  102.         end
  103.     end
  104.     return nil
  105. end
  106.  
  107. function statusUpdate(channel,turtle,previous,new)
  108.     --print("Que:\n"..textutils.serialise(taskQue))
  109.     if new=="idle" then
  110.         turtle.task=nil
  111.         if #taskQue==0 then
  112.             if #craftQue == 0 then return end
  113.             for i,queEntry in ipairs(craftQue) do
  114.                 if craftItem(queEntry.item,queEntry.count,true) == true then
  115.                     craftItem(queEntry.item,queEntry.count)
  116.                     return
  117.                 end
  118.             end
  119.             return
  120.         end
  121.         modems["wireless"].transmit(channel,localChannel,taskQue[1])
  122.         turtle.task=taskQue[1]
  123.         turtle.status="working"
  124.         for id,data in ipairs(taskQue) do
  125.             taskQue[id-1]=data
  126.         end
  127.         taskQue[0]=nil
  128.         taskQue[#taskQue]=nil
  129.     end
  130. end
  131. event.addHandler("onTurtleStatusChange",statusUpdate)
  132.  
  133. function turtleTimed(turtle,channel)
  134.     local command = turtle.task
  135.     if command == nil then return end
  136.     local turtle=getIdleTurtle()
  137.     if turtle==nil then
  138.         taskQue[#taskQue+1]=command
  139.     else
  140.         modems["wireless"].transmit(turtle.channel,localChannel,command)
  141.         turtle.task=command
  142.         turtle.status="working"
  143.     end
  144. end
  145. event.addHandler("onTurtleTimeout",turtleTimed)
  146.  
  147. function createRecipe(targetItem,recipeString)
  148.     data.set(targetItem,recipeString)
  149. end
  150.  
  151. function checkTurtleConnectionTimer(timer)
  152.     if timer ~= turtleTimer then return end
  153.    
  154.     for channel,turtle in pairs(turtles) do
  155.         if turtle.lastMessage < os.clock() - 60 then
  156.             turtle.missed = turtle.missed + 1
  157.             if turtle.missed > pingLimit then
  158.                 --print("Turtle " .. channel .. " has timed out")
  159.                 event.trigger("onTurtleTimeout",turtle,channel)
  160.                 turtles[channel] = nil
  161.             end
  162.         else
  163.             turtle.missed = 0
  164.         end
  165.     end
  166.     --[[
  167.     for channel,turtle in pairs(turtles) do
  168.         if turtle.timer == timer then
  169.             ping(channel)
  170.             if turtle.pingTimer == nil then
  171.                 turtle.missed = 0
  172.                 turtle.pingTimer = os.startTimer(10)
  173.             end
  174.         elseif turtle.pingTimer == timer  and turtle.missed == pingLimit then
  175.             --print("Turtle " .. channel .. " has timed out")
  176.             event.trigger("onTurtleTimeout",turtle,channel)
  177.             turtles[channel] = nil
  178.             return
  179.         elseif turtle.pingTimer == timer and turtle.missed then
  180.             turtle.pingTimer = os.startTimer(10)
  181.             turtle.missed = turtle.missed + 1
  182.         end
  183.     end
  184.     ]]
  185.     turtleTimer = os.startTimer(10)
  186. end
  187. event.addHandler("timer",checkTurtleConnectionTimer)
  188.  
  189. function craftItem(itemName,count,check)
  190.     local hasSubs = false
  191.     local recipe = data.get(itemName,"db/recipes")
  192.     if recipe==nil or recipe=="nil" then return end    
  193.     local command = "craft|"..count.."|"
  194.     for i=1,9 do
  195.         local item = utils.split(recipe,";",i)
  196.         local positions = getItemPosition(item,count)
  197.         local itemFound = false
  198.         if item~=nil and positions ~=nil then
  199.             local remainder=count
  200.             for chestID,data in pairs(positions) do
  201.                 local count=data.count
  202.                 if count>=remainder then
  203.                     command = command .. item ..";".. data.pos.x ..",".. data.pos.y ..",".. data.pos.z .. ";"..i.."|"
  204.                     itemFound = true
  205.                     break
  206.                 end
  207.             end
  208.             if itemFound == false then
  209.                 if data.get(item,"db/recipes")~=nil then
  210.                     command = command .. craftItem(item,count)
  211.                     hasSubs = true
  212.                 end
  213.             end
  214.         elseif positions == nil then
  215.             ----print("item not found in system "..tostring(item).." Recipe: "..tostring(not ( data.get(item,"db/recipes") == nil ) ) )
  216.             if data.get(item,"db/recipes")~=nil then
  217.                 command = command .. craftItem(item,count)
  218.                 hasSubs = true
  219.             end
  220.         end
  221.     end
  222.    
  223.     if hasSubs == true then
  224.         craftQue[#craftQue+1] = { item = itemName, count = count }
  225.     end
  226.     if check == true and hasSubs == false then
  227.         return true
  228.     elseif check == true then
  229.         return false
  230.     end
  231.     local turtle = getIdleTurtle()
  232.     if turtle==nil then
  233.         taskQue[#taskQue+1]=command
  234.     else
  235.         modems["wireless"].transmit(turtle.channel,localChannel,command)
  236.         turtle.task=command
  237.         turtle.status="working"
  238.     end
  239. end
  240.  
  241. function ping(channel)
  242.     modems.wireless.transmit(channel,localChannel,"ping")
  243. end
  244.  
  245. local messageHandles={
  246.     ["ping"]=function(replyChannel,message)
  247.         if turtles[replyChannel]==nil then return end
  248.         event.trigger("onPing",replyChannel)
  249.         return "pong"
  250.     end,
  251.    
  252.     ["pong"]=function(replyChannel,message)
  253.         if turtles[replyChannel]==nil then return end
  254.         event.trigger("onPong",replyChannel)
  255.     end,
  256.    
  257.     ["getItemCount"]=function(replyChannel,message)
  258.         indexItems()
  259.         local itemName=utils.split(message,"|",2)
  260.         return "returnItemCount|"..getItemCount(itemName)
  261.     end,
  262.    
  263.     ["requestItemList"]=function(replyChannel,message)
  264.         indexItems()
  265.         local itemString=""
  266.         for itemname,chests in pairs(items) do
  267.             itemString=itemString..itemname..","..getItemCount(itemname)..";"
  268.         end
  269.         return "returnItemList|"..itemString
  270.     end,
  271.    
  272.     ["requestTurtles"]=function(replyChannel,message)
  273.         local turtleString=""
  274.         for channel,turtle in pairs(turtles) do
  275.             turtleString=turtleString..channel..","..turtle.status..","..tostring(turtle.task)..";"
  276.         end
  277.         return "returnTurtles|"..turtleString
  278.     end,
  279.    
  280.     ["requestQue"]=function(replyChannel,message)
  281.         local queString=""
  282.         for _,queCommand in pairs(taskQue) do
  283.             queString=queString..string.gsub(queCommand,"|",";").."|"
  284.         end
  285.         return "returnQue|"..queString
  286.     end,
  287.    
  288.     ["requestItem"]=function(replyChannel,message)
  289.         indexItems()
  290.         local itemName=utils.split(message,"|",2)
  291.         local count=tonumber(utils.split(message,"|",3))
  292.         --print("Item request: "..itemName.."x"..count)
  293.         local positions=getItemPosition(itemName,count)
  294.         local remainder=count
  295.         if positions==nil then return end
  296.         for chestID,data in pairs(positions) do
  297.             ----print(chestID)
  298.             local count=data.count
  299.             if count>remainder then
  300.                 count=remainder
  301.             end
  302.             remainder=remainder-count
  303.             local command="get|"..itemName.."|"..count.."|"..data.pos.x..","..data.pos.y..","..data.pos.z
  304.             --print("Command: "..command)
  305.             local turtle=getIdleTurtle()
  306.             if turtle==nil then
  307.                 taskQue[#taskQue+1]=command
  308.             else
  309.                 modems["wireless"].transmit(turtle.channel,localChannel,command)
  310.                 turtle.task=command
  311.                 turtle.status="working"
  312.             end
  313.             if remainder<=0 then
  314.                 return
  315.             end
  316.         end
  317.     end,
  318.    
  319.     ["addRecipe"]=function(replyChannel,message)
  320.         local item = utils.split(message,"|",2)
  321.         local recipe = utils.split(message,"|",3)
  322.         data.set(item,recipe,"db/recipes")
  323.         --print("Adding recipe: "..recipe)
  324.     end,
  325.    
  326.     ["requestRecipes"]=function(replyChannel,message)
  327.         local returnString = "returnRecipes|"
  328.         for id,_ in pairs(data.getAll("db/recipes")) do
  329.             returnString = returnString .. id .. ";"
  330.         end
  331.         return returnString
  332.     end,
  333.    
  334.     ["requestCraft"]=function(replyChannel,message)
  335.         local itemName=utils.split(message,"|",2)
  336.         local count=tonumber(utils.split(message,"|",3))
  337.         craftItem(itemName,count)
  338.     end,
  339.    
  340.     ["getItemPosition"]=function(replyChannel,message)
  341.         indexItems()
  342.         local itemName=utils.split(message,"|",2)
  343.         local posString=""
  344.         local positions=getItemPosition(itemName)
  345.         if positions==nil then return end
  346.         for _,pos in pairs(positions) do
  347.             posString=posString..x..","..y..","..z.."|"
  348.         end
  349.         return posString
  350.     end,
  351.    
  352.     ["sendToTurtles"]=function(replyChannel,message)
  353.         local turtleChannel=utils.split(message,"|",2)
  354.         local message=utils.split(message,"|",3)
  355.         local turtle=turtles[replyChannel]
  356.         turtle.task=message
  357.         turtle.status="working"
  358.        
  359.     end,
  360.    
  361.     ["indexItems"]=function(replyChannel,message)
  362.         indexItems()
  363.         return "confirmed"
  364.     end,
  365.    
  366.     ["assign"]=function(replyChannel)
  367.         if turtles[replyChannel]==nil then
  368.             turtles[replyChannel]={
  369.                 channel=replyChannel,
  370.                 status="idle",
  371.                 timer=os.startTimer(10),
  372.             }
  373.             event.trigger("onTurtleAssign",replyChannel,turtles[replyChannel],"confirmed")
  374.             event.trigger("onTurtleStatusChange",replyChannel,turtles[replyChannel],false,"idle")
  375.             return "confirmed"
  376.         else
  377.             event.trigger("onTurtleAssign",replyChannel,turtles[replyChannel],"denied")
  378.             return "denied"
  379.         end
  380.     end,
  381.    
  382.     ["status"]=function(replyChannel,message)
  383.         if turtles[replyChannel]==nil then
  384.             return "denied"
  385.         end
  386.         local previous=turtles[replyChannel].status
  387.         local status=utils.split(message,"|",2)
  388.         turtles[replyChannel].status=status
  389.         event.trigger("onTurtleStatusChange",replyChannel,turtles[replyChannel],previous,status)
  390.     end,
  391.    
  392.     ["requestDropoff"]=function(replyChannel,message)
  393.         return "returnDropoff|"..drop.x..","..drop.y..","..drop.z
  394.     end,
  395.    
  396.     ["requestRestPos"]=function(replyChannel,message)
  397.         return "returnHomePos|"..rest.x..","..rest.y..","..rest.z
  398.     end,
  399. }
  400.  
  401.  
  402. function handleMessages(side,channel,replyChannel,message)
  403.     --print(replyChannel.." : "..message)
  404.     local messageType=utils.split(message,"|",1)
  405.     if messageHandles[messageType]==nil then return end
  406.     local returnMessage=messageHandles[messageType](replyChannel,message)
  407.     sleep(0.10)
  408.     if returnMessage==nil then return end
  409.     --print(replyChannel .. " : " .. returnMessage)
  410.     modems[side].transmit(replyChannel,localChannel,returnMessage)
  411. end
  412. event.addHandler("modem_message",handleMessages)
  413.  
  414. while true do
  415.     event.handleCCEvents()
  416. end
  417. print("ENDED GRACEFULLY")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement