t branch
Merge branch 'task/add-idiom-chain-game_2025-10-28_1'
This commit is contained in:
@@ -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')` 查询状态
|
- 使用 `get_game_state(0, user_id, 'adventure')` 查询状态
|
||||||
- 如果存在状态:
|
- 如果存在状态:
|
||||||
* 计算剩余时间
|
* 计算剩余时间
|
||||||
* 如果已完成:自动删除状态,允许继续
|
* 如果已完成:提示用户先使用 `.adventure` 回收奖励,不允许炼金(2025-10-31修复:避免奖励丢失,移除自动删除逻辑)
|
||||||
* 如果未完成:返回错误消息,显示剩余时间(X分Y秒)
|
* 如果未完成:返回错误消息,显示剩余时间(X分Y秒)
|
||||||
- 异常处理:捕获状态数据异常,自动清理损坏状态
|
- 异常处理:捕获状态数据异常,自动清理损坏状态
|
||||||
|
|
||||||
@@ -206,7 +224,7 @@ state_data = {
|
|||||||
### 游戏互斥机制
|
### 游戏互斥机制
|
||||||
- 炼金前检查:查询冒险状态
|
- 炼金前检查:查询冒险状态
|
||||||
- 如果冒险进行中:返回错误,显示剩余时间
|
- 如果冒险进行中:返回错误,显示剩余时间
|
||||||
- 如果冒险已完成:自动清理状态,允许炼金
|
- 如果冒险已完成:提示用户先使用 `.adventure` 回收奖励,不允许炼金(修复后:确保奖励不会丢失)
|
||||||
- 状态异常:自动清理,允许继续操作
|
- 状态异常:自动清理,允许继续操作
|
||||||
|
|
||||||
# 最终审查
|
# 最终审查
|
||||||
|
|||||||
@@ -268,6 +268,23 @@ class Database:
|
|||||||
logger.error(f"更新用户名失败: user_id={user_id}, username={username}, error={e}", exc_info=True)
|
logger.error(f"更新用户名失败: user_id={user_id}, username={username}, error={e}", exc_info=True)
|
||||||
return False
|
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]:
|
def get_game_state(self, chat_id: int, user_id: int, game_type: str) -> Optional[Dict]:
|
||||||
|
|||||||
@@ -92,9 +92,9 @@ class AlchemyGame(BaseGame):
|
|||||||
end_time = start_time + cost_time * 60
|
end_time = start_time + cost_time * 60
|
||||||
remaining_seconds = end_time - current_time
|
remaining_seconds = end_time - current_time
|
||||||
|
|
||||||
# 如果冒险已完成,自动清理状态,允许炼金
|
# 如果冒险已完成,提示用户先回收奖励,不允许炼金
|
||||||
if remaining_seconds <= 0:
|
if remaining_seconds <= 0:
|
||||||
self.db.delete_game_state(0, user_id, 'adventure')
|
return f"❌ 你有待回收的冒险奖励!\n\n💡 请先使用 `.adventure` 回收冒险奖励后再进行炼金。"
|
||||||
else:
|
else:
|
||||||
# 冒险未完成,返回错误提示
|
# 冒险未完成,返回错误提示
|
||||||
remaining_minutes = remaining_seconds // 60
|
remaining_minutes = remaining_seconds // 60
|
||||||
|
|||||||
@@ -82,12 +82,10 @@ class GiftGame(BaseGame):
|
|||||||
receiver_id = user['user_id']
|
receiver_id = user['user_id']
|
||||||
|
|
||||||
# 获取接收者名称用于显示
|
# 获取接收者名称用于显示
|
||||||
receiver_user = self.db.get_or_create_user(receiver_id)
|
receiver_name = self.db.get_user_display_name(receiver_id)
|
||||||
receiver_name = receiver_user.get('username', f"用户{receiver_id}")
|
|
||||||
|
|
||||||
# 获取发送者名称用于显示
|
# 获取发送者名称用于显示
|
||||||
sender_user = self.db.get_or_create_user(sender_id)
|
sender_name = self.db.get_user_display_name(sender_id)
|
||||||
sender_name = sender_user.get('username', f"用户{sender_id}")
|
|
||||||
|
|
||||||
# 验证参数
|
# 验证参数
|
||||||
if points <= 0:
|
if points <= 0:
|
||||||
@@ -184,7 +182,7 @@ class GiftGame(BaseGame):
|
|||||||
|
|
||||||
for record in records:
|
for record in records:
|
||||||
timestamp = datetime.fromtimestamp(record['created_at']).strftime('%m-%d %H:%M')
|
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']
|
points = record['points']
|
||||||
message = record.get('message', '')
|
message = record.get('message', '')
|
||||||
|
|
||||||
@@ -214,7 +212,7 @@ class GiftGame(BaseGame):
|
|||||||
|
|
||||||
for record in records:
|
for record in records:
|
||||||
timestamp = datetime.fromtimestamp(record['created_at']).strftime('%m-%d %H:%M')
|
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']
|
points = record['points']
|
||||||
message = record.get('message', '')
|
message = record.get('message', '')
|
||||||
|
|
||||||
|
|||||||
@@ -379,10 +379,12 @@ class IdiomGame(BaseGame):
|
|||||||
text += f"**当前链长**:{state_data['chain_length']}\n\n"
|
text += f"**当前链长**:{state_data['chain_length']}\n\n"
|
||||||
|
|
||||||
user_count = state_data['participants'][str(user_id)]
|
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:
|
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:
|
else:
|
||||||
text += "任何人都可以接龙\n\n"
|
text += "任何人都可以接龙\n\n"
|
||||||
|
|
||||||
@@ -416,7 +418,8 @@ class IdiomGame(BaseGame):
|
|||||||
state_data['next_user_id'] = next_user_id
|
state_data['next_user_id'] = next_user_id
|
||||||
self.db.save_game_state(chat_id, 0, 'idiom', state_data)
|
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:
|
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'):
|
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:
|
else:
|
||||||
text += f"**下一位**:任何人都可以接龙\n\n"
|
text += f"**下一位**:任何人都可以接龙\n\n"
|
||||||
|
|
||||||
@@ -522,7 +526,8 @@ class IdiomGame(BaseGame):
|
|||||||
reverse=True
|
reverse=True
|
||||||
)
|
)
|
||||||
for idx, (uid, count) in enumerate(sorted_participants[:5], 1):
|
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"
|
text += "\n"
|
||||||
|
|
||||||
# 最近成语
|
# 最近成语
|
||||||
@@ -588,7 +593,8 @@ class IdiomGame(BaseGame):
|
|||||||
reverse=True
|
reverse=True
|
||||||
)
|
)
|
||||||
for idx, (uid, count) in enumerate(sorted_participants, 1):
|
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:
|
try:
|
||||||
for _ in range(count):
|
for _ in range(count):
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class PointsGame(BaseGame):
|
|||||||
for i, user in enumerate(leaderboard):
|
for i, user in enumerate(leaderboard):
|
||||||
rank = i + 1
|
rank = i + 1
|
||||||
medal = medals[i] if i < len(medals) else "🏅"
|
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)
|
points = user.get('points', 0)
|
||||||
|
|
||||||
text += f"{medal} **第 {rank} 名** {username}\n"
|
text += f"{medal} **第 {rank} 名** {username}\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user