Skip to content

Commit

Permalink
fix: latency test for selector and ipv6 test
Browse files Browse the repository at this point in the history
  • Loading branch information
YetAnotherZephyruso committed Jul 25, 2024
1 parent e84b348 commit b8409c1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 47 deletions.
6 changes: 4 additions & 2 deletions src/components/IPv6Support.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useProxies } from '~/signals'

export const IPv6Support = (props: { name?: string }) => {
const { proxyIPv6SupportMap } = useProxies()
const support = createMemo(() => proxyIPv6SupportMap()[props.name!] === true)
const { proxyIPv6SupportMap, getRealProxyNodeName } = useProxies()
const support = createMemo(() => {
return proxyIPv6SupportMap()[getRealProxyNodeName(props.name || '')]
})

return (
<Show when={support()}>
Expand Down
6 changes: 4 additions & 2 deletions src/components/Latency.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { latencyQualityMap, useProxies } from '~/signals'

export const Latency = (props: { name?: string; class?: string }) => {
const [t] = useI18n()
const { latencyMap } = useProxies()
const { getRealProxyNodeName, latencyMap } = useProxies()
const [textClassName, setTextClassName] = createSignal('')
const latency = createMemo(() => latencyMap()[props.name!])
const latency = createMemo(() => {
return latencyMap()[getRealProxyNodeName(props.name || '')]
})

createEffect(() => {
setTextClassName('text-success')
Expand Down
4 changes: 3 additions & 1 deletion src/signals/connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ export type WsMsg = {
downloadTotal: number
} | null

// DIRECT is from clash
// direct and dns-out is from the example of sing-box office site
export const [quickFilterRegex, setQuickFilterRegex] = makePersisted(
createSignal<string>('Direct|direct|dns-out'),
createSignal<string>('DIRECT|direct|dns-out'),
{
name: 'quickFilterRegex',
storage: localStorage,
Expand Down
69 changes: 27 additions & 42 deletions src/signals/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,51 +88,27 @@ const setProxiesInfo = (
}

if (!fallbackDefault) {
return undefined
return latencyQualityMap().NOT_CONNECTED
}

return proxy.history?.at(-1)?.delay
return proxy.history?.at(-1)?.delay ?? latencyQualityMap().NOT_CONNECTED
}

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 }

// 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.premium 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
})
lastDelay(proxy, urlForIPv6SupportTest(), false) >
latencyQualityMap().NOT_CONNECTED

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]!
newProxyNodeMap[proxy.name] = { udp, xudp, type, now, name, provider }
newLatencyMap[proxy.name] = lastDelay(proxy, urlForLatencyTest())

for (const name of dependedLatencyProxies[now]?.values() ?? []) {
newLatencyMap[name] = delay
independencies.push(name)
// we dont set it when false because there is no "extra" in sing-box so it will always be false in sing-box
// since the ipv6 support is not so often changed i think it is not a big problem
if (proxyIPv6Support) {
newProxyIPv6SupportMap[proxy.name] = proxyIPv6Support
}
}
})

batch(() => {
setProxyNodeMap(newProxyNodeMap)
Expand Down Expand Up @@ -275,17 +251,11 @@ export const useProxies = () => {
const proxyGroupLatencyTest = async (proxyGroupName: string) => {
await proxyGroupIPv6SupportTest(proxyGroupName)
setProxyGroupLatencyTestingMap(proxyGroupName, async () => {
const newLatencyMap = await proxyGroupLatencyTestAPI(
await proxyGroupLatencyTestAPI(
proxyGroupName,
urlForLatencyTest(),
latencyTestTimeoutDuration(),
)

setLatencyMap((latencyMap) => ({
...latencyMap,
...newLatencyMap,
}))

await fetchProxies()
})
}
Expand Down Expand Up @@ -320,6 +290,20 @@ export const useProxies = () => {
await fetchProxies()
})

const getRealProxyNodeName = (name: string) => {
let node = proxyNodeMap()[name]

if (!name || !node) {
return name
}

while (node.now && node.now !== node.name) {
node = proxyNodeMap()[node.now]
}

return node.name
}

return {
proxyIPv6SupportMap,
proxyLatencyTestingMap,
Expand All @@ -339,5 +323,6 @@ export const useProxies = () => {
updateProviderByProviderName,
updateAllProvider,
proxyProviderLatencyTest,
getRealProxyNodeName,
}
}

0 comments on commit b8409c1

Please sign in to comment.