sysproxy and tun controller

This commit is contained in:
pompurin404 2024-08-01 20:26:52 +08:00
parent 536ae67e29
commit bfcd195b4d
No known key found for this signature in database
9 changed files with 162 additions and 11 deletions

View File

@ -19,6 +19,7 @@ import {
removeProfileItem
} from './config'
import { restartCore } from './manager'
import { triggerSysProxy } from './sysproxy'
export function registerIpcMainHandlers(): void {
ipcMain.handle('mihomoVersion', mihomoVersion)
@ -39,4 +40,5 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('addProfileItem', (_e, item) => addProfileItem(item))
ipcMain.handle('removeProfileItem', (_e, id) => removeProfileItem(id))
ipcMain.handle('restartCore', () => restartCore())
ipcMain.handle('triggerSysProxy', (_e, enable) => triggerSysProxy(enable))
}

17
src/main/sysproxy.ts Normal file
View File

@ -0,0 +1,17 @@
import { controledMihomoConfig } from './config'
export function triggerSysProxy(enable: boolean): void {
if (enable) {
enableSysProxy()
} else {
disableSysProxy()
}
}
export function enableSysProxy(): void {
console.log('enableSysProxy', controledMihomoConfig['mixed-port'])
}
export function disableSysProxy(): void {
console.log('disableSysProxy')
}

View File

