From b391de652113b7346dc0cc21e742f34db3ef6a3b Mon Sep 17 00:00:00 2001 From: SukkaW Date: Sat, 8 Feb 2025 22:04:48 +0800 Subject: [PATCH] Fetch ookla servers from `speedtest-net-servers.cdn.skk.moe` --- Build/build-speedtest-domainset.ts | 121 +++++++---------------------- 1 file changed, 29 insertions(+), 92 deletions(-) diff --git a/Build/build-speedtest-domainset.ts b/Build/build-speedtest-domainset.ts index a1a3d6c4..43178cc5 100644 --- a/Build/build-speedtest-domainset.ts +++ b/Build/build-speedtest-domainset.ts @@ -7,50 +7,35 @@ import { readFileIntoProcessedArray } from './lib/fetch-text-by-line'; import { DomainsetOutput } from './lib/rules/domainset'; import { OUTPUT_SURGE_DIR, SOURCE_DIR } from './constants/dir'; -import { newQueue } from '@henrygd/queue'; import { $$fetch } from './lib/fetch-retry'; -const KEYWORDS = [ - 'Hong Kong', - 'Taiwan', - 'China Telecom', - 'China Mobile', - 'China Unicom', - 'Japan', - 'Tokyo', - 'Singapore', - 'Korea', - 'Seoul', - 'Canada', - 'Toronto', - 'Montreal', - 'Los Ang', - 'San Jos', - 'Seattle', - 'New York', - 'Dallas', - 'Miami', - 'Berlin', - 'Frankfurt', - 'London', - 'Paris', - 'Amsterdam', - 'Moscow', - 'Australia', - 'Sydney', - 'Brazil', - 'Turkey' -]; +interface SpeedTestServer { + url: string, + lat: string, + lon: string, + distance: number, + name: string, + country: string, + cc: string, + sponsor: string, + id: string, + preferred: number, + https_functional: number, + host: string +} -const s = newQueue(2); +const getSpeedtestHostsGroupsPromise = $$fetch('https://speedtest-net-servers.cdn.skk.moe/servers.json') + .then(res => res.json() as Promise) + .then((data) => data.reduce((prev, cur) => { + const hn = tldts.getHostname(cur.host || cur.url, { detectIp: false, validateHostname: true }); + if (hn) { + prev.push(hn); + } + return prev; + }, [])); -const latestTopUserAgentsPromise = $$fetch('https://raw.githubusercontent.com/microlinkhq/top-user-agents/master/src/desktop.json') - .then(res => res.json() as Promise) - .then((userAgents: string[]) => userAgents.filter(ua => ua.startsWith('Mozilla/5.0 '))); -const getSpeedtestHostsGroupsPromise = Promise.all(KEYWORDS.flatMap(querySpeedtestApi)); - -export const buildSpeedtestDomainSet = task(require.main === module, __filename)(async (span) => { - const output = new DomainsetOutput(span, 'speedtest') +export const buildSpeedtestDomainSet = task(require.main === module, __filename)( + async (span) => new DomainsetOutput(span, 'speedtest') .withTitle('Sukka\'s Ruleset - Speedtest Domains') .withDescription([ ...SHARED_DESCRIPTION, @@ -58,55 +43,7 @@ export const buildSpeedtestDomainSet = task(require.main === module, __filename) 'This file contains common speedtest endpoints.' ]) .addFromDomainset(readFileIntoProcessedArray(path.resolve(SOURCE_DIR, 'domainset/speedtest.conf'))) - .addFromDomainset(readFileIntoProcessedArray(path.resolve(OUTPUT_SURGE_DIR, 'domainset/speedtest.conf'))); - - const hostnameGroup = await span.traceChildPromise('get speedtest hosts groups', getSpeedtestHostsGroupsPromise); - - hostnameGroup.forEach(output.bulkAddDomain.bind(output)); - - return output.write(); -}); - -async function querySpeedtestApi(keyword: string) { - const topUserAgents = await latestTopUserAgentsPromise; - - const url = `https://www.speedtest.net/api/js/servers?engine=js&search=${keyword}&limit=100`; - - try { - const randomUserAgent = topUserAgents[Math.floor(Math.random() * topUserAgents.length)]; - - const data = await s.add>(() => $$fetch(url, { - headers: { - dnt: '1', - Referer: 'https://www.speedtest.net/', - accept: 'application/json, text/plain, */*', - 'User-Agent': randomUserAgent, - 'Accept-Language': 'en-US,en;q=0.9', - ...(randomUserAgent.includes('Chrome') - ? { - 'Sec-Ch-Ua-Mobile': '?0', - 'Sec-Fetch-Dest': 'empty', - 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Gpc': '1' - } - : {}) - }, - signal: AbortSignal.timeout(1000 * 60) - }).then(res => res.json() as any)); - - return data.reduce( - (prev, cur) => { - const hn = tldts.getHostname(cur.host || cur.url, { detectIp: false, validateHostname: true }); - if (hn) { - prev.push(hn); - } - return prev; - }, - [] - ); - } catch (e) { - console.error(e); - return []; - } -} + .addFromDomainset(readFileIntoProcessedArray(path.resolve(OUTPUT_SURGE_DIR, 'domainset/speedtest.conf'))) + .bulkAddDomain(await span.traceChildPromise('get speedtest hosts groups', getSpeedtestHostsGroupsPromise)) + .write() +);