local MODEM_SIDE = "bottom" local MONITOR_SIDE = "left" local MASTER_PROTOCOL = "rtm_master_state" local REQUEST_PROTOCOL = "rtm_master_query" local CLIENT_NAME = "dispatcher_monitor" local native = term.current() local monitor = nil local masterId = nil local blink = false local lastState = nil local lastSeen = 0 local DEFAULT_MARKERS = { green = { 26, 4 }, blue = { 42, 4 }, red = { 26, 19 }, purple = { 42, 19 }, } local SEGMENTS = { top_left_outer = { points = { {4,6}, {9,6}, {14,6}, {19,6} } }, top_left_inner = { points = { {21,6}, {25,6}, {29,6}, {33,6} } }, top_right_inner = { points = { {39,6}, {43,6}, {47,6}, {51,6} } }, top_right_outer = { points = { {53,6}, {58,6}, {63,6}, {68,6} } }, bot_left_outer = { points = { {4,17}, {9,17}, {14,17}, {19,17} } }, bot_left_inner = { points = { {21,17}, {25,17}, {29,17}, {33,17} } }, bot_right_inner = { points = { {39,17}, {43,17}, {47,17}, {51,17} } }, bot_right_outer = { points = { {53,17}, {58,17}, {63,17}, {68,17} } }, green_diag = { points = { {19,6}, {23,8}, {27,10}, {31,12}, {35,13} } }, red_diag = { points = { {21,16}, {25,14}, {29,12}, {33,10}, {36,9} } }, blue_diag = { points = { {39,10}, {43,9}, {47,7}, {51,6} } }, purple_diag = { points = { {39,12}, {43,14}, {47,16}, {51,18} } }, } local function openNet() if peripheral.getType(MODEM_SIDE) ~= "modem" then error("Nincs modem a bottom oldalon") end if not rednet.isOpen(MODEM_SIDE) then rednet.open(MODEM_SIDE) end end local function initMonitor() if peripheral.getType(MONITOR_SIDE) ~= "monitor" then error("Nincs monitor a left oldalon") end monitor = peripheral.wrap(MONITOR_SIDE) monitor.setTextScale(0.5) end local function drawLineTerm(target, x1, y1, x2, y2, color) term.redirect(target) paintutils.drawLine(x1, y1, x2, y2, color) end local function drawPolyline(target, points, color) for i = 1, #points - 1 do drawLineTerm(target, points[i][1], points[i][2], points[i + 1][1], points[i + 1][2], color) end end local function routeByKey(key) if not lastState or not lastState.routes then return nil end for _, route in ipairs(lastState.routes) do if route.key == key then return route end end return nil end local function hasAlert(route) if not route then return true end return route.missing or route.offline end local function routeColor(route) if hasAlert(route) and blink then return colors.red end return route and route.color or colors.gray end local function drawSegment(name, color) local seg = SEGMENTS[name] if seg then drawPolyline(monitor, seg.points, color) end end local function drawMap() local green = routeByKey("green") local blue = routeByKey("blue") local red = routeByKey("red") local purple = routeByKey("purple") monitor.setBackgroundColor(colors.black) monitor.clear() drawSegment("top_left_outer", colors.gray) drawSegment("top_right_outer", colors.gray) drawSegment("bot_left_outer", colors.gray) drawSegment("bot_right_outer", colors.gray) drawSegment("top_left_inner", (green and not green.active) and routeColor(green) or colors.gray) drawSegment("top_right_inner", (blue and not blue.active) and routeColor(blue) or colors.gray) drawSegment("bot_left_inner", (red and not red.active) and routeColor(red) or colors.gray) drawSegment("bot_right_inner", (purple and not purple.active) and routeColor(purple) or colors.gray) drawSegment("green_diag", (green and green.active) and routeColor(green) or colors.gray) drawSegment("blue_diag", (blue and blue.active) and routeColor(blue) or colors.gray) drawSegment("red_diag", (red and red.active) and routeColor(red) or colors.gray) drawSegment("purple_diag", (purple and purple.active) and routeColor(purple) or colors.gray) end local function drawMarkers() if not lastState or not lastState.routes then return end for i, route in ipairs(lastState.routes) do local marker = route.marker or DEFAULT_MARKERS[route.key] if marker then monitor.setCursorPos(marker[1], marker[2]) monitor.setBackgroundColor(colors.black) if hasAlert(route) and blink then monitor.setTextColor(colors.red) elseif lastState.selected == i then monitor.setTextColor(colors.white) else monitor.setTextColor(route.color) end monitor.write(route.active and "[*]" or "[ ]") end end end local function drawLegend() if not lastState or not lastState.routes then return end local _, h = monitor.getSize() local startY = math.max(1, h - #lastState.routes - 1) for i, route in ipairs(lastState.routes) do monitor.setCursorPos(2, startY + i - 1) monitor.setBackgroundColor(colors.black) if hasAlert(route) and blink then monitor.setTextColor(colors.red) elseif lastState.selected == i then monitor.setTextColor(colors.white) else monitor.setTextColor(route.color) end local stateText = route.active and "KERESZT" or "EGYENES" local line = (route.active and "[*] " or "[ ] ") .. route.name .. " ID:" .. tostring(route.slaveId or "-") .. " " .. stateText if route.missing then line = line .. " NINCS ID" elseif route.offline then line = line .. " OFFLINE" end monitor.write(line) end end local function drawStatus() monitor.setCursorPos(2, 22) monitor.setBackgroundColor(colors.black) monitor.setTextColor(colors.white) if masterId then monitor.write("MASTER ID: " .. masterId .. " LAST: " .. math.floor(os.clock() - lastSeen) .. "s") else monitor.write("MASTER KERESES...") end end local function redraw() term.redirect(monitor) drawMap() drawMarkers() drawLegend() drawStatus() term.redirect(native) end local function findMaster() local found = rednet.lookup(MASTER_PROTOCOL, "rtm_master", 2) if found then masterId = found end end local function requestState() if not masterId then findMaster() return end rednet.send(masterId, { cmd = "get_panel_state", client = os.getComputerID() }, REQUEST_PROTOCOL) local senderId, msg, protocol = rednet.receive(REQUEST_PROTOCOL, 0.8) if senderId == masterId and protocol == REQUEST_PROTOCOL and type(msg) == "table" and msg.routes then lastState = msg lastSeen = os.clock() else masterId = nil end end openNet() initMonitor() redraw() while true do requestState() blink = not blink redraw() sleep(1) end