import { app, BrowserWindow, ipcMain, shell } from 'electron'; import * as path from 'path'; import { spawn, execSync, ChildProcess } from 'child_process'; import * as fs from 'fs'; // 远程调试端口 — Val 通过 CDP 远程控制窗口 const REMOTE_DEBUG_PORT = 9222; app.commandLine.appendSwitch('remote-debugging-port', String(REMOTE_DEBUG_PORT)); app.commandLine.appendSwitch('remote-debugging-address', '0.0.0.0'); let mainWindow: BrowserWindow | null = null; let overlayProcess: ChildProcess | null = null; let monitorProcess: ChildProcess | null = null; // --- 工具路径 --- function getToolsDir(): string { // 开发模式:exe 在项目根目录下的 resources/tools/ if (process.env.VITE_DEV_SERVER_URL) { const devPath = path.join(app.getAppPath(), 'resources', 'tools'); if (fs.existsSync(devPath)) return devPath; // 备选:当前目录的 resources/tools/ const cwdPath = path.join(process.cwd(), 'resources', 'tools'); if (fs.existsSync(cwdPath)) return cwdPath; } // 生产模式:exe 在 resources/tools/ 下 return path.join(process.resourcesPath, 'tools'); } function exePath(name: string): string { return path.join(getToolsDir(), name); } // --- 窗口 --- function createWindow() { mainWindow = new BrowserWindow({ width: 1400, height: 900, minWidth: 1100, minHeight: 700, frame: false, transparent: false, backgroundColor: '#1a1a1a', webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false, devTools: true, }, }); // 优先从 VITE_DEV_SERVER_URL 加载,否则尝试 localhost:5173,最后用 dist 文件 const devUrl = process.env.VITE_DEV_SERVER_URL || 'http://localhost:5173'; // 尝试加载 dev server mainWindow.loadURL(devUrl).catch(() => { console.log('[main] Dev server not available, loading dist...'); mainWindow?.loadFile(path.join(__dirname, '../dist/index.html')); }); mainWindow.webContents.openDevTools({ mode: 'detach' }); } // === IPC: 系统优化 === ipcMain.handle('optimize:list', async () => { // 返回所有优化项及其当前状态 return [ { id: 'hyperv', label: '关闭 Hyper-V', status: 'pending' }, { id: 'services', label: '系统服务优化', status: 'pending' }, { id: 'hpet-perf', label: 'HPET 高性能模式', status: 'pending' }, { id: 'hpet-comp', label: 'HPET 兼容模式', status: 'pending' }, { id: 'power-plan', label: '卓越性能电源计划', status: 'pending' }, { id: 'ntfs', label: 'NTFS 优化', status: 'pending' }, { id: 'memory', label: '内存区域优化', status: 'pending' }, { id: 'gpu-sched', label: 'GPU 硬件加速调度', status: 'pending' }, { id: 'game-bar', label: '关闭游戏栏', status: 'pending' }, { id: 'mouse-accel', label: '关闭鼠标加速', status: 'pending' }, ]; }); ipcMain.handle('optimize:item', async (_event, id: string) => { try { const h1Exe = exePath('MaqiangTangh1.exe'); if (!fs.existsSync(h1Exe)) { console.warn(`[optimize] h1.exe not found at ${h1Exe}, using simulation`); await new Promise(r => setTimeout(r, 1000)); return { success: true, id, action: 'optimized' }; } execSync(`"${h1Exe}" --optimize "${id}"`, { timeout: 30000 }); return { success: true, id, action: 'optimized' }; } catch (err: any) { return { success: false, id, error: err.message }; } }); ipcMain.handle('optimize:restore', async (_event, id: string) => { try { const h1Exe = exePath('MaqiangTangh1.exe'); if (!fs.existsSync(h1Exe)) { await new Promise(r => setTimeout(r, 1000)); return { success: true, id, action: 'restored' }; } execSync(`"${h1Exe}" --restore "${id}"`, { timeout: 30000 }); return { success: true, id, action: 'restored' }; } catch (err: any) { return { success: false, id, error: err.message }; } }); // === IPC: XiXi Overlay === ipcMain.handle('overlay:start', async (_event, options?: any) => { try { if (overlayProcess) { overlayProcess.kill(); overlayProcess = null; } const overlayExe = exePath('MaqiangTangXiXiOverlay.exe'); if (!fs.existsSync(overlayExe)) { return { success: false, error: `Overlay exe not found at ${overlayExe}` }; } const args: string[] = []; if (options?.gameWindow) args.push('--game-window', options.gameWindow); if (options?.opacity) args.push('--opacity', String(options.opacity)); overlayProcess = spawn(overlayExe, args, { cwd: path.dirname(overlayExe), detached: false, }); overlayProcess.on('exit', (code) => { console.log(`[overlay] exited with code ${code}`); overlayProcess = null; }); return { success: true, pid: overlayProcess.pid }; } catch (err: any) { return { success: false, error: err.message }; } }); ipcMain.handle('overlay:stop', async () => { if (overlayProcess) { overlayProcess.kill(); overlayProcess = null; return { success: true }; } return { success: false, error: 'Overlay not running' }; }); // === IPC: 硬件监控 === ipcMain.handle('monitor:start', async () => { try { if (monitorProcess) { monitorProcess.kill(); monitorProcess = null; } const monExe = exePath('MaqiangTangHardwareMonitor.exe'); if (!fs.existsSync(monExe)) { return { success: false, error: `Monitor exe not found at ${monExe}` }; } monitorProcess = spawn(monExe, [], { cwd: path.dirname(monExe), stdio: ['ignore', 'pipe', 'pipe'], }); monitorProcess.stdout?.on('data', (data) => { // 将硬件数据转发到渲染进程 if (mainWindow && !mainWindow.isDestroyed()) { try { const sensors = JSON.parse(data.toString()); mainWindow.webContents.send('monitor:data', sensors); } catch { /* 非 JSON 数据忽略 */ } } }); monitorProcess.on('exit', (code) => { console.log(`[monitor] exited with code ${code}`); monitorProcess = null; }); return { success: true, pid: monitorProcess.pid }; } catch (err: any) { return { success: false, error: err.message }; } }); ipcMain.handle('monitor:stop', async () => { if (monitorProcess) { monitorProcess.kill(); monitorProcess = null; return { success: true }; } return { success: false, error: 'Monitor not running' }; }); // === IPC: 窗口控制 === ipcMain.handle('window:minimize', () => mainWindow?.minimize()); ipcMain.handle('window:maximize', () => { if (mainWindow?.isMaximized()) mainWindow.unmaximize(); else mainWindow?.maximize(); }); ipcMain.handle('window:close', () => mainWindow?.close()); // === IPC: 通用 === ipcMain.handle('get-app-version', () => app.getVersion()); ipcMain.handle('open-external', async (_event, url: string) => { await shell.openExternal(url); }); ipcMain.handle('get-resources-path', () => process.resourcesPath); ipcMain.handle('fs:exists', (_event, p: string) => fs.existsSync(p)); ipcMain.handle('app:screenshot', async () => { if (mainWindow && !mainWindow.isDestroyed()) { const img = await mainWindow.webContents.capturePage(); return { success: true, data: img.toPNG().toString('base64') }; } return { success: false, error: 'No window' }; }); // === 应用生命周期 === app.whenReady().then(createWindow); app.on('window-all-closed', () => { // 清理子进程 if (overlayProcess) overlayProcess.kill(); if (monitorProcess) monitorProcess.kill(); if (process.platform !== 'darwin') app.quit(); }); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });