2025-01-13 14:27:08 +08:00
|
|
|
import gte from 'semver/functions/gte';
|
|
|
|
|
import coerce from 'semver/functions/coerce';
|
|
|
|
|
import $ from '@/core/app';
|
|
|
|
|
|
2024-03-31 10:59:49 +08:00
|
|
|
export function getUserAgentFromHeaders(headers) {
|
2022-06-30 12:19:43 +08:00
|
|
|
const keys = Object.keys(headers);
|
|
|
|
|
let UA = '';
|
2023-08-28 13:10:48 +08:00
|
|
|
let ua = '';
|
2024-11-19 23:06:45 +08:00
|
|
|
let accept = '';
|
2022-06-30 12:19:43 +08:00
|
|
|
for (let k of keys) {
|
2024-11-19 23:06:45 +08:00
|
|
|
const lower = k.toLowerCase();
|
|
|
|
|
if (lower === 'user-agent') {
|
2022-06-30 12:19:43 +08:00
|
|
|
UA = headers[k];
|
2023-08-28 13:10:48 +08:00
|
|
|
ua = UA.toLowerCase();
|
2024-11-19 23:06:45 +08:00
|
|
|
} else if (lower === 'accept') {
|
|
|
|
|
accept = headers[k];
|
2022-06-30 12:19:43 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-11-19 23:06:45 +08:00
|
|
|
return { UA, ua, accept };
|
2024-03-31 10:59:49 +08:00
|
|
|
}
|
2024-11-19 23:06:45 +08:00
|
|
|
|
|
|
|
|
export function getPlatformFromUserAgent({ ua, UA, accept }) {
|
2022-06-30 12:19:43 +08:00
|
|
|
if (UA.indexOf('Quantumult%20X') !== -1) {
|
|
|
|
|
return 'QX';
|
2024-11-20 14:28:05 +08:00
|
|
|
} else if (ua.indexOf('egern') !== -1) {
|
|
|
|
|
return 'Egern';
|
2023-12-27 00:24:06 +08:00
|
|
|
} else if (UA.indexOf('Surfboard') !== -1) {
|
|
|
|
|
return 'Surfboard';
|
2023-08-29 01:46:49 +08:00
|
|
|
} else if (UA.indexOf('Surge Mac') !== -1) {
|
|
|
|
|
return 'SurgeMac';
|
2022-06-30 12:19:43 +08:00
|
|
|
} else if (UA.indexOf('Surge') !== -1) {
|
|
|
|
|
return 'Surge';
|
|
|
|
|
} else if (UA.indexOf('Decar') !== -1 || UA.indexOf('Loon') !== -1) {
|
|
|
|
|
return 'Loon';
|
|
|
|
|
} else if (UA.indexOf('Shadowrocket') !== -1) {
|
feat: 脚本内部 produceArtifact 支持指定 produceType: 'internal', produceOpts: { 'include-unsupported-proxy': true } 来获得内部的数据结构; 订阅链接参数支持 type=internal&includeUnsupportedProxy=true; 文件支持 nunjucks 模板, 为 sing-box 增加的 Filter 用法 sub/col 为订阅/组合订阅中的节点名 {{ '订阅的name' | sub('美国|🇺🇸|us', 'i') }}, subNode/colNode 为订阅/组合订阅中的节点 {{ '订阅的name' | subNode('美国|🇺🇸|us', 'i') }}, 底层 produceArtifact('subscription', 'sing-box', 'internal', '美国|🇺🇸|us', 'i')
2024-01-14 12:13:29 +08:00
|
|
|
return 'Shadowrocket';
|
2022-06-30 12:19:43 +08:00
|
|
|
} else if (UA.indexOf('Stash') !== -1) {
|
|
|
|
|
return 'Stash';
|
2023-08-28 13:10:48 +08:00
|
|
|
} else if (
|
|
|
|
|
ua === 'meta' ||
|
2024-07-20 14:48:39 +08:00
|
|
|
(ua.indexOf('clash') !== -1 && ua.indexOf('meta') !== -1) ||
|
|
|
|
|
ua.indexOf('clash-verge') !== -1 ||
|
|
|
|
|
ua.indexOf('flclash') !== -1
|
2023-08-28 13:10:48 +08:00
|
|
|
) {
|
|
|
|
|
return 'ClashMeta';
|
|
|
|
|
} else if (ua.indexOf('clash') !== -1) {
|
|
|
|
|
return 'Clash';
|
2024-11-20 14:28:05 +08:00
|
|
|
} else if (ua.indexOf('v2ray') !== -1) {
|
2023-08-28 13:10:48 +08:00
|
|
|
return 'V2Ray';
|
2024-01-13 10:28:07 +08:00
|
|
|
} else if (ua.indexOf('sing-box') !== -1) {
|
|
|
|
|
return 'sing-box';
|
2024-11-19 23:06:45 +08:00
|
|
|
} else if (accept.indexOf('application/json') === 0) {
|
2022-06-30 12:19:43 +08:00
|
|
|
return 'JSON';
|
2024-11-19 23:06:45 +08:00
|
|
|
} else {
|
|
|
|
|
return 'V2Ray';
|
2022-06-30 12:19:43 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-11-19 23:06:45 +08:00
|
|
|
|
2024-03-31 10:59:49 +08:00
|
|
|
export function getPlatformFromHeaders(headers) {
|
2024-11-19 23:06:45 +08:00
|
|
|
const { UA, ua, accept } = getUserAgentFromHeaders(headers);
|
|
|
|
|
return getPlatformFromUserAgent({ ua, UA, accept });
|
2024-03-31 10:59:49 +08:00
|
|
|
}
|
2025-01-13 14:27:08 +08:00
|
|
|
export function shouldIncludeUnsupportedProxy(platform, ua) {
|
|
|
|
|
try {
|
|
|
|
|
const version = coerce(ua).version;
|
|
|
|
|
if (platform === 'Stash' && gte(version, '2.8.0')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (platform === 'Egern' && gte(version, '1.29.0')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
$.error(`获取版本号失败: ${e}`);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|