Files
minecraft_launcher/src/installer/preload.ts
claude-bot e30d7418df feat(installer): 최종 리소스팩 다운로드 진행률(퍼센트) 표시
"예" 선택 후 최종 리소스팩 다운로드 시 퍼센트/진행바를 보여준다.
- finalResourcepack:install 을 downloadFile → downloadStream 으로 바꿔 content-length
  기반 진행률을 계산하고 finalResourcepack:progress 이벤트로 렌더러에 전송.
- preload onFinalResourcepackProgress 구독 추가, 렌더러에 진행바+% 표시(완료 100%,
  실패 시 바 숨김). 0.4.17→0.4.18.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-27 00:11:19 +09:00

96 lines
4.5 KiB
TypeScript

import { contextBridge, ipcRenderer } from 'electron'
import type { ClientInstallPayload, FetchedPack, RamCheckResult, ServerInstallPayload, PortForwardResult } from './types.js'
const api = {
// i18n
loadLocale: (): Promise<Record<string, unknown>> => ipcRenderer.invoke('i18n:dict'),
// 1단계
loadPacks: (manifestUrl?: string): Promise<FetchedPack[]> =>
ipcRenderer.invoke('packs:load', manifestUrl),
setSelectedPack: (packKey: string): Promise<void> =>
ipcRenderer.invoke('packs:select', packKey),
// 약관(Markdown) 다운로드
getTerm: (kind: string): Promise<{ ok: boolean; content?: string; message?: string }> =>
ipcRenderer.invoke('terms:get', kind),
// 메인 인스톨러용 약관 목록 (사이트의 visibility 토글에 따라 필터링됨)
getTermsList: (): Promise<{ ok: boolean; terms?: Array<{ kind: string; label: string }>; message?: string }> =>
ipcRenderer.invoke('terms:list'),
// 최종 리소스팩 다운로드용 약관 목록 (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 }> =>
ipcRenderer.invoke('finalResourcepack:install'),
// 3-1
pickFolder: (): Promise<string | null> => ipcRenderer.invoke('dialog:pickFolder'),
validateInstallPath: (target: string): Promise<{ ok: boolean; message?: string }> =>
ipcRenderer.invoke('install:validatePath', target),
// 3-2
detectJdk: (recommendedJdk?: number): Promise<{ found: boolean; path: string; major: number; match: boolean }> =>
ipcRenderer.invoke('jdk:detect', recommendedJdk),
verifyJdk: (jdkPath: string, recommendedJdk?: number): Promise<{ ok: boolean; major: number; required: number; match: boolean }> =>
ipcRenderer.invoke('jdk:verify', jdkPath, recommendedJdk),
installJdk: (recommendedJdk?: number): Promise<{ ok: boolean; path?: string; message?: string }> =>
ipcRenderer.invoke('jdk:install', recommendedJdk),
cancelJdkInstall: (): Promise<{ ok: boolean }> => ipcRenderer.invoke('jdk:cancelInstall'),
// 3-3
startServerInstall: (payload: ServerInstallPayload): Promise<void> =>
ipcRenderer.invoke('server:install', payload),
readEula: (installPath: string): Promise<{ exists: boolean; content: string }> =>
ipcRenderer.invoke('server:readEula', installPath),
fetchMinecraftEula: (): Promise<{ url: string; html: string }> =>
ipcRenderer.invoke('server:fetchMinecraftEula'),
acceptEula: (installPath: string): Promise<void> =>
ipcRenderer.invoke('server:acceptEula', installPath),
checkRam: (packKey: string): Promise<RamCheckResult> =>
ipcRenderer.invoke('server:checkRam', packKey),
// 3-4
startServerConfigEditor: (installPath: string): Promise<{ url: string }> =>
ipcRenderer.invoke('server:configEditor', installPath),
// 3-5
checkPortForward: (port: number): Promise<PortForwardResult> =>
ipcRenderer.invoke('server:portForward', port),
// 4단계
installClient: (payload: ClientInstallPayload): Promise<void> =>
ipcRenderer.invoke('client:install', payload),
// 5단계
openServerFolder: (): Promise<void> => ipcRenderer.invoke('finish:openServerFolder'),
createDesktopShortcut: (): Promise<void> => ipcRenderer.invoke('finish:desktopShortcut'),
startServer: (): Promise<void> => ipcRenderer.invoke('finish:startServer'),
startMinecraftLauncher: (): Promise<void> => ipcRenderer.invoke('finish:startLauncher'),
quitApp: (): Promise<void> => ipcRenderer.invoke('app:quit'),
// log stream
onLog: (handler: (line: string) => void): (() => void) => {
const listener = (_event: unknown, line: string) => handler(line)
ipcRenderer.on('log', listener)
return () => ipcRenderer.removeListener('log', listener)
},
// 최종 리소스팩 다운로드 진행률 구독. 반환값을 호출하면 구독 해제.
onFinalResourcepackProgress: (
handler: (info: { loaded: number; total: number; percent: number }) => void
): (() => void) => {
const listener = (_event: unknown, info: { loaded: number; total: number; percent: number }) => handler(info)
ipcRenderer.on('finalResourcepack:progress', listener)
return () => ipcRenderer.removeListener('finalResourcepack:progress', listener)
}
}
contextBridge.exposeInMainWorld('installer', api)
declare global {
interface Window {
installer: typeof api
}
}