mirror of
http://bgp.hk.skcks.cn:10088/github.com/oneclickvirt/ecs
synced 2026-04-20 12:50:58 +08:00
fix:修改非选项1时的测速逻辑,区分中英文测速使用不同的节点逻辑
This commit is contained in:
@@ -47,43 +47,104 @@ def modify_go_mod(filepath):
|
||||
print(f"✓ Removed privatespeedtest/security from {filepath}")
|
||||
|
||||
|
||||
def remove_code_block(lines, start_marker, end_condition='empty_line'):
|
||||
"""
|
||||
Remove code block from lines starting with start_marker.
|
||||
|
||||
Args:
|
||||
lines: List of file lines
|
||||
start_marker: String or list of strings to identify block start
|
||||
end_condition: 'empty_line' (default) or 'closing_brace' or custom function
|
||||
|
||||
Returns:
|
||||
Modified lines with the block removed
|
||||
"""
|
||||
if isinstance(start_marker, str):
|
||||
start_marker = [start_marker]
|
||||
|
||||
result = []
|
||||
skip_mode = False
|
||||
brace_depth = 0
|
||||
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
|
||||
# Check if we should start skipping
|
||||
if not skip_mode:
|
||||
for marker in start_marker:
|
||||
if marker in line:
|
||||
skip_mode = True
|
||||
if end_condition == 'closing_brace':
|
||||
# Count opening braces on the function declaration line
|
||||
brace_depth = line.count('{') - line.count('}')
|
||||
break
|
||||
|
||||
if not skip_mode:
|
||||
result.append(line)
|
||||
else:
|
||||
# We're in skip mode
|
||||
if end_condition == 'empty_line':
|
||||
# Skip until we find an empty line
|
||||
if line.strip() == '':
|
||||
skip_mode = False
|
||||
# Don't add the empty line, continue to next
|
||||
elif end_condition == 'closing_brace':
|
||||
# Track brace depth
|
||||
brace_depth += line.count('{') - line.count('}')
|
||||
if brace_depth == 0 and '}' in line:
|
||||
# Function ended, skip until next empty line
|
||||
end_condition = 'empty_line'
|
||||
|
||||
i += 1
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def modify_speed_go(filepath):
|
||||
"""
|
||||
Brutally remove privatespeedtest-related code from speed.go
|
||||
by deleting known blocks from upstream source.
|
||||
Remove privatespeedtest-related code from speed.go.
|
||||
Uses line-by-line processing for reliability.
|
||||
"""
|
||||
content = read_file(filepath)
|
||||
|
||||
content = re.sub(
|
||||
r'\n\s*"time"\s*\n',
|
||||
'\n',
|
||||
content,
|
||||
flags=re.MULTILINE
|
||||
)
|
||||
|
||||
lines = content.split('\n')
|
||||
|
||||
# Remove specific code blocks by their comment markers
|
||||
blocks_to_remove = [
|
||||
'// formatString 格式化字符串到指定宽度',
|
||||
'// printTableRow 打印表格行',
|
||||
'// privateSpeedTest 使用 privatespeedtest 进行单个运营商测速',
|
||||
'// privateSpeedTestWithFallback 使用私有测速,如果失败则回退到 global 节点',
|
||||
'// 对于三网测速(cmcc、cu、ct)和 other,优先使用 privatespeedtest 进行私有测速',
|
||||
]
|
||||
|
||||
for block_marker in blocks_to_remove:
|
||||
lines = remove_code_block(lines, block_marker)
|
||||
|
||||
# Reconstruct content
|
||||
content = '\n'.join(lines)
|
||||
|
||||
# Remove privatespeedtest import
|
||||
content = re.sub(
|
||||
r'\n\s*"github\.com/oneclickvirt/privatespeedtest/pst"\s*\n',
|
||||
'\n',
|
||||
content,
|
||||
flags=re.MULTILINE
|
||||
)
|
||||
|
||||
|
||||
# Remove time import (only used by privatespeedtest)
|
||||
content = re.sub(
|
||||
r'// formatString 格式化字符串到指定宽度[\s\S]*?return nil\n}\n',
|
||||
'',
|
||||
content,
|
||||
flags=re.MULTILINE
|
||||
)
|
||||
|
||||
content = re.sub(
|
||||
r'^[ \t]*// 对于三网测速(cmcc、cu、ct),优先使用 privatespeedtest 进行私有测速[\s\S]*?\n\s*\n',
|
||||
r'\n\s*"time"\s*\n',
|
||||
'\n',
|
||||
content,
|
||||
flags=re.MULTILINE
|
||||
)
|
||||
|
||||
|
||||
# Clean up multiple consecutive empty lines (optional)
|
||||
content = re.sub(r'\n{3,}', '\n\n', content)
|
||||
|
||||
write_file(filepath, content)
|
||||
print(f"✓ Cleanly removed privatespeedtest from {filepath}")
|
||||
print(f"✓ Removed privatespeedtest from {filepath}")
|
||||
|
||||
def modify_utils_go(filepath):
|
||||
"""
|
||||
|
||||
@@ -482,6 +482,8 @@ Abuser 或 Abuse 的滥用得分会直接影响机器的正常使用(中国境
|
||||
|
||||
先测的官方推荐的测速点,然后测有代表性的国际测速点,最后测国内三大运营商ping值最低的测速点。
|
||||
|
||||
由于 speedtest.net 和 speedtest.cn 平台公开的测速节点被刷BTPT的刷烂了(他们为了对等上传PCDN的流量狂刷下载),所以这块本人独家融合的境内私有测速节点不再公开,优先使用私有的境内运营商测速节点进行测速,且写死限制每个IP每日仅支持获取测速数据10次,超限自动降级为使用公共测速节点进行测速
|
||||
|
||||
境内使用为主就看境内测速即可,境外使用看境外测速,官方测速点可以代表受测的宿主机本地带宽基准。
|
||||
|
||||
一般来说中国境外的服务器的带宽100Mbps起步,中国境内的服务器1Mbps带宽起步,具体看线路优劣,带宽特别大有时候未必用得上,够用就行了。
|
||||
|
||||
2
goecs.go
2
goecs.go
@@ -27,7 +27,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ecsVersion = "v0.1.108" // 融合怪版本号
|
||||
ecsVersion = "v0.1.109" // 融合怪版本号
|
||||
configs = params.NewConfig(ecsVersion) // 全局配置实例
|
||||
userSetFlags = make(map[string]bool) // 用于跟踪哪些参数是用户显式设置的
|
||||
)
|
||||
|
||||
@@ -348,7 +348,17 @@ func RunSpeedTests(config *params.Config, output, tempOutput string, outputMutex
|
||||
tests.CustomSP("net", "ct", config.SpNum, config.Language)
|
||||
tests.CustomSP("net", "cmcc", config.SpNum, config.Language)
|
||||
} else if config.Choice == "2" || config.Choice == "3" || config.Choice == "4" || config.Choice == "5" {
|
||||
tests.CustomSP("net", "global", 4, config.Language)
|
||||
// 中文模式:就近测速 + 三网各1个 + Other 1个(带回退)
|
||||
if config.Language == "zh" {
|
||||
tests.NearbySP()
|
||||
tests.CustomSP("net", "other", 1, config.Language)
|
||||
tests.CustomSP("net", "cu", 1, config.Language)
|
||||
tests.CustomSP("net", "ct", 1, config.Language)
|
||||
tests.CustomSP("net", "cmcc", 1, config.Language)
|
||||
} else {
|
||||
// 英文模式:保持原有逻辑,测4个global节点
|
||||
tests.CustomSP("net", "global", 4, config.Language)
|
||||
}
|
||||
} else if config.Choice == "6" {
|
||||
tests.CustomSP("net", "global", 11, config.Language)
|
||||
}
|
||||
@@ -442,7 +452,7 @@ func HandleSignalInterrupt(sig chan os.Signal, config *params.Config, startTime
|
||||
// 使用context来控制上传goroutine
|
||||
uploadCtx, uploadCancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer uploadCancel()
|
||||
|
||||
|
||||
go func() {
|
||||
httpURL, httpsURL := utils.ProcessAndUpload(finalOutput, config.FilePath, config.EnableUpload)
|
||||
select {
|
||||
@@ -455,7 +465,7 @@ func HandleSignalInterrupt(sig chan os.Signal, config *params.Config, startTime
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
select {
|
||||
case result := <-resultChan:
|
||||
uploadCancel() // 成功完成,取消context
|
||||
|
||||
@@ -69,7 +69,7 @@ func printTableRow(result pst.SpeedTestResult) {
|
||||
}
|
||||
latency := fmt.Sprintf("%.2f ms", result.PingLatency.Seconds()*1000)
|
||||
packetLoss := "N/A"
|
||||
fmt.Print(formatString(location, 16))
|
||||
fmt.Print(formatString(location, 15))
|
||||
fmt.Print(formatString(upload, 16))
|
||||
fmt.Print(formatString(download, 16))
|
||||
fmt.Print(formatString(latency, 16))
|
||||
@@ -78,25 +78,26 @@ func printTableRow(result pst.SpeedTestResult) {
|
||||
}
|
||||
|
||||
// privateSpeedTest 使用 privatespeedtest 进行单个运营商测速
|
||||
// operator 参数:只支持 "cmcc"、"cu"、"ct"
|
||||
func privateSpeedTest(num int, operator string) error {
|
||||
// operator 参数:只支持 "cmcc"、"cu"、"ct"、"other"
|
||||
// 返回值:实际测试的节点数量和错误信息
|
||||
func privateSpeedTest(num int, operator string) (int, error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Fprintf(os.Stderr, "[WARN] privateSpeedTest panic: %v\n", r)
|
||||
}
|
||||
}()
|
||||
*pst.NoProgress = true
|
||||
*pst.Quiet = true
|
||||
*pst.NoHeader = true
|
||||
*pst.NoProjectURL = true
|
||||
*pst.Quiet = true
|
||||
*pst.NoHeader = true
|
||||
*pst.NoProjectURL = true
|
||||
// 加载服务器列表
|
||||
serverList, err := pst.LoadServerList()
|
||||
if err != nil {
|
||||
return fmt.Errorf("加载自定义服务器列表失败")
|
||||
return 0, fmt.Errorf("加载自定义服务器列表失败")
|
||||
}
|
||||
// 使用三网测速模式(每个运营商选择指定数量的最低延迟节点)
|
||||
serversPerISP := num
|
||||
if serversPerISP <= 0 || serversPerISP > 5{
|
||||
if serversPerISP <= 0 || serversPerISP > 5 {
|
||||
serversPerISP = 2
|
||||
}
|
||||
// 单个运营商测速:先过滤服务器列表
|
||||
@@ -108,8 +109,10 @@ func privateSpeedTest(num int, operator string) error {
|
||||
carrierType = "Unicom"
|
||||
case "ct":
|
||||
carrierType = "Telecom"
|
||||
case "other":
|
||||
carrierType = "Other"
|
||||
default:
|
||||
return fmt.Errorf("不支持的运营商类型: %s", operator)
|
||||
return 0, fmt.Errorf("不支持的运营商类型: %s", operator)
|
||||
}
|
||||
// 过滤出指定运营商的服务器
|
||||
filteredServers := pst.FilterServersByISP(serverList.Servers, carrierType)
|
||||
@@ -121,13 +124,13 @@ func privateSpeedTest(num int, operator string) error {
|
||||
// 使用 FindBestServers 选择最佳服务器
|
||||
candidateServers, err := pst.FindBestServers(
|
||||
filteredServers,
|
||||
candidateCount, // 选择更多候选节点用于去重
|
||||
5*time.Second, // ping 超时
|
||||
true, // 显示进度条
|
||||
true, // 静默
|
||||
candidateCount, // 选择更多候选节点用于去重
|
||||
5*time.Second, // ping 超时
|
||||
true, // 显示进度条
|
||||
true, // 静默
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("分组查找失败")
|
||||
return 0, fmt.Errorf("分组查找失败")
|
||||
}
|
||||
// 去重:确保同一运营商内城市不重复
|
||||
seenCities := make(map[string]bool)
|
||||
@@ -147,18 +150,18 @@ func privateSpeedTest(num int, operator string) error {
|
||||
}
|
||||
}
|
||||
if len(bestServers) == 0 {
|
||||
return fmt.Errorf("去重后没有可用的服务器")
|
||||
return 0, fmt.Errorf("去重后没有可用的服务器")
|
||||
}
|
||||
// 执行测速并逐个打印结果(不打印表头)
|
||||
for i, serverInfo := range bestServers {
|
||||
result := pst.RunSpeedTest(
|
||||
serverInfo.Server,
|
||||
false, // 不禁用下载测试
|
||||
false, // 不禁用上传测试
|
||||
6, // 并发线程数
|
||||
12*time.Second, // 超时时间
|
||||
false, // 不禁用下载测试
|
||||
false, // 不禁用上传测试
|
||||
6, // 并发线程数
|
||||
12*time.Second, // 超时时间
|
||||
&serverInfo,
|
||||
false, // 不显示进度条
|
||||
false, // 不显示进度条
|
||||
)
|
||||
if result.Success {
|
||||
printTableRow(result)
|
||||
@@ -168,7 +171,31 @@ func privateSpeedTest(num int, operator string) error {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
// 返回实际测试的节点数量
|
||||
return len(bestServers), nil
|
||||
}
|
||||
|
||||
// privateSpeedTestWithFallback 使用私有测速,如果失败则回退到 global 节点
|
||||
// 主要用于 Other 类型的测速
|
||||
func privateSpeedTestWithFallback(num int, operator, language string) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Fprintf(os.Stderr, "[WARN] privateSpeedTestWithFallback panic: %v\n", r)
|
||||
}
|
||||
}()
|
||||
// 先尝试私有节点测速
|
||||
testedCount, err := privateSpeedTest(num, operator)
|
||||
if err != nil || testedCount == 0 {
|
||||
// 私有节点失败,回退到 global 节点
|
||||
var url, parseType string
|
||||
url = model.NetGlobal
|
||||
parseType = "id"
|
||||
if runtime.GOOS == "windows" || sp.OfficialAvailableTest() != nil {
|
||||
sp.CustomSpeedTest(url, parseType, num, language)
|
||||
} else {
|
||||
sp.OfficialCustomSpeedTest(url, parseType, num, language)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CustomSP(platform, operator string, num int, language string) {
|
||||
@@ -177,16 +204,23 @@ func CustomSP(platform, operator string, num int, language string) {
|
||||
fmt.Fprintf(os.Stderr, "[WARN] CustomSP panic: %v\n", r)
|
||||
}
|
||||
}()
|
||||
// 对于三网测速(cmcc、cu、ct),优先使用 privatespeedtest 进行私有测速
|
||||
// 对于三网测速(cmcc、cu、ct)和 other,优先使用 privatespeedtest 进行私有测速
|
||||
opLower := strings.ToLower(operator)
|
||||
if opLower == "cmcc" || opLower == "cu" || opLower == "ct" {
|
||||
err := privateSpeedTest(num, opLower)
|
||||
if opLower == "cmcc" || opLower == "cu" || opLower == "ct" || opLower == "other" {
|
||||
testedCount, err := privateSpeedTest(num, opLower)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[WARN] privatespeedtest failed\n")
|
||||
// 继续使用原有的兜底方案
|
||||
} else {
|
||||
// 测速成功,直接返回
|
||||
fmt.Fprintf(os.Stderr, "[WARN] privatespeedtest failed: %v\n", err)
|
||||
// 全部失败,继续使用原有的公共节点兜底方案
|
||||
} else if testedCount >= num {
|
||||
// 私有节点测速成功且数量达标,直接返回
|
||||
return
|
||||
} else if testedCount > 0 {
|
||||
// 部分私有节点测速成功,但数量不足,用公共节点补充
|
||||
fmt.Fprintf(os.Stderr, "[INFO] 私有节点仅测试了 %d 个,补充 %d 个公共节点\n", testedCount, num-testedCount)
|
||||
num = num - testedCount // 只测剩余数量的公共节点
|
||||
// 继续执行下面的公共节点测速逻辑
|
||||
} else {
|
||||
// testedCount == 0,继续使用公共节点
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +257,8 @@ func CustomSP(platform, operator string, num int, language string) {
|
||||
url = model.NetJP
|
||||
} else if strings.ToLower(operator) == "sg" {
|
||||
url = model.NetSG
|
||||
} else if strings.ToLower(operator) == "global" {
|
||||
} else if strings.ToLower(operator) == "global" || strings.ToLower(operator) == "other" {
|
||||
// other 类型回退到 global 节点
|
||||
url = model.NetGlobal
|
||||
}
|
||||
parseType = "id"
|
||||
|
||||
Reference in New Issue
Block a user