diff --git a/package.json b/package.json index 3867215..6ca7103 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minecraft-music-quiz-installer", - "version": "0.2.2", + "version": "0.2.3", "description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트", "main": "dist/installer/main.js", "scripts": { diff --git a/src/installer/main.ts b/src/installer/main.ts index 6dd8228..6511f7b 100644 --- a/src/installer/main.ts +++ b/src/installer/main.ts @@ -1128,46 +1128,49 @@ ipcMain.handle('client:install', async (_event, payload: ClientInstallPayload) = await fsp.mkdir(path.join(customRoot, 'mods'), { recursive: true }) await fsp.mkdir(path.join(customRoot, 'resourcepacks'), { recursive: true }) - // 사용자가 기존 .minecraft 에 저장해둔 설정(options.txt, servers.dat 등)을 - // .mc_custom 으로 가져온다. 이미 있는 파일은 보존. - await copyMinecraftUserSettings(customRoot) + try { + // 사용자가 기존 .minecraft 에 저장해둔 설정(options.txt, servers.dat 등)을 + // .mc_custom 으로 가져온다. 이미 있는 파일은 보존. + await copyMinecraftUserSettings(customRoot) - if (payload.installPlatform && pack.pack.platform.type === 'fabric') { - await installFabricLoader(pack.pack, customRoot) - } else if (payload.installPlatform && pack.pack.platform.type !== 'vanilla' && pack.pack.platform.downloadUrl) { - const platformUrl = resolveManifestRelative(pack.pack.platform.downloadUrl, 'platforms') - const cacheDir = path.join(customRoot, 'platform-cache') - await fsp.mkdir(cacheDir, { recursive: true }) - const installerPath = path.join(cacheDir, deriveFileName(platformUrl) || 'platform-installer.jar') - sendLog(t('log.platformDownload', { type: pack.pack.platform.type, url: platformUrl })) - await downloadFile(platformUrl, installerPath) - sendLog(t('log.platformSaved', { path: installerPath })) - } else if (!payload.installPlatform) { - sendLog(t('log.platformSkipped')) + if (payload.installPlatform && pack.pack.platform.type === 'fabric') { + await installFabricLoader(pack.pack, customRoot) + } else if (payload.installPlatform && pack.pack.platform.type !== 'vanilla' && pack.pack.platform.downloadUrl) { + const platformUrl = resolveManifestRelative(pack.pack.platform.downloadUrl, 'platforms') + const cacheDir = path.join(customRoot, 'platform-cache') + await fsp.mkdir(cacheDir, { recursive: true }) + const installerPath = path.join(cacheDir, deriveFileName(platformUrl) || 'platform-installer.jar') + sendLog(t('log.platformDownload', { type: pack.pack.platform.type, url: platformUrl })) + await downloadFile(platformUrl, installerPath) + sendLog(t('log.platformSaved', { path: installerPath })) + } else if (!payload.installPlatform) { + sendLog(t('log.platformSkipped')) + } + + await downloadModsFolder(pack.pack, customRoot) + await downloadResourcepackZip(pack.pack, customRoot) + + if (payload.skipMap) { + // 참가자 모드: 이전 설치 흐름에서 설치러가 풀어둔 맵이 있다면 제거한다. + // 사용자가 직접 만든 월드는 마커에 포함되지 않으므로 그대로 보존된다. + await cleanupInstallerMap(customRoot) + sendLog(t('log.skipMapZip')) + } else { + await downloadMapZip(pack.pack, customRoot) + } + + // 런처가 .mc_custom 을 gameDir 로 잡아도 assets/libraries/versions 를 + // 찾을 수 있도록 .minecraft 의 해당 폴더로 junction 링크. + await linkMinecraftRuntimeDirs(customRoot) + + await updateLauncherProfile(pack.pack, customRoot) + } finally { + // 설치가 끝나면(또는 실패해도) 더 이상 필요 없는 platform-cache(다운받은 + // fabric/forge/neoforge installer jar 캐시)를 삭제한다. 다음 실행에서 다시 + // 받으면 되고, 남겨두면 사용자 .mc_custom 폴더만 차지한다. 실패 경로에서도 + // 정리되도록 finally 에 둔다. + await fsp.rm(path.join(customRoot, 'platform-cache'), { recursive: true, force: true }).catch(() => {}) } - - await downloadModsFolder(pack.pack, customRoot) - await downloadResourcepackZip(pack.pack, customRoot) - - if (payload.skipMap) { - // 참가자 모드: 이전 설치 흐름에서 설치러가 풀어둔 맵이 있다면 제거한다. - // 사용자가 직접 만든 월드는 마커에 포함되지 않으므로 그대로 보존된다. - await cleanupInstallerMap(customRoot) - sendLog(t('log.skipMapZip')) - } else { - await downloadMapZip(pack.pack, customRoot) - } - - // 런처가 .mc_custom 을 gameDir 로 잡아도 assets/libraries/versions 를 - // 찾을 수 있도록 .minecraft 의 해당 폴더로 junction 링크. - await linkMinecraftRuntimeDirs(customRoot) - - await updateLauncherProfile(pack.pack, customRoot) - - // 설치가 끝나면 더 이상 필요 없는 platform-cache(다운받은 fabric/forge/neoforge - // installer jar 캐시)를 삭제한다. 다음 실행에서 다시 받으면 되고, 남겨두면 - // 사용자 .mc_custom 폴더만 차지한다. - await fsp.rm(path.join(customRoot, 'platform-cache'), { recursive: true, force: true }).catch(() => {}) }) interface FabricInstallerMeta {