Compare commits

..

5 Commits

Author SHA1 Message Date
spiritlhl
5ff18ed7c7 feat: 更新版本 2025-08-05 14:13:46 +00:00
spiritlhl
df897db244 feat: 添加支持如非最新版本使用时提示版本更新,添加使用统计 2025-08-05 14:13:20 +00:00
spiritlhl
9a8680491c fix: 支持三网回程详细路可指定ALL对四个主要城市全测 2025-08-05 13:37:43 +00:00
spiritlhl
33f81fd6aa fix: 修复笔误 2025-08-05 21:02:05 +08:00
github-actions[bot]
940703c3f9 chore: update ECS_VERSION to 0.1.73 in goecs.sh 2025-08-05 09:42:55 +00:00
6 changed files with 149 additions and 17 deletions

View File

@@ -15,7 +15,7 @@
- [流媒体解锁](#流媒体解锁)
- [IP质量检测](#IP质量检测)
- [邮件端口检测](#邮件端口检测)
- [三网回城线路检测](#三网回城线路检测)
- [上游及回程线路检测](#上游及回程线路检测)
- [三网回程路由检测](#三网回程路由检测)
- [就近测速](#就近测速)

2
go.mod
View File

@@ -13,7 +13,7 @@ require (
github.com/oneclickvirt/disktest v0.0.9-20250801101625
github.com/oneclickvirt/gostun v0.0.5-20250727155022
github.com/oneclickvirt/memorytest v0.0.9-20250720135728
github.com/oneclickvirt/nt3 v0.0.6-20250726150925
github.com/oneclickvirt/nt3 v0.0.7-20250805133514
github.com/oneclickvirt/pingtest v0.0.8-20250728015259
github.com/oneclickvirt/portchecker v0.0.3-20250728015900
github.com/oneclickvirt/security v0.0.6-20250805090112

4
go.sum
View File

@@ -118,8 +118,8 @@ github.com/oneclickvirt/mbw v0.0.1-20250630140849 h1:p6RMhOPBnQKAm9+VEQ2axAFsidr
github.com/oneclickvirt/mbw v0.0.1-20250630140849/go.mod h1:0Vq6NRpyLmGUdfHfL3uDcFsuZhi7KlG+OCs5ky2757Y=
github.com/oneclickvirt/memorytest v0.0.9-20250720135728 h1:RusZfaESDXK+k5YYfVXTCW5zLeQEd/dYY80a6xievE0=
github.com/oneclickvirt/memorytest v0.0.9-20250720135728/go.mod h1:7xMacjQobvFAtODht2hxTsB9hM2IFS7vZk3gxx+bsjo=
github.com/oneclickvirt/nt3 v0.0.6-20250726150925 h1:M+9kEpMp+O2a//yp9zJ11DleK7hxEmFd5jOWKNrSlmY=
github.com/oneclickvirt/nt3 v0.0.6-20250726150925/go.mod h1:O7YkaOMFihB8hwQiD74WTbDlyoTieDwTDBR6jbkZaP0=
github.com/oneclickvirt/nt3 v0.0.7-20250805133514 h1:PeDFYMaqO3nH8dVNHek1HtjxBYVli1R5Rtd/5uFOSN0=
github.com/oneclickvirt/nt3 v0.0.7-20250805133514/go.mod h1:O7YkaOMFihB8hwQiD74WTbDlyoTieDwTDBR6jbkZaP0=
github.com/oneclickvirt/pingtest v0.0.8-20250728015259 h1:egoxZRZBOWN3JqBwqEsULDyRo2/dpGMeWcmV3U87zig=
github.com/oneclickvirt/pingtest v0.0.8-20250728015259/go.mod h1:gxwsxxwitNQiGq2OI0ZogYoOLwc8DtuOdSRe6/EvRqs=
github.com/oneclickvirt/portchecker v0.0.3-20250728015900 h1:AomzdppSOFB70AJESQhlp0IPbsHTTJGimAWDk2TzCWM=

View File

@@ -39,7 +39,7 @@ import (
)
var (
ecsVersion = "v0.1.73"
ecsVersion = "v0.1.74"
menuMode bool
onlyChinaTest bool
input, choice string
@@ -144,7 +144,7 @@ func parseFlags() {
goecsFlag.StringVar(&diskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)")
goecsFlag.StringVar(&diskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root")
goecsFlag.BoolVar(&diskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false")
goecsFlag.StringVar(&nt3Location, "nt3loc", "GZ", "Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu)")
goecsFlag.StringVar(&nt3Location, "nt3loc", "GZ", "Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all)")
goecsFlag.StringVar(&nt3CheckType, "nt3t", "ipv4", "Set NT3 test type (supported: both, ipv4, ipv6)")
goecsFlag.IntVar(&spNum, "spnum", 2, "Set the number of servers per operator for speed test")
goecsFlag.BoolVar(&enableLogger, "log", false, "Enable/Disable logging in the current path")
@@ -236,6 +236,7 @@ Loop:
fmt.Println("Can not test without network connection!")
return
}
nt3Location = "ALL"
setRouteTestStatus()
break Loop
default:
@@ -245,21 +246,62 @@ Loop:
}
func printMenuOptions() {
var stats *utils.StatsResponse
var statsErr error
var githubInfo *utils.GitHubRelease
var githubErr error
var pwg sync.WaitGroup
pwg.Add(2)
go func() {
defer pwg.Done()
stats, statsErr = utils.GetGoescStats()
}()
go func() {
defer pwg.Done()
githubInfo, githubErr = utils.GetLatestEcsRelease()
}()
pwg.Wait()
var statsInfo string
if statsErr != nil {
statsInfo = "NULL"
} else {
statsInfo = fmt.Sprintf("总使用量: %s | 今日使用: %s",
utils.FormatGoecsNumber(stats.Total),
utils.FormatGoecsNumber(stats.Daily))
}
var cmp int
if githubErr == nil {
cmp = utils.CompareVersions(ecsVersion, githubInfo.TagName)
} else {
cmp = 0
}
switch language {
case "zh":
fmt.Println("VPS融合怪版本: ", ecsVersion)
fmt.Println("1. 融合怪完全体")
fmt.Printf("VPS融合怪版本: %s\n", ecsVersion)
switch cmp {
case -1:
fmt.Printf("检测到新版本 %s 如有必要请更新!\n", githubInfo.TagName)
}
fmt.Printf("使用统计: %s\n", statsInfo)
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("6. 网络单项(IP质量检测+上游及三网回程+广州三网回程详细路由+全国延迟+测速节点11个)")
fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)")
fmt.Println("8. 硬件单项(系统信息+CPU+内存+dd磁盘测试+fio磁盘测试)")
fmt.Println("8. 硬件单项(系统信息+CPU+dd磁盘测试+fio磁盘测试)")
fmt.Println("9. IP质量检测(15个数据库的IP检测+邮件端口检测)")
fmt.Println("10. 三网回程线路+广州三网路由+全国三网延迟")
fmt.Println("10. 三网回程线路检测+三网回程详细路由(北京上海广州成都)+三网延迟测试(全国)")
case "en":
fmt.Println("VPS Fusion Monster Test Version: ", ecsVersion)
fmt.Printf("VPS Fusion Monster Test Version: %s\n", ecsVersion)
switch cmp {
case -1:
fmt.Printf("New version detected %s update if necessary!\n", githubInfo.TagName)
}
fmt.Printf("Total Usage: %s | Daily Usage: %s\n",
utils.FormatGoecsNumber(stats.Total),
utils.FormatGoecsNumber(stats.Daily))
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 + 5 Speed Test Nodes)")
@@ -339,6 +381,7 @@ func setNetworkOnlyTestStatus() {
speedTestStatus = true
backtraceStatus = true
nt3Status = true
pingTestStatus = true
}
func setUnlockOnlyTestStatus() {

View File

@@ -143,7 +143,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.72"
ECS_VERSION="0.1.73"
for api in \
"https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \
"https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \
@@ -155,8 +155,8 @@ goecs_check() {
sleep 1
done
if [ -z "$ECS_VERSION" ]; then
_yellow "Unable to get version info, using default version 0.1.72"
ECS_VERSION="0.1.72"
_yellow "Unable to get version info, using default version 0.1.73"
ECS_VERSION="0.1.73"
fi
version_output=""
for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do

View File

@@ -11,6 +11,7 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"
"time"
@@ -24,6 +25,21 @@ import (
"github.com/oneclickvirt/security/network"
)
// 获取本程序本日及总执行的统计信息
type StatsResponse struct {
Counter string `json:"counter"`
Action string `json:"action"`
Total int `json:"total"`
Daily int `json:"daily"`
Date string `json:"date"`
Timestamp string `json:"timestamp"`
}
// 获取最新的Github的仓库中的版本
type GitHubRelease struct {
TagName string `json:"tag_name"`
}
// PrintCenteredTitle 根据指定的宽度打印居中标题
func PrintCenteredTitle(title string, width int) {
// 计算字符串的字符数
@@ -336,8 +352,6 @@ func ProcessAndUpload(output string, filePath string, enableUplaod bool) (string
return "", ""
}
// ============================= 前置联网能力检测 =============================
var StackType string
type NetCheckResult struct {
@@ -359,6 +373,7 @@ func makeResolver(proto, dnsAddr string) *net.Resolver {
}
}
// 前置联网能力检测
func CheckPublicAccess(timeout time.Duration) NetCheckResult {
if timeout < 2*time.Second {
timeout = 2 * time.Second
@@ -492,3 +507,77 @@ result:
StackType: stack,
}
}
// 获取每日/总的程序执行统计信息
func GetGoescStats() (*StatsResponse, error) {
client := req.C().SetTimeout(5 * time.Second)
var stats StatsResponse
resp, err := client.R().
SetSuccessResult(&stats).
Get("https://hits.spiritlhl.net/goecs")
if err != nil {
return nil, err
}
if !resp.IsSuccessState() {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return &stats, nil
}
// 统计结果单位转换
func FormatGoecsNumber(num int) string {
if num >= 1000000 {
return fmt.Sprintf("%.1fM", float64(num)/1000000)
} else if num >= 1000 {
return fmt.Sprintf("%.1fK", float64(num)/1000)
}
return fmt.Sprintf("%d", num)
}
// 通过Github的API检索仓库最新TAG的版本
func GetLatestEcsRelease() (*GitHubRelease, error) {
urls := []string{
"https://api.github.com/repos/oneclickvirt/ecs/releases/latest",
"https://fd.spiritlhl.top/https://api.github.com/repos/oneclickvirt/ecs/releases/latest",
"https://githubapi.spiritlhl.top/repos/oneclickvirt/ecs/releases/latest",
"https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest",
}
client := req.C().SetTimeout(3 * time.Second)
for _, url := range urls {
var release GitHubRelease
resp, err := client.R().
SetSuccessResult(&release).
Get(url)
if err != nil {
continue
}
if resp.IsSuccessState() && release.TagName != "" {
return &release, nil
}
}
return nil, fmt.Errorf("failed to fetch release from all sources")
}
// 比较程序版本是否需要升级
func CompareVersions(v1, v2 string) int {
normalize := func(s string) []int {
s = strings.TrimPrefix(strings.ToLower(s), "v")
parts := strings.Split(s, ".")
result := make([]int, 3)
for i := 0; i < 3 && i < len(parts); i++ {
n, _ := strconv.Atoi(parts[i])
result[i] = n
}
return result
}
a := normalize(v1)
b := normalize(v2)
for i := 0; i < 3; i++ {
if a[i] < b[i] {
return -1
} else if a[i] > b[i] {
return 1
}
}
return 0
}