fix(installer): fabric 를 .minecraft 에 설치 — 바닐라 라이브러리/버전 누락 해결
근본 원인(실측): fabric-installer 를 -dir .mc_custom 으로 돌리면 .mc_custom 에 versions/ 와 libraries/ 를 실제 폴더로 만드는데 fabric 것만 들어가고 바닐라 버전 JSON·라이브러리는 빠진다. 그러면 .minecraft 로의 링크가 "폴더 있음" 으로 건너뛰어져 런처가 바닐라 데이터를 못 찾고 "Unable to prepare assets for download" 로 실패. (웹 조사 확인: assets/libraries/versions 는 런처 폴더 .minecraft 아래 형제 폴더.) - fabric 을 .minecraft 에 설치(-dir .minecraft)해 바닐라와 같은 위치에 둠. 최신 fabric 버전 폴더에 .jar 이 없어 설치 완료 판정을 .json 존재로 변경. - linkMinecraftRuntimeDirs: 예전 설치가 gameDir 에 만든 불완전한 versions/libraries 실제 폴더를 .minecraft 링크로 교체(관리 데이터라 안전). assets 는 보존. - 문서 갱신. 0.4.21→0.4.22. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1402,11 +1402,19 @@ async function installFabricLoader(pack: PackDefinition, customRoot: string): Pr
|
||||
// 다시 쓰려고 시도해서, 마인크래프트나 다른 프로세스가 그 파일을 잡고
|
||||
// 있으면 FileSystemException 으로 실패한다. 결과 파일이 그대로 있으면
|
||||
// 재실행할 필요가 없으므로 그냥 통과.
|
||||
// fabric 은 .minecraft(런처 폴더)에 설치한다. gameDir(.mc_custom)에 설치하면 fabric 이
|
||||
// versions/ 와 libraries/ 를 거기에 실제 폴더로 만드는데, 이 폴더에는 fabric 자체 것만
|
||||
// 들어가고 바닐라 마인크래프트의 버전 JSON·라이브러리는 빠져 있다. 그러면 .minecraft 로의
|
||||
// 링크가 "이미 폴더 있음" 으로 건너뛰어져, 런처가 바닐라 데이터를 찾지 못하고
|
||||
// "Unable to prepare assets for download" 로 실패한다. 그래서 .minecraft 에 설치해
|
||||
// 바닐라와 같은 위치에 두고, 링크는 뒤(linkMinecraftRuntimeDirs)에서 성공하게 한다.
|
||||
const mcRoot = path.join(getAppDataDir(), '.minecraft')
|
||||
await fsp.mkdir(mcRoot, { recursive: true })
|
||||
const versionId = `fabric-loader-${loaderVersion}-${pack.mcVersion}`
|
||||
const versionDir = path.join(customRoot, 'versions', versionId)
|
||||
const versionJar = path.join(versionDir, `${versionId}.jar`)
|
||||
const versionDir = path.join(mcRoot, 'versions', versionId)
|
||||
const versionJson = path.join(versionDir, `${versionId}.json`)
|
||||
if (fs.existsSync(versionJar) && fs.existsSync(versionJson)) {
|
||||
// 최신 fabric 은 버전 폴더에 .json 만 만든다(.jar 없음). json 존재를 설치 완료 기준으로 본다.
|
||||
if (fs.existsSync(versionJson)) {
|
||||
sendLog(t('log.fabricAlreadyInstalled', { id: versionId, dir: versionDir }))
|
||||
return
|
||||
}
|
||||
@@ -1446,10 +1454,10 @@ async function installFabricLoader(pack: PackDefinition, customRoot: string): Pr
|
||||
'client',
|
||||
'-mcversion', pack.mcVersion,
|
||||
'-loader', loaderVersion,
|
||||
'-dir', customRoot,
|
||||
'-dir', mcRoot,
|
||||
'-noprofile'
|
||||
]
|
||||
sendLog(t('log.fabricInstallStart', { mc: pack.mcVersion, loader: loaderVersion, dir: customRoot }))
|
||||
sendLog(t('log.fabricInstallStart', { mc: pack.mcVersion, loader: loaderVersion, dir: mcRoot }))
|
||||
await runJavaProcess(javaCmd, args)
|
||||
sendLog(t('log.fabricInstallDone'))
|
||||
}
|
||||
@@ -1774,6 +1782,20 @@ async function linkMinecraftRuntimeDirs(customRoot: string): Promise<void> {
|
||||
try { existing = await fsp.lstat(dst) } catch { existing = null }
|
||||
if (existing) {
|
||||
if (existing.isSymbolicLink()) continue // 이미 링크됨
|
||||
// versions/libraries 가 실제 폴더면, 예전 버전이 gameDir 에 fabric 을 설치하며 만든
|
||||
// 불완전한(바닐라 누락) 폴더일 수 있다. .minecraft 의 완전한 데이터로 링크되도록
|
||||
// 교체한다. 이 두 폴더는 런처가 관리하는 데이터라 삭제해도 세이브/리소스팩 같은
|
||||
// 사용자 데이터 손실은 없다. (assets 는 받아둔 에셋 보존을 위해 그대로 둔다.)
|
||||
if (dir === 'versions' || dir === 'libraries') {
|
||||
try {
|
||||
await fsp.rm(dst, { recursive: true, force: true })
|
||||
await fsp.symlink(src, dst, 'junction')
|
||||
sendLog(t('log.runtimeLinkReplaced', { dir }))
|
||||
} catch (err) {
|
||||
sendLog(t('log.runtimeLinkFail', { dir, message: (err as Error).message }))
|
||||
}
|
||||
continue
|
||||
}
|
||||
sendLog(t('log.runtimeDirExists', { dir }))
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user