mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2024-10-21 16:27:15 +08:00
🐛 修复多bot连接时深渊统计
和猜语音
可能报错的问题
This commit is contained in:
parent
9f88e385c5
commit
4c3b1e5631
@ -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(
|
||||
@ -23,44 +36,67 @@ __plugin_meta__ = PluginMetadata(
|
||||
'author': '惜月',
|
||||
'version': '3.0',
|
||||
'priority': 6,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
guess_voice = on_command('原神猜语音', priority=12, block=True, state={
|
||||
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_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_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_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_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)
|
||||
|
||||
|
@ -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),
|
||||
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)
|
||||
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'➤群<m>{self.group_id}</m>猜语音游戏结束,答案为<m>{answer}</m>,没有人猜对')
|
||||
logger.info(
|
||||
'原神猜语音', f'➤群<m>{self.group_id}</m>猜语音游戏结束,答案为<m>{answer}</m>,没有人猜对'
|
||||
)
|
||||
elif exception:
|
||||
logger.warning('原神猜语音', f'➤群<m>{self.group_id}</m>猜语音游戏发送语音出错, 异常结束')
|
||||
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'➤群<m>{event.group_id}</m>猜语音游戏结束,答案为<m>{role_name}</m>,由<m>{event.sender.card}</m>猜对')
|
||||
msg = Message(MessageSegment.text('恭喜') + MessageSegment.at(event.user_id) + MessageSegment.text(
|
||||
f'猜对了!\n正确答案是:{role_name}'))
|
||||
logger.info(
|
||||
'原神猜语音',
|
||||
f'➤群<m>{event.group_id}</m>猜语音游戏结束,答案为<m>{role_name}</m>,由<m>{event.sender.card}</m>猜对',
|
||||
)
|
||||
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:
|
||||
|
@ -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
|
||||
@ -18,27 +19,45 @@ __plugin_meta__ = PluginMetadata(
|
||||
'author': '惜月',
|
||||
'version': '3.0',
|
||||
'priority': 2,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
sy = on_command('sy', aliases={'深渊战报', '深渊信息'}, priority=10, block=True, state={
|
||||
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_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_priority': 2,
|
||||
},
|
||||
)
|
||||
abyss_team = on_command(
|
||||
'深渊配队',
|
||||
aliases={'配队推荐', '深渊阵容'},
|
||||
priority=10,
|
||||
block=True,
|
||||
state={
|
||||
'pm_name': '深渊配队',
|
||||
'pm_description': '查看深渊配队推荐,数据来源于游创工坊',
|
||||
'pm_usage': '深渊配队',
|
||||
'pm_priority': 3
|
||||
})
|
||||
'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)
|
||||
|
@ -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,20 +36,26 @@ 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']):
|
||||
@ -53,7 +63,7 @@ async def get_statistics(group_id: int):
|
||||
break
|
||||
data = {
|
||||
'群号': str(group_id),
|
||||
'群名称': (await get_bot().get_group_info(group_id=group_id))['group_name'],
|
||||
'群名称': (await bot.get_group_info(group_id=group_id))['group_name'],
|
||||
}
|
||||
# 数据数
|
||||
info_num = len(info_list)
|
||||
@ -65,7 +75,9 @@ 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)
|
||||
@ -80,10 +92,13 @@ async def get_statistics(group_id: int):
|
||||
'用户名': info.nickname,
|
||||
'qq号': info.user_id,
|
||||
'uid': info.uid,
|
||||
} for info in max_damage[:3]
|
||||
}
|
||||
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,
|
||||
@ -94,7 +109,8 @@ async def get_statistics(group_id: int):
|
||||
'用户名': info.nickname,
|
||||
'qq号': info.user_id,
|
||||
'uid': info.uid,
|
||||
} for info in max_take_damage[:3]
|
||||
}
|
||||
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)
|
||||
@ -130,53 +150,129 @@ async def draw_statistics_img(data: Dict[str, Any]):
|
||||
'4small': await load_image(RESOURCE_BASE_PATH / 'abyss' / '4smallbox.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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user