尝试修复逻辑错误

This commit is contained in:
2025-11-07 11:07:57 +08:00
parent 8eeec67730
commit aef45eb9a4
2 changed files with 144 additions and 28 deletions

View File

@@ -231,6 +231,50 @@ if game_type == 'werewolf':
- 状态:成功
[2025-11-07_10:59:09]
- 已修改:
1. games/werewolf.py - 支持在私聊中使用狼人杀技能方案2实施
- 更改:
1. 新增 _find_player_game(user_id) 方法根据玩家ID查找其参与的游戏
2. 修改 _handle_skill() 方法,支持从私聊中使用技能指令
3. 修改 _wolf_group_chat() 方法,支持从私聊中发送狼人群聊
4. 修改 _private_chat() 方法,支持从私聊中发送玩家私聊
5. 修改 _witch_pass() 方法,支持从私聊中跳过女巫行动
6. 添加日志输出,显示在私聊中使用功能的情况
7. 实现逻辑先尝试用当前chat_id查找游戏群聊场景找不到则通过user_id查找玩家游戏私聊场景
- 原因:
解决私聊中无法使用技能的问题。游戏在群里创建,但玩家需要在私聊中使用技能以保密。
之前的设计只能在游戏所在群使用技能,现在支持在私聊中使用,查找玩家参与的游戏并操作。
- 阻碍因素:
- 状态:成功
[2025-11-07_11:06:58]
- 已修改:
1. games/werewolf.py - 改为全局唯一游戏模式不再按chat_id区分
- 更改:
1. 修改 _get_game_state() 方法查询全局唯一游戏而非根据chat_id查询
2. 新增 _get_game_chat_id() 方法获取全局游戏所在的chat_id
3. 简化 _find_player_game() 方法,使用全局游戏查询
4. 修改 _open_game() 方法,检查全局是否已有游戏(而非仅检查当前群)
5. 简化所有需要查找玩家游戏的方法_handle_skill、_wolf_group_chat、_private_chat、_witch_pass
6. 保持数据库兼容性chat_id列仍然存在并记录游戏创建的群但查询时忽略
7. 实现逻辑:所有查询都获取全局最新的一个狼人杀游戏,不再区分群组
- 原因:
Bot全局只需要一个狼人杀游戏不同群的玩家可以参与同一个游戏。
简化逻辑消除按chat_id区分的复杂性同时保持数据库结构兼容。
- 阻碍因素:
- 状态:成功
# 最终审查
待审查阶段完成...

View File

@@ -138,20 +138,32 @@ class WerewolfGame(BaseGame):
logger.error(f"处理狼人杀指令错误: {e}", exc_info=True)
return f"❌ 处理指令出错: {str(e)}"
def _get_game_state(self, chat_id: int) -> Optional[Dict]:
"""获取游戏状态
def _get_game_state(self, chat_id: int = None) -> Optional[Dict]:
"""获取游戏状态全局唯一忽略chat_id
Args:
chat_id: 会话ID
chat_id: 会话ID(保留参数用于兼容性,实际忽略)
Returns:
游戏状态或None
"""
state = self.db.get_game_state(chat_id, 0, 'werewolf')
if state:
logger.debug(f"获取游戏状态成功: chat_id={chat_id}, status={state['state_data'].get('status')}, phase={state['state_data'].get('phase')}")
return state['state_data']
logger.warning(f"获取游戏状态失败: chat_id={chat_id}, 状态不存在")
# 查询全局唯一的狼人杀游戏不依赖chat_id
cursor = self.db.conn.cursor()
cursor.execute(
"SELECT chat_id, state_data FROM game_states WHERE game_type = ? AND user_id = 0 ORDER BY updated_at DESC LIMIT 1",
('werewolf',)
)
row = cursor.fetchone()
if row:
state_data = json.loads(row['state_data']) if row['state_data'] else None
game_chat_id = row['chat_id']
if state_data:
logger.debug(f"获取全局游戏状态成功: game_chat_id={game_chat_id}, status={state_data.get('status')}, phase={state_data.get('phase')}")
return state_data
logger.warning(f"获取游戏状态失败: 全局无进行中的游戏")
return None
def _save_game_state(self, chat_id: int, state_data: Dict):
@@ -164,6 +176,55 @@ class WerewolfGame(BaseGame):
logger.debug(f"保存游戏状态: chat_id={chat_id}, status={state_data.get('status')}, phase={state_data.get('phase')}")
self.db.save_game_state(chat_id, 0, 'werewolf', state_data)
def _get_game_chat_id(self) -> Optional[int]:
"""获取全局游戏所在的chat_id
Returns:
游戏所在的chat_id如果没有游戏返回None
"""
cursor = self.db.conn.cursor()
cursor.execute(
"SELECT chat_id FROM game_states WHERE game_type = ? AND user_id = 0 ORDER BY updated_at DESC LIMIT 1",
('werewolf',)
)
row = cursor.fetchone()
if row:
return row['chat_id']
return None
def _find_player_game(self, user_id: int) -> tuple[Optional[int], Optional[Dict]]:
"""查找玩家参与的游戏(全局唯一游戏)
Args:
user_id: 玩家用户ID
Returns:
(游戏所在chat_id, 游戏状态数据) 或 (None, None)
"""
# 获取全局游戏状态
state_data = self._get_game_state()
if not state_data:
logger.debug(f"未找到全局游戏")
return None, None
# 只查找进行中的游戏
if state_data.get('status') != 'playing':
logger.debug(f"全局游戏未在进行中: status={state_data.get('status')}")
return None, None
# 检查玩家是否在游戏中
players = state_data.get('players', [])
for player in players:
if player.get('user_id') == user_id:
game_chat_id = self._get_game_chat_id()
logger.debug(f"找到玩家 {user_id} 的游戏: chat_id={game_chat_id}")
return game_chat_id, state_data
logger.debug(f"玩家 {user_id} 未参与全局游戏")
return None, None
def _get_phase_description(self, phase: str) -> Dict[str, str]:
"""获取阶段描述信息
@@ -246,13 +307,13 @@ class WerewolfGame(BaseGame):
Returns:
提示消息
"""
# 检查是否已有游戏
state_data = self._get_game_state(chat_id)
# 检查全局是否已有游戏
state_data = self._get_game_state()
if state_data:
if state_data['status'] == 'playing':
return "⚠️ 已经有游戏正在进行中!"
return "⚠️ 全局已经有游戏正在进行中!"
elif state_data['status'] == 'open':
return "⚠️ 房间已存在!\n\n房间状态:等待玩家加入\n\n玩家可以输入 `.werewolf join` 加入游戏"
return "⚠️ 全局房间已存在!\n\n房间状态:等待玩家加入\n\n玩家可以输入 `.werewolf join` 加入游戏"
# 创建新房间
state_data = {
@@ -481,9 +542,11 @@ class WerewolfGame(BaseGame):
Returns:
提示消息
"""
state_data = self._get_game_state(chat_id)
# 查找玩家参与的游戏(全局唯一)
_, state_data = self._find_player_game(user_id)
if not state_data:
return "❌ 没有正在进行的游戏!"
return "没有参与任何进行的游戏!"
if state_data['status'] != 'playing':
return "❌ 游戏未开始或已结束!"
@@ -534,9 +597,11 @@ class WerewolfGame(BaseGame):
Returns:
提示消息
"""
state_data = self._get_game_state(chat_id)
# 查找玩家参与的游戏(全局唯一)
_, state_data = self._find_player_game(user_id)
if not state_data:
return "❌ 没有正在进行的游戏!"
return "没有参与任何进行的游戏!"
if state_data['status'] != 'playing':
return "❌ 游戏未开始或已结束!"
@@ -584,10 +649,15 @@ class WerewolfGame(BaseGame):
提示消息
"""
logger.debug(f"处理技能 - chat_id: {chat_id}, user_id: {user_id}, skill: {skill}, target_id: {target_id}")
state_data = self._get_game_state(chat_id)
# 查找玩家参与的游戏(全局唯一)
game_chat_id, state_data = self._find_player_game(user_id)
if not state_data:
logger.warning(f"技能处理失败 - 未找到游戏状态: chat_id={chat_id}")
return "❌ 没有正在进行的游戏!"
logger.warning(f"技能处理失败 - 玩家未参与任何游戏: user_id={user_id}")
return "没有参与任何进行的游戏!"
logger.debug(f"找到玩家游戏: game_chat_id={game_chat_id}, user_id={user_id}")
if state_data['status'] != 'playing':
return "❌ 游戏未开始或已结束!"
@@ -605,15 +675,15 @@ class WerewolfGame(BaseGame):
if not player['alive']:
return "❌ 死亡玩家无法使用技能!"
# 根据技能类型处理
# 根据技能类型处理(使用 game_chat_id
if skill == '':
return await self._wolf_kill(chat_id, state_data, player, target_id)
return await self._wolf_kill(game_chat_id, state_data, player, target_id)
elif skill == '':
return await self._seer_check(chat_id, state_data, player, target_id)
return await self._seer_check(game_chat_id, state_data, player, target_id)
elif skill == '':
return await self._witch_save(chat_id, state_data, player, target_id)
return await self._witch_save(game_chat_id, state_data, player, target_id)
elif skill == '':
return await self._witch_poison(chat_id, state_data, player, target_id)
return await self._witch_poison(game_chat_id, state_data, player, target_id)
return "❌ 未知技能"
@@ -817,9 +887,11 @@ class WerewolfGame(BaseGame):
Returns:
提示消息
"""
state_data = self._get_game_state(chat_id)
# 查找玩家参与的游戏(全局唯一)
game_chat_id, state_data = self._find_player_game(user_id)
if not state_data:
return "❌ 没有正在进行的游戏!"
return "没有参与任何进行的游戏!"
if state_data['status'] != 'playing':
return "❌ 游戏未开始或已结束!"
@@ -844,8 +916,8 @@ class WerewolfGame(BaseGame):
if current_phase != 'night_witch':
return f"❌ 当前不是女巫行动阶段!当前阶段:{self._get_phase_description(current_phase)['name']}"
# 自动推进到下一阶段
next_phase_msg = self._advance_phase(chat_id, state_data)
# 自动推进到下一阶段(使用 game_chat_id
next_phase_msg = self._advance_phase(game_chat_id, state_data)
return f"✅ 女巫选择跳过,不行动{next_phase_msg}"