新增赌场系统

This commit is contained in:
2025-10-30 16:11:50 +08:00
parent 4bddd4339f
commit 12aac846cc
6 changed files with 1072 additions and 0 deletions

346
games/casino.py Normal file
View File

@@ -0,0 +1,346 @@
"""赌场游戏模块"""
import logging
from games.base import BaseGame
from utils.parser import CommandParser
from core.database import get_db
logger = logging.getLogger(__name__)
class CasinoGame(BaseGame):
"""赌场游戏"""
def __init__(self):
"""初始化游戏"""
super().__init__()
self.db = get_db()
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
"""处理赌场指令
Args:
command: 完整指令
chat_id: 会话ID
user_id: 用户ID
Returns:
回复消息
"""
try:
# 提取参数
_, args = CommandParser.extract_command_args(command)
args = args.strip().lower()
# 没有参数,显示帮助
if not args:
return self.get_help()
# 解析第一个参数为游戏类型
parts = args.split(maxsplit=1)
game_type = parts[0]
sub_args = parts[1] if len(parts) > 1 else ""
# 根据游戏类型分发
if game_type == '大小':
return await self._handle_bigsmall(sub_args, chat_id, user_id)
elif game_type in ['help', '帮助']:
return self.get_help()
else:
return f"❌ 暂不支持的游戏类型: {game_type}\n\n支持的类型:大小"
except Exception as e:
logger.error(f"处理赌场指令错误: {e}", exc_info=True)
return f"❌ 处理指令出错: {str(e)}"
async def _handle_bigsmall(self, args: str, chat_id: int, user_id: int) -> str:
"""处理大小游戏
Args:
args: 子命令和参数
chat_id: 会话ID
user_id: 用户ID
Returns:
回复消息
"""
if not args:
return self._get_bigsmall_help()
# 解析子命令
parts = args.split(maxsplit=1)
action = parts[0].lower()
sub_args = parts[1] if len(parts) > 1 else ""
if action in ['open', '开启', '开始']:
return await self._open_bigsmall(sub_args, chat_id, user_id)
elif action in ['bet', '下注', '']:
return await self._bet_bigsmall(sub_args, chat_id, user_id)
elif action in ['status', '状态', '查看']:
return await self._status_bigsmall(chat_id)
elif action in ['settle', '结算', '开奖']:
return await self._settle_bigsmall(sub_args, chat_id, user_id)
elif action in ['help', '帮助']:
return self._get_bigsmall_help()
else:
return f"❌ 未知命令: {action}\n\n{self._get_bigsmall_help()}"
async def _open_bigsmall(self, args: str, chat_id: int, user_id: int) -> str:
"""庄家开启大小游戏
Args:
args: 参数字符串 "<最小下注> <最大下注> <赔率>"
chat_id: 会话ID
user_id: 用户ID
Returns:
回复消息
"""
try:
# 解析参数
parts = args.split()
if len(parts) != 3:
return "❌ 参数格式错误!\n\n正确格式:`.赌场 大小 open <最小下注> <最大下注> <赔率>`\n\n示例:`.赌场 大小 open 10 100 2.0`"
try:
min_bet = int(parts[0])
max_bet = int(parts[1])
multiplier = float(parts[2])
except ValueError:
return "❌ 参数必须是数字!"
# 参数验证
if min_bet <= 0 or max_bet <= 0:
return "❌ 下注金额必须大于0"
if min_bet > max_bet:
return "❌ 最小下注不能大于最大下注!"
if multiplier <= 0:
return "❌ 赔率必须大于0"
if max_bet > 10000:
return "❌ 最大下注不能超过10000分"
# 检查是否已有活跃游戏
existing = self.db.get_active_casino_session(chat_id, '大小')
if existing:
return "⚠️ 当前已有进行中的大小游戏,请先结算后再开启新游戏。"
# 创建游戏会话
session_id = self.db.create_casino_session(
chat_id=chat_id,
game_type='大小',
banker_id=user_id,
min_bet=min_bet,
max_bet=max_bet,
multiplier=multiplier,
house_fee=0.05 # 固定5%抽水
)
text = f"## 🎰 大小游戏已开启\n\n"
text += f"**庄家**:用户{user_id}\n\n"
text += f"**最小下注**{min_bet}\n\n"
text += f"**最大下注**{max_bet}\n\n"
text += f"**赔率**{multiplier}\n\n"
text += f"**抽水率**5%\n\n"
text += "---\n\n"
text += "💡 提示:玩家可以使用 `.赌场 大小 bet <大/小> <金额>` 进行下注"
return text
except Exception as e:
logger.error(f"开启游戏失败: {e}", exc_info=True)
return f"❌ 开启游戏失败: {str(e)}"
async def _bet_bigsmall(self, args: str, chat_id: int, user_id: int) -> str:
"""玩家下注
Args:
args: 参数字符串 "<大/小> <下注金额>"
chat_id: 会话ID
user_id: 用户ID
Returns:
回复消息
"""
try:
# 解析参数
parts = args.split()
if len(parts) != 2:
return "❌ 参数格式错误!\n\n正确格式:`.赌场 大小 bet <大/小> <下注金额>`\n\n示例:`.赌场 大小 bet 大 50`"
bet_type = parts[0]
try:
amount = int(parts[1])
except ValueError:
return "❌ 下注金额必须是数字!"
# 验证下注类型
if bet_type not in ['', '']:
return f"❌ 下注类型错误!只支持'''',您输入的是:{bet_type}"
# 检查是否有活跃的会话
session = self.db.get_active_casino_session(chat_id, '大小')
if not session:
return "❌ 当前没有进行中的游戏,请等待庄家开启游戏。"
# 验证下注金额
if amount < session['min_bet']:
return f"❌ 下注金额太小!最小下注:{session['min_bet']}"
if amount > session['max_bet']:
return f"❌ 下注金额太大!最大下注:{session['max_bet']}"
# 检查用户积分
user_points = self.db.get_user_points(user_id)
if user_points['points'] < amount:
return f"❌ 积分不足!需要 {amount} 分,当前可用 {user_points['points']}"
# 扣除积分
if not self.db.consume_points(user_id, amount, 'casino_bet', f"大小游戏下注{bet_type}"):
return "❌ 扣除积分失败!"
# 记录下注
bet_id = self.db.create_casino_bet(
chat_id=chat_id,
game_type='大小',
user_id=user_id,
bet_type=bet_type,
amount=amount,
multiplier=session['multiplier']
)
# 获取更新后的积分
updated_points = self.db.get_user_points(user_id)
text = f"## 🎲 下注成功\n\n"
text += f"**下注类型**{bet_type}\n\n"
text += f"**下注金额**{amount}\n\n"
text += f"**赔率**{session['multiplier']}\n\n"
text += f"**剩余积分**{updated_points['points']}\n\n"
text += "---\n\n"
text += "💡 等待庄家结算结果..."
return text
except Exception as e:
logger.error(f"下注失败: {e}", exc_info=True)
return f"❌ 下注失败: {str(e)}"
async def _status_bigsmall(self, chat_id: int) -> str:
"""查看当前游戏状态
Args:
chat_id: 会话ID
Returns:
状态消息
"""
session = self.db.get_active_casino_session(chat_id, '大小')
if not session:
return "❌ 当前没有进行中的大小游戏"
# 获取所有待结算下注
bets = self.db.get_pending_bets(chat_id, '大小')
# 统计下注情况
bet_big = sum(b['amount'] for b in bets if b['bet_type'] == '')
bet_small = sum(b['amount'] for b in bets if b['bet_type'] == '')
text = f"## 🎰 大小游戏状态\n\n"
text += f"**庄家**:用户{session['banker_id']}\n\n"
text += f"**最小下注**{session['min_bet']}\n\n"
text += f"**最大下注**{session['max_bet']}\n\n"
text += f"**赔率**{session['multiplier']}\n\n"
text += "---\n\n"
text += f"**当前下注统计**\n"
text += f"- 压大:{bet_big} 分({len([b for b in bets if b['bet_type'] == ''])}注)\n"
text += f"- 压小:{bet_small} 分({len([b for b in bets if b['bet_type'] == ''])}注)\n"
text += f"- 总下注:{len(bets)}\n\n"
text += "---\n\n"
text += "💡 庄家可以使用 `.赌场 大小 settle <大/小>` 结算"
return text
async def _settle_bigsmall(self, args: str, chat_id: int, user_id: int) -> str:
"""庄家结算游戏
Args:
args: 结果 "<大/小>"
chat_id: 会话ID
user_id: 用户ID
Returns:
结算结果消息
"""
try:
if not args:
return "❌ 请指定结算结果!\n\n正确格式:`.赌场 大小 settle <大/小>`"
result = args.strip()
if result not in ['', '']:
return f"❌ 结果类型错误!只支持'''',您输入的是:{result}"
# 结算
settlement = self.db.settle_casino_bets(chat_id, '大小', result, user_id)
# 构建结算报告
text = f"## 🎰 大小游戏结算\n\n"
text += f"**结算结果**{result}\n\n"
text += "---\n\n"
text += f"**赢家**{len(settlement['winners'])}\n"
text += f"**输家**{len(settlement['losers'])}\n\n"
# 显示赢家详情
if settlement['winners']:
text += "**赢家明细**\n"
for winner in settlement['winners']:
text += f"- 用户{winner['user_id']}: 下注{winner['amount']}分,赢得{winner['win_amount']}\n"
text += "\n"
# 显示输家详情
if settlement['losers']:
text += "**输家明细**\n"
for loser in settlement['losers']:
text += f"- 用户{loser['user_id']}: 下注{loser['amount']}\n"
text += "\n"
text += "---\n\n"
text += "✅ 游戏已结束,欢迎再次游戏!"
return text
except ValueError as e:
return f"{str(e)}"
except Exception as e:
logger.error(f"结算失败: {e}", exc_info=True)
return f"❌ 结算失败: {str(e)}"
def _get_bigsmall_help(self) -> str:
"""获取大小游戏帮助信息"""
return """## 🎰 大小游戏帮助
### 庄家命令
- `.赌场 大小 open <最小> <最大> <赔率>` - 开启游戏
- 示例:`.赌场 大小 open 10 100 2.0`
### 玩家命令
- `.赌场 大小 bet <大/小> <金额>` - 下注
- 示例:`.赌场 大小 bet 大 50`
- 示例:`.赌场 大小 bet 小 30`
### 通用命令
- `.赌场 大小 status` - 查看当前状态
- `.赌场 大小 settle <大/小>` - 庄家结算(仅庄家)
### 游戏规则
- 玩家下注后积分立即扣除
- 结算后根据结果发放奖励
- 系统抽水5%
- 赔率由庄家设置
"""
def get_help(self) -> str:
"""获取帮助信息"""
return self._get_bigsmall_help()