Compare commits

..

No commits in common. "9c592c92826a495c4f72bf18db9382ee73e47e80" and "68bbde0d163ca08fe8b709c60b02b726598fb221" have entirely different histories.

24 changed files with 172 additions and 122 deletions

View File

@ -1,14 +1,3 @@
## 1.8.7
### 新功能 (Feat)
- 增加关闭动画开关
- 增加订阅超时时间设置
-
### 样式调整 (Sytle)
- 改进 logo 设计
- 改进代理模式的图标
## 1.8.6 ## 1.8.6
**本次更新修改了软件名称,可能导致不可预期的 BUG请大家积极反馈** **本次更新修改了软件名称,可能导致不可预期的 BUG请大家积极反馈**
@ -28,4 +17,30 @@
- 修复定时更新订阅引入的删除后自动添加问题 - 修复定时更新订阅引入的删除后自动添加问题
### 样式调整 (Sytle) ### 样式调整 (Sytle)
- DNS 设置部分样式微调 - DNS 设置部分样式微调
## 1.8.5
**🎉 本次更新增加了大家期待已久的托盘图标根据代理状态变化颜色,系统代理为蓝色,虚拟网卡为绿色,双开为红色
⚡ 完善 Smart 规则写,当原有规则中有 url-test 和 load-balance 组时,自动替换为 Smart 规则组;当没有 url-test 和 load-balance 时,增加 全局 Smart 规则组,接管全部流量**
#### 新增 Smart Core 详细文档: [点击查看](https://mihomo.party/docs/guide/smart-core)
### 新功能 (Feat)
- 支持 cron 表达式以自定义订阅更新频率(#766)
- 修复权限检查并优化TUN与自启联动(#977)
- 托盘图标能根据代理状态实时变化颜色
- 更健壮完善的 Smart 覆写规则
### 修复 (Fix)
- Windows 下当前运行内核权限检测(之前没有正确检测管理员权限运行的内核)
- Windows 下 开机自启 按钮卡顿问题 隐藏运行黑框 现在申请权限会弹通知
- 修复 部分情况下 yaml 文件解析错误 (#889)
- 修复 系统中已经运行的内核名称检测
- 修复 订阅信息中的因格式问题导致的信息缺失(#951)
- 修复 轻量模式延迟启动延时输入数值问题(#962)
- 修复 轻量模式下轻量模式下规则失效的问题(#963)
- 修复 MacOS 下默认虚拟网卡名称没有生效的问题
- 修复 ES Module 兼容性问题
### 样式调整 (Sytle)
- 部分样式微调

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 153 KiB

View File

@ -1,6 +1,6 @@
{ {
"name": "mihomo-party", "name": "mihomo-party",
"version": "1.8.7", "version": "1.8.6",
"description": "Clash Party", "description": "Clash Party",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "mihomo-party-org", "author": "mihomo-party-org",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -44,11 +44,6 @@ export async function generateProfile(): Promise<void> {
} }
const profile = deepMerge(currentProfile, controledMihomoConfig) const profile = deepMerge(currentProfile, controledMihomoConfig)
// 确保可以拿到基础日志信息
// 使用 debug 可以调试内核相关问题 `debug/pprof`
if (['info', 'debug'].includes(profile['log-level']) === false) {
profile['log-level'] = 'info'
}
runtimeConfig = profile runtimeConfig = profile
// 先正常生成 YAML 字符串 // 先正常生成 YAML 字符串

View File

@ -7,7 +7,8 @@ import {
mihomoProfileWorkDir, mihomoProfileWorkDir,
mihomoTestDir, mihomoTestDir,
mihomoWorkConfigPath, mihomoWorkConfigPath,
mihomoWorkDir mihomoWorkDir,
mihomoIpcPath
} from '../utils/dirs' } from '../utils/dirs'
import { generateProfile } from './factory' import { generateProfile } from './factory'
import { import {
@ -28,16 +29,14 @@ import {
stopMihomoTraffic, stopMihomoTraffic,
stopMihomoLogs, stopMihomoLogs,
stopMihomoMemory, stopMihomoMemory,
patchMihomoConfig mihomoVersion
} from './mihomoApi' } from './mihomoApi'
import chokidar from 'chokidar' import chokidar from 'chokidar'
import { readFile, rm, writeFile } from 'fs/promises' import { readFile, rm, writeFile } from 'fs/promises'
import { promisify } from 'util' import { promisify } from 'util'
import { mainWindow } from '..'
import path from 'path' import path from 'path'
import os from 'os' import os from 'os'
import { createWriteStream, existsSync } from 'fs' import { createWriteStream, existsSync } from 'fs'
import { uploadRuntimeConfig } from '../resolve/gistApi'
import { startMonitor } from '../resolve/trafficMonitor' import { startMonitor } from '../resolve/trafficMonitor'
import { safeShowErrorBox } from '../utils/init' import { safeShowErrorBox } from '../utils/init'
import i18next from '../../shared/i18n' import i18next from '../../shared/i18n'
@ -52,8 +51,6 @@ chokidar.watch(path.join(mihomoCoreDir(), 'meta-update'), {}).on('unlinkDir', as
} }
}) })
export const mihomoIpcPath =
process.platform === 'win32' ? '\\\\.\\pipe\\MihomoParty\\mihomo' : '/tmp/mihomo-party.sock'
const ctlParam = process.platform === 'win32' ? '-ext-ctl-pipe' : '-ext-ctl-unix' const ctlParam = process.platform === 'win32' ? '-ext-ctl-pipe' : '-ext-ctl-unix'
let setPublicDNSTimer: NodeJS.Timeout | null = null let setPublicDNSTimer: NodeJS.Timeout | null = null
@ -72,7 +69,6 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
disableSystemCA = false, disableSystemCA = false,
skipSafePathCheck = false skipSafePathCheck = false
} = await getAppConfig() } = await getAppConfig()
const { 'log-level': logLevel } = await getControledMihomoConfig()
if (existsSync(path.join(dataDir(), 'core.pid'))) { if (existsSync(path.join(dataDir(), 'core.pid'))) {
const pid = parseInt(await readFile(path.join(dataDir(), 'core.pid'), 'utf-8')) const pid = parseInt(await readFile(path.join(dataDir(), 'core.pid'), 'utf-8'))
try { try {
@ -139,50 +135,42 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
}) })
child.stdout?.pipe(stdout) child.stdout?.pipe(stdout)
child.stderr?.pipe(stderr) child.stderr?.pipe(stderr)
try {
await waitForCoreReady()
await managerLogger.info('Core API is ready, starting background services.')
await startMihomoTraffic()
await startMihomoConnections()
await startMihomoLogs()
await startMihomoMemory()
retry = 10
return [Promise.resolve()]
} catch (error) {
await managerLogger.error('Core failed to start or API not responding.', error)
await stopCore() // Stop the failed core process
throw error // Re-throw the error to be caught by the caller
}
}
async function waitForCoreReady(timeoutMs = 15000): Promise<void> {
const startTime = Date.now()
const pollInterval = 1000 // ms
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
child.stdout?.on('data', async (data) => { const poll = setInterval(async () => {
const str = data.toString() if (Date.now() - startTime > timeoutMs) {
if (str.includes('configure tun interface: operation not permitted')) { clearInterval(poll)
patchControledMihomoConfig({ tun: { enable: false } }) reject(new Error(`Core API did not respond within ${timeoutMs / 1000}s.`))
mainWindow?.webContents.send('controledMihomoConfigUpdated') return
ipcMain.emit('updateTrayMenu')
reject(i18next.t('tun.error.tunPermissionDenied'))
} }
if ((process.platform !== 'win32' && str.includes('External controller unix listen error')) || try {
(process.platform === 'win32' && str.includes('External controller pipe listen error')) await mihomoVersion()
) { clearInterval(poll)
reject(i18next.t('mihomo.error.externalControllerListenError')) resolve()
} catch (error) {
// Ignore connection errors and keep polling
} }
}, pollInterval)
if (
(process.platform !== 'win32' && str.includes('RESTful API unix listening at')) ||
(process.platform === 'win32' && str.includes('RESTful API pipe listening at'))
) {
resolve([
new Promise((resolve) => {
child.stdout?.on('data', async (data) => {
if (data.toString().toLowerCase().includes('start initial compatible provider default')) {
try {
mainWindow?.webContents.send('groupsUpdated')
mainWindow?.webContents.send('rulesUpdated')
await uploadRuntimeConfig()
} catch {
// ignore
}
await patchMihomoConfig({ 'log-level': logLevel })
resolve()
}
})
})
])
await startMihomoTraffic()
await startMihomoConnections()
await startMihomoLogs()
await startMihomoMemory()
retry = 10
}
})
}) })
} }

