Compare commits

...

7 Commits

Author SHA1 Message Date
spiritlhl
6b68e643c7 fix:更新主程序版本 2026-01-12 13:22:47 +00:00
spiritlhl
14c79b9a89 feat:添加私有测速平台节点测速,原测速平台节点仅作为备用方式 2026-01-12 13:21:29 +00:00
github-actions[bot]
60ae7ec3c3 chore: update ECS_VERSION to 0.1.106 in goecs.sh 2025-12-18 04:23:44 +00:00
spiritlhl
3d78128f6a fix:更新版本 2025-12-18 03:39:23 +00:00
spiritlhl
9c67a8d446 fix: 更新内存测试方法逻辑,增强对不同测试方法的支持 2025-12-18 03:35:45 +00:00
spiritlhl
014dba0ce6 feat: 添加更短的短链链接,默认不再进行任何环境安装 2025-11-29 02:49:56 +00:00
github-actions[bot]
b5fdab4b27 chore: update ECS_VERSION to 0.1.105 in goecs.sh 2025-11-26 07:43:20 +00:00
10 changed files with 360 additions and 52 deletions

View File

@@ -40,7 +40,7 @@ jobs:
args: release
env:
GITHUB_TOKEN: ${{ secrets.GHT }}
GOPRIVATE: github.com/oneclickvirt/security
GOPRIVATE: github.com/oneclickvirt/security,github.com/oneclickvirt/privatespeedtest
- name: Update goecs.sh with new version
run: |

View File

@@ -65,8 +65,12 @@ jobs:
sed -i '/SecurityUploadToken/d' utils/utils.go
sed -i 's|"github.com/oneclickvirt/security/network"|"github.com/oneclickvirt/basics/network"|g' utils/utils.go
sed -i '/^import/,/^)/{/^)/a\'$'\n''const token = "OvwKx5qgJtf7PZgCKbtyojSU.MTcwMTUxNzY1MTgwMw"'$'\n''}' utils/utils.go
sed -i '/github.com\/oneclickvirt\/security/d' go.mod
sed -i '/github.com\/oneclickvirt\/security/d' go.mod
sed -i '/github.com\/oneclickvirt\/privatespeedtest/d' go.mod
sed -i 's|var securityFlag = flag.Bool("security", true,|var securityFlag = flag.Bool("security", false,|g' goecs.go
sed -i 's|"github.com/oneclickvirt/privatespeedtest/pst"|// "github.com/oneclickvirt/privatespeedtest/pst"|g' internal/tests/speed.go
sed -i '/^\/\/ privateSpeedTest.*使用 privatespeedtest/,/^func [A-Z]/{/^func [A-Z]/!s/^/\/\/ /}' internal/tests/speed.go
sed -i '/err := privateSpeedTest(num, opLower)/,/return/{/return/!s/^/\/\/ /; s/return$/\/\/ return/}' internal/tests/speed.go
sed -i 's|VPS融合怪测试|VPS融合怪测试(非官方编译)|g' utils/utils.go
sed -i 's|VPS Fusion Monster Test|VPS Fusion Monster Test (Unofficial)|g' utils/utils.go
go mod tidy

View File

