Skip to content

Commit

Permalink
feat: proxy group is always placed at the forefront when sorting prox…
Browse files Browse the repository at this point in the history
…ies (#458)
  • Loading branch information
wzdnzd authored Dec 1, 2023
1 parent 89ad396 commit a0f80aa
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
12 changes: 10 additions & 2 deletions src/helpers/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,17 @@ export const sortProxiesByOrderingType = (
proxyNames: string[],
proxyLatencyMap: Record<string, number>,
orderingType: PROXIES_ORDERING_TYPE,
proxyGroupNames: Set<string> | undefined,
) => {
if (orderingType === PROXIES_ORDERING_TYPE.NATURAL) {
return proxyNames
}

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 nextLatency = proxyLatencyMap[b]

Expand Down Expand Up @@ -77,10 +82,13 @@ export const sortProxiesByOrderingType = (
export const filterProxiesByAvailability = (
proxyNames: string[],
proxyLatencyMap: Record<string, number>,
excludes: Set<string>,
enabled?: boolean,
) =>
enabled
? proxyNames.filter(
(name) => proxyLatencyMap[name] !== latencyQualityMap().NOT_CONNECTED,
? proxyNames.filter((name) =>
excludes?.has(name)
? true
: proxyLatencyMap[name] !== latencyQualityMap().NOT_CONNECTED,
)
: proxyNames
4 changes: 4 additions & 0 deletions src/pages/Proxies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default () => {
proxies,
selectProxyInGroup,
latencyMap,
proxyGroupNames,
proxyProviders,
updateProviderByProviderName,
updateAllProvider,
Expand Down Expand Up @@ -157,8 +158,10 @@ export default () => {
proxyGroup.all ?? [],
latencyMap(),
proxiesOrderingType(),
proxyGroupNames(),
),
latencyMap(),
proxyGroupNames(),
hideUnAvailableProxies(),
),
)
Expand Down Expand Up @@ -244,6 +247,7 @@ export default () => {
proxyProvider.proxies.map((i) => i.name) ?? [],
latencyMap(),
proxiesOrderingType(),
undefined,
),
)

Expand Down
40 changes: 37 additions & 3 deletions src/signals/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ const [isAllProviderUpdating, setIsAllProviderUpdating] = createSignal(false)

// these signals should be global state
const [proxies, setProxies] = createSignal<ProxyWithProvider[]>([])
const [proxyGroupNames, setProxyGroupNames] = createSignal<Set<string>>(
new Set(),
)
const [proxyProviders, setProxyProviders] = createSignal<
(ProxyProvider & { proxies: ProxyNodeWithProvider[] })[]
>([])
Expand Down Expand Up @@ -89,19 +92,46 @@ const setProxiesInfo = (
return proxy.history?.at(-1)?.delay
}

const dependedLatencyProxies = {} as Record<string, Set<string>>

proxies.forEach((proxy) => {
const { udp, xudp, type, now, name, provider = '' } = proxy
newProxyNodeMap[proxy.name] = { udp, xudp, type, now, name, provider }

const latency =
lastDelay(proxy, urlForLatencyTest()) || latencyQualityMap().NOT_CONNECTED
newLatencyMap[proxy.name] = latency
// to solve the problem of the ProxyGroup cannot obtain the latency of the currently used proxy node
// it seems that only clash.core and clash.preminu have issues
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 =
(lastDelay(proxy, urlForIPv6SupportTest(), false) ?? 0) > 0
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(() => {
setProxyNodeMap(newProxyNodeMap)
setLatencyMap(newLatencyMap)
Expand Down Expand Up @@ -142,6 +172,9 @@ export const useProxies = () => {

batch(() => {
setProxies(sortedProxies)
setProxyGroupNames(
new Set(['DIRECT', 'REJECT', ...sortedProxies.map((p) => p.name)]),
)
setProxyProviders(sortedProviders)
setProxiesInfo(allProxies)
})
Expand Down Expand Up @@ -293,6 +326,7 @@ export const useProxies = () => {
updatingMap,
isAllProviderUpdating,
proxies,
proxyGroupNames,
proxyProviders,
proxyLatencyTest,
proxyGroupLatencyTest,
Expand Down

0 comments on commit a0f80aa

Please sign in to comment.