View File

@ -6,7 +6,7 @@ import { tray } from '../resolve/tray'
import { calcTraffic } from '../utils/calc' import { calcTraffic } from '../utils/calc'
import { getRuntimeConfig } from './factory' import { getRuntimeConfig } from './factory'
import { floatingWindow } from '../resolve/floatingWindow' import { floatingWindow } from '../resolve/floatingWindow'
import { mihomoIpcPath } from './manager' import { mihomoIpcPath } from '../utils/dirs'
let axiosIns: AxiosInstance = null! let axiosIns: AxiosInstance = null!
let mihomoTrafficWs: WebSocket | null = null let mihomoTrafficWs: WebSocket | null = null

View File

@ -158,3 +158,6 @@ export function coreLogPath(): string {
const name = `core-${year}-${month}-${day}` const name = `core-${year}-${month}-${day}`
return path.join(logDir(), `${name}.log`) return path.join(logDir(), `${name}.log`)
} }
export const mihomoIpcPath =
process.platform === 'win32' ? '\\\\.\\pipe\\MihomoParty\\mihomo' : '/tmp/mihomo-party.sock'

View File

@ -324,9 +324,6 @@ async function migration(): Promise<void> {
'external-controller-pipe': undefined 'external-controller-pipe': undefined
}) })
} }
if (externalController === undefined) {
await patchControledMihomoConfig({ 'external-controller': '' })
}
if (!showFloatingWindow && disableTray) { if (!showFloatingWindow && disableTray) {
await patchAppConfig({ disableTray: false }) await patchAppConfig({ disableTray: false })
} }

