Added pp for beat leader

This commit is contained in:
Liam 2022-10-20 15:04:49 +01:00
parent f2e36347ad
commit 538714a61e
4 changed files with 86 additions and 18 deletions

@ -3,6 +3,7 @@ import { Component } from "react";
import PlayerStats from "../src/components/PlayerStats"; import PlayerStats from "../src/components/PlayerStats";
import ScoreStats from "../src/components/ScoreStats"; import ScoreStats from "../src/components/ScoreStats";
import SongInfo from "../src/components/SongInfo"; import SongInfo from "../src/components/SongInfo";
import LeaderboardType from "../src/consts/LeaderboardType";
import Utils from "../src/utils/utils"; import Utils from "../src/utils/utils";
import styles from "../styles/overlay.module.css"; import styles from "../styles/overlay.module.css";
@ -37,6 +38,7 @@ export default class Overlay extends Component {
currentScore: 0, currentScore: 0,
percentage: "100.00%", percentage: "100.00%",
failed: false, failed: false,
mapStarCount: undefined,
leftHand: { leftHand: {
averageCut: [15.0], averageCut: [15.0],
averagePreSwing: [70.0], averagePreSwing: [70.0],
@ -175,7 +177,7 @@ export default class Overlay extends Component {
const data = await fetch( const data = await fetch(
Utils.getWebsiteApi( Utils.getWebsiteApi(
id == "test" ? "Test" : this.state.websiteType id == "test" ? "Test" : this.state.websiteType
).ApiUrl.replace("%s", id), ).ApiUrl.PlayerData.replace("%s", id),
{ {
headers: { headers: {
"X-Requested-With": "BeatSaber Overlay", "X-Requested-With": "BeatSaber Overlay",
@ -234,6 +236,7 @@ export default class Overlay extends Component {
console.log( console.log(
"Attempting to re-connect to the HTTP Status socket in 60 seconds." "Attempting to re-connect to the HTTP Status socket in 60 seconds."
); );
this.resetData(false);
this.setState({ isConnectedToSocket: false }); this.setState({ isConnectedToSocket: false });
setTimeout(() => this.connectSocket(), 60_000); setTimeout(() => this.connectSocket(), 60_000);
}); });
@ -261,6 +264,17 @@ export default class Overlay extends Component {
); );
const json = await data.json(); const json = await data.json();
this.setState({ beatSaverData: json }); this.setState({ beatSaverData: json });
if (this.state.websiteType == "BeatLeader") {
const { characteristic, levelId, difficulty } = songData;
let mapHash = levelId.replace("custom_level_", "");
const mapStars = await LeaderboardType.BeatLeader.getMapStarCount(
mapHash,
difficulty,
characteristic
);
this.setState({ mapStarCount: mapStars });
}
} }
/** /**
@ -291,7 +305,8 @@ export default class Overlay extends Component {
currentScore: 0, currentScore: 0,
percentage: "100.00%", percentage: "100.00%",
isVisible: visible, isVisible: visible,
loadedDuringSong: loadedDuringSong loadedDuringSong: loadedDuringSong,
mapStarCount: undefined,
}); });
} }
@ -299,16 +314,16 @@ export default class Overlay extends Component {
handlers = { handlers = {
hello: (data) => { hello: (data) => {
console.log("Hello from HTTP Status!"); console.log("Hello from HTTP Status!");
if (data.status) { if (
if (this.state.songData === undefined) { data.status &&
data.status.beatmap &&
this.state.songData === undefined
) {
console.log("Going into level during song, resetting data."); console.log("Going into level during song, resetting data.");
this.resetData(true, true); this.resetData(true, true);
this.setState({ songData: data, paused: false }); this.setState({ songData: data, paused: false });
if (data.status.beatmap) {
this.setBeatSaver(data.status.beatmap); this.setBeatSaver(data.status.beatmap);
} }
}
}
}, },
scoreChanged: (data) => { scoreChanged: (data) => {
const { status } = data; const { status } = data;

@ -1,6 +1,7 @@
import { Component } from "react"; import { Component } from "react";
import styles from "../../styles/scoreStats.module.css"; import styles from "../../styles/scoreStats.module.css";
import Utils from "../utils/utils";
export default class ScoreStats extends Component { export default class ScoreStats extends Component {
constructor(params) { constructor(params) {
@ -19,12 +20,18 @@ export default class ScoreStats extends Component {
render() { render() {
const data = this.props.data; const data = this.props.data;
const currentPP = Utils.calculatePP(
data.mapStarCount,
data.percentage.replace("%", ""),
data.websiteType
);
return ( return (
<div className={styles.scoreStats}> <div className={styles.scoreStats}>
<div className={styles.scoreStatsInfo}> <div className={styles.scoreStatsInfo}>
<p>{data.percentage}</p> <p>{data.percentage}</p>
<p>{data.currentScore.toLocaleString()}</p> <p>{data.currentScore.toLocaleString()}</p>
{currentPP !== undefined ? <p>{currentPP.toFixed(0)}pp</p> : null}
</div> </div>
<div> <div>
<p className={styles.scoreStatsAverageCut}>Average Cut</p> <p className={styles.scoreStatsAverageCut}>Average Cut</p>

@ -2,10 +2,46 @@ import Config from "../../config.json";
const WebsiteTypes = { const WebsiteTypes = {
ScoreSaber: { ScoreSaber: {
ApiUrl: Config.proxy_url + "/https://scoresaber.com/api/player/%s/basic", ApiUrl: {
PlayerData:
Config.proxy_url + "/https://scoresaber.com/api/player/%s/basic",
},
}, },
BeatLeader: { BeatLeader: {
ApiUrl: Config.proxy_url + "/https://api.beatleader.xyz/player/%s", ApiUrl: {
PlayerData: Config.proxy_url + "/https://api.beatleader.xyz/player/%s",
MapData:
Config.proxy_url +
"/https://api.beatleader.xyz/leaderboard/hash/%h/%d/%m",
},
async getMapStarCount(mapHash, mapDiff, characteristic) {
const data = await fetch(
this.ApiUrl.MapData.replace("%h", mapHash)
.replace("%d", mapDiff.replace("+", "Plus"))
.replace("%m", characteristic),
{
headers: {
"X-Requested-With": "BeatSaber Overlay",
},
}
);
const json = await data.json();
return json.difficulty.stars || undefined;
},
curve(acc, stars) {
var l = 1 - (0.03 * (stars - 3.0)) / 11.0;
var a = 0.96 * l;
var f = 1.2 - (0.6 * stars) / 14.0;
return Math.pow(Math.log10(l / (l - acc)) / Math.log10(l / (l - a)), f);
},
ppFromAcc(acc, stars) {
if (stars === undefined) {
return undefined;
}
const pp = this.curve(acc / 100, stars - 0.5) * (stars + 0.5) * 42;
return pp == NaN ? undefined : pp;
},
}, },
Test: { Test: {
ApiUrl: "/api/mockdata", ApiUrl: "/api/mockdata",

@ -1,9 +1,12 @@
import SteamIdCache from "../../src/caches/SteamIdCache"; import SteamIdCache from "../../src/caches/SteamIdCache";
import LeaderboardType from "../consts/LeaderboardType"; import {
default as LeaderboardType,
default as WebsiteTypes,
} from "../consts/LeaderboardType";
const TO_CHECK = [ const TO_CHECK = [
LeaderboardType.ScoreSaber.ApiUrl, LeaderboardType.ScoreSaber.ApiUrl.PlayerData,
LeaderboardType.BeatLeader.ApiUrl, LeaderboardType.BeatLeader.ApiUrl.PlayerData,
]; ];
export default class Utils { export default class Utils {
@ -64,4 +67,11 @@ export default class Utils {
const json = await data.json(); const json = await data.json();
return !!json.pp; return !!json.pp;
} }
static calculatePP(stars, acc, type) {
if (type === "BeatLeader") {
return WebsiteTypes.BeatLeader.ppFromAcc(acc, stars);
}
return undefined;
}
} }