@ -1,6 +1,7 @@
export const defaultConfig: IAppConfig = {
core: 'mihomo',
silentStart: false
silentStart: false,
sysProxy: { enable: false, mode: 'manual' }
}
export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
@ -9,7 +10,8 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
mode: 'rule',
'mixed-port': 7890,
'allow-lan': false,
'log-level': 'info'
'log-level': 'info',
tun: { enable: false }
}
export const defaultProfileConfig: IProfileConfig = {

View File

@ -1,9 +1,11 @@
import { controledMihomoConfig, setControledMihomoConfig } from './config'
import { appConfig, controledMihomoConfig, setAppConfig, setControledMihomoConfig } from './config'
import icoIcon from '../../resources/icon.ico?asset'
import pngIcon from '../../resources/icon.png?asset'
import { patchMihomoConfig } from './mihomoApi'
import { window } from '.'
import { app, ipcMain, Menu, Tray } from 'electron'
import { app, ipcMain, Menu, shell, Tray } from 'electron'
import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from './dirs'
import { triggerSysProxy } from './sysproxy'
let tray: Tray | null = null
@ -55,6 +57,58 @@ const buildContextMenu = (): Menu => {
}
},
{ type: 'separator' },
{
type: 'checkbox',
label: '系统代理',
checked: appConfig.sysProxy.enable,
click: (item): void => {
const enable = item.checked
setAppConfig({ sysProxy: { enable } })
triggerSysProxy(enable)
window?.webContents.send('appConfigUpdated')
updateTrayMenu()
}
},
{
type: 'checkbox',
label: '虚拟网卡',
checked: controledMihomoConfig.tun?.enable ?? false,
click: (item): void => {
const enable = item.checked
setControledMihomoConfig({ tun: { enable } })
patchMihomoConfig({ tun: { enable } })
window?.webContents.send('controledMihomoConfigUpdated')
updateTrayMenu()
}
},
{ type: 'separator' },
{
type: 'submenu',
label: '打开目录',
submenu: [
{
type: 'normal',
label: '应用目录',
click: (): Promise<string> => shell.openPath(dataDir)
},
{
type: 'normal',
label: '工作目录',
click: (): Promise<string> => shell.openPath(mihomoWorkDir())
},
{
type: 'normal',
label: '内核目录',
click: (): Promise<string> => shell.openPath(mihomoCoreDir())
},
{
type: 'normal',
label: '日志目录',
click: (): Promise<string> => shell.openPath(logDir())
}
]
},
{ type: 'separator' },
{
id: 'restart',
label: '重启应用',
@ -80,6 +134,9 @@ export function createTray(): void {
ipcMain.on('controledMihomoConfigUpdated', () => {
updateTrayMenu()
})
ipcMain.on('appConfigUpdated', () => {
updateTrayMenu()
})
tray.setContextMenu(menu)
tray.setIgnoreDoubleClickEvents(true)

View File

@ -1,13 +1,22 @@
import { Button, Card, CardBody, CardFooter, Switch } from '@nextui-org/react'
import React, { useState } from 'react'
import { AiOutlineGlobal } from 'react-icons/ai'
import { useLocation, useNavigate } from 'react-router-dom'
import { useAppConfig } from '@renderer/hooks/use-config'
import { AiOutlineGlobal } from 'react-icons/ai'
import React from 'react'
import { triggerSysProxy } from '@renderer/utils/ipc'
const SysproxySwitcher: React.FC = () => {
const navigate = useNavigate()
const location = useLocation()
const match = location.pathname.includes('/sysproxy')
const [enable, setEnable] = useState(false)
const { appConfig, patchAppConfig } = useAppConfig()
const { sysProxy } = appConfig || {}
const { enable } = sysProxy || {}
const onChange = async (enable: boolean): Promise<void> => {
await patchAppConfig({ sysProxy: { enable } })
await triggerSysProxy(enable)
}
return (
<Card
@ -31,7 +40,7 @@ const SysproxySwitcher: React.FC = () => {
}}
size="sm"
isSelected={enable}
onValueChange={setEnable}
onValueChange={onChange}
/>
</div>
</CardBody>

View File

@ -1,13 +1,23 @@
import { Button, Card, CardBody, CardFooter, Switch } from '@nextui-org/react'
import React, { useState } from 'react'
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
import { TbDeviceIpadHorizontalBolt } from 'react-icons/tb'
import { useLocation, useNavigate } from 'react-router-dom'
import { patchMihomoConfig } from '@renderer/utils/ipc'
import React from 'react'
const TunSwitcher: React.FC = () => {
const navigate = useNavigate()
const location = useLocation()
const match = location.pathname.includes('/tun')
const [enable, setEnable] = useState(false)
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
const { tun } = controledMihomoConfig || {}
const { enable } = tun || {}
const onChange = async (enable: boolean): Promise<void> => {
await patchControledMihomoConfig({ tun: { enable } })
await patchMihomoConfig({ tun: { enable } })
}
return (
<Card
@ -31,7 +41,7 @@ const TunSwitcher: React.FC = () => {
}}
size="sm"
isSelected={enable}
onValueChange={setEnable}
onValueChange={onChange}
/>
</div>
</CardBody>

View File

@ -1,5 +1,6 @@
import useSWR from 'swr'
import { getAppConfig, setAppConfig } from '@renderer/utils/ipc'
import { useEffect } from 'react'
interface RetuenType {
appConfig: IAppConfig | undefined
@ -13,8 +14,18 @@ export const useAppConfig = (): RetuenType => {
const patchAppConfig = async (value: Partial<IAppConfig>): Promise<void> => {
await setAppConfig(value)
mutateAppConfig()
window.electron.ipcRenderer.send('appConfigUpdated')
}
useEffect(() => {
window.electron.ipcRenderer.on('appConfigUpdated', () => {
mutateAppConfig()
})
return (): void => {
window.electron.ipcRenderer.removeAllListeners('appConfigUpdated')
}
}, [])
return {
appConfig,
mutateAppConfig,

View File

@ -69,3 +69,7 @@ export async function removeProfileItem(id: string): Promise<void> {
export async function restartCore(): Promise<void> {
await window.electron.ipcRenderer.invoke('restartCore')
}
export async function triggerSysProxy(enable: boolean): Promise<void> {
await window.electron.ipcRenderer.invoke('triggerSysProxy', enable)
}

39
src/shared/types.d.ts vendored
View File

@ -63,11 +63,49 @@ interface IMihomoConnectionDetail {
rulePayload: string
}
interface ISysProxyConfig {
enable: boolean
mode?: 'auto' | 'manual'
bypass?: string[]
pacScript?: string
}
interface IAppConfig {
core: 'mihomo' | 'mihomo-alpha'
silentStart: boolean
sysProxy: ISysProxyConfig
}
interface IMihomoTunConfig {
enable: boolean
stack?: 'system' | 'gvisor' | 'mixed'
'auto-route'?: boolean
'auto-redirect'?: boolean
'auto-detect-interface'?: boolean
'dns-hijack'?: string[]
device?: string
mtu?: number
'strict-route'?: boolean
gso?: boolean
'gso-max-size'?: number
'udp-timeout'?: number
'iproute2-table-index'?: number
'iproute2-rule-index'?: number
'endpoint-independent-nat'?: boolean
'route-address-set'?: string[]
'route-exclude-address-set'?: string[]
'route-address'?: string[]
'route-exclude-address'?: string[]
'include-interface'?: string[]
'exclude-interface'?: string[]
'include-uid'?: number[]
'include-uid-range'?: string[]
'exclude-uid'?: number[]
'exclude-uid-range'?: string[]
'include-android-user'?: string[]
'include-package'?: string[]
'exclude-package'?: string[]
}
interface IMihomoConfig {
'external-controller': string
secret?: string
@ -81,6 +119,7 @@ interface IMihomoConfig {
proxies?: []
'proxy-groups'?: []
rules?: []
tun: IMihomoTunConfig
}
interface IProfileConfig {