Files
maqt-desktop/electron/main.js

271 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const electron_1 = require("electron");
const path = __importStar(require("path"));
const child_process_1 = require("child_process");
const fs = __importStar(require("fs"));
// 远程调试端口 — Val 通过 CDP 远程控制窗口
const REMOTE_DEBUG_PORT = 9222;
electron_1.app.commandLine.appendSwitch('remote-debugging-port', String(REMOTE_DEBUG_PORT));
electron_1.app.commandLine.appendSwitch('remote-debugging-address', '0.0.0.0');
let mainWindow = null;
let overlayProcess = null;
let monitorProcess = null;
// --- 工具路径 ---
// 多种可能的路径,适配原版解包和开发环境
function findExe(name) {
const searchPaths = [];
// 开发模式:项目根目录
if (process.env.VITE_DEV_SERVER_URL) {
const devBase = path.join(electron_1.app.getAppPath(), 'resources');
searchPaths.push(path.join(devBase, name));
searchPaths.push(path.join(devBase, 'tools', name));
searchPaths.push(path.join(devBase, 'tools', 'xixi-overlay-helper', name));
searchPaths.push(path.join(process.cwd(), 'resources', name));
searchPaths.push(path.join(process.cwd(), 'resources', 'tools', name));
}
// 生产模式
searchPaths.push(path.join(process.resourcesPath, name));
searchPaths.push(path.join(process.resourcesPath, 'tools', name));
searchPaths.push(path.join(process.resourcesPath, 'tools', 'xixi-overlay-helper', name));
// 额外:直接检查可能的路径
searchPaths.push(path.join(electron_1.app.getAppPath(), 'resources', name));
searchPaths.push(path.join(electron_1.app.getAppPath(), 'resources', 'tools', name));
for (const p of searchPaths) {
const exePath = p.endsWith('.exe') ? p : p + '.exe';
if (fs.existsSync(exePath)) {
console.log('[main] Found:', exePath);
return exePath;
}
if (fs.existsSync(p)) {
console.log('[main] Found:', p);
return p;
}
}
console.warn('[main] NOT found:', name);
return path.join(electron_1.app.getAppPath(), 'resources', 'tools', name); // fallback
}
// --- 窗口 ---
function createWindow() {
mainWindow = new electron_1.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: 系统优化 ===
electron_1.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' },
];
});
electron_1.ipcMain.handle('optimize:item', async (_event, id) => {
try {
const h1Exe = findExe('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' };
}
(0, child_process_1.execSync)(`"${h1Exe}" --optimize "${id}"`, { timeout: 30000 });
return { success: true, id, action: 'optimized' };
}
catch (err) {
return { success: false, id, error: err.message };
}
});
electron_1.ipcMain.handle('optimize:restore', async (_event, id) => {
try {
const h1Exe = findExe('MaqiangTangh1.exe');
if (!fs.existsSync(h1Exe)) {
await new Promise(r => setTimeout(r, 1000));
return { success: true, id, action: 'restored' };
}
(0, child_process_1.execSync)(`"${h1Exe}" --restore "${id}"`, { timeout: 30000 });
return { success: true, id, action: 'restored' };
}
catch (err) {
return { success: false, id, error: err.message };
}
});
// === IPC: XiXi Overlay ===
electron_1.ipcMain.handle('overlay:start', async (_event, options) => {
try {
if (overlayProcess) {
overlayProcess.kill();
overlayProcess = null;
}
const overlayExe = findExe('MaqiangTangXiXiOverlay.exe');
if (!fs.existsSync(overlayExe)) {
return { success: false, error: `Overlay exe not found at ${overlayExe}` };
}
const args = [];
if (options?.gameWindow)
args.push('--game-window', options.gameWindow);
if (options?.opacity)
args.push('--opacity', String(options.opacity));
overlayProcess = (0, child_process_1.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) {
return { success: false, error: err.message };
}
});
electron_1.ipcMain.handle('overlay:stop', async () => {
if (overlayProcess) {
overlayProcess.kill();
overlayProcess = null;
return { success: true };
}
return { success: false, error: 'Overlay not running' };
});
// === IPC: 硬件监控 ===
electron_1.ipcMain.handle('monitor:start', async () => {
try {
if (monitorProcess) {
monitorProcess.kill();
monitorProcess = null;
}
const monExe = findExe('MaqiangTangHardwareMonitor.exe');
if (!fs.existsSync(monExe)) {
return { success: false, error: `Monitor exe not found at ${monExe}` };
}
monitorProcess = (0, child_process_1.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) {
return { success: false, error: err.message };
}
});
electron_1.ipcMain.handle('monitor:stop', async () => {
if (monitorProcess) {
monitorProcess.kill();
monitorProcess = null;
return { success: true };
}
return { success: false, error: 'Monitor not running' };
});
// === IPC: 窗口控制 ===
electron_1.ipcMain.handle('window:minimize', () => mainWindow?.minimize());
electron_1.ipcMain.handle('window:maximize', () => {
if (mainWindow?.isMaximized())
mainWindow.unmaximize();
else
mainWindow?.maximize();
});
electron_1.ipcMain.handle('window:close', () => mainWindow?.close());
// === IPC: 通用 ===
electron_1.ipcMain.handle('get-app-version', () => electron_1.app.getVersion());
electron_1.ipcMain.handle('open-external', async (_event, url) => {
await electron_1.shell.openExternal(url);
});
electron_1.ipcMain.handle('get-resources-path', () => process.resourcesPath);
electron_1.ipcMain.handle('fs:exists', (_event, p) => fs.existsSync(p));
electron_1.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' };
});
// === 应用生命周期 ===
electron_1.app.whenReady().then(createWindow);
electron_1.app.on('window-all-closed', () => {
// 清理子进程
if (overlayProcess)
overlayProcess.kill();
if (monitorProcess)
monitorProcess.kill();
if (process.platform !== 'darwin')
electron_1.app.quit();
});
electron_1.app.on('activate', () => {
if (electron_1.BrowserWindow.getAllWindows().length === 0)
createWindow();
});