🐛 修复多bot连接时深渊统计猜语音可能报错的问题

This commit is contained in:
CMHopeSunshine 2023-02-17 22:36:31 +08:00
parent 9f88e385c5
commit 4c3b1e5631
5 changed files with 477 additions and 187 deletions

View File

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

View File

@ -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'➤群<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:

View File

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

View File

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

View File

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