added chunithm version selector in admin settings

This commit is contained in:
Polaris 2024-08-20 16:49:01 -04:00
parent 552f737650
commit d6629a72eb
37 changed files with 614 additions and 107 deletions

View File

@ -1,10 +1,6 @@
import ExtractData from "./extraction";
const FileExtractionPage = async () => {
return (
<div className="flex min-h-screen w-full flex-col">
<ExtractData />
</div>
);
return <ExtractData />;
};
export default FileExtractionPage;

View File

@ -0,0 +1,68 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { daphnis } from "@/lib/prisma";
import { GameVersion } from "@/prisma/schemas/daphnis/generated/daphnis";
export async function getCurrentGame() {
const { user } = await getAuth();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
}
const currentGameVersion = await daphnis.user.findMany({
where: {
UserId: user.UserId,
},
select: {
gameVersion: true,
},
});
return currentGameVersion;
}
export async function updatePlayerGameVersionChuni(gameVersion?: GameVersion) {
const { user } = await getAuth();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
}
if (gameVersion === undefined) {
throw new Error("gameVersion is required");
}
try {
const updatedUser = await daphnis.user.update({
where: {
UserId: user.UserId,
},
data: {
gameVersion,
},
select: {
gameVersion: true,
},
});
return { gameVersion: updatedUser.gameVersion };
} catch (error) {
console.error("Error updating game version:", error);
throw error;
}
}
export async function getAllGameVersionsChuni() {
const { user } = await getAuth();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
}
const AllGameVersions = await daphnis.user.findMany({
select: {
gameVersion: true,
},
});
return AllGameVersions;
}

View File

