Files
koring-launcher/electron/handlers/instance.ts
T
dream_pep 3653e26a09 feat: 发布 v1.2.0 版本,新增多项核心功能
- 引入 electron-updater 实现自动更新功能
- 新增 Java 环境扫描与校验的 IPC 处理逻辑
- 实现离线账号登录功能
- 新增配置变更跨进程广播机制
- 重构游戏启动逻辑,使用主进程内存配置作为唯一权威来源
- 新增界面显示与语言设置的配置页面
- 添加 Windows 平台自动发布 CI 流水线
- 迁移旧版配置/认证文件到用户数据目录
- 修复崩溃日志路径、表单控件等多项 bug
- 重构设置页组件系统统一界面样式
2026-08-28 02:08:12 +08:00

210 lines
6.7 KiB
TypeScript

import electron from 'electron';
import {
createInstance,
listInstances,
getInstanceInfo,
deleteInstance,
updateInstance,
installInstanceGame,
diagnoseInstance,
getMinecraftVersionList,
getForgeVersionList,
getFabricVersionList,
getQuiltVersionList,
scanGameDirectories,
importExistingInstance,
type InstanceRuntime,
type InstanceConfig,
} from '../core/instance';
import { resolveGamePath } from '../core/paths';
const { ipcMain } = electron;
interface WinRef {
mainWindow: electron.BrowserWindow | null;
}
export function registerInstanceHandlers(win: WinRef) {
ipcMain.handle('instance:create', async (_event, payload: {
name: string;
gamePath: string;
runtime: InstanceRuntime;
author?: string;
description?: string;
java?: string;
minMemory?: number;
maxMemory?: number;
vmOptions?: string[];
mcOptions?: string[];
}) => {
try {
const gamePath = resolveGamePath(payload.gamePath);
const data = await createInstance(
payload.name,
gamePath,
payload.runtime,
{
author: payload.author,
description: payload.description,
java: payload.java,
minMemory: payload.minMemory,
maxMemory: payload.maxMemory,
vmOptions: payload.vmOptions,
mcOptions: payload.mcOptions,
}
);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:list', async (_event, payload: { gamePath: string }) => {
try {
const data = await listInstances(resolveGamePath(payload.gamePath));
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:info', async (_event, payload: { name: string; gamePath: string }) => {
try {
const data = await getInstanceInfo(payload.name, resolveGamePath(payload.gamePath));
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:delete', async (_event, payload: { name: string; gamePath: string }) => {
try {
const data = await deleteInstance(payload.name, resolveGamePath(payload.gamePath));
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:update', async (_event, payload: {
name: string;
gamePath: string;
patch: Partial<Omit<InstanceConfig, 'name' | 'creationDate'>>;
}) => {
try {
const data = await updateInstance(payload.name, resolveGamePath(payload.gamePath), payload.patch);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:install', async (_event, payload: { name: string; gamePath: string }) => {
try {
const requestId = `install-${Date.now()}`;
const gamePath = resolveGamePath(payload.gamePath);
installInstanceGame(payload.name, gamePath, {
onProgress: (progress) => {
win.mainWindow?.webContents.send('instance:progress', { requestId, ...progress });
},
}).then((data) => {
win.mainWindow?.webContents.send('instance:install-complete', { requestId, data });
}).catch((err) => {
win.mainWindow?.webContents.send('instance:install-error', { requestId, error: String(err) });
});
return { success: true, data: { requestId }, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:diagnose', async (_event, payload: { name: string; gamePath: string }) => {
try {
const data = await diagnoseInstance(payload.name, resolveGamePath(payload.gamePath));
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// Version list APIs
ipcMain.handle('instance:version-list', async (_event, payload: { type?: string }) => {
try {
const data = await getMinecraftVersionList(payload.type);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:forge-version-list', async (_event, payload: { mcVersion?: string }) => {
try {
const data = await getForgeVersionList(payload.mcVersion);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:fabric-version-list', async (_event, payload: { mcVersion?: string }) => {
try {
const data = await getFabricVersionList(payload.mcVersion);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
ipcMain.handle('instance:quilt-version-list', async (_event, payload: { mcVersion?: string }) => {
try {
const data = await getQuiltVersionList(payload.mcVersion);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 扫描游戏目录中的已安装版本
ipcMain.handle('instance:scan-dir', async (_event, payload: { gamePath: string }) => {
try {
const versions = scanGameDirectories(resolveGamePath(payload.gamePath));
return { success: true, data: { versions }, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
// 从已安装版本导入实例
ipcMain.handle('instance:import', async (_event, payload: {
name: string;
gamePath: string;
versionId: string;
description?: string;
java?: string;
minMemory?: number;
maxMemory?: number;
/** 版本文件来源目录(扫描副目录导入时传扫描目录) */
sourceGamePath?: string;
}) => {
try {
const data = await importExistingInstance(
payload.name,
resolveGamePath(payload.gamePath),
payload.versionId,
{
description: payload.description,
java: payload.java,
minMemory: payload.minMemory,
maxMemory: payload.maxMemory,
sourceGamePath: payload.sourceGamePath ? resolveGamePath(payload.sourceGamePath) : undefined,
}
);
return { success: true, data, error: null };
} catch (e: unknown) {
return { success: false, data: null, error: String(e) };
}
});
}