Files
game_server/docs/game_completion_detection_implementation.md
zyh c6e8953960 feat: 更新数据库结构和链接任务逻辑
主要修改:
1. 更新`game.sql`文件,添加`system_config`表并调整多个表的`ENGINE`和`AUTO_INCREMENT`设置。
2. 在`LinkTask`实体中新增`completedPoints`字段,更新状态字段以包含`COMPLETED`状态。
3. 在`LinkTaskMapper`中新增根据设备ID和状态查询链接任务的方法。
4. 在`LinkStatusService`中更新状态描述映射,增加对`COMPLETED`状态的处理。
5. 在`DeviceStatusService`和`ScriptClient`中新增解析设备状态的方法,支持检查设备是否完成游戏。

技术细节:
- 通过数据库结构的更新,增强了系统的配置管理和链接任务的状态处理能力。
- 新增的功能支持更灵活的设备状态监控和任务管理。
2025-08-27 16:00:43 +08:00

5.0 KiB
Raw Blame History

游戏完成检测实现文档

📋 功能概述

实现了两种方式来自动检测游戏是否完成,并在检测到完成时自动更新链接状态为 COMPLETED,同时记录完成时的点数。

🔧 实现方案

方案1: 定时检查空闲设备

  • 触发方式: 每1分钟自动执行
  • 检查逻辑:
    1. 获取所有空闲设备列表
    2. 对每个空闲设备,查找是否有 LOGGED_IN 状态的链接任务使用该设备
    3. 如果找到,则将该链接任务标记为 COMPLETED,并记录当前点数

方案2: 选区请求时检查

  • 触发方式: 用户发起选区请求时
  • 检查逻辑:
    1. 在分配新设备给用户前,先检查该设备是否空闲
    2. 如果设备空闲且有之前的 LOGGED_IN 状态链接任务,则标记为完成
    3. 然后继续正常的选区流程

🗄️ 数据库变更

-- 添加完成时点数字段
ALTER TABLE `link_task` 
ADD COLUMN `completed_points` int UNSIGNED NULL DEFAULT NULL COMMENT '完成时的点数' 
AFTER `first_region_select_at`;

-- 更新状态枚举,添加 COMPLETED 状态
ALTER TABLE `link_task` 
MODIFY COLUMN `status` enum('NEW','USING','LOGGED_IN','COMPLETED','REFUNDED','EXPIRED') 
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NEW';

2. 状态流转图

NEW (新建) 
  ↓
USING (使用中)
  ↓
LOGGED_IN (已登录)
  ↓
COMPLETED (正常完成) ← 新增状态

终态状态: COMPLETED, REFUNDED, EXPIRED

💻 代码实现

1. 核心服务类

DeviceStatusCheckService

  • 负责设备状态检查和链接任务更新逻辑
  • 解析设备状态响应数据 (f0: 点数, f1: 状态)
  • 更新相关链接任务为完成状态

DeviceStatusCheckTask

  • 定时任务类,每分钟执行一次
  • 获取空闲设备列表并逐个检查

2. API 接口更新

ScriptClient

// 新增方法:获取特定设备状态
public Mono<Map<String, Object>> getDeviceStatus(String machineId)

DeviceStatusService

// 新增方法:解析特定设备状态
public Map<String, Object> parseDeviceStatusForMachine(String jsonResponse, String machineId)

LinkTaskMapper

// 新增方法根据设备ID和状态查询链接任务
List<LinkTask> findByMachineIdAndStatus(String machineId, String status);

3. 实体类更新

LinkTask

@TableField("completed_points")
private Integer completedPoints;  // 完成时的点数

📊 数据处理流程

设备状态数据格式

{
    "f0": {
        "val": "900",           // 当前点数
        "time": "2025-08-27 15:49:04"
    },
    "f1": {
        "val": "空闲",          // 设备状态
        "time": "2025-08-27 15:49:01"
    }
}

完成检测逻辑

  1. 获取设备状态: 调用 readAllMsg?文件名=判断分数 接口
  2. 解析状态: 提取 f0(点数) 和 f1(状态) 信息
  3. 判断空闲: 检查 f1.val 是否为 "空闲"
  4. 查找任务: 根据 machine_id 和 status='LOGGED_IN' 查询链接任务
  5. 更新状态: 设置 status='COMPLETED', completed_points=f0.val

🔧 配置说明

定时任务配置

  • 执行频率: 每60秒 (@Scheduled(fixedRate = 60000))
  • 启用方式: 主应用类添加 @EnableScheduling 注解

日志记录

  • 定时检查: DEBUG 级别,避免日志过多
  • 状态更新: INFO 级别,记录重要操作
  • 异常处理: WARN/ERROR 级别,不影响主流程

🚀 部署说明

1. 数据库迁移

# 执行迁移脚本
mysql -u username -p database_name < docs/database_migration_add_completed_points.sql

2. 应用重启

  • 新增的定时任务会在应用启动后自动运行
  • 选区请求的检查逻辑会立即生效

3. 验证方法

  1. 查看日志: 观察定时任务执行日志
  2. 数据库检查: 验证 completed_points 字段是否正确填充
  3. API 测试: 测试选区请求是否正常工作

📈 监控指标

关键日志

  • === 开始定时检查空闲设备 ===
  • 发现 X 个空闲设备: [设备列表]
  • 链接任务 X (代码: X) 已标记为完成,完成点数: X

异常监控

  • 设备状态获取失败
  • JSON 解析异常
  • 数据库更新失败

🔄 扩展性

支持更多设备状态

  • 可扩展 DeviceStatusInfo 类添加更多状态字段
  • 支持不同的完成判断条件

自定义检查频率

  • 通过配置文件调整定时任务执行频率
  • 支持不同环境使用不同配置

完成通知

  • 可扩展添加完成通知功能 (邮件、短信、webhook等)
  • 支持完成统计和报表功能

⚠️ 注意事项

  1. 性能考虑: 定时任务频率不宜过高,避免对系统造成压力
  2. 异常处理: 单个设备检查失败不应影响其他设备的检查
  3. 数据一致性: 使用事务确保状态更新的原子性
  4. 日志管理: 合理设置日志级别,避免日志过多影响性能