moved kamaitachi export to chunithm tabs
This commit is contained in:
209
components/kamaitachi/action.ts
Normal file
209
components/kamaitachi/action.ts
Normal file
@ -0,0 +1,209 @@
|
||||
"use server";
|
||||
import { getAuth } from "@/auth/queries/getauth";
|
||||
import { getSupportedVersionNumber } from "@/lib/api";
|
||||
import { artemis } from "@/lib/prisma";
|
||||
import { fromZonedTime, toZonedTime } from "date-fns-tz";
|
||||
import { parse } from "date-fns";
|
||||
|
||||
const TACHI_CLASSES = [
|
||||
undefined,
|
||||
"DAN_I",
|
||||
"DAN_II",
|
||||
"DAN_III",
|
||||
"DAN_IV",
|
||||
"DAN_V",
|
||||
"DAN_INFINITE",
|
||||
] as const;
|
||||
const TACHI_DIFFICULTIES = [
|
||||
"BASIC",
|
||||
"ADVANCED",
|
||||
"EXPERT",
|
||||
"MASTER",
|
||||
"ULTIMA",
|
||||
] as const;
|
||||
|
||||
type BatchManualLamp =
|
||||
| "ALL JUSTICE CRITICAL"
|
||||
| "ALL JUSTICE"
|
||||
| "FULL COMBO"
|
||||
| "CLEAR"
|
||||
| "FAILED";
|
||||
interface BatchManualScore {
|
||||
identifier: string;
|
||||
matchType: "inGameID";
|
||||
score: number;
|
||||
lamp: BatchManualLamp;
|
||||
difficulty: "BASIC" | "ADVANCED" | "EXPERT" | "MASTER" | "ULTIMA";
|
||||
timeAchieved?: number;
|
||||
judgements?: {
|
||||
jcrit: number;
|
||||
justice: number;
|
||||
attack: number;
|
||||
miss: number;
|
||||
};
|
||||
optional?: {
|
||||
maxCombo: number;
|
||||
};
|
||||
}
|
||||
interface BatchManualImport {
|
||||
meta: {
|
||||
game: string;
|
||||
playtype: string;
|
||||
service: string;
|
||||
};
|
||||
scores: BatchManualScore[];
|
||||
classes?: {
|
||||
dan?: string;
|
||||
emblem?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export async function getTachiExport() {
|
||||
const { user } = await getAuth();
|
||||
const version = await getSupportedVersionNumber();
|
||||
|
||||
if (!user || !user.accessCode) {
|
||||
throw new Error("User is not authenticated or accessCode is missing");
|
||||
}
|
||||
|
||||
const profile = await artemis.chuni_profile_data.findFirst({
|
||||
where: {
|
||||
user: user.UserId,
|
||||
version,
|
||||
},
|
||||
select: {
|
||||
classEmblemBase: true,
|
||||
classEmblemMedal: true,
|
||||
},
|
||||
});
|
||||
const playlog = await artemis.chuni_score_playlog.findMany({
|
||||
where: {
|
||||
user: user.UserId,
|
||||
},
|
||||
select: {
|
||||
romVersion: true,
|
||||
userPlayDate: true,
|
||||
musicId: true,
|
||||
level: true,
|
||||
score: true,
|
||||
maxCombo: true,
|
||||
judgeGuilty: true,
|
||||
judgeAttack: true,
|
||||
judgeJustice: true,
|
||||
judgeCritical: true,
|
||||
judgeHeaven: true,
|
||||
isFullCombo: true,
|
||||
isAllJustice: true,
|
||||
isClear: true,
|
||||
},
|
||||
});
|
||||
|
||||
const tachiExport: BatchManualImport = {
|
||||
meta: {
|
||||
game: "chunithm",
|
||||
playtype: "Single",
|
||||
service: "Cozynet",
|
||||
},
|
||||
scores: [],
|
||||
classes: {
|
||||
dan: TACHI_CLASSES[profile?.classEmblemBase ?? 0],
|
||||
emblem: TACHI_CLASSES[profile?.classEmblemMedal ?? 0],
|
||||
},
|
||||
};
|
||||
|
||||
for (const log of playlog) {
|
||||
const {
|
||||
romVersion,
|
||||
userPlayDate,
|
||||
musicId,
|
||||
level,
|
||||
score,
|
||||
judgeHeaven,
|
||||
judgeCritical,
|
||||
judgeJustice,
|
||||
judgeAttack,
|
||||
judgeGuilty,
|
||||
maxCombo,
|
||||
isAllJustice,
|
||||
isFullCombo,
|
||||
isClear,
|
||||
} = log;
|
||||
|
||||
if (
|
||||
romVersion === null ||
|
||||
musicId === null ||
|
||||
level === null ||
|
||||
score === null ||
|
||||
judgeJustice === null ||
|
||||
isAllJustice === null ||
|
||||
isFullCombo === null ||
|
||||
isClear === null
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter out WORLD'S END scores
|
||||
if (romVersion.startsWith("1.") && level === 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (romVersion.startsWith("2.") && level === 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let lamp: BatchManualLamp = "FAILED";
|
||||
|
||||
if (isAllJustice && judgeJustice === 0) {
|
||||
lamp = "ALL JUSTICE CRITICAL";
|
||||
} else if (isAllJustice) {
|
||||
lamp = "ALL JUSTICE";
|
||||
} else if (isFullCombo) {
|
||||
lamp = "FULL COMBO";
|
||||
} else if (isClear) {
|
||||
lamp = "CLEAR";
|
||||
}
|
||||
|
||||
const tachiScore: BatchManualScore = {
|
||||
score,
|
||||
lamp,
|
||||
identifier: musicId.toString(),
|
||||
matchType: "inGameID",
|
||||
difficulty: TACHI_DIFFICULTIES[level],
|
||||
};
|
||||
|
||||
if (userPlayDate !== null) {
|
||||
tachiScore.timeAchieved = fromZonedTime(
|
||||
parse(
|
||||
userPlayDate,
|
||||
"yyyy-MM-dd HH:mm:ss",
|
||||
toZonedTime(new Date(), "Asia/Tokyo"),
|
||||
),
|
||||
"Asia/Tokyo",
|
||||
).valueOf();
|
||||
}
|
||||
|
||||
if (
|
||||
judgeCritical !== null &&
|
||||
judgeJustice !== null &&
|
||||
judgeAttack !== null &&
|
||||
judgeGuilty !== null
|
||||
) {
|
||||
tachiScore.judgements = {
|
||||
jcrit: (judgeHeaven ?? 0) + judgeCritical,
|
||||
justice: judgeJustice,
|
||||
attack: judgeAttack,
|
||||
miss: judgeGuilty,
|
||||
};
|
||||
}
|
||||
|
||||
if (maxCombo !== null) {
|
||||
tachiScore.optional = {
|
||||
maxCombo,
|
||||
};
|
||||
}
|
||||
|
||||
tachiExport.scores.push(tachiScore);
|
||||
}
|
||||
|
||||
return tachiExport;
|
||||
}
|
Reference in New Issue
Block a user