Skip to content

Commit

Permalink
feat: add myt ongeki support (#1076)
Browse files Browse the repository at this point in the history
* feat: add myt ongeki support

* fix: import myt score

* style: undo misc. prettier changes

* fix: nit on logging

* fix: use song-chart desync as the term here

and severe as loglevel

---------

Co-authored-by: zkldi <[email protected]>
  • Loading branch information
albshin and zkrising authored May 15, 2024
1 parent b25819c commit 970f7ca
Show file tree
Hide file tree
Showing 35 changed files with 3,847 additions and 13 deletions.
1 change: 1 addition & 0 deletions bot/src/slashCommands/commands/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const choices: Array<[string, string]> = (
["CG MUSECA", "api/cg-prod-museca"],
["CG Pop'n", "api/cg-prod-popn"],
["MYT WACCA", "api/myt-wacca"],
["MYT ONGEKI", "api/myt-ongeki"],
] as Array<[string, string]>
)

Expand Down
17 changes: 14 additions & 3 deletions client/src/app/pages/dashboard/import/ImportPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ function ImportInfoDisplayer({ game }: { game: Game }) {
key="SL-ITG"
/>
);
} else if (game === 'ongeki') {
} else if (game === "ongeki") {
Content.unshift(
<ImportInfoCard
name="ARTEMiS Exporter"
Expand All @@ -355,9 +355,10 @@ function ImportInfoDisplayer({ game }: { game: Game }) {
</>
}
key="ARTEMiS Exporter"
/>
/>,
<ImportTypeInfoCard key="api/myt-ongeki" importType="api/myt-ongeki" />
);
}// else if (game === "jubeat") {
} // else if (game === "jubeat") {
// Content.unshift(
// <ImportTypeInfoCard key="api/cg-dev-jubeat" importType="api/cg-dev-jubeat" />,
// <ImportTypeInfoCard key="api/cg-prod-jubeat" importType="api/cg-prod-jubeat" />
Expand Down Expand Up @@ -536,6 +537,16 @@ function ImportTypeInfoCard({
key="myt-wacca"
/>
);
case "api/myt-ongeki":
return (
<ImportInfoCard
name="MYT Integration"
href="myt-ongeki"
desc="Pull your Ongeki scores from the MYT Network."
moreInfo="Note: All networks are reduced to their first three letters for anonymity reasons."
key="myt-ongeki"
/>
);
case "file/eamusement-iidx-csv":
return (
<ImportInfoCard
Expand Down
3 changes: 3 additions & 0 deletions client/src/app/routes/ImportRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ export default function ImportRoutes() {
<Route exact path="/import/myt-wacca">
<MytIntegrationPage game="wacca" />
</Route>
<Route exact path="/import/myt-ongeki">
<MytIntegrationPage game="ongeki" />
</Route>

<Route exact path="/import/wacca-mypage-scraper">
<WACCAMyPageScraperPage />
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/imports/MYTIntegrationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import ImportStateRenderer from "./ImportStateRenderer";

interface Props {
// Other games will be added in the future.
game: "wacca";
game: "wacca" | "ongeki";
}

export default function MytIntegrationPage({ game }: Props) {
Expand Down
1 change: 1 addition & 0 deletions common/src/constants/import-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const API_IMPORT_TYPES: Record<APIImportTypes, true> = {
"api/flo-iidx": true,
"api/flo-sdvx": true,
"api/min-sdvx": true,
"api/myt-ongeki": true,
"api/myt-wacca": true,
"api/cg-dev-museca": true,
"api/cg-dev-popn": true,
Expand Down
1 change: 1 addition & 0 deletions common/src/types/import-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type APIImportTypes =
| "api/flo-iidx"
| "api/flo-sdvx"
| "api/min-sdvx"
| "api/myt-ongeki"
| "api/myt-wacca"

// cg has dev and prod supported
Expand Down
1 change: 1 addition & 0 deletions server/example/conf.json5
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"api/cg-gan-sdvx",
"api/cg-gan-popn",
"api/cg-gan-museca",
"api/myt-ongeki",
"api/myt-wacca",
],
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import ConvertAPIMytOngeki from "./converter";
import CreateLogCtx from "lib/logger/logger";
import { ParseDateFromString } from "lib/score-import/framework/common/score-utils";
import {
OngekiBattleScoreRank,
OngekiClearStatus,
OngekiComboStatus,
OngekiLevel,
OngekiTechScoreRank,
} from "proto/generated/ongeki/common_pb";
import t from "tap";
import { dmf } from "test-utils/misc";
import ResetDBState from "test-utils/resets";
import { TestingOngekiChartConverter, TestingOngekiSongConverter } from "test-utils/test-data";
import type { MytOngekiScore } from "./types";

const logger = CreateLogCtx(__filename);

const parsedScore: MytOngekiScore = {
playlogApiId: "806ca7ac-76f5-4d99-8760-770df60e1ff5",
info: {
musicId: 678,
level: OngekiLevel.ONGEKI_LEVEL_MASTER,
techScore: 1003385,
battleScore: 4987905,
overDamage: 13151,
techScoreRank: OngekiTechScoreRank.ONGEKI_TECH_SCORE_RANK_SS_PLUS,
battleScoreRank: OngekiBattleScoreRank.ONGEKI_BATTLE_SCORE_RANK_GREAT,
comboStatus: OngekiComboStatus.ONGEKI_COMBO_STATUS_NONE,
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_OVER_DAMAGE,
isFullBell: true,
isTechNewRecord: true,
isBattleNewRecord: true,
isOverDamageNewRecord: true,
platinumScore: 893,
userPlayDate: "2022-09-28T12:04:21.400Z",
},
judge: {
judgeCriticalBreak: 967,
judgeBreak: 19,
judgeHit: 0,
judgeMiss: 5,
maxCombo: 525,
bellCount: 174,
totalBellCount: 174,
damageCount: 0,
},
};

t.test("#ConvertAPIMytOngeki", (t) => {
t.beforeEach(ResetDBState);

function convert(modifier: any = {}) {
return ConvertAPIMytOngeki(dmf(parsedScore, modifier), {}, "api/myt-ongeki", logger);
}

t.test("Should return a dryScore on valid input.", async (t) => {
const res = await convert();

t.strictSame(res, {
song: TestingOngekiSongConverter,
chart: TestingOngekiChartConverter,
dryScore: {
service: "MYT",
game: "ongeki",
scoreMeta: {},
timeAchieved: ParseDateFromString("2022-09-28T12:04:21.400Z"),
comment: null,
importType: "api/myt-ongeki",
scoreData: {
score: 1003385,
noteLamp: "CLEAR",
bellLamp: "FULL BELL",
judgements: {
cbreak: 967,
break: 19,
hit: 0,
miss: 5,
},
optional: {
damage: 0,
bellCount: 174,
totalBellCount: 174,
platScore: 893,
},
},
},
});
t.end();
});

t.test("Should reject unspecified difficulty", (t) => {
t.rejects(
() =>
convert({
info: {
level: OngekiLevel.ONGEKI_LEVEL_UNSPECIFIED,
},
}),
{
message: /Can't process a score with unspecified difficulty/u,
}
);
t.end();
});

t.test("note lamp", async (t) => {
t.hasStrict(
await convert({
info: {
comboStatus: OngekiComboStatus.ONGEKI_COMBO_STATUS_ALL_BREAK,
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_FAILED,
},
}),
{
dryScore: { scoreData: { noteLamp: "ALL BREAK" } },
}
);
t.hasStrict(
await convert({
info: {
comboStatus: OngekiComboStatus.ONGEKI_COMBO_STATUS_FULL_COMBO,
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_FAILED,
},
}),
{
dryScore: { scoreData: { noteLamp: "FULL COMBO" } },
}
);
t.hasStrict(
await convert({
info: {
comboStatus: OngekiComboStatus.ONGEKI_COMBO_STATUS_NONE,
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_OVER_DAMAGE,
},
}),
{
dryScore: { scoreData: { noteLamp: "CLEAR" } },
}
);
t.hasStrict(
await convert({
info: {
comboStatus: OngekiComboStatus.ONGEKI_COMBO_STATUS_NONE,
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_CLEARED,
},
}),
{
dryScore: { scoreData: { noteLamp: "CLEAR" } },
}
);
t.hasStrict(
await convert({
info: {
comboStatus: OngekiComboStatus.ONGEKI_COMBO_STATUS_NONE,
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_FAILED,
},
}),
{
dryScore: { scoreData: { noteLamp: "LOSS" } },
}
);
t.end();
});

t.test("platinum score should be null if value is 0", async (t) => {
t.hasStrict(
await convert({
info: {
platinumScore: 0,
},
}),
{
dryScore: { scoreData: { optional: { platScore: null } } },
}
);
t.end();
});

t.test("Should reject unspecified clear status", (t) => {
t.rejects(
() =>
convert({
info: {
clearStatus: OngekiClearStatus.ONGEKI_CLEAR_STATUS_UNSPECIFIED,
},
}),
{
message: /Can't process a score with an invalid combo status and\/or clear status/u,
}
);
t.end();
});

t.test("Should throw on missing chart", (t) => {
t.rejects(() => convert({ info: { musicId: 999999 } }), {
message: /Can't find chart with id 999999 and difficulty MASTER/u,
});
t.end();
});

t.end();
});
Loading

0 comments on commit 970f7ca

Please sign in to comment.