diff --git a/GenshinUID/genshinuid_enka/__init__.py b/GenshinUID/genshinuid_enka/__init__.py index 5f8692a8..d24abd0c 100644 --- a/GenshinUID/genshinuid_enka/__init__.py +++ b/GenshinUID/genshinuid_enka/__init__.py @@ -40,7 +40,7 @@ @sv_akasha.on_command('排名统计') -async def sned_rank_data(bot: Bot, ev: Event): +async def send_rank_data(bot: Bot, ev: Event): # 获取uid uid = await get_uid(bot, ev) if uid is None: @@ -50,7 +50,7 @@ async def sned_rank_data(bot: Bot, ev: Event): @sv_akasha.on_command('排名列表') -async def sned_rank_pic(bot: Bot, ev: Event): +async def send_rank_pic(bot: Bot, ev: Event): # 获取uid uid = await get_uid(bot, ev) if uid is None: @@ -67,7 +67,7 @@ async def sned_rank_pic(bot: Bot, ev: Event): @sv_akasha.on_prefix('角色排行榜') -async def sned_role_rank_pic(bot: Bot, ev: Event): +async def send_role_rank_pic(bot: Bot, ev: Event): # 获取角色名 msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text)) if not msg: @@ -83,7 +83,7 @@ async def sned_role_rank_pic(bot: Bot, ev: Event): @sv_akasha.on_prefix('角色排名') -async def sned_my_role_rank_pic(bot: Bot, ev: Event): +async def send_my_role_rank_pic(bot: Bot, ev: Event): # 获取角色名 msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text)) if not msg: @@ -105,7 +105,7 @@ async def sned_my_role_rank_pic(bot: Bot, ev: Event): @sv_akasha.on_command('圣遗物排名') -async def sned_arti_rank_pic(bot: Bot, ev: Event): +async def send_arti_rank_pic(bot: Bot, ev: Event): # 获取排序名 msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text)) logger.info(f'[圣遗物排名]排序: {msg}') @@ -122,14 +122,14 @@ async def sned_arti_rank_pic(bot: Bot, ev: Event): @sv_enka_admin.on_fullmatch('刷新全部圣遗物仓库') -async def sned_fresh_all_list(bot: Bot, ev: Event): +async def send_fresh_all_list(bot: Bot, ev: Event): await bot.send('开始执行...可能时间较久, 执行完成会有提示, 请勿重复执行!') await check_artifacts_list() await bot.send('执行完成!') @sv_get_enka.on_fullmatch(('刷新圣遗物仓库', '强制刷新圣遗物仓库'), block=True) -async def sned_fresh_list(bot: Bot, ev: Event): +async def send_fresh_list(bot: Bot, ev: Event): # 获取uid uid = await get_uid(bot, ev) if uid is None: @@ -144,7 +144,7 @@ async def sned_fresh_list(bot: Bot, ev: Event): @sv_get_enka.on_command('圣遗物仓库') -async def sned_aritifacts_list(bot: Bot, ev: Event): +async def send_aritifacts_list(bot: Bot, ev: Event): # 获取uid uid = await get_uid(bot, ev) if uid is None: @@ -171,7 +171,7 @@ async def sned_aritifacts_list(bot: Bot, ev: Event): @sv_get_original_pic.on_fullmatch(('原图')) -async def sned_original_pic(bot: Bot, ev: Event): +async def send_original_pic(bot: Bot, ev: Event): if ev.reply: path = TEMP_PATH / f'{ev.reply}.jpg' if path.exists(): diff --git a/GenshinUID/genshinuid_enka/draw_rank_list.py b/GenshinUID/genshinuid_enka/draw_rank_list.py index 031f0b39..c914ac2c 100644 --- a/GenshinUID/genshinuid_enka/draw_rank_list.py +++ b/GenshinUID/genshinuid_enka/draw_rank_list.py @@ -1,5 +1,7 @@ +import json from typing import Dict, Union +import aiofiles from PIL import Image, ImageDraw from gsuid_core.models import Event from gsuid_core.utils.image.convert import convert_img @@ -11,6 +13,7 @@ from ..utils.image.image_tools import get_avatar from ..utils.map.name_covert import avatar_id_to_name from .to_card import draw_char_card, draw_weapon_card +from ..utils.resource.RESOURCE_PATH import PLAYER_PATH from ..utils.fonts.genshin_fonts import ( gs_font_15, gs_font_22, @@ -43,12 +46,24 @@ async def draw_rank_img(ev: Event, uid: str) -> Union[bytes, str]: img.paste(title, (0, 0), title) - for index, char in enumerate(rank_data): + _rank_data = {} + for char in rank_data: + stats = rank_data[char]['calculations']['fit']['stats'] + if stats is None: + continue + _rank_data[char] = rank_data[char] + + path = PLAYER_PATH / uid / 'rank.json' + async with aiofiles.open(path, 'w', encoding='UTF-8') as file: + await file.write(json.dumps(_rank_data, indent=4, ensure_ascii=False)) + + for index, char in enumerate(_rank_data): raw_data = rank_data[char] time = raw_data['time'] data = raw_data['calculations']['fit'] stats: Dict = data['stats'] + char_name = await avatar_id_to_name(char) result = '{:.2f}'.format(data['result']) rank = data['ranking'] @@ -73,7 +88,7 @@ async def draw_rank_img(ev: Event, uid: str) -> Union[bytes, str]: ) weapon_card = weapon_card.resize((110, 110)) - _color = get_color(_pc, [10, 23, 34, 55], True) + _color = get_color(_pc, [55, 34, 23, 10]) cv_color = get_color(_cv, [210, 185, 170, 150]) color = Image.new('RGBA', (950, 300), _color) diff --git a/GenshinUID/genshinuid_enka/to_data.py b/GenshinUID/genshinuid_enka/to_data.py index 43a537e0..95a64bd7 100644 --- a/GenshinUID/genshinuid_enka/to_data.py +++ b/GenshinUID/genshinuid_enka/to_data.py @@ -40,6 +40,16 @@ 'Hydro': '42', 'Pyro': '40', } +AT_MAP = { + 'maxHp': 'maxHP', + 'atk': 'maxATK', + 'def': 'maxDEF', + 'elementalMastery': 'elementalMastery', + 'energyRecharge': 'energyRecharge', + 'healingBonus': 'healingBonus', + 'critRate': 'critRate', + 'critDamage': 'critDMG', +} ENKA_API: List[Literal['enka', 'microgg']] = ['enka', 'microgg'] is_enable_akasha = gsconfig.get_config('EnableAkasha').data @@ -73,7 +83,7 @@ async def switch_api(): async def enka_to_dict( uid: str, enka_data: Optional[EnkaData] = None ) -> Union[List[dict], str]: - """ + ''' :说明: 访问enkaAPI并转换为genshinUID的数据Json。 :参数: @@ -81,7 +91,7 @@ async def enka_to_dict( * ``enka_data: Optional[dict] = None``: 来自enka的dict, 可留空。 :返回: * ``刷新完成提示语: str``: 包含刷新成功的角色列表。 - """ + ''' if '未找到绑定的UID' in uid: return UID_HINT if enka_data: @@ -233,39 +243,39 @@ async def enka_to_dict( # 处理属性 fight_prop = {} # 血量 - fight_prop['hp'] = char["fightPropMap"]["2000"] - fight_prop['baseHp'] = char["fightPropMap"]["1"] + fight_prop['hp'] = char['fightPropMap']['2000'] + fight_prop['baseHp'] = char['fightPropMap']['1'] fight_prop['addHp'] = ( - char["fightPropMap"]["2000"] - char["fightPropMap"]["1"] + char['fightPropMap']['2000'] - char['fightPropMap']['1'] ) # 攻击力 - fight_prop['atk'] = char["fightPropMap"]["2001"] - fight_prop['baseAtk'] = char["fightPropMap"]["4"] + fight_prop['atk'] = char['fightPropMap']['2001'] + fight_prop['baseAtk'] = char['fightPropMap']['4'] fight_prop['addAtk'] = ( - char["fightPropMap"]["2001"] - char["fightPropMap"]["4"] + char['fightPropMap']['2001'] - char['fightPropMap']['4'] ) # 防御力 - fight_prop['def'] = char["fightPropMap"]["2002"] - fight_prop['baseDef'] = char["fightPropMap"]["7"] + fight_prop['def'] = char['fightPropMap']['2002'] + fight_prop['baseDef'] = char['fightPropMap']['7'] fight_prop['addDef'] = ( - char["fightPropMap"]["2002"] - char["fightPropMap"]["7"] + char['fightPropMap']['2002'] - char['fightPropMap']['7'] ) # 元素精通 - fight_prop['elementalMastery'] = char["fightPropMap"]["28"] + fight_prop['elementalMastery'] = char['fightPropMap']['28'] # 暴击率 - fight_prop['critRate'] = char["fightPropMap"]["20"] + fight_prop['critRate'] = char['fightPropMap']['20'] # 暴击伤害 - fight_prop['critDmg'] = char["fightPropMap"]["22"] + fight_prop['critDmg'] = char['fightPropMap']['22'] # 充能效率 - fight_prop['energyRecharge'] = char["fightPropMap"]["23"] + fight_prop['energyRecharge'] = char['fightPropMap']['23'] # 治疗&受治疗 - fight_prop['healBonus'] = char["fightPropMap"]["26"] - fight_prop['healedBonus'] = char["fightPropMap"]["27"] + fight_prop['healBonus'] = char['fightPropMap']['26'] + fight_prop['healedBonus'] = char['fightPropMap']['27'] # 物理伤害加成 & 抗性 - fight_prop['physicalDmgSub'] = char["fightPropMap"]["29"] - fight_prop['physicalDmgBonus'] = char["fightPropMap"]["30"] + fight_prop['physicalDmgSub'] = char['fightPropMap']['29'] + fight_prop['physicalDmgBonus'] = char['fightPropMap']['30'] # 伤害加成 - fight_prop['dmgBonus'] = char["fightPropMap"][ + fight_prop['dmgBonus'] = char['fightPropMap'][ PROP_ATTR_MAP[char_data['avatarElement']] ] @@ -317,7 +327,7 @@ async def enka_to_dict( and effect_raw is not None and int(effect_raw['rarity']) > 2 ): - effect = effect_raw[f'r{weapon_info["weaponAffix"]}'][ + effect = effect_raw[f'r{weapon_info['weaponAffix']}'][ 'description' ] else: @@ -441,9 +451,32 @@ async def _restore_cv_data(uid: str, now: str): else: rank_data = {} if not isinstance(data, int): - for i in data['data']: + data1, data2 = data[0], data[1] + for i in data1['data']: + for j in data2['data']: + if i['_id'] == j['_id']: + _value = 0 + stats = {'critValue': j['critValue']} + for k in j['stats']: + if k in AT_MAP: + _k = AT_MAP[k] + elif k.endswith('DamageBonus'): + if j['stats'][k]['value'] > 0: + _value = j['stats'][k]['value'] + continue + else: + continue + else: + _k = k + stats[_k] = j['stats'][k]['value'] + stats['DMG'] = _value + + break + + cal = i['calculations'] + cal['fit']['stats'] = stats rank_data[i['characterId']] = { - 'calculations': i['calculations'], + 'calculations': cal, 'time': now, } async with aiofiles.open(path, 'w', encoding='UTF-8') as file: diff --git a/GenshinUID/utils/api/cv/api.py b/GenshinUID/utils/api/cv/api.py index ba4fe0f1..dc382d1d 100644 --- a/GenshinUID/utils/api/cv/api.py +++ b/GenshinUID/utils/api/cv/api.py @@ -2,6 +2,7 @@ MAIN_API = BASE + '/filters/accounts/' RANK_API = BASE + '/getCalculationsForUser/{}' +BUILDS_API = BASE + '/builds?uid={}' DATA_API = BASE + '/user/{}' REFRESH_API = BASE + '/user/refresh/{}' LEADERBOARD_API = BASE + '/v2/leaderboards/categories?characterId={}' diff --git a/GenshinUID/utils/api/cv/request.py b/GenshinUID/utils/api/cv/request.py index 2b5ec4e2..2d20dbb3 100644 --- a/GenshinUID/utils/api/cv/request.py +++ b/GenshinUID/utils/api/cv/request.py @@ -9,6 +9,7 @@ MAIN_API, RANK_API, SORT_API, + BUILDS_API, REFRESH_API, ARTI_SORT_API, LEADERBOARD_API, @@ -170,14 +171,21 @@ async def get_refresh_data(self, uid: str) -> Union[Dict, int]: {'sessionID': self.sessionID}, ) - async def get_rank_data(self, uid: str) -> Union[Dict, int]: + async def get_rank_data(self, uid: str) -> Union[Tuple[Dict, Dict], int]: await self.get_base_data(uid) await self.get_refresh_data(uid) - data = await self._cv_request( + data1 = await self._cv_request( RANK_API.format(uid), 'GET', self._HEADER ) + data2 = await self._cv_request( + BUILDS_API.format(uid), 'GET', self._HEADER + ) await self.session.close() - return data + if isinstance(data1, int): + return data1 + if isinstance(data2, int): + return data2 + return data1, data2 async def close(self): # 调用session对象的close方法关闭会话