Added pp for beat leader
This commit is contained in:
parent
f2e36347ad
commit
538714a61e
@ -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";
|
||||||
@ -26,7 +27,7 @@ export default class Overlay extends Component {
|
|||||||
showPlayerStats: true,
|
showPlayerStats: true,
|
||||||
showScore: false,
|
showScore: false,
|
||||||
showSongInfo: false,
|
showSongInfo: false,
|
||||||
loadedDuringSong: false,
|
loadedDuringSong: false,
|
||||||
|
|
||||||
socket: undefined,
|
socket: undefined,
|
||||||
isVisible: false,
|
isVisible: false,
|
||||||
@ -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,15 +314,15 @@ 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 &&
|
||||||
console.log("Going into level during song, resetting data.");
|
data.status.beatmap &&
|
||||||
this.resetData(true, true);
|
this.state.songData === undefined
|
||||||
this.setState({ songData: data, paused: false });
|
) {
|
||||||
if (data.status.beatmap) {
|
console.log("Going into level during song, resetting data.");
|
||||||
this.setBeatSaver(data.status.beatmap);
|
this.resetData(true, true);
|
||||||
}
|
this.setState({ songData: data, paused: false });
|
||||||
}
|
this.setBeatSaver(data.status.beatmap);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scoreChanged: (data) => {
|
scoreChanged: (data) => {
|
||||||
@ -438,7 +453,7 @@ export default class Overlay extends Component {
|
|||||||
countryRank={data.countryRank.toLocaleString()}
|
countryRank={data.countryRank.toLocaleString()}
|
||||||
websiteType={websiteType}
|
websiteType={websiteType}
|
||||||
avatar={`/api/steamavatar?steamid=${id}`}
|
avatar={`/api/steamavatar?steamid=${id}`}
|
||||||
loadedDuringSong={this.state.loadedDuringSong}
|
loadedDuringSong={this.state.loadedDuringSong}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user