180 lines
5.3 KiB
Python
180 lines
5.3 KiB
Python
"""
|
|
Copyright (C) 2025 283375
|
|
|
|
This file is part of "arcaea-apk-assets" (stated as "this program" below).
|
|
|
|
This program is free software: you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation, either version 3 of the License, or (at your option) any later
|
|
version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program. If not, see <https://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from arcaea_offline_schemas.dis.v5.dataclass import AodisPack, AodisPackLocalization
|
|
from typeguard import TypeCheckError, check_type
|
|
|
|
from ._shared import blank_str_to_none
|
|
from .defs import ARCAEA_LANGUAGE_KEYS
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PacklistFormatError(Exception):
|
|
pass
|
|
|
|
|
|
class ArcaeaPacklistParser:
|
|
@staticmethod
|
|
def check_root_content(root: dict) -> None:
|
|
try:
|
|
check_type(root, dict)
|
|
check_type(root["packs"], list[dict])
|
|
except (KeyError, TypeCheckError) as e:
|
|
raise PacklistFormatError from e
|
|
|
|
@staticmethod
|
|
def check_pack_object(obj: dict) -> None:
|
|
try:
|
|
check_type(obj, dict)
|
|
check_type(obj["id"], str)
|
|
except (KeyError, TypeCheckError) as e:
|
|
raise PacklistFormatError from e
|
|
|
|
@staticmethod
|
|
def parse_pack(pack: dict) -> AodisPack:
|
|
id_ = pack["id"]
|
|
|
|
name_localized = pack.get("name_localized", {})
|
|
description_localized = pack.get("description_localized", {})
|
|
|
|
name = blank_str_to_none(name_localized.get("en"))
|
|
description = blank_str_to_none(description_localized.get("en"))
|
|
section = blank_str_to_none(pack.get("section"))
|
|
append_parent_id = pack.get("pack_parent")
|
|
plus_character = (
|
|
pack["plus_character"] if pack.get("plus_character", -1) > -1 else None
|
|
)
|
|
|
|
return AodisPack(
|
|
id=id_,
|
|
name=name or "",
|
|
isWorldExtend=pack.get("is_extend_pack") is True,
|
|
description=description,
|
|
section=section,
|
|
unlocksPartner=plus_character,
|
|
appendParentId=append_parent_id,
|
|
)
|
|
|
|
@staticmethod
|
|
def parse_pack_localizations(pack: dict) -> list[AodisPackLocalization]:
|
|
results = []
|
|
|
|
name_localized = pack.get("name_localized", {})
|
|
description_localized = pack.get("description_localized", {})
|
|
|
|
id_ = pack["id"]
|
|
|
|
for lang_key in ARCAEA_LANGUAGE_KEYS:
|
|
name_l10n = blank_str_to_none(name_localized.get(lang_key))
|
|
description_l10n = blank_str_to_none(
|
|
description_localized.get(lang_key),
|
|
)
|
|
|
|
if name_l10n or description_l10n:
|
|
results.append(
|
|
AodisPackLocalization(
|
|
id=id_,
|
|
lang=lang_key,
|
|
name=name_l10n,
|
|
description=description_l10n,
|
|
),
|
|
)
|
|
|
|
return results
|
|
|
|
@classmethod
|
|
def items(
|
|
cls,
|
|
packlist_content: dict,
|
|
*,
|
|
skip_format_checks: bool = False,
|
|
) -> list[AodisPack | AodisPackLocalization]:
|
|
try:
|
|
cls.check_root_content(packlist_content)
|
|
except PacklistFormatError:
|
|
if skip_format_checks:
|
|
logger.exception("Error skipped during packlist parsing:")
|
|
return []
|
|
|
|
raise
|
|
|
|
packs = packlist_content["packs"]
|
|
results: list[AodisPack | AodisPackLocalization] = [
|
|
AodisPack(
|
|
id="single",
|
|
name="Memory Archive",
|
|
isWorldExtend=False,
|
|
description=None,
|
|
section=None,
|
|
unlocksPartner=None,
|
|
appendParentId=None,
|
|
),
|
|
]
|
|
|
|
for pack in packs:
|
|
try:
|
|
cls.check_pack_object(pack)
|
|
except PacklistFormatError:
|
|
if skip_format_checks:
|
|
logger.exception("Error skipped during packlist parsing:")
|
|
continue
|
|
|
|
raise
|
|
|
|
results.append(cls.parse_pack(pack))
|
|
results.extend(cls.parse_pack_localizations(pack))
|
|
|
|
return results
|
|
|
|
@classmethod
|
|
def packs(
|
|
cls,
|
|
packlist_content: dict,
|
|
*,
|
|
skip_format_checks: bool = False,
|
|
) -> list[AodisPack]:
|
|
return [
|
|
item
|
|
for item in cls.items(
|
|
packlist_content,
|
|
skip_format_checks=skip_format_checks,
|
|
)
|
|
if isinstance(item, AodisPack)
|
|
]
|
|
|
|
@classmethod
|
|
def pack_localizations(
|
|
cls,
|
|
packlist_content: dict,
|
|
*,
|
|
skip_format_checks: bool = False,
|
|
) -> list[AodisPackLocalization]:
|
|
return [
|
|
item
|
|
for item in cls.items(
|
|
packlist_content,
|
|
skip_format_checks=skip_format_checks,
|
|
)
|
|
if isinstance(item, AodisPackLocalization)
|
|
]
|