Improve core management

This commit is contained in:
pompurin404 2024-08-06 10:40:23 +08:00
parent ad31bcccff
commit a93a4151e4
No known key found for this signature in database
5 changed files with 88 additions and 49 deletions

View File

@ -1,6 +1,6 @@
import { getControledMihomoConfig } from './controledMihomo' import { getControledMihomoConfig } from './controledMihomo'
import { profileConfigPath, profilePath } from '../utils/dirs' import { profileConfigPath, profilePath } from '../utils/dirs'
import { restartCore } from '../core/manager' import { startCore } from '../core/manager'
import { getAppConfig } from './app' import { getAppConfig } from './app'
import { window } from '..' import { window } from '..'
import axios from 'axios' import axios from 'axios'
@ -28,7 +28,7 @@ export async function changeCurrentProfile(id: string): Promise<void> {
profileConfig.current = id profileConfig.current = id
getCurrentProfile(true) getCurrentProfile(true)
try { try {
restartCore() await startCore()
} catch (e) { } catch (e) {
profileConfig.current = oldId profileConfig.current = oldId
getCurrentProfile(true) getCurrentProfile(true)
@ -38,7 +38,7 @@ export async function changeCurrentProfile(id: string): Promise<void> {
} }
} }
export async function updateProfileItem(item: IProfileItem): Promise<void> { export function updateProfileItem(item: IProfileItem): void {
const index = profileConfig.items.findIndex((i) => i.id === item.id) const index = profileConfig.items.findIndex((i) => i.id === item.id)
profileConfig.items[index] = item profileConfig.items[index] = item
fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig)) fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig))
@ -174,11 +174,11 @@ export function getProfileStr(id: string): string {
return fs.readFileSync(profilePath(id), 'utf-8') return fs.readFileSync(profilePath(id), 'utf-8')
} }
export function setProfileStr(id: string, content: string): void { export async function setProfileStr(id: string, content: string): Promise<void> {
fs.writeFileSync(profilePath(id), content, 'utf-8') fs.writeFileSync(profilePath(id), content, 'utf-8')
if (id === getProfileConfig().current) { if (id === getProfileConfig().current) {
getCurrentProfile(true) getCurrentProfile(true)
restartCore() await startCore()
} }
} }

View File

