package config import ( "encoding/json" "errors" "os" "path/filepath" "runtime" "strconv" "douyu_go/internal/constants" "douyu_go/internal/logger" "douyu_go/internal/types" ) // DefaultAppPaths 收集运行时路径,支持环境变量覆盖。 func DefaultAppPaths() types.AppPaths { return types.AppPaths{ ConfigFile: envOrDefault("DOUYU_CONFIG", constants.DefaultConfigFile), AccountFile: envOrDefault("DOUYU_USERS", constants.DefaultAccountFile), LogDir: envOrDefault("DOUYU_LOG_DIR", constants.DefaultLogDir), SuccessDir: envOrDefault("DOUYU_SUCCESS_DIR", constants.DefaultSuccessDir), FontFiles: CollectFontCandidates(), } } func envOrDefault(key, fallback string) string { if value := os.Getenv(key); value != "" { return filepath.Clean(value) } return fallback } // LoadTraceConfig 读取 trace 开关;默认关闭,避免保存敏感调试数据。 func LoadTraceConfig() types.TraceConfig { return types.TraceConfig{ Enabled: isTruthyEnv("DOUYU_TRACE"), MaxBodyBytes: envInt("DOUYU_TRACE_MAX_BODY", 0), } } func isTruthyEnv(key string) bool { switch os.Getenv(key) { case "1", "true", "TRUE", "yes", "YES", "on", "ON": return true default: return false } } func envInt(key string, fallback int) int { raw := os.Getenv(key) if raw == "" { return fallback } value, err := strconv.Atoi(raw) if err != nil || value <= 0 { return fallback } return value } // LoadConfig 读取配置文件;缺失时安静使用内置默认配置。 func LoadConfig(path string) types.Config { cfg := types.Config{TimeAPIURL: constants.DefaultTimeAPI} if path == "" { path = constants.DefaultConfigFile } f, err := os.Open(path) if err != nil { if errors.Is(err, os.ErrNotExist) { logger.LogEvent("配置", "info", "配置加载完成: 内置默认配置") } else { logger.LogEvent("配置", "warn", "读取 %s 出错,使用内置默认配置: %v", path, err) } return cfg } defer f.Close() if err := json.NewDecoder(f).Decode(&cfg); err != nil { logger.LogEvent("配置", "warn", "解析 %s 失败,使用内置默认配置: %v", path, err) return types.Config{TimeAPIURL: constants.DefaultTimeAPI} } if cfg.TimeAPIURL == "" { cfg.TimeAPIURL = constants.DefaultTimeAPI } logger.LogEvent("配置", "success", "配置加载完成: %s", path) return cfg } // CollectFontCandidates 收集常见中文字体路径,允许用 DOUYU_FONT 指定自定义字体。 func CollectFontCandidates() []string { candidates := []string{} if custom := os.Getenv("DOUYU_FONT"); custom != "" { candidates = append(candidates, custom) } candidates = append(candidates, "Microsoft Yahei.ttf", "Microsoft YaHei.ttf", "NotoSansCJKsc-Regular.otf", "NotoSansCJK-Regular.ttc", ) switch runtime.GOOS { case "darwin": candidates = append(candidates, "/System/Library/Fonts/PingFang.ttc", "/System/Library/Fonts/Supplemental/Arial Unicode.ttf", "/System/Library/Fonts/Supplemental/Songti.ttc", ) case "windows": candidates = append(candidates, `C:\Windows\Fonts\msyh.ttc`, `C:\Windows\Fonts\simhei.ttf`, `C:\Windows\Fonts\simsun.ttc`, ) default: candidates = append(candidates, "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.otf", "/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc", "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc", "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", ) } return candidates }