diff --git a/GenshinUID/genshinuid_config/draw_config_card.py b/GenshinUID/genshinuid_config/draw_config_card.py index 6f97a8d5..a82d8bcf 100644 --- a/GenshinUID/genshinuid_config/draw_config_card.py +++ b/GenshinUID/genshinuid_config/draw_config_card.py @@ -3,7 +3,6 @@ from pathlib import Path from typing import Union from PIL import Image, ImageDraw - from gsuid_core.logger import logger from .gs_config import gsconfig diff --git a/GenshinUID/genshinuid_start/__init__.py b/GenshinUID/genshinuid_start/__init__.py index 71929fa4..c327d3ae 100644 --- a/GenshinUID/genshinuid_start/__init__.py +++ b/GenshinUID/genshinuid_start/__init__.py @@ -9,6 +9,10 @@ from ..genshinuid_xkdata import draw_xk_abyss_img from ..genshinuid_help.draw_help_card import draw_help_img from ..genshinuid_guide.get_abyss_data import generate_data from ..utils.resource.generate_char_card import create_all_char_card +from ..genshinuid_xkdata.get_all_char_data import ( + save_all_char_info, + save_all_abyss_rank, +) async def all_start(): @@ -19,6 +23,8 @@ async def all_start(): await create_all_char_card() await draw_xk_abyss_img() await generate_data() + await save_all_char_info() + await save_all_abyss_rank() except Exception as e: logger.exception(e) diff --git a/GenshinUID/genshinuid_user/qrlogin.py b/GenshinUID/genshinuid_user/qrlogin.py index 2b5832e6..9d1b8b8f 100644 --- a/GenshinUID/genshinuid_user/qrlogin.py +++ b/GenshinUID/genshinuid_user/qrlogin.py @@ -6,11 +6,10 @@ from http.cookies import SimpleCookie from typing import Any, List, Tuple, Union, Literal import qrcode -from qrcode.constants import ERROR_CORRECT_L - from gsuid_core.bot import Bot from gsuid_core.models import Event from gsuid_core.logger import logger +from qrcode.constants import ERROR_CORRECT_L from gsuid_core.segment import MessageSegment from ..utils.mys_api import mys_api diff --git a/GenshinUID/genshinuid_xkdata/__init__.py b/GenshinUID/genshinuid_xkdata/__init__.py index 27c06e6b..ea3e4b28 100644 --- a/GenshinUID/genshinuid_xkdata/__init__.py +++ b/GenshinUID/genshinuid_xkdata/__init__.py @@ -7,6 +7,7 @@ from gsuid_core.models import Event from gsuid_core.aps import scheduler from ..utils.image.convert import convert_img +from .draw_char_abyss import draw_char_abyss_info from .draw_abyss_total import TOTAL_IMG, draw_xk_abyss_img from .get_all_char_data import save_all_char_info, save_all_abyss_rank @@ -32,3 +33,9 @@ async def send_abyss_pic(bot: Bot, ev: Event): img = await convert_img(TOTAL_IMG) await bot.logger.info('获得深渊概览图片成功!') await bot.send(img) + + +@sv_get_abyss_database.on_prefix(('角色深渊详情', '角色深渊'), block=True) +async def send_char_abyss_pic(bot: Bot, ev: Event): + im = await draw_char_abyss_info(ev.text) + await bot.send(im) diff --git a/GenshinUID/genshinuid_xkdata/draw_char_abyss.py b/GenshinUID/genshinuid_xkdata/draw_char_abyss.py new file mode 100644 index 00000000..12b5cb85 --- /dev/null +++ b/GenshinUID/genshinuid_xkdata/draw_char_abyss.py @@ -0,0 +1,140 @@ +from pathlib import Path +from typing import Union + +from PIL import Image, ImageDraw + +from ..utils.image.convert import convert_img +from ..utils.map.GS_MAP_PATH import artifact2attr +from .get_all_char_data import get_akasha_char_data +from ..utils.fonts.genshin_fonts import gs_font_20, gs_font_40 +from ..utils.image.image_tools import get_color_bg, draw_pic_with_ring +from ..utils.resource.generate_char_card import create_single_item_card +from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name +from ..utils.resource.RESOURCE_PATH import REL_PATH, CHAR_PATH, WEAPON_PATH + +black = (10, 10, 10) +grey = (40, 40, 40) + +green = (205, 255, 168) +red = (255, 168, 168) + +TEXT_PATH = Path(__file__).parent / 'texture2d' + +rank_dict = { + 90: (189, 64, 64), + 80: (189, 64, 148), + 60: (95, 64, 189), + 40: (64, 140, 189), + 20: (64, 189, 125), + 0: (200, 200, 200), +} + + +async def draw_char_abyss_info(char_name: str) -> Union[bytes, str]: + char_name = await alias_to_char_name(char_name) + char_id = await name_to_avatar_id(char_name) + # _char_id = char_id[1:].lstrip('0') + char_useage_rank = [] + char_img = Image.open(CHAR_PATH / f'{char_id}.png') + char_pic = await draw_pic_with_ring(char_img, 264) + + _data = await get_akasha_char_data(char_name) + if _data is None: + return '没有该角色的数据...' + + all_char_info, char_useage_rank = _data[0], _data[1] + + char_useage_rank.sort(key=lambda d: int(d['v'])) + + title_bg = Image.open(TEXT_PATH / 'title_bg.png') + + # 计算宽高 + h = 1080 + len(char_useage_rank) * 30 + + # 开始绘图 + img = await get_color_bg(900, h, '_abyss_char') + _img = Image.new('RGBA', img.size) + img.paste(char_pic, (300, 118), char_pic) + img.paste(title_bg, (0, 400), title_bg) + + # 基础文字部分 + img_draw = ImageDraw.Draw(_img) + img_draw.text((450, 450), f'{char_name}的深渊统计', 'White', gs_font_40, 'mm') + + # 绘图 + r = 20 + bg_color = (255, 255, 255, 120) + img_draw.rounded_rectangle((24, 538, 876, 746), r, bg_color) + img_draw.rounded_rectangle((24, 761, 876, 969), r, bg_color) + img_draw.rounded_rectangle((24, 988, 876, h - 40), r, bg_color) + + _start = 1020 + bar_bg = (0, 0, 0, 128) + + for index, rank in enumerate(char_useage_rank): + _intent = _start + index * 30 + y1, y2 = _intent + 9, _intent + 23 + img_draw.rounded_rectangle((108, y1, 708, y2), r, bar_bg) + + d = float(rank["d"]) + _pixel = int((d / 100) * 600) + for _p in rank_dict: + if d >= _p: + fill = rank_dict[_p] + break + else: + fill = (255, 255, 255) + img_draw.rounded_rectangle((108, y1, 108 + _pixel, y2), r, fill) + + value = f'{rank["d"]}% / {rank["r"]}名' + img_draw.text( + (37, 16 + _intent), f'版本{rank["v"]}', 'Black', gs_font_20, 'lm' + ) + img_draw.text((730, 16 + _intent), value, 'Black', gs_font_20, 'lm') + + img.paste(_img, (0, 0), _img) + + # 开始 + for index, weapon in enumerate(all_char_info['weapons']): + if weapon['name'] == '渔获': + weapon_name = '「渔获」' + else: + weapon_name = weapon['name'] + weapon_img = Image.open(WEAPON_PATH / f'{weapon_name}.png') + item = await create_single_item_card(weapon_img, weapon['rarity']) + item_draw = ImageDraw.Draw(item) + weapon_rate = weapon['rate'] + '%' + item_draw.text((128, 280), weapon_rate, 'Black', gs_font_40, 'mm') + item = item.resize((128, 155)) + img.paste(item, (47 + 135 * index, 565), item) + if index >= 5: + break + + for index, equip in enumerate(all_char_info['equips']): + item_list = [] + item_type = 0 + for set in equip['set_list']: + for part in artifact2attr: + if artifact2attr[part] == set['name']: + part_name = part + break + else: + part_name = '冰风迷途的勇士' + item = Image.open(REL_PATH / f'{part_name}.png') + item_list.append(item) + item_type += int(set['count']) + + item = await create_single_item_card(item_list, '5') + + item_draw = ImageDraw.Draw(item) + equip_rate = equip['rate'] + '%' + item_draw.text((128, 280), equip_rate, 'Black', gs_font_40, 'mm') + + item_draw.rounded_rectangle((200, 20, 240, 60), 15, (255, 255, 255)) + item_draw.text((220, 40), f'{item_type}', 'Black', gs_font_40, 'mm') + + item = item.resize((128, 155)) + img.paste(item, (47 + 135 * index, 788), item) + if index >= 5: + break + return await convert_img(img) diff --git a/GenshinUID/genshinuid_xkdata/get_all_char_data.py b/GenshinUID/genshinuid_xkdata/get_all_char_data.py index d8705f7b..ffc18a16 100644 --- a/GenshinUID/genshinuid_xkdata/get_all_char_data.py +++ b/GenshinUID/genshinuid_xkdata/get_all_char_data.py @@ -22,13 +22,13 @@ abyss_rank_path = DATA_PATH / 'abyss_rank.json' async def save_all_char_info(): all_char_info = await get_akasha_all_char_info() async with aiofiles.open(all_char_info_path, 'w') as f: - await f.write(str(all_char_info)) + await f.write(json.dumps(all_char_info)) async def save_all_abyss_rank(): abyss_rank = await get_akasha_abyss_rank() async with aiofiles.open(abyss_rank_path, 'w') as f: - await f.write(str(abyss_rank)) + await f.write(json.dumps(abyss_rank)) async def get_akasha_char_data( @@ -52,7 +52,7 @@ async def get_akasha_char_data( if not char_id: return None - _char_id = char_id.lstrip('100000').strip('0') + _char_id = char_id.lstrip('1').lstrip('0') if _char_id not in all_char_info: return None diff --git a/GenshinUID/genshinuid_xkdata/texture2d/title_bg.png b/GenshinUID/genshinuid_xkdata/texture2d/title_bg.png new file mode 100644 index 00000000..9a6b787c Binary files /dev/null and b/GenshinUID/genshinuid_xkdata/texture2d/title_bg.png differ diff --git a/GenshinUID/utils/image/bg/sp_bg/_abyss_char.jpg b/GenshinUID/utils/image/bg/sp_bg/_abyss_char.jpg new file mode 100644 index 00000000..c6ef3999 Binary files /dev/null and b/GenshinUID/utils/image/bg/sp_bg/_abyss_char.jpg differ diff --git a/GenshinUID/utils/resource/generate_char_card.py b/GenshinUID/utils/resource/generate_char_card.py index 82eb21cf..2dcf37f2 100644 --- a/GenshinUID/utils/resource/generate_char_card.py +++ b/GenshinUID/utils/resource/generate_char_card.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import List, Union from PIL import Image from gsuid_core.logger import logger @@ -9,6 +9,32 @@ from .RESOURCE_PATH import CHAR_PATH, TEXT2D_PATH, CHAR_CARD_PATH texture2d_path = TEXT2D_PATH / 'char_card' +async def create_single_item_card( + item_img: Union[List[Image.Image], Image.Image], star: Union[int, str] +) -> Image.Image: + if isinstance(item_img, List): + img = Image.new('RGBA', (256, 256)) + for i, item in enumerate(item_img): + _intent = int(128 / (i + 1)) + _intent2 = int((256 + (128 * (len(item_img) - 1))) / len(item_img)) + item = item.resize((_intent2, _intent2)) + img.paste(item, (128 - _intent, 128 - _intent), item) + item_img = img + + if item_img.size != (256, 256): + item_img = item_img.resize((256, 256)) + char_frame = Image.open(texture2d_path / 'frame.png') + char_bg = Image.open(texture2d_path / f'star{star}bg.png') + mask = Image.open(texture2d_path / 'mask.png') + img = Image.new('RGBA', (256, 310)) + img_mask = Image.new('RGBA', (256, 310)) + img_mask.paste(char_bg, (0, 0), char_bg) + img_mask.paste(item_img, (0, 0), item_img) + img_mask.paste(char_frame, (0, 0), char_frame) + img.paste(img_mask, (0, 0), mask) + return img + + async def create_single_char_card(char_id: Union[str, int]) -> Image.Image: if str(char_id) not in avatarId2Star_data: logger.warning(f'资源文件夹发现异常图片{char_id}....忽略加载...') diff --git a/GenshinUID/utils/resource/texture2d/char_card/star1bg.png b/GenshinUID/utils/resource/texture2d/char_card/star1bg.png new file mode 100644 index 00000000..229b5a8f Binary files /dev/null and b/GenshinUID/utils/resource/texture2d/char_card/star1bg.png differ diff --git a/GenshinUID/utils/resource/texture2d/char_card/star2bg.png b/GenshinUID/utils/resource/texture2d/char_card/star2bg.png new file mode 100644 index 00000000..e4f6f5e1 Binary files /dev/null and b/GenshinUID/utils/resource/texture2d/char_card/star2bg.png differ diff --git a/GenshinUID/utils/resource/texture2d/char_card/star3bg.png b/GenshinUID/utils/resource/texture2d/char_card/star3bg.png new file mode 100644 index 00000000..f54c84c2 Binary files /dev/null and b/GenshinUID/utils/resource/texture2d/char_card/star3bg.png differ