新增赌场系统
This commit is contained in:
267
core/database.py
267
core/database.py
@@ -129,6 +129,54 @@ class Database:
|
||||
)
|
||||
""")
|
||||
|
||||
# 赌场下注记录表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS casino_bets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chat_id INTEGER NOT NULL,
|
||||
game_type TEXT NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
bet_type TEXT NOT NULL,
|
||||
amount INTEGER NOT NULL,
|
||||
multiplier REAL NOT NULL,
|
||||
status TEXT DEFAULT 'pending',
|
||||
result TEXT,
|
||||
win_amount INTEGER,
|
||||
created_at INTEGER NOT NULL,
|
||||
settled_at INTEGER,
|
||||
FOREIGN KEY (user_id) REFERENCES users (user_id)
|
||||
)
|
||||
""")
|
||||
|
||||
# 赌场游戏会话表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS casino_sessions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chat_id INTEGER NOT NULL,
|
||||
game_type TEXT NOT NULL,
|
||||
banker_id INTEGER NOT NULL,
|
||||
min_bet INTEGER NOT NULL,
|
||||
max_bet INTEGER NOT NULL,
|
||||
multiplier REAL NOT NULL,
|
||||
house_fee REAL DEFAULT 0.05,
|
||||
status TEXT DEFAULT 'open',
|
||||
created_at INTEGER NOT NULL,
|
||||
settled_at INTEGER,
|
||||
UNIQUE(chat_id, game_type, status)
|
||||
)
|
||||
""")
|
||||
|
||||
# 创建索引
|
||||
cursor.execute("""
|
||||
CREATE INDEX IF NOT EXISTS idx_casino_bets
|
||||
ON casino_bets(chat_id, game_type, status)
|
||||
""")
|
||||
|
||||
cursor.execute("""
|
||||
CREATE INDEX IF NOT EXISTS idx_casino_sessions
|
||||
ON casino_sessions(chat_id, game_type, status)
|
||||
""")
|
||||
|
||||
logger.info("数据库表初始化完成")
|
||||
|
||||
# ===== 用户相关操作 =====
|
||||
@@ -587,6 +635,225 @@ class Database:
|
||||
rows = cursor.fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
# ===== 赌场相关操作 =====
|
||||
|
||||
def create_casino_session(self, chat_id: int, game_type: str, banker_id: int,
|
||||
min_bet: int, max_bet: int, multiplier: float,
|
||||
house_fee: float = 0.05) -> int:
|
||||
"""创建新的赌场游戏会话
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
game_type: 游戏类型
|
||||
banker_id: 庄家ID
|
||||
min_bet: 最小下注金额
|
||||
max_bet: 最大下注金额
|
||||
multiplier: 赔率
|
||||
house_fee: 抽水率
|
||||
|
||||
Returns:
|
||||
session_id
|
||||
"""
|
||||
cursor = self.conn.cursor()
|
||||
current_time = int(time.time())
|
||||
|
||||
# 检查是否已有活跃的会话
|
||||
cursor.execute("""
|
||||
SELECT id FROM casino_sessions
|
||||
WHERE chat_id = ? AND game_type = ? AND status = 'open'
|
||||
""", (chat_id, game_type))
|
||||
existing = cursor.fetchone()
|
||||
if existing:
|
||||
return existing['id']
|
||||
|
||||
cursor.execute("""
|
||||
INSERT INTO casino_sessions
|
||||
(chat_id, game_type, banker_id, min_bet, max_bet, multiplier, house_fee, status, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, 'open', ?)
|
||||
""", (chat_id, game_type, banker_id, min_bet, max_bet, multiplier, house_fee, current_time))
|
||||
|
||||
return cursor.lastrowid
|
||||
|
||||
def get_active_casino_session(self, chat_id: int, game_type: str) -> Optional[Dict]:
|
||||
"""获取活跃的游戏会话
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
game_type: 游戏类型
|
||||
|
||||
Returns:
|
||||
会话信息字典或None
|
||||
"""
|
||||
cursor = self.conn.cursor()
|
||||
cursor.execute("""
|
||||
SELECT * FROM casino_sessions
|
||||
WHERE chat_id = ? AND game_type = ? AND status = 'open'
|
||||
ORDER BY id DESC LIMIT 1
|
||||
""", (chat_id, game_type))
|
||||
row = cursor.fetchone()
|
||||
|
||||
if row:
|
||||
return dict(row)
|
||||
return None
|
||||
|
||||
def create_casino_bet(self, chat_id: int, game_type: str, user_id: int,
|
||||
bet_type: str, amount: int, multiplier: float) -> int:
|
||||
"""创建下注记录
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
game_type: 游戏类型
|
||||
user_id: 用户ID
|
||||
bet_type: 下注类型
|
||||
amount: 下注金额
|
||||
multiplier: 赔率
|
||||
|
||||
Returns:
|
||||
bet_id
|
||||
"""
|
||||
cursor = self.conn.cursor()
|
||||
current_time = int(time.time())
|
||||
|
||||
cursor.execute("""
|
||||
INSERT INTO casino_bets
|
||||
(chat_id, game_type, user_id, bet_type, amount, multiplier, status, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, 'pending', ?)
|
||||
""", (chat_id, game_type, user_id, bet_type, amount, multiplier, current_time))
|
||||
|
||||
return cursor.lastrowid
|
||||
|
||||
def get_pending_bets(self, chat_id: int, game_type: str) -> List[Dict]:
|
||||
"""获取待结算的下注列表
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
game_type: 游戏类型
|
||||
|
||||
Returns:
|
||||
下注列表
|
||||
"""
|
||||
cursor = self.conn.cursor()
|
||||
cursor.execute("""
|
||||
SELECT * FROM casino_bets
|
||||
WHERE chat_id = ? AND game_type = ? AND status = 'pending'
|
||||
ORDER BY created_at ASC
|
||||
""", (chat_id, game_type))
|
||||
rows = cursor.fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def settle_casino_bets(self, chat_id: int, game_type: str, result: str,
|
||||
banker_id: int) -> Dict:
|
||||
"""结算所有下注
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
game_type: 游戏类型
|
||||
result: 游戏结果('大' 或 '小')
|
||||
banker_id: 庄家ID
|
||||
|
||||
Returns:
|
||||
结算详情字典
|
||||
"""
|
||||
cursor = self.conn.cursor()
|
||||
current_time = int(time.time())
|
||||
|
||||
# 获取活跃会话
|
||||
session = self.get_active_casino_session(chat_id, game_type)
|
||||
if not session:
|
||||
raise ValueError("没有活跃的游戏会话")
|
||||
|
||||
if session['banker_id'] != banker_id:
|
||||
raise ValueError("只有庄家可以结算游戏")
|
||||
|
||||
# 获取所有待结算下注
|
||||
bets = self.get_pending_bets(chat_id, game_type)
|
||||
|
||||
winners = []
|
||||
losers = []
|
||||
total_win = 0
|
||||
|
||||
# 计算输赢
|
||||
for bet in bets:
|
||||
is_win = (bet['bet_type'] == result)
|
||||
if is_win:
|
||||
# 计算赢得金额
|
||||
win_amount = int(bet['amount'] * bet['multiplier'])
|
||||
# 扣除抽水
|
||||
house_fee = session['house_fee']
|
||||
actual_win = int(win_amount * (1 - house_fee))
|
||||
|
||||
winners.append({
|
||||
'user_id': bet['user_id'],
|
||||
'amount': bet['amount'],
|
||||
'win_amount': actual_win,
|
||||
'bet_id': bet['id']
|
||||
})
|
||||
total_win += actual_win
|
||||
else:
|
||||
losers.append({
|
||||
'user_id': bet['user_id'],
|
||||
'amount': bet['amount'],
|
||||
'bet_id': bet['id']
|
||||
})
|
||||
|
||||
# 使用事务确保原子性
|
||||
try:
|
||||
# 更新下注状态
|
||||
for bet in bets:
|
||||
is_win = (bet['bet_type'] == result)
|
||||
if is_win:
|
||||
win_amount = int(bet['amount'] * bet['multiplier'])
|
||||
actual_win = int(win_amount * (1 - session['house_fee']))
|
||||
|
||||
# 发放奖励
|
||||
self.add_points(bet['user_id'], actual_win, 'casino_win',
|
||||
f"赌场游戏{game_type}赢得")
|
||||
|
||||
cursor.execute("""
|
||||
UPDATE casino_bets
|
||||
SET status = 'settled', result = ?, win_amount = ?, settled_at = ?
|
||||
WHERE id = ?
|
||||
""", (result, actual_win, current_time, bet['id']))
|
||||
else:
|
||||
cursor.execute("""
|
||||
UPDATE casino_bets
|
||||
SET status = 'settled', result = ?, settled_at = ?
|
||||
WHERE id = ?
|
||||
""", (result, current_time, bet['id']))
|
||||
|
||||
# 关闭会话
|
||||
cursor.execute("""
|
||||
UPDATE casino_sessions
|
||||
SET status = 'closed', settled_at = ?
|
||||
WHERE id = ?
|
||||
""", (current_time, session['id']))
|
||||
|
||||
return {
|
||||
'winners': winners,
|
||||
'losers': losers,
|
||||
'total_win': total_win,
|
||||
'result': result
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"结算失败: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def close_casino_session(self, chat_id: int, game_type: str):
|
||||
"""关闭游戏会话
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
game_type: 游戏类型
|
||||
"""
|
||||
cursor = self.conn.cursor()
|
||||
current_time = int(time.time())
|
||||
|
||||
cursor.execute("""
|
||||
UPDATE casino_sessions
|
||||
SET status = 'closed', settled_at = ?
|
||||
WHERE chat_id = ? AND game_type = ? AND status = 'open'
|
||||
""", (current_time, chat_id, game_type))
|
||||
|
||||
def close(self):
|
||||
"""关闭数据库连接"""
|
||||
if self._conn:
|
||||
|
||||
Reference in New Issue
Block a user