From 4c3b1e5631da030ab15f330f1827e79832c0e601 Mon Sep 17 00:00:00 2001
From: CMHopeSunshine <277073121@qq.com>
Date: Fri, 17 Feb 2023 22:36:31 +0800
Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D=E5=A4=9Abot?=
=?UTF-8?q?=E8=BF=9E=E6=8E=A5=E6=97=B6`=E6=B7=B1=E6=B8=8A=E7=BB=9F?=
=?UTF-8?q?=E8=AE=A1`=E5=92=8C`=E7=8C=9C=E8=AF=AD=E9=9F=B3`=E5=8F=AF?=
=?UTF-8?q?=E8=83=BD=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../plugins/Genshin_Voice/__init__.py | 114 ++++--
LittlePaimon/plugins/Genshin_Voice/handler.py | 75 +++-
LittlePaimon/plugins/Paimon_Abyss/__init__.py | 67 ++--
.../plugins/Paimon_Abyss/abyss_statistics.py | 378 +++++++++++++-----
LittlePaimon/plugins/bot_manager/__init__.py | 30 +-
5 files changed, 477 insertions(+), 187 deletions(-)
diff --git a/LittlePaimon/plugins/Genshin_Voice/__init__.py b/LittlePaimon/plugins/Genshin_Voice/__init__.py
index eb01b7d..fd60244 100644
--- a/LittlePaimon/plugins/Genshin_Voice/__init__.py
+++ b/LittlePaimon/plugins/Genshin_Voice/__init__.py
@@ -2,7 +2,13 @@ import random
from typing import Union
from nonebot import on_command
-from nonebot.adapters.onebot.v11 import Message, MessageEvent, GroupMessageEvent, PrivateMessageEvent
+from nonebot.adapters.onebot.v11 import (
+ Bot,
+ GroupMessageEvent,
+ Message,
+ MessageEvent,
+ PrivateMessageEvent,
+)
from nonebot.adapters.onebot.v11.exception import ActionFailed
from nonebot.params import CommandArg
from nonebot.permission import SUPERUSER
@@ -12,7 +18,14 @@ from LittlePaimon.config import config
from LittlePaimon.database import GenshinVoice
from LittlePaimon.utils.alias import get_match_alias
from LittlePaimon.utils.message import CommandCharacter, CommandLang, MessageBuild
-from .handler import GuessVoice, get_character_voice, get_rank, get_voice_list, get_record
+
+from .handler import (
+ GuessVoice,
+ get_character_voice,
+ get_rank,
+ get_record,
+ get_voice_list,
+)
from .resources import update_voice_resources
__plugin_meta__ = PluginMetadata(
@@ -20,47 +33,70 @@ __plugin_meta__ = PluginMetadata(
description='原神语音',
usage='原神猜语音',
extra={
- 'author': '惜月',
- 'version': '3.0',
+ 'author': '惜月',
+ 'version': '3.0',
'priority': 6,
- }
+ },
)
-guess_voice = on_command('原神猜语音', priority=12, block=True, state={
- 'pm_name': '原神猜语音',
+guess_voice = on_command(
+ '原神猜语音',
+ priority=12,
+ block=True,
+ state={
+ 'pm_name': '原神猜语音',
'pm_description': '原神猜语音小游戏',
- 'pm_usage': '原神猜语音[语言][排行榜]',
- 'pm_priority': 1
- })
-get_voice = on_command('原神语音', priority=12, block=True, state={
- 'pm_name': '原神语音',
+ 'pm_usage': '原神猜语音[语言][排行榜]',
+ 'pm_priority': 1,
+ },
+)
+get_voice = on_command(
+ '原神语音',
+ priority=12,
+ block=True,
+ state={
+ 'pm_name': '原神语音',
'pm_description': '获取指定角色的指定语音',
- 'pm_usage': '原神语音<名|序号>[语言]',
- 'pm_priority': 3
- })
-voice_list = on_command('原神语音列表', priority=12, block=True, state={
- 'pm_name': '原神语音列表',
+ 'pm_usage': '原神语音<名|序号>[语言]',
+ 'pm_priority': 3,
+ },
+)
+voice_list = on_command(
+ '原神语音列表',
+ priority=12,
+ block=True,
+ state={
+ 'pm_name': '原神语音列表',
'pm_description': '查看角色的语音列表',
- 'pm_usage': '原神语音列表<名><语言>',
- 'pm_priority': 2
- })
-update_voice = on_command('更新原神语音资源', priority=12, permission=SUPERUSER, block=True, state={
- 'pm_name': '更新原神语音资源',
+ 'pm_usage': '原神语音列表<名><语言>',
+ 'pm_priority': 2,
+ },
+)
+update_voice = on_command(
+ '更新原神语音资源',
+ priority=12,
+ permission=SUPERUSER,
+ block=True,
+ state={
+ 'pm_name': '更新原神语音资源',
'pm_description': '更新原神语音资源',
- 'pm_usage': '更新原神语音资源',
- 'pm_show': False,
- 'pm_priority': 4
- })
+ 'pm_usage': '更新原神语音资源',
+ 'pm_show': False,
+ 'pm_priority': 4,
+ },
+)
@guess_voice.handle()
-async def _(event: GroupMessageEvent, msg: Message = CommandArg(), lang=CommandLang()):
+async def _(
+ bot: Bot, event: GroupMessageEvent, msg: Message = CommandArg(), lang=CommandLang()
+):
msg = msg.extract_plain_text().strip()
if 'rank' in msg or '排行' in msg:
result = await get_rank(event.group_id)
await guess_voice.finish(result)
else:
- game = GuessVoice(event.group_id, config.guess_voice_time, lang)
+ game = GuessVoice(event.group_id, bot, config.guess_voice_time, lang)
result = await game.start()
await guess_voice.send(f'即将发送一段语音,将在{config.guess_voice_time}秒后公布答案')
try:
@@ -71,11 +107,19 @@ async def _(event: GroupMessageEvent, msg: Message = CommandArg(), lang=CommandL
@get_voice.handle()
-async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], lang=CommandLang(), msg: Message = CommandArg()):
+async def _(
+ event: Union[GroupMessageEvent, PrivateMessageEvent],
+ lang=CommandLang(),
+ msg: Message = CommandArg(),
+):
msg = msg.extract_plain_text().strip().split(' ')[0]
if msg.isdigit():
voice = await GenshinVoice.get_or_none(id=int(msg))
- await get_voice.finish(await get_record(voice.voice_url) if voice else MessageBuild.Text(f'没有{msg}号原神语音'))
+ await get_voice.finish(
+ await get_record(voice.voice_url)
+ if voice
+ else MessageBuild.Text(f'没有{msg}号原神语音')
+ )
else:
if chara := get_match_alias(msg, ['角色'], True):
chara = chara[0]
@@ -85,11 +129,17 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], lang=CommandLa
if voices:
await get_voice.finish(await get_record(random.choice(voices).voice_url))
else:
- await get_voice.finish(MessageBuild.Text(f'暂无{chara}的{lang}文语音资源,让超级用户[更新原神语音资源]吧!'))
+ await get_voice.finish(
+ MessageBuild.Text(f'暂无{chara}的{lang}文语音资源,让超级用户[更新原神语音资源]吧!')
+ )
@voice_list.handle()
-async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], character=CommandCharacter(1), lang=CommandLang()):
+async def _(
+ event: Union[GroupMessageEvent, PrivateMessageEvent],
+ character=CommandCharacter(1),
+ lang=CommandLang(),
+):
result = await get_voice_list(character[0], lang)
await get_voice.finish(result)
diff --git a/LittlePaimon/plugins/Genshin_Voice/handler.py b/LittlePaimon/plugins/Genshin_Voice/handler.py
index d147e81..364da8c 100644
--- a/LittlePaimon/plugins/Genshin_Voice/handler.py
+++ b/LittlePaimon/plugins/Genshin_Voice/handler.py
@@ -1,14 +1,15 @@
import datetime
import random
-from nonebot import get_bot, on_regex
-from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageSegment
+from nonebot import on_regex
+from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageSegment
from nonebot.rule import Rule
from LittlePaimon.database import GenshinVoice, GuessVoiceRank
-from LittlePaimon.utils import scheduler, logger
+from LittlePaimon.utils import logger, scheduler
from LittlePaimon.utils.alias import get_alias_by_name
from LittlePaimon.utils.requests import aiorequests
+
from .draw import draw_voice_list
gaming = {}
@@ -19,10 +20,13 @@ class GuessVoice:
group_id: int
language: str
- def __init__(self, group_id: int, game_time: int = 30, language: str = '中'):
+ def __init__(
+ self, group_id: int, bot: Bot, game_time: int = 30, language: str = '中'
+ ):
self.group_id = group_id
self.game_time = game_time
self.language = language
+ self.bot = bot
@property
def is_gaming(self):
@@ -39,10 +43,14 @@ class GuessVoice:
create_guess_matcher(self.group_id, voice.character, self.game_time)
if scheduler.get_job(f'Guess_voice_{self.group_id}'):
scheduler.remove_job(f'Guess_voice_{self.group_id}')
- scheduler.add_job(self.end, 'date',
- run_date=datetime.datetime.now() + datetime.timedelta(seconds=self.game_time),
- id=f'Guess_voice_{self.group_id}',
- misfire_grace_time=10)
+ scheduler.add_job(
+ self.end,
+ 'date',
+ run_date=datetime.datetime.now()
+ + datetime.timedelta(seconds=self.game_time),
+ id=f'Guess_voice_{self.group_id}',
+ misfire_grace_time=10,
+ )
return await get_record(voice.voice_url)
async def end(self, exception: bool = False):
@@ -51,18 +59,22 @@ class GuessVoice:
del gaming[self.group_id]
msg = f'还没有人猜中呢,正确答案是:{answer}!'
try:
- await get_bot().send_group_msg(group_id=self.group_id, message=msg)
+ await self.bot.send_group_msg(group_id=self.group_id, message=msg)
except Exception as e:
logger.warning('原神猜语音', '➤发送结果时出错', str(e))
- logger.info('原神猜语音', f'➤群{self.group_id}猜语音游戏结束,答案为{answer},没有人猜对')
+ logger.info(
+ '原神猜语音', f'➤群{self.group_id}猜语音游戏结束,答案为{answer},没有人猜对'
+ )
elif exception:
logger.warning('原神猜语音', f'➤群{self.group_id}猜语音游戏发送语音出错, 异常结束')
del gaming[self.group_id]
async def get_rank(group_id: int):
- records = await GuessVoiceRank.filter(group_id=group_id,
- guess_time__gte=datetime.datetime.now() - datetime.timedelta(days=7))
+ records = await GuessVoiceRank.filter(
+ group_id=group_id,
+ guess_time__gte=datetime.datetime.now() - datetime.timedelta(days=7),
+ )
if not records:
return '本群本周暂无排行榜数据哦!'
rank = {}
@@ -72,7 +84,9 @@ async def get_rank(group_id: int):
else:
rank[record.user_id] = 1
msg = '本周猜语音排行榜\n'
- for i, (user_id, count) in enumerate(sorted(rank.items(), key=lambda x: x[1], reverse=True), start=1):
+ for i, (user_id, count) in enumerate(
+ sorted(rank.items(), key=lambda x: x[1], reverse=True), start=1
+ ):
msg += f'{i}.{user_id}: {count}次\n'
return msg
@@ -87,24 +101,39 @@ def create_guess_matcher(group_id, role_name, game_time):
def check_group(event: GroupMessageEvent):
return event.group_id == group_id
+
if '旅行者' in role_name:
role_name = role_name.replace('旅行者(', '').replace(')', '')
alias_list = get_alias_by_name(role_name)
re_str = '|'.join(alias_list)
- guess_matcher = on_regex(f'^{re_str}$', temp=True, rule=Rule(check_group),
- expire_time=datetime.timedelta(seconds=game_time))
+ guess_matcher = on_regex(
+ f'^{re_str}$',
+ temp=True,
+ rule=Rule(check_group),
+ expire_time=datetime.timedelta(seconds=game_time),
+ )
guess_matcher.plugin_name = "Genshin_Voice"
@guess_matcher.handle()
async def _(event: GroupMessageEvent):
- await GuessVoiceRank.create(user_id=event.user_id, group_id=event.group_id, answer=role_name,
- guess_time=datetime.datetime.now())
+ await GuessVoiceRank.create(
+ user_id=event.user_id,
+ group_id=event.group_id,
+ answer=role_name,
+ guess_time=datetime.datetime.now(),
+ )
del gaming[event.group_id]
if scheduler.get_job(f'Guess_voice_{event.group_id}'):
scheduler.remove_job(f'Guess_voice_{event.group_id}')
- logger.info('原神猜语音', f'➤群{event.group_id}猜语音游戏结束,答案为{role_name},由{event.sender.card}猜对')
- msg = Message(MessageSegment.text('恭喜') + MessageSegment.at(event.user_id) + MessageSegment.text(
- f'猜对了!\n正确答案是:{role_name}'))
+ logger.info(
+ '原神猜语音',
+ f'➤群{event.group_id}猜语音游戏结束,答案为{role_name},由{event.sender.card}猜对',
+ )
+ msg = Message(
+ MessageSegment.text('恭喜')
+ + MessageSegment.at(event.user_id)
+ + MessageSegment.text(f'猜对了!\n正确答案是:{role_name}')
+ )
await guess_matcher.finish(msg)
@@ -118,7 +147,11 @@ async def get_character_voice(character: str, language: str = '中'):
async def get_voice_list(character: str, language: str = '中'):
voice_list = await GenshinVoice.filter(character=character, language=language).all()
- return await draw_voice_list(voice_list) if voice_list else MessageSegment.text(f'暂无{character}的{language}语音资源,让超级用户[更新原神语音资源]吧!')
+ return (
+ await draw_voice_list(voice_list)
+ if voice_list
+ else MessageSegment.text(f'暂无{character}的{language}语音资源,让超级用户[更新原神语音资源]吧!')
+ )
async def get_record(url: str) -> MessageSegment.record:
diff --git a/LittlePaimon/plugins/Paimon_Abyss/__init__.py b/LittlePaimon/plugins/Paimon_Abyss/__init__.py
index 337f8ce..98fbcd0 100644
--- a/LittlePaimon/plugins/Paimon_Abyss/__init__.py
+++ b/LittlePaimon/plugins/Paimon_Abyss/__init__.py
@@ -1,11 +1,12 @@
from nonebot import on_command
-from nonebot.adapters.onebot.v11 import Message, MessageEvent, GroupMessageEvent
+from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message, MessageEvent
from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from LittlePaimon.utils import logger
from LittlePaimon.utils.genshin import GenshinInfoManager
from LittlePaimon.utils.message import CommandPlayer
+
from .abyss_statistics import get_statistics
from .draw_abyss import draw_abyss_card
from .youchuang import draw_team
@@ -15,30 +16,48 @@ __plugin_meta__ = PluginMetadata(
description='原神深渊查询',
usage='...',
extra={
- 'author': '惜月',
- 'version': '3.0',
+ 'author': '惜月',
+ 'version': '3.0',
'priority': 2,
- }
+ },
)
-sy = on_command('sy', aliases={'深渊战报', '深渊信息'}, priority=10, block=True, state={
- 'pm_name': 'sy',
- 'pm_description': '查看本期|上期的深渊战报',
- 'pm_usage': 'sy(uid)(本期|上期)',
- 'pm_priority': 1
-})
-abyss_stat = on_command('深渊统计', aliases={'深渊群数据', '深渊群排行'}, priority=10, block=True, state={
- 'pm_name': '深渊统计',
- 'pm_description': '查看本群深渊统计,仅群可用',
- 'pm_usage': '深渊统计',
- 'pm_priority': 2
-})
-abyss_team = on_command('深渊配队', aliases={'配队推荐', '深渊阵容'}, priority=10, block=True, state={
- 'pm_name': '深渊配队',
- 'pm_description': '查看深渊配队推荐,数据来源于游创工坊',
- 'pm_usage': '深渊配队',
- 'pm_priority': 3
-})
+sy = on_command(
+ 'sy',
+ aliases={'深渊战报', '深渊信息'},
+ priority=10,
+ block=True,
+ state={
+ 'pm_name': 'sy',
+ 'pm_description': '查看本期|上期的深渊战报',
+ 'pm_usage': 'sy(uid)(本期|上期)',
+ 'pm_priority': 1,
+ },
+)
+abyss_stat = on_command(
+ '深渊统计',
+ aliases={'深渊群数据', '深渊群排行'},
+ priority=10,
+ block=True,
+ state={
+ 'pm_name': '深渊统计',
+ 'pm_description': '查看本群深渊统计,仅群可用',
+ 'pm_usage': '深渊统计',
+ 'pm_priority': 2,
+ },
+)
+abyss_team = on_command(
+ '深渊配队',
+ aliases={'配队推荐', '深渊阵容'},
+ priority=10,
+ block=True,
+ state={
+ 'pm_name': '深渊配队',
+ 'pm_description': '查看深渊配队推荐,数据来源于游创工坊',
+ 'pm_usage': '深渊配队',
+ 'pm_priority': 3,
+ },
+)
@sy.handle()
@@ -66,9 +85,9 @@ async def _(event: MessageEvent, players=CommandPlayer(), msg: Message = Command
@abyss_stat.handle()
-async def _(event: GroupMessageEvent):
+async def _(bot: Bot, event: GroupMessageEvent):
try:
- result = await get_statistics(event.group_id)
+ result = await get_statistics(event.group_id, bot)
except Exception as e:
result = f'制作深渊统计时出错:{e}'
await abyss_stat.finish(result)
diff --git a/LittlePaimon/plugins/Paimon_Abyss/abyss_statistics.py b/LittlePaimon/plugins/Paimon_Abyss/abyss_statistics.py
index faa9a85..8847bb7 100644
--- a/LittlePaimon/plugins/Paimon_Abyss/abyss_statistics.py
+++ b/LittlePaimon/plugins/Paimon_Abyss/abyss_statistics.py
@@ -1,12 +1,14 @@
import datetime
from collections import Counter
-from typing import Dict, Any, Tuple
+from typing import Any, Dict, Tuple
import pytz
-from nonebot import get_bot
+from nonebot.adapters.onebot.v11 import Bot
from LittlePaimon.database import AbyssInfo
-from LittlePaimon.utils.image import PMImage, font_manager as fm, get_qq_avatar, load_image
+from LittlePaimon.utils.image import PMImage
+from LittlePaimon.utils.image import font_manager as fm
+from LittlePaimon.utils.image import get_qq_avatar, load_image
from LittlePaimon.utils.message import MessageBuild
from LittlePaimon.utils.path import RESOURCE_BASE_PATH
from LittlePaimon.utils.requests import aiorequests
@@ -24,7 +26,9 @@ async def get_user_avatar(user_id: str, size: Tuple[int, int] = (60, 60)):
async def get_group_avatar(group_id: str):
try:
- img = await aiorequests.get_img(f'https://p.qlogo.cn/gh/{group_id}/{group_id}/100', size=(110, 110))
+ img = await aiorequests.get_img(
+ f'https://p.qlogo.cn/gh/{group_id}/{group_id}/100', size=(110, 110)
+ )
img = PMImage(img)
await img.to_circle('circle')
return img
@@ -32,28 +36,34 @@ async def get_group_avatar(group_id: str):
return PMImage(size=(110, 110), color=(255, 255, 255, 255))
-async def get_statistics(group_id: int):
- if not (info_list := await AbyssInfo.all()):
+async def get_statistics(group_id: int, bot: Bot):
+ now = datetime.datetime.now()
+ abyss_info_list = await AbyssInfo.filter(
+ total_battle__not=None,
+ total_star__not=None,
+ max_damage__not=None,
+ max_take_damage__not=None,
+ start_time__lte=now,
+ end_time__gte=now,
+ )
+ if not abyss_info_list:
return '本群还没有深渊战斗数据哦!'
- member_list = await get_bot().get_group_member_list(group_id=group_id)
+ member_list = await bot.get_group_member_list(group_id=group_id)
member_id_list = [str(member['user_id']) for member in member_list]
- info_list = [info for info in info_list if
- info.user_id in member_id_list and info.total_battle and info.total_star and info.max_damage and info.max_take_damage]
- now = datetime.datetime.now().replace(tzinfo=pytz.timezone('Asia/Shanghai'))
- info_list = [info for info in info_list if info.start_time <= now <= info.end_time]
- if not info_list:
+ info_list = [info for info in abyss_info_list if info.user_id in member_id_list]
+ if not abyss_info_list:
return '本群还没有深渊战斗数据哦!'
- elif len(info_list) < 3:
+ elif len(abyss_info_list) < 3:
return '本群深渊有效战斗数据不足3人,无法生成统计图!'
- for info in info_list:
+ for info in abyss_info_list:
if info.nickname is None:
for member in member_list:
if info.user_id == str(member['user_id']):
info.nickname = member['card'] or member['nickname']
break
data = {
- '群号': str(group_id),
- '群名称': (await get_bot().get_group_info(group_id=group_id))['group_name'],
+ '群号': str(group_id),
+ '群名称': (await bot.get_group_info(group_id=group_id))['group_name'],
}
# 数据数
info_num = len(info_list)
@@ -65,36 +75,42 @@ async def get_statistics(group_id: int):
average_star = round(sum(info.total_star for info in info_list) / info_num, 1)
data['平均星数'] = average_star
# 平均战斗次数
- average_battle_num = round(sum(info.total_battle for info in info_list) / info_num, 1)
+ average_battle_num = round(
+ sum(info.total_battle for info in info_list) / info_num, 1
+ )
data['平均战斗次数'] = average_battle_num
# 最高伤害角色
# max_damage = max(info_list, key=lambda x: x.max_damage.value)
max_damage = sorted(info_list, key=lambda x: x.max_damage.value, reverse=True)
data['最高伤害'] = [
{
- '图标': info.max_damage.icon,
+ '图标': info.max_damage.icon,
'稀有度': info.max_damage.rarity,
- '等级': info.max_damage.level,
- '数值': info.max_damage.value,
+ '等级': info.max_damage.level,
+ '数值': info.max_damage.value,
# '命座': (await Character.filter(user_id=info.user_id, uid=info.uid, character_id=info.max_damage.character_id).first()).constellation,
'用户名': info.nickname,
- 'qq号': info.user_id,
- 'uid': info.uid,
- } for info in max_damage[:3]
+ 'qq号': info.user_id,
+ 'uid': info.uid,
+ }
+ for info in max_damage[:3]
]
# 最多承伤角色
- max_take_damage = sorted(info_list, key=lambda x: x.max_take_damage.value, reverse=True)
+ max_take_damage = sorted(
+ info_list, key=lambda x: x.max_take_damage.value, reverse=True
+ )
data['最高承受伤害'] = [
{
- '图标': info.max_take_damage.icon,
+ '图标': info.max_take_damage.icon,
'稀有度': info.max_take_damage.rarity,
- '等级': info.max_take_damage.level,
- '数值': info.max_take_damage.value,
+ '等级': info.max_take_damage.level,
+ '数值': info.max_take_damage.value,
# '命座': (await Character.filter(user_id=info.user_id, uid=info.uid, character_id=info.max_damage.character_id).first()).constellation,
'用户名': info.nickname,
- 'qq号': info.user_id,
- 'uid': info.uid,
- } for info in max_take_damage[:3]
+ 'qq号': info.user_id,
+ 'uid': info.uid,
+ }
+ for info in max_take_damage[:3]
]
# 11、12层阵容
battle_characters_up11 = Counter()
@@ -108,14 +124,18 @@ async def get_statistics(group_id: int):
battle_characters_up11[f'{character.icon}-{character.rarity}'] += 1
for battles in floor11.battles_down:
for character in battles.characters:
- battle_characters_down11[f'{character.icon}-{character.rarity}'] += 1
+ battle_characters_down11[
+ f'{character.icon}-{character.rarity}'
+ ] += 1
if floor12 := info.floors.get(12):
for battles in floor12.battles_up:
for character in battles.characters:
battle_characters_up12[f'{character.icon}-{character.rarity}'] += 1
for battles in floor12.battles_down:
for character in battles.characters:
- battle_characters_down12[f'{character.icon}-{character.rarity}'] += 1
+ battle_characters_down12[
+ f'{character.icon}-{character.rarity}'
+ ] += 1
data['11层上半'] = battle_characters_up11.most_common(4)
data['11层下半'] = battle_characters_down11.most_common(4)
data['12层上半'] = battle_characters_up12.most_common(4)
@@ -126,57 +146,133 @@ async def get_statistics(group_id: int):
async def draw_statistics_img(data: Dict[str, Any]):
img = PMImage(image=RESOURCE_BASE_PATH / 'abyss' / 'statistics_bg.png')
box = {
- '4big': await load_image(RESOURCE_BASE_PATH / 'abyss' / '4bigbox.png'),
+ '4big': await load_image(RESOURCE_BASE_PATH / 'abyss' / '4bigbox.png'),
'4small': await load_image(RESOURCE_BASE_PATH / 'abyss' / '4smallbox.png'),
- '5big': await load_image(RESOURCE_BASE_PATH / 'abyss' / '5bigbox.png'),
+ '5big': await load_image(RESOURCE_BASE_PATH / 'abyss' / '5bigbox.png'),
'5small': await load_image(RESOURCE_BASE_PATH / 'abyss' / '5smallbox.png'),
- '4bg': await load_image(RESOURCE_BASE_PATH / 'icon' / 'star4_no_line.png', size=(95, 95)),
- '5bg': await load_image(RESOURCE_BASE_PATH / 'icon' / 'star5_no_line.png', size=(95, 95))
+ '4bg': await load_image(
+ RESOURCE_BASE_PATH / 'icon' / 'star4_no_line.png', size=(95, 95)
+ ),
+ '5bg': await load_image(
+ RESOURCE_BASE_PATH / 'icon' / 'star5_no_line.png', size=(95, 95)
+ ),
}
avatar = await get_group_avatar(data['群号'])
await img.paste(avatar, (38, 47))
await img.text(data['群名称'], 162, 58, fm.get('hywh', 48), '#040404')
await img.text(data['群号'], 165, 116, fm.get('hywh', 36), '#040404')
- await img.text(f'CREATED BY LITTLEPAIMON AT {datetime.datetime.now().strftime("%m-%d %H:%M")}',
- 1033, 195, fm.get('bahnschrift_regular.ttf', 30), '#8c4c2e', 'right')
- await img.text(str(data['总人数']), (233, 352), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
- await img.text(str(data['平均星数']), (492, 586), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
- await img.text(str(data['平均战斗次数']), (698, 840), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404',
- 'center')
+ await img.text(
+ f'CREATED BY LITTLEPAIMON AT {datetime.datetime.now().strftime("%m-%d %H:%M")}',
+ 1033,
+ 195,
+ fm.get('bahnschrift_regular.ttf', 30),
+ '#8c4c2e',
+ 'right',
+ )
+ await img.text(
+ str(data['总人数']),
+ (233, 352),
+ 296,
+ fm.get('bahnschrift_regular.ttf', 48),
+ '#040404',
+ 'center',
+ )
+ await img.text(
+ str(data['平均星数']),
+ (492, 586),
+ 296,
+ fm.get('bahnschrift_regular.ttf', 48),
+ '#040404',
+ 'center',
+ )
+ await img.text(
+ str(data['平均战斗次数']),
+ (698, 840),
+ 296,
+ fm.get('bahnschrift_regular.ttf', 48),
+ '#040404',
+ 'center',
+ )
# 满星人数
full_num = [data['满星人数'] / data['总人数'], 1 - data['满星人数'] / data['总人数']]
now_used_width = 36
if full_num[0] > 0.03:
- await img.draw_rectangle((now_used_width, 402, now_used_width + int(1007 * full_num[0]), 449), '#b6d6f2')
- await img.text(str(data['满星人数']), now_used_width + 18, 413, fm.get('bahnschrift_regular.ttf', 30),
- '#3d6e99')
+ await img.draw_rectangle(
+ (now_used_width, 402, now_used_width + int(1007 * full_num[0]), 449),
+ '#b6d6f2',
+ )
+ await img.text(
+ str(data['满星人数']),
+ now_used_width + 18,
+ 413,
+ fm.get('bahnschrift_regular.ttf', 30),
+ '#3d6e99',
+ )
now_used_width += int(1007 * full_num[0])
if full_num[1] > 0.03:
- await img.draw_rectangle((now_used_width, 402, now_used_width + int(1007 * full_num[1]), 449), '#c8b6f2')
- await img.text(str(data['总人数'] - data['满星人数']), now_used_width + 18, 413,
- fm.get('bahnschrift_regular.ttf', 30), '#593d99')
+ await img.draw_rectangle(
+ (now_used_width, 402, now_used_width + int(1007 * full_num[1]), 449),
+ '#c8b6f2',
+ )
+ await img.text(
+ str(data['总人数'] - data['满星人数']),
+ now_used_width + 18,
+ 413,
+ fm.get('bahnschrift_regular.ttf', 30),
+ '#593d99',
+ )
# 最高伤害
await img.paste(box[f'{data["最高伤害"][0]["稀有度"]}big'], (39, 512))
await img.paste(box[f'{data["最高伤害"][1]["稀有度"]}small'], (39, 664))
await img.paste(box[f'{data["最高伤害"][2]["稀有度"]}small'], (296, 664))
await img.paste(
- await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][0]["图标"]}.png', size=(124, 124)),
- (44, 525))
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][0]["图标"]}.png',
+ size=(124, 124),
+ ),
+ (44, 525),
+ )
await img.paste(
- await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][1]["图标"]}.png', size=(82, 82)),
- (45, 673))
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][1]["图标"]}.png',
+ size=(82, 82),
+ ),
+ (45, 673),
+ )
await img.paste(
- await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][2]["图标"]}.png', size=(82, 82)),
- (300, 673))
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][2]["图标"]}.png',
+ size=(82, 82),
+ ),
+ (300, 673),
+ )
await img.paste(await get_user_avatar(data['最高伤害'][0]['qq号']), (112, 588))
await img.paste(await get_user_avatar(data['最高伤害'][1]['qq号'], (42, 42)), (87, 713))
await img.paste(await get_user_avatar(data['最高伤害'][2]['qq号'], (42, 42)), (344, 713))
await img.text('最强一击', 180, 515, fm.get('hywh', 30), '#040404')
await img.text('第二名', 139, 668, fm.get('hywh', 22), '#040404')
await img.text('第三名', 397, 668, fm.get('hywh', 22), '#040404')
- await img.text(str(data['最高伤害'][0]['数值']), 180, 547, fm.get('bahnschrift_regular.ttf', 68), '#040404')
- await img.text(str(data['最高伤害'][1]['数值']), 137, 693, fm.get('bahnschrift_regular.ttf', 38), '#040404')
- await img.text(str(data['最高伤害'][2]['数值']), 395, 693, fm.get('bahnschrift_regular.ttf', 38), '#040404')
+ await img.text(
+ str(data['最高伤害'][0]['数值']),
+ 180,
+ 547,
+ fm.get('bahnschrift_regular.ttf', 68),
+ '#040404',
+ )
+ await img.text(
+ str(data['最高伤害'][1]['数值']),
+ 137,
+ 693,
+ fm.get('bahnschrift_regular.ttf', 38),
+ '#040404',
+ )
+ await img.text(
+ str(data['最高伤害'][2]['数值']),
+ 395,
+ 693,
+ fm.get('bahnschrift_regular.ttf', 38),
+ '#040404',
+ )
await img.text(data['最高伤害'][0]['用户名'][:11], 180, 610, fm.get('hywh', 30), '#040404')
await img.text(data['最高伤害'][1]['用户名'][:6], 137, 726, fm.get('hywh', 22), '#040404')
await img.text(data['最高伤害'][2]['用户名'][:6], 395, 726, fm.get('hywh', 22), '#040404')
@@ -186,66 +282,158 @@ async def draw_statistics_img(data: Dict[str, Any]):
await img.paste(box[f'{data["最高承受伤害"][1]["稀有度"]}small'], (552, 664))
await img.paste(box[f'{data["最高承受伤害"][2]["稀有度"]}small'], (808, 664))
await img.paste(
- await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][0]["图标"]}.png', size=(124, 124)),
- (560, 525))
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][0]["图标"]}.png',
+ size=(124, 124),
+ ),
+ (560, 525),
+ )
await img.paste(
- await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][1]["图标"]}.png', size=(82, 82)),
- (557, 673))
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][1]["图标"]}.png',
+ size=(82, 82),
+ ),
+ (557, 673),
+ )
await img.paste(
- await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][2]["图标"]}.png', size=(82, 82)),
- (815, 673))
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][2]["图标"]}.png',
+ size=(82, 82),
+ ),
+ (815, 673),
+ )
await img.paste(await get_user_avatar(data['最高承受伤害'][0]['qq号']), (623, 588))
- await img.paste(await get_user_avatar(data['最高承受伤害'][1]['qq号'], (42, 42)), (600, 713))
- await img.paste(await get_user_avatar(data['最高承受伤害'][2]['qq号'], (42, 42)), (857, 713))
+ await img.paste(
+ await get_user_avatar(data['最高承受伤害'][1]['qq号'], (42, 42)), (600, 713)
+ )
+ await img.paste(
+ await get_user_avatar(data['最高承受伤害'][2]['qq号'], (42, 42)), (857, 713)
+ )
await img.text('最多承伤', 693, 515, fm.get('hywh', 30), '#040404')
await img.text('第二名', 652, 668, fm.get('hywh', 22), '#040404')
await img.text('第三名', 910, 668, fm.get('hywh', 22), '#040404')
- await img.text(str(data['最高承受伤害'][0]['数值']), 693, 547, fm.get('bahnschrift_regular.ttf', 68), '#040404')
- await img.text(str(data['最高承受伤害'][1]['数值']), 650, 693, fm.get('bahnschrift_regular.ttf', 38), '#040404')
- await img.text(str(data['最高承受伤害'][2]['数值']), 908, 693, fm.get('bahnschrift_regular.ttf', 38), '#040404')
- await img.text(data['最高承受伤害'][0]['用户名'][:11], 693, 610, fm.get('hywh', 30), '#040404')
- await img.text(data['最高承受伤害'][1]['用户名'][:6], 650, 726, fm.get('hywh', 22), '#040404')
- await img.text(data['最高承受伤害'][2]['用户名'][:6], 908, 726, fm.get('hywh', 22), '#040404')
+ await img.text(
+ str(data['最高承受伤害'][0]['数值']),
+ 693,
+ 547,
+ fm.get('bahnschrift_regular.ttf', 68),
+ '#040404',
+ )
+ await img.text(
+ str(data['最高承受伤害'][1]['数值']),
+ 650,
+ 693,
+ fm.get('bahnschrift_regular.ttf', 38),
+ '#040404',
+ )
+ await img.text(
+ str(data['最高承受伤害'][2]['数值']),
+ 908,
+ 693,
+ fm.get('bahnschrift_regular.ttf', 38),
+ '#040404',
+ )
+ await img.text(
+ data['最高承受伤害'][0]['用户名'][:11], 693, 610, fm.get('hywh', 30), '#040404'
+ )
+ await img.text(
+ data['最高承受伤害'][1]['用户名'][:6], 650, 726, fm.get('hywh', 22), '#040404'
+ )
+ await img.text(
+ data['最高承受伤害'][2]['用户名'][:6], 908, 726, fm.get('hywh', 22), '#040404'
+ )
tag = await load_image(RESOURCE_BASE_PATH / 'general' / 'tag.png')
# 角色出场率
for i in range(4):
try:
- icon, rarity, count = data['11层上半'][i][0].split('-')[0], data['11层上半'][i][0].split('-')[1], \
- data['11层上半'][i][1]
+ icon, rarity, count = (
+ data['11层上半'][i][0].split('-')[0],
+ data['11层上半'][i][0].split('-')[1],
+ data['11层上半'][i][1],
+ )
await img.paste(box[f'{rarity}bg'], (182 + i * 101, 867))
- await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
- (182 + i * 101, 867))
+ await img.paste(
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)
+ ),
+ (182 + i * 101, 867),
+ )
await img.paste(tag, (236 + i * 101, 942))
- await img.text(str(count), (236 + i * 101, 277 + i * 101), 943, fm.get('bahnschrift_regular.ttf', 19),
- 'white', 'center')
+ await img.text(
+ str(count),
+ (236 + i * 101, 277 + i * 101),
+ 943,
+ fm.get('bahnschrift_regular.ttf', 19),
+ 'white',
+ 'center',
+ )
- icon, rarity, count = data['11层下半'][i][0].split('-')[0], data['11层下半'][i][0].split('-')[1], \
- data['11层下半'][i][1]
+ icon, rarity, count = (
+ data['11层下半'][i][0].split('-')[0],
+ data['11层下半'][i][0].split('-')[1],
+ data['11层下半'][i][1],
+ )
await img.paste(box[f'{rarity}bg'], (642 + i * 101, 867))
- await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
- (642 + i * 101, 867))
+ await img.paste(
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)
+ ),
+ (642 + i * 101, 867),
+ )
await img.paste(tag, (696 + i * 101, 942))
- await img.text(str(count), (696 + i * 101, 737 + i * 101), 943, fm.get('bahnschrift_regular.ttf', 19),
- 'white', 'center')
+ await img.text(
+ str(count),
+ (696 + i * 101, 737 + i * 101),
+ 943,
+ fm.get('bahnschrift_regular.ttf', 19),
+ 'white',
+ 'center',
+ )
- icon, rarity, count = data['12层上半'][i][0].split('-')[0], data['12层上半'][i][0].split('-')[1], \
- data['12层上半'][i][1]
+ icon, rarity, count = (
+ data['12层上半'][i][0].split('-')[0],
+ data['12层上半'][i][0].split('-')[1],
+ data['12层上半'][i][1],
+ )
await img.paste(box[f'{rarity}bg'], (182 + i * 101, 983))
- await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
- (182 + i * 101, 983))
+ await img.paste(
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)
+ ),
+ (182 + i * 101, 983),
+ )
await img.paste(tag, (236 + i * 101, 1058))
- await img.text(str(count), (236 + i * 101, 278 + i * 101), 1059, fm.get('bahnschrift_regular.ttf', 19),
- 'white', 'center')
+ await img.text(
+ str(count),
+ (236 + i * 101, 278 + i * 101),
+ 1059,
+ fm.get('bahnschrift_regular.ttf', 19),
+ 'white',
+ 'center',
+ )
- icon, rarity, count = data['12层下半'][i][0].split('-')[0], data['12层下半'][i][0].split('-')[1], \
- data['12层下半'][i][1]
+ icon, rarity, count = (
+ data['12层下半'][i][0].split('-')[0],
+ data['12层下半'][i][0].split('-')[1],
+ data['12层下半'][i][1],
+ )
await img.paste(box[f'{rarity}bg'], (642 + i * 101, 983))
- await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
- (642 + i * 101, 983))
+ await img.paste(
+ await load_image(
+ RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)
+ ),
+ (642 + i * 101, 983),
+ )
await img.paste(tag, (696 + i * 101, 1058))
- await img.text(str(count), (696 + i * 101, 737 + i * 101), 1059, fm.get('bahnschrift_regular.ttf', 19),
- 'white', 'center')
+ await img.text(
+ str(count),
+ (696 + i * 101, 737 + i * 101),
+ 1059,
+ fm.get('bahnschrift_regular.ttf', 19),
+ 'white',
+ 'center',
+ )
i += 1
except IndexError:
pass
diff --git a/LittlePaimon/plugins/bot_manager/__init__.py b/LittlePaimon/plugins/bot_manager/__init__.py
index 71589c5..900f439 100644
--- a/LittlePaimon/plugins/bot_manager/__init__.py
+++ b/LittlePaimon/plugins/bot_manager/__init__.py
@@ -1,26 +1,27 @@
-import os
import asyncio
import contextlib
+import os
import random
import sys
from pathlib import Path
-from nonebot import on_command, get_bot, get_app
+
+from nonebot import get_app, get_bot, on_command
+from nonebot.adapters.onebot.v11 import (
+ ActionFailed,
+ Bot,
+ GroupMessageEvent,
+ Message,
+ MessageEvent,
+)
+from nonebot.params import Arg, ArgPlainText, CommandArg
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot.rule import to_me
-from nonebot.params import CommandArg, ArgPlainText, Arg
from nonebot.typing import T_State
-from nonebot.adapters.onebot.v11 import (
- Bot,
- Message,
- MessageEvent,
- GroupMessageEvent,
- ActionFailed,
-)
from LittlePaimon.config import config
-from LittlePaimon.utils import NICKNAME, DRIVER, __version__
-from LittlePaimon.utils.files import save_json, load_json
+from LittlePaimon.utils import DRIVER, NICKNAME, __version__
+from LittlePaimon.utils.files import load_json, save_json
from LittlePaimon.utils.update import check_update, update
__plugin_meta__ = PluginMetadata(
@@ -209,11 +210,11 @@ async def _(
@DRIVER.on_bot_connect
-async def _():
+async def _(bot: Bot):
if not (reboot_file := (Path() / 'rebooting.json')).exists():
return
- bot = get_bot()
reboot_data = load_json(reboot_file)
+ reboot_file.unlink()
if reboot_data['session_type'] == 'group':
await bot.send_group_msg(
group_id=reboot_data['session_id'],
@@ -230,4 +231,3 @@ async def _():
group_id=int(group_id), user_id=int(bot.self_id), card=card_info
)
await asyncio.sleep(0.25)
- reboot_file.unlink()