Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e80933d21e | |||
| df5947f8bb | |||
| 3c404ecd8c |
@@ -241,6 +241,7 @@
|
|||||||
"modDownload": "모드 다운로드: {{file}}",
|
"modDownload": "모드 다운로드: {{file}}",
|
||||||
"skipResourcepack": "resourcepackPath가 비어 있어 리소스팩 다운로드를 건너뜁니다.",
|
"skipResourcepack": "resourcepackPath가 비어 있어 리소스팩 다운로드를 건너뜁니다.",
|
||||||
"resourcepackDownload": "리소스팩 다운로드: {{url}}",
|
"resourcepackDownload": "리소스팩 다운로드: {{url}}",
|
||||||
|
"skipBaseForFinal": "최종 리소스팩이 등록돼 있어 베이스 리소스팩은 건너뜁니다(설치 마지막에 최종 리소스팩만 받음).",
|
||||||
"finalResourcepackDownload": "최종 리소스팩 다운로드: {{url}}",
|
"finalResourcepackDownload": "최종 리소스팩 다운로드: {{url}}",
|
||||||
"finalResourcepackSaved": "최종 리소스팩 저장: {{path}}",
|
"finalResourcepackSaved": "최종 리소스팩 저장: {{path}}",
|
||||||
"serverInstallPath": "서버 설치 경로: {{path}}",
|
"serverInstallPath": "서버 설치 경로: {{path}}",
|
||||||
@@ -289,7 +290,8 @@
|
|||||||
"settingCopyFail": "설정 복사 실패 ({{name}}): {{message}}",
|
"settingCopyFail": "설정 복사 실패 ({{name}}): {{message}}",
|
||||||
"settingCopySummary": "기존 마인크래프트 설정 복사: 새로 복사 {{copied}}개 / 동기화(options 류 덮어쓰기) {{synced}}개 / 보존(이미 존재) {{skipped}}개.",
|
"settingCopySummary": "기존 마인크래프트 설정 복사: 새로 복사 {{copied}}개 / 동기화(options 류 덮어쓰기) {{synced}}개 / 보존(이미 존재) {{skipped}}개.",
|
||||||
"settingCopyError": "기존 설정 복사 중 오류: {{message}}",
|
"settingCopyError": "기존 설정 복사 중 오류: {{message}}",
|
||||||
"runtimeDirMissing": ".minecraft/{{dir}} 가 없습니다. 마인크래프트 런처를 한 번 실행한 뒤 다시 시도해주세요.",
|
"runtimeDirMissing": ".minecraft/{{dir}} 가 없어 공용 링크를 만들 수 없습니다(런처가 이 폴더에 직접 받게 됩니다).",
|
||||||
|
"runtimeDirCreated": ".mc_custom/{{dir}} 폴더를 새로 만들었습니다(런처가 여기에 직접 다운로드).",
|
||||||
"runtimeDirExists": ".mc_custom/{{dir}} 가 실제 폴더로 이미 존재 — 건너뜀.",
|
"runtimeDirExists": ".mc_custom/{{dir}} 가 실제 폴더로 이미 존재 — 건너뜀.",
|
||||||
"runtimeLinkCreated": "링크 생성: .mc_custom/{{dir}} → .minecraft/{{dir}}",
|
"runtimeLinkCreated": "링크 생성: .mc_custom/{{dir}} → .minecraft/{{dir}}",
|
||||||
"runtimeLinkFail": "링크 생성 실패 ({{dir}}): {{message}}",
|
"runtimeLinkFail": "링크 생성 실패 ({{dir}}): {{message}}",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "minecraft-music-quiz-installer",
|
"name": "minecraft-music-quiz-installer",
|
||||||
"version": "0.4.18",
|
"version": "0.4.21",
|
||||||
"description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트",
|
"description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트",
|
||||||
"main": "dist/installer/main.js",
|
"main": "dist/installer/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -285,11 +285,12 @@ ipcMain.handle('finalResourcepack:install', async (): Promise<{ ok: boolean; pat
|
|||||||
if (!pack) return { ok: false, message: t('errors.packNotFound2') }
|
if (!pack) return { ok: false, message: t('errors.packNotFound2') }
|
||||||
const finalName = pack.pack.finalResourcepackPath
|
const finalName = pack.pack.finalResourcepackPath
|
||||||
if (!finalName || finalName === '.') return { ok: false, message: 'no final resourcepack' }
|
if (!finalName || finalName === '.') return { ok: false, message: 'no final resourcepack' }
|
||||||
|
let dest = ''
|
||||||
try {
|
try {
|
||||||
const cleaned = path.basename(finalName.replace(/^\/+/, ''))
|
const cleaned = path.basename(finalName.replace(/^\/+/, ''))
|
||||||
const url = `${state.baseUrl}/file/resourcepacks/outputs/${encodeURIComponent(cleaned)}`
|
const url = `${state.baseUrl}/file/resourcepacks/outputs/${encodeURIComponent(cleaned)}`
|
||||||
const destDir = path.join(getAppDataDir(), getMcCustomDirName(), 'resourcepacks')
|
const destDir = path.join(getAppDataDir(), getMcCustomDirName(), 'resourcepacks')
|
||||||
const dest = path.join(destDir, cleaned)
|
dest = path.join(destDir, cleaned)
|
||||||
await fsp.mkdir(destDir, { recursive: true })
|
await fsp.mkdir(destDir, { recursive: true })
|
||||||
sendLog(t('log.finalResourcepackDownload', { url }))
|
sendLog(t('log.finalResourcepackDownload', { url }))
|
||||||
// 진행률(퍼센트)을 렌더러로 흘려보내며 스트리밍 다운로드.
|
// 진행률(퍼센트)을 렌더러로 흘려보내며 스트리밍 다운로드.
|
||||||
@@ -307,6 +308,8 @@ ipcMain.handle('finalResourcepack:install', async (): Promise<{ ok: boolean; pat
|
|||||||
sendLog(t('log.finalResourcepackSaved', { path: dest }))
|
sendLog(t('log.finalResourcepackSaved', { path: dest }))
|
||||||
return { ok: true, path: dest }
|
return { ok: true, path: dest }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// 실패 시 부분/0바이트 zip 이 마인크래프트 리소스팩 목록에 깨진 채로 남지 않도록 삭제.
|
||||||
|
if (dest) await fsp.rm(dest, { force: true }).catch(() => {})
|
||||||
return { ok: false, message: (error as Error).message }
|
return { ok: false, message: (error as Error).message }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1352,7 +1355,13 @@ ipcMain.handle('client:install', async (_event, payload: ClientInstallPayload) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
await downloadModsFolder(pack.pack, customRoot)
|
await downloadModsFolder(pack.pack, customRoot)
|
||||||
await downloadResourcepackZip(pack.pack, customRoot)
|
// 최종 리소스팩이 등록돼 있으면(finalResourcepackPath !== "."), 완성본을 설치 마지막에
|
||||||
|
// 따로 받으므로 베이스 리소스팩은 받지 않는다("최종 리소스팩만 다운로드").
|
||||||
|
if (pack.pack.finalResourcepackPath && pack.pack.finalResourcepackPath !== '.') {
|
||||||
|
sendLog(t('log.skipBaseForFinal'))
|
||||||
|
} else {
|
||||||
|
await downloadResourcepackZip(pack.pack, customRoot)
|
||||||
|
}
|
||||||
|
|
||||||
if (payload.skipMap) {
|
if (payload.skipMap) {
|
||||||
// 참가자 모드: 이전 설치 흐름에서 설치러가 풀어둔 맵이 있다면 제거한다.
|
// 참가자 모드: 이전 설치 흐름에서 설치러가 풀어둔 맵이 있다면 제거한다.
|
||||||
@@ -1746,7 +1755,19 @@ async function linkMinecraftRuntimeDirs(customRoot: string): Promise<void> {
|
|||||||
const src = path.join(mcRoot, dir)
|
const src = path.join(mcRoot, dir)
|
||||||
const dst = path.join(customRoot, dir)
|
const dst = path.join(customRoot, dir)
|
||||||
if (!fs.existsSync(src)) {
|
if (!fs.existsSync(src)) {
|
||||||
|
// .minecraft 에 원본이 없으면(바닐라를 한 번도 안 받았거나 런처가 다른 위치를 쓰는
|
||||||
|
// 환경) 링크를 만들 수 없다. 이때 그냥 건너뛰면 .mc_custom/<dir> 이 아예 없어
|
||||||
|
// 런처가 "Unable to prepare assets for download" 로 실패한다. 빈 폴더라도 만들어
|
||||||
|
// 런처가 그 gameDir 에 직접 받아갈 수 있게 한다(없을 때만).
|
||||||
sendLog(t('log.runtimeDirMissing', { dir }))
|
sendLog(t('log.runtimeDirMissing', { dir }))
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(dst)) {
|
||||||
|
await fsp.mkdir(dst, { recursive: true })
|
||||||
|
sendLog(t('log.runtimeDirCreated', { dir }))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
sendLog(t('log.runtimeLinkFail', { dir, message: (err as Error).message }))
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let existing: import('node:fs').Stats | null = null
|
let existing: import('node:fs').Stats | null = null
|
||||||
|
|||||||
Reference in New Issue
Block a user