👤 非专业人员使用指南
⚡ 专业人员技术说明
三步快速开始
1
访问Web页面
打开浏览器,输入服务器地址(例如: http://localhost:8000 或 https://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信号弱时建议使用有线连接
🆘 问题仍未解决?
请按照以下步骤收集信息并联系技术支持:
- 记录完整的错误信息(截图或复制文本)
- 获取任务ID(如果已生成)
- 记录操作步骤和时间
- 准备相关日志文件(如果可能)
- 访问技术支持网站或联系服务器管理员
系统架构概述
┌─────────────────────────────────────────────────────────────────────┐
│ 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=1和RESULT_TTL_HOURS=24控制磁盘占用。高频使用场景可缩短TTL为12小时。 -
速率限制:根据服务器性能调整
RATE_LIMIT_UPLOAD和RATE_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)