🚧 building...

This commit is contained in:
Karako 2023-04-29 22:59:16 +08:00
parent 7e957ccea8
commit fb77ca0569
No known key found for this signature in database
GPG Key ID: 5920831B0095D4A0
10 changed files with 269 additions and 126 deletions

View File

@ -1,8 +1,78 @@
from humps import camelize from datetime import datetime
from utils.model import BaseConfig, BaseModel # noinspection PyPep8Naming
from enum import Enum as E
from typing import Any, TYPE_CHECKING, Type
from databases import Database
# noinspection PyPep8Naming
from ormar import (
BaseField,
Enum as ENUM,
Model as _Model,
ModelMeta as _ModelMeta,
String as STRING,
)
from sqlalchemy import MetaData
from utils import json
try:
import regex as re
except ImportError:
import re
if TYPE_CHECKING:
pass
__all__ = ("Model", "String", "Enum")
DATABASE_URL = "sqlite:///data/db.sqlite"
database = Database(DATABASE_URL)
metadata = MetaData()
class DataModel(BaseModel): class ModelMeta(_ModelMeta):
class Config(BaseConfig): database = database
alias_generator = lambda x: camelize(x.removesuffix("TextHashMap")) metadata = metadata
class Model(_Model):
class Config(_Model.Config):
json_dumps = json.dumps
json_loads = json.loads
json_encoders = {datetime: lambda v: v.timestamp()}
class String(STRING):
def __new__(
cls,
*,
max_length: int = 255,
min_length: int = None,
regex: str = None,
**kwargs: Any,
) -> BaseField:
return super().__new__(
cls=STRING,
max_length=max_length,
min_length=min_length,
regex=regex,
**kwargs,
)
class Enum(ENUM):
def __new__(cls, enum_class: Type[E], **kwargs: Any) -> BaseField:
return super().__new__(
cls,
**{
**kwargs,
**{
k: v
for k, v in locals().items()
if k not in ["cls", "__class__", "kwargs"]
},
},
)

2
model/avatar/__init__.py Normal file
View File

@ -0,0 +1,2 @@
from model.avatar._avatar import *
from model.avatar._talente import *

View File

@ -6,6 +6,16 @@ from utils.model import BaseModel
if TYPE_CHECKING: if TYPE_CHECKING:
from model.item import Item from model.item import Item
__all__ = (
"Avatar",
"AvatarBirth",
"AvatarInfo",
"AvatarConstellation",
"AvatarPromote",
"Seuyu",
"ItemCount",
)
class AvatarBirth(BaseModel): class AvatarBirth(BaseModel):
"""角色生日""" """角色生日"""
@ -46,7 +56,7 @@ class AvatarInfo(BaseModel):
"""声优""" """声优"""
class AvatarItem(BaseModel): class ItemCount(BaseModel):
item: "Item" item: "Item"
"""物品""" """物品"""
count: int count: int
@ -63,43 +73,10 @@ class AvatarPromote(BaseModel):
coin: int = 0 coin: int = 0
"""摩拉""" """摩拉"""
items: list[AvatarItem] items: list[ItemCount] = []
"""突破所需材料""" """突破所需材料"""
class AvatarSkill(BaseModel):
name: str
"""技能名称"""
description: str
"""技能描述"""
promote_level: int = 0
"""所需突破等级"""
icon: str
"""图标"""
class AvatarActiveSkill(AvatarSkill):
"""角色主动技能"""
CD: float
"""冷却时间"""
max_charge_num: int
"""技能最大储存次数"""
class AvatarPassiveSkill(AvatarSkill):
"""角色被动技能"""
class AvatarSkills(BaseModel):
attack_skill: AvatarActiveSkill
"""普通攻击"""
energy_skill: AvatarActiveSkill
"""元素爆发"""
proud_skills: list[AvatarSkill]
"""被动技能"""
class AvatarConstellation(BaseModel): class AvatarConstellation(BaseModel):
"""角色命座""" """角色命座"""

