fix: dns/sniffer override logic

This commit is contained in:
ezequielnick 2025-08-06 17:21:51 +08:00
parent 73161d0cc2
commit 45484ffff2
7 changed files with 60 additions and 37 deletions

View File

@ -20,23 +20,7 @@ export async function getControledMihomoConfig(force = false): Promise<Partial<I
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
const { useNameserverPolicy, controlDns = true, controlSniff = true } = await getAppConfig()
if (!controlDns) {
delete controledMihomoConfig.dns
delete controledMihomoConfig.hosts
} else {
// 从不接管状态恢复
if (controledMihomoConfig.dns?.ipv6 === undefined) {
controledMihomoConfig.dns = defaultControledMihomoConfig.dns
}
}
if (!controlSniff) {
delete controledMihomoConfig.sniffer
} else {
// 从不接管状态恢复
if (!controledMihomoConfig.sniffer) {
controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer
}
}
if (patch.hosts) {
controledMihomoConfig.hosts = patch.hosts
}
@ -45,12 +29,37 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
controledMihomoConfig.dns['nameserver-policy'] = patch.dns['nameserver-policy']
}
controledMihomoConfig = deepMerge(controledMihomoConfig, patch)
// 覆写开关控制
let configForProfile = { ...controledMihomoConfig }
if (!controlDns) {
delete configForProfile.dns
delete configForProfile.hosts
} else {
if (configForProfile.dns?.ipv6 === undefined) {
configForProfile.dns = defaultControledMihomoConfig.dns
}
}
if (!controlSniff) {
delete configForProfile.sniffer
} else {
if (!configForProfile.sniffer) {
configForProfile.sniffer = defaultControledMihomoConfig.sniffer
}
}
if (!useNameserverPolicy) {
delete controledMihomoConfig?.dns?.['nameserver-policy']
delete configForProfile?.dns?.['nameserver-policy']
}
if (process.platform === 'darwin') {
delete controledMihomoConfig?.tun?.device
delete configForProfile?.tun?.device
}
const originalConfig = controledMihomoConfig
controledMihomoConfig = configForProfile
await generateProfile()
controledMihomoConfig = originalConfig
await writeFile(controledMihomoConfigPath(), yaml.stringify(controledMihomoConfig), 'utf-8')
}

View File

@ -285,6 +285,7 @@
"sniffer.skipDstAddress.placeholder": "Example: 1.1.1.1/32",
"sniffer.skipSrcAddress.title": "Skip Source Address Sniffing",
"sniffer.skipSrcAddress.placeholder": "Example: 192.168.1.1/24",
"sniffer.saveOnly": "Save Only",
"sysproxy.title": "System Proxy",
"sysproxy.host.title": "Proxy Host",
"sysproxy.host.placeholder": "Default 127.0.0.1, do not modify unless necessary",
@ -343,6 +344,7 @@
"dns.customHosts.list": "Hosts List",
"dns.customHosts.domainPlaceholder": "Domain",
"dns.customHosts.valuePlaceholder": "Domain or IP",
"dns.saveOnly": "Save Only",
"profiles.title": "Profile Management",
"profiles.updateAll": "Update All Profiles",
"profiles.useProxy": "Proxy",

View File

@ -276,6 +276,7 @@
"sniffer.skipDstAddress.placeholder": "مثال: 1.1.1.1/32",
"sniffer.skipSrcAddress.title": "رد کردن تشخیص آدرس مبدا",
"sniffer.skipSrcAddress.placeholder": "مثال: 192.168.1.1/24",
"sniffer.saveOnly": "فقط ذخیره",
"sysproxy.title": "پراکسی سیستم",
"sysproxy.host.title": "میزبان پراکسی",
"sysproxy.host.placeholder": "پیش‌فرض 127.0.0.1، در صورت عدم نیاز تغییر ندهید",
@ -334,6 +335,7 @@
"dns.customHosts.list": "لیست Hosts",
"dns.customHosts.domainPlaceholder": "دامنه",
"dns.customHosts.valuePlaceholder": "دامنه یا IP",
"dns.saveOnly": "فقط ذخیره",
"profiles.title": "مدیریت پروفایل",
"profiles.updateAll": "به‌روزرسانی همه پروفایل‌ها",
"profiles.useProxy": "پراکسی",

View File

@ -276,6 +276,7 @@
"sniffer.skipDstAddress.placeholder": "Пример: 1.1.1.1/32",
"sniffer.skipSrcAddress.title": "Пропустить анализ исходных адресов",
"sniffer.skipSrcAddress.placeholder": "Пример: 192.168.1.1/24",
"sniffer.saveOnly": "Только сохранить",
"sysproxy.title": "Системный прокси",
"sysproxy.host.title": "Хост прокси",
"sysproxy.host.placeholder": "По умолчанию 127.0.0.1, не изменяйте без необходимости",
@ -334,6 +335,7 @@
"dns.customHosts.list": "Список Hosts",
"dns.customHosts.domainPlaceholder": "Домен",
"dns.customHosts.valuePlaceholder": "Домен или IP",
"dns.saveOnly": "Только сохранить",
"profiles.title": "Управление профилями",
"profiles.updateAll": "Обновить все профили",
"profiles.useProxy": "Прокси",

