From bb5da411200560efbf5249745014c5ceb474efd5 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Fri, 26 Jun 2026 15:36:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E6=96=87=E4=BB=B6=E5=B7=B2?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BD=AC=E6=8D=A2=E4=B8=BA=20Windows=20?= =?UTF-8?q?=E6=8D=A2=E8=A1=8C=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/seckill/scheduler.go | 49 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/internal/seckill/scheduler.go b/internal/seckill/scheduler.go index 0b2fc20..fde7844 100644 --- a/internal/seckill/scheduler.go +++ b/internal/seckill/scheduler.go @@ -2,6 +2,7 @@ package seckill import ( "bufio" + "bytes" "errors" "fmt" "math/rand" @@ -119,7 +120,8 @@ func (s *Scheduler) LoadAccounts() { logger.LogEvent("账号", "warn", "账号目录创建失败: %s: %v", dir, mkErr) } } - hint := "# 格式: 账号名----密码----Cookie\n# 每行一个账号,粘贴后保存即可\n" + // 使用 Windows 换行格式 \r\n + hint := "# 格式: 账号名----密码----Cookie\r\n# 每行一个账号,粘贴后保存即可\r\n" if wrErr := os.WriteFile(path, []byte(hint), 0644); wrErr != nil { logger.LogEvent("账号", "warn", "账号文件创建失败: %s: %v", path, wrErr) } else { @@ -127,7 +129,8 @@ func (s *Scheduler) LoadAccounts() { } } - f, err := os.Open(path) + // 读取文件内容,自动转换换行格式为 Windows 格式 + content, err := os.ReadFile(path) if err != nil { logger.LogEvent("账号", "error", "读取账号文件失败: %s: %v", path, err) s.accountsMu.Lock() @@ -135,10 +138,21 @@ func (s *Scheduler) LoadAccounts() { s.accountsMu.Unlock() return } - defer f.Close() + + // 检测并转换换行格式 + normalized, converted := s.normalizeLineEndings(path, content) + if converted { + // 保存转换后的内容 + if err := os.WriteFile(path, normalized, 0644); err != nil { + logger.LogEvent("账号", "warn", "账号文件换行格式转换失败: %s: %v", path, err) + } else { + logger.LogEvent("账号", "info", "账号文件已自动转换为 Windows 换行格式: %s", path) + } + content = normalized + } var list []types.Account - scanner := bufio.NewScanner(f) + scanner := bufio.NewScanner(bytes.NewReader(content)) scanner.Buffer(make([]byte, 1024), 1024*1024) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) @@ -173,6 +187,33 @@ func (s *Scheduler) AccountCount() int { return len(s.accounts) } +// normalizeLineEndings 检测并转换换行格式为 Windows 格式(\r\n)。 +// 返回转换后的内容和是否进行了转换。 +func (s *Scheduler) normalizeLineEndings(path string, content []byte) ([]byte, bool) { + // 检查是否已经是 Windows 格式(包含 \r\n) + if bytes.Contains(content, []byte("\r\n")) { + // 已经是 Windows 格式,检查是否还有单独的 \n + // 先将所有 \r\n 替换为占位符,检查是否还有单独的 \n + temp := bytes.ReplaceAll(content, []byte("\r\n"), []byte("__RN_PLACEHOLDER__")) + if !bytes.Contains(temp, []byte("\n")) && !bytes.Contains(temp, []byte("\r")) { + // 完全是 Windows 格式,不需要转换 + return content, false + } + // 混合格式,需要统一转换 + } + + // 转换逻辑:先统一为 \n,再转换为 \r\n + normalized := content + // 1. 将 \r\n 替换为 \n + normalized = bytes.ReplaceAll(normalized, []byte("\r\n"), []byte("\n")) + // 2. 将单独的 \r 替换为 \n + normalized = bytes.ReplaceAll(normalized, []byte("\r"), []byte("\n")) + // 3. 将 \n 替换为 \r\n + normalized = bytes.ReplaceAll(normalized, []byte("\n"), []byte("\r\n")) + + return normalized, true +} + // AccountFilePath 返回账号文件路径。 func (s *Scheduler) AccountFilePath() string { return s.paths.AccountFile