diff --git a/simnet/client/components/chronicle/starrail.py b/simnet/client/components/chronicle/starrail.py index 3a5ed9b..5f2ca3d 100644 --- a/simnet/client/components/chronicle/starrail.py +++ b/simnet/client/components/chronicle/starrail.py @@ -4,6 +4,7 @@ from typing import Optional, Mapping, Dict, Any from simnet.client.components.chronicle.base import BaseChronicleClient from simnet.errors import BadRequest, DataNotPublic from simnet.models.lab.record import RecordCard +from simnet.models.starrail.chronicle.activity import StarRailActivity from simnet.models.starrail.chronicle.challenge import StarRailChallenge from simnet.models.starrail.chronicle.characters import StarRailDetailCharacters from simnet.models.starrail.chronicle.museum import StarRailMuseumBasic, StarRailMuseumDetail @@ -265,3 +266,24 @@ class StarRailBattleChronicleClient(BaseChronicleClient): """ data = await self._request_starrail_record("museum/detail", uid, lang=lang) return StarRailMuseumDetail(**data) + + async def get_starrail_activity( + self, + uid: Optional[int] = None, + lang: Optional[str] = None, + ) -> StarRailActivity: + """Get starrail activity info. + + Args: + uid (Optional[int], optional): The player ID. Defaults to None. + lang (Optional[str], optional): The language of the data. Defaults to None. + + Returns: + StarRailActivity: The requested activity info. + + Raises: + BadRequest: If the request is invalid. + DataNotPublic: If the requested data is not public. + """ + data = await self._request_starrail_record("activity", uid, lang=lang) + return StarRailActivity(**data) diff --git a/simnet/client/components/lab.py b/simnet/client/components/lab.py index 10e0f30..e40661f 100644 --- a/simnet/client/components/lab.py +++ b/simnet/client/components/lab.py @@ -227,3 +227,12 @@ class LabClient(BaseClient): """ accounts = await self.get_game_accounts(lang=lang) return [account for account in accounts if account.game == Game.GENSHIN] + + async def get_starrail_accounts(self, *, lang: Optional[str] = None) -> List[Account]: + """Get the starrail accounts of the currently logged-in user. + + Returns: + List[Account]: A list of account info objects of starrail accounts. + """ + accounts = await self.get_game_accounts(lang=lang) + return [account for account in accounts if account.game == Game.STARRAIL] diff --git a/simnet/models/starrail/character.py b/simnet/models/starrail/character.py index 2e2665b..8dcebe3 100644 --- a/simnet/models/starrail/character.py +++ b/simnet/models/starrail/character.py @@ -29,3 +29,10 @@ class RogueCharacter(StarRailBaseCharacter): """Rogue character model.""" level: int + + +class StarFightCharacter(StarRailBaseCharacter): + """Combat character model.""" + + level: int + is_trial: bool diff --git a/simnet/models/starrail/chronicle/activity.py b/simnet/models/starrail/chronicle/activity.py new file mode 100644 index 0000000..476d479 --- /dev/null +++ b/simnet/models/starrail/chronicle/activity.py @@ -0,0 +1,57 @@ +"""Starrail chronicle activity.""" +from typing import List, Optional + +from simnet.models.base import APIModel +from simnet.models.starrail.character import StarFightCharacter + +from .base import PartialTime + +__all__ = ["StarRailActivityBase", "StarRailStarFightRecord", "StarRailStarFight", "StarRailActivity"] + + +class StarRailActivityBase(APIModel): + """StarRailActivity Base Model""" + + exists_data: bool + is_hot: bool + strategy_link: str = "" + + +class StarRailStarFightRecord(APIModel): + """Stellar Flare Record""" + + name: str + difficulty_id: int + round: int + stage_id: int + time: Optional[PartialTime] + lineup: List[StarFightCharacter] + + @property + def time_str(self) -> str: + """Get the time as a string.""" + if self.time is None: + return "N/A" + + return self.time.datetime.strftime("%Y.%m.%d %H:%M") + + +class StarRailStarFight(StarRailActivityBase): + """Stellar Flare""" + + records: List[StarRailStarFightRecord] + + +class StarRailActivity(APIModel): + """Starrail chronicle activity.""" + + activities: List + + @property + def star_fight(self) -> StarRailStarFight: + """Get the star fight activity.""" + for activity in self.activities: + if list(activity.keys())[0] == "star_fight": + return StarRailStarFight(**activity["star_fight"]) + + raise ValueError("No star fight activity found.")