Python自动化分析GMH模组日志:打造Among Us玩家数据看板
在GMH模组(The Other Roles)的私服对局中,每场游戏都会生成详细的日志记录。这些数据如果仅靠人工统计,不仅效率低下,还容易出错。本文将带你用Python构建一个自动化分析系统,从原始日志中提取玩家胜率、首刀概率、职业偏好等23项关键指标,并通过可视化报表呈现。
1. 日志解析基础架构设计
GMH模组的日志文件通常位于BepInEx/LogOutput.log,采用实时追加写入模式。我们需要先建立日志解析的基础框架:
python复制import re
from collections import Counter
from datetime import datetime
class LogParser:
def __init__(self, log_path):
self.log_path = log_path
self.raw_logs = []
self.players = {} # 玩家数据存储结构
def load_logs(self):
with open(self.log_path, 'r', encoding='utf-8') as f:
self.raw_logs = f.readlines()
def parse_game_session(self):
"""识别单场游戏的时间范围"""
session_start = None
for i, line in enumerate(self.raw_logs):
if '[Info :The Other Roles GM]' in line:
timestamp = re.search(r'GM\] \[(.*?)\]', line).group(1)
if not session_start:
session_start = (i, timestamp)
else:
yield (session_start, (i, timestamp))
session_start = (i, timestamp)
关键日志特征识别模式:
- 游戏开始标记:
[Info :The Other Roles GM] - 玩家角色分配:
[Role Assign] - 击杀记录:
[MurderPlayer] => 受害者(角色) - 投票记录:
[Vote] Exiled: 玩家名(角色) - 游戏结果:
[Game Result]
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心数据提取算法实现
2.1 玩家身份识别系统
GMH模组包含40+种角色,需要建立完善的分类体系:
python复制ROLE_CATEGORIES = {
'impostor': ['内鬼','黑手党','化形者','隐蔽者','邪恶的黑客','吸血鬼'],
'crewmate': ['船员','市长','工程师','警长','侦探','医生'],
'neutral': ['小丑','律师','纵火犯','秃鹫','狐妖','豺狼']
}
def categorize_role(role_name):
for category, roles in ROLE_CATEGORIES.items():
if any(r in role_name for r in roles):
return category
return 'unknown'
2.2 胜场统计逻辑优化
原始脚本的胜场判断存在边界情况处理不足的问题,我们改进为:
python复制def determine_winner(game_logs):
result_line = next(line for line in reversed(game_logs)
if '[Game Result]' in line)
# 阵营胜利判定
if '内鬼阵营胜利' in result_line:
winning_team = 'impostor'
elif '船员阵营胜利' in result_line:
winning_team = 'crewmate'
else: # 中立胜利
winning_team = 'neutral'
# 遍历玩家结果段
players_section = extract_players_section(game_logs)
winners = []
for line in players_section:
player_name = extract_player_name(line)
role = extract_player_role(line)
# 特殊角色胜利条件判断
if (winning_team == 'impostor' and role in ROLE_CATEGORIES['impostor']) or \
(winning_team == 'crewmate' and role in ROLE_CATEGORIES['crewmate']) or \
(winning_team == 'neutral' and is_neutral_winner(role, result_line)):
winners.append(player_name)
return winners
2.3 首刀/首投检测算法
采用滑动窗口检测技术提高识别准确率:
python复制def detect_first_events(game_logs):
first_kill = None
first_vote = None
for line in game_logs:
if not first_kill and '[MurderPlayer]' in line:
victim = extract_victim_name(line)
first_kill = victim
if not first_vote and '[Vote]' in line:
exiled = extract_exiled_name(line)
first_vote = exiled
if first_kill and first_vote:
break
return first_kill, first_vote
3. 数据分析与可视化呈现
3.1 玩家综合能力评估模型
建立包含多维度的评估体系:
| 指标维度 | 计算方式 | 权重 |
|---|---|---|
| 胜率 | 获胜场次/总参与场次 | 30% |
| 生存率 | 存活场次/总参与场次 | 20% |
| 首刀率 | 被首刀次数/总参与场次 | 15% |
| 首投率 | 被首投次数/总参与场次 | 15% |
| 角色多样性 | 使用不同角色数量 | 10% |
| 击杀效率 | 总击杀数/内鬼场次 | 10% |
python复制def calculate_player_score(player_data):
total_games = player_data['games_played']
score = (
0.3 * (player_data['wins'] / total_games) +
0.2 * (player_data['survivals'] / total_games) -
0.15 * (player_data['first_killed'] / total_games) -
0.15 * (player_data['first_voted'] / total_games) +
0.1 * len(player_data['roles_played']) / 10 +
0.1 * (player_data['kills'] / max(1, player_data['impostor_games']))
)
return round(score * 100, 1)
3.2 自动生成可视化报告
使用Matplotlib生成专业级数据看板:
python复制import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
def generate_dashboard(player_stats):
fig = plt.figure(figsize=(15, 10))
gs = GridSpec(3, 2, figure=fig)
# 胜率分布雷达图
ax1 = fig.add_subplot(gs[0, 0], polar=True)
plot_radar_chart(ax1, player_stats)
# 角色偏好条形图
ax2 = fig.add_subplot(gs[0, 1])
plot_role_distribution(ax2, player_stats)
# 时间序列趋势图
ax3 = fig.add_subplot(gs[1, :])
plot_trend_over_time(ax3, player_stats)
# 玩家关系网络图
ax4 = fig.add_subplot(gs[2, 0])
plot_social_network(ax4, player_stats)
# 关键指标表格
ax5 = fig.add_subplot(gs[2, 1])
plot_key_metrics_table(ax5, player_stats)
plt.tight_layout()
return fig
4. 系统优化与高级功能
4.1 实时监控模式
通过文件监听实现实时数据分析:
python复制from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class LogHandler(FileSystemEventHandler):
def __init__(self, analyzer):
self.analyzer = analyzer
def on_modified(self, event):
if event.src_path.endswith('LogOutput.log'):
self.analyzer.process_new_entries()
def start_realtime_monitoring(log_path):
analyzer = GameAnalyzer(log_path)
observer = Observer()
observer.schedule(LogHandler(analyzer), path=log_path.parent)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
4.2 自动化报告生成
集成Jinja2模板引擎生成HTML报告:
python复制from jinja2 import Environment, FileSystemLoader
def generate_html_report(player_stats):
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('report.html')
context = {
'players': player_stats,
'generated_at': datetime.now().strftime('%Y-%m-%d %H:%M'),
'total_games': sum(p['games_played'] for p in player_stats.values())
}
with open('output/report.html', 'w') as f:
f.write(template.render(context))
4.3 异常检测系统
识别可能的作弊行为模式:
python复制def detect_anomalies(player_stats):
anomalies = []
for name, data in player_stats.items():
# 异常高胜率检测
if data['wins'] / data['games_played'] > 0.8:
anomalies.append(f"{name} 胜率异常高 ({data['win_rate']}%)")
# 角色选择异常检测
if len(set(data['roles_played']) & set(ROLE_CATEGORIES['impostor'])) / \
len(data['roles_played']) > 0.7:
anomalies.append(f"{name} 内鬼角色选择频率异常")
return anomalies
5. 实战案例:从日志到洞察
假设我们分析了一个包含152场对局的日志文件,关键发现:
-
玩家技术水平分层:
- 前20%玩家平均胜率达68%
- 后20%玩家平均胜率仅19%
-
角色平衡性分析:
- 化形者胜率最高(73%)
- 船员基础角色胜率最低(41%)
-
行为模式洞察:
- 首刀集中在3个活跃玩家(占总首刀次数的62%)
- 警长角色平均每场误杀0.3个船员
-
社交关系网络:
mermaid复制graph TD A[玩家A] -->|经常同队| B[玩家B] B -->|经常敌对| C[玩家C] D[玩家D] -->|新人玩家| A
实现这些分析的核心代码结构:
python复制def analyze_gaming_patterns(logs):
# 初始化分析引擎
analyzer = PatternAnalyzer()
# 时间维度分析
time_stats = analyzer.time_distribution(logs)
# 社交网络构建
social_graph = build_social_graph(logs)
# 角色平衡性计算
role_balance = calculate_role_balance(logs)
return {
'time_analysis': time_stats,
'social_graph': social_graph,
'role_balance': role_balance,
'player_clusters': cluster_players(logs)
}
这个自动化分析系统不仅能节省大量手工统计时间,还能发现人工难以察觉的游戏模式规律。通过持续运行分析,可以跟踪玩家水平变化、评估模组更新后的平衡性调整效果,甚至为比赛选拔提供数据支持。
