Skip to content

Commit d023da5

Browse files
author
V2RaySSR综合网
committed
完善用户体验和错误处理
- 修复WorkerPool panic问题,添加nil检查 - 优化域名验证,支持空格分隔的批量检测 - 改进错误提示格式,添加适当的间距 - 优化无效域名显示,只显示前5个避免界面混乱 - 删除程序运行时的清屏操作 - 移除所有图标,使用简洁的错误信息 - CSV错误时统一提示使用RealiTLScanner工具 - 横幅显示前添加空行,改善视觉间距
1 parent f051a0b commit d023da5

File tree

10 files changed

+99
-55
lines changed

10 files changed

+99
-55
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ jobs:
9191
./reality-checker check example.com
9292
9393
# 批量检测
94-
./reality-checker batch "domain1,domain2,domain3"
94+
./reality-checker batch domain1 domain2 domain3
9595
9696
# CSV文件检测
9797
./reality-checker csv domains.csv

.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# 编译后的可执行文件
2+
reality-checker
3+
reality-checker.exe
4+
reality-checker-linux-amd64
5+
reality-checker-windows-amd64.exe
6+
reality-checker-darwin-amd64
7+
reality-checker-linux-arm64
8+
9+
# 项目状态文档(本地开发用)
10+
PROJECT_STATUS.md
11+
12+
# 子项目目录
13+
reality-checker-go/
14+
15+
# Cursor IDE配置
16+
.cursor/
17+
18+
# 系统文件
19+
.DS_Store
20+
Thumbs.db
21+
22+
# 临时文件
23+
*.tmp
24+
*.log
25+
*.swp
26+
*.swo
27+
*~
28+
29+
# IDE配置
30+
.vscode/
31+
.idea/
32+
*.iml
33+
34+
# Go相关
35+
vendor/
36+
*.test
37+
*.prof
38+
39+
# 配置文件(可选)
40+
config.yaml

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ go build -o reality-checker
7676
### 批量检测
7777

7878
```bash
79-
# 批量检测多个域名(逗号分隔
80-
./reality-checker batch "apple.com,tesla.com,microsoft.com"
79+
# 批量检测多个域名(空格分隔
80+
./reality-checker batch apple.com tesla.com microsoft.com
8181
```
8282

8383
### CSV文件检测

internal/cmd/batch.go

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package cmd
22

