练度统计UI替换
@ -32,12 +32,14 @@ async def send_detail_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
uid = await get_uid(bot, ev)
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
if uid is None:
|
||||
return '你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!'
|
||||
return await bot.send(UID_HINT)
|
||||
|
||||
logger.info(f'[sr查询信息]UID: {uid}')
|
||||
await bot.logger.info('开始执行[sr查询信息]')
|
||||
await bot.send(await get_detail_img(uid))
|
||||
await bot.send(await get_detail_img(user_id, uid))
|
||||
return None
|
||||
|
@ -5,6 +5,10 @@ from typing import Dict, List, Optional, Union
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
get_qq_avatar,
|
||||
draw_pic_with_ring,
|
||||
)
|
||||
|
||||
from ..sruid_utils.api.mys.models import (
|
||||
AvatarDetail,
|
||||
@ -13,8 +17,9 @@ from ..sruid_utils.api.mys.models import (
|
||||
RoleBasicInfo,
|
||||
Stats,
|
||||
)
|
||||
from ..utils.fonts.first_world import fw_font_28
|
||||
from ..utils.fonts.first_world import fw_font_24
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_22,
|
||||
sr_font_24,
|
||||
sr_font_26,
|
||||
sr_font_28,
|
||||
@ -37,7 +42,8 @@ user_avatar = (
|
||||
char_bg_4 = Image.open(TEXT_PATH / 'rarity4_bg.png').convert('RGBA')
|
||||
char_bg_5 = Image.open(TEXT_PATH / 'rarity5_bg.png').convert('RGBA')
|
||||
circle = Image.open(TEXT_PATH / 'char_weapon_bg.png').convert('RGBA')
|
||||
bg_img = Image.open(TEXT_PATH / 'bg.png')
|
||||
bg_img = Image.open(TEXT_PATH / 'bg_light.jpg')
|
||||
rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA')
|
||||
bg_color = (248, 248, 248)
|
||||
white_color = (255, 255, 255)
|
||||
color_color = (40, 18, 7)
|
||||
@ -65,8 +71,8 @@ elements = {
|
||||
async def get_role_img(uid: str) -> Union[bytes, str]:
|
||||
return await draw_role_card(uid)
|
||||
|
||||
async def get_detail_img(uid: str) -> Union[bytes, str]:
|
||||
return await get_detail_card(uid)
|
||||
async def get_detail_img(qid: Union[str, int], uid: str) -> Union[bytes, str]:
|
||||
return await get_detail_card(qid, uid)
|
||||
|
||||
def _lv(level: int) -> str:
|
||||
return f'Lv.0{level}' if level < 10 else f'Lv.{level}'
|
||||
@ -160,7 +166,17 @@ async def _draw_avatar_card(
|
||||
element_icon = elements[avatar.element]
|
||||
|
||||
char_bg.paste(char_icon, (4, 8), mask=char_icon)
|
||||
char_bg.paste(element_icon, (81, 10), mask=element_icon)
|
||||
char_bg.paste(element_icon, (10, 10), mask=element_icon)
|
||||
|
||||
if avatar.rank > 0:
|
||||
char_bg.paste(rank_bg, (89, 6), mask=rank_bg)
|
||||
char_draw.text(
|
||||
(100, 21),
|
||||
f'{avatar.rank}',
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
if equip := equips[avatar.id]:
|
||||
char_bg.paste(circle, (0, 0), mask=circle)
|
||||
@ -258,25 +274,24 @@ async def _draw_detail_card(
|
||||
avatar_detail: AvatarDetail, avatar: AvatarListItemDetail, index: int, char_info: Image.Image
|
||||
) -> Image.Image:
|
||||
if str(avatar.rarity) == '5':
|
||||
bg_color = (255, 240, 211)
|
||||
avatar_img = Image.open(TEXT_PATH / 'bar_5.png')
|
||||
else:
|
||||
bg_color = (239, 222, 255)
|
||||
avatar_img = Image.new('RGBA', (1020, 50), bg_color)
|
||||
avatar_img = Image.open(TEXT_PATH / 'bar_4.png')
|
||||
avatar_draw = ImageDraw.Draw(avatar_img)
|
||||
char_icon = (await get_icon(avatar.icon)).resize((40, 40))
|
||||
element_icon = elements[avatar.element]
|
||||
avatar_img.paste(char_icon, (5, 5), mask=char_icon)
|
||||
avatar_img.paste(char_icon, (75, 10), mask=char_icon)
|
||||
avatar_draw.text(
|
||||
(60, 25),
|
||||
(130, 30),
|
||||
f'{avatar.name}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
)
|
||||
avatar_img.paste(element_icon, (195, 10), mask=element_icon)
|
||||
avatar_img.paste(element_icon, (270, 10), mask=element_icon)
|
||||
|
||||
avatar_draw.text(
|
||||
(270, 25),
|
||||
(339, 30),
|
||||
f'{avatar.level}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
@ -284,7 +299,7 @@ async def _draw_detail_card(
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(325, 25),
|
||||
(385, 30),
|
||||
f'{avatar.rank}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
@ -292,7 +307,7 @@ async def _draw_detail_card(
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(380, 25),
|
||||
(429, 30),
|
||||
f'{avatar_detail.skills[0].cur_level}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
@ -300,7 +315,7 @@ async def _draw_detail_card(
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(430, 25),
|
||||
(469, 30),
|
||||
f'{avatar_detail.skills[1].cur_level}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
@ -308,7 +323,7 @@ async def _draw_detail_card(
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(485, 25),
|
||||
(515, 30),
|
||||
f'{avatar_detail.skills[2].cur_level}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
@ -316,7 +331,7 @@ async def _draw_detail_card(
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(540, 25),
|
||||
(553, 30),
|
||||
f'{avatar_detail.skills[3].cur_level}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
@ -325,137 +340,70 @@ async def _draw_detail_card(
|
||||
|
||||
if avatar.equip:
|
||||
|
||||
equip_icon = (await get_icon(avatar.equip.icon)).resize((40, 40))
|
||||
avatar_img.paste(equip_icon, (580, 5), mask=equip_icon)
|
||||
equip_icon = (await get_icon(avatar.equip.icon)).resize((50, 50))
|
||||
avatar_img.paste(equip_icon, (595, 5), mask=equip_icon)
|
||||
|
||||
avatar_draw.text(
|
||||
(640, 25),
|
||||
(680, 30),
|
||||
f'{avatar.equip.rank}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
'mm',
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(680, 25),
|
||||
f'Lv{avatar.equip.level}',
|
||||
(734, 30),
|
||||
f'Lv.{avatar.equip.level}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(750, 25),
|
||||
(804, 30),
|
||||
f'{avatar.equip.name}',
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
)
|
||||
|
||||
char_info.paste(avatar_img, (15, 211 + 51 * index), mask=avatar_img)
|
||||
char_info.paste(avatar_img, (0, 585 + 62 * index), mask=avatar_img)
|
||||
|
||||
return char_info
|
||||
|
||||
async def get_detail_card(sr_uid: str) -> Union[bytes, str]:
|
||||
async def get_detail_card(qid: Union[str, int], sr_uid: str) -> Union[bytes, str]:
|
||||
# 获取角色列表
|
||||
avatar_list = await mys_api.get_avatar_info(sr_uid, 1001)
|
||||
if isinstance(avatar_list, int):
|
||||
return get_error(avatar_list)
|
||||
avatar_num = len(avatar_list.avatar_list)
|
||||
img_height = 300 + avatar_num * 51
|
||||
img_height = 663 + avatar_num * 62
|
||||
char_info = bg_img.copy()
|
||||
if img_height < 2300:
|
||||
char_info = char_info.crop((0, 0, 1050, img_height))
|
||||
else:
|
||||
char_info = char_info.resize((1050, img_height))
|
||||
char_img_draw = ImageDraw.Draw(char_info)
|
||||
|
||||
char_img_draw.text(
|
||||
(50, 70),
|
||||
'sr角色练度统计',
|
||||
white_color,
|
||||
sr_font_40,
|
||||
'lm',
|
||||
)
|
||||
char_title = Image.open(TEXT_PATH / 'title.png')
|
||||
char_info.paste(char_title, (0, 0), char_title)
|
||||
|
||||
char_img_draw.text(
|
||||
(50, 120),
|
||||
f'UID:{sr_uid} 共{avatar_num}名角色',
|
||||
white_color,
|
||||
sr_font_28,
|
||||
'lm',
|
||||
)
|
||||
# 获取头像
|
||||
_id = str(qid)
|
||||
if _id.startswith('http'):
|
||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||
else:
|
||||
char_pic = await get_qq_avatar(qid=qid)
|
||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||
|
||||
title_img = Image.new('RGBA', (1020, 60), (0, 0, 0, 150))
|
||||
char_info.paste(title_img, (15, 150), mask=title_img)
|
||||
char_img_draw.text(
|
||||
(115, 180),
|
||||
'角色',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
char_info.paste(char_pic, (400, 88), char_pic)
|
||||
|
||||
char_img_draw.text(
|
||||
(220, 180),
|
||||
'属性',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
# 绘制抬头
|
||||
char_img_draw.text((525, 420), f'UID {sr_uid}', white_color, sr_font_28, 'mm')
|
||||
|
||||
char_img_draw.text(
|
||||
(285, 180),
|
||||
'LV',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
title_img = Image.open(TEXT_PATH / 'bar_title.png')
|
||||
char_info.paste(title_img, (0, 515), mask=title_img)
|
||||
|
||||
char_img_draw.text(
|
||||
(340, 180),
|
||||
'星魂',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
|
||||
char_img_draw.text(
|
||||
(395, 180),
|
||||
'N',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
|
||||
char_img_draw.text(
|
||||
(445, 180),
|
||||
'B',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
|
||||
char_img_draw.text(
|
||||
(500, 180),
|
||||
'U',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
|
||||
char_img_draw.text(
|
||||
(555, 180),
|
||||
'T',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
|
||||
char_img_draw.text(
|
||||
(745, 180),
|
||||
'光锥',
|
||||
white_color,
|
||||
sr_font_26,
|
||||
'mm',
|
||||
)
|
||||
for index, avatar in enumerate(avatar_list.avatar_list):
|
||||
avatar_detail = await mys_api.get_avatar_detail(sr_uid, str(avatar.id))
|
||||
if isinstance(avatar_detail, int):
|
||||
@ -470,10 +418,10 @@ async def get_detail_card(sr_uid: str) -> Union[bytes, str]:
|
||||
|
||||
# 写底层文字
|
||||
char_img_draw.text(
|
||||
(525, img_height - 40),
|
||||
'--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--',
|
||||
(525, img_height - 45),
|
||||
'--SR skill statistics by StarrailUID & Code by jiluoQAQ & Power by GsCore--',
|
||||
(255, 255, 255),
|
||||
fw_font_28,
|
||||
fw_font_24,
|
||||
'mm',
|
||||
)
|
||||
|
||||
|
BIN
StarRailUID/starrailuid_roleinfo/texture2D/bar_4.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
StarRailUID/starrailuid_roleinfo/texture2D/bar_5.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
StarRailUID/starrailuid_roleinfo/texture2D/bar_title.png
Normal file
After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 1.2 MiB |
BIN
StarRailUID/starrailuid_roleinfo/texture2D/bg_light.jpg
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
StarRailUID/starrailuid_roleinfo/texture2D/rank_bg.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
StarRailUID/starrailuid_roleinfo/texture2D/title.png
Normal file
After Width: | Height: | Size: 73 KiB |
@ -10,5 +10,7 @@ def first_word_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||
|
||||
|
||||
fw_font_12 = first_word_origin(12)
|
||||
fw_font_24 = first_word_origin(24)
|
||||
fw_font_26 = first_word_origin(26)
|
||||
fw_font_28 = first_word_origin(28)
|
||||
fw_font_120 = first_word_origin(34)
|
||||
|