1.全局黑名单2.修复help遗漏
This commit is contained in:
@@ -206,6 +206,32 @@ if game_type == 'idiom':
|
||||
- 阻碍因素:无
|
||||
- 状态:未确认
|
||||
|
||||
## [2025-10-28 15:50:00]
|
||||
- 已修改:games/base.py
|
||||
- 更改:在get_help_message()的成语接龙部分添加黑名单相关指令说明
|
||||
- 添加 `.idiom reject [词语]` - 拒绝词语加入黑名单(仅发起人)
|
||||
- 添加 `.idiom blacklist` - 查看黑名单
|
||||
- 原因:用户反馈.help帮助信息中看不到黑名单机制的使用说明
|
||||
- 阻碍因素:无
|
||||
- 状态:未确认
|
||||
|
||||
## [2025-10-28 15:55:00]
|
||||
- 已修改:games/idiom.py
|
||||
- 已创建:data/idiom_blacklist.json
|
||||
- 更改:将黑名单机制从游戏状态改为全局永久存储
|
||||
1. 创建data/idiom_blacklist.json作为全局黑名单数据文件
|
||||
2. 在IdiomGame.__init__()中添加黑名单文件路径和懒加载变量
|
||||
3. 添加_load_blacklist()方法从文件懒加载全局黑名单
|
||||
4. 添加_save_blacklist()方法保存黑名单到文件
|
||||
5. 修改_validate_idiom()方法检查全局黑名单而非游戏状态中的黑名单
|
||||
6. 修改_start_game()方法移除state_data中的blacklist字段初始化
|
||||
7. 修改_reject_idiom()方法将词语添加到全局黑名单并保存到文件
|
||||
8. 修改_show_blacklist()方法显示全局黑名单,不再依赖游戏状态
|
||||
9. 更新所有提示信息,明确说明是"永久禁用"
|
||||
- 原因:用户要求被拒绝的词语应该永久不可用,而不是仅本局游戏不可用
|
||||
- 阻碍因素:无
|
||||
- 状态:未确认
|
||||
|
||||
# 最终审查
|
||||
|
||||
(待REVIEW模式完成后填写)
|
||||
|
||||
5
data/idiom_blacklist.json
Normal file
5
data/idiom_blacklist.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"blacklist": [],
|
||||
"description": "成语接龙游戏全局黑名单,被拒绝的词语将永久不可使用"
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ def get_help_message() -> str:
|
||||
- `.idiom [成语] @某人` - 接龙并指定下一位
|
||||
- `.idiom stop` - 结束游戏
|
||||
- `.idiom status` - 查看状态
|
||||
- `.idiom reject [词语]` - 拒绝词语加入黑名单(仅发起人)
|
||||
- `.idiom blacklist` - 查看黑名单
|
||||
|
||||
### 其他
|
||||
- `.help` - 显示帮助
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"""成语接龙游戏"""
|
||||
import json
|
||||
import random
|
||||
import logging
|
||||
import time
|
||||
import re
|
||||
from typing import Optional, Tuple, Dict, Any
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple, Dict, Any, List
|
||||
from pypinyin import pinyin, Style
|
||||
from games.base import BaseGame
|
||||
from utils.parser import CommandParser
|
||||
@@ -23,6 +25,8 @@ class IdiomGame(BaseGame):
|
||||
self.starter_idioms = self.config.get('starter_idioms', [
|
||||
"一马当先", "龙马精神", "马到成功", "开门见山"
|
||||
])
|
||||
self._blacklist = None
|
||||
self.blacklist_file = Path(__file__).parent.parent / "data" / "idiom_blacklist.json"
|
||||
|
||||
async def handle(self, command: str, chat_id: int, user_id: int) -> str:
|
||||
"""处理成语接龙指令
|
||||
@@ -93,6 +97,40 @@ class IdiomGame(BaseGame):
|
||||
logger.error(f"处理成语接龙指令错误: {e}", exc_info=True)
|
||||
return f"❌ 处理指令出错: {str(e)}"
|
||||
|
||||
def _load_blacklist(self) -> List[str]:
|
||||
"""懒加载全局黑名单
|
||||
|
||||
Returns:
|
||||
黑名单列表
|
||||
"""
|
||||
if self._blacklist is None:
|
||||
try:
|
||||
if self.blacklist_file.exists():
|
||||
with open(self.blacklist_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
self._blacklist = data.get('blacklist', [])
|
||||
else:
|
||||
self._blacklist = []
|
||||
logger.info(f"黑名单加载完成,共 {len(self._blacklist)} 个词语")
|
||||
except Exception as e:
|
||||
logger.error(f"加载黑名单失败: {e}")
|
||||
self._blacklist = []
|
||||
return self._blacklist
|
||||
|
||||
def _save_blacklist(self):
|
||||
"""保存黑名单到文件"""
|
||||
try:
|
||||
self.blacklist_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
data = {
|
||||
"blacklist": self._blacklist if self._blacklist is not None else [],
|
||||
"description": "成语接龙游戏全局黑名单,被拒绝的词语将永久不可使用"
|
||||
}
|
||||
with open(self.blacklist_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
logger.info(f"黑名单已保存,共 {len(data['blacklist'])} 个词语")
|
||||
except Exception as e:
|
||||
logger.error(f"保存黑名单失败: {e}")
|
||||
|
||||
def _get_pinyin(self, char: str, all_readings: bool = True) -> list:
|
||||
"""获取单字拼音
|
||||
|
||||
@@ -190,9 +228,10 @@ class IdiomGame(BaseGame):
|
||||
if idiom in state_data.get('used_idioms', []):
|
||||
return False, f"❌ 「{idiom}」已经用过了"
|
||||
|
||||
# 检查是否在黑名单
|
||||
if idiom in state_data.get('blacklist', []):
|
||||
return False, f"❌ 「{idiom}」在黑名单中"
|
||||
# 检查是否在全局黑名单
|
||||
blacklist = self._load_blacklist()
|
||||
if idiom in blacklist:
|
||||
return False, f"❌ 「{idiom}」在黑名单中(永久禁用)"
|
||||
|
||||
# 检查拼音匹配
|
||||
current_idiom = state_data.get('current_idiom', '')
|
||||
@@ -245,7 +284,6 @@ class IdiomGame(BaseGame):
|
||||
'last_user_id': user_id, # 发起人可以接第一个
|
||||
'next_user_id': None,
|
||||
'used_idioms': [idiom],
|
||||
'blacklist': [],
|
||||
'chain_length': 1,
|
||||
'participants': {},
|
||||
'history': [
|
||||
@@ -402,9 +440,12 @@ class IdiomGame(BaseGame):
|
||||
if state_data.get('creator_id') != user_id:
|
||||
return "❌ 只有游戏发起人可以执行裁判操作"
|
||||
|
||||
# 添加到黑名单
|
||||
if idiom not in state_data['blacklist']:
|
||||
state_data['blacklist'].append(idiom)
|
||||
# 添加到全局黑名单
|
||||
blacklist = self._load_blacklist()
|
||||
if idiom not in blacklist:
|
||||
blacklist.append(idiom)
|
||||
self._save_blacklist()
|
||||
logger.info(f"词语「{idiom}」已加入全局黑名单")
|
||||
|
||||
# 如果是最后一个成语,回退状态
|
||||
if state_data.get('current_idiom') == idiom and len(state_data['history']) > 1:
|
||||
@@ -438,7 +479,7 @@ class IdiomGame(BaseGame):
|
||||
# 保存状态
|
||||
self.db.save_game_state(chat_id, 0, 'idiom', state_data)
|
||||
|
||||
text = f"✅ 已将「{idiom}」加入黑名单"
|
||||
text = f"✅ 已将「{idiom}」加入全局黑名单(永久禁用)"
|
||||
if state_data.get('current_idiom') != idiom:
|
||||
text += f"\n\n当前成语:{state_data['current_idiom']}"
|
||||
else:
|
||||
@@ -495,27 +536,24 @@ class IdiomGame(BaseGame):
|
||||
return text
|
||||
|
||||
def _show_blacklist(self, chat_id: int) -> str:
|
||||
"""显示黑名单
|
||||
"""显示全局黑名单
|
||||
|
||||
Args:
|
||||
chat_id: 会话ID
|
||||
chat_id: 会话ID(保留参数以保持接口一致性)
|
||||
|
||||
Returns:
|
||||
黑名单信息
|
||||
"""
|
||||
# 获取群状态
|
||||
state = self.db.get_game_state(chat_id, 0, 'idiom')
|
||||
if not state:
|
||||
return "⚠️ 还没有开始游戏呢!"
|
||||
|
||||
state_data = state['state_data']
|
||||
blacklist = state_data.get('blacklist', [])
|
||||
# 加载全局黑名单
|
||||
blacklist = self._load_blacklist()
|
||||
|
||||
if not blacklist:
|
||||
return "📋 黑名单为空"
|
||||
return "📋 全局黑名单为空\n\n💡 发起人可使用 `.idiom reject [词语]` 添加不合适的词语到黑名单"
|
||||
|
||||
text = f"## 📋 黑名单词语\n\n"
|
||||
text = f"## 📋 全局黑名单词语(永久禁用)\n\n"
|
||||
text += f"**共 {len(blacklist)} 个词语**\n\n"
|
||||
text += "、".join(blacklist)
|
||||
text += "\n\n💡 这些词语在所有游戏中都不可使用"
|
||||
|
||||
return text
|
||||
|
||||
|
||||
Reference in New Issue
Block a user