@ -0,0 +1,162 @@
"use client";
import React, { FC, useState } from "react";
import { Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { toast } from "@/components/ui/use-toast";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { GameVersion, User } from "@/prisma/schemas/daphnis/generated/daphnis";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { updatePlayerGameVersionChuni } from "./actions";
type ChunithmGameVersionSelectionProps = {
chunithmGameVersionNumber: {
gameVersions: { gameVersion: GameVersion }[];
};
};
export function ChunithmGameVersionSelection({
chunithmGameVersionNumber,
}: ChunithmGameVersionSelectionProps) {
const FormSchema = z.object({
mapIconId: z.string({
required_error: "Please select a Game Version.",
}),
});
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
});
const [selectedGameVersion, setSelectedGameVersion] = useState<
string | undefined
>(Object.values(GameVersion)[0]);
function onSubmit(data: z.infer<typeof FormSchema>) {
const newGameVersion = data.mapIconId ?? selectedGameVersion;
// console.log("Submitted Game Version:", newGameVersion);
updatePlayerGameVersionChuni(newGameVersion as GameVersion)
.then((result) => {
toast({
title: "Game version updated successfully!",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">
{JSON.stringify(result, null, 2)}
</code>
</pre>
),
});
setSelectedGameVersion(newGameVersion);
form.reset({
mapIconId: undefined,
});
})
.catch((error) => {
toast({
title: "Error updating game version",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{error.message}</code>
</pre>
),
variant: "destructive",
});
});
}
return (
<main className="flex flex-col items-center space-y-6 p-4">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="mapIconId"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel className="pb-2">Chunithm</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
role="combobox"
className={cn(
"w-[300px] justify-between",
!field.value && "text-muted-foreground",
)}
>
{field.value
? GameVersion[field.value as keyof typeof GameVersion]
: "Select Game Version"}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-[300px] p-0">
<Command>
<CommandList>
<CommandEmpty>No game version found.</CommandEmpty>
<CommandGroup>
{Object.values(GameVersion).map((version) => (
<CommandItem
value={version}
key={version}
onSelect={() => {
form.setValue("mapIconId", version);
setSelectedGameVersion(version);
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
version === field.value
? "opacity-100"
: "opacity-0",
)}
/>
{version}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">Submit</Button>
</div>
</form>
</Form>
</main>
);
}

View File

@ -0,0 +1,28 @@
"use server";
//https://github.com/vercel/next.js/discussions/63862
import React from "react";
import { Card, CardHeader, CardTitle } from "@/components/ui/card";
import { ChunithmGameVersionSelection } from "./gameSelection";
import { getAllGameVersionsChuni } from "./actions";
const getAllGamesChunithm = async () => {
const gameVersions = await getAllGameVersionsChuni();
return { gameVersions };
};
const Page = async () => {
const AllChunithmVersions = await getAllGamesChunithm();
return (
<Card x-chunk="gameverion">
<CardHeader>
<CardTitle className="text-2xl">Update Game Versions</CardTitle>
</CardHeader>
<ChunithmGameVersionSelection
chunithmGameVersionNumber={AllChunithmVersions}
/>
</Card>
);
};
export default Page;

View File

@ -1,14 +1,6 @@
import { getAuth } from "@/auth/queries/getauth";
import AdminHome from "./home";
import UnlockUser from "./unlock";
const ProtectedDashboardPage = async () => {
const { user } = await getAuth();
return (
<div>
<AdminHome />
</div>
);
const FileExtractionPage = async () => {
return <UnlockUser />;
};
export default ProtectedDashboardPage;
export default FileExtractionPage;

View File

@ -4,7 +4,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@radix-ui/react-dropdown-menu";
import React from "react";
const AdminHome = () => {
const UnlockUser = () => {
return (
<Card x-chunk="aimecard">
<CardHeader>
@ -31,4 +31,4 @@ const AdminHome = () => {
);
};
export default AdminHome;
export default UnlockUser;

View File

@ -1,10 +1,6 @@
import UnlockUser from "./unlock";
const FileExtractionPage = async () => {
return (
<div className="flex min-h-screen w-full flex-col">
<UnlockUser />
</div>
);
return <UnlockUser />;
};
export default FileExtractionPage;

View File

@ -89,16 +89,19 @@ const Page = async () => {
const HotChuniPlays = await getChuniHotPlays();
return (
<div className="p-4">
<div className="p-3">
<Tabs defaultValue="scores">
<TabsList className="">
<TabsTrigger value="scores">Scores</TabsTrigger>
<TabsTrigger value="customize">Customize</TabsTrigger>
<TabsTrigger value="TopPlays">Top Plays</TabsTrigger>
<TabsTrigger value="HotPlays">Hot Plays</TabsTrigger>
<TabsTrigger value="Patcher">Patcher</TabsTrigger>
<TabsTrigger value="Settings">Settings</TabsTrigger>
<TabsTrigger value="Patcher" className="hidden md:block">
Patcher
</TabsTrigger>
</TabsList>
<TabsContent className="pt-2" value="scores">
<TabsContent className="pt-1" value="scores">
<ChunithmScorePlaylog />
</TabsContent>
<TabsContent value="customize">
@ -140,6 +143,9 @@ const Page = async () => {
<TabsContent className="" value="Patcher">
<Patcher />
</TabsContent>
<TabsContent className="" value="Settings">
<Patcher />
</TabsContent>
</Tabs>
</div>
);

View File

@ -1,8 +1,8 @@
import { cookies } from "next/headers";
import { cache } from "react";
import type { Session, User } from "lucia";
import { lucia } from "@/lib/lucia";
import { cookies } from "next/dist/client/components/headers";
export const getAuth = cache(
async (): Promise<
@ -24,7 +24,7 @@ export const getAuth = cache(
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes
sessionCookie.attributes,
);
}
if (!result.session) {
@ -32,10 +32,10 @@ export const getAuth = cache(
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes
sessionCookie.attributes,
);
}
} catch {}
return result;
}
},
);

BIN
bun.lockb

Binary file not shown.

View File

@ -1,11 +1,12 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getCurrentAvatarParts() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -36,6 +37,7 @@ export async function updateAvatarParts(
avatarItem?: number,
) {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -69,6 +71,7 @@ export async function updateAvatarParts(
export async function getAllAvatarParts(category: number) {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");

View File

@ -34,11 +34,10 @@ import { toast } from "../../ui/use-toast";
import { updateAvatarParts } from "./actions";
type chunithm_avatar = chuni_static_avatar;
const getAvatarTextureSrc = (id: number | undefined) => {
if (id === undefined) return "";
return `avatarAccessory/CHU_UI_Avatar_Tex_0${id}.png`;
}
};
type AvatarSelectionProps = {
avatarHeadSelectionData: {
@ -116,18 +115,18 @@ export const AvatarCustomization: FC<AvatarSelectionProps> = ({
}, []);
function onSubmit(data: z.infer<typeof FormSchema>) {
// Existing state
const unchangedHeadId = avatarHeadId;
const unchangedFaceId = avatarFaceId;
const unchangedBackId = avatarBackId;
const unchangedWearId = avatarWearId;
const unchangedItemId = avatarItemId;
const defaultHeadId = avatarHeadId;
const defaultFaceId = avatarFaceId;
const defaultBackId = avatarBackId;
const defaultWearId = avatarWearId;
const defaultItemId = avatarItemId;
// either change to the new body part id or fallback to the unchanged if nothing has changed
const newHeadId = data.AvatarHeadAccessory ?? unchangedHeadId;
const newFaceId = data.AvatarFaceAccessory ?? unchangedFaceId;
const newBackId = data.AvatarBackAccessory ?? unchangedBackId;
const newWearId = data.AvatarWearAccessory ?? unchangedWearId;
const newItemId = data.AvatarItemAccessory ?? unchangedItemId;
// either change to the new body part id or fallback to the default if nothing has changed
const newHeadId = data.AvatarHeadAccessory ?? defaultHeadId;
const newFaceId = data.AvatarFaceAccessory ?? defaultFaceId;
const newBackId = data.AvatarBackAccessory ?? defaultBackId;
const newWearId = data.AvatarWearAccessory ?? defaultWearId;
const newItemId = data.AvatarItemAccessory ?? defaultItemId;
updateAvatarParts(newHeadId, newFaceId, newBackId, newWearId, newItemId)
.then(() => {
@ -265,7 +264,7 @@ export const AvatarCustomization: FC<AvatarSelectionProps> = ({
name="AvatarHeadAccessory"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Avatar Head Item</FormLabel>
<FormLabel className="pb-2">Avatar Head Item</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
@ -330,7 +329,7 @@ export const AvatarCustomization: FC<AvatarSelectionProps> = ({
name="AvatarFaceAccessory"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Avatar Face Item</FormLabel>
<FormLabel className="pb-2">Avatar Face Item</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
@ -395,7 +394,7 @@ export const AvatarCustomization: FC<AvatarSelectionProps> = ({
name="AvatarItemAccessory"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Avatar Hand Item</FormLabel>
<FormLabel className="pb-2">Avatar Hand Item</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
@ -460,7 +459,7 @@ export const AvatarCustomization: FC<AvatarSelectionProps> = ({
name="AvatarBackAccessory"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Avatar Back Item</FormLabel>
<FormLabel className="pb-2">Avatar Back Item</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
@ -525,7 +524,7 @@ export const AvatarCustomization: FC<AvatarSelectionProps> = ({
name="AvatarWearAccessory"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Avatar Clothing Item</FormLabel>
<FormLabel className="pb-2">Avatar Clothing Item</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>

View File

@ -1,11 +1,12 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getCurrentMapIcon() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -25,6 +26,7 @@ export async function getCurrentMapIcon() {
export async function updatePlayerMapIcon(mapIconId?: number) {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");

View File

@ -108,7 +108,7 @@ export const MapIconCustomization: FC<SystemVoiceSelectionProps> = ({
mapIconId: {
src: mapIconId
? getTexture(
form.watch("mapIconId"),
mapIconId, // Use mapIconId directly
`mapIcon/CHU_UI_MapIcon_${mapIconId.toString().padStart(8, "0")}.png`,
)
: `systemVoiceThumbnails/CHU_UI_SystemVoice_Default.png`,
@ -121,7 +121,11 @@ export const MapIconCustomization: FC<SystemVoiceSelectionProps> = ({
<div className="">
{Object.entries(MapIconTextures).map(([key, { src }]) => (
<div>
<img className="w-[100px]" src={src} alt={""} />
<img
className="w-[100px]"
src={MapIconTextures.mapIconId.src}
alt={mapIconId ? `Map Icon ${mapIconId}` : "Default Map Icon"}
/>{" "}
</div>
))}
</div>
@ -133,7 +137,7 @@ export const MapIconCustomization: FC<SystemVoiceSelectionProps> = ({
name="mapIconId"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Select Map Icon</FormLabel>
<FormLabel className="pb-2">Select Map Icon</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>

View File

@ -1,11 +1,12 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getCurrentNameplate() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -25,6 +26,7 @@ export async function getCurrentNameplate() {
export async function updatePlayerNamePlate(nameplateId?: number) {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");

View File

@ -77,8 +77,8 @@ export const NameplateCustomization: FC<AvatarSelectionProps> = ({
}, []);
function onSubmit(data: z.infer<typeof FormSchema>) {
const unchangedNamePlateId = nameplateId;
const newNamePlateId = data.nameplateId ?? unchangedNamePlateId;
const defaultNamePlateId = nameplateId;
const newNamePlateId = data.nameplateId ?? defaultNamePlateId;
updatePlayerNamePlate(newNamePlateId).then(() => {
setNameplateId(newNamePlateId);
@ -136,7 +136,7 @@ export const NameplateCustomization: FC<AvatarSelectionProps> = ({
name="nameplateId"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Select Nameplate</FormLabel>
<FormLabel className="pb-2">Select Nameplate</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>

View File

@ -1,11 +1,12 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getCurrentSystemVoice() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -25,6 +26,7 @@ export async function getCurrentSystemVoice() {
export async function updatePlayerSystemVoiceId(voiceId: number) {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -63,7 +65,7 @@ export async function updatePlayerSystemVoiceId(voiceId: number) {
console.log(updatePlayerNameplate);
return updatePlayerNameplate;
return unlockedSystemVoices;
} catch (error) {
console.error("Error updating nameplate:", error);
throw error;

View File

@ -143,7 +143,7 @@ export const SystemVoiceCustomization: FC<SystemVoiceSelectionProps> = ({
name="PlayerSystemVoice"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Select System Voice</FormLabel>
<FormLabel className="pb-2">Select System Voice</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>

View File

@ -1,11 +1,12 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getCurrentTrophies() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
@ -25,6 +26,7 @@ export async function getCurrentTrophies() {
export async function updatePlayerTrophy(trophyId: number) {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");

View File

@ -76,8 +76,8 @@ export const TrophyCustomization: FC<AvatarSelectionProps> = ({
}, []);
function onSubmit(data: z.infer<typeof FormSchema>) {
const unchangedNamePlateId = trophyID;
const newNamePlateId = data.trophies ?? unchangedNamePlateId;
const defaultNamePlateId = trophyID;
const newNamePlateId = data.trophies ?? defaultNamePlateId;
updatePlayerTrophy(newNamePlateId).then(() => {
setTrophyId(newNamePlateId);
@ -112,7 +112,7 @@ export const TrophyCustomization: FC<AvatarSelectionProps> = ({
name="trophies"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Select Trophy</FormLabel>
<FormLabel className="pb-2">Select Trophy</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>

View File

@ -7,6 +7,7 @@ const NAV_ITEMS = [
{ href: "/admin/home", label: "Home" },
{ href: "/admin/unlock", label: "Unlock User" },
{ href: "/admin/extraction", label: "Extract Game Files" },
{ href: "/admin/gameversions", label: "Edit Game Version" },
];
const AdminSubNavigation = () => {

View File

@ -1,10 +1,11 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getUserRatingBaseHotList() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");

View File

@ -1,10 +1,11 @@
"use server";
import { getAuth } from "@/auth/queries/getauth";
import { supportedVersionNumber } from "@/lib/helpers";
import { getSupportedVersionNumber } from "@/lib/api";
import { artemis } from "@/lib/prisma";
export async function getUserRatingBaseList() {
const { user } = await getAuth();
const supportedVersionNumber = await getSupportedVersionNumber();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");

9
global.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
// global.d.ts
import { PrismaClient as DaphnisClient } from "@/prisma/schemas/daphnis/generated/daphnis";
import { PrismaClient as ArtemisClient } from "@/prisma/schemas/artemis/generated/artemis";
// adding types to global so primsa.ts doesnt freak out
declare global {
var daphnisClient: DaphnisClient | undefined;
var artemisClient: ArtemisClient | undefined;
}

View File

@ -2,6 +2,7 @@
import { getAuth } from "@/auth/queries/getauth";
import { artemis, daphnis } from "@/lib/prisma";
import { GameVersion } from "@/prisma/schemas/daphnis/generated/daphnis";
export const getUsername = async () => {
const { user } = await getAuth();
@ -45,3 +46,56 @@ export async function verifyAimeCodeAgainstArtemis() {
});
return aimeUser;
}
const GameVersionToNumber: Record<GameVersion, number> = {
[GameVersion.LuminousPlus]: 16,
[GameVersion.Luminous]: 15,
[GameVersion.SunPlus]: 14,
[GameVersion.Sun]: 13,
[GameVersion.NewPlus]: 12,
[GameVersion.New]: 10,
};
export async function getGameVersion(): Promise<GameVersion> {
const { user } = await getAuth();
if (!user || !user.accessCode) {
throw new Error("User is not authenticated or accessCode is missing");
}
const aimeUser = await daphnis.user.findFirst({
where: {
accessCode: user.accessCode,
},
select: {
gameVersion: true,
},
});
if (!aimeUser || !aimeUser.gameVersion) {
throw new Error("Game version not found for the user");
}
// console.log("User Game Version:", aimeUser.gameVersion);
const gameVersionEnum = aimeUser.gameVersion as GameVersion;
if (!(gameVersionEnum in GameVersionToNumber)) {
throw new Error("Unknown game version");
}
return gameVersionEnum;
}
export async function getSupportedVersionNumber(): Promise<number> {
const gameVersion = await getGameVersion();
const versionNumber = GameVersionToNumber[gameVersion];
if (versionNumber === undefined) {
throw new Error("Unknown version number");
}
// console.log(typeof versionNumber);
return versionNumber;
}

View File

@ -1,3 +1,9 @@
import { getAuth } from "@/auth/queries/getauth";
import { daphnis } from "./prisma";
import { GameVersion } from "@/prisma/schemas/daphnis/generated/daphnis";
import { getGameVersion } from "./api";
import { LucideSuperscript } from "lucide-react";
export const getDifficultyClass = (level: number) => {
switch (level) {
case 0:
@ -53,7 +59,3 @@ export const getGrade = (score: number) => {
if (score < 500000) return "D";
return "";
};
export const supportedVersionNumber = Number(
process.env.SUPPORTED_CHUNITHM_VERSION_NUMBER,
);

View File

@ -1,20 +1,36 @@
import { PrismaClient as daphnisClient } from "@/prisma/schemas/daphnis/generated/daphnis";
import { PrismaClient as artemisClient } from "@/prisma/schemas/artemis/generated/artemis";
import { PrismaClient as DaphnisClient } from "@/prisma/schemas/daphnis/generated/daphnis";
import { PrismaClient as ArtemisClient } from "@/prisma/schemas/artemis/generated/artemis";
const DaphnisSingleton = () => {
return new daphnisClient();
};
const aremisSingleton = () => {
return new artemisClient();
};
declare global {
var daphnis: undefined | ReturnType<typeof DaphnisSingleton>;
var artemis: undefined | ReturnType<typeof aremisSingleton>;
// Singleton pattern for Daphnis client
const DaphnisClientSingleton = () => {
if (process.env.NODE_ENV === "production") {
return new DaphnisClient();
}
export const daphnis = globalThis.daphnis ?? DaphnisSingleton();
export const artemis = globalThis.artemis ?? aremisSingleton();
// In development mode, reuse existing global instance if available
if (globalThis.daphnisClient) {
return globalThis.daphnisClient as DaphnisClient;
}
const client = new DaphnisClient();
globalThis.daphnisClient = client;
return client;
};
if (process.env.NODE_ENV !== "production") globalThis.daphnis = daphnis;
// Singleton pattern for Artemis client
const ArtemisClientSingleton = () => {
if (process.env.NODE_ENV === "production") {
return new ArtemisClient();
}
// In development mode, reuse existing global instance if available
if (globalThis.artemisClient) {
return globalThis.artemisClient as ArtemisClient;
}
const client = new ArtemisClient();
globalThis.artemisClient = client;
return client;
};
// Exporting the singletons
export const daphnis = DaphnisClientSingleton();
export const artemis = ArtemisClientSingleton();

View File

@ -50,6 +50,7 @@
"@tanstack/react-query": "^5.48.0",
"@tanstack/react-table": "^8.17.3",
"@types/bcryptjs": "^2.4.6",
"@types/encoding-japanese": "^2.2.1",
"@types/jsonwebtoken": "^9.0.6",
"@types/luxon": "^3.4.2",
"bcryptjs": "^2.4.3",
@ -58,7 +59,7 @@
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.1.5",
"framer-motion": "^11.2.11",
"encoding-japanese": "^2.2.0",
"geist": "^1.3.0",
"input-otp": "^1.2.4",
"jsonwebtoken": "^9.0.2",

File diff suppressed because one or more lines are too long

View File

@ -124,6 +124,7 @@ exports.Prisma.UserScalarFieldEnum = {
username: 'username',
accessCode: 'accessCode',
UserId: 'UserId',
gameVersion: 'gameVersion',
hashedPassword: 'hashedPassword',
email: 'email',
role: 'role'
@ -161,6 +162,15 @@ exports.Prisma.NullsOrder = {
first: 'first',
last: 'last'
};
exports.GameVersion = exports.$Enums.GameVersion = {
LuminousPlus: 'LuminousPlus',
Luminous: 'Luminous',
SunPlus: 'SunPlus',
Sun: 'Sun',
NewPlus: 'NewPlus',
New: 'New'
};
exports.UserRole = exports.$Enums.UserRole = {
ADMIN: 'ADMIN',
USER: 'USER'

View File

@ -38,6 +38,18 @@ export type Session = $Result.DefaultSelection<Prisma.$SessionPayload>
* Enums
*/
export namespace $Enums {
export const GameVersion: {
LuminousPlus: 'LuminousPlus',
Luminous: 'Luminous',
SunPlus: 'SunPlus',
Sun: 'Sun',
NewPlus: 'NewPlus',
New: 'New'
};
export type GameVersion = (typeof GameVersion)[keyof typeof GameVersion]
export const UserRole: {
ADMIN: 'ADMIN',
USER: 'USER'
@ -47,6 +59,10 @@ export type UserRole = (typeof UserRole)[keyof typeof UserRole]
}
export type GameVersion = $Enums.GameVersion
export const GameVersion: typeof $Enums.GameVersion
export type UserRole = $Enums.UserRole
export const UserRole: typeof $Enums.UserRole
@ -1210,6 +1226,7 @@ export namespace Prisma {
username: string | null
accessCode: string | null
UserId: number | null
gameVersion: $Enums.GameVersion | null
hashedPassword: string | null
email: string | null
role: $Enums.UserRole | null
@ -1220,6 +1237,7 @@ export namespace Prisma {
username: string | null
accessCode: string | null
UserId: number | null
gameVersion: $Enums.GameVersion | null
hashedPassword: string | null
email: string | null
role: $Enums.UserRole | null
@ -1230,6 +1248,7 @@ export namespace Prisma {
username: number
accessCode: number
UserId: number
gameVersion: number
hashedPassword: number
email: number
role: number
@ -1250,6 +1269,7 @@ export namespace Prisma {
username?: true
accessCode?: true
UserId?: true
gameVersion?: true
hashedPassword?: true
email?: true
role?: true
@ -1260,6 +1280,7 @@ export namespace Prisma {
username?: true
accessCode?: true
UserId?: true
gameVersion?: true
hashedPassword?: true
email?: true
role?: true
@ -1270,6 +1291,7 @@ export namespace Prisma {
username?: true
accessCode?: true
UserId?: true
gameVersion?: true
hashedPassword?: true
email?: true
role?: true
@ -1367,6 +1389,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion: $Enums.GameVersion
hashedPassword: string
email: string
role: $Enums.UserRole
@ -1396,6 +1419,7 @@ export namespace Prisma {
username?: boolean
accessCode?: boolean
UserId?: boolean
gameVersion?: boolean
hashedPassword?: boolean
email?: boolean
role?: boolean
@ -1411,6 +1435,7 @@ export namespace Prisma {
username?: boolean
accessCode?: boolean
UserId?: boolean
gameVersion?: boolean
hashedPassword?: boolean
email?: boolean
role?: boolean
@ -1435,6 +1460,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion: $Enums.GameVersion
hashedPassword: string
email: string
role: $Enums.UserRole
@ -1840,6 +1866,7 @@ export namespace Prisma {
readonly username: FieldRef<"User", 'String'>
readonly accessCode: FieldRef<"User", 'String'>
readonly UserId: FieldRef<"User", 'Int'>
readonly gameVersion: FieldRef<"User", 'GameVersion'>
readonly hashedPassword: FieldRef<"User", 'String'>
readonly email: FieldRef<"User", 'String'>
readonly role: FieldRef<"User", 'UserRole'>
@ -4967,6 +4994,7 @@ export namespace Prisma {
username: 'username',
accessCode: 'accessCode',
UserId: 'UserId',
gameVersion: 'gameVersion',
hashedPassword: 'hashedPassword',
email: 'email',
role: 'role'
@ -5042,6 +5070,13 @@ export namespace Prisma {
/**
* Reference to a field of type 'GameVersion'
*/
export type EnumGameVersionFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'GameVersion'>
/**
* Reference to a field of type 'UserRole'
*/
@ -5074,6 +5109,7 @@ export namespace Prisma {
username?: StringFilter<"User"> | string
accessCode?: StringFilter<"User"> | string
UserId?: IntFilter<"User"> | number
gameVersion?: EnumGameVersionFilter<"User"> | $Enums.GameVersion
hashedPassword?: StringFilter<"User"> | string
email?: StringFilter<"User"> | string
role?: EnumUserRoleFilter<"User"> | $Enums.UserRole
@ -5087,6 +5123,7 @@ export namespace Prisma {
username?: SortOrder
accessCode?: SortOrder
UserId?: SortOrder
gameVersion?: SortOrder
hashedPassword?: SortOrder
email?: SortOrder
role?: SortOrder
@ -5104,6 +5141,7 @@ export namespace Prisma {
AND?: UserWhereInput | UserWhereInput[]
OR?: UserWhereInput[]
NOT?: UserWhereInput | UserWhereInput[]
gameVersion?: EnumGameVersionFilter<"User"> | $Enums.GameVersion
hashedPassword?: StringFilter<"User"> | string
role?: EnumUserRoleFilter<"User"> | $Enums.UserRole
sessions?: SessionListRelationFilter
@ -5116,6 +5154,7 @@ export namespace Prisma {
username?: SortOrder
accessCode?: SortOrder
UserId?: SortOrder
gameVersion?: SortOrder
hashedPassword?: SortOrder
email?: SortOrder
role?: SortOrder
@ -5134,6 +5173,7 @@ export namespace Prisma {
username?: StringWithAggregatesFilter<"User"> | string
accessCode?: StringWithAggregatesFilter<"User"> | string
UserId?: IntWithAggregatesFilter<"User"> | number
gameVersion?: EnumGameVersionWithAggregatesFilter<"User"> | $Enums.GameVersion
hashedPassword?: StringWithAggregatesFilter<"User"> | string
email?: StringWithAggregatesFilter<"User"> | string
role?: EnumUserRoleWithAggregatesFilter<"User"> | $Enums.UserRole
@ -5306,6 +5346,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -5319,6 +5360,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -5332,6 +5374,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -5345,6 +5388,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -5358,6 +5402,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -5368,6 +5413,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -5378,6 +5424,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -5566,6 +5613,13 @@ export namespace Prisma {
not?: NestedIntFilter<$PrismaModel> | number
}
export type EnumGameVersionFilter<$PrismaModel = never> = {
equals?: $Enums.GameVersion | EnumGameVersionFieldRefInput<$PrismaModel>
in?: $Enums.GameVersion[]
notIn?: $Enums.GameVersion[]
not?: NestedEnumGameVersionFilter<$PrismaModel> | $Enums.GameVersion
}
export type EnumUserRoleFilter<$PrismaModel = never> = {
equals?: $Enums.UserRole | EnumUserRoleFieldRefInput<$PrismaModel>
in?: $Enums.UserRole[]
@ -5608,6 +5662,7 @@ export namespace Prisma {
username?: SortOrder
accessCode?: SortOrder
UserId?: SortOrder
gameVersion?: SortOrder
hashedPassword?: SortOrder
email?: SortOrder
role?: SortOrder
@ -5622,6 +5677,7 @@ export namespace Prisma {
username?: SortOrder
accessCode?: SortOrder
UserId?: SortOrder
gameVersion?: SortOrder
hashedPassword?: SortOrder
email?: SortOrder
role?: SortOrder
@ -5632,6 +5688,7 @@ export namespace Prisma {
username?: SortOrder
accessCode?: SortOrder
UserId?: SortOrder
gameVersion?: SortOrder
hashedPassword?: SortOrder
email?: SortOrder
role?: SortOrder
@ -5674,6 +5731,16 @@ export namespace Prisma {
_max?: NestedIntFilter<$PrismaModel>
}
export type EnumGameVersionWithAggregatesFilter<$PrismaModel = never> = {
equals?: $Enums.GameVersion | EnumGameVersionFieldRefInput<$PrismaModel>
in?: $Enums.GameVersion[]
notIn?: $Enums.GameVersion[]
not?: NestedEnumGameVersionWithAggregatesFilter<$PrismaModel> | $Enums.GameVersion
_count?: NestedIntFilter<$PrismaModel>
_min?: NestedEnumGameVersionFilter<$PrismaModel>
_max?: NestedEnumGameVersionFilter<$PrismaModel>
}
export type EnumUserRoleWithAggregatesFilter<$PrismaModel = never> = {
equals?: $Enums.UserRole | EnumUserRoleFieldRefInput<$PrismaModel>
in?: $Enums.UserRole[]
@ -5902,6 +5969,10 @@ export namespace Prisma {
divide?: number
}
export type EnumGameVersionFieldUpdateOperationsInput = {
set?: $Enums.GameVersion
}
export type EnumUserRoleFieldUpdateOperationsInput = {
set?: $Enums.UserRole
}
@ -6073,6 +6144,13 @@ export namespace Prisma {
not?: NestedIntFilter<$PrismaModel> | number
}
export type NestedEnumGameVersionFilter<$PrismaModel = never> = {
equals?: $Enums.GameVersion | EnumGameVersionFieldRefInput<$PrismaModel>
in?: $Enums.GameVersion[]
notIn?: $Enums.GameVersion[]
not?: NestedEnumGameVersionFilter<$PrismaModel> | $Enums.GameVersion
}
export type NestedEnumUserRoleFilter<$PrismaModel = never> = {
equals?: $Enums.UserRole | EnumUserRoleFieldRefInput<$PrismaModel>
in?: $Enums.UserRole[]
@ -6124,6 +6202,16 @@ export namespace Prisma {
not?: NestedFloatFilter<$PrismaModel> | number
}
export type NestedEnumGameVersionWithAggregatesFilter<$PrismaModel = never> = {
equals?: $Enums.GameVersion | EnumGameVersionFieldRefInput<$PrismaModel>
in?: $Enums.GameVersion[]
notIn?: $Enums.GameVersion[]
not?: NestedEnumGameVersionWithAggregatesFilter<$PrismaModel> | $Enums.GameVersion
_count?: NestedIntFilter<$PrismaModel>
_min?: NestedEnumGameVersionFilter<$PrismaModel>
_max?: NestedEnumGameVersionFilter<$PrismaModel>
}
export type NestedEnumUserRoleWithAggregatesFilter<$PrismaModel = never> = {
equals?: $Enums.UserRole | EnumUserRoleFieldRefInput<$PrismaModel>
in?: $Enums.UserRole[]
@ -6377,6 +6465,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -6389,6 +6478,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -6417,6 +6507,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -6429,6 +6520,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -6441,6 +6533,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -6453,6 +6546,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -6481,6 +6575,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -6493,6 +6588,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -6505,6 +6601,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -6517,6 +6614,7 @@ export namespace Prisma {
username: string
accessCode: string
UserId: number
gameVersion?: $Enums.GameVersion
hashedPassword: string
email: string
role?: $Enums.UserRole
@ -6545,6 +6643,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole
@ -6557,6 +6656,7 @@ export namespace Prisma {
username?: StringFieldUpdateOperationsInput | string
accessCode?: StringFieldUpdateOperationsInput | string
UserId?: IntFieldUpdateOperationsInput | number
gameVersion?: EnumGameVersionFieldUpdateOperationsInput | $Enums.GameVersion
hashedPassword?: StringFieldUpdateOperationsInput | string
email?: StringFieldUpdateOperationsInput | string
role?: EnumUserRoleFieldUpdateOperationsInput | $Enums.UserRole

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
{
"name": "prisma-client-f6d74f5cbba0fb342495169b34c2d2520dafdd4c2c3b6c0b176fbebe191af770",
"name": "prisma-client-6a081666c2516e1c2776ef81fca5cd408907b1d39b2c10beb50bbdfd20560ba8",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",

View File

@ -19,12 +19,22 @@ enum UserRole {
USER
}
enum GameVersion {
LuminousPlus
Luminous
SunPlus
Sun
NewPlus
New
}
model User {
id String @id
sessions Session[]
username String @unique
accessCode String @unique
UserId Int @unique
gameVersion GameVersion @default(Luminous)
hashedPassword String
email String @unique

View File

@ -124,6 +124,7 @@ exports.Prisma.UserScalarFieldEnum = {
username: 'username',
accessCode: 'accessCode',
UserId: 'UserId',
gameVersion: 'gameVersion',
hashedPassword: 'hashedPassword',
email: 'email',
role: 'role'
@ -161,6 +162,15 @@ exports.Prisma.NullsOrder = {
first: 'first',
last: 'last'
};
exports.GameVersion = exports.$Enums.GameVersion = {
LuminousPlus: 'LuminousPlus',
Luminous: 'Luminous',
SunPlus: 'SunPlus',
Sun: 'Sun',
NewPlus: 'NewPlus',
New: 'New'
};
exports.UserRole = exports.$Enums.UserRole = {
ADMIN: 'ADMIN',
USER: 'USER'

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `user` ADD COLUMN `gameVersion` ENUM('LuminousPlus', 'Luminous', 'SunPlus', 'Sun', 'NewPlus', 'New') NOT NULL DEFAULT 'Luminous';

View File

@ -19,12 +19,22 @@ enum UserRole {
USER
}
enum GameVersion {
LuminousPlus
Luminous
SunPlus
Sun
NewPlus
New
}
model User {
id String @id
sessions Session[]
username String @unique
accessCode String @unique
UserId Int @unique
gameVersion GameVersion @default(Luminous)
hashedPassword String
email String @unique