mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
updated the shuffling algorithm and added a deduplication detection mechanism (#3521)
This commit is contained in:
@@ -65,6 +65,8 @@
|
|||||||
- Mihomo 内核默认日志等级为 warn
|
- Mihomo 内核默认日志等级为 warn
|
||||||
- Clash Verge Rev 应用默认日志等级为 warn
|
- Clash Verge Rev 应用默认日志等级为 warn
|
||||||
- 重构了原来的 IP 信息请求重试机制,采用轮询检测,解决了 Network Error 和超时问题
|
- 重构了原来的 IP 信息请求重试机制,采用轮询检测,解决了 Network Error 和超时问题
|
||||||
|
- 对轮询检测机制进行了优化,引入洗牌算法来增强随机性。
|
||||||
|
- 对获取系统信息的流程进行了优化,并添加了去重检测机制,确保剔除重复的信息
|
||||||
|
|
||||||
## v2.2.3
|
## v2.2.3
|
||||||
|
|
||||||
|
|||||||
@@ -26,28 +26,34 @@ export const SystemInfoCard = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { isAdminMode, isSidecarMode, mutateRunningMode } = useSystemState();
|
const { isAdminMode, isSidecarMode, mutateRunningMode } = useSystemState();
|
||||||
|
|
||||||
// 系统信息状态
|
// 系统信息状态
|
||||||
const [systemState, setSystemState] = useState({
|
const [systemState, setSystemState] = useState({
|
||||||
osInfo: "",
|
osInfo: "",
|
||||||
lastCheckUpdate: "-",
|
lastCheckUpdate: "-",
|
||||||
});
|
});
|
||||||
|
|
||||||
// 初始化系统信息
|
// 初始化系统信息
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 获取系统信息
|
// 获取系统信息
|
||||||
getSystemInfo()
|
getSystemInfo()
|
||||||
.then((info) => {
|
.then((info) => {
|
||||||
const lines = info.split("\n");
|
const lines = info.split("\n");
|
||||||
if (lines.length > 0) {
|
if (lines.length > 0) {
|
||||||
const sysName = lines[0].split(": ")[1] || "";
|
const sysName = lines[0].split(": ")[1] || "";
|
||||||
const sysVersion = lines[1].split(": ")[1] || "";
|
let sysVersion = lines[1].split(": ")[1] || "";
|
||||||
setSystemState((prev) => ({
|
|
||||||
...prev,
|
// 处理sysVersion前缀与sysName相同的情况
|
||||||
osInfo: `${sysName} ${sysVersion}`,
|
if (sysName && sysVersion.toLowerCase().startsWith(sysName.toLowerCase())) {
|
||||||
}));
|
sysVersion = sysVersion.substring(sysName.length).trim();
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(console.error);
|
setSystemState((prev) => ({
|
||||||
|
...prev,
|
||||||
|
osInfo: `${sysName} ${sysVersion}`,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
|
||||||
// 获取最后检查更新时间
|
// 获取最后检查更新时间
|
||||||
const lastCheck = localStorage.getItem("last_check_update");
|
const lastCheck = localStorage.getItem("last_check_update");
|
||||||
|
|||||||
@@ -376,31 +376,97 @@ const IP_CHECK_SERVICES: ServiceConfig[] = [
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: "https://ipinfo.io/json",
|
url: "https://api.ipapi.is/",
|
||||||
mapping: (data) => {
|
mapping: (data) => ({
|
||||||
const [asn, ...orgParts] = (data.org || '').split(' ');
|
ip: data.ip || '',
|
||||||
const asnOrg = orgParts.join(' ');
|
country_code: data.location?.country_code || '',
|
||||||
|
country: data.location?.country || '',
|
||||||
return {
|
region: data.location?.state || '',
|
||||||
ip: data.ip || '',
|
city: data.location?.city || '',
|
||||||
country_code: data.country || '',
|
organization: data.asn?.org || data.company?.name || '',
|
||||||
country: data.country || '',
|
asn: data.asn?.asn || 0,
|
||||||
region: data.region || '',
|
asn_organization: data.asn?.org || '',
|
||||||
city: data.city || '',
|
longitude: data.location?.longitude || 0,
|
||||||
organization: asnOrg || '',
|
latitude: data.location?.latitude || 0,
|
||||||
asn: asn? parseInt(asn.replace('AS', '')) : 0,
|
timezone: data.location?.timezone || '',
|
||||||
asn_organization: asnOrg || '',
|
}),
|
||||||
longitude: parseFloat(data.loc?.split(',')[1] || '0'),
|
},
|
||||||
latitude: parseFloat(data.loc?.split(',')[0] || '0'),
|
{
|
||||||
timezone: data.timezone || '',
|
url: "https://ipwho.is/",
|
||||||
};
|
mapping: (data) => ({
|
||||||
},
|
ip: data.ip || '',
|
||||||
|
country_code: data.country_code || '',
|
||||||
|
country: data.country || '',
|
||||||
|
region: data.region || '',
|
||||||
|
city: data.city || '',
|
||||||
|
organization: data.connection?.org || data.connection?.isp || '',
|
||||||
|
asn: data.connection?.asn || 0,
|
||||||
|
asn_organization: data.connection?.isp || '',
|
||||||
|
longitude: data.longitude || 0,
|
||||||
|
latitude: data.latitude || 0,
|
||||||
|
timezone: data.timezone?.id || '',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 随机打乱服务列表顺序
|
// 随机性服务列表洗牌函数
|
||||||
function shuffleServices() {
|
function shuffleServices() {
|
||||||
return [...IP_CHECK_SERVICES].sort(() => Math.random() - 0.5);
|
// 过滤无效服务并确保每个元素符合ServiceConfig接口
|
||||||
|
const validServices = IP_CHECK_SERVICES.filter(
|
||||||
|
(service): service is ServiceConfig =>
|
||||||
|
service !== null &&
|
||||||
|
service !== undefined &&
|
||||||
|
typeof service.url === 'string' &&
|
||||||
|
typeof service.mapping === 'function' // 添加对mapping属性的检查
|
||||||
|
);
|
||||||
|
|
||||||
|
if (validServices.length === 0) {
|
||||||
|
console.error('No valid services found in IP_CHECK_SERVICES');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用单一Fisher-Yates洗牌算法,增强随机性
|
||||||
|
const shuffled = [...validServices];
|
||||||
|
const length = shuffled.length;
|
||||||
|
|
||||||
|
// 使用多个种子进行多次洗牌
|
||||||
|
const seeds = [
|
||||||
|
Math.random(),
|
||||||
|
Date.now() / 1000,
|
||||||
|
performance.now() / 1000
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const seed of seeds) {
|
||||||
|
const prng = createPrng(seed);
|
||||||
|
|
||||||
|
// Fisher-Yates洗牌算法
|
||||||
|
for (let i = length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(prng() * (i + 1));
|
||||||
|
|
||||||
|
// 使用临时变量进行交换,避免解构赋值可能的问题
|
||||||
|
const temp = shuffled[i];
|
||||||
|
shuffled[i] = shuffled[j];
|
||||||
|
shuffled[j] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shuffled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个简单的随机数生成器
|
||||||
|
function createPrng(seed: number): () => number {
|
||||||
|
// 使用xorshift32算法
|
||||||
|
let state = seed >>> 0;
|
||||||
|
|
||||||
|
// 如果种子为0,设置一个默认值
|
||||||
|
if (state === 0) state = 123456789;
|
||||||
|
|
||||||
|
return function() {
|
||||||
|
state ^= state << 13;
|
||||||
|
state ^= state >>> 17;
|
||||||
|
state ^= state << 5;
|
||||||
|
return (state >>> 0) / 4294967296;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前IP和地理位置信息
|
// 获取当前IP和地理位置信息
|
||||||
|
|||||||
Reference in New Issue
Block a user