Compare commits

...

17 Commits

Author SHA1 Message Date
spiritlhl
e8c4b2b4a7 feat: 公开API接口包,方便GUI调用使用本项目作依赖 2026-02-02 07:32:14 +00:00
spiritlhl
8016a8fe93 fix: 更新dkly的数据库地址 2026-02-02 07:24:50 +00:00
github-actions[bot]
bf0030dc49 chore: update ECS_VERSION to 0.1.113 in goecs.sh 2026-01-30 06:12:06 +00:00
spiritlhl
6d02103aba fix: 修复流媒体解锁的请求头参数设置 2026-01-30 05:57:44 +00:00
github-actions[bot]
5ffb48dcdc chore: update ECS_VERSION to 0.1.112 in goecs.sh 2026-01-16 06:16:27 +00:00
spiritlhl
7c19502950 fix:部分测速成功也输出,但补充节点测速 2026-01-16 14:02:42 +08:00
spiritlhl
3c434781f5 fix:修复私有测速节点可能存在部分上传下载测速失败的问题,自动轮换 2026-01-16 14:00:53 +08:00
spiritlhl
f62636ca3e fix:回退upx安装步骤,实际受限于编译的镜像不可直接进行安装 2026-01-13 20:00:59 +08:00
spiritlhl
c4b11ae37d fix: Install UPX in build workflow
Added step to install UPX for binary compression.
2026-01-13 19:57:55 +08:00
github-actions[bot]
8f2fe236d5 chore: update ECS_VERSION to 0.1.111 in goecs.sh 2026-01-13 11:56:25 +00:00
spiritlhl
347a0faa7a fix:添加UPX操作压缩减小产物大小 2026-01-13 19:42:41 +08:00
spiritlhl
74640e3066 fix:更新版本 2026-01-13 19:36:24 +08:00
spiritlhl
3b646eeeda fix:修复错误的格式化字符 2026-01-13 19:35:39 +08:00
github-actions[bot]
eaad433395 chore: update ECS_VERSION to 0.1.110 in goecs.sh 2026-01-13 04:28:12 +00:00
spiritlhl
03af7c423b Bump ecsVersion to v0.1.110 2026-01-13 12:12:40 +08:00
spiritlhl
0e96a6499b Update build_binary.yaml to disable certain options
Disable large packages, Docker images, and swap storage in the build workflow.
2026-01-13 12:03:44 +08:00
spiritlhl
5b44f5f651 fix:修复编译占用的磁盘过大的问题 2026-01-13 11:49:57 +08:00
15 changed files with 832 additions and 69 deletions

View File

@@ -19,11 +19,31 @@ jobs:
with:
fetch-depth: 0
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: false
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.25.3
go-version: 1.25.4
# - name: Install UPX
# run: |
# apk add --no-cache upx
- name: Configure Git for Private Modules
run: |
git config --global url."https://${{ secrets.GHT }}@github.com/".insteadOf "https://github.com/"
@@ -31,13 +51,18 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GHT }}
- name: Clean Go cache before build
run: |
go clean -cache -modcache -testcache
df -h
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
# version: latest
version: '~> v2'
args: release
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GHT }}
GOPRIVATE: github.com/oneclickvirt/security,github.com/oneclickvirt/privatespeedtest

View File

@@ -1,6 +1,10 @@
before:
hooks:
- go mod tidy -v
- go clean -cache
project_name: goecs
builds:
- id: universal
env:
@@ -31,6 +35,7 @@ builds:
goarch: arm
main: ./
binary: goecs
- id: darwin-amd64
env:
- CGO_ENABLED=1
@@ -44,6 +49,7 @@ builds:
- amd64
main: ./
binary: goecs
- id: darwin-arm64
env:
- CGO_ENABLED=1
@@ -57,18 +63,23 @@ builds:
- arm64
main: ./
binary: goecs
universal_binaries:
- name_template: "goecs"
replace: false
checksum:
name_template: "checksums.txt"
snapshot:
name_template: "goecs"
archives:
- name_template: "goecs_{{ .Os }}_{{ .Arch }}"
format: zip
files:
- none*
changelog:
sort: asc
filters:
@@ -79,4 +90,18 @@ changelog:
- Merge pull request
- Merge branch
- go mod tidy
- New translations
- New translations
upx:
- enabled: true
brute: true
goos:
- linux
- windows
goarch:
- amd64
- 386
- arm64
- ppc64le
- s390x
- riscv64

56
api/api.go Normal file
View File

@@ -0,0 +1,56 @@
package api
const (
// Version API版本号
Version = "v1.0.0"
// DefaultVersion 默认的ECS版本号
DefaultVersion = "v0.1.114"
)
// 测试方法常量
const (
// CPU测试方法
CpuMethodSysbench = "sysbench"
CpuMethodGeekbench = "geekbench"
CpuMethodWinsat = "winsat"
// 内存测试方法
MemoryMethodStream = "stream"
MemoryMethodSysbench = "sysbench"
MemoryMethodDD = "dd"
MemoryMethodWinsat = "winsat"
// 硬盘测试方法
DiskMethodFio = "fio"
DiskMethodDD = "dd"
DiskMethodWinsat = "winsat"
// 线程模式
ThreadModeSingle = "single"
ThreadModeMulti = "multi"
// 语言选项
LanguageZH = "zh"
LanguageEN = "en"
// IP检测类型
CheckTypeIPv4 = "ipv4"
CheckTypeIPv6 = "ipv6"
CheckTypeAuto = "auto"
// 测速平台
PlatformCN = "cn"
PlatformNet = "net"
// 运营商类型
OperatorCMCC = "cmcc" // 中国移动
OperatorCU = "cu" // 中国联通
OperatorCT = "ct" // 中国电信
OperatorGlobal = "global" // 全球节点
OperatorOther = "other" // 其他
OperatorHK = "hk" // 香港
OperatorTW = "tw" // 台湾
OperatorJP = "jp" // 日本
OperatorSG = "sg" // 新加坡
)

