From 5e57113f2d0f4ce7e071a5adf550d9b8f129b44b Mon Sep 17 00:00:00 2001 From: baiqwerdvd <158065462+baiqwerdvd@users.noreply.github.com> Date: Fri, 6 Sep 2024 02:30:44 +0800 Subject: [PATCH] small fix --- .../sruid_utils/api/hakush/requests.py | 24 +- .../sruid_utils/api/mihomo/__init__.py | 2 +- .../sruid_utils/api/mihomo/requests.py | 6 +- StarRailUID/sruid_utils/api/mys/api.py | 92 +- StarRailUID/sruid_utils/api/utils.py | 2 +- StarRailUID/starrailuid_abyss/__init__.py | 40 +- .../starrailuid_abyss/draw_abyss_card.py | 141 +- StarRailUID/starrailuid_abyss/utils.py | 10 +- .../starrailuid_abyss_boss/__init__.py | 40 +- .../starrailuid_abyss_boss/draw_abyss_card.py | 132 +- StarRailUID/starrailuid_abyss_boss/utils.py | 10 +- .../starrailuid_abyss_story/__init__.py | 44 +- .../draw_abyss_card.py | 141 +- StarRailUID/starrailuid_abyss_story/utils.py | 10 +- StarRailUID/starrailuid_calc/__init__.py | 20 +- StarRailUID/starrailuid_charinfo/__init__.py | 67 +- .../starrailuid_charinfo/draw_char_img.py | 531 +++--- .../starrailuid_charinfo/get_char_img.py | 359 ++-- StarRailUID/starrailuid_charinfo/to_card.py | 74 +- StarRailUID/starrailuid_config/__init__.py | 14 +- .../starrailuid_config/config_default.py | 52 +- StarRailUID/starrailuid_config/set_config.py | 18 +- StarRailUID/starrailuid_config/sr_config.py | 2 +- StarRailUID/starrailuid_gachalog/__init__.py | 44 +- .../starrailuid_gachalog/draw_gachalogs.py | 329 ++-- .../starrailuid_gachalog/get_gachalogs.py | 107 +- StarRailUID/starrailuid_help/__init__.py | 6 +- StarRailUID/starrailuid_help/get_help.py | 26 +- StarRailUID/starrailuid_note/__init__.py | 30 +- .../starrailuid_note/draw_note_card.py | 126 +- StarRailUID/starrailuid_note/note_text.py | 14 +- StarRailUID/starrailuid_resource/__init__.py | 12 +- StarRailUID/starrailuid_rogue/__init__.py | 185 +- .../starrailuid_rogue/draw_rogue_card.py | 1668 ++++++++--------- StarRailUID/starrailuid_rogue/utils.py | 10 +- StarRailUID/starrailuid_roleinfo/__init__.py | 44 +- .../draw_roleinfo_card.py | 185 +- StarRailUID/starrailuid_roleinfo/utils.py | 10 +- StarRailUID/starrailuid_signin/__init__.py | 38 +- StarRailUID/starrailuid_stamina/__init__.py | 73 +- .../starrailuid_stamina/draw_stamina_card.py | 104 +- StarRailUID/starrailuid_stamina/notice.py | 56 +- .../starrailuid_stamina/stamina_text.py | 32 +- StarRailUID/starrailuid_user/__init__.py | 56 +- StarRailUID/starrailuid_wiki/__init__.py | 94 +- StarRailUID/utils/convert.py | 32 +- StarRailUID/utils/error_reply.py | 30 +- StarRailUID/utils/excel/model.py | 4 +- StarRailUID/utils/excel/read_excel.py | 10 +- StarRailUID/utils/fonts/first_world.py | 2 +- StarRailUID/utils/fonts/starrail_fonts.py | 2 +- StarRailUID/utils/image/convert.py | 107 -- StarRailUID/utils/image/image_tools.py | 20 +- StarRailUID/utils/map/SR_MAP_PATH.py | 98 +- StarRailUID/utils/map/gen.py | 144 +- StarRailUID/utils/map/name_covert.py | 18 +- StarRailUID/utils/mys_api.py | 509 +++-- StarRailUID/utils/resource/RESOURCE_PATH.py | 46 +- .../utils/resource/download_from_cos.py | 32 +- StarRailUID/utils/sr_prefix.py | 2 +- StarRailUID/version.py | 4 +- pyproject.toml | 103 +- 62 files changed, 2937 insertions(+), 3306 deletions(-) delete mode 100644 StarRailUID/utils/image/convert.py diff --git a/StarRailUID/sruid_utils/api/hakush/requests.py b/StarRailUID/sruid_utils/api/hakush/requests.py index f2da995..1c17704 100644 --- a/StarRailUID/sruid_utils/api/hakush/requests.py +++ b/StarRailUID/sruid_utils/api/hakush/requests.py @@ -16,11 +16,11 @@ async def get_character_data( avatar_id: str, ) -> Union[HakushHsrCharacter, None]: async with AsyncClient( - base_url='https://api.hakush.in/hsr/data', + base_url="https://api.hakush.in/hsr/data", headers=_HEADER, timeout=30, ) as client: - req = await client.get(f'/cn/character/{avatar_id}.json') + req = await client.get(f"/cn/character/{avatar_id}.json") if req.status_code == 200: return convert(req.json(), type=HakushHsrCharacter) return None @@ -30,39 +30,35 @@ async def get_lightcone_data( lightcone_id: str, ) -> Union[HakushHsrLightcone, None]: async with AsyncClient( - base_url='https://api.hakush.in/hsr/data', + base_url="https://api.hakush.in/hsr/data", headers=_HEADER, timeout=30, ) as client: - req = await client.get(f'/cn/lightcone/{lightcone_id}.json') + req = await client.get(f"/cn/lightcone/{lightcone_id}.json") if req.status_code == 200: return convert(req.json(), type=HakushHsrLightcone) return None -async def get_character_index() -> ( - Union[Dict[str, HakushHsrCharacterIndex], None] -): +async def get_character_index() -> Union[Dict[str, HakushHsrCharacterIndex], None]: async with AsyncClient( - base_url='https://api.hakush.in/hsr/data', + base_url="https://api.hakush.in/hsr/data", headers=_HEADER, timeout=30, ) as client: - req = await client.get('/character.json') + req = await client.get("/character.json") if req.status_code == 200: return convert(req.json(), type=Dict[str, HakushHsrCharacterIndex]) return None -async def get_lightcone_index() -> ( - Union[Dict[str, HakushHsrLightconeIndex], None] -): +async def get_lightcone_index() -> Union[Dict[str, HakushHsrLightconeIndex], None]: async with AsyncClient( - base_url='https://api.hakush.in/hsr/data', + base_url="https://api.hakush.in/hsr/data", headers=_HEADER, timeout=30, ) as client: - req = await client.get('/character.json') + req = await client.get("/character.json") if req.status_code == 200: return convert(req.json(), type=Dict[str, HakushHsrLightconeIndex]) return None diff --git a/StarRailUID/sruid_utils/api/mihomo/__init__.py b/StarRailUID/sruid_utils/api/mihomo/__init__.py index 9ce95ac..fc87796 100644 --- a/StarRailUID/sruid_utils/api/mihomo/__init__.py +++ b/StarRailUID/sruid_utils/api/mihomo/__init__.py @@ -3,4 +3,4 @@ from .models import MihomoData as MihomoData from .requests import get_char_card_info as requests -__all__ = ['requests', 'MihomoData'] +__all__ = ["requests", "MihomoData"] diff --git a/StarRailUID/sruid_utils/api/mihomo/requests.py b/StarRailUID/sruid_utils/api/mihomo/requests.py index fdd19a9..e9baedd 100644 --- a/StarRailUID/sruid_utils/api/mihomo/requests.py +++ b/StarRailUID/sruid_utils/api/mihomo/requests.py @@ -12,13 +12,13 @@ from ....utils.resource.RESOURCE_PATH import PLAYER_PATH async def get_char_card_info(uid: str) -> MihomoData: async with AsyncClient( - base_url='http://api.mihomo.me', + base_url="http://api.mihomo.me", headers=_HEADER, timeout=30, ) as client: - req = await client.get(f'/sr_info/{uid}') + req = await client.get(f"/sr_info/{uid}") path = PLAYER_PATH / str(uid) path.mkdir(parents=True, exist_ok=True) - with Path.open(path / f'{uid!s}.json', 'w') as file: + with Path.open(path / f"{uid!s}.json", "w") as file: file.write(req.text) return convert(req.json(), type=MihomoData) diff --git a/StarRailUID/sruid_utils/api/mys/api.py b/StarRailUID/sruid_utils/api/mys/api.py index 2772f51..36393d5 100644 --- a/StarRailUID/sruid_utils/api/mys/api.py +++ b/StarRailUID/sruid_utils/api/mys/api.py @@ -1,75 +1,65 @@ # flake8: noqa -OLD_URL = 'https://api-takumi.mihoyo.com' -OS_OLD_URL = 'https://api-os-takumi.mihoyo.com' -NEW_URL = 'https://api-takumi-record.mihoyo.com' -OS_URL = 'https://sg-public-api.hoyolab.com' -OS_INFO_URL = 'https://bbs-api-os.hoyolab.com' +OLD_URL = "https://api-takumi.mihoyo.com" +OS_OLD_URL = "https://api-os-takumi.mihoyo.com" +NEW_URL = "https://api-takumi-record.mihoyo.com" +OS_URL = "https://sg-public-api.hoyolab.com" +OS_INFO_URL = "https://bbs-api-os.hoyolab.com" -STAR_RAIL_SIGN_INFO_URL = f'{OLD_URL}/event/luna/info' -STAR_RAIL_SIGN_INFO_URL_OS = f'{OS_URL}/event/luna/os/info' -STAR_RAIL_SIGN_LIST_URL = f'{OLD_URL}/event/luna/home' -STAR_RAIL_SIGN_LIST_URL_OS = f'{OS_URL}/event/luna/os/home' -STAR_RAIL_SIGN_EXTRA_INFO_URL = f'{OLD_URL}/event/luna/extra_info' -STAR_RAIL_SIGN_EXTRA_REWARD_URL = f'{OLD_URL}/event/luna/extra_reward' -STAR_RAIL_SIGN_URL = f'{OLD_URL}/event/luna/sign' -STAR_RAIL_SIGN_URL_OS = f'{OS_URL}/event/luna/os/sign' -STAR_RAIL_MONTH_INFO_URL = ( - f'{OLD_URL}/event/srledger/month_info' # 开拓阅历接口 -) +STAR_RAIL_SIGN_INFO_URL = f"{OLD_URL}/event/luna/info" +STAR_RAIL_SIGN_INFO_URL_OS = f"{OS_URL}/event/luna/os/info" +STAR_RAIL_SIGN_LIST_URL = f"{OLD_URL}/event/luna/home" +STAR_RAIL_SIGN_LIST_URL_OS = f"{OS_URL}/event/luna/os/home" +STAR_RAIL_SIGN_EXTRA_INFO_URL = f"{OLD_URL}/event/luna/extra_info" +STAR_RAIL_SIGN_EXTRA_REWARD_URL = f"{OLD_URL}/event/luna/extra_reward" +STAR_RAIL_SIGN_URL = f"{OLD_URL}/event/luna/sign" +STAR_RAIL_SIGN_URL_OS = f"{OS_URL}/event/luna/os/sign" +STAR_RAIL_MONTH_INFO_URL = f"{OLD_URL}/event/srledger/month_info" # 开拓阅历接口 STAR_RAIL_MONTH_DETAIL_URL = ( - f'{OLD_URL}/event/srledger/month_detail' # 开拓阅历详情接口 + f"{OLD_URL}/event/srledger/month_detail" # 开拓阅历详情接口 ) -STAR_RAIL_NOTE_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/note' # 实时便签接口 -) -STAR_RAIL_NOTE_URL_OS = ( - f'{OS_INFO_URL}/game_record/hkrpg/api/note' # OS实时便签接口 -) -STAR_RAIL_INDEX_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/index' # 角色橱窗接口 -) -STAR_RAIL_INDEX_URL_OS = ( - f'{OS_INFO_URL}/game_record/hkrpg/api/index' # OS角色橱窗接口 -) +STAR_RAIL_NOTE_URL = f"{NEW_URL}/game_record/app/hkrpg/api/note" # 实时便签接口 +STAR_RAIL_NOTE_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/note" # OS实时便签接口 +STAR_RAIL_INDEX_URL = f"{NEW_URL}/game_record/app/hkrpg/api/index" # 角色橱窗接口 +STAR_RAIL_INDEX_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/index" # OS角色橱窗接口 STAR_RAIL_AVATAR_BASIC_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/avatar/basic' # 全部角色接口 + f"{NEW_URL}/game_record/app/hkrpg/api/avatar/basic" # 全部角色接口 ) STAR_RAIL_ROLE_BASIC_INFO_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/role/basicInfo' # 角色基础信息接口 + f"{NEW_URL}/game_record/app/hkrpg/api/role/basicInfo" # 角色基础信息接口 ) -STAR_RAIL_ROLE_BASIC_INFO_URL_OS = f'{OS_INFO_URL}/game_record/hkrpg/api/index' +STAR_RAIL_ROLE_BASIC_INFO_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/index" STAR_RAIL_AVATAR_INFO_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/avatar/info' # 角色详细信息接口 + f"{NEW_URL}/game_record/app/hkrpg/api/avatar/info" # 角色详细信息接口 ) STAR_RAIL_AVATAR_INFO_URL_OS = ( - f'{OS_INFO_URL}/game_record/hkrpg/api/avatar/info' # OS角色详细信息接口 + f"{OS_INFO_URL}/game_record/hkrpg/api/avatar/info" # OS角色详细信息接口 ) -STAR_RAIL_AVATAR_LIST_URL = f'{OLD_URL}/event/rpgcalc/avatar/list' -STAR_RAIL_AVATAR_DETAIL_URL = f'{OLD_URL}/event/rpgcalc/avatar/detail' +STAR_RAIL_AVATAR_LIST_URL = f"{OLD_URL}/event/rpgcalc/avatar/list" +STAR_RAIL_AVATAR_DETAIL_URL = f"{OLD_URL}/event/rpgcalc/avatar/detail" -CHALLENGE_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge' # 忘却之庭 -CHALLENGE_INFO_URL_OS = f'{OS_INFO_URL}/game_record/hkrpg/api/challenge' # OS忘却之庭 -CHALLENGE_STORY_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge_story' # 虚构叙事 -CHALLENGE_BOSS_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge_boss' # 末日幻影 - -ROGUE_INFO_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/rogue' # 角色模拟宇宙信息接口 +CHALLENGE_INFO_URL = f"{NEW_URL}/game_record/app/hkrpg/api/challenge" # 忘却之庭 +CHALLENGE_INFO_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/challenge" # OS忘却之庭 +CHALLENGE_STORY_INFO_URL = ( + f"{NEW_URL}/game_record/app/hkrpg/api/challenge_story" # 虚构叙事 ) +CHALLENGE_BOSS_INFO_URL = ( + f"{NEW_URL}/game_record/app/hkrpg/api/challenge_boss" # 末日幻影 +) + +ROGUE_INFO_URL = f"{NEW_URL}/game_record/app/hkrpg/api/rogue" # 角色模拟宇宙信息接口 ROGUE_LOCUST_INFO_URL = ( - f'{NEW_URL}/game_record/app/hkrpg/api/rogue_locust' # 角色寰宇蝗灾信息接口 + f"{NEW_URL}/game_record/app/hkrpg/api/rogue_locust" # 角色寰宇蝗灾信息接口 ) -STAR_RAIL_GACHA_LOG_URL = f'{OLD_URL}/common/gacha_record/api/getGachaLog' -STAR_RAIL_GACHA_LOG_URL_OS = ( - f'{OS_OLD_URL}/common/gacha_record/api/getGachaLog' -) +STAR_RAIL_GACHA_LOG_URL = f"{OLD_URL}/common/gacha_record/api/getGachaLog" +STAR_RAIL_GACHA_LOG_URL_OS = f"{OS_OLD_URL}/common/gacha_record/api/getGachaLog" -GET_FP_URL = 'https://public-data-api.mihoyo.com/device-fp/api/getFp' -GET_FP_URL_OS = 'https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp' +GET_FP_URL = "https://public-data-api.mihoyo.com/device-fp/api/getFp" +GET_FP_URL_OS = "https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp" # CREATE_QRCODE = f'{OLD_URL}/event/bbs_sign_reward/gen_auth_code' -STAR_RAIL_WIDGRT_URL = f'{NEW_URL}/game_record/app/hkrpg/aapi/widget' +STAR_RAIL_WIDGRT_URL = f"{NEW_URL}/game_record/app/hkrpg/aapi/widget" _API = locals() diff --git a/StarRailUID/sruid_utils/api/utils.py b/StarRailUID/sruid_utils/api/utils.py index e308ccd..a8a80f3 100644 --- a/StarRailUID/sruid_utils/api/utils.py +++ b/StarRailUID/sruid_utils/api/utils.py @@ -1,3 +1,3 @@ from gsuid_core.version import __version__ -_HEADER = {'User-Agent': f'StarRailUID/{__version__}'} +_HEADER = {"User-Agent": f"StarRailUID/{__version__}"} diff --git a/StarRailUID/starrailuid_abyss/__init__.py b/StarRailUID/starrailuid_abyss/__init__.py index 2589776..fc8aa4d 100644 --- a/StarRailUID/starrailuid_abyss/__init__.py +++ b/StarRailUID/starrailuid_abyss/__init__.py @@ -1,45 +1,43 @@ import re -from gsuid_core.sv import SV +from .draw_abyss_card import draw_abyss_img +from ..utils.sr_prefix import PREFIX + from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind from gsuid_core.utils.error_reply import UID_HINT -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from .draw_abyss_card import draw_abyss_img - -sv_srabyss = SV('sr查询深渊') +sv_srabyss = SV("sr查询深渊") @sv_srabyss.on_command( ( - f'{PREFIX}查询深渊', - f'{PREFIX}查询上期深渊', - f'{PREFIX}上期深渊', - f'{PREFIX}深渊', + f"{PREFIX}查询深渊", + f"{PREFIX}查询上期深渊", + f"{PREFIX}上期深渊", + f"{PREFIX}深渊", ), block=True, ) async def send_srabyss_info(bot: Bot, ev: Event): - name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text)) + name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text)) if name: return None - await bot.logger.info('开始执行[sr查询深渊信息]') - get_uid_ = await get_uid(bot, ev, True) - if get_uid_ is None: - return await bot.send(UID_HINT) - uid, user_id = get_uid_ + await bot.logger.info("开始执行[sr查询深渊信息]") + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) if uid is None: return await bot.send(UID_HINT) - await bot.logger.info(f'[sr查询深渊信息]uid: {uid}') + await bot.logger.info(f"[sr查询深渊信息]uid: {uid}") - if '上期' in ev.command: - schedule_type = '2' + if "上期" in ev.command: + schedule_type = "2" else: - schedule_type = '1' - await bot.logger.info(f'[sr查询深渊信息]深渊期数: {schedule_type}') + schedule_type = "1" + await bot.logger.info(f"[sr查询深渊信息]深渊期数: {schedule_type}") im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type) await bot.send(im) diff --git a/StarRailUID/starrailuid_abyss/draw_abyss_card.py b/StarRailUID/starrailuid_abyss/draw_abyss_card.py index ec42950..281dcd7 100644 --- a/StarRailUID/starrailuid_abyss/draw_abyss_card.py +++ b/StarRailUID/starrailuid_abyss/draw_abyss_card.py @@ -1,17 +1,7 @@ from pathlib import Path -from typing import Union, Optional - -from PIL import Image, ImageDraw -from gsuid_core.logger import logger -from gsuid_core.utils.error_reply import get_error -from gsuid_core.utils.image.image_tools import ( - get_qq_avatar, - draw_pic_with_ring, -) +from typing import Any, Dict, Union from .utils import get_icon -from ..utils.mys_api import mys_api -from ..utils.image.convert import convert_img from ..sruid_utils.api.mys.models import AbyssAvatar from ..utils.fonts.starrail_fonts import ( sr_font_22, @@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import ( sr_font_34, sr_font_42, ) +from ..utils.mys_api import mys_api -TEXT_PATH = Path(__file__).parent / 'texture2D' +from PIL import Image, ImageDraw +from gsuid_core.logger import logger +from gsuid_core.utils.error_reply import get_error +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import ( + draw_pic_with_ring, + get_qq_avatar, +) + +TEXT_PATH = Path(__file__).parent / "texture2D" white_color = (255, 255, 255) gray_color = (175, 175, 175) -img_bg = Image.open(TEXT_PATH / 'bg.jpg') -level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA') -char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA') -char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA') -rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA') -star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA') -star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA') +img_bg = Image.open(TEXT_PATH / "bg.jpg") +level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA") +char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA") +char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA") +rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA") +star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA") +star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA") elements = { - 'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'), - 'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'), - 'imaginary': Image.open( - TEXT_PATH / 'IconNatureColorImaginary.png' - ).convert('RGBA'), - 'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert( - 'RGBA' - ), - 'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert( - 'RGBA' - ), - 'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'), - 'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert( - 'RGBA' - ), + "ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"), + "fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"), + "imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"), + "quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"), + "lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"), + "wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"), + "physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"), } async def get_abyss_star_pic(star: int) -> Image.Image: - return Image.open(TEXT_PATH / f'star{star}.png') + return Image.open(TEXT_PATH / f"star{star}.png") async def _draw_abyss_card( @@ -72,17 +64,17 @@ async def _draw_abyss_card( char_bg.paste(rank_bg, (150, 16), mask=rank_bg) char_card_draw.text( (162, 31), - f'{char.rank}', + f"{char.rank}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) char_card_draw.text( (100, 165), - f'等级 {char.level}', + f"等级 {char.level}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) floor_pic.paste( char_bg, @@ -92,16 +84,16 @@ async def _draw_abyss_card( async def _draw_floor_card( - level_star: int, + level_star: Union[int, str], floor_pic: Image.Image, img: Image.Image, index_floor: int, floor_name: str, - round_num: int, + round_num: Union[int, None], ): for index_num in [0, 1, 2]: star_num = index_num + 1 - if star_num <= level_star: + if star_num <= int(level_star): star_pic = star_yes.copy() else: star_pic = star_gray.copy() @@ -112,14 +104,14 @@ async def _draw_floor_card( floor_name, font=sr_font_42, fill=white_color, - anchor='mm', + anchor="mm", ) floor_pic_draw.text( (802, 60), - f'使用轮: {round_num}', + f"使用轮: {round_num}", font=sr_font_28, fill=gray_color, - anchor='rm', + anchor="rm", ) img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic) @@ -127,8 +119,8 @@ async def _draw_floor_card( async def draw_abyss_img( qid: Union[str, int], uid: str, - sender: Union[str, str], - schedule_type: str = '1', + sender: Dict[str, Any], + schedule_type: str = "1", ) -> Union[bytes, str]: raw_abyss_data = await mys_api.get_abyss_info(uid, schedule_type) @@ -136,10 +128,12 @@ async def draw_abyss_img( return get_error(raw_abyss_data) # 获取查询者数据 - if raw_abyss_data.max_floor == '': - return '你还没有挑战本期深渊!\n可以使用[sr上期深渊]命令查询上期~' - # 过滤掉 is_fast(快速通关) 为 True 的项 - floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast] + if raw_abyss_data.max_floor == "": + return "你还没有挑战本期深渊!\n可以使用[sr上期深渊]命令查询上期~" + # 过滤掉 is_fast (快速通关) 为 True 的项 + floor_detail = [ + detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast + ] floor_num = len(floor_detail) # 获取背景图片各项参数 @@ -147,15 +141,15 @@ async def draw_abyss_img( based_h = 657 + 570 * floor_num img = img_bg.copy() img = img.crop((0, 0, based_w, based_h)) - abyss_title = Image.open(TEXT_PATH / 'head.png') + abyss_title = Image.open(TEXT_PATH / "head.png") img.paste(abyss_title, (0, 0), abyss_title) # 获取头像 _id = str(qid) - if _id.startswith('http'): + if _id.startswith("http"): char_pic = await get_qq_avatar(avatar_url=_id) - elif sender.get('avatar') is not None: - char_pic = await get_qq_avatar(avatar_url=sender['avatar']) + elif sender.get("avatar") is not None: + char_pic = await get_qq_avatar(avatar_url=sender["avatar"]) else: char_pic = await get_qq_avatar(qid=qid) char_pic = await draw_pic_with_ring(char_pic, 250, None, False) @@ -164,42 +158,42 @@ async def draw_abyss_img( # 绘制抬头 img_draw = ImageDraw.Draw(img) - img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm') + img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm") # 总体数据 - abyss_data = Image.open(TEXT_PATH / 'data.png') + abyss_data = Image.open(TEXT_PATH / "data.png") img.paste(abyss_data, (0, 500), abyss_data) # 最深抵达 img_draw.text( (220, 565), - f'{raw_abyss_data.max_floor}', + f"{raw_abyss_data.max_floor}", white_color, sr_font_34, - 'lm', + "lm", ) # 挑战次数 img_draw.text( (220, 612), - f'{raw_abyss_data.battle_num}', + f"{raw_abyss_data.battle_num}", white_color, sr_font_34, - 'lm', + "lm", ) - star_num_pic = Image.open(TEXT_PATH / 'star.png') + star_num_pic = Image.open(TEXT_PATH / "star.png") img.paste(star_num_pic, (615, 557), star_num_pic) img_draw.text( (695, 590), - f'{raw_abyss_data.star_num}/36', + f"{raw_abyss_data.star_num}/36", white_color, sr_font_42, - 'lm', + "lm", ) for index_floor, level in enumerate(raw_abyss_data.all_floor_detail): - floor_pic = Image.open(TEXT_PATH / 'floor_bg.png') + floor_pic = Image.open(TEXT_PATH / "floor_bg.png") level_star = level.star_num floor_name = level.name round_num = level.round_num @@ -211,23 +205,24 @@ async def draw_abyss_img( time_array = node_1.challenge_time else: time_array = node_2.challenge_time - time_str = f'{time_array.year}-{time_array.month}' - time_str = f'{time_str}-{time_array.day}' - time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00' + assert time_array is not None + time_str = f"{time_array.year}-{time_array.month}" + time_str = f"{time_str}-{time_array.day}" + time_str = f"{time_str} {time_array.hour}:{time_array.minute}:00" floor_pic_draw = ImageDraw.Draw(floor_pic) floor_pic_draw.text( (112, 120 + index_part * 219), - f'节点{node_num}', + f"节点{node_num}", white_color, sr_font_30, - 'lm', + "lm", ) floor_pic_draw.text( (201, 120 + index_part * 219), - f'{time_str}', + f"{time_str}", gray_color, sr_font_22, - 'lm', + "lm", ) if node_num == 1: avatars_array = node_1 @@ -251,5 +246,5 @@ async def draw_abyss_img( ) res = await convert_img(img) - logger.info('[查询深渊信息]绘图已完成,等待发送!') + logger.info("[查询深渊信息]绘图已完成,等待发送!") return res diff --git a/StarRailUID/starrailuid_abyss/utils.py b/StarRailUID/starrailuid_abyss/utils.py index a18f624..c6bda1b 100644 --- a/StarRailUID/starrailuid_abyss/utils.py +++ b/StarRailUID/starrailuid_abyss/utils.py @@ -6,14 +6,14 @@ from PIL import Image from aiohttp import ClientSession from gsuid_core.data_store import get_res_path -T = TypeVar('T') +T = TypeVar("T") -ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo' +ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo" ROLEINFO_PATH.mkdir(parents=True, exist_ok=True) async def get_icon(url: str) -> Image.Image: - name = url.split('/')[-1] + name = url.split("/")[-1] path = ROLEINFO_PATH / name if (path).exists(): content = path.read_bytes() @@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image: async with ClientSession() as client: async with client.get(url) as resp: content = await resp.read() - with Path.open(path, 'wb') as f: + with Path.open(path, "wb") as f: f.write(content) - return Image.open(BytesIO(content)).convert('RGBA') + return Image.open(BytesIO(content)).convert("RGBA") diff --git a/StarRailUID/starrailuid_abyss_boss/__init__.py b/StarRailUID/starrailuid_abyss_boss/__init__.py index 4f862a3..8bf8dce 100644 --- a/StarRailUID/starrailuid_abyss_boss/__init__.py +++ b/StarRailUID/starrailuid_abyss_boss/__init__.py @@ -1,45 +1,43 @@ import re -from gsuid_core.sv import SV +from .draw_abyss_card import draw_abyss_img +from ..utils.sr_prefix import PREFIX + from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind from gsuid_core.utils.error_reply import UID_HINT -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from .draw_abyss_card import draw_abyss_img - -sv_abyss_boss = SV('sr查询末日幻影') +sv_abyss_boss = SV("sr查询末日幻影") @sv_abyss_boss.on_command( ( - f'{PREFIX}查询末日幻影', - f'{PREFIX}查询上期末日幻影', - f'{PREFIX}上期末日', - f'{PREFIX}末日', + f"{PREFIX}查询末日幻影", + f"{PREFIX}查询上期末日幻影", + f"{PREFIX}上期末日", + f"{PREFIX}末日", ), block=True, ) async def send_srabyss_info(bot: Bot, ev: Event): - name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text)) + name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text)) if name: return None - await bot.logger.info('开始执行[sr查询末日幻影信息]') - get_uid_ = await get_uid(bot, ev, True) - if get_uid_ is None: - return await bot.send(UID_HINT) - uid, user_id = get_uid_ + await bot.logger.info("开始执行[sr查询末日幻影信息]") + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) if uid is None: return await bot.send(UID_HINT) - await bot.logger.info(f'[sr查询末日幻影信息]uid: {uid}') + await bot.logger.info(f"[sr查询末日幻影信息]uid: {uid}") - if '上期' in ev.command: - schedule_type = '2' + if "上期" in ev.command: + schedule_type = "2" else: - schedule_type = '1' - await bot.logger.info(f'[sr查询末日幻影信息]末日幻影期数: {schedule_type}') + schedule_type = "1" + await bot.logger.info(f"[sr查询末日幻影信息]末日幻影期数: {schedule_type}") im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type) await bot.send(im) diff --git a/StarRailUID/starrailuid_abyss_boss/draw_abyss_card.py b/StarRailUID/starrailuid_abyss_boss/draw_abyss_card.py index 24f40a7..804fce8 100644 --- a/StarRailUID/starrailuid_abyss_boss/draw_abyss_card.py +++ b/StarRailUID/starrailuid_abyss_boss/draw_abyss_card.py @@ -1,17 +1,7 @@ from pathlib import Path -from typing import Union, Optional - -from PIL import Image, ImageDraw -from gsuid_core.logger import logger -from gsuid_core.utils.error_reply import get_error -from gsuid_core.utils.image.image_tools import ( - get_qq_avatar, - draw_pic_with_ring, -) +from typing import Any, Dict, Union from .utils import get_icon -from ..utils.mys_api import mys_api -from ..utils.image.convert import convert_img from ..sruid_utils.api.mys.models import AbyssAvatar from ..utils.fonts.starrail_fonts import ( sr_font_22, @@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import ( sr_font_34, sr_font_42, ) +from ..utils.mys_api import mys_api -TEXT_PATH = Path(__file__).parent / 'texture2D' +from PIL import Image, ImageDraw +from gsuid_core.logger import logger +from gsuid_core.utils.error_reply import get_error +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import ( + draw_pic_with_ring, + get_qq_avatar, +) + +TEXT_PATH = Path(__file__).parent / "texture2D" white_color = (255, 255, 255) gray_color = (175, 175, 175) -img_bg = Image.open(TEXT_PATH / 'bg.jpg') -level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA') -char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA') -char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA') -rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA') -star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA') -star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA') +img_bg = Image.open(TEXT_PATH / "bg.jpg") +level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA") +char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA") +char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA") +rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA") +star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA") +star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA") elements = { - 'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'), - 'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'), - 'imaginary': Image.open( - TEXT_PATH / 'IconNatureColorImaginary.png' - ).convert('RGBA'), - 'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert( - 'RGBA' - ), - 'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert( - 'RGBA' - ), - 'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'), - 'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert( - 'RGBA' - ), + "ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"), + "fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"), + "imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"), + "quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"), + "lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"), + "wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"), + "physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"), } async def get_abyss_star_pic(star: int) -> Image.Image: - return Image.open(TEXT_PATH / f'star{star}.png') + return Image.open(TEXT_PATH / f"star{star}.png") async def _draw_abyss_card( @@ -75,17 +67,17 @@ async def _draw_abyss_card( char_bg.paste(rank_bg, (150, 16), mask=rank_bg) char_card_draw.text( (162, 31), - f'{char.rank}', + f"{char.rank}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) char_card_draw.text( (100, 165), - f'等级 {char.level}', + f"等级 {char.level}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) floor_pic.paste( char_bg, @@ -114,7 +106,7 @@ async def _draw_floor_card( floor_name, font=sr_font_42, fill=white_color, - anchor='mm', + anchor="mm", ) img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic) @@ -122,18 +114,20 @@ async def _draw_floor_card( async def draw_abyss_img( qid: Union[str, int], uid: str, - sender: Union[str, str], - schedule_type: str = '1', + sender: Dict[str, Any], + schedule_type: str = "1", ) -> Union[bytes, str]: raw_abyss_data = await mys_api.get_abyss_boss_info(uid, schedule_type) if isinstance(raw_abyss_data, int): return get_error(raw_abyss_data) # 获取查询者数据 - if raw_abyss_data.max_floor == '': - return '你还没有挑战本期末日幻影!\n可以使用[sr上期末日幻影]命令查询上期~' - # 过滤掉 is_fast(快速通关) 为 True 的项 - floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast] + if raw_abyss_data.max_floor == "": + return "你还没有挑战本期末日幻影!\n可以使用[sr上期末日幻影]命令查询上期~" + # 过滤掉 is_fast (快速通关) 为 True 的项 + floor_detail = [ + detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast + ] floor_num = len(floor_detail) # 获取背景图片各项参数 @@ -141,15 +135,15 @@ async def draw_abyss_img( based_h = 657 + 570 * floor_num img = img_bg.copy() img = img.crop((0, 0, based_w, based_h)) - abyss_title = Image.open(TEXT_PATH / 'head.png') + abyss_title = Image.open(TEXT_PATH / "head.png") img.paste(abyss_title, (0, 0), abyss_title) # 获取头像 _id = str(qid) - if _id.startswith('http'): + if _id.startswith("http"): char_pic = await get_qq_avatar(avatar_url=_id) - elif sender.get('avatar') is not None: - char_pic = await get_qq_avatar(avatar_url=sender['avatar']) + elif sender.get("avatar") is not None: + char_pic = await get_qq_avatar(avatar_url=sender["avatar"]) else: char_pic = await get_qq_avatar(qid=qid) char_pic = await draw_pic_with_ring(char_pic, 250, None, False) @@ -158,42 +152,42 @@ async def draw_abyss_img( # 绘制抬头 img_draw = ImageDraw.Draw(img) - img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm') + img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm") # 总体数据 - abyss_data = Image.open(TEXT_PATH / 'data.png') + abyss_data = Image.open(TEXT_PATH / "data.png") img.paste(abyss_data, (0, 500), abyss_data) # 最深抵达 img_draw.text( (220, 565), - f'{raw_abyss_data.max_floor}', + f"{raw_abyss_data.max_floor}", white_color, sr_font_34, - 'lm', + "lm", ) # 挑战次数 img_draw.text( (220, 612), - f'{raw_abyss_data.battle_num}', + f"{raw_abyss_data.battle_num}", white_color, sr_font_34, - 'lm', + "lm", ) - star_num_pic = Image.open(TEXT_PATH / 'star.png') + star_num_pic = Image.open(TEXT_PATH / "star.png") img.paste(star_num_pic, (615, 557), star_num_pic) img_draw.text( (695, 590), - f'{raw_abyss_data.star_num}/12', + f"{raw_abyss_data.star_num}/12", white_color, sr_font_42, - 'lm', + "lm", ) for index_floor, level in enumerate(floor_detail): - floor_pic = Image.open(TEXT_PATH / 'floor_bg.png') + floor_pic = Image.open(TEXT_PATH / "floor_bg.png") level_star = int(level.star_num) floor_name = level.name node_1 = level.node_1 @@ -204,23 +198,24 @@ async def draw_abyss_img( time_array = node_1.challenge_time else: time_array = node_2.challenge_time - time_str = f'{time_array.year}-{time_array.month}' - time_str = f'{time_str}-{time_array.day}' - time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00' + assert time_array is not None + time_str = f"{time_array.year}-{time_array.month}" + time_str = f"{time_str}-{time_array.day}" + time_str = f"{time_str} {time_array.hour}:{time_array.minute}:00" floor_pic_draw = ImageDraw.Draw(floor_pic) floor_pic_draw.text( (112, 120 + index_part * 219), - f'节点{node_num}', + f"节点{node_num}", white_color, sr_font_30, - 'lm', + "lm", ) floor_pic_draw.text( (201, 120 + index_part * 219), - f'{time_str}', + f"{time_str}", gray_color, sr_font_22, - 'lm', + "lm", ) if node_num == 1: avatars_array = node_1 @@ -240,9 +235,8 @@ async def draw_abyss_img( img, index_floor, floor_name, - ) res = await convert_img(img) - logger.info('[查询末日幻影信息]绘图已完成,等待发送!') + logger.info("[查询末日幻影信息]绘图已完成,等待发送!") return res diff --git a/StarRailUID/starrailuid_abyss_boss/utils.py b/StarRailUID/starrailuid_abyss_boss/utils.py index a18f624..c6bda1b 100644 --- a/StarRailUID/starrailuid_abyss_boss/utils.py +++ b/StarRailUID/starrailuid_abyss_boss/utils.py @@ -6,14 +6,14 @@ from PIL import Image from aiohttp import ClientSession from gsuid_core.data_store import get_res_path -T = TypeVar('T') +T = TypeVar("T") -ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo' +ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo" ROLEINFO_PATH.mkdir(parents=True, exist_ok=True) async def get_icon(url: str) -> Image.Image: - name = url.split('/')[-1] + name = url.split("/")[-1] path = ROLEINFO_PATH / name if (path).exists(): content = path.read_bytes() @@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image: async with ClientSession() as client: async with client.get(url) as resp: content = await resp.read() - with Path.open(path, 'wb') as f: + with Path.open(path, "wb") as f: f.write(content) - return Image.open(BytesIO(content)).convert('RGBA') + return Image.open(BytesIO(content)).convert("RGBA") diff --git a/StarRailUID/starrailuid_abyss_story/__init__.py b/StarRailUID/starrailuid_abyss_story/__init__.py index 433622f..cb684dd 100644 --- a/StarRailUID/starrailuid_abyss_story/__init__.py +++ b/StarRailUID/starrailuid_abyss_story/__init__.py @@ -1,47 +1,45 @@ import re -from gsuid_core.sv import SV +from .draw_abyss_card import draw_abyss_img +from ..utils.sr_prefix import PREFIX + from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind from gsuid_core.utils.error_reply import UID_HINT -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from .draw_abyss_card import draw_abyss_img - -sv_abyss_story = SV('sr查询虚构叙事') +sv_abyss_story = SV("sr查询虚构叙事") @sv_abyss_story.on_command( ( - f'{PREFIX}查询虚构叙事', - f'{PREFIX}xg', - f'{PREFIX}查询上期虚构叙事', - f'{PREFIX}sqxg', - f'{PREFIX}上期虚构', - f'{PREFIX}虚构', + f"{PREFIX}查询虚构叙事", + f"{PREFIX}xg", + f"{PREFIX}查询上期虚构叙事", + f"{PREFIX}sqxg", + f"{PREFIX}上期虚构", + f"{PREFIX}虚构", ), block=True, ) async def send_srabyss_info(bot: Bot, ev: Event): - name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text)) + name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text)) if name: return None - await bot.logger.info('开始执行[sr查询虚构叙事信息]') - get_uid_ = await get_uid(bot, ev, True) - if get_uid_ is None: - return await bot.send(UID_HINT) - uid, user_id = get_uid_ + await bot.logger.info("开始执行[sr查询虚构叙事信息]") + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) if uid is None: return await bot.send(UID_HINT) - await bot.logger.info(f'[sr查询虚构叙事信息]uid: {uid}') + await bot.logger.info(f"[sr查询虚构叙事信息]uid: {uid}") - if 'sq' in ev.command or '上期' in ev.command: - schedule_type = '2' + if "sq" in ev.command or "上期" in ev.command: + schedule_type = "2" else: - schedule_type = '1' - await bot.logger.info(f'[sr查询虚构叙事信息]虚构叙事期数: {schedule_type}') + schedule_type = "1" + await bot.logger.info(f"[sr查询虚构叙事信息]虚构叙事期数: {schedule_type}") im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type) await bot.send(im) diff --git a/StarRailUID/starrailuid_abyss_story/draw_abyss_card.py b/StarRailUID/starrailuid_abyss_story/draw_abyss_card.py index 41c30d6..f6181a3 100644 --- a/StarRailUID/starrailuid_abyss_story/draw_abyss_card.py +++ b/StarRailUID/starrailuid_abyss_story/draw_abyss_card.py @@ -1,17 +1,7 @@ from pathlib import Path -from typing import Union, Optional - -from PIL import Image, ImageDraw -from gsuid_core.logger import logger -from gsuid_core.utils.error_reply import get_error -from gsuid_core.utils.image.image_tools import ( - get_qq_avatar, - draw_pic_with_ring, -) +from typing import Any, Dict, Union from .utils import get_icon -from ..utils.mys_api import mys_api -from ..utils.image.convert import convert_img from ..sruid_utils.api.mys.models import AbyssAvatar from ..utils.fonts.starrail_fonts import ( sr_font_22, @@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import ( sr_font_34, sr_font_42, ) +from ..utils.mys_api import mys_api -TEXT_PATH = Path(__file__).parent / 'texture2D' +from PIL import Image, ImageDraw +from gsuid_core.logger import logger +from gsuid_core.utils.error_reply import get_error +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import ( + draw_pic_with_ring, + get_qq_avatar, +) + +TEXT_PATH = Path(__file__).parent / "texture2D" white_color = (255, 255, 255) gray_color = (175, 175, 175) -img_bg = Image.open(TEXT_PATH / 'bg.jpg') -level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA') -char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA') -char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA') -rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA') -star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA') -star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA') +img_bg = Image.open(TEXT_PATH / "bg.jpg") +level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA") +char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA") +char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA") +rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA") +star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA") +star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA") elements = { - 'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'), - 'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'), - 'imaginary': Image.open( - TEXT_PATH / 'IconNatureColorImaginary.png' - ).convert('RGBA'), - 'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert( - 'RGBA' - ), - 'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert( - 'RGBA' - ), - 'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'), - 'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert( - 'RGBA' - ), + "ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"), + "fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"), + "imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"), + "quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"), + "lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"), + "wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"), + "physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"), } async def get_abyss_star_pic(star: int) -> Image.Image: - return Image.open(TEXT_PATH / f'star{star}.png') + return Image.open(TEXT_PATH / f"star{star}.png") async def _draw_abyss_card( @@ -76,10 +68,10 @@ async def _draw_abyss_card( char_bg.paste(rank_bg, (150, 16), mask=rank_bg) char_card_draw.text( (162, 31), - f'{char.rank}', + f"{char.rank}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) # 不存在自动下载 # if not char_pic_path.exists(): @@ -89,10 +81,10 @@ async def _draw_abyss_card( # char_card.paste(talent_pic, (137, 260), talent_pic) char_card_draw.text( (100, 165), - f'等级 {char.level}', + f"等级 {char.level}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) floor_pic.paste( char_bg, @@ -102,16 +94,16 @@ async def _draw_abyss_card( async def _draw_floor_card( - level_star: int, + level_star: Union[int, str], floor_pic: Image.Image, img: Image.Image, index_floor: int, floor_name: str, - round_num: int, + round_num: Union[int, None], ): for index_num in [0, 1, 2]: star_num = index_num + 1 - if star_num <= level_star: + if star_num <= int(level_star): star_pic = star_yes.copy() else: star_pic = star_gray.copy() @@ -122,14 +114,14 @@ async def _draw_floor_card( floor_name, font=sr_font_42, fill=white_color, - anchor='mm', + anchor="mm", ) floor_pic_draw.text( (802, 60), - f'使用轮: {round_num}', + f"使用轮: {round_num}", font=sr_font_28, fill=gray_color, - anchor='rm', + anchor="rm", ) img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic) @@ -137,18 +129,20 @@ async def _draw_floor_card( async def draw_abyss_img( qid: Union[str, int], uid: str, - sender: Union[str, str], - schedule_type: str = '1', + sender: Dict[str, Any], + schedule_type: str = "1", ) -> Union[bytes, str]: raw_abyss_data = await mys_api.get_abyss_story_info(uid, schedule_type) if isinstance(raw_abyss_data, int): return get_error(raw_abyss_data) # 获取查询者数据 - if raw_abyss_data.max_floor == '': - return '你还没有挑战本期虚构叙事!\n可以使用[sr上期虚构叙事]命令查询上期~' - # 过滤掉 is_fast(快速通关) 为 True 的项 - floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast] + if raw_abyss_data.max_floor == "": + return "你还没有挑战本期虚构叙事!\n可以使用[sr上期虚构叙事]命令查询上期~" + # 过滤掉 is_fast (快速通关) 为 True 的项 + floor_detail = [ + detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast + ] floor_num = len(floor_detail) # 获取背景图片各项参数 @@ -156,15 +150,15 @@ async def draw_abyss_img( based_h = 657 + 570 * floor_num img = img_bg.copy() img = img.crop((0, 0, based_w, based_h)) - abyss_title = Image.open(TEXT_PATH / 'head.png') + abyss_title = Image.open(TEXT_PATH / "head.png") img.paste(abyss_title, (0, 0), abyss_title) # 获取头像 _id = str(qid) - if _id.startswith('http'): + if _id.startswith("http"): char_pic = await get_qq_avatar(avatar_url=_id) - elif sender.get('avatar') is not None: - char_pic = await get_qq_avatar(avatar_url=sender['avatar']) + elif sender.get("avatar") is not None: + char_pic = await get_qq_avatar(avatar_url=sender["avatar"]) else: char_pic = await get_qq_avatar(qid=qid) char_pic = await draw_pic_with_ring(char_pic, 250, None, False) @@ -173,42 +167,42 @@ async def draw_abyss_img( # 绘制抬头 img_draw = ImageDraw.Draw(img) - img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm') + img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm") # 总体数据 - abyss_data = Image.open(TEXT_PATH / 'data.png') + abyss_data = Image.open(TEXT_PATH / "data.png") img.paste(abyss_data, (0, 500), abyss_data) # 最深抵达 img_draw.text( (220, 565), - f'{raw_abyss_data.max_floor}', + f"{raw_abyss_data.max_floor}", white_color, sr_font_34, - 'lm', + "lm", ) # 挑战次数 img_draw.text( (220, 612), - f'{raw_abyss_data.battle_num}', + f"{raw_abyss_data.battle_num}", white_color, sr_font_34, - 'lm', + "lm", ) - star_num_pic = Image.open(TEXT_PATH / 'star.png') + star_num_pic = Image.open(TEXT_PATH / "star.png") img.paste(star_num_pic, (615, 557), star_num_pic) img_draw.text( (695, 590), - f'{raw_abyss_data.star_num}/12', + f"{raw_abyss_data.star_num}/12", white_color, sr_font_42, - 'lm', + "lm", ) for index_floor, level in enumerate(raw_abyss_data.all_floor_detail): - floor_pic = Image.open(TEXT_PATH / 'floor_bg.png') + floor_pic = Image.open(TEXT_PATH / "floor_bg.png") level_star = level.star_num floor_name = level.name round_num = level.round_num @@ -220,23 +214,24 @@ async def draw_abyss_img( time_array = node_1.challenge_time else: time_array = node_2.challenge_time - time_str = f'{time_array.year}-{time_array.month}' - time_str = f'{time_str}-{time_array.day}' - time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00' + assert time_array is not None + time_str = f"{time_array.year}-{time_array.month}" + time_str = f"{time_str}-{time_array.day}" + time_str = f"{time_str} {time_array.hour}:{time_array.minute}:00" floor_pic_draw = ImageDraw.Draw(floor_pic) floor_pic_draw.text( (112, 120 + index_part * 219), - f'节点{node_num}', + f"节点{node_num}", white_color, sr_font_30, - 'lm', + "lm", ) floor_pic_draw.text( (201, 120 + index_part * 219), - f'{time_str}', + f"{time_str}", gray_color, sr_font_22, - 'lm', + "lm", ) if node_num == 1: avatars_array = node_1 @@ -261,5 +256,5 @@ async def draw_abyss_img( ) res = await convert_img(img) - logger.info('[查询虚构叙事信息]绘图已完成,等待发送!') + logger.info("[查询虚构叙事信息]绘图已完成,等待发送!") return res diff --git a/StarRailUID/starrailuid_abyss_story/utils.py b/StarRailUID/starrailuid_abyss_story/utils.py index a18f624..c6bda1b 100644 --- a/StarRailUID/starrailuid_abyss_story/utils.py +++ b/StarRailUID/starrailuid_abyss_story/utils.py @@ -6,14 +6,14 @@ from PIL import Image from aiohttp import ClientSession from gsuid_core.data_store import get_res_path -T = TypeVar('T') +T = TypeVar("T") -ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo' +ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo" ROLEINFO_PATH.mkdir(parents=True, exist_ok=True) async def get_icon(url: str) -> Image.Image: - name = url.split('/')[-1] + name = url.split("/")[-1] path = ROLEINFO_PATH / name if (path).exists(): content = path.read_bytes() @@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image: async with ClientSession() as client: async with client.get(url) as resp: content = await resp.read() - with Path.open(path, 'wb') as f: + with Path.open(path, "wb") as f: f.write(content) - return Image.open(BytesIO(content)).convert('RGBA') + return Image.open(BytesIO(content)).convert("RGBA") diff --git a/StarRailUID/starrailuid_calc/__init__.py b/StarRailUID/starrailuid_calc/__init__.py index 33730ba..32c7889 100644 --- a/StarRailUID/starrailuid_calc/__init__.py +++ b/StarRailUID/starrailuid_calc/__init__.py @@ -1,6 +1,5 @@ from typing import TYPE_CHECKING -from ..utils.convert import get_uid from ..utils.error_reply import UID_HINT from ..utils.map.name_covert import ( alias_to_char_name, @@ -10,26 +9,29 @@ from ..utils.mys_api import mys_api from ..utils.sr_prefix import PREFIX from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind from gsuid_core.utils.error_reply import get_error if TYPE_CHECKING: from gsuid_core.bot import Bot from gsuid_core.models import Event -sv_char_calc = SV('sr养成计算') +sv_char_calc = SV("sr养成计算") -@sv_char_calc.on_command(f'{PREFIX}养成计算', block=True) -async def send_char_calc_info(bot: 'Bot', ev: 'Event'): +@sv_char_calc.on_command(f"{PREFIX}养成计算", block=True) +async def send_char_calc_info(bot: "Bot", ev: "Event"): name = ev.text.strip() char_id = await name_to_avatar_id(name) - if char_id == '': + if char_id == "": result_fake_name = await alias_to_char_name(name) if result_fake_name is None: - return '请输入正确的角色名' + return "请输入正确的角色名" fake_name = result_fake_name char_id = await name_to_avatar_id(fake_name) - uid = await get_uid(bot, ev, only_uid=True) + + uid = await get_uid(bot, ev, GsBind, "sr") if uid is None: return await bot.send(UID_HINT) @@ -39,8 +41,6 @@ async def send_char_calc_info(bot: 'Bot', ev: 'Event'): avatar_skills = avatar_detail.skills + avatar_detail.skills_other skill_list = [] for skill in avatar_skills: - skill_list.append( - f'{skill.point_id}({skill.cur_level}/{skill.max_level})' - ) + skill_list.append(f"{skill.point_id}({skill.cur_level}/{skill.max_level})") return None diff --git a/StarRailUID/starrailuid_charinfo/__init__.py b/StarRailUID/starrailuid_charinfo/__init__.py index 6339585..00b8c05 100644 --- a/StarRailUID/starrailuid_charinfo/__init__.py +++ b/StarRailUID/starrailuid_charinfo/__init__.py @@ -1,28 +1,29 @@ -import re from pathlib import Path +import re from typing import Tuple, cast +from .get_char_img import draw_char_info_img +from .to_card import api_to_card +from ..utils.error_reply import UID_HINT +from ..utils.resource.RESOURCE_PATH import TEMP_PATH +from ..utils.sr_prefix import PREFIX + from PIL import Image -from gsuid_core.sv import SV from gsuid_core.bot import Bot -from gsuid_core.models import Event from gsuid_core.message_models import Button +from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind +from gsuid_core.utils.image.convert import convert_img from starrail_damage_cal.map.SR_MAP_PATH import avatarId2Name -from .to_card import api_to_card -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from ..utils.error_reply import UID_HINT -from .get_char_img import draw_char_info_img -from ..utils.image.convert import convert_img -from ..utils.resource.RESOURCE_PATH import TEMP_PATH - -sv_char_info_config = SV('sr面板设置', pm=2) -sv_get_char_info = SV('sr面板查询', priority=10) -sv_get_sr_original_pic = SV('sr查看面板原图', priority=5) +sv_char_info_config = SV("sr面板设置", pm=2) +sv_get_char_info = SV("sr面板查询", priority=10) +sv_get_sr_original_pic = SV("sr查看面板原图", priority=5) -@sv_get_char_info.on_prefix(f'{PREFIX}查询') +@sv_get_char_info.on_prefix(f"{PREFIX}查询") async def send_char_info(bot: Bot, ev: Event): name = ev.text.strip() im = await _get_char_info(bot, ev, ev.text) @@ -36,12 +37,12 @@ async def send_char_info(bot: Bot, ev: Event): await bot.send_option( img, [ - Button('🔄更换武器', f'sr查询{name}换', action=2), - Button('⏫提高命座', f'sr查询六魂{name}', action=2), + Button("🔄更换武器", f"sr查询{name}换", action=2), + Button("⏫提高命座", f"sr查询六魂{name}", action=2), ], ) if im[1]: - with Path.open(TEMP_PATH / f'{ev.msg_id}.jpg', 'wb') as f: + with Path.open(TEMP_PATH / f"{ev.msg_id}.jpg", "wb") as f: f.write(cast(bytes, im[1])) elif isinstance(im, Image.Image): await bot.send(await convert_img(im)) @@ -50,14 +51,14 @@ async def send_char_info(bot: Bot, ev: Event): await bot.send_option( im, [ - Button('🔄更换武器', f'sr查询{name}换', action=2), - Button('⏫提高命座', f'sr查询六魂{name}', action=2), + Button("🔄更换武器", f"sr查询{name}换", action=2), + Button("⏫提高命座", f"sr查询六魂{name}", action=2), ], ) elif im is None: return else: - await bot.send('发生未知错误') + await bot.send("发生未知错误") async def _get_char_info(bot: Bot, ev: Event, text: str): @@ -66,33 +67,33 @@ async def _get_char_info(bot: Bot, ev: Event, text: str): if not msg: return None # 获取角色名 - await bot.logger.info('开始执行[查询角色面板]') + await bot.logger.info("开始执行[查询角色面板]") # 获取uid - if '换' in msg or '拿' in msg or '带' in msg: - uid = await get_uid(bot, ev, False, True) + if "换" in msg or "拿" in msg or "带" in msg: + uid = await get_uid(bot, ev, GsBind, "sr", False) else: - uid = await get_uid(bot, ev) - msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', text)) + uid = await get_uid(bot, ev, GsBind, "sr") + msg = " ".join(re.findall("[\u4e00-\u9fa5]+", text)) if uid is None: return await bot.send(UID_HINT) - await bot.logger.info(f'[查询角色面板]uid: {uid}') + await bot.logger.info(f"[查询角色面板]uid: {uid}") return await draw_char_info_img(msg, uid) -@sv_get_char_info.on_command(f'{PREFIX}强制刷新') +@sv_get_char_info.on_command(f"{PREFIX}强制刷新") async def send_card_info(bot: Bot, ev: Event): - uid = await get_uid(bot, ev) + uid = await get_uid(bot, ev, GsBind, "sr") if uid is None: return await bot.send(UID_HINT) - await bot.logger.info(f'[sr强制刷新]uid: {uid}') + await bot.logger.info(f"[sr强制刷新]uid: {uid}") im = await api_to_card(uid) - await bot.logger.info(f'UID{uid}获取角色数据成功!') + await bot.logger.info(f"UID{uid}获取角色数据成功!") if isinstance(im, Tuple): buttons = [ Button( - f'✅查询{avatarId2Name[str(avatarid)]}', - f'sr查询{avatarId2Name[str(avatarid)]}', + f"✅查询{avatarId2Name[str(avatarid)]}", + f"sr查询{avatarId2Name[str(avatarid)]}", ) for avatarid in im[1] ] diff --git a/StarRailUID/starrailuid_charinfo/draw_char_img.py b/StarRailUID/starrailuid_charinfo/draw_char_img.py index 1071f12..0494566 100644 --- a/StarRailUID/starrailuid_charinfo/draw_char_img.py +++ b/StarRailUID/starrailuid_charinfo/draw_char_img.py @@ -40,64 +40,62 @@ from ..utils.fonts.starrail_fonts import ( ) Excel_path = Path(__file__).parent -with Path.open(Excel_path / 'Excel' / 'SkillData.json', encoding='utf-8') as f: +with Path.open(Excel_path / "Excel" / "SkillData.json", encoding="utf-8") as f: skill_dict = json.load(f) -TEXT_PATH = Path(__file__).parent / 'texture2D' +TEXT_PATH = Path(__file__).parent / "texture2D" -bg_img = Image.open(TEXT_PATH / 'bg.png') +bg_img = Image.open(TEXT_PATH / "bg.png") white_color = (213, 213, 213) NUM_MAP = { - 0: '零', - 1: '一', - 2: '二', - 3: '三', - 4: '四', - 5: '五', - 6: '六', - 7: '七', + 0: "零", + 1: "一", + 2: "二", + 3: "三", + 4: "四", + 5: "五", + 6: "六", + 7: "七", } RANK_MAP = { - 1: '_rank1.png', - 2: '_rank2.png', - 3: '_ultimate.png', - 4: '_rank4.png', - 5: '_skill.png', - 6: '_rank6.png', + 1: "_rank1.png", + 2: "_rank2.png", + 3: "_ultimate.png", + 4: "_rank4.png", + 5: "_skill.png", + 6: "_rank6.png", } skill_type_map = { - 'Normal': ('普攻', 'basic_atk'), - 'BPSkill': ('战技', 'skill'), - 'Ultra': ('终结技', 'ultimate'), - '': ('天赋', 'talent'), - 'MazeNormal': 'dev_连携', - 'Maze': ('秘技', 'technique'), + "Normal": ("普攻", "basic_atk"), + "BPSkill": ("战技", "skill"), + "Ultra": ("终结技", "ultimate"), + "": ("天赋", "talent"), + "MazeNormal": "dev_连携", + "Maze": ("秘技", "technique"), } RELIC_POS = { - '1': (26, 1162), - '2': (367, 1162), - '3': (700, 1162), - '4': (26, 1593), - '5': (367, 1593), - '6': (700, 1593), + "1": (26, 1162), + "2": (367, 1162), + "3": (700, 1162), + "4": (26, 1593), + "5": (367, 1593), + "6": (700, 1593), } RELIC_CNT = { - 1: '', - 2: '●', - 3: '●●', - 4: '●●●', - 5: '●●●●', - 6: '●●●●●', + 1: "", + 2: "●", + 3: "●●", + 4: "●●●", + 5: "●●●●", + 6: "●●●●●", } -async def draw_char_img( - char_data: Dict, sr_uid: str, msg: str -) -> Union[bytes, str]: +async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes, str]: if isinstance(char_data, str): return char_data char = await cal_char_info(char_data) @@ -113,7 +111,7 @@ async def draw_char_img( char_change = 0 msg_h = 0 para = [] - if '换' in msg or '拿' in msg or '带' in msg: + if "换" in msg or "拿" in msg or "带" in msg: char_change = 1 para = textwrap.wrap(msg, width=45) msg_h = 40 * (len(para) + 1) @@ -122,22 +120,20 @@ async def draw_char_img( char_info = bg_img.copy() char_info = char_info.resize((1050, 2050 + bg_height)) char_img = ( - Image.open(CHAR_PORTRAIT_PATH / f'{char.char_id}.png') + Image.open(CHAR_PORTRAIT_PATH / f"{char.char_id}.png") .resize((1050, 1050)) - .convert('RGBA') + .convert("RGBA") ) char_info.paste(char_img, (-220, -130), char_img) # 放属性图标 - attr_img = Image.open(TEXT_PATH / f'IconAttribute{char.char_element}.png') + attr_img = Image.open(TEXT_PATH / f"IconAttribute{char.char_element}.png") char_info.paste(attr_img, (540, 122), attr_img) # 放角色名 char_img_draw = ImageDraw.Draw(char_info) - char_img_draw.text( - (620, 162), char.char_name, (255, 255, 255), sr_font_38, 'lm' - ) - if hasattr(sr_font_38, 'getsize'): + char_img_draw.text((620, 162), char.char_name, (255, 255, 255), sr_font_38, "lm") + if hasattr(sr_font_38, "getsize"): char_name_len = sr_font_38.getsize(char.char_name)[0] # type: ignore else: bbox = sr_font_38.getbbox(char.char_name) @@ -146,193 +142,187 @@ async def draw_char_img( # 放等级 char_img_draw.text( (620 + char_name_len + 50, 168), - f'LV.{char.char_level!s}', + f"LV.{char.char_level!s}", white_color, sr_font_24, - 'mm', + "mm", ) # 放星级 rarity_img = Image.open( - TEXT_PATH / f'LightCore_Rarity{char.char_rarity}.png' + TEXT_PATH / f"LightCore_Rarity{char.char_rarity}.png" ).resize((306, 72)) char_info.paste(rarity_img, (490, 189), rarity_img) # 放命座 - rank_img = Image.open(TEXT_PATH / 'ImgNewBg.png') + rank_img = Image.open(TEXT_PATH / "ImgNewBg.png") rank_img_draw = ImageDraw.Draw(rank_img) rank_img_draw.text( - (70, 44), f'{NUM_MAP[char.char_rank]}命', white_color, sr_font_28, 'mm' + (70, 44), f"{NUM_MAP[char.char_rank]}命", white_color, sr_font_28, "mm" ) char_info.paste(rank_img, (722, 181), rank_img) # 放uid char_img_draw.text( (995, 715), - f'uid {sr_uid}', + f"uid {sr_uid}", white_color, sr_font_28, - 'rm', + "rm", ) # 放属性列表 - attr_bg = Image.open(TEXT_PATH / 'attr_bg.png') + attr_bg = Image.open(TEXT_PATH / "attr_bg.png") attr_bg_draw = ImageDraw.Draw(attr_bg) # 生命值 - hp = int(char.base_attributes.get('hp')) + hp = int(char.base_attributes.get("hp")) add_hp = int( - char.add_attr.get('HPDelta', 0) + char.add_attr.get("HPDelta", 0) + hp * char.add_attr.get( - 'HPAddedRatio', + "HPAddedRatio", 0, ) ) - attr_bg_draw.text( - (413, 31), f'{hp + add_hp}', white_color, sr_font_26, 'rm' - ) + attr_bg_draw.text((413, 31), f"{hp + add_hp}", white_color, sr_font_26, "rm") attr_bg_draw.text( (428, 31), - f'(+{round(add_hp)!s})', + f"(+{round(add_hp)!s})", (95, 251, 80), sr_font_26, - anchor='lm', + anchor="lm", ) # 攻击力 - attack = int(char.base_attributes['attack']) + attack = int(char.base_attributes["attack"]) add_attack = int( - char.add_attr.get('AttackDelta', 0) - + attack * char.add_attr.get('AttackAddedRatio', 0) + char.add_attr.get("AttackDelta", 0) + + attack * char.add_attr.get("AttackAddedRatio", 0) ) attr_bg_draw.text( (413, 31 + 48), - f'{attack + add_attack}', + f"{attack + add_attack}", white_color, sr_font_26, - 'rm', + "rm", ) attr_bg_draw.text( (428, 31 + 48), - f'(+{round(add_attack)!s})', + f"(+{round(add_attack)!s})", (95, 251, 80), sr_font_26, - anchor='lm', + anchor="lm", ) # 防御力 - defence = int(char.base_attributes['defence']) + defence = int(char.base_attributes["defence"]) add_defence = int( - char.add_attr.get('DefenceDelta', 0) - + defence * char.add_attr.get('DefenceAddedRatio', 0) + char.add_attr.get("DefenceDelta", 0) + + defence * char.add_attr.get("DefenceAddedRatio", 0) ) attr_bg_draw.text( (413, 31 + 48 * 2), - f'{defence + add_defence}', + f"{defence + add_defence}", white_color, sr_font_26, - 'rm', + "rm", ) attr_bg_draw.text( (428, 31 + 48 * 2), - f'(+{round(add_defence)!s})', + f"(+{round(add_defence)!s})", (95, 251, 80), sr_font_26, - anchor='lm', + anchor="lm", ) # 速度 - speed = int(char.base_attributes['speed']) + speed = int(char.base_attributes["speed"]) add_speed = int( - char.add_attr.get('SpeedDelta', 0) - + speed * char.add_attr.get('SpeedAddedRatio', 0) + char.add_attr.get("SpeedDelta", 0) + + speed * char.add_attr.get("SpeedAddedRatio", 0) ) attr_bg_draw.text( (413, 31 + 48 * 3), - f'{speed + add_speed}', + f"{speed + add_speed}", white_color, sr_font_26, - 'rm', + "rm", ) attr_bg_draw.text( (428, 31 + 48 * 3), - f'(+{round(add_speed)!s})', + f"(+{round(add_speed)!s})", (95, 251, 80), sr_font_26, - anchor='lm', + anchor="lm", ) # 暴击率 - critical_chance = char.base_attributes['CriticalChanceBase'] - critical_chance_base = char.add_attr.get('CriticalChanceBase', 0) + critical_chance = char.base_attributes["CriticalChanceBase"] + critical_chance_base = char.add_attr.get("CriticalChanceBase", 0) critical_chance = (critical_chance + critical_chance_base) * 100 attr_bg_draw.text( (500, 31 + 48 * 4), - f'{critical_chance:.1f}%', + f"{critical_chance:.1f}%", white_color, sr_font_26, - 'rm', + "rm", ) # 暴击伤害 - critical_damage = char.base_attributes['CriticalDamageBase'] - critical_damage_base = char.add_attr.get('CriticalDamageBase', 0) + critical_damage = char.base_attributes["CriticalDamageBase"] + critical_damage_base = char.add_attr.get("CriticalDamageBase", 0) critical_damage = (critical_damage + critical_damage_base) * 100 attr_bg_draw.text( (500, 31 + 48 * 5), - f'{critical_damage:.1f}%', + f"{critical_damage:.1f}%", white_color, sr_font_26, - 'rm', + "rm", ) # 效果命中 - status_probability_base = ( - char.add_attr.get('StatusProbabilityBase', 0) * 100 - ) + status_probability_base = char.add_attr.get("StatusProbabilityBase", 0) * 100 attr_bg_draw.text( (500, 31 + 48 * 6), - f'{status_probability_base:.1f}%', + f"{status_probability_base:.1f}%", white_color, sr_font_26, - 'rm', + "rm", ) # 效果抵抗 - status_resistance_base = char.add_attr.get('StatusResistanceBase', 0) * 100 + status_resistance_base = char.add_attr.get("StatusResistanceBase", 0) * 100 attr_bg_draw.text( (500, 31 + 48 * 7), - f'{status_resistance_base:.1f}%', + f"{status_resistance_base:.1f}%", white_color, sr_font_26, - 'rm', + "rm", ) # 击破特攻 - status_resistance_base = ( - char.add_attr.get('BreakDamageAddedRatioBase', 0) * 100 - ) + status_resistance_base = char.add_attr.get("BreakDamageAddedRatioBase", 0) * 100 attr_bg_draw.text( (500, 31 + 48 * 8), - f'{status_resistance_base:.1f}%', + f"{status_resistance_base:.1f}%", white_color, sr_font_26, - 'rm', + "rm", ) char_info.paste(attr_bg, (475, 256), attr_bg) # 命座 for rank in range(6): - rank_bg = Image.open(TEXT_PATH / 'mz_bg.png') - rank_no_bg = Image.open(TEXT_PATH / 'mz_no_bg.png') + rank_bg = Image.open(TEXT_PATH / "mz_bg.png") + rank_no_bg = Image.open(TEXT_PATH / "mz_no_bg.png") if rank < char.char_rank: rank_img = ( - Image.open(SKILL_PATH / f'{char.char_id}{RANK_MAP[rank + 1]}') - .convert('RGBA') + Image.open(SKILL_PATH / f"{char.char_id}{RANK_MAP[rank + 1]}") + .convert("RGBA") .resize((50, 50)) ) rank_bg.paste(rank_img, (19, 19), rank_img) char_info.paste(rank_bg, (20 + rank * 80, 630), rank_bg) else: rank_img = ( - Image.open(SKILL_PATH / f'{char.char_id}{RANK_MAP[rank + 1]}') + Image.open(SKILL_PATH / f"{char.char_id}{RANK_MAP[rank + 1]}") .resize((50, 50)) - .convert('RGBA') + .convert("RGBA") ) rank_img.putalpha( - rank_img.getchannel('A').point( + rank_img.getchannel("A").point( lambda x: round(x * 0.45) if x > 0 else 0 ) ) @@ -340,17 +330,17 @@ async def draw_char_img( char_info.paste(rank_no_bg, (20 + rank * 80, 630), rank_no_bg) # 技能 - skill_bg = Image.open(TEXT_PATH / 'skill_bg.png') + skill_bg = Image.open(TEXT_PATH / "skill_bg.png") i = 0 for skill in char.char_skill: - skill_attr_img = Image.open(TEXT_PATH / f'skill_attr{i + 1}.png') - skill_panel_img = Image.open(TEXT_PATH / 'skill_panel.png') + skill_attr_img = Image.open(TEXT_PATH / f"skill_attr{i + 1}.png") + skill_panel_img = Image.open(TEXT_PATH / "skill_panel.png") skill_img = ( Image.open( SKILL_PATH / f'{char.char_id}_' f'{skill_type_map[skill["skillAttackType"]][1]}.png' ) - .convert('RGBA') + .convert("RGBA") .resize((55, 55)) ) skill_panel_img.paste(skill_img, (18, 15), skill_img) @@ -361,21 +351,21 @@ async def draw_char_img( f'{skill_type_map[skill["skillAttackType"]][0]}', white_color, sr_font_26, - 'lm', + "lm", ) skill_panel_img_draw.text( (89, 55), f'Lv.{skill["skillLevel"]}', white_color, sr_font_26, - 'lm', + "lm", ) skill_panel_img_draw.text( (75, 90), f'{skill["skillName"]}', (105, 105, 105), sr_font_20, - 'mm', + "mm", ) skill_bg.paste(skill_panel_img, (50 + 187 * i, 35), skill_panel_img) i += 1 @@ -383,11 +373,11 @@ async def draw_char_img( # 武器 if char.equipment != {}: - weapon_bg = Image.open(TEXT_PATH / 'weapon_bg.png') - weapon_id = char.equipment['equipmentID'] + weapon_bg = Image.open(TEXT_PATH / "weapon_bg.png") + weapon_id = char.equipment["equipmentID"] weapon_img = ( - Image.open(WEAPON_PATH / f'{weapon_id}.png') - .convert('RGBA') + Image.open(WEAPON_PATH / f"{weapon_id}.png") + .convert("RGBA") .resize((170, 180)) ) weapon_bg.paste(weapon_img, (20, 90), weapon_img) @@ -397,30 +387,29 @@ async def draw_char_img( f'{char.equipment["equipmentName"]}', white_color, sr_font_34, - 'lm', + "lm", ) - if hasattr(sr_font_34, 'getsize'): + if hasattr(sr_font_34, "getsize"): weapon_name_len = sr_font_34.getsize( # type: ignore - char.equipment['equipmentName'] + char.equipment["equipmentName"] )[0] else: - bbox = sr_font_34.getbbox(char.equipment['equipmentName']) + bbox = sr_font_34.getbbox(char.equipment["equipmentName"]) weapon_name_len = bbox[2] - bbox[0] # 放阶 - rank_img = Image.open(TEXT_PATH / 'ImgNewBg.png') + rank_img = Image.open(TEXT_PATH / "ImgNewBg.png") rank_img_draw = ImageDraw.Draw(rank_img) rank_img_draw.text( (70, 44), f'{NUM_MAP[char.equipment["equipmentRank"]]}阶', white_color, sr_font_28, - 'mm', + "mm", ) weapon_bg.paste(rank_img, (weapon_name_len + 330, 2), rank_img) rarity_img = Image.open( - TEXT_PATH - / f'LightCore_Rarity{char.equipment["equipmentRarity"]}.png' + TEXT_PATH / f'LightCore_Rarity{char.equipment["equipmentRarity"]}.png' ).resize((306, 72)) weapon_bg.paste(rarity_img, (223, 55), rarity_img) weapon_bg_draw.text( @@ -428,20 +417,20 @@ async def draw_char_img( f'Lv.{char.equipment["equipmentLevel"]}', white_color, sr_font_28, - 'mm', + "mm", ) # 武器技能 - desc = light_cone_ranks[str(char.equipment['equipmentID'])]['desc'] - desc_params = light_cone_ranks[str(char.equipment['equipmentID'])][ - 'params' - ][char.equipment['equipmentRank'] - 1] + desc = light_cone_ranks[str(char.equipment["equipmentID"])]["desc"] + desc_params = light_cone_ranks[str(char.equipment["equipmentID"])]["params"][ + char.equipment["equipmentRank"] - 1 + ] for i in range(len(desc_params)): temp = math.floor(desc_params[i] * 1000) / 10 - desc = desc.replace(f'#{i + 1}[i]%', f'{temp!s}%') - desc = desc.replace(f'#{i + 1}[f1]%', f'{temp!s}%') + desc = desc.replace(f"#{i + 1}[i]%", f"{temp!s}%") + desc = desc.replace(f"#{i + 1}[f1]%", f"{temp!s}%") for i in range(len(desc_params)): - desc = desc.replace(f'#{i + 1}[i]', str(desc_params[i])) + desc = desc.replace(f"#{i + 1}[i]", str(desc_params[i])) desclist = desc.split() desctexty = 115 for desctext in desclist: @@ -450,7 +439,7 @@ async def draw_char_img( (210, desctexty), # type: ignore desctext, sr_font_24, - '#F9F9F9', + "#F9F9F9", 370, ) desctexty += 28 @@ -458,22 +447,22 @@ async def draw_char_img( else: char_img_draw.text( (525, 1005), - 'No light cone!', + "No light cone!", white_color, fw_font_28, - 'mm', + "mm", ) # 遗器 if char.char_relic: - weapon_rank_bg = Image.open(TEXT_PATH / 'rank_bg.png') + weapon_rank_bg = Image.open(TEXT_PATH / "rank_bg.png") char_info.paste(weapon_rank_bg, (735, 880), weapon_rank_bg) relic_score = 0 for relic in char.char_relic: - rarity = RelicId2Rarity[str(relic['relicId'])] - relic_img = Image.open(TEXT_PATH / f'yq_bg{rarity}.png') - if str(relic['SetId'])[0] == '3': + rarity = RelicId2Rarity[str(relic["relicId"])] + relic_img = Image.open(TEXT_PATH / f"yq_bg{rarity}.png") + if str(relic["SetId"])[0] == "3": relic_piece_img = Image.open( RELIC_PATH / f'{relic["SetId"]}_{relic["Type"] - 5}.png' ) @@ -483,7 +472,7 @@ async def draw_char_img( ) relic_piece_new_img = relic_piece_img.resize( (105, 105), Image.Resampling.LANCZOS - ).convert('RGBA') + ).convert("RGBA") relic_img.paste( relic_piece_new_img, (200, 90), @@ -495,32 +484,32 @@ async def draw_char_img( ).resize((200, 48)) relic_img.paste(rarity_img, (-10, 80), rarity_img) relic_img_draw = ImageDraw.Draw(relic_img) - if len(relic['relicName']) <= 5: - main_name = relic['relicName'] + if len(relic["relicName"]) <= 5: + main_name = relic["relicName"] else: - main_name = relic['relicName'][:2] + relic['relicName'][4:] + main_name = relic["relicName"][:2] + relic["relicName"][4:] relic_img_draw.text( (30, 70), main_name, (255, 255, 255), sr_font_34, - anchor='lm', + anchor="lm", ) # 主属性 - main_value = relic['MainAffix']['Value'] - main_name: str = relic['MainAffix']['Name'] - main_level: int = relic['Level'] + main_value = relic["MainAffix"]["Value"] + main_name: str = relic["MainAffix"]["Name"] + main_level: int = relic["Level"] - if main_name in ['攻击力', '生命值', '防御力', '速度']: - mainValueStr = f'{main_value:.1f}' + if main_name in ["攻击力", "生命值", "防御力", "速度"]: + mainValueStr = f"{main_value:.1f}" else: - mainValueStr = str(math.floor(main_value * 1000) / 10) + '%' + mainValueStr = str(math.floor(main_value * 1000) / 10) + "%" mainNameNew = ( - main_name.replace('百分比', '') - .replace('伤害加成', '伤加成') - .replace('属性伤害', '伤害') + main_name.replace("百分比", "") + .replace("伤害加成", "伤加成") + .replace("属性伤害", "伤害") ) relic_img_draw.text( @@ -528,48 +517,48 @@ async def draw_char_img( mainNameNew, (255, 255, 255), sr_font_28, - anchor='lm', + anchor="lm", ) relic_img_draw.text( (35, 195), - f'+{mainValueStr}', + f"+{mainValueStr}", (255, 255, 255), sr_font_28, - anchor='lm', + anchor="lm", ) relic_img_draw.text( (180, 105), - f'+{main_level!s}', + f"+{main_level!s}", (255, 255, 255), sr_font_23, - anchor='mm', + anchor="mm", ) single_relic_score = 0 main_value_score = await get_relic_score( - relic['MainAffix']['Property'], + relic["MainAffix"]["Property"], main_value, char.char_name, True, - relic['Type'], + relic["Type"], ) single_relic_score += main_value_score - for index, i in enumerate(relic['SubAffixList']): - subName: str = i['Name'] - subCnt = i['Cnt'] - subValue = i['Value'] - subProperty = i['Property'] + for index, i in enumerate(relic["SubAffixList"]): + subName: str = i["Name"] + subCnt = i["Cnt"] + subValue = i["Value"] + subProperty = i["Property"] tmp_score = await get_relic_score( - subProperty, subValue, char.char_name, False, relic['Type'] + subProperty, subValue, char.char_name, False, relic["Type"] ) single_relic_score += tmp_score - if subName in ['攻击力', '生命值', '防御力', '速度']: - subValueStr = f'{subValue:.1f}' + if subName in ["攻击力", "生命值", "防御力", "速度"]: + subValueStr = f"{subValue:.1f}" else: - subValueStr = f'{subValue * 100:.1f}' + '%' - subNameStr = subName.replace('百分比', '').replace('元素', '') + subValueStr = f"{subValue * 100:.1f}" + "%" + subNameStr = subName.replace("百分比", "").replace("元素", "") # 副词条文字颜色 if tmp_score == 0: relic_color = (150, 150, 150) @@ -578,160 +567,156 @@ async def draw_char_img( relic_img_draw.text( (47, 237 + index * 47), - f'{subNameStr}', + f"{subNameStr}", relic_color, sr_font_26, - anchor='lm', + anchor="lm", ) relic_img_draw.text( (155, 237 + index * 47), - f'{RELIC_CNT[subCnt]}', + f"{RELIC_CNT[subCnt]}", relic_color, sr_font_18, - anchor='lm', + anchor="lm", ) relic_img_draw.text( (290, 237 + index * 47), - f'{subValueStr}', + f"{subValueStr}", relic_color, sr_font_26, - anchor='rm', + anchor="rm", ) relic_img_draw.text( (210, 195), - f'{int(single_relic_score)}分', + f"{int(single_relic_score)}分", (255, 255, 255), sr_font_28, - anchor='rm', + anchor="rm", ) - char_info.paste( - relic_img, RELIC_POS[str(relic['Type'])], relic_img - ) + char_info.paste(relic_img, RELIC_POS[str(relic["Type"])], relic_img) relic_score += single_relic_score if relic_score > 210: - relic_value_level = Image.open(TEXT_PATH / 'CommonIconSSS.png') + relic_value_level = Image.open(TEXT_PATH / "CommonIconSSS.png") char_info.paste(relic_value_level, (825, 963), relic_value_level) elif relic_score > 190: - relic_value_level = Image.open(TEXT_PATH / 'CommonIconSS.png') + relic_value_level = Image.open(TEXT_PATH / "CommonIconSS.png") char_info.paste(relic_value_level, (825, 963), relic_value_level) elif relic_score > 160: - relic_value_level = Image.open(TEXT_PATH / 'CommonIconS.png') + relic_value_level = Image.open(TEXT_PATH / "CommonIconS.png") char_info.paste(relic_value_level, (825, 963), relic_value_level) elif relic_score > 130: - relic_value_level = Image.open(TEXT_PATH / 'CommonIconA.png') + relic_value_level = Image.open(TEXT_PATH / "CommonIconA.png") char_info.paste(relic_value_level, (825, 963), relic_value_level) elif relic_score > 80: - relic_value_level = Image.open(TEXT_PATH / 'CommonIconB.png') + relic_value_level = Image.open(TEXT_PATH / "CommonIconB.png") char_info.paste(relic_value_level, (825, 963), relic_value_level) elif relic_score > 0: - relic_value_level = Image.open(TEXT_PATH / 'CommonIconC.png') + relic_value_level = Image.open(TEXT_PATH / "CommonIconC.png") char_info.paste(relic_value_level, (825, 963), relic_value_level) else: char_img_draw.text( (525, 1565), - 'No relic!', + "No relic!", white_color, fw_font_28, - 'mm', + "mm", ) if damage_len > 0: - damage_title_img = Image.open(TEXT_PATH / 'base_info_pure.png') + damage_title_img = Image.open(TEXT_PATH / "base_info_pure.png") char_info.paste(damage_title_img, (0, 2028), damage_title_img) # 写伤害 char_img_draw.text( (55, 2048), - '角色动作', + "角色动作", white_color, sr_font_26, - 'lm', + "lm", ) char_img_draw.text( (370, 2048), - '暴击值', + "暴击值", white_color, sr_font_26, - 'lm', + "lm", ) char_img_draw.text( (560, 2048), - '期望值', + "期望值", white_color, sr_font_26, - 'lm', + "lm", ) char_img_draw.text( (750, 2048), - '满配辅助末日兽', + "满配辅助末日兽", white_color, sr_font_26, - 'lm', + "lm", ) damage_num = 0 for damage_info in damage_list: damage_num = damage_num + 1 if damage_num % 2 == 0: - damage_img = Image.open(TEXT_PATH / 'attack_1.png') + damage_img = Image.open(TEXT_PATH / "attack_1.png") else: - damage_img = Image.open(TEXT_PATH / 'attack_2.png') - char_info.paste( - damage_img, (0, 2028 + damage_num * 48), damage_img - ) + damage_img = Image.open(TEXT_PATH / "attack_2.png") + char_info.paste(damage_img, (0, 2028 + damage_num * 48), damage_img) char_img_draw.text( (55, 2048 + damage_num * 48), f'{damage_info["name"]}', white_color, sr_font_26, - 'lm', + "lm", ) - dmg_list = damage_info['damagelist'] + dmg_list = damage_info["damagelist"] if len(dmg_list) == 3: damage1 = math.floor(dmg_list[0]) # type: ignore char_img_draw.text( (370, 2048 + damage_num * 48), - f'{damage1}', + f"{damage1}", white_color, sr_font_26, - 'lm', + "lm", ) damage2 = math.floor(dmg_list[1]) # type: ignore char_img_draw.text( (560, 2048 + damage_num * 48), - f'{damage2}', + f"{damage2}", white_color, sr_font_26, - 'lm', + "lm", ) damage3 = math.floor(dmg_list[2]) # type: ignore char_img_draw.text( (750, 2048 + damage_num * 48), - f'{damage3}', + f"{damage3}", white_color, sr_font_26, - 'lm', + "lm", ) else: damage = math.floor(dmg_list[0]) # type: ignore char_img_draw.text( (560, 2048 + damage_num * 48), - f'{damage}', + f"{damage}", white_color, sr_font_26, - 'lm', + "lm", ) if char_change == 1: char_img_draw.text( (525, 2022 + bg_height - msg_h), - '面板数据来源于: 【面板替换】', + "面板数据来源于: 【面板替换】", (180, 180, 180), sr_font_26, - 'mm', + "mm", ) current_h = 2022 + bg_height - msg_h + 40 @@ -741,22 +726,22 @@ async def draw_char_img( line, (180, 180, 180), sr_font_26, - 'mm', + "mm", ) current_h += 35 # 写底层文字 char_img_draw.text( (525, 2022 + bg_height), - '--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--', + "--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--", (255, 255, 255), fw_font_28, - 'mm', + "mm", ) # 发送图片 res = await convert_img(char_info) - logger.info('[sr面板]绘图已完成,等待发送!') + logger.info("[sr面板]绘图已完成,等待发送!") return res @@ -764,16 +749,16 @@ async def get_char_data( uid: str, char_name: str, enable_self: bool = True ) -> Union[Dict, str]: player_path = PLAYER_PATH / str(uid) - SELF_PATH = player_path / 'SELF' - if '开拓者' in str(char_name): - char_name = '开拓者' + SELF_PATH = player_path / "SELF" + if "开拓者" in str(char_name): + char_name = "开拓者" char_id = await name_to_avatar_id(char_name) - if char_id == '': + if char_id == "": char_name = await alias_to_char_name(char_name) if char_name is False: - return '请输入正确的角色名' - char_path = player_path / f'{char_name}.json' - char_self_path = SELF_PATH / f'{char_name}.json' + return "请输入正确的角色名" + char_path = player_path / f"{char_name}.json" + char_self_path = SELF_PATH / f"{char_name}.json" path = Path() if char_path.exists(): path = char_path @@ -795,7 +780,7 @@ async def get_char_data( else: return CHAR_HINT.format(char_name, char_name) - with Path.open(path, encoding='utf8') as fp: + with Path.open(path, encoding="utf8") as fp: return json.load(fp) @@ -805,71 +790,61 @@ async def get_relic_score( relic_score = 0 weight_dict = {} for item in AvatarRelicScore: - if item['role'] == char_name: + if item["role"] == char_name: weight_dict = item if weight_dict == {}: return 0 if is_main: elementlist = [ - 'Quantum', - 'Thunder', - 'Wind', - 'Physical', - 'Imaginary', - 'Ice', - 'Fire', + "Quantum", + "Thunder", + "Wind", + "Physical", + "Imaginary", + "Ice", + "Fire", ] if relicType in [3, 4, 5, 6]: - if subProperty.__contains__('AddedRatio') and relicType == 5: - if subProperty.split('AddedRatio')[0] in elementlist: - subProperty = 'AttributeAddedRatio' + if subProperty.__contains__("AddedRatio") and relicType == 5: + if subProperty.split("AddedRatio")[0] in elementlist: + subProperty = "AttributeAddedRatio" if weight_dict.get(subProperty, 0) > 0: relic_score += 5.83 else: - if subProperty == 'CriticalDamageBase': - add_value = subValue * 1 * weight_dict['CriticalDamageBase'] * 100 + if subProperty == "CriticalDamageBase": + add_value = subValue * 1 * weight_dict["CriticalDamageBase"] * 100 relic_score += add_value - if subProperty == 'CriticalChanceBase': - add_value = subValue * 2 * weight_dict['CriticalChanceBase'] * 100 + if subProperty == "CriticalChanceBase": + add_value = subValue * 2 * weight_dict["CriticalChanceBase"] * 100 relic_score += add_value - if subProperty == 'AttackDelta': - add_value = subValue * 0.3 * 0.5 * weight_dict['AttackDelta'] * 1.0 + if subProperty == "AttackDelta": + add_value = subValue * 0.3 * 0.5 * weight_dict["AttackDelta"] * 1.0 relic_score += add_value - if subProperty == 'DefenceDelta': - add_value = ( - subValue * 0.3 * 0.5 * weight_dict['DefenceDelta'] * 1.0 - ) + if subProperty == "DefenceDelta": + add_value = subValue * 0.3 * 0.5 * weight_dict["DefenceDelta"] * 1.0 relic_score += add_value - if subProperty == 'HPDelta': - add_value = subValue * 0.158 * 0.5 * weight_dict['HPDelta'] * 1.0 + if subProperty == "HPDelta": + add_value = subValue * 0.158 * 0.5 * weight_dict["HPDelta"] * 1.0 relic_score += add_value - if subProperty == 'AttackAddedRatio': - add_value = subValue * 1.5 * weight_dict['AttackAddedRatio'] * 100 + if subProperty == "AttackAddedRatio": + add_value = subValue * 1.5 * weight_dict["AttackAddedRatio"] * 100 relic_score += add_value - if subProperty == 'DefenceAddedRatio': - add_value = ( - subValue * 1.19 * weight_dict['DefenceAddedRatio'] * 100 - ) + if subProperty == "DefenceAddedRatio": + add_value = subValue * 1.19 * weight_dict["DefenceAddedRatio"] * 100 relic_score += add_value - if subProperty == 'HPAddedRatio': - add_value = subValue * 1.5 * weight_dict['HPAddedRatio'] * 100 + if subProperty == "HPAddedRatio": + add_value = subValue * 1.5 * weight_dict["HPAddedRatio"] * 100 relic_score += add_value - if subProperty == 'SpeedDelta': - add_value = subValue * 2.53 * weight_dict['SpeedDelta'] + if subProperty == "SpeedDelta": + add_value = subValue * 2.53 * weight_dict["SpeedDelta"] relic_score += add_value - if subProperty == 'BreakDamageAddedRatioBase': - add_value = ( - subValue * 1.0 * weight_dict['BreakDamageAddedRatioBase'] * 100 - ) + if subProperty == "BreakDamageAddedRatioBase": + add_value = subValue * 1.0 * weight_dict["BreakDamageAddedRatioBase"] * 100 relic_score += add_value - if subProperty == 'StatusProbabilityBase': - add_value = ( - subValue * 1.49 * weight_dict['StatusProbabilityBase'] * 100 - ) + if subProperty == "StatusProbabilityBase": + add_value = subValue * 1.49 * weight_dict["StatusProbabilityBase"] * 100 relic_score += add_value - if subProperty == 'StatusResistanceBase': - add_value = ( - subValue * 1.49 * weight_dict['StatusResistanceBase'] * 100 - ) + if subProperty == "StatusResistanceBase": + add_value = subValue * 1.49 * weight_dict["StatusResistanceBase"] * 100 relic_score += add_value return relic_score diff --git a/StarRailUID/starrailuid_charinfo/get_char_img.py b/StarRailUID/starrailuid_charinfo/get_char_img.py index 8f08633..84ac529 100644 --- a/StarRailUID/starrailuid_charinfo/get_char_img.py +++ b/StarRailUID/starrailuid_charinfo/get_char_img.py @@ -1,67 +1,67 @@ -import re import json from pathlib import Path -from typing import Dict, Tuple, Union, Optional +import re +from typing import Dict, Optional, Tuple, Union + +from .draw_char_img import draw_char_img +from ..utils.error_reply import CHAR_HINT +from ..utils.map.SR_MAP_PATH import ( + AvatarRankSkillUp, + EquipmentID2Name, + EquipmentID2Rarity, + Property2Name, + avatarId2DamageType, + avatarId2EnName, + avatarId2Name, + avatarId2Rarity, + characterSkillTree, + rankId2Name, + skillId2AttackType, + skillId2Effect, + skillId2Name, +) +from ..utils.map.name_covert import ( + alias_to_char_name, + alias_to_weapon_name, + name_to_avatar_id, + name_to_weapon_id, +) +from ..utils.resource.RESOURCE_PATH import PLAYER_PATH from gsuid_core.logger import logger -from starrail_damage_cal.to_data import api_to_dict from starrail_damage_cal.excel.model import ( AvatarPromotionConfig, EquipmentPromotionConfig, ) - -from .draw_char_img import draw_char_img -from ..utils.error_reply import CHAR_HINT -from ..utils.resource.RESOURCE_PATH import PLAYER_PATH -from ..utils.map.name_covert import ( - name_to_avatar_id, - name_to_weapon_id, - alias_to_char_name, - alias_to_weapon_name, -) -from ..utils.map.SR_MAP_PATH import ( - Property2Name, - EquipmentID2Name, - AvatarRankSkillUp, - EquipmentID2Rarity, - rankId2Name, - skillId2Name, - avatarId2Name, - skillId2Effect, - avatarId2EnName, - avatarId2Rarity, - characterSkillTree, - skillId2AttackType, - avatarId2DamageType, -) +from starrail_damage_cal.to_data import api_to_dict WEAPON_TO_INT = { - '一': 1, - '二': 2, - '三': 3, - '四': 4, - '五': 5, - '满': 5, + "一": 1, + "二": 2, + "三": 3, + "四": 4, + "五": 5, + "满": 5, } CHAR_TO_INT = { - '零': 0, - '一': 1, - '二': 2, - '三': 3, - '四': 4, - '五': 5, - '六': 6, - '满': 6, + "零": 0, + "一": 1, + "二": 2, + "三": 3, + "四": 4, + "五": 5, + "六": 6, + "满": 6, } PieceName_ilst = { - 0: ['头', '帽'], - 1: ['手'], - 2: ['衣', '服', '躯'], - 3: ['鞋', '腿'], - 4: ['球'], - 5: ['绳', '链'], + 0: ["头", "帽"], + 1: ["手"], + 2: ["衣", "服", "躯"], + 3: ["鞋", "腿"], + 4: ["球"], + 5: ["绳", "链"], } @@ -77,11 +77,11 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str): char = await get_char(*_args) if isinstance(char, str): - logger.info('[sr查询角色] 绘图失败, 替换的武器不正确!') + logger.info("[sr查询角色] 绘图失败, 替换的武器不正确!") return char im = await draw_char_img(char, sr_uid, raw_mes) - logger.info('[查询角色] 绘图完成,等待发送...') + logger.info("[查询角色] 绘图完成,等待发送...") return im @@ -92,24 +92,24 @@ async def get_char_args( # 六命希儿带于夜色中换1000xxxx4青雀遗器换1000xxxx6希儿头换银狼手 # 六命希儿带于夜色中换1000xxxx6希儿头 # 希儿换银狼手 - fake_name = '' + fake_name = "" talent_num = None char_data = {} weapon, weapon_affix = None, None - msg = msg.replace('带', '换').replace('拿', '换').replace('圣遗物', '遗器') + msg = msg.replace("带", "换").replace("拿", "换").replace("圣遗物", "遗器") # 希儿带于夜色中换1000xxxx6希儿头 - msg_list = msg.split('换') + msg_list = msg.split("换") for index, part in enumerate(msg_list): changeuid = await get_part_uid(part, uid) if changeuid is None: - return 'UID不正确噢~' + return "UID不正确噢~" # 判断主体 if index == 0: fake_name, talent_num = await get_fake_char_str(part) # 判断是否开启fake_char - if '遗器' in msg: + if "遗器" in msg: char_data = await get_char_data(uid, fake_name) if isinstance(char_data, str): char_data = await make_new_charinfo(uid, fake_name) @@ -119,29 +119,25 @@ async def get_char_args( return char_data continue - if '遗器' in part: + if "遗器" in part: char_data = await get_fake_char_data( char_data, - part.replace('遗器', '').replace(changeuid, ''), + part.replace("遗器", "").replace(changeuid, ""), changeuid, ) if isinstance(char_data, str): return char_data else: - for i, s in enumerate( - ['头部', '手部', '躯干', '腿部', '位面球', '连结绳'] - ): - if '赤沙' in part: + for i, s in enumerate(["头部", "手部", "躯干", "腿部", "位面球", "连结绳"]): + if "赤沙" in part: continue if part[-1] in PieceName_ilst[i]: if isinstance(char_data, str): return char_data - char_data = await change_equip( - changeuid, char_data, part, s, i - ) + char_data = await change_equip(changeuid, char_data, part, s, i) if not char_data: - change_name = part.replace(part[-1], '') - return f'要替换的{change_name}的{s}遗器不存在噢~' + change_name = part.replace(part[-1], "") + return f"要替换的{change_name}的{s}遗器不存在噢~" break else: weapon, weapon_affix = await get_fake_weapon_str(part) @@ -149,24 +145,22 @@ async def get_char_args( return char_data, weapon, weapon_affix, talent_num -async def change_equip( - uid: str, char_data: Dict, part: str, s: str, i: int -) -> Dict: - char_name = part.replace(part[-1], '').replace(uid, '') +async def change_equip(uid: str, char_data: Dict, part: str, s: str, i: int) -> Dict: + char_name = part.replace(part[-1], "").replace(uid, "") fake_data = await get_char_data(uid, char_name) if isinstance(fake_data, str): return {} relicmap = i + 1 - for equip in fake_data['RelicInfo']: - if str(str(equip['relicId'])[-1]) == str(relicmap): - char_data['RelicInfo'][i] = equip + for equip in fake_data["RelicInfo"]: + if str(str(equip["relicId"])[-1]) == str(relicmap): + char_data["RelicInfo"][i] = equip break return char_data async def get_part_uid(part: str, uid: str): sr_uid = uid - uid_data = re.findall(r'\d{9}', part) + uid_data = re.findall(r"\d{9}", part) if uid_data: sr_uid: Optional[str] = uid_data[0] return sr_uid @@ -178,9 +172,7 @@ async def get_fake_char_str(char_name: str) -> Tuple[str, Optional[int]]: """ talent_num = None - if ('魂' in char_name or '命' in char_name) and char_name[ - 0 - ] in CHAR_TO_INT: + if ("魂" in char_name or "命" in char_name) and char_name[0] in CHAR_TO_INT: talent_num = CHAR_TO_INT[char_name[0]] char_name = char_name[2:] return char_name, talent_num @@ -188,7 +180,7 @@ async def get_fake_char_str(char_name: str) -> Tuple[str, Optional[int]]: async def get_fake_weapon_str(msg: str) -> Tuple[str, Optional[int]]: weapon_affix = 1 - if '精' in msg and msg[1] in WEAPON_TO_INT: + if "精" in msg and msg[1] in WEAPON_TO_INT: weapon_affix = WEAPON_TO_INT[msg[1]] weapon = msg[2:] else: @@ -203,7 +195,7 @@ async def get_fake_char_data( if isinstance(original_data, str): return original_data if isinstance(original_data, Dict): - char_data['RelicInfo'] = original_data['RelicInfo'] + char_data["RelicInfo"] = original_data["RelicInfo"] return char_data @@ -212,16 +204,16 @@ async def get_char_data( uid: str, char_name: str, enable_self: bool = True ) -> Union[Dict, str]: player_path = PLAYER_PATH / str(uid) - SELF_PATH = player_path / 'SELF' - if '开拓者' in str(char_name): - char_name = '开拓者' + SELF_PATH = player_path / "SELF" + if "开拓者" in str(char_name): + char_name = "开拓者" char_id = await name_to_avatar_id(char_name) - if char_id == '': + if char_id == "": char_name = await alias_to_char_name(char_name) if char_name is False: - return '请输入正确的角色名' - char_path = player_path / f'{char_name}.json' - char_self_path = SELF_PATH / f'{char_name}.json' + return "请输入正确的角色名" + char_path = player_path / f"{char_name}.json" + char_self_path = SELF_PATH / f"{char_name}.json" path = Path() if char_path.exists(): path = char_path @@ -243,7 +235,7 @@ async def get_char_data( else: return CHAR_HINT.format(char_name, char_name) - with Path.open(path, encoding='utf8') as fp: + with Path.open(path, encoding="utf8") as fp: return json.load(fp) @@ -252,39 +244,29 @@ async def make_new_charinfo( fake_name: str, ): char_data = {} - char_data['uid'] = uid - char_data['nickName'] = 'test' + char_data["uid"] = uid + char_data["nickName"] = "test" char_id = await name_to_avatar_id(fake_name) - if char_id == '': + if char_id == "": fake_name = await alias_to_char_name(fake_name) if fake_name is False: - return '请输入正确的角色名' + return "请输入正确的角色名" char_id = await name_to_avatar_id(fake_name) - char_data['avatarId'] = int(char_id) - char_data['avatarName'] = fake_name - char_data['avatarElement'] = avatarId2DamageType[ - str(char_data['avatarId']) - ] - char_data['avatarRarity'] = str( - avatarId2Rarity[str(char_data['avatarId'])] - ) - char_data['avatarPromotion'] = 6 - char_data['avatarLevel'] = 80 - char_data['avatarSkill'] = await get_skill_list(char_data['avatarId']) - char_data['avatarExtraAbility'] = await get_extra_list( - char_data['avatarId'] - ) - char_data['avatarAttributeBonus'] = await get_attribute_list( - char_data['avatarId'] - ) - char_data['RelicInfo'] = [] - char_data['avatarEnName'] = avatarId2EnName[str(char_data['avatarId'])] - char_data['rank'] = 0 - char_data['rankList'] = [] - char_data['baseAttributes'] = await get_baseAttributes( - char_data['avatarId'] - ) - char_data['equipmentInfo'] = {} + char_data["avatarId"] = int(char_id) + char_data["avatarName"] = fake_name + char_data["avatarElement"] = avatarId2DamageType[str(char_data["avatarId"])] + char_data["avatarRarity"] = str(avatarId2Rarity[str(char_data["avatarId"])]) + char_data["avatarPromotion"] = 6 + char_data["avatarLevel"] = 80 + char_data["avatarSkill"] = await get_skill_list(char_data["avatarId"]) + char_data["avatarExtraAbility"] = await get_extra_list(char_data["avatarId"]) + char_data["avatarAttributeBonus"] = await get_attribute_list(char_data["avatarId"]) + char_data["RelicInfo"] = [] + char_data["avatarEnName"] = avatarId2EnName[str(char_data["avatarId"])] + char_data["rank"] = 0 + char_data["rankList"] = [] + char_data["baseAttributes"] = await get_baseAttributes(char_data["avatarId"]) + char_data["equipmentInfo"] = {} return char_data @@ -293,35 +275,40 @@ async def get_baseAttributes( ): # 处理基础属性 base_attributes = {} - avatar_promotion_base = AvatarPromotionConfig.Avatar[str(char_id)]['6'] + + avatar_promotion_base = None + for avatar in AvatarPromotionConfig: + if avatar.AvatarID == str(char_id): + avatar_promotion_base = avatar + break + + if not avatar_promotion_base: + msg = f"AvatarPromotionConfig not found: {char_id}" + raise ValueError(msg) # 攻击力 - base_attributes['attack'] = ( + base_attributes["attack"] = ( avatar_promotion_base.AttackBase.Value + avatar_promotion_base.AttackAdd.Value * (80 - 1) ) # 防御力 - base_attributes['defence'] = ( + base_attributes["defence"] = ( avatar_promotion_base.DefenceBase.Value + avatar_promotion_base.DefenceAdd.Value * (80 - 1) ) # 血量 - base_attributes['hp'] = ( + base_attributes["hp"] = ( avatar_promotion_base.HPBase.Value + avatar_promotion_base.HPAdd.Value * (80 - 1) ) # 速度 - base_attributes['speed'] = avatar_promotion_base.SpeedBase.Value + base_attributes["speed"] = avatar_promotion_base.SpeedBase.Value # 暴击率 - base_attributes['CriticalChanceBase'] = ( - avatar_promotion_base.CriticalChance.Value - ) + base_attributes["CriticalChanceBase"] = avatar_promotion_base.CriticalChance.Value # 暴击伤害 - base_attributes['CriticalDamageBase'] = ( - avatar_promotion_base.CriticalDamage.Value - ) + base_attributes["CriticalDamageBase"] = avatar_promotion_base.CriticalDamage.Value # 嘲讽 - base_attributes['BaseAggro'] = avatar_promotion_base.BaseAggro.Value + base_attributes["BaseAggro"] = avatar_promotion_base.BaseAggro.Value return base_attributes @@ -331,21 +318,19 @@ async def get_attribute_list( attribute_list = [] for attributeid in [201, 202, 203, 204, 205, 206, 207, 208, 209, 210]: attribute_bonus_temp = {} - attribute_bonus_temp['attributeBonusId'] = char_id * 1000 + attributeid - attribute_bonus_temp['attributeBonusLevel'] = 1 + attribute_bonus_temp["attributeBonusId"] = char_id * 1000 + attributeid + attribute_bonus_temp["attributeBonusLevel"] = 1 status_add = characterSkillTree[str(char_id)][ - str(attribute_bonus_temp['attributeBonusId']) - ]['levels'][0]['properties'] - attribute_bonus_temp['statusAdd'] = {} + str(attribute_bonus_temp["attributeBonusId"]) + ]["levels"][0]["properties"] + attribute_bonus_temp["statusAdd"] = {} if status_add: for property_ in status_add: - attribute_bonus_temp['statusAdd']['property'] = property_[ - 'type' + attribute_bonus_temp["statusAdd"]["property"] = property_["type"] + attribute_bonus_temp["statusAdd"]["name"] = Property2Name[ + property_["type"] ] - attribute_bonus_temp['statusAdd']['name'] = Property2Name[ - property_['type'] - ] - attribute_bonus_temp['statusAdd']['value'] = property_['value'] + attribute_bonus_temp["statusAdd"]["value"] = property_["value"] attribute_list.append(attribute_bonus_temp) return attribute_list @@ -356,8 +341,8 @@ async def get_extra_list( extra_list = [] for extraid in [101, 102, 103]: extra_temp = {} - extra_temp['extraAbilityId'] = char_id * 1000 + extraid - extra_temp['extraAbilityLevel'] = 1 + extra_temp["extraAbilityId"] = char_id * 1000 + extraid + extra_temp["extraAbilityLevel"] = 1 extra_list.append(extra_temp) return extra_list @@ -368,18 +353,16 @@ async def get_skill_list( Skilllist = [] for skillid in [1, 2, 3, 4, 7]: skill_temp = {} - skill_temp['skillId'] = char_id * 100 + skillid - skill_temp['skillName'] = skillId2Name[str(skill_temp['skillId'])] - skill_temp['skillEffect'] = skillId2Effect[str(skill_temp['skillId'])] - skill_temp['skillAttackType'] = skillId2AttackType[ - str(skill_temp['skillId']) - ] + skill_temp["skillId"] = char_id * 100 + skillid + skill_temp["skillName"] = skillId2Name[str(skill_temp["skillId"])] + skill_temp["skillEffect"] = skillId2Effect[str(skill_temp["skillId"])] + skill_temp["skillAttackType"] = skillId2AttackType[str(skill_temp["skillId"])] skilllevel = 10 if skillid == 1: skilllevel = 6 if skillid == 7: skilllevel = 1 - skill_temp['skillLevel'] = skilllevel + skill_temp["skillLevel"] = skilllevel Skilllist.append(skill_temp) return Skilllist @@ -391,9 +374,9 @@ async def get_rank_list( rank_temp = [] for index in range(talent_num): rankTemp = {} - rank_id = int(str(char_id) + '0' + str(index + 1)) - rankTemp['rankId'] = rank_id - rankTemp['rankName'] = rankId2Name[str(rank_id)] + rank_id = int(str(char_id) + "0" + str(index + 1)) + rankTemp["rankId"] = rank_id + rankTemp["rankName"] = rankId2Name[str(rank_id)] rank_temp.append(rankTemp) return rank_temp @@ -407,82 +390,82 @@ async def get_char( if isinstance(talent_num, int): # 处理命座 rank_temp = [] - char_data['rank'] = talent_num + char_data["rank"] = talent_num for index in range(talent_num): rankTemp = {} - rank_id = int(str(char_data['avatarId']) + '0' + str(index + 1)) - rankTemp['rankId'] = rank_id - rankTemp['rankName'] = rankId2Name[str(rank_id)] + rank_id = int(str(char_data["avatarId"]) + "0" + str(index + 1)) + rankTemp["rankId"] = rank_id + rankTemp["rankName"] = rankId2Name[str(rank_id)] rank_temp.append(rankTemp) - char_data['rankList'] = rank_temp + char_data["rankList"] = rank_temp # 处理命座中的 level_up_skills - if char_data.get('rankList'): - for rank_item in char_data['rankList']: - rank_id = rank_item['rankId'] + if char_data.get("rankList"): + for rank_item in char_data["rankList"]: + rank_id = rank_item["rankId"] level_up_skill = AvatarRankSkillUp[str(rank_id)] if level_up_skill: for item in level_up_skill: - skill_id = item['id'] - skill_up_num = item['num'] + skill_id = item["id"] + skill_up_num = item["num"] # 查找skill_id在不在avatarSkill中 - for index, skill_item in enumerate( - char_data['avatarSkill'] - ): - if str(skill_id) == str(skill_item['skillId']): + for index, skill_item in enumerate(char_data["avatarSkill"]): + if str(skill_id) == str(skill_item["skillId"]): if skill_id[-1] == 1: skilllevel_max = 7 else: skilllevel_max = 12 skilllevel = min( skilllevel_max, - char_data['avatarSkill'][index][ - 'skillLevel' - ] + char_data["avatarSkill"][index]["skillLevel"] + skill_up_num, ) - char_data['avatarSkill'][index][ - 'skillLevel' - ] = skilllevel + char_data["avatarSkill"][index]["skillLevel"] = ( + skilllevel + ) break if isinstance(weapon, str): # 处理武器 equipmentid = await name_to_weapon_id(weapon) - if equipmentid == '': + if equipmentid == "": weapon = await alias_to_weapon_name(weapon) equipmentid = await name_to_weapon_id(weapon) equipment_info = {} - equipment_info['equipmentID'] = int(equipmentid) - equipment_info['equipmentName'] = EquipmentID2Name[str(equipmentid)] + equipment_info["equipmentID"] = int(equipmentid) + equipment_info["equipmentName"] = EquipmentID2Name[str(equipmentid)] - equipment_info['equipmentLevel'] = 80 - equipment_info['equipmentPromotion'] = 6 - equipment_info['equipmentRank'] = weapon_affix - equipment_info['equipmentRarity'] = EquipmentID2Rarity[ - str(equipmentid) - ] + equipment_info["equipmentLevel"] = 80 + equipment_info["equipmentPromotion"] = 6 + equipment_info["equipmentRank"] = weapon_affix + equipment_info["equipmentRarity"] = EquipmentID2Rarity[str(equipmentid)] equipment_base_attributes = {} - equipment_promotion_base = EquipmentPromotionConfig.Equipment[ - str(equipmentid) - ]['6'] + + equipment_promotion_base = None + for equipment in EquipmentPromotionConfig: + if equipment.EquipmentID == str(equipmentid): + equipment_promotion_base = equipment + break + if not equipment_promotion_base: + msg = f"EquipmentPromotionConfig not found: {equipmentid}" + raise ValueError(msg) # 生命值 - equipment_base_attributes['hp'] = ( + equipment_base_attributes["hp"] = ( equipment_promotion_base.BaseHP.Value + equipment_promotion_base.BaseHPAdd.Value * (80 - 1) ) # 攻击力 - equipment_base_attributes['attack'] = ( + equipment_base_attributes["attack"] = ( equipment_promotion_base.BaseAttack.Value + equipment_promotion_base.BaseAttackAdd.Value * (80 - 1) ) # 防御力 - equipment_base_attributes['defence'] = ( + equipment_base_attributes["defence"] = ( equipment_promotion_base.BaseDefence.Value + equipment_promotion_base.BaseDefenceAdd.Value * (80 - 1) ) - equipment_info['baseAttributes'] = equipment_base_attributes + equipment_info["baseAttributes"] = equipment_base_attributes - char_data['equipmentInfo'] = equipment_info + char_data["equipmentInfo"] = equipment_info return char_data diff --git a/StarRailUID/starrailuid_charinfo/to_card.py b/StarRailUID/starrailuid_charinfo/to_card.py index 4db0baa..a9b7e31 100644 --- a/StarRailUID/starrailuid_charinfo/to_card.py +++ b/StarRailUID/starrailuid_charinfo/to_card.py @@ -19,12 +19,12 @@ second_color = (67, 61, 56) white_color = (247, 247, 247) gray_color = (175, 175, 175) -TEXT_PATH = Path(__file__).parent / 'texture2D' -char_mask = Image.open(TEXT_PATH / 'ring_mask.png') -char_bg_mask = Image.open(TEXT_PATH / 'char_bg_mask.png') -tag = Image.open(TEXT_PATH / 'tag.png') -footbar = Image.open(TEXT_PATH / 'footbar.png') -pic_500 = Image.open(TEXT_PATH / '500.png') +TEXT_PATH = Path(__file__).parent / "texture2D" +char_mask = Image.open(TEXT_PATH / "ring_mask.png") +char_bg_mask = Image.open(TEXT_PATH / "char_bg_mask.png") +tag = Image.open(TEXT_PATH / "tag.png") +footbar = Image.open(TEXT_PATH / "footbar.png") +pic_500 = Image.open(TEXT_PATH / "500.png") async def api_to_card(uid: str) -> Union[Tuple[bytes, List[str]], bytes]: @@ -52,19 +52,17 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0): avatarName = avatarId2Name[str(char)] char_data_list.append( { - 'avatarName': avatarName, - 'avatarId': str(char), + "avatarName": avatarName, + "avatarId": str(char), } ) if showfrom == 0: - line1 = f'展柜内有 {len(char_data_list)} 个角色!' + line1 = f"展柜内有 {len(char_data_list)} 个角色!" elif char_data_list is None: - return await convert_img(Image.new('RGBA', (0, 1), (255, 255, 255))) + return await convert_img(Image.new("RGBA", (0, 1), (255, 255, 255))) else: - line1 = f'UID {uid} 刷新成功' - line2 = ( - f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板' - ) + line1 = f"UID {uid} 刷新成功" + line2 = f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板' char_num = len(char_data_list) if char_num <= 4: based_w, based_h = 1380, 926 @@ -73,19 +71,19 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0): show_type = 0 based_w, based_h = 1380, 310 + (((char_num - 1) // 4) + 1) * 320 - img = Image.open(TEXT_PATH / 'shin.jpg') + img = Image.open(TEXT_PATH / "shin.jpg") img = crop_center_img(img, based_w, based_h) img.paste(tag, (0, 0), tag) - img_draw = ImageDraw.Draw(img, 'RGBA') + img_draw = ImageDraw.Draw(img, "RGBA") # 写底层文字 img_draw.text( (690, based_h - 26), - '--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--', + "--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--", (22, 22, 22), fw_font_28, - 'mm', + "mm", ) img_draw.text( @@ -93,14 +91,14 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0): line1, white_color, sr_font_58, - 'lm', + "lm", ) img_draw.text( (225, 175), line2, gray_color, sr_font_24, - 'lm', + "lm", ) tasks = [] for index, char_data in enumerate(char_data_list): @@ -113,17 +111,17 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0): async def draw_mihomo_char(index: int, img: Image.Image, char_data: Dict): - char_id = char_data['avatarId'] - char_name = char_data['avatarName'] + char_id = char_data["avatarId"] + char_name = char_data["avatarName"] char_star = await avatar_id_to_char_star(str(char_id)) - char_card = Image.open(TEXT_PATH / f'char{char_star}_bg.png') - char_temp = Image.new('RGBA', (300, 650)) + char_card = Image.open(TEXT_PATH / f"char{char_star}_bg.png") + char_temp = Image.new("RGBA", (300, 650)) char_img = ( - Image.open(str(CHAR_PREVIEW_PATH / f'{char_id}.png')) - .convert('RGBA') + Image.open(str(CHAR_PREVIEW_PATH / f"{char_id}.png")) + .convert("RGBA") .resize((449, 615)) ) - if char_name == '希儿': + if char_name == "希儿": char_img = char_img.resize((449, 650)) char_img = char_img.crop((135, 0, 379, 457)) char_temp.paste(char_img, (32, 98), char_img) @@ -132,40 +130,40 @@ async def draw_mihomo_char(index: int, img: Image.Image, char_data: Dict): char_temp.paste(char_img, (32, 38), char_img) char_card.paste(char_temp, (0, 0), char_bg_mask) - img_draw = ImageDraw.Draw(char_card, 'RGBA') + img_draw = ImageDraw.Draw(char_card, "RGBA") img_draw.text( (150, 585), char_name, white_color, sr_font_30, - 'mm', + "mm", ) x = 42 + index * 325 img.paste(char_card, (x, 199), char_card) async def draw_enka_char(index: int, img: Image.Image, char_data: Dict): - char_id = char_data['avatarId'] + char_id = char_data["avatarId"] char_star = await avatar_id_to_char_star(str(char_id)) - char_card = Image.open(TEXT_PATH / f'ring_{char_star}.png') - _path = CHAR_PREVIEW_PATH / f'{char_id}.png' - char_img = Image.open(_path).convert('RGBA') + char_card = Image.open(TEXT_PATH / f"ring_{char_star}.png") + _path = CHAR_PREVIEW_PATH / f"{char_id}.png" + char_img = Image.open(_path).convert("RGBA") char_img = char_img.resize( (int(char_img.size[0] * 0.76), int(char_img.size[1] * 0.76)) ) - char_temp = Image.new('RGBA', (300, 400)) - card_temp = Image.new('RGBA', (300, 400)) + char_temp = Image.new("RGBA", (300, 400)) + card_temp = Image.new("RGBA", (300, 400)) char_temp.paste(char_img, (19, 57), char_img) card_temp.paste(char_temp, (0, 0), char_mask) char_draw = ImageDraw.Draw(card_temp) char_draw.text( (144, 285), - char_data['avatarName'], - 'white', + char_data["avatarName"], + "white", sr_font_30, - 'mm', + "mm", ) img.paste( diff --git a/StarRailUID/starrailuid_config/__init__.py b/StarRailUID/starrailuid_config/__init__.py index b95a7ed..168ef05 100644 --- a/StarRailUID/starrailuid_config/__init__.py +++ b/StarRailUID/starrailuid_config/__init__.py @@ -7,18 +7,16 @@ from gsuid_core.models import Event from gsuid_core.sv import SV from gsuid_core.utils.database.models import GsBind -PREFIX = srconfig.get_config('StarRailPrefix').data +PREFIX = srconfig.get_config("StarRailPrefix").data -sv_self_config = SV('星穹铁道配置') +sv_self_config = SV("星穹铁道配置") -@sv_self_config.on_prefix((f'{PREFIX}开启', f'{PREFIX}关闭')) +@sv_self_config.on_prefix((f"{PREFIX}开启", f"{PREFIX}关闭")) async def open_switch_func(bot: Bot, ev: Event): - uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr') + uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, "sr") if uid is None: - return await bot.send('[星穹铁道] 你还没有绑定UID哦!') - logger.info( - f'[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能' - ) + return await bot.send("[星穹铁道] 你还没有绑定UID哦!") + logger.info(f"[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能") await bot.send(await set_config_func(uid, ev)) return None diff --git a/StarRailUID/starrailuid_config/config_default.py b/StarRailUID/starrailuid_config/config_default.py index e905d05..3794655 100644 --- a/StarRailUID/starrailuid_config/config_default.py +++ b/StarRailUID/starrailuid_config/config_default.py @@ -4,47 +4,43 @@ from gsuid_core.utils.plugins_config.models import ( GSC, GsStrConfig, GsBoolConfig, - GsListStrConfig, GsIntConfig, + GsListStrConfig, + GsIntConfig, ) CONIFG_DEFAULT: Dict[str, GSC] = { - 'SignTime': GsListStrConfig( - '每晚签到时间设置', '每晚米游社签到时间设置(时,分)', ['0', '38'] + "SignTime": GsListStrConfig( + "每晚签到时间设置", "每晚米游社签到时间设置(时,分)", ["0", "38"] ), - 'PrivateSignReport': GsBoolConfig( - '签到私聊报告', - '关闭后将不再给任何人推送当天签到任务完成情况', + "PrivateSignReport": GsBoolConfig( + "签到私聊报告", + "关闭后将不再给任何人推送当天签到任务完成情况", False, ), - 'SchedSignin': GsBoolConfig( - '定时签到', - '开启后每晚00:30将开始自动签到任务', + "SchedSignin": GsBoolConfig( + "定时签到", + "开启后每晚00:30将开始自动签到任务", True, ), - 'SchedStaminaPush': GsBoolConfig( - '定时检查开拓力', - '开启后每隔半小时检查一次开拓力', + "SchedStaminaPush": GsBoolConfig( + "定时检查开拓力", + "开启后每隔半小时检查一次开拓力", True, ), - 'push_max_value': GsIntConfig( - '提醒阈值', - '发送提醒的阈值', - 200, - 240 - ), - 'CrazyNotice': GsBoolConfig( - '催命模式', - '开启后当达到推送阈值将会一直推送', + "push_max_value": GsIntConfig("提醒阈值", "发送提醒的阈值", 200, 240), + "CrazyNotice": GsBoolConfig( + "催命模式", + "开启后当达到推送阈值将会一直推送", False, ), - 'StarRailPrefix': GsStrConfig( - '插件命令前缀(确认无冲突再修改)', - '用于本插件的前缀设定', - 'sr', + "StarRailPrefix": GsStrConfig( + "插件命令前缀(确认无冲突再修改)", + "用于本插件的前缀设定", + "sr", ), - 'WidgetResin': GsBoolConfig( - '体力使用组件API', - '开启后mr功能将转为调用组件API, 可能缺失数据、数据不准', + "WidgetResin": GsBoolConfig( + "体力使用组件API", + "开启后mr功能将转为调用组件API, 可能缺失数据、数据不准", True, ), } diff --git a/StarRailUID/starrailuid_config/set_config.py b/StarRailUID/starrailuid_config/set_config.py index 7789207..f294d85 100644 --- a/StarRailUID/starrailuid_config/set_config.py +++ b/StarRailUID/starrailuid_config/set_config.py @@ -8,26 +8,26 @@ async def set_config_func( uid: str, ev: Event, ): - if '开启' in ev.command: - if ev.user_type == 'direct': - value = 'on' + if "开启" in ev.command: + if ev.user_type == "direct": + value = "on" elif ev.group_id: value = ev.group_id else: - value = 'on' + value = "on" else: - value = 'off' + value = "off" text = await set_database_value( GsUser, - 'sr', - 'sr开启', + "sr", + "sr开启", ev.text.strip(), uid, ev.bot_id, value, ) if text is None: - return '[星穹铁道] 未找到配置项' - logger.success(f'[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!') + return "[星穹铁道] 未找到配置项" + logger.success(f"[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!") return text diff --git a/StarRailUID/starrailuid_config/sr_config.py b/StarRailUID/starrailuid_config/sr_config.py index 0e2fa23..beb2fdb 100644 --- a/StarRailUID/starrailuid_config/sr_config.py +++ b/StarRailUID/starrailuid_config/sr_config.py @@ -4,7 +4,7 @@ from .config_default import CONIFG_DEFAULT from ..utils.resource.RESOURCE_PATH import CONFIG_PATH srconfig = StringConfig( - 'StarRailUID', + "StarRailUID", CONFIG_PATH, CONIFG_DEFAULT, ) diff --git a/StarRailUID/starrailuid_gachalog/__init__.py b/StarRailUID/starrailuid_gachalog/__init__.py index e852088..490048a 100644 --- a/StarRailUID/starrailuid_gachalog/__init__.py +++ b/StarRailUID/starrailuid_gachalog/__init__.py @@ -1,24 +1,22 @@ -from gsuid_core.sv import SV +from .draw_gachalogs import draw_gachalogs_img +from .get_gachalogs import save_gachalogs +from ..utils.error_reply import UID_HINT +from ..utils.sr_prefix import PREFIX + from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from ..utils.error_reply import UID_HINT -from .get_gachalogs import save_gachalogs -from .draw_gachalogs import draw_gachalogs_img - -sv_gacha_log = SV('sr抽卡记录') -sv_get_gachalog_by_link = SV('sr导入抽卡链接', area='DIRECT') +sv_gacha_log = SV("sr抽卡记录") +sv_get_gachalog_by_link = SV("sr导入抽卡链接", area="DIRECT") -@sv_gacha_log.on_fullmatch(f'{PREFIX}抽卡记录') +@sv_gacha_log.on_fullmatch(f"{PREFIX}抽卡记录") async def send_gacha_log_card_info(bot: Bot, ev: Event): - await bot.logger.info('开始执行[sr抽卡记录]') - get_uid_ = await get_uid(bot, ev, True, False) - if get_uid_ is None: - return await bot.send(UID_HINT) - uid, user_id = get_uid_ + await bot.logger.info("开始执行[sr抽卡记录]") + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) if uid is None: return await bot.send(UID_HINT) im = await draw_gachalogs_img(uid, user_id) @@ -26,21 +24,19 @@ async def send_gacha_log_card_info(bot: Bot, ev: Event): return None -@sv_get_gachalog_by_link.on_command(f'{PREFIX}导入抽卡链接') +@sv_get_gachalog_by_link.on_command(f"{PREFIX}导入抽卡链接") async def get_gachalog_by_link(bot: Bot, ev: Event): - await bot.logger.info('开始执行[sr导入抽卡链接]') - uid = await get_uid(bot, ev, only_uid=True) + await bot.logger.info("开始执行[sr导入抽卡链接]") + uid = await get_uid(bot, ev, GsBind, "sr") if uid is None: return await bot.send(UID_HINT) gacha_url = ev.text.strip() if not gacha_url or not isinstance(gacha_url, str): - return await bot.send('请给出正确的抽卡记录链接') + return await bot.send("请给出正确的抽卡记录链接") is_force = False - if ev.command.startswith('强制'): - await bot.logger.info('[WARNING]本次为强制刷新') + if ev.command.startswith("强制"): + await bot.logger.info("[WARNING]本次为强制刷新") is_force = True - await bot.send( - f'UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!' - ) + await bot.send(f"UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!") im = await save_gachalogs(uid, gacha_url, None, is_force) return await bot.send(im) diff --git a/StarRailUID/starrailuid_gachalog/draw_gachalogs.py b/StarRailUID/starrailuid_gachalog/draw_gachalogs.py index bee1a08..09b1d35 100644 --- a/StarRailUID/starrailuid_gachalog/draw_gachalogs.py +++ b/StarRailUID/starrailuid_gachalog/draw_gachalogs.py @@ -1,24 +1,9 @@ -import json import asyncio import datetime +import json from pathlib import Path from typing import List, Tuple, Union -from PIL import Image, ImageDraw -from gsuid_core.logger import logger -from gsuid_core.utils.image.image_tools import ( - get_color_bg, - get_qq_avatar, - draw_pic_with_ring, -) - -from ..utils.image.convert import convert_img -from ..utils.map.name_covert import name_to_avatar_id, name_to_weapon_id -from ..utils.resource.RESOURCE_PATH import ( - PLAYER_PATH, - WEAPON_PATH, - CHAR_ICON_PATH, -) from ..utils.fonts.starrail_fonts import ( sr_font_20, sr_font_24, @@ -26,13 +11,28 @@ from ..utils.fonts.starrail_fonts import ( sr_font_38, sr_font_40, ) +from ..utils.map.name_covert import name_to_avatar_id, name_to_weapon_id +from ..utils.resource.RESOURCE_PATH import ( + CHAR_ICON_PATH, + PLAYER_PATH, + WEAPON_PATH, +) -TEXT_PATH = Path(__file__).parent / 'texture2d' -EMO_PATH = Path(__file__).parent / 'texture2d' / 'emo' +from PIL import Image, ImageDraw +from gsuid_core.logger import logger +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import ( + draw_pic_with_ring, + get_color_bg, + get_qq_avatar, +) + +TEXT_PATH = Path(__file__).parent / "texture2d" +EMO_PATH = Path(__file__).parent / "texture2d" / "emo" # up_tag = Image.open(TEXT_PATH / 'up.png') -Abg3_img = Image.open(TEXT_PATH / 'Abg3.png') -bg1_img = Image.open(TEXT_PATH / 'bg1.png') +Abg3_img = Image.open(TEXT_PATH / "Abg3.png") +bg1_img = Image.open(TEXT_PATH / "bg1.png") first_color = (29, 29, 29) brown_color = (41, 25, 0) @@ -42,33 +42,33 @@ white_color = (213, 213, 213) whole_white_color = (255, 255, 255) CHANGE_MAP = { - '始发跃迁': 'begin', - '群星跃迁': 'normal', - '角色跃迁': 'char', - '光锥跃迁': 'weapon', + "始发跃迁": "begin", + "群星跃迁": "normal", + "角色跃迁": "char", + "光锥跃迁": "weapon", } -HOMO_TAG = ['非到极致', '运气不好', '平稳保底', '小欧一把', '欧狗在此'] +HOMO_TAG = ["非到极致", "运气不好", "平稳保底", "小欧一把", "欧狗在此"] NORMAL_LIST = [ - '彦卿', - '白露', - '姬子', - '瓦尔特', - '布洛妮娅', - '克拉拉', - '杰帕德', - '银河铁道之夜', - '以世界之名', - '但战斗还未结束', - '制胜的瞬间', - '无可取代的东西', - '时节不居', - '如泥酣眠', + "彦卿", + "白露", + "姬子", + "瓦尔特", + "布洛妮娅", + "克拉拉", + "杰帕德", + "银河铁道之夜", + "以世界之名", + "但战斗还未结束", + "制胜的瞬间", + "无可取代的东西", + "时节不居", + "如泥酣眠", ] UP_LIST = { - '刻晴': [(2021, 2, 17, 18, 0, 0), (2021, 3, 2, 15, 59, 59)], - '提纳里': [(2022, 8, 24, 11, 0, 0), (2022, 9, 9, 17, 59, 59)], - '迪希雅': [(2023, 3, 1, 11, 0, 0), (2023, 3, 21, 17, 59, 59)], + "刻晴": [(2021, 2, 17, 18, 0, 0), (2021, 3, 2, 15, 59, 59)], + "提纳里": [(2022, 8, 24, 11, 0, 0), (2022, 9, 9, 17, 59, 59)], + "迪希雅": [(2023, 3, 1, 11, 0, 0), (2023, 3, 21, 17, 59, 59)], } @@ -80,24 +80,20 @@ async def _draw_card( gacha_num: int, is_up: bool, ): - card_img = Image.open(TEXT_PATH / 'char_bg.png') + card_img = Image.open(TEXT_PATH / "char_bg.png") card_img_draw = ImageDraw.Draw(card_img) point = (47, 31) text_point = (100, 165) - if card_type == '角色': + if card_type == "角色": _id = await name_to_avatar_id(name) item_pic = ( - Image.open(CHAR_ICON_PATH / f'{_id}.png') - .convert('RGBA') - .resize((105, 105)) + Image.open(CHAR_ICON_PATH / f"{_id}.png").convert("RGBA").resize((105, 105)) ) else: name = await name_to_weapon_id(name) # _id = await weapon_id_to_en_name(name) item_pic = ( - Image.open(WEAPON_PATH / f'{name}.png') - .convert('RGBA') - .resize((124, 124)) + Image.open(WEAPON_PATH / f"{name}.png").convert("RGBA").resize((124, 124)) ) point = (37, 24) card_img.paste(item_pic, point, item_pic) @@ -107,17 +103,15 @@ async def _draw_card( text_color = green_color else: text_color = brown_color - card_img_draw.text( - text_point, f'{gacha_num}抽', text_color, sr_font_24, 'mm' - ) + card_img_draw.text(text_point, f"{gacha_num}抽", text_color, sr_font_24, "mm") if is_up: - logger.info(f'up: {name}') + logger.info(f"up: {name}") # card_img.paste(up_tag, (47, -2), up_tag) img.paste(card_img, xy_point, card_img) async def random_emo_pic(level: int) -> Image.Image: - emo_fold = EMO_PATH / f'3000{level}.png' + emo_fold = EMO_PATH / f"3000{level}.png" return Image.open(emo_fold) @@ -140,7 +134,7 @@ def check_up(name: str, _time: str) -> bool: time = UP_LIST[char] s_time = datetime.datetime(*time[0]) e_time = datetime.datetime(*time[1]) - gacha_time = datetime.datetime.strptime(_time, '%Y-%m-%d %H:%M:%S') + gacha_time = datetime.datetime.strptime(_time, "%Y-%m-%d %H:%M:%S") if gacha_time < s_time or gacha_time > e_time: return False return True @@ -148,33 +142,33 @@ def check_up(name: str, _time: str) -> bool: async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]: - path = PLAYER_PATH / str(uid) / 'gacha_logs.json' + path = PLAYER_PATH / str(uid) / "gacha_logs.json" if not path.exists(): - return '你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~' - with Path.open(path, encoding='UTF-8') as f: + return "你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~" + with Path.open(path, encoding="UTF-8") as f: gacha_data = json.load(f) # 数据初始化 total_data = {} - for i in ['群星跃迁', '始发跃迁', '角色跃迁', '光锥跃迁']: + for i in ["群星跃迁", "始发跃迁", "角色跃迁", "光锥跃迁"]: total_data[i] = { - 'total': 0, # 五星总数 - 'avg': 0, # 抽卡平均数 - 'avg_up': 0, # up平均数 - 'remain': 0, # 已xx抽未出金 - 'r_num': [], # 不包含首位的抽卡数量 - 'e_num': [], # 包含首位的up抽卡数量 - 'up_list': [], # 抽到的UP列表(不包含首位) - 'normal_list': [], # 抽到的五星列表(不包含首位) - 'list': [], # 抽到的五星列表 - 'time_range': '', # 抽卡时间 - 'all_time': 0, # 抽卡总计秒数 - 'type': '一般型', # 抽卡类型: 随缘型, 氪金型, 规划型, 仓鼠型, 佛系型 - 'short_gacha_data': {'time': 0, 'num': 0}, - 'long_gacha_data': {'time': 0, 'num': 0}, + "total": 0, # 五星总数 + "avg": 0, # 抽卡平均数 + "avg_up": 0, # up平均数 + "remain": 0, # 已xx抽未出金 + "r_num": [], # 不包含首位的抽卡数量 + "e_num": [], # 包含首位的up抽卡数量 + "up_list": [], # 抽到的UP列表(不包含首位) + "normal_list": [], # 抽到的五星列表(不包含首位) + "list": [], # 抽到的五星列表 + "time_range": "", # 抽卡时间 + "all_time": 0, # 抽卡总计秒数 + "type": "一般型", # 抽卡类型: 随缘型, 氪金型, 规划型, 仓鼠型, 佛系型 + "short_gacha_data": {"time": 0, "num": 0}, + "long_gacha_data": {"time": 0, "num": 0}, } # 拿到数据列表 - data_list = gacha_data['data'][i] + data_list = gacha_data["data"][i] # 初始化开关 is_not_first = True # 开始初始化抽卡数 @@ -184,141 +178,137 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]: for index, data in enumerate(data_list[::-1]): # 计算抽卡时间跨度 if index == 0: - total_data[i]['time_range'] = data['time'] + total_data[i]["time_range"] = data["time"] if index == len(data_list) - 1: - total_data[i]['all_time'] = ( - datetime.datetime.strptime( - data['time'], '%Y-%m-%d %H:%M:%S' - ) + total_data[i]["all_time"] = ( + datetime.datetime.strptime(data["time"], "%Y-%m-%d %H:%M:%S") - datetime.datetime.strptime( - total_data[i]['time_range'], '%Y-%m-%d %H:%M:%S' + total_data[i]["time_range"], "%Y-%m-%d %H:%M:%S" ) ).total_seconds() - total_data[i]['time_range'] += '~' + data['time'] + total_data[i]["time_range"] += "~" + data["time"] # 计算时间间隔 if index != 0: - now_time = datetime.datetime.strptime( - data['time'], '%Y-%m-%d %H:%M:%S' - ) + now_time = datetime.datetime.strptime(data["time"], "%Y-%m-%d %H:%M:%S") dis = (now_time - temp_time).total_seconds() temp_time = now_time if dis <= 5000: - total_data[i]['short_gacha_data']['num'] += 1 - total_data[i]['short_gacha_data']['time'] += dis + total_data[i]["short_gacha_data"]["num"] += 1 + total_data[i]["short_gacha_data"]["time"] += dis elif dis >= 86400: - total_data[i]['long_gacha_data']['num'] += 1 - total_data[i]['long_gacha_data']['time'] += dis + total_data[i]["long_gacha_data"]["num"] += 1 + total_data[i]["long_gacha_data"]["time"] += dis else: temp_time = datetime.datetime.strptime( - data['time'], '%Y-%m-%d %H:%M:%S' + data["time"], "%Y-%m-%d %H:%M:%S" ) # 如果这是个五星 - if data['rank_type'] == '5': + if data["rank_type"] == "5": # 抽到这个五星花了多少抽 - data['gacha_num'] = num + data["gacha_num"] = num # 判断是否是UP - if data['name'] in NORMAL_LIST: - data['is_up'] = False - elif data['name'] in UP_LIST: - data['is_up'] = check_up(data['name'], data['time']) + if data["name"] in NORMAL_LIST: + data["is_up"] = False + elif data["name"] in UP_LIST: + data["is_up"] = check_up(data["name"], data["time"]) else: - data['is_up'] = True + data["is_up"] = True # 往里加东西 if is_not_first: - total_data[i]['r_num'].append(num) - total_data[i]['normal_list'].append(data) - if data['is_up']: - total_data[i]['up_list'].append(data) + total_data[i]["r_num"].append(num) + total_data[i]["normal_list"].append(data) + if data["is_up"]: + total_data[i]["up_list"].append(data) # 把这个数据扔到抽到的五星列表内 - total_data[i]['list'].append(data) + total_data[i]["list"].append(data) # 判断经过了第一个 - if total_data[i]['list']: + if total_data[i]["list"]: is_not_first = True num = 1 # 五星总数增加1 - total_data[i]['total'] += 1 + total_data[i]["total"] += 1 else: num += 1 # 计算已多少抽 - total_data[i]['remain'] = num - 1 + total_data[i]["remain"] = num - 1 # 计算平均抽卡数 - if len(total_data[i]['normal_list']) == 0: - total_data[i]['avg'] = 0 + if len(total_data[i]["normal_list"]) == 0: + total_data[i]["avg"] = 0 else: - total_data[i]['avg'] = float( - '{:.2f}'.format( - sum(total_data[i]['r_num']) / len(total_data[i]['r_num']) + total_data[i]["avg"] = float( + "{:.2f}".format( + sum(total_data[i]["r_num"]) / len(total_data[i]["r_num"]) ) ) # 计算平均up数量 - if len(total_data[i]['up_list']) == 0: - total_data[i]['avg_up'] = 0 + if len(total_data[i]["up_list"]) == 0: + total_data[i]["avg_up"] = 0 else: - total_data[i]['avg_up'] = float( - '{:.2f}'.format( - sum(total_data[i]['r_num']) / len(total_data[i]['up_list']) + total_data[i]["avg_up"] = float( + "{:.2f}".format( + sum(total_data[i]["r_num"]) / len(total_data[i]["up_list"]) ) ) # 计算抽卡类型 # 如果抽卡总数小于40 - if gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] <= 40: - total_data[i]['type'] = '佛系型' + if gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] <= 40: + total_data[i]["type"] = "佛系型" # 如果长时抽卡总数占据了总抽卡数的70% elif ( - total_data[i]['long_gacha_data']['num'] - / gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] + total_data[i]["long_gacha_data"]["num"] + / gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] >= 0.7 ): - total_data[i]['type'] = '随缘型' + total_data[i]["type"] = "随缘型" # 如果短时抽卡总数占据了总抽卡数的70% elif ( - total_data[i]['short_gacha_data']['num'] - / gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] + total_data[i]["short_gacha_data"]["num"] + / gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] >= 0.7 ): - total_data[i]['type'] = '规划型' + total_data[i]["type"] = "规划型" # 如果抽卡数量远远大于标称抽卡数量 elif ( - total_data[i]['all_time'] / 30000 - <= gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] + total_data[i]["all_time"] / 30000 + <= gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] ): # 如果长时抽卡数量大于短时抽卡数量 if ( - total_data[i]['long_gacha_data']['num'] - >= total_data[i]['short_gacha_data']['num'] + total_data[i]["long_gacha_data"]["num"] + >= total_data[i]["short_gacha_data"]["num"] ): - total_data[i]['type'] = '规划型' + total_data[i]["type"] = "规划型" else: - total_data[i]['type'] = '氪金型' + total_data[i]["type"] = "氪金型" # 如果抽卡数量远远小于标称抽卡数量 elif ( - total_data[i]['all_time'] / 32000 - >= gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] * 2 + total_data[i]["all_time"] / 32000 + >= gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] * 2 ): - total_data[i]['type'] = '仓鼠型' + total_data[i]["type"] = "仓鼠型" # 常量偏移数据 single_y = 170 # 计算图片尺寸 - normal_y = (1 + ((total_data['群星跃迁']['total'] - 1) // 5)) * single_y - begin_y = (1 + ((total_data['始发跃迁']['total'] - 1) // 5)) * single_y - char_y = (1 + ((total_data['角色跃迁']['total'] - 1) // 5)) * single_y - weapon_y = (1 + ((total_data['光锥跃迁']['total'] - 1) // 5)) * single_y + normal_y = (1 + ((total_data["群星跃迁"]["total"] - 1) // 5)) * single_y + begin_y = (1 + ((total_data["始发跃迁"]["total"] - 1) // 5)) * single_y + char_y = (1 + ((total_data["角色跃迁"]["total"] - 1) // 5)) * single_y + weapon_y = (1 + ((total_data["光锥跃迁"]["total"] - 1) // 5)) * single_y # 获取背景图片各项参数 _id = str(user_id) - if _id.startswith('http'): + if _id.startswith("http"): char_pic = await get_qq_avatar(avatar_url=_id) else: char_pic = await get_qq_avatar(qid=user_id) @@ -326,37 +316,35 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]: # 获取背景图片各项参数 img = Abg3_img.copy() - img = await get_color_bg( - 800, 1600 + 400 + normal_y + char_y + weapon_y + begin_y - ) + img = await get_color_bg(800, 1600 + 400 + normal_y + char_y + weapon_y + begin_y) gacha_title = bg1_img.copy() gacha_title.paste(char_pic, (297, 81), char_pic) img.paste(gacha_title, (0, 0), gacha_title) img_draw = ImageDraw.Draw(img) - img_draw.text((400, 345), f'UID {uid}', white_color, sr_font_28, 'mm') + img_draw.text((400, 345), f"UID {uid}", white_color, sr_font_28, "mm") # 处理title # {'total': 0, 'avg': 0, 'remain': 0, 'list': []} - type_list = ['角色跃迁', '光锥跃迁', '群星跃迁', '始发跃迁'] + type_list = ["角色跃迁", "光锥跃迁", "群星跃迁", "始发跃迁"] y_extend = 0 level = 3 for index, i in enumerate(type_list): - title = Image.open(TEXT_PATH / 'bg2.png') - if i == '群星跃迁': + title = Image.open(TEXT_PATH / "bg2.png") + if i == "群星跃迁": level = await get_level_from_list( - total_data[i]['avg'], [54, 61, 67, 73, 80] + total_data[i]["avg"], [54, 61, 67, 73, 80] ) - elif i == '始发跃迁': + elif i == "始发跃迁": level = await get_level_from_list( - total_data[i]['avg'], [10, 20, 30, 40, 50] + total_data[i]["avg"], [10, 20, 30, 40, 50] ) - elif i == '光锥跃迁': + elif i == "光锥跃迁": level = await get_level_from_list( - total_data[i]['avg_up'], [62, 75, 88, 99, 111] + total_data[i]["avg_up"], [62, 75, 88, 99, 111] ) else: level = await get_level_from_list( - total_data[i]['avg_up'], [74, 87, 99, 105, 120] + total_data[i]["avg_up"], [74, 87, 99, 105, 120] ) emo_pic = await random_emo_pic(level) @@ -364,55 +352,54 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]: title.paste(emo_pic, (500, 123), emo_pic) title_draw = ImageDraw.Draw(title) # 卡池 - title_draw.text((110, 73), i, whole_white_color, sr_font_38, 'lm') + title_draw.text((110, 73), i, whole_white_color, sr_font_38, "lm") # 抽卡时间 - if total_data[i]['time_range']: - time_range = total_data[i]['time_range'] + if total_data[i]["time_range"]: + time_range = total_data[i]["time_range"] else: - time_range = '暂未抽过卡!' - title_draw.text((78, 340), time_range, brown_color, sr_font_20, 'lm') + time_range = "暂未抽过卡!" + title_draw.text((78, 340), time_range, brown_color, sr_font_20, "lm") # 平均抽卡数量 title_draw.text( (143, 215), - str(total_data[i]['avg']), + str(total_data[i]["avg"]), first_color, sr_font_40, - 'mm', + "mm", ) # 平均up title_draw.text( (280, 215), - str(total_data[i]['avg_up']), + str(total_data[i]["avg_up"]), first_color, sr_font_40, - 'mm', + "mm", ) # 抽卡总数 title_draw.text( (413, 215), - str(gacha_data[f'{CHANGE_MAP[i]}_gacha_num']), + str(gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]), first_color, sr_font_40, - 'mm', + "mm", ) # 已抽数 title_draw.text( (333, 75), - str(total_data[i]['remain']), + str(total_data[i]["remain"]), red_color, sr_font_28, - 'mm', + "mm", ) y_extend += ( - (1 + ((total_data[type_list[index - 1]]['total'] - 1) // 5)) - * single_y + (1 + ((total_data[type_list[index - 1]]["total"] - 1) // 5)) * single_y if index != 0 else 0 ) y = 350 + index * 400 + y_extend img.paste(title, (0, y), title) tasks = [] - for item_index, item in enumerate(total_data[i]['list']): + for item_index, item in enumerate(total_data[i]["list"]): item_x = (item_index % 5) * 138 + 25 item_y = (item_index // 5) * single_y + y + 355 xy_point = (item_x, item_y) @@ -420,10 +407,10 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]: _draw_card( img, xy_point, - item['item_type'], - item['name'], - item['gacha_num'], - item['is_up'], + item["item_type"], + item["name"], + item["gacha_num"], + item["is_up"], ) ) await asyncio.gather(*tasks) @@ -431,6 +418,6 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]: # 发送图片 res = await convert_img(img) - logger.info('[查询抽卡]绘图已完成,等待发送!') + logger.info("[查询抽卡]绘图已完成,等待发送!") # res = 123 return res diff --git a/StarRailUID/starrailuid_gachalog/get_gachalogs.py b/StarRailUID/starrailuid_gachalog/get_gachalogs.py index eec5419..630e824 100644 --- a/StarRailUID/starrailuid_gachalog/get_gachalogs.py +++ b/StarRailUID/starrailuid_gachalog/get_gachalogs.py @@ -12,29 +12,27 @@ from ..utils.resource.RESOURCE_PATH import PLAYER_PATH from ..sruid_utils.api.mys.models import SingleGachaLog gacha_type_meta_data = { - '群星跃迁': ['1'], - '始发跃迁': ['2'], - '角色跃迁': ['11'], - '光锥跃迁': ['12'], + "群星跃迁": ["1"], + "始发跃迁": ["2"], + "角色跃迁": ["11"], + "光锥跃迁": ["12"], } async def get_new_gachalog_by_link( uid: str, gacha_url: str, full_data: Dict, is_force: bool ): - full_data = msgspec.convert( - full_data, type=Dict[str, List[SingleGachaLog]] - ) + full_data = msgspec.convert(full_data, type=Dict[str, List[SingleGachaLog]]) temp = [] for gacha_name in gacha_type_meta_data: for gacha_type in gacha_type_meta_data[gacha_name]: - end_id = '0' + end_id = "0" for page in range(1, 999): url = parse.urlparse(gacha_url) url_parse = parse.parse_qs(url.query) - if 'authkey' not in url_parse: + if "authkey" not in url_parse: return {} - authkey = url_parse['authkey'][0] + authkey = url_parse["authkey"][0] data = await mys_api.get_gacha_log_by_link_in_authkey( uid, authkey, gacha_type, page, end_id ) @@ -74,13 +72,13 @@ async def save_gachalogs( # 获取当前时间 now = datetime.now() - current_time = now.strftime('%Y-%m-%d %H-%M-%S') + current_time = now.strftime("%Y-%m-%d %H-%M-%S") # 初始化最后保存的数据 result = {} # 抽卡记录json路径 - gachalogs_path = path / 'gacha_logs.json' + gachalogs_path = path / "gacha_logs.json" # 如果有老的,准备合并, 先打开文件 gachalogs_history = {} @@ -91,19 +89,19 @@ async def save_gachalogs( old_weapon_gacha_num, ) = (0, 0, 0, 0) if gachalogs_path.exists(): - with Path.open(gachalogs_path, encoding='UTF-8') as f: + with Path.open(gachalogs_path, encoding="UTF-8") as f: gachalogs_history: Dict = json.load(f) - gachalogs_history = gachalogs_history['data'] - old_normal_gacha_num = len(gachalogs_history['群星跃迁']) - old_begin_gacha_num = len(gachalogs_history['始发跃迁']) - old_char_gacha_num = len(gachalogs_history['角色跃迁']) - old_weapon_gacha_num = len(gachalogs_history['光锥跃迁']) + gachalogs_history = gachalogs_history["data"] + old_normal_gacha_num = len(gachalogs_history["群星跃迁"]) + old_begin_gacha_num = len(gachalogs_history["始发跃迁"]) + old_char_gacha_num = len(gachalogs_history["角色跃迁"]) + old_weapon_gacha_num = len(gachalogs_history["光锥跃迁"]) else: gachalogs_history = { - '群星跃迁': [], - '始发跃迁': [], - '角色跃迁': [], - '光锥跃迁': [], + "群星跃迁": [], + "始发跃迁": [], + "角色跃迁": [], + "光锥跃迁": [], } # 获取新抽卡记录 @@ -113,69 +111,66 @@ async def save_gachalogs( ) else: new_data = { - '始发跃迁': [], - '群星跃迁': [], - '角色跃迁': [], - '光锥跃迁': [], + "始发跃迁": [], + "群星跃迁": [], + "角色跃迁": [], + "光锥跃迁": [], } if gachalogs_history: - for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']: + for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]: for item in raw_data[i]: - if ( - item not in gachalogs_history[i] - and item not in new_data[i] - ): + if item not in gachalogs_history[i] and item not in new_data[i]: new_data[i].append(item) raw_data = new_data - for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']: + for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]: raw_data[i].extend(gachalogs_history[i]) if raw_data == {} or not raw_data: - return '请给出正确的抽卡记录链接或链接已失效' + return "请给出正确的抽卡记录链接或链接已失效" temp_data = { - '始发跃迁': [], - '群星跃迁': [], - '角色跃迁': [], - '光锥跃迁': [], + "始发跃迁": [], + "群星跃迁": [], + "角色跃迁": [], + "光锥跃迁": [], } - for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']: + for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]: for item in raw_data[i]: if item not in temp_data[i]: temp_data[i].append(item) raw_data = temp_data - result['uid'] = uid - result['data_time'] = current_time - result['normal_gacha_num'] = len(raw_data['群星跃迁']) - result['begin_gacha_num'] = len(raw_data['始发跃迁']) - result['char_gacha_num'] = len(raw_data['角色跃迁']) - result['weapon_gacha_num'] = len(raw_data['光锥跃迁']) - for i in ['群星跃迁', '角色跃迁', '光锥跃迁']: + result["uid"] = uid + result["data_time"] = current_time + result["normal_gacha_num"] = len(raw_data["群星跃迁"]) + result["begin_gacha_num"] = len(raw_data["始发跃迁"]) + result["char_gacha_num"] = len(raw_data["角色跃迁"]) + result["weapon_gacha_num"] = len(raw_data["光锥跃迁"]) + for i in ["群星跃迁", "角色跃迁", "光锥跃迁"]: if len(raw_data[i]) > 1: raw_data[i].sort(key=lambda x: (-int(x.id))) - result['data'] = raw_data + result["data"] = raw_data # 计算数据 - normal_add = result['normal_gacha_num'] - old_normal_gacha_num - begin_gacha_add = result['begin_gacha_num'] - old_begin_gacha_num - char_add = result['char_gacha_num'] - old_char_gacha_num - weapon_add = result['weapon_gacha_num'] - old_weapon_gacha_num + normal_add = result["normal_gacha_num"] - old_normal_gacha_num + begin_gacha_add = result["begin_gacha_num"] - old_begin_gacha_num + char_add = result["char_gacha_num"] - old_char_gacha_num + weapon_add = result["weapon_gacha_num"] - old_weapon_gacha_num all_add = normal_add + char_add + weapon_add + begin_gacha_add # 保存文件 result = msgspec.to_builtins(result) - with Path.open(gachalogs_path, 'w', encoding='UTF-8') as file: + with Path.open(gachalogs_path, "w", encoding="UTF-8") as file: json.dump(result, file, indent=2, ensure_ascii=False) # 回复文字 if all_add == 0: - im = f'UID{uid}没有新增祈愿数据!' + im = f"UID{uid}没有新增祈愿数据!" else: im = ( - f'UID{uid}数据更新成功!' - f'本次更新{all_add}个数据\n' - f'群星跃迁{normal_add}个\n始发跃迁{begin_gacha_add}\n' - f'角色跃迁{char_add}个\n光锥跃迁{weapon_add}个!' + f"UID{uid}数据更新成功!" + f"本次更新{all_add}个数据\n" + f"群星跃迁{normal_add}个\n始发跃迁{begin_gacha_add}\n" + f"角色跃迁{char_add}个\n光锥跃迁{weapon_add}个!" ) return im diff --git a/StarRailUID/starrailuid_help/__init__.py b/StarRailUID/starrailuid_help/__init__.py index c09580a..10ffe0a 100644 --- a/StarRailUID/starrailuid_help/__init__.py +++ b/StarRailUID/starrailuid_help/__init__.py @@ -6,11 +6,11 @@ from gsuid_core.logger import logger from .get_help import get_core_help from ..utils.sr_prefix import PREFIX -sv_sr_help = SV('sr帮助') +sv_sr_help = SV("sr帮助") -@sv_sr_help.on_fullmatch(f'{PREFIX}帮助') +@sv_sr_help.on_fullmatch(f"{PREFIX}帮助") async def send_help_img(bot: Bot, ev: Event): - logger.info('开始执行[sr帮助]') + logger.info("开始执行[sr帮助]") im = await get_core_help() await bot.send(im) diff --git a/StarRailUID/starrailuid_help/get_help.py b/StarRailUID/starrailuid_help/get_help.py index e4f7313..7f5d7fe 100644 --- a/StarRailUID/starrailuid_help/get_help.py +++ b/StarRailUID/starrailuid_help/get_help.py @@ -10,32 +10,30 @@ from gsuid_core.help.draw_plugin_help import get_help from ..version import StarRail_version from ..utils.fonts.starrail_fonts import starrail_font_origin -TEXT_PATH = Path(__file__).parent / 'texture2d' -HELP_DATA = Path(__file__).parent / 'Help.json' +TEXT_PATH = Path(__file__).parent / "texture2d" +HELP_DATA = Path(__file__).parent / "Help.json" async def get_help_data() -> Optional[Dict[str, PluginHelp]]: if HELP_DATA.exists(): - async with aiofiles.open(HELP_DATA, 'rb') as file: - return msgjson.decode( - await file.read(), type=Dict[str, PluginHelp] - ) + async with aiofiles.open(HELP_DATA, "rb") as file: + return msgjson.decode(await file.read(), type=Dict[str, PluginHelp]) return None async def get_core_help() -> Union[bytes, str]: help_data = await get_help_data() if help_data is None: - return '暂未找到帮助数据...' + return "暂未找到帮助数据..." return await get_help( - 'StarRailUID', - f'版本号:{StarRail_version}', + "StarRailUID", + f"版本号:{StarRail_version}", help_data, - Image.open(TEXT_PATH / 'bg.jpg'), - Image.open(TEXT_PATH / 'ICON.png'), - Image.open(TEXT_PATH / 'badge.png'), - Image.open(TEXT_PATH / 'banner.png'), - Image.open(TEXT_PATH / 'button.png'), + Image.open(TEXT_PATH / "bg.jpg"), + Image.open(TEXT_PATH / "ICON.png"), + Image.open(TEXT_PATH / "badge.png"), + Image.open(TEXT_PATH / "banner.png"), + Image.open(TEXT_PATH / "button.png"), starrail_font_origin, ) diff --git a/StarRailUID/starrailuid_note/__init__.py b/StarRailUID/starrailuid_note/__init__.py index 83134b3..4b4442d 100644 --- a/StarRailUID/starrailuid_note/__init__.py +++ b/StarRailUID/starrailuid_note/__init__.py @@ -1,21 +1,21 @@ -from gsuid_core.sv import SV +from .draw_note_card import draw_note_img +from .note_text import award +from ..utils.error_reply import UID_HINT +from ..utils.sr_prefix import PREFIX + from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid from gsuid_core.utils.database.models import GsBind -from .note_text import award -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from ..utils.error_reply import UID_HINT -from .draw_note_card import draw_note_img - -sv_get_monthly_data = SV('sr查询月历') +sv_get_monthly_data = SV("sr查询月历") # 群聊内 每月统计 功能 -@sv_get_monthly_data.on_fullmatch(f'{PREFIX}每月统计') +@sv_get_monthly_data.on_fullmatch(f"{PREFIX}每月统计") async def send_monthly_data(bot: Bot, ev: Event): - sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr') + sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, "sr") if sr_uid is None: return UID_HINT await bot.send(await award(sr_uid)) @@ -24,14 +24,14 @@ async def send_monthly_data(bot: Bot, ev: Event): @sv_get_monthly_data.on_fullmatch( ( - f'{PREFIX}开拓月历', - f'{PREFIX}zj', - f'{PREFIX}月历', + f"{PREFIX}开拓月历", + f"{PREFIX}zj", + f"{PREFIX}月历", ) ) async def send_monthly_pic(bot: Bot, ev: Event): - await bot.logger.info('开始执行[sr开拓月历]') - sr_uid = await get_uid(bot, ev) + await bot.logger.info("开始执行[sr开拓月历]") + sr_uid = await get_uid(bot, ev, GsBind, "sr") if sr_uid is None: return UID_HINT im = await draw_note_img(str(sr_uid)) diff --git a/StarRailUID/starrailuid_note/draw_note_card.py b/StarRailUID/starrailuid_note/draw_note_card.py index 6c62dd0..28081e3 100644 --- a/StarRailUID/starrailuid_note/draw_note_card.py +++ b/StarRailUID/starrailuid_note/draw_note_card.py @@ -1,23 +1,23 @@ +from datetime import datetime import json from pathlib import Path from typing import Union -from datetime import datetime from PIL import Image, ImageDraw -from msgspec import json as msgjson from gsuid_core.logger import logger +from gsuid_core.utils.image.convert import convert_img +from msgspec import json as msgjson -from ..utils.mys_api import mys_api -from ..utils.error_reply import get_error -from ..utils.image.convert import convert_img from ..sruid_utils.api.mys.models import MonthlyAward -from ..utils.resource.RESOURCE_PATH import PLAYER_PATH +from ..utils.error_reply import get_error from ..utils.fonts.starrail_fonts import sr_font_20, sr_font_28, sr_font_34 +from ..utils.mys_api import mys_api +from ..utils.resource.RESOURCE_PATH import PLAYER_PATH -TEXT_PATH = Path(__file__).parent / 'texture2d' +TEXT_PATH = Path(__file__).parent / "texture2d" -monthly_bg = Image.open(TEXT_PATH / 'monthly_bg.png') -avatar_default = Image.open(TEXT_PATH / '200101.png') +monthly_bg = Image.open(TEXT_PATH / "monthly_bg.png") +avatar_default = Image.open(TEXT_PATH / "200101.png") first_color = (29, 29, 29) second_color = (67, 61, 56) @@ -26,20 +26,20 @@ black_color = (54, 54, 54) white_color = (213, 213, 213) COLOR_MAP = { - '每日活跃': (248, 227, 157), - '活动奖励': (99, 231, 176), - '冒险奖励': (114, 205, 251), - '模拟宇宙奖励': (160, 149, 248), - '忘却之庭奖励': (221, 119, 250), - '邮件奖励': (244, 110, 104), - '其他': (255, 242, 200), - 'Daily Activity': (248, 227, 157), - 'Events': (99, 231, 176), - 'Adventure': (114, 205, 251), - 'moni': (160, 149, 248), - 'Spiral Abyss': (221, 119, 250), - 'Quests': (244, 110, 104), - 'Other': (255, 242, 200), + "每日活跃": (248, 227, 157), + "活动奖励": (99, 231, 176), + "冒险奖励": (114, 205, 251), + "模拟宇宙奖励": (160, 149, 248), + "忘却之庭奖励": (221, 119, 250), + "邮件奖励": (244, 110, 104), + "其他": (255, 242, 200), + "Daily Activity": (248, 227, 157), + "Events": (99, 231, 176), + "Adventure": (114, 205, 251), + "moni": (160, 149, 248), + "Spiral Abyss": (221, 119, 250), + "Quests": (244, 110, 104), + "Other": (255, 242, 200), } @@ -50,25 +50,25 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: # 获取当前时间 now = datetime.now() - current_year_mon = now.strftime('%Y-%m') - add_month = '' + current_year_mon = now.strftime("%Y-%m") + add_month = "" if int(now.month) < 10: - add_month = '0' + add_month = "0" now_month = str(now.year) + str(add_month) + str(now.month) # 获取数据 - data = await mys_api.get_award(sr_uid, now_month) + data = await mys_api.get_sr_award(sr_uid, now_month) if isinstance(data, int): return get_error(data) # 保存数据 with Path.open( - path / f'monthly_{current_year_mon}.json', 'w', encoding='utf-8' + path / f"monthly_{current_year_mon}.json", "w", encoding="utf-8" ) as f: save_json_data = msgjson.format(msgjson.encode(data), indent=4) save_data = json.dumps( { - 'data_time': now.strftime('%Y-%m-%d %H:%M:%S'), - 'data': save_json_data.decode('utf-8'), + "data_time": now.strftime("%Y-%m-%d %H:%M:%S"), + "data": save_json_data.decode("utf-8"), }, ensure_ascii=False, ) @@ -80,33 +80,31 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: if last_month == 0: last_month = 12 last_year -= 1 - last_year_mon = f'{last_year}-{last_month:02d}' - last_monthly_path = path / f'monthly_{last_year_mon}.json' + last_year_mon = f"{last_year}-{last_month:02d}" + last_monthly_path = path / f"monthly_{last_year_mon}.json" if last_monthly_path.exists(): - with Path.open(last_monthly_path, encoding='utf-8') as f: + with Path.open(last_monthly_path, encoding="utf-8") as f: last_monthly_data = json.load(f) last_monthly_data = msgjson.decode( - last_monthly_data['data'], type=MonthlyAward + last_monthly_data["data"], type=MonthlyAward ) else: - add_month = '' + add_month = "" if int(last_month) < 10: - add_month = '0' + add_month = "0" find_last_month = str(last_year) + str(add_month) + str(last_month) - last_monthly_data = await mys_api.get_award(sr_uid, find_last_month) + last_monthly_data = await mys_api.get_sr_award(sr_uid, find_last_month) if isinstance(last_monthly_data, int): return get_error(last_monthly_data) # 保存上月数据 with Path.open( - path / f'monthly_{last_year_mon}.json', 'w', encoding='utf-8' + path / f"monthly_{last_year_mon}.json", "w", encoding="utf-8" ) as f: - save_json_data = msgjson.format( - msgjson.encode(last_monthly_data), indent=4 - ) + save_json_data = msgjson.format(msgjson.encode(last_monthly_data), indent=4) save_data = json.dumps( { - 'data_time': now.strftime('%Y-%m-%d %H:%M:%S'), - 'data': save_json_data.decode('utf-8'), + "data_time": now.strftime("%Y-%m-%d %H:%M:%S"), + "data": save_json_data.decode("utf-8"), }, ensure_ascii=False, ) @@ -141,7 +139,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: img = monthly_bg.copy() avatar_img = avatar_default.copy() - char_pic = avatar_img.convert('RGBA').resize( + char_pic = avatar_img.convert("RGBA").resize( (125, 125), Image.Resampling.LANCZOS, # type: ignore ) @@ -149,17 +147,15 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: img_draw = ImageDraw.Draw(img) # 写Nickname - img_draw.text( - (310, 184), nickname, font=sr_font_34, fill=first_color, anchor='lm' - ) + img_draw.text((310, 184), nickname, font=sr_font_34, fill=first_color, anchor="lm") # 写UID img_draw.text( (267, 219), - f'UID {sr_uid}', + f"UID {sr_uid}", font=sr_font_20, fill=second_color2, - anchor='lm', + anchor="lm", ) # 写本日星琼 @@ -168,7 +164,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: day_hcoin_str, font=sr_font_28, fill=white_color, - anchor='lm', + anchor="lm", ) # 写本月星琼 @@ -177,7 +173,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: month_hcoin_str, font=sr_font_28, fill=white_color, - anchor='lm', + anchor="lm", ) # 写昨日星琼 @@ -186,7 +182,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: lastday_hcoin_str, font=sr_font_28, fill=black_color, - anchor='lm', + anchor="lm", ) # 写上月星琼 @@ -195,7 +191,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: lastmonth_hcoin_str, font=sr_font_28, fill=black_color, - anchor='lm', + anchor="lm", ) # 写本日铁票 @@ -204,7 +200,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: day_rails_pass_str, font=sr_font_28, fill=white_color, - anchor='lm', + anchor="lm", ) # 写本月铁票 @@ -213,7 +209,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: month_rails_pass_str, font=sr_font_28, fill=white_color, - anchor='lm', + anchor="lm", ) # 写昨日铁票 @@ -222,7 +218,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: lastday_rails_pass_str, font=sr_font_28, fill=black_color, - anchor='lm', + anchor="lm", ) # 写上月铁票 @@ -231,16 +227,16 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: lastmonth_rails_pass_str, font=sr_font_28, fill=black_color, - anchor='lm', + anchor="lm", ) xy = ((0, 0), (2100, 2100)) temp = -90 if not data.month_data.group_by: - pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0)) + pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0)) pie_image_draw = ImageDraw.Draw(pie_image) pie_image_draw.ellipse(xy, fill=(128, 128, 128)) else: - pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0)) + pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0)) pie_image_draw = ImageDraw.Draw(pie_image) for _index, i in enumerate(data.month_data.group_by): pie_image_draw.pieslice( @@ -251,7 +247,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: ) temp = temp + (i.percent / 100) * 360 # 绘制蒙版圆形 - new_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0)) + new_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0)) pie_image_draw.ellipse((150, 150, 1950, 1950), fill=(255, 255, 255, 0)) position = (1050, 1050) @@ -260,7 +256,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: img.paste(result_pie, (138, 618), result_pie) if last_monthly_data: - pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0)) + pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0)) pie_image_draw = ImageDraw.Draw(pie_image) for _index, i in enumerate(last_monthly_data.month_data.group_by): pie_image_draw.pieslice( @@ -271,12 +267,12 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: ) temp = temp + (i.percent / 100) * 360 else: - pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0)) + pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0)) pie_image_draw = ImageDraw.Draw(pie_image) pie_image_draw.ellipse(xy, fill=(128, 128, 128)) # 绘制蒙版圆形 - new_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0)) + new_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0)) pie_image_draw.ellipse((150, 150, 1950, 1950), fill=(255, 255, 255, 0)) position = (1050, 1050) @@ -285,13 +281,13 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]: img.paste(result_pie, (138, 618 + 350), result_pie) img = await convert_img(img) - logger.info('[开拓月历] 图片绘制完成!等待发送...') + logger.info("[开拓月历] 图片绘制完成!等待发送...") return img async def int_carry(i: int) -> str: if i >= 100000: - i_str = f'{i / 10000:.1f}W' + i_str = f"{i / 10000:.1f}W" else: i_str = str(i) return i_str diff --git a/StarRailUID/starrailuid_note/note_text.py b/StarRailUID/starrailuid_note/note_text.py index 4bfc61c..16f224c 100644 --- a/StarRailUID/starrailuid_note/note_text.py +++ b/StarRailUID/starrailuid_note/note_text.py @@ -1,7 +1,7 @@ from datetime import datetime -from ..utils.mys_api import mys_api from ..utils.error_reply import get_error +from ..utils.mys_api import mys_api month_im = """============== SR_UID:{} @@ -24,7 +24,7 @@ SR_UID:{} async def award(uid) -> str: # 获取当前的月份 - data = await mys_api.get_award(uid, datetime.now().month) + data = await mys_api.get_sr_award(uid, datetime.now().month) if isinstance(data, int): return get_error(data) day_hcoin = data.day_data.current_hcoin @@ -38,17 +38,17 @@ async def award(uid) -> str: month_rails_pass = data.month_data.current_rails_pass lastmonth_stone = data.month_data.last_hcoin lastmonth_rails_pass = data.month_data.last_rails_pass - group_str = '' + group_str = "" for i in data.month_data.group_by: group_str = ( group_str + i.action_name - + ':' + + ":" + str(i.num) - + '(' + + "(" + str(i.percent) - + '%)' - + '\n' + + "%)" + + "\n" ) return month_im.format( diff --git a/StarRailUID/starrailuid_resource/__init__.py b/StarRailUID/starrailuid_resource/__init__.py index 55df6fc..33cdea6 100644 --- a/StarRailUID/starrailuid_resource/__init__.py +++ b/StarRailUID/starrailuid_resource/__init__.py @@ -6,18 +6,16 @@ from gsuid_core.logger import logger from ..utils.sr_prefix import PREFIX from ..utils.resource.download_from_cos import check_use -sv_sr_download_config = SV('sr下载资源', pm=1) +sv_sr_download_config = SV("sr下载资源", pm=1) -@sv_sr_download_config.on_fullmatch(f'{PREFIX}下载全部资源') +@sv_sr_download_config.on_fullmatch(f"{PREFIX}下载全部资源") async def send_download_resource_msg(bot: Bot, ev: Event): - await bot.send('sr正在开始下载~可能需要较久的时间!') + await bot.send("sr正在开始下载~可能需要较久的时间!") im = await check_use() await bot.send(im) async def startup(): - logger.info( - '[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等' - ) - logger.info(f'[sr资源文件下载] {await check_use()}') + logger.info("[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等") + logger.info(f"[sr资源文件下载] {await check_use()}") diff --git a/StarRailUID/starrailuid_rogue/__init__.py b/StarRailUID/starrailuid_rogue/__init__.py index 2b31ecf..cc22f74 100644 --- a/StarRailUID/starrailuid_rogue/__init__.py +++ b/StarRailUID/starrailuid_rogue/__init__.py @@ -1,95 +1,90 @@ -import re - -from gsuid_core.sv import SV -from gsuid_core.bot import Bot -from gsuid_core.models import Event -from gsuid_core.utils.error_reply import UID_HINT - -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX -from .draw_rogue_card import draw_rogue_img, draw_rogue_locust_img - -sv_srabyss = SV('sr查询模拟宇宙') -sv_srabyss_locust = SV('sr查询寰宇蝗灾') - - -@sv_srabyss.on_command( - ( - f'{PREFIX}查询宇宙', - f'{PREFIX}yz', - f'{PREFIX}查询上期宇宙', - f'{PREFIX}sqyz', - f'{PREFIX}上期宇宙', - f'{PREFIX}宇宙', - f'{PREFIX}查询模拟宇宙', - f'{PREFIX}上期模拟宇宙', - f'{PREFIX}查询上期模拟宇宙', - ), - block=True, -) -async def send_srabyss_info(bot: Bot, ev: Event): - name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text)) - if name: - return None - - await bot.logger.info('开始执行[sr查询模拟宇宙信息]') - 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 await bot.send(UID_HINT) - await bot.logger.info(f'[sr查询模拟宇宙信息]uid: {uid}') - - if 'sq' in ev.command or '上期' in ev.command: - schedule_type = '2' - else: - schedule_type = '3' - await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}') - - if ev.text in ['一', '二', '三', '四', '五', '六']: - floor = ( - ev.text.replace('一', '1') - .replace('二', '2') - .replace('三', '3') - .replace('四', '4') - .replace('五', '5') - .replace('六', '6') - ) - else: - floor = ev.text - if floor and floor.isdigit(): - floor = int(floor) - else: - floor = None - await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}') - im = await draw_rogue_img(user_id, uid, ev.sender, floor, schedule_type) - await bot.send(im) - return None - - -@sv_srabyss_locust.on_command( - ( - f'{PREFIX}寰宇蝗灾', - f'{PREFIX}hyhz', - f'{PREFIX}查询寰宇蝗灾', - f'{PREFIX}sqhyhz', - ), - block=True, -) -async def send_srabyss_locust_info(bot: Bot, ev: Event): - name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text)) - if name: - return None - - await bot.logger.info('开始执行[sr查询寰宇蝗灾信息]') - 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 await bot.send(UID_HINT) - await bot.logger.info(f'[sr查询寰宇蝗灾信息]uid: {uid}') - im = await draw_rogue_locust_img(user_id, uid, ev.sender) - await bot.send(im) - return None +import re + +from .draw_rogue_card import draw_rogue_img, draw_rogue_locust_img +from ..utils.sr_prefix import PREFIX + +from gsuid_core.bot import Bot +from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind +from gsuid_core.utils.error_reply import UID_HINT + +sv_srabyss = SV("sr查询模拟宇宙") +sv_srabyss_locust = SV("sr查询寰宇蝗灾") + + +@sv_srabyss.on_command( + ( + f"{PREFIX}查询宇宙", + f"{PREFIX}yz", + f"{PREFIX}查询上期宇宙", + f"{PREFIX}sqyz", + f"{PREFIX}上期宇宙", + f"{PREFIX}宇宙", + f"{PREFIX}查询模拟宇宙", + f"{PREFIX}上期模拟宇宙", + f"{PREFIX}查询上期模拟宇宙", + ), + block=True, +) +async def send_srabyss_info(bot: Bot, ev: Event): + name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text)) + if name: + return None + + await bot.logger.info("开始执行[sr查询模拟宇宙信息]") + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) + if uid is None: + return await bot.send(UID_HINT) + await bot.logger.info(f"[sr查询模拟宇宙信息]uid: {uid}") + + if "sq" in ev.command or "上期" in ev.command: + schedule_type = "2" + else: + schedule_type = "3" + await bot.logger.info(f"[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}") + + if ev.text in ["一", "二", "三", "四", "五", "六"]: + floor = ( + ev.text.replace("一", "1") + .replace("二", "2") + .replace("三", "3") + .replace("四", "4") + .replace("五", "5") + .replace("六", "6") + ) + else: + floor = ev.text + if floor and floor.isdigit(): + floor = int(floor) + else: + floor = None + await bot.logger.info(f"[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}") + im = await draw_rogue_img(user_id, uid, ev.sender, floor, schedule_type) + await bot.send(im) + return None + + +@sv_srabyss_locust.on_command( + ( + f"{PREFIX}寰宇蝗灾", + f"{PREFIX}hyhz", + f"{PREFIX}查询寰宇蝗灾", + f"{PREFIX}sqhyhz", + ), + block=True, +) +async def send_srabyss_locust_info(bot: Bot, ev: Event): + name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text)) + if name: + return None + + await bot.logger.info("开始执行[sr查询寰宇蝗灾信息]") + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) + if uid is None: + return await bot.send(UID_HINT) + await bot.logger.info(f"[sr查询寰宇蝗灾信息]uid: {uid}") + im = await draw_rogue_locust_img(user_id, uid, ev.sender) + await bot.send(im) + return None diff --git a/StarRailUID/starrailuid_rogue/draw_rogue_card.py b/StarRailUID/starrailuid_rogue/draw_rogue_card.py index e739c29..c2af269 100644 --- a/StarRailUID/starrailuid_rogue/draw_rogue_card.py +++ b/StarRailUID/starrailuid_rogue/draw_rogue_card.py @@ -1,846 +1,822 @@ -import math -from pathlib import Path -from typing import List, Union, Optional - -from PIL import Image, ImageDraw -from gsuid_core.logger import logger -from gsuid_core.utils.error_reply import get_error -from gsuid_core.utils.image.image_tools import ( - get_qq_avatar, - draw_pic_with_ring, -) - -from .utils import get_icon -from ..utils.mys_api import mys_api -from ..utils.image.convert import convert_img -from ..utils.fonts.starrail_fonts import ( - sr_font_22, - sr_font_28, - sr_font_34, - sr_font_42, -) -from ..sruid_utils.api.mys.models import ( - RogueAvatar, - LocustBlocks, - RogueMiracles, - RogueBuffitems, -) - -TEXT_PATH = Path(__file__).parent / 'texture2D' -white_color = (255, 255, 255) -gray_color = (175, 175, 175) -img_bg = Image.open(TEXT_PATH / 'bg.jpg') -level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA') -char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA') -char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA') -rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA') -content_center = Image.open(TEXT_PATH / 'center.png').convert('RGBA') - -elements = { - 'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'), - 'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'), - 'imaginary': Image.open( - TEXT_PATH / 'IconNatureColorImaginary.png' - ).convert('RGBA'), - 'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert( - 'RGBA' - ), - 'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert( - 'RGBA' - ), - 'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'), - 'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert( - 'RGBA' - ), -} - -progresslist = { - 1: '第一世界', - 2: '第二世界', - 3: '第三世界', - 4: '第四世界', - 5: '第五世界', - 6: '第六世界', - 7: '第七世界', - 8: '第八世界', -} - -difficultylist = { - 1: 'I', - 2: 'Ⅱ', - 3: 'Ⅲ', - 4: 'Ⅳ', - 5: 'V', - 6: 'Ⅵ', - 7: 'Ⅶ', - 8: 'Ⅷ', -} - -bufflist = { - 120: '存护', - 121: '记忆', - 122: '虚无', - 123: '丰饶', - 124: '巡猎', - 125: '毁灭', - 126: '欢愉', - 127: '繁育', -} - - -async def get_abyss_star_pic(star: int) -> Image.Image: - return Image.open(TEXT_PATH / f'star{star}.png') - - -async def _draw_rogue_buff( - buffs: List[RogueBuffitems], - buff_icon: str, - buff_name: str, - floor_pic: Image.Image, - buff_height: int, -): - draw_height = 0 - floor_pic_draw = ImageDraw.Draw(floor_pic) - buff_icon_img = Image.open(TEXT_PATH / f'{buff_icon}.png') - buff_icon_img = buff_icon_img.resize((40, 40)) - floor_pic.paste(buff_icon_img, (95, 400 + buff_height), buff_icon_img) - floor_pic_draw.text( - (140, 425 + buff_height), - f'{buff_name}:', - font=sr_font_28, - fill=gray_color, - anchor='lm', - ) - draw_height = draw_height + 40 - buff_num = len(buffs) - need_middle = math.ceil(buff_num / 3) - draw_height = draw_height + need_middle * 55 - zb_list = [] - for m in range(need_middle): - for n in range(3): - zb_list.append([m, n]) - jishu = 0 - for item in buffs: - if item.is_evoluted is True: - is_evoluted = 1 - else: - is_evoluted = 0 - buff_bg = Image.open( - TEXT_PATH / f'zhufu_{item.rank}_{is_evoluted}.png' - ) - buff_bg = buff_bg.resize((233, 35)) - z_left = 90 + 240 * zb_list[jishu][1] - z_top = buff_height + 450 + 55 * zb_list[jishu][0] - jishu = jishu + 1 - floor_pic.paste(buff_bg, (z_left, z_top), mask=buff_bg) - floor_pic_draw.text( - (z_left + 115, z_top + 18), - item.name, - font=sr_font_22, - fill=white_color, - anchor='mm', - ) - return draw_height - - -async def _draw_rogue_blocks( - blocks: List[LocustBlocks], - floor_pic: Image.Image, - buff_height: int, -): - draw_height = 0 - floor_pic_draw = ImageDraw.Draw(floor_pic) - blocks_num = len(blocks) - need_middle = math.ceil(blocks_num / 2) - draw_height = draw_height + need_middle * 80 - zb_list = [] - for m in range(need_middle): - for n in range(2): - zb_list.append([m, n]) - jishu = 0 - for block in blocks: - block_icon = Image.open(TEXT_PATH / f'{block.name}.png') - z_left_bg = 90 + 357 * zb_list[jishu][1] - z_top_bg = buff_height + 470 + 80 * zb_list[jishu][0] - jishu = jishu + 1 - z_left_icon = z_left_bg + 10 - z_top_icon = z_top_bg + 5 - floor_pic.paste(block_icon, (z_left_icon, z_top_icon), mask=block_icon) - floor_pic_draw.text( - (z_left_bg + 80, z_top_bg + 35), - f'{block.name} x{block.num}', - font=sr_font_22, - fill=white_color, - anchor='lm', - ) - return draw_height - - -async def _draw_rogue_miracles( - miracles: List[RogueMiracles], - floor_pic: Image.Image, - buff_height: int, -): - draw_height = 0 - miracles_num = len(miracles) - need_middle = math.ceil(miracles_num / 8) - draw_height = draw_height + need_middle * 90 - zb_list = [] - for m in range(need_middle): - for n in range(8): - zb_list.append([m, n]) - jishu = 0 - for miracle in miracles: - miracles_icon = (await get_icon(miracle.icon)).resize((80, 80)) - z_left = 90 + 90 * zb_list[jishu][1] - z_top = buff_height + 470 + 90 * zb_list[jishu][0] - jishu = jishu + 1 - floor_pic.paste(miracles_icon, (z_left, z_top), mask=miracles_icon) - - return draw_height - - -async def _draw_rogue_card( - char: RogueAvatar, - talent_num: str, - floor_pic: Image.Image, - index_char: int, -): - # char_id = char['id'] - # # 确认角色头像路径 - # char_pic_path = CHAR_ICON_PATH / f'{char_id}.png' - char_bg = (char_bg_4 if char.rarity == 4 else char_bg_5).copy() - char_icon = (await get_icon(char.icon)).resize((151, 170)) - element_icon = elements[char.element] - char_bg.paste(char_icon, (24, 16), mask=char_icon) - char_bg.paste(level_cover, (0, 0), mask=level_cover) - char_bg.paste(element_icon, (35, 25), mask=element_icon) - # 不存在自动下载 - # if not char_pic_path.exists(): - # await create_single_char_card(char_id) - # talent_pic = await get_talent_pic(int(talent_num)) - # talent_pic = talent_pic.resize((90, 45)) - # char_card.paste(talent_pic, (137, 260), talent_pic) - char_card_draw = ImageDraw.Draw(char_bg) - if char.rank > 0: - char_bg.paste(rank_bg, (150, 16), mask=rank_bg) - char_card_draw.text( - (162, 31), - f'{char.rank}', - font=sr_font_22, - fill=white_color, - anchor='mm', - ) - char_card_draw.text( - (100, 165), - f'等级 {char.level}', - font=sr_font_22, - fill=white_color, - anchor='mm', - ) - floor_pic.paste( - char_bg, - (75 + 185 * index_char, 130), - char_bg, - ) - - -async def draw_rogue_img( - qid: Union[str, int], - uid: str, - sender: Union[str, str], - floor: Optional[int] = None, - schedule_type: str = '3', -) -> Union[bytes, str]: - raw_rogue_data = await mys_api.get_rogue_info(uid, '3') - - if isinstance(raw_rogue_data, int): - return get_error(raw_rogue_data) - - # 计算背景图尺寸 - if schedule_type == '3': - rogue_detail = raw_rogue_data.current_record.records - else: - rogue_detail = raw_rogue_data.last_record.records - - # 记录打的宇宙列表 - detail_list = [] - based_h = 700 - detail_h_list = [] - based_h_list = [] - for detail in rogue_detail: - # 100+70+170 - # 头+底+角色 - detail_h = 340 - progress = detail.progress - detail_list.append(progress) - # 祝福 - if len(detail.base_type_list) > 0: - buff_h = 60 - for buff in detail.buffs: - buff_h = buff_h + 50 - buff_num = len(buff.items) - buff_h = buff_h + math.ceil(buff_num / 3) * 55 - else: - buff_h = 0 - detail_h = detail_h + buff_h - - # 奇物 - if len(detail.miracles) > 0: - miracles_h = 60 - miracles_num = len(detail.miracles) - miracles_h = miracles_h + math.ceil(miracles_num / 8) * 90 - else: - miracles_h = 0 - detail_h = detail_h + miracles_h - detail_h_list.append(detail_h) - based_h_list.append(based_h) - if floor: - if progress == floor: - pass - else: - detail_h = 0 - based_h = based_h + detail_h - - # 获取查询者数据 - if floor: - if floor > 8: - return '世界不能大于第八世界!' - if floor not in detail_list: - return '你还没有挑战该模拟宇宙!' - elif schedule_type == '3': - if raw_rogue_data.current_record.basic.finish_cnt == 0: - return '你还没有挑战本期模拟宇宙!\n可以使用[sr上期模拟宇宙]命令查询上期~' - elif raw_rogue_data.last_record.basic.finish_cnt == 0: - return '你还没有挑战上期模拟宇宙!\n可以使用[sr模拟宇宙]命令查询本期~' - - # 获取背景图片各项参数 - based_w = 900 - img = Image.new('RGB', (based_w, based_h), (10, 18, 49)) - img.paste(img_bg, (0, 0)) - # img = img.crop((0, 0, based_w, based_h)) - rogue_title = Image.open(TEXT_PATH / 'head.png') - img.paste(rogue_title, (0, 0), rogue_title) - - # 获取头像 - _id = str(qid) - if _id.startswith('http'): - char_pic = await get_qq_avatar(avatar_url=_id) - elif sender.get('avatar') is not None: - char_pic = await get_qq_avatar(avatar_url=sender['avatar']) - else: - char_pic = await get_qq_avatar(qid=qid) - char_pic = await draw_pic_with_ring(char_pic, 250, None, False) - - img.paste(char_pic, (325, 132), char_pic) - - # 绘制抬头 - img_draw = ImageDraw.Draw(img) - img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm') - - # 总体数据 - rogue_data = Image.open(TEXT_PATH / 'data.png') - img.paste(rogue_data, (0, 500), rogue_data) - - # 技能树激活 - img_draw.text( - (165, 569), - f'{raw_rogue_data.basic_info.unlocked_skill_points}', - white_color, - sr_font_42, - 'mm', - ) - img_draw.text( - (165, 615), - '已激活技能树', - gray_color, - sr_font_28, - 'mm', - ) - - # 奇物解锁 - img_draw.text( - (450, 569), - f'{raw_rogue_data.basic_info.unlocked_miracle_num}', - white_color, - sr_font_42, - 'mm', - ) - img_draw.text( - (450, 615), - '已解锁奇物', - gray_color, - sr_font_28, - 'mm', - ) - - # 祝福解锁 - img_draw.text( - (730, 569), - f'{raw_rogue_data.basic_info.unlocked_buff_num}', - white_color, - sr_font_42, - 'mm', - ) - img_draw.text( - (730, 615), - '已解锁祝福', - gray_color, - sr_font_28, - 'mm', - ) - - for index_floor, detail in enumerate(rogue_detail): - if floor: - if floor == detail.progress: - index_floor = 0 # noqa: PLW2901 - else: - continue - - if detail_h_list[index_floor] is None: - continue - - floor_pic = Image.open(TEXT_PATH / 'detail_bg.png').convert('RGBA') - floor_pic = floor_pic.resize((900, detail_h_list[index_floor])) - - floor_top_pic = Image.open(TEXT_PATH / 'floor_bg_top.png').convert( - 'RGBA' - ) - floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic) - - floor_center_pic = Image.open( - TEXT_PATH / 'floor_bg_center.png' - ).convert('RGBA') - floor_center_pic = floor_center_pic.resize( - (900, detail_h_list[index_floor] - 170) - ) - floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic) - - floor_bot_pic = Image.open(TEXT_PATH / 'floor_bg_bot.png').convert( - 'RGBA' - ) - floor_pic.paste( - floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic - ) - - floor_name = progresslist[detail.progress] - difficulty_name = difficultylist[detail.difficulty] - - time_array = detail.finish_time - time_str = f'{time_array.year}-{time_array.month}' - time_str = f'{time_str}-{time_array.day}' - time_str = f'{time_str} {time_array.hour}:{time_array.minute}' - floor_pic_draw = ImageDraw.Draw(floor_pic) - floor_pic_draw.text( - (450, 60), - f'{floor_name} {difficulty_name}', - white_color, - sr_font_42, - 'mm', - ) - floor_pic_draw.text( - (93, 120), - f'挑战时间:{time_str}', - gray_color, - sr_font_22, - 'lm', - ) - floor_pic_draw.text( - (800, 120), - f'当前积分:{detail.score}', - gray_color, - sr_font_22, - 'rm', - ) - - # 角色 - for index_char, char in enumerate(detail.final_lineup): - # 获取命座 - # if char["id"] in char_temp: - # talent_num = char_temp[char["id"]] - # else: - # for i in char_data: - # if i["id"] == char["id"]: - # talent_num = str( - # i["actived_constellation_num"] - # ) - # char_temp[char["id"]] = talent_num - # break - await _draw_rogue_card( - char, - 0, # type: ignore - floor_pic, - index_char, - ) - - # 祝福 - buff_height = 0 - if len(detail.base_type_list) > 0: - floor_pic_draw.text( - (93, 370), - '获得祝福', - white_color, - sr_font_34, - 'lm', - ) - floor_pic.paste(content_center, (0, 390), content_center) - for buff in detail.buffs: - buff_icon = bufflist[buff.base_type.id] - buff_name = buff.base_type.name - buffs = buff.items - draw_height = await _draw_rogue_buff( - buffs, - buff_icon, - buff_name, - floor_pic, - buff_height, - ) - buff_height = buff_height + draw_height - - # 奇物 - if len(detail.miracles) > 0: - floor_pic_draw.text( - (93, 370 + buff_height + 60), - '获得奇物', - white_color, - sr_font_34, - 'lm', - ) - floor_pic.paste( - content_center, (0, 370 + buff_height + 80), content_center - ) - await _draw_rogue_miracles( - detail.miracles, - floor_pic, - buff_height, - ) - - if based_h_list[index_floor] is None: - continue - - img.paste(floor_pic, (0, based_h_list[index_floor]), floor_pic) - # await _draw_floor_card( - # level_star, - # floor_pic, - # img, - # index_floor, - # floor_name, - # round_num, - # ) - - res = await convert_img(img) - logger.info('[查询模拟宇宙]绘图已完成,等待发送!') - return res - - -async def draw_rogue_locust_img( - qid: Union[str, int], - uid: str, - sender: Union[str, str], -) -> Union[bytes, str]: - raw_rogue_data = await mys_api.get_rogue_locust_info(uid, '3') - - if isinstance(raw_rogue_data, int): - return get_error(raw_rogue_data) - - # 获取数据 - # if raw_data: - # char_data = raw_data['avatars'] - # else: - # return '没有获取到角色数据' - # char_temp = {} - - # 计算背景图尺寸 - rogue_detail = raw_rogue_data.detail.records - - # 记录打的宇宙列表 - # detail_list = [] - based_h = 700 - detail_h_list = [] - based_h_list = [] - for detail in rogue_detail: - # 100+70+170 - # 头+底+角色 - detail_h = 340 - - # 祝福 - if len(detail.base_type_list) > 0: - buff_h = 60 - for buff in detail.buffs: - buff_h = buff_h + 50 - buff_num = len(buff.items) - buff_h = buff_h + math.ceil(buff_num / 3) * 55 - else: - buff_h = 0 - detail_h = detail_h + buff_h - - # 奇物 - if len(detail.miracles) > 0: - miracles_h = 60 - miracles_num = len(detail.miracles) - miracles_h = miracles_h + math.ceil(miracles_num / 8) * 90 - else: - miracles_h = 0 - detail_h = detail_h + miracles_h - - # 事件 - blocks_h = 0 - if len(detail.blocks) > 0: - blocks_h = 60 - blocks_num = len(detail.blocks) - blocks_h = blocks_h + math.ceil(blocks_num / 2) * 80 - else: - blocks_num = 0 - detail_h = detail_h + blocks_h - detail_h_list.append(detail_h) - based_h_list.append(based_h) - based_h = based_h + detail_h - - # 获取查询者数据 - if len(rogue_detail) == 0: - return '你还没有挑战寰宇蝗灾~' - - # 获取背景图片各项参数 - based_w = 900 - img = Image.new('RGB', (based_w, based_h), (10, 18, 49)) - img.paste(img_bg, (0, 0)) - # img = img.crop((0, 0, based_w, based_h)) - rogue_title = Image.open(TEXT_PATH / 'head.png') - img.paste(rogue_title, (0, 0), rogue_title) - - # 获取头像 - _id = str(qid) - if _id.startswith('http'): - char_pic = await get_qq_avatar(avatar_url=_id) - elif sender.get('avatar') is not None: - char_pic = await get_qq_avatar(avatar_url=sender['avatar']) - else: - char_pic = await get_qq_avatar(qid=qid) - char_pic = await draw_pic_with_ring(char_pic, 250, None, False) - - img.paste(char_pic, (325, 132), char_pic) - - # 绘制抬头 - img_draw = ImageDraw.Draw(img) - img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm') - - # 总体数据 - rogue_data = Image.open(TEXT_PATH / 'data.png') - img.paste(rogue_data, (0, 500), rogue_data) - - # 行者之道激活 - img_draw.text( - (165, 569), - f'{raw_rogue_data.basic.cnt.narrow}', - white_color, - sr_font_42, - 'mm', - ) - img_draw.text( - (165, 615), - '行者之道', - gray_color, - sr_font_28, - 'mm', - ) - - # 奇物解锁 - img_draw.text( - (450, 569), - f'{raw_rogue_data.basic.cnt.miracle}', - white_color, - sr_font_42, - 'mm', - ) - img_draw.text( - (450, 615), - '已解锁奇物', - gray_color, - sr_font_28, - 'mm', - ) - - # 事件解锁 - img_draw.text( - (730, 569), - f'{raw_rogue_data.basic.cnt.event}', - white_color, - sr_font_42, - 'mm', - ) - img_draw.text( - (730, 615), - '已解锁事件', - gray_color, - sr_font_28, - 'mm', - ) - - for index_floor, detail in enumerate(rogue_detail): - if detail_h_list[index_floor] is None: - continue - - floor_pic = Image.open(TEXT_PATH / 'detail_bg.png').convert('RGBA') - floor_pic = floor_pic.resize((900, detail_h_list[index_floor])) - - floor_top_pic = Image.open(TEXT_PATH / 'floor_bg_top.png').convert( - 'RGBA' - ) - floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic) - - floor_center_pic = Image.open( - TEXT_PATH / 'floor_bg_center.png' - ).convert('RGBA') - floor_center_pic = floor_center_pic.resize( - (900, detail_h_list[index_floor] - 170) - ) - floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic) - - floor_bot_pic = Image.open(TEXT_PATH / 'floor_bg_bot.png').convert( - 'RGBA' - ) - floor_pic.paste( - floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic - ) - - floor_name = detail.name - difficulty_name = difficultylist[detail.difficulty] - - time_array = detail.finish_time - time_str = f'{time_array.year}-{time_array.month}' - time_str = f'{time_str}-{time_array.day}' - time_str = f'{time_str} {time_array.hour}:{time_array.minute}' - floor_pic_draw = ImageDraw.Draw(floor_pic) - floor_pic_draw.text( - (450, 60), - f'{floor_name} {difficulty_name}', - white_color, - sr_font_42, - 'mm', - ) - floor_pic_draw.text( - (93, 120), - f'挑战时间:{time_str}', - gray_color, - sr_font_22, - 'lm', - ) - if detail.fury.type == 1: - floor_pic_draw.text( - (800, 120), - f'扰动等级:{detail.fury.point}', - gray_color, - sr_font_22, - 'rm', - ) - else: - floor_pic_draw.text( - (800, 120), - f'位面紊乱倒计时:{detail.fury.point}', - gray_color, - sr_font_22, - 'rm', - ) - - # 角色 - for index_char, char in enumerate(detail.final_lineup): - # 获取命座 - # if char["id"] in char_temp: - # talent_num = char_temp[char["id"]] - # else: - # for i in char_data: - # if i["id"] == char["id"]: - # talent_num = str( - # i["actived_constellation_num"] - # ) - # char_temp[char["id"]] = talent_num - # break - await _draw_rogue_card( - char, - 0, # type: ignore - floor_pic, - index_char, - ) - - # 祝福 - buff_height = 0 - if len(detail.base_type_list) > 0: - floor_pic_draw.text( - (93, 370), - '获得祝福', - white_color, - sr_font_34, - 'lm', - ) - floor_pic.paste(content_center, (0, 390), content_center) - for buff in detail.buffs: - buff_icon = bufflist[buff.base_type.id] - buff_name = buff.base_type.name - buffs = buff.items - draw_height = await _draw_rogue_buff( - buffs, - buff_icon, - buff_name, - floor_pic, - buff_height, - ) - buff_height = buff_height + draw_height - - # 奇物 - miracles_height = buff_height - if len(detail.miracles) > 0: - floor_pic_draw.text( - (93, 370 + miracles_height + 60), - '获得奇物', - white_color, - sr_font_34, - 'lm', - ) - floor_pic.paste( - content_center, (0, 370 + miracles_height + 80), content_center - ) - draw_height = await _draw_rogue_miracles( - detail.miracles, - floor_pic, - miracles_height, - ) - miracles_height = miracles_height + 80 - miracles_height = miracles_height + draw_height - - # 事件 - blocks_height = miracles_height - if len(detail.blocks) > 0: - floor_pic_draw.text( - (93, 370 + blocks_height + 60), - '通过区域类型', - white_color, - sr_font_34, - 'lm', - ) - floor_pic.paste( - content_center, (0, 370 + blocks_height + 80), content_center - ) - draw_height = await _draw_rogue_blocks( - detail.blocks, - floor_pic, - blocks_height, - ) - blocks_height = blocks_height + 80 - blocks_height = blocks_height + draw_height - - if based_h_list[index_floor] is None: - continue - - img.paste(floor_pic, (0, based_h_list[index_floor]), floor_pic) - # await _draw_floor_card( - # level_star, - # floor_pic, - # img, - # index_floor, - # floor_name, - # round_num, - # ) - - res = await convert_img(img) - logger.info('[查询寰宇蝗灾]绘图已完成,等待发送!') - return res +import math +from pathlib import Path +from typing import Any, Dict, List, Optional, Union + +from .utils import get_icon +from ..sruid_utils.api.mys.models import ( + LocustBlocks, + RogueAvatar, + RogueBuffitems, + RogueMiracles, +) +from ..utils.fonts.starrail_fonts import ( + sr_font_22, + sr_font_28, + sr_font_34, + sr_font_42, +) +from ..utils.mys_api import mys_api + +from PIL import Image, ImageDraw +from gsuid_core.logger import logger +from gsuid_core.utils.error_reply import get_error +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import ( + draw_pic_with_ring, + get_qq_avatar, +) + +TEXT_PATH = Path(__file__).parent / "texture2D" +white_color = (255, 255, 255) +gray_color = (175, 175, 175) +img_bg = Image.open(TEXT_PATH / "bg.jpg") +level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA") +char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA") +char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA") +rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA") +content_center = Image.open(TEXT_PATH / "center.png").convert("RGBA") + +elements = { + "ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"), + "fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"), + "imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"), + "quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"), + "lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"), + "wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"), + "physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"), +} + +progresslist = { + 1: "第一世界", + 2: "第二世界", + 3: "第三世界", + 4: "第四世界", + 5: "第五世界", + 6: "第六世界", + 7: "第七世界", + 8: "第八世界", +} + +difficultylist = { + 1: "I", + 2: "Ⅱ", + 3: "Ⅲ", + 4: "Ⅳ", + 5: "V", + 6: "Ⅵ", + 7: "Ⅶ", + 8: "Ⅷ", +} + +bufflist = { + 120: "存护", + 121: "记忆", + 122: "虚无", + 123: "丰饶", + 124: "巡猎", + 125: "毁灭", + 126: "欢愉", + 127: "繁育", +} + + +async def get_abyss_star_pic(star: int) -> Image.Image: + return Image.open(TEXT_PATH / f"star{star}.png") + + +async def _draw_rogue_buff( + buffs: List[RogueBuffitems], + buff_icon: str, + buff_name: str, + floor_pic: Image.Image, + buff_height: int, +): + draw_height = 0 + floor_pic_draw = ImageDraw.Draw(floor_pic) + buff_icon_img = Image.open(TEXT_PATH / f"{buff_icon}.png") + buff_icon_img = buff_icon_img.resize((40, 40)) + floor_pic.paste(buff_icon_img, (95, 400 + buff_height), buff_icon_img) + floor_pic_draw.text( + (140, 425 + buff_height), + f"{buff_name}:", + font=sr_font_28, + fill=gray_color, + anchor="lm", + ) + draw_height = draw_height + 40 + buff_num = len(buffs) + need_middle = math.ceil(buff_num / 3) + draw_height = draw_height + need_middle * 55 + zb_list = [] + for m in range(need_middle): + for n in range(3): + zb_list.append([m, n]) + jishu = 0 + for item in buffs: + if item.is_evoluted is True: + is_evoluted = 1 + else: + is_evoluted = 0 + buff_bg = Image.open(TEXT_PATH / f"zhufu_{item.rank}_{is_evoluted}.png") + buff_bg = buff_bg.resize((233, 35)) + z_left = 90 + 240 * zb_list[jishu][1] + z_top = buff_height + 450 + 55 * zb_list[jishu][0] + jishu = jishu + 1 + floor_pic.paste(buff_bg, (z_left, z_top), mask=buff_bg) + floor_pic_draw.text( + (z_left + 115, z_top + 18), + item.name, + font=sr_font_22, + fill=white_color, + anchor="mm", + ) + return draw_height + + +async def _draw_rogue_blocks( + blocks: List[LocustBlocks], + floor_pic: Image.Image, + buff_height: int, +): + draw_height = 0 + floor_pic_draw = ImageDraw.Draw(floor_pic) + blocks_num = len(blocks) + need_middle = math.ceil(blocks_num / 2) + draw_height = draw_height + need_middle * 80 + zb_list = [] + for m in range(need_middle): + for n in range(2): + zb_list.append([m, n]) + jishu = 0 + for block in blocks: + block_icon = Image.open(TEXT_PATH / f"{block.name}.png") + z_left_bg = 90 + 357 * zb_list[jishu][1] + z_top_bg = buff_height + 470 + 80 * zb_list[jishu][0] + jishu = jishu + 1 + z_left_icon = z_left_bg + 10 + z_top_icon = z_top_bg + 5 + floor_pic.paste(block_icon, (z_left_icon, z_top_icon), mask=block_icon) + floor_pic_draw.text( + (z_left_bg + 80, z_top_bg + 35), + f"{block.name} x{block.num}", + font=sr_font_22, + fill=white_color, + anchor="lm", + ) + return draw_height + + +async def _draw_rogue_miracles( + miracles: List[RogueMiracles], + floor_pic: Image.Image, + buff_height: int, +): + draw_height = 0 + miracles_num = len(miracles) + need_middle = math.ceil(miracles_num / 8) + draw_height = draw_height + need_middle * 90 + zb_list = [] + for m in range(need_middle): + for n in range(8): + zb_list.append([m, n]) + jishu = 0 + for miracle in miracles: + miracles_icon = (await get_icon(miracle.icon)).resize((80, 80)) + z_left = 90 + 90 * zb_list[jishu][1] + z_top = buff_height + 470 + 90 * zb_list[jishu][0] + jishu = jishu + 1 + floor_pic.paste(miracles_icon, (z_left, z_top), mask=miracles_icon) + + return draw_height + + +async def _draw_rogue_card( + char: RogueAvatar, + talent_num: str, + floor_pic: Image.Image, + index_char: int, +): + # char_id = char['id'] + # # 确认角色头像路径 + # char_pic_path = CHAR_ICON_PATH / f'{char_id}.png' + char_bg = (char_bg_4 if char.rarity == 4 else char_bg_5).copy() + char_icon = (await get_icon(char.icon)).resize((151, 170)) + element_icon = elements[char.element] + char_bg.paste(char_icon, (24, 16), mask=char_icon) + char_bg.paste(level_cover, (0, 0), mask=level_cover) + char_bg.paste(element_icon, (35, 25), mask=element_icon) + # 不存在自动下载 + # if not char_pic_path.exists(): + # await create_single_char_card(char_id) + # talent_pic = await get_talent_pic(int(talent_num)) + # talent_pic = talent_pic.resize((90, 45)) + # char_card.paste(talent_pic, (137, 260), talent_pic) + char_card_draw = ImageDraw.Draw(char_bg) + if char.rank > 0: + char_bg.paste(rank_bg, (150, 16), mask=rank_bg) + char_card_draw.text( + (162, 31), + f"{char.rank}", + font=sr_font_22, + fill=white_color, + anchor="mm", + ) + char_card_draw.text( + (100, 165), + f"等级 {char.level}", + font=sr_font_22, + fill=white_color, + anchor="mm", + ) + floor_pic.paste( + char_bg, + (75 + 185 * index_char, 130), + char_bg, + ) + + +async def draw_rogue_img( + qid: Union[str, int], + uid: str, + sender: Dict[str, Any], + floor: Optional[int] = None, + schedule_type: str = "3", +) -> Union[bytes, str]: + raw_rogue_data = await mys_api.get_rogue_info(uid, "3") + + if isinstance(raw_rogue_data, int): + return get_error(raw_rogue_data) + + # 计算背景图尺寸 + if schedule_type == "3": + rogue_detail = raw_rogue_data.current_record.records + else: + rogue_detail = raw_rogue_data.last_record.records + + # 记录打的宇宙列表 + detail_list = [] + based_h = 700 + detail_h_list = [] + based_h_list = [] + for detail in rogue_detail: + # 100+70+170 + # 头+底+角色 + detail_h = 340 + progress = detail.progress + detail_list.append(progress) + # 祝福 + if len(detail.base_type_list) > 0: + buff_h = 60 + for buff in detail.buffs: + buff_h = buff_h + 50 + buff_num = len(buff.items) + buff_h = buff_h + math.ceil(buff_num / 3) * 55 + else: + buff_h = 0 + detail_h = detail_h + buff_h + + # 奇物 + if len(detail.miracles) > 0: + miracles_h = 60 + miracles_num = len(detail.miracles) + miracles_h = miracles_h + math.ceil(miracles_num / 8) * 90 + else: + miracles_h = 0 + detail_h = detail_h + miracles_h + detail_h_list.append(detail_h) + based_h_list.append(based_h) + if floor: + if progress == floor: + pass + else: + detail_h = 0 + based_h = based_h + detail_h + + # 获取查询者数据 + if floor: + if floor > 8: + return "世界不能大于第八世界!" + if floor not in detail_list: + return "你还没有挑战该模拟宇宙!" + elif schedule_type == "3": + if raw_rogue_data.current_record.basic.finish_cnt == 0: + return "你还没有挑战本期模拟宇宙!\n可以使用[sr上期模拟宇宙]命令查询上期~" + elif raw_rogue_data.last_record.basic.finish_cnt == 0: + return "你还没有挑战上期模拟宇宙!\n可以使用[sr模拟宇宙]命令查询本期~" + + # 获取背景图片各项参数 + based_w = 900 + img = Image.new("RGB", (based_w, based_h), (10, 18, 49)) + img.paste(img_bg, (0, 0)) + # img = img.crop((0, 0, based_w, based_h)) + rogue_title = Image.open(TEXT_PATH / "head.png") + img.paste(rogue_title, (0, 0), rogue_title) + + # 获取头像 + _id = str(qid) + if _id.startswith("http"): + char_pic = await get_qq_avatar(avatar_url=_id) + elif sender.get("avatar") is not None: + char_pic = await get_qq_avatar(avatar_url=sender["avatar"]) + else: + char_pic = await get_qq_avatar(qid=qid) + char_pic = await draw_pic_with_ring(char_pic, 250, None, False) + + img.paste(char_pic, (325, 132), char_pic) + + # 绘制抬头 + img_draw = ImageDraw.Draw(img) + img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm") + + # 总体数据 + rogue_data = Image.open(TEXT_PATH / "data.png") + img.paste(rogue_data, (0, 500), rogue_data) + + # 技能树激活 + img_draw.text( + (165, 569), + f"{raw_rogue_data.basic_info.unlocked_skill_points}", + white_color, + sr_font_42, + "mm", + ) + img_draw.text( + (165, 615), + "已激活技能树", + gray_color, + sr_font_28, + "mm", + ) + + # 奇物解锁 + img_draw.text( + (450, 569), + f"{raw_rogue_data.basic_info.unlocked_miracle_num}", + white_color, + sr_font_42, + "mm", + ) + img_draw.text( + (450, 615), + "已解锁奇物", + gray_color, + sr_font_28, + "mm", + ) + + # 祝福解锁 + img_draw.text( + (730, 569), + f"{raw_rogue_data.basic_info.unlocked_buff_num}", + white_color, + sr_font_42, + "mm", + ) + img_draw.text( + (730, 615), + "已解锁祝福", + gray_color, + sr_font_28, + "mm", + ) + + for index_floor, detail in enumerate(rogue_detail): + if floor: + if floor == detail.progress: + index_floor = 0 # noqa: PLW2901 + else: + continue + + if detail_h_list[index_floor] is None: + continue + + floor_pic = Image.open(TEXT_PATH / "detail_bg.png").convert("RGBA") + floor_pic = floor_pic.resize((900, detail_h_list[index_floor])) + + floor_top_pic = Image.open(TEXT_PATH / "floor_bg_top.png").convert("RGBA") + floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic) + + floor_center_pic = Image.open(TEXT_PATH / "floor_bg_center.png").convert("RGBA") + floor_center_pic = floor_center_pic.resize( + (900, detail_h_list[index_floor] - 170) + ) + floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic) + + floor_bot_pic = Image.open(TEXT_PATH / "floor_bg_bot.png").convert("RGBA") + floor_pic.paste( + floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic + ) + + floor_name = progresslist[detail.progress] + difficulty_name = difficultylist[detail.difficulty] + + time_array = detail.finish_time + time_str = f"{time_array.year}-{time_array.month}" + time_str = f"{time_str}-{time_array.day}" + time_str = f"{time_str} {time_array.hour}:{time_array.minute}" + floor_pic_draw = ImageDraw.Draw(floor_pic) + floor_pic_draw.text( + (450, 60), + f"{floor_name} {difficulty_name}", + white_color, + sr_font_42, + "mm", + ) + floor_pic_draw.text( + (93, 120), + f"挑战时间:{time_str}", + gray_color, + sr_font_22, + "lm", + ) + floor_pic_draw.text( + (800, 120), + f"当前积分:{detail.score}", + gray_color, + sr_font_22, + "rm", + ) + + # 角色 + for index_char, char in enumerate(detail.final_lineup): + # 获取命座 + # if char["id"] in char_temp: + # talent_num = char_temp[char["id"]] + # else: + # for i in char_data: + # if i["id"] == char["id"]: + # talent_num = str( + # i["actived_constellation_num"] + # ) + # char_temp[char["id"]] = talent_num + # break + await _draw_rogue_card( + char, + 0, # type: ignore + floor_pic, + index_char, + ) + + # 祝福 + buff_height = 0 + if len(detail.base_type_list) > 0: + floor_pic_draw.text( + (93, 370), + "获得祝福", + white_color, + sr_font_34, + "lm", + ) + floor_pic.paste(content_center, (0, 390), content_center) + for buff in detail.buffs: + buff_icon = bufflist[buff.base_type.id] + buff_name = buff.base_type.name + buffs = buff.items + draw_height = await _draw_rogue_buff( + buffs, + buff_icon, + buff_name, + floor_pic, + buff_height, + ) + buff_height = buff_height + draw_height + + # 奇物 + if len(detail.miracles) > 0: + floor_pic_draw.text( + (93, 370 + buff_height + 60), + "获得奇物", + white_color, + sr_font_34, + "lm", + ) + floor_pic.paste(content_center, (0, 370 + buff_height + 80), content_center) + await _draw_rogue_miracles( + detail.miracles, + floor_pic, + buff_height, + ) + + if based_h_list[index_floor] is None: + continue + + img.paste(floor_pic, (0, based_h_list[index_floor]), floor_pic) + # await _draw_floor_card( + # level_star, + # floor_pic, + # img, + # index_floor, + # floor_name, + # round_num, + # ) + + res = await convert_img(img) + logger.info("[查询模拟宇宙]绘图已完成,等待发送!") + return res + + +async def draw_rogue_locust_img( + qid: Union[str, int], + uid: str, + sender: Dict[str, Any], +) -> Union[bytes, str]: + raw_rogue_data = await mys_api.get_rogue_locust_info(uid, "3") + + if isinstance(raw_rogue_data, int): + return get_error(raw_rogue_data) + + # 获取数据 + # if raw_data: + # char_data = raw_data['avatars'] + # else: + # return '没有获取到角色数据' + # char_temp = {} + + # 计算背景图尺寸 + rogue_detail = raw_rogue_data.detail.records + + # 记录打的宇宙列表 + # detail_list = [] + based_h = 700 + detail_h_list = [] + based_h_list = [] + for detail in rogue_detail: + # 100+70+170 + # 头+底+角色 + detail_h = 340 + + # 祝福 + if len(detail.base_type_list) > 0: + buff_h = 60 + for buff in detail.buffs: + buff_h = buff_h + 50 + buff_num = len(buff.items) + buff_h = buff_h + math.ceil(buff_num / 3) * 55 + else: + buff_h = 0 + detail_h = detail_h + buff_h + + # 奇物 + if len(detail.miracles) > 0: + miracles_h = 60 + miracles_num = len(detail.miracles) + miracles_h = miracles_h + math.ceil(miracles_num / 8) * 90 + else: + miracles_h = 0 + detail_h = detail_h + miracles_h + + # 事件 + blocks_h = 0 + if len(detail.blocks) > 0: + blocks_h = 60 + blocks_num = len(detail.blocks) + blocks_h = blocks_h + math.ceil(blocks_num / 2) * 80 + else: + blocks_num = 0 + detail_h = detail_h + blocks_h + detail_h_list.append(detail_h) + based_h_list.append(based_h) + based_h = based_h + detail_h + + # 获取查询者数据 + if len(rogue_detail) == 0: + return "你还没有挑战寰宇蝗灾~" + + # 获取背景图片各项参数 + based_w = 900 + img = Image.new("RGB", (based_w, based_h), (10, 18, 49)) + img.paste(img_bg, (0, 0)) + # img = img.crop((0, 0, based_w, based_h)) + rogue_title = Image.open(TEXT_PATH / "head.png") + img.paste(rogue_title, (0, 0), rogue_title) + + # 获取头像 + _id = str(qid) + if _id.startswith("http"): + char_pic = await get_qq_avatar(avatar_url=_id) + elif sender.get("avatar") is not None: + char_pic = await get_qq_avatar(avatar_url=sender["avatar"]) + else: + char_pic = await get_qq_avatar(qid=qid) + char_pic = await draw_pic_with_ring(char_pic, 250, None, False) + + img.paste(char_pic, (325, 132), char_pic) + + # 绘制抬头 + img_draw = ImageDraw.Draw(img) + img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm") + + # 总体数据 + rogue_data = Image.open(TEXT_PATH / "data.png") + img.paste(rogue_data, (0, 500), rogue_data) + + # 行者之道激活 + img_draw.text( + (165, 569), + f"{raw_rogue_data.basic.cnt.narrow}", + white_color, + sr_font_42, + "mm", + ) + img_draw.text( + (165, 615), + "行者之道", + gray_color, + sr_font_28, + "mm", + ) + + # 奇物解锁 + img_draw.text( + (450, 569), + f"{raw_rogue_data.basic.cnt.miracle}", + white_color, + sr_font_42, + "mm", + ) + img_draw.text( + (450, 615), + "已解锁奇物", + gray_color, + sr_font_28, + "mm", + ) + + # 事件解锁 + img_draw.text( + (730, 569), + f"{raw_rogue_data.basic.cnt.event}", + white_color, + sr_font_42, + "mm", + ) + img_draw.text( + (730, 615), + "已解锁事件", + gray_color, + sr_font_28, + "mm", + ) + + for index_floor, detail in enumerate(rogue_detail): + if detail_h_list[index_floor] is None: + continue + + floor_pic = Image.open(TEXT_PATH / "detail_bg.png").convert("RGBA") + floor_pic = floor_pic.resize((900, detail_h_list[index_floor])) + + floor_top_pic = Image.open(TEXT_PATH / "floor_bg_top.png").convert("RGBA") + floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic) + + floor_center_pic = Image.open(TEXT_PATH / "floor_bg_center.png").convert("RGBA") + floor_center_pic = floor_center_pic.resize( + (900, detail_h_list[index_floor] - 170) + ) + floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic) + + floor_bot_pic = Image.open(TEXT_PATH / "floor_bg_bot.png").convert("RGBA") + floor_pic.paste( + floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic + ) + + floor_name = detail.name + difficulty_name = difficultylist[detail.difficulty] + + time_array = detail.finish_time + time_str = f"{time_array.year}-{time_array.month}" + time_str = f"{time_str}-{time_array.day}" + time_str = f"{time_str} {time_array.hour}:{time_array.minute}" + floor_pic_draw = ImageDraw.Draw(floor_pic) + floor_pic_draw.text( + (450, 60), + f"{floor_name} {difficulty_name}", + white_color, + sr_font_42, + "mm", + ) + floor_pic_draw.text( + (93, 120), + f"挑战时间:{time_str}", + gray_color, + sr_font_22, + "lm", + ) + if detail.fury.type == 1: + floor_pic_draw.text( + (800, 120), + f"扰动等级:{detail.fury.point}", + gray_color, + sr_font_22, + "rm", + ) + else: + floor_pic_draw.text( + (800, 120), + f"位面紊乱倒计时:{detail.fury.point}", + gray_color, + sr_font_22, + "rm", + ) + + # 角色 + for index_char, char in enumerate(detail.final_lineup): + # 获取命座 + # if char["id"] in char_temp: + # talent_num = char_temp[char["id"]] + # else: + # for i in char_data: + # if i["id"] == char["id"]: + # talent_num = str( + # i["actived_constellation_num"] + # ) + # char_temp[char["id"]] = talent_num + # break + await _draw_rogue_card( + char, + 0, # type: ignore + floor_pic, + index_char, + ) + + # 祝福 + buff_height = 0 + if len(detail.base_type_list) > 0: + floor_pic_draw.text( + (93, 370), + "获得祝福", + white_color, + sr_font_34, + "lm", + ) + floor_pic.paste(content_center, (0, 390), content_center) + for buff in detail.buffs: + buff_icon = bufflist[buff.base_type.id] + buff_name = buff.base_type.name + buffs = buff.items + draw_height = await _draw_rogue_buff( + buffs, + buff_icon, + buff_name, + floor_pic, + buff_height, + ) + buff_height = buff_height + draw_height + + # 奇物 + miracles_height = buff_height + if len(detail.miracles) > 0: + floor_pic_draw.text( + (93, 370 + miracles_height + 60), + "获得奇物", + white_color, + sr_font_34, + "lm", + ) + floor_pic.paste( + content_center, (0, 370 + miracles_height + 80), content_center + ) + draw_height = await _draw_rogue_miracles( + detail.miracles, + floor_pic, + miracles_height, + ) + miracles_height = miracles_height + 80 + miracles_height = miracles_height + draw_height + + # 事件 + blocks_height = miracles_height + if len(detail.blocks) > 0: + floor_pic_draw.text( + (93, 370 + blocks_height + 60), + "通过区域类型", + white_color, + sr_font_34, + "lm", + ) + floor_pic.paste( + content_center, (0, 370 + blocks_height + 80), content_center + ) + draw_height = await _draw_rogue_blocks( + detail.blocks, + floor_pic, + blocks_height, + ) + blocks_height = blocks_height + 80 + blocks_height = blocks_height + draw_height + + if based_h_list[index_floor] is None: + continue + + img.paste(floor_pic, (0, based_h_list[index_floor]), floor_pic) + # await _draw_floor_card( + # level_star, + # floor_pic, + # img, + # index_floor, + # floor_name, + # round_num, + # ) + + res = await convert_img(img) + logger.info("[查询寰宇蝗灾]绘图已完成,等待发送!") + return res diff --git a/StarRailUID/starrailuid_rogue/utils.py b/StarRailUID/starrailuid_rogue/utils.py index a18f624..c6bda1b 100644 --- a/StarRailUID/starrailuid_rogue/utils.py +++ b/StarRailUID/starrailuid_rogue/utils.py @@ -6,14 +6,14 @@ from PIL import Image from aiohttp import ClientSession from gsuid_core.data_store import get_res_path -T = TypeVar('T') +T = TypeVar("T") -ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo' +ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo" ROLEINFO_PATH.mkdir(parents=True, exist_ok=True) async def get_icon(url: str) -> Image.Image: - name = url.split('/')[-1] + name = url.split("/")[-1] path = ROLEINFO_PATH / name if (path).exists(): content = path.read_bytes() @@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image: async with ClientSession() as client: async with client.get(url) as resp: content = await resp.read() - with Path.open(path, 'wb') as f: + with Path.open(path, "wb") as f: f.write(content) - return Image.open(BytesIO(content)).convert('RGBA') + return Image.open(BytesIO(content)).convert("RGBA") diff --git a/StarRailUID/starrailuid_roleinfo/__init__.py b/StarRailUID/starrailuid_roleinfo/__init__.py index 6d452a2..b5740c6 100644 --- a/StarRailUID/starrailuid_roleinfo/__init__.py +++ b/StarRailUID/starrailuid_roleinfo/__init__.py @@ -1,47 +1,45 @@ import re -from gsuid_core.sv import SV -from gsuid_core.bot import Bot -from gsuid_core.models import Event -from gsuid_core.logger import logger - -from ..utils.convert import get_uid -from ..utils.sr_prefix import PREFIX +from .draw_roleinfo_card import get_detail_img, get_role_img from ..utils.error_reply import UID_HINT -from .draw_roleinfo_card import get_role_img, get_detail_img +from ..utils.sr_prefix import PREFIX -sv_get_info = SV('sr查询信息') +from gsuid_core.bot import Bot +from gsuid_core.logger import logger +from gsuid_core.models import Event +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind + +sv_get_info = SV("sr查询信息") -@sv_get_info.on_command(f'{PREFIX}uid') +@sv_get_info.on_command(f"{PREFIX}uid") async def send_role_info(bot: Bot, ev: Event): - name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text)) + name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text)) if name: return None - uid = await get_uid(bot, ev) + uid = await get_uid(bot, ev, GsBind, "sr") if uid is None: - return '你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!' + return "你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!" - logger.info(f'[sr查询信息]UID: {uid}') - await bot.logger.info('开始执行[sr查询信息]') + logger.info(f"[sr查询信息]UID: {uid}") + await bot.logger.info("开始执行[sr查询信息]") await bot.send(await get_role_img(uid)) return None -@sv_get_info.on_command(f'{PREFIX}练度统计') +@sv_get_info.on_command(f"{PREFIX}练度统计") 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: return None - get_uid_ = await get_uid(bot, ev, True) - if get_uid_ is None: - return await bot.send(UID_HINT) - uid, user_id = get_uid_ + uid, user_id = await get_uid(bot, ev, GsBind, "sr", True) if uid is None: return await bot.send(UID_HINT) - logger.info(f'[sr查询信息]UID: {uid}') - await bot.logger.info('开始执行[sr查询信息]') + logger.info(f"[sr查询信息]UID: {uid}") + await bot.logger.info("开始执行[sr查询信息]") await bot.send(await get_detail_img(user_id, uid, ev.sender)) return None diff --git a/StarRailUID/starrailuid_roleinfo/draw_roleinfo_card.py b/StarRailUID/starrailuid_roleinfo/draw_roleinfo_card.py index ce87b36..3d42832 100644 --- a/StarRailUID/starrailuid_roleinfo/draw_roleinfo_card.py +++ b/StarRailUID/starrailuid_roleinfo/draw_roleinfo_card.py @@ -1,26 +1,16 @@ import asyncio from pathlib import Path -from typing import Dict, List, Union, Optional +from typing import Any, Dict, List, Optional, Union -from PIL import Image, ImageDraw -from gsuid_core.logger import logger -from gsuid_core.utils.error_reply import get_error -from gsuid_core.utils.image.image_tools import ( - get_qq_avatar, - draw_pic_with_ring, -) - -from ..utils.mys_api import mys_api from .utils import get_icon, wrap_list -from ..utils.image.convert import convert_img -from ..utils.fonts.first_world import fw_font_24 from ..sruid_utils.api.mys.models import ( - Stats, AvatarDetail, - RoleBasicInfo, AvatarListItem, AvatarListItemDetail, + RoleBasicInfo, + Stats, ) +from ..utils.fonts.first_world import fw_font_24 from ..utils.fonts.starrail_fonts import ( sr_font_22, sr_font_24, @@ -28,41 +18,41 @@ from ..utils.fonts.starrail_fonts import ( sr_font_30, sr_font_36, ) +from ..utils.mys_api import mys_api -TEXT_PATH = Path(__file__).parent / 'texture2D' - -bg1 = Image.open(TEXT_PATH / 'bg1.png') -bg2 = Image.open(TEXT_PATH / 'bg2.png') -bg3 = Image.open(TEXT_PATH / 'bg3.png') -user_avatar = ( - Image.open(TEXT_PATH / '200101.png').resize((220, 220)).convert('RGBA') +from PIL import Image, ImageDraw +from gsuid_core.logger import logger +from gsuid_core.utils.error_reply import get_error +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import ( + draw_pic_with_ring, + get_qq_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_light.jpg') -rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA') + +TEXT_PATH = Path(__file__).parent / "texture2D" + +bg1 = Image.open(TEXT_PATH / "bg1.png") +bg2 = Image.open(TEXT_PATH / "bg2.png") +bg3 = Image.open(TEXT_PATH / "bg3.png") +user_avatar = Image.open(TEXT_PATH / "200101.png").resize((220, 220)).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") +circle = Image.open(TEXT_PATH / "char_weapon_bg.png").convert("RGBA") +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) first_color = (22, 8, 31) elements = { - 'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'), - 'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'), - 'imaginary': Image.open( - TEXT_PATH / 'IconNatureColorImaginary.png' - ).convert('RGBA'), - 'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert( - 'RGBA' - ), - 'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert( - 'RGBA' - ), - 'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'), - 'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert( - 'RGBA' - ), + "ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"), + "fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"), + "imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"), + "quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"), + "lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"), + "wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"), + "physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"), } @@ -70,14 +60,12 @@ async def get_role_img(uid: str) -> Union[bytes, str]: return await draw_role_card(uid) -async def get_detail_img( - qid: Union[str, int], uid: str, sender -) -> Union[bytes, str]: +async def get_detail_img(qid: Union[str, int], uid: str, sender) -> Union[bytes, str]: return await get_detail_card(qid, uid, sender) 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}" async def _draw_card_1( @@ -100,16 +88,14 @@ async def _draw_card_1( bg1_draw = ImageDraw.Draw(img_bg1) # 写Nickname - bg1_draw.text( - (400, 85), nickname, font=sr_font_36, fill=white_color, anchor='mm' - ) + bg1_draw.text((400, 85), nickname, font=sr_font_36, fill=white_color, anchor="mm") # 写UID bg1_draw.text( (400, 165), - f'UID {sr_uid}', + f"UID {sr_uid}", font=sr_font_30, fill=white_color, - anchor='mm', + anchor="mm", ) # 贴头像 img_bg1.paste(user_avatar, (286, 213), mask=user_avatar) @@ -120,31 +106,31 @@ async def _draw_card_1( str(active_days), font=sr_font_36, fill=white_color, - anchor='mm', + anchor="mm", ) # 活跃天数 bg1_draw.text( (270, 590), str(avater_num), font=sr_font_36, fill=white_color, - anchor='mm', + anchor="mm", ) # 解锁角色 bg1_draw.text( (398, 590), str(achievement_num), font=sr_font_36, fill=white_color, - anchor='mm', + anchor="mm", ) # 达成成就 bg1_draw.text( (525, 590), str(chest_num), font=sr_font_36, fill=white_color, - anchor='mm', + anchor="mm", ) # 战利品开启 bg1_draw.text( - (666, 590), str(level), font=sr_font_36, fill=white_color, anchor='mm' + (666, 590), str(level), font=sr_font_36, fill=white_color, anchor="mm" ) # 开拓等级 # 画忘却之庭 @@ -153,7 +139,7 @@ async def _draw_card_1( abyss_process, font=sr_font_30, fill=first_color, - anchor='mm', + anchor="mm", ) return img_bg1 @@ -174,10 +160,10 @@ async def _draw_avatar_card( char_bg.paste(rank_bg, (89, 6), mask=rank_bg) char_draw.text( (100, 21), - f'{avatar.rank}', + f"{avatar.rank}", font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) if equip := equips[avatar.id]: @@ -190,7 +176,7 @@ async def _draw_avatar_card( _lv(avatar.level), font=sr_font_24, fill=color_color, - anchor='mm', + anchor="mm", ) return char_bg @@ -214,12 +200,9 @@ async def _draw_card_2( ) -> Image.Image: # 角色部分 每五个一组 lines = await asyncio.gather( - *[ - _draw_line(five_avatars, equips) - for five_avatars in wrap_list(avatars, 5) - ] + *[_draw_line(five_avatars, equips) for five_avatars in wrap_list(avatars, 5)] ) - img_card_2 = Image.new('RGBA', (800, len(lines) * 200)) + img_card_2 = Image.new("RGBA", (800, len(lines) * 200)) y = 0 for line in lines: @@ -237,8 +220,8 @@ async def draw_role_card(sr_uid: str) -> Union[bytes, str]: return get_error(role_basic_info) else: role_basic_info = {} - role_basic_info['nickname'] = '开拓者' - role_basic_info['level'] = 0 + role_basic_info["nickname"] = "开拓者" + role_basic_info["level"] = 0 if isinstance(role_index, int): return get_error(role_index) @@ -266,7 +249,7 @@ async def draw_role_card(sr_uid: str) -> Union[bytes, str]: ) img2: Image.Image height = img2.size[1] - img = Image.new('RGBA', (800, 880 + height), bg_color) + img = Image.new("RGBA", (800, 880 + height), bg_color) img.paste(img1, (0, 0)) img.paste(img2, (0, 810)) img.paste(bg3, (0, height + 810)) @@ -279,69 +262,69 @@ async def _draw_detail_card( index: int, char_info: Image.Image, ) -> Image.Image: - if str(avatar.rarity) == '5': - avatar_img = Image.open(TEXT_PATH / 'bar_5.png') + if str(avatar.rarity) == "5": + avatar_img = Image.open(TEXT_PATH / "bar_5.png") else: - avatar_img = Image.open(TEXT_PATH / 'bar_4.png') + 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, (75, 10), mask=char_icon) avatar_draw.text( (130, 30), - f'{avatar.name}', + f"{avatar.name}", first_color, sr_font_24, - 'lm', + "lm", ) avatar_img.paste(element_icon, (270, 10), mask=element_icon) avatar_draw.text( (339, 30), - f'{avatar.level}', + f"{avatar.level}", first_color, sr_font_24, - 'mm', + "mm", ) avatar_draw.text( (385, 30), - f'{avatar.rank}', + f"{avatar.rank}", first_color, sr_font_24, - 'mm', + "mm", ) avatar_draw.text( (429, 30), - f'{avatar_detail.skills[0].cur_level}', + f"{avatar_detail.skills[0].cur_level}", first_color, sr_font_24, - 'mm', + "mm", ) avatar_draw.text( (469, 30), - f'{avatar_detail.skills[1].cur_level}', + f"{avatar_detail.skills[1].cur_level}", first_color, sr_font_24, - 'mm', + "mm", ) avatar_draw.text( (515, 30), - f'{avatar_detail.skills[2].cur_level}', + f"{avatar_detail.skills[2].cur_level}", first_color, sr_font_24, - 'mm', + "mm", ) avatar_draw.text( (553, 30), - f'{avatar_detail.skills[3].cur_level}', + f"{avatar_detail.skills[3].cur_level}", first_color, sr_font_24, - 'mm', + "mm", ) if avatar.equip: @@ -350,26 +333,26 @@ async def _draw_detail_card( avatar_draw.text( (680, 30), - f'{avatar.equip.rank}', + f"{avatar.equip.rank}", first_color, sr_font_24, - 'mm', + "mm", ) avatar_draw.text( (734, 30), - f'Lv.{avatar.equip.level}', + f"Lv.{avatar.equip.level}", first_color, sr_font_24, - 'lm', + "lm", ) avatar_draw.text( (804, 30), - f'{avatar.equip.name}', + f"{avatar.equip.name}", first_color, sr_font_24, - 'lm', + "lm", ) char_info.paste(avatar_img, (0, 585 + 62 * index), mask=avatar_img) @@ -378,7 +361,7 @@ async def _draw_detail_card( async def get_detail_card( - qid: Union[str, int], sr_uid: str, sender: Union[str, str] + qid: Union[str, int], sr_uid: str, sender: Dict[str, Any] ) -> Union[bytes, str]: # 获取角色列表 avatar_list = await mys_api.get_avatar_info(sr_uid, 1001) @@ -393,15 +376,15 @@ async def get_detail_card( char_info = char_info.resize((1050, img_height)) char_img_draw = ImageDraw.Draw(char_info) - char_title = Image.open(TEXT_PATH / 'title.png') + char_title = Image.open(TEXT_PATH / "title.png") char_info.paste(char_title, (0, 0), char_title) # 获取头像 _id = str(qid) - if _id.startswith('http'): + if _id.startswith("http"): char_pic = await get_qq_avatar(avatar_url=_id) - elif sender.get('avatar') is not None: - char_pic = await get_qq_avatar(avatar_url=sender['avatar']) + elif sender.get("avatar") is not None: + char_pic = await get_qq_avatar(avatar_url=sender["avatar"]) else: char_pic = await get_qq_avatar(qid=qid) char_pic = await draw_pic_with_ring(char_pic, 250, None, False) @@ -409,11 +392,9 @@ async def get_detail_card( char_info.paste(char_pic, (400, 88), char_pic) # 绘制抬头 - char_img_draw.text( - (525, 420), f'UID {sr_uid}', white_color, sr_font_28, 'mm' - ) + char_img_draw.text((525, 420), f"UID {sr_uid}", white_color, sr_font_28, "mm") - title_img = Image.open(TEXT_PATH / 'bar_title.png') + title_img = Image.open(TEXT_PATH / "bar_title.png") char_info.paste(title_img, (0, 515), mask=title_img) for index, avatar in enumerate(avatar_list.avatar_list): @@ -431,12 +412,12 @@ async def get_detail_card( # 写底层文字 char_img_draw.text( (525, img_height - 45), - '--SR skill statistics by StarrailUID & Code by jiluoQAQ & Power by GsCore--', + "--SR skill statistics by StarrailUID & Code by jiluoQAQ & Power by GsCore--", (255, 255, 255), fw_font_24, - 'mm', + "mm", ) res = await convert_img(char_info) - logger.info('[查询练度统计]绘图已完成,等待发送!') + logger.info("[查询练度统计]绘图已完成,等待发送!") return res diff --git a/StarRailUID/starrailuid_roleinfo/utils.py b/StarRailUID/starrailuid_roleinfo/utils.py index 89afb1a..48629c3 100644 --- a/StarRailUID/starrailuid_roleinfo/utils.py +++ b/StarRailUID/starrailuid_roleinfo/utils.py @@ -6,9 +6,9 @@ from PIL import Image from aiohttp import ClientSession from gsuid_core.data_store import get_res_path -T = TypeVar('T') +T = TypeVar("T") -ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo' +ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo" ROLEINFO_PATH.mkdir(parents=True, exist_ok=True) @@ -18,7 +18,7 @@ def wrap_list(lst: List[T], n: int) -> Generator[List[T], None, None]: async def get_icon(url: str) -> Image.Image: - name = url.split('/')[-1] + name = url.split("/")[-1] path = ROLEINFO_PATH / name if (path).exists(): content = path.read_bytes() @@ -26,6 +26,6 @@ async def get_icon(url: str) -> Image.Image: async with ClientSession() as client: async with client.get(url) as resp: content = await resp.read() - with Path.open(path, 'wb') as f: + with Path.open(path, "wb") as f: f.write(content) - return Image.open(BytesIO(content)).convert('RGBA') + return Image.open(BytesIO(content)).convert("RGBA") diff --git a/StarRailUID/starrailuid_signin/__init__.py b/StarRailUID/starrailuid_signin/__init__.py index 368181b..4d481a8 100644 --- a/StarRailUID/starrailuid_signin/__init__.py +++ b/StarRailUID/starrailuid_signin/__init__.py @@ -11,40 +11,40 @@ from gsuid_core.utils.boardcast.send_msg import send_board_cast_msg from gsuid_core.utils.database.models import GsBind from gsuid_core.utils.sign.sign import daily_sign, sign_in -SIGN_TIME = srconfig.get_config('SignTime').data -IS_REPORT = srconfig.get_config('PrivateSignReport').data +SIGN_TIME = srconfig.get_config("SignTime").data +IS_REPORT = srconfig.get_config("PrivateSignReport").data -sv_sign = SV('星穹铁道签到') -sv_sign_config = SV('星穹铁道管理', pm=2) +sv_sign = SV("星穹铁道签到") +sv_sign_config = SV("星穹铁道管理", pm=2) -@sv_sign.on_fullmatch(f'{PREFIX}签到') +@sv_sign.on_fullmatch(f"{PREFIX}签到") async def get_sign_func(bot: Bot, ev: Event): - logger.info(f'[星穹铁道] [签到] 用户: {ev.user_id}') - uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr') + logger.info(f"[星穹铁道] [签到] 用户: {ev.user_id}") + uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, "sr") if uid is None: return await bot.send(UID_HINT) - logger.info(f'[星穹铁道] [签到] UID: {uid}') - await bot.send(await sign_in(uid, 'sr')) + logger.info(f"[星穹铁道] [签到] UID: {uid}") + await bot.send(await sign_in(uid, "sr")) return None -@sv_sign_config.on_fullmatch(f'{PREFIX}全部重签') +@sv_sign_config.on_fullmatch(f"{PREFIX}全部重签") async def recheck(bot: Bot, ev: Event): - await bot.logger.info('开始执行[全部重签]') - await bot.send('[星穹铁道] [全部重签] 已开始执行!') - result = await daily_sign('sr') + await bot.logger.info("开始执行[全部重签]") + await bot.send("[星穹铁道] [全部重签] 已开始执行!") + result = await daily_sign("sr") if not IS_REPORT: - result['private_msg_dict'] = {} + result["private_msg_dict"] = {} await send_board_cast_msg(result) - await bot.send('[星穹铁道] [全部重签] 执行完成!') + await bot.send("[星穹铁道] [全部重签] 执行完成!") # 每日零点半执行米游社星穹铁道签到 -@scheduler.scheduled_job('cron', hour=SIGN_TIME[0], minute=SIGN_TIME[1]) +@scheduler.scheduled_job("cron", hour=SIGN_TIME[0], minute=SIGN_TIME[1]) async def sr_sign_at_night(): - if srconfig.get_config('SchedSignin').data: - result = await daily_sign('sr') + if srconfig.get_config("SchedSignin").data: + result = await daily_sign("sr") if not IS_REPORT: - result['private_msg_dict'] = {} + result["private_msg_dict"] = {} await send_board_cast_msg(result) diff --git a/StarRailUID/starrailuid_stamina/__init__.py b/StarRailUID/starrailuid_stamina/__init__.py index 68fe958..97c0863 100644 --- a/StarRailUID/starrailuid_stamina/__init__.py +++ b/StarRailUID/starrailuid_stamina/__init__.py @@ -1,82 +1,83 @@ import asyncio -from gsuid_core.sv import SV +from .draw_stamina_card import get_stamina_img +from .notice import get_notice_list +from .stamina_text import get_stamina_text +from ..utils.error_reply import UID_HINT +from ..utils.sr_prefix import PREFIX + +from gsuid_core.aps import scheduler from gsuid_core.bot import Bot from gsuid_core.gss import gss -from gsuid_core.models import Event -from gsuid_core.aps import scheduler from gsuid_core.logger import logger +from gsuid_core.models import Event from gsuid_core.segment import MessageSegment +from gsuid_core.sv import SV +from gsuid_core.utils.database.api import get_uid +from gsuid_core.utils.database.models import GsBind -from ..utils.convert import get_uid -from .notice import get_notice_list -from ..utils.sr_prefix import PREFIX -from ..utils.error_reply import UID_HINT -from .stamina_text import get_stamina_text -from .draw_stamina_card import get_stamina_img - -sv_get_stamina = SV('sr查询体力') -sv_get_stamina_admin = SV('sr强制推送', pm=1) +sv_get_stamina = SV("sr查询体力") +sv_get_stamina_admin = SV("sr强制推送", pm=1) -@sv_get_stamina.on_fullmatch(f'{PREFIX}当前状态') +@sv_get_stamina.on_fullmatch(f"{PREFIX}当前状态") async def send_daily_info(bot: Bot, ev: Event): - await bot.logger.info('开始执行[sr每日信息文字版]') - uid = await get_uid(bot, ev) + await bot.logger.info("开始执行[sr每日信息文字版]") + uid = await get_uid(bot, ev, GsBind, "sr") if uid is None: return await bot.send(UID_HINT) - await bot.logger.info(f'[sr每日信息文字版]UID: {uid}') + await bot.logger.info(f"[sr每日信息文字版]UID: {uid}") im = await get_stamina_text(uid) await bot.send(im) return None -@sv_get_stamina_admin.on_fullmatch(f'{PREFIX}强制推送体力提醒') +@sv_get_stamina_admin.on_fullmatch(f"{PREFIX}强制推送体力提醒") async def force_notice_job(bot: Bot, ev: Event): - await bot.logger.info('开始执行[sr强制推送体力信息]') + await bot.logger.info("开始执行[sr强制推送体力信息]") await sr_notice_job() -@scheduler.scheduled_job('cron', minute='*/30') +@scheduler.scheduled_job("cron", minute="*/30") async def sr_notice_job(): result = await get_notice_list() - logger.info('[sr推送检查]完成!等待消息推送中...') + logger.info("[sr推送检查]完成!等待消息推送中...") logger.debug(result) # 执行私聊推送 for bot_id in result: for BOT_ID in gss.active_bot: bot = gss.active_bot[BOT_ID] - for user_id in result[bot_id]['direct']: - msg = result[bot_id]['direct'][user_id] - await bot.target_send(msg, 'direct', user_id, bot_id, '', '') + for user_id in result[bot_id]["direct"]: + msg = result[bot_id]["direct"][user_id] + await bot.target_send(msg, "direct", user_id, bot_id, "", "") await asyncio.sleep(0.5) - logger.info('[sr推送检查] 私聊推送完成') - for gid in result[bot_id]['group']: + logger.info("[sr推送检查] 私聊推送完成") + for gid in result[bot_id]["group"]: msg_list = [] - for user_id in result[bot_id]['group'][gid]: + for user_id in result[bot_id]["group"][gid]: msg_list.append(MessageSegment.at(user_id)) - msg = result[bot_id]['group'][gid][user_id] + msg = result[bot_id]["group"][gid][user_id] msg_list.append(MessageSegment.text(msg)) - await bot.target_send(msg_list, 'group', gid, bot_id, '', '') + await bot.target_send(msg_list, "group", gid, bot_id, "", "") await asyncio.sleep(0.5) - logger.info('[sr推送检查] 群聊推送完成') + logger.info("[sr推送检查] 群聊推送完成") @sv_get_stamina.on_fullmatch( ( - f'{PREFIX}每日', - f'{PREFIX}mr', - f'{PREFIX}实时便笺', - f'{PREFIX}便笺', - f'{PREFIX}便签', + f"{PREFIX}每日", + f"{PREFIX}mr", + f"{PREFIX}实时便笺", + f"{PREFIX}便笺", + f"{PREFIX}便签", ) ) async def send_daily_info_pic(bot: Bot, ev: Event): - await bot.logger.info('开始执行[sr每日信息]') + await bot.logger.info("开始执行[sr每日信息]") user_id = ev.at if ev.at else ev.user_id - await bot.logger.info(f'[sr每日信息]QQ号: {user_id}') + await bot.logger.info(f"[sr每日信息]QQ号: {user_id}") im = await get_stamina_img(bot.bot_id, user_id) await bot.send(im) diff --git a/StarRailUID/starrailuid_stamina/draw_stamina_card.py b/StarRailUID/starrailuid_stamina/draw_stamina_card.py index 1a1f982..42f02f6 100644 --- a/StarRailUID/starrailuid_stamina/draw_stamina_card.py +++ b/StarRailUID/starrailuid_stamina/draw_stamina_card.py @@ -3,16 +3,14 @@ from io import BytesIO from pathlib import Path from typing import Optional -import aiohttp from PIL import Image, ImageDraw +import aiohttp from gsuid_core.logger import logger from gsuid_core.utils.database.models import GsBind, GsUser +from gsuid_core.utils.image.convert import convert_img -from ..utils.mys_api import mys_api -from ..utils.image.convert import convert_img from ..sruid_utils.api.mys.models import Expedition from ..starrailuid_config.sr_config import srconfig -from ..utils.image.image_tools import get_simple_bg from ..utils.error_reply import get_error as get_error_msg from ..utils.fonts.starrail_fonts import ( sr_font_22, @@ -21,18 +19,20 @@ from ..utils.fonts.starrail_fonts import ( sr_font_36, sr_font_50, ) +from ..utils.image.image_tools import get_simple_bg +from ..utils.mys_api import mys_api -use_widget = srconfig.get_config('WidgetResin').data +use_widget = srconfig.get_config("WidgetResin").data -TEXT_PATH = Path(__file__).parent / 'texture2D' +TEXT_PATH = Path(__file__).parent / "texture2D" -note_bg = Image.open(TEXT_PATH / 'note_bg.png') -note_travel_bg = Image.open(TEXT_PATH / 'note_travel_bg.png') -warn_pic = Image.open(TEXT_PATH / 'warn.png') +note_bg = Image.open(TEXT_PATH / "note_bg.png") +note_travel_bg = Image.open(TEXT_PATH / "note_travel_bg.png") +warn_pic = Image.open(TEXT_PATH / "warn.png") based_w = 700 based_h = 1200 -white_overlay = Image.new('RGBA', (based_w, based_h), (255, 251, 242, 225)) +white_overlay = Image.new("RGBA", (based_w, based_h), (255, 251, 242, 225)) first_color = (29, 29, 29) second_color = (98, 98, 98) @@ -45,7 +45,7 @@ red_color = (235, 61, 75) def seconds2hours(seconds: int) -> str: m, s = divmod(int(seconds), 60) h, m = divmod(m, 60) - return '%02d:%02d:%02d' % (h, m, s) + return "%02d:%02d:%02d" % (h, m, s) async def download_image(url: str) -> Image.Image: @@ -68,14 +68,14 @@ async def _draw_task_img( for i in range(2): avatar_url = char.avatars[i] image = await download_image(avatar_url) - char_pic = image.convert('RGBA').resize( + char_pic = image.convert("RGBA").resize( (40, 40), Image.Resampling.LANCZOS, # type: ignore ) note_travel_img.paste(char_pic, (495 + 68 * i, 20), char_pic) img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img) - if char.status == 'Finished': - status_mark = '待收取' + if char.status == "Finished": + status_mark = "待收取" else: status_mark = str(remaining_time) img_draw.text( @@ -83,55 +83,55 @@ async def _draw_task_img( expedition_name, font=sr_font_22, fill=white_color, - anchor='lm', + anchor="lm", ) img_draw.text( (380, 830 + index * 80), status_mark, font=sr_font_22, fill=white_color, - anchor='mm', + anchor="mm", ) else: note_travel_img = note_travel_bg.copy() img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img) img_draw.text( (120, 830 + index * 80), - '等待加入探索队列...', + "等待加入探索队列...", font=sr_font_22, fill=white_color, - anchor='lm', + anchor="lm", ) async def get_stamina_img(bot_id: str, user_id: str): try: - uid_list = await GsBind.get_uid_list_by_game(user_id, bot_id, 'sr') - logger.info(f'[每日信息]UID: {uid_list}') + uid_list = await GsBind.get_uid_list_by_game(user_id, bot_id, "sr") + logger.info(f"[每日信息]UID: {uid_list}") if uid_list is None: - return '请先绑定一个UID再来查询哦~' + return "请先绑定一个UID再来查询哦~" # 进行校验UID是否绑定CK useable_uid_list = [] for uid in uid_list: - status = await GsUser.get_user_cookie_by_uid(uid, 'sr') + status = await GsUser.get_user_cookie_by_uid(uid, "sr") if status is not None: useable_uid_list.append(uid) - logger.info(f'[每日信息]可用UID: {useable_uid_list}') + logger.info(f"[每日信息]可用UID: {useable_uid_list}") if len(useable_uid_list) == 0: - return '请先绑定一个可用CK & UID再来查询哦~' + return "请先绑定一个可用CK & UID再来查询哦~" # 开始绘图任务 task = [] img = Image.new( - 'RGBA', (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0) + "RGBA", (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0) ) for uid_index, uid in enumerate(useable_uid_list): task.append(_draw_all_stamina_img(img, uid, uid_index)) await asyncio.gather(*task) res = await convert_img(img) - logger.info('[查询每日信息]绘图已完成,等待发送!') + logger.info("[查询每日信息]绘图已完成,等待发送!") except TypeError: - logger.exception('[查询每日信息]绘图失败!') - res = '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~' + logger.exception("[查询每日信息]绘图失败!") + res = "你绑定过的UID中可能存在过期CK~请重新绑定一下噢~" return res @@ -147,18 +147,18 @@ def get_error(img: Image.Image, uid: str, daily_data: int): # 写UID img_draw.text( (350, 680), - f'UID{uid}', + f"UID{uid}", font=sr_font_26, fill=first_color, - anchor='mm', + anchor="mm", ) error_text = get_error_msg(daily_data) img_draw.text( (350, 650), - f'{error_text}, 错误码{daily_data}', + f"{error_text}, 错误码{daily_data}", font=sr_font_26, fill=red_color, - anchor='mm', + anchor="mm", ) return img @@ -166,7 +166,7 @@ def get_error(img: Image.Image, uid: str, daily_data: int): async def seconds2hours_zhcn(seconds: int) -> str: m, s = divmod(int(seconds), 60) h, m = divmod(m, 60) - return '%02d小时%02d分' % (h, m) + return "%02d小时%02d分" % (h, m) async def draw_stamina_img(sr_uid: str) -> Image.Image: @@ -181,7 +181,7 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image: # daily_data = transform_fake_resin(_daily_data) daily_data = _daily_data else: - daily_data = await mys_api.get_daily_data(sr_uid) + daily_data = await mys_api.get_sr_daily_data(sr_uid) if isinstance(daily_data, int): return get_error(img, sr_uid, daily_data) @@ -194,13 +194,13 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image: nickname = role_basic_info.nickname level = role_basic_info.level else: - nickname = '开拓者' - level = '0' + nickname = "开拓者" + level = "0" # 开拓力 stamina = daily_data.current_stamina max_stamina = daily_data.max_stamina - stamina_str = f'{stamina}/{max_stamina}' + stamina_str = f"{stamina}/{max_stamina}" stamina_percent = stamina / max_stamina if stamina_percent > 0.8: stamina_color = red_color @@ -216,31 +216,23 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image: # 派遣 task_task = [] for i in range(4): - char = ( - daily_data.expeditions[i] - if i < len(daily_data.expeditions) - else None - ) + char = daily_data.expeditions[i] if i < len(daily_data.expeditions) else None task_task.append(_draw_task_img(img, img_draw, i, char)) await asyncio.gather(*task_task) # 绘制树脂圆环 - ring_pic = Image.open(TEXT_PATH / 'ring.apng') - percent = ( - round(stamina_percent * 89) - if round(stamina_percent * 89) <= 89 - else 89 - ) + ring_pic = Image.open(TEXT_PATH / "ring.apng") + percent = round(stamina_percent * 89) if round(stamina_percent * 89) <= 89 else 89 ring_pic.seek(percent) img.paste(ring_pic, (0, 5), ring_pic) # 写树脂剩余时间 img_draw.text( (350, 490), - f'还剩{stamina_recovery_time}', + f"还剩{stamina_recovery_time}", font=sr_font_24, fill=stamina_color, - anchor='mm', + anchor="mm", ) # 写Nickname img_draw.text( @@ -248,23 +240,23 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image: nickname, font=sr_font_36, fill=white_color, - anchor='mm', + anchor="mm", ) # 写开拓等级 img_draw.text( (350, 190), - f'开拓等级{level}', + f"开拓等级{level}", font=sr_font_24, fill=white_color, - anchor='mm', + anchor="mm", ) # 写UID img_draw.text( (350, 663), - f'UID{sr_uid}', + f"UID{sr_uid}", font=sr_font_26, fill=first_color, - anchor='mm', + anchor="mm", ) # 写树脂 img_draw.text( @@ -272,7 +264,7 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image: stamina_str, font=sr_font_50, fill=first_color, - anchor='mm', + anchor="mm", ) return img diff --git a/StarRailUID/starrailuid_stamina/notice.py b/StarRailUID/starrailuid_stamina/notice.py index d2be9cc..8692d7c 100644 --- a/StarRailUID/starrailuid_stamina/notice.py +++ b/StarRailUID/starrailuid_stamina/notice.py @@ -8,11 +8,11 @@ from ..sruid_utils.api.mys.models import DailyNoteData from ..starrailuid_config.sr_config import srconfig from ..utils.mys_api import mys_api -MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n' +MR_NOTICE = "\n可发送[srmr]或者[sr每日]来查看更多信息!\n" NOTICE = { - 'stamina': f'你的开拓力快满啦!{MR_NOTICE}', - 'go': f'你有派遣信息即将可收取!{MR_NOTICE}', + "stamina": f"你的开拓力快满啦!{MR_NOTICE}", + "go": f"你有派遣信息即将可收取!{MR_NOTICE}", } @@ -22,11 +22,11 @@ async def get_notice_list() -> Dict[str, Dict[str, Dict]]: user_list = await GsUser.get_all_push_user_list() for user in user_list: if user.sr_uid is not None: - raw_data = await mys_api.get_daily_data(user.sr_uid) + raw_data = await mys_api.get_sr_daily_data(user.sr_uid) if isinstance(raw_data, int): - logger.error(f'[sr推送提醒]获取{user.sr_uid}的数据失败!') + logger.error(f"[sr推送提醒]获取{user.sr_uid}的数据失败!") continue - push_data = await GsPush.select_data_by_uid(user.sr_uid, 'sr') + push_data = await GsPush.select_data_by_uid(user.sr_uid, "sr") msg_dict = await all_check( user.bot_id, raw_data, @@ -48,59 +48,59 @@ async def all_check( ) -> Dict[str, Dict[str, Dict]]: for mode in NOTICE.keys(): # 检查条件 - if push_data[f'{mode}_is_push'] == 'on': - if srconfig.get_config('CrazyNotice').data: - if not await check(mode, raw_data, push_data[f'{mode}_value']): + if push_data[f"{mode}_is_push"] == "on": + if srconfig.get_config("CrazyNotice").data: + if not await check(mode, raw_data, push_data[f"{mode}_value"]): await GsPush.update_data_by_uid( - uid, bot_id, 'sr', **{f'{mode}_is_push': 'off'} + uid, bot_id, "sr", **{f"{mode}_is_push": "off"} ) continue # 准备推送 - if await check(mode, raw_data, push_data[f'{mode}_value']): - if push_data[f'{mode}_push'] == 'off': + if await check(mode, raw_data, push_data[f"{mode}_value"]): + if push_data[f"{mode}_push"] == "off": pass # on 推送到私聊 else: # 初始化 if bot_id not in msg_dict: - msg_dict[bot_id] = {'direct': {}, 'group': {}} + msg_dict[bot_id] = {"direct": {}, "group": {}} - if push_data[f'{mode}_push'] == 'on': + if push_data[f"{mode}_push"] == "on": # 添加私聊信息 - if user_id not in msg_dict[bot_id]['direct']: - msg_dict[bot_id]['direct'][user_id] = NOTICE[mode] + if user_id not in msg_dict[bot_id]["direct"]: + msg_dict[bot_id]["direct"][user_id] = NOTICE[mode] else: - msg_dict[bot_id]['direct'][user_id] += NOTICE[mode] + msg_dict[bot_id]["direct"][user_id] += NOTICE[mode] await GsPush.update_data_by_uid( - uid, bot_id, 'sr', **{f'{mode}_is_push': 'on'} + uid, bot_id, "sr", **{f"{mode}_is_push": "on"} ) # 群号推送到群聊 else: # 初始化 - gid = push_data[f'{mode}_push'] - if gid not in msg_dict[bot_id]['group']: - msg_dict[bot_id]['group'][gid] = {} + gid = push_data[f"{mode}_push"] + if gid not in msg_dict[bot_id]["group"]: + msg_dict[bot_id]["group"][gid] = {} - if user_id not in msg_dict[bot_id]['group'][gid]: - msg_dict[bot_id]['group'][gid][user_id] = NOTICE[mode] + if user_id not in msg_dict[bot_id]["group"][gid]: + msg_dict[bot_id]["group"][gid][user_id] = NOTICE[mode] else: - msg_dict[bot_id]['group'][gid][user_id] += NOTICE[mode] + msg_dict[bot_id]["group"][gid][user_id] += NOTICE[mode] await GsPush.update_data_by_uid( - uid, bot_id, 'sr', **{f'{mode}_is_push': 'on'} + uid, bot_id, "sr", **{f"{mode}_is_push": "on"} ) return msg_dict async def check(mode: str, data: DailyNoteData, limit: int) -> bool: - if mode == 'resin': + if mode == "resin": if data.current_stamina >= limit: return True if data.current_stamina >= data.max_stamina: return True return False - if mode == 'go': + if mode == "go": for i in data.expeditions: - if i.status == 'Ongoing': + if i.status == "Ongoing": if i.remaining_time <= limit * 60: return True else: diff --git a/StarRailUID/starrailuid_stamina/stamina_text.py b/StarRailUID/starrailuid_stamina/stamina_text.py index 651471c..10a56c0 100644 --- a/StarRailUID/starrailuid_stamina/stamina_text.py +++ b/StarRailUID/starrailuid_stamina/stamina_text.py @@ -2,8 +2,8 @@ from typing import List from gsuid_core.logger import logger -from ..utils.mys_api import mys_api from ..utils.error_reply import get_error +from ..utils.mys_api import mys_api daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数据为准 ============== @@ -16,31 +16,27 @@ daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数 def seconds2hours(seconds: int) -> str: m, s = divmod(int(seconds), 60) h, m = divmod(m, 60) - return '%02d:%02d:%02d' % (h, m, s) + return "%02d:%02d:%02d" % (h, m, s) async def get_stamina_text(uid: str) -> str: try: - dailydata = await mys_api.get_daily_data(uid) + dailydata = await mys_api.get_sr_daily_data(uid) if isinstance(dailydata, int): return get_error(dailydata) max_stamina = dailydata.max_stamina - rec_time = '' + rec_time = "" current_stamina = dailydata.current_stamina if current_stamina < 160: - stamina_recover_time = seconds2hours( - dailydata.stamina_recover_time - ) + stamina_recover_time = seconds2hours(dailydata.stamina_recover_time) next_stamina_rec_time = seconds2hours( 8 * 60 - ( - (dailydata.max_stamina - dailydata.current_stamina) - * 8 - * 60 + (dailydata.max_stamina - dailydata.current_stamina) * 8 * 60 - dailydata.stamina_recover_time ) ) - rec_time = f' ({next_stamina_rec_time}/{stamina_recover_time})' + rec_time = f" ({next_stamina_rec_time}/{stamina_recover_time})" accepted_epedition_num = dailydata.accepted_expedition_num total_expedition_num = dailydata.total_expedition_num @@ -49,16 +45,14 @@ async def get_stamina_text(uid: str) -> str: for expedition in dailydata.expeditions: expedition_name = expedition.name - if expedition.status == 'Finished': - expedition_info.append(f'{expedition_name} 探索完成') + if expedition.status == "Finished": + expedition_info.append(f"{expedition_name} 探索完成") finished_expedition_num += 1 else: remaining_time: str = seconds2hours(expedition.remaining_time) - expedition_info.append( - f'{expedition_name} 剩余时间{remaining_time}' - ) + expedition_info.append(f"{expedition_name} 剩余时间{remaining_time}") - expedition_data = '\n'.join(expedition_info) + expedition_data = "\n".join(expedition_info) return daily_im.format( current_stamina, max_stamina, @@ -69,5 +63,5 @@ async def get_stamina_text(uid: str) -> str: expedition_data, ) except TypeError: - logger.exception('[查询当前状态]查询失败!') - return '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~' + logger.exception("[查询当前状态]查询失败!") + return "你绑定过的UID中可能存在过期CK~请重新绑定一下噢~" diff --git a/StarRailUID/starrailuid_user/__init__.py b/StarRailUID/starrailuid_user/__init__.py index e24450b..914782d 100644 --- a/StarRailUID/starrailuid_user/__init__.py +++ b/StarRailUID/starrailuid_user/__init__.py @@ -7,72 +7,72 @@ from ..utils.message import send_diff_msg from ..utils.sr_prefix import PREFIX from .draw_user_card import get_user_card -sv_user_config = SV('sr用户管理', pm=2) -sv_user_info = SV('sr用户信息') +sv_user_config = SV("sr用户管理", pm=2) +sv_user_info = SV("sr用户信息") -@sv_user_info.on_fullmatch(f'{PREFIX}绑定信息') +@sv_user_info.on_fullmatch(f"{PREFIX}绑定信息") async def send_bind_card(bot: Bot, ev: Event): - await bot.logger.info('sr开始执行[查询用户绑定状态]') + await bot.logger.info("sr开始执行[查询用户绑定状态]") uid_list = await get_user_card(ev.bot_id, ev.user_id) if not uid_list: - return await bot.send('你还没有绑定SR_UID哦!') - await bot.logger.info('sr[查询用户绑定状态]完成!等待图片发送中...') + return await bot.send("你还没有绑定SR_UID哦!") + await bot.logger.info("sr[查询用户绑定状态]完成!等待图片发送中...") await bot.send(uid_list) return None @sv_user_info.on_command( ( - f'{PREFIX}绑定uid', - f'{PREFIX}切换uid', - f'{PREFIX}删除uid', - f'{PREFIX}解绑uid', + f"{PREFIX}绑定uid", + f"{PREFIX}切换uid", + f"{PREFIX}删除uid", + f"{PREFIX}解绑uid", ) ) async def send_link_uid_msg(bot: Bot, ev: Event): - await bot.logger.info('sr开始执行[绑定/解绑用户信息]') + await bot.logger.info("sr开始执行[绑定/解绑用户信息]") qid = ev.user_id - await bot.logger.info(f'sr[绑定/解绑]UserID: {qid}') + await bot.logger.info(f"sr[绑定/解绑]UserID: {qid}") sr_uid = ev.text.strip() if sr_uid and not sr_uid.isdigit(): - return await bot.send('你输入了错误的格式!') + return await bot.send("你输入了错误的格式!") - if '绑定' in ev.command: + if "绑定" in ev.command: data = await GsBind.insert_uid( - qid, ev.bot_id, sr_uid, ev.group_id, 9, game_name='sr' + qid, ev.bot_id, sr_uid, ev.group_id, 9, game_name="sr" ) return await send_diff_msg( bot, data, { - 0: f'✅[崩铁]绑定UID{sr_uid}成功!', - -1: f'❌SR_UID{sr_uid}的位数不正确!', - -2: f'❌SR_UID{sr_uid}已经绑定过了!', - -3: '❌你输入了错误的格式!', + 0: f"✅[崩铁]绑定UID{sr_uid}成功!", + -1: f"❌SR_UID{sr_uid}的位数不正确!", + -2: f"❌SR_UID{sr_uid}已经绑定过了!", + -3: "❌你输入了错误的格式!", }, ) - if '切换' in ev.command: - data = await GsBind.switch_uid_by_game(qid, ev.bot_id, sr_uid, 'sr') + if "切换" in ev.command: + data = await GsBind.switch_uid_by_game(qid, ev.bot_id, sr_uid, "sr") return await send_diff_msg( bot, data, { - 0: f'✅[崩铁]切换uid{sr_uid}成功!', - -1: '❌[崩铁]不存在绑定记录!', - -2: '❌[崩铁]请绑定两个以上UID再进行切换!', - -3: '❌[崩铁]请绑定两个以上UID再进行切换!', + 0: f"✅[崩铁]切换uid{sr_uid}成功!", + -1: "❌[崩铁]不存在绑定记录!", + -2: "❌[崩铁]请绑定两个以上UID再进行切换!", + -3: "❌[崩铁]请绑定两个以上UID再进行切换!", }, ) - data = await GsBind.delete_uid(qid, ev.bot_id, sr_uid, 'sr') + data = await GsBind.delete_uid(qid, ev.bot_id, sr_uid, "sr") return await send_diff_msg( bot, data, { - 0: f'✅[崩铁]删除UID{sr_uid}成功!', - -1: f'❌[崩铁]该UID{sr_uid}不在已绑定列表中!', + 0: f"✅[崩铁]删除UID{sr_uid}成功!", + -1: f"❌[崩铁]该UID{sr_uid}不在已绑定列表中!", }, ) diff --git a/StarRailUID/starrailuid_wiki/__init__.py b/StarRailUID/starrailuid_wiki/__init__.py index dccc812..3dcb0b2 100644 --- a/StarRailUID/starrailuid_wiki/__init__.py +++ b/StarRailUID/starrailuid_wiki/__init__.py @@ -20,104 +20,104 @@ from ..utils.resource.RESOURCE_PATH import ( WIKI_MATERIAL_FOR_ROLE, ) -sv_sr_wiki = SV('星铁WIKI') -sv_sr_guide = SV('星铁攻略') +sv_sr_wiki = SV("星铁WIKI") +sv_sr_guide = SV("星铁攻略") -@sv_sr_wiki.on_prefix('sr角色图鉴') +@sv_sr_wiki.on_prefix("sr角色图鉴") async def send_role_wiki_pic(bot: Bot, ev: Event): - char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) - await bot.logger.info(f'开始获取{char_name}图鉴') - if '开拓者' in str(char_name): - char_name = '开拓者' + char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text)) + await bot.logger.info(f"开始获取{char_name}图鉴") + if "开拓者" in str(char_name): + char_name = "开拓者" char_id = await name_to_avatar_id(char_name) - if char_id == '': + if char_id == "": char_name = await alias_to_char_name(char_name) char_id = await name_to_avatar_id(char_name) - img = WIKI_ROLE_PATH / f'{char_id}.png' + img = WIKI_ROLE_PATH / f"{char_id}.png" if img.exists(): img = await convert_img(img) - await bot.logger.info(f'获得{char_name}图鉴图片成功!') + await bot.logger.info(f"获得{char_name}图鉴图片成功!") await bot.send(img) else: - await bot.logger.warning(f'未找到{char_name}图鉴图片') + await bot.logger.warning(f"未找到{char_name}图鉴图片") -@sv_sr_guide.on_prefix('sr角色攻略') +@sv_sr_guide.on_prefix("sr角色攻略") async def send_role_guide_pic(bot: Bot, ev: Event): - char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) - await bot.logger.info(f'开始获取{char_name}图鉴') - if '开拓者' in str(char_name): - char_name = '开拓者' + char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text)) + await bot.logger.info(f"开始获取{char_name}图鉴") + if "开拓者" in str(char_name): + char_name = "开拓者" char_id = await name_to_avatar_id(char_name) - if char_id == '': + if char_id == "": char_name = await alias_to_char_name(char_name) char_id = await name_to_avatar_id(char_name) - img = GUIDE_CHARACTER_PATH / f'{char_id}.png' + img = GUIDE_CHARACTER_PATH / f"{char_id}.png" if img.exists(): img = await convert_img(img) - await bot.logger.info(f'获得{char_id}图鉴图片成功!') + await bot.logger.info(f"获得{char_id}图鉴图片成功!") await bot.send(img) else: - await bot.logger.warning(f'未找到{char_id}图鉴图片') + await bot.logger.warning(f"未找到{char_id}图鉴图片") -@sv_sr_guide.on_prefix('sr光锥攻略') +@sv_sr_guide.on_prefix("sr光锥攻略") async def send_weapon_guide_pic(bot: Bot, ev: Event): - msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) - await bot.logger.info(f'开始获取{msg}图鉴') + msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text)) + await bot.logger.info(f"开始获取{msg}图鉴") light_cone_id = await name_to_weapon_id(msg) - img = GUIDE_LIGHT_CONE_PATH / f'{light_cone_id}.png' + img = GUIDE_LIGHT_CONE_PATH / f"{light_cone_id}.png" if img.exists(): img = await convert_img(img) - await bot.logger.info(f'获得{light_cone_id}光锥图片成功!') + await bot.logger.info(f"获得{light_cone_id}光锥图片成功!") await bot.send(img) else: - await bot.logger.warning(f'未找到{light_cone_id}光锥图片') + await bot.logger.warning(f"未找到{light_cone_id}光锥图片") -@sv_sr_wiki.on_prefix('sr遗器') +@sv_sr_wiki.on_prefix("sr遗器") async def send_relic_wiki_pic(bot: Bot, ev: Event): - msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) - await bot.logger.info(f'开始获取{msg}遗器') + msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text)) + await bot.logger.info(f"开始获取{msg}遗器") set_id = await name_to_relic_set_id(msg) - img = WIKI_RELIC_PATH / f'{set_id}.png' + img = WIKI_RELIC_PATH / f"{set_id}.png" if img.exists(): img = await convert_img(img) - await bot.logger.info(f'获得{msg}遗器图片成功!') + await bot.logger.info(f"获得{msg}遗器图片成功!") await bot.send(img) else: - await bot.logger.warning(f'未找到{msg}遗器图片') + await bot.logger.warning(f"未找到{msg}遗器图片") -@sv_sr_wiki.on_prefix('sr突破材料') +@sv_sr_wiki.on_prefix("sr突破材料") async def send_material_for_role_wiki_pic(bot: Bot, ev: Event): - char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) - await bot.logger.info(f'开始获取{char_name}突破材料') - if '开拓者' in str(char_name): - char_name = '开拓者' + char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text)) + await bot.logger.info(f"开始获取{char_name}突破材料") + if "开拓者" in str(char_name): + char_name = "开拓者" char_id = await name_to_avatar_id(char_name) - if char_id == '': + if char_id == "": char_name = await alias_to_char_name(char_name) char_id = await name_to_avatar_id(char_name) - img = WIKI_MATERIAL_FOR_ROLE / f'{char_id}.png' + img = WIKI_MATERIAL_FOR_ROLE / f"{char_id}.png" if img.exists(): img = await convert_img(img) - await bot.logger.info(f'获得{char_name}突破材料图片成功!') + await bot.logger.info(f"获得{char_name}突破材料图片成功!") await bot.send(img) else: - await bot.logger.warning(f'未找到{char_name}突破材料图片') + await bot.logger.warning(f"未找到{char_name}突破材料图片") -@sv_sr_wiki.on_prefix('sr武器') +@sv_sr_wiki.on_prefix("sr武器") async def send_light_cone_wiki_pic(bot: Bot, ev: Event): - msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text)) - await bot.logger.info(f'开始获取{msg}武器') + msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text)) + await bot.logger.info(f"开始获取{msg}武器") light_cone_id = await name_to_weapon_id(msg) - img = WIKI_LIGHT_CONE_PATH / f'{light_cone_id}.png' + img = WIKI_LIGHT_CONE_PATH / f"{light_cone_id}.png" if img.exists(): img = await convert_img(img) - await bot.logger.info(f'获得{msg}武器图片成功!') + await bot.logger.info(f"获得{msg}武器图片成功!") await bot.send(img) else: - await bot.logger.warning(f'未找到{msg}武器图片') + await bot.logger.warning(f"未找到{msg}武器图片") diff --git a/StarRailUID/utils/convert.py b/StarRailUID/utils/convert.py index d08a3e2..f3499bc 100644 --- a/StarRailUID/utils/convert.py +++ b/StarRailUID/utils/convert.py @@ -1,36 +1,12 @@ -import re -from typing import Tuple, Union, Optional, overload +from typing import Optional, Tuple, Union from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.utils.database.api import get_uid as get_uid_db from gsuid_core.utils.database.models import GsBind -@overload async def get_uid( - bot: Bot, ev: Event, get_user_id: bool = False, only_uid: bool = False -) -> Optional[str]: ... - - -@overload -async def get_uid( - bot: Bot, ev: Event, get_user_id: bool = True, only_uid: bool = False -) -> Tuple[Optional[str], str]: ... - - -async def get_uid( - bot: Bot, ev: Event, get_user_id: bool = False, only_uid: bool = False + bot: Bot, ev: Event, get_user_id: bool = False ) -> Union[Optional[str], Tuple[Optional[str], str]]: - uid_data = re.findall(r'\d{9}', ev.text) - user_id = ev.at if ev.at else ev.user_id - if uid_data: - sr_uid: Optional[str] = uid_data[0] - if sr_uid: - ev.text = ev.text.replace(sr_uid, '') - else: - sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr') - if only_uid: - sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr') - if get_user_id: - return sr_uid, user_id - return sr_uid + return await get_uid_db(bot, ev, GsBind, "sr", get_user_id) # type: ignore diff --git a/StarRailUID/utils/error_reply.py b/StarRailUID/utils/error_reply.py index 2461cb2..5a40dea 100644 --- a/StarRailUID/utils/error_reply.py +++ b/StarRailUID/utils/error_reply.py @@ -1,16 +1,16 @@ from typing import Union -UID_HINT = '你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑定!' -MYS_HINT = '你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!' +UID_HINT = "你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑定!" +MYS_HINT = "你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!" CK_HINT = """你还没有绑定过Cookie哦!发送【ck帮助】获取帮助! 警告:绑定Cookie可能会带来未知的账号风险,请确保信任机器人管理员""" -CHAR_HINT = '您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !' +CHAR_HINT = "您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !" VERIFY_HINT = """出现验证码! 如已绑定CK: 请至米游社软件->我的->我的角色处解锁验证码 (可使用[gs关闭推送]命令关闭体力推送以减少出现验证码风险) 如未绑定CK: 可联系管理员使用[gs清除缓存]命令 """ -SK_HINT = '你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK' +SK_HINT = "你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK" UPDATE_HINT = """更新失败!更多错误信息请查看控制台... >> 可以尝试使用 >> [gs强制更新](危险) @@ -21,27 +21,27 @@ def get_error(retcode: Union[int, str]) -> str: if retcode == -51: return CK_HINT if retcode == -100: - return '您的cookie已经失效, 请重新获取!' + return "您的cookie已经失效, 请重新获取!" if retcode == 10001: - return '您的cookie已经失效, 请重新获取!' + return "您的cookie已经失效, 请重新获取!" if retcode == 10101: - return '当前查询CK已超过每日30次上限!' + return "当前查询CK已超过每日30次上限!" if retcode == 10102: - return '当前查询id已经设置了隐私, 无法查询!' + return "当前查询id已经设置了隐私, 无法查询!" if retcode == 1034: return VERIFY_HINT if retcode == -10001: - return '请求体出错, 请检查具体实现代码...' + return "请求体出错, 请检查具体实现代码..." if retcode == 10104: return CK_HINT if retcode == -512009: - return '[留影叙佳期]已经获取过该内容~!' + return "[留影叙佳期]已经获取过该内容~!" if retcode == -201: - return '你的账号可能已被封禁, 请联系米游社客服...' + return "你的账号可能已被封禁, 请联系米游社客服..." if retcode == -501101: - return '当前角色冒险等阶未达到10级, 暂时无法参加此活动...' + return "当前角色冒险等阶未达到10级, 暂时无法参加此活动..." if retcode == 400: - return '[MINIGG]暂未找到此内容...' + return "[MINIGG]暂未找到此内容..." if retcode == -400: - return '请输入更详细的名称...' - return f'API报错, 错误码为{retcode}!' + return "请输入更详细的名称..." + return f"API报错, 错误码为{retcode}!" diff --git a/StarRailUID/utils/excel/model.py b/StarRailUID/utils/excel/model.py index 26aa542..df84b85 100644 --- a/StarRailUID/utils/excel/model.py +++ b/StarRailUID/utils/excel/model.py @@ -88,8 +88,6 @@ class SingleRelicSubAffix(Struct): AvatarPromotionConfig = convert(AvatarPromotion, List[SingleAvatarPromotion]) -EquipmentPromotionConfig = convert( - EquipmentPromotion, List[SingleEquipmentPromotion] -) +EquipmentPromotionConfig = convert(EquipmentPromotion, List[SingleEquipmentPromotion]) RelicMainAffixConfig = convert(RelicMainAffix, List[SingleRelicMainAffix]) RelicSubAffixConfig = convert(RelicSubAffix, List[SingleRelicSubAffix]) diff --git a/StarRailUID/utils/excel/read_excel.py b/StarRailUID/utils/excel/read_excel.py index 00cf9a3..e17547a 100644 --- a/StarRailUID/utils/excel/read_excel.py +++ b/StarRailUID/utils/excel/read_excel.py @@ -3,17 +3,17 @@ from pathlib import Path EXCEL = Path(__file__).parent -with Path.open(EXCEL / 'RelicMainAffixConfig.json', encoding='utf8') as f: +with Path.open(EXCEL / "RelicMainAffixConfig.json", encoding="utf8") as f: RelicMainAffix = json.load(f) -with Path.open(EXCEL / 'RelicSubAffixConfig.json', encoding='utf8') as f: +with Path.open(EXCEL / "RelicSubAffixConfig.json", encoding="utf8") as f: RelicSubAffix = json.load(f) -with Path.open(EXCEL / 'AvatarPromotionConfig.json', encoding='utf8') as f: +with Path.open(EXCEL / "AvatarPromotionConfig.json", encoding="utf8") as f: AvatarPromotion = json.load(f) -with Path.open(EXCEL / 'EquipmentPromotionConfig.json', encoding='utf8') as f: +with Path.open(EXCEL / "EquipmentPromotionConfig.json", encoding="utf8") as f: EquipmentPromotion = json.load(f) -with Path.open(EXCEL / 'light_cone_ranks.json', encoding='utf8') as f: +with Path.open(EXCEL / "light_cone_ranks.json", encoding="utf8") as f: light_cone_ranks = json.load(f) diff --git a/StarRailUID/utils/fonts/first_world.py b/StarRailUID/utils/fonts/first_world.py index 5fdaa7d..80a1def 100644 --- a/StarRailUID/utils/fonts/first_world.py +++ b/StarRailUID/utils/fonts/first_world.py @@ -2,7 +2,7 @@ from pathlib import Path from PIL import ImageFont -FONT_ORIGIN_PATH = Path(__file__).parent / 'FirstWorld.ttf' +FONT_ORIGIN_PATH = Path(__file__).parent / "FirstWorld.ttf" def first_word_origin(size: int) -> ImageFont.FreeTypeFont: diff --git a/StarRailUID/utils/fonts/starrail_fonts.py b/StarRailUID/utils/fonts/starrail_fonts.py index 0316bac..89f27f2 100644 --- a/StarRailUID/utils/fonts/starrail_fonts.py +++ b/StarRailUID/utils/fonts/starrail_fonts.py @@ -2,7 +2,7 @@ from pathlib import Path from PIL import ImageFont -FONT_ORIGIN_PATH = Path(__file__).parent / 'starrail_origin.ttf' +FONT_ORIGIN_PATH = Path(__file__).parent / "starrail_origin.ttf" def starrail_font_origin(size: int) -> ImageFont.FreeTypeFont: diff --git a/StarRailUID/utils/image/convert.py b/StarRailUID/utils/image/convert.py deleted file mode 100644 index 2535522..0000000 --- a/StarRailUID/utils/image/convert.py +++ /dev/null @@ -1,107 +0,0 @@ -from io import BytesIO -from pathlib import Path -from base64 import b64encode -from typing import Union, overload - -import aiofiles -from PIL import Image, ImageFont - - -@overload -async def convert_img(img: Image.Image, is_base64: bool = False) -> bytes: ... - - -@overload -async def convert_img(img: Image.Image, is_base64: bool = True) -> str: ... - - -@overload -async def convert_img(img: bytes, is_base64: bool = False) -> str: ... - - -@overload -async def convert_img(img: Path, is_base64: bool = False) -> str: ... - - -async def convert_img( - img: Union[Image.Image, str, Path, bytes], is_base64: bool = False -) -> Union[str, bytes]: - """ - :说明: - 将PIL.Image对象转换为bytes或者base64格式。 - :参数: - * img (Image): 图片。 - * is_base64 (bool): 是否转换为base64格式, 不填默认转为bytes。 - :返回: - * res: bytes对象或base64编码图片。 - """ - if isinstance(img, Image.Image): - img = img.convert('RGB') - result_buffer = BytesIO() - img.save(result_buffer, format='PNG', quality=80, subsampling=0) - res = result_buffer.getvalue() - if is_base64: - res = 'base64://' + b64encode(res).decode() - return res - if isinstance(img, bytes): - pass - else: - async with aiofiles.open(img, 'rb') as fp: - img = await fp.read() - return f'base64://{b64encode(img).decode()}' - - -async def str_lenth(r: str, size: int, limit: int = 540) -> str: - result = '' - temp = 0 - for i in r: - if i == '\n': - temp = 0 - result += i - continue - - if temp >= limit: - result += '\n' + i - temp = 0 - else: - result += i - - if i.isdigit(): - temp += round(size / 10 * 6) - elif i == '/': - temp += round(size / 10 * 2.2) - elif i == '.': - temp += round(size / 10 * 3) - elif i == '%': - temp += round(size / 10 * 9.4) - else: - temp += size - return result - - -def get_str_size( - r: str, font: ImageFont.FreeTypeFont, limit: int = 540 -) -> str: - result = '' - line = '' - for i in r: - if i == '\n': - result += f'{line}\n' - line = '' - continue - - line += i - if hasattr(font, 'getsize'): - size, _ = font.getsize(line) # type: ignore - else: - size, _, _, _ = font.getbbox(line) - if size >= limit: - result += f'{line}\n' - line = '' - result += line - return result - - -def get_height(content: str, size: int) -> int: - line_count = content.count('\n') - return (line_count + 1) * size diff --git a/StarRailUID/utils/image/image_tools.py b/StarRailUID/utils/image/image_tools.py index 504842e..d3df96e 100644 --- a/StarRailUID/utils/image/image_tools.py +++ b/StarRailUID/utils/image/image_tools.py @@ -7,9 +7,9 @@ from gsuid_core.utils.image.image_tools import TEXT_PATH, CustomizeImage from ..resource.RESOURCE_PATH import CU_BG_PATH from ...starrailuid_config.sr_config import srconfig -BG_PATH = Path(__file__).parent / 'bg' -NM_BG_PATH = BG_PATH / 'nm_bg' -SP_BG_PATH = BG_PATH / 'sp_bg' +BG_PATH = Path(__file__).parent / "bg" +NM_BG_PATH = BG_PATH / "nm_bg" +SP_BG_PATH = BG_PATH / "sp_bg" if list(CU_BG_PATH.iterdir()) != []: bg_path = CU_BG_PATH @@ -35,10 +35,10 @@ async def get_color_bg( bg: Optional[str] = None, without_mask: bool = False, ) -> Image.Image: - image = '' - if bg and srconfig.get_config('DefaultBaseBG').data: - path = SP_BG_PATH / f'{bg}.jpg' - path2 = CU_BG_PATH / f'{bg}.jpg' + image = "" + if bg and srconfig.get_config("DefaultBaseBG").data: + path = SP_BG_PATH / f"{bg}.jpg" + path2 = CU_BG_PATH / f"{bg}.jpg" if path2.exists(): image = Image.open(path2) elif path.exists(): @@ -47,9 +47,7 @@ async def get_color_bg( img = CI_img.get_image(image, based_w, based_h) color = CI_img.get_bg_color(img) if not without_mask: - color_mask = Image.new('RGBA', (based_w, based_h), color) - enka_mask = Image.open(TEXT_PATH / 'bg_mask.png').resize( - (based_w, based_h) - ) + color_mask = Image.new("RGBA", (based_w, based_h), color) + enka_mask = Image.open(TEXT_PATH / "bg_mask.png").resize((based_w, based_h)) img.paste(color_mask, (0, 0), enka_mask) return img diff --git a/StarRailUID/utils/map/SR_MAP_PATH.py b/StarRailUID/utils/map/SR_MAP_PATH.py index 583e22b..7b299fd 100644 --- a/StarRailUID/utils/map/SR_MAP_PATH.py +++ b/StarRailUID/utils/map/SR_MAP_PATH.py @@ -12,36 +12,34 @@ class RelicSetStatusAdd(Struct): Value: float -MAP = Path(__file__).parent / 'data' +MAP = Path(__file__).parent / "data" version = StarRail_version -avatarId2Name_fileName = f'avatarId2Name_mapping_{version}.json' -avatarId2EnName_fileName = f'avatarId2EnName_mapping_{version}.json' -EquipmentID2Name_fileName = f'EquipmentID2Name_mapping_{version}.json' -EquipmentID2EnName_fileName = f'EquipmentID2EnName_mapping_{version}.json' -skillId2Name_fileName = f'skillId2Name_mapping_{version}.json' -skillId2Type_fileName = f'skillId2Type_mapping_{version}.json' -Property2Name_fileName = f'Property2Name_mapping_{version}.json' -RelicId2SetId_fileName = f'RelicId2SetId_mapping_{version}.json' -SetId2Name_fileName = f'SetId2Name_mapping_{version}.json' -rankId2Name_fileName = f'rankId2Name_mapping_{version}.json' -characterSkillTree_fileName = f'characterSkillTree_mapping_{version}.json' -avatarId2DamageType_fileName = f'avatarId2DamageType_mapping_{version}.json' -avatarId2Rarity_fileName = f'avatarId2Rarity_mapping_{version}.json' +avatarId2Name_fileName = f"avatarId2Name_mapping_{version}.json" +avatarId2EnName_fileName = f"avatarId2EnName_mapping_{version}.json" +EquipmentID2Name_fileName = f"EquipmentID2Name_mapping_{version}.json" +EquipmentID2EnName_fileName = f"EquipmentID2EnName_mapping_{version}.json" +skillId2Name_fileName = f"skillId2Name_mapping_{version}.json" +skillId2Type_fileName = f"skillId2Type_mapping_{version}.json" +Property2Name_fileName = f"Property2Name_mapping_{version}.json" +RelicId2SetId_fileName = f"RelicId2SetId_mapping_{version}.json" +SetId2Name_fileName = f"SetId2Name_mapping_{version}.json" +rankId2Name_fileName = f"rankId2Name_mapping_{version}.json" +characterSkillTree_fileName = f"characterSkillTree_mapping_{version}.json" +avatarId2DamageType_fileName = f"avatarId2DamageType_mapping_{version}.json" +avatarId2Rarity_fileName = f"avatarId2Rarity_mapping_{version}.json" EquipmentID2AbilityProperty_fileName = ( - f'EquipmentID2AbilityProperty_mapping_{version}.json' + f"EquipmentID2AbilityProperty_mapping_{version}.json" ) -RelicSetSkill_fileName = f'RelicSetSkill_mapping_{version}.json' -skillId2AttackType_fileName = f'skillId2AttackType_mapping_{version}.json' -EquipmentID2Rarity_fileName = f'EquipmentID2Rarity_mapping_{version}.json' -RelicId2Rarity_fileName = f'RelicId2Rarity_mapping_{version}.json' -ItemId2Name_fileName = f'ItemId2Name_mapping_{version}.json' -RelicId2MainAffixGroup_fileName = ( - f'RelicId2MainAffixGroup_mapping_{version}.json' -) -AvatarRelicScore_fileName = 'AvatarRelicScore.json' -avatarRankSkillUp_fileName = f'avatarRankSkillUp_mapping_{version}.json' +RelicSetSkill_fileName = f"RelicSetSkill_mapping_{version}.json" +skillId2AttackType_fileName = f"skillId2AttackType_mapping_{version}.json" +EquipmentID2Rarity_fileName = f"EquipmentID2Rarity_mapping_{version}.json" +RelicId2Rarity_fileName = f"RelicId2Rarity_mapping_{version}.json" +ItemId2Name_fileName = f"ItemId2Name_mapping_{version}.json" +RelicId2MainAffixGroup_fileName = f"RelicId2MainAffixGroup_mapping_{version}.json" +AvatarRelicScore_fileName = "AvatarRelicScore.json" +avatarRankSkillUp_fileName = f"avatarRankSkillUp_mapping_{version}.json" class TS(TypedDict): @@ -54,51 +52,49 @@ class LU(TypedDict): num: int -with Path.open(MAP / avatarId2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / avatarId2Name_fileName, encoding="UTF-8") as f: avatarId2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / avatarId2EnName_fileName, encoding='UTF-8') as f: +with Path.open(MAP / avatarId2EnName_fileName, encoding="UTF-8") as f: avatarId2EnName = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / EquipmentID2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / EquipmentID2Name_fileName, encoding="UTF-8") as f: EquipmentID2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / EquipmentID2EnName_fileName, encoding='UTF-8') as f: +with Path.open(MAP / EquipmentID2EnName_fileName, encoding="UTF-8") as f: EquipmentID2EnName = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / skillId2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / skillId2Name_fileName, encoding="UTF-8") as f: skillId2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / skillId2Type_fileName, encoding='UTF-8') as f: +with Path.open(MAP / skillId2Type_fileName, encoding="UTF-8") as f: skillId2Effect = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / Property2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / Property2Name_fileName, encoding="UTF-8") as f: Property2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / RelicId2SetId_fileName, encoding='UTF-8') as f: +with Path.open(MAP / RelicId2SetId_fileName, encoding="UTF-8") as f: RelicId2SetId = msgjson.decode(f.read(), type=Dict[str, int]) -with Path.open(MAP / SetId2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / SetId2Name_fileName, encoding="UTF-8") as f: SetId2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / rankId2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / rankId2Name_fileName, encoding="UTF-8") as f: rankId2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / characterSkillTree_fileName, encoding='UTF-8') as f: +with Path.open(MAP / characterSkillTree_fileName, encoding="UTF-8") as f: characterSkillTree = msgjson.decode(f.read(), type=Dict[str, Dict]) -with Path.open(MAP / avatarId2DamageType_fileName, encoding='UTF-8') as f: +with Path.open(MAP / avatarId2DamageType_fileName, encoding="UTF-8") as f: avatarId2DamageType = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / 'char_alias.json', encoding='UTF-8') as f: +with Path.open(MAP / "char_alias.json", encoding="UTF-8") as f: alias_data = msgjson.decode(f.read(), type=Dict[str, Dict[str, List]]) -with Path.open(MAP / avatarId2Rarity_fileName, encoding='UTF-8') as f: +with Path.open(MAP / avatarId2Rarity_fileName, encoding="UTF-8") as f: avatarId2Rarity = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open( - MAP / EquipmentID2AbilityProperty_fileName, encoding='UTF-8' -) as f: +with Path.open(MAP / EquipmentID2AbilityProperty_fileName, encoding="UTF-8") as f: EquipmentID2AbilityProperty = msgjson.decode( f.read(), type=Dict[str, Dict[str, List]] ) @@ -107,25 +103,23 @@ with Path.open( # RelicSetSkill = convert(json.load(f), Dict[str, Dict[str, object]]) # print(RelicSetSkill) -with Path.open(MAP / skillId2AttackType_fileName, encoding='UTF-8') as f: +with Path.open(MAP / skillId2AttackType_fileName, encoding="UTF-8") as f: skillId2AttackType = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / EquipmentID2Rarity_fileName, encoding='UTF-8') as f: +with Path.open(MAP / EquipmentID2Rarity_fileName, encoding="UTF-8") as f: EquipmentID2Rarity = msgjson.decode(f.read(), type=Dict[str, int]) -with Path.open(MAP / RelicId2Rarity_fileName, encoding='UTF-8') as f: +with Path.open(MAP / RelicId2Rarity_fileName, encoding="UTF-8") as f: RelicId2Rarity = msgjson.decode(f.read(), type=Dict[str, int]) -with Path.open(MAP / ItemId2Name_fileName, encoding='UTF-8') as f: +with Path.open(MAP / ItemId2Name_fileName, encoding="UTF-8") as f: ItemId2Name = msgjson.decode(f.read(), type=Dict[str, str]) -with Path.open(MAP / RelicId2MainAffixGroup_fileName, encoding='UTF-8') as f: +with Path.open(MAP / RelicId2MainAffixGroup_fileName, encoding="UTF-8") as f: RelicId2MainAffixGroup = msgjson.decode(f.read(), type=Dict[str, int]) -with Path.open(MAP / AvatarRelicScore_fileName, encoding='UTF-8') as f: +with Path.open(MAP / AvatarRelicScore_fileName, encoding="UTF-8") as f: AvatarRelicScore = msgjson.decode(f.read(), type=List[Dict]) -with Path.open(MAP / avatarRankSkillUp_fileName, encoding='UTF-8') as f: - AvatarRankSkillUp = msgjson.decode( - f.read(), type=Dict[str, Union[List[LU], None]] - ) +with Path.open(MAP / avatarRankSkillUp_fileName, encoding="UTF-8") as f: + AvatarRankSkillUp = msgjson.decode(f.read(), type=Dict[str, Union[List[LU], None]]) diff --git a/StarRailUID/utils/map/gen.py b/StarRailUID/utils/map/gen.py index 5d3737e..b31d08f 100644 --- a/StarRailUID/utils/map/gen.py +++ b/StarRailUID/utils/map/gen.py @@ -1,54 +1,54 @@ import json -with open('./data/characters.json', 'r', encoding='utf8') as f: +with open("./data/characters.json", "r", encoding="utf8") as f: characters = json.load(f) -with open('./data/character_ranks.json', 'r', encoding='utf8') as f: +with open("./data/character_ranks.json", "r", encoding="utf8") as f: character_ranks = json.load(f) -with open('./data/character_skills.json', 'r', encoding='utf8') as f: +with open("./data/character_skills.json", "r", encoding="utf8") as f: character_skills = json.load(f) -with open('./data/character_skill_trees.json', 'r', encoding='utf8') as f: +with open("./data/character_skill_trees.json", "r", encoding="utf8") as f: character_skill_trees = json.load(f) -with open('./data/AvatarConfig.json', 'r', encoding='utf8') as f: +with open("./data/AvatarConfig.json", "r", encoding="utf8") as f: AvatarConfig = json.load(f) -with open('./data/TextMapCN.json', 'r', encoding='utf8') as f: +with open("./data/TextMapCN.json", "r", encoding="utf8") as f: TextMapCN = json.load(f) -with open('./data/TextMapEN.json', 'r', encoding='utf8') as f: +with open("./data/TextMapEN.json", "r", encoding="utf8") as f: TextMapEN = json.load(f) -with open('./data/EquipmentConfig.json', 'r', encoding='utf8') as f: +with open("./data/EquipmentConfig.json", "r", encoding="utf8") as f: EquipmentConfig = json.load(f) -with open('./data/AvatarSkillConfig.json', 'r', encoding='utf8') as f: +with open("./data/AvatarSkillConfig.json", "r", encoding="utf8") as f: AvatarSkillConfig = json.load(f) -with open('./data/AvatarPropertyConfig.json', 'r', encoding='utf8') as f: +with open("./data/AvatarPropertyConfig.json", "r", encoding="utf8") as f: AvatarPropertyConfig = json.load(f) -with open('./data/EquipmentSkillConfig.json', 'r', encoding='utf8') as f: +with open("./data/EquipmentSkillConfig.json", "r", encoding="utf8") as f: EquipmentSkillConfig = json.load(f) -with open('./data/RelicConfig.json', 'r', encoding='utf8') as f: +with open("./data/RelicConfig.json", "r", encoding="utf8") as f: RelicConfig = json.load(f) -with open('./data/RelicSetConfig.json', 'r', encoding='utf8') as f: +with open("./data/RelicSetConfig.json", "r", encoding="utf8") as f: RelicSetConfig = json.load(f) -with open('./data/RelicSetSkillConfig.json', 'r', encoding='utf8') as f: +with open("./data/RelicSetSkillConfig.json", "r", encoding="utf8") as f: RelicSetSkillConfig = json.load(f) -with open('./data/light_cones.json', 'r', encoding='utf8') as f: +with open("./data/light_cones.json", "r", encoding="utf8") as f: light_cones = json.load(f) -with open('./data/relics_new.json', 'r', encoding='utf8') as f: +with open("./data/relics_new.json", "r", encoding="utf8") as f: relics_new = json.load(f) -with open('./data/ItemConfigRelic.json', 'r', encoding='utf8') as f: +with open("./data/ItemConfigRelic.json", "r", encoding="utf8") as f: ItemConfigRelic = json.load(f) avatarId2Name = {} @@ -74,32 +74,32 @@ RelicId2MainAffixGroup = {} for char in characters: char_item = characters[char] - rank_list = characters[char]['ranks'] - rarity = characters[char]['rarity'] + rank_list = characters[char]["ranks"] + rarity = characters[char]["rarity"] avatarId2Rarity[char] = str(rarity) for rank in rank_list: if character_ranks.get(str(rank)): eidolon = character_ranks[str(rank)] - rank_id = eidolon['id'] - rank_name = eidolon['name'] + rank_id = eidolon["id"] + rank_name = eidolon["name"] rankId2Name[rank_id] = rank_name for item in AvatarConfig: avatar_item = AvatarConfig[item] - avatar_id = avatar_item['AvatarID'] - avatar_name_hash = avatar_item['AvatarName']['Hash'] - avatar_damage_type = avatar_item['DamageType'] - avatar_en_name = '' - avatar_name = '' + avatar_id = avatar_item["AvatarID"] + avatar_name_hash = avatar_item["AvatarName"]["Hash"] + avatar_damage_type = avatar_item["DamageType"] + avatar_en_name = "" + avatar_name = "" for item in TextMapCN: if str(item) == str(avatar_name_hash): avatar_name = TextMapCN[item] - if avatar_name == '{NICKNAME}': - avatar_name = '开拓者' + if avatar_name == "{NICKNAME}": + avatar_name = "开拓者" break for item in TextMapEN: if str(item) == str(avatar_name_hash): - avatar_en_name = TextMapEN[item].replace(' ', '') + avatar_en_name = TextMapEN[item].replace(" ", "") break avatarId2EnName[avatar_id] = avatar_en_name avatarId2Name[avatar_id] = avatar_name @@ -108,9 +108,9 @@ for item in AvatarConfig: for item in EquipmentConfig: equipment_item = EquipmentConfig[item] - equipment_id = equipment_item['EquipmentID'] - equipment_name_hash = equipment_item['EquipmentName']['Hash'] - equipment_name = '' + equipment_id = equipment_item["EquipmentID"] + equipment_name_hash = equipment_item["EquipmentName"]["Hash"] + equipment_name = "" for item in TextMapCN: if str(item) == str(equipment_name_hash): equipment_name = TextMapCN[item] @@ -122,30 +122,30 @@ for item in EquipmentSkillConfig: equipment_item = EquipmentSkillConfig[item] EquipmentID2AbilityProperty[str(item)] = {} for i in equipment_item: - equipment_ability_property = equipment_item[str(i)]['AbilityProperty'] + equipment_ability_property = equipment_item[str(i)]["AbilityProperty"] EquipmentID2AbilityProperty[str(item)][i] = equipment_ability_property for item in EquipmentConfig: equipment_item = EquipmentConfig[item] - equipment_id = equipment_item['EquipmentID'] - equipment_name_hash = equipment_item['EquipmentName']['Hash'] - equipment_name = '' + equipment_id = equipment_item["EquipmentID"] + equipment_name_hash = equipment_item["EquipmentName"]["Hash"] + equipment_name = "" for item in TextMapEN: if str(item) == str(equipment_name_hash): - equipment_name = TextMapEN[item].replace(' ', '') + equipment_name = TextMapEN[item].replace(" ", "") break EquipmentID2EnName[equipment_id] = equipment_name for skill in AvatarSkillConfig: skill_item = AvatarSkillConfig[skill] - skill_id = skill_item['1']['SkillID'] - skill_name_hash = skill_item['1']['SkillName']['Hash'] - skill_type_hash = skill_item['1']['SkillTag']['Hash'] - skill_attack_type = skill_item['1'].get('AttackType', '') - skill_name = '' - skill_type = '' + skill_id = skill_item["1"]["SkillID"] + skill_name_hash = skill_item["1"]["SkillName"]["Hash"] + skill_type_hash = skill_item["1"]["SkillTag"]["Hash"] + skill_attack_type = skill_item["1"].get("AttackType", "") + skill_name = "" + skill_type = "" for item in TextMapCN: if str(item) == str(skill_name_hash): skill_name = TextMapCN[item] @@ -160,12 +160,12 @@ for skill in AvatarSkillConfig: for avatar_property in AvatarPropertyConfig: - PropertyType = AvatarPropertyConfig[avatar_property]['PropertyType'] - PropertyName = AvatarPropertyConfig[avatar_property]['PropertyName'] - PropertyNameHash = AvatarPropertyConfig[avatar_property][ - 'PropertyNameFilter' - ]['Hash'] - Property_Name = '' + PropertyType = AvatarPropertyConfig[avatar_property]["PropertyType"] + PropertyName = AvatarPropertyConfig[avatar_property]["PropertyName"] + PropertyNameHash = AvatarPropertyConfig[avatar_property]["PropertyNameFilter"][ + "Hash" + ] + Property_Name = "" for item in TextMapCN: if str(item) == str(PropertyNameHash): Property_Name = TextMapCN[item] @@ -174,13 +174,13 @@ for avatar_property in AvatarPropertyConfig: for relic in RelicConfig: - Relic2SetId[relic] = RelicConfig[relic]['SetID'] - RelicId2MainAffixGroup[relic] = RelicConfig[relic]['MainAffixGroup'] + Relic2SetId[relic] = RelicConfig[relic]["SetID"] + RelicId2MainAffixGroup[relic] = RelicConfig[relic]["MainAffixGroup"] for set_group in RelicSetConfig: - set_name_hash = RelicSetConfig[set_group]['SetName']['Hash'] - set_name = '' + set_name_hash = RelicSetConfig[set_group]["SetName"]["Hash"] + set_name = "" for item in TextMapCN: if str(item) == str(set_name_hash): set_name = TextMapCN[item] @@ -189,13 +189,13 @@ for set_group in RelicSetConfig: for character in characters: - char_id = characters[character]['id'] + char_id = characters[character]["id"] characterSkillTree[str(char_id)] = ( {} if str(char_id) not in characterSkillTree else characterSkillTree[str(char_id)] ) - skill_tree_list = characters[character]['skill_trees'] + skill_tree_list = characters[character]["skill_trees"] for skill in skill_tree_list: skill_tree = character_skill_trees[skill] characterSkillTree[str(char_id)][str(skill)] = skill_tree @@ -203,38 +203,34 @@ for character in characters: for set_ in RelicSetSkillConfig: for item in RelicSetSkillConfig[set_]: - set_id = RelicSetSkillConfig[set_][item]['SetID'] - property_list = RelicSetSkillConfig[set_][item]['PropertyList'] - RelicSetSkill[set_] = ( - {} if set_ not in RelicSetSkill else RelicSetSkill[set_] - ) + set_id = RelicSetSkillConfig[set_][item]["SetID"] + property_list = RelicSetSkillConfig[set_][item]["PropertyList"] + RelicSetSkill[set_] = {} if set_ not in RelicSetSkill else RelicSetSkill[set_] RelicSetSkill[set_][item] = ( - {} - if item not in RelicSetSkill[set_] - else RelicSetSkill[set_][item] + {} if item not in RelicSetSkill[set_] else RelicSetSkill[set_][item] ) for property_ in property_list: - property_id = property_['NAOGDGBJNOJ'] - property_value = property_['MBOHKHKHFPD']['Value'] - RelicSetSkill[set_][item]['Property'] = property_id - RelicSetSkill[set_][item]['Value'] = property_value + property_id = property_["NAOGDGBJNOJ"] + property_value = property_["MBOHKHKHFPD"]["Value"] + RelicSetSkill[set_][item]["Property"] = property_id + RelicSetSkill[set_][item]["Value"] = property_value for light_cone in light_cones: - rarity = light_cones[light_cone]['rarity'] - light_cone_id = light_cones[light_cone]['id'] + rarity = light_cones[light_cone]["rarity"] + light_cone_id = light_cones[light_cone]["id"] EquipmentID2Rarity[light_cone_id] = rarity for item in relics_new: - rarity = relics_new[item]['rarity'] - relic_id = relics_new[item]['id'] + rarity = relics_new[item]["rarity"] + relic_id = relics_new[item]["id"] RelicId2Rarity[relic_id] = rarity for item in ItemConfigRelic: - item_id = ItemConfigRelic[item]['ID'] - item_name_hash = ItemConfigRelic[item]['ItemName']['Hash'] - item_name = '' + item_id = ItemConfigRelic[item]["ID"] + item_name_hash = ItemConfigRelic[item]["ItemName"]["Hash"] + item_name = "" for item in TextMapCN: if str(item) == str(item_name_hash): item_name = TextMapCN[item] diff --git a/StarRailUID/utils/map/name_covert.py b/StarRailUID/utils/map/name_covert.py index 87cdf05..713210f 100644 --- a/StarRailUID/utils/map/name_covert.py +++ b/StarRailUID/utils/map/name_covert.py @@ -20,7 +20,7 @@ async def avatar_id_to_name(avatar_id: str) -> str: async def name_to_avatar_id(name: str) -> str: - avatar_id = '' + avatar_id = "" for i in avatarId2Name: if avatarId2Name[i] == name: avatar_id = i @@ -33,16 +33,16 @@ async def avatar_id_to_char_star(char_id: str) -> str: async def alias_to_char_name(char_name: str) -> str: - for i in alias_data['characters']: - if char_name in alias_data['characters'][i]: - return alias_data['characters'][i][0] + for i in alias_data["characters"]: + if char_name in alias_data["characters"][i]: + return alias_data["characters"][i][0] return char_name async def alias_to_weapon_name(weapon_name: str) -> str: - for i in alias_data['light_cones']: - if weapon_name in alias_data['light_cones'][i]: - return alias_data['light_cones'][i][0] + for i in alias_data["light_cones"]: + if weapon_name in alias_data["light_cones"][i]: + return alias_data["light_cones"][i][0] return weapon_name @@ -51,7 +51,7 @@ async def weapon_id_to_name(weapon_id: str) -> str: async def name_to_weapon_id(name: str) -> str: - weapon_id = '' + weapon_id = "" for i in EquipmentID2Name: if EquipmentID2Name[i] == name: weapon_id = i @@ -64,7 +64,7 @@ async def weapon_id_to_en_name(weapon_id: str) -> str: async def en_name_to_weapon_id(name: str) -> str: - weapon_id = '' + weapon_id = "" for i in EquipmentID2EnName: if EquipmentID2EnName[i] == name: weapon_id = i diff --git a/StarRailUID/utils/mys_api.py b/StarRailUID/utils/mys_api.py index 8f20de0..9d85e62 100644 --- a/StarRailUID/utils/mys_api.py +++ b/StarRailUID/utils/mys_api.py @@ -1,66 +1,55 @@ import copy import time -from typing import Any, Dict, Union, Literal, Optional +from typing import Dict, Literal, Optional, Union -import msgspec -from gsuid_core.utils.api.mys_api import _MysApi - -# from gsuid_core.utils.api.mys.models import MysSign, SignList from gsuid_core.utils.api.mys.tools import ( - mys_version, - _random_int_ds, generate_os_ds, + get_ds_token, get_web_ds_token, + mys_version, ) +from gsuid_core.utils.api.mys_api import _MysApi +import msgspec from ..sruid_utils.api.mys.api import _API from ..sruid_utils.api.mys.models import ( - MysSign, + AbyssBossData, + AbyssData, + AbyssStoryData, + AvatarDetail, + AvatarInfo, + DailyNoteData, GachaLog, + MonthlyAward, + MysSign, + RogueData, + RogueLocustData, + RoleBasicInfo, + RoleIndex, SignInfo, SignList, - AbyssData, - RogueData, - RoleIndex, - AvatarInfo, - AvatarDetail, - MonthlyAward, - DailyNoteData, - RoleBasicInfo, WidgetStamina, - RogueLocustData, AbyssStoryData, AbyssBossData, ) RECOGNIZE_SERVER = { - '1': 'prod_gf_cn', - '2': 'prod_gf_cn', - '5': 'prod_qd_cn', - '6': 'prod_official_usa', - '7': 'prod_official_euro', - '8': 'prod_official_asia', - '9': 'prod_official_cht', + "1": "prod_gf_cn", + "2": "prod_gf_cn", + "5": "prod_qd_cn", + "6": "prod_official_usa", + "7": "prod_official_euro", + "8": "prod_official_asia", + "9": "prod_official_cht", } -def get_ds_token2( - q: str = '', - b: Optional[Dict[str, Any]] = None, -): - salt = 't0qEgfub6cvueAPgR5m9aQWWVciEer7v' - return _random_int_ds(salt, q, b) - - class MysApi(_MysApi): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) async def get_sr_ck( - self, uid: str, mode: Literal['OWNER', 'RANDOM'] = 'RANDOM' + self, uid: str, mode: Literal["OWNER", "RANDOM"] = "RANDOM" ) -> Optional[str]: - return await self.get_ck(uid, mode, 'sr') - - def check_os(self, uid: str) -> bool: - return False if int(str(uid)[0]) < 6 else True + return await self.get_ck(uid, mode, "sr") async def simple_sr_req( self, @@ -76,40 +65,38 @@ class MysApi(_MysApi): params, header, cookie, - 'sr', + "sr", ) - async def get_daily_data(self, uid: str) -> Union[DailyNoteData, int]: - is_os = self.check_os(uid) - if is_os: + async def get_sr_daily_data(self, uid: str) -> Union[DailyNoteData, int]: + if self.check_os(uid, game_name="sr"): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER data = await self.simple_sr_req( - 'STAR_RAIL_NOTE_URL', + "STAR_RAIL_NOTE_URL", uid, params={ - 'role_id': uid, - 'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'), + "role_id": uid, + "server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"), }, header=header, ) else: data = await self.simple_sr_req( - 'STAR_RAIL_NOTE_URL', uid, header=self._HEADER + "STAR_RAIL_NOTE_URL", uid, header=self._HEADER ) if isinstance(data, Dict): # workaround for mistake params in hoyolab - if data['data']['accepted_epedition_num']: - data['data']['accepted_expedition_num'] = data['data'][ - 'accepted_epedition_num' + if data["data"]["accepted_epedition_num"]: + data["data"]["accepted_expedition_num"] = data["data"][ + "accepted_epedition_num" ] - data = msgspec.convert(data['data'], type=DailyNoteData) - # data = cast(DailyNoteData, data['data']) + data = msgspec.convert(data["data"], type=DailyNoteData) return data async def get_widget_stamina_data( @@ -117,389 +104,373 @@ class MysApi(_MysApi): uid: str, ) -> Union[WidgetStamina, int]: header = copy.deepcopy(self._HEADER) - sk = await self.get_stoken(uid, 'sr') + sk = await self.get_stoken(uid, "sr") if sk is None: return -51 - header['Cookie'] = sk - header['x-rpc-channel'] = 'beta' - device_id = await self.get_user_device_id(uid, 'sr') - header['x-rpc-device_id'] = '23' if device_id is None else device_id - header['x-rpc-app_version'] = '2.53.0' - header['x-rpc-device_model'] = 'Mi 10' - fp = await self.get_user_fp(uid, 'sr') - header['x-rpc-device_fp'] = 'Asmr489' if fp is None else fp - header['x-rpc-client_type'] = '2' - header['DS'] = get_ds_token2() - header['Referer'] = 'https://app.mihoyo.com' - del header['Origin'] - header['x-rpc-sys_version'] = '12' - header['User-Agent'] = 'okhttp/4.8.0' + header["Cookie"] = sk + header["x-rpc-channel"] = "beta" + device_id = await self.get_user_device_id(uid, "sr") + header["x-rpc-device_id"] = "23" if device_id is None else device_id + header["x-rpc-app_version"] = "2.53.0" + header["x-rpc-device_model"] = "Mi 10" + fp = await self.get_user_fp(uid, "sr") + header["x-rpc-device_fp"] = "Asmr489" if fp is None else fp + header["x-rpc-client_type"] = "2" + header["DS"] = get_ds_token() + header["Referer"] = "https://app.mihoyo.com" + del header["Origin"] + header["x-rpc-sys_version"] = "12" + header["User-Agent"] = "okhttp/4.8.0" data = await self._mys_request( - _API['STAR_RAIL_WIDGRT_URL'], - 'GET', + _API["STAR_RAIL_WIDGRT_URL"], + "GET", header, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=WidgetStamina) - # data = cast(WidgetStamina, data['data']) + data = msgspec.convert(data["data"], type=WidgetStamina) return data async def get_role_index(self, uid: str) -> Union[RoleIndex, int]: - is_os = self.check_os(uid) - if is_os: + if self.check_os(uid, game_name="sr"): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER data = await self.simple_sr_req( - 'STAR_RAIL_INDEX_URL', + "STAR_RAIL_INDEX_URL", uid, params={ - 'role_id': uid, - 'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'), + "role_id": uid, + "server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"), }, header=header, ) else: data = await self.simple_sr_req( - 'STAR_RAIL_INDEX_URL', uid, header=self._HEADER + "STAR_RAIL_INDEX_URL", uid, header=self._HEADER ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=RoleIndex) - # data = cast(RoleIndex, data['data']) + data = msgspec.convert(data["data"], type=RoleIndex) return data async def get_gacha_log_by_link_in_authkey( self, uid: str, authkey: str, - gacha_type: str = '11', + gacha_type: str = "11", page: int = 1, - end_id: str = '0', + end_id: str = "0", ) -> Union[int, GachaLog]: - # server_id = 'cn_qd01' if - # uid[0] == '5' else 'cn_gf01' server_id = RECOGNIZE_SERVER.get(str(uid)[0]) if self.check_os(uid): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER - url = self.MAPI['STAR_RAIL_GACHA_LOG_URL_OS'] - game_biz = 'hkrpg_global' + url = self.MAPI["STAR_RAIL_GACHA_LOG_URL_OS"] + game_biz = "hkrpg_global" else: header = self._HEADER - url = self.MAPI['STAR_RAIL_GACHA_LOG_URL'] - game_biz = 'hkrpg_cn' + url = self.MAPI["STAR_RAIL_GACHA_LOG_URL"] + game_biz = "hkrpg_cn" data = await self._mys_request( url=url, - method='GET', + method="GET", header=header, params={ - 'authkey_ver': '1', - 'sign_type': '2', - 'auth_appid': 'webview_gacha', - 'default_gacha_type': 11, - 'gacha_id': 'dbebc8d9fbb0d4ffa067423482ce505bc5ea', - 'timestamp': str(int(time.time())), - 'lang': 'zh-cn', - 'plat_type': 'pc', - 'region': server_id, - 'authkey': authkey, - 'game_biz': game_biz, - 'gacha_type': gacha_type, - 'page': page, - 'size': '20', - 'end_id': end_id, + "authkey_ver": "1", + "sign_type": "2", + "auth_appid": "webview_gacha", + "default_gacha_type": 11, + "gacha_id": "dbebc8d9fbb0d4ffa067423482ce505bc5ea", + "timestamp": str(int(time.time())), + "lang": "zh-cn", + "plat_type": "pc", + "region": server_id, + "authkey": authkey, + "game_biz": game_biz, + "gacha_type": gacha_type, + "page": page, + "size": "20", + "end_id": end_id, }, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=GachaLog) - # data = cast(GachaLog, data['data']) + data = msgspec.convert(data["data"], type=GachaLog) return data async def get_avatar_info( self, uid: str, avatar_id: int, need_wiki: bool = False ) -> Union[AvatarInfo, int]: - is_os = self.check_os(uid) - if is_os: + if self.check_os(uid, game_name="sr"): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER data = await self.simple_sr_req( - 'STAR_RAIL_AVATAR_INFO_URL', + "STAR_RAIL_AVATAR_INFO_URL", uid, params={ - 'need_wiki': 'true' if need_wiki else 'false', - 'role_id': uid, - 'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'), + "need_wiki": "true" if need_wiki else "false", + "role_id": uid, + "server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_official_asia"), }, header=header, ) else: data = await self.simple_sr_req( - 'STAR_RAIL_AVATAR_INFO_URL', + "STAR_RAIL_AVATAR_INFO_URL", uid, params={ - 'id': avatar_id, - 'need_wiki': 'true' if need_wiki else 'false', - 'role_id': uid, - 'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'), + "id": avatar_id, + "need_wiki": "true" if need_wiki else "false", + "role_id": uid, + "server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"), }, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=AvatarInfo) - # data = cast(AvatarInfo, data['data']) + data = msgspec.convert(data["data"], type=AvatarInfo) return data async def get_avatar_detail(self, uid: str, avatarid: str): data = await self.simple_sr_req( - 'STAR_RAIL_AVATAR_DETAIL_URL', + "STAR_RAIL_AVATAR_DETAIL_URL", uid, params={ - 'game': 'hkrpg', - 'lang': 'zh-cn', - 'item_id': avatarid, - 'tab_from': 'TabOwned', - 'change_target_level': '0', - 'uid': uid, - 'region': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'), + "game": "hkrpg", + "lang": "zh-cn", + "item_id": avatarid, + "tab_from": "TabOwned", + "change_target_level": "0", + "uid": uid, + "region": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"), }, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=AvatarDetail) + data = msgspec.convert(data["data"], type=AvatarDetail) return data - async def get_sign_list(self, uid) -> Union[SignList, int]: + async def get_sr_sign_list(self, uid) -> Union[SignList, int]: is_os = self.check_os(uid) if is_os: params = { - 'act_id': 'e202303301540311', - 'lang': 'zh-cn', + "act_id": "e202303301540311", + "lang": "zh-cn", } else: params = { - 'act_id': 'e202304121516551', - 'lang': 'zh-cn', + "act_id": "e202304121516551", + "lang": "zh-cn", } + data = await self._mys_req_get( - 'STAR_RAIL_SIGN_LIST_URL', + "STAR_RAIL_SIGN_LIST_URL", is_os, params, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=SignList) - # data = cast(SignList, data['data']) + data = msgspec.convert(data["data"], type=SignList) return data - async def get_sign_info(self, uid) -> Union[SignInfo, int]: - # server_id = RECOGNIZE_SERVER.get(str(uid)[0]) + async def get_sr_sign_info(self, uid) -> Union[SignInfo, int]: is_os = self.check_os(uid) if is_os: # TODO params = { - 'act_id': 'e202303301540311', - 'lang': 'zh-cn', + "act_id": "e202303301540311", + "lang": "zh-cn", } HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER else: params = { - 'act_id': 'e202304121516551', - 'lang': 'zh-cn', - 'region': 'prod_gf_cn', - 'uid': uid, + "act_id": "e202304121516551", + "lang": "zh-cn", + "region": "prod_gf_cn", + "uid": uid, } header = self._HEADER data = await self._mys_req_get( - 'STAR_RAIL_SIGN_INFO_URL', + "STAR_RAIL_SIGN_INFO_URL", is_os, params, header, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=SignInfo) - # data = cast(SignInfo, data['data']) + data = msgspec.convert(data["data"], type=SignInfo) return data async def get_abyss_info( self, uid: str, - schedule_type='1', + schedule_type="1", ck: Optional[str] = None, ) -> Union[AbyssData, int]: server_id = self.RECOGNIZE_SERVER.get(uid[0]) - is_os = self.check_os(uid) - if is_os: + if self.check_os(uid, game_name="sr"): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER data = await self.simple_sr_req( - 'CHALLENGE_INFO_URL', + "CHALLENGE_INFO_URL", uid, params={ - 'need_all': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "need_all": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, header=header, ) else: data = await self.simple_sr_req( - 'CHALLENGE_INFO_URL', + "CHALLENGE_INFO_URL", uid, params={ - 'isPrev': 'true', - 'need_all': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "isPrev": "true", + "need_all": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, cookie=ck, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=AbyssData) - # data = cast(AbyssData, data['data']) + data = msgspec.convert(data["data"], type=AbyssData) return data async def get_abyss_story_info( self, uid: str, - schedule_type='1', + schedule_type="1", ck: Optional[str] = None, - ) -> Union[AbyssData, int]: + ) -> Union[AbyssStoryData, int]: server_id = self.RECOGNIZE_SERVER.get(uid[0]) - is_os = self.check_os(uid) - if is_os: + if self.check_os(uid, game_name="sr"): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER data = await self.simple_sr_req( - 'CHALLENGE_STORY_INFO_URL', + "CHALLENGE_STORY_INFO_URL", uid, params={ - 'need_all': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "need_all": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, header=header, ) else: data = await self.simple_sr_req( - 'CHALLENGE_STORY_INFO_URL', + "CHALLENGE_STORY_INFO_URL", uid, params={ - 'isPrev': 'true', - 'need_all': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "isPrev": "true", + "need_all": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, cookie=ck, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=AbyssStoryData) + data = msgspec.convert(data["data"], type=AbyssStoryData) return data async def get_abyss_boss_info( self, uid: str, - schedule_type='1', + schedule_type="1", ck: Optional[str] = None, ) -> Union[AbyssBossData, int]: server_id = self.RECOGNIZE_SERVER.get(uid[0]) - is_os = self.check_os(uid) - if is_os: + if self.check_os(uid, game_name="sr"): HEADER = copy.deepcopy(self._HEADER_OS) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() header = HEADER data = await self.simple_sr_req( - 'CHALLENGE_BOSS_INFO_URL', + "CHALLENGE_BOSS_INFO_URL", uid, params={ - 'need_all': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "need_all": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, header=header, ) else: data = await self.simple_sr_req( - 'CHALLENGE_BOSS_INFO_URL', + "CHALLENGE_BOSS_INFO_URL", uid, params={ - 'isPrev': 'true', - 'need_all': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "isPrev": "true", + "need_all": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, cookie=ck, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=AbyssBossData) - # data = cast(AbyssData, data['data']) + data = msgspec.convert(data["data"], type=AbyssBossData) return data async def get_rogue_info( self, uid: str, - schedule_type='3', + schedule_type="3", ck: Optional[str] = None, ) -> Union[RogueData, int]: server_id = self.RECOGNIZE_SERVER.get(uid[0]) data = await self.simple_sr_req( - 'ROGUE_INFO_URL', + "ROGUE_INFO_URL", uid, params={ - 'need_detail': 'true', - 'role_id': uid, - 'schedule_type': schedule_type, - 'server': server_id, + "need_detail": "true", + "role_id": uid, + "schedule_type": schedule_type, + "server": server_id, }, cookie=ck, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=RogueData) - # data = cast(RogueData, data['data']) + data = msgspec.convert(data["data"], type=RogueData) return data async def get_rogue_locust_info( @@ -508,99 +479,96 @@ class MysApi(_MysApi): ck: Optional[str] = None, ) -> Union[RogueLocustData, int]: server_id = self.RECOGNIZE_SERVER.get(uid[0]) - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") data = await self.simple_sr_req( - 'ROGUE_LOCUST_INFO_URL', + "ROGUE_LOCUST_INFO_URL", uid, params={ - 'need_detail': 'true', - 'role_id': uid, - 'server': server_id, + "need_detail": "true", + "role_id": uid, + "server": server_id, }, cookie=ck, header=self._HEADER, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=RogueLocustData) - # data = cast(RogueLocustData, data['data']) + data = msgspec.convert(data["data"], type=RogueLocustData) return data - async def mys_sign( - self, uid, header=None, server_id='cn_gf01' + async def sr_mys_sign( + self, uid, header=None, server_id="cn_gf01" ) -> Union[MysSign, int]: if header is None: header = {} - ck = await self.get_sr_ck(uid, 'OWNER') + ck = await self.get_sr_ck(uid, "OWNER") if ck is None: return -51 if int(str(uid)[0]) < 6: HEADER = copy.deepcopy(self._HEADER) - HEADER['Cookie'] = ck - HEADER['x-rpc-app_version'] = mys_version - HEADER['x-rpc-client_type'] = '5' - HEADER['X_Requested_With'] = 'com.mihoyo.hyperion' - HEADER['DS'] = get_web_ds_token(True) - HEADER['Referer'] = 'https://webstatic.mihoyo.com' + HEADER["Cookie"] = ck + HEADER["x-rpc-app_version"] = mys_version + HEADER["x-rpc-client_type"] = "5" + HEADER["X_Requested_With"] = "com.mihoyo.hyperion" + HEADER["DS"] = get_web_ds_token(True) + HEADER["Referer"] = "https://webstatic.mihoyo.com" HEADER.update(header) data = await self._mys_request( - url=_API['STAR_RAIL_SIGN_URL'], - method='POST', + url=_API["STAR_RAIL_SIGN_URL"], + method="POST", header=HEADER, data={ - 'act_id': 'e202304121516551', - 'region': 'prod_gf_cn', - 'uid': uid, - 'lang': 'zh-cn', + "act_id": "e202304121516551", + "region": "prod_gf_cn", + "uid": uid, + "lang": "zh-cn", }, ) else: HEADER = copy.deepcopy(self._HEADER_OS) - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() HEADER.update(header) data = await self._mys_request( - url=_API['STAR_RAIL_SIGN_URL_OS'], - method='POST', + url=_API["STAR_RAIL_SIGN_URL_OS"], + method="POST", header=HEADER, data={ - 'act_id': 'e202303301540311', - 'lang': 'zh-cn', + "act_id": "e202303301540311", + "lang": "zh-cn", }, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=MysSign) - # data = cast(MysSign, data['data']) + data = msgspec.convert(data["data"], type=MysSign) return data - async def get_award(self, sr_uid, month) -> Union[MonthlyAward, int]: + async def get_sr_award(self, sr_uid, month) -> Union[MonthlyAward, int]: server_id = RECOGNIZE_SERVER.get(str(sr_uid)[0]) - ck = await self.get_sr_ck(sr_uid, 'OWNER') + ck = await self.get_sr_ck(sr_uid, "OWNER") if ck is None: return -51 if int(str(sr_uid)[0]) < 6: HEADER = copy.deepcopy(self._HEADER) - HEADER['Cookie'] = ck - HEADER['DS'] = get_web_ds_token(True) + HEADER["Cookie"] = ck + HEADER["DS"] = get_web_ds_token(True) data = await self._mys_request( - url=_API['STAR_RAIL_MONTH_INFO_URL'], - method='GET', + url=_API["STAR_RAIL_MONTH_INFO_URL"], + method="GET", header=HEADER, - params={'uid': sr_uid, 'region': server_id, 'month': month}, + params={"uid": sr_uid, "region": server_id, "month": month}, ) else: HEADER = copy.deepcopy(self._HEADER_OS) - HEADER['Cookie'] = ck - HEADER['DS'] = generate_os_ds() + HEADER["Cookie"] = ck + HEADER["DS"] = generate_os_ds() data = await self._mys_request( - url=_API['STAR_RAIL_MONTH_INFO_URL'], - method='GET', + url=_API["STAR_RAIL_MONTH_INFO_URL"], + method="GET", header=HEADER, - params={'uid': sr_uid, 'region': server_id, 'month': month}, + params={"uid": sr_uid, "region": server_id, "month": month}, use_proxy=True, ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=MonthlyAward) - # data = cast(MonthlyAward, data['data']) + data = msgspec.convert(data["data"], type=MonthlyAward) return data async def get_role_basic_info( @@ -608,11 +576,10 @@ class MysApi(_MysApi): sr_uid: str, ) -> Union[RoleBasicInfo, int]: data = await self.simple_sr_req( - 'STAR_RAIL_ROLE_BASIC_INFO_URL', sr_uid, header=self._HEADER + "STAR_RAIL_ROLE_BASIC_INFO_URL", sr_uid, header=self._HEADER ) if isinstance(data, Dict): - data = msgspec.convert(data['data'], type=RoleBasicInfo) - # data = cast(RoleBasicInfo, data['data']) + data = msgspec.convert(data["data"], type=RoleBasicInfo) return data diff --git a/StarRailUID/utils/resource/RESOURCE_PATH.py b/StarRailUID/utils/resource/RESOURCE_PATH.py index ca7acb3..97a90fd 100644 --- a/StarRailUID/utils/resource/RESOURCE_PATH.py +++ b/StarRailUID/utils/resource/RESOURCE_PATH.py @@ -3,35 +3,35 @@ from pathlib import Path from gsuid_core.data_store import get_res_path -MAIN_PATH = get_res_path() / 'StarRailUID' +MAIN_PATH = get_res_path() / "StarRailUID" sys.path.append(str(MAIN_PATH)) -CU_BG_PATH = MAIN_PATH / 'bg' -CONFIG_PATH = MAIN_PATH / 'config.json' -PLAYER_PATH = MAIN_PATH / 'players' -RESOURCE_PATH = MAIN_PATH / 'resource' -WIKI_PATH = MAIN_PATH / 'wiki' -GUIDE_PATH = MAIN_PATH / 'guide' +CU_BG_PATH = MAIN_PATH / "bg" +CONFIG_PATH = MAIN_PATH / "config.json" +PLAYER_PATH = MAIN_PATH / "players" +RESOURCE_PATH = MAIN_PATH / "resource" +WIKI_PATH = MAIN_PATH / "wiki" +GUIDE_PATH = MAIN_PATH / "guide" -CHAR_ICON_PATH = RESOURCE_PATH / 'character' -CHAR_PORTRAIT_PATH = RESOURCE_PATH / 'character_portrait' -CONSUMABLE_PATH = RESOURCE_PATH / 'consumable' -ELEMENT_PATH = RESOURCE_PATH / 'element' -WEAPON_PATH = RESOURCE_PATH / 'light_cone' -RELIC_PATH = RESOURCE_PATH / 'relic' -SKILL_PATH = RESOURCE_PATH / 'skill' -TEMP_PATH = RESOURCE_PATH / 'temp' -CHAR_PREVIEW_PATH = RESOURCE_PATH / 'character_preview' +CHAR_ICON_PATH = RESOURCE_PATH / "character" +CHAR_PORTRAIT_PATH = RESOURCE_PATH / "character_portrait" +CONSUMABLE_PATH = RESOURCE_PATH / "consumable" +ELEMENT_PATH = RESOURCE_PATH / "element" +WEAPON_PATH = RESOURCE_PATH / "light_cone" +RELIC_PATH = RESOURCE_PATH / "relic" +SKILL_PATH = RESOURCE_PATH / "skill" +TEMP_PATH = RESOURCE_PATH / "temp" +CHAR_PREVIEW_PATH = RESOURCE_PATH / "character_preview" -WIKI_LIGHT_CONE_PATH = WIKI_PATH / 'light_cone' -WIKI_MATERIAL_FOR_ROLE = WIKI_PATH / 'character_material' -WIKI_RELIC_PATH = WIKI_PATH / 'relic_set' -WIKI_ROLE_PATH = WIKI_PATH / 'character_overview' +WIKI_LIGHT_CONE_PATH = WIKI_PATH / "light_cone" +WIKI_MATERIAL_FOR_ROLE = WIKI_PATH / "character_material" +WIKI_RELIC_PATH = WIKI_PATH / "relic_set" +WIKI_ROLE_PATH = WIKI_PATH / "character_overview" -GUIDE_LIGHT_CONE_PATH = GUIDE_PATH / 'light_cone' -GUIDE_CHARACTER_PATH = GUIDE_PATH / 'character_overview' +GUIDE_LIGHT_CONE_PATH = GUIDE_PATH / "light_cone" +GUIDE_CHARACTER_PATH = GUIDE_PATH / "character_overview" -TEXT2D_PATH = Path(__file__).parent / 'texture2d' +TEXT2D_PATH = Path(__file__).parent / "texture2d" def init_dir(): diff --git a/StarRailUID/utils/resource/download_from_cos.py b/StarRailUID/utils/resource/download_from_cos.py index 69d717e..894e491 100644 --- a/StarRailUID/utils/resource/download_from_cos.py +++ b/StarRailUID/utils/resource/download_from_cos.py @@ -20,22 +20,22 @@ from gsuid_core.utils.download_resource.download_core import download_all_file async def check_use(): await download_all_file( - 'StarRailUID', + "StarRailUID", { - 'resource/character': CHAR_ICON_PATH, - 'resource/character_portrait': CHAR_PORTRAIT_PATH, - 'resource/character_preview': CHAR_PREVIEW_PATH, - 'resource/consumable': CONSUMABLE_PATH, - 'resource/element': ELEMENT_PATH, - 'guide/character_overview': GUIDE_CHARACTER_PATH, - 'guide/light_cone': GUIDE_LIGHT_CONE_PATH, - 'resource/relic': RELIC_PATH, - 'resource/skill': SKILL_PATH, - 'resource/light_cone': WEAPON_PATH, - 'wiki/light_cone': WIKI_LIGHT_CONE_PATH, - 'wiki/character_material': WIKI_MATERIAL_FOR_ROLE, - 'wiki/relic_set': WIKI_RELIC_PATH, - 'wiki/character_overview': WIKI_ROLE_PATH, + "resource/character": CHAR_ICON_PATH, + "resource/character_portrait": CHAR_PORTRAIT_PATH, + "resource/character_preview": CHAR_PREVIEW_PATH, + "resource/consumable": CONSUMABLE_PATH, + "resource/element": ELEMENT_PATH, + "guide/character_overview": GUIDE_CHARACTER_PATH, + "guide/light_cone": GUIDE_LIGHT_CONE_PATH, + "resource/relic": RELIC_PATH, + "resource/skill": SKILL_PATH, + "resource/light_cone": WEAPON_PATH, + "wiki/light_cone": WIKI_LIGHT_CONE_PATH, + "wiki/character_material": WIKI_MATERIAL_FOR_ROLE, + "wiki/relic_set": WIKI_RELIC_PATH, + "wiki/character_overview": WIKI_ROLE_PATH, }, ) - return 'sr全部资源下载完成!' + return "sr全部资源下载完成!" diff --git a/StarRailUID/utils/sr_prefix.py b/StarRailUID/utils/sr_prefix.py index f8c9b13..5cdc8c3 100644 --- a/StarRailUID/utils/sr_prefix.py +++ b/StarRailUID/utils/sr_prefix.py @@ -1,3 +1,3 @@ from ..starrailuid_config.sr_config import srconfig -PREFIX = srconfig.get_config('StarRailPrefix').data +PREFIX = srconfig.get_config("StarRailPrefix").data diff --git a/StarRailUID/version.py b/StarRailUID/version.py index 0dd7774..962aafc 100644 --- a/StarRailUID/version.py +++ b/StarRailUID/version.py @@ -1,2 +1,2 @@ -StarRailUID_version = '0.1.0' -StarRail_version = '2.4.0' +StarRailUID_version = "0.1.0" +StarRail_version = "2.4.0" diff --git a/pyproject.toml b/pyproject.toml index 1541c22..cdb38d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,33 +38,37 @@ pytest = "^7.2.0" pytest-asyncio = "^0.20.3" [tool.ruff] -line-length = 79 +line-length = 88 +target-version = "py38" + +[tool.ruff.lint] select = [ - "E", "W", # pycodestyle - "F", # pyflakes + "E", + "W", # pycodestyle + "F", # pyflakes # "I", # isort - "RUF", # ruff - "TRY", # tryceratops + "RUF", # ruff + "TRY", # tryceratops "UP", # pylint - "PLW", # Warning - "PLR", # Refactor - "PLE", # Error + "PLW", # Warning + "PLR", # Refactor + "PLE", # Error - "PTH", # flake8-use-pathlib - "SLF", # flake8-self - "RET", # flake8-return - "RSE", # flake8-raise - "T20", # flake8-print - "PIE", # flake8-pie - "ISC", # flake8-implicit-str-concat - "C4", # flake8-comprehensions - "COM", # flake8-commas - "A", # flake8-builtins - "B", # flake8-bugbear - "ASYNC", # flake8-async - "Q", # flake8-quotes + "PTH", # flake8-use-pathlib + "SLF", # flake8-self + "RET", # flake8-return + "RSE", # flake8-raise + "T20", # flake8-print + "PIE", # flake8-pie + "ISC", # flake8-implicit-str-concat + "C4", # flake8-comprehensions + "COM", # flake8-commas + "A", # flake8-builtins + "B", # flake8-bugbear + "ASYNC", # flake8-async + "Q", # flake8-quotes ] ignore = [ "ISC", @@ -76,32 +80,19 @@ ignore = [ "PLR0915", "PLR0913", "PLR0911", - "PLW0603", # Using the global statement + "PLW0603", # Using the global statement "TRY002", - "TRY003" + "TRY003", ] -exclude = [ - "gen.py", - ".ruff_cache" -] -# Assume Python 3.8 -target-version = "py38" +exclude = ["gen.py", ".ruff_cache"] -[tool.ruff.flake8-quotes] -inline-quotes = "single" - -[tool.ruff.format] -quote-style = "single" - -[tool.ruff.isort] +[tool.ruff.lint.isort] case-sensitive = true force-sort-within-sections = true extra-standard-library = ["typing_extensions"] -#force-wrap-aliases = true combine-as-imports = true order-by-type = true relative-imports-order = "closest-to-furthest" -section-order = ["future", "standard-library", "first-party", "local-folder", "third-party"] [tool.pdm] [tool.pdm.build] @@ -117,36 +108,32 @@ name = "StarRailUID" version = "0.1.0" description = "支持 NoneBot2 & HoshinoBot & ZeroBot & YunzaiBot 的全功能星穹铁道Bot插件" authors = [ - {name = "qwerdvd", email = "105906879+qwerdvd@users.noreply.github.com"}, + { name = "qwerdvd", email = "105906879+qwerdvd@users.noreply.github.com" }, ] dependencies = [ - "beautifulsoup4>=4.12.2", - "msgspec>=0.18.4", - "httpx>=0.25.0", - "pillow>=10.1.0", - "aiofiles>=23.2.1", - "aiohttp>=3.8.6", - "qrcode[pil]>=7.4.2", - "starrail-damage-cal>=1.2.1", + "beautifulsoup4>=4.12.2", + "msgspec>=0.18.4", + "httpx>=0.25.0", + "pillow>=10.1.0", + "aiofiles>=23.2.1", + "aiohttp>=3.8.6", + "qrcode[pil]>=7.4.2", + "starrail-damage-cal>=1.2.1", ] requires-python = ">=3.8.1,<4.0" readme = "README.md" -license = {text = "GPL-3.0-or-later"} +license = { text = "GPL-3.0-or-later" } [tool.pdm.dev-dependencies] dev = [ - "ruff>=0.0.276", - "pre-commit>=3.3.2", - "flake8>=6.0.0", - "isort>=5.12.0", - "pycln>=2.1.2" -] -test = [ - "nonebug>=0.3.0", - "pytest>=7.2.0", - "pytest-asyncio>=0.20.3" + "ruff>=0.0.276", + "pre-commit>=3.3.2", + "flake8>=6.0.0", + "isort>=5.12.0", + "pycln>=2.1.2", ] +test = ["nonebug>=0.3.0", "pytest>=7.2.0", "pytest-asyncio>=0.20.3"] [build-system] requires = ["pdm-backend"]