Compare commits

...

2 Commits

Author SHA1 Message Date
a8698ef394 fix(installer): 자바 못 찾을 때(ENOENT) "바닐라 먼저 실행" 안내 + JDK 추가 탐색
원인: findJavaExecutable 이 JAVA_HOME → .minecraft/runtime(런처 번들 JRE, 바닐라를
한 번 실행해야 생김) → 폴백 "java.exe" 순이라, 바닐라 미실행 + 시스템 java 없음이면
fabric-installer 실행에서 spawn java.exe ENOENT 로 실패.

- findJavaExecutable 에 설치기 자동설치 JDK(.mc_custom/jdk) 와 C:\Program Files\Java
  탐색을 추가해 불필요한 실패를 줄인다(fabric 실행엔 아무 자바나 됨).
- 그래도 자바가 전혀 없어 ENOENT 면, "먼저 [버전] 바닐라를 한 번 실행해 자바 런타임을
  받은 뒤 다시 시도" 안내 메시지로 바꿔 던진다. 0.4.24→0.4.25.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-10 23:08:13 +09:00
80059d6696 fix(installer): 최종 리소스팩 자동 적용 실패를 UI 에 경고
options.txt 자동 적용이 실패하면(권한/잠금/손상 등) 예전엔 성공처럼 "자동 적용됩니다"
로 보였다. 이제 finalResourcepack:install 이 applied=false 를 반환하고, 렌더러가
"받았지만 자동 적용 실패 — 직접 켜주세요" 경고를 표시한다(다운로드 자체는 성공). 0.4.23→0.4.24.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-28 22:36:57 +09:00
5 changed files with 41 additions and 10 deletions

View File

