Advertisement
Myros27

spatialInfoBot

Jun 12th, 2025 (edited)
713
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.19 KB | None | 0 0
  1. --[[
  2.     Spatial InfoBot
  3.  
  4.     A dedicated, read-only bot that provides information about the spatial system.
  5.     It listens for specific chat commands and responds with helpful, interactive messages.
  6.     This bot does NOT move or modify any disks.
  7. ]]
  8.  
  9. -- =========================================================================
  10. --  Core Helper Functions (from previous steps)
  11. -- =========================================================================
  12.  
  13. local function findPeripheralByType(typeName)
  14.     for _, name in ipairs(peripheral.getNames()) do
  15.         if peripheral.getType(name) == typeName then return name end
  16.     end
  17.     return nil
  18. end
  19.  
  20. function listMeDiskNames()
  21.     local bridgeName = findPeripheralByType("meBridge")
  22.     if not bridgeName then return nil, "ME Bridge peripheral not found." end
  23.     local bridge = peripheral.wrap(bridgeName)
  24.     local all_items = bridge.listItems()
  25.     if not all_items then return nil, "Could not access ME system contents." end
  26.     local disk_data = {}
  27.     for _, item in ipairs(all_items) do
  28.         if item.name and string.find(item.name, "storage_cell") then
  29.             local cleaned_name = string.gsub(item.displayName, "[%[%]]", "")
  30.             cleaned_name = string.gsub(cleaned_name, "^%s*(.-)%s*$", "%1")
  31.             table.insert(disk_data, { name = cleaned_name, fingerprint = item.fingerprint })
  32.         end
  33.     end
  34.     return disk_data, nil
  35. end
  36.  
  37. function notifyUser(message, options)
  38.     local chatBox = peripheral.find("chatBox")
  39.     if not chatBox then printError("Chat Box not found.") return end
  40.     options = options or {}
  41.     local prefix = options.prefix or "InfoBot"
  42.     local brackets = options.brackets or "[]"
  43.     local bracketColor = options.bracketColor or "&7"
  44.     local targetUser = options.user
  45.     local messageBody = {}
  46.     local lastPos = 1
  47.     while true do
  48.         local start, finish = string.find(message, "{(.-)}", lastPos)
  49.         if not start then break end
  50.         local beforeText = message:sub(lastPos, start - 1)
  51.         if #beforeText > 0 then table.insert(messageBody, { text = beforeText, color = "white", underlined = false }) end
  52.         local inside = message:sub(start + 1, finish - 1)
  53.         local inlineOpts = {}
  54.         for key, value in string.gmatch(inside, "(%w+)%s*=%s*'([^']*)'") do inlineOpts[string.gsub(key, "%s", "")] = value end
  55.         if inlineOpts.msg then
  56.             local component = { text = inlineOpts.msg, color = inlineOpts.color or "aqua", underlined = (inlineOpts.underlined == 'true') }
  57.             if inlineOpts.clickAction and inlineOpts.value then component.clickEvent = { action = inlineOpts.clickAction, value = inlineOpts.value } end
  58.             table.insert(messageBody, component)
  59.         else
  60.             table.insert(messageBody, { text = "{" .. inside .. "}", color = "white", underlined = false })
  61.         end
  62.         lastPos = finish + 1
  63.     end
  64.     local remainingText = message:sub(lastPos)
  65.     if #remainingText > 0 then table.insert(messageBody, { text = remainingText, color = "white", underlined = false }) end
  66.     local jsonMessage = textutils.serialiseJSON(messageBody)
  67.     if targetUser and targetUser ~= "" then
  68.         chatBox.sendFormattedMessageToPlayer(jsonMessage, targetUser, prefix, brackets, bracketColor)
  69.     else
  70.         chatBox.sendFormattedMessage(jsonMessage, prefix, brackets, bracketColor)
  71.     end
  72. end
  73.  
  74.  
  75. -- =========================================================================
  76. --  Specific Command Handlers
  77. -- =========================================================================
  78.  
  79. --- Handles the '@all' command.
  80. function handleAllCommand(userName)
  81.     notifyUser("Use '@spatial help' for my commands", { user = userName, prefix = "SpatialBot" })
  82. end
  83.  
  84. --- Handles the '@spatial help' command.
  85. function handleHelpCommand(userName)
  86.     local helpText = "Commands: @spatial move <disk> <location>, @spatial clear <disk|location>, @disks. Example: @spatial move expFarm here"
  87.     notifyUser(helpText, { user = userName, prefix = "Help", brackets = "()" })
  88. end
  89.  
  90. --- Handles the '@disks' command by generating a clickable list.
  91. function handleListDisksCommand(userName)
  92.     local disks, err = listMeDiskNames()
  93.     if err then
  94.         notifyUser("Error: " .. err, { user = userName, prefix = "Error", bracketColor = "&c" })
  95.         return
  96.     end
  97.     if #disks == 0 then
  98.         notifyUser("No storage disks found in the ME system.", { user = userName, prefix = "Disks" })
  99.         return
  100.     end
  101.  
  102.     -- Build the message template with a clickable block for each disk
  103.     local messageParts = {}
  104.     for _, diskData in ipairs(disks) do
  105.         local diskName = diskData.name
  106.         local command = "@spatial move " .. diskName .. " here"
  107.         local clickablePart = "{ msg = '" .. diskName .. "', clickAction = 'suggest_command', value = '" .. command .. "' }"
  108.         table.insert(messageParts, clickablePart)
  109.     end
  110.  
  111.     -- Join the clickable parts with commas and send the message
  112.     local messageTemplate = "Available Disks: " .. table.concat(messageParts, ", ")
  113.     notifyUser(messageTemplate, { user = userName, prefix = "Disks" })
  114. end
  115.  
  116.  
  117. -- =========================================================================
  118. --  Main Command Router and Listener Loop
  119. -- =========================================================================
  120.  
  121. --- The main command router. It checks the command and calls the correct handler.
  122. function handleCommand(userName, arg1, arg2)
  123.     if arg1 == "@all" then
  124.         handleAllCommand(userName)
  125.     elseif arg1 == "@spatial" and arg2 == "help" then
  126.         handleHelpCommand(userName)
  127.     elseif arg1 == "@disks" then
  128.         handleListDisksCommand(userName)
  129.     end
  130. end
  131.  
  132. --- The main function that listens for chat events and dispatches commands.
  133. local function runChatListener()
  134.     print("InfoBot command listener is now active. Waiting for messages...")
  135.     while true do
  136.         local event, username, message = os.pullEvent("chat")
  137.         local args = {}
  138.         for word in string.gmatch(message, "[^%s]+") do
  139.             table.insert(args, word)
  140.         end
  141.         handleCommand(username, args[1] or "", args[2] or "")
  142.     end
  143. end
  144.  
  145. -- Start the listener.
  146. runChatListener()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement