mirror of
https://github.com/oneclickvirt/ecs.git
synced 2026-04-22 15:17:06 +08:00
791ec8df5e
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
|
|
}
|