From dbddbc29a3c6d87318170d44c49b6fe30cc6be44 Mon Sep 17 00:00:00 2001 From: spiritysdx Date: Mon, 1 Jul 2024 11:50:33 +0800 Subject: [PATCH] update --- go.mod | 2 +- go.sum | 2 + goecs.go | 448 +++++++++++++++++++++++++++++++++++-------------- utils/utils.go | 119 ++++++++++++- 4 files changed, 442 insertions(+), 129 deletions(-) diff --git a/go.mod b/go.mod index 79d5186..e8b253c 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/oneclickvirt/UnlockTests v0.0.10-20240630044930 github.com/oneclickvirt/backtrace v0.0.4-20240624090335 github.com/oneclickvirt/basics v0.0.3-20240625075226 - github.com/oneclickvirt/cputest v0.0.6-20240630144058 + github.com/oneclickvirt/cputest v0.0.7-20240701020012 github.com/oneclickvirt/defaultset v0.0.2-20240624082446 github.com/oneclickvirt/disktest v0.0.3-20240629152513 github.com/oneclickvirt/memorytest v0.0.1-20240624151629 diff --git a/go.sum b/go.sum index c497dcf..9eee107 100644 --- a/go.sum +++ b/go.sum @@ -85,6 +85,8 @@ github.com/oneclickvirt/basics v0.0.3-20240625075226 h1:K9VriCHIYnXPZXBSn9PRQX+j github.com/oneclickvirt/basics v0.0.3-20240625075226/go.mod h1:dTB+/oyFQYfTYX55rFJVWatum5F9g62zjfmHCM6Vj1s= github.com/oneclickvirt/cputest v0.0.6-20240630144058 h1:bFOM4MS+uaU7slFaZR91/bJ57AFM23RWPEik+GTFS2w= github.com/oneclickvirt/cputest v0.0.6-20240630144058/go.mod h1:MmaHN9+XMntI3rLycwj8Ne31fG18IfNoa8N2utDK1CY= +github.com/oneclickvirt/cputest v0.0.7-20240701020012 h1:U5cCI+6ZU3pudoAlmb1b3yB9IQNm5AnDXi1TQAZJCIA= +github.com/oneclickvirt/cputest v0.0.7-20240701020012/go.mod h1:MmaHN9+XMntI3rLycwj8Ne31fG18IfNoa8N2utDK1CY= github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc= github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E= github.com/oneclickvirt/disktest v0.0.3-20240629152513 h1:ZW7MBMd2HxQi1ktg/ztVI2A10JzF4ZI6I7ATZvcK9w8= diff --git a/goecs.go b/goecs.go index 9ee2172..e310c1f 100644 --- a/goecs.go +++ b/goecs.go @@ -1,8 +1,12 @@ package main import ( + "bufio" "flag" "fmt" + "github.com/oneclickvirt/CommonMediaTests/commediatests" + backtraceori "github.com/oneclickvirt/backtrace/bk" + basicmodel "github.com/oneclickvirt/basics/model" "github.com/oneclickvirt/ecs/backtrace" "github.com/oneclickvirt/ecs/commediatest" "github.com/oneclickvirt/ecs/cputest" @@ -12,96 +16,301 @@ import ( "github.com/oneclickvirt/ecs/speedtest" "github.com/oneclickvirt/ecs/unlocktest" "github.com/oneclickvirt/ecs/utils" + gostunmodel "github.com/oneclickvirt/gostun/model" "github.com/oneclickvirt/portchecker/email" + speedtestmodel "github.com/oneclickvirt/speedtest/model" "os" - "path/filepath" "regexp" "runtime" + "strings" "sync" "time" ) var ( - ecsVersion = "2024.06.30" - showVersion bool - language string - cpuTestMethod, cpuTestThreadMode string - memoryTestMethod string - diskTestMethod, diskTestPath string - diskMultiCheck bool - nt3CheckType, nt3Location string - spNum int - width = 84 + ecsVersion = "2024.07.01.1" + menuMode bool + choice string + showVersion bool + enableLogger bool + language string + cpuTestMethod, cpuTestThreadMode string + memoryTestMethod string + diskTestMethod, diskTestPath string + diskMultiCheck bool + nt3CheckType, nt3Location string + spNum int + width = 84 + basicStatus, cpuTestStatus, memoryTestStatus, diskTestStatus bool + commTestStatus, utTestStatus, securityTestStatus, emailTestStatus bool + backtraceStatus, nt3Status, speedTestStatus bool ) func main() { - flag.BoolVar(&showVersion, "v", false, "Show version information") - flag.StringVar(&language, "l", "zh", "Specify language (supported: en, zh)") - flag.StringVar(&cpuTestMethod, "cpum", "sysbench", "Specify CPU test method (supported: sysbench, geekbench, winsat)") - flag.StringVar(&cpuTestThreadMode, "cput", "multi", "Specify CPU test thread mode (supported: single multi)") - flag.StringVar(&memoryTestMethod, "memorym", "dd", "Specify Memory test method (supported: sysbench, dd, winsat)") - flag.StringVar(&diskTestMethod, "diskm", "fio", "Specify Disk test method (supported: fio, dd, winsat)") - flag.StringVar(&diskTestPath, "diskp", "", "Specify Disk test path, example: -diskp /root") - flag.BoolVar(&diskMultiCheck, "diskmc", false, "Enable multiple disk checks, example: -diskmc=false") - flag.StringVar(&nt3Location, "nt3loc", "GZ", "指定三网回程路由检测的地址,支持 GZ, SH, BJ, CD 对应 广州,上海,北京,成都") - flag.StringVar(&nt3CheckType, "nt3t", "ipv4", "指定三网回程路由检测的类型,支持 both, ipv4, ipv6") - flag.IntVar(&spNum, "spnum", 2, "Specify speedtest each operator servers num") + flag.BoolVar(&showVersion, "v", false, "Display version information") + flag.BoolVar(&menuMode, "menu", true, "Enable/Disable menu mode, disable example: -menu=false") // true 默认启用菜单栏模式 + flag.StringVar(&language, "l", "zh", "Set language (supported: en, zh)") + flag.BoolVar(&basicStatus, "basic", true, "Enable/Disable basic test") + flag.BoolVar(&cpuTestStatus, "cpu", true, "Enable/Disable CPU test") + flag.BoolVar(&memoryTestStatus, "memory", true, "Enable/Disable memory test") + flag.BoolVar(&diskTestStatus, "disk", true, "Enable/Disable disk test") + flag.BoolVar(&commTestStatus, "comm", true, "Enable/Disable common media test") + flag.BoolVar(&utTestStatus, "ut", true, "Enable/Disable unlock media test") + flag.BoolVar(&securityTestStatus, "security", true, "Enable/Disable security test") + flag.BoolVar(&emailTestStatus, "email", true, "Enable/Disable email port test") + flag.BoolVar(&backtraceStatus, "backtrace", true, "Enable/Disable backtrace test (in 'en' language or on `windows` it always false)") + flag.BoolVar(&nt3Status, "nt3", true, "Enable/Disable NT3 test (in 'en' language or on `windows` it always false)") + flag.BoolVar(&speedTestStatus, "speed", true, "Enable/Disable speed test") + flag.StringVar(&cpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)") + flag.StringVar(&cpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)") + flag.StringVar(&memoryTestMethod, "memorym", "dd", "Set memory test method (supported: sysbench, dd, winsat)") + flag.StringVar(&diskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)") + flag.StringVar(&diskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root") + flag.BoolVar(&diskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false") + flag.StringVar(&nt3Location, "nt3loc", "GZ", "Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu)") + flag.StringVar(&nt3CheckType, "nt3t", "ipv4", "Set NT3 test type (supported: both, ipv4, ipv6)") + flag.IntVar(&spNum, "spnum", 2, "Set the number of servers per operator for speed test") + flag.BoolVar(&enableLogger, "log", false, "Enable/Disable logging in the current path") flag.Parse() if showVersion { fmt.Println(ecsVersion) return } + if enableLogger { + basicmodel.EnableLoger = true + speedtestmodel.EnableLoger = true + gostunmodel.EnableLoger = true + commediatests.EnableLoger = true + backtraceori.EnableLoger = true + } + if menuMode { + basicStatus, cpuTestStatus, memoryTestStatus, diskTestStatus = false, false, false, false + commTestStatus, utTestStatus, securityTestStatus, emailTestStatus = false, false, false, false + backtraceStatus, nt3Status, speedTestStatus = false, false, false + // 正则表达式匹配纯数字 + re := regexp.MustCompile(`^\d+$`) + reader := bufio.NewReader(os.Stdin) + switch language { + case "zh": + fmt.Println("1. 融合怪完全体") + fmt.Println("2. 极简版(系统信息+CPU+内存+磁盘+测速节点5个)") + fmt.Println("3. 精简版(系统信息+CPU+内存+磁盘+御三家+常用流媒体+回程+路由+测速节点5个)") + fmt.Println("4. 精简网络版(系统信息+CPU+内存+磁盘+回程+路由+测速节点5个)") + fmt.Println("5. 精简解锁版(系统信息+CPU+内存+磁盘IO+御三家+常用流媒体+测速节点5个)") + fmt.Println("6. 网络单项(IP质量检测+三网回程+三网路由与延迟+测速节点11个)") + fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)") + fmt.Println("8. 硬件单项(基础系统信息+CPU+内存+dd磁盘测试+fio磁盘测试)") + fmt.Println("9. IP质量检测(15个数据库的IP检测+邮件端口检测)") + fmt.Println("10. 三网回程线路+广州三网路由+全国三网延迟") + case "en": + fmt.Println("1. VPS Fusion Monster Test Comprehensive Test Suite") + fmt.Println("2. Minimal Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)") + fmt.Println("3. Standard Test Suite (System Info + CPU + Memory + Disk + Basic Unlock Tests + Common Streaming Services + 5 Speed Test Nodes)") + fmt.Println("4. Network-Focused Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)") + fmt.Println("5. Unlock-Focused Test Suite (System Info + CPU + Memory + Disk IO + Basic Unlock Tests + Common Streaming Services + 5 Speed Test Nodes)") + fmt.Println("6. Network-Only Test (IP Quality Test + 5 Speed Test Nodes)") + fmt.Println("7. Unlock-Only Test (Basic Unlock Tests + Common Streaming Services Unlock)") + fmt.Println("8. Hardware-Only Test (Basic System Info + CPU + Memory + dd Disk Test + fio Disk Test)") + fmt.Println("9. IP Quality Test (IP Test with 15 Databases + Email Port Test)") + } + for { + fmt.Print("请输入选项 / Please enter your choice: ") + input, _ := reader.ReadString('\n') + input = strings.TrimSpace(input) + if re.MatchString(input) { + choice = input + switch choice { + case "1": + basicStatus = true + cpuTestStatus = true + memoryTestStatus = true + diskTestStatus = true + commTestStatus = true + utTestStatus = true + securityTestStatus = true + emailTestStatus = true + backtraceStatus = true + nt3Status = true + speedTestStatus = true + break + case "2": + basicStatus = true + cpuTestStatus = true + memoryTestStatus = true + diskTestStatus = true + speedTestStatus = true + break + case "3": + basicStatus = true + cpuTestStatus = true + memoryTestStatus = true + diskTestStatus = true + commTestStatus = true + utTestStatus = true + securityTestStatus = true + backtraceStatus = true + nt3Status = true + speedTestStatus = true + break + case "4": + basicStatus = true + cpuTestStatus = true + memoryTestStatus = true + diskTestStatus = true + backtraceStatus = true + nt3Status = true + speedTestStatus = true + break + case "5": + basicStatus = true + cpuTestStatus = true + memoryTestStatus = true + diskTestStatus = true + securityTestStatus = true + speedTestStatus = true + break + case "6": + speedTestStatus = true + backtraceStatus = true + nt3Status = true + break + case "7": + securityTestStatus = true + commTestStatus = true + break + case "8": + basicStatus = true + cpuTestStatus = true + memoryTestStatus = true + diskTestStatus = true + break + case "9": + emailTestStatus = true + break + case "10": + backtraceStatus = true + nt3Status = true + speedTestStatus = true + break + default: + if language == "zh" { + fmt.Println("无效的选项") + } else { + fmt.Println("Invalid choice") + } + } + } else { + if language == "zh" { + fmt.Println("输入错误,请输入一个纯数字") + } else { + fmt.Println("Invalid input, please enter a number") + } + } + } + } + if language == "en" { + backtraceStatus = false + nt3Status = false + } startTime := time.Now() var ( - wg sync.WaitGroup - basicInfo, securityInfo, emailInfo, mediaInfo string - output, tempOutput string + wg1, wg2, wg3 sync.WaitGroup + basicInfo, securityInfo, emailInfo, mediaInfo, backtraceInfo string + output, tempOutput string ) output = utils.PrintAndCapture(func() { switch language { case "zh": utils.PrintHead(language, width, ecsVersion) - utils.PrintCenteredTitle("基础信息", width) - basicInfo, securityInfo, nt3CheckType = utils.SecurityCheck(language, nt3CheckType) - fmt.Printf(basicInfo) - utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", cpuTestMethod), width) - cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode) - utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", cpuTestMethod), width) - memorytest.MemoryTest(language, memoryTestMethod) - utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", diskTestMethod), width) - disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck) - utils.PrintCenteredTitle("御三家流媒体解锁", width) - wg.Add(2) - go func() { - defer wg.Done() - emailInfo = email.EmailCheck() - }() - go func() { - defer wg.Done() - mediaInfo = unlocktest.MediaTest(language) - }() - commediatest.ComMediaTest(language) - utils.PrintCenteredTitle("跨国流媒体解锁", width) - wg.Wait() // 后台任务含流媒体测试和邮件测试 - fmt.Printf(mediaInfo) - utils.PrintCenteredTitle("IP质量检测", width) - fmt.Printf(securityInfo) - utils.PrintCenteredTitle("邮件端口检测", width) - fmt.Println(emailInfo) - if runtime.GOOS != "windows" { - utils.PrintCenteredTitle("三网回程", width) - backtrace.BackTrace() - // nexttrace 在win上不支持检测,报错 bind: An invalid argument was supplied. - utils.PrintCenteredTitle("路由检测", width) - ntrace.TraceRoute3(language, nt3Location, nt3CheckType) + if basicStatus || securityTestStatus { + if basicStatus { + utils.PrintCenteredTitle("基础信息", width) + } + basicInfo, securityInfo, nt3CheckType = utils.SecurityCheck(language, nt3CheckType, securityTestStatus) + if basicStatus { + fmt.Printf(basicInfo) + } + } + if cpuTestStatus { + utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", cpuTestMethod), width) + cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode) + } + if memoryTestStatus { + utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", cpuTestMethod), width) + memorytest.MemoryTest(language, memoryTestMethod) + } + if diskTestStatus { + utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", diskTestMethod), width) + disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck) + } + if emailTestStatus { + wg2.Add(1) + go func() { + defer wg1.Done() + emailInfo = email.EmailCheck() + }() + } + if utTestStatus { + wg1.Add(1) + go func() { + defer wg1.Done() + mediaInfo = unlocktest.MediaTest(language) + }() + } + if runtime.GOOS == "windows" { + if backtraceStatus { + wg3.Add(1) + go func() { + defer wg3.Done() + backtraceInfo = utils.GetCaptureOutput(func() { + backtrace.BackTrace() + }) + }() + } + } + if commTestStatus { + utils.PrintCenteredTitle("御三家流媒体解锁", width) + commediatest.ComMediaTest(language) + } + if utTestStatus { + utils.PrintCenteredTitle("跨国流媒体解锁", width) + wg1.Wait() + fmt.Printf(mediaInfo) + } + if securityTestStatus { + utils.PrintCenteredTitle("IP质量检测", width) + fmt.Printf(securityInfo) + } + if emailTestStatus { + utils.PrintCenteredTitle("邮件端口检测", width) + wg2.Wait() + fmt.Println(emailInfo) + } + if runtime.GOOS != "windows" { + if backtraceStatus { + utils.PrintCenteredTitle("三网回程", width) + wg3.Wait() + fmt.Printf(backtraceInfo) + } + // nexttrace 在win上不支持检测,报错 bind: An invalid argument was supplied. + if nt3Status { + utils.PrintCenteredTitle("路由检测", width) + ntrace.TraceRoute3(language, nt3Location, nt3CheckType) + } + } + if speedTestStatus { + utils.PrintCenteredTitle("就近节点测速", width) + speedtest.ShowHead(language) + if (menuMode && choice == "1") || !menuMode { + speedtest.NearbySP() + speedtest.CustomSP("net", "global", 2) + speedtest.CustomSP("net", "cu", spNum) + speedtest.CustomSP("net", "ct", spNum) + speedtest.CustomSP("net", "cmcc", spNum) + } else if menuMode && choice == "2" || choice == "3" || choice == "4" || choice == "5" { + speedtest.CustomSP("net", "global", 4) + } } - utils.PrintCenteredTitle("就近节点测速", width) - speedtest.ShowHead(language) - speedtest.NearbySP() - speedtest.CustomSP("net", "global", 4) - speedtest.CustomSP("net", "cu", spNum) - speedtest.CustomSP("net", "ct", spNum) - speedtest.CustomSP("net", "cmcc", spNum) utils.PrintCenteredTitle("", width) endTime := time.Now() duration := endTime.Sub(startTime) @@ -113,34 +322,57 @@ func main() { utils.PrintCenteredTitle("", width) case "en": utils.PrintHead(language, width, ecsVersion) - utils.PrintCenteredTitle("Basic Information", width) - basicInfo, securityInfo, nt3CheckType = utils.SecurityCheck(language, nt3CheckType) - fmt.Printf(basicInfo) - utils.PrintCenteredTitle(fmt.Sprintf("CPU Test - %s Method", cpuTestMethod), width) - cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode) - utils.PrintCenteredTitle(fmt.Sprintf("Memory Test - %s Method", memoryTestMethod), width) - utils.PrintCenteredTitle(fmt.Sprintf("Disk Test - %s Method", diskTestMethod), width) - utils.PrintCenteredTitle(fmt.Sprintf("Disk Test - %s Method", diskTestMethod), width) - disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck) - wg.Add(1) - go func() { - defer wg.Done() - emailInfo = email.EmailCheck() - }() - utils.PrintCenteredTitle("The Three Families Streaming Media Unlock", width) - commediatest.ComMediaTest(language) - utils.PrintCenteredTitle("Cross-Border Streaming Media Unlock", width) - unlocktest.MediaTest(language) - utils.PrintCenteredTitle("IP Quality Check", width) - fmt.Printf(securityInfo) - utils.PrintCenteredTitle("Email Port Check", width) - wg.Wait() - fmt.Println(emailInfo) - //utils.PrintCenteredTitle("Return Path Routing", width) - utils.PrintCenteredTitle("Nearby Node Speed Test", width) - speedtest.ShowHead(language) - speedtest.NearbySP() - speedtest.CustomSP("net", "global", -1) + if basicStatus || securityTestStatus { + if basicStatus { + utils.PrintCenteredTitle("Basic Information", width) + } + basicInfo, securityInfo, nt3CheckType = utils.SecurityCheck(language, nt3CheckType, securityTestStatus) + if basicStatus { + fmt.Printf(basicInfo) + } + } + if cpuTestStatus { + utils.PrintCenteredTitle(fmt.Sprintf("CPU Test - %s Method", cpuTestMethod), width) + cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode) + } + if memoryTestStatus { + utils.PrintCenteredTitle(fmt.Sprintf("Memory Test - %s Method", memoryTestMethod), width) + memorytest.MemoryTest(language, memoryTestMethod) + } + if diskTestStatus { + utils.PrintCenteredTitle(fmt.Sprintf("Disk Test - %s Method", diskTestMethod), width) + disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck) + } + if emailTestStatus { + wg1.Add(1) + go func() { + defer wg1.Done() + emailInfo = email.EmailCheck() + }() + } + if commTestStatus { + utils.PrintCenteredTitle("The Three Families Streaming Media Unlock", width) + commediatest.ComMediaTest(language) + } + if utTestStatus { + utils.PrintCenteredTitle("Cross-Border Streaming Media Unlock", width) + unlocktest.MediaTest(language) + } + if securityTestStatus { + utils.PrintCenteredTitle("IP Quality Check", width) + fmt.Printf(securityInfo) + } + if emailTestStatus { + utils.PrintCenteredTitle("Email Port Check", width) + wg1.Wait() + fmt.Println(emailInfo) + } + if speedTestStatus { + utils.PrintCenteredTitle("Nearby Node Speed Test", width) + speedtest.ShowHead(language) + speedtest.NearbySP() + speedtest.CustomSP("net", "global", -1) + } utils.PrintCenteredTitle("", width) endTime := time.Now() duration := endTime.Sub(startTime) @@ -154,34 +386,6 @@ func main() { fmt.Println("Unsupported language") } }, tempOutput, output) - // 创建文件 filePath := "goecs.txt" - file, err := os.Create(filePath) - if err != nil { - fmt.Println("Can not make file:", err) - return - } - defer file.Close() - // 将 output 写入文件 - // 匹配 ANSI 转义序列 - ansiRegex := regexp.MustCompile("\x1B\\[[0-9;]+[a-zA-Z]") - // 移除 ANSI 转义序列 - cleanedOutput := ansiRegex.ReplaceAllString(output, "") - _, err = file.WriteString(cleanedOutput) - if err != nil { - fmt.Println("Can not write file:", err) - return - } - // 获取文件的绝对路径 - absPath, err := filepath.Abs(filePath) - if err != nil { - fmt.Println("Get file absPath failed:", err) - return - } - shorturl, err := utils.UploadText(absPath) - if err != nil { - fmt.Println("Upload failed, can not generate short URL.") - fmt.Println(err.Error()) - } - fmt.Println("Upload successful, short URL:", shorturl) + utils.ProcessAndUpload(output, filePath, true) } diff --git a/utils/utils.go b/utils/utils.go index 824ef02..314d6fe 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -9,8 +9,11 @@ import ( "github.com/oneclickvirt/security/network" "io" "os" + "path/filepath" + "regexp" "strings" "sync" + "time" "unicode/utf8" ) @@ -27,13 +30,13 @@ func PrintCenteredTitle(title string, width int) { // PrintHead 根据语言打印头部信息 func PrintHead(language string, width int, ecsVersion string) { if language == "zh" { - PrintCenteredTitle("融合怪测试", width) + PrintCenteredTitle("VPS融合怪测试", width) fmt.Printf("版本:%s\n", ecsVersion) fmt.Println("测评频道: https://t.me/vps_reviews\n" + "Go项目地址:https://github.com/oneclickvirt/ecs\n" + "Shell项目地址:https://github.com/spiritLHLS/ecs") } else { - PrintCenteredTitle("Fusion Monster Test", width) + PrintCenteredTitle("VPS Fusion Monster Test", width) fmt.Printf("Version: %s\n", ecsVersion) fmt.Println("Review Channel: https://t.me/vps_reviews\n" + "Go Project URL: https://github.com/oneclickvirt/ecs\n" + @@ -42,14 +45,14 @@ func PrintHead(language string, width int, ecsVersion string) { } // SecurityCheck 执行安全检查 -func SecurityCheck(language, nt3CheckType string) (string, string, string) { +func SecurityCheck(language, nt3CheckType string, securtyCheckStatus bool) (string, string, string) { var wgt sync.WaitGroup var ipInfo, securityInfo, systemInfo string var err error wgt.Add(2) go func() { defer wgt.Done() - ipInfo, securityInfo, err = network.NetworkCheck("both", true, language) + ipInfo, securityInfo, err = network.NetworkCheck("both", securtyCheckStatus, language) if err != nil { fmt.Println(err.Error()) } @@ -88,7 +91,57 @@ func SecurityCheck(language, nt3CheckType string) (string, string, string) { return basicInfo, securityInfo, nt3CheckType } -// CaptureOutput 捕获函数输出和错误输出并返回字符串 +// GetCaptureOutput 仅捕获输出不实时输出 +func GetCaptureOutput(f func()) string { + // 保存旧的 stdout 和 stderr + oldStdout := os.Stdout + oldStderr := os.Stderr + // 创建管道 + stdoutPipeR, stdoutPipeW, err := os.Pipe() + if err != nil { + return "Error creating stdout pipe" + } + stderrPipeR, stderrPipeW, err := os.Pipe() + if err != nil { + stdoutPipeW.Close() + stdoutPipeR.Close() + return "Error creating stderr pipe" + } + // 替换标准输出和标准错误输出为管道写入端 + os.Stdout = stdoutPipeW + os.Stderr = stderrPipeW + // 恢复标准输出和标准错误输出 + defer func() { + os.Stdout = oldStdout + os.Stderr = oldStderr + stdoutPipeW.Close() + stderrPipeW.Close() + }() + // 缓冲区 + var stdoutBuf, stderrBuf bytes.Buffer + // 并发读取 stdout 和 stderr + done := make(chan struct{}) + go func() { + io.Copy(&stdoutBuf, stdoutPipeR) + done <- struct{}{} + }() + go func() { + io.Copy(&stderrBuf, stderrPipeR) + done <- struct{}{} + }() + // 执行函数 + f() + // 关闭管道写入端,让管道读取端可以读取所有数据 + stdoutPipeW.Close() + stderrPipeW.Close() + // 等待两个 goroutine 完成 + <-done + <-done + // 返回捕获的输出字符串 + return stdoutBuf.String() + stderrBuf.String() +} + +// CaptureOutput 捕获函数输出和错误输出,实时输出,并返回字符串 func CaptureOutput(f func()) string { // 保存旧的 stdout 和 stderr oldStdout := os.Stdout @@ -139,7 +192,8 @@ func CaptureOutput(f func()) string { <-done <-done // 返回捕获的输出字符串 - return stdoutBuf.String() + stderrBuf.String() + // stderrBuf.String() + return stdoutBuf.String() } // PrintAndCapture 捕获函数输出的同时打印内容 @@ -154,6 +208,11 @@ func UploadText(absPath string) (string, error) { url := "https://paste.spiritlhl.net/api/upload" token := network.SecurityUploadToken client := req.DefaultClient() + client.SetTimeout(6 * time.Second) + client.R(). + SetRetryCount(2). + SetRetryBackoffInterval(1*time.Second, 5*time.Second). + SetRetryFixedInterval(2 * time.Second) file, _ := os.Open(absPath) resp, err := client.R(). SetHeader("Authorization", token). @@ -173,3 +232,51 @@ func UploadText(absPath string) (string, error) { return "", fmt.Errorf("upload failed with status code: %d", resp.StatusCode) } } + +// ProcessAndUpload 创建结果文件并上传文件 +func ProcessAndUpload(output string, filePath string, enableUplaod bool) { + // 检查文件是否存在 + if _, err := os.Stat(filePath); err == nil { + // 文件存在,删除文件 + err = os.Remove(filePath) + if err != nil { + fmt.Println("Cannot delete file:", err) + return + } + } + // 创建文件 + file, err := os.Create(filePath) + if err != nil { + fmt.Println("Cannot create file:", err) + return + } + defer file.Close() + // 匹配 ANSI 转义序列 + ansiRegex := regexp.MustCompile("\x1B\\[[0-9;]+[a-zA-Z]") + // 移除 ANSI 转义序列 + cleanedOutput := ansiRegex.ReplaceAllString(output, "") + // 写入文件 + _, err = file.WriteString(cleanedOutput) + if err != nil { + fmt.Println("Cannot write to file:", err) + return + } else { + fmt.Println("Write test result in ", filePath) + } + if enableUplaod { + // 获取文件的绝对路径 + absPath, err := filepath.Abs(filePath) + if err != nil { + fmt.Println("Failed to get absolute file path:", err) + return + } + // 上传文件并生成短链接 + shorturl, err := UploadText(absPath) + if err != nil { + fmt.Println("Upload failed, cannot generate short URL.") + fmt.Println(err.Error()) + return + } + fmt.Println("Upload successful, short URL:", shorturl) + } +}