diff --git a/src/app/api/submit/route.ts b/src/app/api/submit/route.ts index 1e8db43..8407777 100644 --- a/src/app/api/submit/route.ts +++ b/src/app/api/submit/route.ts @@ -49,7 +49,7 @@ const submitSchema = z.object({ // Save data way miiDataFile: z .instanceof(File) - .refine((blob) => blob.size < 1024 * 1024 * 1.5, "File too large") // TODO: actual size + .refine((blob) => blob.size < 1024 * 1024 * 1, "File too large") // TODO: actual size .optional(), // Manual way @@ -97,7 +97,7 @@ export async function POST(request: NextRequest) { // Minify instructions to save space and improve user experience let minifiedInstructions: Partial | undefined; - if (formData.get("platform") === "SWITCH" && formData.get("way") === "manual") + if (formData.get("platform") === "SWITCH") minifiedInstructions = minifyInstructions(JSON.parse((formData.get("instructions") as string) ?? "{}") as SwitchMiiInstructions); // Parse and check all submission info @@ -211,8 +211,13 @@ export async function POST(request: NextRequest) { if (way === "savedata") { if (!miiData || !miiDataFileBuffer) return rateLimit.sendResponse({ error: "No valid Mii data provided" }, 400); - parsedSwitchMii = new SwitchTomodachiLifeMii(miiDataFileBuffer, miiData); - minifiedInstructions = parsedSwitchMii.toInstructions(); + try { + parsedSwitchMii = new SwitchTomodachiLifeMii(miiDataFileBuffer, miiData); + } catch (error) { + console.warn("Failed to verify Switch Mii data", error); + return rateLimit.sendResponse({ error: "Failed to verify Mii data: is your ShareMii file up to date?" }, 400); + } + // minifiedInstructions = parsedSwitchMii.toInstructions(); } // Create Mii in database @@ -285,7 +290,7 @@ export async function POST(request: NextRequest) { if (parsedSwitchMii) { const pngBuffer = await parsedSwitchMii.extractFacePaintImage(); if (pngBuffer) { - const fileLocation = path.join(miiUploadsDirectory, "features.png"); // Save as features because it isn't used + const fileLocation = path.join(miiUploadsDirectory, "facepaint.png"); await fs.writeFile(fileLocation, pngBuffer); } } else { diff --git a/src/app/mii/[id]/image/route.ts b/src/app/mii/[id]/image/route.ts index ced1e92..4007302 100644 --- a/src/app/mii/[id]/image/route.ts +++ b/src/app/mii/[id]/image/route.ts @@ -12,8 +12,8 @@ import { prisma } from "@/lib/prisma"; const searchParamsSchema = z.object({ type: z - .enum(["mii", "qr-code", "features", "image0", "image1", "image2", "metadata"], { - message: "Image type must be either 'mii', 'qr-code', 'features', 'image[number from 0 to 2]' or 'metadata'", + .enum(["mii", "qr-code", "features", "facepaint", "image0", "image1", "image2", "metadata"], { + message: "Image type must be either 'mii', 'qr-code', 'features', 'facepaint', 'image[number from 0 to 2]' or 'metadata'", }) .default("mii"), }); diff --git a/src/app/mii/[id]/page.tsx b/src/app/mii/[id]/page.tsx index a5ba679..75f6d9b 100644 --- a/src/app/mii/[id]/page.tsx +++ b/src/app/mii/[id]/page.tsx @@ -164,23 +164,13 @@ export default async function MiiPage({ params }: Props) { /> ) : ( - <> - {mii.isFromSaveFile && ( -
-
- Face Paint Texture -
-
- )} - - - + )}
@@ -437,9 +427,9 @@ export default async function MiiPage({ params }: Props) { Gallery - {images.length > 0 ? ( + {images.length > 0 || mii.isFromSaveFile ? (
- {images.map((src, index) => ( + {[...(mii.isFromSaveFile ? [`/mii/${mii.id}/image?type=facepaint`] : []), ...images].map((src, index) => (
(target: T, source: Partial): T { - const output = structuredClone(target); - - if (typeof source !== "object" || source === null) return output; - - for (const key in source) { - const sourceValue = source[key]; - const targetValue = (output as any)[key]; - - if (typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue)) { - (output as any)[key] = deepMerge(targetValue, sourceValue); - } else { - (output as any)[key] = sourceValue; - } - } - - return output; -} - export default function EditForm({ mii, likes }: Props) { const session = useSession(); const [files, setFiles] = useState([]); @@ -387,9 +369,11 @@ export default function EditForm({ mii, likes }: Props) {
- - - + + {!mii.isFromSaveFile && ( + + )} +

You must upload a screenshot of the features, check tutorial on how.

@@ -423,7 +407,7 @@ export default function EditForm({ mii, likes }: Props) {
- + )} diff --git a/src/components/submit-form/index.tsx b/src/components/submit-form/index.tsx index cb2dd8d..1f4f3b2 100644 --- a/src/components/submit-form/index.tsx +++ b/src/components/submit-form/index.tsx @@ -477,8 +477,14 @@ export default function SubmitForm({ inQueueMiisCount }: Props) { + {way === "savedata" && ( +

+ Unfortunately, at this time we can't automatically generate instructions from a .ltd file. +

+ )} + {/* Step 2 - Features */} -
+
2 @@ -544,31 +550,14 @@ export default function SubmitForm({ inQueueMiisCount }: Props) { - {/* YouTube */} -
- - { - const val = e.target.value; - const match = val.match(/(?:youtube\.com\/(?:watch\?v=|shorts\/|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/); - setYouTubeId(match ? match[1] : val); - }} - /> -
+ {way === "savedata" && ( +

Only the v3 format is supported, please make sure ShareMii is up to date.

+ )}
{/* (Switch only) Mii instructions */} -
+

Mii Instructions