@@ -60,7 +60,7 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS
- 邮件端口测试:[portchecker](https://github.com/oneclickvirt/portchecker)
- 上游及回程路由线路检测:借鉴 [zhanghanyun/backtrace](https://github.com/zhanghanyun/backtrace),二次开发至 [oneclickvirt/backtrace](https://github.com/oneclickvirt/backtrace)
- 三网路由测试:基于 [NTrace-core](https://github.com/nxtrace/NTrace-core),二次开发至 [nt3](https://github.com/oneclickvirt/nt3)
- 网速测试:基于 [speedtest.net](https://github.com/spiritLHLS/speedtest.net-CN-ID) 和 [speedtest.cn](https://github.com/spiritLHLS/speedtest.cn-CN-ID) 数据,开发至 [oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest)
- 网速测试:基于 [speedtest.net](https://github.com/spiritLHLS/speedtest.net-CN-ID) 和 [speedtest.cn](https://github.com/spiritLHLS/speedtest.cn-CN-ID) 数据,开发至 [oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest),同时融合私有国内测速平台
- 三网 Ping 值测试:借鉴 [ecsspeed](https://github.com/spiritLHLS/ecsspeed),二次开发至 [pingtest](https://github.com/oneclickvirt/pingtest)
- 支持root或admin环境下测试支持非root或非admin环境下测试支持离线环境下进行测试**暂未**支持无DNS的在线环境下进行测试
@@ -74,35 +74,43 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS
#### **一键命令**
**一键命令**将**默认安装依赖****默认更新包管理器****默认非互动模式**
**一键命令**将默认**不安装依赖**,默认**不更新包管理器**,默认**非互动模式**
- **国际用户无加速:**
```bash
export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
- **国际/国内使用 CDN 加速:**
```bash
export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
- **国内用户使用 CNB 加速:**
```bash
export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
- **短链接:**
```bash
export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
```bash
export noninteractive=true && curl -L https://ba.sh/JrVa -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
**如果需要测试更准确,请按照下面的详细说明进行安装,添加非必需的依赖**
#### **详细说明**
**详细说明**中的命令**可控制是否安装依赖****是否更新包管理器****默认互动模式可进行选择**
以下命令可控制**是否安装依赖****是否更新包管理器****互动模式和非交互模式**
<details>
<summary>展开查看详细说明</summary>

View File

@@ -74,35 +74,43 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https:
#### **One-click command**
**One-Click Command** will **Install Dependencies by Default**, **Update Package Manager by Default**, **Default Non-Interactive Mode***
**One-Click Command** will **Not install Dependencies** by Default, **Not update Package Manager** by Default, **Non-Interactive Mode** by Default.
- **International users without acceleration:**
```bash
export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
- **International/domestic users with CDN acceleration:**
```bash
export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://cdn.spiritlhl.net/https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
- **Domestic users with CNB acceleration:**
```bash
export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh env && ./goecs.sh install && goecs
export noninteractive=true && curl -L https://cnb.cool/oneclickvirt/ecs/-/git/raw/main/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
- **Short Link:**
```bash
export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && bash goecs.sh env && bash goecs.sh install && goecs
``
export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && bash goecs.sh install && goecs
```
OR
```bash
export noninteractive=true && curl -L https://ba.sh/JrVa -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs
```
**For more accurate testing, please follow the detailed instructions below to install and add non-essential dependencies**
#### **Detailed instructions**
**Detailed description** of the commands in **Command **Controls whether to install dependencies**, **Whether to update the package manager**, **Default interaction mode can be selected***
The following commands control whether dependencies are installed, whether the package manager is updated, and whether interactive or non-interactive mode is used.
<details>
<summary>Expand to view detailed instructions</summary>

5
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/oneclickvirt/defaultset v0.0.2-20240624082446
github.com/oneclickvirt/disktest v0.0.10-20250924030424
github.com/oneclickvirt/gostun v0.0.5-20250727155022
github.com/oneclickvirt/memorytest v0.0.10-20250924154648
github.com/oneclickvirt/memorytest v0.0.10-20251218032900
github.com/oneclickvirt/nt3 v0.0.10-20251111095706
github.com/oneclickvirt/pingtest v0.0.9-20251104112920
github.com/oneclickvirt/portchecker v0.0.3-20250728015900
@@ -60,6 +60,7 @@ require (
github.com/oneclickvirt/dd v0.0.2-20250808062818 // indirect
github.com/oneclickvirt/fio v0.0.2-20250808045755 // indirect
github.com/oneclickvirt/mbw v0.0.1-20250808061222 // indirect
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218 // indirect
github.com/oneclickvirt/stream v0.0.2-20250924154001 // indirect
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
@@ -77,7 +78,7 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rodaine/table v1.3.0 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/schollz/progressbar/v3 v3.14.4 // indirect
github.com/schollz/progressbar/v3 v3.17.1 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/shirou/gopsutil/v4 v4.25.6 // indirect
github.com/showwin/speedtest-go v1.7.10 // indirect

10
go.sum
View File

@@ -114,14 +114,18 @@ github.com/oneclickvirt/gostun v0.0.5-20250727155022 h1:/e3gSUrOp1tg/1NTRx+P8B51
github.com/oneclickvirt/gostun v0.0.5-20250727155022/go.mod h1:pfp7MFZJK9n/KTLAVqqFcCAns4xqMykmjI+1UeF/vdE=
github.com/oneclickvirt/mbw v0.0.1-20250808061222 h1:WGXOe6QvHiDRhPVMI0VcctjzW08kGvJf50yq5YeZCtw=
github.com/oneclickvirt/mbw v0.0.1-20250808061222/go.mod h1:0Vq6NRpyLmGUdfHfL3uDcFsuZhi7KlG+OCs5ky2757Y=
github.com/oneclickvirt/memorytest v0.0.10-20250924154648 h1:trk6oZ7xs1eVtr+6oIv5IX8LDVtEMG+E6GVzQ810BtU=
github.com/oneclickvirt/memorytest v0.0.10-20250924154648/go.mod h1:4kiHsEWkW9r3/1ZcV5xIweU0smiKP0IRfQj74AUIiVI=
github.com/oneclickvirt/memorytest v0.0.10-20251218032900 h1:SmRFfPLyGfTVWIgC50lEGgOpbqahtMHIlyOMSbrhj9Y=
github.com/oneclickvirt/memorytest v0.0.10-20251218032900/go.mod h1:4kiHsEWkW9r3/1ZcV5xIweU0smiKP0IRfQj74AUIiVI=
github.com/oneclickvirt/nt3 v0.0.10-20251111095706 h1:GEdgL6oAWXY80NIq23mLjcTR3gvLGh9iusFzJK6SoDo=
github.com/oneclickvirt/nt3 v0.0.10-20251111095706/go.mod h1:yo1ufkduFt9QjqG7nqSUf1D3YlQOmFpdlTYniJfclQI=
github.com/oneclickvirt/pingtest v0.0.9-20251104112920 h1:j3Fjhy0YHT/VF7iuAVVELaRXkquvRd64tWWfFLJs01o=
github.com/oneclickvirt/pingtest v0.0.9-20251104112920/go.mod h1:gxwsxxwitNQiGq2OI0ZogYoOLwc8DtuOdSRe6/EvRqs=
github.com/oneclickvirt/portchecker v0.0.3-20250728015900 h1:AomzdppSOFB70AJESQhlp0IPbsHTTJGimAWDk2TzCWM=
github.com/oneclickvirt/portchecker v0.0.3-20250728015900/go.mod h1:9sjMDPCd4Z40wkYB0S9gQPGH8YPtnNE1ZJthVIuHUzA=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112095218 h1:VcglFz85LVPo8wE8AkBhgXHHUUVI2Ae9ng6+hY6ewx4=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112095218/go.mod h1:IXOlKKX4DUNqxOaW/K9bcdrBiWxo0jGSLXeBeo7NrTo=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218 h1:h2k2fHtrsIIP/x/apEWkQGlTKuIumz8GrUR/df41YhE=
github.com/oneclickvirt/privatespeedtest v0.0.1-20260112130218/go.mod h1:IXOlKKX4DUNqxOaW/K9bcdrBiWxo0jGSLXeBeo7NrTo=
github.com/oneclickvirt/security v0.0.8-20251112080734 h1:WpwdGbwpiBP2YA1lNsymati5uvBbWFlN9CXHYgd3/fE=
github.com/oneclickvirt/security v0.0.8-20251112080734/go.mod h1:aPMIwqsz7wiUH1cqvtRr9+QcQRkKzlUWecDM6SGVddc=
github.com/oneclickvirt/speedtest v0.0.11-20251102151740 h1:1NUrNt5ay6/xVNC5x62UrQjPqK8jgbKtyjBml/3boZg=
@@ -168,6 +172,8 @@ github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDc
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
github.com/schollz/progressbar/v3 v3.14.4 h1:W9ZrDSJk7eqmQhd3uxFNNcTr0QL+xuGNI9dEMrw0r74=
github.com/schollz/progressbar/v3 v3.14.4/go.mod h1:aT3UQ7yGm+2ZjeXPqsjTenwL3ddUiuZ0kfQ/2tHlyNI=
github.com/schollz/progressbar/v3 v3.17.1 h1:bI1MTaoQO+v5kzklBjYNRQLoVpe0zbyRZNK6DFkVC5U=
github.com/schollz/progressbar/v3 v3.17.1/go.mod h1:RzqpnsPQNjUyIgdglUjRLgD7sVnxN1wpmBMV+UiEbL4=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs=

View File

@@ -27,7 +27,7 @@ import (
)
var (
ecsVersion = "v0.1.105" // 融合怪版本号
ecsVersion = "v0.1.107" // 融合怪版本号
configs = params.NewConfig(ecsVersion) // 全局配置实例
userSetFlags = make(map[string]bool) // 用于跟踪哪些参数是用户显式设置的
)

View File

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

View File

@@ -25,51 +25,132 @@ func MemoryTest(language, testMethod string) (realTestMethod, res string) {
if runtime.GOOS == "windows" {
switch testMethod {
case "stream":
res = memory.WinsatTest(language)
realTestMethod = "winsat"
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WinsatTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WindowsDDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "winsat"
}
} else {
realTestMethod = "stream"
}
case "dd":
res = memory.WindowsDDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res += memory.WinsatTest(language)
realTestMethod = "winsat"
res = memory.WinsatTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "stream"
}
} else {
realTestMethod = "winsat"
}
} else {
realTestMethod = "dd"
}
case "sysbench":
// Windows下不支持sysbench使用stream → winsat → dd
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WinsatTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WindowsDDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "winsat"
}
} else {
realTestMethod = "stream"
}
case "auto":
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WinsatTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WindowsDDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "winsat"
}
} else {
realTestMethod = "stream"
}
case "winsat":
res = memory.WinsatTest(language)
realTestMethod = "winsat"
case "auto", "winsat":
res = memory.WinsatTest(language)
realTestMethod = "winsat"
if res == "" || strings.TrimSpace(res) == "" {
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WindowsDDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "stream"
}
} else {
realTestMethod = "winsat"
}
default:
res = memory.WinsatTest(language)
realTestMethod = "winsat"
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WinsatTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.WindowsDDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "winsat"
}
} else {
realTestMethod = "stream"
}
}
} else {
switch testMethod {
case "stream":
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res += memory.DDTest(language)
realTestMethod = "dd"
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.DDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "sysbench"
}
} else {
realTestMethod = "stream"
}
case "dd":
res = memory.DDTest(language)
realTestMethod = "dd"
case "sysbench":
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res += memory.DDTest(language)
realTestMethod = "dd"
} else {
realTestMethod = "sysbench"
}
case "auto":
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.DDTest(language)
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
@@ -78,15 +159,68 @@ func MemoryTest(language, testMethod string) (realTestMethod, res string) {
realTestMethod = "sysbench"
}
} else {
realTestMethod = "dd"
realTestMethod = "stream"
}
} else {
realTestMethod = "dd"
}
case "sysbench":
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.DDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "sysbench"
}
} else {
realTestMethod = "stream"
}
} else {
realTestMethod = "sysbench"
}
case "auto":
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.DDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "sysbench"
}
} else {
realTestMethod = "stream"
}
case "winsat":
// winsat 仅 Windows 支持,非 Windows fallback 到 dd
res = memory.DDTest(language)
realTestMethod = "dd"
// winsat 仅 Windows 支持,非 Windows fallback 到 stream → sysbench → dd
res = memory.StreamTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.SysBenchTest(language)
if res == "" || strings.TrimSpace(res) == "" {
res = memory.DDTest(language)
if res == "" || strings.TrimSpace(res) == "" {
realTestMethod = ""
} else {
realTestMethod = "dd"
}
} else {
realTestMethod = "sysbench"
}
} else {
realTestMethod = "stream"
}
default:
res = "Unsupported test method"
realTestMethod = ""

