feat: proxy group is always placed at the forefront when sorting proxies (#458)

This commit is contained in:
wzdnzd 2023-12-01 19:16:42 +08:00 committed by GitHub
parent 89ad396bc2
commit a0f80aa62d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 5 deletions

View File

@ -38,12 +38,17 @@ export const sortProxiesByOrderingType = (
proxyNames: string[], proxyNames: string[],
proxyLatencyMap: Record<string, number>, proxyLatencyMap: Record<string, number>,
orderingType: PROXIES_ORDERING_TYPE, orderingType: PROXIES_ORDERING_TYPE,
proxyGroupNames: Set<string> | undefined,
) => { ) => {
if (orderingType === PROXIES_ORDERING_TYPE.NATURAL) { if (orderingType === PROXIES_ORDERING_TYPE.NATURAL) {
return proxyNames return proxyNames
} }
return proxyNames.sort((a, b) => { return proxyNames.sort((a, b) => {
if (proxyGroupNames?.has(a) && !proxyGroupNames?.has(b)) return -1
if (proxyGroupNames?.has(b) && !proxyGroupNames?.has(a)) return 1
const prevLatency = proxyLatencyMap[a] const prevLatency = proxyLatencyMap[a]
const nextLatency = proxyLatencyMap[b] const nextLatency = proxyLatencyMap[b]
@ -77,10 +82,13 @@ export const sortProxiesByOrderingType = (
export const filterProxiesByAvailability = ( export const filterProxiesByAvailability = (
proxyNames: string[], proxyNames: string[],
proxyLatencyMap: Record<string, number>, proxyLatencyMap: Record<string, number>,
excludes: Set<string>,
enabled?: boolean, enabled?: boolean,
) => ) =>
enabled enabled
? proxyNames.filter( ? proxyNames.filter((name) =>
(name) => proxyLatencyMap[name] !== latencyQualityMap().NOT_CONNECTED, excludes?.has(name)
? true
: proxyLatencyMap[name] !== latencyQualityMap().NOT_CONNECTED,
) )
: proxyNames : proxyNames

View File

@ -41,6 +41,7 @@ export default () => {
proxies, proxies,
selectProxyInGroup, selectProxyInGroup,
latencyMap, latencyMap,
proxyGroupNames,
proxyProviders, proxyProviders,
updateProviderByProviderName, updateProviderByProviderName,
updateAllProvider, updateAllProvider,
@ -157,8 +158,10 @@ export default () => {
proxyGroup.all ?? [], proxyGroup.all ?? [],
latencyMap(), latencyMap(),
proxiesOrderingType(), proxiesOrderingType(),
proxyGroupNames(),
), ),
latencyMap(), latencyMap(),
proxyGroupNames(),
hideUnAvailableProxies(), hideUnAvailableProxies(),
), ),
) )
@ -244,6 +247,7 @@ export default () => {
proxyProvider.proxies.map((i) => i.name) ?? [], proxyProvider.proxies.map((i) => i.name) ?? [],
latencyMap(), latencyMap(),
proxiesOrderingType(), proxiesOrderingType(),
undefined,
), ),
) )

View File

@ -52,6 +52,9 @@ const [isAllProviderUpdating, setIsAllProviderUpdating] = createSignal(false)
// these signals should be global state // these signals should be global state
const [proxies, setProxies] = createSignal<ProxyWithProvider[]>([]) const [proxies, setProxies] = createSignal<ProxyWithProvider[]>([])
const [proxyGroupNames, setProxyGroupNames] = createSignal<Set<string>>(
new Set(),
)
const [proxyProviders, setProxyProviders] = createSignal< const [proxyProviders, setProxyProviders] = createSignal<
(ProxyProvider & { proxies: ProxyNodeWithProvider[] })[] (ProxyProvider & { proxies: ProxyNodeWithProvider[] })[]
>([]) >([])
@ -89,19 +92,46 @@ const setProxiesInfo = (
return proxy.history?.at(-1)?.delay return proxy.history?.at(-1)?.delay
} }
const dependedLatencyProxies = {} as Record<string, Set<string>>
proxies.forEach((proxy) => { proxies.forEach((proxy) => {
const { udp, xudp, type, now, name, provider = '' } = proxy const { udp, xudp, type, now, name, provider = '' } = proxy
newProxyNodeMap[proxy.name] = { udp, xudp, type, now, name, provider } newProxyNodeMap[proxy.name] = { udp, xudp, type, now, name, provider }
const latency = // to solve the problem of the ProxyGroup cannot obtain the latency of the currently used proxy node
lastDelay(proxy, urlForLatencyTest()) || latencyQualityMap().NOT_CONNECTED // it seems that only clash.core and clash.preminu have issues
newLatencyMap[proxy.name] = latency if (!now) {
newLatencyMap[proxy.name] =
lastDelay(proxy, urlForLatencyTest()) ||
latencyQualityMap().NOT_CONNECTED
} else if (newLatencyMap[now] !== undefined) {
newLatencyMap[proxy.name] = newLatencyMap[now]
} else {
const dependencies = dependedLatencyProxies[now] ?? new Set()
dependencies.add(proxy.name)
dependedLatencyProxies[now] = dependencies
}
const proxyIPv6Support = const proxyIPv6Support =
(lastDelay(proxy, urlForIPv6SupportTest(), false) ?? 0) > 0 (lastDelay(proxy, urlForIPv6SupportTest(), false) ?? 0) > 0
newProxyIPv6SupportMap[proxy.name] = proxyIPv6Support newProxyIPv6SupportMap[proxy.name] = proxyIPv6Support
}) })
const independencies = Object.keys(dependedLatencyProxies).filter(
(now) => newLatencyMap[now] !== undefined,
)
// maybe we should use Union-Find to implement this
while (independencies.length > 0) {
const now = independencies.shift()!
const delay = newLatencyMap[now]!
for (const name of dependedLatencyProxies[now]?.values() ?? []) {
newLatencyMap[name] = delay
independencies.push(name)
}
}
batch(() => { batch(() => {
setProxyNodeMap(newProxyNodeMap) setProxyNodeMap(newProxyNodeMap)
setLatencyMap(newLatencyMap) setLatencyMap(newLatencyMap)
@ -142,6 +172,9 @@ export const useProxies = () => {
batch(() => { batch(() => {
setProxies(sortedProxies) setProxies(sortedProxies)
setProxyGroupNames(
new Set(['DIRECT', 'REJECT', ...sortedProxies.map((p) => p.name)]),
)
setProxyProviders(sortedProviders) setProxyProviders(sortedProviders)
setProxiesInfo(allProxies) setProxiesInfo(allProxies)
}) })
@ -293,6 +326,7 @@ export const useProxies = () => {
updatingMap, updatingMap,
isAllProviderUpdating, isAllProviderUpdating,
proxies, proxies,
proxyGroupNames,
proxyProviders, proxyProviders,
proxyLatencyTest, proxyLatencyTest,
proxyGroupLatencyTest, proxyGroupLatencyTest,