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

177 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 游戏完成检测实现文档
## 📋 功能概述
实现了两种方式来自动检测游戏是否完成,并在检测到完成时自动更新链接状态为 `COMPLETED`,同时记录完成时的点数。
## 🔧 实现方案
### **方案1: 定时检查空闲设备**
- **触发方式**: 每1分钟自动执行
- **检查逻辑**:
1. 获取所有空闲设备列表
2. 对每个空闲设备,查找是否有 `LOGGED_IN` 状态的链接任务使用该设备
3. 如果找到,则将该链接任务标记为 `COMPLETED`,并记录当前点数
### **方案2: 选区请求时检查**
- **触发方式**: 用户发起选区请求时
- **检查逻辑**:
1. 在分配新设备给用户前,先检查该设备是否空闲
2. 如果设备空闲且有之前的 `LOGGED_IN` 状态链接任务,则标记为完成
3. 然后继续正常的选区流程
## 🗄️ 数据库变更
### **1. link_task 表结构更新**
```sql
-- 添加完成时点数字段
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**
```java
// 新增方法:获取特定设备状态
public Mono<Map<String, Object>> getDeviceStatus(String machineId)
```
#### **DeviceStatusService**
```java
// 新增方法:解析特定设备状态
public Map<String, Object> parseDeviceStatusForMachine(String jsonResponse, String machineId)
```
#### **LinkTaskMapper**
```java
// 新增方法根据设备ID和状态查询链接任务
List<LinkTask> findByMachineIdAndStatus(String machineId, String status);
```
### **3. 实体类更新**
#### **LinkTask**
```java
@TableField("completed_points")
private Integer completedPoints; // 完成时的点数
```
## 📊 数据处理流程
### **设备状态数据格式**
```json
{
"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. 数据库迁移**
```bash
# 执行迁移脚本
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. **日志管理**: 合理设置日志级别,避免日志过多影响性能