1.全局黑名单2.修复help遗漏

This commit is contained in:
2025-10-28 16:25:04 +08:00
parent c761a12377
commit c4be929b3a
4 changed files with 91 additions and 20 deletions

View File

@@ -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