import { app, dialog, ipcMain } from 'electron' import { mihomoChangeProxy, mihomoCloseAllConnections, mihomoCloseConnection, mihomoGroupDelay, mihomoGroups, mihomoProxies, mihomoProxyDelay, mihomoProxyProviders, mihomoRuleProviders, mihomoRules, mihomoUnfixedProxy, mihomoUpdateProxyProviders, mihomoUpdateRuleProviders, mihomoUpgrade, mihomoUpgradeGeo, mihomoVersion, patchMihomoConfig, mihomoSmartGroupWeights, mihomoSmartFlushCache } from '../core/mihomoApi' import { checkAutoRun, disableAutoRun, enableAutoRun } from '../sys/autoRun' import { getAppConfig, patchAppConfig, getControledMihomoConfig, patchControledMihomoConfig, getProfileConfig, getCurrentProfileItem, getProfileItem, addProfileItem, removeProfileItem, changeCurrentProfile, getProfileStr, getFileStr, setFileStr, setProfileStr, updateProfileItem, setProfileConfig, getOverrideConfig, setOverrideConfig, getOverrideItem, addOverrideItem, removeOverrideItem, getOverride, setOverride, updateOverrideItem } from '../config' import { startSubStoreFrontendServer, startSubStoreBackendServer, stopSubStoreFrontendServer, stopSubStoreBackendServer, downloadSubStore, subStoreFrontendPort, subStorePort } from '../resolve/server' import { quitWithoutCore, restartCore, checkTunPermissions, grantTunPermissions, manualGrantCorePermition, checkAdminPrivileges, restartAsAdmin, checkMihomoCorePermissions, requestTunPermissions, checkHighPrivilegeCore, showTunPermissionDialog, showErrorDialog } from '../core/manager' import { triggerSysProxy } from '../sys/sysproxy' import { checkUpdate, downloadAndInstallUpdate } from '../resolve/autoUpdater' import { getFilePath, openFile, openUWPTool, readTextFile, resetAppConfig, setNativeTheme, setupFirewall } from '../sys/misc' import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory' import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '../resolve/backup' import { getInterfaces } from '../sys/interface' import { closeTrayIcon, copyEnv, showTrayIcon, updateTrayIcon, updateTrayIconImmediate } from '../resolve/tray' import { registerShortcut } from '../resolve/shortcut' import { closeMainWindow, mainWindow, showMainWindow, triggerMainWindow } from '..' import { applyTheme, fetchThemes, importThemes, readTheme, resolveThemes, writeTheme } from '../resolve/theme' import { subStoreCollections, subStoreSubs } from '../core/subStoreApi' import { logDir } from './dirs' import path from 'path' import v8 from 'v8' import { getGistUrl } from '../resolve/gistApi' import { getImageDataURL } from './image' import { startMonitor } from '../resolve/trafficMonitor' import { closeFloatingWindow, showContextMenu, showFloatingWindow } from '../resolve/floatingWindow' import i18next from 'i18next' import { addProfileUpdater, removeProfileUpdater } from '../core/profileUpdater' function ipcErrorWrapper( // eslint-disable-next-line @typescript-eslint/no-explicit-any fn: (...args: any[]) => Promise // eslint-disable-next-line @typescript-eslint/no-explicit-any ): (...args: any[]) => Promise { // eslint-disable-next-line @typescript-eslint/no-explicit-any return async (...args: any[]) => { try { return await fn(...args) } catch (e) { if (e && typeof e === 'object') { if ('message' in e) { return { invokeError: e.message } } else { return { invokeError: JSON.stringify(e) } } } if (e instanceof Error || typeof e === 'string') { return { invokeError: e } } return { invokeError: 'Unknown Error' } } } } export function registerIpcMainHandlers(): void { ipcMain.handle('mihomoVersion', ipcErrorWrapper(mihomoVersion)) ipcMain.handle('mihomoCloseConnection', (_e, id) => ipcErrorWrapper(mihomoCloseConnection)(id)) ipcMain.handle('mihomoCloseAllConnections', ipcErrorWrapper(mihomoCloseAllConnections)) ipcMain.handle('mihomoRules', ipcErrorWrapper(mihomoRules)) ipcMain.handle('mihomoProxies', ipcErrorWrapper(mihomoProxies)) ipcMain.handle('mihomoGroups', ipcErrorWrapper(mihomoGroups)) ipcMain.handle('mihomoProxyProviders', ipcErrorWrapper(mihomoProxyProviders)) ipcMain.handle('mihomoUpdateProxyProviders', (_e, name) => ipcErrorWrapper(mihomoUpdateProxyProviders)(name) ) ipcMain.handle('mihomoRuleProviders', ipcErrorWrapper(mihomoRuleProviders)) ipcMain.handle('mihomoUpdateRuleProviders', (_e, name) => ipcErrorWrapper(mihomoUpdateRuleProviders)(name) ) ipcMain.handle('mihomoChangeProxy', (_e, group, proxy) => ipcErrorWrapper(mihomoChangeProxy)(group, proxy) ) ipcMain.handle('mihomoUnfixedProxy', (_e, group) => ipcErrorWrapper(mihomoUnfixedProxy)(group)) ipcMain.handle('mihomoUpgradeGeo', ipcErrorWrapper(mihomoUpgradeGeo)) ipcMain.handle('mihomoUpgrade', ipcErrorWrapper(mihomoUpgrade)) ipcMain.handle('mihomoProxyDelay', (_e, proxy, url) => ipcErrorWrapper(mihomoProxyDelay)(proxy, url) ) ipcMain.handle('mihomoGroupDelay', (_e, group, url) => ipcErrorWrapper(mihomoGroupDelay)(group, url) ) ipcMain.handle('patchMihomoConfig', (_e, patch) => ipcErrorWrapper(patchMihomoConfig)(patch)) // Smart 内核 API ipcMain.handle('mihomoSmartGroupWeights', (_e, groupName) => ipcErrorWrapper(mihomoSmartGroupWeights)(groupName) ) ipcMain.handle('mihomoSmartFlushCache', (_e, configName) => ipcErrorWrapper(mihomoSmartFlushCache)(configName) ) ipcMain.handle('checkAutoRun', ipcErrorWrapper(checkAutoRun)) ipcMain.handle('enableAutoRun', ipcErrorWrapper(enableAutoRun)) ipcMain.handle('disableAutoRun', ipcErrorWrapper(disableAutoRun)) ipcMain.handle('getAppConfig', (_e, force) => ipcErrorWrapper(getAppConfig)(force)) ipcMain.handle('patchAppConfig', (_e, config) => ipcErrorWrapper(patchAppConfig)(config)) ipcMain.handle('getControledMihomoConfig', (_e, force) => ipcErrorWrapper(getControledMihomoConfig)(force) ) ipcMain.handle('patchControledMihomoConfig', (_e, config) => ipcErrorWrapper(patchControledMihomoConfig)(config) ) ipcMain.handle('getProfileConfig', (_e, force) => ipcErrorWrapper(getProfileConfig)(force)) ipcMain.handle('setProfileConfig', (_e, config) => ipcErrorWrapper(setProfileConfig)(config)) ipcMain.handle('getCurrentProfileItem', ipcErrorWrapper(getCurrentProfileItem)) ipcMain.handle('getProfileItem', (_e, id) => ipcErrorWrapper(getProfileItem)(id)) ipcMain.handle('getProfileStr', (_e, id) => ipcErrorWrapper(getProfileStr)(id)) ipcMain.handle('getFileStr', (_e, path) => ipcErrorWrapper(getFileStr)(path)) ipcMain.handle('setFileStr', (_e, path, str) => ipcErrorWrapper(setFileStr)(path, str)) ipcMain.handle('setProfileStr', (_e, id, str) => ipcErrorWrapper(setProfileStr)(id, str)) ipcMain.handle('updateProfileItem', (_e, item) => ipcErrorWrapper(updateProfileItem)(item)) ipcMain.handle('changeCurrentProfile', (_e, id) => ipcErrorWrapper(changeCurrentProfile)(id)) ipcMain.handle('addProfileItem', (_e, item) => ipcErrorWrapper(addProfileItem)(item)) ipcMain.handle('removeProfileItem', (_e, id) => ipcErrorWrapper(removeProfileItem)(id)) ipcMain.handle('addProfileUpdater', (_e, item) => ipcErrorWrapper(addProfileUpdater)(item)) ipcMain.handle('removeProfileUpdater', (_e, id) => ipcErrorWrapper(removeProfileUpdater)(id)) ipcMain.handle('getOverrideConfig', (_e, force) => ipcErrorWrapper(getOverrideConfig)(force)) ipcMain.handle('setOverrideConfig', (_e, config) => ipcErrorWrapper(setOverrideConfig)(config)) ipcMain.handle('getOverrideItem', (_e, id) => ipcErrorWrapper(getOverrideItem)(id)) ipcMain.handle('addOverrideItem', (_e, item) => ipcErrorWrapper(addOverrideItem)(item)) ipcMain.handle('removeOverrideItem', (_e, id) => ipcErrorWrapper(removeOverrideItem)(id)) ipcMain.handle('updateOverrideItem', (_e, item) => ipcErrorWrapper(updateOverrideItem)(item)) ipcMain.handle('getOverride', (_e, id, ext) => ipcErrorWrapper(getOverride)(id, ext)) ipcMain.handle('setOverride', (_e, id, ext, str) => ipcErrorWrapper(setOverride)(id, ext, str)) ipcMain.handle('restartCore', ipcErrorWrapper(restartCore)) ipcMain.handle('startMonitor', (_e, detached) => ipcErrorWrapper(startMonitor)(detached)) ipcMain.handle('triggerSysProxy', (_e, enable) => ipcErrorWrapper(triggerSysProxy)(enable)) ipcMain.handle('manualGrantCorePermition', () => ipcErrorWrapper(manualGrantCorePermition)()) ipcMain.handle('checkAdminPrivileges', () => ipcErrorWrapper(checkAdminPrivileges)()) ipcMain.handle('restartAsAdmin', () => ipcErrorWrapper(restartAsAdmin)()) ipcMain.handle('checkMihomoCorePermissions', () => ipcErrorWrapper(checkMihomoCorePermissions)()) ipcMain.handle('requestTunPermissions', () => ipcErrorWrapper(requestTunPermissions)()) ipcMain.handle('checkHighPrivilegeCore', () => ipcErrorWrapper(checkHighPrivilegeCore)()) ipcMain.handle('showTunPermissionDialog', () => ipcErrorWrapper(showTunPermissionDialog)()) ipcMain.handle('showErrorDialog', (_, title: string, message: string) => ipcErrorWrapper(showErrorDialog)(title, message)) ipcMain.handle('checkTunPermissions', () => ipcErrorWrapper(checkTunPermissions)()) ipcMain.handle('grantTunPermissions', () => ipcErrorWrapper(grantTunPermissions)()) ipcMain.handle('getFilePath', (_e, ext) => getFilePath(ext)) ipcMain.handle('readTextFile', (_e, filePath) => ipcErrorWrapper(readTextFile)(filePath)) ipcMain.handle('getRuntimeConfigStr', ipcErrorWrapper(getRuntimeConfigStr)) ipcMain.handle('getRuntimeConfig', ipcErrorWrapper(getRuntimeConfig)) ipcMain.handle('downloadAndInstallUpdate', (_e, version) => ipcErrorWrapper(downloadAndInstallUpdate)(version) ) ipcMain.handle('checkUpdate', ipcErrorWrapper(checkUpdate)) ipcMain.handle('getVersion', () => app.getVersion()) ipcMain.handle('platform', () => process.platform) ipcMain.handle('openUWPTool', ipcErrorWrapper(openUWPTool)) ipcMain.handle('setupFirewall', ipcErrorWrapper(setupFirewall)) ipcMain.handle('getInterfaces', getInterfaces) ipcMain.handle('webdavBackup', ipcErrorWrapper(webdavBackup)) ipcMain.handle('webdavRestore', (_e, filename) => ipcErrorWrapper(webdavRestore)(filename)) ipcMain.handle('listWebdavBackups', ipcErrorWrapper(listWebdavBackups)) ipcMain.handle('webdavDelete', (_e, filename) => ipcErrorWrapper(webdavDelete)(filename)) ipcMain.handle('registerShortcut', (_e, oldShortcut, newShortcut, action) => ipcErrorWrapper(registerShortcut)(oldShortcut, newShortcut, action) ) ipcMain.handle('startSubStoreFrontendServer', () => ipcErrorWrapper(startSubStoreFrontendServer)() ) ipcMain.handle('stopSubStoreFrontendServer', () => ipcErrorWrapper(stopSubStoreFrontendServer)()) ipcMain.handle('startSubStoreBackendServer', () => ipcErrorWrapper(startSubStoreBackendServer)()) ipcMain.handle('stopSubStoreBackendServer', () => ipcErrorWrapper(stopSubStoreBackendServer)()) ipcMain.handle('downloadSubStore', () => ipcErrorWrapper(downloadSubStore)()) ipcMain.handle('subStorePort', () => subStorePort) ipcMain.handle('subStoreFrontendPort', () => subStoreFrontendPort) ipcMain.handle('subStoreSubs', () => ipcErrorWrapper(subStoreSubs)()) ipcMain.handle('subStoreCollections', () => ipcErrorWrapper(subStoreCollections)()) ipcMain.handle('getGistUrl', ipcErrorWrapper(getGistUrl)) ipcMain.handle('setNativeTheme', (_e, theme) => { setNativeTheme(theme) }) ipcMain.handle('setTitleBarOverlay', (_e, overlay) => ipcErrorWrapper(async (overlay): Promise => { if (mainWindow && typeof mainWindow.setTitleBarOverlay === 'function') { mainWindow.setTitleBarOverlay(overlay) } })(overlay) ) ipcMain.handle('setAlwaysOnTop', (_e, alwaysOnTop) => { mainWindow?.setAlwaysOnTop(alwaysOnTop) }) ipcMain.handle('isAlwaysOnTop', () => { return mainWindow?.isAlwaysOnTop() }) ipcMain.handle('showTrayIcon', () => ipcErrorWrapper(showTrayIcon)()) ipcMain.handle('closeTrayIcon', () => ipcErrorWrapper(closeTrayIcon)()) ipcMain.handle('updateTrayIcon', () => ipcErrorWrapper(updateTrayIcon)()) ipcMain.handle('updateTrayIconImmediate', (_e, sysProxyEnabled, tunEnabled) => { updateTrayIconImmediate(sysProxyEnabled, tunEnabled) }) ipcMain.handle('showMainWindow', showMainWindow) ipcMain.handle('closeMainWindow', closeMainWindow) ipcMain.handle('triggerMainWindow', triggerMainWindow) ipcMain.handle('showFloatingWindow', () => ipcErrorWrapper(showFloatingWindow)()) ipcMain.handle('closeFloatingWindow', () => ipcErrorWrapper(closeFloatingWindow)()) ipcMain.handle('showContextMenu', () => ipcErrorWrapper(showContextMenu)()) ipcMain.handle('openFile', (_e, type, id, ext) => openFile(type, id, ext)) ipcMain.handle('openDevTools', () => { mainWindow?.webContents.openDevTools() }) ipcMain.handle('createHeapSnapshot', () => { v8.writeHeapSnapshot(path.join(logDir(), `${Date.now()}.heapsnapshot`)) }) ipcMain.handle('getImageDataURL', (_e, url) => ipcErrorWrapper(getImageDataURL)(url)) ipcMain.handle('resolveThemes', () => ipcErrorWrapper(resolveThemes)()) ipcMain.handle('fetchThemes', () => ipcErrorWrapper(fetchThemes)()) ipcMain.handle('importThemes', (_e, file) => ipcErrorWrapper(importThemes)(file)) ipcMain.handle('readTheme', (_e, theme) => ipcErrorWrapper(readTheme)(theme)) ipcMain.handle('writeTheme', (_e, theme, css) => ipcErrorWrapper(writeTheme)(theme, css)) ipcMain.handle('applyTheme', (_e, theme) => ipcErrorWrapper(applyTheme)(theme)) ipcMain.handle('copyEnv', (_e, type) => ipcErrorWrapper(copyEnv)(type)) ipcMain.handle('alert', (_e, msg) => { dialog.showErrorBox('Clash Party', msg) }) ipcMain.handle('showDetailedError', (_e, title, message) => { dialog.showErrorBox(title, message) }) ipcMain.handle('getSmartOverrideContent', async () => { const { getOverrideItem } = await import('../config') try { const override = await getOverrideItem('smart-core-override') return override?.file || null } catch (error) { return null } }) ipcMain.handle('resetAppConfig', resetAppConfig) ipcMain.handle('relaunchApp', () => { app.relaunch() app.quit() }) ipcMain.handle('quitWithoutCore', ipcErrorWrapper(quitWithoutCore)) ipcMain.handle('quitApp', () => app.quit()) // Add language change handler ipcMain.handle('changeLanguage', async (_e, lng) => { await i18next.changeLanguage(lng) // 触发托盘菜单更新 ipcMain.emit('updateTrayMenu') }) }