33
import (
44
"fmt"
5-
"net"
6-
"regexp"
75
"strings"
86

97
"RealityChecker/internal/ui"
@@ -14,22 +12,38 @@ func (r *RootCmd) executeBatch(domainsStr string) {
1412
// 解析域名列表
1513
domains, invalidDomains := parseDomains(domainsStr)
1614

17-
// 显示无效域名警告
18-
if len(invalidDomains) > 0 {
19-
fmt.Printf("警告:发现 %d 个无效域名,已跳过:\n", len(invalidDomains))
20-
for _, domain := range invalidDomains {
21-
fmt.Printf(" - %s\n", domain)
22-
}
23-
fmt.Println()
24-
}
25-
2615
if len(domains) == 0 {
16+
fmt.Println()
2717
fmt.Println("错误:没有有效的域名可以检测")
2818
fmt.Println("提示:请检查域名格式,例如:apple.com, google.com")
19+
fmt.Println()
2920
return
3021
}
3122

3223
ui.PrintBanner()
24+
25+
// 显示无效域名警告(在横幅下面)
26+
if len(invalidDomains) > 0 {
27+
fmt.Printf("警告:发现 %d 个无效域名,已跳过:\n", len(invalidDomains))
28+
29+
// 只显示前5个无效域名,避免显示过多
30+
displayCount := 5
31+
if len(invalidDomains) < displayCount {
32+
displayCount = len(invalidDomains)
33+
}
34+
35+
for i := 0; i < displayCount; i++ {
36+
fmt.Printf(" - %s\n", invalidDomains[i])
37+
}
38+
39+
// 如果还有更多无效域名,显示省略提示
40+
if len(invalidDomains) > displayCount {
41+
fmt.Printf(" ... 还有 %d 个无效域名\n", len(invalidDomains)-displayCount)
42+
}
43+
44+
fmt.Println()
45+
}
46+
3347
ui.PrintTimestampedMessage("开始批量检测 %d 个域名...", len(domains))
3448

3549
_, err := r.batchManager.CheckDomains(r.ctx, domains)
@@ -63,41 +77,3 @@ func parseDomains(domainsStr string) ([]string, []string) {
6377
return validDomains, invalidDomains
6478
}
6579

66-
// isValidDomain 验证域名格式是否有效
67-
func isValidDomain(domain string) bool {
68-
// 基本长度检查
69-
if len(domain) == 0 || len(domain) > 253 {
70-
return false
71-
}
72-
73-
// 检查是否包含非法字符
74-
if strings.ContainsAny(domain, " \t\n\r") {
75-
return false
76-
}
77-
78-
// 检查是否以点开头或结尾
79-
if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") {
80-
return false
81-
}
82-
83-
// 检查是否包含连续的点
84-
if strings.Contains(domain, "..") {
85-
return false
86-
}
87-
88-
// 使用正则表达式验证域名格式
89-
domainRegex := regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$`)
90-
if !domainRegex.MatchString(domain) {
91-
return false
92-
}
93-
94-
// 尝试解析域名(不进行实际DNS查询)
95-
_, err := net.LookupHost(domain)
96-
if err != nil {
97-
// 即使DNS解析失败,只要格式正确就认为是有效的
98-
// 因为可能是网络问题或域名确实不存在
99-
return true
100-
}
101-
102-
return true
103-
}

internal/cmd/check.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ func (r *RootCmd) executeCheck(domain string) {
1616
// 验证域名格式
1717
domain = strings.TrimSpace(domain)
1818
if !isValidDomain(domain) {
19+
fmt.Println()
1920
fmt.Printf("错误:域名格式无效 '%s'\n", domain)
2021
fmt.Println("提示:请检查域名格式,例如:apple.com, google.com")
2122
fmt.Println("域名要求:")
2223
fmt.Println(" - 只能包含字母、数字、连字符和点")
2324
fmt.Println(" - 不能以点开头或结尾")
2425
fmt.Println(" - 不能包含连续的点")
2526
fmt.Println(" - 长度不超过253个字符")
27+
fmt.Println()
2628
return
2729
}
2830

@@ -41,7 +43,7 @@ func (r *RootCmd) executeCheck(domain string) {
4143
fmt.Printf("\n%s", formatter.FormatSingleResult(result))
4244
}
4345

44-
// isValidDomain 验证域名格式是否有效(与batch.go中的函数相同)
46+
// isValidDomain 验证域名格式是否有效
4547
func isValidDomain(domain string) bool {
4648
// 基本长度检查
4749
if len(domain) == 0 || len(domain) > 253 {
@@ -79,3 +81,4 @@ func isValidDomain(domain string) bool {
7981

8082
return true
8183
}
84+

internal/cmd/csv.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,21 @@ import (
1313
func (r *RootCmd) executeCSV(csvFile string) {
1414
// 检查文件是否存在
1515
if _, err := os.Stat(csvFile); os.IsNotExist(err) {
16+
fmt.Println()
1617
fmt.Printf("错误:CSV文件不存在 '%s'\n", csvFile)
1718
fmt.Println("请使用 RealiTLScanner 工具扫描,得到 CSV 文件")
1819
fmt.Println("命令:./RealiTLScanner -addr <VPS IP> -port 443 -thread 50 -timeout 5 -out file.csv")
1920
fmt.Println("(提示:RealiTLScanner 不要在VPS上面运行)")
21+
fmt.Println()
2022
return
2123
}
2224

2325
// 读取CSV文件
2426
file, err := os.Open(csvFile)
2527
if err != nil {
28+
fmt.Println()
2629
fmt.Printf("错误:无法打开CSV文件 '%s': %v\n", csvFile, err)
30+
fmt.Println()
2731
return
2832
}
2933
defer file.Close()
@@ -32,25 +36,31 @@ func (r *RootCmd) executeCSV(csvFile string) {
3236
reader := csv.NewReader(file)
3337
records, err := reader.ReadAll()
3438
if err != nil {
39+
fmt.Println()
3540
fmt.Printf("错误:解析CSV文件失败: %v\n", err)
3641
fmt.Println("请使用 RealiTLScanner 工具扫描,得到 CSV 文件")
3742
fmt.Println("命令:./RealiTLScanner -addr <VPS IP> -port 443 -thread 50 -timeout 5 -out file.csv")
43+
fmt.Println()
3844
return
3945
}
4046

4147
if len(records) < 2 {
48+
fmt.Println()
4249
fmt.Println("错误:CSV文件格式错误或为空")
4350
fmt.Println("请使用 RealiTLScanner 工具扫描,得到 CSV 文件")
4451
fmt.Println("命令:./RealiTLScanner -addr <VPS IP> -port 443 -thread 50 -timeout 5 -out file.csv")
52+
fmt.Println()
4553
return
4654
}
4755

4856
// 提取域名(从CERT_DOMAIN列)
4957
domains := extractDomainsFromCSV(records)
5058
if len(domains) == 0 {
59+
fmt.Println()
5160
fmt.Println("错误:未找到有效的域名")
5261
fmt.Println("请使用 RealiTLScanner 工具扫描,得到 CSV 文件")
5362
fmt.Println("命令:./RealiTLScanner -addr <VPS IP> -port 443 -thread 50 -timeout 5 -out file.csv")
63+
fmt.Println()
5464
return
5565
}
5666

internal/cmd/root.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77
"os/signal"
8+
"strings"
89
"syscall"
910

1011
"RealityChecker/internal/batch"
@@ -72,37 +73,45 @@ func (r *RootCmd) Execute() {
7273
switch os.Args[1] {
7374
case "check":
7475
if len(os.Args) < 3 {
76+
fmt.Println()
7577
fmt.Println("错误:缺少域名参数")
7678
fmt.Println("用法: reality-checker check <domain>")
7779
fmt.Println("示例: reality-checker check apple.com")
80+
fmt.Println()
7881
os.Exit(1)
7982
}
8083
r.executeCheck(os.Args[2])
8184
case "batch":
8285
if len(os.Args) < 3 {
86+
fmt.Println()
8387
fmt.Println("错误:缺少域名参数")
8488
fmt.Println("用法: reality-checker batch <domain1> <domain2> <domain3> ...")
8589
fmt.Println("示例: reality-checker batch apple.com google.com microsoft.com")
90+
fmt.Println()
8691
os.Exit(1)
8792
}
8893
// 将所有参数(除了命令名)合并为空格分隔的字符串
8994
domainsStr := strings.Join(os.Args[2:], " ")
9095
r.executeBatch(domainsStr)
9196
case "csv":
9297
if len(os.Args) < 3 {
98+
fmt.Println()
9399
fmt.Println("错误:缺少CSV文件参数")
94100
fmt.Println("用法: reality-checker csv <csv_file>")
95101
fmt.Println("示例: reality-checker csv domains.csv")
102+
fmt.Println()
96103
os.Exit(1)
97104
}
98105
r.executeCSV(os.Args[2])
99106
case "version", "-v", "--version":
100107
r.showVersion()
101108
default:
109+
fmt.Println()
102110
fmt.Printf("错误:未知命令 '%s'\n", os.Args[1])
103111
fmt.Println("可用命令: check, batch, csv, version")
104112
fmt.Println()
105113
ui.PrintUsage()
114+
fmt.Println()
106115
os.Exit(1)
107116
}
108117
}

internal/core/coordinator.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ func (wp *WorkerPool) worker(id int) {
284284
for {
285285
select {
286286
case task := <-wp.taskQueue:
287+
// 检查task是否为nil
288+
if task == nil {
289+
continue
290+
}
291+
287292
wp.mu.Lock()
288293
wp.activeWorkers++
289294
wp.mu.Unlock()

internal/ui/banner.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
// PrintBanner 打印程序横幅
99
func PrintBanner() {
10+
fmt.Println()
1011

1112
// 获取版本信息
1213
versionInfo := getVersionInfo()

internal/ui/display.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ func PrintUsage() {
2121
fmt.Printf("Reality协议目标网站检测器 %s\n\n", version.GetVersion())
2222
fmt.Println("用法:")
2323
fmt.Println(" reality-checker check <domain> 检测单个域名")
24-
fmt.Println(" reality-checker batch <domain1,domain2,...> 批量检测域名")
24+
fmt.Println(" reality-checker batch <domain1> <domain2> <domain3> ... 批量检测域名")
2525
fmt.Println(" reality-checker csv <csv_file> 从CSV文件批量检测域名")
2626
fmt.Println("")
2727
fmt.Println("示例:")
2828
fmt.Println(" reality-checker check apple.com")
29-
fmt.Println(" reality-checker batch apple.com,tesla.com,microsoft.com")
29+
fmt.Println(" reality-checker batch apple.com tesla.com microsoft.com")
3030
fmt.Println(" reality-checker csv file.csv")
3131
}
3232

0 commit comments

Comments
 (0)