Files
abot/plugins/game_task/main.py

550 lines
21 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import random
import logging
from datetime import datetime
from typing import Dict, Any, List, Optional, Tuple
from wcferry import Wcf
from message_util import MessageUtil
from plugin_common.message_plugin_interface import MessagePluginInterface
from plugin_common.plugin_interface import PluginStatus
from utils.decorator.plugin_decorators import plugin_stats_decorator
from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
from utils.decorator.points_decorator import points_reward_decorator
from utils.ai.game_chatgpt_qa import game_question_json, game_answer_json
from db.connection import DBConnectionManager
from db.encyclopedia import EncyclopediaDB
class GameTaskPlugin(MessagePluginInterface):
"""游戏任务插件"""
@property
def name(self) -> str:
return "百科问答"
@property
def version(self) -> str:
return "1.0.0"
@property
def description(self) -> str:
return "百科问答游戏系统,支持问答积分"
@property
def author(self) -> str:
return "Trae AI"
@property
def command_prefix(self) -> Optional[str]:
return "" # 不需要前缀,直接匹配命令
@property
def commands(self) -> List[str]:
return self._commands
def __init__(self):
super().__init__()
def initialize(self, context: Dict[str, Any]) -> bool:
"""初始化插件"""
self.LOG = logging.getLogger(f"Plugin.{self.name}")
self.LOG.info(f"正在初始化 {self.name} 插件...")
# 保存上下文对象
self.wcf = context.get("wcf")
self.event_system = context.get("event_system")
self.message_util: MessageUtil = context.get("message_util")
# 初始化配置
self._commands = self._config.get("GameTask", {}).get("command",
["game", "任务", "/t", "/a", "/s", "/r", "/l", "/h"])
self.command_format = self._config.get("GameTask", {}).get("command-format", """
🎮 百科问答指令:
/s - 加入游戏
/t - 获取任务
/a <任务ID> <答案> - 提交答案
/r - 查看排行榜
/l - 查看活跃任务
/h - 查看未完成任务
""")
self.enable = self._config.get("GameTask", {}).get("enable", True)
# 初始化数据库连接
self.db_manager = DBConnectionManager.get_instance()
self.encyclopedia_db = EncyclopediaDB(self.db_manager)
self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands}")
return True
def start(self) -> bool:
"""启动插件"""
self.LOG.info(f"[{self.name}] 插件已启动")
self.status = PluginStatus.RUNNING
return True
def stop(self) -> bool:
"""停止插件"""
self.LOG.info(f"[{self.name}] 插件已停止")
self.status = PluginStatus.STOPPED
return True
def can_process(self, message: Dict[str, Any]) -> bool:
"""检查是否可以处理该消息"""
if not self.enable:
return False
content = str(message.get("content", "")).strip()
command = content.split(" ")[0]
return command in self._commands
def calculate_reward_points(self, message: Dict[str, Any], success: bool, response: str) -> int:
"""计算奖励积分"""
if not success:
return 0
return int(response)
@plugin_stats_decorator(plugin_name="百科问答")
def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
"""处理消息"""
content = str(message.get("content", "")).strip()
command = content.split(" ")[0].lower()
sender = message.get("sender")
roomid = message.get("roomid", "")
wcf: Wcf = message.get("wcf")
gbm: GroupBotManager = message.get("gbm")
all_contacts = message.get("all_contacts", {})
self.LOG.info(f"插件执行: {self.name}{content}")
# 检查权限
if roomid and gbm.get_group_permission(roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
return False, "没有权限"
try:
# 获取用户昵称
wx_nick_name = all_contacts.get(sender, sender)
if command == "/s":
self._handle_join_game(sender, roomid, wx_nick_name)
return True, "加入游戏成功"
elif command == "/t":
self._handle_get_task(sender, roomid)
return True, "获取任务成功"
elif command == "/a":
# 修改这里,传入整个 message 对象
points = self._handle_submit_answer(message)
return True, str(points)
elif command == "/r":
self._handle_show_rank(sender, roomid)
return True, "显示排行榜成功"
elif command == "/l":
self._handle_show_active_tasks(sender, roomid)
return True, "显示活跃任务成功"
elif command == "/h":
self._handle_list_uncompleted_tasks(sender, roomid)
return True, "列举未完成任务成功"
else:
self.message_util.send_text_msg(f"❌未知命令!\n{self.command_format}",
(roomid if roomid else sender), sender)
return False, "未知命令"
except Exception as e:
self.LOG.error(f"处理消息出错: {e}")
return False, f"处理出错: {e}"
def _handle_join_game(self, sender: str, roomid: str, wx_nick_name: str) -> None:
"""处理加入游戏请求"""
try:
# 检查并添加群聊
if not self.encyclopedia_db.check_group_exists(roomid):
self.encyclopedia_db.add_group(roomid)
self.message_util.send_text_msg(
f"🎉 群 {roomid} 已就位,准备开燥!",
(roomid if roomid else sender),
sender
)
# 检查并添加玩家
player = self.encyclopedia_db.get_player(sender, roomid)
if not player:
self.encyclopedia_db.add_player(sender, roomid, wx_nick_name)
self.message_util.send_text_msg(
f"🎉 哇塞,{wx_nick_name} 你来啦!\n"
f"🌟 群 {roomid} 瞬间燃爆!\n"
f"🎈 快来接任务,秀翻全场!指令: /t",
(roomid if roomid else sender),
sender
)
except Exception as e:
self.LOG.error(f"加入游戏出错: {e}")
self.message_util.send_text_msg(
f"😔 加入游戏出错,请稍后再试!",
(roomid if roomid else sender),
sender
)
def _handle_get_task(self, sender: str, roomid: str) -> None:
"""处理获取任务请求"""
try:
# 获取群内所有玩家
players = self.encyclopedia_db.get_all_players_in_group(roomid)
if not players:
self.message_util.send_text_msg(
f"😔 哎呀,群 {roomid} 静悄悄\n"
f"🌟 快拉小伙伴来嗨吧!",
(roomid if roomid else sender),
sender
)
return
player_dict = {p['player_id']: p['player_name'] for p in players}
if sender not in player_dict:
self.message_util.send_text_msg(
f"😅 嘿,你谁啊?\n"
f"🌟 先用 /s 报名,不然没法玩哦!",
(roomid if roomid else sender),
sender
)
return
task = game_question_json("请出题!")
category = task["category"]
question = task["question"]
answer = task["answer"]
score = int(task["score"])
description = task.get("description", "")
# 创建活跃任务
active_task_id = self.encyclopedia_db.create_active_task(
roomid, question, answer, score, description, sender
)
if not active_task_id:
self.message_util.send_text_msg(
f"😔 任务创建失败,请稍后再试!",
(roomid if roomid else sender),
sender
)
return
self.message_util.send_text_msg(
f"🎁 {player_dict[sender]},你的专属任务闪亮登场!\n"
f"🎀 任务ID: {active_task_id}\n"
f"🎈 问题:[{category}]{question}\n"
f"🌼 积分:{score}\n"
f"🌈 快上答案:/a {active_task_id} 答案",
(roomid if roomid else sender),
sender
)
except Exception as e:
self.LOG.error(f"获取任务出错: {e}")
self.message_util.send_text_msg(
f"😔 获取任务出错,请稍后再试!",
(roomid if roomid else sender),
sender
)
def calculate_game_points(self, message: Dict[str, Any], success: bool, response: str) -> int:
"""计算游戏积分"""
if not success:
return 0
try:
return int(response)
except (TypeError, ValueError):
return 0
# 修复参数问题,确保方法签名与调用方式匹配
@points_reward_decorator(calculate_game_points, "game", "百科答题奖励")
def _handle_submit_answer(self, message: Dict[str, Any]) -> int:
"""处理提交答案请求"""
try:
content = str(message.get("content", "")).strip()
sender = message.get("sender")
roomid = message.get("roomid", "")
parts = content.split(" ", 2)
if len(parts) < 3:
self.message_util.send_text_msg(
f"😅 喂,格式不对啊!\n"
f"🌟 正确姿势:/a [任务ID] [答案]\n"
f"🎈 比如:/a 1 钒",
(roomid if roomid else sender),
sender
)
return 0
task_id = parts[1]
answer = parts[2]
# 获取玩家信息
player = self.encyclopedia_db.get_player(sender, roomid)
if not player:
self.message_util.send_text_msg(
f"😅 嘿,你是路人甲吗?\n"
f"🌟 用 /s 先加入群 {roomid} 吧!",
(roomid if roomid else sender),
sender
)
return 0
player_name = player['player_name']
if not task_id.isdigit():
self.message_util.send_text_msg(
f"😅 喂任务ID得是数字好吗\n"
f"🌟 比如1\n"
f"🎈 别瞎搞,重新来!",
(roomid if roomid else sender),
sender
)
return 0
active_task_id = int(task_id)
# 获取任务信息
task_data = self.encyclopedia_db.get_task_by_id(roomid, active_task_id)
if not task_data:
self.message_util.send_text_msg(
f"😔 哎哟,任务 task_{active_task_id} 不翼而飞啦!\n"
f"🌼 可能被别人抢先一步咯!",
(roomid if roomid else sender),
sender
)
return 0
if task_data['status'] == 'completed':
self.message_util.send_text_msg(
f"😄 哈哈,你慢了一步!\n"
f"🌟 任务 task_{active_task_id} 已经完结\n"
f"🎈 快去抢新任务吧!",
(roomid if roomid else sender),
sender
)
return 0
question = task_data['question']
correct_answer_db = task_data['answer'].lower()
top_score = task_data['score']
holder_id = task_data['holder_id']
# 获取任务持有者信息
holder = self.encyclopedia_db.get_task_holder(roomid, holder_id)
holder_name = holder['player_name'] if holder else "未知玩家"
answer_json = {"question": question, "top_score": str(top_score), "answer": answer}
result = game_answer_json(answer_json)
points = int(result["score"])
description = result["description"]
is_correct = points > 0
# 记录答题历史
self.encyclopedia_db.add_task_history(
roomid, active_task_id, sender, answer, is_correct, points
)
if is_correct:
# 完成任务
self.encyclopedia_db.complete_task(active_task_id)
if sender == holder_id:
self.message_util.send_text_msg(
f"🎉 {player_name} 你是天才吗?\n"
f"🌟 任务:{question}\n"
f"🎈 答对啦,简直无敌!\n"
f"🌈 奖励:{points}\n"
f"🎀 彩蛋:{description}",
(roomid if roomid else sender),
sender
)
else:
self.message_util.send_text_msg(
f"🎉 {player_name} 抢答王上线!\n"
f"🌟 任务:{question}\n"
f"🎈 原主:{holder_name} 被你截胡啦!\n"
f"🌈 狂揽 {points} 分,太骚了!\n"
f"🎀 彩蛋:{description}",
(roomid if roomid else sender),
sender
)
else:
# 扣除积分
self.encyclopedia_db.update_player_points(sender, roomid, -1)
points = -1
self.message_util.send_text_msg(
f"😅 {player_name} 你这是要笑死我吗?\n"
f"🌼 任务:{question}\n"
f"🎈 你答:{answer}\n"
f"🌟 正确答案:{correct_answer_db}\n"
f"🌈 扣 1 分,别哭哦!\n"
f"🎀 提示:{description}\n"
f"🌟 任务ID: {active_task_id} 还能抢救一下!",
(roomid if roomid else sender),
sender
)
return points
except Exception as e:
self.LOG.error(f"提交答案出错: {e}")
self.message_util.send_text_msg(
f"😔 提交答案出错,请稍后再试!",
(roomid if roomid else sender),
sender
)
return 0
def _handle_show_rank(self, sender: str, roomid: str) -> None:
"""处理显示排行榜请求"""
try:
# 获取排行榜
ranks = self.encyclopedia_db.get_player_ranking(roomid, 10)
if not ranks:
self.message_util.send_text_msg(
f"😔 群 {roomid} 冷冷清清\n"
f"🌟 快来一起燥起来吧!",
(roomid if roomid else sender),
sender
)
return
rank_text = f"🎉 群 {roomid} 排行榜Top 10来啦\n"
for i, row in enumerate(ranks, 1):
rank_text += f"🐓 {i}. {row['player_name']}: {row['points']}\n"
self.message_util.send_text_msg(
rank_text,
(roomid if roomid else sender),
sender
)
except Exception as e:
self.LOG.error(f"显示排行榜出错: {e}")
self.message_util.send_text_msg(
f"😔 获取排行榜出错,请稍后再试!",
(roomid if roomid else sender),
sender
)
def _handle_show_active_tasks(self, sender: str, roomid: str) -> None:
"""处理显示活跃任务请求"""
try:
# 获取活跃任务
tasks = self.encyclopedia_db.get_active_tasks_in_group(roomid)
if not tasks:
self.message_util.send_text_msg(
f"😄 群 {roomid} 现在一片祥和\n"
f"🌟 没任务?快用 /t 搞一个!",
(roomid if roomid else sender),
sender
)
return
task_text = f"🎉 群 {roomid} 活跃任务速递:\n"
for task in tasks:
task_text += (
f"🌈 任务ID: task_{task['active_task_id']}\n"
f"🎀 问题:{task['question']}\n"
f"🌼 大佬:{task['player_name']}\n"
)
self.message_util.send_text_msg(
task_text,
(roomid if roomid else sender),
sender
)
except Exception as e:
self.LOG.error(f"显示活跃任务出错: {e}")
self.message_util.send_text_msg(
f"😔 获取活跃任务出错,请稍后再试!",
(roomid if roomid else sender),
sender
)
def _handle_list_uncompleted_tasks(self, sender: str, roomid: str) -> None:
"""处理列举未完成任务请求"""
try:
# 获取未完成任务
tasks = self.encyclopedia_db.get_active_tasks_in_group(roomid)
if not tasks:
self.message_util.send_text_msg(
f"😄 群 {roomid} 全员开挂?\n"
f"🌟 没未完成任务,快用 /t 再战!",
(roomid if roomid else sender),
sender
)
return
task_text = f"🎉 群 {roomid} 未完成任务大曝光:\n"
for task in tasks:
task_text += (
f"🌈 任务ID: task_{task['active_task_id']}\n"
f"🎀 问题:{task['question']}\n"
f"🌼 主人:{task['player_name']}\n"
)
self.message_util.send_text_msg(
task_text,
(roomid if roomid else sender),
sender
)
except Exception as e:
self.LOG.error(f"列举未完成任务出错: {e}")
self.message_util.send_text_msg(
f"😔 获取未完成任务出错,请稍后再试!",
(roomid if roomid else sender),
sender
)
def run_random_task_assignment(self) -> None:
"""定时任务整点触发排除23:00-08:00"""
current_hour = datetime.now().hour
if current_hour >= 23 or current_hour < 9:
self.LOG.info(f"当前时间 {current_hour}:00 在23:00-08:00区间跳过任务发放")
return
try:
# 获取所有群聊
groups = self.encyclopedia_db.get_all_groups()
for group in groups:
group_id = group['group_id']
# 获取群内所有玩家
players = self.encyclopedia_db.get_all_players_in_group(group_id)
if not players:
continue
# 随机选择一个玩家
holder = random.choice(players)
holder_id = holder['player_id']
holder_name = holder['player_name']
# 创建任务
task = game_question_json("请出题!")
category = task["category"]
question = task["question"]
answer = task["answer"]
score = int(task["score"])
description = task.get("description", "")
# 创建活跃任务
active_task_id = self.encyclopedia_db.create_active_task(
group_id, question, answer, score, description, holder_id
)
if active_task_id:
self.message_util.send_text_msg(
f"🎁 新任务来袭,够不够刺激?\n"
f"🎀 任务ID: {active_task_id}\n"
f"🌟 幸运鹅:{holder_name}\n"
f"🎈 问题:[{category}]{question}\n"
f"🌼 积分:{score}\n"
f"🌈 抢答格式:/a {active_task_id} 答案",
group_id
)
except Exception as e:
self.LOG.error(f"定时任务出错: {e}")