Add more metadata, fix button state bug

This commit is contained in:
Trenton Zimmer
2025-12-10 19:07:28 -05:00
parent 40b8a4c348
commit 427d61c442
8 changed files with 158 additions and 50 deletions

View File

@@ -1,4 +1,4 @@
VITE_APP_VERSION="3.0.36"
VITE_APP_VERSION="3.0.37"
VITE_API_URL="http://localhost:8000/"
VITE_API_KEY="your_api_key_should_be_here"
VITE_ASSET_PATH="/assets"

View File

@@ -1,4 +1,4 @@
VITE_APP_VERSION="3.0.36"
VITE_APP_VERSION="3.0.37"
VITE_API_URL="https://restfulsleep.phaseii.network"
VITE_API_KEY="your_api_key_should_be_here"
VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets"

View File

@@ -35,5 +35,6 @@
"3.0.33": ["- (Major) Condense all score tables to one parser and format", "- (Major) Add more game metadata", "- (Bugfix) Fix difficulties showing as `NaN`", "- (Beta) Add a developmental device plugin for card effect"],
"3.0.34": ["- (Major) Add support for Jubeat titles", "- (Major) Add base BTA support"],
"3.0.35": ["- (Bugfix) Fix cursor hover state on news card and profile card", "- (Minor) Update DDR game options", "- (Minor) Update IIDX event settings", "- (Minor) Add IIDX 32 basic QPro settings"],
"3.0.36": ["- (Major) Finish more game metadata (DRS, Museca, Nostalgia, pop'n, jubeat)"]
"3.0.36": ["- (Major) Finish more game metadata (DRS, Museca, Nostalgia, pop'n, jubeat)"],
"3.0.37": ["- (Major) Finish more game metadata (RB, SDVX, FTT)", "- (Bugfix) Fix personal record button showing for games without scores."]
}

View File

