📚 使用说明 v3.0.2

MC部落日志分析器 - Web版操作指南与技术说明

👤 非专业人员使用指南
专业人员技术说明
🚀

三步快速开始

1
访问Web页面

打开浏览器,输入服务器地址(例如: http://localhost:8000https://mclans.sakurain.net )。页面加载后,您会看到简洁的操作界面。

💡 提示

推荐Chrome、Edge或Firefox浏览器,确保版本为近2年内更新。IE浏览器不被支持

2
上传日志文件

点击上传区域选择您的日志文件(.log.log.gz ),支持多文件批量上传。

⚠️ 重要

单个文件最大100MB,总大小不超过500MB。如果文件超过限制,请先压缩为.gz格式。

3
下载分析结果

选择分析模式(PvP或商会),点击"开始分析"。完成后即可下载Excel、PDF或图片报告。

🎯 建议

首次使用建议先上传1-2个小文件测试,熟悉流程后再批量处理。

📋

详细操作指南

🖼️ 界面功能说明

区域 功能 操作说明
上传区域 文件选择与拖拽 点击或拖拽日志文件到此区域,支持多选和压缩文件
配置面板 分析模式与格式选择 选择PvP(击杀分析)或Shop(商会分析),再选输出格式
进度面板 实时显示分析进度 自动显示,无需操作,可查看详细日志
结果面板 下载与预览 分析完成后显示下载按钮,图片/PDF可在线预览

🎮 PvP击杀分析模式

适用于分析玩家之间的战斗记录。日志中需要包含类似这样的内容:

[14:32:10] [main/INFO] [CHAT] ?玩家A 被 玩家B 使用 [钻石剑] 击杀了! 支持多种格式变体: - [时间] [CHAT] ?受害者 被 击杀者 使用 [武器] 击杀了! - [时间] [CHAT] 受害者 被 击杀者 击杀了 - [时间] [main/INFO] [CHAT] ?玩家A[称号] 被 VIP玩家B 使用 [弓箭] 击杀了!

支持导出为:Excel表格(详细数据)、PDF报告(正式文档)、PNG图表(可视化统计)。

🏪 商会交易分析模式

适用于分析商会的买卖记录。日志中需要包含类似这样的内容:

收购记录格式: [时间] [main/INFO] [CHAT] 收购: 玩家:花葬 | 商品:钻石 | 数量:64 | 金额:1280.0 出售记录格式: [时间] [main/INFO] [CHAT] 出售: 玩家:花葬 | 商品:钻石剑 | 数量:1 | 金额:500.0 支持的变体: - 自动清理玩家ID中的§颜色代码 - 自动移除VIP前缀(如vip1, sfvip2) - 自动移除称号(如[萌新], [限制用户])

支持导出为:JSON数据(程序处理)、PDF报告(正式文档)、PNG图表(可视化统计)。

📦 文件管理最佳实践

  • 命名规范:使用日期和类型命名,如 pvp_2025-01-10.log
  • 定期清理:结果文件24小时后自动删除,重要文件请及时下载备份
  • 压缩上传:大文件建议先用7-Zip或WinRAR压缩为.gz格式,上传更快且节省带宽
  • 文件备份:原始日志文件请保留,分析器不会修改或删除它们
  • 批量处理:可以一次性上传多个客户端的日志,系统会自动合并和去重
📡

WebSocket实时通信

分析器支持WebSocket实时推送进度,相比传统轮询方式更及时且节省服务器资源。

// JavaScript客户端示例 const ws = new WebSocket('ws://localhost:8000/ws/progress'); ws.onmessage = (event) => { const data = JSON.parse(event.data); console.log(`任务 ${data.task_id}: ${data.progress}`); // 更新进度条 const progressBar = document.getElementById('progress-bar'); const percent = parseInt(data.progress); if (!isNaN(percent)) { progressBar.style.width = `${percent}%`; } }; ws.onclose = () => { console.log('[WebSocket] 连接关闭,5秒后重连...'); setTimeout(connectWebSocket, 5000); };

💡 优势说明

  • 实时性:分析进度实时推送,无需客户端频繁轮询
  • 节省资源:减少HTTP请求,降低服务器负载
  • 自动重连:网络中断后自动恢复连接
  • 断线续传:重连后自动同步最新进度
🛡️

审计日志查询工具

系统内置完整的审计系统,记录所有操作行为。管理员可使用命令行工具查询:

# 查询最近24小时的上传行为 python audit_tool.py query --action upload # 查询特定IP的所有行为 python audit_tool.py query --ip 192.168.1.100 --hours 48 # 显示灰名单IP(可疑行为超过10次) python audit_tool.py graylist # 查看黑名单 python audit_tool.py blacklist # 解封IP python audit_tool.py unblock 192.168.1.100 # 导出错误日志 python audit_tool.py export errors.json --hours 48 --actions error,critical # 清理30天前的旧数据 python audit_tool.py clear 30

🔍 审计日志包含的信息

  • 时间戳:记录操作发生的精确时间
  • IP地址:客户端IP(支持X-Forwarded-For)
  • 操作类型:upload/analyze/download/error/suspicious/blocked
  • 任务ID:关联的分析任务
  • 详细描述:操作的具体信息
  • 严重级别:info/warning/critical
  • 用户代理:客户端浏览器/工具信息

常见问题(FAQ)

Q: 上传文件后一直显示"等待中",怎么办?
A: 首先检查文件大小是否超过100MB限制。如果文件正常,尝试刷新页面重新上传。若问题持续,可能是服务器负载较高,请等待几分钟后重试。也可以尝试将大文件压缩为.gz格式后再上传。
Q: 分析完成后下载的文件打不开?
A: 请确认您的设备安装了相应软件:Excel文件需要Microsoft Excel或WPS,PDF需要PDF阅读器(如Adobe Reader),PNG图片可直接在浏览器查看。如果文件名乱码,请手动修改扩展名为正确的格式(.xlsx/.pdf/.png)。
Q: 分析结果中数据量很少,正常吗?
A: 这取决于您的日志文件。如果日志中PvP或商会记录较少,结果自然也会少。检查日志时间范围和游戏活动频率,确保选择了正确的分析模式。也可以尝试上传更长时间的日志文件。
Q: 可以同时上传多个玩家客户端的日志吗?
A: 完全可以!分析器会自动合并所有日志并去重。建议将不同客户端的日志一起上传,以获得更全面的统计结果。系统使用MD5哈希确保同一事件在不同文件中只被计算一次。
Q: 分析结果中的"∞"符号是什么意思?
A: 这是K/D比率的特殊标识,表示该玩家击杀数大于0但死亡数为0(完美战绩),在排行榜中会优先显示。这是MC部落日志分析器的特色功能之一。
Q: 为什么我的日志文件被拒绝了?
A: 系统会进行严格的内容验证,常见原因包括:
  • 文件格式不正确(必须是.log.gz
  • 日志内容不符合Minecraft日志格式(验证特征率需≥15%)
  • 文件熵值过高(>7.5,可能是压缩或加密文件)
  • 包含二进制代码或危险文件签名
  • 文件为空或损坏
🔧

故障排查指南

🚨 页面无法打开

  • 检查服务器地址是否正确,确认协议(http/https)和端口(默认8000)
  • 确认服务器正在运行(联系管理员检查进程:ps aux | grep main_web.py
  • 检查网络连接是否正常,尝试ping服务器IP
  • 尝试清除浏览器缓存或换用其他浏览器(推荐Chrome/Edge)
  • 检查防火墙设置,确保端口8000已开放

📤 上传失败或超时

  • 检查文件是否为.log.gz格式,不支持.txt或其他格式
  • 确认文件未被其他程序占用(如记事本、日志查看器)
  • 检查文件大小是否超过100MB限制,总大小不超过500MB
  • 尝试减少单次上传的文件数量,分批上传
  • 大文件先压缩为.gz格式,可大幅减少上传时间
  • 检查网络稳定性,WiFi信号弱时建议使用有线连接

🆘 问题仍未解决?

请按照以下步骤收集信息并联系技术支持:

  1. 记录完整的错误信息(截图或复制文本)
  2. 获取任务ID(如果已生成)
  3. 记录操作步骤和时间
  4. 准备相关日志文件(如果可能)
  5. 访问技术支持网站或联系服务器管理员
🏗️

系统架构概述

┌─────────────────────────────────────────────────────────────────────┐ │ Web客户端 (浏览器) │ │ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │ │ │ 上传页面 │◄────────┤ 分析页面 │◄─────── ┤ API文档 │ │ │ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │ │ │ │ │ │ └─────────┼───────────────────────┼────────────────────────┼─────────—┘ │ │ │ ▼ ▼ │ ┌────────────────────────────────────────────────────────────────────┐│ │ FastAPI服务器 (uvicorn) - 异步处理 + WebSocket实时推送 ││ │ ┌──────────────────────────────────────────────────────────────┐ ││ │ │ 安全中间件:速率限制 + 灰名单 + 内容验证 + 路径防护 │ ││ │ └──────────────────────┬───────────────────────────────────────┘ ││ │ │ ││ │ ┌──────────────────────┴────────────────────┐ ││ │ │ API路由层 │ ││ │ │ ┌──────────┬──────────┬─────────┐ │ ││ │ │ │/api/upload│/api/**/*│/ws/... │ │ ││ │ │ └────┬─────┴────┬─────┴────┬────┘ │ ││ │ └───────┼──────────┼──────────┼─────────────┘ ││ │ │ │ │ ││ │ ┌───────┴──────┐ │ │ ││ │ │ 后台任务池 │ │ │ SQLite审计数据库 ││ │ │ 最大3并发 │ │ │ ┌────────────────────────────┐ ││ │ └───────┬──────┘ │ │ │ audit_log + ip_graylist │ ││ │ │ │ │ │ rate_limits + 自动清理 │ ││ │ ┌───────▼──────────▼──────┐ │ └────────────────────────────┘ ││ │ │ 核心分析引擎 │ │ ││ │ │ ┌────────┬────────┐ │ │ ││ │ │ │PvP解析 │Shop解析│ │ │ ││ │ │ └────┬───┴────┬───┘ │ │ 文件系统 ││ │ └───────┼────────┼────────┘ │ ┌────────────────────────────┐ ││ │ │ │ │ │ /web_uploads/{task_id}/ │ ││ │ ┌───────▼────────▼──────┐ │ │ /web_results/*.xlsx/pdf │ ││ │ │ 导出引擎 │ │ │ 24小时后自动清理 │ ││ │ │ Excel/PDF/PNG/JSON │ │ └────────────────────────────┘ ││ │ └───────────────────────┘ └────────────────────────────────—──┘│ └─────────────────────────────────────────────────────────────────────┘

关键技术特性:

  • 异步处理:基于FastAPI的BackgroundTasks,支持并发但限制3个任务防止资源耗尽。使用async/await实现非阻塞I/O。
  • 内存解压:Windows平台使用io.BytesIO内存解压,避免临时文件锁定问题。Linux/macOS使用临时文件+自动清理。
  • 智能去重:基于MD5哈希的事件去重,确保跨文件重复数据被识别。哈希基于时间戳+事件类型+原始文本生成。
  • 审计追踪:完整的SQLite审计系统,记录所有操作便于安全分析。支持按时间、IP、行为类型筛选。
  • 灰名单机制:替代传统黑名单,更温和地处理可疑IP行为。达到阈值后仅加强监控,不直接封禁。
  • 跨平台适配:自动检测Windows/macOS/Linux,调整工作进程数和监听地址。
📝

日志格式技术说明

🗡️ PvP击杀格式(正则匹配)

主要匹配规则: 1. 必须包含: [main/INFO] [net.minecraft.client.gui.GuiNewChat]: [CHAT] 2. 必须包含: "击杀了" 关键词 3. 标准格式: ?受害者 被 击杀者 使用 [武器] 击杀了! 4. 简化格式: 受害者 被 击杀者 击杀了 解析流程: 1. 检测关键词匹配 (matching_rules) 2. 分割文本提取时间戳、玩家ID 3. 清理§颜色代码和称号前缀 4. 生成PvPEvent对象 5. MD5哈希去重处理 特殊处理: - 自动移除玩家ID中的VIP前缀 (vip1, sfvip2, etc.) - 自动移除称号 ([萌新], [限制用户], etc.) - 处理Minecraft颜色代码 §x - 支持全角冒号和半角冒号混用

🏪 商会交易格式(严格解析)

收购格式: [时间] [main/INFO] [CHAT] 收购: 玩家:{ID} | 商品:{名称} | 数量:{数字} | 金额:{浮点数} 出售格式: [时间] [main/INFO] [CHAT] 出售: 玩家:{ID} | 商品:{名称} | 数量:{数字} | 金额:{浮点数} 解析流程: 1. 检测"收购:"或"出售:"关键词 2. 提取玩家ID(自动清理VIP前缀和称号) 3. 按" | "分割获取商品/数量/金额 4. 验证数据完整性(数量>0, 金额≥0) 5. 生成ShopEvent对象 6. 累计计算玩家和商品统计 特殊处理: - 商品名称支持Minecraft符号(Ⅰ-Ⅹ等级符号) - 自动转换全角数字为半角 - 支持科学计数法金额(自动转换) - 商品名称清理颜色代码和非法字符

🔍 内容验证机制

严格验证流程(上传接口): 1. 速率限制检查(IP+行为类型) ├─ 超限 → 记录suspicious事件 → 返回429 └─ 正常 → 继续 2. 文件大小验证 ├─ 总大小>500MB → 返回413 ├─ 单文件>100MB → 返回413 └─ 正常 → 继续 3. 文件扩展名验证 ├─ 不在白名单 → 返回400 └─ 正常 → 继续 4. 内容验证(严格模式) ├─ 采样检查(前1000行+随机位置) ├─ 计算日志格式匹配率(需≥15%) ├─ 熵值检测(≤7.5) └─ 二进制签名检测 ├─ 失败 → 返回400,记录blocked事件 └─ 通过 → 继续 5. GZIP文件处理 ├─ 内存解压(Windows)或临时文件解压(Linux/macOS) ├─ 验证压缩比(≤1000倍) └─ 验证解压后大小(≤5GB,软限制) 6. 保存文件到任务隔离目录 7. 记录upload审计事件 8. 返回task_id和文件信息

性能优化与部署建议

🔧 配置优化

  • 并发任务控制:通过 MAX_CONCURRENT_TASKS=3 限制并发分析数,防止CPU和内存耗尽。可根据服务器配置调整为2-5。
  • 内存限制:建议设置 MAX_DECOMPRESSED_SIZE=5GB,超过仅记录警告而不阻止。对于超大日志服务器可调整为10GB。
  • 清理策略:通过 CLEANUP_INTERVAL_HOURS=1RESULT_TTL_HOURS=24 控制磁盘占用。高频使用场景可缩短TTL为12小时。
  • 速率限制:根据服务器性能调整 RATE_LIMIT_UPLOADRATE_LIMIT_ANALYZE。内网部署可适当放宽限制。
  • 工作进程数:WORKERS在Linux生产环境可设为CPU核心数,Windows强制为1避免socket冲突。

🐳 Docker部署建议

FROM python:3.11-slim WORKDIR /app # 安装中文字体(PDF导出必需) RUN apt-get update && apt-get install -y \ fonts-noto-cjk \ fonts-noto-color-emoji \ && rm -rf /var/lib/apt/lists/* # 复制依赖文件 COPY requirements_web.txt . RUN pip install --no-cache-dir -r requirements_web.txt # 复制项目文件 COPY . . RUN mkdir -p resources web_uploads web_results # 设置环境变量 ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 # 创建非root用户运行(安全最佳实践) RUN useradd -m -u 1000 mcuser && \ chown -R mcuser:mcuser /app USER mcuser EXPOSE 8000 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8000/ || exit 1 CMD ["python", "main_web.py"] # Docker构建和运行命令: # docker build -t mc-log-analyzer:v3.0.2 . # docker run -d -p 8000:8000 -v /path/to/data:/app/data --name mc-analyzer mc-log-analyzer:v3.0.2

🔄 反向代理配置(Nginx)

# 生产环境Nginx配置示例 server { listen 443 ssl http2; server_name mclans.sakurain.net; ssl_certificate /etc/nginx/ssl/mc-analyzer.crt; ssl_certificate_key /etc/nginx/ssl/mc-analyzer.key; ssl_protocols TLSv1.2 TLSv1.3; # 限制请求体大小(500MB) client_max_body_size 500M; # 超时设置(WebSocket需要长连接) proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 86400s; location / { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; # WebSocket支持 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 真实IP传递 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 缓冲区设置(大文件下载) proxy_buffering off; proxy_request_buffering off; } # 限制访问频率(可选) limit_req_zone $binary_remote_addr zone=api:10m rate=50r/m; location /api/ { limit_req zone=api burst=10 nodelay; proxy_pass http://127.0.0.1:8000/api/; } } # HTTP重定向到HTTPS server { listen 80; server_name mclans.sakurain.net; return 301 https://$server_name$request_uri; }

💡 生产环境建议

  • 使用Gunicorn+Uvicorn多进程部署,WORKERS=4(4核CPU推荐)
  • 启用HTTPS和HTTP/2,提升安全性和传输效率
  • 定期备份security.db审计数据库到远程存储
  • 监控磁盘空间,上传和结果目录可能占用大量空间
  • 使用systemd管理服务,确保崩溃后自动重启
  • 配置日志轮转,防止uvicorn日志文件过大
🛡️

安全机制详解

📊 审计日志系统

所有操作记录在SQLite数据库中,包含以下表结构:

-- audit_log表(审计日志) CREATE TABLE audit_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TEXT NOT NULL, -- ISO 8601时间戳 ip_address TEXT NOT NULL, -- 客户端IP(支持X-Forwarded-For) action TEXT NOT NULL, -- 行为类型(upload/analyze/download/error/suspicious/blocked) task_id TEXT, -- 关联任务ID(UUID) details TEXT NOT NULL, -- 详细描述(JSON格式) severity TEXT NOT NULL, -- 严重级别(info/warning/critical) user_agent TEXT, -- 用户代理字符串 metadata TEXT -- 元数据JSON ); -- ip_graylist表(灰名单) CREATE TABLE ip_graylist ( ip_address TEXT PRIMARY KEY, first_seen TEXT NOT NULL, last_seen TEXT NOT NULL, suspicious_count INTEGER NOT NULL DEFAULT 0, reasons TEXT NOT NULL DEFAULT '[]' -- 可疑原因数组(JSON) ); -- rate_limits表(速率限制) CREATE TABLE rate_limits ( ip_address TEXT NOT NULL, action_type TEXT NOT NULL, count INTEGER NOT NULL DEFAULT 0, window_start TEXT NOT NULL, PRIMARY KEY (ip_address, action_type) ); -- 索引优化 CREATE INDEX idx_audit_timestamp ON audit_log(timestamp DESC); CREATE INDEX idx_audit_ip_action ON audit_log(ip_address, action); CREATE INDEX idx_graylist_count ON ip_graylist(suspicious_count DESC);

🚦 灰名单机制

  • 设计理念:替代传统黑名单,采用更温和的方式处理可疑行为,避免误封有效用户
  • 触发条件:速率超限、内容验证失败、路径遍历尝试、超高压缩比等
  • 监控阈值:GRAYLIST_THRESHOLD=10(默认10次),可在.env.web中自定义
  • 处理策略:不自动封禁IP,仅记录加强监控。管理员可通过audit_tool.py主动审查
  • 过期机制:灰名单IP 24小时无新可疑行为后自动从监控列表中移除(仍可查询历史记录)

⚠️ 公网部署安全警告

当前版本无内置用户认证,部署到公网时请务必实施以下安全措施:

  • 使用Nginx反向代理添加Basic Auth或JWT认证
  • 限制来源IP访问(防火墙白名单),仅允许可信IP段
  • 定期审计security.db,关注可疑行为超过20次的IP
  • 启用HTTPS并配置HSTS,防止中间人攻击
  • 不要在日志中包含敏感信息(如密码、Token)
  • 考虑添加WAF(Web应用防火墙)防护
🐛

高级故障排查

📊 性能瓶颈分析

  • CPU占用高:分析过程涉及大量正则匹配(O(n)复杂度)和MD5计算,属正常现象。可通过MAX_CONCURRENT_TASKS限制并发。
  • 内存占用高:大文件解压和事件去重会占用内存(每个事件约200-500字节)。建议设置MAX_DECOMPRESSED_SIZE软限制。
  • 磁盘I/O高:频繁的文件读写操作。使用SSD可显著提升性能50%以上。考虑使用tmpfs存储临时文件。
  • WebSocket断开:网络不稳定或Nginx超时设置过短。调整nginx.conf中proxy_read_timeout 86400;

🔍 日志分析失败深度排查

排查步骤: 1. 检查uvicorn日志(标准输出或 systemd journal) journalctl -u mc-analyzer -f 2. 查询审计日志中的blocked记录 python audit_tool.py query --action blocked --hours 24 3. 检查具体任务日志 sqlite3 security.db "SELECT * FROM audit_log WHERE task_id='xxx'" 4. 验证日志编码(非GBK编码会解析失败) file -i player.log (输出应包含: charset=gbk 或 charset=utf-8) 5. 测试小文件确认基础功能 head -n 1000 player.log > test.log 上传test.log测试 6. 检查事件是否被去重 - 查看进度日志中的"去重X条"提示 - 相同内容的事件在不同文件中只算一次 7. 验证Python版本和依赖 python --version # 必须≥3.8 pip list | grep -E "(pandas|openpyxl|reportlab|matplotlib)"

🛠️ 调试工具与命令

# 查看实时uvicorn日志 tail -f uvicorn.log # 查询特定IP的审计记录 python audit_tool.py query --ip 192.168.1.100 --hours 48 # 查询错误日志(critical级别) python audit_tool.py query --action error --severity critical --limit 100 # 查看灰名单统计 python audit_tool.py graylist # 手动清理过期文件 curl -X DELETE http://localhost:8000/api/cleanup # 测试API连通性 curl http://localhost:8000/api/status/test # 查看系统资源占用 htop # CPU/内存 iostat -x 1 # 磁盘I/O netstat -anp | grep 8000 # 网络连接 # 数据库维护(定期执行) sqlite3 security.db "VACUUM;" # 压缩数据库 sqlite3 security.db "REINDEX;" # 重建索引
🔌

扩展开发指南

🎯 添加新的日志解析器

# 步骤1: 继承LogsReader基类 from core.base import LogsReader, LogEvent class CustomLogsReader(LogsReader): def __init__(self, logs_paths: List[str]): super().__init__(logs_paths) self.keywords = ['[特定行为]', '关键词2'] # 匹配关键词 def matching_rules(self, text: str) -> bool: # 返回True如果该行日志匹配目标事件 return any(keyword in text for keyword in self.keywords) def parse_event(self, text: str) -> Optional[LogEvent]: try: # 解析时间戳 timestamp = text.split()[0][1:-1] # 提取关键信息(根据你的日志格式) player_id = self._extract_player_id(text) action_type = self._extract_action(text) return CustomEvent( timestamp=timestamp, player_id=player_id, action=action_type, raw_text=text ) except Exception as e: print(f"解析失败: {text[:60]}... - {e}") return None def export(self, output_path: str, format: str = 'json'): # 实现导出逻辑 if format == 'json': from exporters.json_exporter import CustomJsonExporter exporter = CustomJsonExporter() return exporter.export(self.events, output_path) elif format == 'excel': from exporters.excel_exporter import CustomExcelExporter exporter = CustomExcelExporter() return exporter.export(self.events, output_path) else: raise ValueError(f"不支持的格式: {format}")

📦 添加新的导出格式

# 步骤1: 在exporters/目录创建新文件 # exporters/csv_exporter.py from typing import List import csv import os from datetime import datetime from core.models import PvPEvent class PvPCsvExporter: """PvP CSV导出器""" def export(self, events: List[PvPEvent], output_path: str) -> str: if not events: print("没有PvP事件可导出") return "" filename = f"PvP_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" filepath = os.path.join(output_path, filename) with open(filepath, 'w', encoding='gbk', newline='') as f: writer = csv.writer(f) writer.writerow(['击杀时间', '击杀者', '被击杀者']) # 表头 for event in events: writer.writerow([event.timestamp, event.winner, event.loser]) return filepath # 步骤2: 在parser中添加导出分支 # parsers/pvp_parser.py elif format == 'csv': from exporters.csv_exporter import PvPCsvExporter exporter = PvPCsvExporter() return exporter.export(self.events, output_path)

💡 开发建议

  • 遵循PEP 8编码规范,使用black或autopep8自动格式化
  • 强制类型提示,使用mypy进行静态类型检查
  • 新功能添加单元测试,覆盖率目标80%+
  • 更新README和API文档,保持文档同步
  • 提交Pull Request前运行安全扫描(bandit)
⬆️