Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Controller Script
- -- Variables
- local PROTOCOL = "mobFarm"
- local LOCAL_ID = "controller"
- -- Mapping between hostName and computerID
- local nodeIDs = {}
- -- Peripherals
- peripheral.find("modem", rednet.open)
- local monitor = peripheral.find("monitor")
- -- Host controller as 'controller' on network
- rednet.host(PROTOCOL, LOCAL_ID)
- if not monitor then
- error("Monitor not found!")
- end
- if not rednet.isOpen() then
- error("Rednet is not open! Check the modem.")
- end
- -- Configuration
- monitor.setTextScale(0.5)
- monitor.clear()
- local itemsPerPage = 6
- local nodes = {}
- local messageBuffer = {}
- local currentPage = 1
- -- Utility Functions
- -- Updated addNode Function
- local function addNode(hostName, computerID)
- if not nodes[hostName] then
- nodes[hostName] = {
- type = hostName:match("^(%a+)_"),
- id = tonumber(hostName:match("_(%d+)$")),
- status = "UNKNOWN",
- }
- nodeIDs[hostName] = computerID -- Map hostName to computerID
- end
- end
- local function getNodeLabel(hostName)
- local node = nodes[hostName]
- return string.format("%s FARM %d", node.type, node.id)
- end
- -- UI Functions
- local function countTableItems(tbl)
- local count = 0
- for _ in pairs(tbl) do
- count = count + 1
- end
- return count
- end
- local function drawButtons()
- monitor.clear() -- Clear the monitor before drawing
- monitor.setCursorPos(1, 1)
- monitor.write("Mob Farm Controller")
- local nodeCount = countTableItems(nodes) -- Count nodes manually
- if nodeCount == 0 then
- -- If no nodes exist, display a message
- monitor.setCursorPos(2, 3)
- monitor.write("No nodes available")
- monitor.setCursorPos(2, 5)
- monitor.write("Waiting for nodes...")
- return
- end
- local x, y = 2, 2
- local startIndex = (currentPage - 1) * itemsPerPage + 1
- local endIndex = math.min(startIndex + itemsPerPage - 1, nodeCount)
- --print("startIndex:", startIndex, "endIndex:", endIndex) -- Debug output
- local nodeIndex = 1
- for hostName, _ in pairs(nodes) do
- if nodeIndex >= startIndex and nodeIndex <= endIndex then
- local label = getNodeLabel(hostName)
- local status = nodes[hostName].status or "UNKNOWN"
- local color = (status == "RUNNING") and colors.red or colors.green
- -- Format the label and status with blit
- local labelText = label .. " (" .. status .. ")"
- local textLength = #labelText
- local foreground = string.rep(colors.toBlit(colors.white), textLength) -- Foreground is white
- local background = string.rep(colors.toBlit(color), textLength) -- Background based on node status
- monitor.setCursorPos(x, y)
- monitor.blit(labelText, foreground, background) -- Write text with foreground and background
- y = y + 2 -- Move to the next line
- if y > 15 then
- x = x + 14
- y = 2
- end
- end
- nodeIndex = nodeIndex + 1
- end
- -- Pagination
- local totalPages = math.ceil(nodeCount / itemsPerPage)
- monitor.setCursorPos(2, 18)
- monitor.write("Page " .. currentPage .. " of " .. totalPages)
- end
- -- Network Functions
- -- Discover Nodes (Updated to Pass computerID to addNode)
- local function discoverNodes()
- print("Discovering nodes...")
- local computers = {rednet.lookup(PROTOCOL)} -- Get IDs of computers hosting the protocol
- print("Discovered computers:", textutils.serialize(computers)) -- Debug log
- if #computers == 0 then
- print("No nodes discovered, awaiting contact from nodes as they come online")
- else
- for _, computerID in pairs(computers) do
- if computerID ~= os.getComputerID() then
- print("Requesting CLIENT_ID from computer ID: " .. computerID)
- rednet.send(computerID, { type = "requestId", controllerId = LOCAL_ID }, PROTOCOL)
- local senderId, response = rednet.receive(PROTOCOL, 3) -- 3-second timeout
- print("Response received:", textutils.serialize(response)) -- Debug log
- if senderId == computerID and response and response.type == "responseId" then
- local clientId = response.CLIENT_ID -- Read CLIENT_ID from the response
- print("Received CLIENT_ID: " .. clientId .. " from computer ID: " .. computerID)
- addNode(clientId, computerID) -- Use CLIENT_ID and computerID in addNode
- drawButtons() -- Trigger UI update after adding the node
- else
- print("No response or invalid response from computer ID: " .. computerID)
- end
- end
- end
- end
- end
- -- Request Status Update Function
- local function requestStatusUpdates()
- while true do
- for hostName, node in pairs(nodes) do
- if node.status == "UNKNOWN" then
- local computerID = nodeIDs[hostName]
- if computerID then
- print("Requesting status update from node: " .. hostName)
- rednet.send(computerID, { type = "requestStatus" }, PROTOCOL)
- else
- print("No computer ID found for node: " .. hostName)
- end
- end
- end
- sleep(5) -- Wait 5 seconds before rechecking
- end
- end
- -- Handle Incoming Messages (Modified to process status responses)
- local function handleIncomingMessage()
- while true do
- local senderId, message = rednet.receive(PROTOCOL)
- table.insert(messageBuffer, { senderId = senderId, message = message })
- if message.type == "status" then
- local hostName = message.hostName
- if nodes[hostName] then
- nodes[hostName].status = message.status
- print("Updated status for node: " .. hostName .. " to " .. message.status)
- end
- elseif message.type == "handshake" then
- addNode(message.hostName)
- print("Added node: " .. message.hostName)
- elseif message.type == "storageUpdate" then
- nodes[message.hostName].storage = message.storage
- end
- end
- end
- local function toggleNode(hostName)
- if not nodes[hostName] then return end
- local currentStatus = nodes[hostName].status
- local newStatus = (currentStatus == "RUNNING") and "STOPPED" or "RUNNING"
- local computerID = nodeIDs[hostName] -- Get the computerID for the node
- print(computerID)
- if not computerID then
- print("No computer ID found for node: " .. hostName)
- return
- end
- -- Send the toggle message to the computerID
- rednet.send(computerID, { type = "toggle" }, PROTOCOL)
- nodes[hostName].status = "PENDING" -- Update the status to "PENDING"
- end
- -- Function to check for mouse click
- local function handleMouseClick()
- while true do
- local event, button, x, y = os.pullEvent("monitor_touch") -- This waits for a mouse click
- if event then
- print("Monitor clicked")
- end
- -- Check if the click is within the bounds of the buttons
- if x >= 2 and x <= 17 and y >= 2 and y <= 15 then
- -- Calculate startIndex and endIndex
- local nodeCount = countTableItems(nodes) -- Count nodes manually
- local startIndex = (currentPage - 1) * itemsPerPage + 1
- local endIndex = math.min(startIndex + itemsPerPage - 1, nodeCount)
- local nodeIndex = 1
- local clickedNode = nil
- -- Calculate which button was clicked based on x and y positions
- for hostName, _ in pairs(nodes) do
- if nodeIndex >= startIndex and nodeIndex <= endIndex then
- local label = getNodeLabel(hostName)
- local labelLength = #label + 12 -- Button width (to ensure coverage of full text)
- -- Check if the click is inside the button area (simple check based on the x/y position)
- if x >= 2 and x <= labelLength and y >= (2 + (nodeIndex - 1) * 2) and y <= (2 + nodeIndex * 2) then
- clickedNode = hostName
- break
- end
- end
- nodeIndex = nodeIndex + 1
- end
- -- If a node was clicked, toggle it
- if clickedNode then
- print("Node clicked: " .. clickedNode)
- toggleNode(clickedNode)
- drawButtons() -- Redraw the buttons after toggling
- end
- end
- end
- end
- -- Main Loop
- discoverNodes()
- parallel.waitForAll(
- handleIncomingMessage,
- requestStatusUpdates,
- handleMouseClick, -- This listens for mouse clicks and handles them
- function()
- while true do
- drawButtons() -- Periodically update the monitor
- sleep(1) -- Redraw the monitor every second
- end
- end
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement