diff --git a/ArknightsUID/arknightsuid_wiki/__init__.py b/ArknightsUID/arknightsuid_wiki/__init__.py index 71ed30b..4504430 100644 --- a/ArknightsUID/arknightsuid_wiki/__init__.py +++ b/ArknightsUID/arknightsuid_wiki/__init__.py @@ -1,8 +1,13 @@ +import asyncio import re +from pathlib import Path from gsuid_core.bot import Bot +from gsuid_core.data_store import get_res_path from gsuid_core.models import Event +from gsuid_core.plugins.ArknightsUID.ArknightsUID.arknightsuid_resource.memoryStore import store from gsuid_core.plugins.ArknightsUID.ArknightsUID.arknightsuid_wiki.draw_wiki_img import ( + # draw_wiki, get_equip_info, get_wiki_info, ) @@ -32,6 +37,15 @@ async def text2pic(text: str, max_size: int = 800, font_size: int = 20): async def send_role_wiki_pic(bot: Bot, ev: Event): char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) + try: + CHARACTER_TABLE = Excel.CHARATER_TABLE + except AttributeError: + TASK = [] + for file_path in Path(get_res_path(['ArknightsUID', 'resource', 'gamedata'])).glob('*.json'): + TASK.append(store.get_file(file_path)) + asyncio.gather(*TASK) + + await Excel.preload_table() CHARACTER_TABLE = Excel.CHARATER_TABLE char_id = None @@ -43,6 +57,7 @@ async def send_role_wiki_pic(bot: Bot, ev: Event): await bot.send('未找到该干员') return await bot.logger.info(f'开始获取{char_name}图鉴') + # img = await draw_wiki(char_id=char_id) img = await get_wiki_info(char_id=char_id) await bot.send(await text2pic(img)) @@ -51,6 +66,15 @@ async def send_role_wiki_pic(bot: Bot, ev: Event): async def send_equip_wiki_pic(bot: Bot, ev: Event): char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) + try: + CHARACTER_TABLE = Excel.CHARATER_TABLE + except AttributeError: + TASK = [] + for file_path in Path(get_res_path(['ArknightsUID', 'resource', 'gamedata'])).glob('*.json'): + TASK.append(store.get_file(file_path)) + asyncio.gather(*TASK) + + await Excel.preload_table() CHARACTER_TABLE = Excel.CHARATER_TABLE char_id = None diff --git a/ArknightsUID/arknightsuid_wiki/draw_wiki_img.py b/ArknightsUID/arknightsuid_wiki/draw_wiki_img.py index 10ae1ac..9c1d586 100644 --- a/ArknightsUID/arknightsuid_wiki/draw_wiki_img.py +++ b/ArknightsUID/arknightsuid_wiki/draw_wiki_img.py @@ -1,17 +1,23 @@ import asyncio import re from pathlib import Path -from typing import Union +from pprint import pformat +from typing import Any, Dict, Union +from colorama import Fore, Style +from gsuid_core.utils.colortext.ColorText import ColorTextGroup, split_ctg +from gsuid_core.utils.image.image_tools import draw_text_by_line from jinja2 import Template from PIL import Image, ImageDraw from ..arknightsuid_resource.constants import Excel from ..utils.fonts.source_han_sans import ( - # sans_font_18, - # sans_font_26, - # sans_font_34, - # sans_font_50, + sans_font_18, + sans_font_20, + sans_font_24, + sans_font_26, + sans_font_34, + sans_font_50, sans_font_120, ) @@ -80,7 +86,18 @@ potential_id_to_cn = { } -def render_template(template_str, data): +def test_ctg(length: int, *params): + print( + f'{Fore.GREEN}> running split_ctg(){Style.RESET_ALL}\ + \n length: {length}\ + \n texts: {params}' + ) + groups_ = ColorTextGroup(list(params)) + f_ = pformat(split_ctg(groups_, length)).split('\n') + print(Fore.CYAN, '\t', f_[0], '\n\t'.join(f_[0:])) + + +def render_template(template_str: str, data: Dict[str, Union[float, int]]): matches = re.finditer(r'\{([^}:]+)\}', template_str) matches_1 = re.finditer(r'\{([^{}]+):([^{}]+)\}', template_str) @@ -91,8 +108,13 @@ def render_template(template_str, data): placeholder_data[placeholder[0]] = (formatting_option, data.get(placeholder[0], '')) for match in matches_1: placeholder, formatting_option = match.groups() - - placeholder_data[placeholder] = (formatting_option, data.get(placeholder.replace('-', ''), '')) + value = data.get(placeholder.replace('-', ''), '') + # 可以在下列状态和初始状态间切换:\n攻击范围缩小,防御力+{def:0%}, + # 每秒恢复最大生命的{HP_RECOVERY_PER_SEC_BY_MAX_HP_RATIO:0.0%} + # {'def': 1, 'hp_recovery_per_sec_by_max_hp_ratio': 0.06} + if value == '': + value = data.get(placeholder.replace('-', '_').lower(), '') + placeholder_data[placeholder] = (formatting_option, value) for placeholder, (formatting_option, value) in placeholder_data.items(): if formatting_option == '': @@ -367,18 +389,19 @@ async def draw_wiki(char_id: str): CHARACTER_TABLE = Excel.CHARATER_TABLE SKILL_TABLE = Excel.SKILL_TABLE UNIEQUIP_TABLE = Excel.UNIEQUIP_TABLE + RANGE_TABLE = Excel.RANGE_TABLE img = Image.new('RGBA', (1500, 2800), (255, 255, 255, 0)) draw = ImageDraw.Draw(img) img.paste(bg_img, (0, 0)) img.paste(vvan_img, (-700, -100), vvan_img) - img.paste(title_img, (0, 0), title_img) + img.paste(title_img, (0, -50), title_img) character_data = CHARACTER_TABLE[char_id] char_name = character_data.name draw.text( - (80, 145), + (144, 85), char_name, font=sans_font_120, fill=black_color, @@ -387,24 +410,202 @@ async def draw_wiki(char_id: str): char_rarity = character_data.rarity rarity_img = Image.open(TEXTURE2D_PATH / f'rarity_yellow_{char_rarity}.png') - img.paste(rarity_img, (800, 300), rarity_img) + img.paste(rarity_img, (960, 120), rarity_img) profession = character_data.profession profession_img = Image.open(TEXTURE2D_PATH / f'icon_{profession.lower()}.png') - img.paste(profession_img, (1000, 500), profession_img) + img.paste(profession_img, (1100, 7050), profession_img) + + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (290, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) char_position = character_data.position + char_position_cn = char_position_en_to_cn[char_position] + bar_img_draw.text( + (160, 100), + char_position_cn, + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + sub_profession_id = character_data.subProfessionId sub_profession = UNIEQUIP_TABLE.subProfDict[sub_profession_id].subProfessionName + bar_img_draw.text( + (360, 100), + sub_profession, + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + img.paste(bar_img, (40, 110), bar_img) + nation_id = character_data.nationId + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (290, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (155, 100), + '势力', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (355, 100), + nation_id if nation_id else '未知', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + img.paste(bar_img, (940, 180 - 50), bar_img) + group_id = character_data.groupId + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (290, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (155, 100), + '阵营', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (355, 100), + group_id if group_id else '未知', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + img.paste(bar_img, (940, 188 + 20), bar_img) + team_id = character_data.teamId + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (290, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (155, 100), + '队伍', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (355, 100), + team_id if team_id else '未知', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + img.paste(bar_img, (940, 196 + 90), bar_img) char_phases_data = character_data.phases[-1] char_max_phase = len(character_data.phases) char_max_level = char_phases_data.maxLevel char_attributes_key_frame = char_phases_data.attributesKeyFrames[-1].data + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (320, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (140, 100), + '生命上限', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (420, 100), + str(char_attributes_key_frame.maxHp), + font=sans_font_34, + fill=white_color, + anchor='mm', + ) + img.paste(bar_img, (940, 380), bar_img) + + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (320, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (140, 100), + '攻击力', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (420, 100), + str(char_attributes_key_frame.atk), + font=sans_font_34, + fill=white_color, + anchor='mm', + ) + img.paste(bar_img, (940, 380 + 78), bar_img) + + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (320, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (140, 100), + '防御力', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (420, 100), + str(char_attributes_key_frame.def_), + font=sans_font_34, + fill=white_color, + anchor='mm', + ) + img.paste(bar_img, (940, 380 + 78 * 2), bar_img) + + bar_img = Image.open(TEXTURE2D_PATH / 'bar.png') + light_line = Image.open(TEXTURE2D_PATH / 'light_line.png') + bar_img.paste(light_line, (320, 60), light_line) + bar_img_draw = ImageDraw.ImageDraw(bar_img) + bar_img_draw.text( + (140, 100), + '法抗', + font=sans_font_34, + fill=white_color, + anchor='lm', + ) + bar_img_draw.text( + (420, 100), + str(char_attributes_key_frame.magicResistance), + font=sans_font_34, + fill=white_color, + anchor='mm', + ) + img.paste(bar_img, (940, 380 + 78 * 3), bar_img) + + # 攻击范围 + range_id = char_phases_data.rangeId + attack_area_img = Image.open(TEXTURE2D_PATH / 'attack_area.png') + if range_id: + range_data = RANGE_TABLE.range_[range_id] + grids = range_data.grids + area_0 = Image.open(TEXTURE2D_PATH / 'area_0.png').resize((58, 58)) + area_1 = Image.open(TEXTURE2D_PATH / 'area_1.png') + for grid in grids: + col = grid.col + row = grid.row + if col == 1 and row == 1: + attack_area_img.paste(area_1, (90, 105), area_1) + attack_area_img.paste(area_0, (105 + col * 56, 120 + row * 56), area_0) + img.paste(attack_area_img, (915, 730), attack_area_img) + char_potential_data = character_data.potentialRanks potential_add_dict: dict[int, tuple[int, float]] = {} for potential_id, potential in enumerate(char_potential_data): @@ -441,6 +642,9 @@ async def draw_wiki(char_id: str): skill_id_list.append(skill.skillId) for skill in skill_id_list: + skill_bg = Image.open(TEXTURE2D_PATH / 'skill_bg.png') + skill3_bar_bg = Image.open(TEXTURE2D_PATH / 'skill3_bar.png') + skill_data = SKILL_TABLE.skills[skill] skill_level_data = skill_data.levels[-1] skill_name = skill_level_data.name @@ -453,8 +657,26 @@ async def draw_wiki(char_id: str): black_board_dict[black_board.key] = black_board.value if skill_description: skill_description = re.sub(r'<[^>]+>', '', skill_description) - skill_description = skill_description.format(**black_board_dict) - skill_description = re.sub(r'.000000', '', skill_description) + skill_description = render_template(skill_description, black_board_dict).replace('--', '-') + last_skill_description = re.sub(r'.000000', '', skill_description) + print(last_skill_description) + if '{' in last_skill_description: + raise NotImplementedError + # 匹配 -70% +200% 这种格式的数字 + c = re.sub(r'(\d+)%', r'\1%', last_skill_description) + print(c) + print(test_ctg(30, last_skill_description)) + draw_text_by_line( + img=skill_bg, + pos=(70, 20), + text=last_skill_description, + font=sans_font_24, + fill='#3b4354', + max_length=400, + ) + # skill_bg.show() + + # img.show() return img diff --git a/ArknightsUID/arknightsuid_wiki/texture2D/skill1_bar.png b/ArknightsUID/arknightsuid_wiki/texture2D/skill1_bar.png new file mode 100644 index 0000000..60ab6f8 Binary files /dev/null and b/ArknightsUID/arknightsuid_wiki/texture2D/skill1_bar.png differ diff --git a/ArknightsUID/arknightsuid_wiki/texture2D/skill2_bar.png b/ArknightsUID/arknightsuid_wiki/texture2D/skill2_bar.png new file mode 100644 index 0000000..6f9efc7 Binary files /dev/null and b/ArknightsUID/arknightsuid_wiki/texture2D/skill2_bar.png differ diff --git a/ArknightsUID/arknightsuid_wiki/texture2D/skill3_bar.png b/ArknightsUID/arknightsuid_wiki/texture2D/skill3_bar.png new file mode 100644 index 0000000..dc25094 Binary files /dev/null and b/ArknightsUID/arknightsuid_wiki/texture2D/skill3_bar.png differ diff --git a/ArknightsUID/arknightsuid_wiki/texture2D/skill_bg.png b/ArknightsUID/arknightsuid_wiki/texture2D/skill_bg.png new file mode 100644 index 0000000..5024145 Binary files /dev/null and b/ArknightsUID/arknightsuid_wiki/texture2D/skill_bg.png differ