-- leaderboard.lua -- Fetches player stats and displays a cycling leaderboard on wrapped monitors. local API_URL = "https://script.lclr.dev/api/w/scripts/jobs/run_wait_result/p/f/scripts/cc-stats" local API_TOKEN = "4mHiIDc5y1YBX05j68MFyhVoo2qbICe3" local CYCLE_DELAY = 5 -- seconds per stat local FETCH_COOLDOWN = 300 -- seconds between fetches (5 minutes) -- Stats to cycle through (in order) local STAT_KEYS = { "playtime", "deaths", "mobs_killed", "damage_taken", "damage_dealt", "distance_walked", "lootr", "waystones", } -- Rank colours (ComputerCraft colour constants) local RANK_COLORS = { [1] = colors.yellow, -- gold [2] = colors.lightGray, [3] = colors.orange, -- brown-ish (closest CC colour) } local DEFAULT_COLOR = colors.white local TITLE_COLOR = colors.cyan local SEP_COLOR = colors.gray local LABEL_COLOR = colors.lightBlue local BG_COLOR = colors.black -- Helpers local function getMonitors() local mons = {} for _, name in ipairs(peripheral.getNames()) do if peripheral.getType(name) == "monitor" then local m = peripheral.wrap(name) if m then m.setTextScale(0.5) -- start at base scale; will be overridden table.insert(mons, m) end end end return mons end local function centerText(mon, y, text, color, scale) -- scale is unused here; CC monitors don't support per-text scaling, -- so we use setTextScale on the whole monitor between draws. local w, _ = mon.getSize() local x = math.max(1, math.floor((w - #text) / 2) + 1) mon.setCursorPos(x, y) if color then mon.setTextColor(color) end mon.write(text) end local function leftText(mon, y, text, color) mon.setCursorPos(1, y) if color then mon.setTextColor(color) end mon.write(text) end local function truncate(str, maxLen) if #str > maxLen then return str:sub(1, maxLen - 1) .. "." end return str end -- Data fetching local function fetchData() local ok, result = pcall(function() -- Build JSON payload with list of stats to fetch local payload = textutils.serialiseJSON(STAT_KEYS) local resp = http.post( API_URL, payload, { ["Content-Type"] = "application/json", ["Authorization"] = "Bearer " .. API_TOKEN } ) if not resp then error("HTTP request failed") end local raw = resp.readAll() resp.close() return textutils.unserialiseJSON(raw) end) if ok and type(result) == "table" then return result end return nil end -- Build sorted list of {username, value, type, label} for a given stat key. -- New format: {"":{"":{"type":"","data":"","label":"