--TODO: ascending sort as well? --TODO: limit and cursor fields function handle() if not params.chart then error("chartNotFound") return end local chart = db.get(params.chart) if not chart then error("chartNotFound") return end local game = db.get(chart.game) local tableName = getTableName(chart.game) local componentOrder = game.componentOrder if not componentOrder and params.listComponents then componentOrder = toarray({}) local i = 0 for k, _ in game.scoreComponents do i = i+1 componentOrder[i] = k end end local mode = params.mode if game.modes and not mode then mode = game.modes[1] end local inputMethod = params.inputMethod if game.inputMethods and not inputMethod then inputMethod = game.inputMethods[1] end local versions = params.versions if chart.rankedVersions and not versions then versions = chart.rankedVersions end local sortBy = params.sortBy if not sortBy then sortBy = game.defaultComponent end local query = "SELECT uri, did, MAX(" .. sortBy .. ") " query = query .. "FROM '" .. tableName .. "' WHERE chart = '" .. params.chart .. "' " if mode then query = query .. "AND mode = '" .. mode .. "' " end if inputMethod then query = query .. "AND inputMethod = '" .. inputMethod .. "' " end if versions then if #versions > 1 then query = query .. "AND (" for i, v in ipairs(versions) do query = query .. "version = '" .. v .. "' " if i < #versions then query = query .. "OR " end end query = query .. ") " else query = query .. "AND version = '" .. versions[1] .. "' " end end query = query .. "GROUP BY did ORDER BY " .. sortBy .. " DESC" local rows = db.raw(query) local leaderboard = toarray({}) for _, row in ipairs(rows) do local entry = {} entry["did"] = row.did local resp = http.get("https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc?identifier=" .. row.did) entry["handle"] = json.decode(resp.body).handle local profile = db.get("at://" .. row.did .. "/dev.tsunagite.profile/" .. tableName) if profile then entry["profile"] = profile end entry["score"] = db.get(row.uri) table.insert(leaderboard, entry) end local result = {["scores"] = leaderboard} if params.listComponents then result["components"] = game.scoreComponents result["componentOrder"] = componentOrder end return result end function getTableName(uri) local trimmed = string.sub(uri, string.len("at://")+1) local did = string.sub(trimmed, 1, string.find(trimmed, "/")-1) local _, j = string.find(trimmed, "dev.tsunagite.game/") local key = string.sub(trimmed, j+1, string.len(trimmed)) local resp = http.get("https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc?identifier=" .. did) local hdl = json.decode(resp.body).handle local splitHandle = {} for str in string.gmatch(hdl, "([^.]+)") do table.insert(splitHandle, str) end local result = "" for i=0, #splitHandle-1 do result = result .. splitHandle[#splitHandle-i] .. "." end result = result .. key return result end