Advertisement
Myros27

LagBot V1.1

May 17th, 2025
581
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 22.74 KB | None | 0 0
  1. --[[
  2.     LagBot Turtle Script v1.1
  3.     Monitors server TPS via a direct redstone signal and provides alerts.
  4.     Also reports the redstone signal (TPS value) on command.
  5.  
  6.     Changes:
  7.     - (v1.0) Initial concept with peripheral assumption.
  8.     - (v1.1) Adapted to read TPS from a direct redstone signal using the redstone API.
  9.              Removed TPS_METER_PERIPHERAL_NAME.
  10.              Added TPS_INPUT_SIDE configuration.
  11.              Power reporting now reports the direct redstone (TPS) input.
  12. ]]
  13.  
  14. --#region Configuration
  15. local CHAT_BOX_PERIPHERAL_NAME = "chatBox"
  16. local TPS_INPUT_SIDE = "front" -- CHANGE THIS to the side the turtle is facing the TPS meter block
  17.                               -- Valid sides: "top", "bottom", "left", "right", "front", "back"
  18.  
  19. local COMMAND_PREFIX = "@lag"
  20. local CHAT_BOT_NAME = "LagBot"
  21. local CHAT_BOT_BRACKETS = "[]"
  22. local CHAT_BOT_BRACKET_COLOR = "&c" -- Red color for brackets
  23.  
  24. -- TPS alert thresholds (triggers if Redstone Signal strength <= value)
  25. -- Assuming 0-15 Redstone signal directly maps to a scaled TPS value.
  26. -- For example, if 15 RS = 20 TPS, then 11 RS ~ 15 TPS, 7 RS ~ 10 TPS, 3 RS ~ 5 TPS.
  27. -- You'll need to adjust these based on how your TPS meter block scales its output.
  28. local DEFAULT_TPS_ALERT_THRESHOLDS = {3, 2, 1} -- Example: Alert if RS signal <= 3 (e.g. ~5 TPS)
  29. local TPS_RECOVERY_THRESHOLD_RS = 7 -- Example: Recover if RS signal > 7 (e.g. >10 TPS)
  30.                                      -- This is the REDSTONE SIGNAL value for recovery.
  31.  
  32. local TPS_CHECK_INTERVAL_SECONDS = 5
  33. local TPS_REPORT_INTERVAL_SECONDS = 2 -- Renamed from POWER_REPORT for clarity
  34.  
  35. local DEBUG_MODE = false
  36. local DEBUG_LOG_FILE = "lagbot.log"
  37. --#endregion
  38.  
  39. --#region Peripherals
  40. local chatBox = peripheral.find(CHAT_BOX_PERIPHERAL_NAME)
  41. -- No tpsMeter peripheral needed anymore
  42. --#endregion
  43.  
  44. --#region Debug Logger
  45. local function logDebug(message)
  46.     if not DEBUG_MODE then return end
  47.     local logMessage = string.format("[%s] %s\n", os.date("%Y-%m-%d %H:%M:%S"), message)
  48.     local file, err = fs.open(DEBUG_LOG_FILE, "a")
  49.     if file then
  50.         file.write(logMessage)
  51.         file.close()
  52.     else
  53.         print("DEBUG LOG ERROR: Could not open " .. DEBUG_LOG_FILE .. ": " .. (err or "unknown error"))
  54.     end
  55. end
  56. --#endregion
  57.  
  58. --#region State Variables
  59. logDebug("Script initializing state variables...")
  60. local currentTpsAlertThresholdsRS = {} -- Stores Redstone Signal thresholds
  61. for _, v in ipairs(DEFAULT_TPS_ALERT_THRESHOLDS) do table.insert(currentTpsAlertThresholdsRS, v) end
  62. table.sort(currentTpsAlertThresholdsRS, function(a,b) return a > b end) -- Ensure sorted descending
  63.  
  64. local isMuted = false
  65. local lastNotifiedTpsLevelRS = 16 -- Stores the RS threshold that last triggered (initially > 15)
  66. local tpsCheckTimerId = nil
  67. local isReportingTps = false -- Renamed from isReportingPower
  68. local tpsReportTimerId = nil -- Renamed from powerReportTimerId
  69. logDebug("State variables initialized. Muted: " .. tostring(isMuted))
  70. --#endregion
  71.  
  72. --#region Minecraft JSON Text Component Colors
  73. local COLORS = {
  74.     BLACK = "black", DARK_BLUE = "dark_blue", DARK_GREEN = "dark_green", DARK_AQUA = "dark_aqua",
  75.     DARK_RED = "dark_red", DARK_PURPLE = "dark_purple", GOLD = "gold", GRAY = "gray",
  76.     DARK_GRAY = "dark_gray", BLUE = "blue", GREEN = "green", AQUA = "aqua", RED = "red",
  77.     LIGHT_PURPLE = "light_purple", YELLOW = "yellow", WHITE = "white", RESET = "reset"
  78. }
  79. --#endregion
  80.  
  81. --#region Helper Functions
  82. local function sendFormattedChat(messageComponents, recipientUsername)
  83.     logDebug("Attempting to send formatted chat. Recipient: " .. (recipientUsername or "ALL"))
  84.     if not chatBox then
  85.         local plainText = ""
  86.         for _, comp in ipairs(messageComponents) do plainText = plainText .. (comp.text or "") end
  87.         local noChatMsg = "[" .. CHAT_BOT_NAME .. "-NoChatBox" .. (recipientUsername and (" to " .. recipientUsername) or "") .. "] " .. plainText
  88.         print(noChatMsg)
  89.         logDebug("ChatBox not found. Printed to console: " .. noChatMsg)
  90.         return
  91.     end
  92.  
  93.     local jsonMessage = textutils.serialiseJSON(messageComponents)
  94.     if not jsonMessage then
  95.         local fallbackMsg = "Error: Could not serialize message for formatted sending."
  96.         logDebug("JSON Serialization Error. Fallback: " .. fallbackMsg .. " Data: " .. textutils.serialize(messageComponents, {max_depth=2}))
  97.         if recipientUsername then
  98.             chatBox.sendMessageToPlayer(fallbackMsg, recipientUsername, CHAT_BOT_NAME, CHAT_BOT_BRACKETS, CHAT_BOT_BRACKET_COLOR)
  99.         else
  100.             chatBox.sendMessage(fallbackMsg, CHAT_BOT_NAME, CHAT_BOT_BRACKETS, CHAT_BOT_BRACKET_COLOR)
  101.         end
  102.         return
  103.     end
  104.  
  105.     local success, err
  106.     if recipientUsername then
  107.         success, err = chatBox.sendFormattedMessageToPlayer(jsonMessage, recipientUsername, CHAT_BOT_NAME, CHAT_BOT_BRACKETS, CHAT_BOT_BRACKET_COLOR)
  108.     else
  109.         success, err = chatBox.sendFormattedMessage(jsonMessage, CHAT_BOT_NAME, CHAT_BOT_BRACKETS, CHAT_BOT_BRACKET_COLOR)
  110.     end
  111.  
  112.     if not success then
  113.         logDebug("Error sending formatted message: " .. (err or "Unknown error") .. ". Attempting fallback to plain text.")
  114.         local plainText = ""
  115.         for _, comp in ipairs(messageComponents) do plainText = plainText .. (comp.text or "") end
  116.         if recipientUsername then
  117.             chatBox.sendMessageToPlayer(plainText, recipientUsername, CHAT_BOT_NAME, CHAT_BOT_BRACKETS, CHAT_BOT_BRACKET_COLOR)
  118.         else
  119.             chatBox.sendMessage(plainText, CHAT_BOT_NAME, CHAT_BOT_BRACKETS, CHAT_BOT_BRACKET_COLOR)
  120.         end
  121.     else
  122.         logDebug("Formatted message sent successfully.")
  123.     end
  124.     os.sleep(0.3)
  125. end
  126.  
  127. local function announce(messageComponents)
  128.     sendFormattedChat(messageComponents)
  129. end
  130.  
  131. local function getCurrentRedstoneTps()
  132.     local success, value = pcall(redstone.getAnalogInput, TPS_INPUT_SIDE)
  133.     if success and type(value) == "number" then
  134.         logDebug("Read Redstone TPS from " .. TPS_INPUT_SIDE .. ": " .. value)
  135.         return value
  136.     else
  137.         logDebug("Failed to read Redstone TPS from " .. TPS_INPUT_SIDE .. ". Error/Value: " .. tostring(value))
  138.         return nil
  139.     end
  140. end
  141.  
  142. local function checkTpsAndAlert()
  143.     logDebug("Checking Redstone TPS...")
  144.     local currentRSTps = getCurrentRedstoneTps()
  145.  
  146.     if currentRSTps == nil then
  147.         logDebug("Could not retrieve Redstone TPS for alert check.")
  148.         return
  149.     end
  150.  
  151.     -- Optional: Convert Redstone signal (0-15) to actual TPS (0-20) for display
  152.     -- Example scaling: actualTPS = currentRSTps * (20/15)
  153.     local displayTPS = string.format("%d RS", currentRSTps) -- Default to showing Redstone Signal
  154.     -- If you want to show estimated actual TPS:
  155.     -- local estimatedActualTps = currentRSTps * (20/15)
  156.     -- displayTPS = string.format("%.1f TPS (RS: %d)", estimatedActualTps, currentRSTps)
  157.  
  158.  
  159.     logDebug(string.format("Current Redstone TPS: %d, Last Notified RS Level: %s, Muted: %s", currentRSTps, tostring(lastNotifiedTpsLevelRS), tostring(isMuted)))
  160.  
  161.     if not isMuted then
  162.         local alertTriggeredThisCheck = false
  163.         for _, thresholdRS in ipairs(currentTpsAlertThresholdsRS) do -- Assumes sorted descending
  164.             if currentRSTps <= thresholdRS then
  165.                 if thresholdRS < lastNotifiedTpsLevelRS then
  166.                     announce({
  167.                         {text="WARNING: Server health indicator dropped to ", color=COLORS.YELLOW},
  168.                         {text=displayTPS, color=COLORS.RED, bold=true},
  169.                         {text=" (Alert Level: <=" .. thresholdRS .. " RS)", color=COLORS.YELLOW}
  170.                     })
  171.                     lastNotifiedTpsLevelRS = thresholdRS
  172.                     alertTriggeredThisCheck = true
  173.                     logDebug("Alert sent for RS TPS <= " .. thresholdRS .. ". New lastNotifiedTpsLevelRS: " .. lastNotifiedTpsLevelRS)
  174.                     break
  175.                 else
  176.                     logDebug("RS TPS is " .. currentRSTps .. ", which is <= threshold " .. thresholdRS .. ", but lastNotifiedTpsLevelRS (" .. lastNotifiedTpsLevelRS .. ") is not higher. No new alert.")
  177.                     break
  178.                 end
  179.             end
  180.         end
  181.  
  182.         if not alertTriggeredThisCheck and currentRSTps > TPS_RECOVERY_THRESHOLD_RS and lastNotifiedTpsLevelRS <= TPS_RECOVERY_THRESHOLD_RS then
  183.             announce({
  184.                 {text="RECOVERY: Server health indicator is now ", color=COLORS.GREEN},
  185.                 {text=displayTPS, color=COLORS.AQUA, bold=true},
  186.                 {text=" (Above recovery RS threshold of " .. TPS_RECOVERY_THRESHOLD_RS .. ")", color=COLORS.GREEN}
  187.             })
  188.             lastNotifiedTpsLevelRS = 16
  189.             logDebug("Recovery message sent. RS TPS: " .. currentRSTps .. ". lastNotifiedTpsLevelRS reset.")
  190.         end
  191.     else
  192.         logDebug("Alerts are muted. No TPS alert action taken.")
  193.     end
  194. end
  195.  
  196. local function reportCurrentTps() -- Renamed from reportPowerLevel
  197.     if not isReportingTps then return end
  198.     logDebug("Reporting current Redstone TPS...")
  199.  
  200.     local currentRSTps = getCurrentRedstoneTps()
  201.     if currentRSTps ~= nil then
  202.         -- Optional: Convert to display actual TPS as well
  203.         -- local estimatedActualTps = currentRSTps * (20/15)
  204.         -- local displayTPS = string.format("%.1f TPS (Redstone Signal: %d)", estimatedActualTps, currentRSTps)
  205.         local displayTPS = string.format("%d", currentRSTps) -- Default: just show RS value
  206.  
  207.         announce({{text="Current Health Indicator (Redstone Signal): ", color=COLORS.GRAY}, {text=displayTPS, color=COLORS.YELLOW}})
  208.     else
  209.         logDebug("Failed to get Redstone TPS for reporting.")
  210.         announce({{text="Error reading health indicator (Redstone Signal).", color=COLORS.RED}})
  211.         isReportingTps = false -- Stop trying
  212.         if tpsReportTimerId then os.cancelTimer(tpsReportTimerId); tpsReportTimerId = nil; end
  213.         return
  214.     end
  215.  
  216.     if isReportingTps then
  217.         tpsReportTimerId = os.startTimer(TPS_REPORT_INTERVAL_SECONDS)
  218.         logDebug("TPS report timer restarted. ID: " .. (tpsReportTimerId or "nil"))
  219.     else
  220.         logDebug("TPS reporting was stopped, not restarting timer.")
  221.     end
  222. end
  223.  
  224. local function startTpsCheckTimer()
  225.     if tpsCheckTimerId then os.cancelTimer(tpsCheckTimerId) end
  226.     tpsCheckTimerId = os.startTimer(TPS_CHECK_INTERVAL_SECONDS)
  227.     logDebug("TPS check timer started/restarted. ID: " .. tpsCheckTimerId)
  228. end
  229.  
  230. local function startTpsReportTimer() -- Renamed from startPowerReportTimer
  231.     if not isReportingTps then return end
  232.     if tpsReportTimerId then os.cancelTimer(tpsReportTimerId) end
  233.     reportCurrentTps() -- Report immediately, then start timer
  234. end
  235. --#endregion
  236.  
  237. --#region Command Handlers
  238. local commandHandlers = {}
  239.  
  240. commandHandlers.help = function(username, _)
  241.     logDebug("Executing command: help, User: " .. username)
  242.     announce({{text = "--- LagBot Commands (".. COMMAND_PREFIX .. ") ---", color = COLORS.GOLD, bold = true}})
  243.     announce({{text = COMMAND_PREFIX .. " help", color = COLORS.AQUA}, {text = " - Shows this help message.", color = COLORS.GRAY}})
  244.     announce({{text = COMMAND_PREFIX .. " status", color = COLORS.AQUA}, {text = " - Shows current TPS (Redstone Signal) and bot status.", color = COLORS.GRAY}})
  245.     announce({{text = COMMAND_PREFIX .. " mute", color = COLORS.AQUA}, {text = " - Toggles TPS alert announcements.", color = COLORS.GRAY}})
  246.     announce({{text = COMMAND_PREFIX .. " setalerts <rs1> [rs2...]", color = COLORS.AQUA}, {text = " - Sets Redstone Signal alert thresholds (0-15).", color = COLORS.GRAY}})
  247.     announce({{text = COMMAND_PREFIX .. " startreport", color = COLORS.AQUA}, {text = " - Starts reporting Redstone Signal every " ..TPS_REPORT_INTERVAL_SECONDS.. "s.", color = COLORS.GRAY}})
  248.     announce({{text = COMMAND_PREFIX .. " stopreport", color = COLORS.AQUA}, {text = " - Stops reporting Redstone Signal.", color = COLORS.GRAY}})
  249. end
  250.  
  251. commandHandlers.status = function(username, _)
  252.     logDebug("Executing command: status, User: " .. username)
  253.     local currentRSTps = getCurrentRedstoneTps()
  254.     if currentRSTps ~= nil then
  255.         -- Optional: Convert to display actual TPS as well
  256.         -- local estimatedActualTps = currentRSTps * (20/15)
  257.         -- local displayTPS = string.format("%.1f TPS (Redstone Signal: %d)", estimatedActualTps, currentRSTps)
  258.         local displayTPS = string.format("%d", currentRSTps) -- Default: just show RS value
  259.         announce({{text="Current Health Indicator (Redstone Signal): ", color=COLORS.GREEN}, {text=displayTPS, color=COLORS.AQUA}})
  260.     else
  261.         announce({{text="Could not retrieve current health indicator (Redstone Signal).", color=COLORS.RED}})
  262.     end
  263.     announce({{text="Alerts Muted: ", color=COLORS.GRAY}, {text=tostring(isMuted), color=(isMuted and COLORS.YELLOW or COLORS.GREEN)}})
  264.     local thresholdsStr = ""
  265.     for i, t in ipairs(currentTpsAlertThresholdsRS) do thresholdsStr = thresholdsStr .. t .. (i < #currentTpsAlertThresholdsRS and ", " or "") end
  266.     announce({{text="Current Alert Thresholds (Redstone Signal <=): ", color=COLORS.GRAY}, {text=thresholdsStr, color=COLORS.YELLOW}})
  267.     announce({{text="Reporting Redstone Signal: ", color=COLORS.GRAY}, {text=tostring(isReportingTps), color=(isReportingTps and COLORS.GREEN or COLORS.YELLOW)}})
  268. end
  269.  
  270. commandHandlers.mute = function(username, _)
  271.     logDebug("Executing command: mute, User: " .. username)
  272.     isMuted = not isMuted
  273.     if isMuted then
  274.         announce({{text="Health alerts are now ", color=COLORS.YELLOW}, {text="MUTED", bold=true, color=COLORS.RED}, {text=" by " .. username .. ".", color=COLORS.YELLOW}})
  275.     else
  276.         announce({{text="Health alerts are now ", color=COLORS.GREEN}, {text="UNMUTED", bold=true, color=COLORS.AQUA}, {text=" by " .. username .. ".", color=COLORS.GREEN}})
  277.         lastNotifiedTpsLevelRS = 16
  278.         checkTpsAndAlert()
  279.     end
  280.     logDebug("Mute status changed to: " .. tostring(isMuted))
  281. end
  282.  
  283. commandHandlers.setalerts = function(username, args)
  284.     logDebug("Executing command: setalerts, User: " .. username .. ", Args: " .. textutils.serialize(args))
  285.     if #args == 0 then
  286.         announce({{text="Usage: " .. COMMAND_PREFIX .. " setalerts <rs_value1> [rs_value2...]", color=COLORS.YELLOW}})
  287.         announce({{text="Values are Redstone Signal strength (0-15). Example: " .. COMMAND_PREFIX .. " setalerts 3 2 1", color=COLORS.YELLOW}})
  288.         return
  289.     end
  290.  
  291.     local newThresholdsRS = {}
  292.     for _, arg_val in ipairs(args) do
  293.         local num = tonumber(arg_val)
  294.         if num and num >= 0 and num <= 15 then -- Redstone signal is 0-15
  295.             table.insert(newThresholdsRS, math.floor(num))
  296.         else
  297.             announce({{text="Invalid threshold value: '", color=COLORS.RED}, {text=tostring(arg_val), color=COLORS.YELLOW}, {text="'. Must be a number between 0 and 15.", color=COLORS.RED}})
  298.             return
  299.         end
  300.     end
  301.  
  302.     if #newThresholdsRS == 0 then
  303.         announce({{text="No valid thresholds provided.", color=COLORS.RED}})
  304.         return
  305.     end
  306.  
  307.     table.sort(newThresholdsRS, function(a,b) return a > b end)
  308.     currentTpsAlertThresholdsRS = newThresholdsRS
  309.     lastNotifiedTpsLevelRS = 16
  310.  
  311.     local thresholdsStr = ""
  312.     for i, t in ipairs(currentTpsAlertThresholdsRS) do thresholdsStr = thresholdsStr .. t .. (i < #currentTpsAlertThresholdsRS and ", " or "") end
  313.  
  314.     announce({{text="Redstone Signal alert thresholds set to: ", color=COLORS.GREEN}, {text=thresholdsStr, color=COLORS.AQUA}, {text=" by " .. username .. ".", color=COLORS.GREEN}})
  315.     logDebug("Alert thresholds updated: " .. thresholdsStr)
  316.     checkTpsAndAlert()
  317. end
  318.  
  319. commandHandlers.startreport = function(username, _) -- Renamed from startpower
  320.     logDebug("Executing command: startreport, User: " .. username)
  321.     if isReportingTps then
  322.         announce({{text="Redstone Signal reporting is already active.", color=COLORS.YELLOW}})
  323.         return
  324.     end
  325.     isReportingTps = true
  326.     announce({{text="Starting Redstone Signal reporting every "..TPS_REPORT_INTERVAL_SECONDS.."s (requested by " .. username .. ").", color=COLORS.GREEN}})
  327.     startTpsReportTimer()
  328. end
  329.  
  330. commandHandlers.stopreport = function(username, _) -- Renamed from stoppower
  331.     logDebug("Executing command: stopreport, User: " .. username)
  332.     if not isReportingTps then
  333.         announce({{text="Redstone Signal reporting is not currently active.", color=COLORS.YELLOW}})
  334.         return
  335.     end
  336.     isReportingTps = false
  337.     if tpsReportTimerId then
  338.         os.cancelTimer(tpsReportTimerId)
  339.         tpsReportTimerId = nil
  340.         logDebug("TPS report timer cancelled.")
  341.     end
  342.     announce({{text="Stopped Redstone Signal reporting (requested by " .. username .. ").", color=COLORS.GREEN}})
  343. end
  344. --#endregion
  345.  
  346. --#region Main Loop
  347. local function run()
  348.     term.clear(); term.setCursorPos(1,1)
  349.  
  350.     if DEBUG_MODE then
  351.         local file, err = fs.open(DEBUG_LOG_FILE, "w")
  352.         if file then
  353.             file.write(string.format("[%s] LagBot Script Initializing - DEBUG MODE ENABLED (v1.1)\n", os.date("%Y-%m-%d %H:%M:%S")))
  354.             file.write("======================================================================\n")
  355.             file.close()
  356.         else print("DEBUG LOG ERROR: Could not clear/initialize " .. DEBUG_LOG_FILE .. ": " .. (err or "unknown error")) end
  357.     end
  358.     logDebug("Script run() started.")
  359.  
  360.     if not chatBox then
  361.         logDebug("WARNING: Chat Box peripheral ('" .. CHAT_BOX_PERIPHERAL_NAME .. "') not found!")
  362.         print("WARNING: Chat Box ('" .. CHAT_BOX_PERIPHERAL_NAME .. "') not found! Chat features disabled/printed to console.")
  363.     end
  364.  
  365.     -- Validate TPS_INPUT_SIDE
  366.     local validSides = redstone.getSides()
  367.     local sideIsValid = false
  368.     for _, side in ipairs(validSides) do if side == TPS_INPUT_SIDE then sideIsValid = true; break; end end
  369.     if not sideIsValid then
  370.         logDebug("CRITICAL: Invalid TPS_INPUT_SIDE ('" .. TPS_INPUT_SIDE .. "') configured! Core functionality disabled.")
  371.         print("CRITICAL: Invalid TPS_INPUT_SIDE ('" .. TPS_INPUT_SIDE .. "')! Check config. LagBot functionality disabled.")
  372.         if chatBox then announce({{text=CHAT_BOT_NAME .. " starting with CRITICAL ERROR: Invalid TPS_INPUT_SIDE!", color=COLORS.RED, bold=true}}) end
  373.         return -- Stop script if side is invalid, as it can't function
  374.     end
  375.     logDebug("TPS_INPUT_SIDE ('" .. TPS_INPUT_SIDE .. "') is valid.")
  376.  
  377.  
  378.     logDebug("Announcing online status.")
  379.     print(CHAT_BOT_NAME .. " script started. Type '" .. COMMAND_PREFIX .. " help' in chat or '@all'.")
  380.     if chatBox then
  381.         announce({{text = CHAT_BOT_NAME .. " online.", color = COLORS.GREEN, bold = true}, {text = " Monitoring server health via Redstone Signal on side: " .. TPS_INPUT_SIDE, color = COLORS.GRAY}})
  382.         announce({{text = "Type '", color = COLORS.GRAY}, {text = COMMAND_PREFIX .. " help", color = COLORS.AQUA}, {text = "' or '@all' for commands.", color = COLORS.GRAY}})
  383.     end
  384.  
  385.     checkTpsAndAlert()
  386.     startTpsCheckTimer()
  387.  
  388.     while true do
  389.         local eventData = {os.pullEvent()}
  390.         local eventType = eventData[1]
  391.  
  392.         -- Optimized: If it's a redstone event and it's for our TPS_INPUT_SIDE, check TPS immediately.
  393.         if eventType == "redstone" then
  394.             logDebug("Redstone event received.")
  395.             -- The redstone event itself doesn't give the side or new value in CC:Tweaked by default.
  396.             -- We just use it as a trigger to re-check.
  397.             checkTpsAndAlert()
  398.         end
  399.  
  400.         logDebug("Event pulled: " .. eventType .. " - Data: " .. textutils.serialize(eventData, {compact = true, max_depth = 2}))
  401.  
  402.         if eventType == "chat" then
  403.             local eUsername, eMessage, _, eIsHidden = eventData[2], eventData[3], eventData[4], eventData[5]
  404.             if not eIsHidden and eMessage then
  405.                 if string.lower(eMessage) == "@all" then
  406.                     logDebug("@all command received from " .. eUsername)
  407.                     announce({{text = "Use '", color = COLORS.GREEN}, {text = COMMAND_PREFIX .. " help", color = COLORS.AQUA}, {text = "' to see what this health monitor can do.", color = COLORS.GREEN}})
  408.                 elseif string.sub(eMessage, 1, #COMMAND_PREFIX) == COMMAND_PREFIX then
  409.                     logDebug("Chat command received from " .. eUsername .. ": " .. eMessage)
  410.                     local parts = {}; for part in string.gmatch(eMessage, "[^%s]+") do table.insert(parts, part) end
  411.                     local commandName = ""; if parts[2] then commandName = string.lower(parts[2]) end
  412.                     local cmdArgs = {}; for i = 3, #parts do table.insert(cmdArgs, parts[i]) end
  413.                     logDebug("Parsed command: '" .. commandName .. "', Args: " .. textutils.serialize(cmdArgs))
  414.  
  415.                     if commandHandlers[commandName] then
  416.                         local success, err = pcall(commandHandlers[commandName], eUsername, cmdArgs)
  417.                         if not success then
  418.                             logDebug("Error executing command '" .. commandName .. "': " .. tostring(err))
  419.                             announce({{text = "Command execution failed: ", color = COLORS.RED}, {text = commandName, color = COLORS.YELLOW}})
  420.                         end
  421.                     elseif commandName ~= "" then
  422.                         announce({{text = "Unknown command: '", color = COLORS.RED}, {text = commandName, color = COLORS.YELLOW},
  423.                                   {text = "'. Consult '", color = COLORS.RED}, {text = COMMAND_PREFIX .. " help", color = COLORS.AQUA}, {text = "'.", color = COLORS.RED}})
  424.                     end
  425.                 end
  426.             end
  427.         elseif eventType == "timer" then
  428.             local timerId = eventData[2]
  429.             logDebug("Timer event received for ID: " .. timerId)
  430.             if timerId == tpsCheckTimerId then
  431.                 logDebug("TPS check timer triggered.")
  432.                 checkTpsAndAlert(); startTpsCheckTimer()
  433.             elseif timerId == tpsReportTimerId then
  434.                 logDebug("TPS report timer triggered.")
  435.                 reportCurrentTps()
  436.             else
  437.                 logDebug("Unknown timer ID: " .. timerId)
  438.             end
  439.         elseif eventType == "terminate" then
  440.             logDebug("Terminate event received. System halt.")
  441.             if tpsCheckTimerId then os.cancelTimer(tpsCheckTimerId); logDebug("TPS check timer cancelled.") end
  442.             if tpsReportTimerId then os.cancelTimer(tpsReportTimerId); logDebug("TPS report timer cancelled.") end
  443.             if chatBox then announce({{text = CHAT_BOT_NAME .. " is going offline.", color = COLORS.YELLOW, bold = true}}) end
  444.             logDebug("Script terminated."); print(CHAT_BOT_NAME .. " terminated.")
  445.             return
  446.         end
  447.     end
  448. end
  449.  
  450. run()
  451. --#endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement