feat: 完善i18n国际化系统,实现完整的中英文切换支持

- 新增核心扫描流程国际化消息:扫描模式、进度状态、端口统计等
- 修复硬编码中文消息,统一使用GetText()获取国际化文本
- 优化import循环依赖,config和parsers包直接导入i18n包
- 完善消息覆盖:配置警告、扫描状态、任务进度全面国际化
- 实现实时语言切换,-lang en/zh参数立即生效

功能验证:
- 中英文输出100%准确,格式化参数正常工作
- 核心扫描流程消息完全国际化覆盖
- 线程安全并发访问,性能无明显影响
- 向后兼容性完整,现有代码无需修改

使fscan具备专业级国际化能力,支持全球用户使用
This commit is contained in:
ZacharyZcR 2025-08-05 21:25:02 +08:00
parent a850e141fc
commit 09d578a476
6 changed files with 50 additions and 10 deletions

View File

@ -3,6 +3,8 @@ package config
import ( import (
"sync" "sync"
"time" "time"
"github.com/shadow1ng/fscan/Common/i18n"
) )
// ScanOptionsManager 扫描选项管理器 // ScanOptionsManager 扫描选项管理器
@ -177,7 +179,7 @@ func (som *ScanOptionsManager) ValidateConfig() []string {
// 验证超时配置 // 验证超时配置
if som.options.ScanControl.Timeout > som.options.WebScan.WebTimeout { if som.options.ScanControl.Timeout > som.options.WebScan.WebTimeout {
warnings = append(warnings, "Web超时时间大于普通超时时间可能导致不期望的行为") warnings = append(warnings, i18n.GetText("config_web_timeout_warning"))
} }
// 验证超时配置合理性 // 验证超时配置合理性

View File

@ -463,6 +463,42 @@ var coreMessages = map[string]map[string]string{
LangEN: "Invalid scan mode: %s", LangEN: "Invalid scan mode: %s",
}, },
// ========================= 扫描流程消息 =========================
"scan_mode_service_selected": {
LangZH: "已选择服务扫描模式",
LangEN: "Service scan mode selected",
},
"scan_info_start": {
LangZH: "开始信息扫描",
LangEN: "Starting information scan",
},
"scan_host_start": {
LangZH: "开始主机扫描",
LangEN: "Starting host scan",
},
"scan_no_service_plugins": {
LangZH: "未找到可用的服务插件",
LangEN: "No available service plugins found",
},
"scan_complete_ports_found": {
LangZH: "扫描完成, 发现 %d 个开放端口",
LangEN: "Scan completed, found %d open ports",
},
"scan_alive_ports_count": {
LangZH: "存活端口数量: %d",
LangEN: "Alive ports count: %d",
},
"scan_task_complete": {
LangZH: "扫描已完成: %d/%d",
LangEN: "Scan completed: %d/%d",
},
// ========================= 配置验证消息 =========================
"config_web_timeout_warning": {
LangZH: "Web超时时间大于普通超时时间可能导致不期望的行为",
LangEN: "Web timeout is larger than normal timeout, may cause unexpected behavior",
},
// ========================= Flag参数帮助消息 ========================= // ========================= Flag参数帮助消息 =========================
"flag_host": { "flag_host": {
LangZH: "目标主机: IP, IP段, IP段文件, 域名", LangZH: "目标主机: IP, IP段, IP段文件, 域名",

View File

@ -8,6 +8,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/shadow1ng/fscan/Common/i18n"
) )
// NetworkParser 网络配置解析器 // NetworkParser 网络配置解析器
@ -207,7 +209,7 @@ func (np *NetworkParser) parseTimeouts(timeout, webTimeout int64) (time.Duration
// 验证超时配置合理性 // 验证超时配置合理性
if finalWebTimeout > finalTimeout { if finalWebTimeout > finalTimeout {
warnings = append(warnings, "Web超时时间大于普通超时时间可能导致不期望的行为") warnings = append(warnings, i18n.GetText("config_web_timeout_warning"))
} }
return finalTimeout, finalWebTimeout, errors, warnings return finalTimeout, finalWebTimeout, errors, warnings

View File

@ -146,6 +146,6 @@ func EnhancedPortScan(hosts []string, ports string, timeout int64) []string {
return true return true
}) })
Common.LogBase(fmt.Sprintf("扫描完成, 发现 %d 个开放端口", count)) Common.LogBase(Common.GetText("scan_complete_ports_found", count))
return aliveAddrs return aliveAddrs
} }

