Skip to content

Commit

Permalink
Merge pull request #157 from KotRikD/chore/pp-fix
Browse files Browse the repository at this point in the history
HotFix: pp and graph
  • Loading branch information
cyperdark authored Jul 1, 2024
2 parents 7eda92a + 2c4cd07 commit bad12f6
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 73 deletions.
53 changes: 39 additions & 14 deletions packages/tosu/src/entities/BeatmapPpData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,7 @@ export class BeatmapPPData extends AbstractEntity {

const { menuData, allTimesData } = this.osuInstance.getServices([
'menuData',
'allTimesData',
'beatmapPpData'
'allTimesData'
]);

const mapPath = path.join(
Expand Down Expand Up @@ -280,7 +279,6 @@ export class BeatmapPPData extends AbstractEntity {
parseHitObjects: true,

parseColours: false,
parseDifficulty: false,
parseEditor: false,
parseGeneral: false,
parseStoryboard: false,
Expand Down Expand Up @@ -322,22 +320,45 @@ export class BeatmapPPData extends AbstractEntity {
return;
}

const offset = strains.sectionLength;
const firstObj = this.timings.firstObj / attributes.clockRate;
const lastObj = this.timings.full / attributes.clockRate;
const mp3Length = menuData.MP3Length / attributes.clockRate;

const beatmapParseTime = performance.now();
wLogger.debug(
`BPPD(updateMapMetadata) [${(
beatmapParseTime - calculationTime
).toFixed(2)}ms] Spend on parsing beatmap`
);

const LEFT_OFFSET = Math.floor(firstObj / offset);
let strainsAmount = 0;
switch (strains.mode) {
case 0:
strainsAmount = strains.aim?.length || 0;
break;

case 1:
strainsAmount = strains.color?.length || 0;
break;

case 2:
strainsAmount = strains.movement?.length || 0;
break;

case 3:
strainsAmount = strains.strains?.length || 0;
break;
}

const sectionOffsetTime = strains.sectionLength;
const firstObjectTime =
this.timings.firstObj / attributes.clockRate;
const lastObjectTime =
firstObjectTime + strainsAmount * sectionOffsetTime;
const mp3LengthTime = menuData.MP3Length / attributes.clockRate;

const LEFT_OFFSET = Math.floor(firstObjectTime / sectionOffsetTime);
const RIGHT_OFFSET =
mp3Length >= lastObj
? Math.ceil((mp3Length - lastObj) / offset)
mp3LengthTime >= lastObjectTime
? Math.ceil(
(mp3LengthTime - lastObjectTime) / sectionOffsetTime
)
: 0;

const updateWithOffset = (
Expand Down Expand Up @@ -410,19 +431,23 @@ export class BeatmapPPData extends AbstractEntity {
);

for (let i = 0; i < LEFT_OFFSET; i++) {
resultStrains.xaxis.push(i * offset);
resultStrains.xaxis.push(i * sectionOffsetTime);
}

const total =
resultStrains.series[0].data.length -
LEFT_OFFSET -
RIGHT_OFFSET;
for (let i = 0; i < total; i++) {
resultStrains.xaxis.push(firstObj + i * offset);
resultStrains.xaxis.push(
firstObjectTime + i * sectionOffsetTime
);
}

for (let i = 0; i < RIGHT_OFFSET; i++) {
resultStrains.xaxis.push(lastObj + i * offset);
resultStrains.xaxis.push(
lastObjectTime + i * sectionOffsetTime
);
}

const endTime = performance.now();
Expand Down
101 changes: 69 additions & 32 deletions packages/tosu/src/entities/GamePlayData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export class GamePlayData extends AbstractEntity {
isDefaultState: boolean = true;
isKeyOverlayDefaultState: boolean = true;

PerformanceAttributes?: rosu.PerformanceAttributes | rosu.Beatmap;
PerformanceAttributes: rosu.PerformanceAttributes;
GradualPerformance: rosu.GradualPerformance | null;

Retries: number;
PlayerName: string;
Expand Down Expand Up @@ -58,6 +59,7 @@ export class GamePlayData extends AbstractEntity {
private cachedkeys: string = '';

previousState: string = '';
previousPassedObjects = 0;

constructor(osuInstance: OsuInstance) {
super(osuInstance);
Expand Down Expand Up @@ -112,6 +114,9 @@ export class GamePlayData extends AbstractEntity {
};
this.isReplayUiHidden = false;

this.previousPassedObjects = 0;
this.GradualPerformance = null;

// below is gata that shouldn't be reseted on retry
if (isRetry === true) {
return;
Expand Down Expand Up @@ -548,6 +553,7 @@ export class GamePlayData extends AbstractEntity {
}

private updateStarsAndPerformance() {
const t1 = performance.now();
if (!config.calculatePP) {
wLogger.debug(
'GD(updateStarsAndPerformance) pp calculation disabled'
Expand Down Expand Up @@ -577,52 +583,83 @@ export class GamePlayData extends AbstractEntity {
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,
misses: this.HitMiss,
n50: this.Hit50,
n100: this.Hit100,
n300: this.Hit300
};

const currentState = `${menuData.MD5}:${menuData.MenuGameMode}:${this.Mods}:${menuData.MP3Length}`;

const isUpdate = this.previousState !== currentState;
if (isUpdate) {
this.previousState = currentState;

// update precalculated attributes
if (
isUpdate ||
!this.GradualPerformance ||
!this.PerformanceAttributes
) {
if (this.GradualPerformance) this.GradualPerformance.free();
if (this.PerformanceAttributes) this.PerformanceAttributes.free();

const calculate = new rosu.Performance(scoreParams).calculate(
const difficulty = new rosu.Difficulty({ mods: this.Mods });
this.GradualPerformance = new rosu.GradualPerformance(
difficulty,
currentBeatmap
);
this.PerformanceAttributes = calculate;

this.PerformanceAttributes = new rosu.Performance({
mods: this.Mods
}).calculate(currentBeatmap);

this.previousState = currentState;
}

const curPerformance = new rosu.Performance(scoreParams).calculate(
this.PerformanceAttributes!
if (!this.GradualPerformance && !this.PerformanceAttributes) return;

const passedObjects = calculatePassedObjects(
this.Mode,
this.Hit300,
this.Hit100,
this.Hit50,
this.HitMiss,
this.HitKatu,
this.HitGeki
);

const offset = passedObjects - this.previousPassedObjects;
if (offset <= 0) return;

const scoreParams: rosu.ScoreState = {
maxCombo: this.MaxCombo,
misses: this.HitMiss,
n50: this.Hit50,
n100: this.Hit100,
n300: this.Hit300,
nKatu: this.HitKatu,
nGeki: this.HitGeki
};

const curPerformance = this.GradualPerformance.nth(
scoreParams,
offset - 1
)!;

const fcPerformance = new rosu.Performance({
mods: this.Mods,
misses: 0,
accuracy: this.Accuracy
}).calculate(this.PerformanceAttributes!);
}).calculate(this.PerformanceAttributes);
const t2 = performance.now();

if (curPerformance) {
beatmapPpData.updateCurrentAttributes(
curPerformance.difficulty.stars,
curPerformance.pp
);
}

if (fcPerformance) {
beatmapPpData.updateFcPP(fcPerformance.pp);
}

this.PerformanceAttributes = curPerformance;
this.previousPassedObjects = passedObjects;

beatmapPpData.updateCurrentAttributes(
curPerformance.difficulty.stars,
curPerformance.pp
wLogger.debug(
`GD(updateStarsAndPerformance) [${(t2 - t1).toFixed(2)}ms] elapsed time`
);
beatmapPpData.updateFcPP(fcPerformance.pp);
}
}
24 changes: 6 additions & 18 deletions packages/tosu/src/entities/ResultsScreenData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import rosu from 'rosu-pp-js';

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

Expand Down Expand Up @@ -159,29 +155,21 @@ export class ResultsScreenData extends AbstractEntity {
return;
}

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

const curPerformance = new rosu.Performance(scoreParams).calculate(
currentBeatmap
);
const fcPerformance = new rosu.Performance({
combo: curPerformance.difficulty.maxCombo,
mods: this.Mods,
misses: 0,
accuracy: this.Accuracy
Expand Down
2 changes: 1 addition & 1 deletion packages/tosu/src/entities/TourneyUserProfileData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class TourneyUserProfileData extends AbstractEntity {
wLogger.debug('TUPD(updateState) Slot is not equiped');

this.resetState();
gamePlayData.init();
gamePlayData.init(undefined, 'tourney');
return;
}

Expand Down
26 changes: 18 additions & 8 deletions packages/tosu/src/objects/instanceManager/osuInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export class OsuInstance {
case 5:
// Reset Gameplay/ResultScreen data on joining to songSelect
if (!gamePlayData.isDefaultState) {
gamePlayData.init();
gamePlayData.init(undefined, '4,5');
resultsScreenData.init();
beatmapPpData.resetCurrentAttributes();
}
Expand All @@ -316,8 +316,8 @@ export class OsuInstance {
this.previousTime = allTimesData.PlayTime;

if (
allTimesData.PlayTime < 0 &&
!gamePlayData.isDefaultState
allTimesData.PlayTime <
Math.min(50, beatmapPpData.timings.firstObj)
) {
gamePlayData.init(true, 'not-default');
break;
Expand All @@ -338,7 +338,7 @@ export class OsuInstance {
break;

default:
gamePlayData.init();
gamePlayData.init(undefined, 'default');
resultsScreenData.init();
break;
}
Expand Down Expand Up @@ -400,7 +400,8 @@ export class OsuInstance {
'menuData',
'allTimesData',
'gamePlayData',
'beatmapPpData'
'beatmapPpData',
'resultsScreenData'
]);

this.updateMapMetadata(entities);
Expand All @@ -411,12 +412,21 @@ export class OsuInstance {
allTimesData: AllTimesData;
gamePlayData: GamePlayData;
beatmapPpData: BeatmapPPData;
resultsScreenData: ResultsScreenData;
}) {
const { menuData, allTimesData, gamePlayData, beatmapPpData } = entries;
const {
menuData,
allTimesData,
gamePlayData,
beatmapPpData,
resultsScreenData
} = entries;
const currentMods =
allTimesData.Status === 2 || allTimesData.Status === 7
allTimesData.Status === 2
? gamePlayData.Mods
: allTimesData.MenuMods;
: allTimesData.Status === 7
? resultsScreenData.Mods
: allTimesData.MenuMods;

const currentState = `${menuData.MD5}:${menuData.MenuGameMode}:${currentMods}:${menuData.MP3Length}`;

Expand Down

0 comments on commit bad12f6

Please sign in to comment.