@@ -1167,8 +1167,14 @@ function downloadFinalResourcepack() {
if (res && res.ok) {
bar.style.width = '100%'
percentEl.textContent = '100%'
if (res.applied === false) {
// 다운로드는 됐지만 자동 적용(options.txt) 실패 → 직접 켜라고 경고.
msg.textContent = tt('resourcepack.downloadDoneNotApplied', { message: res.applyMessage || '' })
msg.classList.add('error')
} else {
msg.textContent = tt('resourcepack.downloadDone')
msg.classList.add('success')
}
actions.innerHTML = '<button class="primaryBtn" id="rpNext">' + tt('common.next') + '</button>'
actions.querySelector('#rpNext').addEventListener('click', proceed)
} else {

View File

@@ -168,6 +168,7 @@
"downloadHeading": "최종 리소스팩 다운로드",
"downloading": "최종 리소스팩을 다운로드하는 중…",
"downloadDone": "최종 리소스팩 다운로드 완료. 마인크래프트를 켜면 자동으로 적용됩니다.",
"downloadDoneNotApplied": "최종 리소스팩은 받았지만 자동 적용에 실패했습니다({{message}}). 마인크래프트 설정 → 리소스팩에서 직접 켜주세요.",
"downloadFailed": "최종 리소스팩 다운로드 실패: {{message}}"
},
"step5": {
@@ -207,6 +208,7 @@
"jdkBusy": "이미 JDK 설치가 진행 중입니다.",
"javaExeMissing": "설치 후 java 실행 파일을 찾지 못했습니다: {{path}}",
"javaSpawnFailed": "Java 실행 실패: {{message}}",
"javaNotFoundRunVanilla": "자바를 찾지 못해 설치를 진행할 수 없습니다. 먼저 마인크래프트 런처에서 [{{version}}] 바닐라를 한 번 실행해 자바 런타임을 받은 다음, 이 설치기를 다시 시도해 주세요.",
"fabricInstallerExit": "fabric-installer 종료 코드 {{code}}{{detail}}",
"fabricLoaderRequired": "Fabric 로더 버전이 음악퀴즈에 지정되지 않았습니다. 관리 사이트에서 platform.loaderVersion 을 설정해 주세요.",
"fabricInstallerListEmpty": "Fabric installer 목록을 받지 못했습니다.",

View File

@@ -1,6 +1,6 @@
{
"name": "minecraft-music-quiz-installer",
"version": "0.4.23",
"version": "0.4.25",
"description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트",
"main": "dist/installer/main.js",
"scripts": {

View File

@@ -280,7 +280,7 @@ ipcMain.handle('terms:listFinal', async (): Promise<{ ok: boolean; terms?: Array
})
// 최종 리소스팩(zip)을 /file/resourcepacks/outputs/ 에서 받아 .mc_custom/resourcepacks/ 에 저장.
ipcMain.handle('finalResourcepack:install', async (): Promise<{ ok: boolean; path?: string; message?: string }> => {
ipcMain.handle('finalResourcepack:install', async (): Promise<{ ok: boolean; path?: string; message?: string; applied?: boolean; applyMessage?: string }> => {
const pack = state.selectedKey ? state.packs.get(state.selectedKey) : undefined
if (!pack) return { ok: false, message: t('errors.packNotFound2') }
const finalName = pack.pack.finalResourcepackPath
@@ -311,10 +311,14 @@ ipcMain.handle('finalResourcepack:install', async (): Promise<{ ok: boolean; pat
try {
await enableResourcePackInOptions(gameDir, cleaned)
sendLog(t('log.finalResourcepackApplied', { name: cleaned }))
return { ok: true, path: dest, applied: true }
} catch (err) {
sendLog(t('log.finalResourcepackApplyFail', { message: (err as Error).message }))
// 다운로드는 됐지만 자동 적용(options.txt)에 실패 → 성공으로 숨기지 말고 렌더러가
// 경고를 띄우도록 applied=false 로 알린다(사용자가 직접 켤 수 있게).
const msg = (err as Error).message
sendLog(t('log.finalResourcepackApplyFail', { message: msg }))
return { ok: true, path: dest, applied: false, applyMessage: msg }
}
return { ok: true, path: dest }
} catch (error) {
// 실패 시 부분/0바이트 zip 이 마인크래프트 리소스팩 목록에 깨진 채로 남지 않도록 삭제.
if (dest) await fsp.rm(dest, { force: true }).catch(() => {})
@@ -1514,7 +1518,17 @@ async function installFabricLoader(pack: PackDefinition, customRoot: string): Pr
'-noprofile'
]
sendLog(t('log.fabricInstallStart', { mc: pack.mcVersion, loader: loaderVersion, dir: mcRoot }))
try {
await runJavaProcess(javaCmd, args)
} catch (err) {
// 자바를 못 찾아 spawn ENOENT 면, 대개 바닐라를 한 번도 실행하지 않아 런처 자바 런타임
// (.minecraft/runtime)이 없고 다른 자바도 없는 경우다. 해당 버전으로 마인크래프트를 먼저
// 실행하라고 안내한다.
if (/ENOENT/i.test((err as Error).message)) {
throw new Error(t('errors.javaNotFoundRunVanilla', { version: pack.mcVersion }))
}
throw err
}
sendLog(t('log.fabricInstallDone'))
}
@@ -1566,7 +1580,16 @@ async function findJavaExecutable(): Promise<string> {
// skip
}
// 3) PATH 폴백.
// 3) 설치기가 자동 설치한 JDK(.mc_custom/jdk) 또는 시스템 JDK(C:\Program Files\Java).
// fabric-installer 실행에는 아무 자바나 되므로(버전 무관) 있으면 그대로 쓴다.
for (const base of [path.join(getAppDataDir(), getMcCustomDirName(), 'jdk'), 'C:\\Program Files\\Java']) {
for (const home of jdkHomesUnder(base)) {
const exe = path.join(home, 'bin', javaName)
if (fs.existsSync(exe)) return exe
}
}
// 4) PATH 폴백.
return javaName
}

View File

@@ -20,8 +20,8 @@ const api = {
// 최종 리소스팩 다운로드용 약관 목록 (showInFinalResourcepack 필터)
getFinalTermsList: (): Promise<{ ok: boolean; terms?: Array<{ kind: string; label: string }>; message?: string }> =>
ipcRenderer.invoke('terms:listFinal'),
// 최종 리소스팩 다운로드 실행
installFinalResourcepack: (): Promise<{ ok: boolean; path?: string; message?: string }> =>
// 최종 리소스팩 다운로드 실행. applied=false 면 다운로드는 됐지만 자동 적용 실패.
installFinalResourcepack: (): Promise<{ ok: boolean; path?: string; message?: string; applied?: boolean; applyMessage?: string }> =>
ipcRenderer.invoke('finalResourcepack:install'),
// 3-1