View File

@ -285,6 +285,7 @@
"sniffer.skipDstAddress.placeholder": "例1.1.1.1/32",
"sniffer.skipSrcAddress.title": "跳过来源地址嗅探",
"sniffer.skipSrcAddress.placeholder": "例192.168.1.1/24",
"sniffer.saveOnly": "仅保存",
"sysproxy.title": "系统代理",
"sysproxy.host.title": "代理主机",
"sysproxy.host.placeholder": "默认 127.0.0.1 若无特殊需求请勿修改",
@ -343,6 +344,7 @@
"dns.customHosts.list": "Hosts 列表",
"dns.customHosts.domainPlaceholder": "域名",
"dns.customHosts.valuePlaceholder": "域名或 IP",
"dns.saveOnly": "仅保存",
"profiles.title": "订阅管理",
"profiles.updateAll": "更新全部订阅",
"profiles.useProxy": "代理",

View File

@ -13,7 +13,7 @@ const DNS: React.FC = () => {
const { t } = useTranslation()
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
const { appConfig, patchAppConfig } = useAppConfig()
const { nameserverPolicy, useNameserverPolicy } = appConfig || {}
const { nameserverPolicy, useNameserverPolicy, controlDns = true } = appConfig || {}
const { dns, hosts } = controledMihomoConfig || {}
const {
enable = true,
@ -128,8 +128,10 @@ const DNS: React.FC = () => {
try {
setChanged(false)
await patchControledMihomoConfig(patch)
if (controlDns) {
await patchMihomoConfig(patch)
await restartCore()
}
} catch (e) {
alert(e)
}
@ -175,7 +177,7 @@ const DNS: React.FC = () => {
onSave(result)
}}
>
{t('common.save')}
{controlDns ? t('common.save') : t('dns.saveOnly')}
</Button>
)
}

View File

@ -3,7 +3,8 @@ import BasePage from '@renderer/components/base/base-page'
import SettingCard from '@renderer/components/base/base-setting-card'
import SettingItem from '@renderer/components/base/base-setting-item'
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
import { restartCore } from '@renderer/utils/ipc'
import { useAppConfig } from '@renderer/hooks/use-app-config'
import { restartCore, patchMihomoConfig } from '@renderer/utils/ipc'
import React, { ReactNode, useState } from 'react'
import { MdDeleteForever } from 'react-icons/md'
import { useTranslation } from 'react-i18next'
@ -11,6 +12,8 @@ import { useTranslation } from 'react-i18next'
const Sniffer: React.FC = () => {
const { t } = useTranslation()
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
const { appConfig } = useAppConfig()
const { controlSniff = true } = appConfig || {}
const { sniffer } = controledMihomoConfig || {}
const {
enable = true,
@ -42,6 +45,7 @@ const Sniffer: React.FC = () => {
} = sniffer || {}
const [changed, setChanged] = useState(false)
const [values, originSetValues] = useState({
enable,
parsePureIP,
forceDNSMapping,
overrideDestination,
@ -60,16 +64,11 @@ const Sniffer: React.FC = () => {
try {
setChanged(false)
await patchControledMihomoConfig(patch)
await restartCore()
} catch (e) {
alert(e)
}
}
const onEnableChange = async (enable: boolean): Promise<void> => {
try {
await patchControledMihomoConfig({ sniffer: { enable } })
if (controlSniff) {
await patchMihomoConfig(patch)
await restartCore()
}
} catch (e) {
alert(e)
}
@ -140,17 +139,20 @@ const Sniffer: React.FC = () => {
onPress={() =>
onSave({
sniffer: {
enable: values.enable,
'parse-pure-ip': values.parsePureIP,
'force-dns-mapping': values.forceDNSMapping,
'override-destination': values.overrideDestination,
sniff: values.sniff,
'skip-domain': values.skipDomain,
'force-domain': values.forceDomain
'force-domain': values.forceDomain,
'skip-dst-address': values.skipDstAddress,
'skip-src-address': values.skipSrcAddress
}
})
}
>
{t('common.save')}
{controlSniff ? t('common.save') : t('sniffer.saveOnly')}
</Button>
)
}
@ -159,8 +161,10 @@ const Sniffer: React.FC = () => {
<SettingItem title={t('sniffer.enable')} divider>
<Switch
size="sm"
isSelected={enable}
onValueChange={onEnableChange}
isSelected={values.enable}
onValueChange={(v) => {
setValues({ ...values, enable: v })
}}
/>
</SettingItem>
<SettingItem title={t('sniffer.overrideDestination')} divider>