练度统计UI替换
@ -32,12 +32,14 @@ async def send_detail_info(bot: Bot, ev: Event):
|
|||||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||||
if name:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
get_uid_ = await get_uid(bot, ev, True)
|
||||||
uid = await get_uid(bot, ev)
|
if get_uid_ is None:
|
||||||
|
return await bot.send(UID_HINT)
|
||||||
|
uid, user_id = get_uid_
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return '你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!'
|
return await bot.send(UID_HINT)
|
||||||
|
|
||||||
logger.info(f'[sr查询信息]UID: {uid}')
|
logger.info(f'[sr查询信息]UID: {uid}')
|
||||||
await bot.logger.info('开始执行[sr查询信息]')
|
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
|
return None
|
||||||
|
@ -5,6 +5,10 @@ from typing import Dict, List, Optional, Union
|
|||||||
from gsuid_core.logger import logger
|
from gsuid_core.logger import logger
|
||||||
from gsuid_core.utils.error_reply import get_error
|
from gsuid_core.utils.error_reply import get_error
|
||||||
from PIL import Image, ImageDraw
|
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 (
|
from ..sruid_utils.api.mys.models import (
|
||||||
AvatarDetail,
|
AvatarDetail,
|
||||||
@ -13,8 +17,9 @@ from ..sruid_utils.api.mys.models import (
|
|||||||
RoleBasicInfo,
|
RoleBasicInfo,
|
||||||
Stats,
|
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 (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
|
sr_font_22,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
sr_font_26,
|
sr_font_26,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
@ -37,7 +42,8 @@ user_avatar = (
|
|||||||
char_bg_4 = Image.open(TEXT_PATH / 'rarity4_bg.png').convert('RGBA')
|
char_bg_4 = Image.open(TEXT_PATH / 'rarity4_bg.png').convert('RGBA')
|
||||||
char_bg_5 = Image.open(TEXT_PATH / 'rarity5_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')
|
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)
|
bg_color = (248, 248, 248)
|
||||||
white_color = (255, 255, 255)
|
white_color = (255, 255, 255)
|
||||||
color_color = (40, 18, 7)
|
color_color = (40, 18, 7)
|
||||||
@ -65,8 +71,8 @@ elements = {
|
|||||||
async def get_role_img(uid: str) -> Union[bytes, str]:
|
async def get_role_img(uid: str) -> Union[bytes, str]:
|
||||||
return await draw_role_card(uid)
|
return await draw_role_card(uid)
|
||||||
|
|
||||||
async def get_detail_img(uid: str) -> Union[bytes, str]:
|
async def get_detail_img(qid: Union[str, int], uid: str) -> Union[bytes, str]:
|
||||||
return await get_detail_card(uid)
|
return await get_detail_card(qid, uid)
|
||||||
|
|
||||||
def _lv(level: int) -> str:
|
def _lv(level: int) -> str:
|
||||||
return f'Lv.0{level}' if level < 10 else f'Lv.{level}'
|
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]
|
element_icon = elements[avatar.element]
|
||||||
|
|
||||||
char_bg.paste(char_icon, (4, 8), mask=char_icon)
|
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]:
|
if equip := equips[avatar.id]:
|
||||||
char_bg.paste(circle, (0, 0), mask=circle)
|
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
|
avatar_detail: AvatarDetail, avatar: AvatarListItemDetail, index: int, char_info: Image.Image
|
||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
if str(avatar.rarity) == '5':
|
if str(avatar.rarity) == '5':
|
||||||
bg_color = (255, 240, 211)
|
avatar_img = Image.open(TEXT_PATH / 'bar_5.png')
|
||||||
else:
|
else:
|
||||||
bg_color = (239, 222, 255)
|
avatar_img = Image.open(TEXT_PATH / 'bar_4.png')
|
||||||
avatar_img = Image.new('RGBA', (1020, 50), bg_color)
|
|
||||||
avatar_draw = ImageDraw.Draw(avatar_img)
|
avatar_draw = ImageDraw.Draw(avatar_img)
|
||||||
char_icon = (await get_icon(avatar.icon)).resize((40, 40))
|
char_icon = (await get_icon(avatar.icon)).resize((40, 40))
|
||||||
element_icon = elements[avatar.element]
|
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(
|
avatar_draw.text(
|
||||||
(60, 25),
|
(130, 30),
|
||||||
f'{avatar.name}',
|
f'{avatar.name}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
'lm',
|
||||||
)
|
)
|
||||||
avatar_img.paste(element_icon, (195, 10), mask=element_icon)
|
avatar_img.paste(element_icon, (270, 10), mask=element_icon)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(270, 25),
|
(339, 30),
|
||||||
f'{avatar.level}',
|
f'{avatar.level}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -284,7 +299,7 @@ async def _draw_detail_card(
|
|||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(325, 25),
|
(385, 30),
|
||||||
f'{avatar.rank}',
|
f'{avatar.rank}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -292,7 +307,7 @@ async def _draw_detail_card(
|
|||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(380, 25),
|
(429, 30),
|
||||||
f'{avatar_detail.skills[0].cur_level}',
|
f'{avatar_detail.skills[0].cur_level}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -300,7 +315,7 @@ async def _draw_detail_card(
|
|||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(430, 25),
|
(469, 30),
|
||||||
f'{avatar_detail.skills[1].cur_level}',
|
f'{avatar_detail.skills[1].cur_level}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -308,7 +323,7 @@ async def _draw_detail_card(
|
|||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(485, 25),
|
(515, 30),
|
||||||
f'{avatar_detail.skills[2].cur_level}',
|
f'{avatar_detail.skills[2].cur_level}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -316,7 +331,7 @@ async def _draw_detail_card(
|
|||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(540, 25),
|
(553, 30),
|
||||||
f'{avatar_detail.skills[3].cur_level}',
|
f'{avatar_detail.skills[3].cur_level}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -325,137 +340,70 @@ async def _draw_detail_card(
|
|||||||
|
|
||||||
if avatar.equip:
|
if avatar.equip:
|
||||||
|
|
||||||
equip_icon = (await get_icon(avatar.equip.icon)).resize((40, 40))
|
equip_icon = (await get_icon(avatar.equip.icon)).resize((50, 50))
|
||||||
avatar_img.paste(equip_icon, (580, 5), mask=equip_icon)
|
avatar_img.paste(equip_icon, (595, 5), mask=equip_icon)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(640, 25),
|
(680, 30),
|
||||||
f'{avatar.equip.rank}',
|
f'{avatar.equip.rank}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
'mm',
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(680, 25),
|
(734, 30),
|
||||||
f'Lv{avatar.equip.level}',
|
f'Lv.{avatar.equip.level}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
'lm',
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(750, 25),
|
(804, 30),
|
||||||
f'{avatar.equip.name}',
|
f'{avatar.equip.name}',
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
'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
|
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)
|
avatar_list = await mys_api.get_avatar_info(sr_uid, 1001)
|
||||||
if isinstance(avatar_list, int):
|
if isinstance(avatar_list, int):
|
||||||
return get_error(avatar_list)
|
return get_error(avatar_list)
|
||||||
avatar_num = len(avatar_list.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()
|
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_info = char_info.resize((1050, img_height))
|
||||||
char_img_draw = ImageDraw.Draw(char_info)
|
char_img_draw = ImageDraw.Draw(char_info)
|
||||||
|
|
||||||
char_img_draw.text(
|
char_title = Image.open(TEXT_PATH / 'title.png')
|
||||||
(50, 70),
|
char_info.paste(char_title, (0, 0), char_title)
|
||||||
'sr角色练度统计',
|
|
||||||
white_color,
|
|
||||||
sr_font_40,
|
|
||||||
'lm',
|
|
||||||
)
|
|
||||||
|
|
||||||
char_img_draw.text(
|
# 获取头像
|
||||||
(50, 120),
|
_id = str(qid)
|
||||||
f'UID:{sr_uid} 共{avatar_num}名角色',
|
if _id.startswith('http'):
|
||||||
white_color,
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
sr_font_28,
|
else:
|
||||||
'lm',
|
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(char_pic, (400, 88), char_pic)
|
||||||
char_info.paste(title_img, (15, 150), mask=title_img)
|
|
||||||
char_img_draw.text(
|
|
||||||
(115, 180),
|
|
||||||
'角色',
|
|
||||||
white_color,
|
|
||||||
sr_font_26,
|
|
||||||
'mm',
|
|
||||||
)
|
|
||||||
|
|
||||||
char_img_draw.text(
|
# 绘制抬头
|
||||||
(220, 180),
|
char_img_draw.text((525, 420), f'UID {sr_uid}', white_color, sr_font_28, 'mm')
|
||||||
'属性',
|
|
||||||
white_color,
|
|
||||||
sr_font_26,
|
|
||||||
'mm',
|
|
||||||
)
|
|
||||||
|
|
||||||
char_img_draw.text(
|
title_img = Image.open(TEXT_PATH / 'bar_title.png')
|
||||||
(285, 180),
|
char_info.paste(title_img, (0, 515), mask=title_img)
|
||||||
'LV',
|
|
||||||
white_color,
|
|
||||||
sr_font_26,
|
|
||||||
'mm',
|
|
||||||
)
|
|
||||||
|
|
||||||
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):
|
for index, avatar in enumerate(avatar_list.avatar_list):
|
||||||
avatar_detail = await mys_api.get_avatar_detail(sr_uid, str(avatar.id))
|
avatar_detail = await mys_api.get_avatar_detail(sr_uid, str(avatar.id))
|
||||||
if isinstance(avatar_detail, int):
|
if isinstance(avatar_detail, int):
|
||||||
@ -470,10 +418,10 @@ async def get_detail_card(sr_uid: str) -> Union[bytes, str]:
|
|||||||
|
|
||||||
# 写底层文字
|
# 写底层文字
|
||||||
char_img_draw.text(
|
char_img_draw.text(
|
||||||
(525, img_height - 40),
|
(525, img_height - 45),
|
||||||
'--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--',
|
'--SR skill statistics by StarrailUID & Code by jiluoQAQ & Power by GsCore--',
|
||||||
(255, 255, 255),
|
(255, 255, 255),
|
||||||
fw_font_28,
|
fw_font_24,
|
||||||
'mm',
|
'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_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_28 = first_word_origin(28)
|
||||||
fw_font_120 = first_word_origin(34)
|
fw_font_120 = first_word_origin(34)
|
||||||
|