Files
ecs/ui/executor.go
spiritlhl 791ec8df5e
Some checks failed
Build All UI APP / Prepare Version (push) Has been cancelled
Build All UI APP / Build Android APK (push) Has been cancelled
Build All UI APP / Build Desktop Apps (amd64, macos-amd64, macos-13, darwin) (push) Has been cancelled
Build All UI APP / Build Desktop Apps (amd64, windows-amd64, windows-latest, windows) (push) Has been cancelled
Build All UI APP / Build Desktop Apps (arm64, macos-arm64, macos-latest, darwin) (push) Has been cancelled
fix:添加UI配置参数对接
2025-11-02 18:59:03 +08:00

330 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ui
import (
"fmt"
"io"
"os"
"os/signal"
"strings"
"sync"
"syscall"
"time"
"github.com/oneclickvirt/CommonMediaTests/commediatests"
"github.com/oneclickvirt/basics/utils"
"github.com/oneclickvirt/ecs/cputest"
"github.com/oneclickvirt/ecs/disktest"
"github.com/oneclickvirt/ecs/memorytest"
"github.com/oneclickvirt/ecs/nexttrace"
"github.com/oneclickvirt/ecs/speedtest"
"github.com/oneclickvirt/ecs/unlocktest"
"github.com/oneclickvirt/ecs/upstreams"
ecsutils "github.com/oneclickvirt/ecs/utils"
"github.com/oneclickvirt/pingtest/pt"
"github.com/oneclickvirt/portchecker/email"
)
const ecsVersion = "v0.1.93"
type CommandExecutor struct {
outputCallback func(string)
}
func NewCommandExecutor(outputCallback func(string)) *CommandExecutor {
return &CommandExecutor{
outputCallback: outputCallback,
}
}
func (e *CommandExecutor) Execute(selectedOptions map[string]bool, language string, testUpload bool, testDownload bool, chinaModeEnabled bool,
cpuMethod, threadMode, memoryMethod, diskMethod, diskPath string, diskMulti bool,
nt3Location, nt3Type string, spNum int) error {
// 设置测试选项
basicStatus := selectedOptions["basic"]
cpuTestStatus := selectedOptions["cpu"]
memoryTestStatus := selectedOptions["memory"]
diskTestStatus := selectedOptions["disk"]
commTestStatus := selectedOptions["comm"]
utTestStatus := selectedOptions["unlock"]
securityTestStatus := selectedOptions["security"]
emailTestStatus := selectedOptions["email"]
backtraceStatus := selectedOptions["backtrace"]
nt3Status := selectedOptions["nt3"]
speedTestStatus := selectedOptions["speed"]
pingTestStatus := selectedOptions["ping"]
// 中国模式逻辑禁用流媒体测试启用PING测试
if chinaModeEnabled {
commTestStatus = false
utTestStatus = false
pingTestStatus = true
}
// 检查网络连接
preCheck := utils.CheckPublicAccess(3 * time.Second)
// 初始化变量
var (
wg1, wg2 sync.WaitGroup
basicInfo, securityInfo, emailInfo, mediaInfo string
output, tempOutput string
outputMutex sync.Mutex
)
startTime := time.Now()
uploadDone := make(chan bool, 1)
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
// 重定向输出到回调
oldStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
done := make(chan bool)
go func() {
buf := make([]byte, 8192) // 增加缓冲区大小
var partial string // 用于保存不完整的行
for {
n, err := r.Read(buf)
if n > 0 && e.outputCallback != nil {
text := partial + string(buf[:n])
// 找到最后一个换行符
lastNewline := strings.LastIndex(text, "\n")
if lastNewline >= 0 {
// 输出完整的行
e.outputCallback(text[:lastNewline+1])
// 保存不完整的部分
partial = text[lastNewline+1:]
} else {
// 没有换行符,全部保存为不完整部分
partial = text
}
}
if err != nil {
if err == io.EOF {
// 输出剩余的不完整部分
if partial != "" && e.outputCallback != nil {
e.outputCallback(partial)
}
break
}
}
}
done <- true
}()
// 执行测试参考原goecs.go的runChineseTests和runEnglishTests顺序
// 1. 基础信息测试
if basicStatus || securityTestStatus {
outputMutex.Lock()
ecsutils.PrintHead(language, 82, ecsVersion)
if basicStatus {
if language == "zh" {
ecsutils.PrintCenteredTitle("系统基础信息", 82)
} else {
ecsutils.PrintCenteredTitle("System-Basic-Information", 82)
}
}
if preCheck.Connected {
_, _, basicInfo, securityInfo, _ = ecsutils.BasicsAndSecurityCheck(language, "ipv4", securityTestStatus)
}
if basicStatus {
fmt.Printf("%s", basicInfo)
}
outputMutex.Unlock()
}
// 2. CPU测试
if cpuTestStatus {
outputMutex.Lock()
realTestMethod, res := cputest.CpuTest(language, cpuMethod, threadMode)
if language == "zh" {
ecsutils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", realTestMethod), 82)
} else {
ecsutils.PrintCenteredTitle(fmt.Sprintf("CPU-Test--%s-Method", realTestMethod), 82)
}
fmt.Print(res)
outputMutex.Unlock()
}
// 3. 内存测试
if memoryTestStatus {
outputMutex.Lock()
realTestMethod, res := memorytest.MemoryTest(language, memoryMethod)
if language == "zh" {
ecsutils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", realTestMethod), 82)
} else {
ecsutils.PrintCenteredTitle(fmt.Sprintf("Memory-Test--%s-Method", realTestMethod), 82)
}
fmt.Print(res)
outputMutex.Unlock()
}
// 4. 磁盘测试
if diskTestStatus {
outputMutex.Lock()
realTestMethod, res := disktest.DiskTest(language, diskMethod, diskPath, diskMulti, true)
if language == "zh" {
ecsutils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", realTestMethod), 82)
} else {
ecsutils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", realTestMethod), 82)
}
fmt.Print(res)
outputMutex.Unlock()
}
// 5. 启动异步测试(流媒体解锁和邮件端口)
if utTestStatus && preCheck.Connected {
wg1.Add(1)
go func() {
defer wg1.Done()
mediaInfo = unlocktest.MediaTest(language)
}()
}
if emailTestStatus && preCheck.Connected {
wg2.Add(1)
go func() {
defer wg2.Done()
emailInfo = email.EmailCheck()
}()
}
// 6. 御三家流媒体测试(仅中文)
if commTestStatus && preCheck.Connected && language == "zh" {
outputMutex.Lock()
ecsutils.PrintCenteredTitle("御三家流媒体测试", 82)
commInfo := commediatests.MediaTests(language)
fmt.Print(commInfo)
outputMutex.Unlock()
}
// 7. 显示跨国流媒体解锁结果
if utTestStatus && preCheck.Connected {
wg1.Wait()
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("跨国流媒体解锁", 82)
} else {
ecsutils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", 82)
}
fmt.Printf("%s", mediaInfo)
outputMutex.Unlock()
}
// 8. 显示IP质量检测结果
if securityTestStatus && preCheck.Connected {
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("IP质量检测", 82)
} else {
ecsutils.PrintCenteredTitle("IP-Quality-Check", 82)
}
fmt.Printf("%s", securityInfo)
outputMutex.Unlock()
}
// 9. 显示邮件端口测试结果
if emailTestStatus && preCheck.Connected {
wg2.Wait()
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("邮件端口检测", 82)
} else {
ecsutils.PrintCenteredTitle("Email-Port-Check", 82)
}
fmt.Println(emailInfo)
outputMutex.Unlock()
}
// 10. 上游及回程线路检测
if backtraceStatus && preCheck.Connected {
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("上游及回程线路检测", 82)
} else {
ecsutils.PrintCenteredTitle("Upstreams-Backtrace-Check", 82)
}
upstreams.UpstreamsCheck()
outputMutex.Unlock()
}
// 11. 三网回程路由检测
if nt3Status && preCheck.Connected {
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("三网回程路由检测", 82)
} else {
ecsutils.PrintCenteredTitle("NextTrace-3Networks-Check", 82)
}
nexttrace.NextTrace3Check(language, nt3Location, nt3Type)
outputMutex.Unlock()
}
// 12. PING值测试
if pingTestStatus && preCheck.Connected {
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("三网PING值检测", 82)
} else {
ecsutils.PrintCenteredTitle("Three-Network-PING-Test", 82)
}
pingResult := pt.PingTest()
fmt.Print(pingResult)
outputMutex.Unlock()
}
// 13. 速度测试
if speedTestStatus && preCheck.Connected {
outputMutex.Lock()
if language == "zh" {
ecsutils.PrintCenteredTitle("就近节点测速", 82)
} else {
ecsutils.PrintCenteredTitle("Speed-Test", 82)
}
speedtest.ShowHead(language)
// 根据上传/下载配置进行测试
if testUpload || testDownload {
speedtest.NearbySP()
if language == "zh" {
speedtest.CustomSP("net", "global", spNum, language)
} else {
speedtest.CustomSP("net", "global", -1, language)
}
}
outputMutex.Unlock()
}
// 打印时间信息
outputMutex.Lock()
endTime := time.Now()
duration := endTime.Sub(startTime)
minutes := int(duration.Minutes())
seconds := int(duration.Seconds()) % 60
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
ecsutils.PrintCenteredTitle("", 82)
if language == "zh" {
fmt.Printf("花费 : %d 分 %d 秒\n", minutes, seconds)
fmt.Printf("时间 : %s\n", currentTime)
} else {
fmt.Printf("Cost Time : %d min %d sec\n", minutes, seconds)
fmt.Printf("Current Time : %s\n", currentTime)
}
ecsutils.PrintCenteredTitle("", 82)
outputMutex.Unlock()
// 清理
_ = uploadDone
_ = sig
_ = output
_ = tempOutput
// 恢复输出
w.Close()
<-done
os.Stdout = oldStdout
return nil
}