2023-05-06 23:22:51 +08:00

361 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import time
from typing import List, Union, Literal, Optional
from httpx import ReadTimeout, ConnectTimeout
from gsuid_core.utils.error_reply import UID_HINT
from gsuid_core.utils.api.enka.models import EnkaData
from gsuid_core.utils.api.enka.request import get_enka_info
from gsuid_core.utils.api.minigg.request import get_weapon_info
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
from ..utils.ambr_to_minigg import convert_ambr_to_weapon
from ..utils.map.GS_MAP_PATH import (
icon2Name,
propId2Name,
skillId2Name,
artifact2attr,
avatarId2Name,
talentId2Name,
weaponHash2Name,
weaponHash2Type,
artifactId2Piece,
avatarName2Element,
)
PROP_ATTR_MAP = {
'Anemo': '44',
'Cryo': '46',
'Dendro': '43',
'Electro': '41',
'Geo': '45',
'Hydro': '42',
'Pyro': '40',
}
ENKA_API: List[Literal['enka', 'microgg']] = ['enka', 'microgg']
async def switch_api():
global ENKA_API
if ENKA_API[0] == 'enka':
ENKA_API = ['microgg', 'enka']
else:
ENKA_API = ['enka', 'microgg']
return f'切换成功!当前api为{ENKA_API[0]}!'
async def enka_to_dict(
uid: str, enka_data: Optional[EnkaData] = None
) -> Union[List[dict], str]:
"""
:说明:
访问enkaAPI并转换为genshinUID的数据Json。
:参数:
* ``uid: str``: 玩家uid。
* ``enka_data: Optional[dict] = None``: 来自enka的dict, 可留空。
:返回:
* ``刷新完成提示语: str``: 包含刷新成功的角色列表。
"""
if '未找到绑定的UID' in uid:
return UID_HINT
if enka_data:
pass
else:
try:
enka_data = await get_enka_info(uid, ENKA_API[0])
except ReadTimeout:
return '网络不太稳定...'
if isinstance(enka_data, str):
return []
if isinstance(enka_data, dict):
if 'playerInfo' not in enka_data:
im = (
'服务器正在维护或者关闭中...\n'
f'检查{ENKA_API[0]}是否可以访问\n'
'如可以访问,尝试[切换api]或上报Bug!'
)
return im
elif enka_data is None:
return []
now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
playerInfo = enka_data['playerInfo']
path = PLAYER_PATH / str(uid)
path.mkdir(parents=True, exist_ok=True)
with open(
path / '{}.json'.format(str(uid)), 'w', encoding='UTF-8'
) as file:
json.dump(playerInfo, file, ensure_ascii=False)
with open(path / 'rawData.json', 'w', encoding='UTF-8') as file:
json.dump(enka_data, file, ensure_ascii=False)
if 'avatarInfoList' not in enka_data:
return f'UID{uid}刷新失败!未打开角色展柜!'
char_dict_list = []
for char in enka_data['avatarInfoList']:
# 处理基本信息
char_data = {}
avatarId = char['avatarId']
char_data['playerUid'] = str(uid)
char_data['playerName'] = enka_data['playerInfo']['nickname']
char_data['avatarId'] = avatarId
avatarName = avatarId2Name[str(char['avatarId'])]
char_data['avatarName'] = avatarId2Name[str(char['avatarId'])]
char_data['avatarFetter'] = char['fetterInfo']['expLevel']
char_data['avatarLevel'] = char['propMap']['4001']['val']
try:
char_data['avatarElement'] = avatarName2Element[
char_data['avatarName']
]
except KeyError:
check = skillId2Name['Name'][
str(list(char['skillLevelMap'].keys())[2])
]
if '' in check:
char_data['avatarElement'] = 'Anemo'
elif '' in check:
char_data['avatarElement'] = 'Electro'
elif '' in check:
char_data['avatarElement'] = 'Geo'
elif '' in check:
char_data['avatarElement'] = 'Dendro'
elif '' in check:
char_data['avatarElement'] = 'Cryo'
elif '' in check:
char_data['avatarElement'] = 'Hydro'
else:
char_data['avatarElement'] = 'Pyro'
char_data['dataTime'] = now
char_data['avatarSkill'] = []
# 处理天赋
for skill in char['skillLevelMap']:
skill_temp = {}
skill_temp['skillId'] = skill
skill_temp['skillName'] = skillId2Name['Name'][
skill_temp['skillId']
]
skill_temp['skillLevel'] = char['skillLevelMap'][skill]
skill_temp['skillIcon'] = skillId2Name['Icon'][
skill_temp['skillId']
]
char_data['avatarSkill'].append(skill_temp)
if char_data['avatarName'] in ['神里绫华', '安柏']:
char_data['avatarSkill'][0], char_data['avatarSkill'][-1] = (
char_data['avatarSkill'][-1],
char_data['avatarSkill'][0],
)
char_data['avatarSkill'][2], char_data['avatarSkill'][-1] = (
char_data['avatarSkill'][-1],
char_data['avatarSkill'][2],
)
char_data['avatarEnName'] = char_data['avatarSkill'][1][
'skillIcon'
].split('_')[-2]
elif char_data['avatarName'] in ['旅行者']:
char_data['avatarSkill'][0], char_data['avatarSkill'][-1] = (
char_data['avatarSkill'][-1],
char_data['avatarSkill'][0],
)
char_data['avatarSkill'][1], char_data['avatarSkill'][-1] = (
char_data['avatarSkill'][-1],
char_data['avatarSkill'][1],
)
char_data['avatarEnName'] = str(avatarId)
else:
char_data['avatarEnName'] = char_data['avatarSkill'][-1][
'skillIcon'
].split('_')[-2]
# 处理命座
talent_temp = []
if 'talentIdList' in char:
for index, talent in enumerate(char['talentIdList']):
talentTemp = {}
talentTemp['talentId'] = char['talentIdList'][index]
talentTemp['talentName'] = talentId2Name['Name'][str(talent)]
talentTemp['talentIcon'] = talentId2Name['Icon'][str(talent)]
talent_temp.append(talentTemp)
char_data['talentList'] = talent_temp
# 处理属性
fight_prop = {}
# 血量
fight_prop['hp'] = char["fightPropMap"]["2000"]
fight_prop['baseHp'] = char["fightPropMap"]["1"]
fight_prop['addHp'] = (
char["fightPropMap"]["2000"] - char["fightPropMap"]["1"]
)
# 攻击力
fight_prop['atk'] = char["fightPropMap"]["2001"]
fight_prop['baseAtk'] = char["fightPropMap"]["4"]
fight_prop['addAtk'] = (
char["fightPropMap"]["2001"] - char["fightPropMap"]["4"]
)
# 防御力
fight_prop['def'] = char["fightPropMap"]["2002"]
fight_prop['baseDef'] = char["fightPropMap"]["7"]
fight_prop['addDef'] = (
char["fightPropMap"]["2002"] - char["fightPropMap"]["7"]
)
# 元素精通
fight_prop['elementalMastery'] = char["fightPropMap"]["28"]
# 暴击率
fight_prop['critRate'] = char["fightPropMap"]["20"]
# 暴击伤害
fight_prop['critDmg'] = char["fightPropMap"]["22"]
# 充能效率
fight_prop['energyRecharge'] = char["fightPropMap"]["23"]
# 治疗&受治疗
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['dmgBonus'] = char["fightPropMap"][
PROP_ATTR_MAP[char_data['avatarElement']]
]
char_data['avatarFightProp'] = fight_prop
# 处理武器
weapon_info = {}
weapon_data = char['equipList'][-1]
weapon_info['itemId'] = weapon_data['itemId']
weapon_info['nameTextMapHash'] = weapon_data['flat']['nameTextMapHash']
weapon_info['weaponIcon'] = weapon_data['flat']['icon']
weapon_info['weaponType'] = weaponHash2Type[
weapon_info['nameTextMapHash']
]
weapon_info['weaponName'] = weaponHash2Name[
weapon_info['nameTextMapHash']
]
weapon_info['weaponStar'] = weapon_data['flat']['rankLevel']
# 防止未精炼
if 'promoteLevel' in weapon_data['weapon']:
weapon_info['promoteLevel'] = weapon_data['weapon']['promoteLevel']
else:
weapon_info['promoteLevel'] = 0
weapon_info['weaponLevel'] = weapon_data['weapon']['level']
if 'affixMap' in weapon_data['weapon']:
weapon_info['weaponAffix'] = (
list(weapon_data['weapon']['affixMap'].values())[0] + 1
)
else:
weapon_info['weaponAffix'] = 1
weapon_info['weaponStats'] = []
for k in weapon_data['flat']['weaponStats']:
weapon_prop_temp = {}
weapon_prop_temp['appendPropId'] = k['appendPropId']
weapon_prop_temp['statName'] = propId2Name[k['appendPropId']]
weapon_prop_temp['statValue'] = k['statValue']
weapon_info['weaponStats'].append(weapon_prop_temp)
# 武器特效须请求API
try:
effect_raw = await get_weapon_info(weapon_info['weaponName'])
except ConnectTimeout:
effect_raw = await convert_ambr_to_weapon(weapon_info['itemId'])
if not isinstance(effect_raw, List) and not isinstance(
effect_raw, int
):
effect = effect_raw['effect'].format( # type:ignore
*effect_raw[ # type:ignore
'r{}'.format(str(weapon_info['weaponAffix']))
]
)
else:
effect = '无特效。'
weapon_info['weaponEffect'] = effect
char_data['weaponInfo'] = weapon_info
# 处理圣遗物
artifacts_info = []
artifacts_data = char['equipList'][:-1]
artifact_set_list = []
for artifact in artifacts_data:
artifact_temp = {}
artifact_temp['itemId'] = artifact['itemId']
artifact_temp['nameTextMapHash'] = artifact['flat'][
'nameTextMapHash'
]
artifact_temp['icon'] = artifact['flat']['icon']
artifact_temp['aritifactName'] = icon2Name[
artifact['flat']['icon']
]
artifact_temp['aritifactSetsName'] = artifact2attr[
artifact_temp['aritifactName']
]
artifact_set_list.append(artifact_temp['aritifactSetsName'])
artifact_temp['aritifactSetPiece'] = artifactId2Piece[
artifact_temp['icon'].split('_')[-1]
][0]
artifact_temp['aritifactPieceName'] = artifactId2Piece[
artifact_temp['icon'].split('_')[-1]
][1]
artifact_temp['aritifactStar'] = artifact['flat']['rankLevel']
artifact_temp['aritifactLevel'] = (
artifact['reliquary']['level'] - 1
)
artifact_temp['reliquaryMainstat'] = artifact['flat'][
'reliquaryMainstat'
]
artifact_temp['reliquaryMainstat']['statName'] = propId2Name[
artifact_temp['reliquaryMainstat']['mainPropId']
]
if 'reliquarySubstats' in artifact['flat']:
artifact_temp['reliquarySubstats'] = artifact['flat'][
'reliquarySubstats'
]
else:
artifact_temp['reliquarySubstats'] = []
for sub in artifact_temp['reliquarySubstats']:
sub['statName'] = propId2Name[sub['appendPropId']]
artifacts_info.append(artifact_temp)
equipSetList = set(artifact_set_list)
char_data['equipSets'] = {'type': '', 'set': ''}
char_data['equipList'] = artifacts_info
for equip in equipSetList:
if artifact_set_list.count(equip) >= 4:
char_data['equipSets']['type'] = '4'
char_data['equipSets']['set'] = equip
break
elif artifact_set_list.count(equip) == 1:
pass
elif artifact_set_list.count(equip) >= 2:
char_data['equipSets']['type'] += '2'
char_data['equipSets']['set'] += '|' + equip
if char_data['equipSets']['set'].startswith('|'):
char_data['equipSets']['set'] = char_data['equipSets']['set'][1:]
char_dict_list.append(char_data)
with open(
path / '{}.json'.format(avatarName), 'w', encoding='UTF-8'
) as file:
json.dump(char_data, file, ensure_ascii=False)
return char_dict_list
async def enka_to_data(
uid: str, enka_data: Optional[EnkaData] = None
) -> Union[dict, str]:
raw_data = await enka_to_dict(uid, enka_data)
if isinstance(raw_data, str):
return raw_data
char_name_list = []
char_name_list_str = ''
for char_data in raw_data:
char_name_list.append(char_data['avatarName'])
char_name_list_str = ','.join(char_name_list)
return f'UID{uid}刷新完成!\n本次缓存:{char_name_list_str}'