103
model/avatar/_talente.py Normal file
View File

@ -0,0 +1,103 @@
from utils.model import BaseModel
from typing import ClassVar
__all__ = (
"Talent",
"CombatTalent",
"NormalAttack",
"ElementalBurst",
"ElementalSkill",
"AlternateSprint",
"PassiveTalent",
"AscensionPassive",
"FirstAscensionPassive",
"FourthAscensionPassive",
"UtilityPassive",
"MiscellaneousPassive",
"AvatarTalents",
)
class Talent(BaseModel):
name: str
"""天赋名称"""
description: str
"""天赋描述"""
icon: str
"""图标"""
level: int = 0
"""解锁等级"""
params: list[float] = []
"""数值参数列表"""
class CombatTalent(Talent):
"""战斗天赋"""
cooldown: float = 0
"""冷却时间"""
class NormalAttack(CombatTalent):
"""普通攻击"""
class ElementalSkill(CombatTalent):
"""元素战技"""
class ElementalBurst(CombatTalent):
"""元素爆发"""
class AlternateSprint(CombatTalent):
"""冲刺技能"""
class PassiveTalent(Talent):
"""被动天赋"""
class AscensionPassive(PassiveTalent):
"""突破被动天赋"""
ascension: ClassVar[int]
class FirstAscensionPassive(AscensionPassive):
"""第一次突破被动天赋"""
ascension = 1
class FourthAscensionPassive(AscensionPassive):
"""第四次突破被动天赋"""
ascension = 4
class UtilityPassive(PassiveTalent):
"""实用被动天赋"""
class MiscellaneousPassive(PassiveTalent):
"""杂项被动天赋"""
class AvatarTalents(BaseModel):
"""角色天赋"""
normal_attack: NormalAttack
"""普通攻击"""
elemental_skill: ElementalSkill
"""元素战技"""
elemental_burst: ElementalBurst
"""元素爆发"""
alternate_sprint: AlternateSprint | None = None
"""冲刺技能"""
first_ascension_passive: FirstAscensionPassive
fourth_ascension_passive: FourthAscensionPassive
utility_passive: UtilityPassive | None = None
miscellaneous_passive: MiscellaneousPassive | None = None

View File

@ -1,7 +1,7 @@
from model.enums import ItemType, MaterialType from model.enums import ItemType, MaterialType
from model.enums import FoodQuality from model.enums import FoodQuality
from utils.model import BaseModel from model._base import Model as BaseModel
class Item(BaseModel): class Item(BaseModel):
@ -9,8 +9,6 @@ class Item(BaseModel):
"""ID""" """ID"""
name: str name: str
"""名称""" """名称"""
family: str
"""种类"""
type: str | None type: str | None
"""类型""" """类型"""
icon: str icon: str

89
run.py
View File