259
api/config.go Normal file
View File

@@ -0,0 +1,259 @@
package api
import (
"github.com/oneclickvirt/ecs/internal/params"
)
// Config 配置接口,导出用于外部调用
type Config = params.Config
// NewConfig 创建默认配置
// version: 版本号字符串
func NewConfig(version string) *Config {
return params.NewConfig(version)
}
// NewDefaultConfig 创建默认配置(使用默认版本号)
func NewDefaultConfig() *Config {
return params.NewConfig("v0.1.114")
}
// ConfigOption 配置选项函数类型
type ConfigOption func(*Config)
// WithLanguage 设置语言
func WithLanguage(lang string) ConfigOption {
return func(c *Config) {
c.Language = lang
}
}
// WithCpuTestMethod 设置CPU测试方法
// method: "sysbench" 或 "geekbench"
func WithCpuTestMethod(method string) ConfigOption {
return func(c *Config) {
c.CpuTestMethod = method
}
}
// WithCpuTestThreadMode 设置CPU测试线程模式
// mode: "single" 或 "multi"
func WithCpuTestThreadMode(mode string) ConfigOption {
return func(c *Config) {
c.CpuTestThreadMode = mode
}
}
// WithMemoryTestMethod 设置内存测试方法
// method: "stream", "sysbench", "dd"
func WithMemoryTestMethod(method string) ConfigOption {
return func(c *Config) {
c.MemoryTestMethod = method
}
}
// WithDiskTestMethod 设置硬盘测试方法
// method: "fio" 或 "dd"
func WithDiskTestMethod(method string) ConfigOption {
return func(c *Config) {
c.DiskTestMethod = method
}
}
// WithDiskTestPath 设置硬盘测试路径
func WithDiskTestPath(path string) ConfigOption {
return func(c *Config) {
c.DiskTestPath = path
}
}
// WithDiskMultiCheck 设置是否进行硬盘多路径检测
func WithDiskMultiCheck(enable bool) ConfigOption {
return func(c *Config) {
c.DiskMultiCheck = enable
}
}
// WithSpeedTestNum 设置测速节点数量
func WithSpeedTestNum(num int) ConfigOption {
return func(c *Config) {
c.SpNum = num
}
}
// WithWidth 设置输出宽度
func WithWidth(width int) ConfigOption {
return func(c *Config) {
c.Width = width
}
}
// WithFilePath 设置输出文件路径
func WithFilePath(path string) ConfigOption {
return func(c *Config) {
c.FilePath = path
}
}
// WithEnableUpload 设置是否启用上传
func WithEnableUpload(enable bool) ConfigOption {
return func(c *Config) {
c.EnableUpload = enable
}
}
// WithEnableLogger 设置是否启用日志
func WithEnableLogger(enable bool) ConfigOption {
return func(c *Config) {
c.EnableLogger = enable
}
}
// WithBasicTest 设置是否执行基础信息测试
func WithBasicTest(enable bool) ConfigOption {
return func(c *Config) {
c.BasicStatus = enable
}
}
// WithCpuTest 设置是否执行CPU测试
func WithCpuTest(enable bool) ConfigOption {
return func(c *Config) {
c.CpuTestStatus = enable
}
}
// WithMemoryTest 设置是否执行内存测试
func WithMemoryTest(enable bool) ConfigOption {
return func(c *Config) {
c.MemoryTestStatus = enable
}
}
// WithDiskTest 设置是否执行硬盘测试
func WithDiskTest(enable bool) ConfigOption {
return func(c *Config) {
c.DiskTestStatus = enable
}
}
// WithUnlockTest 设置是否执行流媒体解锁测试
func WithUnlockTest(enable bool) ConfigOption {
return func(c *Config) {
c.UtTestStatus = enable
}
}
// WithSecurityTest 设置是否执行IP质量测试
func WithSecurityTest(enable bool) ConfigOption {
return func(c *Config) {
c.SecurityTestStatus = enable
}
}
// WithEmailTest 设置是否执行邮件端口测试
func WithEmailTest(enable bool) ConfigOption {
return func(c *Config) {
c.EmailTestStatus = enable
}
}
// WithBacktraceTest 设置是否执行回程路由测试
func WithBacktraceTest(enable bool) ConfigOption {
return func(c *Config) {
c.BacktraceStatus = enable
}
}
// WithNt3Test 设置是否执行三网路由测试
func WithNt3Test(enable bool) ConfigOption {
return func(c *Config) {
c.Nt3Status = enable
}
}
// WithSpeedTest 设置是否执行测速测试
func WithSpeedTest(enable bool) ConfigOption {
return func(c *Config) {
c.SpeedTestStatus = enable
}
}
// WithPingTest 设置是否执行PING测试
func WithPingTest(enable bool) ConfigOption {
return func(c *Config) {
c.PingTestStatus = enable
}
}
// WithTgdcTest 设置是否执行Telegram DC测试
func WithTgdcTest(enable bool) ConfigOption {
return func(c *Config) {
c.TgdcTestStatus = enable
}
}
// WithWebTest 设置是否执行网站测试
func WithWebTest(enable bool) ConfigOption {
return func(c *Config) {
c.WebTestStatus = enable
}
}
// WithNt3CheckType 设置三网路由检测类型
// checkType: "ipv4", "ipv6" 或 "auto"
func WithNt3CheckType(checkType string) ConfigOption {
return func(c *Config) {
c.Nt3CheckType = checkType
}
}
// WithNt3Location 设置三网路由检测位置
func WithNt3Location(location string) ConfigOption {
return func(c *Config) {
c.Nt3Location = location
}
}
// WithAutoChangeDiskMethod 设置是否自动切换硬盘测试方法
func WithAutoChangeDiskMethod(enable bool) ConfigOption {
return func(c *Config) {
c.AutoChangeDiskMethod = enable
}
}
// WithOnlyChinaTest 设置是否只进行国内测试
func WithOnlyChinaTest(enable bool) ConfigOption {
return func(c *Config) {
c.OnlyChinaTest = enable
}
}
// WithMenuMode 设置是否启用菜单模式
func WithMenuMode(enable bool) ConfigOption {
return func(c *Config) {
c.MenuMode = enable
}
}
// WithOnlyIpInfoCheck 设置是否只进行IP信息检测
func WithOnlyIpInfoCheck(enable bool) ConfigOption {
return func(c *Config) {
c.OnlyIpInfoCheck = enable
}
}
// WithChoice 设置菜单选择
func WithChoice(choice string) ConfigOption {
return func(c *Config) {
c.Choice = choice
}
}
// ApplyOptions 应用配置选项
func ApplyOptions(config *Config, options ...ConfigOption) *Config {
for _, opt := range options {
opt(config)
}
return config
}