@ -1,4 +1,4 @@
import { ChildProcess, execFileSync, execSync, spawn } from 'child_process' import { ChildProcess, execFile, execSync, spawn } from 'child_process'
import { import {
logPath, logPath,
mihomoCorePath, mihomoCorePath,
@ -12,15 +12,30 @@ import { dialog, safeStorage } from 'electron'
import fs from 'fs' import fs from 'fs'
let child: ChildProcess let child: ChildProcess
let retry = 10
export function startCore(): void { export async function startCore(): Promise<void> {
const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo') const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo')
grantCorePermition(corePath) grantCorePermition(corePath)
generateProfile() generateProfile()
checkProfile() await checkProfile()
stopCore() stopCore()
return new Promise((resolve, reject) => {
child = spawn(corePath, ['-d', mihomoWorkDir()]) child = spawn(corePath, ['-d', mihomoWorkDir()])
child.stdout?.on('data', (data) => { child.stdout?.on('data', (data) => {
if (data.toString().includes('External controller listen error')) {
if (retry) {
retry--
resolve(startCore())
} else {
dialog.showErrorBox('External controller listen error', data.toString())
reject('External controller listen error')
}
}
if (data.toString().includes('RESTful API listening at')) {
retry = 10
resolve()
}
fs.writeFileSync( fs.writeFileSync(
logPath(), logPath(),
data data
@ -37,36 +52,57 @@ export function startCore(): void {
} }
) )
}) })
child.on('close', (code, signal) => { child.on('error', (err) => {
if (retry) {
retry--
startCore()
} else {
dialog.showErrorBox('External controller listen error', err.toString())
reject(err)
}
})
child.on('close', async (code, signal) => {
fs.writeFileSync(logPath(), `[Manager]: Core closed, code: ${code}, signal: ${signal}\n`, { fs.writeFileSync(logPath(), `[Manager]: Core closed, code: ${code}, signal: ${signal}\n`, {
flag: 'a' flag: 'a'
}) })
fs.writeFileSync(logPath(), `[Manager]: Restart Core\n`, { fs.writeFileSync(logPath(), `[Manager]: Restart Core\n`, {
flag: 'a' flag: 'a'
}) })
restartCore() await startCore()
})
}) })
} }
export function stopCore(): void { export function stopCore(): void {
if (child) { if (child) {
child.removeAllListeners() child.removeAllListeners()
child.kill('SIGINT') if (!child.kill('SIGINT')) {
stopCore()
}
} }
} }
export function restartCore(): void { export function checkProfile(): Promise<void> {
startCore()
}
export function checkProfile(): void {
const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo') const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo')
try { return new Promise((resolve, reject) => {
execFileSync(corePath, ['-t', '-f', mihomoWorkConfigPath(), '-d', mihomoTestDir()]) const child = execFile(corePath, ['-t', '-f', mihomoWorkConfigPath(), '-d', mihomoTestDir()])
} catch (e) { child.stdout?.on('data', (data) => {
dialog.showErrorBox('Profile check failed', `${e}`) data
throw new Error('Profile check failed') .toString()
.split('\n')
.forEach((line: string) => {
if (line.includes('level=error')) {
dialog.showErrorBox('Profile Check Failed', line.split('level=error')[1])
reject(line)
} }
})
})
child.on('close', (code) => {
if (code === 0) {
resolve()
}
})
})
} }
export function grantCorePermition(corePath: string): void { export function grantCorePermition(corePath: string): void {

View File

@ -29,7 +29,7 @@ import {
setProfileStr, setProfileStr,
updateProfileItem updateProfileItem
} from '../config' } from '../config'
import { isEncryptionAvailable, restartCore } from '../core/manager' import { isEncryptionAvailable, startCore } from '../core/manager'
import { triggerSysProxy } from '../resolve/sysproxy' import { triggerSysProxy } from '../resolve/sysproxy'
import { checkUpdate } from '../resolve/autoUpdater' import { checkUpdate } from '../resolve/autoUpdater'
@ -62,7 +62,7 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('changeCurrentProfile', (_e, id) => changeCurrentProfile(id)) ipcMain.handle('changeCurrentProfile', (_e, id) => changeCurrentProfile(id))
ipcMain.handle('addProfileItem', (_e, item) => addProfileItem(item)) ipcMain.handle('addProfileItem', (_e, item) => addProfileItem(item))
ipcMain.handle('removeProfileItem', (_e, id) => removeProfileItem(id)) ipcMain.handle('removeProfileItem', (_e, id) => removeProfileItem(id))
ipcMain.handle('restartCore', restartCore) ipcMain.handle('restartCore', startCore)
ipcMain.handle('triggerSysProxy', (_e, enable) => triggerSysProxy(enable)) ipcMain.handle('triggerSysProxy', (_e, enable) => triggerSysProxy(enable))
ipcMain.handle('isEncryptionAvailable', isEncryptionAvailable) ipcMain.handle('isEncryptionAvailable', isEncryptionAvailable)
ipcMain.handle('encryptString', (_e, str) => safeStorage.encryptString(str)) ipcMain.handle('encryptString', (_e, str) => safeStorage.encryptString(str))

View File

@ -50,8 +50,12 @@ const MihomoCoreCard: React.FC = () => {
size="sm" size="sm"
variant="light" variant="light"
color="default" color="default"
onPress={() => { onPress={async () => {
restartCore() await restartCore()
mutate()
setTimeout(() => {
mutate()
}, 2000)
}} }}
> >
<IoMdRefresh className={`${match ? 'text-white' : 'text-foreground'} text-[24px]`} /> <IoMdRefresh className={`${match ? 'text-white' : 'text-foreground'} text-[24px]`} />

View File

@ -18,10 +18,9 @@ const Proxies: React.FC = () => {
const { data: proxies, mutate } = useSWR('mihomoProxies', mihomoProxies) const { data: proxies, mutate } = useSWR('mihomoProxies', mihomoProxies)
const { appConfig, patchAppConfig } = useAppConfig() const { appConfig, patchAppConfig } = useAppConfig()
const { proxyDisplayMode = 'simple', proxyDisplayOrder = 'default' } = appConfig || {} const { proxyDisplayMode = 'simple', proxyDisplayOrder = 'default' } = appConfig || {}
const groups = useMemo(() => { const groups = useMemo(() => {
const groups: IMihomoGroup[] = [] const groups: IMihomoGroup[] = []
if (proxies) { if (proxies && proxies.proxies && proxies.proxies['GLOBAL']) {
const globalGroup = proxies.proxies['GLOBAL'] as IMihomoGroup const globalGroup = proxies.proxies['GLOBAL'] as IMihomoGroup
for (const global of globalGroup.all) { for (const global of globalGroup.all) {
if (isGroup(proxies.proxies[global])) { if (isGroup(proxies.proxies[global])) {