@ -1,98 +1,21 @@
import asyncio from scripts.avatar import parse_avatar_data
from scripts.item import parse_item_data
from model.enums import ItemType, MaterialType
from model.item import Material, Namecard
from utils.const import PROJECT_ROOT
from utils.context import ContextManager
from utils.manager import ResourceManager
from utils.text import Text
from utils.typedefs import Lang from utils.typedefs import Lang
import ujson as json
OUTPUT_DIR = PROJECT_ROOT / "data"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# noinspection PyShadowingBuiltins async def parse(lang: Lang):
async def parse_item_data(resource: ResourceManager): await parse_item_data(lang)
from model.item import Food, FoodQuality, Item await parse_avatar_data(lang)
json_data = resource.fetch("MaterialExcelConfigData")
data_list = []
for item_data in json_data:
id = item_data["id"]
name = Text(item_data["nameTextMapHash"])
family = item_data.get("materialType", "")
rarity = item_data.get("rankLevel")
type = Text(item_data["typeDescTextMapHash"])
icon = item_data["icon"]
description = Text(item_data["descTextMapHash"])
special = Text(item_data["specialDescTextMapHash"]) or None
item_type = ItemType(item_data["itemType"].removeprefix("ITEM_"))
base_kwargs = {
"id": id,
"name": name,
"family": family,
"rarity": rarity,
"type": type,
"icon": icon,
"description": description,
"item_type": item_type,
}
if special is not None:
base_kwargs["special_description"] = special
if pics := list(filter(lambda x: x, item_data["picPath"])):
item = Namecard(pictures=pics, **base_kwargs)
elif "materialType" in item_data: # 材料
material_type = MaterialType(
item_data["materialType"].removeprefix("MATERIAL_")
)
item = Material(material_type=material_type, **base_kwargs)
elif "foodQuality" in item_data: # 食物
quality = FoodQuality(
item_data["foodQuality"].removeprefix("FOOD_QUALITY_").title()
)
effect = Text(item_data["effectDescTextMapHash"])
item = Food(quality=quality, effect=effect, **base_kwargs)
else:
item = Item(**base_kwargs)
data_list.append(item.dict(exclude_none=True))
item_data_file = OUTPUT_DIR / "item.json"
with open(item_data_file, "w", encoding="utf-8") as f:
f.write(json.dumps(data_list, ensure_ascii=False))
breakpoint()
async def fetch_parse_data(lang: Lang):
with ContextManager().with_context(
"resource_manager", ResourceManager(lang=lang)
) as resource_manager:
try:
await parse_item_data(resource_manager)
except Exception as e:
breakpoint()
async def main(): async def main():
task_list = []
for lang in Lang.__args__: for lang in Lang.__args__:
task = asyncio.create_task(fetch_parse_data(lang=lang)) await parse(lang)
task_list.append(task)
await asyncio.gather(*task_list)
def __main__(): def __main__():
import asyncio import asyncio
import sys
if (3, 10) >= sys.version_info >= (3, 8) and sys.platform.startswith("win"):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
loop.run_until_complete(main()) loop.run_until_complete(main())

0
scripts/__init__.py Normal file
View File

44
scripts/_base.py Normal file
View File

@ -0,0 +1,44 @@
import asyncio
from abc import ABC, abstractmethod
from asyncio import Task
targets: list["Target"] = []
class Target(ABC):
_task: Task | None = None
@property
def task(self) -> Task:
return self._task
def __init__(self):
targets.append(self)
async def __async_init__(self) -> None:
pass
async def __async_del__(self) -> None:
pass
@abstractmethod
async def run(self) -> None:
pass
async def _run(self) -> None:
await self.__async_init__()
await self.run()
await self.__async_del__()
async def run_in_background(self) -> Task:
self._task = asyncio.create_task(self._run())
return self._task
async def waiting_for_done():
task_list: list[Task] = []
for target in targets:
if target.task is not None and not target.task.done():
task_list.append(target.task)
await asyncio.gather(*task_list)

7
scripts/avatar.py Normal file
View File

@ -0,0 +1,7 @@
from utils.typedefs import Lang
from utils.manager import ResourceManager
async def parse_avatar_data(lang: Lang):
...

19
scripts/item.py Normal file
View File

@ -0,0 +1,19 @@
from model.enums import ItemType
from utils.manager import ResourceManager
from utils.typedefs import Lang
# noinspection PyShadowingBuiltins
async def parse_item_data(lang: Lang):
manager = ResourceManager(lang=lang)
json_data = manager.fetch("MaterialExcelConfigData")
for data in json_data:
id = data["id"]
name = manager.get_text(data["nameTextMapHash"])
type = manager.get_text(data["typeDescTextMapHash"])
icon = data["icon"]
rarity = data["rankLevel"]
description = manager.get_text(data["descTextMapHash"])
special_description = manager.get_text(data["specialDescTextMapHash"])
item_type = ItemType(data["itemType"].removeprefix('ITEM_'))
breakpoint()