AlexMastang

OC-NTM-Missile_en Mk2

Jan 4th, 2026 (edited)
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 18.75 KB | None | 0 0
  1. local serialization = require("serialization")
  2. local filesystem = require("filesystem")
  3. local component = require("component")
  4. local computer = require("computer")
  5. local event = require("event")
  6. local side = require("sides")
  7. local term = require("term")
  8.  
  9.  
  10. local gpu = component.gpu
  11. local modem
  12.  
  13. local alphabet = {"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray", "Yankee", "Zulu"}
  14. local w, h = term.getViewport()
  15. local halfh = math.floor(h/2)
  16.  
  17. local coords = {}
  18. coords.x = {}
  19. coords.x.start = {}
  20. coords.x.start.circle = 2
  21. coords.x.start.buttons = 2
  22. coords.x.start.log = h
  23. coords.x.start.console = 4
  24. coords.x.stop = {}
  25. coords.x.stop.circle = h-2
  26. coords.x.stop.buttons = halfh-2
  27. coords.x.stop.log = w-1
  28. coords.x.stop.console = w-1
  29. coords.x.target = 0.0
  30. coords.y = {}
  31. coords.y.start = {}
  32. coords.y.start.circle = 2
  33. coords.y.start.buttons = halfh+2
  34. coords.y.start.log = 2
  35. coords.y.start.console = h-1
  36. coords.y.stop = {}
  37. coords.y.stop.circle = h
  38. coords.y.stop.buttons = h-3
  39. coords.y.stop.log = h-3
  40. coords.y.stop.console = h-1
  41. coords.y.target = 0.0
  42.  
  43. local logBuffer = {}
  44. local logIndex = 0
  45. local inputCommand = ""
  46. local sanitizer -- used to "clean" input
  47. local frequency = 1
  48. local radius = 0.0
  49. local bckColor = 0x000000
  50. local forColor = 0x00FF00
  51. local configPath = "home/config.txt"
  52. local configFile
  53. local countdown = 10
  54. local countdownIndex = 0
  55. local countdownDo = false
  56. local broadcastDo = true
  57. local launchCommit = false
  58. local launchConfirm = false
  59. local launchCommence = false
  60. local checkList = false
  61. local allReady = true
  62. local waitAll = true
  63. local canLaunch = false
  64. local frequency_old = frequency
  65.  
  66. local eventRes = {}
  67. local keywords = {}
  68. local buttons = {}
  69. local data = {}
  70. local pads = {}
  71. local pads_coords = {}
  72. local matrixCircle = {}
  73.  
  74.  
  75. -- circle subsequence
  76. local function circleSub(mat, xc, yc, x, y)
  77.   mat[xc+x][yc+y] = -1
  78.   mat[xc-x][yc+y] = -1
  79.   mat[xc+x][yc-y] = -1
  80.   mat[xc-x][yc-y] = -1
  81.   mat[xc+y][yc+x] = -1
  82.   mat[xc-y][yc+x] = -1
  83.   mat[xc+y][yc-x] = -1
  84.   mat[xc-y][yc-x] = -1
  85.  
  86.   return
  87. end
  88.  
  89. -- draws a cicle starting at (posX, posY), with radius rad (Breseham's algorithm)
  90. local function circle(posX, posY, rad)
  91.   local matrix = {}
  92.   local diameter = 2*rad+1
  93.  
  94.   for i=1,diameter,1 do
  95.     matrix[i] = {}
  96.     for k=1,diameter,1 do
  97.       matrix[i][k] = 0
  98.     end
  99.   end
  100.  
  101.   local X = 0
  102.   local Y = rad
  103.   local D = 3 - 2 * rad
  104.   circleSub(matrix, posX+rad-1, posY+rad-1, X, Y)
  105.   while (Y >= X) do
  106.     if (D > 0) then
  107.       Y = Y - 1
  108.       D = D + 4 * (X - Y) + 10
  109.     else
  110.       D = D + 4 * X + 6
  111.     end
  112.     X = X + 1
  113.     circleSub(matrix, posX+rad-1, posY+rad-1, X, Y)
  114.   end
  115.  
  116.   return matrix
  117. end
  118.  
  119. -- actually draws the circle
  120. local function circleDraw(matrix, posX, posY, rad)
  121.   local diameter = 2*rad+1
  122.  
  123.   term.setCursor(posX, posY)
  124.   for i=1,diameter,1 do
  125.     for k=1,diameter,1 do
  126.       if (matrix[i][k] == -1) then
  127.         term.write("@")
  128.       elseif (matrix[i][k] == 1) then
  129.         term.write("X")
  130.       else
  131.         term.write(" ")
  132.       end
  133.       term.write(" ")
  134.     end
  135.     term.setCursor(posX, posY+i)
  136.   end
  137.  
  138.   return
  139. end
  140.  
  141. -- random target distribution calculation
  142. local function bomb(r)
  143.   local x, y
  144.   local mx, my
  145.   local dm = #matrixCircle
  146.   pads_coords = {}
  147.  
  148.   for i=1,dm,1 do
  149.     for k=1,dm,1 do
  150.       if (matrixCircle[i][k] == 1) then
  151.         matrixCircle[i][k] = 0
  152.       end
  153.     end
  154.   end
  155.  
  156.   for i=1,#pads,1 do
  157.     pads_coords[i] = {}
  158.     if (r > 0.0) then
  159.       repeat
  160.         x = math.random(2*r)
  161.         y = math.random(2*r)
  162.         mx = math.floor(x/(2*r+1)*dm)
  163.         my = math.floor(y/(2*r+1)*dm)
  164.         mx = (mx > 0) and mx or 1
  165.         my = (my > 0) and my or 1
  166.       until ((x-r-1)^2 + (y-r-1)^2 < r^2-1 and matrixCircle[my][mx] ~= 1 and matrixCircle[my][mx] ~= -1)
  167.       matrixCircle[my][mx] = 1
  168.     else
  169.       x = 0.0
  170.       y = 0.0
  171.       matrixCircle[math.floor(dm/2)][math.floor(dm/2)] = 1
  172.     end
  173.     pads_coords[i][1] = x - r + coords.x.target
  174.     pads_coords[i][2] = y - r + coords.y.target
  175.   end
  176.  
  177.   return
  178. end
  179.  
  180. -- returns an array of the specified peripheral
  181. local function multiPer(peripheral)
  182.   local C = 1
  183.   local peripheralArray = {}
  184.   for add, n in component.list(peripheral) do
  185.     peripheralArray[C] = component.proxy(add)
  186.     C = C + 1
  187.   end
  188.  
  189.   return peripheralArray
  190. end
  191.  
  192. -- clears the log
  193. local function clearLog()
  194.   term.setCursor(coords.x.start.log, coords.y.start.log)
  195.   for i=coords.y.start.log,coords.y.stop.log,1 do
  196.     term.setCursor(coords.x.start.log, i)
  197.     for k=coords.x.start.log,coords.x.stop.log,1 do
  198.       term.write(" ")
  199.     end
  200.   end
  201.   term.setCursor(coords.x.start.log, coords.y.start.log)
  202.  
  203.   return 0
  204. end
  205.  
  206. -- prints a single line in custom format to fit in the log space
  207. local function logPrint(line, index)
  208.   local x, y
  209.   local char
  210.   local localIndex = index
  211.  
  212.   term.setCursor(coords.x.start.log, coords.y.start.log + localIndex)
  213.   x, y = term.getCursor()
  214.   if (y > coords.y.stop.log) then
  215.     localIndex = clearLog()
  216.   end
  217.   term.write(line:sub(1,1)=="1" and "> " or "< ")
  218.   for k=2,#line,1 do
  219.     x, y = term.getCursor()
  220.     char = line:sub(k,k)
  221.     if (y > coords.y.stop.log) then
  222.       localIndex = clearLog()
  223.     end
  224.     if (x > coords.x.stop.log or char == "\n") then
  225.       localIndex = localIndex + 1
  226.       term.setCursor(coords.x.start.log, coords.y.start.log + localIndex)
  227.     end
  228.     if (char ~= "\n") then
  229.       term.write(char)
  230.     end
  231.   end
  232.  
  233.   localIndex = localIndex + 1
  234.  
  235.   return localIndex
  236. end
  237.  
  238. -- segments a string containing spaces
  239. local function segment(line, value)
  240.   local k_word = {}
  241.   local k = 1
  242.   local char = ""
  243.  
  244.   if (line == nil) then
  245.     return nil
  246.   end
  247.  
  248.   for i=1,#line,1 do
  249.     char = line:sub(i,i)
  250.     if (char == value or char == nil) then
  251.       k = k + 1
  252.     else
  253.       if (k_word[k] == nil) then k_word[k] = "" end
  254.       k_word[k] = k_word[k] .. char
  255.     end
  256.   end
  257.  
  258.   return k_word
  259. end
  260.  
  261. -- saves data in the configPath path
  262. local function saveData()
  263.   data = {frequency, broadcastDo, coords.x.target, coords.y.target, radius, countdown, countdownDo, forColor, bckColor, waitAll}
  264.   configFile = filesystem.open(configPath, "w")
  265.   if (configFile == nil) then
  266.     table.insert(logBuffer, 1 .. "Save failed")
  267.     return false
  268.   end
  269.   configFile:write(serialization.serialize(data))
  270.   configFile:close()
  271.   table.insert(logBuffer, 1 .. "Save succeded")
  272.  
  273.   return true
  274. end
  275.  
  276. -- updates data and pads
  277. local function update(matrix, posX, posY, rad)
  278.   pads = multiPer("ntm_launch_pad")
  279.   table.insert(logBuffer, 1 .. "Detected " .. #pads .. " launch pads")
  280.   bomb(radius)
  281.   circleDraw(matrix, posX, posY, rad)
  282.  
  283.   return
  284. end
  285.  
  286. -- allocates a new button entry
  287. local function newButton(buffer, name1, name2, sx, sy, ex, ey)
  288.   table.insert(buffer, {label1=name1, label2=name2, posX=sx, posY=sy, endX=ex, endY=ey})
  289.  
  290.   return
  291. end
  292.  
  293. -- checks the value with the button, then inverts it
  294. local function checkButton(button, value, posX, posY)
  295.   if (posX >= button.posX and posX <= button.endX and posY >= button.posY and posY <= button.endY) then
  296.     value = not value
  297.   end
  298.  
  299.   gpu.setBackground(forColor)
  300.   gpu.setForeground(bckColor)
  301.   term.setCursor(button.posX, button.posY)
  302.   term.write(("%9s"):format(value and button.label2 or button.label1))
  303.   gpu.setBackground(bckColor)
  304.   gpu.setForeground(forColor)
  305.  
  306.   return value
  307. end
  308.  
  309. -- unpacks the data vector
  310. local function unpack()
  311.   frequency = data[1]
  312.   broadcastDo = data[2]
  313.   coords.x.target = data[3]
  314.   coords.y.target = data[4]
  315.   radius = data[5]
  316.   countdown = data[6]
  317.   countdownDo = data[7]
  318.   forColor = data[8]
  319.   bckColor = data[9]
  320.   waitAll = data[10]
  321.  
  322.   return
  323. end
  324.  
  325.  
  326. data = {frequency, broadcastDo, coords.x.target, coords.y.target, radius, countdown, countdownDo, forColor, bckColor, waitAll}
  327. table.insert(logBuffer, 1 .. "Checking for " .. configPath .. "...")
  328. if (filesystem.exists(configPath)) then
  329.   table.insert(logBuffer, 1 .. "Success. Reading...")
  330.   configFile = filesystem.open(configPath, "r")
  331.   data = serialization.unserialize(configFile:read(filesystem.size(configPath)*8))
  332. else
  333.   table.insert(logBuffer, 1 .. "Failed. Creating new...")
  334.   configFile = filesystem.open(configPath, "w")
  335.   configFile:write(serialization.serialize(data))
  336. end
  337. configFile:close()
  338. unpack()
  339. frequency_old = frequency
  340. table.insert(logBuffer, 1 .. "Config complete")
  341.  
  342. newButton(buttons, "LISTEN", "BROADCAST", coords.x.start.buttons+2, coords.y.start.buttons+1, coords.x.start.buttons+10, coords.y.start.buttons+1)
  343. newButton(buttons, "INSTANT", "COUNTDOWN", coords.x.start.buttons+2, coords.y.start.buttons+3, coords.x.start.buttons+10, coords.y.start.buttons+3)
  344. newButton(buttons, "FIREALL", "WAITALL", coords.x.start.buttons+2, coords.y.start.buttons+5, coords.x.start.buttons+10, coords.y.start.buttons+5)
  345.  
  346. modem = multiPer("modem")
  347. modem = modem[1]
  348.  
  349.  
  350. term.clear()
  351.  
  352. checkButton(buttons[1], broadcastDo, 0, 0)
  353. checkButton(buttons[2], countdownDo, 0, 0)
  354. checkButton(buttons[3], waitAll, 0, 0)
  355.  
  356. gpu.setBackground(bckColor)
  357. gpu.setForeground(forColor)
  358.  
  359. for i=2,w-1,1 do
  360.   term.setCursor(i, 1)
  361.   term.write("-")
  362.   term.setCursor(i, h-2)
  363.   term.write("-")
  364.   term.setCursor(i, h)
  365.   term.write("-")
  366. end
  367. term.setCursor(2, halfh+1)
  368. for i=2,h-2,1 do
  369.   term.write("-")
  370. end
  371. for i=2,h-3,1 do
  372.   term.setCursor(1, i)
  373.   term.write("|")
  374.   term.setCursor(h-1, i)
  375.   term.write("|")
  376.   term.setCursor(w, i)
  377.   term.write("|")
  378. end
  379.  
  380. term.setCursor(1, 1)
  381. term.write("+")
  382. term.setCursor(h-1, 1)
  383. term.write("+")
  384. term.setCursor(w, 1)
  385. term.write("+")
  386.  
  387. term.setCursor(1, h-2)
  388. term.write("+")
  389. term.setCursor(h-1, h-2)
  390. term.write("+")
  391. term.setCursor(w, h-2)
  392. term.write("+")
  393.  
  394. term.setCursor(1, halfh+1)
  395. term.write("+")
  396. term.setCursor(h-1, halfh+1)
  397. term.write("+")
  398.  
  399. term.setCursor(1, h)
  400. term.write("+")
  401. term.setCursor(w, h)
  402. term.write("+")
  403.  
  404. term.setCursor(1, h-1)
  405. term.write("| $")
  406. term.setCursor(w, h-1)
  407. term.write("|")
  408.  
  409.  
  410. matrixCircle = circle(coords.x.start.circle, coords.y.start.circle, math.floor(halfh/2)-1)
  411. update(matrixCircle, coords.x.start.circle, coords.y.start.circle, math.floor(halfh/2)-1)
  412.  
  413. while (true) do
  414.   if (not launchCommence) then
  415.     eventRes = {term.pull(1)}
  416.  
  417.     term.setCursor(coords.x.start.console, coords.y.start.console)
  418.     for i=coords.x.start.console,coords.x.stop.console,1 do
  419.       term.write(" ")
  420.     end
  421.    
  422.     if (modem ~= nil) then
  423.       if (not modem.isOpen(frequency) or frequency ~= frequency_old) then
  424.         modem.close(frequency_old)
  425.         modem.open(frequency)
  426.         table.insert(logBuffer, 1 .. "Changed freq " .. frequency_old .. " -> " .. frequency)
  427.         frequency_old = frequency
  428.       end
  429.     end
  430.  
  431.     if (eventRes[1] == "key_down") then
  432.       if (eventRes[3] == 0) then
  433.         -- input reset
  434.         inputCommand = ""
  435.       elseif (eventRes[3] == 8) then
  436.         -- backspace
  437.         inputCommand = inputCommand:sub(1, -2)
  438.       elseif (eventRes[3] >= 32 and eventRes[3] <= 126) then
  439.         -- characters input
  440.         inputCommand = inputCommand .. string.char(eventRes[3])
  441.       elseif (eventRes[3] == 13) then
  442.         -- return
  443.         table.insert(logBuffer, 0 .. inputCommand)
  444.         inputCommand = string.lower(inputCommand)
  445.         keywords = segment(inputCommand, " ")
  446.         inputCommand = ""
  447.        
  448.         if (keywords[1] == "get") then
  449.           if (keywords[2] == "frequency") then
  450.             table.insert(logBuffer, 1 .. frequency)
  451.           elseif (keywords[2] == "radius") then
  452.             table.insert(logBuffer, 1 .. radius)
  453.           elseif (keywords[2] == "countdown") then
  454.             table.insert(logBuffer, 1 .. countdown)
  455.           elseif (keywords[2] == "coords") then
  456.             table.insert(logBuffer, 1 .. "X: " .. coords.x.target .. ", Z: " .. coords.y.target)
  457.           else
  458.             table.insert(logBuffer, 1 .. "Usage: get [-a]\n -a: specified value\n- frequency\n- radius\n- countdown\n- coords")
  459.           end
  460.         elseif (keywords[1] == "set") then
  461.           sanitizer = tonumber(keywords[3])
  462.           if (keywords[2] == "frequency") then
  463.             if (sanitizer ~= nil) then
  464.               frequency = ((sanitizer > 65535) and 65535 or ((sanitizer < 1) and 1 or sanitizer))
  465.               table.insert(logBuffer, 1 .. "Changed frequency to " .. frequency)
  466.             else
  467.               table.insert(logBuffer, 1 .. "Must be a number 1-65535")
  468.             end
  469.           elseif (keywords[2] == "radius") then
  470.             if (sanitizer ~= nil) then
  471.               radius = (sanitizer < 0.0) and 0.0 or sanitizer
  472.               table.insert(logBuffer, 1 .. "Changed bombing radius to " .. radius)
  473.             else
  474.               table.insert(logBuffer, 1 .. "Must be a number >= 0.0")
  475.             end
  476.           elseif (keywords[2] == "countdown") then
  477.             if (sanitizer ~= nil) then
  478.               countdown = (sanitizer < 0) and 0 or math.floor(sanitizer)
  479.               table.insert(logBuffer, 1 .. "Changed the countdown to " .. countdown)
  480.             else
  481.               table.insert(logBuffer, 1 .. "Must be a number > 0")
  482.             end
  483.           else
  484.             sanitizer = segment(keywords[2], "/")
  485.             if (type(sanitizer) == "table") then
  486.               sanitizer[1] = tonumber(sanitizer[1])
  487.               sanitizer[2] = tonumber(sanitizer[2])
  488.               if (sanitizer[1] ~= nil and sanitizer[2] ~= nil) then
  489.                 coords.x.target = sanitizer[1]
  490.                 coords.y.target = sanitizer[2]
  491.                 table.insert(logBuffer, 1 .. "Changed target coords to X: " .. coords.x.target .. ", Z: " .. coords.y.target)
  492.               else
  493.                 table.insert(logBuffer, 1 .. "Must use the format X/Z")
  494.               end
  495.             else
  496.               table.insert(logBuffer, 1 .. "Usage: set [-a] [-n]\n -a: specified value\n- frequency\n- radius\n- countdown\n -n: number 0-65535")
  497.             end
  498.           end
  499.         elseif (keywords[1] == "clear") then
  500.           logIndex = clearLog()
  501.         elseif (keywords[1] == "update") then
  502.           update(matrixCircle, coords.x.start.circle, coords.y.start.circle, math.floor(halfh/2)-1)
  503.         elseif (keywords[1] == "help") then
  504.           table.insert(logBuffer, 1 .. "Avaiable commands: (for more info about a specific command type as shown)\nset: sets a value to the specified field\nget: returns a value from the specified field\nupdate: checks for avaiable pads and returns the total\nsave: saves the current configuration\nreboot: reboots the system\ncommit: commits to launch\nexport: exports config on all avaiable systems (must be on the same frequency)")
  505.         elseif (keywords[1] == "save") then
  506.           saveData()
  507.         elseif (keywords[1] == "export") then
  508.           if (modem == nil) then
  509.             table.insert(logBuffer, 1 .. "No network card detected")
  510.           else
  511.             if (broadcastDo) then
  512.               saveData()
  513.               data[2] = false
  514.               modem.broadcast(frequency, serialization.serialize(data))
  515.             else
  516.               table.insert(logBuffer, 1 .. "Program in LISTEN mode. Change to BROADCAST")
  517.             end
  518.           end
  519.         elseif (keywords[1] == "reboot") then
  520.           table.insert(logBuffer, 1 .. "Rebooting...")
  521.           computer.shutdown(true)
  522.         elseif (keywords[1] == "commit" or launchCommit) then
  523.           if (launchCommit) then
  524.             launchCommit = false
  525.             if (keywords[1] == "y") then
  526.               launchConfirm = true
  527.               checkList = false
  528.               table.insert(logBuffer, 1 .. "Committed")
  529.               table.insert(logBuffer, 1 .. "STARTING LAUNCH SEQUENCE")
  530.             else
  531.               launchConfirm = false
  532.               table.insert(logBuffer, 1 .. "Aborted")
  533.             end
  534.           else
  535.             launchCommit = true
  536.             computer.beep(1000, 1)
  537.             table.insert(logBuffer, 1 .. "Commit to launch " .. #pads .. " base(s)? (Y/n)")
  538.           end
  539.         else
  540.           table.insert(logBuffer, 1 .. "Unknown command. type 'help' for help")
  541.         end
  542.       end
  543.     elseif (eventRes[1] == "touch") then
  544.       broadcastDo = checkButton(buttons[1], broadcastDo, eventRes[3], eventRes[4])
  545.       countdownDo = checkButton(buttons[2], countdownDo, eventRes[3], eventRes[4])
  546.       waitAll = checkButton(buttons[3], waitAll, eventRes[3], eventRes[4])
  547.     elseif (eventRes[1] == "modem_message" and (not broadcastDo)) then
  548.       if (type(eventRes[6]) == "string") then
  549.         sanitizer = serialization.unserialize(eventRes[6])
  550.         if (type(sanitizer) == "table") then
  551.           if (#sanitizer == 10) then
  552.             data = sanitizer
  553.             unpack()
  554.             saveData()
  555.             table.insert(logBuffer, 1 .. "Data from " .. eventRes[3] .. " at " .. math.floor(eventRes[5]*100.0)/100.0 .. "m away")
  556.           elseif (#sanitizer == 2) then
  557.             if (type(sanitizer[1]) == "boolean" and type(sanitizer[2]) == "boolean") then
  558.               launchConfirm = sanitizer[1]
  559.               checkList = sanitizer[2]
  560.             end
  561.           end
  562.         end
  563.       end
  564.     end
  565.   else
  566.     os.sleep(0.5)
  567.   end
  568.  
  569.   if (launchConfirm and not checkList) then
  570.     if (modem ~= nil and broadcastDo) then
  571.       modem.broadcast(frequency, serialization.serialize({true, false}))
  572.     end
  573.     checkList = true
  574.     table.insert(logBuffer, 1 .. "CHECKING PADS STATUS...")
  575.     allReady = true
  576.     update(matrixCircle, coords.x.start.circle, coords.y.start.circle, math.floor(halfh/2)-1)
  577.     for i=1,#pads,1 do
  578.       canLaunch = pads[i].canLaunch()
  579.       if (not canLaunch) then
  580.         allReady = false
  581.       end
  582.       table.insert(logBuffer, 1 .. ("%02d"):format(i) .. " -> " .. (canLaunch and "Ready" or "Pending"))
  583.     end
  584.     if (allReady or not waitAll) then
  585.       table.insert(logBuffer, 1 .. "Commence")
  586.       launchCommence = true
  587.       countdownIndex = 0
  588.     else
  589.       table.insert(logBuffer, 1 .. "Not all ready")
  590.       launchCommence = false
  591.     end
  592.   end
  593.  
  594.   if (launchCommence) then
  595.     if (countdownDo and countdownIndex < countdown) then
  596.       countdownIndex = countdownIndex + 1
  597.       table.insert(logBuffer, 1 .. countdown - countdownIndex)
  598.       computer.beep(2000, 0.5)
  599.     else
  600.       launchCommence = false
  601.       for i=1,#pads,1 do
  602.         pads[i].launch(pads_coords[i][1], pads_coords[i][2])
  603.       end
  604.       table.insert(logBuffer, 1 .. "LAUNCH!")
  605.     end
  606.   end
  607.  
  608.   term.setCursor(coords.x.start.console, coords.y.start.console)
  609.   term.write(inputCommand)
  610.  
  611.   if (#logBuffer > 0) then
  612.     for i,line in ipairs(logBuffer) do
  613.       logIndex = logPrint(line, logIndex)
  614.     end
  615.     logBuffer = {}
  616.   end
  617. end
Advertisement
Add Comment
Please, Sign In to add comment