Files
DanDingNoneBot/danding_bot/plugins/group_horse_racing
Mr.Xia 5df0487b88 fix(测试): 修复完全模拟比赛测试中的消息验证逻辑
- 将消息列表中的消息强制转换为字符串,避免类型错误
- 使用 any() 检查关键消息是否存在,而不是依赖固定索引
- 改进开赛名单和进度消息的验证逻辑
- 修复回合进度条目数量检查的逻辑
2026-04-07 20:38:31 +08:00
..

Group Horse Racing 插件

群赛马插件 - 一个支持群组内多人参与的赛马游戏,集成积分系统和下注功能。

功能概述

这是一个完整的群组赛马游戏系统,支持以下核心功能:

  • 马匹报名:用户可以报名参加赛马比赛
  • 下注系统:支持用户对任意参赛马匹进行下注(含自己的马)
  • 自动比赛:基于随机算法的赛马进程模拟
  • 积分集成:与 danding_points 积分系统无缝集成
  • 自动撤回:支持配置消息自动撤回时间
  • 多房间支持:支持群组和私聊两种模式

命令列表

基础命令

命令 说明 示例
/赛马报名 报名参加赛马比赛 /赛马报名
/赛马开赛 开始比赛需要至少2匹马 /赛马开赛
/赛马帮助 显示帮助信息 /赛马帮助

配置说明

环境变量

所有配置项都可通过环境变量设置,前缀为 GROUP_HORSE_RACING_

# 测试模式
GROUP_HORSE_RACING_TEST_MODE=false

# 测试用户ID集合
GROUP_HORSE_RACING_TESTERS=[]

# 测试群组ID集合
GROUP_HORSE_RACING_TEST_GROUPS=[]

# 允许的群组ID集合
GROUP_HORSE_RACING_ALLOWED_GROUPS=[]

游戏配置

配置项 默认值 说明
PARTICIPANT_REWARD 50 参赛者奖励积分
CHAMPION_REWARD 200 冠军奖励积分
MIN_BET 10 最小下注积分
MIN_ODDS 1.2 最小赔率
RACE_DISTANCE 100 比赛距离
RACE_TICK_INTERVAL 5 比赛更新间隔(秒)

消息撤回配置

可配置不同类型消息的自动撤回时间0表示不撤回

MESSAGE_RECALL = {
    "race_update": 30,        # 比赛更新消息
    "registration": 180,      # 报名确认消息
    "bet_confirm": 180,       # 下注确认消息
    "cancel_confirm": 60,     # 取消确认消息
    "error": 60,              # 错误消息
    "race_result": 0,         # 比赛结果(不撤回)
    "leaderboard": 0,         # 排行榜(不撤回)
    "help": 0,                # 帮助信息(不撤回)
    "odds_display": 0,        # 赔率显示(不撤回)
}

数据库配置

RACE_DB_FILE = "data/group_horse_racing/race.db"

核心模块

models.py

定义了游戏中的数据模型:

  • RoomState房间状态枚举WAITING、RUNNING、FINISHED、INTERRUPTED
  • HorseState马匹状态枚举READY、RACING、FINISHED
  • Horse马匹数据类包含所有者ID、名称、位置、状态
  • Bet下注数据类包含用户ID、马匹名称、下注金额
  • Room:房间数据类,管理马匹、下注、比赛状态
  • RaceResult:比赛结果数据类,记录比赛统计信息

race_engine.py

比赛引擎,负责比赛逻辑:

  • start_race():启动比赛循环
  • _race_loop()主比赛循环每个tick更新马匹位置
  • _determine_champion():确定冠军(处理平局情况)

比赛采用高斯分布随机算法每个tick马匹随机前进一定距离。

points_service.py

积分服务,与 danding_points 插件集成:

  • spend_bet_points():扣除下注积分(支持重试)
  • refund_bet_points():退还下注积分
  • payout_winnings():支付中奖积分
  • reward_participant():奖励参赛者
  • reward_champion():奖励冠军
  • get_balance():获取用户余额

message_service.py

消息服务,处理消息发送和自动撤回:

  • send_with_recall():发送消息并根据配置自动撤回
  • _schedule_recall():异步调度消息撤回
  • clear_pending_recalls():清除待撤回消息任务

room_store.py

房间存储,管理比赛房间的生命周期:

  • 支持并发访问控制使用asyncio.Lock
  • 房间持久化存储
  • 房间清理和过期处理

commands.py

命令处理器,实现所有用户命令:

  • handle_register():处理报名命令
  • handle_start():处理开赛命令
  • handle_help():处理帮助命令

使用流程

基本游戏流程

  1. 报名阶段

    • 用户执行 /赛马报名 命令
    • 系统检查权限和房间容量最多8匹马
    • 成功报名
  2. 下注阶段

    • 用户可对参赛马匹进行下注
    • 下注金额需满足最小下注要求
    • 下注积分从用户账户扣除
    • 可以给自己的马下注
  3. 比赛阶段

    • 房主执行 /赛马开赛 命令
    • 系统启动比赛引擎
    • 每个tick更新马匹位置
    • 首先到达终点的马匹为冠军
  4. 结算阶段

    • 冠军获得冠军奖励
    • 中奖用户获得下注奖金(下注金额 × 赔率)
    • 比赛结果保存到数据库

权限控制

插件支持两种权限模式:

测试模式TEST_MODE=true

  • 仅允许 TEST_GROUPS 中的群组使用
  • 仅允许 TESTERS 中的用户在私聊中使用

正常模式TEST_MODE=false

  • 仅允许 ALLOWED_GROUPS 中的群组使用
  • 私聊中禁用

依赖关系

  • 必需danding_bot.plugins.danding_points - 积分系统插件

数据存储

比赛数据存储在SQLite数据库中

  • 位置:data/group_horse_racing/race.db
  • 存储内容:比赛历史、结果统计、用户数据

并发控制

  • 使用 asyncio.Lock 保证房间操作的线程安全
  • 支持多个房间同时进行比赛
  • 每个房间有独立的锁和异步任务

错误处理

  • 权限检查:无权限时返回错误提示
  • 房间检查:房间不存在或已满时返回错误
  • 参赛人数检查少于2匹马时无法开赛
  • 积分检查:积分不足时下注失败

测试

项目包含 test_commands.py 用于测试各项功能。

扩展建议

  • 支持更多赛马属性(速度、耐力等)
  • 实现赔率动态计算
  • 添加排行榜功能
  • 支持马匹升级系统
  • 实现更复杂的下注规则