mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/mihomo-party-org/clash-party.git
synced 2026-09-20 08:03:39 +08:00
fix: support provider proxies after mihomo api change
This commit is contained in:
@@ -238,31 +238,95 @@ export const mihomoProxies = async (): Promise<IMihomoProxies> => {
|
||||
return proxies
|
||||
}
|
||||
|
||||
function isMihomoGroup(proxy: IMihomoProxy | IMihomoGroup | undefined): proxy is IMihomoGroup {
|
||||
return Boolean(proxy && 'all' in proxy)
|
||||
}
|
||||
|
||||
const PROVIDER_DETAIL_FETCH_THRESHOLD = 8
|
||||
|
||||
async function mihomoProxyProvider(name: string): Promise<IMihomoProxyProvider> {
|
||||
const instance = await getAxios()
|
||||
return await instance.get(`/providers/proxies/${encodeURIComponent(name)}`)
|
||||
}
|
||||
|
||||
async function resolveProviderProxies(
|
||||
names: Set<string>,
|
||||
providerNames: Set<string>,
|
||||
fallbackToAllProviders: boolean
|
||||
): Promise<Record<string, IMihomoProxy>> {
|
||||
if (names.size === 0) return {}
|
||||
|
||||
const providers =
|
||||
fallbackToAllProviders || providerNames.size > PROVIDER_DETAIL_FETCH_THRESHOLD
|
||||
? Object.values((await mihomoProxyProviders()).providers)
|
||||
: (
|
||||
await Promise.allSettled([...providerNames].map((name) => mihomoProxyProvider(name)))
|
||||
).flatMap((result) => (result.status === 'fulfilled' ? [result.value] : []))
|
||||
|
||||
const providerProxies: Record<string, IMihomoProxy> = {}
|
||||
providers.forEach((provider) => {
|
||||
provider.proxies?.forEach((proxy) => {
|
||||
if (names.has(proxy.name)) {
|
||||
providerProxies[proxy.name] = proxy
|
||||
}
|
||||
})
|
||||
})
|
||||
return providerProxies
|
||||
}
|
||||
|
||||
export const mihomoGroups = async (): Promise<IMihomoMixedGroup[]> => {
|
||||
const { mode = 'rule' } = await getControledMihomoConfig()
|
||||
if (mode === 'direct') return []
|
||||
const proxies = await mihomoProxies()
|
||||
const runtime = await getRuntimeConfig()
|
||||
const groups: IMihomoMixedGroup[] = []
|
||||
runtime?.['proxy-groups']?.forEach((group: { name: string; url?: string }) => {
|
||||
const { name, url } = group
|
||||
if (proxies.proxies[name] && 'all' in proxies.proxies[name] && !proxies.proxies[name].hidden) {
|
||||
const newGroup = proxies.proxies[name]
|
||||
newGroup.testUrl = url
|
||||
const newAll = (newGroup.all || []).map((name) => proxies.proxies[name])
|
||||
groups.push({ ...newGroup, all: newAll })
|
||||
const [proxies, runtime] = await Promise.all([mihomoProxies(), getRuntimeConfig()])
|
||||
const rawGroups: { group: IMihomoGroup; providers: string[] }[] = []
|
||||
|
||||
runtime?.['proxy-groups']?.forEach((group: { name: string; url?: string; use?: string[] }) => {
|
||||
const proxy = proxies.proxies[group.name]
|
||||
if (isMihomoGroup(proxy) && !proxy.hidden) {
|
||||
rawGroups.push({ group: { ...proxy, testUrl: group.url }, providers: group.use || [] })
|
||||
}
|
||||
})
|
||||
if (!groups.find((group) => group.name === 'GLOBAL')) {
|
||||
const newGlobal = proxies.proxies['GLOBAL'] as IMihomoGroup
|
||||
if (!newGlobal.hidden) {
|
||||
const newAll = (newGlobal.all || []).map((name) => proxies.proxies[name])
|
||||
groups.push({ ...newGlobal, all: newAll })
|
||||
|
||||
if (!rawGroups.find(({ group }) => group.name === 'GLOBAL')) {
|
||||
const global = proxies.proxies['GLOBAL']
|
||||
if (isMihomoGroup(global) && !global.hidden) {
|
||||
rawGroups.push({ group: global, providers: [] })
|
||||
}
|
||||
}
|
||||
|
||||
const missingProxyNames = new Set<string>()
|
||||
const providerNames = new Set<string>()
|
||||
let fallbackToAllProviders = false
|
||||
rawGroups.forEach(({ group, providers }) => {
|
||||
const proxyNames = group.all || []
|
||||
proxyNames.forEach((name) => {
|
||||
if (!proxies.proxies[name]) {
|
||||
missingProxyNames.add(name)
|
||||
if (providers.length > 0) {
|
||||
providers.forEach((provider) => providerNames.add(provider))
|
||||
} else {
|
||||
fallbackToAllProviders = true
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const providerProxies = await resolveProviderProxies(
|
||||
missingProxyNames,
|
||||
providerNames,
|
||||
fallbackToAllProviders
|
||||
)
|
||||
const groups: IMihomoMixedGroup[] = []
|
||||
rawGroups.forEach(({ group }) => {
|
||||
const newAll = (group.all || [])
|
||||
.map((name) => proxies.proxies[name] || providerProxies[name])
|
||||
.filter((proxy): proxy is IMihomoProxy | IMihomoGroup => Boolean(proxy))
|
||||
groups.push({ ...group, all: newAll })
|
||||
})
|
||||
|
||||
if (mode === 'global') {
|
||||
const global = groups.findIndex((group) => group.name === 'GLOBAL')
|
||||
groups.unshift(groups.splice(global, 1)[0])
|
||||
if (global > 0) groups.unshift(groups.splice(global, 1)[0])
|
||||
}
|
||||
return groups
|
||||
}
|
||||
@@ -302,11 +366,18 @@ export const mihomoUpgradeGeo = async (): Promise<void> => {
|
||||
return await instance.post('/configs/geo')
|
||||
}
|
||||
|
||||
export const mihomoProxyDelay = async (proxy: string, url?: string): Promise<IMihomoDelay> => {
|
||||
export const mihomoProxyDelay = async (
|
||||
proxy: string,
|
||||
url?: string,
|
||||
provider?: string
|
||||
): Promise<IMihomoDelay> => {
|
||||
const appConfig = await getAppConfig()
|
||||
const { delayTestUrl, delayTestTimeout } = appConfig
|
||||
const instance = await getAxios()
|
||||
return await instance.get(`/proxies/${encodeURIComponent(proxy)}/delay`, {
|
||||
const path = provider
|
||||
? `/providers/proxies/${encodeURIComponent(provider)}/${encodeURIComponent(proxy)}/healthcheck`
|
||||
: `/proxies/${encodeURIComponent(proxy)}/delay`
|
||||
return await instance.get(path, {
|
||||
params: {
|
||||
url: delayTestUrl || url || 'https://www.gstatic.com/generate_204',
|
||||
timeout: delayTestTimeout || 5000
|
||||
|
||||
@@ -7,7 +7,7 @@ import { KeyedMutator } from 'swr'
|
||||
|
||||
interface Props {
|
||||
mutateProxies: KeyedMutator<IMihomoMixedGroup[]>
|
||||
onProxyDelay: (proxy: string, url?: string) => Promise<IMihomoDelay>
|
||||
onProxyDelay: (proxy: IMihomoProxy | IMihomoGroup, url?: string) => Promise<IMihomoDelay>
|
||||
proxyDisplayMode: 'simple' | 'full'
|
||||
proxy: IMihomoProxy | IMihomoGroup
|
||||
group: IMihomoMixedGroup
|
||||
@@ -55,11 +55,11 @@ const ProxyItemBase: React.FC<Props> = (props) => {
|
||||
|
||||
const onDelay = useCallback((): void => {
|
||||
setLoading(true)
|
||||
onProxyDelay(proxy.name, group.testUrl).finally(() => {
|
||||
onProxyDelay(proxy, group.testUrl).finally(() => {
|
||||
mutateProxies()
|
||||
setLoading(false)
|
||||
})
|
||||
}, [proxy.name, group.testUrl, onProxyDelay, mutateProxies])
|
||||
}, [proxy, group.testUrl, onProxyDelay, mutateProxies])
|
||||
|
||||
const fixed = useMemo(() => group.fixed && group.fixed === proxy.name, [group.fixed, proxy.name])
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ import { useTranslation } from 'react-i18next'
|
||||
|
||||
const GROUP_EXPAND_STATE_KEY = 'proxy_group_expand_state'
|
||||
|
||||
function getProviderName(proxy: IMihomoProxy | IMihomoGroup): string | undefined {
|
||||
return 'provider-name' in proxy ? proxy['provider-name'] : undefined
|
||||
}
|
||||
|
||||
// 自定义 hook 用于管理展开状态
|
||||
const useProxyState = (
|
||||
groups: IMihomoMixedGroup[]
|
||||
@@ -191,9 +195,12 @@ const Proxies: React.FC = () => {
|
||||
[autoCloseConnection, mutate]
|
||||
)
|
||||
|
||||
const onProxyDelay = useCallback(async (proxy: string, url?: string): Promise<IMihomoDelay> => {
|
||||
return await mihomoProxyDelay(proxy, url)
|
||||
}, [])
|
||||
const onProxyDelay = useCallback(
|
||||
async (proxy: IMihomoProxy | IMihomoGroup, url?: string): Promise<IMihomoDelay> => {
|
||||
return await mihomoProxyDelay(proxy.name, url, getProviderName(proxy))
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
// 组测速时逐节点写回会造成 O(N²) 分配与 N 次 allProxies 重算
|
||||
const pendingDelayResults = useRef<Map<string, Map<string, { time: string; delay: number }>>>(
|
||||
@@ -299,7 +306,7 @@ const Proxies: React.FC = () => {
|
||||
const promise = Promise.resolve().then(async () => {
|
||||
let res: IMihomoDelay | undefined
|
||||
try {
|
||||
res = await mihomoProxyDelay(proxy.name, groups[index].testUrl)
|
||||
res = await mihomoProxyDelay(proxy.name, groups[index].testUrl, getProviderName(proxy))
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ interface IpcApi {
|
||||
mihomoUpgradeGeo: () => Promise<void>
|
||||
mihomoUpgrade: () => Promise<void>
|
||||
mihomoUpgradeUI: () => Promise<void>
|
||||
mihomoProxyDelay: (proxy: string, url?: string) => Promise<IMihomoDelay>
|
||||
mihomoProxyDelay: (proxy: string, url?: string, provider?: string) => Promise<IMihomoDelay>
|
||||
mihomoGroupDelay: (group: string, url?: string) => Promise<IMihomoGroupDelay>
|
||||
patchMihomoConfig: (patch: Partial<IMihomoConfig>) => Promise<void>
|
||||
mihomoSmartGroupWeights: (groupName: string) => Promise<Record<string, number>>
|
||||
|
||||
Reference in New Issue
Block a user