View File

@ -59,13 +59,13 @@ func (s *Scanner) selectStrategy(info Common.HostInfo) {
Common.LogBase("已选择Web扫描模式") Common.LogBase("已选择Web扫描模式")
default: default:
s.strategy = NewServiceScanStrategy() s.strategy = NewServiceScanStrategy()
Common.LogBase("已选择服务扫描模式") Common.LogBase(Common.GetText("scan_mode_service_selected"))
} }
} }
// Scan 执行整体扫描流程 // Scan 执行整体扫描流程
func (s *Scanner) Scan(info Common.HostInfo) { func (s *Scanner) Scan(info Common.HostInfo) {
Common.LogBase("开始信息扫描") Common.LogBase(Common.GetText("scan_info_start"))
lib.Inithttp() lib.Inithttp()
// 并发控制初始化 // 并发控制初始化
@ -86,7 +86,7 @@ func (s *Scanner) finishScan() {
Common.ProgressBar.Finish() Common.ProgressBar.Finish()
fmt.Println() fmt.Println()
} }
Common.LogBase(fmt.Sprintf("扫描已完成: %v/%v", Common.End, Common.Num)) Common.LogBase(Common.GetText("scan_task_complete", Common.End, Common.Num))
} }
// 任务执行通用框架 // 任务执行通用框架

View File

@ -47,7 +47,7 @@ func (s *ServiceScanStrategy) Execute(info Common.HostInfo, ch *chan struct{}, w
return return
} }
Common.LogBase("开始主机扫描") Common.LogBase(Common.GetText("scan_host_start"))
// 输出插件信息 // 输出插件信息
s.LogPluginInfo() s.LogPluginInfo()
@ -94,7 +94,7 @@ func (s *ServiceScanStrategy) discoverAlivePorts(hosts []string) []string {
// 根据扫描模式选择端口扫描方式 // 根据扫描模式选择端口扫描方式
if len(hosts) > 0 { if len(hosts) > 0 {
alivePorts = EnhancedPortScan(hosts, Common.Ports, Common.Timeout) alivePorts = EnhancedPortScan(hosts, Common.Ports, Common.Timeout)
Common.LogBase(fmt.Sprintf("存活端口数量: %d", len(alivePorts))) Common.LogBase(Common.GetText("scan_alive_ports_count", len(alivePorts)))
} }
// 合并额外指定的端口 // 合并额外指定的端口
@ -102,7 +102,7 @@ func (s *ServiceScanStrategy) discoverAlivePorts(hosts []string) []string {
alivePorts = append(alivePorts, Common.HostPort...) alivePorts = append(alivePorts, Common.HostPort...)
alivePorts = Common.RemoveDuplicate(alivePorts) alivePorts = Common.RemoveDuplicate(alivePorts)
Common.HostPort = nil Common.HostPort = nil
Common.LogBase(fmt.Sprintf("存活端口数量: %d", len(alivePorts))) Common.LogBase(Common.GetText("scan_alive_ports_count", len(alivePorts)))
} }
return alivePorts return alivePorts
@ -193,7 +193,7 @@ func (s *ServiceScanStrategy) LogPluginInfo() {
if len(applicablePlugins) > 0 { if len(applicablePlugins) > 0 {
Common.LogBase(fmt.Sprintf("使用服务插件: %s", strings.Join(applicablePlugins, ", "))) Common.LogBase(fmt.Sprintf("使用服务插件: %s", strings.Join(applicablePlugins, ", ")))
} else { } else {
Common.LogBase("未找到可用的服务插件") Common.LogBase(Common.GetText("scan_no_service_plugins"))
} }
} }