From 3e936b7eb891b1493caa20d520d2660e11df5336 Mon Sep 17 00:00:00 2001 From: omg-xtao <100690902+omg-xtao@users.noreply.github.com> Date: Wed, 25 Sep 2024 23:14:21 +0800 Subject: [PATCH] :sparkles: Support zzz ledger --- simnet/client/components/diary/base.py | 4 +- simnet/client/components/diary/zzz.py | 29 ++++++++ simnet/client/routes.py | 4 ++ simnet/client/zzz.py | 2 + simnet/models/zzz/diary.py | 98 ++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 simnet/client/components/diary/zzz.py create mode 100644 simnet/models/zzz/diary.py diff --git a/simnet/client/components/diary/base.py b/simnet/client/components/diary/base.py index e3902f3..a8df4cc 100644 --- a/simnet/client/components/diary/base.py +++ b/simnet/client/components/diary/base.py @@ -46,7 +46,7 @@ class BaseDiaryClient(BaseClient): base_url = DETAIL_LEDGER_URL if detail else INFO_LEDGER_URL url = base_url.get_url(self.region, game) - if self.region == Region.OVERSEAS or game == Game.STARRAIL: + if self.region == Region.OVERSEAS or game == Game.STARRAIL or game == Game.ZZZ: params["uid"] = player_id params["region"] = recognize_server(player_id, game) elif self.region == Region.CHINESE: @@ -54,7 +54,7 @@ class BaseDiaryClient(BaseClient): params["bind_region"] = recognize_server(player_id, game) else: raise TypeError(f"{self.region!r} is not a valid region.") - if game == Game.STARRAIL: + if game in [Game.STARRAIL, Game.ZZZ]: month = month or datetime.now(CN_TIMEZONE).strftime("%Y%m") elif game == Game.GENSHIN: month = month or str(datetime.now(CN_TIMEZONE).month) diff --git a/simnet/client/components/diary/zzz.py b/simnet/client/components/diary/zzz.py new file mode 100644 index 0000000..60c3f04 --- /dev/null +++ b/simnet/client/components/diary/zzz.py @@ -0,0 +1,29 @@ +from typing import Optional + +from simnet.client.components.diary.base import BaseDiaryClient +from simnet.models.zzz.diary import ZZZDiary +from simnet.utils.enums import Game + + +class ZZZDiaryClient(BaseDiaryClient): + """ZZZ diary component.""" + + async def get_zzz_diary( + self, + player_id: Optional[int] = None, + *, + month: Optional[str] = None, + lang: Optional[str] = None, + ) -> ZZZDiary: + """Get a traveler's diary with earning details for the month. + + Args: + player_id (int, optional): The player's ID. Defaults to None. + month (int, optional): The month to get the diary for. Defaults to None. + lang (str, optional): The language to get the diary in. Defaults to None. + + Returns: + ZZZDiary: The diary for the month. + """ + data = await self.request_ledger(player_id, game=Game.ZZZ, month=month, lang=lang) + return ZZZDiary(**data) diff --git a/simnet/client/routes.py b/simnet/client/routes.py index b56f903..b534426 100644 --- a/simnet/client/routes.py +++ b/simnet/client/routes.py @@ -303,10 +303,12 @@ DETAIL_LEDGER_URL = GameRoute( overseas=dict( genshin="https://sg-hk4e-api.hoyolab.com/event/ysledgeros/month_detail", hkrpg="https://sg-public-api.hoyolab.com/event/srledger/month_detail", + nap="https://sg-public-api.hoyolab.com/event/nap_ledger/month_detail", ), chinese=dict( genshin="https://hk4e-api.mihoyo.com/event/ys_ledger/monthDetail", hkrpg="https://api-takumi.mihoyo.com/event/srledger/month_detail", + nap="https://api-takumi.mihoyo.com/event/nap_ledger/month_detail", ), ) @@ -314,10 +316,12 @@ INFO_LEDGER_URL = GameRoute( overseas=dict( genshin="https://sg-hk4e-api.hoyolab.com/event/ysledgeros/month_info", hkrpg="https://sg-public-api.hoyolab.com/event/srledger/month_info", + nap="https://sg-public-api.hoyolab.com/event/nap_ledger/month_info", ), chinese=dict( genshin="https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo", hkrpg="https://api-takumi.mihoyo.com/event/srledger/month_info", + nap="https://api-takumi.mihoyo.com/event/nap_ledger/month_info", ), ) diff --git a/simnet/client/zzz.py b/simnet/client/zzz.py index df3b871..aef7b94 100644 --- a/simnet/client/zzz.py +++ b/simnet/client/zzz.py @@ -3,6 +3,7 @@ from typing import Optional from simnet.client.components.auth import AuthClient from simnet.client.components.chronicle.zzz import ZZZBattleChronicleClient from simnet.client.components.daily import DailyRewardClient +from simnet.client.components.diary.zzz import ZZZDiaryClient from simnet.client.components.lab import LabClient from simnet.client.components.self_help.zzz import ZZZSelfHelpClient from simnet.client.components.verify import VerifyClient @@ -15,6 +16,7 @@ __all__ = ("ZZZClient",) class ZZZClient( ZZZBattleChronicleClient, ZZZWishClient, + ZZZDiaryClient, ZZZSelfHelpClient, DailyRewardClient, AuthClient, diff --git a/simnet/models/zzz/diary.py b/simnet/models/zzz/diary.py new file mode 100644 index 0000000..403641e --- /dev/null +++ b/simnet/models/zzz/diary.py @@ -0,0 +1,98 @@ +from typing import List + +from pydantic import Field + +from simnet.models.base import APIModel +from simnet.models.diary import BaseDiary + +__all__ = ( + "ZZZDiaryDataList", + "ZZZDiaryActionCategory", + "ZZZMonthDiaryData", + "ZZZDiary", +) + + +class ZZZDiaryDataList(APIModel): + """List of diary data. + + Attributes: + id: Data ID. + name: Data name. + amount: Amount of data. + """ + + id: str = Field(alias="data_type") + name: str = Field(alias="data_name") + amount: int = Field(alias="count") + + +class ZZZDiaryActionCategory(APIModel): + """Diary category for PolychromesData . + + Attributes: + action: Category name. + amount: Amount of rails_pass. + percentage: Percentage of rails_pass. + """ + + action: str + amount: int = Field(alias="num") + percentage: int = Field(alias="percent") + + @property + def name(self) -> str: + return { + "growth_rewards": "成长奖励", + "daily_activity_rewards": "日常活跃奖励", + "mail_rewards": "邮件奖励", + "event_rewards": "活动奖励", + "hollow_rewards": "零号空洞奖励", + "shiyu_rewards": "式舆防卫战奖励", + "other_rewards": "其他奖励", + }.get(self.action, "其他奖励") + + +class ZZZMonthDiaryData(APIModel): + """Diary data for a month. + + Attributes: + categories: List of diary categories. + """ + + list: List[ZZZDiaryDataList] + categories: List[ZZZDiaryActionCategory] = Field(alias="income_components") + + +class ZZZDiaryRoleInfo(APIModel): + """Role info for a diary.""" + + nickname: str + avatar: str + + +class ZZZDiary(BaseDiary): + """Traveler's diary. + + Attributes: + data: Diary data for a month. + optional_month: Optional month. + current_month: Current month. + data_month: Data month. + """ + + data: ZZZMonthDiaryData = Field(alias="month_data") + optional_month: List[str] + current_month: str + data_month: str + role_info: ZZZDiaryRoleInfo + + @property + def data_id(self) -> int: + """Get the data ID.""" + return self.month + + @property + def month_data(self) -> ZZZMonthDiaryData: + """Diary data for a month.""" + return self.data