feat(server): 권장 JDK 탐색을 PF/환경변수 중심으로 + 불일치 경고 + .mc_custom/jdk 설치

- JDK 탐색을 C:\Program Files\Java → 환경변수(JAVA_HOME/JDK_HOME) → 설치기
  자동설치 위치 순으로 훑어 권장 버전을 우선 선택. 권장이 없으면 가장 높은 버전을
  대신 고르되 match=false 로 표시.
- 권장과 다른 버전을 찾거나 직접 선택하면 "권장과 달라 정상 실행이 안 될 수 있음"
  경고를 띄우고, 동의(확인) 시에만 진행(무조건 차단 대신 경고+동의).
- 자동 설치 경로를 %APPDATA%/jdk → .mc_custom/jdk 로 변경(파일제거기가 함께 정리).
  Adoptium zip 의 중첩 jdk-* 폴더까지 탐색하도록 resolveJdkHome 보강.
- 버전 0.4.6→0.4.7.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 12:13:33 +09:00
parent a1d8435b71
commit 9d9b5183b8
5 changed files with 115 additions and 51 deletions

View File

@@ -641,13 +641,17 @@ function renderSubStep32(host, back, done) {
autoBtn.addEventListener('click', async function () {
if (installing) return
var detect = await installerApi.detectJdk(recommendedJdk)
if (detect.found) {
if (detect.found && detect.match) {
input.value = detect.path
msg.textContent = detect.source === 'recommended'
? tt('step3.sub32.foundRecommended', { path: detect.path, major: recommendedJdk })
: tt('step3.sub32.found', { path: detect.path })
msg.textContent = tt('step3.sub32.foundRecommended', { path: detect.path, major: recommendedJdk })
msg.classList.remove('error')
msg.classList.add('success')
} else if (detect.found) {
// 권장 버전이 아닌 다른 JDK 를 찾음 → 경고와 함께 채워 넣는다.
input.value = detect.path
msg.textContent = tt('step3.sub32.foundMismatch', { path: detect.path, major: detect.major, required: recommendedJdk })
msg.classList.remove('success')
msg.classList.add('error')
} else {
msg.textContent = tt('step3.sub32.notFound', { major: recommendedJdk })
msg.classList.remove('success')
@@ -703,21 +707,31 @@ function renderSubStep32(host, back, done) {
msg.classList.add('error')
return
}
// 직접 입력/선택한 JDK 도 서버 실행에 충분한 버전(Java 25+)인지 검증한다.
// 너무 낮으면 run.bat 이 그 자바를 써도 UnsupportedClassVersionError 로 서버가 안 뜬다.
// 직접 입력/선택한 JDK 를 확인한다. 자바를 못 읽으면 진행을 막고, 권장과 다른
// 버전이면 "정상 실행이 안 될 수 있다"는 경고를 띄운 뒤 사용자가 동의하면 진행한다.
nextBtn.disabled = true
msg.classList.remove('success', 'error')
msg.textContent = tt('step3.sub32.verifying')
var required = recommendedJdk
try {
var v = await installerApi.verifyJdk(val, recommendedJdk)
if (!v || !v.ok) {
required = (v && v.required) || recommendedJdk
if (!v || !v.major) {
msg.classList.add('error')
msg.textContent = (v && v.major)
? tt('step3.sub32.versionTooLow', { major: v.major, required: (v && v.required) || recommendedJdk })
: tt('step3.sub32.versionUnknown')
msg.textContent = tt('step3.sub32.versionUnknown')
nextBtn.disabled = false
return
}
if (!v.match) {
// 권장 버전과 다름 → 경고 후 동의 시에만 계속.
var proceed = window.confirm(tt('step3.sub32.mismatchConfirm', { major: v.major, required: required }))
if (!proceed) {
msg.classList.add('error')
msg.textContent = tt('step3.sub32.foundMismatch', { path: val, major: v.major, required: required })
nextBtn.disabled = false
return
}
}
} catch (err) {
msg.classList.add('error')
msg.textContent = tt('step3.sub32.versionUnknown')
@@ -732,10 +746,13 @@ function renderSubStep32(host, back, done) {
var detect = await installerApi.detectJdk(recommendedJdk)
if (detect.found && !input.value) {
input.value = detect.path
msg.textContent = detect.source === 'recommended'
? tt('step3.sub32.foundRecommended', { path: detect.path, major: recommendedJdk })
: tt('step3.sub32.autoDetected', { path: detect.path })
msg.classList.add('success')
if (detect.match) {
msg.textContent = tt('step3.sub32.foundRecommended', { path: detect.path, major: recommendedJdk })
msg.classList.add('success')
} else {
msg.textContent = tt('step3.sub32.foundMismatch', { path: detect.path, major: detect.major, required: recommendedJdk })
msg.classList.add('error')
}
} else if (!detect.found) {
msg.textContent = tt('step3.sub32.notFoundHint', { major: recommendedJdk })
}