27
api/menu.go Normal file
View File

@@ -0,0 +1,27 @@
package api
import (
"github.com/oneclickvirt/ecs/internal/menu"
"github.com/oneclickvirt/ecs/utils"
)
// GetMenuChoice 获取用户菜单选择
// language: 语言 ("zh" 或 "en")
// 返回: 用户选择的选项
func GetMenuChoice(language string) string {
return menu.GetMenuChoice(language)
}
// PrintMenuOptions 打印菜单选项
// preCheck: 网络检查结果
// config: 配置对象
func PrintMenuOptions(preCheck utils.NetCheckResult, config *Config) {
menu.PrintMenuOptions(preCheck, config)
}
// HandleMenuMode 处理菜单模式
// preCheck: 网络检查结果
// config: 配置对象
func HandleMenuMode(preCheck utils.NetCheckResult, config *Config) {
menu.HandleMenuMode(preCheck, config)
}

187
api/runner.go Normal file
View File

@@ -0,0 +1,187 @@
package api
import (
"sync"
"time"
"github.com/oneclickvirt/ecs/internal/runner"
"github.com/oneclickvirt/ecs/utils"
)
// RunResult 运行结果
type RunResult struct {
Output string // 完整输出
Duration time.Duration // 运行时长
StartTime time.Time // 开始时间
EndTime time.Time // 结束时间
}
// RunAllTests 执行所有测试(高级接口)
// preCheck: 网络检查结果
// config: 配置对象
// 返回: 运行结果
func RunAllTests(preCheck utils.NetCheckResult, config *Config) *RunResult {
var (
wg1, wg2, wg3 sync.WaitGroup
basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo string
output, tempOutput string
outputMutex sync.Mutex
infoMutex sync.Mutex
)
startTime := time.Now()
switch config.Language {
case "zh":
runner.RunChineseTests(preCheck, config, &wg1, &wg2, &wg3,
&basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo,
&output, tempOutput, startTime, &outputMutex, &infoMutex)
case "en":
runner.RunEnglishTests(preCheck, config, &wg1, &wg2, &wg3,
&basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo,
&output, tempOutput, startTime, &outputMutex, &infoMutex)
default:
runner.RunChineseTests(preCheck, config, &wg1, &wg2, &wg3,
&basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo,
&output, tempOutput, startTime, &outputMutex, &infoMutex)
}
endTime := time.Now()
return &RunResult{
Output: output,
Duration: endTime.Sub(startTime),
StartTime: startTime,
EndTime: endTime,
}
}
// RunBasicTests 运行基础信息测试
func RunBasicTests(preCheck utils.NetCheckResult, config *Config) string {
var (
basicInfo, securityInfo string
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunBasicTests(preCheck, config, &basicInfo, &securityInfo, output, tempOutput, &outputMutex)
}
// RunCPUTest 运行CPU测试
func RunCPUTest(config *Config) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunCPUTest(config, output, tempOutput, &outputMutex)
}
// RunMemoryTest 运行内存测试
func RunMemoryTest(config *Config) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunMemoryTest(config, output, tempOutput, &outputMutex)
}
// RunDiskTest 运行硬盘测试
func RunDiskTest(config *Config) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunDiskTest(config, output, tempOutput, &outputMutex)
}
// RunIpInfoCheck 执行IP信息检测
func RunIpInfoCheck(config *Config) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunIpInfoCheck(config, output, tempOutput, &outputMutex)
}
// RunStreamingTests 运行流媒体测试
func RunStreamingTests(config *Config, mediaInfo string) string {
var (
wg1 sync.WaitGroup
output, tempOutput string
outputMutex sync.Mutex
infoMutex sync.Mutex
)
return runner.RunStreamingTests(config, &wg1, &mediaInfo, output, tempOutput, &outputMutex, &infoMutex)
}
// RunSecurityTests 运行安全测试
func RunSecurityTests(config *Config, securityInfo string) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunSecurityTests(config, securityInfo, output, tempOutput, &outputMutex)
}
// RunEmailTests 运行邮件端口测试
func RunEmailTests(config *Config, emailInfo string) string {
var (
wg2 sync.WaitGroup
output, tempOutput string
outputMutex sync.Mutex
infoMutex sync.Mutex
)
return runner.RunEmailTests(config, &wg2, &emailInfo, output, tempOutput, &outputMutex, &infoMutex)
}
// RunNetworkTests 运行网络测试(中文模式)
func RunNetworkTests(config *Config, ptInfo string) string {
var (
wg3 sync.WaitGroup
output, tempOutput string
outputMutex sync.Mutex
infoMutex sync.Mutex
)
return runner.RunNetworkTests(config, &wg3, &ptInfo, output, tempOutput, &outputMutex, &infoMutex)
}
// RunSpeedTests 运行测速测试(中文模式)
func RunSpeedTests(config *Config) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunSpeedTests(config, output, tempOutput, &outputMutex)
}
// RunEnglishNetworkTests 运行网络测试(英文模式)
func RunEnglishNetworkTests(config *Config, ptInfo string) string {
var (
wg3 sync.WaitGroup
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunEnglishNetworkTests(config, &wg3, &ptInfo, output, tempOutput, &outputMutex)
}
// RunEnglishSpeedTests 运行测速测试(英文模式)
func RunEnglishSpeedTests(config *Config) string {
var (
output, tempOutput string
outputMutex sync.Mutex
)
return runner.RunEnglishSpeedTests(config, output, tempOutput, &outputMutex)
}
// AppendTimeInfo 添加时间信息
func AppendTimeInfo(config *Config, output string, startTime time.Time) string {
var (
tempOutput string
outputMutex sync.Mutex
)
return runner.AppendTimeInfo(config, output, tempOutput, startTime, &outputMutex)
}
// HandleUploadResults 处理上传结果
func HandleUploadResults(config *Config, output string) {
runner.HandleUploadResults(config, output)
}

101
api/tests.go Normal file
View File

@@ -0,0 +1,101 @@
package api
import (
"github.com/oneclickvirt/ecs/internal/tests"
)
// TestResult 测试结果结构
type TestResult struct {
TestMethod string // 实际使用的测试方法
Output string // 测试输出结果
Success bool // 是否成功
Error error // 错误信息
}
// CpuTest CPU测试公共接口
// language: 语言 ("zh" 或 "en")
// testMethod: 测试方法 ("sysbench" 或 "geekbench")
// testThread: 线程模式 ("single" 或 "multi")
// 返回: (实际测试方法, 测试结果)
func CpuTest(language, testMethod, testThread string) (string, string) {
return tests.CpuTest(language, testMethod, testThread)
}
// MemoryTest 内存测试公共接口
// language: 语言 ("zh" 或 "en")
// testMethod: 测试方法 ("stream", "sysbench", "dd")
// 返回: (实际测试方法, 测试结果)
func MemoryTest(language, testMethod string) (string, string) {
return tests.MemoryTest(language, testMethod)
}
// DiskTest 硬盘测试公共接口
// language: 语言 ("zh" 或 "en")
// testMethod: 测试方法 ("fio" 或 "dd")
// testPath: 测试路径
// isMultiCheck: 是否多路径检测
// autoChange: 是否自动切换方法
// 返回: (实际测试方法, 测试结果)
func DiskTest(language, testMethod, testPath string, isMultiCheck, autoChange bool) (string, string) {
return tests.DiskTest(language, testMethod, testPath, isMultiCheck, autoChange)
}
// MediaTest 流媒体解锁测试公共接口
// language: 语言 ("zh" 或 "en")
// 返回: 测试结果
func MediaTest(language string) string {
return tests.MediaTest(language)
}
// SpeedTestShowHead 显示测速表头
// language: 语言 ("zh" 或 "en")
func SpeedTestShowHead(language string) {
tests.ShowHead(language)
}
// SpeedTestNearby 就近节点测速
func SpeedTestNearby() {
tests.NearbySP()
}
// SpeedTestCustom 自定义测速
// platform: 平台 ("cn" 或 "net")
// operator: 运营商 ("cmcc", "cu", "ct", "global", "other" 等)
// num: 测试节点数量
// language: 语言 ("zh" 或 "en")
func SpeedTestCustom(platform, operator string, num int, language string) {
tests.CustomSP(platform, operator, num, language)
}
// NextTrace3Check 三网路由追踪测试
// language: 语言 ("zh" 或 "en")
// location: 位置
// checkType: 检测类型 ("ipv4", "ipv6")
func NextTrace3Check(language, location, checkType string) {
tests.NextTrace3Check(language, location, checkType)
}
// UpstreamsCheck 上游及回程线路检测
func UpstreamsCheck() {
tests.UpstreamsCheck()
}
// GetIPv4Address 获取当前IPv4地址
func GetIPv4Address() string {
return tests.IPV4
}
// GetIPv6Address 获取当前IPv6地址
func GetIPv6Address() string {
return tests.IPV6
}
// SetIPv4Address 设置IPv4地址用于测试
func SetIPv4Address(ipv4 string) {
tests.IPV4 = ipv4
}
// SetIPv6Address 设置IPv6地址用于测试
func SetIPv6Address(ipv6 string) {
tests.IPV6 = ipv6
}

91
api/utils.go Normal file
View File

@@ -0,0 +1,91 @@
package api
import (
"time"
"github.com/oneclickvirt/ecs/utils"
)
// NetCheckResult 网络检查结果
type NetCheckResult = utils.NetCheckResult
// StatsResponse 统计信息响应
type StatsResponse = utils.StatsResponse
// GitHubRelease GitHub发布信息
type GitHubRelease = utils.GitHubRelease
// CheckPublicAccess 检查公网访问能力
// timeout: 超时时间
// 返回: 网络检查结果
func CheckPublicAccess(timeout time.Duration) NetCheckResult {
return utils.CheckPublicAccess(timeout)
}
// GetGoescStats 获取goecs统计信息
// 返回: (统计响应, 错误)
func GetGoescStats() (*StatsResponse, error) {
return utils.GetGoescStats()
}
// GetLatestEcsRelease 获取最新的ECS版本信息
// 返回: (GitHub发布信息, 错误)
func GetLatestEcsRelease() (*GitHubRelease, error) {
return utils.GetLatestEcsRelease()
}
// PrintHead 打印程序头部信息
// language: 语言 ("zh" 或 "en")
// width: 显示宽度
// version: 版本号
func PrintHead(language string, width int, version string) {
utils.PrintHead(language, width, version)
}
// PrintCenteredTitle 打印居中标题
// title: 标题文本
// width: 显示宽度
func PrintCenteredTitle(title string, width int) {
utils.PrintCenteredTitle(title, width)
}
// ProcessAndUpload 处理并上传结果
// output: 输出内容
// filePath: 文件路径
// enableUpload: 是否启用上传
// 返回: (HTTP URL, HTTPS URL)
func ProcessAndUpload(output, filePath string, enableUpload bool) (string, string) {
return utils.ProcessAndUpload(output, filePath, enableUpload)
}
// BasicsAndSecurityCheck 基础信息和安全检查
// language: 语言
// checkType: 检查类型
// securityTestStatus: 是否执行安全测试
// 返回: (IPv4地址, IPv6地址, 基础信息, 安全信息, 检查类型)
func BasicsAndSecurityCheck(language, checkType string, securityTestStatus bool) (string, string, string, string, string) {
return utils.BasicsAndSecurityCheck(language, checkType, securityTestStatus)
}
// OnlyBasicsIpInfo 仅获取基础IP信息
// language: 语言
// 返回: (IPv4地址, IPv6地址, IP信息)
func OnlyBasicsIpInfo(language string) (string, string, string) {
return utils.OnlyBasicsIpInfo(language)
}
// FormatGoecsNumber 格式化数字显示
// num: 数字
// 返回: 格式化后的字符串
func FormatGoecsNumber(num int) string {
return utils.FormatGoecsNumber(num)
}
// PrintAndCapture 打印并捕获输出
// fn: 执行的函数
// tempOutput: 临时输出
// existingOutput: 现有输出
// 返回: 捕获的输出
func PrintAndCapture(fn func(), tempOutput, existingOutput string) string {
return utils.PrintAndCapture(fn, tempOutput, existingOutput)
}

14
go.mod
View File

@@ -4,7 +4,7 @@ go 1.25.4
require (
github.com/imroc/req/v3 v3.54.0
github.com/oneclickvirt/UnlockTests v0.0.33-20251126065725
github.com/oneclickvirt/UnlockTests v0.0.34-20260130055000
github.com/oneclickvirt/backtrace v0.0.8-20251109090457
github.com/oneclickvirt/basics v0.0.16-20251112033526
github.com/oneclickvirt/cputest v0.0.12-20251111095842
@@ -15,7 +15,8 @@ require (
github.com/oneclickvirt/nt3 v0.0.11-20260112140912
github.com/oneclickvirt/pingtest v0.0.9-20251104112920
github.com/oneclickvirt/portchecker v0.0.3-20250728015900
github.com/oneclickvirt/security v0.0.8-20251112080734
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218
github.com/oneclickvirt/security v0.0.8-20260202071316
github.com/oneclickvirt/speedtest v0.0.11-20251102151740
)
@@ -28,7 +29,7 @@ require (
github.com/ebitengine/purego v0.8.4 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gofrs/uuid/v5 v5.2.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
@@ -41,12 +42,12 @@ require (
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jaypipes/ghw v0.17.0 // indirect
github.com/jaypipes/pcidb v1.0.1 // indirect
github.com/jsdelivr/globalping-cli v1.5.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
github.com/lionsoul2014/ip2region v2.11.2+incompatible // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -60,7 +61,6 @@ require (
github.com/oneclickvirt/dd v0.0.2-20250808062818 // indirect
github.com/oneclickvirt/fio v0.0.2-20250808045755 // indirect
github.com/oneclickvirt/mbw v0.0.1-20250808061222 // indirect
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218 // indirect
github.com/oneclickvirt/stream v0.0.2-20250924154001 // indirect
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
@@ -82,7 +82,6 @@ require (
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/shirou/gopsutil/v4 v4.25.6 // indirect
github.com/showwin/speedtest-go v1.7.10 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
@@ -92,11 +91,10 @@ require (
github.com/tidwall/match v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect
github.com/tsosunchia/powclient v0.2.0 // indirect
github.com/xjasonlyu/windivert-go v0.0.0-20201010013527-4239d0afa76f // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/mock v0.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect

58
go.sum
View File

@@ -6,6 +6,8 @@ github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwTo
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -21,8 +23,9 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
@@ -56,9 +59,10 @@ github.com/jaypipes/ghw v0.17.0/go.mod h1:In8SsaDqlb1oTyrbmTC14uy+fbBMvp+xdqX51M
github.com/jaypipes/pcidb v1.0.1 h1:WB2zh27T3nwg8AE8ei81sNRb9yWBii3JGNJtT7K9Oic=
github.com/jaypipes/pcidb v1.0.1/go.mod h1:6xYUz/yYEyOkIkUt2t2J2folIuZ4Yg6uByCGFXMCeE4=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jsdelivr/globalping-cli v1.5.1 h1:7RZNmIljSBXe0xBeOoGQHXZNwHo6zDuQ0BI9hF12gLY=
github.com/jsdelivr/globalping-cli v1.5.1/go.mod h1:Gw70OWvN6hIt0t4hftyUhcHuJQMTn4CvoobJiaTU0qg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
@@ -71,8 +75,6 @@ github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
github.com/lionsoul2014/ip2region v2.11.2+incompatible h1:+VRsGcrHz8ewXI/2UzTptJlACsxD/p4xCxuql4u2nKU=
github.com/lionsoul2014/ip2region v2.11.2+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
@@ -92,12 +94,10 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nxtrace/NTrace-core v1.4.3-rc.1 h1:V19tkw3kKAMQOOh7Ibb/jZFBk4kMUfQYmpxxtsOfYWo=
github.com/nxtrace/NTrace-core v1.4.3-rc.1/go.mod h1:lGhfZ916pEUJh+VzWZTYu7bKBo06pAn+/gXb0A/7gGg=
github.com/nxtrace/NTrace-core v1.5.0 h1:n+a/FObw/+CcqvhuSQiWcm1q+ODtfo7Wt3VmaIx504I=
github.com/nxtrace/NTrace-core v1.5.0/go.mod h1:/jME48iJ7QaVTzsrTPQyTJ+yExhjeWjax2L6uBd4ckk=
github.com/oneclickvirt/UnlockTests v0.0.33-20251126065725 h1:VaaK2v17nLGU8FQmJRXPe2bEESzRePbGws0bfq7s/2o=
github.com/oneclickvirt/UnlockTests v0.0.33-20251126065725/go.mod h1:oOa6wj/qECtRMxwBO6D7o0L0F0Q/5sQ747OCnFQqoGE=
github.com/oneclickvirt/UnlockTests v0.0.34-20260130055000 h1:amgZH8QyTmgZ09t6j0Fi0SbSU03vhZIFjW/1/sOT70M=
github.com/oneclickvirt/UnlockTests v0.0.34-20260130055000/go.mod h1:oOa6wj/qECtRMxwBO6D7o0L0F0Q/5sQ747OCnFQqoGE=
github.com/oneclickvirt/backtrace v0.0.8-20251109090457 h1:599/R/qMAtfPCPG1bPoi6KbjNJzVkKtxm8dvVIdtn5o=
github.com/oneclickvirt/backtrace v0.0.8-20251109090457/go.mod h1:mj9TSow7FNszBb3bQj2Hhm41LwBo7HQP6sgaPtovKdM=
github.com/oneclickvirt/basics v0.0.16-20251112033526 h1:bgoLaqStV3a6mbPiM++0mYizd278GVa6J6yeIiusV+A=
@@ -118,20 +118,16 @@ github.com/oneclickvirt/mbw v0.0.1-20250808061222 h1:WGXOe6QvHiDRhPVMI0VcctjzW08
github.com/oneclickvirt/mbw v0.0.1-20250808061222/go.mod h1:0Vq6NRpyLmGUdfHfL3uDcFsuZhi7KlG+OCs5ky2757Y=
github.com/oneclickvirt/memorytest v0.0.10-20251218032900 h1:SmRFfPLyGfTVWIgC50lEGgOpbqahtMHIlyOMSbrhj9Y=
github.com/oneclickvirt/memorytest v0.0.10-20251218032900/go.mod h1:4kiHsEWkW9r3/1ZcV5xIweU0smiKP0IRfQj74AUIiVI=
github.com/oneclickvirt/nt3 v0.0.10-20251111095706 h1:GEdgL6oAWXY80NIq23mLjcTR3gvLGh9iusFzJK6SoDo=
github.com/oneclickvirt/nt3 v0.0.10-20251111095706/go.mod h1:yo1ufkduFt9QjqG7nqSUf1D3YlQOmFpdlTYniJfclQI=
github.com/oneclickvirt/nt3 v0.0.11-20260112140912 h1:e3tgkEmydsML6ziOdWwsVGwysTRYS82SuWrP0HnIw9g=
github.com/oneclickvirt/nt3 v0.0.11-20260112140912/go.mod h1:u/y3sMhyt4wiQlR7yS68CudwjXCa/4V6ozWI7awsCws=
github.com/oneclickvirt/pingtest v0.0.9-20251104112920 h1:j3Fjhy0YHT/VF7iuAVVELaRXkquvRd64tWWfFLJs01o=
github.com/oneclickvirt/pingtest v0.0.9-20251104112920/go.mod h1:gxwsxxwitNQiGq2OI0ZogYoOLwc8DtuOdSRe6/EvRqs=
github.com/oneclickvirt/portchecker v0.0.3-20250728015900 h1:AomzdppSOFB70AJESQhlp0IPbsHTTJGimAWDk2TzCWM=
github.com/oneclickvirt/portchecker v0.0.3-20250728015900/go.mod h1:9sjMDPCd4Z40wkYB0S9gQPGH8YPtnNE1ZJthVIuHUzA=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112095218 h1:VcglFz85LVPo8wE8AkBhgXHHUUVI2Ae9ng6+hY6ewx4=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112095218/go.mod h1:IXOlKKX4DUNqxOaW/K9bcdrBiWxo0jGSLXeBeo7NrTo=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218 h1:h2k2fHtrsIIP/x/apEWkQGlTKuIumz8GrUR/df41YhE=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218/go.mod h1:IXOlKKX4DUNqxOaW/K9bcdrBiWxo0jGSLXeBeo7NrTo=
github.com/oneclickvirt/security v0.0.8-20251112080734 h1:WpwdGbwpiBP2YA1lNsymati5uvBbWFlN9CXHYgd3/fE=
github.com/oneclickvirt/security v0.0.8-20251112080734/go.mod h1:aPMIwqsz7wiUH1cqvtRr9+QcQRkKzlUWecDM6SGVddc=
github.com/oneclickvirt/security v0.0.8-20260202071316 h1:ULZWXC99IzrdFEG05D2/MQklKAhztQNc6UYCE3fEQeU=
github.com/oneclickvirt/security v0.0.8-20260202071316/go.mod h1:aPMIwqsz7wiUH1cqvtRr9+QcQRkKzlUWecDM6SGVddc=
github.com/oneclickvirt/speedtest v0.0.11-20251102151740 h1:1NUrNt5ay6/xVNC5x62UrQjPqK8jgbKtyjBml/3boZg=
github.com/oneclickvirt/speedtest v0.0.11-20251102151740/go.mod h1:fy0II2Wo7kDWVBKTwcHdodZwyfmJo0g8N9V02EwQDZE=
github.com/oneclickvirt/stream v0.0.2-20250924154001 h1:GuJWdiPkoK84+y/+oHKr2Ghl3c/MzS9Z5m1nM+lMmy4=
@@ -161,8 +157,6 @@ github.com/prometheus-community/pro-bing v0.4.1 h1:aMaJwyifHZO0y+h8+icUz0xbToHbi
github.com/prometheus-community/pro-bing v0.4.1/go.mod h1:aLsw+zqCaDoa2RLVVSX3+UiCkBBXTMtZC3c7EkfWnAE=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.53.0 h1:QHX46sISpG2S03dPeZBgVIZp8dGagIaiu2FiVYvpCZI=
github.com/quic-go/quic-go v0.53.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
github.com/refraction-networking/utls v1.7.3 h1:L0WRhHY7Oq1T0zkdzVZMR6zWZv+sXbHB9zcuvsAEqCo=
@@ -174,12 +168,8 @@ github.com/rodaine/table v1.3.0 h1:4/3S3SVkHnVZX91EHFvAMV7K42AnJ0XuymRR2C5HlGE=
github.com/rodaine/table v1.3.0/go.mod h1:47zRsHar4zw0jgxGxL9YtFfs7EGN6B/TaS+/Dmk4WxU=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
github.com/schollz/progressbar/v3 v3.14.4 h1:W9ZrDSJk7eqmQhd3uxFNNcTr0QL+xuGNI9dEMrw0r74=
github.com/schollz/progressbar/v3 v3.14.4/go.mod h1:aT3UQ7yGm+2ZjeXPqsjTenwL3ddUiuZ0kfQ/2tHlyNI=
github.com/schollz/progressbar/v3 v3.17.1 h1:bI1MTaoQO+v5kzklBjYNRQLoVpe0zbyRZNK6DFkVC5U=
github.com/schollz/progressbar/v3 v3.17.1/go.mod h1:RzqpnsPQNjUyIgdglUjRLgD7sVnxN1wpmBMV+UiEbL4=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
@@ -188,8 +178,6 @@ github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dI
github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
github.com/showwin/speedtest-go v1.7.10 h1:9o5zb7KsuzZKn+IE2//z5btLKJ870JwO6ETayUkqRFw=
github.com/showwin/speedtest-go v1.7.10/go.mod h1:Ei7OCTmNPdWofMadzcfgq1rUO7mvJy9Jycj//G7vyfA=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
@@ -214,7 +202,6 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
@@ -223,8 +210,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo=
github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI=
github.com/tsosunchia/powclient v0.2.0 h1:BDrI3O69CbzarbD+CnnY10Kuwn8xlmtQR0m5tBp+BG8=
github.com/tsosunchia/powclient v0.2.0/go.mod h1:fkb7tTW+HMH3ZWZzQUgwvvFKMj/8Ys+C8Sm/uGQzDA0=
github.com/xjasonlyu/windivert-go v0.0.0-20201010013527-4239d0afa76f h1:glX3VZCYwW1/OmFxOjazfCtBLxXB3YNZk9LF2lYx+Lw=
@@ -236,8 +223,6 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -251,16 +236,12 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -271,16 +252,12 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -292,14 +269,12 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -308,9 +283,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -319,8 +291,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -328,8 +298,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -27,7 +27,7 @@ import (
)
var (
ecsVersion = "v0.1.109" // 融合怪版本号
ecsVersion = "v0.1.114" // 融合怪版本号
configs = params.NewConfig(ecsVersion) // 全局配置实例
userSetFlags = make(map[string]bool) // 用于跟踪哪些参数是用户显式设置的
)

View File

@@ -152,7 +152,7 @@ goecs_check() {
os=$(uname -s 2>/dev/null || echo "Unknown")
arch=$(uname -m 2>/dev/null || echo "Unknown")
check_china
ECS_VERSION="0.1.108"
ECS_VERSION="0.1.113"
for api in \
"https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \
"https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \
@@ -164,8 +164,8 @@ goecs_check() {
sleep 1
done
if [ -z "$ECS_VERSION" ]; then
_yellow "Unable to get version info, using default version 0.1.108"
ECS_VERSION="0.1.108"
_yellow "Unable to get version info, using default version 0.1.113"
ECS_VERSION="0.1.113"
fi
version_output=""
for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do

View File

@@ -330,6 +330,8 @@ func RunNetworkTests(config *params.Config, wg3 *sync.WaitGroup, ptInfo *string,
fmt.Println(pt.WebsiteTest())
}
}
// 等待第三方库的输出完全刷新到标准输出
time.Sleep(300 * time.Millisecond)
}, tempOutput, output)
}
@@ -362,6 +364,8 @@ func RunSpeedTests(config *params.Config, output, tempOutput string, outputMutex
} else if config.Choice == "6" {
tests.CustomSP("net", "global", 11, config.Language)
}
// 等待第三方库的输出完全刷新到标准输出
time.Sleep(500 * time.Millisecond)
}
}, tempOutput, output)
}
@@ -380,6 +384,8 @@ func RunEnglishNetworkTests(config *params.Config, wg3 *sync.WaitGroup, ptInfo *
fmt.Println(pt.WebsiteTest())
}
}
// 等待第三方库的输出完全刷新到标准输出
time.Sleep(300 * time.Millisecond)
}, tempOutput, output)
}
@@ -393,6 +399,8 @@ func RunEnglishSpeedTests(config *params.Config, output, tempOutput string, outp
tests.ShowHead(config.Language)
tests.NearbySP()
tests.CustomSP("net", "global", -1, config.Language)
// 等待第三方库的输出完全刷新到标准输出
time.Sleep(500 * time.Millisecond)
}
}, tempOutput, output)
}

