Add support for regional leaderboards
5
index.js
|
@ -14,6 +14,7 @@ import { generateDB } from './libs/database/generate.js'
|
|||
import { dbInit } from './libs/database/init.js'
|
||||
import { getStats, setStat } from './libs/serverStats.js'
|
||||
import { downloadEssentialData } from './libs/download/dowload.js'
|
||||
import { ddnssStart } from './libs/ddnss/handler.js'
|
||||
|
||||
const start = Date.now()
|
||||
const log = initLog("[ MAIN ]")
|
||||
|
@ -49,4 +50,6 @@ Server.use('/assets', express.static('static'))
|
|||
const elapsed = Date.now() - start
|
||||
log(`Took ${elapsed/1000} seconds to start the server!`)
|
||||
|
||||
Server.listen(process.env.PORT ?? 12345, () => log(`Server started and listening on port ${process.env.PORT}.`))
|
||||
Server.listen(process.env.PORT ?? 12345, () => log(`Server started and listening on port ${process.env.PORT}.`))
|
||||
|
||||
//ddnssStart()
|
|
@ -78,7 +78,8 @@ export function generateDB() {
|
|||
`CREATE INDEX IF NOT EXISTS "idx_rankings_rank" ON "rankings" ("rank")`,
|
||||
`CREATE INDEX IF NOT EXISTS "idx_rankings_player" ON "rankings" ("player")`,
|
||||
`CREATE INDEX IF NOT EXISTS "idx_rankings_finishes" ON "rankings" ("finishes")`,
|
||||
`CREATE INDEX IF NOT EXISTS "idx_rankings_mapRank" ON "rankings" ("map", "rank")`
|
||||
`CREATE INDEX IF NOT EXISTS "idx_rankings_mapRank" ON "rankings" ("map", "rank")`,
|
||||
`CREATE INDEX IF NOT EXISTS "idx_rankings_playerServer" ON "rankings" ("player", "server")`
|
||||
])
|
||||
|
||||
log("Generating teamrace index...")
|
||||
|
@ -181,4 +182,5 @@ export function generateDB() {
|
|||
"colorFeetHex" varchar(8) NOT NULL
|
||||
)
|
||||
`)
|
||||
skinDB.exec(`CREATE INDEX IF NOT EXISTS "idx_player" ON "skindata" ("player")`)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import decodeMsgpack from './decodeMsgpack.js'
|
||||
import { execMany } from './helper.js'
|
||||
import { sqlite } from './init.js'
|
||||
import { mapToRegion, playerServer } from './wrapper.js'
|
||||
|
||||
/**
|
||||
* This generates rankings for each map...
|
||||
|
@ -163,6 +164,7 @@ export function processAllPoints() {
|
|||
CREATE TABLE IF NOT EXISTS "points"
|
||||
(
|
||||
"type" varchar(16) NOT NULL,
|
||||
"region" varchar(24) NOT NULL,
|
||||
"rank" INTEGER NOT NULL,
|
||||
"player" varchar(16) NOT NULL,
|
||||
"points" INTEGER NOT NULL
|
||||
|
@ -178,25 +180,27 @@ export function processAllPoints() {
|
|||
.prepare(`
|
||||
INSERT INTO "points"
|
||||
(
|
||||
type, rank, player, points
|
||||
) VALUES (?, ?, ?, ?)
|
||||
type, region, rank, player, points
|
||||
) VALUES (?, ?, ?, ?, ?)
|
||||
`)
|
||||
.run(
|
||||
type,
|
||||
mapToRegion(playerServer(entry[0])),
|
||||
rank,
|
||||
entry[0],
|
||||
entry[1]
|
||||
)
|
||||
|
||||
++rank
|
||||
}
|
||||
console.log(`${type} Done...`)
|
||||
}
|
||||
|
||||
/* Generate indexes */
|
||||
execMany([
|
||||
`CREATE INDEX IF NOT EXISTS "idx_points_type" ON "points" ("type")`,
|
||||
`CREATE INDEX IF NOT EXISTS "Idx_points_rank" on "points" ("rank")`,
|
||||
`CREATE INDEX IF NOT EXISTS "Idx_points_name" on "points" ("player")`
|
||||
`CREATE INDEX IF NOT EXISTS "idx_points_rank" on "points" ("rank")`,
|
||||
`CREATE INDEX IF NOT EXISTS "idx_points_name" on "points" ("player")`
|
||||
`CREATE INDEX IF NOT EXISTS "idx_points_name" on "points" ("region", "type")`
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { sqlite } from './init.js'
|
||||
import { sqlite, skinDB } from './init.js'
|
||||
import { simpleSanitize } from './searcher.js'
|
||||
/**
|
||||
* This function checks if a player exists
|
||||
|
@ -222,17 +222,32 @@ export function leaderboardRace(map, start, end) {
|
|||
* (points, pointsRank, pointsTeam, pointsThisWeek, pointsThisMonth)
|
||||
*
|
||||
* @param {string} type Which type of points to fetch
|
||||
* @param {string} region Which region should be included (Global, Europe, Asia, SA, NA, Africa, ME, OLD, Other)
|
||||
* @param {number} start At which rank the leaderboard should begin
|
||||
* @param {number} end At which rank the leaderboard should end
|
||||
|
||||
* @returns {array} An array containing the leaderboard
|
||||
*/
|
||||
export function leaderboardPoints(type, start, end) {
|
||||
const leaderboard = sqlite.prepare(`
|
||||
SELECT rank, player, points FROM points WHERE type = ? AND rank >= ? AND rank <= ? ORDER BY rank`)
|
||||
.all(type, start, end)
|
||||
export function leaderboardPoints(type, region, start, end) {
|
||||
let output = []
|
||||
let leaderboard
|
||||
|
||||
return leaderboard
|
||||
if(region == "Global") {
|
||||
leaderboard = sqlite.prepare(`
|
||||
SELECT rank, region, player, points FROM points WHERE type = ? AND rank >= ? AND rank <= ? ORDER BY rank`)
|
||||
.all(type, start, end)
|
||||
}
|
||||
else {
|
||||
leaderboard = sqlite.prepare(`
|
||||
SELECT rank, region, player, points FROM points WHERE type = ? AND region = ? ORDER BY rank ASC LIMIT ?, ${end}`)
|
||||
.all(type, region, start - 1)
|
||||
}
|
||||
for (const entry of leaderboard) {
|
||||
let flag = skinDB.prepare(`SELECT flag FROM skindata WHERE player = ?`).get(entry.player)?.flag ?? "default"
|
||||
|
||||
output.push({ rank: entry.rank, player: entry.player, points: entry.points, region: entry.region, flag: flag })
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -376,6 +391,80 @@ export function searchMap(query, categories, stars, sortBy, order) {
|
|||
|
||||
return output
|
||||
}
|
||||
/*
|
||||
Europe
|
||||
/ RUS - Russia
|
||||
/ GER - Germany
|
||||
/ NLD - Netherlands
|
||||
/ TUR - Turkey
|
||||
/ POL - Poland
|
||||
/ FRA - France
|
||||
|
||||
Asia
|
||||
/ IND - INDIA
|
||||
/ SGP - Singapore
|
||||
/ CHN - China
|
||||
/ JAP - Japan
|
||||
/ KOR - South Korea
|
||||
|
||||
South America
|
||||
/ COL - Columbia
|
||||
/ ARG - Argentina
|
||||
/ CHL - Chile
|
||||
/ BRA - Brazil
|
||||
|
||||
North America
|
||||
/ CAN - Cananda
|
||||
/ USA - USA
|
||||
|
||||
Africa
|
||||
/ ZAF - South Africa
|
||||
|
||||
Middle east
|
||||
/ KSA/UAE/IRN
|
||||
|
||||
Others
|
||||
/ CRI - Costa Rica
|
||||
/ AUS - Australia
|
||||
/ OLD ranks (NA/EU)
|
||||
/ UNK - Some bugged ranks
|
||||
|
||||
*/
|
||||
export function mapToRegion(srv) {
|
||||
if(srv == "RUS" || srv == "GER" || srv == "NLD" || srv == "TUR" || srv == "POL" || srv == "FRA")
|
||||
return "Europe"
|
||||
|
||||
if(srv == "IND" || srv == "SGP" || srv == "CHN" || srv == "JAP" || srv == "KOR")
|
||||
return "Asia"
|
||||
|
||||
if(srv == "COL" || srv == "ARG" || srv == "CHL" || srv == "BRA")
|
||||
return "SA"
|
||||
|
||||
if(srv == "CAN" || srv == "USA")
|
||||
return "NA"
|
||||
|
||||
if(srv == "ZAF")
|
||||
return "Africa"
|
||||
|
||||
/* Middle east */
|
||||
if(srv == "KSA" || srv == "UAE" || srv == "IRN")
|
||||
return "ME"
|
||||
|
||||
if(srv == "")
|
||||
return "OLD"
|
||||
|
||||
return "Other"
|
||||
}
|
||||
|
||||
export function playerServer(player) {
|
||||
/* This can be undefined if a player has changed their name */
|
||||
const server = sqlite.prepare(
|
||||
`SELECT server, COUNT(server) as a FROM rankings WHERE player = ? GROUP BY server ORDER BY a DESC`)
|
||||
.get(player)?.server ?? ""
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
playerExists,
|
||||
|
@ -393,4 +482,7 @@ export default {
|
|||
leaderboardRace,
|
||||
leaderboardTeamrace,
|
||||
categoryExists,
|
||||
|
||||
mapToRegion,
|
||||
playerServer,
|
||||
}
|
|
@ -53,11 +53,11 @@ routes.get(
|
|||
'/leaderboards',
|
||||
(req, res) => {
|
||||
const leaderboards = {
|
||||
points: wrapper.leaderboardPoints("points", 1, 10),
|
||||
pointsRank: wrapper.leaderboardPoints("pointsRank", 1, 10),
|
||||
pointsTeam: wrapper.leaderboardPoints("pointsTeam", 1, 10),
|
||||
pointsThisWeek: wrapper.leaderboardPoints("pointsThisWeek", 1, 10),
|
||||
pointsThisMonth: wrapper.leaderboardPoints("pointsThisMonth", 1, 10)
|
||||
points: wrapper.leaderboardPoints("points", "Global", 1, 10),
|
||||
pointsRank: wrapper.leaderboardPoints("pointsRank", "Global", 1, 10),
|
||||
pointsTeam: wrapper.leaderboardPoints("pointsTeam", "Global", 1, 10),
|
||||
pointsThisWeek: wrapper.leaderboardPoints("pointsThisWeek", "Global", 1, 10),
|
||||
pointsThisMonth: wrapper.leaderboardPoints("pointsThisMonth", "Global", 1, 10)
|
||||
}
|
||||
|
||||
tx(req, res)('pages/leaderboards.njk', { leaderboards }, true, { currentSection: "leaderboards" })
|
||||
|
|
BIN
static/countryflags/AD.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
static/countryflags/AE.png
Executable file
After Width: | Height: | Size: 707 B |
BIN
static/countryflags/AF.png
Executable file
After Width: | Height: | Size: 2.5 KiB |
BIN
static/countryflags/AG.png
Executable file
After Width: | Height: | Size: 2.0 KiB |
BIN
static/countryflags/AI.png
Executable file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/countryflags/AL.png
Executable file
After Width: | Height: | Size: 2.1 KiB |
BIN
static/countryflags/AM.png
Executable file
After Width: | Height: | Size: 636 B |
BIN
static/countryflags/AO.png
Executable file
After Width: | Height: | Size: 1.6 KiB |
BIN
static/countryflags/AR.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
static/countryflags/AS.png
Executable file
After Width: | Height: | Size: 3.8 KiB |
BIN
static/countryflags/AT.png
Executable file
After Width: | Height: | Size: 723 B |
BIN
static/countryflags/AU.png
Executable file
After Width: | Height: | Size: 2.2 KiB |
BIN
static/countryflags/AW.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
static/countryflags/AX.png
Executable file
After Width: | Height: | Size: 910 B |
BIN
static/countryflags/AZ.png
Executable file
After Width: | Height: | Size: 1.2 KiB |
BIN
static/countryflags/BA.png
Executable file
After Width: | Height: | Size: 2.0 KiB |
BIN
static/countryflags/BB.png
Executable file
After Width: | Height: | Size: 1.2 KiB |
BIN
static/countryflags/BD.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/BE.png
Executable file
After Width: | Height: | Size: 567 B |
BIN
static/countryflags/BF.png
Executable file
After Width: | Height: | Size: 982 B |
BIN
static/countryflags/BG.png
Executable file
After Width: | Height: | Size: 709 B |
BIN
static/countryflags/BH.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
static/countryflags/BI.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
static/countryflags/BJ.png
Executable file
After Width: | Height: | Size: 677 B |
BIN
static/countryflags/BL.png
Executable file
After Width: | Height: | Size: 6.6 KiB |
BIN
static/countryflags/BM.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
static/countryflags/BN.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
BIN
static/countryflags/BO.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/countryflags/BR.png
Executable file
After Width: | Height: | Size: 2.5 KiB |
BIN
static/countryflags/BS.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
static/countryflags/BT.png
Executable file
After Width: | Height: | Size: 4.0 KiB |
BIN
static/countryflags/BW.png
Executable file
After Width: | Height: | Size: 639 B |
BIN
static/countryflags/BY.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/countryflags/BZ.png
Executable file
After Width: | Height: | Size: 4.9 KiB |
BIN
static/countryflags/CA.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
static/countryflags/CC.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
static/countryflags/CD.png
Executable file
After Width: | Height: | Size: 2.6 KiB |
BIN
static/countryflags/CF.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/CG.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
static/countryflags/CH.png
Executable file
After Width: | Height: | Size: 827 B |
BIN
static/countryflags/CI.png
Executable file
After Width: | Height: | Size: 669 B |
BIN
static/countryflags/CK.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
static/countryflags/CL.png
Executable file
After Width: | Height: | Size: 914 B |
BIN
static/countryflags/CM.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/CN.png
Executable file
After Width: | Height: | Size: 1.2 KiB |
BIN
static/countryflags/CO.png
Executable file
After Width: | Height: | Size: 698 B |
BIN
static/countryflags/CR.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
static/countryflags/CU.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
static/countryflags/CV.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/countryflags/CW.png
Executable file
After Width: | Height: | Size: 1007 B |
BIN
static/countryflags/CX.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
static/countryflags/CY.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/countryflags/CZ.png
Executable file
After Width: | Height: | Size: 890 B |
BIN
static/countryflags/DE.png
Executable file
After Width: | Height: | Size: 561 B |
BIN
static/countryflags/DJ.png
Executable file
After Width: | Height: | Size: 1.6 KiB |
BIN
static/countryflags/DK.png
Executable file
After Width: | Height: | Size: 803 B |
BIN
static/countryflags/DM.png
Executable file
After Width: | Height: | Size: 2.1 KiB |
BIN
static/countryflags/DO.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/countryflags/DZ.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/countryflags/EC.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
static/countryflags/EE.png
Executable file
After Width: | Height: | Size: 559 B |
BIN
static/countryflags/EG.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
static/countryflags/EH.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
static/countryflags/ER.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
static/countryflags/ES.png
Executable file
After Width: | Height: | Size: 2.0 KiB |
BIN
static/countryflags/ET.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
static/countryflags/FI.png
Executable file
After Width: | Height: | Size: 765 B |
BIN
static/countryflags/FJ.png
Executable file
After Width: | Height: | Size: 3.0 KiB |
BIN
static/countryflags/FK.png
Executable file
After Width: | Height: | Size: 3.8 KiB |
BIN
static/countryflags/FM.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
static/countryflags/FO.png
Executable file
After Width: | Height: | Size: 918 B |
BIN
static/countryflags/FR.png
Executable file
After Width: | Height: | Size: 664 B |
BIN
static/countryflags/GA.png
Executable file
After Width: | Height: | Size: 724 B |
BIN
static/countryflags/GB.png
Executable file
After Width: | Height: | Size: 2.6 KiB |
BIN
static/countryflags/GD.png
Executable file
After Width: | Height: | Size: 2.5 KiB |
BIN
static/countryflags/GE.png
Executable file
After Width: | Height: | Size: 1.4 KiB |
BIN
static/countryflags/GF.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/countryflags/GG.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/GH.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/GI.png
Executable file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/countryflags/GL.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/countryflags/GM.png
Executable file
After Width: | Height: | Size: 720 B |
BIN
static/countryflags/GN.png
Executable file
After Width: | Height: | Size: 649 B |
BIN
static/countryflags/GP.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/GQ.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/countryflags/GR.png
Executable file
After Width: | Height: | Size: 921 B |
BIN
static/countryflags/GS.png
Executable file
After Width: | Height: | Size: 4.5 KiB |
BIN
static/countryflags/GT.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
static/countryflags/GU.png
Executable file
After Width: | Height: | Size: 2.1 KiB |
BIN
static/countryflags/GW.png
Executable file
After Width: | Height: | Size: 1.0 KiB |
BIN
static/countryflags/GY.png
Executable file
After Width: | Height: | Size: 2.7 KiB |
BIN
static/countryflags/HK.png
Executable file
After Width: | Height: | Size: 1.9 KiB |
BIN
static/countryflags/HN.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
static/countryflags/HR.png
Executable file
After Width: | Height: | Size: 2.2 KiB |
BIN
static/countryflags/HT.png
Executable file
After Width: | Height: | Size: 1.4 KiB |