Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Spatial InfoBot
- A dedicated, read-only bot that provides information about the spatial system.
- It listens for specific chat commands and responds with helpful, interactive messages.
- This bot does NOT move or modify any disks.
- ]]
- -- =========================================================================
- -- Core Helper Functions (from previous steps)
- -- =========================================================================
- local function findPeripheralByType(typeName)
- for _, name in ipairs(peripheral.getNames()) do
- if peripheral.getType(name) == typeName then return name end
- end
- return nil
- end
- function listMeDiskNames()
- local bridgeName = findPeripheralByType("meBridge")
- if not bridgeName then return nil, "ME Bridge peripheral not found." end
- local bridge = peripheral.wrap(bridgeName)
- local all_items = bridge.listItems()
- if not all_items then return nil, "Could not access ME system contents." end
- local disk_data = {}
- for _, item in ipairs(all_items) do
- if item.name and string.find(item.name, "storage_cell") then
- local cleaned_name = string.gsub(item.displayName, "[%[%]]", "")
- cleaned_name = string.gsub(cleaned_name, "^%s*(.-)%s*$", "%1")
- table.insert(disk_data, { name = cleaned_name, fingerprint = item.fingerprint })
- end
- end
- return disk_data, nil
- end
- function notifyUser(message, options)
- local chatBox = peripheral.find("chatBox")
- if not chatBox then printError("Chat Box not found.") return end
- options = options or {}
- local prefix = options.prefix or "InfoBot"
- local brackets = options.brackets or "[]"
- local bracketColor = options.bracketColor or "&7"
- local targetUser = options.user
- local messageBody = {}
- local lastPos = 1
- while true do
- local start, finish = string.find(message, "{(.-)}", lastPos)
- if not start then break end
- local beforeText = message:sub(lastPos, start - 1)
- if #beforeText > 0 then table.insert(messageBody, { text = beforeText, color = "white", underlined = false }) end
- local inside = message:sub(start + 1, finish - 1)
- local inlineOpts = {}
- for key, value in string.gmatch(inside, "(%w+)%s*=%s*'([^']*)'") do inlineOpts[string.gsub(key, "%s", "")] = value end
- if inlineOpts.msg then
- local component = { text = inlineOpts.msg, color = inlineOpts.color or "aqua", underlined = (inlineOpts.underlined == 'true') }
- if inlineOpts.clickAction and inlineOpts.value then component.clickEvent = { action = inlineOpts.clickAction, value = inlineOpts.value } end
- table.insert(messageBody, component)
- else
- table.insert(messageBody, { text = "{" .. inside .. "}", color = "white", underlined = false })
- end
- lastPos = finish + 1
- end
- local remainingText = message:sub(lastPos)
- if #remainingText > 0 then table.insert(messageBody, { text = remainingText, color = "white", underlined = false }) end
- local jsonMessage = textutils.serialiseJSON(messageBody)
- if targetUser and targetUser ~= "" then
- chatBox.sendFormattedMessageToPlayer(jsonMessage, targetUser, prefix, brackets, bracketColor)
- else
- chatBox.sendFormattedMessage(jsonMessage, prefix, brackets, bracketColor)
- end
- end
- -- =========================================================================
- -- Specific Command Handlers
- -- =========================================================================
- --- Handles the '@all' command.
- function handleAllCommand(userName)
- notifyUser("Use '@spatial help' for my commands", { user = userName, prefix = "SpatialBot" })
- end
- --- Handles the '@spatial help' command.
- function handleHelpCommand(userName)
- local helpText = "Commands: @spatial move <disk> <location>, @spatial clear <disk|location>, @disks. Example: @spatial move expFarm here"
- notifyUser(helpText, { user = userName, prefix = "Help", brackets = "()" })
- end
- --- Handles the '@disks' command by generating a clickable list.
- function handleListDisksCommand(userName)
- local disks, err = listMeDiskNames()
- if err then
- notifyUser("Error: " .. err, { user = userName, prefix = "Error", bracketColor = "&c" })
- return
- end
- if #disks == 0 then
- notifyUser("No storage disks found in the ME system.", { user = userName, prefix = "Disks" })
- return
- end
- -- Build the message template with a clickable block for each disk
- local messageParts = {}
- for _, diskData in ipairs(disks) do
- local diskName = diskData.name
- local command = "@spatial move " .. diskName .. " here"
- local clickablePart = "{ msg = '" .. diskName .. "', clickAction = 'suggest_command', value = '" .. command .. "' }"
- table.insert(messageParts, clickablePart)
- end
- -- Join the clickable parts with commas and send the message
- local messageTemplate = "Available Disks: " .. table.concat(messageParts, ", ")
- notifyUser(messageTemplate, { user = userName, prefix = "Disks" })
- end
- -- =========================================================================
- -- Main Command Router and Listener Loop
- -- =========================================================================
- --- The main command router. It checks the command and calls the correct handler.
- function handleCommand(userName, arg1, arg2)
- if arg1 == "@all" then
- handleAllCommand(userName)
- elseif arg1 == "@spatial" and arg2 == "help" then
- handleHelpCommand(userName)
- elseif arg1 == "@disks" then
- handleListDisksCommand(userName)
- end
- end
- --- The main function that listens for chat events and dispatches commands.
- local function runChatListener()
- print("InfoBot command listener is now active. Waiting for messages...")
- while true do
- local event, username, message = os.pullEvent("chat")
- local args = {}
- for word in string.gmatch(message, "[^%s]+") do
- table.insert(args, word)
- end
- handleCommand(username, args[1] or "", args[2] or "")
- end
- end
- -- Start the listener.
- runChatListener()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement