mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-04-12 23:50:31 +08:00
fix: apply smart override after rule override
This commit is contained in:
parent
48e3f5120e
commit
e336b3c88d
@ -131,11 +131,11 @@ function main(config) {
|
|||||||
// 找到策略组名称的位置
|
// 找到策略组名称的位置
|
||||||
let targetIndex = -1
|
let targetIndex = -1
|
||||||
|
|
||||||
// MATCH 规则:MATCH,策略组
|
// MATCH 规则:MATCH,策略组
|
||||||
if (parts[0] === 'MATCH' && parts.length === 2) {
|
if (parts[0] === 'MATCH' && parts.length === 2) {
|
||||||
targetIndex = 1
|
targetIndex = 1
|
||||||
} else if (parts.length >= 3) {
|
} else if (parts.length >= 3) {
|
||||||
// 其他规则:TYPE,MATCHER,策略组[,参数...]
|
// 其他规则:TYPE,MATCHER,策略组 [,参数...]
|
||||||
// 策略组通常在第 3 个位置(索引 2),但需要跳过参数
|
// 策略组通常在第 3 个位置(索引 2),但需要跳过参数
|
||||||
for (let i = 2; i < parts.length; i++) {
|
for (let i = 2; i < parts.length; i++) {
|
||||||
if (!ruleParamsSet.has(parts[i])) {
|
if (!ruleParamsSet.has(parts[i])) {
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import { deepMerge } from '../utils/merge'
|
|||||||
import { createLogger } from '../utils/logger'
|
import { createLogger } from '../utils/logger'
|
||||||
|
|
||||||
const factoryLogger = createLogger('Factory')
|
const factoryLogger = createLogger('Factory')
|
||||||
|
const SMART_OVERRIDE_ID = 'smart-core-override'
|
||||||
|
|
||||||
let runtimeConfigStr: string = ''
|
let runtimeConfigStr: string = ''
|
||||||
let runtimeConfig: IMihomoConfig = {} as IMihomoConfig
|
let runtimeConfig: IMihomoConfig = {} as IMihomoConfig
|
||||||
@ -68,7 +69,11 @@ export async function generateProfile(): Promise<string | undefined> {
|
|||||||
controlSniff = true,
|
controlSniff = true,
|
||||||
useNameserverPolicy
|
useNameserverPolicy
|
||||||
} = await getAppConfig()
|
} = await getAppConfig()
|
||||||
const currentProfile = await overrideProfile(current, await getProfile(current))
|
const baseProfile = await getProfile(current)
|
||||||
|
const overrideIds = await getOrderedOverrideIds(current)
|
||||||
|
const profileWithNormalOverride = await applyOverrides(baseProfile, overrideIds.normal)
|
||||||
|
const profileWithRuleOverride = await applyRuleOverride(current, profileWithNormalOverride)
|
||||||
|
const currentProfile = await applyOverrides(profileWithRuleOverride, overrideIds.smart)
|
||||||
let controledMihomoConfig = await getControledMihomoConfig()
|
let controledMihomoConfig = await getControledMihomoConfig()
|
||||||
|
|
||||||
// 根据开关状态过滤控制配置
|
// 根据开关状态过滤控制配置
|
||||||
@ -84,60 +89,6 @@ export async function generateProfile(): Promise<string | undefined> {
|
|||||||
delete controledMihomoConfig?.dns?.['nameserver-policy']
|
delete controledMihomoConfig?.dns?.['nameserver-policy']
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用规则文件
|
|
||||||
try {
|
|
||||||
const ruleFilePath = rulePath(current || 'default')
|
|
||||||
if (existsSync(ruleFilePath)) {
|
|
||||||
const ruleFileContent = await readFile(ruleFilePath, 'utf-8')
|
|
||||||
const ruleData = parse(ruleFileContent) as {
|
|
||||||
prepend?: string[]
|
|
||||||
append?: string[]
|
|
||||||
delete?: string[]
|
|
||||||
} | null
|
|
||||||
|
|
||||||
if (ruleData && typeof ruleData === 'object') {
|
|
||||||
// 确保 rules 数组存在
|
|
||||||
if (!currentProfile.rules) {
|
|
||||||
currentProfile.rules = [] as unknown as []
|
|
||||||
}
|
|
||||||
|
|
||||||
let rules = [...currentProfile.rules] as unknown as string[]
|
|
||||||
|
|
||||||
// 处理前置规则
|
|
||||||
if (ruleData.prepend?.length) {
|
|
||||||
const { normalRules: prependRules, insertRules } = processRulesWithOffset(
|
|
||||||
ruleData.prepend,
|
|
||||||
rules
|
|
||||||
)
|
|
||||||
rules = [...prependRules, ...insertRules]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理后置规则
|
|
||||||
if (ruleData.append?.length) {
|
|
||||||
const { normalRules: appendRules, insertRules } = processRulesWithOffset(
|
|
||||||
ruleData.append,
|
|
||||||
rules,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
rules = [...insertRules, ...appendRules]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理删除规则
|
|
||||||
if (ruleData.delete?.length) {
|
|
||||||
const deleteSet = new Set(ruleData.delete)
|
|
||||||
rules = rules.filter((rule) => {
|
|
||||||
const ruleStr = Array.isArray(rule) ? rule.join(',') : rule
|
|
||||||
return !deleteSet.has(ruleStr)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
currentProfile.rules = rules as unknown as []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
factoryLogger.error('Failed to read or apply rule file', error)
|
|
||||||
}
|
|
||||||
|
|
||||||
const profile = deepMerge(currentProfile, controledMihomoConfig)
|
const profile = deepMerge(currentProfile, controledMihomoConfig)
|
||||||
// 确保可以拿到基础日志信息
|
// 确保可以拿到基础日志信息
|
||||||
// 使用 debug 可以调试内核相关问题 `debug/pprof`
|
// 使用 debug 可以调试内核相关问题 `debug/pprof`
|
||||||
@ -160,6 +111,66 @@ export async function generateProfile(): Promise<string | undefined> {
|
|||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function applyRuleOverride(
|
||||||
|
current: string | undefined,
|
||||||
|
profile: IMihomoConfig
|
||||||
|
): Promise<IMihomoConfig> {
|
||||||
|
try {
|
||||||
|
const ruleFilePath = rulePath(current || 'default')
|
||||||
|
if (!existsSync(ruleFilePath)) {
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
const ruleFileContent = await readFile(ruleFilePath, 'utf-8')
|
||||||
|
const ruleData = parse(ruleFileContent) as {
|
||||||
|
prepend?: string[]
|
||||||
|
append?: string[]
|
||||||
|
delete?: string[]
|
||||||
|
} | null
|
||||||
|
|
||||||
|
if (!ruleData || typeof ruleData !== 'object') {
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profile.rules) {
|
||||||
|
profile.rules = [] as unknown as []
|
||||||
|
}
|
||||||
|
|
||||||
|
let rules = [...profile.rules] as unknown as string[]
|
||||||
|
|
||||||
|
if (ruleData.prepend?.length) {
|
||||||
|
const { normalRules: prependRules, insertRules } = processRulesWithOffset(
|
||||||
|
ruleData.prepend,
|
||||||
|
rules
|
||||||
|
)
|
||||||
|
rules = [...prependRules, ...insertRules]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ruleData.append?.length) {
|
||||||
|
const { normalRules: appendRules, insertRules } = processRulesWithOffset(
|
||||||
|
ruleData.append,
|
||||||
|
rules,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
rules = [...insertRules, ...appendRules]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ruleData.delete?.length) {
|
||||||
|
const deleteSet = new Set(ruleData.delete)
|
||||||
|
rules = rules.filter((rule) => {
|
||||||
|
const ruleStr = Array.isArray(rule) ? rule.join(',') : rule
|
||||||
|
return !deleteSet.has(ruleStr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.rules = rules as unknown as []
|
||||||
|
return profile
|
||||||
|
} catch (error) {
|
||||||
|
factoryLogger.error('Failed to read or apply rule file', error)
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function prepareProfileWorkDir(current: string | undefined): Promise<void> {
|
async function prepareProfileWorkDir(current: string | undefined): Promise<void> {
|
||||||
if (!existsSync(mihomoProfileWorkDir(current))) {
|
if (!existsSync(mihomoProfileWorkDir(current))) {
|
||||||
await mkdir(mihomoProfileWorkDir(current), { recursive: true })
|
await mkdir(mihomoProfileWorkDir(current), { recursive: true })
|
||||||
@ -193,14 +204,26 @@ async function prepareProfileWorkDir(current: string | undefined): Promise<void>
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function overrideProfile(
|
async function getOrderedOverrideIds(current: string | undefined): Promise<{
|
||||||
current: string | undefined,
|
normal: string[]
|
||||||
profile: IMihomoConfig
|
smart: string[]
|
||||||
): Promise<IMihomoConfig> {
|
}> {
|
||||||
const { items = [] } = (await getOverrideConfig()) || {}
|
const { items = [] } = (await getOverrideConfig()) || {}
|
||||||
const globalOverride = items.filter((item) => item.global).map((item) => item.id)
|
const globalOverride = items.filter((item) => item.global).map((item) => item.id)
|
||||||
const { override = [] } = (await getProfileItem(current)) || {}
|
const { override = [] } = (await getProfileItem(current)) || {}
|
||||||
for (const ov of new Set(globalOverride.concat(override))) {
|
const orderedOverrideIds = [...new Set(globalOverride.concat(override))]
|
||||||
|
|
||||||
|
return {
|
||||||
|
normal: orderedOverrideIds.filter((id) => id !== SMART_OVERRIDE_ID),
|
||||||
|
smart: orderedOverrideIds.filter((id) => id === SMART_OVERRIDE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyOverrides(
|
||||||
|
profile: IMihomoConfig,
|
||||||
|
overrideIds: string[]
|
||||||
|
): Promise<IMihomoConfig> {
|
||||||
|
for (const ov of overrideIds) {
|
||||||
const item = await getOverrideItem(ov)
|
const item = await getOverrideItem(ov)
|
||||||
const content = await getOverride(ov, item?.ext || 'js')
|
const content = await getOverride(ov, item?.ext || 'js')
|
||||||
switch (item?.ext) {
|
switch (item?.ext) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user