Advertisement
efrim

Miner Server 1.1 for Warpdrive 1.6.2

Oct 17th, 2013
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --------------------------------------------------
  2. -- Сервер для оравы шахтерских лазеров из кросоварпа.
  3. -- Ставится в кабине шахтерской платформы
  4. -- и подключается сетевыми кабелями к компьютерам,
  5. -- стоящим у лазеров. На те компьютеры
  6. -- нужно поставить клиентскую программу.
  7. -- И то, и то нужно поставить в autostart.
  8. --
  9. -- (c) Efrim
  10. -- skype: gods_pee
  11. -- 05.10.2013
  12. --------------------------------------------------
  13. -- Changelog:
  14. -- 1.0: release
  15. -- 1.1: saving only IDs of miners instead of full statuses
  16. --------------------------------------------------
  17.  
  18. NETWORK_SIDE = "bottom" -- Сторона, к которой подключен модем
  19. DATA_FILE = "miners.dat" -- Файл для сохранения данных
  20. TEMP_FILE = "miners.temp" -- Временное хранилище
  21. TIMEOUTS_MAX = 3 -- Максимальное количество таймаутов в сетевом общении
  22. TIMEOUT = 1 -- Время таймаута
  23. REFRESH_PERIOD = 1 -- Период обновления экрана
  24.  
  25. --------------------------------------------------
  26.  
  27. nTotal = -1
  28. nOnline = -1
  29. nLowEnergy = -1
  30. nMining = -1
  31. nQuarry = -1
  32. nStopped = -1
  33. maxLayer = -1
  34. minLayer = -1
  35.  
  36.  
  37. --------------------------------------------------
  38.  
  39.     -- Массив данных о майнерах:
  40.     -- 1 - ID
  41.     -- 2 - 'state'
  42.     -- 3 - 'energy'
  43.     -- 4 - 'currentLayer'
  44.     -- 5 - 'mined'
  45.     -- 6 - 'total'
  46.     -- 7 - online
  47.  
  48. miners = {}
  49. for i = 1, 81 do
  50.     miners[i] = {}
  51.  
  52.     for j = 1, 7 do
  53.         miners[i][j] = 0 -- Fill the values here
  54.     end
  55. end
  56.  
  57. minersCompact = {}
  58.  
  59. --------------------------------------------------
  60. -- Графическая часть
  61. --------------------------------------------------
  62.  
  63. function DisplayStats()
  64.     term.clear()
  65.     term.setCursorPos(1, 1)
  66.     print("__ Lasers __")
  67.     print("Online / Total: " .. nOnline .. " / " .. nTotal)
  68.     print("Stopped / Mining / Quarry: " .. nStopped .. " / " .. nMining .. " / " .. nQuarry)
  69.     print("Max / Min layer: " .. maxLayer .. " / " .. minLayer)
  70.     print("With low energy: " .. nLowEnergy)
  71.     print("")
  72.     print("Press C to type a command")
  73.     return 0
  74. end
  75.  
  76. function SubmitCommand()
  77.     print("")
  78.     print("Enter command")
  79.     sleep(1/10)
  80.     print("> ")
  81.     local input = read()
  82.     return input
  83. end
  84.  
  85. function ExecuteCommand(command)
  86.     if command == "help" then
  87.         PrintHelp()
  88.         SubmitCommand()
  89.     elseif command == "reinit" then
  90.         rednet.broadcast(command)
  91.         sleep(1/3)
  92.         rednet.broadcast(command)
  93.         sleep(1/3)
  94.         rednet.broadcast(command)
  95.         sleep(1/3)
  96.         InitializeNetwork()
  97.         DisplayStats()
  98.     else
  99.         rednet.broadcast(command)
  100.         DisplayStats()
  101.     end
  102.     return 0
  103. end
  104.  
  105. function PrintHelp()
  106.     print("help")
  107.     print("start")
  108.     print("quarry")
  109.     print("stop")
  110.     print("restart")
  111.     print("reinit")
  112.     print("offset --layers")
  113.     print("update --pastebin")
  114.     print("")
  115.     return 0
  116. end
  117.  
  118. --------------------------------------------------
  119. -- Инициализация
  120. --------------------------------------------------
  121.  
  122. function InitializeNetwork()
  123.     rednet.open(NETWORK_SIDE)
  124.  
  125.     nTotal = 0
  126.     local nTimeouts = 0
  127.  
  128.     term.clear()
  129.     term.setCursorPos(1,1)
  130.     print("Initializing...")
  131.  
  132.     while nTimeouts <= TIMEOUTS_MAX do
  133.         sleep(1/4)
  134.         rednet.broadcast("Server is here")
  135.  
  136.         local receivedID, receivedMessage, _ = rednet.receive(TIMEOUT)
  137.  
  138.         print(receivedID)
  139.  
  140.         if receivedID == nil then
  141.             nTimeouts = nTimeouts + 1
  142.             print("Timeout.")
  143.         else
  144.             print("Received message.")
  145.             local _, _, minerIDstr = string.find(receivedMessage, "Miner (%d+) is here")
  146.             minerID = tonumber(minerIDstr)
  147.             if receivedID == minerID then
  148.                 AddMiner(minerID)
  149.                 nTimeouts = 0
  150.                 rednet.send(minerID, "Gotcha")
  151.                 print("Miner " .. nTotal .. " initialized.")
  152.             end
  153.         end
  154.     end
  155.  
  156.     print("Initialized total " .. nTotal .. " miners.")
  157.  
  158.     SaveMinersTableToFile()
  159.  
  160.     return 0
  161. end
  162.  
  163. function AddMiner(minerID)
  164.     nTotal = nTotal + 1
  165.     miners[nTotal][1] = minerID
  166.     miners[nTotal][7] = 1
  167.  
  168.     minersCompact[nTotal] = minerID
  169.  
  170.     return 0
  171. end
  172.  
  173. --------------------------------------------------
  174. -- Общение с имеющимися майнерами
  175. --------------------------------------------------
  176.  
  177. function UpdateMiner(minerN) -- Обновление статуса майнера
  178.     local timeouts = 0
  179.     local minerID = miners[minerN][1]
  180.  
  181.     while timeouts <= TIMEOUTS_MAX do
  182.         CommandMiner(minerN, "statusrequest")
  183.         local receivedID, receivedMessage, _ = rednet.receive(TIMEOUT)
  184.  
  185.         if receivedID == minerID then
  186.             local state = textutils.unserialize(receivedMessage)
  187.  
  188.             miners[minerN][2] = state[1]
  189.             miners[minerN][3] = state[2]
  190.             miners[minerN][4] = state[3]
  191.             miners[minerN][5] = state[4]
  192.             miners[minerN][6] = state[5]
  193.             miners[minerN][7] = 1
  194.  
  195.             return 0
  196.         end
  197.  
  198.         timeouts = timeouts + 1 -- Если дошли до этого места, то таймаут
  199.     end
  200.     miners[minerN][7] = 0 -- Если дошли до этого места, то майнер в оффлайне
  201.     return 1
  202. end
  203.  
  204. function UpdateAllMiners() -- Обновление статусов всех майнеров
  205.     for i = 1, nTotal do
  206.         UpdateMiner(i)
  207.     end
  208.  
  209.     return 0
  210. end
  211.  
  212. function CommandMiner(minerN, action)
  213.     local minerID = miners[minerN][1]
  214.  
  215.     rednet.send(minerID, action)
  216.  
  217.     return 0
  218. end
  219.  
  220. function CommandAllMiners(action)
  221.  
  222.     rednet.broadcast(action)
  223.  
  224.     return 0
  225. end
  226.  
  227. --------------------------------------------------
  228. -- Пересчет статистики
  229. --------------------------------------------------
  230.  
  231. function RecalculateStatistics ()
  232.     nOnline = 0
  233.     nLowEnergy = 0
  234.     nMining = 0
  235.     nQuarry = 0
  236.     nStopped = 0
  237.     maxLayer = 0
  238.     minLayer = 256
  239.  
  240.     for i = 1, nTotal do
  241.         -- nOnline
  242.         nOnline = nOnline + miners[i][7]
  243.         -- nLowEnergyTemp
  244.         if miners[i][3] <= 50000 then
  245.             nLowEnergy = nLowEnergy + 1
  246.         end
  247.         -- nMiningTemp, nQuarryTemp, nStoppedTemp
  248.         if miners[i][2] == "not mining" then
  249.             nStopped = nStopped + 1
  250.         elseif miners[i][2] == "mining" then
  251.             nMining = nMining + 1
  252.         elseif miners[i][2] == "mining %(quarry mode%)" then
  253.             nQuarry = nQuarry + 1
  254.         end
  255.         -- maxLayerTemp
  256.         maxLayer = math.max(maxLayer, miners[i][4])
  257.         minLayer = math.min(minLayer, miners[i][4])
  258.     end
  259.  
  260.     return 0
  261. end
  262.  
  263. --------------------------------------------------
  264. -- Сохранение и загрузка
  265. --------------------------------------------------
  266.  
  267. function SaveMinersTableToFile()
  268.     local file = fs.open(TEMP_FILE, "w")
  269.     file.writeLine(textutils.serialize(minersCompact))
  270.     file.writeLine(nTotal)
  271.     file.close()
  272.  
  273.     fs.delete(DATA_FILE)
  274.     fs.move(TEMP_FILE, DATA_FILE)
  275.  
  276.     return 0
  277. end
  278.  
  279. function LoadMinersTableFromFile()
  280.     local file = fs.open(DATA_FILE, "r")
  281.     minersCompact = textutils.unserialize(file.readLine())
  282.     nTotal = tonumber(file.readLine())
  283.  
  284.     for i = 1, nTotal do
  285.         miners[i][1] = minersCompact[i]
  286.     end
  287.  
  288.     file.close()
  289.  
  290.     return 0
  291. end
  292.  
  293. --------------------------------------------------
  294. -- Главный луп
  295. --------------------------------------------------
  296.  
  297. function main()
  298.     rednet.open(NETWORK_SIDE)
  299.  
  300.     if fs.exists(DATA_FILE) then
  301.         print("Loading previous data...")
  302.         LoadMinersTableFromFile()
  303.     else
  304.         print("Initializing...")
  305.         InitializeNetwork()
  306.     end
  307.  
  308.     while true do
  309.         UpdateAllMiners()
  310.         RecalculateStatistics()
  311.         DisplayStats()
  312.  
  313.         local timeout = os.startTimer(REFRESH_PERIOD)
  314.         while true do
  315.             event = {os.pullEvent()}
  316.             if event[1] == "key" and event[2] == 46 then
  317.                 local command = SubmitCommand()
  318.                 ExecuteCommand(command)
  319.                 timeout = os.startTimer(REFRESH_PERIOD)
  320.             elseif event[1] == "timer" and event[2] == timeout then
  321.                 break
  322.             end
  323.         end
  324.     end
  325. end
  326.  
  327. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement