Skip to content

Commit

Permalink
feat: More data for Result screen (api v2)
Browse files Browse the repository at this point in the history
  • Loading branch information
ck authored and cyperdark committed Jun 28, 2024
1 parent 48187f6 commit 67e51dc
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 20 deletions.
6 changes: 6 additions & 0 deletions packages/tosu/src/api/types/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@ export interface Pp {
fc: number;
maxAchievedThisPlay: number;
}
export interface Pp2 {
current: number;
fc: number;
}

export interface Leaderboard {
isFailed: boolean;
Expand Down Expand Up @@ -438,6 +442,7 @@ export interface Series {
}

export interface ResultsScreen {
playerName: string;
mode: NumberName;
score: number;
accuracy: number;
Expand All @@ -446,6 +451,7 @@ export interface ResultsScreen {
mods: NumberName;
maxCombo: number;
rank: string;
pp: Pp2;
createdAt: string;
}

Expand Down
17 changes: 10 additions & 7 deletions packages/tosu/src/api/utils/buildResultV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,25 +389,28 @@ export const buildResult = (instanceManager: InstanceManager): ApiAnswer => {
graph: beatmapPpData.strainsAll
},
resultsScreen: {
playerName: resultsScreenData.PlayerName,

mode: {
number: gamePlayData.Mode,
name: Modes[gamePlayData.Mode] || ''
number: resultsScreenData.Mode,
name: Modes[resultsScreenData.Mode] || ''
},

score: resultsScreenData.Score,
accuracy: calculateAccuracy({
hits: resultScreenHits,
mode: gamePlayData.Mode
}),
accuracy: resultsScreenData.Accuracy,

name: resultsScreenData.PlayerName,
name: resultsScreenData.PlayerName, // legacy, remove it later
hits: resultScreenHits,
mods: {
number: resultsScreenData.Mods,
name: getOsuModsString(resultsScreenData.Mods)
},
maxCombo: resultsScreenData.MaxCombo,
rank: resultsScreenData.Grade,
pp: {
current: resultsScreenData.pp,
fc: resultsScreenData.fcPP
},
createdAt: resultsScreenData.Date
},
folders: {
Expand Down
92 changes: 79 additions & 13 deletions packages/tosu/src/entities/ResultsScreenData/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { Calculator } from '@kotrikd/rosu-pp';
import { wLogger } from '@tosu/common';

import { AbstractEntity } from '@/entities/AbstractEntity';
import { OsuInstance } from '@/objects/instanceManager/osuInstance';
import { calculateGrade } from '@/utils/calculators';
import {
calculateAccuracy,
calculateGrade,
calculatePassedObjects
} from '@/utils/calculators';
import { netDateBinaryToDate } from '@/utils/converters';
import { OsuMods } from '@/utils/osuMods.types';

Expand All @@ -20,6 +25,11 @@ export class ResultsScreenData extends AbstractEntity {
HitMiss: number;
Grade: string;
Date: string;
Accuracy: number;
pp: number;
fcPP: number;

previousBeatmap: string;

constructor(osuInstance: OsuInstance) {
super(osuInstance);
Expand All @@ -42,15 +52,20 @@ export class ResultsScreenData extends AbstractEntity {
this.HitKatu = 0;
this.HitMiss = 0;
this.Date = '';
this.Accuracy = 0;
this.pp = 0;
this.fcPP = 0;
}

updateState() {
try {
const { process, patterns, allTimesData } =
const { process, patterns, allTimesData, beatmapPpData, menuData } =
this.osuInstance.getServices([
'process',
'patterns',
'allTimesData'
'allTimesData',
'beatmapPpData',
'menuData'
]);
if (process === null) {
throw new Error('Process not found');
Expand All @@ -68,13 +83,13 @@ export class ResultsScreenData extends AbstractEntity {
process.readInt(rulesetsAddr - 0xb) + 0x4
);
if (rulesetAddr === 0) {
wLogger.debug('RSD(init) rulesetAddr is zero');
wLogger.debug('RSD(updateState) rulesetAddr is zero');
return;
}

const resultScreenBase = process.readInt(rulesetAddr + 0x38);
if (resultScreenBase === 0) {
wLogger.debug('RSD(init) resultScreenBase is zero');
wLogger.debug('RSD(updateState) resultScreenBase is zero');
return;
}

Expand Down Expand Up @@ -106,24 +121,75 @@ export class ResultsScreenData extends AbstractEntity {
this.HitKatu = process.readShort(resultScreenBase + 0x90);
// HitMiss int16 `mem:"[Ruleset + 0x38] + 0x92"`
this.HitMiss = process.readShort(resultScreenBase + 0x92);

const hits = {
300: this.Hit300,
geki: 0,
100: this.Hit100,
katu: 0,
50: this.Hit50,
0: this.HitMiss
};

this.Grade = calculateGrade({
mods: this.Mods,
mode: this.Mode,
hits: {
300: this.Hit300,
geki: 0,
100: this.Hit100,
katu: 0,
50: this.Hit50,
0: this.HitMiss
}
hits
});

this.Accuracy = calculateAccuracy({
mode: this.Mode,
hits
});

this.Date = netDateBinaryToDate(
process.readInt(resultScreenBase + 0xa4),
process.readInt(resultScreenBase + 0xa0)
).toISOString();

const key = `${menuData.MD5}${this.Mods}${this.Mode}${this.PlayerName}`;
if (this.previousBeatmap === key) {
return;
}

const currentBeatmap = beatmapPpData.getCurrentBeatmap();
if (!currentBeatmap) {
wLogger.debug("RSD(updateState) can't get current map");
return;
}

const scoreParams = {
passedObjects: calculatePassedObjects(
this.Mode,
this.Hit300,
this.Hit100,
this.Hit50,
this.HitMiss,
this.HitKatu,
this.HitGeki
),
combo: this.MaxCombo,
mods: this.Mods,
nMisses: this.HitMiss,
n50: this.Hit50,
n100: this.Hit100,
n300: this.Hit300
};

const curPerformance = new Calculator(scoreParams).performance(
currentBeatmap
);
const fcPerformance = new Calculator({
combo: curPerformance.difficulty.maxCombo,
mods: this.Mods,
nMisses: 0,
acc: this.Accuracy
}).performance(currentBeatmap);

this.pp = curPerformance.pp;
this.fcPP = fcPerformance.pp;

this.previousBeatmap = key;
this.resetReportCount('RSD(updateState)');
} catch (exc) {
this.reportError(
Expand Down
5 changes: 5 additions & 0 deletions packages/tosu/src/objects/instanceManager/osuInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,11 @@ export class OsuInstance {
resultsScreenData.init();
beatmapPpData.resetCurrentAttributes();
}

// Reset ResultScreen if we in song select
if (resultsScreenData.PlayerName) {
resultsScreenData.init();
}
break;

case 2:
Expand Down

0 comments on commit 67e51dc

Please sign in to comment.