1
- import { ChildProcess , execFileSync , execSync , spawn } from 'child_process'
1
+ import { ChildProcess , execFile , execSync , spawn } from 'child_process'
2
2
import {
3
3
logPath ,
4
4
mihomoCorePath ,
@@ -12,61 +12,97 @@ import { dialog, safeStorage } from 'electron'
12
12
import fs from 'fs'
13
13
14
14
let child : ChildProcess
15
+ let retry = 10
15
16
16
- export function startCore ( ) : void {
17
+ export async function startCore ( ) : Promise < void > {
17
18
const corePath = mihomoCorePath ( getAppConfig ( ) . core ?? 'mihomo' )
18
19
grantCorePermition ( corePath )
19
20
generateProfile ( )
20
- checkProfile ( )
21
+ await checkProfile ( )
21
22
stopCore ( )
22
- child = spawn ( corePath , [ '-d' , mihomoWorkDir ( ) ] )
23
- child . stdout ?. on ( 'data' , ( data ) => {
24
- fs . writeFileSync (
25
- logPath ( ) ,
26
- data
27
- . toString ( )
28
- . split ( '\n' )
29
- . map ( ( line : string ) => {
30
- if ( line ) return `[Mihomo]: ${ line } `
31
- return ''
32
- } )
33
- . filter ( Boolean )
34
- . join ( '\n' ) ,
35
- {
36
- flag : 'a'
23
+ return new Promise ( ( resolve , reject ) => {
24
+ child = spawn ( corePath , [ '-d' , mihomoWorkDir ( ) ] )
25
+ child . stdout ?. on ( 'data' , ( data ) => {
26
+ if ( data . toString ( ) . includes ( 'External controller listen error' ) ) {
27
+ if ( retry ) {
28
+ retry --
29
+ resolve ( startCore ( ) )
30
+ } else {
31
+ dialog . showErrorBox ( 'External controller listen error' , data . toString ( ) )
32
+ reject ( 'External controller listen error' )
33
+ }
34
+ }
35
+ if ( data . toString ( ) . includes ( 'RESTful API listening at' ) ) {
36
+ retry = 10
37
+ resolve ( )
38
+ }
39
+ fs . writeFileSync (
40
+ logPath ( ) ,
41
+ data
42
+ . toString ( )
43
+ . split ( '\n' )
44
+ . map ( ( line : string ) => {
45
+ if ( line ) return `[Mihomo]: ${ line } `
46
+ return ''
47
+ } )
48
+ . filter ( Boolean )
49
+ . join ( '\n' ) ,
50
+ {
51
+ flag : 'a'
52
+ }
53
+ )
54
+ } )
55
+ child . on ( 'error' , ( err ) => {
56
+ if ( retry ) {
57
+ retry --
58
+ startCore ( )
59
+ } else {
60
+ dialog . showErrorBox ( 'External controller listen error' , err . toString ( ) )
61
+ reject ( err )
37
62
}
38
- )
39
- } )
40
- child . on ( 'close' , ( code , signal ) => {
41
- fs . writeFileSync ( logPath ( ) , `[Manager]: Core closed, code: ${ code } , signal: ${ signal } \n` , {
42
- flag : 'a'
43
63
} )
44
- fs . writeFileSync ( logPath ( ) , `[Manager]: Restart Core\n` , {
45
- flag : 'a'
64
+ child . on ( 'close' , async ( code , signal ) => {
65
+ fs . writeFileSync ( logPath ( ) , `[Manager]: Core closed, code: ${ code } , signal: ${ signal } \n` , {
66
+ flag : 'a'
67
+ } )
68
+ fs . writeFileSync ( logPath ( ) , `[Manager]: Restart Core\n` , {
69
+ flag : 'a'
70
+ } )
71
+ await startCore ( )
46
72
} )
47
- restartCore ( )
48
73
} )
49
74
}
50
75
51
76
export function stopCore ( ) : void {
52
77
if ( child ) {
53
78
child . removeAllListeners ( )
54
- child . kill ( 'SIGINT' )
79
+ if ( ! child . kill ( 'SIGINT' ) ) {
80
+ stopCore ( )
81
+ }
55
82
}
56
83
}
57
84
58
- export function restartCore ( ) : void {
59
- startCore ( )
60
- }
61
-
62
- export function checkProfile ( ) : void {
85
+ export function checkProfile ( ) : Promise < void > {
63
86
const corePath = mihomoCorePath ( getAppConfig ( ) . core ?? 'mihomo' )
64
- try {
65
- execFileSync ( corePath , [ '-t' , '-f' , mihomoWorkConfigPath ( ) , '-d' , mihomoTestDir ( ) ] )
66
- } catch ( e ) {
67
- dialog . showErrorBox ( 'Profile check failed' , `${ e } ` )
68
- throw new Error ( 'Profile check failed' )
69
- }
87
+ return new Promise ( ( resolve , reject ) => {
88
+ const child = execFile ( corePath , [ '-t' , '-f' , mihomoWorkConfigPath ( ) , '-d' , mihomoTestDir ( ) ] )
89
+ child . stdout ?. on ( 'data' , ( data ) => {
90
+ data
91
+ . toString ( )
92
+ . split ( '\n' )
93
+ . forEach ( ( line : string ) => {
94
+ if ( line . includes ( 'level=error' ) ) {
95
+ dialog . showErrorBox ( 'Profile Check Failed' , line . split ( 'level=error' ) [ 1 ] )
96
+ reject ( line )
97
+ }
98
+ } )
99
+ } )
100
+ child . on ( 'close' , ( code ) => {
101
+ if ( code === 0 ) {
102
+ resolve ( )
103
+ }
104
+ } )
105
+ } )
70
106
}
71
107
72
108
export function grantCorePermition ( corePath : string ) : void {
0 commit comments