View File

@@ -5,7 +5,9 @@ import (
"os"
"runtime"
"strings"
"time"
"github.com/oneclickvirt/privatespeedtest/pst"
"github.com/oneclickvirt/speedtest/model"
"github.com/oneclickvirt/speedtest/sp"
)
@@ -32,12 +34,157 @@ func NearbySP() {
}
}
// formatString 格式化字符串到指定宽度
func formatString(s string, width int) string {
return fmt.Sprintf("%-*s", width, s)
}
// printTableRow 打印表格行
func printTableRow(result pst.SpeedTestResult) {
location := result.City
if result.CarrierType != "" {
carrier := result.CarrierType
switch carrier {
case "Telecom":
carrier = "电信"
case "Unicom":
carrier = "联通"
case "Mobile":
carrier = "移动"
case "Other":
carrier = "其他"
}
location = fmt.Sprintf("%s%s", carrier, result.City)
}
if len(location) > 14 {
location = location[:14] + "..."
}
upload := "N/A"
if result.UploadMbps > 0 {
upload = fmt.Sprintf("%.2f Mbps", result.UploadMbps)
}
download := "N/A"
if result.DownloadMbps > 0 {
download = fmt.Sprintf("%.2f Mbps", result.DownloadMbps)
}
latency := fmt.Sprintf("%.2f ms", result.PingLatency.Seconds()*1000)
packetLoss := "N/A"
fmt.Print(formatString(location, 16))
fmt.Print(formatString(upload, 16))
fmt.Print(formatString(download, 16))
fmt.Print(formatString(latency, 16))
fmt.Print(formatString(packetLoss, 16))
fmt.Println()
}
// privateSpeedTest 使用 privatespeedtest 进行单个运营商测速
// operator 参数:只支持 "cmcc"、"cu"、"ct"
func privateSpeedTest(num int, operator string) error {
defer func() {
if r := recover(); r != nil {
fmt.Fprintf(os.Stderr, "[WARN] privateSpeedTest panic: %v\n", r)
}
}()
// 加载服务器列表
serverList, err := pst.LoadServerList()
if err != nil {
return fmt.Errorf("加载自定义服务器列表失败")
}
// 使用三网测速模式(每个运营商选择指定数量的最低延迟节点)
serversPerISP := num
if serversPerISP <= 0 || serversPerISP > 5{
serversPerISP = 2
}
// 单个运营商测速:先过滤服务器列表
var carrierType string
switch strings.ToLower(operator) {
case "cmcc":
carrierType = "Mobile"
case "cu":
carrierType = "Unicom"
case "ct":
carrierType = "Telecom"
default:
return fmt.Errorf("不支持的运营商类型: %s", operator)
}
// 过滤出指定运营商的服务器
filteredServers := pst.FilterServersByISP(serverList.Servers, carrierType)
// 先找足够多的候选服务器用于去重(找 serversPerISP * 3 个,确保去重后还能剩下足够的服务器)
candidateCount := serversPerISP * 3
if candidateCount > len(filteredServers) {
candidateCount = len(filteredServers)
}
// 使用 FindBestServers 选择最佳服务器
candidateServers, err := pst.FindBestServers(
filteredServers,
candidateCount, // 选择更多候选节点用于去重
5*time.Second, // ping 超时
true, // 显示进度条
true, // 静默
)
if err != nil {
return fmt.Errorf("分组查找失败")
}
// 去重:确保同一运营商内城市不重复
seenCities := make(map[string]bool)
var bestServers []pst.ServerWithLatencyInfo
for _, serverInfo := range candidateServers {
city := serverInfo.Server.City
if city == "" {
city = "Unknown"
}
if !seenCities[city] {
seenCities[city] = true
bestServers = append(bestServers, serverInfo)
// 去重后取前 serversPerISP 个
if len(bestServers) >= serversPerISP {
break
}
}
}
if len(bestServers) == 0 {
return fmt.Errorf("去重后没有可用的服务器")
}
// 执行测速并逐个打印结果(不打印表头)
for i, serverInfo := range bestServers {
result := pst.RunSpeedTest(
serverInfo.Server,
false, // 不禁用下载测试
false, // 不禁用上传测试
6, // 并发线程数
12*time.Second, // 超时时间
&serverInfo,
false, // 不显示进度条
)
if result.Success {
printTableRow(result)
}
// 在测试之间暂停(除了最后一个)
if i < len(bestServers)-1 {
time.Sleep(1 * time.Second)
}
}
return nil
}
func CustomSP(platform, operator string, num int, language string) {
defer func() {
if r := recover(); r != nil {
fmt.Fprintf(os.Stderr, "[WARN] CustomSP panic: %v\n", r)
}
}()
// 对于三网测速cmcc、cu、ct优先使用 privatespeedtest 进行私有测速
opLower := strings.ToLower(operator)
if opLower == "cmcc" || opLower == "cu" || opLower == "ct" {
err := privateSpeedTest(num, opLower)
if err != nil {
fmt.Fprintf(os.Stderr, "[WARN] privatespeedtest failed\n")
// 继续使用原有的兜底方案
} else {
// 测速成功,直接返回
return
}
}
var url, parseType string
if strings.ToLower(platform) == "cn" {
if strings.ToLower(operator) == "cmcc" {