Advertisement
Skortioth

[OC] Refined Storage - Autocrafter

Jul 7th, 2020 (edited)
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.20 KB | None | 0 0
  1. --Server performant version
  2. --this script is a server performant (but slower) version
  3.  
  4. --a adapter has to be connected to a chest and a refinedstorage exporter
  5. --just insert any item you want in the chest and wait until the script says that the recipe has been registered
  6. --the count in the chest is the count the autocrafter will craft for you as a example: put 64 sticks in the chest, after that
  7. --autocrafter will always try to craft to 64 sticks for you (if there is less than 64 sticks in your refined storage)
  8.  
  9. --The amount of crafting co-workers
  10. local coworker = 1
  11.  
  12. --The max allowed tasks in refined storage
  13. local maxTasks = 4
  14. --
  15.  
  16. function StringSeperate(str, seperator)
  17. local words = {}
  18. local word = ""
  19. if(string.sub(str,str:len(),str:len())~="sperator")then
  20.     str = str .. "" .. seperator
  21. end
  22.     for x=1,str:len() do
  23.         local s = string.sub(str,x,x)
  24.         if(s==seperator)then
  25.             table.insert(words, word)
  26.             word = ""
  27.         else
  28.             word = word .. string.sub(str,x,x)
  29.         end
  30.     end
  31.     return words
  32. end
  33.  
  34. local recipeList = {}
  35.  
  36. local f = io.open("recipes", "ab")
  37.     for line in io.lines("recipes") do
  38.         local tab = StringSeperate(line, "|")
  39.         if(tab[1]~=nil)and(tab[2]~=nil)and(tab[3]~=nil)and(tab[4]~=nil)and(tab[5]~=nil)then
  40.             print("Registered recipe: "..tab[3].."x " ..tab[1].. ":"..tab[2])
  41.             os.sleep(0.1)
  42.             local recipe = {name=tab[1],damage=tonumber(tab[2]),minAmount=tonumber(tab[3]),maxCraftAmount=tonumber(tab[4]),fails = 0,timer=0}
  43.             if(tab[5]=="true")then
  44.                 recipe.useDmg = true
  45.             else
  46.                 recipe.useDmg = false
  47.             end
  48.             table.insert(recipeList,recipe)
  49.         end
  50.     end
  51. f:close()
  52.  
  53. local component = require("component")
  54. local rs = component.block_refinedstorage_exporter
  55. local inventory = component.inventory_controller
  56. local side = require("sides")
  57.  
  58. local craftingQueue = {}
  59.  
  60. function GetRecipe(pattern)
  61.     for k,v in pairs(recipeList)do
  62.         if(v.name == pattern.name)then
  63.             if(v.useDmg)then
  64.                 if(v.damage == pattern.damage)then
  65.                     return v
  66.                 end
  67.             else
  68.                 return v
  69.             end
  70.         end
  71.     end
  72.     return nil
  73. end
  74.  
  75. function GetRecipeKey(pattern)
  76.     for k,v in pairs(recipeList)do
  77.         if(v.name == pattern.name)then
  78.             if(v.useDmg)then
  79.                 if(v.damage == pattern.damage)then
  80.                     return k
  81.                 end
  82.             else
  83.                 return k
  84.             end
  85.         end
  86.     end
  87.     return nil
  88. end
  89.  
  90. function GetAmount(itemAmount, recipe)
  91. local amount = 0
  92.     if(itemAmount < recipe.minAmount)then
  93.         if(recipe.maxCraftAmount > 0)then
  94.             if(recipe.minAmount-itemAmount > recipe.maxCraftAmount)then
  95.                 amount = recipe.maxCraftAmount
  96.             else
  97.                 amount = recipe.minAmount-itemAmount
  98.             end
  99.         else
  100.             amount = recipe.minAmount-itemAmount
  101.         end
  102.     end
  103.     return amount
  104. end
  105.  
  106. function CheckRequirements(pattern, recipe)
  107.     if(recipe.require~=nil)then
  108.         if(#recipe.require>0)then
  109.             for k,v in pairs(recipe.require)do
  110.                 local item = rs.getItem(v)
  111.                 if(v.minAmount > item.size)then
  112.                     return false
  113.                 end
  114.             end
  115.         end
  116.     end
  117.     return true
  118. end
  119.  
  120. function CheckCrafting(pattern)
  121.     local recipe = GetRecipe(pattern)
  122.     if(recipe~=nil)then
  123.         local item = rs.getItem(pattern)
  124.         local amount = 0
  125.         if(item~=nil)then
  126.             amount = GetAmount(item.size, recipe)
  127.         else
  128.             amount = GetAmount(0, recipe)
  129.         end
  130.         if(amount > 0)then
  131.             --if(CheckRequirements(pattern, recipe))then
  132.             table.insert(craftingQueue, {item=pattern, amount=amount})
  133.             --end
  134.         end
  135.     end
  136.     return false
  137. end
  138.  
  139. function CheckItems()
  140.     for k,v in pairs(rs.getPatterns())do
  141.         if(type(v)=="table")then
  142.             CheckCrafting(v)
  143.             os.sleep(0.25)
  144.         end
  145.     end
  146. end
  147.  
  148. function FindKeyInTable(table, item)
  149.     for k,v in pairs(table)do
  150.         if(v==item)then
  151.             return k
  152.         end
  153.     end
  154.     return nil
  155. end
  156.  
  157. function IsTaskActive(task)
  158.     for k,v in pairs(rs.getTasks())do
  159.         if(type(v)=="table")then
  160.             if(v.stack.item.name==task.stack.item.name)and(v.stack.item.damage==task.stack.item.damage)then
  161.                 return true
  162.             end
  163.         end
  164.     end
  165.     return false
  166. end
  167.  
  168. function RemoveRecipe(item)
  169. local key = -1
  170.     for k,v in pairs(recipeList)do
  171.         if(v.name == item.name)and(v.damage== item.damage)then
  172.             key = k
  173.         end
  174.     end
  175.     if(key>=0)then
  176.         table.remove(recipeList, key)
  177.     end
  178.     SaveToFile()
  179. end
  180.  
  181. function UpdateCraftingQueue()
  182.     while(#craftingQueue > 0)do
  183.         local activeCoWorkers = {}
  184.         local coworkerAmount = 0
  185.         local craftingQueuesToRemove = {}
  186.         for k,v in pairs(craftingQueue)do
  187.             if(coworkerAmount+1 <= coworker)then
  188.                 local recipeKey = GetRecipeKey(v.item)
  189.  
  190.                 local waittimer = 0
  191.                 local multiplier = 1
  192.  
  193.                 if(recipeList[recipeKey].fails > 0)and(recipeList[recipeKey].fails <=10)then
  194.                     multiplier = recipeList[recipeKey].fails
  195.                 elseif(recipeList[recipeKey].fails > 10)then
  196.                     multiplier = 10
  197.                 end
  198.                 waittimer = multiplier * 3000
  199.                 --[[if(v.item.label=="Ultra Ball")then
  200.                     if(os.time()>=recipeList[recipeKey].timer+waittimer)then
  201.                     print("Time: "..os.time().." "..recipeList[recipeKey].timer+waittimer.." true")
  202.                     else
  203.                         print("Time: "..os.time().." "..recipeList[recipeKey].timer+waittimer.." false")
  204.                     end
  205.                 end]]
  206.                 if(os.time()>=recipeList[recipeKey].timer+waittimer)then
  207.                     local task, info = pcall(rs.scheduleTask, v.item, v.amount)
  208.                     if(task)then
  209.                         print("Scheduled Task: "..v.amount.." "..v.item.label)
  210.                         if(info.missing.n > 0)then
  211.                             local missingItems = ""
  212.                             for a,b in pairs(info.missing)do
  213.                                 if(type(b)=="table")then
  214.                                     missingItems = missingItems .. b.size.."x "..b.label.." "
  215.                                 end
  216.                             end
  217.                             print("Missing Items: "..missingItems.." ")
  218.                             recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
  219.                             recipeList[recipeKey].timer = os.time()
  220.                         else
  221.                             table.insert(activeCoWorkers, info)
  222.                             coworkerAmount = coworkerAmount + 1
  223.                             recipeList[recipeKey].fails = 0
  224.                         end
  225.                     else
  226.                         print("------------------")
  227.                         print("Error scheduling task: "..v.amount.." "..v.item.label)
  228.                         print("Error message: " ..info)
  229.                         print("Recipe got removed from the recipe list")
  230.                         print("------------------")
  231.                         RemoveRecipe(v.item)
  232.                     end
  233.                 end
  234.                 table.insert(craftingQueuesToRemove, v)
  235.             end
  236.         end
  237.  
  238.         if(#craftingQueuesToRemove > 0)then
  239.             for k,v in pairs(craftingQueuesToRemove)do
  240.                 local id = FindKeyInTable(craftingQueue, v)
  241.                 table.remove(craftingQueue, id)
  242.             end
  243.         end
  244.  
  245.         while(#activeCoWorkers > 0)do
  246.             local finishedCoworker = {}
  247.             for k,v in pairs(activeCoWorkers)do
  248.                 if(IsTaskActive(v) ~= true)then
  249.                     table.insert(finishedCoworker, v)
  250.                 end
  251.             end
  252.             if(#finishedCoworker>0)then
  253.                 for k,v in pairs(finishedCoworker)do
  254.                     local id = FindKeyInTable(activeCoWorkers, v)
  255.                     table.remove(activeCoWorkers, id)
  256.                 end
  257.             end
  258.             os.sleep(0.75)
  259.         end
  260.         os.sleep(0.75)
  261.     end
  262. end
  263.  
  264. function FindKeyWithItemName(table, itemname, damage)
  265.     for k,v in pairs(table)do
  266.         if(v.name==itemname)and(v.damage == damage)then
  267.             return k
  268.         end
  269.     end
  270.     return nil
  271. end
  272.  
  273. function SaveToFile()
  274.     local file = io.open("recipes", "wb")
  275.     for k,v in pairs(recipeList)do
  276.         if(v.useDmg)then
  277.             file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|true|", "\n")
  278.         else
  279.             file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|false|", "\n")
  280.         end
  281.     end
  282.     file:close()
  283. end
  284.  
  285. function CheckChestForNewEntrys()
  286. local items = {}
  287. local itemAmounts = {}
  288. local sides = {0,1,2,3,4,5}
  289. local somethingChanged = false
  290.  
  291.     if(inventory~=nil)then
  292.         for k,v in pairs(sides)do
  293.             local chest = inventory.getAllStacks(v)
  294.             if(chest~=nil)then
  295.                 local chestItems = chest.getAll()
  296.                 for a,b in pairs(chestItems)do
  297.                     if(b.name~="minecraft:air")then
  298.                         table.insert(items, b)
  299.                     end
  300.                     os.sleep(0.5)
  301.                 end
  302.             end
  303.             os.sleep(1)
  304.         end
  305.     end
  306.  
  307.     if(#items > 0)then
  308.         for k,v in pairs(items)do
  309.             local key = FindKeyWithItemName(itemAmounts, v.name, v.damage)
  310.             if(key~=nil)then
  311.                 itemAmounts[key].size = itemAmounts[key].size + v.size
  312.             else
  313.                 table.insert( itemAmounts, {name=v.name, damage=v.damage, size = v.size})
  314.             end
  315.  
  316.         end
  317.     end
  318.  
  319.     if(#itemAmounts > 0)then
  320.         for k,v in pairs(itemAmounts)do
  321.             local key = FindKeyWithItemName(recipeList, v.name, v.damage)
  322.             if(key~=nil)then
  323.                 if(recipeList[key].minAmount ~= v.size)then
  324.                     print("Edited recipe: "..v.name.. ":"..v.damage.." new count: "..v.size)
  325.                 end
  326.                 somethingChanged = true
  327.                 recipeList[key].minAmount = v.size
  328.             else
  329.                 table.insert( recipeList, {name=v.name, damage=v.damage, minAmount = v.size, maxCraftAmount = 0, useDmg = true, fails = 0, timer = 0})
  330.                 somethingChanged = true
  331.                 print("Registered recipe: "..v.size.."x "..v.name.. ":"..v.damage)
  332.             end
  333.         end
  334.         if(somethingChanged)then
  335.             SaveToFile()        
  336.         end
  337.     end
  338. end
  339.  
  340.  
  341. print("Autocrafter successfully loaded...")
  342. while true do
  343.     CheckChestForNewEntrys()
  344.     os.sleep(1)
  345.     if(#rs.getTasks() < maxTasks)then
  346.         CheckItems()
  347.         os.sleep(1)
  348.         UpdateCraftingQueue()
  349.         os.sleep(1)
  350.     else
  351.         os.sleep(5)
  352.     end
  353. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement