mirror of
https://github.com/oneclickvirt/ecs.git
synced 2025-12-24 12:37:53 +08:00
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
330 lines
8.8 KiB
Go
330 lines
8.8 KiB
Go
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
|
||
}
|