function addToLeaderboard(lb, result, username) { //insertedAt is index of array inserted position, 1 is added after retData = { insertedAt: -1 }; //check for duplicate user for (i = 0; i < lb.board.length; i++) { if (lb.board[i].name == username) { if (lb.board[i].wpm <= result.wpm) { //delete old entry if speed is faster this time lb.board.splice(i, 1); retData.foundAt = i + 1; retData.newBest = true; } else { //don't add new entry if slower than last time return lb, { insertedAt: -1, foundAt: i + 1 }; } } } //when is newBest not true? retData.newBest = true; if (!retData.foundAt) retData.foundAt = -1; //determine if the entry should be hidden //add item to leaderboard const lbitem = { name: username, wpm: result.wpm, raw: result.rawWpm, acc: result.acc, consistency: result.consistency, mode: result.mode, mode2: result.mode2, timestamp: Date.now(), hidden: false, }; if (lb.board.length == 0) { console.log("adding to first position"); lb.board.push(lbitem); retData.insertedAt = 0; } else if (lbitem.wpm < lb.board.slice(-1)[0].wpm) { console.log("adding to the end"); console.log(lb.board.slice(-1)[0].wpm); lb.board.push(lbitem); retData.insertedAt = lb.board.length - 1; } else { console.log("searching for addition spot"); for (i = 0; i < lb.board.length; i++) { //start from top, if item wpm > lb item wpm, insert before it if (lbitem.wpm >= lb.board[i].wpm) { console.log("adding to daily lb position " + i); lb.board.splice(i, 0, lbitem); retData.insertedAt = i; break; } } if (lb.board.length > lb.size) { lb.pop(); } } return lb, retData; } app.post("/attemptAddToLeaderboards", authenticateToken, (req, res) => { const result = req.body.result; let retData = {}; User.findOne({ uid: req.uid }, (err, user) => { admin .auth() .getUser(req.uid) .then((fbUser) => { return fbUser.emailVerified; }) .then((emailVerified) => { if (user.emailVerified === false) { if (emailVerified === true) { user.emailVerified = true; } else { res.status(200).send({ needsToVerifyEmail: true }); return; } } if (user.name === undefined) { //cannot occur since name is required, why is this here? res.status(200).send({ noName: true }); return; } if (user.banned) { res.status(200).send({ banned: true }); return; } /* if (user.verified === false) { res.status(200).send({ needsToVerify: true }); return; }*/ Leaderboard.find( { mode: result.mode, mode2: result.mode2, }, (err, lbs) => { //for all leaderboards queried, determine if it qualifies, and add if it does lbs.forEach((lb) => { if ( lb.board.length == 0 || lb.board.length < lb.size || result.wpm > lb.board.slice(-1)[0].wpm ) { lb, (lbPosData = addToLeaderboard(lb, result, user.name)); //should uid be added instead of name? //or together console.log(user.lbMemory[lb.mode + lb.mode2][lb.type]); //lbPosData.foundAt = user.lbMemory[lb.mode+lb.mode2][lb.type]; retData[lb.type] = lbPosData; lb.save(); user.lbMemory[lb.mode + lb.mode2][lb.type] = retData[lb.type].insertedAt; //check if made global top 10 and send to discord if it did if (lb.type == "global") { let usr = user.discordId != undefined ? user.discordId : user.name; if ( retData.global !== null && retData.global.insertedAt >= 0 && retData.global.insertedAt <= 9 && retData.global.newBest ) { let lbstring = `${result.mode} ${result.mode2} global`; console.log( `sending command to the bot to announce lb update ${usr} ${ retData.global.insertedAt + 1 } ${lbstring} ${result.wpm}` ); announceLbUpdate( usr, retData.global.insertedAt + 1, lbstring, result.wpm, result.rawWpm, result.acc, result.consistency ); } } } }); } ).then((e) => { retData.status = 2; user.save(); res.json(retData); }); }); }); res.status(200); }); app.get("/getLeaderboard/:type/:mode/:mode2", (req, res) => { Leaderboard.findOne( { mode: req.params.mode, mode2: req.params.mode2, type: req.params.type }, (err, lb) => { res.send(lb); } ); }); // Initialize database leaderboards if no leaderboards exist and start clearDailyLeaderboards Leaderboard.findOne((err, lb) => { if (lb === null) { let lb = { size: 999, board: [], mode: "time", mode2: 15, type: "global", }; Leaderboard.create(lb); lb.mode2 = 60; Leaderboard.create(lb); lb.type = "daily"; lb.size = 100; Leaderboard.create(lb); lb.mode2 = 15; Leaderboard.create(lb); } }).then(() => { clearDailyLeaderboards(); }); // Daily leaderboard clear function function clearDailyLeaderboards() { var nextClear = new Date(); nextClear.setHours(24, 0, 0, 0); //next occurrence of 12am let currentTime = new Date(); Leaderboard.find({ type: "daily" }, (err, lbs) => { lbs.forEach((lb) => { lb.resetTime = nextClear; lb.save(); }); }); setTimeout(() => { Leaderboard.find({ type: "daily" }, (err, lbs) => { lbs.forEach((lb) => { User.findOne({ name: lb.board[0].name }, (err, user) => { if (user) { if (user.dailyLbWins === undefined) { user.dailyLbWins = { [lb.mode + lb.mode2]: 1, }; } else if (user.dailyLbWins[lb.mode + lb.mode2] === undefined) { user.dailyLbWins[lb.mode + lb.mode2] = 1; } else { user.dailyLbWins[lb.mode + lb.mode2]++; } user.save(); } }).then(() => { announceDailyLbResult(lb); lb.board = []; lb.save(); }); }); }); clearDailyLeaderboards(); }, nextClear.getTime() - currentTime.getTime()); }