diff --git a/DorkNet.Server/Controllers/Admin/RoomZipImportController.cs b/DorkNet.Server/Controllers/Admin/RoomZipImportController.cs index d1e6ec2..6dff6d8 100644 --- a/DorkNet.Server/Controllers/Admin/RoomZipImportController.cs +++ b/DorkNet.Server/Controllers/Admin/RoomZipImportController.cs @@ -140,6 +140,14 @@ public class RoomZipImportController( { PropertyNameCaseInsensitive = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + // RecNet serializes large snowflake-style IDs (SubRoomId, save IDs) + // as JSON strings to avoid JS 2^53 precision loss, while smaller/older + // IDs stay as raw numbers — and a single SubRooms[] array can mix both + // forms (Showdown's export is numeric for entries 0-17, then string + // from "SD_Archive_120822_Catalyst" on). Allow numeric properties to + // read from either token so the import doesn't crash on the first + // string-encoded ID. + NumberHandling = JsonNumberHandling.AllowReadingFromString, }; // ── RoomDetails.json DTOs ────────────────────────────────────────── diff --git a/DorkNet.Server/admin-ui/src/pages/ImportRoom.tsx b/DorkNet.Server/admin-ui/src/pages/ImportRoom.tsx index 7b62aae..062083a 100644 --- a/DorkNet.Server/admin-ui/src/pages/ImportRoom.tsx +++ b/DorkNet.Server/admin-ui/src/pages/ImportRoom.tsx @@ -95,6 +95,9 @@ interface PreviewRoom { /// release window — see CLIENT_BUILD_CUTOFF. latestModifiedAt: string | null; postBuildCutoff: boolean; + /// True when this room came from a Studio single-room dump (room.json + + /// SubRooms// saves) rather than a standard RoomDetails.json export. + isStudio: boolean; } interface PreviewSubroom { @@ -545,6 +548,11 @@ export function ImportRoom() { {r.name} {r.folder.split('/').pop()} + {r.isStudio && ( + + Studio + + )} {!r.hasImage && no image} {r.postBuildCutoff && ( voi promoImageCount, latestModifiedAt, postBuildCutoff, + isStudio: false, }); bump(); } @@ -1213,6 +1222,7 @@ async function parseZipPreview(file: File, onProgress?: (percent: number) => voi promoImageCount, latestModifiedAt, postBuildCutoff, + isStudio: true, }); bump(); }