installer: options.txt 류는 .mc_custom 으로 매번 덮어쓰기 동기화
기존 copyMinecraftUserSettings 는 .mc_custom 에 같은 이름의 파일이 있으면 무조건 보존했기 때문에, 사용자가 .minecraft 에서 새로 바꾼 키설정·옵션이 .mc_custom 으로 이어지지 못했다. options.txt / optionsof.txt / optionsshaders.txt 는 사용자가 원래 쓰던 설정을 그대로 가져오기 위한 파일이므로 매번 .minecraft 쪽으로 덮어써서 동기화하고, servers.dat 같은 그 외 파일은 종전대로 보존한다.
This commit is contained in:
@@ -263,7 +263,7 @@
|
||||
"launcherProfilesUpdated": "launcher_profiles.json 갱신: 프로필 \"{{profile}}\", gameDir={{dir}}",
|
||||
"minecraftRootMissing": ".minecraft 폴더가 없어 기존 설정 복사를 건너뜁니다.",
|
||||
"settingCopyFail": "설정 복사 실패 ({{name}}): {{message}}",
|
||||
"settingCopySummary": "기존 마인크래프트 설정 복사: 새로 복사 {{copied}}개 / 보존(이미 존재) {{skipped}}개.",
|
||||
"settingCopySummary": "기존 마인크래프트 설정 복사: 새로 복사 {{copied}}개 / 동기화(options 류 덮어쓰기) {{synced}}개 / 보존(이미 존재) {{skipped}}개.",
|
||||
"settingCopyError": "기존 설정 복사 중 오류: {{message}}",
|
||||
"runtimeDirMissing": ".minecraft/{{dir}} 가 없습니다. 마인크래프트 런처를 한 번 실행한 뒤 다시 시도해주세요.",
|
||||
"runtimeDirExists": ".mc_custom/{{dir}} 가 실제 폴더로 이미 존재 — 건너뜀.",
|
||||
|
||||
@@ -1354,9 +1354,18 @@ async function updateLauncherProfile(pack: PackDefinition, gameDir: string): Pro
|
||||
/**
|
||||
* 사용자가 기존에 .minecraft 에 만들어둔 설정 파일들(options.txt, optionsof.txt,
|
||||
* servers.dat, usercache.json 등 최상위 파일 전부)을 .mc_custom 으로 복사한다.
|
||||
* 이미 .mc_custom 에 같은 이름의 파일이 있으면 보존(덮어쓰지 않음).
|
||||
* 기본 규칙은 "이미 .mc_custom 에 같은 이름의 파일이 있으면 보존" 이지만,
|
||||
* ALWAYS_SYNC_FILES 목록에 든 파일(=사용자가 원래 .minecraft 에서 쓰던
|
||||
* 설정을 그대로 이어 쓰고 싶은 옵션 파일들)은 매번 .minecraft 쪽으로
|
||||
* 덮어써서 동기화한다.
|
||||
* 디렉터리(mods/saves/versions/assets 등)는 각자 별도 처리하므로 여기서는 건드리지 않는다.
|
||||
*/
|
||||
const ALWAYS_SYNC_FILES = new Set([
|
||||
'options.txt',
|
||||
'optionsof.txt',
|
||||
'optionsshaders.txt'
|
||||
])
|
||||
|
||||
async function copyMinecraftUserSettings(customRoot: string): Promise<void> {
|
||||
const mcRoot = path.join(getAppDataDir(), '.minecraft')
|
||||
if (!fs.existsSync(mcRoot)) {
|
||||
@@ -1365,24 +1374,28 @@ async function copyMinecraftUserSettings(customRoot: string): Promise<void> {
|
||||
}
|
||||
let copied = 0
|
||||
let skipped = 0
|
||||
let synced = 0
|
||||
try {
|
||||
const entries = await fsp.readdir(mcRoot, { withFileTypes: true })
|
||||
for (const entry of entries) {
|
||||
if (!entry.isFile()) continue
|
||||
const src = path.join(mcRoot, entry.name)
|
||||
const dst = path.join(customRoot, entry.name)
|
||||
if (fs.existsSync(dst)) {
|
||||
const dstExists = fs.existsSync(dst)
|
||||
const alwaysSync = ALWAYS_SYNC_FILES.has(entry.name)
|
||||
if (dstExists && !alwaysSync) {
|
||||
skipped += 1
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await fsp.copyFile(src, dst)
|
||||
copied += 1
|
||||
if (dstExists) synced += 1
|
||||
else copied += 1
|
||||
} catch (err) {
|
||||
sendLog(t('log.settingCopyFail', { name: entry.name, message: (err as Error).message }))
|
||||
}
|
||||
}
|
||||
sendLog(t('log.settingCopySummary', { copied, skipped }))
|
||||
sendLog(t('log.settingCopySummary', { copied, skipped, synced }))
|
||||
} catch (err) {
|
||||
sendLog(t('log.settingCopyError', { message: (err as Error).message }))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user