feat(import): overhauled version importing

This commit is contained in:
DecDuck
2024-12-31 00:04:50 +11:00
parent ccce1cf20d
commit dd001b0f58
9 changed files with 631 additions and 181 deletions
@@ -1,5 +1,6 @@
import prisma from "~/server/internal/db/database";
import libraryManager from "~/server/internal/library";
import { parsePlatform } from "~/server/internal/utils/parseplatform";
export default defineEventHandler(async (h3) => {
const user = await h3.context.session.getAdminUser(h3);
@@ -8,35 +9,32 @@ export default defineEventHandler(async (h3) => {
const body = await readBody(h3);
const gameId = body.id;
const versionName = body.version;
const platform = body.platform;
const startup = body.startup;
const setup = body.setup ?? "";
const delta = body.delta ?? false;
const umuId = body.umuId;
// startup & delta require more complex checking logic
if (!gameId || !versionName || !platform)
const platform = body.platform as string | undefined;
const launch = (body.launch ?? "") as string;
const launchArgs = (body.launchArgs ?? "") as string;
const setup = (body.setup ?? "") as string;
const setupArgs = (body.setupArgs ?? "") as string;
const onlySetup = body.onlySetup ?? (false as boolean);
const delta = (body.delta ?? false) as boolean;
const umuId = (body.umuId ?? "") as string;
if (!gameId || !versionName)
throw createError({
statusCode: 400,
statusMessage:
"ID, version, platform, setup, and startup (if not in update mode) are required.",
statusMessage: "Game ID and version are required.",
});
if (umuId && typeof umuId !== "string")
throw createError({
statusCode: 400,
statusMessage: "If specified, UMU ID must be a string.",
});
if (!platform)
throw createError({ statusCode: 400, statusMessage: "Missing platform." });
if (!delta && !startup)
throw createError({
statusCode: 400,
statusMessage: "Startup executable is required for non-update versions",
});
const platformParsed = parsePlatform(platform);
if (!platformParsed)
throw createError({ statusCode: 400, statusMessage: "Invalid platform." });
if (delta) {
const validOverlayVersions = await prisma.gameVersion.count({
where: { gameId: gameId, platform: platform, delta: false },
where: { gameId: gameId, platform: platformParsed, delta: false },
});
if (validOverlayVersions == 0)
throw createError({
@@ -46,17 +44,39 @@ export default defineEventHandler(async (h3) => {
});
}
const taskId = await libraryManager.importVersion(
gameId,
versionName,
{
platform,
startup,
setup,
umuId,
},
delta
);
if (umuId && typeof umuId !== "string")
throw createError({
statusCode: 400,
statusMessage: "If specified, UMU ID must be a string.",
});
if (onlySetup) {
if (!setup)
throw createError({
statusCode: 400,
statusMessage: 'Setup required in "setup mode".',
});
} else {
if (!delta && !launch)
throw createError({
statusCode: 400,
statusMessage: "Startup executable is required for non-update versions",
});
}
// startup & delta require more complex checking logic
const taskId = await libraryManager.importVersion(gameId, versionName, {
platform,
onlySetup,
launch,
launchArgs,
setup,
setupArgs,
umuId,
delta,
});
if (!taskId)
throw createError({
statusCode: 400,
@@ -15,15 +15,6 @@ export default defineClientEventHandler(async (h3, {}) => {
where: {
gameId: id,
},
select: {
versionIndex: true,
versionName: true,
platform: true,
setupCommand: true,
launchCommand: true,
delta: true,
dropletManifest: true,
},
orderBy: {
versionIndex: "desc", // Latest one first
},
+47 -30
View File
@@ -170,8 +170,9 @@ class LibraryManager {
for (const checkExt of checkExts) {
if (checkExt != ext) continue;
const fuzzyValue = fuzzy(filename, game.mName);
const relative = path.relative(targetDir, file);
options.push({
filename: file,
filename: relative,
platform: platform,
match: fuzzyValue,
});
@@ -180,19 +181,8 @@ class LibraryManager {
}
const sortedOptions = options.sort((a, b) => b.match - a.match);
let startupGuess = "";
let platformGuess = "";
if (sortedOptions.length > 0) {
const finalChoice = sortedOptions[0];
const finalChoiceRelativePath = path.relative(
targetDir,
finalChoice.filename
);
startupGuess = finalChoiceRelativePath;
platformGuess = finalChoice.platform;
}
return { startupGuess, platformGuess };
return sortedOptions;
}
// Checks are done in least to most expensive order
@@ -212,11 +202,16 @@ class LibraryManager {
versionName: string,
metadata: {
platform: string;
onlySetup: boolean;
setup: string;
startup: string;
umuId: string | undefined;
},
delta = false
setupArgs: string;
launch: string;
launchArgs: string;
delta: boolean;
umuId: string;
}
) {
const taskId = `import:${gameId}:${versionName}`;
@@ -264,19 +259,41 @@ class LibraryManager {
});
// Then, create the database object
const version = await prisma.gameVersion.create({
data: {
gameId: gameId,
versionName: versionName,
platform: platform,
setupCommand: metadata.setup,
launchCommand: metadata.startup,
umuIdOverride: metadata.umuId,
dropletManifest: manifest,
versionIndex: currentIndex,
delta: delta,
},
});
if (metadata.onlySetup) {
await prisma.gameVersion.create({
data: {
gameId: gameId,
versionName: versionName,
dropletManifest: manifest,
versionIndex: currentIndex,
delta: metadata.delta,
umuIdOverride: metadata.umuId,
platform: platform,
onlySetup: true,
setupCommand: metadata.setup,
setupArgs: metadata.setupArgs.split(" "),
},
});
} else {
await prisma.gameVersion.create({
data: {
gameId: gameId,
versionName: versionName,
dropletManifest: manifest,
versionIndex: currentIndex,
delta: metadata.delta,
umuIdOverride: metadata.umuId,
platform: platform,
onlySetup: false,
setupCommand: metadata.setup,
setupArgs: metadata.setupArgs.split(" "),
launchCommand: metadata.launch,
launchArgs: metadata.launchArgs.split(" "),
},
});
}
log("Successfully created version!");