mirror of
https://github.com/oneclickvirt/ecs.git
synced 2025-12-24 04:03:43 +08:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78b5634306 | ||
|
|
a0bc2de61a | ||
|
|
3c45667c55 | ||
|
|
6111554225 | ||
|
|
1bba9cde26 | ||
|
|
280d292c4c | ||
|
|
cf85b67ae4 | ||
|
|
3ebbf186fc | ||
|
|
3ba3301cc7 | ||
|
|
8674a82eb0 | ||
|
|
5116493338 | ||
|
|
c6f3e7a285 | ||
|
|
40f63e6cb1 | ||
|
|
6b42f626b0 | ||
|
|
4503fb55b0 | ||
|
|
cb1634cb68 | ||
|
|
95ece8c28d | ||
|
|
fd44c079b3 | ||
|
|
5c5bd37074 | ||
|
|
1676045e3d | ||
|
|
58e6941bfa | ||
|
|
3989708c4e |
@@ -1,84 +0,0 @@
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy -v
|
||||
builds:
|
||||
- id: universal
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- freebsd
|
||||
goarch:
|
||||
- arm
|
||||
- arm64
|
||||
- 386
|
||||
- amd64
|
||||
- mips
|
||||
- mipsle
|
||||
- s390x
|
||||
- riscv64
|
||||
gomips:
|
||||
- softfloat
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
main: ./
|
||||
binary: goecs
|
||||
- id: darwin-amd64
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=o64-clang
|
||||
- CXX=o64-clang++
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
main: ./
|
||||
binary: goecs
|
||||
- id: darwin-arm64
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=oa64-clang
|
||||
- CXX=oa64-clang++
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- darwin
|
||||
goarch:
|
||||
- arm64
|
||||
main: ./
|
||||
binary: goecs
|
||||
universal_binaries:
|
||||
- name_template: "goecs"
|
||||
replace: false
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
snapshot:
|
||||
name_template: "goecs"
|
||||
archives:
|
||||
- name_template: "goecs_{{ .Os }}_{{ .Arch }}"
|
||||
format: zip
|
||||
files:
|
||||
- none*
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
- "^chore"
|
||||
- Merge pull request
|
||||
- Merge branch
|
||||
- go mod tidy
|
||||
- New translations
|
||||
@@ -1,522 +0,0 @@
|
||||
version: 2
|
||||
project_name: goecs
|
||||
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy -v
|
||||
|
||||
builds:
|
||||
# Linux AMD64 with CGO
|
||||
- id: linux-amd64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
- CGO_CFLAGS=-O2 -static -fno-stack-protector
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/amd64 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/amd64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux 386 with CGO - 修复了编译器和标志
|
||||
- id: linux-386-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=gcc
|
||||
- CGO_CFLAGS=-m32 -O1 -march=i686 -mtune=generic -fno-stack-protector
|
||||
- CGO_LDFLAGS=-m32
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags="-m32 -static"
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- 386
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/386 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/386 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux ARM64 with CGO
|
||||
- id: linux-arm64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
- CGO_CFLAGS=-O1 -fno-stack-protector
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/arm64 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/arm64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Windows AMD64 with CGO
|
||||
- id: windows-amd64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=x86_64-w64-mingw32-gcc
|
||||
- CGO_CFLAGS=-O2 -static-libgcc -static-libstdc++
|
||||
- CGO_LDFLAGS=-static-libgcc -static-libstdc++
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for windows/amd64 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built windows/amd64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Windows 386 with CGO - 修复了编译器名称
|
||||
- id: windows-386-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=i686-w64-mingw32-gcc
|
||||
- CGO_CFLAGS=-O2 -static-libgcc -static-libstdc++
|
||||
- CGO_LDFLAGS=-static-libgcc -static-libstdc++
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- windows
|
||||
goarch:
|
||||
- 386
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for windows/386 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built windows/386 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Darwin AMD64 with CGO
|
||||
- id: darwin-amd64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=o64-clang
|
||||
- CGO_CFLAGS=-O2 -arch x86_64 -mmacosx-version-min=10.12
|
||||
- CGO_LDFLAGS=-arch x86_64 -mmacosx-version-min=10.12
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for darwin/amd64 (CGO)"
|
||||
- echo "Checking osxcross tools..."
|
||||
- which o64-clang || echo "o64-clang not found"
|
||||
- which o64-clang++ || echo "o64-clang++ not found"
|
||||
post:
|
||||
- echo "Successfully built darwin/amd64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Darwin ARM64 with CGO
|
||||
- id: darwin-arm64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=oa64-clang
|
||||
- CGO_CFLAGS=-O2 -arch arm64 -mmacosx-version-min=11.0
|
||||
- CGO_LDFLAGS=-arch arm64 -mmacosx-version-min=11.0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- darwin
|
||||
goarch:
|
||||
- arm64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for darwin/arm64 (CGO)"
|
||||
- echo "Checking osxcross tools..."
|
||||
- which oa64-clang || echo "oa64-clang not found"
|
||||
- which oa64-clang++ || echo "oa64-clang++ not found"
|
||||
post:
|
||||
- echo "Successfully built darwin/arm64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux RISC-V 64 with CGO
|
||||
- id: linux-riscv64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=riscv64-linux-gnu-gcc
|
||||
- CGO_CFLAGS=-O1 -fno-stack-protector
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- riscv64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/riscv64 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/riscv64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux MIPS64 with CGO
|
||||
- id: linux-mips64-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=mips64-linux-gnuabi64-gcc
|
||||
- CGO_CFLAGS=-O1 -fno-stack-protector
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- mips64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/mips64 (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/mips64 (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux MIPS64LE with CGO
|
||||
- id: linux-mips64le-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=mips64el-linux-gnuabi64-gcc
|
||||
- CGO_CFLAGS=-O1 -fno-stack-protector
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- mips64le
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/mips64le (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/mips64le (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux PPC64LE with CGO
|
||||
- id: linux-ppc64le-cgo
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=powerpc64le-linux-gnu-gcc
|
||||
- CGO_CFLAGS=-O1 -fno-stack-protector
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- ppc64le
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/ppc64le (CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/ppc64le (CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux ARM (no CGO)
|
||||
- id: linux-arm-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm
|
||||
goarm:
|
||||
- "5"
|
||||
- "6"
|
||||
- "7"
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/arm (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/arm (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux S390X (no CGO)
|
||||
- id: linux-s390x-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- s390x
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/s390x (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/s390x (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux MIPS (no CGO)
|
||||
- id: linux-mips-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- mips
|
||||
gomips:
|
||||
- softfloat
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/mips (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/mips (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux MIPSLE (no CGO)
|
||||
- id: linux-mipsle-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- mipsle
|
||||
gomips:
|
||||
- softfloat
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/mipsle (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/mipsle (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
# Linux PPC64 (no CGO)
|
||||
- id: linux-ppc64-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- ppc64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for linux/ppc64 (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built linux/ppc64 (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
# FreeBSD AMD64 (no CGO)
|
||||
- id: freebsd-amd64-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- freebsd
|
||||
goarch:
|
||||
- amd64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for freebsd/amd64 (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built freebsd/amd64 (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
# FreeBSD ARM64 (no CGO)
|
||||
- id: freebsd-arm64-nocgo
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- freebsd
|
||||
goarch:
|
||||
- arm64
|
||||
main: ./
|
||||
binary: goecs
|
||||
no_unique_dist_dir: true
|
||||
hooks:
|
||||
pre:
|
||||
- echo "Starting build for freebsd/arm64 (no CGO)"
|
||||
post:
|
||||
- echo "Successfully built freebsd/arm64 (no CGO)"
|
||||
- echo "---"
|
||||
|
||||
universal_binaries:
|
||||
- name_template: "goecs"
|
||||
replace: false
|
||||
ids:
|
||||
- darwin-amd64-cgo
|
||||
- darwin-arm64-cgo
|
||||
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
algorithm: sha256
|
||||
disable: false
|
||||
ids:
|
||||
- linux-amd64-cgo
|
||||
- linux-386-cgo
|
||||
- linux-arm64-cgo
|
||||
- linux-riscv64-cgo
|
||||
- linux-mips64-cgo
|
||||
- linux-mips64le-cgo
|
||||
- linux-ppc64le-cgo
|
||||
- windows-amd64-cgo
|
||||
- windows-386-cgo
|
||||
- darwin-amd64-cgo
|
||||
- darwin-arm64-cgo
|
||||
- linux-arm-nocgo
|
||||
- linux-s390x-nocgo
|
||||
- linux-mips-nocgo
|
||||
- linux-mipsle-nocgo
|
||||
- linux-ppc64-nocgo
|
||||
- freebsd-amd64-nocgo
|
||||
- freebsd-arm64-nocgo
|
||||
extra_files:
|
||||
- glob: "./goecs.sh"
|
||||
|
||||
snapshot:
|
||||
name_template: "goecs"
|
||||
|
||||
archives:
|
||||
- id: default
|
||||
name_template: "goecs_{{ .Os }}_{{ .Arch }}"
|
||||
format: zip
|
||||
files:
|
||||
- none*
|
||||
allow_different_binary_count: true
|
||||
builds:
|
||||
- linux-amd64-cgo
|
||||
- linux-386-cgo
|
||||
- linux-arm64-cgo
|
||||
- linux-riscv64-cgo
|
||||
- linux-mips64-cgo
|
||||
- linux-mips64le-cgo
|
||||
- linux-ppc64le-cgo
|
||||
- windows-amd64-cgo
|
||||
- windows-386-cgo
|
||||
- darwin-amd64-cgo
|
||||
- darwin-arm64-cgo
|
||||
- linux-arm-nocgo
|
||||
- linux-s390x-nocgo
|
||||
- linux-mips-nocgo
|
||||
- linux-mipsle-nocgo
|
||||
- linux-ppc64-nocgo
|
||||
- freebsd-amd64-nocgo
|
||||
- freebsd-arm64-nocgo
|
||||
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
- "^chore"
|
||||
- Merge pull request
|
||||
- Merge branch
|
||||
- go mod tidy
|
||||
- New translations
|
||||
@@ -1,14 +0,0 @@
|
||||
// clearScreen 清屏
|
||||
func clearScreen() {
|
||||
var cmd *exec.Cmd
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
cmd = exec.Command("cmd", "/c", "cls")
|
||||
case "darwin":
|
||||
cmd = exec.Command("clear")
|
||||
default:
|
||||
cmd = exec.Command("clear")
|
||||
}
|
||||
cmd.Stdout = os.Stdout
|
||||
_ = cmd.Run()
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package basic1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_basic(t *testing.T) {
|
||||
Basic("zh")
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package basic1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/oneclickvirt/basics/network"
|
||||
"github.com/oneclickvirt/basics/system"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 本包不在main中使用,仅做测试使用,真正调用的在 utils 中的 BasicsAndSecurityCheck
|
||||
func Basic(language string) {
|
||||
ipInfo, _, _ := network.NetworkCheck("both", false, language)
|
||||
systemInfo := system.CheckSystemInfo(language)
|
||||
basicInfo := strings.ReplaceAll(systemInfo+ipInfo, "\n\n", "\n")
|
||||
fmt.Print(basicInfo)
|
||||
}
|
||||
132
.back/build.yaml
132
.back/build.yaml
@@ -1,132 +0,0 @@
|
||||
name: Goreleaser
|
||||
on:
|
||||
workflow_dispatch:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
# 1.20 是 Windows 7/8 Server 2008/2012 最后一个支持版本
|
||||
image: goreleaser/goreleaser-cross:v1.20
|
||||
steps:
|
||||
- name: Configure git safe directory
|
||||
run: |
|
||||
git config --global --add safe.directory /__w/ecs/ecs
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.23.4
|
||||
|
||||
- name: Configure Git for Private Modules
|
||||
run: |
|
||||
git config --global url."https://${{ secrets.GHT }}@github.com/".insteadOf "https://github.com/"
|
||||
git config --global url."git@github.com:".insteadOf "https://github.com/"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
|
||||
- name: Install missing cross-compilation tools
|
||||
run: |
|
||||
echo "Installing missing cross-compilation tools..."
|
||||
apt-get update
|
||||
PACKAGES=(
|
||||
gcc-multilib
|
||||
g++-multilib
|
||||
linux-libc-dev
|
||||
linux-libc-dev:i386
|
||||
libc6-dev-i386
|
||||
libc6-dev-i386-cross
|
||||
gcc-aarch64-linux-gnu
|
||||
gcc-riscv64-linux-gnu
|
||||
gcc-mips64-linux-gnuabi64
|
||||
gcc-mips64el-linux-gnuabi64
|
||||
gcc-powerpc64le-linux-gnu
|
||||
gcc-mingw-w64-x86-64
|
||||
gcc-mingw-w64-i686
|
||||
libc6-dev-amd64-cross
|
||||
libc6-dev-arm64-cross
|
||||
libc6-dev-riscv64-cross
|
||||
libc6-dev-mips64-cross
|
||||
libc6-dev-mips64el-cross
|
||||
libc6-dev-ppc64el-cross
|
||||
)
|
||||
for pkg in "${PACKAGES[@]}"; do
|
||||
echo "Installing $pkg..."
|
||||
apt-get install -y "$pkg" || echo "Failed to install $pkg, continuing..."
|
||||
done
|
||||
|
||||
- name: Verify cross-compilation tools
|
||||
run: |
|
||||
echo "Checking available cross-compilation tools..."
|
||||
echo "=== GCC compilers ==="
|
||||
which gcc || echo "gcc not found"
|
||||
which x86_64-linux-gnu-gcc || echo "x86_64-linux-gnu-gcc not found"
|
||||
which aarch64-linux-gnu-gcc || echo "aarch64-linux-gnu-gcc not found"
|
||||
which riscv64-linux-gnu-gcc || echo "riscv64-linux-gnu-gcc not found"
|
||||
which mips64-linux-gnuabi64-gcc || echo "mips64-linux-gnuabi64-gcc not found"
|
||||
which mips64el-linux-gnuabi64-gcc || echo "mips64el-linux-gnuabi64-gcc not found"
|
||||
which powerpc64le-linux-gnu-gcc || echo "powerpc64le-linux-gnu-gcc not found"
|
||||
echo "=== MinGW compilers ==="
|
||||
which x86_64-w64-mingw32-gcc || echo "x86_64-w64-mingw32-gcc not found"
|
||||
which i686-w64-mingw32-gcc || echo "i686-w64-mingw32-gcc not found"
|
||||
echo "=== OSXCross compilers ==="
|
||||
which o64-clang || echo "o64-clang not found"
|
||||
which oa64-clang || echo "oa64-clang not found"
|
||||
which o64-clang++ || echo "o64-clang++ not found"
|
||||
which oa64-clang++ || echo "oa64-clang++ not found"
|
||||
echo "=== Clang compilers ==="
|
||||
which clang || echo "clang not found"
|
||||
echo "=== Available gcc binaries ==="
|
||||
ls -la /usr/bin/*gcc* | head -20
|
||||
echo "=== Available clang binaries ==="
|
||||
ls -la /usr/bin/*clang* | head -10
|
||||
echo "=== OSXCross directory ==="
|
||||
ls -la /usr/osxcross/bin/ 2>/dev/null || echo "OSXCross not found in /usr/osxcross/bin/"
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --parallelism 1 --verbose
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
GOPRIVATE: github.com/oneclickvirt/security
|
||||
|
||||
- name: Update goecs.sh with new version
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
|
||||
VERSION="${GITHUB_REF#refs/tags/v}"
|
||||
else
|
||||
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.1.37")
|
||||
fi
|
||||
echo "Using version: $VERSION"
|
||||
FILE="goecs.sh"
|
||||
BRANCH="master"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global --unset url."git@github.com:".insteadOf || true
|
||||
git fetch origin $BRANCH
|
||||
git checkout $BRANCH
|
||||
if [ ! -f "$FILE" ]; then
|
||||
echo "Error: $FILE not found"
|
||||
exit 1
|
||||
fi
|
||||
sed -i "s/\(_yellow \"Unable to get version info, using default version \).*\(\".*\)/\1$VERSION\2/" "$FILE"
|
||||
sed -i "s/\(ECS_VERSION=\"\).*\(\"\)/\1$VERSION\2/" "$FILE"
|
||||
if git diff --quiet "$FILE"; then
|
||||
echo "No changes detected in $FILE"
|
||||
exit 0
|
||||
fi
|
||||
git add "$FILE"
|
||||
git commit -m "chore: update ECS_VERSION to $VERSION in goecs.sh"
|
||||
git push origin $BRANCH
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
@@ -1,467 +0,0 @@
|
||||
name: Build and Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Release Check And Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 "$TAG^" 2>/dev/null || echo "")
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
CHANGELOG=$(git log --oneline --pretty=format:"* %H %s" "$TAG" | head -20)
|
||||
else
|
||||
CHANGELOG=$(git log --oneline --pretty=format:"* %H %s" "$PREV_TAG..$TAG")
|
||||
fi
|
||||
FULL_CHANGELOG="## Changelog"$'\n'"$CHANGELOG"
|
||||
echo "$FULL_CHANGELOG" > changelog.txt
|
||||
echo "changelog<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$FULL_CHANGELOG" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create or update release
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
CHANGELOG_BODY=$(cat changelog.txt | jq -Rs .)
|
||||
RELEASE_EXISTS=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id // empty')
|
||||
if [ -z "$RELEASE_EXISTS" ]; then
|
||||
curl -s -X POST -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":$CHANGELOG_BODY,\"draft\":false,\"prerelease\":false}" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/releases"
|
||||
else
|
||||
curl -s -X PATCH -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"body\":$CHANGELOG_BODY}" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_EXISTS"
|
||||
fi
|
||||
|
||||
- name: Delete existing release assets
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
if [ "$RELEASE_ID" != "null" ]; then
|
||||
ASSETS=$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets" | jq -r '.[] | .id')
|
||||
for asset in $ASSETS; do
|
||||
curl -s -X DELETE -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/assets/$asset"
|
||||
done
|
||||
sleep 30
|
||||
fi
|
||||
|
||||
release-binary:
|
||||
name: Release Go Binary
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
cgo_enabled: "1"
|
||||
cc: x86_64-linux-gnu-gcc
|
||||
cflags: "-O2 -static -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: 386
|
||||
cgo_enabled: "1"
|
||||
cc: x86_64-linux-gnu-gcc
|
||||
cflags: "-m32 -O1 -march=i686 -mtune=generic -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-multilib"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: arm64
|
||||
cgo_enabled: "1"
|
||||
cc: aarch64-linux-gnu-gcc
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-aarch64-linux-gnu"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: riscv64
|
||||
cgo_enabled: "1"
|
||||
cc: riscv64-linux-gnu-gcc
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-riscv64-linux-gnu"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mips64
|
||||
cgo_enabled: "1"
|
||||
cc: mips64-linux-gnuabi64-gcc
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-mips64-linux-gnuabi64"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mips64le
|
||||
cgo_enabled: "1"
|
||||
cc: mips64el-linux-gnuabi64-gcc
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-mips64el-linux-gnuabi64"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: ppc64le
|
||||
cgo_enabled: "1"
|
||||
cc: powerpc64le-linux-gnu-gcc
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-powerpc64le-linux-gnu"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: arm
|
||||
# goarm: 7
|
||||
cgo_enabled: "1"
|
||||
cc: arm-linux-gnueabihf-gcc
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-arm-linux-gnueabihf"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: amd64
|
||||
cgo_enabled: "1"
|
||||
cc: x86_64-w64-mingw32-gcc
|
||||
cflags: "-O2 -static-libgcc -static-libstdc++"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-mingw-w64-x86-64"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: 386
|
||||
cgo_enabled: "1"
|
||||
cc: i686-w64-mingw32-gcc
|
||||
cflags: "-O2 -static-libgcc -static-libstdc++"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential gcc-mingw-w64-i686"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-extldflags=-static -s -w"
|
||||
packages: "build-essential"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: darwin
|
||||
goarch: amd64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: macos-latest
|
||||
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: macos-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: s390x
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mips
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mipsle
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: ppc64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: freebsd
|
||||
goarch: amd64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: freebsd
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.25.3
|
||||
|
||||
- name: Configure Git for Private Modules
|
||||
run: |
|
||||
git config --global url."https://${{ secrets.GHT }}@github.com/".insteadOf "https://github.com/"
|
||||
git config --global url."git@github.com:".insteadOf "https://github.com/"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
|
||||
- name: Install cross-compilation tools
|
||||
if: matrix.runner != 'macos-latest'
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
case "${{ matrix.goos }}-${{ matrix.goarch }}" in
|
||||
linux-386)
|
||||
sudo apt-get install -y build-essential gcc-multilib g++-multilib ;;
|
||||
linux-arm64)
|
||||
sudo apt-get install -y build-essential gcc-aarch64-linux-gnu ;;
|
||||
linux-riscv64)
|
||||
sudo apt-get install -y build-essential gcc-riscv64-linux-gnu ;;
|
||||
linux-mips64)
|
||||
sudo apt-get install -y build-essential gcc-mips64-linux-gnuabi64 ;;
|
||||
linux-mips64le)
|
||||
sudo apt-get install -y build-essential gcc-mips64el-linux-gnuabi64 ;;
|
||||
linux-ppc64le)
|
||||
sudo apt-get install -y build-essential gcc-powerpc64le-linux-gnu ;;
|
||||
linux-arm)
|
||||
sudo apt-get install -y build-essential gcc-arm-linux-gnueabihf ;;
|
||||
windows-amd64|windows-386)
|
||||
sudo apt-get install -y build-essential gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 ;;
|
||||
*)
|
||||
sudo apt-get install -y build-essential ;;
|
||||
esac
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build Binary
|
||||
env:
|
||||
CGO_ENABLED: ${{ matrix.cgo_enabled }}
|
||||
GOOS: ${{ matrix.goos }}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
CC: ${{ matrix.cc }}
|
||||
CGO_CFLAGS: ${{ matrix.cflags }}
|
||||
CGO_LDFLAGS: ${{ matrix.ldflags }}
|
||||
run: |
|
||||
go clean -cache -modcache -testcache
|
||||
|
||||
# 设置额外的环境变量
|
||||
if [[ -n "${{ matrix.goarm }}" ]]; then
|
||||
export GOARM=${{ matrix.goarm }}
|
||||
fi
|
||||
if [[ -n "${{ matrix.gomips }}" ]]; then
|
||||
export GOMIPS=${{ matrix.gomips }}
|
||||
fi
|
||||
|
||||
# 针对 Darwin 的特殊处理
|
||||
if [[ "${{ matrix.cgo_enabled }}" == "1" && "${{ matrix.goos }}" == "darwin" ]]; then
|
||||
if [[ "${{ matrix.goarch }}" == "amd64" ]]; then
|
||||
export CC="x86_64-apple-darwin21.4-clang"
|
||||
export CXX="x86_64-apple-darwin21.4-clang++"
|
||||
elif [[ "${{ matrix.goarch }}" == "arm64" ]]; then
|
||||
export CC="aarch64-apple-darwin21.4-clang"
|
||||
export CXX="aarch64-apple-darwin21.4-clang++"
|
||||
fi
|
||||
export OSXCROSS_ROOT="${OSXCROSS_ROOT}"
|
||||
elif [[ "${{ matrix.cgo_enabled }}" == "1" && "${{ matrix.runner }}" != "macos-latest" ]]; then
|
||||
# 对于 Windows 的特殊处理
|
||||
if [[ "${{ matrix.goos }}" == "windows" ]]; then
|
||||
export CGO_LDFLAGS="-static-libgcc -static-libstdc++"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 测试编译器(仅在启用 CGO 时)
|
||||
if [[ "${{ matrix.cgo_enabled }}" == "1" && -n "$CC" ]]; then
|
||||
echo 'int main() { return 0; }' > test.c
|
||||
$CC $CGO_CFLAGS test.c -o test || exit 1
|
||||
rm -f test.c test
|
||||
fi
|
||||
|
||||
# 清理和准备
|
||||
rm -rf vendor/
|
||||
go mod download
|
||||
go mod tidy
|
||||
mkdir -p bin
|
||||
|
||||
# 设置二进制文件名
|
||||
BINARY_NAME="goecs"
|
||||
if [[ "${{ matrix.goos }}" == "windows" ]]; then
|
||||
BINARY_NAME="${BINARY_NAME}.exe"
|
||||
fi
|
||||
|
||||
# 构建 LDFLAGS
|
||||
LDFLAGS="-s -w -X main.version=${{ steps.tag.outputs.version }} -X main.arch=${{ matrix.goarch }}"
|
||||
if [[ "${{ matrix.cgo_enabled }}" == "1" ]]; then
|
||||
LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}"
|
||||
else
|
||||
LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}"
|
||||
fi
|
||||
|
||||
# 执行构建
|
||||
echo "Building for GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=$CGO_ENABLED"
|
||||
go build -a -o bin/$BINARY_NAME -ldflags="$LDFLAGS" -trimpath ./
|
||||
|
||||
# 验证文件是否存在
|
||||
[[ -f "bin/$BINARY_NAME" ]] || exit 1
|
||||
|
||||
# 显示构建信息
|
||||
echo "Built binary: bin/$BINARY_NAME"
|
||||
ls -la bin/
|
||||
if command -v file >/dev/null 2>&1; then
|
||||
file bin/$BINARY_NAME
|
||||
fi
|
||||
|
||||
- name: Create ZIP archive
|
||||
run: |
|
||||
cd bin
|
||||
BINARY_NAME="goecs"
|
||||
if [[ "${{ matrix.goos }}" == "windows" ]]; then
|
||||
BINARY_NAME="${BINARY_NAME}.exe"
|
||||
fi
|
||||
ZIP_NAME="goecs_${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||
if [[ -n "${{ matrix.goarm }}" ]]; then
|
||||
ZIP_NAME="${ZIP_NAME}v${{ matrix.goarm }}"
|
||||
fi
|
||||
if [[ -n "${{ matrix.gomips }}" ]]; then
|
||||
ZIP_NAME="${ZIP_NAME}_${{ matrix.gomips }}"
|
||||
fi
|
||||
ZIP_NAME="${ZIP_NAME}.zip"
|
||||
zip "$ZIP_NAME" "$BINARY_NAME"
|
||||
|
||||
- name: Upload to Release
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
cd bin
|
||||
for file in *.zip; do
|
||||
if [[ -f "$file" ]]; then
|
||||
curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: application/zip" \
|
||||
--data-binary @"$file" \
|
||||
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$file"
|
||||
fi
|
||||
done
|
||||
|
||||
checksums:
|
||||
name: Generate Checksums
|
||||
runs-on: ubuntu-latest
|
||||
needs: release-binary
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Download release assets
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
mkdir -p assets
|
||||
ASSETS=$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets")
|
||||
echo "$ASSETS" | jq -r '.[] | select(.name | endswith(".zip")) | .browser_download_url' | while read url; do
|
||||
filename=$(basename "$url")
|
||||
curl -L -H "Authorization: Bearer ${{ secrets.GHT }}" "$url" -o "assets/$filename"
|
||||
done
|
||||
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
cd assets
|
||||
sha256sum *.zip > checksums.txt
|
||||
if [[ -f "../goecs.sh" ]]; then
|
||||
sha256sum ../goecs.sh >> checksums.txt
|
||||
fi
|
||||
|
||||
- name: Upload checksums
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: text/plain" \
|
||||
--data-binary @assets/checksums.txt \
|
||||
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=checksums.txt"
|
||||
|
||||
update-script:
|
||||
name: Update Script Version
|
||||
runs-on: ubuntu-latest
|
||||
needs: checksums
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update goecs.sh version
|
||||
run: |
|
||||
VERSION="${{ steps.tag.outputs.version }}"
|
||||
BRANCH="master"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global --unset url."git@github.com:".insteadOf || true
|
||||
git fetch origin $BRANCH
|
||||
git checkout $BRANCH
|
||||
if [ -f "goecs.sh" ]; then
|
||||
sed -i "s/\(_yellow \"Unable to get version info, using default version \).*\(\".*\)/\1$VERSION\2/" "goecs.sh"
|
||||
sed -i "s/\(ECS_VERSION=\"\).*\(\"\)/\1$VERSION\2/" "goecs.sh"
|
||||
if ! git diff --quiet "goecs.sh"; then
|
||||
git add "goecs.sh"
|
||||
git commit -m "chore: update ECS_VERSION to $VERSION in goecs.sh"
|
||||
git push origin $BRANCH
|
||||
fi
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
@@ -1,527 +0,0 @@
|
||||
name: Build and Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Release Check And Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 "$TAG^" 2>/dev/null || echo "")
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
CHANGELOG=$(git log --oneline --pretty=format:"* %H %s" "$TAG" | head -20)
|
||||
else
|
||||
CHANGELOG=$(git log --oneline --pretty=format:"* %H %s" "$PREV_TAG..$TAG")
|
||||
fi
|
||||
FULL_CHANGELOG="## Changelog"$'\n'"$CHANGELOG"
|
||||
echo "$FULL_CHANGELOG" > changelog.txt
|
||||
echo "changelog<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$FULL_CHANGELOG" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create or update release
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
CHANGELOG_BODY=$(cat changelog.txt | jq -Rs .)
|
||||
RELEASE_EXISTS=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id // empty')
|
||||
if [ -z "$RELEASE_EXISTS" ]; then
|
||||
curl -s -X POST -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":$CHANGELOG_BODY,\"draft\":false,\"prerelease\":false}" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/releases"
|
||||
else
|
||||
curl -s -X PATCH -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"body\":$CHANGELOG_BODY}" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_EXISTS"
|
||||
fi
|
||||
|
||||
- name: Delete existing release assets
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
if [ "$RELEASE_ID" != "null" ]; then
|
||||
ASSETS=$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets" | jq -r '.[] | .id')
|
||||
for asset in $ASSETS; do
|
||||
curl -s -X DELETE -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/assets/$asset"
|
||||
done
|
||||
sleep 30
|
||||
fi
|
||||
|
||||
build-musl-toolchain:
|
||||
name: Build musl Cross-Compiler Toolchain
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- x86_64-linux-musl
|
||||
- i686-linux-musl
|
||||
- aarch64-linux-musl
|
||||
- riscv64-linux-musl
|
||||
- mips64-linux-musl
|
||||
- mips64el-linux-musl
|
||||
- powerpc64le-linux-musl
|
||||
- arm-linux-musleabihf
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y build-essential curl
|
||||
|
||||
- name: Cache musl toolchain
|
||||
id: cache-musl
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /opt/musl-${{ matrix.target }}
|
||||
key: musl-toolchain-${{ matrix.target }}-v2
|
||||
|
||||
- name: Build musl cross-compiler
|
||||
if: steps.cache-musl.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
# Clone musl-cross-make
|
||||
git clone https://github.com/richfelker/musl-cross-make.git
|
||||
cd musl-cross-make
|
||||
|
||||
# Create config for target
|
||||
cat > config.mak << EOF
|
||||
TARGET = ${{ matrix.target }}
|
||||
OUTPUT = /opt/musl-${{ matrix.target }}
|
||||
COMMON_CONFIG += --disable-nls
|
||||
GCC_CONFIG += --enable-languages=c,c++
|
||||
GCC_CONFIG += --disable-libquadmath --disable-decimal-float
|
||||
GCC_CONFIG += --disable-libitm --disable-fixed-point
|
||||
EOF
|
||||
|
||||
# Build the toolchain
|
||||
make -j$(nproc)
|
||||
sudo make install
|
||||
|
||||
# Verify installation
|
||||
ls -la /opt/musl-${{ matrix.target }}/bin/
|
||||
/opt/musl-${{ matrix.target }}/bin/${{ matrix.target }}-gcc --version
|
||||
|
||||
- name: Create toolchain artifact
|
||||
run: |
|
||||
sudo tar -czf musl-${{ matrix.target }}-toolchain.tar.gz -C /opt musl-${{ matrix.target }}
|
||||
|
||||
- name: Upload toolchain artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: musl-${{ matrix.target }}-toolchain
|
||||
path: musl-${{ matrix.target }}-toolchain.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
release-binary:
|
||||
name: Release Go Binary
|
||||
needs: [build, build-musl-toolchain]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
cgo_enabled: "1"
|
||||
musl_target: x86_64-linux-musl
|
||||
cflags: "-O2 -static -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: 386
|
||||
cgo_enabled: "1"
|
||||
musl_target: i686-linux-musl
|
||||
cflags: "-O1 -march=i686 -mtune=generic -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: arm64
|
||||
cgo_enabled: "1"
|
||||
musl_target: aarch64-linux-musl
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: riscv64
|
||||
cgo_enabled: "1"
|
||||
musl_target: riscv64-linux-musl
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mips64
|
||||
cgo_enabled: "1"
|
||||
musl_target: mips64-linux-musl
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mips64le
|
||||
cgo_enabled: "1"
|
||||
musl_target: mips64el-linux-musl
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: ppc64le
|
||||
cgo_enabled: "1"
|
||||
musl_target: powerpc64le-linux-musl
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: arm
|
||||
cgo_enabled: "1"
|
||||
musl_target: arm-linux-musleabihf
|
||||
cflags: "-O1 -fno-stack-protector"
|
||||
ldflags: "-extldflags=-latomic -static"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: amd64
|
||||
cgo_enabled: "1"
|
||||
cc: x86_64-w64-mingw32-gcc
|
||||
cflags: "-O2 -static-libgcc -static-libstdc++"
|
||||
ldflags: "-extldflags=-static"
|
||||
packages: "build-essential gcc-mingw-w64-x86-64"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: 386
|
||||
cgo_enabled: "1"
|
||||
cc: i686-w64-mingw32-gcc
|
||||
cflags: "-O2 -static-libgcc -static-libstdc++"
|
||||
ldflags: "-extldflags=-static"
|
||||
packages: "build-essential gcc-mingw-w64-i686"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
packages: "build-essential"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: darwin
|
||||
goarch: amd64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: macos-latest
|
||||
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: macos-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: s390x
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mips
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: mipsle
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: linux
|
||||
goarch: ppc64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: freebsd
|
||||
goarch: amd64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
- goos: freebsd
|
||||
goarch: arm64
|
||||
cgo_enabled: "0"
|
||||
ldflags: "-s -w"
|
||||
runner: ubuntu-latest
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.25.3
|
||||
|
||||
- name: Configure Git for Private Modules
|
||||
run: |
|
||||
git config --global url."https://${{ secrets.GHT }}@github.com/".insteadOf "https://github.com/"
|
||||
git config --global url."git@github.com:".insteadOf "https://github.com/"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
|
||||
- name: Download musl toolchain
|
||||
if: matrix.musl_target != ''
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: musl-${{ matrix.musl_target }}-toolchain
|
||||
|
||||
- name: Setup musl toolchain
|
||||
if: matrix.musl_target != ''
|
||||
run: |
|
||||
sudo tar -xzf musl-${{ matrix.musl_target }}-toolchain.tar.gz -C /opt/
|
||||
echo "/opt/musl-${{ matrix.musl_target }}/bin" >> $GITHUB_PATH
|
||||
|
||||
# Verify toolchain is working
|
||||
/opt/musl-${{ matrix.musl_target }}/bin/${{ matrix.musl_target }}-gcc --version
|
||||
|
||||
# Test compiler
|
||||
echo 'int main() { return 0; }' > test.c
|
||||
/opt/musl-${{ matrix.musl_target }}/bin/${{ matrix.musl_target }}-gcc ${{ matrix.cflags }} test.c -o test
|
||||
rm -f test.c test
|
||||
|
||||
- name: Install cross-compilation tools (non-musl)
|
||||
if: matrix.runner != 'macos-latest' && matrix.musl_target == ''
|
||||
run: |
|
||||
sudo systemctl restart systemd-resolved || true
|
||||
sudo apt-get update -qq || (sleep 10 && sudo apt-get update -qq)
|
||||
|
||||
case "${{ matrix.goos }}-${{ matrix.goarch }}" in
|
||||
windows-amd64|windows-386)
|
||||
for i in 1 2 3; do
|
||||
sudo apt-get install -y build-essential gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 && break || sleep 10
|
||||
done ;;
|
||||
*)
|
||||
sudo systemctl restart systemd-resolved || true
|
||||
for i in 1 2 3; do
|
||||
sudo apt-get install -y build-essential && break || sleep 10
|
||||
done ;;
|
||||
esac
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build Binary
|
||||
env:
|
||||
CGO_ENABLED: ${{ matrix.cgo_enabled }}
|
||||
GOOS: ${{ matrix.goos }}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
CGO_CFLAGS: ${{ matrix.cflags }}
|
||||
CGO_LDFLAGS: ${{ matrix.ldflags }}
|
||||
run: |
|
||||
go clean -cache -modcache -testcache
|
||||
|
||||
# Set CC based on target
|
||||
if [[ "${{ matrix.musl_target }}" != "" ]]; then
|
||||
export CC="/opt/musl-${{ matrix.musl_target }}/bin/${{ matrix.musl_target }}-gcc"
|
||||
export CXX="/opt/musl-${{ matrix.musl_target }}/bin/${{ matrix.musl_target }}-g++"
|
||||
elif [[ "${{ matrix.cc }}" != "" ]]; then
|
||||
export CC="${{ matrix.cc }}"
|
||||
fi
|
||||
|
||||
# 设置额外的环境变量
|
||||
if [[ -n "${{ matrix.goarm }}" ]]; then
|
||||
export GOARM=${{ matrix.goarm }}
|
||||
fi
|
||||
if [[ -n "${{ matrix.gomips }}" ]]; then
|
||||
export GOMIPS=${{ matrix.gomips }}
|
||||
fi
|
||||
|
||||
# 针对 Darwin 的特殊处理
|
||||
if [[ "${{ matrix.cgo_enabled }}" == "1" && "${{ matrix.goos }}" == "darwin" ]]; then
|
||||
if [[ "${{ matrix.goarch }}" == "amd64" ]]; then
|
||||
export CC="x86_64-apple-darwin21.4-clang"
|
||||
export CXX="x86_64-apple-darwin21.4-clang++"
|
||||
elif [[ "${{ matrix.goarch }}" == "arm64" ]]; then
|
||||
export CC="aarch64-apple-darwin21.4-clang"
|
||||
export CXX="aarch64-apple-darwin21.4-clang++"
|
||||
fi
|
||||
export OSXCROSS_ROOT="${OSXCROSS_ROOT}"
|
||||
fi
|
||||
|
||||
# 清理和准备
|
||||
rm -rf vendor/
|
||||
go mod download
|
||||
go mod tidy
|
||||
mkdir -p bin
|
||||
|
||||
# 设置二进制文件名
|
||||
BINARY_NAME="goecs"
|
||||
if [[ "${{ matrix.goos }}" == "windows" ]]; then
|
||||
BINARY_NAME="${BINARY_NAME}.exe"
|
||||
fi
|
||||
|
||||
# 构建 LDFLAGS
|
||||
LDFLAGS="-s -w -X main.version=${{ steps.tag.outputs.version }} -X main.arch=${{ matrix.goarch }}"
|
||||
if [[ "${{ matrix.cgo_enabled }}" == "1" ]]; then
|
||||
LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}"
|
||||
else
|
||||
LDFLAGS="${LDFLAGS} -checklinkname=0 ${{ matrix.ldflags }}"
|
||||
fi
|
||||
|
||||
# 执行构建
|
||||
echo "Building for GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=$CGO_ENABLED"
|
||||
if [[ -n "$CC" ]]; then
|
||||
echo "Using CC=$CC"
|
||||
fi
|
||||
|
||||
go build -a -o bin/$BINARY_NAME -ldflags="$LDFLAGS" -trimpath ./
|
||||
|
||||
# 验证文件是否存在
|
||||
[[ -f "bin/$BINARY_NAME" ]] || exit 1
|
||||
|
||||
# 显示构建信息
|
||||
echo "Built binary: bin/$BINARY_NAME"
|
||||
ls -la bin/
|
||||
if command -v file >/dev/null 2>&1; then
|
||||
file bin/$BINARY_NAME
|
||||
fi
|
||||
|
||||
- name: Create ZIP archive
|
||||
run: |
|
||||
cd bin
|
||||
BINARY_NAME="goecs"
|
||||
if [[ "${{ matrix.goos }}" == "windows" ]]; then
|
||||
BINARY_NAME="${BINARY_NAME}.exe"
|
||||
fi
|
||||
ZIP_NAME="goecs_${{ matrix.goos }}_${{ matrix.goarch }}"
|
||||
if [[ -n "${{ matrix.goarm }}" ]]; then
|
||||
ZIP_NAME="${ZIP_NAME}v${{ matrix.goarm }}"
|
||||
fi
|
||||
if [[ -n "${{ matrix.gomips }}" ]]; then
|
||||
ZIP_NAME="${ZIP_NAME}_${{ matrix.gomips }}"
|
||||
fi
|
||||
ZIP_NAME="${ZIP_NAME}.zip"
|
||||
zip "$ZIP_NAME" "$BINARY_NAME"
|
||||
|
||||
- name: Upload to Release
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
cd bin
|
||||
for file in *.zip; do
|
||||
if [[ -f "$file" ]]; then
|
||||
curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: application/zip" \
|
||||
--data-binary @"$file" \
|
||||
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$file"
|
||||
fi
|
||||
done
|
||||
|
||||
checksums:
|
||||
name: Generate Checksums
|
||||
runs-on: ubuntu-latest
|
||||
needs: release-binary
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Download release assets
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
mkdir -p assets
|
||||
ASSETS=$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets")
|
||||
echo "$ASSETS" | jq -r '.[] | select(.name | endswith(".zip")) | .browser_download_url' | while read url; do
|
||||
filename=$(basename "$url")
|
||||
curl -L -H "Authorization: Bearer ${{ secrets.GHT }}" "$url" -o "assets/$filename"
|
||||
done
|
||||
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
cd assets
|
||||
sha256sum *.zip > checksums.txt
|
||||
if [[ -f "../goecs.sh" ]]; then
|
||||
sha256sum ../goecs.sh >> checksums.txt
|
||||
fi
|
||||
|
||||
- name: Upload checksums
|
||||
run: |
|
||||
TAG="${{ steps.tag.outputs.tag }}"
|
||||
RELEASE_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" "https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG" | jq -r '.id')
|
||||
curl -s -H "Authorization: Bearer ${{ secrets.GHT }}" \
|
||||
-H "Content-Type: text/plain" \
|
||||
--data-binary @assets/checksums.txt \
|
||||
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=checksums.txt"
|
||||
|
||||
update-script:
|
||||
name: Update Script Version
|
||||
runs-on: ubuntu-latest
|
||||
needs: checksums
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get latest tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update goecs.sh version
|
||||
run: |
|
||||
VERSION="${{ steps.tag.outputs.version }}"
|
||||
BRANCH="master"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global --unset url."git@github.com:".insteadOf || true
|
||||
git fetch origin $BRANCH
|
||||
git checkout $BRANCH
|
||||
if [ -f "goecs.sh" ]; then
|
||||
sed -i "s/\(_yellow \"Unable to get version info, using default version \).*\(\".*\)/\1$VERSION\2/" "goecs.sh"
|
||||
sed -i "s/\(ECS_VERSION=\"\).*\(\"\)/\1$VERSION\2/" "goecs.sh"
|
||||
if ! git diff --quiet "goecs.sh"; then
|
||||
git add "goecs.sh"
|
||||
git commit -m "chore: update ECS_VERSION to $VERSION in goecs.sh"
|
||||
git push origin $BRANCH
|
||||
fi
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GHT }}
|
||||
@@ -1,11 +0,0 @@
|
||||
package commediatest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/oneclickvirt/CommonMediaTests/commediatests"
|
||||
)
|
||||
|
||||
func ComMediaTest(language string) {
|
||||
res := commediatests.MediaTests(language)
|
||||
fmt.Print(res)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package commediatest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// 本包仅测试无实际使用
|
||||
func TestMedia(t *testing.T) {
|
||||
ComMediaTest("zh")
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package network1
|
||||
|
||||
import "github.com/oneclickvirt/security/network"
|
||||
|
||||
// 本包在main中不使用
|
||||
func NetworkCheck(checkType string, enableSecurityCheck bool, language string) (string, string, error) {
|
||||
return network.NetworkCheck(checkType, enableSecurityCheck, language)
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package network1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIpv4SecurityCheck(t *testing.T) {
|
||||
// 单项测试
|
||||
//result1, _ := Ipv4SecurityCheck("8.8.8.8", nil, "zh")
|
||||
//fmt.Println(result1)
|
||||
//result2, _ := Ipv6SecurityCheck("2001:4860:4860::8844", nil, "zh")
|
||||
//fmt.Println(result2)
|
||||
|
||||
// 全项测试
|
||||
ipInfo, securityInfo, _ := NetworkCheck("both", true, "zh")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
fmt.Print(ipInfo)
|
||||
fmt.Println("--------------------------------------------------")
|
||||
fmt.Print(securityInfo)
|
||||
fmt.Println("--------------------------------------------------")
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package port
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/oneclickvirt/portchecker/email"
|
||||
)
|
||||
|
||||
// 常用端口阻断检测 TCP/UDP/ICMP 协议
|
||||
// 本包不在main中使用
|
||||
func EmailCheck() {
|
||||
res := email.EmailCheck()
|
||||
fmt.Println(res)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package port
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
EmailCheck()
|
||||
}
|
||||
6
.github/workflows/build_public.yml
vendored
6
.github/workflows/build_public.yml
vendored
@@ -54,8 +54,10 @@ jobs:
|
||||
|
||||
- name: Create public branch
|
||||
run: |
|
||||
git checkout -b public || git checkout public
|
||||
git merge ${{ github.ref_name }} --no-edit || true
|
||||
# 删除本地 public 分支(如果存在)
|
||||
git branch -D public 2>/dev/null || true
|
||||
# 基于当前分支创建新的 public 分支(完全覆盖)
|
||||
git checkout -b public
|
||||
|
||||
- name: Remove security package references
|
||||
run: |
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
vendor/
|
||||
.idea/
|
||||
.idea/
|
||||
ecs
|
||||
goecs.txt
|
||||
*.log
|
||||
24
Dockerfile
24
Dockerfile
@@ -1,10 +1,24 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM alpine:latest
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache wget curl bash
|
||||
RUN apk add --no-cache bind-tools
|
||||
# --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main
|
||||
RUN apk add --no-cache grep openssl ca-certificates uuidgen
|
||||
|
||||
RUN apk update && apk add --no-cache wget curl bash || \
|
||||
(echo "Standard repo failed, trying edge repo..." && \
|
||||
apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main wget curl bash)
|
||||
|
||||
RUN apk add --no-cache bind-tools || \
|
||||
(echo "Standard repo failed for bind-tools, trying edge repo..." && \
|
||||
apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main bind-tools)
|
||||
|
||||
RUN apk add --no-cache grep openssl ca-certificates || \
|
||||
(echo "Standard repo failed, trying edge repo..." && \
|
||||
apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main grep openssl ca-certificates)
|
||||
|
||||
RUN apk add --no-cache uuidgen || \
|
||||
apk add --no-cache util-linux || \
|
||||
(echo "Standard repo failed for uuidgen, trying edge repo..." && \
|
||||
apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main uuidgen) || \
|
||||
apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main util-linux
|
||||
|
||||
RUN export noninteractive=true
|
||||
# 下载并执行 goecs.sh 脚本
|
||||
RUN curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && \
|
||||
|
||||
15
README.md
15
README.md
@@ -45,7 +45,6 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS
|
||||
|
||||
| 系统 | 说明 |
|
||||
|----------------|---------------------------|
|
||||
| Android(arm64) | 存在权限问题未修复,非安卓系统的ARM架构无问题 |
|
||||
| OpenBSD/NetBSD | 部分Goalng的官方库未支持本系统(尤其是net相关项目) |
|
||||
|
||||
---
|
||||
@@ -205,6 +204,8 @@ Usage: goecs [options]
|
||||
-email
|
||||
Enable/Disable email port test (default true)
|
||||
-h Show help information
|
||||
-help
|
||||
Show help information
|
||||
-l string
|
||||
Set language (supported: en, zh) (default "zh")
|
||||
-log
|
||||
@@ -212,26 +213,34 @@ Usage: goecs [options]
|
||||
-memory
|
||||
Enable/Disable memory test (default true)
|
||||
-memorym string
|
||||
Set memory test method (supported: sysbench, dd, winsat) (default "sysbench")
|
||||
Set memory test method (supported: stream, sysbench, dd, winsat, auto) (default "stream")
|
||||
-menu
|
||||
Enable/Disable menu mode, disable example: -menu=false (default true)
|
||||
-nt3
|
||||
Enable/Disable NT3 test (in 'en' language or on windows it always false) (default true)
|
||||
-nt3loc string
|
||||
Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu) (default "GZ")
|
||||
Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all) (default "GZ")
|
||||
-nt3t string
|
||||
Set NT3 test type (supported: both, ipv4, ipv6) (default "ipv4")
|
||||
-ping
|
||||
Enable/Disable ping test
|
||||
-security
|
||||
Enable/Disable security test (default true)
|
||||
-speed
|
||||
Enable/Disable speed test (default true)
|
||||
-spnum int
|
||||
Set the number of servers per operator for speed test (default 2)
|
||||
-tgdc
|
||||
Enable/Disable Telegram DC test
|
||||
-upload
|
||||
Enable/Disable upload the result (default true)
|
||||
-ut
|
||||
Enable/Disable unlock media test (default true)
|
||||
-v Display version information
|
||||
-version
|
||||
Display version information
|
||||
-web
|
||||
Enable/Disable popular websites test
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
15
README_EN.md
15
README_EN.md
@@ -45,7 +45,6 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https:
|
||||
|
||||
| OS | Notes |
|
||||
|--------|-------------------------------------------------------------------------------------------------|
|
||||
| Android(arm64) | Permission issues that are not fixed, no problems with ARM architecture for non-Android systems |
|
||||
| OpenBSD/NetBSD | Some of Goalng's official libraries do not support this system (especially net-related items) |
|
||||
|
||||
---
|
||||
@@ -204,6 +203,8 @@ Usage: goecs [options]
|
||||
-email
|
||||
Enable/Disable email port test (default true)
|
||||
-h Show help information
|
||||
-help
|
||||
Show help information
|
||||
-l string
|
||||
Set language (supported: en, zh) (default "zh")
|
||||
-log
|
||||
@@ -211,26 +212,34 @@ Usage: goecs [options]
|
||||
-memory
|
||||
Enable/Disable memory test (default true)
|
||||
-memorym string
|
||||
Set memory test method (supported: sysbench, dd, winsat) (default "sysbench")
|
||||
Set memory test method (supported: stream, sysbench, dd, winsat, auto) (default "stream")
|
||||
-menu
|
||||
Enable/Disable menu mode, disable example: -menu=false (default true)
|
||||
-nt3
|
||||
Enable/Disable NT3 test (in 'en' language or on windows it always false) (default true)
|
||||
-nt3loc string
|
||||
Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu) (default "GZ")
|
||||
Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all) (default "GZ")
|
||||
-nt3t string
|
||||
Set NT3 test type (supported: both, ipv4, ipv6) (default "ipv4")
|
||||
-ping
|
||||
Enable/Disable ping test
|
||||
-security
|
||||
Enable/Disable security test (default true)
|
||||
-speed
|
||||
Enable/Disable speed test (default true)
|
||||
-spnum int
|
||||
Set the number of servers per operator for speed test (default 2)
|
||||
-tgdc
|
||||
Enable/Disable Telegram DC test
|
||||
-upload
|
||||
Enable/Disable upload the result (default true)
|
||||
-ut
|
||||
Enable/Disable unlock media test (default true)
|
||||
-v Display version information
|
||||
-version
|
||||
Display version information
|
||||
-web
|
||||
Enable/Disable popular websites test
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
- [邮件端口检测](#邮件端口检测)
|
||||
- [上游及回程线路检测](#上游及回程线路检测)
|
||||
- [三网回程路由检测](#三网回程路由检测)
|
||||
- [PING值测试](#PING值测试)
|
||||
- [就近测速](#就近测速)
|
||||
|
||||
## English
|
||||
@@ -27,6 +28,7 @@
|
||||
- [Streaming Media Unlocking](#Streaming-Media-Unlocking)
|
||||
- [IP Quality Detection](#IP-Quality-Detection)
|
||||
- [Email Port Detection](#Email-Port-Detection)
|
||||
- [PING Testing](#PING-Testing)
|
||||
- [Nearby Speed Testing](#Nearby-Speed-Testing)
|
||||
|
||||
## 日本語
|
||||
@@ -37,12 +39,15 @@
|
||||
- [ストリーミングメディアロック解除](#ストリーミングメディアロック解除)
|
||||
- [IP品質検出](#IP品質検出)
|
||||
- [メールポート検出](#メールポート検出)
|
||||
- [PING検出](#PING検出)
|
||||
- [近隣スピードテスト](#近隣スピードテスト)
|
||||
|
||||
---
|
||||
|
||||
## 中文
|
||||
|
||||
menu模式默认启用,执行时显示菜单可选择选项测试,在menu模式启用的情况下,默认额外提供的CI参数设置优先级高于选项本身的预设值,方便用户随时针对某个选项自行修改某些单项测试的参数设置。
|
||||
|
||||
### **系统基础信息**
|
||||
|
||||
依赖项目:[https://github.com/oneclickvirt/basics](https://github.com/oneclickvirt/basics) [https://github.com/oneclickvirt/gostun](https://github.com/oneclickvirt/gostun)
|
||||
@@ -407,6 +412,20 @@ Abuser 或 Abuse 的滥用得分会直接影响机器的正常使用(中国境
|
||||
|
||||
有时候路由信息完全藏起来了,只知道实际使用的延迟低,实际可能也是优质线路只是查不到信息,这就没办法直接识别了。
|
||||
|
||||
所有测不出来失败的地址以及延迟大于等于9999ms的,延迟都设为了9999,延迟超过这个也证明目标延迟过大影响使用,此时认为目标不可用就行。
|
||||
|
||||
### **PING值测试**
|
||||
|
||||
依赖项目:[https://github.com/oneclickvirt/pingtest](https://github.com/oneclickvirt/pingtest)
|
||||
|
||||
对于选项1:如果启用中国模式,将仅检测三网全国各省份的PING值延迟,从小到大排序。如果不启用中国模式,默认将不检测三网全国各省份的PING值延迟,仅检测TGDC和主流网站的延迟。
|
||||
|
||||
对于选项6和选项10:默认都进行测试。
|
||||
|
||||
对于中国境内的测试,测试TGDC和主流跨国网站的延迟无意义,所以默认不测试。
|
||||
|
||||
对于参数指定的状态,优先级会高于选项中默认的参数设置。
|
||||
|
||||
### **就近测速**
|
||||
|
||||
依赖项目:[https://github.com/oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest)
|
||||
@@ -423,6 +442,8 @@ Abuser 或 Abuse 的滥用得分会直接影响机器的正常使用(中国境
|
||||
|
||||
## English
|
||||
|
||||
Menu mode is enabled by default, the menu is displayed to select the option test, in the case of menu mode enabled, the default additional CI parameter setting priority is higher than the preset value of the option itself, which is convenient for the user to modify the parameter settings of some single test for a certain option at any time by themselves.
|
||||
|
||||
### Basic System Information
|
||||
|
||||
Dependency project: [https://github.com/oneclickvirt/basics](https://github.com/oneclickvirt/basics) [https://github.com/oneclickvirt/gostun](https://github.com/oneclickvirt/gostun)
|
||||
@@ -733,6 +754,14 @@ Dependency project: [https://github.com/oneclickvirt/portchecker](https://github
|
||||
|
||||
If the current host doesn't function as a mail server and doesn't send/receive emails, this project indicator can be ignored.
|
||||
|
||||
### PING Testing
|
||||
|
||||
Dependency project: [https://github.com/oneclickvirt/pingtest](https://github.com/oneclickvirt/pingtest)
|
||||
|
||||
Measure the latency from the current IP address to each TG data center and major websites.
|
||||
|
||||
All addresses that cannot be tested for failure, as well as those with latency greater than or equal to 9999ms, have their latency set to 9999. Latency exceeding this threshold also indicates excessive target latency that impairs usability. At this point, the target should be considered unavailable.
|
||||
|
||||
### Nearby Speed Testing
|
||||
|
||||
Dependency project: [https://github.com/oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest)
|
||||
@@ -747,6 +776,8 @@ In daily use, I prefer to use servers with 1Gbps bandwidth, at least the speed o
|
||||
|
||||
## 日本語
|
||||
|
||||
メニューモードはデフォルトで有効化されており、実行時にメニューを表示してオプションテストを選択できます。メニューモードが有効な場合、デフォルトで追加提供されるCIパラメータ設定はオプション自体のプリセット値よりも優先度が高く、ユーザーが特定のオプションに対して随時個別のテストパラメータ設定を変更できるようにします。
|
||||
|
||||
### システム基本情報
|
||||
|
||||
依存プロジェクト:[https://github.com/oneclickvirt/basics](https://github.com/oneclickvirt/basics) [https://github.com/oneclickvirt/gostun](https://github.com/oneclickvirt/gostun)
|
||||
@@ -1057,6 +1088,14 @@ IPタイプの分類について詳しく説明する必要がある
|
||||
|
||||
現在のホストがメール局として機能せず、電子メールの送受信を行わない場合、この項目指標は無視して構いません。
|
||||
|
||||
### PING検出
|
||||
|
||||
依存プロジェクト:[https://github.com/oneclickvirt/pingtest](https://github.com/oneclickvirt/pingtest)
|
||||
|
||||
現在のIPアドレスからTGの各データセンターおよび主要ウェブサイトまでの遅延を測定します。
|
||||
|
||||
検出不能な失敗アドレスおよび遅延が9999ms以上のものは、遅延を9999に設定する。この値を超える遅延は対象の遅延が過大で利用に影響することを示すため、この時点で対象は利用不可と判断すればよい。
|
||||
|
||||
### 近隣スピードテスト
|
||||
|
||||
依存プロジェクト:[https://github.com/oneclickvirt/speedtest](https://github.com/oneclickvirt/speedtest)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package cputest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
_, res := CpuTest("zh", "sysbench", "1")
|
||||
fmt.Print(res)
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package disktest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDiskIoTest(t *testing.T) {
|
||||
_, res := DiskTest("zh", "sysbench", "", false, false)
|
||||
fmt.Print(res)
|
||||
}
|
||||
8
go.mod
8
go.mod
@@ -6,18 +6,18 @@ require (
|
||||
github.com/imroc/req/v3 v3.54.0
|
||||
github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841
|
||||
github.com/oneclickvirt/UnlockTests v0.0.30-20251030112700
|
||||
github.com/oneclickvirt/backtrace v0.0.7-20250811023541
|
||||
github.com/oneclickvirt/backtrace v0.0.8-20251102140847
|
||||
github.com/oneclickvirt/basics v0.0.16-20251030093657
|
||||
github.com/oneclickvirt/cputest v0.0.12-20250720122317
|
||||
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/nt3 v0.0.9-20251031045617
|
||||
github.com/oneclickvirt/pingtest v0.0.8-20250728015259
|
||||
github.com/oneclickvirt/nt3 v0.0.10-20251104114914
|
||||
github.com/oneclickvirt/pingtest v0.0.9-20251104112920
|
||||
github.com/oneclickvirt/portchecker v0.0.3-20250728015900
|
||||
github.com/oneclickvirt/security v0.0.7-20251030094114
|
||||
github.com/oneclickvirt/speedtest v0.0.10-20250728015734
|
||||
github.com/oneclickvirt/speedtest v0.0.11-20251102151740
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
16
go.sum
16
go.sum
@@ -98,8 +98,8 @@ github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 h1:Zef93z9UiZQwRA
|
||||
github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841/go.mod h1:DAmFPRjFV5p9fEzUUSml5jJGn2f1NZJQCzTxITHDjc4=
|
||||
github.com/oneclickvirt/UnlockTests v0.0.30-20251030112700 h1:dtHHyWZdshox8StzrjgImj3Rvqwup5OZJ8FAZZQjPIA=
|
||||
github.com/oneclickvirt/UnlockTests v0.0.30-20251030112700/go.mod h1:oOa6wj/qECtRMxwBO6D7o0L0F0Q/5sQ747OCnFQqoGE=
|
||||
github.com/oneclickvirt/backtrace v0.0.7-20250811023541 h1:GzkzvUC6U9b6Dkz/Bl4JRPeQ7XBGoW7Qw1aWqzhF+MQ=
|
||||
github.com/oneclickvirt/backtrace v0.0.7-20250811023541/go.mod h1:/+KUtOWz48TyiTTbhVTsp3D6b5WY+4pCgvFBYtUGtns=
|
||||
github.com/oneclickvirt/backtrace v0.0.8-20251102140847 h1:OiwD06+Mql3pYP8jJFFdP3OUlCrx/qJT7y2YCd/OMiI=
|
||||
github.com/oneclickvirt/backtrace v0.0.8-20251102140847/go.mod h1:mj9TSow7FNszBb3bQj2Hhm41LwBo7HQP6sgaPtovKdM=
|
||||
github.com/oneclickvirt/basics v0.0.16-20251030093657 h1:6SWWILNjJfMTXbspqYRpktUEOe/QIVhGonKO8ODC7n4=
|
||||
github.com/oneclickvirt/basics v0.0.16-20251030093657/go.mod h1:2PV+1ge01zb0Sqzj2V2I7P0wAdFSLF1XgAiumchJJbg=
|
||||
github.com/oneclickvirt/cputest v0.0.12-20250720122317 h1:toiwAK1hZE5b8klu2mOQ7J4sv5yV9lpPKwgPahfRYBQ=
|
||||
@@ -118,16 +118,16 @@ github.com/oneclickvirt/mbw v0.0.1-20250808061222 h1:WGXOe6QvHiDRhPVMI0VcctjzW08
|
||||
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/nt3 v0.0.9-20251031045617 h1:g42R4kwOL4s6sDsG+axEXJsI82pldv42HLMYCDFypNg=
|
||||
github.com/oneclickvirt/nt3 v0.0.9-20251031045617/go.mod h1:yo1ufkduFt9QjqG7nqSUf1D3YlQOmFpdlTYniJfclQI=
|
||||
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/nt3 v0.0.10-20251104114914 h1:P4nbdKcIA7+FH4feLLxfiJVf1f3ENi/oo37EsdyX9oI=
|
||||
github.com/oneclickvirt/nt3 v0.0.10-20251104114914/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/security v0.0.7-20251030094114 h1:Ax8J1TYqprXyiWNAIJJ3xhoyGhvBlKw4m9j6va5Q2nM=
|
||||
github.com/oneclickvirt/security v0.0.7-20251030094114/go.mod h1:YfDilPFW22szjdUNgv4VOuSwHnZzsFsdPOfRYiMoc3I=
|
||||
github.com/oneclickvirt/speedtest v0.0.10-20250728015734 h1:HKO7/JQ74ueXA8Wo8NIvcK9DphbEG/YTfAAVz/akSiY=
|
||||
github.com/oneclickvirt/speedtest v0.0.10-20250728015734/go.mod h1:0W8vnMbA3iucXLXFdGfe9Ia6RPS0izRO7jvu/SnH1P8=
|
||||
github.com/oneclickvirt/speedtest v0.0.11-20251102151740 h1:1NUrNt5ay6/xVNC5x62UrQjPqK8jgbKtyjBml/3boZg=
|
||||
github.com/oneclickvirt/speedtest v0.0.11-20251102151740/go.mod h1:fy0II2Wo7kDWVBKTwcHdodZwyfmJo0g8N9V02EwQDZE=
|
||||
github.com/oneclickvirt/stream v0.0.2-20250924154001 h1:GuJWdiPkoK84+y/+oHKr2Ghl3c/MzS9Z5m1nM+lMmy4=
|
||||
github.com/oneclickvirt/stream v0.0.2-20250924154001/go.mod h1:oWaizaHTC2VQciBC9RfaLbAOf8qeR6n20/gY7QxriDE=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||
|
||||
854
goecs.go
854
goecs.go
@@ -1,16 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -21,151 +16,25 @@ import (
|
||||
basicmodel "github.com/oneclickvirt/basics/model"
|
||||
cputestmodel "github.com/oneclickvirt/cputest/model"
|
||||
disktestmodel "github.com/oneclickvirt/disktest/disk"
|
||||
"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"
|
||||
menu "github.com/oneclickvirt/ecs/internal/menu"
|
||||
params "github.com/oneclickvirt/ecs/internal/params"
|
||||
"github.com/oneclickvirt/ecs/internal/runner"
|
||||
"github.com/oneclickvirt/ecs/utils"
|
||||
gostunmodel "github.com/oneclickvirt/gostun/model"
|
||||
memorytestmodel "github.com/oneclickvirt/memorytest/memory"
|
||||
nt3model "github.com/oneclickvirt/nt3/model"
|
||||
ptmodel "github.com/oneclickvirt/pingtest/model"
|
||||
"github.com/oneclickvirt/pingtest/pt"
|
||||
"github.com/oneclickvirt/portchecker/email"
|
||||
speedtestmodel "github.com/oneclickvirt/speedtest/model"
|
||||
)
|
||||
|
||||
var (
|
||||
ecsVersion = "v0.1.93"
|
||||
menuMode bool
|
||||
onlyChinaTest bool
|
||||
input, choice string
|
||||
showVersion bool
|
||||
enableLogger bool
|
||||
language string
|
||||
cpuTestMethod, cpuTestThreadMode string
|
||||
memoryTestMethod string
|
||||
diskTestMethod, diskTestPath string
|
||||
diskMultiCheck bool
|
||||
nt3CheckType, nt3Location string
|
||||
spNum int
|
||||
width = 82
|
||||
basicStatus, cpuTestStatus, memoryTestStatus, diskTestStatus bool
|
||||
commTestStatus, utTestStatus, securityTestStatus, emailTestStatus bool
|
||||
backtraceStatus, nt3Status, speedTestStatus, pingTestStatus bool
|
||||
autoChangeDiskTestMethod = true
|
||||
filePath = "goecs.txt"
|
||||
enabelUpload = true
|
||||
onlyIpInfoCheckStatus, help bool
|
||||
goecsFlag = flag.NewFlagSet("goecs", flag.ContinueOnError)
|
||||
finish bool
|
||||
ecsVersion = "v0.1.99" // 融合怪版本号
|
||||
configs = params.NewConfig(ecsVersion) // 全局配置实例
|
||||
userSetFlags = make(map[string]bool) // 用于跟踪哪些参数是用户显式设置的
|
||||
)
|
||||
|
||||
func getMenuChoice(language string) string {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer signal.Stop(sigChan)
|
||||
inputChan := make(chan string, 1)
|
||||
go func() {
|
||||
select {
|
||||
case <-sigChan:
|
||||
fmt.Println("\n程序在选择过程中被用户中断")
|
||||
os.Exit(0)
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}()
|
||||
for {
|
||||
go func() {
|
||||
var input string
|
||||
fmt.Print("请输入选项 / Please enter your choice: ")
|
||||
fmt.Scanln(&input)
|
||||
input = strings.TrimSpace(input)
|
||||
input = strings.TrimRight(input, "\n")
|
||||
select {
|
||||
case inputChan <- input:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case input := <-inputChan:
|
||||
re := regexp.MustCompile(`^\d+$`)
|
||||
if re.MatchString(input) {
|
||||
inChoice := input
|
||||
switch inChoice {
|
||||
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10":
|
||||
return inChoice
|
||||
default:
|
||||
if language == "zh" {
|
||||
fmt.Println("无效的选项")
|
||||
} else {
|
||||
fmt.Println("Invalid choice")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if language == "zh" {
|
||||
fmt.Println("输入错误,请输入一个纯数字")
|
||||
} else {
|
||||
fmt.Println("Invalid input, please enter a number")
|
||||
}
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseFlags() {
|
||||
goecsFlag.BoolVar(&help, "h", false, "Show help information")
|
||||
goecsFlag.BoolVar(&showVersion, "v", false, "Display version information")
|
||||
goecsFlag.BoolVar(&menuMode, "menu", true, "Enable/Disable menu mode, disable example: -menu=false") // true 默认启用菜单栏模式
|
||||
goecsFlag.StringVar(&language, "l", "zh", "Set language (supported: en, zh)")
|
||||
goecsFlag.BoolVar(&basicStatus, "basic", true, "Enable/Disable basic test")
|
||||
goecsFlag.BoolVar(&cpuTestStatus, "cpu", true, "Enable/Disable CPU test")
|
||||
goecsFlag.BoolVar(&memoryTestStatus, "memory", true, "Enable/Disable memory test")
|
||||
goecsFlag.BoolVar(&diskTestStatus, "disk", true, "Enable/Disable disk test")
|
||||
goecsFlag.BoolVar(&commTestStatus, "comm", true, "Enable/Disable common media test")
|
||||
goecsFlag.BoolVar(&utTestStatus, "ut", true, "Enable/Disable unlock media test")
|
||||
goecsFlag.BoolVar(&securityTestStatus, "security", true, "Enable/Disable security test")
|
||||
goecsFlag.BoolVar(&emailTestStatus, "email", true, "Enable/Disable email port test")
|
||||
goecsFlag.BoolVar(&backtraceStatus, "backtrace", true, "Enable/Disable backtrace test (in 'en' language or on windows it always false)")
|
||||
goecsFlag.BoolVar(&nt3Status, "nt3", true, "Enable/Disable NT3 test (in 'en' language or on windows it always false)")
|
||||
goecsFlag.BoolVar(&speedTestStatus, "speed", true, "Enable/Disable speed test")
|
||||
goecsFlag.StringVar(&cpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)")
|
||||
goecsFlag.StringVar(&cpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)")
|
||||
goecsFlag.StringVar(&memoryTestMethod, "memorym", "stream", "Set memory test method (supported: stream, sysbench, dd, winsat, auto)")
|
||||
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, 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")
|
||||
goecsFlag.BoolVar(&enabelUpload, "upload", true, "Enable/Disable upload the result")
|
||||
goecsFlag.Parse(os.Args[1:])
|
||||
}
|
||||
|
||||
func handleHelpAndVersion() bool {
|
||||
if help {
|
||||
fmt.Printf("Usage: %s [options]\n", os.Args[0])
|
||||
goecsFlag.PrintDefaults()
|
||||
return true
|
||||
}
|
||||
if showVersion {
|
||||
fmt.Println(ecsVersion)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func initLogger() {
|
||||
if enableLogger {
|
||||
if configs.EnableLogger {
|
||||
gostunmodel.EnableLoger = true
|
||||
basicmodel.EnableLoger = true
|
||||
cputestmodel.EnableLoger = true
|
||||
@@ -180,694 +49,19 @@ func initLogger() {
|
||||
}
|
||||
}
|
||||
|
||||
func handleMenuMode(preCheck utils.NetCheckResult) {
|
||||
basicStatus, cpuTestStatus, memoryTestStatus, diskTestStatus = false, false, false, false
|
||||
commTestStatus, utTestStatus, securityTestStatus, emailTestStatus = false, false, false, false
|
||||
backtraceStatus, nt3Status, speedTestStatus = false, false, false
|
||||
autoChangeDiskTestMethod = true
|
||||
printMenuOptions(preCheck)
|
||||
Loop:
|
||||
for {
|
||||
choice = getMenuChoice(language)
|
||||
switch choice {
|
||||
case "0":
|
||||
os.Exit(0)
|
||||
case "1":
|
||||
setFullTestStatus(preCheck)
|
||||
onlyChinaTest = utils.CheckChina(enableLogger)
|
||||
break Loop
|
||||
case "2":
|
||||
setMinimalTestStatus(preCheck)
|
||||
break Loop
|
||||
case "3":
|
||||
setStandardTestStatus(preCheck)
|
||||
break Loop
|
||||
case "4":
|
||||
setNetworkFocusedTestStatus(preCheck)
|
||||
break Loop
|
||||
case "5":
|
||||
setUnlockFocusedTestStatus(preCheck)
|
||||
break Loop
|
||||
case "6":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
setNetworkOnlyTestStatus()
|
||||
break Loop
|
||||
case "7":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
setUnlockOnlyTestStatus()
|
||||
break Loop
|
||||
case "8":
|
||||
setHardwareOnlyTestStatus(preCheck)
|
||||
break Loop
|
||||
case "9":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
setIPQualityTestStatus()
|
||||
break Loop
|
||||
case "10":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
nt3Location = "ALL"
|
||||
setRouteTestStatus()
|
||||
break Loop
|
||||
default:
|
||||
printInvalidChoice()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printMenuOptions(preCheck utils.NetCheckResult) {
|
||||
var stats *utils.StatsResponse
|
||||
var statsErr error
|
||||
var githubInfo *utils.GitHubRelease
|
||||
var githubErr error
|
||||
// 只有在网络连接正常时才获取统计信息和版本信息
|
||||
if preCheck.Connected {
|
||||
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()
|
||||
} else {
|
||||
statsErr = fmt.Errorf("network not connected")
|
||||
githubErr = fmt.Errorf("network not connected")
|
||||
}
|
||||
var statsInfo string
|
||||
var cmp int
|
||||
if preCheck.Connected {
|
||||
// 网络连接正常时处理统计信息和版本比较
|
||||
if statsErr != nil {
|
||||
statsInfo = "NULL"
|
||||
} else {
|
||||
switch language {
|
||||
case "zh":
|
||||
statsInfo = fmt.Sprintf("总使用量: %s | 今日使用: %s",
|
||||
utils.FormatGoecsNumber(stats.Total),
|
||||
utils.FormatGoecsNumber(stats.Daily))
|
||||
case "en":
|
||||
statsInfo = fmt.Sprintf("Total Usage: %s | Daily Usage: %s",
|
||||
utils.FormatGoecsNumber(stats.Total),
|
||||
utils.FormatGoecsNumber(stats.Daily))
|
||||
}
|
||||
}
|
||||
if githubErr == nil {
|
||||
cmp = utils.CompareVersions(ecsVersion, githubInfo.TagName)
|
||||
} else {
|
||||
cmp = 0
|
||||
}
|
||||
}
|
||||
switch language {
|
||||
case "zh":
|
||||
fmt.Printf("VPS融合怪版本: %s\n", ecsVersion)
|
||||
if preCheck.Connected {
|
||||
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("7. 解锁单项(御三家解锁+常用流媒体解锁)")
|
||||
fmt.Println("8. 硬件单项(系统信息+CPU+dd磁盘测试+fio磁盘测试)")
|
||||
fmt.Println("9. IP质量检测(15个数据库的IP质量检测+邮件端口检测)")
|
||||
fmt.Println("10. 三网回程线路检测+三网回程详细路由(北京上海广州成都)+三网延迟测试(全国)")
|
||||
fmt.Println("0. 退出程序")
|
||||
case "en":
|
||||
fmt.Printf("VPS Fusion Monster Test Version: %s\n", ecsVersion)
|
||||
if preCheck.Connected {
|
||||
switch cmp {
|
||||
case -1:
|
||||
fmt.Printf("New version detected %s update if necessary!\n", githubInfo.TagName)
|
||||
}
|
||||
fmt.Printf("%s\n", statsInfo)
|
||||
}
|
||||
fmt.Println("1. VPS Fusion Monster Test (Full Test)")
|
||||
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)")
|
||||
fmt.Println("4. Network-Focused Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)")
|
||||
fmt.Println("5. Unlock-Focused Test Suite (System Info + CPU + Memory + Disk IO + Basic Unlock Tests + Common Streaming Services + 5 Speed Test Nodes)")
|
||||
fmt.Println("6. Network-Only Test (IP Quality Test + 5 Speed Test Nodes)")
|
||||
fmt.Println("7. Unlock-Only Test (Basic Unlock Tests + Common Streaming Services Unlock)")
|
||||
fmt.Println("8. Hardware-Only Test (System Info + CPU + Memory + dd Disk Test + fio Disk Test)")
|
||||
fmt.Println("9. IP Quality Test (IP Test with 15 Databases + Email Port Test)")
|
||||
fmt.Println("0. Exit Program")
|
||||
}
|
||||
}
|
||||
|
||||
func setFullTestStatus(preCheck utils.NetCheckResult) {
|
||||
basicStatus = true
|
||||
cpuTestStatus = true
|
||||
memoryTestStatus = true
|
||||
diskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
commTestStatus = true
|
||||
utTestStatus = true
|
||||
securityTestStatus = true
|
||||
emailTestStatus = true
|
||||
backtraceStatus = true
|
||||
nt3Status = true
|
||||
speedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
func setMinimalTestStatus(preCheck utils.NetCheckResult) {
|
||||
basicStatus = true
|
||||
cpuTestStatus = true
|
||||
memoryTestStatus = true
|
||||
diskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
speedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
func setStandardTestStatus(preCheck utils.NetCheckResult) {
|
||||
basicStatus = true
|
||||
cpuTestStatus = true
|
||||
memoryTestStatus = true
|
||||
diskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
utTestStatus = true
|
||||
nt3Status = true
|
||||
speedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
func setNetworkFocusedTestStatus(preCheck utils.NetCheckResult) {
|
||||
basicStatus = true
|
||||
cpuTestStatus = true
|
||||
memoryTestStatus = true
|
||||
diskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
backtraceStatus = true
|
||||
nt3Status = true
|
||||
speedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
func setUnlockFocusedTestStatus(preCheck utils.NetCheckResult) {
|
||||
basicStatus = true
|
||||
cpuTestStatus = true
|
||||
memoryTestStatus = true
|
||||
diskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
commTestStatus = true
|
||||
utTestStatus = true
|
||||
speedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
func setNetworkOnlyTestStatus() {
|
||||
onlyIpInfoCheckStatus = true
|
||||
securityTestStatus = true
|
||||
speedTestStatus = true
|
||||
backtraceStatus = true
|
||||
nt3Status = true
|
||||
pingTestStatus = true
|
||||
}
|
||||
|
||||
func setUnlockOnlyTestStatus() {
|
||||
onlyIpInfoCheckStatus = true
|
||||
commTestStatus = true
|
||||
utTestStatus = true
|
||||
}
|
||||
|
||||
func setHardwareOnlyTestStatus(preCheck utils.NetCheckResult) {
|
||||
_ = preCheck
|
||||
basicStatus = true
|
||||
cpuTestStatus = true
|
||||
memoryTestStatus = true
|
||||
diskTestStatus = true
|
||||
securityTestStatus = false
|
||||
autoChangeDiskTestMethod = false
|
||||
}
|
||||
|
||||
func setIPQualityTestStatus() {
|
||||
onlyIpInfoCheckStatus = true
|
||||
securityTestStatus = true
|
||||
emailTestStatus = true
|
||||
}
|
||||
|
||||
func setRouteTestStatus() {
|
||||
onlyIpInfoCheckStatus = true
|
||||
backtraceStatus = true
|
||||
nt3Status = true
|
||||
pingTestStatus = true
|
||||
}
|
||||
|
||||
func printInvalidChoice() {
|
||||
if language == "zh" {
|
||||
fmt.Println("无效的选项")
|
||||
} else {
|
||||
fmt.Println("Invalid choice")
|
||||
}
|
||||
}
|
||||
|
||||
func handleLanguageSpecificSettings() {
|
||||
if language == "en" {
|
||||
backtraceStatus = false
|
||||
nt3Status = false
|
||||
if configs.Language == "en" {
|
||||
configs.BacktraceStatus = false
|
||||
configs.Nt3Status = false
|
||||
}
|
||||
if !enabelUpload {
|
||||
securityTestStatus = false
|
||||
}
|
||||
}
|
||||
|
||||
func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *string, _ string, uploadDone chan bool, outputMutex *sync.Mutex) {
|
||||
select {
|
||||
case <-sig:
|
||||
if !finish {
|
||||
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")
|
||||
outputMutex.Lock()
|
||||
timeInfo := utils.PrintAndCapture(func() {
|
||||
utils.PrintCenteredTitle("", width)
|
||||
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)
|
||||
}
|
||||
utils.PrintCenteredTitle("", width)
|
||||
}, "", "")
|
||||
*output += timeInfo
|
||||
finalOutput := *output
|
||||
outputMutex.Unlock()
|
||||
resultChan := make(chan struct {
|
||||
httpURL string
|
||||
httpsURL string
|
||||
}, 1)
|
||||
if enabelUpload {
|
||||
go func() {
|
||||
httpURL, httpsURL := utils.ProcessAndUpload(finalOutput, filePath, enabelUpload)
|
||||
resultChan <- struct {
|
||||
httpURL string
|
||||
httpsURL string
|
||||
}{httpURL, httpsURL}
|
||||
uploadDone <- true
|
||||
}()
|
||||
select {
|
||||
case result := <-resultChan:
|
||||
if result.httpURL != "" || result.httpsURL != "" {
|
||||
if language == "en" {
|
||||
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", result.httpURL, result.httpsURL)
|
||||
} else {
|
||||
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", result.httpURL, result.httpsURL)
|
||||
}
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(0)
|
||||
case <-time.After(30 * time.Second):
|
||||
if language == "en" {
|
||||
fmt.Println("Upload timeout, program exit")
|
||||
} else {
|
||||
fmt.Println("上传超时,程序退出")
|
||||
}
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
|
||||
*output = runBasicTests(preCheck, basicInfo, securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = runCPUTest(*output, tempOutput, outputMutex)
|
||||
*output = runMemoryTest(*output, tempOutput, outputMutex)
|
||||
*output = runDiskTest(*output, tempOutput, outputMutex)
|
||||
if onlyIpInfoCheckStatus && !basicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = runIpInfoCheck(*output, tempOutput, outputMutex)
|
||||
}
|
||||
if utTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !onlyChinaTest {
|
||||
wg1.Add(1)
|
||||
go func() {
|
||||
defer wg1.Done()
|
||||
*mediaInfo = unlocktest.MediaTest(language)
|
||||
}()
|
||||
}
|
||||
if emailTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
wg2.Add(1)
|
||||
go func() {
|
||||
defer wg2.Done()
|
||||
*emailInfo = email.EmailCheck()
|
||||
}()
|
||||
}
|
||||
if (onlyChinaTest || pingTestStatus) && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
wg3.Add(1)
|
||||
go func() {
|
||||
defer wg3.Done()
|
||||
*ptInfo = pt.PingTest()
|
||||
}()
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = runStreamingTests(wg1, mediaInfo, *output, tempOutput, outputMutex)
|
||||
*output = runSecurityTests(*securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = runEmailTests(wg2, emailInfo, *output, tempOutput, outputMutex)
|
||||
}
|
||||
if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = runNetworkTests(wg3, ptInfo, *output, tempOutput, outputMutex)
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = runSpeedTests(*output, tempOutput, outputMutex)
|
||||
}
|
||||
*output = appendTimeInfo(*output, tempOutput, startTime, outputMutex)
|
||||
}
|
||||
|
||||
func runEnglishTests(preCheck utils.NetCheckResult, wg1, wg2 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
|
||||
*output = runBasicTests(preCheck, basicInfo, securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = runCPUTest(*output, tempOutput, outputMutex)
|
||||
*output = runMemoryTest(*output, tempOutput, outputMutex)
|
||||
*output = runDiskTest(*output, tempOutput, outputMutex)
|
||||
if onlyIpInfoCheckStatus && !basicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = runIpInfoCheck(*output, tempOutput, outputMutex)
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
if utTestStatus {
|
||||
wg1.Add(1)
|
||||
go func() {
|
||||
defer wg1.Done()
|
||||
*mediaInfo = unlocktest.MediaTest(language)
|
||||
}()
|
||||
}
|
||||
if emailTestStatus {
|
||||
wg2.Add(1)
|
||||
go func() {
|
||||
defer wg2.Done()
|
||||
*emailInfo = email.EmailCheck()
|
||||
}()
|
||||
}
|
||||
*output = runStreamingTests(wg1, mediaInfo, *output, tempOutput, outputMutex)
|
||||
*output = runSecurityTests(*securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = runEmailTests(wg2, emailInfo, *output, tempOutput, outputMutex)
|
||||
*output = runEnglishSpeedTests(*output, tempOutput, outputMutex)
|
||||
}
|
||||
*output = appendTimeInfo(*output, tempOutput, startTime, outputMutex)
|
||||
}
|
||||
|
||||
// runIpInfoCheck 系统和网络基础信息检测不进行测试的时候,该函数检测取得本机IP信息并显示(单项测试中输出)
|
||||
func runIpInfoCheck(output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
var ipinfo string
|
||||
upstreams.IPV4, upstreams.IPV6, ipinfo = utils.OnlyBasicsIpInfo(language)
|
||||
if ipinfo != "" {
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle("IP信息", width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("IP-Information", width)
|
||||
}
|
||||
fmt.Printf("%s", ipinfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runBasicTests(preCheck utils.NetCheckResult, basicInfo, securityInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
utils.PrintHead(language, width, ecsVersion)
|
||||
if basicStatus || securityTestStatus {
|
||||
if basicStatus {
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle("系统基础信息", width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("System-Basic-Information", width)
|
||||
}
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType == "DualStack" {
|
||||
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, nt3CheckType, securityTestStatus)
|
||||
} else if preCheck.Connected && preCheck.StackType == "IPv4" {
|
||||
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, "ipv4", securityTestStatus)
|
||||
} else if preCheck.Connected && preCheck.StackType == "IPv6" {
|
||||
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, "ipv6", securityTestStatus)
|
||||
} else {
|
||||
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, "", false)
|
||||
securityTestStatus = false
|
||||
}
|
||||
if basicStatus {
|
||||
fmt.Printf("%s", *basicInfo)
|
||||
} else if (input == "6" || input == "9") && securityTestStatus {
|
||||
scanner := bufio.NewScanner(strings.NewReader(*basicInfo))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.Contains(line, "IPV") {
|
||||
fmt.Println(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runCPUTest(output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if cpuTestStatus {
|
||||
realTestMethod, res := cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode)
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", realTestMethod), width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("CPU-Test--%s-Method", realTestMethod), width)
|
||||
}
|
||||
fmt.Print(res)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runMemoryTest(output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if memoryTestStatus {
|
||||
realTestMethod, res := memorytest.MemoryTest(language, memoryTestMethod)
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", realTestMethod), width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Memory-Test--%s-Method", realTestMethod), width)
|
||||
}
|
||||
fmt.Print(res)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runDiskTest(output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if diskTestStatus && autoChangeDiskTestMethod {
|
||||
realTestMethod, res := disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", realTestMethod), width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", realTestMethod), width)
|
||||
}
|
||||
fmt.Print(res)
|
||||
} else if diskTestStatus && !autoChangeDiskTestMethod {
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "dd"), width)
|
||||
_, res := disktest.DiskTest(language, "dd", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
||||
fmt.Print(res)
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "fio"), width)
|
||||
_, res = disktest.DiskTest(language, "fio", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
||||
fmt.Print(res)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "dd"), width)
|
||||
_, res := disktest.DiskTest(language, "dd", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
||||
fmt.Print(res)
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "fio"), width)
|
||||
_, res = disktest.DiskTest(language, "fio", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
||||
fmt.Print(res)
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runStreamingTests(wg1 *sync.WaitGroup, mediaInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if language == "zh" {
|
||||
if commTestStatus && !onlyChinaTest {
|
||||
utils.PrintCenteredTitle("御三家流媒体解锁", width)
|
||||
fmt.Printf("%s", commediatests.MediaTests(language))
|
||||
}
|
||||
}
|
||||
if utTestStatus && (language == "zh" && !onlyChinaTest || language == "en") {
|
||||
wg1.Wait()
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle("跨国流媒体解锁", width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", width)
|
||||
}
|
||||
fmt.Printf("%s", *mediaInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runSecurityTests(securityInfo, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if securityTestStatus {
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle("IP质量检测", width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("IP-Quality-Check", width)
|
||||
}
|
||||
fmt.Printf("%s", securityInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runEmailTests(wg2 *sync.WaitGroup, emailInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if emailTestStatus {
|
||||
wg2.Wait()
|
||||
if language == "zh" {
|
||||
utils.PrintCenteredTitle("邮件端口检测", width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("Email-Port-Check", width)
|
||||
}
|
||||
fmt.Println(*emailInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runNetworkTests(wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if backtraceStatus && !onlyChinaTest {
|
||||
utils.PrintCenteredTitle("上游及回程线路检测", width)
|
||||
upstreams.UpstreamsCheck() // 不能在重定向的同时外部并发,此处仅可以顺序执行
|
||||
}
|
||||
if nt3Status && !onlyChinaTest {
|
||||
utils.PrintCenteredTitle("三网回程路由检测", width)
|
||||
nexttrace.NextTrace3Check(language, nt3Location, nt3CheckType) // 不能在重定向的同时外部并发,此处仅可以顺序执行
|
||||
}
|
||||
if (onlyChinaTest || pingTestStatus) && *ptInfo != "" {
|
||||
wg3.Wait()
|
||||
utils.PrintCenteredTitle("三网ICMP的PING值检测", width)
|
||||
fmt.Println(*ptInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runSpeedTests(output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if speedTestStatus {
|
||||
utils.PrintCenteredTitle("就近节点测速", width)
|
||||
speedtest.ShowHead(language)
|
||||
if choice == "1" || !menuMode {
|
||||
speedtest.NearbySP()
|
||||
speedtest.CustomSP("net", "global", 2, language)
|
||||
speedtest.CustomSP("net", "cu", spNum, language)
|
||||
speedtest.CustomSP("net", "ct", spNum, language)
|
||||
speedtest.CustomSP("net", "cmcc", spNum, language)
|
||||
} else if choice == "2" || choice == "3" || choice == "4" || choice == "5" {
|
||||
speedtest.CustomSP("net", "global", 4, language)
|
||||
} else if choice == "6" {
|
||||
speedtest.CustomSP("net", "global", 11, language)
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func runEnglishSpeedTests(output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if speedTestStatus {
|
||||
utils.PrintCenteredTitle("Speed-Test", width)
|
||||
speedtest.ShowHead(language)
|
||||
speedtest.NearbySP()
|
||||
speedtest.CustomSP("net", "global", -1, language)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func appendTimeInfo(output, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
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")
|
||||
return utils.PrintAndCapture(func() {
|
||||
utils.PrintCenteredTitle("", width)
|
||||
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)
|
||||
}
|
||||
utils.PrintCenteredTitle("", width)
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
func handleUploadResults(output string) {
|
||||
httpURL, httpsURL := utils.ProcessAndUpload(output, filePath, enabelUpload)
|
||||
if httpURL != "" || httpsURL != "" {
|
||||
if language == "en" {
|
||||
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
|
||||
fmt.Println("Each Test Benchmark: https://bash.spiritlhl.net/ecsguide")
|
||||
} else {
|
||||
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
|
||||
fmt.Println("每项测试基准见: https://bash.spiritlhl.net/ecsguide")
|
||||
}
|
||||
if !configs.EnableUpload {
|
||||
configs.SecurityTestStatus = false
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
parseFlags()
|
||||
if handleHelpAndVersion() {
|
||||
configs.ParseFlags(os.Args[1:])
|
||||
if configs.HandleHelpAndVersion("goecs") {
|
||||
return
|
||||
}
|
||||
initLogger()
|
||||
@@ -877,14 +71,14 @@ func main() {
|
||||
http.Get("https://hits.spiritlhl.net/goecs.svg?action=hit&title=Hits&title_bg=%23555555&count_bg=%230eecf8&edge_flat=false")
|
||||
}
|
||||
}()
|
||||
if menuMode {
|
||||
handleMenuMode(preCheck)
|
||||
if configs.MenuMode {
|
||||
menu.HandleMenuMode(preCheck, configs)
|
||||
} else {
|
||||
onlyIpInfoCheckStatus = true
|
||||
configs.OnlyIpInfoCheck = true
|
||||
}
|
||||
handleLanguageSpecificSettings()
|
||||
if !preCheck.Connected {
|
||||
enabelUpload = false
|
||||
configs.EnableUpload = false
|
||||
}
|
||||
var (
|
||||
wg1, wg2, wg3 sync.WaitGroup
|
||||
@@ -896,19 +90,19 @@ func main() {
|
||||
uploadDone := make(chan bool, 1)
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
go handleSignalInterrupt(sig, &startTime, &output, tempOutput, uploadDone, &outputMutex)
|
||||
switch language {
|
||||
go runner.HandleSignalInterrupt(sig, configs, &startTime, &output, tempOutput, uploadDone, &outputMutex)
|
||||
switch configs.Language {
|
||||
case "zh":
|
||||
runChineseTests(preCheck, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, &output, tempOutput, startTime, &outputMutex)
|
||||
runner.RunChineseTests(preCheck, configs, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, &output, tempOutput, startTime, &outputMutex)
|
||||
case "en":
|
||||
runEnglishTests(preCheck, &wg1, &wg2, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &output, tempOutput, startTime, &outputMutex)
|
||||
runner.RunEnglishTests(preCheck, configs, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, &output, tempOutput, startTime, &outputMutex)
|
||||
default:
|
||||
fmt.Println("Unsupported language")
|
||||
}
|
||||
if preCheck.Connected {
|
||||
handleUploadResults(output)
|
||||
runner.HandleUploadResults(configs, output)
|
||||
}
|
||||
finish = true
|
||||
configs.Finish = true
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
|
||||
6
goecs.sh
6
goecs.sh
@@ -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.91"
|
||||
ECS_VERSION="0.1.98"
|
||||
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.91"
|
||||
ECS_VERSION="0.1.91"
|
||||
_yellow "Unable to get version info, using default version 0.1.98"
|
||||
ECS_VERSION="0.1.98"
|
||||
fi
|
||||
version_output=""
|
||||
for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do
|
||||
|
||||
365
internal/menu/menu.go
Normal file
365
internal/menu/menu.go
Normal file
@@ -0,0 +1,365 @@
|
||||
package menu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/oneclickvirt/ecs/internal/params"
|
||||
"github.com/oneclickvirt/ecs/utils"
|
||||
)
|
||||
|
||||
// GetMenuChoice prompts user for menu choice
|
||||
func GetMenuChoice(language string) string {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer signal.Stop(sigChan)
|
||||
inputChan := make(chan string, 1)
|
||||
go func() {
|
||||
select {
|
||||
case <-sigChan:
|
||||
fmt.Println("\n程序在选择过程中被用户中断")
|
||||
os.Exit(0)
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}()
|
||||
for {
|
||||
go func() {
|
||||
var input string
|
||||
fmt.Print("请输入选项 / Please enter your choice: ")
|
||||
fmt.Scanln(&input)
|
||||
input = strings.TrimSpace(input)
|
||||
input = strings.TrimRight(input, "\n")
|
||||
select {
|
||||
case inputChan <- input:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case input := <-inputChan:
|
||||
re := regexp.MustCompile(`^\d+$`)
|
||||
if re.MatchString(input) {
|
||||
inChoice := input
|
||||
switch inChoice {
|
||||
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10":
|
||||
return inChoice
|
||||
default:
|
||||
if language == "zh" {
|
||||
fmt.Println("无效的选项")
|
||||
} else {
|
||||
fmt.Println("Invalid choice")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if language == "zh" {
|
||||
fmt.Println("输入错误,请输入一个纯数字")
|
||||
} else {
|
||||
fmt.Println("Invalid input, please enter a number")
|
||||
}
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PrintMenuOptions displays menu options
|
||||
func PrintMenuOptions(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
var stats *utils.StatsResponse
|
||||
var statsErr error
|
||||
var githubInfo *utils.GitHubRelease
|
||||
var githubErr error
|
||||
if preCheck.Connected {
|
||||
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()
|
||||
} else {
|
||||
statsErr = fmt.Errorf("network not connected")
|
||||
githubErr = fmt.Errorf("network not connected")
|
||||
}
|
||||
var statsInfo string
|
||||
var cmp int
|
||||
if preCheck.Connected {
|
||||
if statsErr != nil {
|
||||
statsInfo = "NULL"
|
||||
} else {
|
||||
switch config.Language {
|
||||
case "zh":
|
||||
statsInfo = fmt.Sprintf("总使用量: %s | 今日使用: %s",
|
||||
utils.FormatGoecsNumber(stats.Total),
|
||||
utils.FormatGoecsNumber(stats.Daily))
|
||||
case "en":
|
||||
statsInfo = fmt.Sprintf("Total Usage: %s | Daily Usage: %s",
|
||||
utils.FormatGoecsNumber(stats.Total),
|
||||
utils.FormatGoecsNumber(stats.Daily))
|
||||
}
|
||||
}
|
||||
if githubErr == nil {
|
||||
cmp = utils.CompareVersions(config.EcsVersion, githubInfo.TagName)
|
||||
} else {
|
||||
cmp = 0
|
||||
}
|
||||
}
|
||||
switch config.Language {
|
||||
case "zh":
|
||||
fmt.Printf("VPS融合怪版本: %s\n", config.EcsVersion)
|
||||
if preCheck.Connected {
|
||||
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质量检测+上游及三网回程+广州三网回程详细路由+全国延迟+TGDC+网站延迟+测速节点11个)")
|
||||
fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)")
|
||||
fmt.Println("8. 硬件单项(系统信息+CPU+dd磁盘测试+fio磁盘测试)")
|
||||
fmt.Println("9. IP质量检测(15个数据库的IP质量检测+邮件端口检测)")
|
||||
fmt.Println("10. 三网回程线路检测+三网回程详细路由(北京上海广州成都)+全国延迟+TGDC+网站延迟")
|
||||
fmt.Println("0. 退出程序")
|
||||
case "en":
|
||||
fmt.Printf("VPS Fusion Monster Test Version: %s\n", config.EcsVersion)
|
||||
if preCheck.Connected {
|
||||
switch cmp {
|
||||
case -1:
|
||||
fmt.Printf("New version detected %s update if necessary!\n", githubInfo.TagName)
|
||||
}
|
||||
fmt.Printf("%s\n", statsInfo)
|
||||
}
|
||||
fmt.Println("1. VPS Fusion Monster Test (Full Test)")
|
||||
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)")
|
||||
fmt.Println("4. Network-Focused Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)")
|
||||
fmt.Println("5. Unlock-Focused Test Suite (System Info + CPU + Memory + Disk IO + Basic Unlock Tests + Common Streaming Services + 5 Speed Test Nodes)")
|
||||
fmt.Println("6. Network-Only Test (IP Quality Test + TGDC + Websites + 11 Speed Test Nodes)")
|
||||
fmt.Println("7. Unlock-Only Test (Basic Unlock Tests + Common Streaming Services Unlock)")
|
||||
fmt.Println("8. Hardware-Only Test (System Info + CPU + Memory + dd Disk Test + fio Disk Test)")
|
||||
fmt.Println("9. IP Quality Test (IP Test with 15 Databases + Email Port Test)")
|
||||
fmt.Println("0. Exit Program")
|
||||
}
|
||||
}
|
||||
|
||||
// HandleMenuMode handles menu selection
|
||||
func HandleMenuMode(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
savedParams := config.SaveUserSetParams()
|
||||
config.BasicStatus = false
|
||||
config.CpuTestStatus = false
|
||||
config.MemoryTestStatus = false
|
||||
config.DiskTestStatus = false
|
||||
config.CommTestStatus = false
|
||||
config.UtTestStatus = false
|
||||
config.SecurityTestStatus = false
|
||||
config.EmailTestStatus = false
|
||||
config.BacktraceStatus = false
|
||||
config.Nt3Status = false
|
||||
config.SpeedTestStatus = false
|
||||
config.TgdcTestStatus = false
|
||||
config.WebTestStatus = false
|
||||
config.AutoChangeDiskMethod = true
|
||||
PrintMenuOptions(preCheck, config)
|
||||
Loop:
|
||||
for {
|
||||
config.Choice = GetMenuChoice(config.Language)
|
||||
switch config.Choice {
|
||||
case "0":
|
||||
os.Exit(0)
|
||||
case "1":
|
||||
SetFullTestStatus(preCheck, config)
|
||||
config.OnlyChinaTest = utils.CheckChina(config.EnableLogger)
|
||||
break Loop
|
||||
case "2":
|
||||
SetMinimalTestStatus(preCheck, config)
|
||||
break Loop
|
||||
case "3":
|
||||
SetStandardTestStatus(preCheck, config)
|
||||
break Loop
|
||||
case "4":
|
||||
SetNetworkFocusedTestStatus(preCheck, config)
|
||||
break Loop
|
||||
case "5":
|
||||
SetUnlockFocusedTestStatus(preCheck, config)
|
||||
break Loop
|
||||
case "6":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
SetNetworkOnlyTestStatus(config)
|
||||
break Loop
|
||||
case "7":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
SetUnlockOnlyTestStatus(config)
|
||||
break Loop
|
||||
case "8":
|
||||
SetHardwareOnlyTestStatus(preCheck, config)
|
||||
break Loop
|
||||
case "9":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
SetIPQualityTestStatus(config)
|
||||
break Loop
|
||||
case "10":
|
||||
if !preCheck.Connected {
|
||||
fmt.Println("Can not test without network connection!")
|
||||
return
|
||||
}
|
||||
config.Nt3Location = "ALL"
|
||||
SetRouteTestStatus(config)
|
||||
break Loop
|
||||
default:
|
||||
PrintInvalidChoice(config.Language)
|
||||
}
|
||||
}
|
||||
config.RestoreUserSetParams(savedParams)
|
||||
}
|
||||
|
||||
// SetFullTestStatus enables all tests
|
||||
func SetFullTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
config.BasicStatus = true
|
||||
config.CpuTestStatus = true
|
||||
config.MemoryTestStatus = true
|
||||
config.DiskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
config.CommTestStatus = true
|
||||
config.UtTestStatus = true
|
||||
config.SecurityTestStatus = true
|
||||
config.EmailTestStatus = true
|
||||
config.BacktraceStatus = true
|
||||
config.Nt3Status = true
|
||||
config.SpeedTestStatus = true
|
||||
config.TgdcTestStatus = true
|
||||
config.WebTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// SetMinimalTestStatus sets minimal test configuration
|
||||
func SetMinimalTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
config.BasicStatus = true
|
||||
config.CpuTestStatus = true
|
||||
config.MemoryTestStatus = true
|
||||
config.DiskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
config.SpeedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// SetStandardTestStatus sets standard test configuration
|
||||
func SetStandardTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
config.BasicStatus = true
|
||||
config.CpuTestStatus = true
|
||||
config.MemoryTestStatus = true
|
||||
config.DiskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
config.UtTestStatus = true
|
||||
config.Nt3Status = true
|
||||
config.SpeedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// SetNetworkFocusedTestStatus sets network-focused test configuration
|
||||
func SetNetworkFocusedTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
config.BasicStatus = true
|
||||
config.CpuTestStatus = true
|
||||
config.MemoryTestStatus = true
|
||||
config.DiskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
config.BacktraceStatus = true
|
||||
config.Nt3Status = true
|
||||
config.SpeedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// SetUnlockFocusedTestStatus sets unlock-focused test configuration
|
||||
func SetUnlockFocusedTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
config.BasicStatus = true
|
||||
config.CpuTestStatus = true
|
||||
config.MemoryTestStatus = true
|
||||
config.DiskTestStatus = true
|
||||
if preCheck.Connected {
|
||||
config.CommTestStatus = true
|
||||
config.UtTestStatus = true
|
||||
config.SpeedTestStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// SetNetworkOnlyTestStatus sets network-only test configuration
|
||||
func SetNetworkOnlyTestStatus(config *params.Config) {
|
||||
config.OnlyIpInfoCheck = true
|
||||
config.SecurityTestStatus = true
|
||||
config.SpeedTestStatus = true
|
||||
config.BacktraceStatus = true
|
||||
config.Nt3Status = true
|
||||
config.PingTestStatus = true
|
||||
config.TgdcTestStatus = true
|
||||
config.WebTestStatus = true
|
||||
}
|
||||
|
||||
// SetUnlockOnlyTestStatus sets unlock-only test configuration
|
||||
func SetUnlockOnlyTestStatus(config *params.Config) {
|
||||
config.OnlyIpInfoCheck = true
|
||||
config.CommTestStatus = true
|
||||
config.UtTestStatus = true
|
||||
}
|
||||
|
||||
// SetHardwareOnlyTestStatus sets hardware-only test configuration
|
||||
func SetHardwareOnlyTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
|
||||
_ = preCheck
|
||||
config.BasicStatus = true
|
||||
config.CpuTestStatus = true
|
||||
config.MemoryTestStatus = true
|
||||
config.DiskTestStatus = true
|
||||
config.SecurityTestStatus = false
|
||||
config.AutoChangeDiskMethod = false
|
||||
}
|
||||
|
||||
// SetIPQualityTestStatus sets IP quality test configuration
|
||||
func SetIPQualityTestStatus(config *params.Config) {
|
||||
config.OnlyIpInfoCheck = true
|
||||
config.SecurityTestStatus = true
|
||||
config.EmailTestStatus = true
|
||||
}
|
||||
|
||||
// SetRouteTestStatus sets route test configuration
|
||||
func SetRouteTestStatus(config *params.Config) {
|
||||
config.OnlyIpInfoCheck = true
|
||||
config.BacktraceStatus = true
|
||||
config.Nt3Status = true
|
||||
config.PingTestStatus = true
|
||||
config.TgdcTestStatus = true
|
||||
config.WebTestStatus = true
|
||||
}
|
||||
|
||||
// PrintInvalidChoice prints invalid choice message
|
||||
func PrintInvalidChoice(language string) {
|
||||
if language == "zh" {
|
||||
fmt.Println("无效的选项")
|
||||
} else {
|
||||
fmt.Println("Invalid choice")
|
||||
}
|
||||
}
|
||||
369
internal/params/params.go
Normal file
369
internal/params/params.go
Normal file
@@ -0,0 +1,369 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Config holds all configuration parameters
|
||||
type Config struct {
|
||||
EcsVersion string
|
||||
MenuMode bool
|
||||
OnlyChinaTest bool
|
||||
Input string
|
||||
Choice string
|
||||
ShowVersion bool
|
||||
EnableLogger bool
|
||||
Language string
|
||||
CpuTestMethod string
|
||||
CpuTestThreadMode string
|
||||
MemoryTestMethod string
|
||||
DiskTestMethod string
|
||||
DiskTestPath string
|
||||
DiskMultiCheck bool
|
||||
Nt3CheckType string
|
||||
Nt3Location string
|
||||
SpNum int
|
||||
Width int
|
||||
BasicStatus bool
|
||||
CpuTestStatus bool
|
||||
MemoryTestStatus bool
|
||||
DiskTestStatus bool
|
||||
CommTestStatus bool
|
||||
UtTestStatus bool
|
||||
SecurityTestStatus bool
|
||||
EmailTestStatus bool
|
||||
BacktraceStatus bool
|
||||
Nt3Status bool
|
||||
SpeedTestStatus bool
|
||||
PingTestStatus bool
|
||||
TgdcTestStatus bool
|
||||
WebTestStatus bool
|
||||
AutoChangeDiskMethod bool
|
||||
FilePath string
|
||||
EnableUpload bool
|
||||
OnlyIpInfoCheck bool
|
||||
Help bool
|
||||
Finish bool
|
||||
UserSetFlags map[string]bool
|
||||
GoecsFlag *flag.FlagSet
|
||||
}
|
||||
|
||||
// NewConfig creates a new Config with default values
|
||||
func NewConfig(version string) *Config {
|
||||
return &Config{
|
||||
EcsVersion: version,
|
||||
MenuMode: true,
|
||||
Language: "zh",
|
||||
CpuTestMethod: "sysbench",
|
||||
CpuTestThreadMode: "multi",
|
||||
MemoryTestMethod: "stream",
|
||||
DiskTestMethod: "fio",
|
||||
SpNum: 2,
|
||||
Width: 82,
|
||||
BasicStatus: true,
|
||||
CpuTestStatus: true,
|
||||
MemoryTestStatus: true,
|
||||
DiskTestStatus: true,
|
||||
CommTestStatus: true,
|
||||
UtTestStatus: true,
|
||||
SecurityTestStatus: true,
|
||||
EmailTestStatus: true,
|
||||
BacktraceStatus: true,
|
||||
Nt3Status: true,
|
||||
SpeedTestStatus: true,
|
||||
Nt3Location: "GZ",
|
||||
Nt3CheckType: "ipv4",
|
||||
AutoChangeDiskMethod: true,
|
||||
FilePath: "goecs.txt",
|
||||
EnableUpload: true,
|
||||
UserSetFlags: make(map[string]bool),
|
||||
GoecsFlag: flag.NewFlagSet("goecs", flag.ContinueOnError),
|
||||
}
|
||||
}
|
||||
|
||||
// ParseFlags parses command line flags
|
||||
func (c *Config) ParseFlags(args []string) {
|
||||
c.GoecsFlag.BoolVar(&c.Help, "h", false, "Show help information")
|
||||
c.GoecsFlag.BoolVar(&c.Help, "help", false, "Show help information")
|
||||
c.GoecsFlag.BoolVar(&c.ShowVersion, "v", false, "Display version information")
|
||||
c.GoecsFlag.BoolVar(&c.ShowVersion, "version", false, "Display version information")
|
||||
c.GoecsFlag.BoolVar(&c.MenuMode, "menu", true, "Enable/Disable menu mode, disable example: -menu=false")
|
||||
c.GoecsFlag.StringVar(&c.Language, "l", "zh", "Set language (supported: en, zh)")
|
||||
c.GoecsFlag.BoolVar(&c.BasicStatus, "basic", true, "Enable/Disable basic test")
|
||||
c.GoecsFlag.BoolVar(&c.CpuTestStatus, "cpu", true, "Enable/Disable CPU test")
|
||||
c.GoecsFlag.BoolVar(&c.MemoryTestStatus, "memory", true, "Enable/Disable memory test")
|
||||
c.GoecsFlag.BoolVar(&c.DiskTestStatus, "disk", true, "Enable/Disable disk test")
|
||||
c.GoecsFlag.BoolVar(&c.CommTestStatus, "comm", true, "Enable/Disable common media test")
|
||||
c.GoecsFlag.BoolVar(&c.UtTestStatus, "ut", true, "Enable/Disable unlock media test")
|
||||
c.GoecsFlag.BoolVar(&c.SecurityTestStatus, "security", true, "Enable/Disable security test")
|
||||
c.GoecsFlag.BoolVar(&c.EmailTestStatus, "email", true, "Enable/Disable email port test")
|
||||
c.GoecsFlag.BoolVar(&c.BacktraceStatus, "backtrace", true, "Enable/Disable backtrace test (in 'en' language or on windows it always false)")
|
||||
c.GoecsFlag.BoolVar(&c.Nt3Status, "nt3", true, "Enable/Disable NT3 test (in 'en' language or on windows it always false)")
|
||||
c.GoecsFlag.BoolVar(&c.SpeedTestStatus, "speed", true, "Enable/Disable speed test")
|
||||
c.GoecsFlag.BoolVar(&c.PingTestStatus, "ping", false, "Enable/Disable ping test")
|
||||
c.GoecsFlag.BoolVar(&c.TgdcTestStatus, "tgdc", false, "Enable/Disable Telegram DC test")
|
||||
c.GoecsFlag.BoolVar(&c.WebTestStatus, "web", false, "Enable/Disable popular websites test")
|
||||
c.GoecsFlag.StringVar(&c.CpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)")
|
||||
c.GoecsFlag.StringVar(&c.CpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)")
|
||||
c.GoecsFlag.StringVar(&c.MemoryTestMethod, "memorym", "stream", "Set memory test method (supported: stream, sysbench, dd, winsat, auto)")
|
||||
c.GoecsFlag.StringVar(&c.DiskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)")
|
||||
c.GoecsFlag.StringVar(&c.DiskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root")
|
||||
c.GoecsFlag.BoolVar(&c.DiskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false")
|
||||
c.GoecsFlag.StringVar(&c.Nt3Location, "nt3loc", "GZ", "Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all)")
|
||||
c.GoecsFlag.StringVar(&c.Nt3CheckType, "nt3t", "ipv4", "Set NT3 test type (supported: both, ipv4, ipv6)")
|
||||
c.GoecsFlag.IntVar(&c.SpNum, "spnum", 2, "Set the number of servers per operator for speed test")
|
||||
c.GoecsFlag.BoolVar(&c.EnableLogger, "log", false, "Enable/Disable logging in the current path")
|
||||
c.GoecsFlag.BoolVar(&c.EnableUpload, "upload", true, "Enable/Disable upload the result")
|
||||
c.GoecsFlag.Parse(args)
|
||||
|
||||
c.GoecsFlag.Visit(func(f *flag.Flag) {
|
||||
c.UserSetFlags[f.Name] = true
|
||||
})
|
||||
}
|
||||
|
||||
// HandleHelpAndVersion handles help and version flags
|
||||
func (c *Config) HandleHelpAndVersion(programName string) bool {
|
||||
if c.Help {
|
||||
fmt.Printf("Usage: %s [options]\n", programName)
|
||||
c.GoecsFlag.PrintDefaults()
|
||||
return true
|
||||
}
|
||||
if c.ShowVersion {
|
||||
fmt.Println(c.EcsVersion)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SaveUserSetParams saves user-set parameters
|
||||
func (c *Config) SaveUserSetParams() map[string]interface{} {
|
||||
saved := make(map[string]interface{})
|
||||
|
||||
if c.UserSetFlags["basic"] {
|
||||
saved["basic"] = c.BasicStatus
|
||||
}
|
||||
if c.UserSetFlags["cpu"] {
|
||||
saved["cpu"] = c.CpuTestStatus
|
||||
}
|
||||
if c.UserSetFlags["memory"] {
|
||||
saved["memory"] = c.MemoryTestStatus
|
||||
}
|
||||
if c.UserSetFlags["disk"] {
|
||||
saved["disk"] = c.DiskTestStatus
|
||||
}
|
||||
if c.UserSetFlags["comm"] {
|
||||
saved["comm"] = c.CommTestStatus
|
||||
}
|
||||
if c.UserSetFlags["ut"] {
|
||||
saved["ut"] = c.UtTestStatus
|
||||
}
|
||||
if c.UserSetFlags["security"] {
|
||||
saved["security"] = c.SecurityTestStatus
|
||||
}
|
||||
if c.UserSetFlags["email"] {
|
||||
saved["email"] = c.EmailTestStatus
|
||||
}
|
||||
if c.UserSetFlags["backtrace"] {
|
||||
saved["backtrace"] = c.BacktraceStatus
|
||||
}
|
||||
if c.UserSetFlags["nt3"] {
|
||||
saved["nt3"] = c.Nt3Status
|
||||
}
|
||||
if c.UserSetFlags["speed"] {
|
||||
saved["speed"] = c.SpeedTestStatus
|
||||
}
|
||||
if c.UserSetFlags["ping"] {
|
||||
saved["ping"] = c.PingTestStatus
|
||||
}
|
||||
if c.UserSetFlags["tgdc"] {
|
||||
saved["tgdc"] = c.TgdcTestStatus
|
||||
}
|
||||
if c.UserSetFlags["web"] {
|
||||
saved["web"] = c.WebTestStatus
|
||||
}
|
||||
if c.UserSetFlags["cpum"] {
|
||||
saved["cpum"] = c.CpuTestMethod
|
||||
}
|
||||
if c.UserSetFlags["cput"] {
|
||||
saved["cput"] = c.CpuTestThreadMode
|
||||
}
|
||||
if c.UserSetFlags["memorym"] {
|
||||
saved["memorym"] = c.MemoryTestMethod
|
||||
}
|
||||
if c.UserSetFlags["diskm"] {
|
||||
saved["diskm"] = c.DiskTestMethod
|
||||
}
|
||||
if c.UserSetFlags["diskp"] {
|
||||
saved["diskp"] = c.DiskTestPath
|
||||
}
|
||||
if c.UserSetFlags["diskmc"] {
|
||||
saved["diskmc"] = c.DiskMultiCheck
|
||||
}
|
||||
if c.UserSetFlags["nt3loc"] {
|
||||
saved["nt3loc"] = c.Nt3Location
|
||||
}
|
||||
if c.UserSetFlags["nt3t"] {
|
||||
saved["nt3t"] = c.Nt3CheckType
|
||||
}
|
||||
if c.UserSetFlags["spnum"] {
|
||||
saved["spnum"] = c.SpNum
|
||||
}
|
||||
|
||||
return saved
|
||||
}
|
||||
|
||||
// RestoreUserSetParams restores user-set parameters
|
||||
func (c *Config) RestoreUserSetParams(saved map[string]interface{}) {
|
||||
if val, ok := saved["basic"]; ok {
|
||||
c.BasicStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["cpu"]; ok {
|
||||
c.CpuTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["memory"]; ok {
|
||||
c.MemoryTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["disk"]; ok {
|
||||
c.DiskTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["comm"]; ok {
|
||||
c.CommTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["ut"]; ok {
|
||||
c.UtTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["security"]; ok {
|
||||
c.SecurityTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["email"]; ok {
|
||||
c.EmailTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["backtrace"]; ok {
|
||||
c.BacktraceStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["nt3"]; ok {
|
||||
c.Nt3Status = val.(bool)
|
||||
}
|
||||
if val, ok := saved["speed"]; ok {
|
||||
c.SpeedTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["ping"]; ok {
|
||||
c.PingTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["tgdc"]; ok {
|
||||
c.TgdcTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["web"]; ok {
|
||||
c.WebTestStatus = val.(bool)
|
||||
}
|
||||
if val, ok := saved["cpum"]; ok {
|
||||
c.CpuTestMethod = val.(string)
|
||||
}
|
||||
if val, ok := saved["cput"]; ok {
|
||||
c.CpuTestThreadMode = val.(string)
|
||||
}
|
||||
if val, ok := saved["memorym"]; ok {
|
||||
c.MemoryTestMethod = val.(string)
|
||||
}
|
||||
if val, ok := saved["diskm"]; ok {
|
||||
c.DiskTestMethod = val.(string)
|
||||
}
|
||||
if val, ok := saved["diskp"]; ok {
|
||||
c.DiskTestPath = val.(string)
|
||||
}
|
||||
if val, ok := saved["diskmc"]; ok {
|
||||
c.DiskMultiCheck = val.(bool)
|
||||
}
|
||||
if val, ok := saved["nt3loc"]; ok {
|
||||
if c.Choice != "10" {
|
||||
c.Nt3Location = val.(string)
|
||||
}
|
||||
}
|
||||
if val, ok := saved["nt3t"]; ok {
|
||||
c.Nt3CheckType = val.(string)
|
||||
}
|
||||
if val, ok := saved["spnum"]; ok {
|
||||
c.SpNum = val.(int)
|
||||
}
|
||||
|
||||
c.ValidateParams()
|
||||
}
|
||||
|
||||
// ValidateParams validates parameter values
|
||||
func (c *Config) ValidateParams() {
|
||||
validCpuMethods := map[string]bool{"sysbench": true, "geekbench": true, "winsat": true}
|
||||
if !validCpuMethods[c.CpuTestMethod] {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: CPU测试方法 '%s' 无效,使用默认值 'sysbench'\n", c.CpuTestMethod)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid CPU test method '%s', using default 'sysbench'\n", c.CpuTestMethod)
|
||||
}
|
||||
c.CpuTestMethod = "sysbench"
|
||||
}
|
||||
|
||||
validThreadModes := map[string]bool{"single": true, "multi": true}
|
||||
if !validThreadModes[c.CpuTestThreadMode] {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: CPU线程模式 '%s' 无效,使用默认值 'multi'\n", c.CpuTestThreadMode)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid CPU thread mode '%s', using default 'multi'\n", c.CpuTestThreadMode)
|
||||
}
|
||||
c.CpuTestThreadMode = "multi"
|
||||
}
|
||||
|
||||
validMemoryMethods := map[string]bool{"stream": true, "sysbench": true, "dd": true, "winsat": true, "auto": true}
|
||||
if !validMemoryMethods[c.MemoryTestMethod] {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: 内存测试方法 '%s' 无效,使用默认值 'stream'\n", c.MemoryTestMethod)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid memory test method '%s', using default 'stream'\n", c.MemoryTestMethod)
|
||||
}
|
||||
c.MemoryTestMethod = "stream"
|
||||
}
|
||||
|
||||
validDiskMethods := map[string]bool{"fio": true, "dd": true, "winsat": true}
|
||||
if !validDiskMethods[c.DiskTestMethod] {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: 磁盘测试方法 '%s' 无效,使用默认值 'fio'\n", c.DiskTestMethod)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid disk test method '%s', using default 'fio'\n", c.DiskTestMethod)
|
||||
}
|
||||
c.DiskTestMethod = "fio"
|
||||
}
|
||||
|
||||
validNt3Locations := map[string]bool{"GZ": true, "SH": true, "BJ": true, "CD": true, "ALL": true}
|
||||
if !validNt3Locations[c.Nt3Location] {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: NT3测试位置 '%s' 无效,使用默认值 'GZ'\n", c.Nt3Location)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid NT3 location '%s', using default 'GZ'\n", c.Nt3Location)
|
||||
}
|
||||
c.Nt3Location = "GZ"
|
||||
}
|
||||
|
||||
validNt3Types := map[string]bool{"both": true, "ipv4": true, "ipv6": true}
|
||||
if !validNt3Types[c.Nt3CheckType] {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: NT3测试类型 '%s' 无效,使用默认值 'ipv4'\n", c.Nt3CheckType)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid NT3 check type '%s', using default 'ipv4'\n", c.Nt3CheckType)
|
||||
}
|
||||
c.Nt3CheckType = "ipv4"
|
||||
}
|
||||
|
||||
if c.SpNum < 0 {
|
||||
if c.Language == "zh" {
|
||||
fmt.Printf("警告: 测速节点数量 '%d' 无效,使用默认值 2\n", c.SpNum)
|
||||
} else {
|
||||
fmt.Printf("Warning: Invalid speed test node count '%d', using default 2\n", c.SpNum)
|
||||
}
|
||||
c.SpNum = 2
|
||||
}
|
||||
|
||||
validLanguages := map[string]bool{"zh": true, "en": true}
|
||||
if !validLanguages[c.Language] {
|
||||
fmt.Printf("Warning: Invalid language '%s', using default 'zh'\n", c.Language)
|
||||
c.Language = "zh"
|
||||
}
|
||||
}
|
||||
483
internal/runner/runner.go
Normal file
483
internal/runner/runner.go
Normal file
@@ -0,0 +1,483 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/oneclickvirt/CommonMediaTests/commediatests"
|
||||
"github.com/oneclickvirt/ecs/internal/params"
|
||||
"github.com/oneclickvirt/ecs/internal/tests"
|
||||
"github.com/oneclickvirt/ecs/utils"
|
||||
"github.com/oneclickvirt/pingtest/pt"
|
||||
"github.com/oneclickvirt/portchecker/email"
|
||||
)
|
||||
|
||||
// RunChineseTests runs all tests in Chinese mode
|
||||
func RunChineseTests(preCheck utils.NetCheckResult, config *params.Config, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
|
||||
*output = RunBasicTests(preCheck, config, basicInfo, securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunCPUTest(config, *output, tempOutput, outputMutex)
|
||||
*output = RunMemoryTest(config, *output, tempOutput, outputMutex)
|
||||
*output = RunDiskTest(config, *output, tempOutput, outputMutex)
|
||||
if config.OnlyIpInfoCheck && !config.BasicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = RunIpInfoCheck(config, *output, tempOutput, outputMutex)
|
||||
}
|
||||
if config.UtTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !config.OnlyChinaTest {
|
||||
wg1.Add(1)
|
||||
go func() {
|
||||
defer wg1.Done()
|
||||
*mediaInfo = tests.MediaTest(config.Language)
|
||||
}()
|
||||
}
|
||||
if config.EmailTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
wg2.Add(1)
|
||||
go func() {
|
||||
defer wg2.Done()
|
||||
*emailInfo = email.EmailCheck()
|
||||
}()
|
||||
}
|
||||
if (config.OnlyChinaTest || config.PingTestStatus) && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
wg3.Add(1)
|
||||
go func() {
|
||||
defer wg3.Done()
|
||||
*ptInfo = pt.PingTest()
|
||||
}()
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = RunStreamingTests(config, wg1, mediaInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunSecurityTests(config, *securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunEmailTests(config, wg2, emailInfo, *output, tempOutput, outputMutex)
|
||||
}
|
||||
if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = RunNetworkTests(config, wg3, ptInfo, *output, tempOutput, outputMutex)
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = RunSpeedTests(config, *output, tempOutput, outputMutex)
|
||||
}
|
||||
*output = AppendTimeInfo(config, *output, tempOutput, startTime, outputMutex)
|
||||
}
|
||||
|
||||
// RunEnglishTests runs all tests in English mode
|
||||
func RunEnglishTests(preCheck utils.NetCheckResult, config *params.Config, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
|
||||
*output = RunBasicTests(preCheck, config, basicInfo, securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunCPUTest(config, *output, tempOutput, outputMutex)
|
||||
*output = RunMemoryTest(config, *output, tempOutput, outputMutex)
|
||||
*output = RunDiskTest(config, *output, tempOutput, outputMutex)
|
||||
if config.OnlyIpInfoCheck && !config.BasicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
*output = RunIpInfoCheck(config, *output, tempOutput, outputMutex)
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
||||
if config.UtTestStatus {
|
||||
wg1.Add(1)
|
||||
go func() {
|
||||
defer wg1.Done()
|
||||
*mediaInfo = tests.MediaTest(config.Language)
|
||||
}()
|
||||
}
|
||||
if config.EmailTestStatus {
|
||||
wg2.Add(1)
|
||||
go func() {
|
||||
defer wg2.Done()
|
||||
*emailInfo = email.EmailCheck()
|
||||
}()
|
||||
}
|
||||
*output = RunStreamingTests(config, wg1, mediaInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunSecurityTests(config, *securityInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunEmailTests(config, wg2, emailInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunEnglishNetworkTests(config, wg3, ptInfo, *output, tempOutput, outputMutex)
|
||||
*output = RunEnglishSpeedTests(config, *output, tempOutput, outputMutex)
|
||||
}
|
||||
*output = AppendTimeInfo(config, *output, tempOutput, startTime, outputMutex)
|
||||
}
|
||||
|
||||
// RunIpInfoCheck performs IP info check
|
||||
func RunIpInfoCheck(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
var ipinfo string
|
||||
tests.IPV4, tests.IPV6, ipinfo = utils.OnlyBasicsIpInfo(config.Language)
|
||||
if ipinfo != "" {
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle("IP信息", config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("IP-Information", config.Width)
|
||||
}
|
||||
fmt.Printf("%s", ipinfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunBasicTests runs basic system tests
|
||||
func RunBasicTests(preCheck utils.NetCheckResult, config *params.Config, basicInfo, securityInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
utils.PrintHead(config.Language, config.Width, config.EcsVersion)
|
||||
if config.BasicStatus || config.SecurityTestStatus {
|
||||
if config.BasicStatus {
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle("系统基础信息", config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("System-Basic-Information", config.Width)
|
||||
}
|
||||
}
|
||||
if preCheck.Connected && preCheck.StackType == "DualStack" {
|
||||
tests.IPV4, tests.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, config.Nt3CheckType, config.SecurityTestStatus)
|
||||
} else if preCheck.Connected && preCheck.StackType == "IPv4" {
|
||||
tests.IPV4, tests.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, "ipv4", config.SecurityTestStatus)
|
||||
} else if preCheck.Connected && preCheck.StackType == "IPv6" {
|
||||
tests.IPV4, tests.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, "ipv6", config.SecurityTestStatus)
|
||||
} else {
|
||||
tests.IPV4, tests.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, "", false)
|
||||
config.SecurityTestStatus = false
|
||||
}
|
||||
if config.BasicStatus {
|
||||
fmt.Printf("%s", *basicInfo)
|
||||
} else if (config.Input == "6" || config.Input == "9") && config.SecurityTestStatus {
|
||||
scanner := bufio.NewScanner(strings.NewReader(*basicInfo))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.Contains(line, "IPV") {
|
||||
fmt.Println(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunCPUTest runs CPU test
|
||||
func RunCPUTest(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.CpuTestStatus {
|
||||
realTestMethod, res := tests.CpuTest(config.Language, config.CpuTestMethod, config.CpuTestThreadMode)
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", realTestMethod), config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("CPU-Test--%s-Method", realTestMethod), config.Width)
|
||||
}
|
||||
fmt.Print(res)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunMemoryTest runs memory test
|
||||
func RunMemoryTest(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.MemoryTestStatus {
|
||||
realTestMethod, res := tests.MemoryTest(config.Language, config.MemoryTestMethod)
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", realTestMethod), config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Memory-Test--%s-Method", realTestMethod), config.Width)
|
||||
}
|
||||
fmt.Print(res)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunDiskTest runs disk test
|
||||
func RunDiskTest(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.DiskTestStatus && config.AutoChangeDiskMethod {
|
||||
realTestMethod, res := tests.DiskTest(config.Language, config.DiskTestMethod, config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", realTestMethod), config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", realTestMethod), config.Width)
|
||||
}
|
||||
fmt.Print(res)
|
||||
} else if config.DiskTestStatus && !config.AutoChangeDiskMethod {
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "dd"), config.Width)
|
||||
_, res := tests.DiskTest(config.Language, "dd", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
|
||||
fmt.Print(res)
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "fio"), config.Width)
|
||||
_, res = tests.DiskTest(config.Language, "fio", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
|
||||
fmt.Print(res)
|
||||
} else {
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "dd"), config.Width)
|
||||
_, res := tests.DiskTest(config.Language, "dd", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
|
||||
fmt.Print(res)
|
||||
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "fio"), config.Width)
|
||||
_, res = tests.DiskTest(config.Language, "fio", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
|
||||
fmt.Print(res)
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunStreamingTests runs streaming media tests
|
||||
func RunStreamingTests(config *params.Config, wg1 *sync.WaitGroup, mediaInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.Language == "zh" {
|
||||
if config.CommTestStatus && !config.OnlyChinaTest {
|
||||
utils.PrintCenteredTitle("御三家流媒体解锁", config.Width)
|
||||
fmt.Printf("%s", commediatests.MediaTests(config.Language))
|
||||
}
|
||||
}
|
||||
if config.UtTestStatus && (config.Language == "zh" && !config.OnlyChinaTest || config.Language == "en") {
|
||||
wg1.Wait()
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle("跨国流媒体解锁", config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", config.Width)
|
||||
}
|
||||
fmt.Printf("%s", *mediaInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunSecurityTests runs security tests
|
||||
func RunSecurityTests(config *params.Config, securityInfo, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.SecurityTestStatus {
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle("IP质量检测", config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("IP-Quality-Check", config.Width)
|
||||
}
|
||||
fmt.Printf("%s", securityInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunEmailTests runs email port tests
|
||||
func RunEmailTests(config *params.Config, wg2 *sync.WaitGroup, emailInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.EmailTestStatus {
|
||||
wg2.Wait()
|
||||
if config.Language == "zh" {
|
||||
utils.PrintCenteredTitle("邮件端口检测", config.Width)
|
||||
} else {
|
||||
utils.PrintCenteredTitle("Email-Port-Check", config.Width)
|
||||
}
|
||||
fmt.Println(*emailInfo)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunNetworkTests runs network tests (Chinese mode)
|
||||
func RunNetworkTests(config *params.Config, wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.BacktraceStatus && !config.OnlyChinaTest {
|
||||
utils.PrintCenteredTitle("上游及回程线路检测", config.Width)
|
||||
tests.UpstreamsCheck()
|
||||
}
|
||||
if config.Nt3Status && !config.OnlyChinaTest {
|
||||
utils.PrintCenteredTitle("三网回程路由检测", config.Width)
|
||||
tests.NextTrace3Check(config.Language, config.Nt3Location, config.Nt3CheckType)
|
||||
}
|
||||
if config.OnlyChinaTest && *ptInfo != "" {
|
||||
wg3.Wait()
|
||||
utils.PrintCenteredTitle("PING值检测", config.Width)
|
||||
fmt.Println(*ptInfo)
|
||||
}
|
||||
if config.PingTestStatus && *ptInfo != "" {
|
||||
wg3.Wait()
|
||||
utils.PrintCenteredTitle("PING值检测", config.Width)
|
||||
fmt.Println(*ptInfo)
|
||||
if config.TgdcTestStatus {
|
||||
fmt.Println(pt.TelegramDCTest())
|
||||
}
|
||||
if config.WebTestStatus {
|
||||
fmt.Println(pt.WebsiteTest())
|
||||
}
|
||||
}
|
||||
if !config.OnlyChinaTest && !config.PingTestStatus && (config.TgdcTestStatus || config.WebTestStatus) {
|
||||
utils.PrintCenteredTitle("PING值检测", config.Width)
|
||||
if config.TgdcTestStatus {
|
||||
fmt.Println(pt.TelegramDCTest())
|
||||
}
|
||||
if config.WebTestStatus {
|
||||
fmt.Println(pt.WebsiteTest())
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunSpeedTests runs speed tests (Chinese mode)
|
||||
func RunSpeedTests(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.SpeedTestStatus {
|
||||
utils.PrintCenteredTitle("就近节点测速", config.Width)
|
||||
tests.ShowHead(config.Language)
|
||||
if config.Choice == "1" || !config.MenuMode {
|
||||
tests.NearbySP()
|
||||
tests.CustomSP("net", "global", 2, config.Language)
|
||||
tests.CustomSP("net", "cu", config.SpNum, config.Language)
|
||||
tests.CustomSP("net", "ct", config.SpNum, config.Language)
|
||||
tests.CustomSP("net", "cmcc", config.SpNum, config.Language)
|
||||
} else if config.Choice == "2" || config.Choice == "3" || config.Choice == "4" || config.Choice == "5" {
|
||||
tests.CustomSP("net", "global", 4, config.Language)
|
||||
} else if config.Choice == "6" {
|
||||
tests.CustomSP("net", "global", 11, config.Language)
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunEnglishNetworkTests runs network tests (English mode)
|
||||
func RunEnglishNetworkTests(config *params.Config, wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.TgdcTestStatus || config.WebTestStatus {
|
||||
utils.PrintCenteredTitle("PING-Test", config.Width)
|
||||
if config.TgdcTestStatus {
|
||||
fmt.Println(pt.TelegramDCTest())
|
||||
}
|
||||
if config.WebTestStatus {
|
||||
fmt.Println(pt.WebsiteTest())
|
||||
}
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// RunEnglishSpeedTests runs speed tests (English mode)
|
||||
func RunEnglishSpeedTests(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
return utils.PrintAndCapture(func() {
|
||||
if config.SpeedTestStatus {
|
||||
utils.PrintCenteredTitle("Speed-Test", config.Width)
|
||||
tests.ShowHead(config.Language)
|
||||
tests.NearbySP()
|
||||
tests.CustomSP("net", "global", -1, config.Language)
|
||||
}
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// AppendTimeInfo appends timing information
|
||||
func AppendTimeInfo(config *params.Config, output, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) string {
|
||||
outputMutex.Lock()
|
||||
defer outputMutex.Unlock()
|
||||
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")
|
||||
return utils.PrintAndCapture(func() {
|
||||
utils.PrintCenteredTitle("", config.Width)
|
||||
if config.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)
|
||||
}
|
||||
utils.PrintCenteredTitle("", config.Width)
|
||||
}, tempOutput, output)
|
||||
}
|
||||
|
||||
// HandleSignalInterrupt handles interrupt signals
|
||||
func HandleSignalInterrupt(sig chan os.Signal, config *params.Config, startTime *time.Time, output *string, tempOutput string, uploadDone chan bool, outputMutex *sync.Mutex) {
|
||||
select {
|
||||
case <-sig:
|
||||
if !config.Finish {
|
||||
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")
|
||||
outputMutex.Lock()
|
||||
timeInfo := utils.PrintAndCapture(func() {
|
||||
utils.PrintCenteredTitle("", config.Width)
|
||||
if config.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)
|
||||
}
|
||||
utils.PrintCenteredTitle("", config.Width)
|
||||
}, "", "")
|
||||
*output += timeInfo
|
||||
finalOutput := *output
|
||||
outputMutex.Unlock()
|
||||
resultChan := make(chan struct {
|
||||
httpURL string
|
||||
httpsURL string
|
||||
}, 1)
|
||||
if config.EnableUpload {
|
||||
go func() {
|
||||
httpURL, httpsURL := utils.ProcessAndUpload(finalOutput, config.FilePath, config.EnableUpload)
|
||||
resultChan <- struct {
|
||||
httpURL string
|
||||
httpsURL string
|
||||
}{httpURL, httpsURL}
|
||||
uploadDone <- true
|
||||
}()
|
||||
select {
|
||||
case result := <-resultChan:
|
||||
if result.httpURL != "" || result.httpsURL != "" {
|
||||
if config.Language == "en" {
|
||||
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", result.httpURL, result.httpsURL)
|
||||
} else {
|
||||
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", result.httpURL, result.httpsURL)
|
||||
}
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(0)
|
||||
case <-time.After(30 * time.Second):
|
||||
if config.Language == "en" {
|
||||
fmt.Println("Upload timeout, program exit")
|
||||
} else {
|
||||
fmt.Println("上传超时,程序退出")
|
||||
}
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
fmt.Println("Press Enter to exit...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleUploadResults handles uploading results
|
||||
func HandleUploadResults(config *params.Config, output string) {
|
||||
httpURL, httpsURL := utils.ProcessAndUpload(output, config.FilePath, config.EnableUpload)
|
||||
if httpURL != "" || httpsURL != "" {
|
||||
if config.Language == "en" {
|
||||
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
|
||||
fmt.Println("Each Test Benchmark: https://bash.spiritlhl.net/ecsguide")
|
||||
} else {
|
||||
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
|
||||
fmt.Println("每项测试基准见: https://bash.spiritlhl.net/ecsguide")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cputest
|
||||
package tests
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
@@ -1,4 +1,4 @@
|
||||
package disktest
|
||||
package tests
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
@@ -1,4 +1,4 @@
|
||||
package memorytest
|
||||
package tests
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
@@ -1,4 +1,4 @@
|
||||
package nexttrace
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -27,7 +27,7 @@ func NextTrace3Check(language, nt3Location, nt3CheckType string) {
|
||||
fmt.Println(res)
|
||||
}
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
for _, res := range result.Output {
|
||||
res = strings.TrimSpace(res)
|
||||
@@ -1,10 +1,11 @@
|
||||
package speedtest
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/oneclickvirt/speedtest/model"
|
||||
"github.com/oneclickvirt/speedtest/sp"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/oneclickvirt/speedtest/model"
|
||||
"github.com/oneclickvirt/speedtest/sp"
|
||||
)
|
||||
|
||||
func ShowHead(language string) {
|
||||
@@ -1,8 +1,8 @@
|
||||
package unlocktest
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/oneclickvirt/UnlockTests/utils"
|
||||
"github.com/oneclickvirt/UnlockTests/executor"
|
||||
"github.com/oneclickvirt/UnlockTests/utils"
|
||||
"github.com/oneclickvirt/defaultset"
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package upstreams
|
||||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,11 +0,0 @@
|
||||
package memorytest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
_, res := MemoryTest("zh", "stream")
|
||||
fmt.Print(res)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package nexttrace
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNextTrace3Check(t *testing.T) {
|
||||
start := time.Now()
|
||||
NextTrace3Check("zh", "ALL", "ipv4")
|
||||
duration := time.Since(start)
|
||||
t.Logf("执行耗时: %s", duration)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package speedtest
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test(t *testing.T) {
|
||||
ShowHead("en")
|
||||
NearbySP()
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package unlocktest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
fmt.Printf("%s", MediaTest("zh"))
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package upstreams
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestUpstreamsCheck(t *testing.T) {
|
||||
IPV4 = "148.100.85.25"
|
||||
UpstreamsCheck()
|
||||
}
|
||||
Reference in New Issue
Block a user