add score acc chart
Some checks failed
Deploy Backend / docker (ubuntu-latest) (push) Failing after 32s
Deploy Website / docker (ubuntu-latest) (push) Failing after 31s

This commit is contained in:
Lee
2024-10-23 17:44:55 +01:00
parent 0731d20edc
commit 90c57ad086
23 changed files with 387 additions and 19 deletions

View File

@ -0,0 +1,35 @@
import Service from "../service";
import { BeatSaverMapToken } from "../../types/token/beatsaver/map";
import { ScoreStatsToken } from "../../types/token/beatleader/score-stats/score-stats";
const LOOKUP_MAP_STATS_BY_SCORE_ID_ENDPOINT = `https://cdn.scorestats.beatleader.xyz/:scoreId.json`;
class BeatLeaderService extends Service {
constructor() {
super("BeatLeader");
}
/**
* Looks up the score stats for a score
*
* @param scoreId the score id to get
* @returns the score stats, or undefined if nothing was found
*/
async lookupScoreStats(scoreId: number): Promise<ScoreStatsToken | undefined> {
const before = performance.now();
this.log(`Looking score stats for "${scoreId}"...`);
const response = await this.fetch<ScoreStatsToken>(
LOOKUP_MAP_STATS_BY_SCORE_ID_ENDPOINT.replace(":scoreId", scoreId)
);
// Score stats not found
if (response == undefined) {
return undefined;
}
this.log(`Found score stats for score "${scoreId}" in ${(performance.now() - before).toFixed(0)}ms`);
return response;
}
}
export const beatLeaderService = new BeatLeaderService();

View File

@ -1,5 +1,5 @@
import { BeatLeaderModifierToken } from "./beatleader-modifiers-token";
import { BeatLeaderModifierRatingToken } from "./beatleader-modifier-rating-token";
import { BeatLeaderModifierToken } from "./modifier/modifiers";
import { BeatLeaderModifierRatingToken } from "./modifier/modifier-rating";
export type BeatLeaderDifficultyToken = {
id: number;

View File

@ -1,5 +1,5 @@
import { BeatLeaderSongToken } from "./beatleader-song-token";
import { BeatLeaderDifficultyToken } from "./beatleader-difficulty-token";
import { BeatLeaderSongToken } from "./score/song";
import { BeatLeaderDifficultyToken } from "./difficulty";
export type BeatLeaderLeaderboardToken = {
id: string;

View File

@ -0,0 +1,66 @@
export type ScoreStatsAccuracyTrackerToken = {
/**
* The accuracy of the right hand.
*/
accRight: number;
/**
* The accuracy of the left hand.
*/
accLeft: number;
/**
* The left hand pre-swing.
*/
leftPreswing: number;
/**
* The right hand pre-swing.
*/
rightPreswing: number;
/**
* The average pre-swing.
*/
averagePreswing: number;
/**
* The left hand post-swing.
*/
leftPostswing: number;
/**
* The right hand post-swing.
*/
rightPostswing: number;
/**
* The left hand time dependence.
*/
leftTimeDependence: number;
/**
* The right hand time dependence.
*/
rightTimeDependence: number;
/**
* The left hand average cut.
*/
leftAverageCut: number[];
/**
* The right hand average cut.
*/
rightAverageCut: number[];
/**
* The grid accuracy.
*/
gridAcc: number[];
/**
* The full combo accuracy.
*/
fcAcc: number;
};

View File

@ -0,0 +1,16 @@
export type ScoreStatsHeadPositionToken = {
/**
* The X position of the head
*/
x: number;
/**
* The Y position of the head
*/
y: number;
/**
* The Z position of the head
*/
z: number;
};

View File

@ -0,0 +1,51 @@
export type ScoreStatsHitTrackerToken = {
/**
* The maximum combo achieved.
*/
maxCombo: number;
/**
* The highest amount of 115 notes hit in a row.
*/
maxStreak: number;
/**
* The left hand timing.
*/
leftTiming: number;
/**
* The right hand timing.
*/
rightTiming: number;
/**
* The left hand misses.
*/
leftMiss: number;
/**
* The right hand misses.
*/
rightMiss: number;
/**
* The left hand bad cuts.
*/
leftBadCuts: number;
/**
* The right hand bad cuts.
*/
rightBadCuts: number;
/**
* The left hand bombs.
*/
leftBombs: number;
/**
* The right hand bombs.
*/
rightBombs: number;
};

View File

@ -0,0 +1,6 @@
export type ScoreStatsGraphTrackerToken = {
/**
* The accuracy graph data.
*/
graph: number[];
};

View File

@ -0,0 +1,26 @@
import { ScoreStatsHitTrackerToken } from "./hit-tracker";
import { ScoreStatsAccuracyTrackerToken } from "./accuracy-tracker";
import { ScoreStatsWinTrackerToken } from "./win-tracker";
import { ScoreStatsGraphTrackerToken } from "./score-graph-tracker";
export type ScoreStatsToken = {
/**
* The hit tracker stats.
*/
hitTracker: ScoreStatsHitTrackerToken;
/**
* The accuracy tracker stats.
*/
accuracyTracker: ScoreStatsAccuracyTrackerToken;
/**
* The win tracker stats.
*/
winTracker: ScoreStatsWinTrackerToken;
/**
* The score graph tracker stats.
*/
scoreGraphTracker: ScoreStatsGraphTrackerToken;
};

View File

@ -0,0 +1,48 @@
import { ScoreStatsHeadPositionToken } from "./head-position";
export type ScoreStatsWinTrackerToken = {
/**
* Whether the score was won. (not failed)
*/
won: boolean;
/**
* The time the score ended.
*/
endTime: number;
/**
* The total amount of pauses.
*/
nbOfPause: number;
/**
* The total amount of pause time.
*/
totalPauseDuration: number;
/**
* The jump distance the score was played on.
*/
jumpDistance: number;
/**
* The average height of the player.
*/
averageHeight: number;
/**
* The average head position of the player.
*/
averageHeadPosition: ScoreStatsHeadPositionToken;
/**
* The total score.
*/
totalScore: number;
/**
* The maximum score for this song.
*/
maxScore: number;
};

View File

@ -1,7 +1,7 @@
import { BeatLeaderLeaderboardToken } from "./beatleader-leaderboard-token";
import { BeatLeaderScoreImprovementToken } from "./beatleader-score-improvement-token";
import { BeatLeaderScoreOffsetsToken } from "./beatleader-score-offsets-token";
import { BeatLeaderPlayerToken } from "./beatleader-player-token";
import { BeatLeaderLeaderboardToken } from "../leaderboard";
import { BeatLeaderScoreImprovementToken } from "./score-improvement";
import { BeatLeaderScoreOffsetsToken } from "./score-offsets";
import { BeatLeaderPlayerToken } from "../player";
export type BeatLeaderScoreToken = {
myScore: null; // ??

View File

@ -1,5 +1,5 @@
import { connectWebSocket, WebsocketCallbacks } from "./websocket";
import { BeatLeaderScoreToken } from "../types/token/beatleader/beatleader-score-token";
import { BeatLeaderScoreToken } from "../types/token/beatleader/score/score";
type BeatLeaderWebsocket = {
/**