diff --git a/bun.lockb b/bun.lockb index af22972..7933a79 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/projects/backend/package.json b/projects/backend/package.json index 4a5e990..5466fec 100644 --- a/projects/backend/package.json +++ b/projects/backend/package.json @@ -14,6 +14,7 @@ "@elysiajs/swagger": "^1.1.3", "@ssr/common": "workspace:common", "@tqman/nice-logger": "^1.0.1", + "@typegoose/auto-increment": "^4.7.0", "@typegoose/typegoose": "^12.8.0", "@typescript-eslint/eslint-plugin": "^8.9.0", "@typescript-eslint/parser": "^8.9.0", diff --git a/projects/backend/src/index.ts b/projects/backend/src/index.ts index 575d649..37d3e54 100644 --- a/projects/backend/src/index.ts +++ b/projects/backend/src/index.ts @@ -8,7 +8,6 @@ import { etag } from "@bogeychan/elysia-etag"; import AppController from "./controller/app.controller"; import * as dotenv from "@dotenvx/dotenvx"; import mongoose from "mongoose"; -import { setLogLevel } from "@typegoose/typegoose"; import PlayerController from "./controller/player.controller"; import { PlayerService } from "./service/player.service"; import { cron } from "@elysiajs/cron"; @@ -33,9 +32,10 @@ dotenv.config({ override: true, }); +// Connect to Mongo await mongoose.connect(Config.mongoUri!); // Connect to MongoDB -setLogLevel("DEBUG"); +// Connect to websockets connectScoresaberWebsocket({ onScore: async score => { await ScoreService.trackScoreSaberScore(score); diff --git a/projects/backend/src/service/score.service.ts b/projects/backend/src/service/score.service.ts index 82de6d8..784f446 100644 --- a/projects/backend/src/service/score.service.ts +++ b/projects/backend/src/service/score.service.ts @@ -7,7 +7,6 @@ import BeatSaverService from "./beatsaver.service"; import ScoreSaberLeaderboard, { getScoreSaberLeaderboardFromToken, } from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; -import { getScoreSaberScoreFromToken } from "@ssr/common/score/impl/scoresaber-score"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; import { ScoreSort } from "@ssr/common/score/score-sort"; import { Leaderboards } from "@ssr/common/leaderboard"; @@ -16,7 +15,6 @@ import LeaderboardService from "./leaderboard.service"; import { BeatSaverMap } from "@ssr/common/model/beatsaver/map"; import { PlayerScore } from "@ssr/common/score/player-score"; import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-response"; -import Score from "@ssr/common/score/score"; import PlayerScoresResponse from "@ssr/common/response/player-scores-response"; import { DiscordChannels, logToChannel } from "../bot/bot"; import { EmbedBuilder } from "discord.js"; @@ -30,6 +28,8 @@ import { AdditionalScoreDataModel, } from "@ssr/common/model/additional-score-data/additional-score-data"; import { BeatLeaderScoreImprovementToken } from "@ssr/common/types/token/beatleader/score/score-improvement"; +import { getScoreSaberScoreFromToken, ScoreSaberScoreModel } from "@ssr/common/model/score/impl/scoresaber-score"; +import { ScoreType } from "@ssr/common/model/score/score"; const playerScoresCache = new SSRCache({ ttl: 1000 * 60, // 1 minute @@ -52,7 +52,7 @@ export class ScoreService { } const { score: scoreToken, leaderboard: leaderboardToken } = playerScore; - const score = getScoreSaberScoreFromToken(scoreToken, leaderboardToken); + const score = getScoreSaberScoreFromToken(scoreToken, leaderboardToken, scoreToken.leaderboardPlayerInfo.id); const leaderboard = getScoreSaberLeaderboardFromToken(leaderboardToken); const playerInfo = score.playerInfo; @@ -153,8 +153,13 @@ export class ScoreService { player.markModified("statisticHistory"); await player.save(); + const scoreToken = getScoreSaberScoreFromToken(score, leaderboard, playerId); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + delete scoreToken.playerInfo; + await ScoreSaberScoreModel.create(scoreToken); console.log( - `Updated scores set statistic for "${playerName}"(${playerId}), scores today: ${scores.rankedScores} ranked, ${scores.unrankedScores} unranked` + `Tracked score and updated scores set statistic for "${playerName}"(${playerId}), scores today: ${scores.rankedScores} ranked, ${scores.unrankedScores} unranked` ); } @@ -268,7 +273,7 @@ export class ScoreService { * Gets scores for a player. * * @param leaderboardName the leaderboard to get the scores from - * @param id the players id + * @param playerId the players id * @param page the page to get * @param sort the sort to use * @param search the search to use @@ -276,14 +281,14 @@ export class ScoreService { */ public static async getPlayerScores( leaderboardName: Leaderboards, - id: string, + playerId: string, page: number, sort: string, search?: string ): Promise | undefined> { return fetchWithCache( playerScoresCache, - `player-scores-${leaderboardName}-${id}-${page}-${sort}-${search}`, + `player-scores-${leaderboardName}-${playerId}-${page}-${sort}-${search}`, async () => { const scores: PlayerScore[] | undefined = []; let metadata: Metadata = new Metadata(0, 0, 0, 0); // Default values @@ -291,7 +296,7 @@ export class ScoreService { switch (leaderboardName) { case "scoresaber": { const leaderboardScores = await scoresaberService.lookupPlayerScores({ - playerId: id, + playerId: playerId, page: page, sort: sort as ScoreSort, search: search, @@ -308,17 +313,18 @@ export class ScoreService { ); for (const token of leaderboardScores.playerScores) { - const score = getScoreSaberScoreFromToken(token.score, token.leaderboard); + const score = getScoreSaberScoreFromToken(token.score, token.leaderboard, playerId); if (score == undefined) { continue; } + const leaderboard = getScoreSaberLeaderboardFromToken(token.leaderboard); if (leaderboard == undefined) { continue; } const additionalData = await this.getAdditionalScoreData( - id, + playerId, leaderboard.songHash, `${leaderboard.difficulty.difficulty}-${leaderboard.difficulty.characteristic}`, score.score @@ -352,65 +358,73 @@ export class ScoreService { * Gets scores for a leaderboard. * * @param leaderboardName the leaderboard to get the scores from - * @param id the leaderboard id + * @param leaderboardId the leaderboard id * @param page the page to get * @returns the scores */ public static async getLeaderboardScores( leaderboardName: Leaderboards, - id: string, + leaderboardId: string, page: number ): Promise | undefined> { - return fetchWithCache(leaderboardScoresCache, `leaderboard-scores-${leaderboardName}-${id}-${page}`, async () => { - const scores: Score[] = []; - let leaderboard: Leaderboard | undefined; - let beatSaverMap: BeatSaverMap | undefined; - let metadata: Metadata = new Metadata(0, 0, 0, 0); // Default values + return fetchWithCache( + leaderboardScoresCache, + `leaderboard-scores-${leaderboardName}-${leaderboardId}-${page}`, + async () => { + const scores: ScoreType[] = []; + let leaderboard: Leaderboard | undefined; + let beatSaverMap: BeatSaverMap | undefined; + let metadata: Metadata = new Metadata(0, 0, 0, 0); // Default values - switch (leaderboardName) { - case "scoresaber": { - const leaderboardResponse = await LeaderboardService.getLeaderboard( - leaderboardName, - id - ); - if (leaderboardResponse == undefined) { - throw new NotFoundError(`Leaderboard "${leaderboardName}" not found`); - } - leaderboard = leaderboardResponse.leaderboard; - beatSaverMap = leaderboardResponse.beatsaver; + switch (leaderboardName) { + case "scoresaber": { + const leaderboardResponse = await LeaderboardService.getLeaderboard( + leaderboardName, + leaderboardId + ); + if (leaderboardResponse == undefined) { + throw new NotFoundError(`Leaderboard "${leaderboardName}" not found`); + } + leaderboard = leaderboardResponse.leaderboard; + beatSaverMap = leaderboardResponse.beatsaver; - const leaderboardScores = await scoresaberService.lookupLeaderboardScores(id, page); - if (leaderboardScores == undefined) { + const leaderboardScores = await scoresaberService.lookupLeaderboardScores(leaderboardId, page); + if (leaderboardScores == undefined) { + break; + } + + for (const token of leaderboardScores.scores) { + const score = getScoreSaberScoreFromToken( + token, + leaderboardResponse.leaderboard, + token.leaderboardPlayerInfo.id + ); + if (score == undefined) { + continue; + } + scores.push(score); + } + + metadata = new Metadata( + Math.ceil(leaderboardScores.metadata.total / leaderboardScores.metadata.itemsPerPage), + leaderboardScores.metadata.total, + leaderboardScores.metadata.page, + leaderboardScores.metadata.itemsPerPage + ); break; } - - for (const token of leaderboardScores.scores) { - const score = getScoreSaberScoreFromToken(token, leaderboardResponse.leaderboard); - if (score == undefined) { - continue; - } - scores.push(score); + default: { + throw new NotFoundError(`Leaderboard "${leaderboardName}" not found`); } + } - metadata = new Metadata( - Math.ceil(leaderboardScores.metadata.total / leaderboardScores.metadata.itemsPerPage), - leaderboardScores.metadata.total, - leaderboardScores.metadata.page, - leaderboardScores.metadata.itemsPerPage - ); - break; - } - default: { - throw new NotFoundError(`Leaderboard "${leaderboardName}" not found`); - } + return { + scores: scores, + leaderboard: leaderboard, + beatSaver: beatSaverMap, + metadata: metadata, + }; } - - return { - scores: scores, - leaderboard: leaderboard, - beatSaver: beatSaverMap, - metadata: metadata, - }; - }); + ); } } diff --git a/projects/common/package.json b/projects/common/package.json index 7a123a8..900637b 100644 --- a/projects/common/package.json +++ b/projects/common/package.json @@ -19,6 +19,7 @@ "typescript": "^5" }, "dependencies": { + "@typegoose/auto-increment": "^4.7.0", "@typegoose/typegoose": "^12.8.0", "ky": "^1.7.2", "ws": "^8.18.0" diff --git a/projects/common/src/model/additional-score-data/additional-score-data.ts b/projects/common/src/model/additional-score-data/additional-score-data.ts index 98f79a6..579eaf0 100644 --- a/projects/common/src/model/additional-score-data/additional-score-data.ts +++ b/projects/common/src/model/additional-score-data/additional-score-data.ts @@ -4,7 +4,7 @@ import { HandAccuracy } from "./hand-accuracy"; import { Misses } from "./misses"; /** - * The model for a BeatSaver map. + * The model for additional score data. */ @modelOptions({ options: { allowMixed: Severity.ALLOW }, diff --git a/projects/common/src/model/score/impl/scoresaber-score.ts b/projects/common/src/model/score/impl/scoresaber-score.ts new file mode 100644 index 0000000..d36ea1e --- /dev/null +++ b/projects/common/src/model/score/impl/scoresaber-score.ts @@ -0,0 +1,123 @@ +import { getModelForClass, modelOptions, plugin, Prop, ReturnModelType, Severity } from "@typegoose/typegoose"; +import Score from "../score"; +import { Modifier } from "../../../score/modifier"; +import ScoreSaberScoreToken from "../../../types/token/scoresaber/score-saber-score-token"; +import ScoreSaberLeaderboardToken from "../../../types/token/scoresaber/score-saber-leaderboard-token"; +import ScoreSaberLeaderboard from "../../../leaderboard/impl/scoresaber-leaderboard"; +import { type ScoreSaberLeaderboardPlayerInfoToken } from "../../../types/token/scoresaber/score-saber-leaderboard-player-info-token"; +import { Document } from "mongoose"; +import { AutoIncrementID } from "@typegoose/auto-increment"; + +@modelOptions({ + options: { allowMixed: Severity.ALLOW }, + schemaOptions: { + collection: "scoresaber-scores", + toObject: { + virtuals: true, + transform: function (_, ret) { + ret.id = ret._id; + delete ret._id; + delete ret.__v; + return ret; + }, + }, + }, +}) +@plugin(AutoIncrementID, { + field: "_id", + startAt: 1, + trackerModelName: "scores", + trackerCollection: "increments", + overwriteModelName: "scoresaber-scores", +}) +export class ScoreSaberScoreInternal extends Score { + /** + * The score's id. + */ + @Prop({ required: true, index: true }) + public readonly scoreId!: string; + + /** + * The leaderboard the score was set on. + */ + @Prop({ required: true, index: true }) + public readonly leaderboardId!: number; + + /** + * The amount of pp for the score. + * @private + */ + @Prop({ required: true }) + public readonly pp!: number; + + /** + * The weight of the score, or undefined if not ranked. + * @private + */ + @Prop() + public readonly weight?: number; + + /** + * The max combo of the score. + */ + @Prop({ required: true }) + public readonly maxCombo!: number; +} + +class ScoreSaberScorePublic extends ScoreSaberScoreInternal { + /** + * The player who set the score. + */ + public playerInfo!: ScoreSaberLeaderboardPlayerInfoToken; +} + +export type ScoreSaberScore = InstanceType; + +/** + * Gets a {@link ScoreSaberScore} from a {@link ScoreSaberScoreToken}. + * + * @param token the token to convert + * @param playerId the id of the player who set the score + * @param leaderboard the leaderboard the score was set on + */ +export function getScoreSaberScoreFromToken( + token: ScoreSaberScoreToken, + leaderboard: ScoreSaberLeaderboardToken | ScoreSaberLeaderboard, + playerId?: string +): ScoreSaberScore { + const modifiers: Modifier[] = + token.modifiers == undefined || token.modifiers === "" + ? [] + : token.modifiers.split(",").map(mod => { + mod = mod.toUpperCase(); + const modifier = Modifier[mod as keyof typeof Modifier]; + if (modifier === undefined) { + throw new Error(`Unknown modifier: ${mod}`); + } + return modifier; + }); + + return { + leaderboard: "scoresaber", + playerId: playerId || token.leaderboardPlayerInfo.id, + leaderboardId: leaderboard.id, + score: token.baseScore, + accuracy: (token.baseScore / leaderboard.maxScore) * 100, + rank: token.rank, + modifiers: modifiers, + misses: token.missedNotes + token.badCuts, + missedNotes: token.missedNotes, + badCuts: token.badCuts, + fullCombo: token.fullCombo, + timestamp: new Date(token.timeSet), + scoreId: token.id, + pp: token.pp, + weight: token.weight, + maxCombo: token.maxCombo, + playerInfo: token.leaderboardPlayerInfo, + }; +} + +export type ScoreSaberScoreDocument = ScoreSaberScore & Document; +export const ScoreSaberScoreModel: ReturnModelType = + getModelForClass(ScoreSaberScoreInternal); diff --git a/projects/common/src/model/score/score.ts b/projects/common/src/model/score/score.ts new file mode 100644 index 0000000..39aa040 --- /dev/null +++ b/projects/common/src/model/score/score.ts @@ -0,0 +1,96 @@ +import { Modifier } from "../../score/modifier"; +import { AdditionalScoreData } from "../additional-score-data/additional-score-data"; +import { type Leaderboards } from "../../leaderboard"; +import { prop } from "@typegoose/typegoose"; + +/** + * The model for a score. + */ +export default class Score { + /** + * The internal score id. + */ + @prop() + private _id?: number; + + /** + * The leaderboard the score is from. + */ + @prop({ required: true }) + public readonly leaderboard!: Leaderboards; + + /** + * The id of the player who set the score. + * @private + */ + @prop({ required: true, index: true }) + public readonly playerId!: string; + + /** + * The base score for the score. + * @private + */ + @prop({ required: true }) + public readonly score!: number; + + /** + * The accuracy of the score. + */ + @prop({ required: true }) + public readonly accuracy!: number; + + /** + * The rank for the score. + * @private + */ + @prop({ required: true }) + public readonly rank!: number; + + /** + * The modifiers used on the score. + * @private + */ + @prop({ enum: () => Modifier, type: String, required: true }) + public readonly modifiers!: Modifier[]; + + /** + * The total amount of misses. + * @private + */ + @prop({ required: true }) + public readonly misses!: number; + + /** + * The amount of missed notes. + */ + @prop({ required: true }) + public readonly missedNotes!: number; + + /** + * The amount of bad cuts. + * @private + */ + @prop({ required: true }) + public readonly badCuts!: number; + + /** + * Whether every note was hit. + * @private + */ + @prop({ required: true }) + public readonly fullCombo!: boolean; + + /** + * The additional data for the score. + */ + public additionalData?: AdditionalScoreData; + + /** + * The time the score was set. + * @private + */ + @prop({ required: true }) + public readonly timestamp!: Date; +} + +export type ScoreType = InstanceType; diff --git a/projects/common/src/score/impl/scoresaber-score.ts b/projects/common/src/score/impl/scoresaber-score.ts deleted file mode 100644 index 4706a17..0000000 --- a/projects/common/src/score/impl/scoresaber-score.ts +++ /dev/null @@ -1,76 +0,0 @@ -import Score from "../score"; -import { Modifier } from "../modifier"; -import ScoreSaberScoreToken from "../../types/token/scoresaber/score-saber-score-token"; -import ScoreSaberLeaderboardPlayerInfoToken from "../../types/token/scoresaber/score-saber-leaderboard-player-info-token"; -import ScoreSaberLeaderboardToken from "../../types/token/scoresaber/score-saber-leaderboard-token"; -import ScoreSaberLeaderboard from "../../leaderboard/impl/scoresaber-leaderboard"; - -export default interface ScoreSaberScore extends Score { - /** - * The score's id. - */ - readonly id: string; - - /** - * The amount of pp for the score. - * @private - */ - readonly pp: number; - - /** - * The weight of the score, or undefined if not ranked.s - * @private - */ - readonly weight?: number; - - /** - * The max combo of the score. - */ - readonly maxCombo: number; - - /** - * The player who set the score - */ - readonly playerInfo: ScoreSaberLeaderboardPlayerInfoToken; -} - -/** - * Gets a {@link ScoreSaberScore} from a {@link ScoreSaberScoreToken}. - * - * @param token the token to convert - * @param leaderboard the leaderboard the score was set on - */ -export function getScoreSaberScoreFromToken( - token: ScoreSaberScoreToken, - leaderboard?: ScoreSaberLeaderboardToken | ScoreSaberLeaderboard -): ScoreSaberScore { - const modifiers: Modifier[] = - token.modifiers == undefined || token.modifiers === "" - ? [] - : token.modifiers.split(",").map(mod => { - mod = mod.toUpperCase(); - const modifier = Modifier[mod as keyof typeof Modifier]; - if (modifier === undefined) { - throw new Error(`Unknown modifier: ${mod}`); - } - return modifier; - }); - - return { - leaderboard: "scoresaber", - score: token.baseScore, - accuracy: leaderboard ? (token.baseScore / leaderboard.maxScore) * 100 : Infinity, - rank: token.rank, - modifiers: modifiers, - misses: token.missedNotes + token.badCuts, - missedNotes: token.missedNotes, - badCuts: token.badCuts, - fullCombo: token.fullCombo, - timestamp: new Date(token.timeSet), - id: token.id, - pp: token.pp, - weight: token.weight, - maxCombo: token.maxCombo, - playerInfo: token.leaderboardPlayerInfo, - }; -} diff --git a/projects/common/src/score/score.ts b/projects/common/src/score/score.ts deleted file mode 100644 index fc78648..0000000 --- a/projects/common/src/score/score.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Modifier } from "./modifier"; -import { Leaderboards } from "../leaderboard"; -import { AdditionalScoreData } from "../model/additional-score-data/additional-score-data"; - -export default interface Score { - /** - * The leaderboard the score is from. - */ - readonly leaderboard: Leaderboards; - - /** - * The base score for the score. - * @private - */ - readonly score: number; - - /** - * The accuracy of the score. - */ - readonly accuracy: number; - - /** - * The rank for the score. - * @private - */ - readonly rank: number; - - /** - * The modifiers used on the score. - * @private - */ - readonly modifiers: Modifier[]; - - /** - * The amount total amount of misses. - * @private - */ - readonly misses: number; - - /** - * The amount of missed notes. - */ - readonly missedNotes: number; - - /** - * The amount of bad cuts. - * @private - */ - readonly badCuts: number; - - /** - * Whether every note was hit. - * @private - */ - readonly fullCombo: boolean; - - /** - * The additional data for the score. - */ - additionalData?: AdditionalScoreData; - - /** - * The time the score was set. - * @private - */ - readonly timestamp: Date; -} diff --git a/projects/common/src/types/token/scoresaber/score-saber-leaderboard-player-info-token.ts b/projects/common/src/types/token/scoresaber/score-saber-leaderboard-player-info-token.ts index f450c58..e6569b0 100644 --- a/projects/common/src/types/token/scoresaber/score-saber-leaderboard-player-info-token.ts +++ b/projects/common/src/types/token/scoresaber/score-saber-leaderboard-player-info-token.ts @@ -1,8 +1,8 @@ -export default interface ScoreSaberLeaderboardPlayerInfoToken { +export type ScoreSaberLeaderboardPlayerInfoToken = { id: string; name: string; profilePicture: string; country: string; permissions: number; role: string; -} +}; diff --git a/projects/common/src/types/token/scoresaber/score-saber-score-token.ts b/projects/common/src/types/token/scoresaber/score-saber-score-token.ts index 215a2c1..322411e 100644 --- a/projects/common/src/types/token/scoresaber/score-saber-score-token.ts +++ b/projects/common/src/types/token/scoresaber/score-saber-score-token.ts @@ -1,5 +1,5 @@ import ScoreSaberLeaderboardToken from "./score-saber-leaderboard-token"; -import ScoreSaberLeaderboardPlayerInfoToken from "./score-saber-leaderboard-player-info-token"; +import { ScoreSaberLeaderboardPlayerInfoToken } from "./score-saber-leaderboard-player-info-token"; export default interface ScoreSaberScoreToken { id: string; diff --git a/projects/common/src/utils/scoresaber.util.ts b/projects/common/src/utils/scoresaber.util.ts index 8b135ab..829480f 100644 --- a/projects/common/src/utils/scoresaber.util.ts +++ b/projects/common/src/utils/scoresaber.util.ts @@ -1,6 +1,6 @@ import ScoreSaberPlayerToken from "../types/token/scoresaber/score-saber-player-token"; -import ScoreSaberLeaderboardPlayerInfoToken from "../types/token/scoresaber/score-saber-leaderboard-player-info-token"; import ScoreSaberPlayer from "../player/impl/scoresaber-player"; +import { ScoreSaberLeaderboardPlayerInfoToken } from "../types/token/scoresaber/score-saber-leaderboard-player-info-token"; export type ScoreSaberRole = { /** diff --git a/projects/website/src/app/(pages)/leaderboard/[...slug]/page.tsx b/projects/website/src/app/(pages)/leaderboard/[...slug]/page.tsx index a6e7d48..0efa0db 100644 --- a/projects/website/src/app/(pages)/leaderboard/[...slug]/page.tsx +++ b/projects/website/src/app/(pages)/leaderboard/[...slug]/page.tsx @@ -4,7 +4,7 @@ import { Colors } from "@/common/colors"; import { getAverageColor } from "@/common/image-utils"; import { LeaderboardData } from "@/components/leaderboard/leaderboard-data"; import { Config } from "@ssr/common/config"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import { LeaderboardResponse } from "@ssr/common/response/leaderboard-response"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { fetchLeaderboard } from "@ssr/common/utils/leaderboard.util"; diff --git a/projects/website/src/app/(pages)/player/[...slug]/page.tsx b/projects/website/src/app/(pages)/player/[...slug]/page.tsx index f5cc071..058a7eb 100644 --- a/projects/website/src/app/(pages)/player/[...slug]/page.tsx +++ b/projects/website/src/app/(pages)/player/[...slug]/page.tsx @@ -8,7 +8,7 @@ import { getCookieValue } from "@ssr/common/utils/cookie-utils"; import { Config } from "@ssr/common/config"; import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/player/impl/scoresaber-player"; import { ScoreSort } from "@ssr/common/score/score-sort"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { fetchPlayerScores } from "@ssr/common/utils/score-utils"; import PlayerScoresResponse from "@ssr/common/response/player-scores-response"; diff --git a/projects/website/src/components/leaderboard/chart/player-score-accuracy-chart.tsx b/projects/website/src/components/leaderboard/chart/player-score-accuracy-chart.tsx index 96c1def..4879a29 100644 --- a/projects/website/src/components/leaderboard/chart/player-score-accuracy-chart.tsx +++ b/projects/website/src/components/leaderboard/chart/player-score-accuracy-chart.tsx @@ -1,6 +1,5 @@ "use client"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; import { ScoreStatsToken } from "@ssr/common/types/token/beatleader/score-stats/score-stats"; import { formatTime } from "@ssr/common/utils/time-utils"; import GenericChart, { DatasetConfig } from "@/components/chart/generic-chart"; diff --git a/projects/website/src/components/leaderboard/leaderboard-data.tsx b/projects/website/src/components/leaderboard/leaderboard-data.tsx index 16ea3a7..9538aa9 100644 --- a/projects/website/src/components/leaderboard/leaderboard-data.tsx +++ b/projects/website/src/components/leaderboard/leaderboard-data.tsx @@ -2,7 +2,7 @@ import LeaderboardScores from "@/components/leaderboard/leaderboard-scores"; import { LeaderboardInfo } from "@/components/leaderboard/leaderboard-info"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { LeaderboardResponse } from "@ssr/common/response/leaderboard-response"; import { useQuery } from "@tanstack/react-query"; diff --git a/projects/website/src/components/leaderboard/leaderboard-score.tsx b/projects/website/src/components/leaderboard/leaderboard-score.tsx index d7b45a0..ea7b320 100644 --- a/projects/website/src/components/leaderboard/leaderboard-score.tsx +++ b/projects/website/src/components/leaderboard/leaderboard-score.tsx @@ -1,4 +1,4 @@ -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import { formatNumberWithCommas, formatPp } from "@ssr/common/utils/number-utils"; import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token"; import { PlayerInfo } from "@/components/player/player-info"; diff --git a/projects/website/src/components/leaderboard/leaderboard-scores.tsx b/projects/website/src/components/leaderboard/leaderboard-scores.tsx index ddab1ed..cba964b 100644 --- a/projects/website/src/components/leaderboard/leaderboard-scores.tsx +++ b/projects/website/src/components/leaderboard/leaderboard-scores.tsx @@ -10,7 +10,7 @@ import { scoreAnimation } from "@/components/score/score-animation"; import { Button } from "@/components/ui/button"; import { getDifficulty } from "@/common/song-utils"; import { fetchLeaderboardScores } from "@ssr/common/utils/score-utils"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import LeaderboardScoresResponse from "@ssr/common/response/leaderboard-scores-response"; import useDatabase from "@/hooks/use-database"; diff --git a/projects/website/src/components/player/player-data.tsx b/projects/website/src/components/player/player-data.tsx index b83bc8f..f1cfccd 100644 --- a/projects/website/src/components/player/player-data.tsx +++ b/projects/website/src/components/player/player-data.tsx @@ -15,7 +15,7 @@ import useDatabase from "@/hooks/use-database"; import { useLiveQuery } from "dexie-react-hooks"; import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/player/impl/scoresaber-player"; import { ScoreSort } from "@ssr/common/score/score-sort"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import PlayerScoresResponse from "@ssr/common/response/player-scores-response"; diff --git a/projects/website/src/components/player/player-scores.tsx b/projects/website/src/components/player/player-scores.tsx index d73d2e5..26ade96 100644 --- a/projects/website/src/components/player/player-scores.tsx +++ b/projects/website/src/components/player/player-scores.tsx @@ -15,7 +15,7 @@ import { scoreAnimation } from "@/components/score/score-animation"; import ScoreSaberPlayer from "@ssr/common/player/impl/scoresaber-player"; import { ScoreSort } from "@ssr/common/score/score-sort"; import { setCookieValue } from "@ssr/common/utils/cookie-utils"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { fetchPlayerScores } from "@ssr/common/utils/score-utils"; import PlayerScoresResponse from "@ssr/common/response/player-scores-response"; diff --git a/projects/website/src/components/score/badges/badge-props.ts b/projects/website/src/components/score/badges/badge-props.ts index 1860ce0..72c4fd1 100644 --- a/projects/website/src/components/score/badges/badge-props.ts +++ b/projects/website/src/components/score/badges/badge-props.ts @@ -1,4 +1,4 @@ -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; export type ScoreBadgeProps = { /** diff --git a/projects/website/src/components/score/score-badge.tsx b/projects/website/src/components/score/score-badge.tsx index ea1b710..2f7851c 100644 --- a/projects/website/src/components/score/score-badge.tsx +++ b/projects/website/src/components/score/score-badge.tsx @@ -1,5 +1,5 @@ import StatValue from "@/components/stat-value"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; /** diff --git a/projects/website/src/components/score/score-buttons.tsx b/projects/website/src/components/score/score-buttons.tsx index fbc25cd..aa391c0 100644 --- a/projects/website/src/components/score/score-buttons.tsx +++ b/projects/website/src/components/score/score-buttons.tsx @@ -10,7 +10,7 @@ import { copyToClipboard } from "@/common/browser-utils"; import { ArrowDownIcon } from "@heroicons/react/24/solid"; import clsx from "clsx"; import ScoreEditorButton from "@/components/score/score-editor-button"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { BeatSaverMap } from "@ssr/common/model/beatsaver/map"; import BeatSaberPepeLogo from "@/components/logos/beatsaber-pepe-logo"; diff --git a/projects/website/src/components/score/score-editor-button.tsx b/projects/website/src/components/score/score-editor-button.tsx index 6b555a8..d784d25 100644 --- a/projects/website/src/components/score/score-editor-button.tsx +++ b/projects/website/src/components/score/score-editor-button.tsx @@ -6,7 +6,7 @@ import { Slider } from "@/components/ui/slider"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { ResetIcon } from "@radix-ui/react-icons"; import Tooltip from "@/components/tooltip"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; type ScoreEditorButtonProps = { diff --git a/projects/website/src/components/score/score-feed/score-feed.tsx b/projects/website/src/components/score/score-feed/score-feed.tsx index d735168..8588c08 100644 --- a/projects/website/src/components/score/score-feed/score-feed.tsx +++ b/projects/website/src/components/score/score-feed/score-feed.tsx @@ -7,7 +7,7 @@ import { parseDate } from "@ssr/common/utils/time-utils"; import Link from "next/link"; import useWebSocket, { ReadyState } from "react-use-websocket"; import { ScoreSaberWebsocketMessageToken } from "@ssr/common/types/token/scoresaber/websocket/scoresaber-websocket-message"; -import { getScoreSaberScoreFromToken } from "@ssr/common/score/impl/scoresaber-score"; +import { getScoreSaberScoreFromToken } from "@ssr/common/model/score/impl/scoresaber-score"; import { getScoreSaberLeaderboardFromToken } from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; export default function ScoreFeed() { diff --git a/projects/website/src/components/score/score-modifiers.tsx b/projects/website/src/components/score/score-modifiers.tsx index 9a075a6..d59fdaa 100644 --- a/projects/website/src/components/score/score-modifiers.tsx +++ b/projects/website/src/components/score/score-modifiers.tsx @@ -1,4 +1,4 @@ -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import { Modifier } from "@ssr/common/score/modifier"; type ScoreModifiersProps = { diff --git a/projects/website/src/components/score/score-rank-info.tsx b/projects/website/src/components/score/score-rank-info.tsx index 5d278c2..97bd291 100644 --- a/projects/website/src/components/score/score-rank-info.tsx +++ b/projects/website/src/components/score/score-rank-info.tsx @@ -2,7 +2,7 @@ import { formatNumberWithCommas } from "@ssr/common/utils/number-utils"; import { GlobeAmericasIcon } from "@heroicons/react/24/solid"; import Link from "next/link"; import { getPageFromRank } from "@ssr/common/utils/utils"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { ScoreTimeSet } from "@/components/score/score-time-set"; diff --git a/projects/website/src/components/score/score-stats.tsx b/projects/website/src/components/score/score-stats.tsx index e0daede..8020412 100644 --- a/projects/website/src/components/score/score-stats.tsx +++ b/projects/website/src/components/score/score-stats.tsx @@ -1,6 +1,6 @@ import { getScoreBadgeFromAccuracy } from "@/common/song-utils"; import { ScoreBadge, ScoreBadges } from "@/components/score/score-badge"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import ScoreMissesBadge from "@/components/score/badges/score-misses"; import { HandAccuracyBadge } from "@/components/score/badges/hand-accuracy"; diff --git a/projects/website/src/components/score/score-time-set.tsx b/projects/website/src/components/score/score-time-set.tsx index 29995ca..0127712 100644 --- a/projects/website/src/components/score/score-time-set.tsx +++ b/projects/website/src/components/score/score-time-set.tsx @@ -1,7 +1,7 @@ import { format } from "@formkit/tempo"; import { timeAgo } from "@ssr/common/utils/time-utils"; import Tooltip from "@/components/tooltip"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; type ScoreTimeSetProps = { /** diff --git a/projects/website/src/components/score/score.tsx b/projects/website/src/components/score/score.tsx index 51d4bd7..d3b6f7f 100644 --- a/projects/website/src/components/score/score.tsx +++ b/projects/website/src/components/score/score.tsx @@ -9,7 +9,7 @@ import ScoreStats from "./score-stats"; import { motion } from "framer-motion"; import { getPageFromRank } from "@ssr/common/utils/utils"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; -import ScoreSaberScore from "@ssr/common/score/impl/scoresaber-score"; +import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard"; import { BeatSaverMap } from "@ssr/common/model/beatsaver/map"; import { useIsMobile } from "@/hooks/use-is-mobile";