View File

@ -59,8 +59,8 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
'tproxy-port': 0, 'tproxy-port': 0,
'allow-lan': false, 'allow-lan': false,
'unified-delay': true, 'unified-delay': true,
'tcp-concurrent': false, 'tcp-concurrent': true,
'log-level': 'info', 'log-level': 'warning',
'find-process-mode': 'strict', 'find-process-mode': 'strict',
'bind-address': '*', 'bind-address': '*',
'lan-allowed-ips': ['0.0.0.0/0', '::/0'], 'lan-allowed-ips': ['0.0.0.0/0', '::/0'],
@ -80,16 +80,17 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
}, },
dns: { dns: {
enable: true, enable: true,
ipv6: false, ipv6: true,
'enhanced-mode': 'fake-ip', 'enhanced-mode': 'fake-ip',
'fake-ip-range': '198.18.0.1/16', 'fake-ip-range': '198.18.0.1/16',
'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'], 'fake-ip-filter': ['+.lan', '+.local', '+.arpa', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com', 'localhost.ptlogin2.qq.com', '+.msftncsi.com', 'www.msftconnecttest.com'],
'fake-ip-filter-mode': 'blacklist',
'use-hosts': false, 'use-hosts': false,
'use-system-hosts': false, 'use-system-hosts': false,
'respect-rules': false, 'respect-rules': false,
'default-nameserver': ['tls://223.5.5.5'], 'default-nameserver': ['system', '223.6.6.6', '8.8.8.8', '2400:3200::1', '2001:4860:4860::8888'],
nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'], nameserver: ['8.8.8.8', 'https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'], 'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query', 'tls://223.5.5.5'],
'direct-nameserver': [], 'direct-nameserver': [],
fallback: [], fallback: [],
'fallback-filter': { 'fallback-filter': {
@ -137,10 +138,10 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
'geo-update-interval': 24, 'geo-update-interval': 24,
'geodata-mode': false, 'geodata-mode': false,
'geox-url': { 'geox-url': {
geoip: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat', geoip: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip-lite.dat',
geosite: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat', geosite: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat',
mmdb: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb', mmdb: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb',
asn: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb' asn: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/GeoLite2-ASN.mmdb'
} }
} }

View File

@ -1,30 +1,70 @@
const SVGComponent = (props) => ( import React from 'react'
<svg import { GenIcon } from 'react-icons'
viewBox="0 0 123 126.11"
{...props} function MihomoIcon(props: any): React.JSX.Element {
> return GenIcon({
<path tag: 'svg',
className="cls-1" attr: { viewBox: '0 0 128 128' },
d="M123,105.41c0,15.99-13.44,20.46-20.54,20.6h-29.1c5.33-1.74,8.97-5.24,9.18-5.44.05-.05.28-.27.55-.56h19.31c1.44-.04,14.6-.78,14.6-14.6,0-9.22-3.85-21.88-34.64-29.67l-1.47-6.53c28.67,6.6,42.11,18.22,42.11,36.2Z" child: [
/> {
<path tag: 'g',
className="cls-1" attr: {
d="M81.1,37.6c-2.42.76-4.68,1.55-6.78,2.37l-1.33-5.92c2.05-.77,4.21-1.51,6.47-2.21.27,2.03.83,3.96,1.64,5.76Z" transform: 'matrix(-1, 0, 0, 1, 127.931404, 0)'
/> },
<circle className="cls-1" cx={53.83} cy={33.01} r={3} /> child: [
<circle className="cls-1" cx={33.83} cy={33.01} r={3} /> {
<path tag: 'path',
className="cls-1" attr: {
d="M67.53,126.01h-1.49c-1.83,0-3.4-1.54-3.19-3.36.17-1.52,1.4-2.64,2.98-2.64h1.7c4.3,0,8.3-1.9,11-5.3,2.7-3.3,3.6-7.6,2.7-11.8L60.13,8.91l-.4.4c-4.3,4.4-9.9,6.7-15.9,6.7s-11.6-2.3-15.8-6.6l-.5-.4L6.33,103.01c-.9,4.1,0,8.4,2.7,11.8s6.7,5.3,11,5.3h.59c1.83,0,3.4,1.54,3.19,3.36-.17,1.52-1.4,2.64-2.98,2.64h-.8c-6.1,0-11.8-2.7-15.7-7.5-3.8-4.9-5.2-11-3.8-17L22.93,2.31c.2-1.1,1-1.9,2.1-2.2,1-.3,2.2,0,3,.8l4.3,4.3c3,3.1,7.1,4.8,11.5,4.8s8.5-1.7,11.6-4.8l4.24-4.24c.37-.37.81-.68,1.31-.83,1.95-.58,3.56.68,3.86,2.16l22.3,99.3c1.3,5.9-.1,12.1-3.9,16.8-.4.5-1.4,1.5-1.4,1.5,0,0-6.26,6.1-14.3,6.1h0Z" d: 'm121.3 103.3-22.3-99.3-4.3 4.3c-3.7 3.7-8.6 5.7-13.7 5.7s-10-2-13.7-5.7l-4.3-4.3-22.3 99.3c-1 4.3-.2 8.5 1.7 12l-26.9-6.4c-4.8-1.1-9.4 2.6-9.4 7.5 0 4.3 3.5 7.7 7.7 7.7h91c10.8-.1 18.9-10.2 16.5-20.8z',
/> fill: '#fff',
<path strokeWidth: '6'
className="cls-1" },
d="M22.23,70.11c1.6-.3,3.2.7,3.5,2.4l9,45.1c.3,1.5,1.5,2.5,3,2.5,1.7,0,3-1.3,3-3v-34.1c0-1.7,1.3-3,3-3s3,1.3,3,3v34c0,1.6,1.4,3,3.1,3h1c1.5,0,2.7-1,3-2.5l9.1-45.1c.3-1.6,1.9-2.7,3.5-2.3,1.6.3,2.7,1.9,2.3,3.5l-9.1,45c-.7,4.3-4.5,7.4-8.9,7.4h-1c-2.3,0-4.5-.9-6.1-2.3-1.6,1.4-3.7,2.3-6,2.3-4.3,0-7.9-3-8.8-7.3l-9-45.1c-.3-1.6.8-3.2,2.4-3.5Z" child: []
/> },
<path {
className="cls-1" tag: 'circle',
d="M100.75,7.39c-11.85,0-21.5,9.64-21.5,21.5,0,1,.07,1.99.21,2.95.27,2.03.83,3.96,1.64,5.76,3.35,7.53,10.9,12.79,19.65,12.79,11.86,0,21.5-9.65,21.5-21.5s-9.64-21.5-21.5-21.5ZM100.75,45.39c-9.1,0-16.5-7.4-16.5-16.5s7.4-16.5,16.5-16.5,16.5,7.4,16.5,16.5-7.4,16.5-16.5,16.5Z" attr: {
/> cx: '71',
</svg> cy: '34',
); fill: '#444b54',
export default SVGComponent; r: '3',
strokeWidth: '6'
},
child: []
},
{
tag: 'circle',
attr: {
cx: '91',
cy: '34',
fill: '#444b54',
r: '3',
strokeWidth: '6'
},
child: []
},
{
tag: 'path',
attr: {
d: 'm124.3 102.6-22.4-99.3c-.2-1.1-1-1.9-2.1-2.2-1-.3-2.2 0-3 .8l-4.3 4.3c-3 3.1-7.1 4.8-11.5 4.8s-8.5-1.7-11.6-4.8l-4.3-4.3c-.8-.8-1.9-1.1-3-.8s-1.9 1.2-2.1 2.2l-22.3 99.3c-1.3 5.9.1 12.1 3.9 16.8.4.5.9 1 1.4 1.5h-29.3c-2.6 0-4.7-2.1-4.7-4.7 0-1.4.6-2.8 1.8-3.7 1.1-.9 2.6-1.2 4-.9l11.9 2.8c1.6.4 3.2-.6 3.6-2.2s-.6-3.2-2.2-3.6l-11.9-2.8c-3.2-.7-6.5 0-9.1 2.1-2.6 2-4 5.1-4 8.4 0 5.9 4.8 10.7 10.7 10.7h43.5.1 1.6c1.7 0 3-1.3 3-3s-1.3-3-3-3h-1.7c-4.3 0-8.3-1.9-11-5.3-2.7-3.3-3.6-7.6-2.7-11.8l21.1-94 .4.4c4.3 4.4 9.9 6.7 15.9 6.7s11.6-2.3 15.8-6.6l.5-.4 21.2 94c.9 4.1 0 8.4-2.7 11.8s-6.7 5.3-11 5.3h-.8c-1.7 0-3 1.3-3 3s1.3 3 3 3h.8c6.1 0 11.8-2.7 15.7-7.5 3.8-4.9 5.2-11 3.8-17z',
fill: '#444b54',
strokeWidth: '6'
},
child: []
},
{
tag: 'path',
attr: {
d: 'm102.6 71.1c-1.6-.3-3.2.7-3.5 2.4l-9 45.1c-.3 1.5-1.5 2.5-3 2.5-1.7 0-3-1.3-3-3v-34.1c0-1.7-1.3-3-3-3s-3 1.3-3 3v34c0 1.6-1.4 3-3.1 3h-1c-1.5 0-2.7-1-3-2.5l-9.1-45.1c-.3-1.6-1.9-2.7-3.5-2.3-1.6.3-2.7 1.9-2.3 3.5l9.1 45c.7 4.3 4.5 7.4 8.9 7.4h1c2.3 0 4.5-.9 6.1-2.3 1.6 1.4 3.7 2.3 6 2.3 4.3 0 7.9-3 8.8-7.3l9-45.1c.3-1.6-.8-3.2-2.4-3.5z',
fill: '#444b54',
strokeWidth: '6'
},
child: []
}
]
}
]
})(props)
}
export default MihomoIcon

View File

@ -17,25 +17,30 @@ const DNS: React.FC = () => {
const { dns, hosts } = controledMihomoConfig || {} const { dns, hosts } = controledMihomoConfig || {}
const { const {
enable = true, enable = true,
ipv6 = false, ipv6 = true,
'fake-ip-range': fakeIPRange = '198.18.0.1/16', 'fake-ip-range': fakeIPRange = '198.18.0.1/16',
'fake-ip-filter': fakeIPFilter = [ 'fake-ip-filter': fakeIPFilter = [
'*',
'+.lan', '+.lan',
'+.local', '+.local',
'+.arpa',
'time.*.com', 'time.*.com',
'ntp.*.com', 'ntp.*.com',
'+.market.xiaomi.com' '+.market.xiaomi.com',
'localhost.ptlogin2.qq.com',
'+.msftncsi.com',
'www.msftconnecttest.com'
], ],
'fake-ip-filter-mode': fakeIPFilterMode = 'blacklist',
'enhanced-mode': enhancedMode = 'fake-ip', 'enhanced-mode': enhancedMode = 'fake-ip',
'use-hosts': useHosts = false, 'use-hosts': useHosts = false,
'use-system-hosts': useSystemHosts = false, 'use-system-hosts': useSystemHosts = false,
'respect-rules': respectRules = false, 'respect-rules': respectRules = false,
'default-nameserver': defaultNameserver = ['tls://223.5.5.5'], 'default-nameserver': defaultNameserver = ['system', '223.6.6.6', '8.8.8.8', '2400:3200::1', '2001:4860:4860::8888'],
nameserver = ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'], nameserver = ['8.8.8.8', 'https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': proxyServerNameserver = [ 'proxy-server-nameserver': proxyServerNameserver = [
'https://doh.pub/dns-query', 'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query' 'https://dns.alidns.com/dns-query',
'tls://223.5.5.5'
], ],
'direct-nameserver': directNameserver = [], 'direct-nameserver': directNameserver = [],
fallback = [], fallback = [],
@ -54,6 +59,7 @@ const DNS: React.FC = () => {
enhancedMode, enhancedMode,
fakeIPRange, fakeIPRange,
fakeIPFilter, fakeIPFilter,
fakeIPFilterMode,
useSystemHosts, useSystemHosts,
respectRules, respectRules,
defaultNameserver, defaultNameserver,
@ -61,10 +67,10 @@ const DNS: React.FC = () => {
proxyServerNameserver, proxyServerNameserver,
directNameserver, directNameserver,
fallback, fallback,
fallbackGeoip: fallbackFilter?.geoip || true, fallbackGeoip: fallbackFilter.geoip,
fallbackGeoipCode: fallbackFilter?.['geoip-code'] || 'CN', fallbackGeoipCode: fallbackFilter['geoip-code'],
fallbackIpcidr: fallbackFilter?.ipcidr || ['240.0.0.0/4', '0.0.0.0/32'], fallbackIpcidr: fallbackFilter.ipcidr,
fallbackDomain: fallbackFilter?.domain || ['+.google.com', '+.facebook.com', '+.youtube.com'], fallbackDomain: fallbackFilter.domain,
useNameserverPolicy, useNameserverPolicy,
nameserverPolicy: Object.entries(nameserverPolicy || {}).map(([domain, value]) => ({ nameserverPolicy: Object.entries(nameserverPolicy || {}).map(([domain, value]) => ({
domain, domain,

View File

@ -49,7 +49,7 @@ const Mihomo: React.FC = () => {
secret, secret,
authentication = [], authentication = [],
'skip-auth-prefixes': skipAuthPrefixes = ['127.0.0.1/32', '::1/128'], 'skip-auth-prefixes': skipAuthPrefixes = ['127.0.0.1/32', '::1/128'],
'log-level': logLevel = 'info', 'log-level': logLevel = 'warning',
'find-process-mode': findProcessMode = 'strict', 'find-process-mode': findProcessMode = 'strict',
'allow-lan': allowLan, 'allow-lan': allowLan,
'lan-allowed-ips': lanAllowedIps = ['0.0.0.0/0', '::/0'], 'lan-allowed-ips': lanAllowedIps = ['0.0.0.0/0', '::/0'],

View File

@ -354,7 +354,12 @@ interface IMihomoDNSConfig {
'default-nameserver'?: string[] 'default-nameserver'?: string[]
nameserver?: string[] nameserver?: string[]
fallback?: string[] fallback?: string[]
'fallback-filter'?: { [key: string]: boolean | string | string[] } 'fallback-filter'?: {
geoip?: boolean
'geoip-code'?: string
ipcidr?: string[]
domain?: string[]
}
'proxy-server-nameserver'?: string[] 'proxy-server-nameserver'?: string[]
'direct-nameserver'?: string[] 'direct-nameserver'?: string[]
'direct-nameserver-follow-policy'?: boolean 'direct-nameserver-follow-policy'?: boolean