Advertisement
sanovskiy

Miner soft network 2

Aug 8th, 2014
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.62 KB | None | 0 0
  1. os.loadAPI("debug")
  2. __const = {}
  3. __const.product_name = "Miner OS"
  4. __const.version = "2.0.1 beta"
  5. __const.bgcolor = colors.green
  6. __const.fgcolor = colors.black
  7.  
  8. -- FUNCTIONS
  9. function table.contains(table, element)
  10.   for _, value in pairs(table) do
  11.     if value == element then
  12.       return true
  13.     end
  14.   end
  15.   return false
  16. end
  17.  
  18. function split(pString, pPattern)
  19.   local Table = {}
  20.   local fpat = "(.-)" .. pPattern
  21.   local last_end = 1
  22.   local s, e, cap = pString:find(fpat, 1)
  23.   while s do
  24.     if s ~= 1 or cap ~= "" then
  25.       table.insert(Table,cap)
  26.     end
  27.     last_end = e+1
  28.     s, e, cap = pString:find(fpat, last_end)
  29.   end
  30.   if last_end <= #pString then
  31.     cap = pString:sub(last_end)
  32.     table.insert(Table, cap)
  33.   end
  34.   return Table
  35. end
  36.  
  37. local modem
  38. local monitor
  39. function scanMiners ()
  40.   print("Scanning network...")
  41.   local list = {}
  42.   local n = 1
  43.   local peripherals = peripheral.getNames()
  44.   for i = 1, #peripherals do
  45.     if peripheral.getType(peripherals[i]) == "mininglaser" then
  46.       n = n + 1
  47.       table.insert(list,peripherals[i])
  48.     elseif peripheral.getType(peripherals[i]) == "modem" then
  49.       modem = peripheral.wrap(peripherals[i])
  50.     elseif peripheral.getType(peripherals[i]) == "monitor" then
  51.       monitor = peripheral.wrap(peripherals[i])
  52.     end
  53.   end
  54.   print(tostring(#list).." miners found")
  55.   return list
  56. end
  57.  
  58. function saveFile(t, file)
  59.   local fConfig = fs.open(file, "w") or error("Cannot open file "..file, 2)
  60.   fConfig.write(textutils.serialize(t))
  61.   fConfig.close()
  62. end
  63.  
  64. function loadFile(file)
  65.   local fConfig = fs.open(file, "r")
  66.   local ret = textutils.unserialize(fConfig.readAll())
  67.   fConfig.close()
  68.   return ret
  69. end
  70.  
  71. function getLongest( _table )
  72.     local longest = 0
  73.     for index,c_text in pairs( _table ) do
  74.         longest = #c_text > longest and #c_text or longest
  75.     end
  76.     return longest + 1
  77. end
  78.  
  79. function menu( _term, _table, startX, startY )
  80.     sX, sY = _term.getSize()
  81.     local function printMenu(_term, _table, long, sel, yPos )
  82.         _term.clear()
  83.         --for index, text in pairs( _table ) do
  84.         --  _term.setCursorPos( startX, startY + index - 1 )
  85.         --  write( ( index == sel and '[ ' or '  ' ) .. text .. string.rep(' ', long - #text) .. ( index == sel and ']' or ' ' ) )
  86.         --end
  87.         for i = 1, sY do
  88.             if _table[i + yPos - 1] then
  89.                 local tmp = _table[i + yPos - 1]
  90.                 _term.setCursorPos( startX, startY + i - 1 )
  91.                 _term.write( ( i + yPos - 1 == sel and '[ ' or '  ' ) .. tmp .. string.rep(' ', long - #tmp) .. ( i + yPos - 1 == sel and ']' or ' ' ) )
  92.             else break end
  93.         end
  94.     end
  95.    
  96.     local longest = getLongest( _table )
  97.     local sel = 1
  98.     local yPos = 1
  99.    
  100.     while true do
  101.         printMenu(_term, _table, longest, sel, yPos )
  102.         local e, key = os.pullEvent()
  103.         if e == "key" or e == "mouse_scroll" then
  104.             if key == keys.up or key == -1 then
  105.                 -- up
  106.                 if yPos > 1 then
  107.                     yPos = yPos - 1
  108.                 end
  109.                 if sel > 1 then
  110.                     sel = sel - 1
  111.                 end
  112.             elseif key == keys.down or key == 1 then
  113.                 -- down
  114.                 if sel < #_table then
  115.                     sel = sel + 1
  116.                 end
  117.                 if yPos < #_table - 18 and sel >= 20 then
  118.                     yPos = yPos + 1
  119.                 end
  120.             elseif key == keys.enter then
  121.                 return _table[sel], sel
  122.             end
  123.         end
  124.     end
  125. end
  126.  
  127. function initialize()
  128.   if fs.exists("miner_groups.dat") then
  129.     registry["groups"]=loadFile("miner_groups.dat")
  130.   else
  131.     registry["groups"]={{name="All",list="*"}}
  132.     saveFile(registry["groups"], "miner_groups.dat")
  133.   end
  134.  
  135.   registry["currentGroup"] = 1
  136.   registry['main_section'] = "mainstats"
  137.   registry["miner_ids"] = scanMiners()
  138. end
  139.  
  140. function drawMainScreen()
  141.   term.setBackgroundColor(__const.bgcolor)
  142.   term.setTextColor(__const.fgcolor)
  143.   term.clear()
  144.   term.setCursorPos(1, 1)
  145.   term.write(__const.product_name.." "..__const.version)
  146.   term.setCursorPos(1, 2)
  147.   term.write(string.rep("-",51))
  148.   for i=3,19 do
  149.   term.setCursorPos(35, i)
  150.   term.write("|")
  151.   end
  152. --  term.setCursorPos(1, 17)
  153. --  term.write(string.rep("-",51))
  154. --  term.setCursorPos(1, 18)
  155. --  term.write("G - group manipulations, O - group orders, X - exit")
  156. end
  157.  
  158. function updateSoftware()
  159.   windows['main'].clear()
  160.   windows['main'].setCursorPos(1, 1)
  161.   if not(fs.exists("san")) then
  162.     print("Retrieving latest installer")
  163.     shell.run("pastebin","get wf2EBfvT san")
  164.   else
  165.     print("Updating installer")
  166.     shell.run("san"," update san")
  167.   end
  168.   shell.run("san"," update mineos2")
  169.   if not(fs.exists("launcher")) then
  170.     print("Removing old startup")
  171.     shell.run("rm","startup")
  172.     sfile= fs.open("startup", "w") or error("Cannot open file startup", 2)
  173.     print("Writing new startup")
  174.     sfile.write("shell.run(\"mineos2\")")
  175.     sfile.close()
  176.   end
  177.   print("Rebooting...")
  178.   os.reboot()
  179. end
  180.  
  181. function getCurrentGroupMinerIDs()
  182.     local groupMinerIDs = split(registry["groups"][registry["currentGroup"]]["list"],',')
  183.     local prepend = true
  184.     if groupMinerIDs[1]=="*" then
  185.         groupMinerIDs = registry["miner_ids"]
  186.         prepend = false
  187.     end
  188.     local list = {}
  189.     for i=1,#groupMinerIDs do
  190.         local elemname = groupMinerIDs[i]
  191.         if prepend then
  192.             elemname = "mininglaser_"..tostring(tonumber(elemname))
  193.         end
  194.         if peripheral.isPresent(elemname) then
  195.             table.insert(list,elemname)
  196.         end
  197.     end
  198.     return list
  199. end
  200.  
  201. function drawMainStat()
  202.     local w = windows['main']
  203.     w.clear()
  204.     w.setCursorPos(1, 1)
  205.     w.write("Miners total: "..(#registry["miner_ids"]))
  206.     w.setCursorPos(1, 2)
  207.   -- debug.dump(registry["currentGroup"])
  208.     -- debug.dump(registry["groups"])
  209.     w.write("Current group: "..registry["groups"][registry["currentGroup"]]['name'])
  210.     w.setCursorPos(1, 3)
  211.     local stat = getMinerStats(getCurrentGroupMinerIDs())
  212.     w.write("Miners in group: "..(stat["total"]))
  213.     w.setCursorPos(1, 4)
  214.     w.write("M/Q/W/I: "..stat["mining"].."/"..stat["quarry"].."/"..stat["warmup"].."/"..stat["idle"])
  215.     w.setCursorPos(1, 5)
  216.     w.write("Low energy: "..stat["lowenergy"])
  217.     w.setCursorPos(1, 6)
  218.     w.write("Levels: "..stat["lowest"].."/"..stat["highrst"])
  219.     w.setCursorPos(1,7)
  220.     -- debug.dump(stat["raw"])
  221. end
  222.  
  223. function userInputReader()
  224.     while true do
  225.         wX, wY = windows['menu'].getSize()
  226.         windows['menu'].clear()
  227.         local sOption, sNumb = menu(windows['menu'], __main_menu, (wX-getLongest(__main_menu))/2, 1 )
  228.         windows['main'].setCursorPos(1, 1)
  229.         -- windows['main'].write(sOption)
  230.         if sOption=="Exit" then
  231.           break
  232.         elseif sOption=="Orders" then
  233.             ordersMenu()
  234.         elseif sOption=="Groups" then
  235.           groupsMenu()
  236.         elseif sOption=="Update" then
  237.           registry['main_section'] = 'none';
  238.           updateSoftware()
  239.         end
  240.     end
  241.  
  242. end
  243.  
  244. function monitorUpdater()
  245. end
  246.  
  247. function monitorListener()
  248. end
  249.  
  250. function mainScreenDrawer()
  251.     while true do
  252.         if registry['main_section'] == "mainstats" then
  253.             drawMainStat()
  254.         else
  255.             local e, key = os.pullEvent()
  256.         end
  257.         sleep(1)
  258.     end
  259. end
  260.  
  261. function groupsMenu()
  262.     while true do
  263.         wX, wY = windows['menu'].getSize()
  264.         windows['menu'].clear()
  265.         local sOption, sNumb = menu(windows['menu'], __groups_menu, (wX-getLongest(__groups_menu))/2, 1 )
  266.         windows['main'].setCursorPos(1, 1)
  267.         -- windows['main'].write(sOption)
  268.         if sOption=="<< Back" then
  269.           break
  270.         elseif sOption=="Add new" then
  271.             local entry = askGroupData()
  272.             table.insert(registry["groups"], entry)
  273.             saveFile(registry["groups"], "miner_groups.dat")
  274.         elseif  sOption=="Select" then
  275.             local groupsList = getGroupList(true)
  276.             local sOption, sNumb = menu(windows['menu'], groupsList, (wX-getLongest(groupsList))/2, 1 )
  277.             registry["currentGroup"] = sNumb-1
  278.             return
  279.         elseif sOption=="Edit" then
  280.             local groupsList = getGroupList()
  281.             windows['menu'].clear()
  282.             local sOption, sNumb = menu(windows['menu'], groupsList, (wX-getLongest(groupsList))/2, 1 )
  283.             if not(sOption=="<< Back") then
  284.                 local entry = askGroupData()
  285.                 if type(entry)=="table" then
  286.                     registry["groups"][sNumb]=entry
  287.                 end
  288.                 saveFile(registry["groups"], "miner_groups.dat")
  289.             end
  290.         elseif sOption=="Remove" then
  291.             local groupsList = getGroupList()
  292.             windows['menu'].clear()
  293.             local sOption, sNumb = menu(windows['menu'], groupsList, (wX-getLongest(groupsList))/2, 1 )
  294.             if not(sOption=="<< Back") then
  295.                 table.remove(registry["groups"],sNumb)
  296.                 if sNumb==registry["currentGroup"] then
  297.                     registry["currentGroup"] = 1
  298.                 elseif registry["currentGroup"]>sNumb then
  299.                     registry["currentGroup"] = registry["currentGroup"] - 1
  300.                 end
  301.                 local newgroups = {}
  302.                 for key,val in pairs(registry["groups"]) do
  303.                     table.insert(newgroups,val)
  304.                 end
  305.                 registry["groups"] = newgroups
  306.                 saveFile(registry["groups"], "miner_groups.dat")
  307.                 registry["groups"]=loadFile("miner_groups.dat")
  308.             end
  309.         end
  310.         sOption = ''
  311.     end
  312. end
  313.  
  314. function ordersMenu()
  315.     while true do
  316.         wX, wY = windows['menu'].getSize()
  317.         windows['menu'].clear()
  318.         local sOption, sNumb = menu(windows['menu'], __orders_menu, (wX-getLongest(__orders_menu))/2, 1 )
  319.         windows['main'].setCursorPos(1, 1)
  320.         if sOption=="<< Back" then
  321.             break
  322.         elseif sOption=="Stop" then
  323.             for _,val in pairs(getCurrentGroupMinerIDs()) do
  324.                 orderStop(val);
  325.             end
  326.             return
  327.         elseif sOption=="Mine" or sOption=="Mine S" then
  328.             for _,val in pairs(getCurrentGroupMinerIDs()) do
  329.                 orderMine(val,not(sOption=="Mine S"));
  330.             end
  331.             return
  332.         elseif sOption=="Quarry" or sOption=="Quarry S" then
  333.             for _,val in pairs(getCurrentGroupMinerIDs()) do
  334.                 orderQuarry(val,not(sOption=="Quarry S"));
  335.             end
  336.             return
  337.         elseif sOption=="Offset" then
  338.             registry['main_section'] = "none"
  339.             local cw = windows['main'];
  340.             cw.clear()
  341.             local offset = ""
  342.             cw.setCursorPos(1,1)
  343.             cw.write("Offset : ")
  344.             offset = read()
  345.             offset = tonumber(offset)
  346.             if offset>0 then
  347.                 for _,val in pairs(getCurrentGroupMinerIDs()) do
  348.                     orderOffset(val,offset);
  349.                 end
  350.             end
  351.             cw.clear()
  352.             registry['main_section'] = "mainstats"
  353.         end
  354.         sOption = ''
  355.     end
  356. end
  357.  
  358. function orderQuarry(miner,nosilktouch)
  359.     nosilktouch = nosilktouch or true
  360.     if peripheral.isPresent(miner) then
  361.         local m = peripheral.wrap(miner)
  362.         m.quarry(not(nosilktouch))
  363.     end
  364. end
  365.  
  366. function orderMine(miner,nosilktouch)
  367.     nosilktouch = nosilktouch or true
  368.     if peripheral.isPresent(miner) then
  369.         local m = peripheral.wrap(miner)
  370.         m.mine(not(nosilktouch))
  371.     end
  372. end
  373.  
  374. function orderStop(miner)
  375.     if peripheral.isPresent(miner) then
  376.         local m = peripheral.wrap(miner)
  377.         m.stop()
  378.     end
  379. end
  380.  
  381. function orderOffset(miner,offset)
  382.     offset = offset or 1
  383.     if peripheral.isPresent(miner) then
  384.         local m = peripheral.wrap(miner)
  385.         m.offset(offset)
  386.     end
  387. end
  388.  
  389. function askGroupData(info)
  390.     local info = info or {name="",list=""}
  391.     registry['main_section'] = "none"
  392.     local cw = windows['main'];
  393.     cw.clear()
  394.     local groupName = ""
  395.     while string.len(groupName)<3 do
  396.         cw.setCursorPos(1,1)
  397.         cw.write("New group name (at least 3 chars): ")
  398.         cw.setCursorPos(1,2)
  399.         groupName = read()
  400.         if groupName=="" then
  401.             registry['main_section'] = "mainstats"
  402.             return false
  403.         end
  404.     end
  405.     local ids = ""
  406.     while string.len(ids)<1 do
  407.         cw.setCursorPos(1,3)
  408.         cw.write("Peripheral ids (comma separated):")
  409.         cw.setCursorPos(1,4)
  410.         ids = read()
  411.         if ids=="" then
  412.             registry['main_section'] = "mainstats"
  413.             return false
  414.         end
  415.     end
  416.     local entry = {name = groupName, list=ids}
  417.     registry['main_section'] = "mainstats"
  418.     return entry
  419. end
  420.  
  421. function getGroupList(withAll)
  422.     withAll = withAll or false
  423.     local list = {"<< Back"}
  424.     for key,val in pairs(registry["groups"]) do
  425.         if withAll or not(val["name"]=="All") then
  426.             table.insert(list,val['name'])
  427.         end
  428.     end
  429.     return list
  430. end
  431.  
  432. function getMinerStats(ids)
  433.     local stat={}
  434.     stat["total"] = #ids
  435.     stat["idle"] = 0
  436.     stat["mining"] = 0
  437.     stat["quarry"] = 0
  438.     stat["lowenergy"] = 0
  439.     stat["lowest"] = 255
  440.     stat["highrst"] = 0
  441.     stat["warmup"] = 0
  442.     stat["raw"] = {}
  443.     for _,id in pairs(ids) do
  444.         if peripheral.isPresent(id)then
  445.             local state,energy,curlayer,mined,total = modem.callRemote(id,"state")
  446.             if not(stat["raw"][state]==nil) then
  447.                 stat["raw"][state] = stat["raw"][state]+1
  448.             else
  449.                 stat["raw"][state] = 1
  450.             end
  451.             if string.find(state,"IDLE") then
  452.                 stat["idle"] = stat["idle"]+1
  453.             elseif string.find(state,"Mining ores") or string.find(state,"Scanning ores") then
  454.                 stat["mining"] = stat["mining"]+1
  455.             elseif string.find(state,"Mining all") or string.find(state,"Scanning all") then
  456.                 stat["quarry"] = stat["quarry"]+1
  457.             elseif string.find(state,"Warming up") then
  458.                 stat["warmup"] = stat["warmup"]+1
  459.             end
  460.             if string.find(state,"Out of energy") then
  461.                 stat["lowenergy"]=stat["lowenergy"]+1
  462.             end
  463.             if curlayer<stat["lowest"] then
  464.                 stat["lowest"]=curlayer
  465.             end
  466.             if curlayer>stat["highrst"] then
  467.                 stat["highrst"]=curlayer
  468.             end
  469.         end
  470.     end
  471.     return stat
  472. end
  473. -- /FUNCTIONS
  474.  
  475. __main_menu = {"Orders","Groups","Update","Exit"}
  476. __groups_menu = {"<< Back","Select","Add new","Edit","Remove"}
  477. __orders_menu = {"<< Back","Stop","Mine","Mine S","Quarry","Quarry S","Offset"}
  478.  
  479. registry = {}
  480. windows = {}
  481. initialize()
  482. -- debug.dump(loadFile("miner_groups.dat"))
  483. -- error()
  484. -- debug.dump(split(registry["groups"][registry["currentGroup"]]["list"],','))
  485. -- debug.dump(getCurrentGroupMinerIDs())
  486. -- error()
  487. drawMainScreen()
  488.  
  489. windows['menu']=window.create(term.current(),36,3,15,10,true)
  490. windows['menu'].setBackgroundColor(__const.bgcolor)
  491. windows['menu'].setTextColor(__const.fgcolor)
  492. windows['menu'].clear()
  493. windows['main']=window.create(term.current(),1,3,34,17,true)
  494. windows['main'].setBackgroundColor(__const.bgcolor)
  495. windows['main'].setTextColor(__const.fgcolor)
  496. windows['main'].clear()
  497.  
  498. parallel.waitForAny(userInputReader, mainScreenDrawer)
  499.  
  500. term.setBackgroundColor(colors.black)
  501. term.setTextColor(colors.white)
  502. term.clear()
  503. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement