From 6f05ca98f1240a5f20311e8277dcc37605ac06be Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Fri, 31 Oct 2025 10:30:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=86=92=E9=99=A9?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=90=8E=E4=B8=8D=E5=9B=9E=E6=94=B6=E5=A5=96?= =?UTF-8?q?=E5=8A=B1=E5=B0=B1=E8=BF=9B=E8=A1=8C=E7=82=BC=E9=87=91=E4=BC=9A?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1=E5=A5=96=E5=8A=B1=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-10-29_2_complete-adventure-game.md | 22 +++++++++++++++++-- games/alchemy.py | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.tasks/2025-10-29_2_complete-adventure-game.md b/.tasks/2025-10-29_2_complete-adventure-game.md index 20b5c24..c334576 100644 --- a/.tasks/2025-10-29_2_complete-adventure-game.md +++ b/.tasks/2025-10-29_2_complete-adventure-game.md @@ -122,6 +122,24 @@ WPSBotGame/ - 阻碍因素:无 - 状态:成功 +## 2025-10-31_10:27:59 +- 已修改: + - games/alchemy.py(修复冒险任务完成后自动删除状态导致奖励丢失的bug) +- 更改: + 1. **Bug修复**:修复冒险任务完成后奖励丢失问题 + - **问题**:在 `_perform_alchemy` 中,当检测到冒险任务已完成时,代码会自动删除冒险状态(`self.db.delete_game_state`),但没有发放奖励,导致用户奖励丢失 + - **修复**:移除自动删除逻辑,改为提示用户先使用 `.adventure` 回收奖励 + - **修改前**:冒险完成后自动删除状态,允许炼金(导致奖励丢失) + - **修改后**:冒险完成后提示用户先回收奖励,不允许炼金,确保奖励只能通过 `.adventure` 命令回收 + 2. **行为变更**: + - 冒险进行中:提示剩余时间,不允许炼金(保持不变) + - 冒险已完成:提示先回收奖励,不允许炼金(修复后) + - 用户使用 `.adventure`:发放奖励并删除状态(保持不变) + - 状态已删除:可以正常炼金(保持不变) +- 原因:修复冒险任务完成后自动删除状态导致奖励丢失的严重bug,确保用户必须先主动回收奖励才能继续其他操作 +- 阻碍因素:无 +- 状态:成功 + # 详细实施记录 ## 文件修改清单 @@ -150,7 +168,7 @@ WPSBotGame/ - 使用 `get_game_state(0, user_id, 'adventure')` 查询状态 - 如果存在状态: * 计算剩余时间 - * 如果已完成:自动删除状态,允许继续 + * 如果已完成:提示用户先使用 `.adventure` 回收奖励,不允许炼金(2025-10-31修复:避免奖励丢失,移除自动删除逻辑) * 如果未完成:返回错误消息,显示剩余时间(X分Y秒) - 异常处理:捕获状态数据异常,自动清理损坏状态 @@ -206,7 +224,7 @@ state_data = { ### 游戏互斥机制 - 炼金前检查:查询冒险状态 - 如果冒险进行中:返回错误,显示剩余时间 -- 如果冒险已完成:自动清理状态,允许炼金 +- 如果冒险已完成:提示用户先使用 `.adventure` 回收奖励,不允许炼金(修复后:确保奖励不会丢失) - 状态异常:自动清理,允许继续操作 # 最终审查 diff --git a/games/alchemy.py b/games/alchemy.py index 4209bc0..3ae235c 100644 --- a/games/alchemy.py +++ b/games/alchemy.py @@ -92,9 +92,9 @@ class AlchemyGame(BaseGame): end_time = start_time + cost_time * 60 remaining_seconds = end_time - current_time - # 如果冒险已完成,自动清理状态,允许炼金 + # 如果冒险已完成,提示用户先回收奖励,不允许炼金 if remaining_seconds <= 0: - self.db.delete_game_state(0, user_id, 'adventure') + return f"❌ 你有待回收的冒险奖励!\n\n💡 请先使用 `.adventure` 回收冒险奖励后再进行炼金。" else: # 冒险未完成,返回错误提示 remaining_minutes = remaining_seconds // 60 From 19cde88acf968edf2b32026356d67f9b2504dbd9 Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Fri, 31 Oct 2025 11:07:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3BaseGame.db.get=5Fuser=5Fdisplay=5Fname?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E7=94=A8=E6=88=B7=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/database.py | 17 +++++++++++++++++ games/gift.py | 10 ++++------ games/idiom.py | 18 ++++++++++++------ games/points.py | 2 +- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/core/database.py b/core/database.py index cd9680c..1a2c86c 100644 --- a/core/database.py +++ b/core/database.py @@ -220,6 +220,23 @@ class Database: logger.error(f"更新用户名失败: user_id={user_id}, username={username}, error={e}", exc_info=True) return False + def get_user_display_name(self, user_id: int) -> str: + """获取用户显示名称 + 如果用户已注册(username不为None),返回用户名;否则返回"用户{user_id}" + + Args: + user_id: 用户ID + + Returns: + 用户显示名称(用户名或"用户{user_id}") + """ + user_dict = self.get_or_create_user(user_id) + username = user_dict.get('username') + if username: + return username + else: + return f"用户{user_id}" + # ===== 游戏状态相关操作 ===== def get_game_state(self, chat_id: int, user_id: int, game_type: str) -> Optional[Dict]: diff --git a/games/gift.py b/games/gift.py index 68a591c..376a906 100644 --- a/games/gift.py +++ b/games/gift.py @@ -82,12 +82,10 @@ class GiftGame(BaseGame): receiver_id = user['user_id'] # 获取接收者名称用于显示 - receiver_user = self.db.get_or_create_user(receiver_id) - receiver_name = receiver_user.get('username', f"用户{receiver_id}") + receiver_name = self.db.get_user_display_name(receiver_id) # 获取发送者名称用于显示 - sender_user = self.db.get_or_create_user(sender_id) - sender_name = sender_user.get('username', f"用户{sender_id}") + sender_name = self.db.get_user_display_name(sender_id) # 验证参数 if points <= 0: @@ -184,7 +182,7 @@ class GiftGame(BaseGame): for record in records: timestamp = datetime.fromtimestamp(record['created_at']).strftime('%m-%d %H:%M') - receiver_name = record.get('receiver_name', f"用户{record['receiver_id']}") + receiver_name = self.db.get_user_display_name(record['receiver_id']) points = record['points'] message = record.get('message', '') @@ -214,7 +212,7 @@ class GiftGame(BaseGame): for record in records: timestamp = datetime.fromtimestamp(record['created_at']).strftime('%m-%d %H:%M') - sender_name = record.get('sender_name', f"用户{record['sender_id']}") + sender_name = self.db.get_user_display_name(record['sender_id']) points = record['points'] message = record.get('message', '') diff --git a/games/idiom.py b/games/idiom.py index 15a0384..6968146 100644 --- a/games/idiom.py +++ b/games/idiom.py @@ -379,10 +379,12 @@ class IdiomGame(BaseGame): text += f"**当前链长**:{state_data['chain_length']}\n\n" user_count = state_data['participants'][str(user_id)] - text += f"@用户{user_id} 成功次数:{user_count}\n\n" + user_display_name = self.db.get_user_display_name(user_id) + text += f"@{user_display_name} 成功次数:{user_count}\n\n" if mentioned_user_id: - text += f"已指定 @用户{mentioned_user_id} 接龙\n\n" + mentioned_display_name = self.db.get_user_display_name(mentioned_user_id) + text += f"已指定 @{mentioned_display_name} 接龙\n\n" else: text += "任何人都可以接龙\n\n" @@ -416,7 +418,8 @@ class IdiomGame(BaseGame): state_data['next_user_id'] = next_user_id self.db.save_game_state(chat_id, 0, 'idiom', state_data) - return f"✅ 已指定 @用户{next_user_id} 接龙" + next_user_display_name = self.db.get_user_display_name(next_user_id) + return f"✅ 已指定 @{next_user_display_name} 接龙" def _reject_idiom(self, chat_id: int, user_id: int, idiom: str) -> str: """裁判拒绝词语 @@ -509,7 +512,8 @@ class IdiomGame(BaseGame): # 下一位 if state_data.get('next_user_id'): - text += f"**下一位**:@用户{state_data['next_user_id']}\n\n" + next_user_display_name = self.db.get_user_display_name(state_data['next_user_id']) + text += f"**下一位**:@{next_user_display_name}\n\n" else: text += f"**下一位**:任何人都可以接龙\n\n" @@ -522,7 +526,8 @@ class IdiomGame(BaseGame): reverse=True ) for idx, (uid, count) in enumerate(sorted_participants[:5], 1): - text += f"{idx}. @用户{uid} - {count}次\n" + user_display_name = self.db.get_user_display_name(int(uid)) + text += f"{idx}. @{user_display_name} - {count}次\n" text += "\n" # 最近成语 @@ -588,7 +593,8 @@ class IdiomGame(BaseGame): reverse=True ) for idx, (uid, count) in enumerate(sorted_participants, 1): - text += f"{idx}. @用户{uid} - {count}次\n" + user_display_name = self.db.get_user_display_name(int(uid)) + text += f"{idx}. @{user_display_name} - {count}次\n" # 更新统计 try: for _ in range(count): diff --git a/games/points.py b/games/points.py index d90a125..dbfa79a 100644 --- a/games/points.py +++ b/games/points.py @@ -126,7 +126,7 @@ class PointsGame(BaseGame): for i, user in enumerate(leaderboard): rank = i + 1 medal = medals[i] if i < len(medals) else "🏅" - username = user.get('username', f"用户{user['user_id']}") + username = self.db.get_user_display_name(user['user_id']) points = user.get('points', 0) text += f"{medal} **第 {rank} 名** {username}\n"