init leaderboards branch

This commit is contained in:
Jack 2021-09-05 23:57:07 +01:00
parent 2160285e1e
commit 54c68e68bc
6 changed files with 242 additions and 9 deletions

View file

@ -0,0 +1,38 @@
const LeaderboardsDAO = require("../../dao/leaderboards");
class LeaderboardsController {
static async get(req, res, next) {
try {
const { language, mode, mode2 } = req.query;
if (!language || !mode || !mode2) {
return res.status(400).json({
message: "Missing parameters",
});
}
let retval = await LeaderboardsDAO.get(mode, mode2, language);
retval.forEach((item) => {
delete item.uid;
});
return res.status(200).json(retval);
} catch (e) {
return next(e);
}
}
static async update(req, res, next) {
try {
const { language, mode, mode2 } = req.body;
if (!language || !mode || !mode2) {
return res.status(400).json({
message: "Missing parameters",
});
}
let retval = await LeaderboardsDAO.update(mode, mode2, language);
return res.status(200).json(retval);
} catch (e) {
return next(e);
}
}
}
module.exports = LeaderboardsController;

View file

@ -0,0 +1,22 @@
const { authenticateRequest } = require("../../middlewares/auth");
const LeaderboardsController = require("../controllers/leaderboards");
const RateLimit = require("../../middlewares/rate-limit");
const { Router } = require("express");
const router = Router();
router.get(
"/",
RateLimit.limit1persec,
authenticateRequest,
LeaderboardsController.get
);
router.post(
"/debug_update",
RateLimit.limit1persec,
LeaderboardsController.update
);
module.exports = router;

View file

@ -0,0 +1,84 @@
const MonkeyError = require("../handlers/error");
const { mongoDB } = require("../init/mongodb");
const { ObjectID } = require("mongodb");
class LeaderboardsDAO {
static async get(mode, mode2, language) {
const preset = await mongoDB()
.collection(`leaderboards.${language}.${mode}.${mode2}`)
.find()
.toArray();
return preset;
}
static async getRank(mode, mode2, language, uid) {
const res = await mongoDB()
.collection(`leaderboards.${language}.${mode}.${mode2}`)
.findOne({ uid });
return res.rank;
}
static async update(mode, mode2, language, uid = undefined) {
let str = `lbPersonalBests.${mode}.${mode2}.${language}`;
let lb = await mongoDB()
.collection("users")
.aggregate([
{
$match: {
[str]: {
$exists: true,
},
},
},
{
$set: {
[str + ".uid"]: "$uid",
[str + ".name"]: "$name",
},
},
{
$replaceRoot: {
newRoot: "$" + str,
},
},
{
$sort: {
wpm: -1,
acc: -1,
timestamp: -1,
},
},
])
.toArray();
let rerval = undefined;
lb.forEach((lbEntry, index) => {
lbEntry.rank = index + 1;
if (uid && lbEntry.uid === uid) {
rerval = index + 1;
}
});
try {
await mongoDB()
.collection(`leaderboards.${language}.${mode}.${mode2}`)
.drop();
} catch (e) {}
await mongoDB()
.collection(`leaderboards.${language}.${mode}.${mode2}`)
.insertMany(lb);
if (rerval) {
return {
message: "Successfully updated leaderboard",
rank: retval,
};
} else {
return {
message: "Successfully updated leaderboard",
};
}
}
}
module.exports = LeaderboardsDAO;

View file

@ -191,6 +191,11 @@ class UsersDAO {
await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { personalBests: pb.obj } });
if (pb.lbPb) {
await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { lbPersonalBests: pb.lbPb } });
}
return true;
} else {
return false;

View file

@ -96,20 +96,50 @@ module.exports = {
});
}
let topIndex = 0;
let topWpm = 0;
obj[mode][mode2].forEach((pb, index) => {
delete pb.best;
if (pb.wpm > topWpm) {
topIndex = index;
topWpm = pb.wpm;
let lbPb;
if (isPb && mode === "time" && (mode2 == "15" || mode2 == "60")) {
lbPb = {
time: {
15: {},
60: {},
},
};
let bestForEveryLanguage = {};
if (obj?.time?.[15]) {
obj.time[15].forEach((pb) => {
if (!bestForEveryLanguage[pb.language]) {
bestForEveryLanguage[pb.language] = pb;
} else {
if (bestForEveryLanguage[pb.language].wpm < pb.wpm) {
bestForEveryLanguage[pb.language] = pb;
}
}
});
Object.keys(bestForEveryLanguage).forEach((key) => {
lbPb.time[15][key] = bestForEveryLanguage[key];
});
bestForEveryLanguage = {};
}
});
obj[mode][mode2][topIndex].best = true;
if (obj?.time?.[60]) {
obj.time[60].forEach((pb) => {
if (!bestForEveryLanguage[pb.language]) {
bestForEveryLanguage[pb.language] = pb;
} else {
if (bestForEveryLanguage[pb.language].wpm < pb.wpm) {
bestForEveryLanguage[pb.language] = pb;
}
}
});
Object.keys(bestForEveryLanguage).forEach((key) => {
lbPb.time[60][key] = bestForEveryLanguage[key];
});
}
}
return {
isPb,
obj,
lbPb,
};
},
};

View file

@ -32,6 +32,8 @@ const quoteRatings = require("./api/routes/quote-ratings");
app.use("/quote-ratings", quoteRatings);
const psaRouter = require("./api/routes/psa");
app.use("/psa", psaRouter);
const leaderboardsRouter = require("./api/routes/leaderboards");
app.use("/leaderboards", leaderboardsRouter);
app.use(function (e, req, res, next) {
let uid = undefined;
@ -70,4 +72,56 @@ app.listen(PORT, async () => {
credential: admin.credential.cert(serviceAccount),
});
console.log("Database Connected");
// refactor();
});
async function refactor() {
let users = await mongoDB().collection("users").find({}).toArray();
for (let user of users) {
let obj = user.personalBests;
lbPb = {
time: {
15: {},
60: {},
},
};
let bestForEveryLanguage = {};
if (obj?.time?.[15]) {
obj.time[15].forEach((pb) => {
if (!bestForEveryLanguage[pb.language]) {
bestForEveryLanguage[pb.language] = pb;
} else {
if (bestForEveryLanguage[pb.language].wpm < pb.wpm) {
bestForEveryLanguage[pb.language] = pb;
}
}
});
Object.keys(bestForEveryLanguage).forEach((key) => {
lbPb.time[15][key] = bestForEveryLanguage[key];
});
bestForEveryLanguage = {};
}
if (obj?.time?.[60]) {
obj.time[60].forEach((pb) => {
if (!bestForEveryLanguage[pb.language]) {
bestForEveryLanguage[pb.language] = pb;
} else {
if (bestForEveryLanguage[pb.language].wpm < pb.wpm) {
bestForEveryLanguage[pb.language] = pb;
}
}
});
Object.keys(bestForEveryLanguage).forEach((key) => {
lbPb.time[60][key] = bestForEveryLanguage[key];
});
}
await mongoDB()
.collection("users")
.updateOne({ _id: user._id }, { $set: { lbPersonalBests: lbPb } });
console.log(`updated ${user.name}`);
}
}