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 { profileConfigPath, profilePath } from '../utils/dirs'
import { restartCore } from '../core/manager'
import { startCore } from '../core/manager'
import { getAppConfig } from './app'
import { window } from '..'
import axios from 'axios'
@ -28,7 +28,7 @@ export async function changeCurrentProfile(id: string): Promise<void> {
profileConfig.current = id
getCurrentProfile(true)
try {
restartCore()
await startCore()
} catch (e) {
profileConfig.current = oldId
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)
profileConfig.items[index] = item
fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig))
@ -174,11 +174,11 @@ export function getProfileStr(id: string): string {
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')
if (id === getProfileConfig().current) {
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 {
logPath,
mihomoCorePath,
@ -12,61 +12,97 @@ import { dialog, safeStorage } from 'electron'
import fs from 'fs'
let child: ChildProcess
let retry = 10
export function startCore(): void {
export async function startCore(): Promise<void> {
const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo')
grantCorePermition(corePath)
generateProfile()
checkProfile()
await checkProfile()
stopCore()
child = spawn(corePath, ['-d', mihomoWorkDir()])
child.stdout?.on('data', (data) => {
fs.writeFileSync(
logPath(),
data
.toString()
.split('\n')
.map((line: string) => {
if (line) return `[Mihomo]: ${line}`
return ''
})
.filter(Boolean)
.join('\n'),
{
flag: 'a'
return new Promise((resolve, reject) => {
child = spawn(corePath, ['-d', mihomoWorkDir()])
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')
}
}
)
})
child.on('close', (code, signal) => {
fs.writeFileSync(logPath(), `[Manager]: Core closed, code: ${code}, signal: ${signal}\n`, {
flag: 'a'
if (data.toString().includes('RESTful API listening at')) {
retry = 10
resolve()
}
fs.writeFileSync(
logPath(),
data
.toString()
.split('\n')
.map((line: string) => {
if (line) return `[Mihomo]: ${line}`
return ''
})
.filter(Boolean)
.join('\n'),
{
flag: 'a'
}
)
})
fs.writeFileSync(logPath(), `[Manager]: Restart Core\n`, {
flag: 'a'
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`, {
flag: 'a'
})
fs.writeFileSync(logPath(), `[Manager]: Restart Core\n`, {
flag: 'a'
})
await startCore()
})
restartCore()
})
}
export function stopCore(): void {
if (child) {
child.removeAllListeners()
child.kill('SIGINT')
if (!child.kill('SIGINT')) {
stopCore()
}
}
}
export function restartCore(): void {
startCore()
}
export function checkProfile(): void {
export function checkProfile(): Promise<void> {
const corePath = mihomoCorePath(getAppConfig().core ?? 'mihomo')
try {
execFileSync(corePath, ['-t', '-f', mihomoWorkConfigPath(), '-d', mihomoTestDir()])
} catch (e) {
dialog.showErrorBox('Profile check failed', `${e}`)
throw new Error('Profile check failed')
}
return new Promise((resolve, reject) => {
const child = execFile(corePath, ['-t', '-f', mihomoWorkConfigPath(), '-d', mihomoTestDir()])
child.stdout?.on('data', (data) => {
data
.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 {

View File

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

View File

@ -50,8 +50,12 @@ const MihomoCoreCard: React.FC = () => {
size="sm"
variant="light"
color="default"
onPress={() => {
restartCore()
onPress={async () => {
await restartCore()
mutate()
setTimeout(() => {
mutate()
}, 2000)
}}
>
<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 { appConfig, patchAppConfig } = useAppConfig()
const { proxyDisplayMode = 'simple', proxyDisplayOrder = 'default' } = appConfig || {}
const groups = useMemo(() => {
const groups: IMihomoGroup[] = []
if (proxies) {
if (proxies && proxies.proxies && proxies.proxies['GLOBAL']) {
const globalGroup = proxies.proxies['GLOBAL'] as IMihomoGroup
for (const global of globalGroup.all) {
if (isGroup(proxies.proxies[global])) {