From 9905db00963f984426271feedcadd3a36adbccdd Mon Sep 17 00:00:00 2001 From: ibratabian17 Date: Fri, 18 Oct 2024 20:45:32 +0700 Subject: [PATCH] Improve DOTW and Leaderboard --- core/route/account.js | 1 + core/route/leaderboard.js | 142 +++++++++++++++++++++----------------- 2 files changed, 81 insertions(+), 62 deletions(-) diff --git a/core/route/account.js b/core/route/account.js index 043e372..2ce5380 100644 --- a/core/route/account.js +++ b/core/route/account.js @@ -296,6 +296,7 @@ exports.initroute = (app) => { // Entry exists for this profile, update if the new score is higher if ((currentScores[existingEntryIndex].score < song.score) && song.score <= 13334) { currentScores[existingEntryIndex].score = song.score; + currentScores[existingEntryIndex].weekOptain = getWeekNumber() console.log(`[DOTW] Updated score dotw list on map ${song.mapName}`); } else { return res.send('1'); // Do nothing if the new score is lower diff --git a/core/route/leaderboard.js b/core/route/leaderboard.js index 30387aa..9b72a91 100644 --- a/core/route/leaderboard.js +++ b/core/route/leaderboard.js @@ -12,26 +12,15 @@ const LEADERBOARD_PATH = path.join(core.getSavefilePath(), 'leaderboard/leaderbo const DOTW_PATH = path.join(core.getSavefilePath(), 'leaderboard/dotw.json'); const { getSavefilePath } = require('../helper'); -const { encrypt, decrypt } = require('../lib/encryptor') const secretKey = require('../../database/encryption.json').encrpytion.userEncrypt; decryptedData = {}; -function generateToolNickname() { - const prefixes = ["Wordkeeper", "Special", "Krakenbite", "DinosaurFan", "Definehub", "Termtracker", "Lexiconet", "Vocabvault", "Lingolink", "Glossarygenius", "Thesaurustech", "Synonymster", "Definitionary", "Jargonjot", "Idiomizer", "Phraseforge", "Meaningmaker", "Languageledger", "Etymologyengine", "Grammarguard", "Syntaxsense", "Semanticsearch", "Orthographix", "Phraseology", "Vernacularvault", "Dictionet", "Slangscroll", "Lingualist", "Grammargrid", "Lingoledge", "Termtoolbox", "Wordware", "Lexigizmo", "Synosearch", "Thesaurustech", "Phrasefinder", "Vocabvortex", "Meaningmatrix", "Languageledger", "Etymologist", "Grammargate", "Syntaxsphere", "Semanticsearch", "Orthographix", "Phraseplay", "Vernacularvault", "Dictionator", "Slangstack", "Lingolink", "Grammarguide", "Lingopedia", "Termtracker", "Wordwizard", "Lexilist", "Synomate", "Thesaurustool", "Definitizer", "Jargonjunction", "Idiomgenius", "Phrasemaker", "Meaningmate", "Duolingo", "Languagelink", "Etymoengine", "Grammarguru", "Syntaxsage", "Semanticsuite", "Orthography", "Phrasefinder", "Vocabverse", "Lexipedia", "Synoscribe", "Thesaurusware", "Definitionary", "Jargonscribe", "Idiomster", "Phrasetech", "Meaningmax", "Flop", "Slayguy", "Languagelex", "Etymoedge", "Grammargenie", "Syntaxsync", "Semanticsearch", "Orthography", "Phraseforge", "Vernacularex", "Dictionmaster", "Slangster", "Lingoware", "Grammargraph", "Lingomate", "Termmate", "Wordwork", "Lexixpert", "Synostar", "Thesaurusmax", "OculusVision", "FlowerPower", "RustySilver", "Underfire", "Shakeawake", "Truthhand", "Kittywake", "Definize", "Jargonize", "Idiomify", "Phrasemaster", "Meaningmark", "Lingualine", "Etymogenius", "Grammarguard", "Syntaxsmart", "Semanticsearch", "Orthography", "Phrasedex", "Vocabmax", "Lexilock", "Synomind", "Thesaurusmart", "Definify", "Jargonmatrix", "Idiomnet", "Phraseplay", "Meaningmate", "Lingolink", "Etymoexpert", "Grammargetter", "Syntaxsage", "Semanticsearch", "Orthography", "Phrasepad", "Vernacularvibe", "Dictiondom", "Slangster", "Lingolytics", "Grammargenie", "Lingotutor", "Termtracker", "Wordwarp", "Lexisync", "Synomind", "Thesaurusmate", "Definizer", "Jargonify", "Idiomster", "Phraselab", "Meaningmark", "Languageleaf", "Etymoedge", "Grammargrid", "Syntaxsync", "Semanticsuite", "Orthographix", "Phraseforge", "Vernacularvibe", "Dictiondom", "Slangster", "Lingolytics", "Grammargenie", "Lingotutor", "Termtracker", "Wordwarp", "Lexisync", "Synomind", "Thesaurusmate", "Definizer", "Jargonify", "Idiomster", "Phraselab", "Meaningmark", "Languageleaf", "Etymoedge", "Grammargrid", "Syntaxsync", "Semanticsuite", "Orthographix"]; - const suffixes = ["", "K", "Eja", "Guru", "Master", "Expert", "Ninja", "Pro", "Genius", "Champion", "Mega", "Super", "Ultra", "Ok", "Boomer"]; - const numbers = Math.floor(Math.random() * 10000); // Generate a random 4-digit number - - const randomPrefix = prefixes[Math.floor(Math.random() * prefixes.length)]; - const randomSuffix = suffixes[Math.floor(Math.random() * suffixes.length)]; - - var name = ""; - if (Math.floor(Math.random() * 2) == 1) { - return randomPrefix + numbers; - } else { - return randomSuffix + numbers; - } - +function getWeekNumber() { + const now = new Date(); + const startOfWeek = new Date(now.getFullYear(), 0, 1); + const daysSinceStartOfWeek = Math.floor((now - startOfWeek) / (24 * 60 * 60 * 1000)); + return Math.ceil((daysSinceStartOfWeek + 1) / 7); } const getGameVersion = (req) => { @@ -40,37 +29,57 @@ const getGameVersion = (req) => { }; const initroute = (app) => { + const fs = require('fs'); + app.get("/leaderboard/v1/maps/:mapName/:type", async (req, res) => { const { mapName } = req.params; + const currentWeekNumber = getWeekNumber(); // Get the current week number + switch (req.params.type) { case "dancer-of-the-week": try { if (fs.existsSync(DOTW_PATH)) { const data = fs.readFileSync(DOTW_PATH, 'utf-8'); const leaderboard = JSON.parse(data); - + // Check if the map exists in the leaderboard if (leaderboard[mapName] && leaderboard[mapName].length > 0) { - // Find the highest score entry for this map - const highestEntry = leaderboard[mapName].reduce((max, entry) => entry.score > max.score ? entry : max); - - const dancerOfTheWeek = { - "__class": "DancerOfTheWeek", - "profileId": highestEntry.profileId, - "score": highestEntry.score, - "gameVersion": highestEntry.gameVersion || "jd2020", - "rank": highestEntry.rank, // Since it's the highest, assign rank 1 - "name": highestEntry.name, - "avatar": highestEntry.avatar, - "country": highestEntry.country, - "platformId": highestEntry.platformId, - "alias": highestEntry.alias, - "aliasGender": highestEntry.aliasGender, - "jdPoints": highestEntry.jdPoints, - "portraitBorder": highestEntry.portraitBorder - }; - - res.json(dancerOfTheWeek); + // Filter entries for the current week + const currentWeekEntries = leaderboard[mapName].filter( + entry => entry.weekOptain === currentWeekNumber + ); + + // Check if there are any entries for the current week + if (currentWeekEntries.length > 0) { + // Find the highest score entry for this map and current week + const highestEntry = currentWeekEntries.reduce((max, entry) => + entry.score > max.score ? entry : max + ); + + const dancerOfTheWeek = { + "__class": "DancerOfTheWeek", + "profileId": highestEntry.profileId, + "score": highestEntry.score, + "gameVersion": highestEntry.gameVersion || "jd2020", + "rank": highestEntry.rank || 1, // Since it's the highest, assign rank 1 + "name": highestEntry.name, + "avatar": highestEntry.avatar, + "country": highestEntry.country, + "platformId": highestEntry.platformId, + "alias": highestEntry.alias, + "aliasGender": highestEntry.aliasGender, + "jdPoints": highestEntry.jdPoints, + "portraitBorder": highestEntry.portraitBorder + }; + + res.json(dancerOfTheWeek); + } else { + // No entries for the current week, return default response + res.json({ + "__class": "DancerOfTheWeek", + "gameVersion": "jd2019", + }); + } } else { res.json({ "__class": "DancerOfTheWeek", @@ -78,7 +87,7 @@ const initroute = (app) => { }); } } else { - console.log('[ACC] Unable to find DOTW Files') + console.log('[ACC] Unable to find DOTW Files'); // If leaderboard file does not exist, return default "NO DOTW" response res.json({ "__class": "DancerOfTheWeek", @@ -89,57 +98,66 @@ const initroute = (app) => { console.error("Error:", error.message); res.status(500).send("Internal Server Error"); } - break; // <--- Add this break - + break; // Ensure break is here + case "friends": res.send({ __class: "LeaderboardList", entries: [] }); - break; // <--- Add this break - + break; + case "world": { let leaderboardData = { "__class": "LeaderboardList", "entries": [] }; - + try { // Read the leaderboard file const leaderboardFilePath = LEADERBOARD_PATH; if (fs.existsSync(leaderboardFilePath)) { const data = fs.readFileSync(leaderboardFilePath, 'utf-8'); const leaderboard = JSON.parse(data); - + // Check if there are entries for the mapName if (leaderboard[mapName]) { // Sort the leaderboard entries by score in descending order const sortedEntries = leaderboard[mapName].sort((a, b) => b.score - a.score); - - leaderboardData.entries = sortedEntries.map(entry => ({ - "__class": "LeaderboardEntry_Online", - "profileId": entry.profileId, - "score": entry.score, - "name": entry.nickname, - "avatar": entry.avatar, - "country": entry.country, - "platformId": entry.platformId, - "alias": entry.alias, - "aliasGender": entry.aliasGender, - "jdPoints": entry.jdPoints, - "portraitBorder": entry.portraitBorder, - "mapName": mapName - })); + + // Limit the sorted entries to the first 6 + const topSixEntries = sortedEntries.slice(0, 6); + let rank = 0; + + leaderboardData.entries = topSixEntries.map(entry => { + rank++; + const newLeaderboard = { + "__class": "LeaderboardEntry_Online", + "profileId": entry.profileId, + "score": entry.score, + "name": entry.name || entry.nickname, + "avatar": entry.avatar, + "rank": rank, + "country": entry.country, + "platformId": entry.platformId, + "alias": entry.alias, + "aliasGender": entry.aliasGender, + "jdPoints": entry.jdPoints, + "portraitBorder": entry.portraitBorder, + "mapName": mapName + } + return newLeaderboard; + }); } } - + res.json(leaderboardData); } catch (error) { console.error("Error:", error.message); res.status(500).send("Internal Server Error"); } - break; // <--- Add this break + break; } } }); - +