mirror of
https://github.com/PaiGramTeam/genshin-wiki.git
synced 2024-11-27 18:04:03 +00:00
🐛 fix some bugs
This commit is contained in:
parent
7cb30c4b04
commit
ea67d86f4b
@ -1,12 +1,8 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from model.avatar._talente import AvatarTalents
|
||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||
from model.other import ItemCount
|
||||
from utils.model import BaseModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from model.avatar._talente import AvatarTalents
|
||||
|
||||
__all__ = (
|
||||
"Avatar",
|
||||
"AvatarBirth",
|
||||
@ -74,17 +70,17 @@ class AvatarStories(BaseModel):
|
||||
story_5: Story
|
||||
"""角色故事5"""
|
||||
|
||||
miscellaneous: Story
|
||||
miscellaneous: Story | None = None
|
||||
"""角色杂谈"""
|
||||
|
||||
vision: Story
|
||||
vision: Story | None = None
|
||||
"""神之眼"""
|
||||
|
||||
|
||||
class AvatarInfo(BaseModel):
|
||||
title: str
|
||||
title: str | None
|
||||
"""称号"""
|
||||
birth: AvatarBirth
|
||||
birth: AvatarBirth | None
|
||||
"""生日"""
|
||||
occupation: str
|
||||
"""所属"""
|
||||
@ -123,6 +119,8 @@ class AvatarConstellation(BaseModel):
|
||||
"""命座描述"""
|
||||
icon: str
|
||||
"""命座图标"""
|
||||
param_list: list[float]
|
||||
"""命座数据参数列表"""
|
||||
|
||||
|
||||
class AvatarAttribute(BaseModel):
|
||||
@ -177,7 +175,7 @@ class Avatar(BaseModel):
|
||||
"""角色信息"""
|
||||
attributes: AvatarAttribute
|
||||
"""角色基础属性"""
|
||||
talents: "AvatarTalents"
|
||||
talents: AvatarTalents
|
||||
"""角色天赋信息"""
|
||||
promotes: list[AvatarPromote]
|
||||
"""角色突破数据"""
|
||||
|
@ -112,16 +112,16 @@ class AvatarTalents(BaseModel):
|
||||
|
||||
normal_attack: NormalAttack
|
||||
"""普通攻击"""
|
||||
elemental_skill: ElementalSkill
|
||||
elemental_skill: ElementalSkill | None
|
||||
"""元素战技"""
|
||||
elemental_burst: ElementalBurst
|
||||
elemental_burst: ElementalBurst | None
|
||||
"""元素爆发"""
|
||||
alternate_sprint: AlternateSprint | None = None
|
||||
"""冲刺技能"""
|
||||
|
||||
first_ascension_passive: FirstAscensionPassive
|
||||
first_ascension_passive: FirstAscensionPassive | None
|
||||
"""第一次突破固有天赋"""
|
||||
fourth_ascension_passive: FourthAscensionPassive
|
||||
fourth_ascension_passive: FourthAscensionPassive | None
|
||||
"""第四次突破固有天赋"""
|
||||
utility_passive: UtilityPassive | None = None
|
||||
"""实用固有天赋"""
|
||||
|
@ -1,10 +1,15 @@
|
||||
from itertools import chain
|
||||
from typing import TypeVar
|
||||
|
||||
import ujson as json
|
||||
from aiofiles import open as async_open
|
||||
|
||||
from model.avatar import (
|
||||
AlternateSprint,
|
||||
Avatar,
|
||||
AvatarAttribute,
|
||||
AvatarBirth,
|
||||
AvatarConstellation,
|
||||
AvatarInfo,
|
||||
AvatarPromote,
|
||||
AvatarStories,
|
||||
@ -26,6 +31,7 @@ from model.avatar import (
|
||||
from model.enums import Association, AvatarQuality, Element, WeaponType
|
||||
from model.other import ItemCount
|
||||
from utils.const import PROJECT_ROOT
|
||||
from utils.funcs import remove_rich_tag
|
||||
from utils.manager import ResourceManager
|
||||
from utils.typedefs import Lang
|
||||
|
||||
@ -38,127 +44,81 @@ TalentType = TypeVar("TalentType", bound=Talent)
|
||||
|
||||
OUT_DIR = PROJECT_ROOT.joinpath("out")
|
||||
|
||||
elements = {
|
||||
3057990932: Element.Cryo,
|
||||
467004516: Element.Anemo,
|
||||
821712868: Element.Null,
|
||||
2480172868: Element.Electro,
|
||||
4022324356: Element.Hydro,
|
||||
627825788: Element.Pyro,
|
||||
2596397668: Element.Dendro,
|
||||
967031460: Element.Geo,
|
||||
elements_map = {
|
||||
(
|
||||
230082676,
|
||||
313529204,
|
||||
627825788,
|
||||
1247335084,
|
||||
1646245548,
|
||||
1740638908,
|
||||
3105283268,
|
||||
3112476852,
|
||||
3177381772,
|
||||
3847511308,
|
||||
): Element.Pyro,
|
||||
(
|
||||
321258364,
|
||||
483165900,
|
||||
756679372,
|
||||
1688473500,
|
||||
2480954540,
|
||||
3228108484,
|
||||
3400532572,
|
||||
3646588372,
|
||||
4022324356,
|
||||
): Element.Hydro,
|
||||
(
|
||||
126875444,
|
||||
467004516,
|
||||
550531300,
|
||||
898621369,
|
||||
1778251796,
|
||||
2075460644,
|
||||
2477900860,
|
||||
2648184060,
|
||||
): Element.Anemo,
|
||||
(
|
||||
122554396,
|
||||
608089036,
|
||||
689445588,
|
||||
1072755468,
|
||||
1821644548,
|
||||
1843086100,
|
||||
2085306033,
|
||||
2143937940,
|
||||
2480172868,
|
||||
2689029804,
|
||||
3352621156,
|
||||
4219874220,
|
||||
): Element.Electro,
|
||||
(2161032364, 4017448612): Element.Dendro,
|
||||
(
|
||||
98482612,
|
||||
766902996,
|
||||
862088588,
|
||||
1480674860,
|
||||
1695600284,
|
||||
2778487532,
|
||||
2809830820,
|
||||
3057990932,
|
||||
4127670180,
|
||||
4220569804,
|
||||
): Element.Cryo,
|
||||
(
|
||||
825986772,
|
||||
967031460,
|
||||
1016213980,
|
||||
1662907292,
|
||||
2507042785,
|
||||
3219124204,
|
||||
3617274620,
|
||||
3929787020,
|
||||
): Element.Geo,
|
||||
(471154292, 821712868, 1128382182, 3053155130, 4168416172): Element.Null,
|
||||
}
|
||||
|
||||
|
||||
# noinspection PyShadowingBuiltins,SpellCheckingInspection
|
||||
async def parse_avatar_data(lang: Lang):
|
||||
out_path = OUT_DIR.joinpath(f"{lang}")
|
||||
out_path.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
manager = ResourceManager(lang=lang)
|
||||
avatar_json_data = manager.fetch("AvatarExcelConfigData")
|
||||
fetter_info_json_data = manager.fetch("FetterInfoExcelConfigData")
|
||||
story_json_data = manager.fetch("FetterStoryExcelConfigData")
|
||||
promote_json_data = manager.fetch("AvatarPromoteExcelConfigData")
|
||||
|
||||
skill_depot_json_data = manager.fetch("AvatarSkillDepotExcelConfigData")
|
||||
skill_json_data = manager.fetch("AvatarSkillExcelConfigData")
|
||||
proud_skill_json_data = manager.fetch("ProudSkillExcelConfigData")
|
||||
|
||||
avatar_list = []
|
||||
for data in avatar_json_data:
|
||||
id = data["id"]
|
||||
if (
|
||||
info_data := next(
|
||||
chain(
|
||||
filter(lambda x: x["avatarId"] == id, fetter_info_json_data),
|
||||
[
|
||||
None,
|
||||
],
|
||||
)
|
||||
)
|
||||
) is None:
|
||||
continue
|
||||
name = manager.get_text(data["nameTextMapHash"])
|
||||
element = elements[info_data["avatarVisionBeforTextMapHash"]]
|
||||
quality = AvatarQuality(data["qualityType"].removeprefix("QUALITY_"))
|
||||
weapon_type = next(
|
||||
filter(lambda x: x in data["weaponType"], WeaponType.__members__.values())
|
||||
)
|
||||
|
||||
# 角色信息
|
||||
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
||||
birth = AvatarBirth(
|
||||
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
||||
)
|
||||
occupation = manager.get_text(info_data["avatarNativeTextMapHash"])
|
||||
vision = manager.get_text(info_data["avatarVisionBeforTextMapHash"])
|
||||
constellation = manager.get_text(
|
||||
info_data["avatarConstellationBeforTextMapHash"]
|
||||
)
|
||||
description = manager.get_text(info_data["avatarDetailTextMapHash"])
|
||||
association = Association(
|
||||
info_data["avatarAssocType"].removeprefix("ASSOC_TYPE_")
|
||||
)
|
||||
seuyu = Seuyu(
|
||||
cn=manager.get_text(info_data["cvChineseTextMapHash"]),
|
||||
jp=manager.get_text(info_data["cvJapaneseTextMapHash"]),
|
||||
en=manager.get_text(info_data["cvEnglishTextMapHash"]),
|
||||
kr=manager.get_text(info_data["cvKoreanTextMapHash"]),
|
||||
)
|
||||
story_data = sorted(
|
||||
filter(lambda x: x["avatarId"] == id, story_json_data),
|
||||
key=lambda x: x["fetterId"],
|
||||
)
|
||||
stories = AvatarStories(
|
||||
**{
|
||||
i[0]: i[1]
|
||||
for i in zip(
|
||||
AvatarStories.__fields__.keys(),
|
||||
map(
|
||||
lambda x: Story(
|
||||
title=manager.get_text(x["storyTitleTextMapHash"]),
|
||||
content=manager.get_text(x["storyContextTextMapHash"]),
|
||||
tips=list(
|
||||
filter(
|
||||
lambda y: y is not None,
|
||||
map(
|
||||
lambda z: manager.get_text(z),
|
||||
x["tips"],
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
sorted(
|
||||
filter(lambda x: x["avatarId"] == id, story_data),
|
||||
key=lambda x: x["fetterId"],
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
)
|
||||
information = AvatarInfo(
|
||||
title=title,
|
||||
birth=birth,
|
||||
occupation=occupation,
|
||||
vision=vision,
|
||||
constellation=constellation,
|
||||
description=description,
|
||||
association=association,
|
||||
seuyu=seuyu,
|
||||
stories=stories,
|
||||
)
|
||||
|
||||
# 角色基础属性
|
||||
attribute = AvatarAttribute(
|
||||
HP=data["hpBase"],
|
||||
Attack=data["attackBase"],
|
||||
Defense=data["defenseBase"],
|
||||
Critical=data["critical"],
|
||||
CriticalDamage=data["criticalHurt"],
|
||||
ChargeEfficiency=data["chargeEfficiency"],
|
||||
)
|
||||
|
||||
def get_skill_attributes(proud_skill_group_id: int) -> list[TalentAttribute]:
|
||||
proud_skill_datas = sorted(
|
||||
filter(
|
||||
@ -193,10 +153,7 @@ async def parse_avatar_data(lang: Lang):
|
||||
coin=proud_skill_data.get("coinCost", 0),
|
||||
cost_items=list(
|
||||
map(
|
||||
lambda x: ItemCount(
|
||||
item_id=x["id"],
|
||||
count=x["count"],
|
||||
),
|
||||
lambda x: ItemCount(item_id=x["id"], count=x["count"]),
|
||||
filter(lambda x: x, proud_skill_data["costItems"]),
|
||||
)
|
||||
),
|
||||
@ -204,15 +161,14 @@ async def parse_avatar_data(lang: Lang):
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def parse_skill(skill_id: int, skill_cls: type[CombatTalent]) -> CombatTalent:
|
||||
skill_data = next(filter(lambda x: x["id"] == skill_id, skill_json_data))
|
||||
_name = manager.get_text(skill_data["nameTextMapHash"])
|
||||
_description = manager.get_text(skill_data["descTextMapHash"])
|
||||
icon = skill_data["skillIcon"]
|
||||
cooldown = (
|
||||
skill_data.get("cdTime", 0)
|
||||
if "cooldown" in skill_cls.__fields__.keys()
|
||||
else None
|
||||
skill_data.get("cdTime", 0) if "cooldown" in skill_cls.__fields__ else None
|
||||
)
|
||||
attributes = get_skill_attributes(skill_data["proudSkillGroupId"])
|
||||
return skill_cls(
|
||||
@ -226,15 +182,14 @@ async def parse_avatar_data(lang: Lang):
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def parse_passive_talent(
|
||||
talent_data: dict, talent_cls: type[PassiveTalent]
|
||||
) -> PassiveTalent:
|
||||
group_id = talent_data["proudSkillGroupId"]
|
||||
_promote_level = talent_data.get("needAvatarPromoteLevel", 0)
|
||||
skill_data = next(
|
||||
filter(
|
||||
lambda x: x["proudSkillGroupId"] == group_id, proud_skill_json_data
|
||||
)
|
||||
filter(lambda x: x["proudSkillGroupId"] == group_id, proud_skill_json_data)
|
||||
)
|
||||
param_descriptions = list(
|
||||
filter(
|
||||
@ -247,20 +202,11 @@ async def parse_avatar_data(lang: Lang):
|
||||
)
|
||||
_description = manager.get_text(skill_data["descTextMapHash"])
|
||||
_param_list = skill_data["paramList"][
|
||||
: len(
|
||||
re.findall(
|
||||
r"(\d+)|(?:(\d+)%)|(?:(\d+\.\d+))",
|
||||
re.sub(
|
||||
r"(<(?P<tag_name>[a-z]+?)=(?P<value>.+?)>.+</(?P=tag_name)>)",
|
||||
"",
|
||||
_description,
|
||||
),
|
||||
)
|
||||
)
|
||||
: len(re.findall(r"(\d+(?:\.)?\d+)", remove_rich_tag(_description) or ""))
|
||||
]
|
||||
return talent_cls(
|
||||
name=manager.get_text(skill_data["nameTextMapHash"]),
|
||||
description=_description,
|
||||
name=manager.get_text(skill_data["nameTextMapHash"]) or "",
|
||||
description=_description or "",
|
||||
icon=skill_data["icon"],
|
||||
promote_level=_promote_level,
|
||||
attribute=TalentAttribute(
|
||||
@ -270,6 +216,125 @@ async def parse_avatar_data(lang: Lang):
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# noinspection PyShadowingBuiltins,SpellCheckingInspection,PyGlobalUndefined
|
||||
async def parse_avatar_data(lang: Lang):
|
||||
global out_path, manager
|
||||
global avatar_json_data, fetter_info_json_data, story_json_data, promote_json_data
|
||||
global skill_depot_json_data, skill_json_data, proud_skill_json_data, talent_json_data
|
||||
out_path = OUT_DIR.joinpath(f"{lang}")
|
||||
out_path.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
manager = ResourceManager(lang=lang)
|
||||
avatar_json_data = manager.fetch("AvatarExcelConfigData")
|
||||
fetter_info_json_data = manager.fetch("FetterInfoExcelConfigData")
|
||||
story_json_data = manager.fetch("FetterStoryExcelConfigData")
|
||||
promote_json_data = manager.fetch("AvatarPromoteExcelConfigData")
|
||||
|
||||
skill_depot_json_data = manager.fetch("AvatarSkillDepotExcelConfigData")
|
||||
skill_json_data = manager.fetch("AvatarSkillExcelConfigData")
|
||||
proud_skill_json_data = manager.fetch("ProudSkillExcelConfigData")
|
||||
talent_json_data = manager.fetch("AvatarTalentExcelConfigData")
|
||||
|
||||
avatar_list = []
|
||||
for data in avatar_json_data:
|
||||
id = data["id"]
|
||||
if (
|
||||
info_data := next(
|
||||
chain(
|
||||
filter(lambda x: x["avatarId"] == id, fetter_info_json_data), [None]
|
||||
)
|
||||
)
|
||||
) is None:
|
||||
continue
|
||||
name = manager.get_text(data["nameTextMapHash"])
|
||||
element = next(
|
||||
filter(
|
||||
lambda x: info_data["avatarVisionBeforTextMapHash"] in x[0],
|
||||
elements_map.items(),
|
||||
)
|
||||
)[1]
|
||||
quality = AvatarQuality(
|
||||
data["qualityType"].removeprefix("QUALITY_").replace("ORANGE_SP", "SPECIAL")
|
||||
)
|
||||
weapon_type = next(
|
||||
filter(
|
||||
lambda x: x in data["weaponType"].replace("POLE", "POLEARM"),
|
||||
WeaponType.__members__.values(),
|
||||
)
|
||||
)
|
||||
|
||||
# 角色信息
|
||||
title = manager.get_text(info_data["avatarTitleTextMapHash"])
|
||||
birth = (
|
||||
AvatarBirth(
|
||||
month=info_data["infoBirthMonth"], day=info_data["infoBirthDay"]
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
occupation = manager.get_text(info_data["avatarNativeTextMapHash"])
|
||||
vision = manager.get_text(info_data["avatarVisionBeforTextMapHash"])
|
||||
constellation = manager.get_text(
|
||||
info_data["avatarConstellationBeforTextMapHash"]
|
||||
)
|
||||
description = manager.get_text(info_data["avatarDetailTextMapHash"])
|
||||
association = Association(
|
||||
info_data["avatarAssocType"].removeprefix("ASSOC_TYPE_")
|
||||
)
|
||||
seuyu = Seuyu(
|
||||
cn=manager.get_text(info_data["cvChineseTextMapHash"]),
|
||||
jp=manager.get_text(info_data["cvJapaneseTextMapHash"]),
|
||||
en=manager.get_text(info_data["cvEnglishTextMapHash"]),
|
||||
kr=manager.get_text(info_data["cvKoreanTextMapHash"]),
|
||||
)
|
||||
story_datas = sorted(
|
||||
filter(lambda x: x["avatarId"] == id, story_json_data),
|
||||
key=lambda x: x["fetterId"],
|
||||
)
|
||||
stories = []
|
||||
for story_data in sorted(
|
||||
filter(lambda x: x["avatarId"] == id, story_datas),
|
||||
key=lambda x: x["fetterId"],
|
||||
):
|
||||
tips = list(
|
||||
filter(
|
||||
lambda x: x is not None,
|
||||
map(lambda x: manager.get_text(x), story_data["tips"]),
|
||||
)
|
||||
)
|
||||
story = Story(
|
||||
title=manager.get_text(story_data["storyTitleTextMapHash"]),
|
||||
content=manager.get_text(story_data["storyContextTextMapHash"]),
|
||||
tips=tips,
|
||||
)
|
||||
stories.append(story)
|
||||
|
||||
avatar_stories = AvatarStories(
|
||||
**{i[0]: i[1] for i in zip(AvatarStories.__fields__, stories)}
|
||||
)
|
||||
information = AvatarInfo(
|
||||
title=title,
|
||||
birth=birth,
|
||||
occupation=occupation,
|
||||
vision=vision,
|
||||
constellation=constellation,
|
||||
description=description,
|
||||
association=association,
|
||||
seuyu=seuyu,
|
||||
stories=avatar_stories,
|
||||
)
|
||||
|
||||
# 角色基础属性
|
||||
attributes = AvatarAttribute(
|
||||
HP=data["hpBase"],
|
||||
Attack=data["attackBase"],
|
||||
Defense=data["defenseBase"],
|
||||
Critical=data["critical"],
|
||||
CriticalDamage=data["criticalHurt"],
|
||||
ChargeEfficiency=data["chargeEfficiency"],
|
||||
)
|
||||
|
||||
# 天赋
|
||||
skill_depot_data = next(
|
||||
filter(lambda x: x["id"] == data["skillDepotId"], skill_depot_json_data)
|
||||
@ -278,36 +343,47 @@ async def parse_avatar_data(lang: Lang):
|
||||
# 普通攻击
|
||||
normal_attack = parse_skill(skill_ids[0], NormalAttack)
|
||||
# 元素战技
|
||||
elemental_skill = parse_skill(skill_ids[1], ElementalSkill)
|
||||
elemental_skill = (
|
||||
parse_skill(skill_ids[1], ElementalSkill)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 冲刺技能
|
||||
alternate_sprint = (
|
||||
parse_skill(skill_ids[2], AlternateSprint) if len(skill_ids) == 3 else None
|
||||
)
|
||||
# 元素爆发
|
||||
burst_skill = parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
||||
burst_skill = (
|
||||
parse_skill(skill_depot_data["energySkill"], ElementalBurst)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 第一次突破被动天赋
|
||||
first_passive = parse_passive_talent(
|
||||
first_passive = (
|
||||
parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][0], FirstAscensionPassive
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 第四次突破被动天赋
|
||||
fourth_passive = parse_passive_talent(
|
||||
fourth_passive = (
|
||||
parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][1], FourthAscensionPassive
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 实用固有天赋
|
||||
utility_passive = parse_passive_talent(
|
||||
utility_passive = (
|
||||
parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][2], UtilityPassive
|
||||
)
|
||||
if id not in [10000005, 10000007]
|
||||
else None
|
||||
)
|
||||
# 杂项固有天赋
|
||||
if (
|
||||
len(
|
||||
list(
|
||||
filter(
|
||||
lambda x: x != 0, skill_depot_data["inherentProudSkillOpens"]
|
||||
)
|
||||
)
|
||||
)
|
||||
== 4
|
||||
):
|
||||
if skill_depot_data["inherentProudSkillOpens"][3]:
|
||||
miscellaneous_passive = parse_passive_talent(
|
||||
skill_depot_data["inherentProudSkillOpens"][3], MiscellaneousPassive
|
||||
)
|
||||
@ -335,7 +411,7 @@ async def parse_avatar_data(lang: Lang):
|
||||
for promote_data in promote_datas:
|
||||
items = []
|
||||
for item_data in promote_data["costItems"]:
|
||||
if item_data:
|
||||
if item_data and id not in [10000005, 10000007]:
|
||||
items.append(
|
||||
ItemCount(item_id=item_data["id"], count=item_data["count"])
|
||||
)
|
||||
@ -347,4 +423,47 @@ async def parse_avatar_data(lang: Lang):
|
||||
cost_items=items,
|
||||
)
|
||||
)
|
||||
breakpoint()
|
||||
|
||||
# 角色命座信息
|
||||
constellations: list[AvatarConstellation] = []
|
||||
for constellation_id in filter(lambda x: x != 0, skill_depot_data["talents"]):
|
||||
constellation_data = next(
|
||||
filter(lambda x: x["talentId"] == constellation_id, talent_json_data)
|
||||
)
|
||||
constellation_description = manager.get_text(
|
||||
constellation_data["descTextMapHash"]
|
||||
)
|
||||
# noinspection PyTypeChecker
|
||||
constellations.append(
|
||||
AvatarConstellation(
|
||||
name=manager.get_text(constellation_data["nameTextMapHash"]),
|
||||
description=constellation_description,
|
||||
icon=constellation_data["icon"],
|
||||
param_list=list(
|
||||
filter(lambda x: x != 0.0, constellation_data["paramList"])
|
||||
),
|
||||
)
|
||||
)
|
||||
avatar = Avatar(
|
||||
id=id,
|
||||
name=name,
|
||||
element=element,
|
||||
quality=quality,
|
||||
weapon_type=weapon_type,
|
||||
information=information,
|
||||
attributes=attributes,
|
||||
talents=avatar_talents,
|
||||
promotes=promotes,
|
||||
constellations=constellations,
|
||||
)
|
||||
avatar_list.append(avatar)
|
||||
async with async_open(out_path / "avatar.json", encoding="utf-8", mode="w") as file:
|
||||
await file.write(
|
||||
json.dumps(
|
||||
[i.dict() for i in avatar_list],
|
||||
ensure_ascii=False,
|
||||
encode_html_chars=False,
|
||||
indent=4,
|
||||
),
|
||||
)
|
||||
return out_path, avatar_list
|
||||
|
14
utils/funcs.py
Normal file
14
utils/funcs.py
Normal file
@ -0,0 +1,14 @@
|
||||
try:
|
||||
import regex as re
|
||||
except ImportError:
|
||||
import re
|
||||
|
||||
__all__ = ("remove_rich_tag",)
|
||||
|
||||
|
||||
def remove_rich_tag(string: str | None) -> str:
|
||||
"""去除富文本标签"""
|
||||
if string is not None:
|
||||
return re.sub(
|
||||
r"(<(?P<tag_name>[a-z]+?)=(?P<value>.+?)>.+?</(?P=tag_name)>)", "", string
|
||||
)
|
Loading…
Reference in New Issue
Block a user