diff --git a/package.json b/package.json index ad1e91c..538bfc0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minecraft-music-quiz-installer", - "version": "0.3.5", + "version": "0.3.6", "description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트", "main": "dist/installer/main.js", "scripts": { diff --git a/src/installer-rp/main.ts b/src/installer-rp/main.ts index 8a75e19..ec90f55 100644 --- a/src/installer-rp/main.ts +++ b/src/installer-rp/main.ts @@ -365,6 +365,9 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string async function tryDownloadTrack(i: number, emitErrorProgress: boolean): Promise { const entry = musicList[i] const idx = i + 1 + // 최종 산출물 경로. 실패 시 부분 생성된 파일을 지워, 다음 재시도(이어받기)에서 + // 완성본으로 오인해 건너뛰는 일을 막는다. + const expectedOut = path.join(musicDir, String(idx).padStart(2, '0') + '.ogg') sendLog(t('log.musicTrackStart', { idx })) sendProgress({ phase: 'item', kind: 'music', index: idx, total: musicTotal, percent: 0, status: 'running' }) let child: ChildProcess | null = null @@ -394,6 +397,8 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string return true } catch (err) { if (child) state.activeChildren.delete(child) + // 부분 생성된 .ogg 를 제거(이어받기 시 완성본 오인 방지). + await fsp.rm(expectedOut, { force: true }).catch(() => {}) if (state.cancelRequested) { sendProgress({ phase: 'item', kind: 'music', index: idx, total: musicTotal, percent: 0, status: 'error', message: t('progress.cancelled') }) return false @@ -483,15 +488,19 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string try { buf = await downloadImage(entry.url) } catch (err) { + // 부분 생성됐을 수 있는 커버 파일 제거(이어받기 시 완성본 오인 방지). + await fsp.rm(coverPath, { force: true }).catch(() => {}) sendProgress({ phase: 'item', kind: 'image', index: idx, total: imageTotal, percent: 0, status: 'error', message: (err as Error).message }) throw new Error(t('errors.imageDownloadFailed', { idx, message: (err as Error).message })) } throwIfCancelled() sendProgress({ phase: 'item', kind: 'image', index: idx, total: imageTotal, percent: 60, status: 'running' }) - const outPath = path.join(paintingDir, coverFileName(idx)) + const outPath = coverPath try { await normalizeToCover(buf, outPath) } catch (err) { + // 변환 중 부분 생성된 PNG 제거(이어받기 시 완성본 오인 방지). + await fsp.rm(coverPath, { force: true }).catch(() => {}) sendProgress({ phase: 'item', kind: 'image', index: idx, total: imageTotal, percent: 0, status: 'error', message: (err as Error).message }) throw new Error(t('errors.imageNormalizeFailed', { idx, message: (err as Error).message })) }