View File

@@ -56,8 +56,8 @@ func printTableRow(result pst.SpeedTestResult) {
}
location = fmt.Sprintf("%s%s", carrier, result.City)
}
if len(location) > 14 {
location = location[:14] + "..."
if len(location) > 15 {
location = location[:15]
}
upload := "N/A"
if result.UploadMbps > 0 {
@@ -135,6 +135,8 @@ func privateSpeedTest(num int, operator string) (int, error) {
// 去重:确保同一运营商内城市不重复
seenCities := make(map[string]bool)
var bestServers []pst.ServerWithLatencyInfo
// 保留更多备用节点,以应对测速失败的情况(保留 serversPerISP * 2 个备用节点)
maxBackupServers := serversPerISP * 2
for _, serverInfo := range candidateServers {
city := serverInfo.Server.City
if city == "" {
@@ -143,8 +145,8 @@ func privateSpeedTest(num int, operator string) (int, error) {
if !seenCities[city] {
seenCities[city] = true
bestServers = append(bestServers, serverInfo)
// 去重后取前 serversPerISP 个
if len(bestServers) >= serversPerISP {
// 去重后保留足够的备用节点
if len(bestServers) >= maxBackupServers {
break
}
}
@@ -153,7 +155,13 @@ func privateSpeedTest(num int, operator string) (int, error) {
return 0, fmt.Errorf("去重后没有可用的服务器")
}
// 执行测速并逐个打印结果(不打印表头)
// 统计成功输出的节点数
successCount := 0
for i, serverInfo := range bestServers {
// 如果已经成功输出了足够的节点,则停止测试
if successCount >= serversPerISP {
break
}
result := pst.RunSpeedTest(
serverInfo.Server,
false, // 不禁用下载测试
@@ -163,16 +171,21 @@ func privateSpeedTest(num int, operator string) (int, error) {
&serverInfo,
false, // 不显示进度条
)
if result.Success {
// 只要测试成功且有任意一个速度值有效,就输出结果(部分成功也显示)
if result.Success && (result.UploadMbps > 0 || result.DownloadMbps > 0) {
printTableRow(result)
// 只有上传和下载都成功时才计入成功数
if result.UploadMbps > 0 && result.DownloadMbps > 0 {
successCount++
}
}
// 在测试之间暂停(除了最后一个
if i < len(bestServers)-1 {
// 在测试之间暂停(如果还需要继续测试的话
if successCount < serversPerISP && i < len(bestServers)-1 {
time.Sleep(1 * time.Second)
}
}
// 返回实际测试的节点数量
return len(bestServers), nil
// 返回实际成功输出的节点数量
return successCount, nil
}
// privateSpeedTestWithFallback 使用私有测速,如果失败则回退到 global 节点

View File

@@ -219,6 +219,11 @@ func CaptureOutput(f func()) string {
}()
// 执行函数
f()
// 确保所有输出都已经刷新
os.Stdout.Sync()
os.Stderr.Sync()
// 等待一小段时间确保后台goroutine的输出完成
time.Sleep(100 * time.Millisecond)
// 关闭管道写入端,让管道读取端可以读取所有数据
stdoutPipeW.Close()
stderrPipeW.Close()