@@ -82,15 +82,15 @@ function loadRoutes() {
path: `/games/${props.game.id}/scores/${mainStore.userId}`,
color: "info",
});
}
navigationData.push({
label: "My Records",
icon: PhListStar,
path: `/games/${props.game.id}/records/${mainStore.userId}`,
route: "personal_records",
color: "success",
});
navigationData.push({
label: "My Records",
icon: PhListStar,
path: `/games/${props.game.id}/records/${mainStore.userId}`,
route: "personal_records",
color: "success",
});
}
}
if (!props.game.noScores) {

View File

@@ -362,6 +362,7 @@ export const gameData = [
noRivals: true,
useUnicode: true,
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Clear Gauge", value: "data.clear_gauge", width: 120 },
{ text: "Combos", value: "data.combo", width: 120 },
{ text: "Medal", value: "data.medal", width: 120 },
@@ -444,6 +445,7 @@ export const gameData = [
cardBG: null,
noRivals: true,
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 120 },
{ text: "Halo", value: "data.param", width: 120 },
],
@@ -490,6 +492,7 @@ export const gameData = [
VersionConstants.DDR_A3,
],
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Halo", value: "data.halo", width: 80 },
],
@@ -700,6 +703,7 @@ export const gameData = [
useActiveRival: true,
videoTable: [VersionConstants.DDR_A20_PLUS],
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Halo", value: "data.halo", width: 80 },
],
@@ -842,6 +846,7 @@ export const gameData = [
},
],
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "medal", width: 100 },
{ text: "SKILL %", value: "data.skill_perc", width: 90 },
@@ -1010,6 +1015,7 @@ export const gameData = [
},
],
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "medal", width: 140 },
{ text: "SKILL %", value: "data.perc", width: 90 },
@@ -1061,6 +1067,7 @@ export const gameData = [
},
],
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "medal", width: 140 },
{ text: "SKILL %", value: "data.perc", width: 90 },
@@ -1096,6 +1103,7 @@ export const gameData = [
cardBG: null,
gameOptions: GFDMOptions,
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "medal", width: 100 },
{ text: "SKILL %", value: "data.skill_perc", width: 90 },
@@ -1232,6 +1240,7 @@ export const gameData = [
assetId: "iidx",
gameOptions: IIDXOptions,
splitRivals: true,
maxLength: 6,
videoTable: [
VersionConstants.IIDX_TRICORO,
VersionConstants.IIDX_SPADA,
@@ -1248,7 +1257,8 @@ export const gameData = [
VersionConstants.IIDX_PINKY_CRUSH,
],
scoreHeaders: [
{ text: "Misses", value: "data.misses", width: 100 },
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Misses", value: "data.miss_count", width: 100 },
{ text: "Clear Status", value: "data.medal", width: 100 },
],
chartTable: {
@@ -1264,14 +1274,24 @@ export const gameData = [
9: "DP LEGGENDARIA",
},
rankTable: {
100: "E",
200: "D",
300: "C",
400: "B",
500: "A",
600: "S",
700: "SS",
800: "EXC",
100: "F",
200: "E",
300: "D",
400: "C",
500: "B",
600: "A",
700: "AA",
800: "AAA",
},
percTable: {
0: 100,
2222: 200,
3333: 300,
4444: 400,
5556: 500,
6667: 600,
7778: 700,
8889: 800,
},
medalTable: {
50: "NO PLAY",
@@ -1554,6 +1574,7 @@ export const gameData = [
icon: null,
cardBG: null,
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "data.medal", width: 120 },
{ text: "Music Rate", value: "data.music_rate", width: 120 },
@@ -1732,6 +1753,7 @@ export const gameData = [
300: "FULL COMBO",
},
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "data.clear_type", width: 80 },
],
@@ -1871,6 +1893,7 @@ export const gameData = [
1100: "PERFECT",
},
scoreHeaders: [
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "data.medal", width: 120 },
],
@@ -2022,10 +2045,43 @@ export const gameData = [
2: "HARD",
3: "SPECIAL",
},
rankTable: {
100: "C",
200: "B",
300: "A",
400: "AA",
500: "AAA",
600: "AAA+",
700: "S",
},
percTable: {
0: 100,
6000: 200,
7000: 300,
8000: 400,
9000: 500,
9500: 600,
9800: 700,
},
medalTable: {
100: "NO PLAY",
200: "FAILED",
300: "CLEARED",
400: "HARD CLEAR",
500: "S HARD CLEAR",
},
comboTable: {
100: "NONE",
200: "ALMOST FULL COMBO",
300: "FULL COMBO",
400: "ALL JUST FULL COMBO",
},
scoreHeaders: [
{ text: "Combos", value: "combo", width: 80 },
{ text: "Misses", value: "misses", width: 80 },
{ text: "Halo", value: "halo", width: 80 },
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Rate", value: "data.achievement_rate", width: 100 },
{ text: "Misses", value: "data.miss_count", width: 80 },
{ text: "Medal", value: "data.clear_type", width: 80 },
{ text: "Combo Medal", value: "data.combo_type", width: 120 },
],
versions: [
{
@@ -2084,9 +2140,31 @@ export const gameData = [
3: "INFINITE",
4: "MAXIMUM",
},
rankTable: {
100: "NO PLAY",
200: "D",
300: "C",
400: "B",
500: "A",
550: "A+",
600: "AA",
650: "AA+",
700: "AAA",
800: "AAA+",
900: "S",
},
medalTable: {
50: "NO PLAY",
100: "FAILED",
200: "CLEARED",
300: "HARD CLEAR",
400: "UC",
500: "PUC",
},
scoreHeaders: [
{ text: "Combos", value: "combo", width: 80 },
{ text: "Halo", value: "halo", width: 80 },
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Combos", value: "data.combo", width: 80 },
{ text: "Medal", value: "data.clear_type", width: 80 },
],
playerHeaders: [
{ text: "Skill Level", value: "skill_level", sortable: true, width: 100 },

View File

@@ -7,7 +7,7 @@ export function shouldRenderChart(difficulty, chartTable, chartKey) {
export function formatDifficulty(difficulty, difficultyDenom = 1) {
if (isNaN(difficulty / difficultyDenom)) {
return difficulty.difnum ? difficulty.difnum : difficulty;
return difficulty?.difnum ? difficulty.difnum : difficulty;
}
return difficulty / difficultyDenom;
}

View File

@@ -4,13 +4,12 @@ import { formatDifficulty, rankFromScore } from "@/constants/scoreDataFilters";
export function scoreHeaders(thisGame) {
const headers = [
{ text: "Player", value: "username", width: 120 },
{ text: "New PB", value: "newRecord", width: 100 },
{ text: "Timestamp", value: "timestamp", width: 140 },
{ text: "New PB", value: "newRecord", width: 80 },
{ text: "Timestamp", value: "timestamp", width: 120 },
{ text: "Song", value: "song.name", width: 180 },
{ text: "Artist", value: "song.artist", width: 150 },
{ text: "Chart", value: "song.chart", width: 100 },
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Score", value: "points", width: 120 },
{ text: "Score", value: "points", width: 100 },
];
if (thisGame.scoreHeaders) {
@@ -24,13 +23,12 @@ export function scoreHeaders(thisGame) {
export function personalScoreHeaders(thisGame) {
const headers = [
{ text: "Timestamp", value: "timestamp", width: 140 },
{ text: "New PB", value: "newRecord", width: 100 },
{ text: "Timestamp", value: "timestamp", width: 120 },
{ text: "New PB", value: "newRecord", width: 80 },
{ text: "Song", value: "song.name", width: 180 },
{ text: "Artist", value: "song.artist", width: 180 },
{ text: "Chart", value: "song.chart", width: 120 },
{ text: "Grade", value: "data.rank", width: 80 },
{ text: "Score", value: "points", width: 120 },
{ text: "Score", value: "points", width: 100 },
];
if (thisGame.scoreHeaders) {
@@ -42,6 +40,27 @@ export function personalScoreHeaders(thisGame) {
return headers;
}
export function topScoreHeaders(thisGame) {
const headers = [
{ text: "Player", value: "username", width: 120, sortable: true },
{ text: "Timestamp", value: "timestamp", width: 140, sortable: true },
{ text: "Score", value: "points", width: 100, sortable: true },
];
if (thisGame.scoreHeaders) {
for (var header of thisGame.scoreHeaders) {
header.sortable = true;
headers.push(header);
}
}
return headers;
}
export function formatScoreData(thisGame, data) {
return data;
}
export function formatScoreTable(thisGame, scores) {
var formattedItems = [];
for (var item of scores) {
@@ -78,10 +97,21 @@ export function formatScoreTable(thisGame, scores) {
item.data.clear_type = thisGame.medalTable[item.data?.clear_type];
}
if (item.data?.combo_type != undefined && thisGame.comboTable) {
item.data.combo_type = thisGame.comboTable[item.data?.combo_type];
}
if (!item.data?.rank && thisGame.ratingTable) {
item.data.rank = rankFromScore(thisGame.ratingTable, item.points);
}
if (!item.data?.rank && thisGame.percTable) {
item.data.rank = rankFromScore(
thisGame.percTable,
item.data?.achievement_rate,
);
}
if (item.data?.rank != undefined && thisGame.rankTable) {
item.data.rank = thisGame.rankTable[item.data?.rank];
}
@@ -118,6 +148,10 @@ export function formatScoreTable(thisGame, scores) {
item.data.music_rate = item.data?.music_rate / 10;
}
if (item.data?.achievement_rate) {
item.data.achievement_rate = `${item.data?.achievement_rate / 100}%`;
}
if (item.data?.excellent) {
item.medal = "EX FC";
} else if (item.data?.fullcombo) {
@@ -136,6 +170,10 @@ export function formatScoreTable(thisGame, scores) {
item.data.combo = 0;
}
if (item.data?.miss_count === -1) {
item.data.miss_count = 0;
}
if (item.points != undefined) {
item.points = item.points
.toString()

View File

@@ -15,7 +15,11 @@ import GameHeader from "@/components/Cards/GameHeader.vue";
import { APIGetTopScore } from "@/stores/api/music";
import { getGameInfo } from "@/constants";
import { formatDifficulty } from "@/constants/scoreDataFilters";
import { formatScoreTable } from "@/constants/table/scores";
import {
topScoreHeaders,
formatScoreData,
formatScoreTable,
} from "@/constants/table/scores";
const $route = useRoute();
const $router = useRouter();
var gameId = $route.params.game;
@@ -35,25 +39,12 @@ if (!thisGame) {
onMounted(async () => {
try {
const data = await APIGetTopScore(gameId, songId);
songData.value = data;
songData.value = formatScoreData(thisGame, data);
} catch (error) {
console.error("Failed to fetch score data:", error);
}
});
const headers = [
{ text: "Player", value: "username", width: 120, sortable: true },
{ text: "Timestamp", value: "timestamp", width: 140, sortable: true },
{ text: "Grade", value: "data.rank", width: 80, sortable: true },
{ text: "Score", value: "points", width: 120, sortable: true },
];
if (thisGame.scoreHeaders) {
for (var header of thisGame.scoreHeaders) {
headers.push(header);
}
}
const chartSelector = reactive({
currentChart: 0,
});
@@ -163,7 +154,7 @@ const navigateToProfile = (item) => {
>
<div class="w-full">
<GeneralTable
:headers="headers"
:headers="topScoreHeaders(thisGame)"
:items="selectedChartRecords"
@row-clicked="navigateToProfile"
/>