-- Load necessary APIs os.loadAPI("/button") -- Configuration local config = { boxColor = colors.blue, buttonsPerRow = 4, buttonWidth = 16, buttonHeight = 3, textScale = 0.5, infoBG = colors.red, updateTime = 60 } -- ########### ToDo -- set different portal color after portal switch -- Debug data local debug = false local debugArray = {} local entries = 200 -- Populate debugArray for i = 1, entries do table.insert(debugArray, {key = "Portal" .. i, public = true}) end -- Function to ensure the presence of required peripherals (monitor and teleporter). function checkPeripheral(name, errorMessage) local peripheral = peripheral.find(name) if not peripheral then error(errorMessage) end return peripheral end -- Retrieve peripherals local mon = checkPeripheral("monitor", "Monitor peripheral not found.") local tp = checkPeripheral("teleporter", "Teleporter peripheral not found.") lastActiveButton = nil -- Determine whether to use debug data or actual teleporter frequencies. local inputArray = debug and debugArray or tp.getFrequencies() -- Function to display a countdown timer on the monitor when the monitorsize is incorrect. function showTimer(seconds, centerX, centerY) while seconds >= 0 do mon.setCursorPos(centerX, centerY) mon.setTextColor(colors.white) mon.setBackgroundColor(colors.black) mon.write("Timer: " .. tostring(seconds) .. "s remaining ") os.sleep(1) seconds = seconds - 1 end os.reboot() end -- Function to check and handle monitor size discrepancies. function checkMonitorSize() local w, h = mon.getSize() if w ~= 79 or h ~= 38 then mon.clear() local centerX = math.floor((w - #"ERROR: Monitor size is not correct.") / 2) local centerY = math.floor(h / 2) mon.setCursorPos(centerX, centerY) mon.setTextColor(colors.red) mon.write("ERROR: Monitor size is not correct.") centerY = centerY + 1 mon.setCursorPos(centerX, centerY) mon.write("Required size: 3 Heigh / 4 Width") centerY = centerY + 1 mon.setCursorPos(centerX, centerY) mon.write("Please adjust the monitor size and restart.") showTimer(10, centerX, centerY + 2) error("Monitor size is not correct.") end end -- Set monitor text properties and initialize variables for pagination. mon.setTextScale(config.textScale) mon.setBackgroundColor(colors.black) currentPage = 1 maxButtons = 24 totalPages = math.ceil(#inputArray / maxButtons) -- Function to set the frequency based on the button pressed. local function setFrequency(freq) if not debug then tp.setFrequency(freq) end button.toggleButton(freq) end -- Function to dynamically fill the button table based on the current page. function fillTable() local w, h = mon.getSize() local spacingX = 2 local spacingY = 1 local maxButtons = maxButtons local startIndex = (currentPage - 1) * maxButtons + 1 local endIndex = math.min(startIndex + maxButtons - 1, #inputArray) local totalRows = math.ceil(maxButtons / config.buttonsPerRow) local totalWidth = config.buttonsPerRow * (config.buttonWidth + spacingX) - spacingX local startX = math.floor((w - totalWidth) / 2) + 1 for i = startIndex, endIndex do -- Calculate the position of the current button local col = (i - 1) % config.buttonsPerRow local row = math.floor((i - 1) / config.buttonsPerRow) % totalRows local x = startX + col * (config.buttonWidth + spacingX) local y = 9 + row * (config.buttonHeight + spacingY) -- Place the button at the calculated position local entry = inputArray[i] button.setTable(entry.key, function() setFrequency(entry.key) end, x, x + config.buttonWidth - 1, y, y + config.buttonHeight - 1) end if currentPage > 1 then button.setTable("Previous", prevPage, 2 , 22 , 35 , 37) end button.setTable("Refresh", refresh, 30 , 50 , 35 , 37) if currentPage < totalPages then button.setTable("Next" , nextPage, 58 , 78 , 35 , 37) end button.screen() end -- Function to display portal information. function displayInfo() mon.setCursorPos(10, 6) mon.setBackgroundColor(config.infoBG) mon.setTextColor(colors.white) mon.write("Active Portal: Status: ") end -- Function to update portal information continuously. local function updateInfo() while true do local afq = tp.getFrequency() local sfq = tp.getStatus() mon.setCursorPos(25,6) mon.setBackgroundColor(config.infoBG) mon.setTextColor(colors.white) mon.write(string.format("%-25s", afq.key)) mon.setCursorPos(60,6) mon.write(string.format("%-10s", sfq:sub(1, 1):upper() .. sfq:sub(2))) mon.setBackgroundColor(colors.black) os.sleep(0.25) end end -- Function to initialize the main interface. local function main() button.clearTable() checkMonitorSize() fillTable() button.drawButtonBoxes(config.boxColor) button.drawBox(5, 5, 74, 7, config.infoBG) button.drawBox(5, 6, 74, 6, config.infoBG) button.heading(" Portal Control ", 2, config.infoBG) displayInfo() local activeFreq = tp.getFrequency() if not debug then button.toggleButton(activeFreq.key) end end -- Functions to navigate to the next page of portals. function nextPage() currentPage = currentPage + 1 button.flash("Next") main() end -- Functions to navigate to the previous page of portals. function prevPage() if currentPage > 1 then currentPage = currentPage - 1 button.flash("Previous") main() end end -- Function to refresh the portal list. function refresh() button.flash("Refresh") inputArray = debug and debugArray or tp.getFrequencies() main() end -- Function to handle monitor touch events. local function getClick() event,side,x,y = os.pullEvent("monitor_touch") button.checkxy(x,y) end -- Function to auto-refresh frequencies. local function autoRefresh() while true do os.sleep(config.updateTime) inputArray = debug and debugArray or tp.getFrequencies() main() end end -- Initialize the main interface. main() -- Continuously wait for monitor touch events or display portal information. while true do parallel.waitForAny(getClick, updateInfo, autoRefresh) end