2023-08-11 08:29:15 +00:00
|
|
|
import re
|
|
|
|
from typing import Tuple, List, Optional
|
|
|
|
|
|
|
|
from python_genshin_artifact.enka.artifacts import artifacts_name_map, equip_type_map
|
|
|
|
from python_genshin_artifact.enka.assets import Assets
|
|
|
|
from python_genshin_artifact.enka.characters import characters_map
|
2023-11-07 16:42:44 +00:00
|
|
|
from python_genshin_artifact.enka.fight import fight_map, to_float
|
2023-08-11 08:29:15 +00:00
|
|
|
from python_genshin_artifact.enka.weapon import weapon_name_map
|
2023-10-24 08:26:40 +00:00
|
|
|
from python_genshin_artifact.error import EnkaParseException
|
2023-11-07 16:42:44 +00:00
|
|
|
from python_genshin_artifact import Artifact, CharacterInterface, WeaponInterface
|
2023-08-11 08:29:15 +00:00
|
|
|
|
|
|
|
assets = Assets()
|
|
|
|
|
|
|
|
|
|
|
|
def is_ascend(level: int, promote_level: int) -> bool:
|
|
|
|
if level < 20:
|
|
|
|
return False
|
2023-10-22 07:34:20 +00:00
|
|
|
if 20 <= level < 40:
|
2023-08-11 08:29:15 +00:00
|
|
|
return promote_level >= 1
|
2023-10-22 07:34:20 +00:00
|
|
|
expected_promote_level = level // 10 - 2
|
|
|
|
return promote_level >= expected_promote_level
|
2023-08-11 08:29:15 +00:00
|
|
|
|
|
|
|
|
2023-11-07 16:42:44 +00:00
|
|
|
def enka_parser(data: dict, avatar_id: int) -> Tuple[CharacterInterface, WeaponInterface, List[Artifact]]:
|
2023-08-11 08:29:15 +00:00
|
|
|
character_info = assets.get_character(avatar_id)
|
|
|
|
if character_info is None:
|
2023-10-24 08:26:40 +00:00
|
|
|
raise EnkaParseException(f"avatarId={avatar_id} is not found in assets")
|
2023-08-11 08:29:15 +00:00
|
|
|
_avatar_info_list = data["avatarInfoList"]
|
|
|
|
_avatar_info: dict = {}
|
|
|
|
for _value in _avatar_info_list:
|
|
|
|
if _value["avatarId"] == avatar_id:
|
|
|
|
_avatar_info = _value
|
|
|
|
break
|
|
|
|
else:
|
2023-10-24 08:26:40 +00:00
|
|
|
raise EnkaParseException(f"avatarId={avatar_id} is not found")
|
2023-10-23 02:46:14 +00:00
|
|
|
_prop_map = _avatar_info.get("propMap", {})
|
|
|
|
level = int(_prop_map["4001"].get("ival", 0)) if "4001" in _prop_map else 0
|
2023-08-11 08:29:15 +00:00
|
|
|
talent_id_list = _avatar_info.get("talentIdList", []) # 命之座 ID 列 如果未解锁任何命之座则此数据不存在
|
|
|
|
_skill_level_map: "dict" = _avatar_info["skillLevelMap"]
|
|
|
|
skill_info = {"skill1": 1, "skill2": 1, "skill3": 1}
|
|
|
|
for _index, _value in enumerate(character_info["ProudMap"]):
|
|
|
|
_level = _skill_level_map.get(str(_value))
|
|
|
|
_key_name = "skill" + str(_index + 1)
|
2023-10-21 18:03:48 +00:00
|
|
|
skill_info[_key_name] = _level - 1 # mona 的角色等级是从 0 开始并非 1 估计是使用了List导致的
|
2023-08-11 08:29:15 +00:00
|
|
|
for _index, _value in enumerate(character_info["Consts"]):
|
|
|
|
if "UI_Talent_U_" in _value and len(talent_id_list) > _index:
|
|
|
|
if _value.endswith("01"):
|
|
|
|
skill_info["skill2"] += 3
|
|
|
|
if _value.endswith("02"):
|
|
|
|
skill_info["skill3"] += 3
|
|
|
|
character_name = characters_map.get(avatar_id)
|
2023-11-07 16:42:44 +00:00
|
|
|
character = CharacterInterface(
|
2023-08-11 08:29:15 +00:00
|
|
|
name=character_name,
|
|
|
|
level=level,
|
|
|
|
constellation=len(talent_id_list),
|
|
|
|
ascend=False,
|
|
|
|
skill1=skill_info["skill1"],
|
|
|
|
skill2=skill_info["skill2"],
|
|
|
|
skill3=skill_info["skill3"],
|
|
|
|
)
|
|
|
|
_equip_list = _avatar_info["equipList"]
|
|
|
|
weapon, artifacts = de_equip_list(_equip_list)
|
|
|
|
|
|
|
|
return character, weapon, artifacts
|
|
|
|
|
|
|
|
|
2023-11-07 16:42:44 +00:00
|
|
|
def de_equip_list(equip_list: list[dict]) -> Tuple[WeaponInterface, List[Artifact]]:
|
|
|
|
weapon: Optional[WeaponInterface] = None
|
|
|
|
artifacts: List[Artifact] = []
|
2023-08-11 08:29:15 +00:00
|
|
|
for _equip in equip_list:
|
|
|
|
_weapon = _equip.get("weapon")
|
|
|
|
_reliquary = _equip.get("reliquary")
|
|
|
|
if _reliquary:
|
|
|
|
sub_stats: List[Tuple[str, float]] = []
|
|
|
|
_flat = _equip["flat"]
|
2023-10-24 08:26:40 +00:00
|
|
|
try:
|
|
|
|
artifact_id = int(re.findall(r"\d+", _flat["icon"])[0])
|
|
|
|
except IndexError:
|
|
|
|
raise EnkaParseException(f"artifact_id is not found in {_flat['icon']}")
|
2023-08-11 08:29:15 +00:00
|
|
|
set_name = artifacts_name_map.get(artifact_id)
|
|
|
|
if set_name is None:
|
2023-10-24 08:26:40 +00:00
|
|
|
raise EnkaParseException(f"artifact_id={artifact_id} is not found in assets")
|
2023-08-11 08:29:15 +00:00
|
|
|
_level = _reliquary["level"] - 1
|
|
|
|
_reliquary_main_stat = _flat["reliquaryMainstat"]
|
|
|
|
_main_prop_id = _reliquary_main_stat["mainPropId"]
|
|
|
|
stat_name = fight_map[_main_prop_id]
|
2023-11-07 16:42:44 +00:00
|
|
|
stat_value = to_float(_main_prop_id, _reliquary_main_stat["statValue"])
|
2023-08-11 08:29:15 +00:00
|
|
|
_main_stat = (stat_name, stat_value)
|
2023-11-10 06:04:41 +00:00
|
|
|
reliquary_sub_stats = _flat.get("reliquarySubstats")
|
|
|
|
if reliquary_sub_stats is not None:
|
|
|
|
for _reliquary_sub_stats in reliquary_sub_stats:
|
|
|
|
_append_prop_id = _reliquary_sub_stats["appendPropId"]
|
|
|
|
stat_name = fight_map[_append_prop_id]
|
|
|
|
stat_value = to_float(_append_prop_id, _reliquary_sub_stats["statValue"])
|
|
|
|
_sub_stats = (stat_name, stat_value)
|
|
|
|
sub_stats.append(_sub_stats)
|
2023-08-11 08:29:15 +00:00
|
|
|
slot = equip_type_map[_flat["equipType"]]
|
|
|
|
star = _flat["rankLevel"]
|
|
|
|
artifacts.append(
|
2023-11-07 16:42:44 +00:00
|
|
|
Artifact(
|
2023-08-11 08:29:15 +00:00
|
|
|
set_name=set_name,
|
|
|
|
id=artifact_id,
|
|
|
|
level=_level,
|
|
|
|
main_stat=_main_stat,
|
|
|
|
sub_stats=sub_stats,
|
|
|
|
slot=slot,
|
|
|
|
star=star,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if _weapon:
|
|
|
|
weapon_id = _equip["itemId"]
|
|
|
|
weapon_name = weapon_name_map.get(weapon_id)
|
|
|
|
if weapon_name is None:
|
2023-10-24 08:26:40 +00:00
|
|
|
raise EnkaParseException(f"weapon_id={weapon_id} is not found in assets")
|
2023-10-21 16:51:31 +00:00
|
|
|
_level = _weapon["level"]
|
2023-11-08 06:27:59 +00:00
|
|
|
affix_map = _weapon.get("affixMap")
|
|
|
|
refinement_level = 0
|
|
|
|
if affix_map is not None:
|
|
|
|
refinement_level = next(iter(affix_map.values())) + 1
|
2023-10-24 08:26:40 +00:00
|
|
|
_promote_level = _weapon.get("promoteLevel")
|
|
|
|
ascend = False
|
|
|
|
if _promote_level is not None:
|
|
|
|
ascend = is_ascend(_level, _promote_level)
|
2023-11-07 16:42:44 +00:00
|
|
|
weapon = WeaponInterface(level=_level, refine=refinement_level, ascend=ascend, name=weapon_name)
|
2023-08-11 08:29:15 +00:00
|
|
|
return weapon, artifacts
|