From f9021413d4e5e5464724f6ed8b289c029cb8599f Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 30 Oct 2023 15:01:08 +0000 Subject: [PATCH] add score averages data --- src/db/schemas/score.ts | 22 ++++++++ src/services/updateData.ts | 103 ++++++++++++++++++++++++++++++++++++- 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/db/schemas/score.ts diff --git a/src/db/schemas/score.ts b/src/db/schemas/score.ts new file mode 100644 index 0000000..ebd7cba --- /dev/null +++ b/src/db/schemas/score.ts @@ -0,0 +1,22 @@ +import mongoose from "mongoose"; +const { Schema } = mongoose; + +const scoreSchema = new Schema({ + _id: String, + player: { + id: String, + hmd: String, + }, + acc: Number, + pp: Number, + stars: Number, + mistakes: { + badCuts: Number, + missed: Number, + }, + rank: Number, + maxCombo: Number, +}); + +export const Score = + mongoose.models.Score || mongoose.model("Score", scoreSchema); diff --git a/src/services/updateData.ts b/src/services/updateData.ts index 25c8a7e..e86447f 100644 --- a/src/services/updateData.ts +++ b/src/services/updateData.ts @@ -4,6 +4,7 @@ import { w3cwebsocket as WebsocketClient } from "websocket"; import { InfluxWriteAPI } from ".."; import { connectMongo } from "../db/mongo"; import { LeaderboardSchema } from "../db/schemas/leaderboard"; +import { Score } from "../db/schemas/score"; async function update() { const response = await axios.get("https://scoresaber.com/api/players/count"); @@ -40,7 +41,7 @@ async function connectWebsocket() { console.error("Websocket error:", error); }; - socket.onmessage = (message) => { + socket.onmessage = async (message) => { const data = message.data; let json; try { @@ -52,11 +53,49 @@ async function connectWebsocket() { const commandName = json.commandName; const commandData = json.commandData; if (commandName == "score") { + const { score, leaderboard } = commandData; totalScores++; LeaderboardSchema.updateOne( { _id: "scoresaber" }, { totalPlays: totalScores } ).exec(); + + const { + id, + hmd, + baseScore, + missedNotes, + badCuts, + leaderboardPlayerInfo: player, + pp, + } = score; + const { maxScore, stars, id: leaderboardId } = leaderboard; + + const data: any = { + _id: id, + player: { + id: player.id, + hmd: hmd, + }, + mistakes: { + badCuts: badCuts, + missed: missedNotes, + }, + rank: score.rank, + maxCombo: score.maxCombo, + leaderboardId: leaderboardId, + }; + if (maxScore) { + data.acc = ((baseScore / maxScore) * 100).toFixed(2); + } + if (pp && stars > 0) { + data.pp = pp; + data.stars = stars; + } + + await Score.findByIdAndDelete(id).exec(); + Score.create(data); + const point = new Point("scoresaber") .tag("type", "score_count") .intField("value", totalScores) @@ -66,6 +105,68 @@ async function connectWebsocket() { }; } +async function updateAverages() { + const before = new Date().getTime(); + Score.find({}).then((scores) => { + // create an average for all data for all scores + const average = { + acc: 0, + pp: 0, + stars: 0, + mistakes: { + badCuts: 0, + missed: 0, + }, + rank: 0, + maxCombo: 0, + }; + scores.forEach((score) => { + if (score.acc) { + average.acc += score.acc; + } + if (score.pp) { + average.pp += score.pp; + } + if (score.stars) { + average.stars += score.stars; + } + if (score.mistakes) { + average.mistakes.badCuts += score.mistakes.badCuts; + average.mistakes.missed += score.mistakes.missed; + } + if (score.rank) { + average.rank += score.rank; + } + if (score.maxCombo) { + average.maxCombo += score.maxCombo; + } + }); + average.acc /= scores.length; + average.pp /= scores.length; + average.stars /= scores.length; + average.mistakes.badCuts /= scores.length; + average.mistakes.missed /= scores.length; + average.rank /= scores.length; + average.maxCombo /= scores.length; + + // create the point and write it to influx + const point = new Point("scoresaber") + .tag("type", "average") + .floatField("acc", average.acc) + .floatField("pp", average.pp) + .floatField("stars", average.stars) + .floatField("badCuts", average.mistakes.badCuts) + .floatField("missed", average.mistakes.missed) + .floatField("rank", average.rank) + .floatField("maxCombo", average.maxCombo) + .timestamp(new Date()); + InfluxWriteAPI.writePoint(point); + console.log(`Updated averages in ${new Date().getTime() - before}ms`); + }); +} + update(); +updateAverages(); connectWebsocket(); setInterval(update, 60_000); // 1 minute +setInterval(updateAverages, 60_000 * 5); // 5 minutes