Files
XiaM-Admin dedc872f1b 功能:通过 HTTP API 实现 Danding_QqPush 插件,用于 QQ 群通知
- 增加了通过外部 HTTP API 向 QQ 群组发送消息的核心功能。
- 实现了对长文本消息的图片渲染,以避免被认定为垃圾信息。
- 支持在消息中提及特定的 QQ 用户。
- 创建了用于 API 令牌和图片渲染设置的配置选项。
- 开发了一个测试脚本以验证 API 功能。
- 对现有代码进行了重构,以提高组织性和可维护性。
2026-01-20 21:19:05 +08:00

762 lines
32 KiB
Python
Raw Permalink 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 os
from nonebot import on_command, on_startswith
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, MessageEvent, Message
from nonebot.adapters.onebot.v11.message import MessageSegment
from nonebot.typing import T_State
from nonebot.rule import Rule
from pathlib import Path
from .config import Config
from .gacha import GachaSystem
from .utils import format_user_mention, get_image_path
from .api_utils import process_ssr_sp_reward, process_achievement_reward
from . import web_api
# 创建Config实例
config = Config()
# 允许的群聊ID和用户ID
ALLOWED_GROUP_ID = config.ALLOWED_GROUP_ID
ALLOWED_USER_ID = config.ALLOWED_USER_ID
GACHA_COMMANDS = config.GACHA_COMMANDS
STATS_COMMANDS = config.STATS_COMMANDS
DAILY_STATS_COMMANDS = config.DAILY_STATS_COMMANDS
TRIPLE_GACHA_COMMANDS = config.TRIPLE_GACHA_COMMANDS
ACHIEVEMENT_COMMANDS = config.ACHIEVEMENT_COMMANDS
INTRO_COMMANDS = config.INTRO_COMMANDS
DAILY_LIMIT = config.DAILY_LIMIT
gacha_system = GachaSystem()
# 检查是否允许使用功能的规则
def check_permission() -> Rule:
async def _checker(event: MessageEvent) -> bool:
# 允许特定用户在任何场景下使用
if event.user_id == ALLOWED_USER_ID:
return True
# 在允许的群聊中任何人都可以使用
if isinstance(event, GroupMessageEvent) and event.group_id == ALLOWED_GROUP_ID:
return True
return False
return Rule(_checker)
# 注册抽卡命令,添加权限检查规则
gacha_matcher = on_command("抽卡", aliases=set(GACHA_COMMANDS), priority=10, rule=check_permission())
@gacha_matcher.handle()
async def handle_gacha(bot: Bot, event: MessageEvent, state: T_State):
user_id = str(event.user_id)
user_name = event.sender.card if isinstance(event, GroupMessageEvent) else event.sender.nickname
# 执行抽卡
result = gacha_system.draw(user_id)
if not result["success"]:
await gacha_matcher.finish(format_user_mention(user_id, user_name) + "" + result["message"])
# 成功抽卡,格式化消息
rarity = result["rarity"]
name = result["name"]
image_url = result["image_url"]
draws_left = result["draws_left"]
unlocked_achievements = result.get("unlocked_achievements", [])
# 构建消息
msg = Message()
# 根据稀有度设置不同的消息样式
if rarity == "SSR":
msg.append(f"🌟✨ 恭喜 {format_user_mention(user_id, user_name)} ✨🌟\n")
msg.append(f"🎊 抽到了 SSR 式神:{name} 🎊\n")
msg.append(f"💫 真是太幸运了!💫")
elif rarity == "SP":
msg.append(f"🌈🎆 恭喜 {format_user_mention(user_id, user_name)} 🎆🌈\n")
msg.append(f"🎉 抽到了 SP 式神:{name} 🎉\n")
msg.append(f"🔥 这是传说中的SP🔥")
elif rarity == "SR":
msg.append(f"⭐ 恭喜 {format_user_mention(user_id, user_name)}\n")
msg.append(f"✨ 抽到了 SR 式神:{name}")
else: # R
msg.append(f"🍀 {format_user_mention(user_id, user_name)} 🍀\n")
msg.append(f"📜 抽到了 R 式神:{name}")
# 添加图片
if image_url and os.path.exists(image_url):
msg.append(MessageSegment.image(f"file:///{get_image_path(image_url)}"))
# 添加成就通知
if unlocked_achievements:
msg.append("\n\n🏆 恭喜解锁新成就!\n")
has_manual_rewards = False
for achievement_id in unlocked_achievements:
# 尝试自动发放成就奖励
auto_success, reward_msg = await process_achievement_reward(user_id, achievement_id)
# 检查是否是重复奖励
if "_repeat_" in achievement_id:
base_achievement_id = achievement_id.split("_repeat_")[0]
achievement_config = config.ACHIEVEMENTS.get(base_achievement_id)
if achievement_config:
achievement_name = achievement_config["name"]
# 使用重复奖励或默认为天卡
reward = achievement_config.get("repeat_reward", "天卡")
status = "✅ 已自动发放" if auto_success else "⚠️ 需手动领取"
msg.append(f"🎖️ {achievement_name} 重复奖励 (奖励:{reward}) {status}\n")
else:
msg.append(f"🎖️ {achievement_id}\n")
else:
achievement_config = config.ACHIEVEMENTS.get(achievement_id)
if achievement_config:
achievement_name = achievement_config["name"]
reward = achievement_config["reward"]
status = "✅ 已自动发放" if auto_success else "⚠️ 需手动领取"
msg.append(f"🎖️ {achievement_name} (奖励:{reward}) {status}\n")
else:
msg.append(f"🎖️ {achievement_id}\n")
# 记录是否有需要手动领取的奖励
if not auto_success:
has_manual_rewards = True
# 如果有未自动发放的奖励,提示联系管理员
if has_manual_rewards:
msg.append("💰 未自动发放的奖励请联系管理员\n")
# 添加成就进度提示
achievement_data = gacha_system.get_user_achievements(user_id)
if achievement_data["success"]:
progress = achievement_data["progress"]
consecutive_days = progress.get("consecutive_days", 0)
no_ssr_streak = progress.get("no_ssr_streak", 0)
msg.append("\n📈 成就进度:\n")
# 连续抽卡天数进度
if consecutive_days > 0:
if consecutive_days < 30:
msg.append(f"📅 勤勤恳恳Ⅰ:{consecutive_days}/30天 🎯\n")
elif consecutive_days < 60:
msg.append(f"📅 勤勤恳恳Ⅱ:{consecutive_days}/60天 🎯\n")
elif consecutive_days < 90:
msg.append(f"📅 勤勤恳恳Ⅲ:{consecutive_days}/90天 🎯\n")
elif consecutive_days < 120:
msg.append(f"📅 勤勤恳恳Ⅳ:{consecutive_days}/120天 ⭐\n")
elif consecutive_days < 150:
msg.append(f"📅 勤勤恳恳Ⅴ:{consecutive_days}/150天 ⭐\n")
else:
next_reward_days = 30 - (consecutive_days % 30)
if next_reward_days == 30:
next_reward_days = 0
if next_reward_days > 0:
msg.append(f"📅 勤勤恳恳Ⅴ (满级){consecutive_days}天,距离下次奖励{next_reward_days}天 🎁\n")
else:
msg.append(f"📅 勤勤恳恳Ⅴ (满级){consecutive_days}天,可获得奖励!🎉\n")
# 无SSR/SP连击进度
if no_ssr_streak > 0:
if no_ssr_streak < 60:
msg.append(f"💔 非酋进度:{no_ssr_streak}/60次 😭\n")
elif no_ssr_streak < 120:
msg.append(f"💔 顶级非酋:{no_ssr_streak}/120次 😱\n")
elif no_ssr_streak < 180:
msg.append(f"💔 月见黑:{no_ssr_streak}/180次 🌙\n")
else:
msg.append(f"💔 已达月见黑级别:{no_ssr_streak}次 🌚\n")
# 添加剩余次数和概率信息
msg.append(f"\n📊 今日剩余抽卡次数:{draws_left}/{DAILY_LIMIT}\n")
msg.append(gacha_system.get_probability_text())
# 如果抽到了SSR或SP处理奖励发放
if rarity in ["SSR", "SP"]:
# 尝试自动发放奖励
auto_success, reward_msg = await process_ssr_sp_reward(user_id)
msg.append(f"\n\n{reward_msg}")
# 通知管理员好友
admin_id = 2185330092
notify_msg = Message()
if auto_success:
notify_msg.append(f"用户 {user_name}({user_id}) 抽中了{rarity}稀有度式神: {name}! 已自动发放奖励!")
else:
notify_msg.append(f"用户 {user_name}({user_id}) 抽中了{rarity}稀有度式神: {name}! 需要手动发放奖励!")
await bot.send_private_msg(user_id=admin_id, message=notify_msg)
else:
msg.append(f"\n\n抽中SSR或SP时可获得蛋定助手天卡一张哦~~")
await gacha_matcher.finish(msg)
async def notify_admin(bot: Bot, message: str):
"""通知管理员"""
admin_id = 2185330092
try:
await bot.send_private_msg(user_id=admin_id, message=message)
except Exception as e:
pass # 忽略通知失败的错误
# 注册查询命令,添加权限检查规则
stats_matcher = on_command("我的抽卡", aliases=set(STATS_COMMANDS), priority=5, rule=check_permission())
# 注册今日统计命令
daily_stats_matcher = on_command("今日抽卡", aliases=set(DAILY_STATS_COMMANDS), priority=5, rule=check_permission())
# 注册三连抽命令
triple_gacha_matcher = on_command("三连抽", aliases=set(TRIPLE_GACHA_COMMANDS), priority=5, rule=check_permission())
# 注册成就查询命令
achievement_matcher = on_command("查询成就", aliases=set(ACHIEVEMENT_COMMANDS), priority=5, rule=check_permission())
@stats_matcher.handle()
async def handle_stats(bot: Bot, event: MessageEvent, state: T_State):
user_id = str(event.user_id)
user_name = event.sender.card if isinstance(event, GroupMessageEvent) else event.sender.nickname
# 获取用户统计
stats = gacha_system.get_user_stats(user_id)
if not stats["success"]:
await stats_matcher.finish(format_user_mention(user_id, user_name) + " " + stats["message"])
# 构建消息
msg = Message()
msg.append(f"📊 {format_user_mention(user_id, user_name)} 的抽卡统计:\n\n")
msg.append(f"🎲 总抽卡次数:{stats['total_draws']}\n\n")
# 稀有度统计
msg.append("🎯 稀有度分布:\n")
msg.append(f"📜 R{stats['R_count']}张 ({stats['R_count']/stats['total_draws']*100:.1f}%)\n")
msg.append(f"⭐ SR{stats['SR_count']}张 ({stats['SR_count']/stats['total_draws']*100:.1f}%)\n")
msg.append(f"🌟 SSR{stats['SSR_count']}张 ({stats['SSR_count']/stats['total_draws']*100:.1f}%)\n")
msg.append(f"🌈 SP{stats['SP_count']}张 ({stats['SP_count']/stats['total_draws']*100:.1f}%)\n")
# 添加最近抽卡记录
if stats["recent_draws"]:
msg.append("\n🕐 最近抽卡记录:\n")
for draw in reversed(stats["recent_draws"]):
# 根据稀有度添加emoji
if draw['rarity'] == "SSR":
emoji = "🌟"
elif draw['rarity'] == "SP":
emoji = "🌈"
elif draw['rarity'] == "SR":
emoji = ""
else:
emoji = "📜"
msg.append(f"{emoji} {draw['rarity']} - {draw['name']} ({draw['date']})\n")
await stats_matcher.finish(msg)
@triple_gacha_matcher.handle()
async def handle_triple_gacha(bot: Bot, event: MessageEvent, state: T_State):
"""处理三连抽命令"""
user_id = str(event.user_id)
user_name = event.sender.card or event.sender.nickname or "未知用户"
# 执行三连抽
result = gacha_system.triple_draw(user_id)
if not result["success"]:
await triple_gacha_matcher.finish(f"{result['message']}")
# 构建三连抽结果消息
msg = Message()
msg.append(f"🎯 {format_user_mention(user_id, user_name)} 的三连抽结果:\n\n")
# 显示每次抽卡结果
for i, draw_result in enumerate(result["results"], 1):
rarity = draw_result["rarity"]
name = draw_result["name"]
# 根据稀有度添加emoji
if rarity == "SSR":
msg.append(f"🌟 第{i}SSR - {name}\n")
elif rarity == "SP":
msg.append(f"🌈 第{i}SP - {name}\n")
elif rarity == "SR":
msg.append(f"⭐ 第{i}SR - {name}\n")
else: # R
msg.append(f"📜 第{i}R - {name}\n")
# 统计结果
ssr_count = sum(1 for r in result["results"] if r["rarity"] in ["SSR", "SP"])
sr_count = sum(1 for r in result["results"] if r["rarity"] == "SR")
r_count = sum(1 for r in result["results"] if r["rarity"] == "R")
msg.append(f"\n📈 本次三连抽统计:\n")
if ssr_count > 0:
msg.append(f"🎊 SSR/SP{ssr_count}\n")
if sr_count > 0:
msg.append(f"✨ SR{sr_count}\n")
if r_count > 0:
msg.append(f"📜 R{r_count}\n")
# 添加成就通知
unlocked_achievements = result.get("unlocked_achievements", [])
if unlocked_achievements:
msg.append("\n🏆 恭喜解锁新成就!\n")
has_manual_rewards = False
for achievement_id in unlocked_achievements:
# 尝试自动发放成就奖励
auto_success, reward_msg = await process_achievement_reward(user_id, achievement_id)
# 检查是否是重复奖励
if "_repeat_" in achievement_id:
base_achievement_id = achievement_id.split("_repeat_")[0]
achievement_config = config.ACHIEVEMENTS.get(base_achievement_id)
if achievement_config:
achievement_name = achievement_config["name"]
# 使用重复奖励或默认为天卡
reward = achievement_config.get("repeat_reward", "天卡")
status = "✅ 已自动发放" if auto_success else "⚠️ 需手动领取"
msg.append(f"🎖️ {achievement_name} 重复奖励 (奖励:{reward}) {status}\n")
else:
msg.append(f"🎖️ {achievement_id}\n")
else:
achievement_config = config.ACHIEVEMENTS.get(achievement_id)
if achievement_config:
achievement_name = achievement_config["name"]
reward = achievement_config["reward"]
status = "✅ 已自动发放" if auto_success else "⚠️ 需手动领取"
msg.append(f"🎖️ {achievement_name} (奖励:{reward}) {status}\n")
else:
msg.append(f"🎖️ {achievement_id}\n")
# 记录是否有需要手动领取的奖励
if not auto_success:
has_manual_rewards = True
# 如果有未自动发放的奖励,提示联系管理员
if has_manual_rewards:
msg.append("💰 未自动发放的奖励请联系管理员\n")
# 添加成就进度提示
achievement_data = gacha_system.get_user_achievements(user_id)
if achievement_data["success"]:
progress = achievement_data["progress"]
consecutive_days = progress.get("consecutive_days", 0)
no_ssr_streak = progress.get("no_ssr_streak", 0)
msg.append("\n📈 成就进度:\n")
# 连续抽卡天数进度
if consecutive_days > 0:
if consecutive_days < 30:
msg.append(f"📅 勤勤恳恳Ⅰ:{consecutive_days}/30天 🎯\n")
elif consecutive_days < 60:
msg.append(f"📅 勤勤恳恳Ⅱ:{consecutive_days}/60天 🎯\n")
elif consecutive_days < 90:
msg.append(f"📅 勤勤恳恳Ⅲ:{consecutive_days}/90天 🎯\n")
elif consecutive_days < 120:
msg.append(f"📅 勤勤恳恳Ⅳ:{consecutive_days}/120天 ⭐\n")
elif consecutive_days < 150:
msg.append(f"📅 勤勤恳恳Ⅴ:{consecutive_days}/150天 ⭐\n")
else:
next_reward_days = 30 - (consecutive_days % 30)
if next_reward_days == 30:
next_reward_days = 0
if next_reward_days > 0:
msg.append(f"📅 勤勤恳恳Ⅴ (满级){consecutive_days}天,距离下次奖励{next_reward_days}天 🎁\n")
else:
msg.append(f"📅 勤勤恳恳Ⅴ (满级){consecutive_days}天,可获得奖励!🎉\n")
# 无SSR/SP连击进度
if no_ssr_streak > 0:
if no_ssr_streak < 60:
msg.append(f"💔 非酋进度:{no_ssr_streak}/60次 😭\n")
elif no_ssr_streak < 120:
msg.append(f"💔 顶级非酋:{no_ssr_streak}/120次 😱\n")
elif no_ssr_streak < 180:
msg.append(f"💔 月见黑:{no_ssr_streak}/180次 🌙\n")
else:
msg.append(f"💔 已达月见黑级别:{no_ssr_streak}次 🌚\n")
# 添加剩余次数
draws_left = result["draws_left"]
msg.append(f"\n📊 今日剩余抽卡次数:{draws_left}/{DAILY_LIMIT}")
# 如果抽到SSR/SP处理奖励发放
if ssr_count > 0:
# 为每张SSR/SP处理奖励
auto_success, reward_msg = await process_ssr_sp_reward(user_id, ssr_count)
msg.append(f"\n\n{reward_msg}")
# 通知管理员
admin_msg = f"🎉 用户 {user_name}({user_id}) 在三连抽中抽到了 {ssr_count} 张 SSR/SP"
if auto_success:
admin_msg += f" 已自动发放 {ssr_count} 张奖励!"
else:
admin_msg += f" 需要手动发放 {ssr_count} 张奖励!"
await notify_admin(bot, admin_msg)
await triple_gacha_matcher.finish(msg)
@achievement_matcher.handle()
async def handle_achievement(bot: Bot, event: MessageEvent, state: T_State):
"""处理成就查询命令"""
user_id = str(event.user_id)
user_name = event.sender.card or event.sender.nickname or "未知用户"
# 获取用户成就信息
result = gacha_system.get_user_achievements(user_id)
if not result["success"]:
await achievement_matcher.finish(f"{result['message']}")
# 构建成就消息
msg = Message()
msg.append(f"🏆 {format_user_mention(user_id, user_name)} 的成就信息:\n\n")
# 显示已解锁成就
unlocked = result["achievements"]
if unlocked:
msg.append("🎖️ 已解锁成就:\n")
for achievement in unlocked:
# 检查是否是重复奖励
if "_repeat_" in achievement:
base_achievement_id = achievement.split("_repeat_")[0]
achievement_config = config.ACHIEVEMENTS.get(base_achievement_id)
if achievement_config:
achievement_name = achievement_config["name"]
reward = achievement_config.get("repeat_reward", "天卡")
msg.append(f"{achievement_name} 重复奖励 (奖励:{reward})\n")
else:
msg.append(f"{achievement}\n")
else:
achievement_config = config.ACHIEVEMENTS.get(achievement)
if achievement_config:
achievement_name = achievement_config["name"]
reward = achievement_config["reward"]
msg.append(f"{achievement_name} (奖励:{reward})\n")
else:
msg.append(f"{achievement}\n")
msg.append("\n💰 获取奖励请联系管理员\n\n")
# 显示成就进度
progress = result["progress"]
msg.append("📊 成就进度:\n")
# 连续抽卡天数 - 勤勤恳恳系列成就
consecutive_days = progress.get("consecutive_days", 0)
if consecutive_days > 0:
# 判断当前应该显示哪个等级的进度
if consecutive_days < 30:
msg.append(f"📅 勤勤恳恳Ⅰ:{consecutive_days}/30 天 (奖励:天卡)\n")
elif consecutive_days < 60:
msg.append(f"📅 勤勤恳恳Ⅱ:{consecutive_days}/60 天 (奖励:天卡)\n")
elif consecutive_days < 90:
msg.append(f"📅 勤勤恳恳Ⅲ:{consecutive_days}/90 天 (奖励:天卡)\n")
elif consecutive_days < 120:
msg.append(f"📅 勤勤恳恳Ⅳ:{consecutive_days}/120 天 (奖励:周卡)\n")
elif consecutive_days < 150:
msg.append(f"📅 勤勤恳恳Ⅴ:{consecutive_days}/150 天 (奖励:周卡)\n")
else:
# 已达到最高等级,显示下次奖励进度
next_reward_days = 30 - (consecutive_days % 30)
if next_reward_days == 30:
next_reward_days = 0
msg.append(f"📅 勤勤恳恳Ⅴ (已满级){consecutive_days}\n")
if next_reward_days > 0:
msg.append(f"🎁 距离下次奖励:{next_reward_days} 天 (奖励:天卡)\n")
else:
msg.append(f"🎁 可获得奖励!请联系管理员 (奖励:天卡)\n")
# 无SSR/SP连击数
no_ssr_streak = progress.get("no_ssr_streak", 0)
if no_ssr_streak > 0:
msg.append(f"💔 无SSR/SP连击{no_ssr_streak}\n")
# 显示各个非酋成就的进度
if no_ssr_streak < 60:
msg.append(f" 🎯 非酋成就:{no_ssr_streak}/60 (奖励:天卡)\n")
elif no_ssr_streak < 120:
msg.append(f" 🎯 顶级非酋成就:{no_ssr_streak}/120 (奖励:周卡)\n")
elif no_ssr_streak < 180:
msg.append(f" 🎯 月见黑成就:{no_ssr_streak}/180 (奖励:月卡)\n")
else:
msg.append(f" 🌙 已达到月见黑级别!\n")
# 如果没有任何进度,显示提示
if consecutive_days == 0 and no_ssr_streak == 0:
msg.append("🌱 还没有任何成就进度,快去抽卡吧!")
await achievement_matcher.finish(msg)
# 注册查询抽卡指令,支持@用户查询功能
query_matcher = on_command("查询抽卡", aliases={"查询抽奖"}, priority=5, rule=check_permission())
@query_matcher.handle()
async def handle_query(bot: Bot, event: MessageEvent, state: T_State):
# 获取消息中的@用户
message = event.get_message()
at_segment = None
for segment in message:
if segment.type == "at":
at_segment = segment
break
# 确定查询的用户ID
if at_segment:
# 查询被@的用户
target_user_id = str(at_segment.data.get("qq", ""))
# 获取被@用户的信息
if isinstance(event, GroupMessageEvent):
try:
group_id = event.group_id
user_info = await bot.get_group_member_info(group_id=group_id, user_id=int(target_user_id))
target_user_name = user_info.get("card") or user_info.get("nickname", "用户")
except:
target_user_name = "用户"
else:
target_user_name = "用户"
else:
# 查询自己
target_user_id = str(event.user_id)
target_user_name = event.sender.card if isinstance(event, GroupMessageEvent) else event.sender.nickname
# 获取用户统计
stats = gacha_system.get_user_stats(target_user_id)
# 构建响应消息
msg = Message()
# 如果查询的是他人
if target_user_id != str(event.user_id):
msg.append(format_user_mention(str(event.user_id), event.sender.card if isinstance(event, GroupMessageEvent) else event.sender.nickname))
msg.append(f" 查询了 ")
msg.append(format_user_mention(target_user_id, target_user_name))
msg.append(f" 的抽卡记录\n\n")
else:
msg.append(format_user_mention(target_user_id, target_user_name) + "\n")
if not stats["success"]:
msg.append(f"该用户还没有抽卡记录哦!")
await query_matcher.finish(msg)
# 构建统计信息
msg.append(f"总抽卡次数:{stats['total_draws']}\n")
msg.append(f"R卡数量{stats['R_count']}\n")
msg.append(f"SR卡数量{stats['SR_count']}\n")
msg.append(f"SSR卡数量{stats['SSR_count']}\n")
msg.append(f"SP卡数量{stats['SP_count']}\n")
# 计算每种稀有度的比例
if stats['total_draws'] > 0:
msg.append("\n稀有度比例:\n")
msg.append(f"R: {stats['R_count']/stats['total_draws']*100:.2f}%\n")
msg.append(f"SR: {stats['SR_count']/stats['total_draws']*100:.2f}%\n")
msg.append(f"SSR: {stats['SSR_count']/stats['total_draws']*100:.2f}%\n")
msg.append(f"SP: {stats['SP_count']/stats['total_draws']*100:.2f}%\n")
# 添加最近抽卡记录
if stats["recent_draws"]:
msg.append("\n最近5次抽卡记录\n")
for draw in reversed(stats["recent_draws"]):
msg.append(f"{draw['date']}: {draw['rarity']} - {draw['name']}\n")
await query_matcher.finish(msg)
# 自定义排行榜权限检查(仅检查白名单,不检查抽卡次数)
def check_rank_permission() -> Rule:
async def _checker(event: MessageEvent) -> bool:
# 允许特定用户在任何场景下使用
if event.user_id == ALLOWED_USER_ID:
return True
# 在允许的群聊中任何人都可以使用
if isinstance(event, GroupMessageEvent) and event.group_id == ALLOWED_GROUP_ID:
return True
return False
return Rule(_checker)
rank_matcher = on_startswith(("抽卡排行","抽卡榜"), priority=1, rule=check_rank_permission())
@rank_matcher.handle()
async def handle_rank(bot: Bot, event: MessageEvent, state: T_State):
# 获取排行榜数据
rank_data = gacha_system.get_rank_list()
if not rank_data:
await rank_matcher.finish("暂无抽卡排行榜数据")
# 构建消息
msg = Message("✨┈┈┈┈┈ 抽卡排行榜 ┈┈┈┈┈✨\n")
msg.append("🏆 SSR/SP稀有度式神排行榜 🏆\n")
msg.append("┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈\n")
for i, (user_id, data) in enumerate(rank_data[:10], 1):
# 获取用户昵称
user_name = "未知用户"
try:
if isinstance(event, GroupMessageEvent):
# 群聊场景获取群名片或昵称
user_info = await bot.get_group_member_info(group_id=event.group_id, user_id=int(user_id))
user_name = user_info.get("card") or user_info.get("nickname", "未知用户")
else:
# 私聊场景获取昵称
user_info = await bot.get_stranger_info(user_id=int(user_id))
user_name = user_info.get("nickname", "未知用户")
except Exception as e:
# 如果获取失败,尝试从事件中获取发送者信息
if str(user_id) == str(event.user_id):
user_name = event.sender.card if isinstance(event, GroupMessageEvent) else event.sender.nickname
# 美化输出格式
rank_icon = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else f"{i}."
ssr_icon = "🌟"
sp_icon = "💫"
total = data['SSR_count'] + data['SP_count']
msg.append(f"{rank_icon} {user_name}\n")
msg.append(f" {ssr_icon}SSR: {data['SSR_count']}{sp_icon}SP: {data['SP_count']}\n")
msg.append(f" 🔮总计: {total}\n")
msg.append("┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈\n")
await rank_matcher.finish(msg)
@daily_stats_matcher.handle()
async def handle_daily_stats(bot: Bot, event: MessageEvent, state: T_State):
"""处理今日抽卡统计命令"""
result = gacha_system.get_daily_stats()
if not result["success"]:
await daily_stats_matcher.finish(f"{result['message']}")
stats = result["stats"]
date = result["date"]
# 构建统计消息
msg = Message()
msg.append(f"📊 今日抽卡统计 ({date})\n\n")
msg.append(f"👥 参与人数:{stats['total_users']}\n")
msg.append(f"🎲 总抽卡次数:{stats['total_draws']}\n\n")
# 稀有度分布
msg.append("🎯 稀有度分布:\n")
if stats['total_draws'] > 0:
msg.append(f"📜 R{stats['rarity_stats']['R']}张 ({stats['rarity_stats']['R']/stats['total_draws']*100:.1f}%)\n")
msg.append(f"⭐ SR{stats['rarity_stats']['SR']}张 ({stats['rarity_stats']['SR']/stats['total_draws']*100:.1f}%)\n")
msg.append(f"🌟 SSR{stats['rarity_stats']['SSR']}张 ({stats['rarity_stats']['SSR']/stats['total_draws']*100:.1f}%)\n")
msg.append(f"🌈 SP{stats['rarity_stats']['SP']}张 ({stats['rarity_stats']['SP']/stats['total_draws']*100:.1f}%)\n\n")
else:
msg.append("暂无数据\n\n")
# SSR/SP排行榜
if stats['top_users']:
msg.append("🏆 今日SSR/SP排行榜\n")
for i, user_data in enumerate(stats['top_users'][:5], 1):
user_id = user_data['user_id']
ssr_count = user_data['ssr_count']
# 尝试获取用户昵称
try:
user_info = await bot.get_stranger_info(user_id=int(user_id))
user_name = user_info.get('nickname', f'用户{user_id}')
except:
user_name = f'用户{user_id}'
if i == 1:
msg.append(f"🥇 {user_name}{ssr_count}\n")
elif i == 2:
msg.append(f"🥈 {user_name}{ssr_count}\n")
elif i == 3:
msg.append(f"🥉 {user_name}{ssr_count}\n")
else:
msg.append(f"🏅 {user_name}{ssr_count}\n")
else:
msg.append("🏆 今日还没有人抽到SSR/SP哦~")
await daily_stats_matcher.finish(msg)
# 抽卡介绍命令
intro_matcher = on_command("抽卡介绍", aliases=set(INTRO_COMMANDS), priority=5, rule=check_permission())
@intro_matcher.handle()
async def handle_intro(bot: Bot, event: MessageEvent, state: T_State):
"""处理抽卡介绍命令"""
# 构建介绍消息
msg = "🎮 阴阳师抽卡系统介绍 🎮\n\n"
# 抽卡机制
msg += "📋 抽卡机制:\n"
msg += f"• 每日限制:{DAILY_LIMIT}次免费抽卡\n"
msg += "• 稀有度概率:\n"
for rarity, prob in config.RARITY_PROBABILITY.items():
msg += f" - {rarity}: {prob}%\n"
msg += "\n"
# 可用指令
msg += "🎯 可用指令:\n"
msg += f"• 抽卡:{', '.join(GACHA_COMMANDS[:3])}\n"
msg += f"• 三连抽:{', '.join(TRIPLE_GACHA_COMMANDS)}\n"
msg += f"• 个人统计:{', '.join(STATS_COMMANDS[:2])}\n"
msg += f"• 今日统计:{', '.join(DAILY_STATS_COMMANDS[:2])}\n"
msg += f"• 查询成就:{', '.join(ACHIEVEMENT_COMMANDS)}\n"
msg += "• 查询抽卡/查询抽奖:查询自己的或@他人的抽卡数据\n"
msg += "• 抽卡排行/抽卡榜查看SSR/SP排行榜\n"
msg += "\n"
# 成就系统
msg += "🏆 成就系统:\n"
msg += "\n📅 勤勤恳恳系列(连续抽卡):\n"
consecutive_achievements = [
("勤勤恳恳Ⅰ", "30天", "天卡"),
("勤勤恳恳Ⅱ", "60天", "天卡"),
("勤勤恳恳Ⅲ", "90天", "天卡"),
("勤勤恳恳Ⅳ", "120天", "周卡"),
("勤勤恳恳Ⅴ", "150天", "周卡")
]
for name, days, reward in consecutive_achievements:
msg += f"{name}:连续{days}{reward} 💎\n"
msg += " ※ 达到最高等级后每30天可重复获得天卡奖励\n\n"
msg += "😭 非酋系列无SSR/SP连击\n"
no_ssr_achievements = [
("非酋", "60次", "天卡"),
("顶级非酋", "120次", "周卡"),
("月见黑", "180次", "月卡")
]
for name, count, reward in no_ssr_achievements:
msg += f"{name}:连续{count}未中SSR/SP → {reward} 💎\n"
msg += "\n"
# 奖励说明
msg += "🎁 奖励说明:\n"
msg += "• 天卡:蛋定助手天卡奖励\n"
msg += "• 周卡:蛋定助手周卡奖励\n"
msg += "• 月卡:蛋定助手月卡奖励\n"
msg += "\n"
# 联系管理员
msg += "📞 重要提醒:\n"
msg += "🔸 所有奖励需要联系管理员获取 🔸\n"
msg += "请在获得成就后主动联系管理员领取奖励哦~ 😊\n\n"
# 祝福语
msg += "🍀 祝您抽卡愉快,欧气满满! ✨"
await intro_matcher.finish(msg)
# 导入 Web API 模块,使其路由能够注册到 NoneBot 的 FastAPI 应用
from . import web_api
# 注册 Web 路由
try:
web_api.register_web_routes()
except Exception as e:
print(f"❌ 注册 onmyoji_gacha Web 路由失败: {e}")