mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-24 09:45:35 +08:00
feat: add support for IPv6 check (#403)
* feat: add support for IPv6 check * Update src/i18n/en.ts Co-authored-by: kunish <17328586+kunish@users.noreply.github.com> Signed-off-by: ak <140048181+arkxfly@users.noreply.github.com> * Update src/i18n/zh.ts Co-authored-by: kunish <17328586+kunish@users.noreply.github.com> Signed-off-by: ak <140048181+arkxfly@users.noreply.github.com> --------- Signed-off-by: ak <140048181+arkxfly@users.noreply.github.com> Co-authored-by: kunish <17328586+kunish@users.noreply.github.com>
This commit is contained in:
parent
f5509c0290
commit
4d5543c64b
15
src/components/IPv6Support.tsx
Normal file
15
src/components/IPv6Support.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Show, createMemo } from 'solid-js'
|
||||||
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
|
export const IPv6Support = (props: { name?: string }) => {
|
||||||
|
const { proxyIPv6SupportMap } = useProxies()
|
||||||
|
const support = createMemo(() => proxyIPv6SupportMap()[props.name!] === true)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Show when={support()}>
|
||||||
|
<span class="badge badge-sm p-px">
|
||||||
|
<span class="scale-75">IPv6</span>
|
||||||
|
</span>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
}
|
@ -15,6 +15,8 @@ import {
|
|||||||
setProxiesOrderingType,
|
setProxiesOrderingType,
|
||||||
setProxiesPreviewType,
|
setProxiesPreviewType,
|
||||||
setUrlForLatencyTest,
|
setUrlForLatencyTest,
|
||||||
|
setUrlIPv6SupportTest,
|
||||||
|
urlForIPv6SupportTest,
|
||||||
urlForLatencyTest,
|
urlForLatencyTest,
|
||||||
} from '~/signals'
|
} from '~/signals'
|
||||||
|
|
||||||
@ -68,6 +70,16 @@ export const ProxiesSettingsModal: Component<{
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<ConfigTitle withDivider>{t('urlForIPv6SupportTest')}</ConfigTitle>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class="input input-bordered w-full"
|
||||||
|
value={urlForIPv6SupportTest()}
|
||||||
|
onChange={(e) => setUrlIPv6SupportTest(e.target.value?.trim())}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ConfigTitle withDivider>{t('proxiesSorting')}</ConfigTitle>
|
<ConfigTitle withDivider>{t('proxiesSorting')}</ConfigTitle>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
||||||
import { createMemo, Show } from 'solid-js'
|
import { createMemo, Show } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { Button, Latency } from '~/components'
|
import { Button, IPv6Support, Latency } from '~/components'
|
||||||
import { filterSpecialProxyType, formatProxyType } from '~/helpers'
|
import { filterSpecialProxyType, formatProxyType } from '~/helpers'
|
||||||
import { useProxies } from '~/signals'
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
@ -36,6 +36,8 @@ export const ProxyNodeCard = (props: {
|
|||||||
<div class="flex items-center justify-between gap-2">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<span class="text-left text-sm">{proxyName}</span>
|
<span class="text-left text-sm">{proxyName}</span>
|
||||||
|
|
||||||
|
<span class="flex items-center gap-1">
|
||||||
|
<IPv6Support name={props.proxyName} />
|
||||||
<Button
|
<Button
|
||||||
class="btn-circle btn-ghost h-auto min-h-0 w-auto"
|
class="btn-circle btn-ghost h-auto min-h-0 w-auto"
|
||||||
icon={
|
icon={
|
||||||
@ -53,6 +55,7 @@ export const ProxyNodeCard = (props: {
|
|||||||
void proxyLatencyTest(proxyName, proxyNode().provider)
|
void proxyLatencyTest(proxyName, proxyNode().provider)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between gap-1">
|
<div class="flex items-center justify-between gap-1">
|
||||||
|
@ -4,6 +4,7 @@ export * from './ConfigTitle'
|
|||||||
export * from './ConnectionsSettingsModal'
|
export * from './ConnectionsSettingsModal'
|
||||||
export * from './ConnectionsTableDetailsModal'
|
export * from './ConnectionsTableDetailsModal'
|
||||||
export * from './Header'
|
export * from './Header'
|
||||||
|
export * from './IPv6Support'
|
||||||
export * from './Latency'
|
export * from './Latency'
|
||||||
export * from './LogoText'
|
export * from './LogoText'
|
||||||
export * from './LogsSettingsModal'
|
export * from './LogsSettingsModal'
|
||||||
|
@ -46,6 +46,7 @@ export default {
|
|||||||
auto: 'Auto',
|
auto: 'Auto',
|
||||||
off: 'Off',
|
off: 'Off',
|
||||||
proxiesPreviewType: 'Proxies preview type',
|
proxiesPreviewType: 'Proxies preview type',
|
||||||
|
urlForIPv6SupportTest: 'URL for IPv6 support test',
|
||||||
urlForLatencyTest: 'URL for latency test',
|
urlForLatencyTest: 'URL for latency test',
|
||||||
autoCloseConns: 'Automatically Close connections',
|
autoCloseConns: 'Automatically Close connections',
|
||||||
useTwemoji: 'Use Twemoji Mozilla Font',
|
useTwemoji: 'Use Twemoji Mozilla Font',
|
||||||
|
@ -48,6 +48,7 @@ export default {
|
|||||||
auto: '自适应',
|
auto: '自适应',
|
||||||
off: '关闭',
|
off: '关闭',
|
||||||
proxiesPreviewType: '节点组预览样式',
|
proxiesPreviewType: '节点组预览样式',
|
||||||
|
urlForIPv6SupportTest: '测试 IPv6 支持链接',
|
||||||
urlForLatencyTest: '测速链接',
|
urlForLatencyTest: '测速链接',
|
||||||
autoCloseConns: '自动断开连接',
|
autoCloseConns: '自动断开连接',
|
||||||
useTwemoji: '使用 Twemoji Mozilla 字体',
|
useTwemoji: '使用 Twemoji Mozilla 字体',
|
||||||
|
@ -36,6 +36,12 @@ export const [urlForLatencyTest, setUrlForLatencyTest] = makePersisted(
|
|||||||
createSignal('https://www.gstatic.com/generate_204'),
|
createSignal('https://www.gstatic.com/generate_204'),
|
||||||
{ name: 'urlForLatencyTest', storage: localStorage },
|
{ name: 'urlForLatencyTest', storage: localStorage },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const [urlForIPv6SupportTest, setUrlIPv6SupportTest] = makePersisted(
|
||||||
|
createSignal('https://api-ipv6.ip.sb/ip'),
|
||||||
|
{ name: 'urlForIPv6SupportTest', storage: localStorage },
|
||||||
|
)
|
||||||
|
|
||||||
export const [autoCloseConns, setAutoCloseConns] = makePersisted(
|
export const [autoCloseConns, setAutoCloseConns] = makePersisted(
|
||||||
createSignal(false),
|
createSignal(false),
|
||||||
{ name: 'autoCloseConns', storage: localStorage },
|
{ name: 'autoCloseConns', storage: localStorage },
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
latencyTestTimeoutDuration,
|
latencyTestTimeoutDuration,
|
||||||
latestConnectionMsg,
|
latestConnectionMsg,
|
||||||
restructRawMsgToConnection,
|
restructRawMsgToConnection,
|
||||||
|
urlForIPv6SupportTest,
|
||||||
urlForLatencyTest,
|
urlForLatencyTest,
|
||||||
} from '~/signals'
|
} from '~/signals'
|
||||||
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
|
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
|
||||||
@ -56,6 +57,9 @@ const [proxyProviders, setProxyProviders] = createSignal<
|
|||||||
>([])
|
>([])
|
||||||
|
|
||||||
const [latencyMap, setLatencyMap] = createSignal<Record<string, number>>({})
|
const [latencyMap, setLatencyMap] = createSignal<Record<string, number>>({})
|
||||||
|
const [proxyIPv6SupportMap, setProxyIPv6SupportMap] = createSignal<
|
||||||
|
Record<string, boolean>
|
||||||
|
>({})
|
||||||
const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
@ -65,20 +69,43 @@ const setProxiesInfo = (
|
|||||||
) => {
|
) => {
|
||||||
const newProxyNodeMap = { ...proxyNodeMap() }
|
const newProxyNodeMap = { ...proxyNodeMap() }
|
||||||
const newLatencyMap = { ...latencyMap() }
|
const newLatencyMap = { ...latencyMap() }
|
||||||
|
const newProxyIPv6SupportMap = { ...proxyIPv6SupportMap() }
|
||||||
|
|
||||||
|
const lastDelay = (
|
||||||
|
proxy: Pick<Proxy, 'extra' | 'history'>,
|
||||||
|
url: string,
|
||||||
|
fallbackDefault = true,
|
||||||
|
) => {
|
||||||
|
const extra = proxy.extra?.[url] as Proxy['history'] | undefined
|
||||||
|
|
||||||
|
if (Array.isArray(extra)) {
|
||||||
|
const delay = extra.at(-1)?.delay
|
||||||
|
|
||||||
|
if (delay || !fallbackDefault) {
|
||||||
|
return delay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy.history?.at(-1)?.delay
|
||||||
|
}
|
||||||
|
|
||||||
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 }
|
||||||
|
|
||||||
const latency =
|
const latency =
|
||||||
proxy.history.at(-1)?.delay || latencyQualityMap().NOT_CONNECTED
|
lastDelay(proxy, urlForLatencyTest()) || latencyQualityMap().NOT_CONNECTED
|
||||||
|
|
||||||
newProxyNodeMap[proxy.name] = { udp, xudp, type, now, name, provider }
|
|
||||||
newLatencyMap[proxy.name] = latency
|
newLatencyMap[proxy.name] = latency
|
||||||
|
|
||||||
|
const proxyIPv6Support =
|
||||||
|
(lastDelay(proxy, urlForIPv6SupportTest(), false) ?? 0) > 0
|
||||||
|
newProxyIPv6SupportMap[proxy.name] = proxyIPv6Support
|
||||||
})
|
})
|
||||||
|
|
||||||
batch(() => {
|
batch(() => {
|
||||||
setProxyNodeMap(newProxyNodeMap)
|
setProxyNodeMap(newProxyNodeMap)
|
||||||
setLatencyMap(newLatencyMap)
|
setLatencyMap(newLatencyMap)
|
||||||
|
setProxyIPv6SupportMap(newProxyIPv6SupportMap)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +171,56 @@ export const useProxies = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const proxyLatencyTest = (proxyName: string, provider: string) =>
|
const proxyIPv6SupportTest = async (proxyName: string, provider: string) => {
|
||||||
|
const urlForTest = urlForIPv6SupportTest()
|
||||||
|
|
||||||
|
if (!urlForTest || urlForTest.length === 0) {
|
||||||
|
setProxyIPv6SupportMap({})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let support = false
|
||||||
|
try {
|
||||||
|
const { delay } = await proxyLatencyTestAPI(
|
||||||
|
proxyName,
|
||||||
|
provider,
|
||||||
|
urlForTest,
|
||||||
|
latencyTestTimeoutDuration(),
|
||||||
|
)
|
||||||
|
support = delay > 0
|
||||||
|
} catch {
|
||||||
|
support = false
|
||||||
|
}
|
||||||
|
setProxyIPv6SupportMap((supportMap) => ({
|
||||||
|
...supportMap,
|
||||||
|
[proxyName]: support,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
const proxyGroupIPv6SupportTest = async (proxyGroupName: string) => {
|
||||||
|
const urlForTest = urlForIPv6SupportTest()
|
||||||
|
|
||||||
|
if (!urlForTest || urlForTest.length === 0) {
|
||||||
|
setProxyIPv6SupportMap({})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const newLatencyMap = await proxyGroupLatencyTestAPI(
|
||||||
|
proxyGroupName,
|
||||||
|
urlForTest,
|
||||||
|
latencyTestTimeoutDuration(),
|
||||||
|
)
|
||||||
|
const newSupportMap = Object.fromEntries(
|
||||||
|
Object.entries(newLatencyMap).map(([k, v]) => [k, v > 0]),
|
||||||
|
)
|
||||||
|
setProxyIPv6SupportMap((supportMap) => ({
|
||||||
|
...supportMap,
|
||||||
|
...newSupportMap,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxyLatencyTest = async (proxyName: string, provider: string) => {
|
||||||
setProxyLatencyTestingMap(proxyName, async () => {
|
setProxyLatencyTestingMap(proxyName, async () => {
|
||||||
const { delay } = await proxyLatencyTestAPI(
|
const { delay } = await proxyLatencyTestAPI(
|
||||||
proxyName,
|
proxyName,
|
||||||
@ -158,8 +234,10 @@ export const useProxies = () => {
|
|||||||
[proxyName]: delay,
|
[proxyName]: delay,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
await proxyIPv6SupportTest(proxyName, provider)
|
||||||
|
}
|
||||||
|
|
||||||
const proxyGroupLatencyTest = (proxyGroupName: string) =>
|
const proxyGroupLatencyTest = async (proxyGroupName: string) => {
|
||||||
setProxyGroupLatencyTestingMap(proxyGroupName, async () => {
|
setProxyGroupLatencyTestingMap(proxyGroupName, async () => {
|
||||||
const newLatencyMap = await proxyGroupLatencyTestAPI(
|
const newLatencyMap = await proxyGroupLatencyTestAPI(
|
||||||
proxyGroupName,
|
proxyGroupName,
|
||||||
@ -174,6 +252,8 @@ export const useProxies = () => {
|
|||||||
|
|
||||||
await fetchProxies()
|
await fetchProxies()
|
||||||
})
|
})
|
||||||
|
await proxyGroupIPv6SupportTest(proxyGroupName)
|
||||||
|
}
|
||||||
|
|
||||||
const updateProviderByProviderName = (providerName: string) =>
|
const updateProviderByProviderName = (providerName: string) =>
|
||||||
setUpdatingMap(providerName, async () => {
|
setUpdatingMap(providerName, async () => {
|
||||||
@ -206,6 +286,7 @@ export const useProxies = () => {
|
|||||||
return {
|
return {
|
||||||
collapsedMap,
|
collapsedMap,
|
||||||
setCollapsedMap,
|
setCollapsedMap,
|
||||||
|
proxyIPv6SupportMap,
|
||||||
proxyLatencyTestingMap,
|
proxyLatencyTestingMap,
|
||||||
proxyGroupLatencyTestingMap,
|
proxyGroupLatencyTestingMap,
|
||||||
proxyProviderLatencyTestingMap,
|
proxyProviderLatencyTestingMap,
|
||||||
|
Loading…
Reference in New Issue
Block a user