From f958a2d749d0c26fb29396426861d503142aee9c Mon Sep 17 00:00:00 2001 From: Karako Date: Tue, 2 May 2023 11:10:53 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20parse=20avatar=20stories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/avatar/_avatar.py | 50 +++++++++++++++++- model/enums.py | 18 +++++++ scripts/avatar.py | 113 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 178 insertions(+), 3 deletions(-) diff --git a/model/avatar/_avatar.py b/model/avatar/_avatar.py index 5eb175e..afa7d59 100644 --- a/model/avatar/_avatar.py +++ b/model/avatar/_avatar.py @@ -1,10 +1,11 @@ from typing import TYPE_CHECKING -from model.enums import AvatarQuality, Element, WeaponType +from model.enums import Association, AvatarQuality, Element, WeaponType from utils.model import BaseModel if TYPE_CHECKING: from model.item import Item + from model.avatar._talente import AvatarTalents __all__ = ( "Avatar", @@ -12,6 +13,8 @@ __all__ = ( "AvatarInfo", "AvatarConstellation", "AvatarPromote", + "AvatarStories", + "Story", "Seuyu", "ItemCount", ) @@ -39,6 +42,45 @@ class Seuyu(BaseModel): """韩语CV""" +class Story(BaseModel): + """故事""" + + title: str + """标题""" + content: str + """内容""" + tips: list[str] + """提示""" + + +class AvatarStories(BaseModel): + """角色故事""" + + details: Story + """角色详情""" + + story_1: Story + """角色故事1""" + + story_2: Story + """角色故事2""" + + story_3: Story + """角色故事3""" + + story_4: Story + """角色故事4""" + + story_5: Story + """角色故事5""" + + miscellaneous: Story + """角色杂谈""" + + vision: Story + """神之眼""" + + class AvatarInfo(BaseModel): title: str """称号""" @@ -52,8 +94,12 @@ class AvatarInfo(BaseModel): """星座""" description: str """描述""" + association: Association + """区域""" seuyu: Seuyu """声优""" + stories: AvatarStories + """故事""" class ItemCount(BaseModel): @@ -105,5 +151,7 @@ class Avatar(BaseModel): """角色信息""" promote: AvatarPromote """角色突破数据""" + talents: "AvatarTalents" + """角色天赋信息""" constellations: list[AvatarConstellation] """角色命座信息""" diff --git a/model/enums.py b/model/enums.py index 976166e..43001d9 100644 --- a/model/enums.py +++ b/model/enums.py @@ -102,6 +102,7 @@ class FoodQuality(StrEnum): """美味的""" +# noinspection SpellCheckingInspection class MaterialType(StrEnum): Adsorbate = "ADSORBATE" FakeAbsorbate = "FAKE_ABSORBATE" @@ -142,3 +143,20 @@ class MaterialType(StrEnum): Costume = "COSTUME" FurnitureSuiteFormula = "FURNITURE_SUITE_FORMULA" FurnitureFormula = "FURNITURE_FORMULA" + + +class Association(StrEnum): + Inazuma = "INAZUMA" + """稻妻""" + Mondstadt = "MONDSTADT" + """蒙德""" + Mainactor = "MAINACTOR" + """主角""" + Liyue = "LIYUE" + """璃月""" + Fatui = "FATUI" + """愚人众""" + Ranger = "RANGER" + """游侠""" + Sumeru = "SUMERU" + """须弥""" diff --git a/scripts/avatar.py b/scripts/avatar.py index db7e3b0..e921d5d 100644 --- a/scripts/avatar.py +++ b/scripts/avatar.py @@ -1,7 +1,116 @@ +from itertools import chain + +from model.avatar import AvatarBirth, AvatarInfo, AvatarStories, Seuyu, Story +from model.enums import Association, AvatarQuality, Element, WeaponType +from utils.const import PROJECT_ROOT +from utils.manager import ResourceManager from utils.typedefs import Lang -from utils.manager import ResourceManager +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, +} +# 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") + + 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, + ) + + breakpoint()