Module genshin.client.components.chronicle.zzz
StarRail battle chronicle component.
Classes
class ZZZBattleChronicleClient (cookies: ForwardRef('http.cookies.BaseCookie[Any]') | Mapping[Any, Any] | str | Sequence[ForwardRef('http.cookies.BaseCookie[Any]') | Mapping[Any, Any] | str] | None = None,
*,
authkey: str | None = None,
lang: Literal['zh-cn', 'zh-tw', 'de-de', 'en-us', 'es-es', 'fr-fr', 'id-id', 'it-it', 'ja-jp', 'ko-kr', 'pt-pt', 'ru-ru', 'th-th', 'vi-vn', 'tr-tr'] = 'en-us',
region: Region = Region.OVERSEAS,
proxy: str | None = None,
game: Game | None = None,
uid: int | None = None,
hoyolab_id: int | None = None,
device_id: str | None = None,
device_fp: str | None = None,
headers: Mapping[str, str] | Mapping[multidict._multidict.istr, str] | multidict._multidict.CIMultiDict | multidict._multidict.CIMultiDictProxy | Iterable[Tuple[str | multidict._multidict.istr, str]] | None = None,
cache: BaseCache | None = None,
debug: bool = False,
on_cookie_update: Callable[[Mapping[str, str]], Awaitable[None] | None] | None = None)-
Expand source code
class ZZZBattleChronicleClient(base.BaseBattleChronicleClient, badge.BadgeLoginClient): """ZZZ battle chronicle component.""" async def _request_zzz_record( self, endpoint: str, uid: typing.Optional[int] = None, *, method: str = "GET", lang: typing.Optional[str] = None, payload: typing.Optional[typing.Mapping[str, typing.Any]] = None, cache: bool = False, is_nap_ledger: bool = False, use_uid_in_payload: bool = False, ) -> typing.Mapping[str, typing.Any]: """Get an arbitrary ZZZ object.""" payload = dict(payload or {}) original_payload = payload.copy() uid = uid or await self._get_uid(types.Game.ZZZ) if is_nap_ledger or use_uid_in_payload: payload = { "uid": uid, "region": utility.recognize_zzz_server(uid), **payload, } else: payload = { "role_id": uid, "server": utility.recognize_zzz_server(uid), **payload, } data, params = None, None if method == "POST": data = payload else: params = payload cache_key: typing.Optional[base.ChronicleCacheKey] = None if cache: cache_key = base.ChronicleCacheKey( types.Game.ZZZ, endpoint, uid, lang=lang or self.lang, params=tuple(original_payload.values()), ) return await self.request_game_record( endpoint, lang=lang, game=types.Game.ZZZ, region=utility.recognize_region(uid, game=types.Game.ZZZ), params=params, data=data, cache=cache_key, custom_route=routes.NAP_LEDGER_URL if is_nap_ledger else None, ) @typing.overload async def get_zzz_notes( self, uid: typing.Optional[int] = ..., *, lang: typing.Optional[str] = ..., autoauth: bool = ..., return_raw_data: typing.Literal[False] = ..., ) -> models.ZZZNotes: ... @typing.overload async def get_zzz_notes( self, uid: typing.Optional[int] = ..., *, lang: typing.Optional[str] = ..., autoauth: bool = ..., return_raw_data: typing.Literal[True] = ..., ) -> typing.Mapping[str, typing.Any]: ... async def get_zzz_notes( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None, autoauth: bool = True, return_raw_data: bool = False, ) -> typing.Union[models.ZZZNotes, typing.Mapping[str, typing.Any]]: """Get ZZZ sticky notes (real-time notes).""" try: data = await self._request_zzz_record("note", uid, lang=lang) except errors.DataNotPublic as e: # error raised only when real-time notes are not enabled if uid and (await self._get_uid(types.Game.ZZZ)) != uid: raise errors.GenshinException(e.response, "Cannot view real-time notes of other users.") from e if not autoauth: raise errors.GenshinException(e.response, "Real-time notes are not enabled.") from e await self.update_settings(3, True, game=types.Game.ZZZ) data = await self._request_zzz_record("note", uid, lang=lang) if return_raw_data: return data return models.ZZZNotes(**data) async def get_zzz_diary( self, uid: typing.Optional[int] = None, *, month: typing.Optional[str] = None, lang: typing.Optional[str] = None, ) -> models.ZZZDiary: """Get ZZZ inter-knot monthly earning data.""" data = await self._request_zzz_record( "month_info", uid, lang=lang, payload={"month": month or ""}, is_nap_ledger=True ) return models.ZZZDiary(**data) async def get_zzz_diary_detail( self, month: str, *, type: models.ZZZCurrencyType, page: int = 1, page_size: int = 20, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> models.ZZZDiaryDetail: """Get ZZZ inter-knot monthly earning data.""" if not month: raise ValueError("month is required.") data = await self._request_zzz_record( "month_detail", uid, lang=lang, payload={"month": month, "current_page": page, "type": type.value, "page_size": page_size}, is_nap_ledger=True, ) return models.ZZZDiaryDetail(**data) async def get_zzz_user( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None, ) -> models.ZZZUserStats: """Get ZZZ user stats.""" data = await self._request_zzz_record("index", uid, lang=lang) return models.ZZZUserStats(**data) async def get_zzz_agents( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZPartialAgent]: """Get all owned ZZZ characters (only brief info).""" data = await self._request_zzz_record("avatar/basic", uid, lang=lang) return [models.ZZZPartialAgent(**item) for item in data["avatar_list"]] async def get_bangboos( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZBaseBangboo]: """Get all owned ZZZ bangboos.""" data = await self._request_zzz_record("buddy/info", uid, lang=lang) return [models.ZZZBaseBangboo(**item) for item in data["list"]] @typing.overload async def get_zzz_agent_info( self, character_id: int, *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> models.ZZZFullAgent: ... @typing.overload async def get_zzz_agent_info( self, character_id: typing.Sequence[int], *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.ZZZFullAgent]: ... async def get_zzz_agent_info( self, character_id: typing.Union[int, typing.Sequence[int]], *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Union[models.ZZZFullAgent, typing.Sequence[models.ZZZFullAgent]]: """Get a ZZZ character's detailed info.""" if isinstance(character_id, typing.Sequence): tasks = [ self._request_zzz_record("avatar/info", uid, lang=lang, payload={"id_list[]": character_id_}) for character_id_ in character_id ] results = await asyncio.gather(*tasks) return [models.ZZZFullAgent(**data["avatar_list"][0]) for data in results] data = await self._request_zzz_record("avatar/info", uid, lang=lang, payload={"id_list[]": character_id}) return models.ZZZFullAgent(**data["avatar_list"][0]) async def _request_upgrade_guide( self, endpoint: str, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None, body: typing.Optional[typing.Mapping[str, typing.Any]] = None, ) -> typing.Mapping[str, typing.Any]: """Make a request towards the ZZZ agent upgrade guide tool. The cultivate tool endpoints reject requests carrying an ``x-rpc-device_id`` header with a ``-100`` "Not Logged In" error, so it is stripped for the request. """ uid = uid or await self._get_uid(types.Game.ZZZ) region = utility.recognize_region(uid, game=types.Game.ZZZ) or types.Region.OVERSEAS params = {"uid": uid, "region": utility.recognize_zzz_server(uid)} url = routes.NAP_CULTIVATE_URL.get_url(region) / endpoint method = "POST" if body is not None else "GET" return await self._request_with_badge( types.Game.ZZZ, url, uid, lang=lang, method=method, params=params, data=body, suppress_device_id=True ) async def get_zzz_upgrade_guide_agents( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZUpgradeGuideAgent]: """Get all agents available in the ZZZ agent upgrade guide tool.""" data = await self._request_upgrade_guide("user/avatar_basic_list", uid, lang=lang) return [models.ZZZUpgradeGuideAgent(**item) for item in data["list"]] async def get_zzz_agent_upgrade_guide( self, character_id: typing.Union[int, typing.Sequence[int]], *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.ZZZAgentUpgradeGuide]: """Get detailed builds and recommended upgrade guides for ZZZ agents.""" if isinstance(character_id, int): character_id = [character_id] if len(character_id) > 10: raise ValueError("Cannot request more than 10 agents at once.") avatar_list = [ {"avatar_id": id_, "is_teaser": False, "teaser_need_weapon": False, "teaser_sp_skill": False} for id_ in character_id ] data = await self._request_upgrade_guide( "user/batch_avatar_detail_v2", uid, lang=lang, body={"avatar_list": avatar_list} ) return [models.ZZZAgentUpgradeGuide(**item) for item in data["list"]] async def get_all_zzz_agent_upgrade_guides( self, uid: typing.Optional[int] = None, *, unlocked_only: bool = True, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.ZZZAgentUpgradeGuide]: """Get the upgrade guides for all of the user's agents. The agents are fetched first, then their guides are requested in batches of 10 simultaneously. If ``unlocked_only`` is ``True`` (the default), only unlocked agents are included. """ agents = await self.get_zzz_upgrade_guide_agents(uid, lang=lang) if unlocked_only: agents = [agent for agent in agents if agent.unlocked] ids = [agent.id for agent in agents] batches = [ids[i : i + 10] for i in range(0, len(ids), 10)] tasks = [self.get_zzz_agent_upgrade_guide(batch, uid=uid, lang=lang) for batch in batches] results = await asyncio.gather(*tasks) return [guide for batch_result in results for guide in batch_result] @typing.overload async def get_shiyu_defense( self, uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[False] = ..., ) -> typing.Union[models.ShiyuDefenseV1, models.ShiyuDefenseV2]: ... @typing.overload async def get_shiyu_defense( self, uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[True] = ..., ) -> typing.Mapping[str, typing.Any]: ... async def get_shiyu_defense( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.ShiyuDefenseV1, models.ShiyuDefenseV2, typing.Mapping[str, typing.Any]]: """Get ZZZ Shiyu defense stats.""" payload = {"schedule_type": 2 if previous else 1} data = await self._request_zzz_record("hadal_info_v2", uid, lang=lang, payload=payload) version = data["hadal_ver"] # v1 or v2 key = f"hadal_info_{version}" if version == "v1": data = data[key] elif version == "v2": nickname = data["nick_name"] icon = data["icon"] data = data[key] data["nick_name"] = nickname data["icon"] = icon else: msg = f"Unknown Shiyu Defense version: {version!r}" raise ValueError(msg) data = self._add_timezone_to_data( data, ("hadal_begin_time", "hadal_end_time", "challenge_time", "floor_challenge_time"), game=types.Game.ZZZ, uid=uid, ) if raw: return data if version == "v2": return models.ShiyuDefenseV2(**data) return models.ShiyuDefenseV1(**data) @typing.overload async def get_deadly_assault( self, uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[False] = ..., ) -> models.DeadlyAssault: ... @typing.overload async def get_deadly_assault( self, uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[True] = ..., ) -> typing.Mapping[str, typing.Any]: ... async def get_deadly_assault( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.DeadlyAssault, typing.Mapping[str, typing.Any]]: """Get ZZZ Deadly Assault stats.""" payload = {"schedule_type": 2 if previous else 1} data = await self._request_zzz_record( "hadal_mem_detail_v2", uid, lang=lang, payload=payload, use_uid_in_payload=True ) data = self._add_timezone_to_data( data, ("start_time", "end_time", "challenge_time"), game=types.Game.ZZZ, uid=uid ) if raw: return data return models.DeadlyAssault(**data) @typing.overload async def get_annihilation_simulacrum( self, uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[False] = ..., ) -> models.AnnihilationSimulacrum: ... @typing.overload async def get_annihilation_simulacrum( self, uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[True] = ..., ) -> typing.Mapping[str, typing.Any]: ... async def get_annihilation_simulacrum( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.AnnihilationSimulacrum, typing.Mapping[str, typing.Any]]: """Get ZZZ Annihilation Simulacrum stats.""" payload = {"schedule_type": 2 if previous else 1} data = await self._request_zzz_record( "holo_boss_detail", uid, lang=lang, payload=payload, use_uid_in_payload=True ) data = self._add_timezone_to_data(data, ("start_time", "end_time"), game=types.Game.ZZZ, uid=uid) if raw: return data return models.AnnihilationSimulacrum(**data) async def get_lost_void_summary( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> models.LostVoidSummary: """Get ZZZ Lost Void summary.""" data = await self._request_zzz_record("abysss2_abstract", uid, lang=lang, use_uid_in_payload=True) return models.LostVoidSummary(**data) async def get_threshold_simulation_brief( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None ) -> models.ThresholdSimulationInfo: """Get ZZZ Threshold Simulation brief info.""" schedule_type = 2 if previous else 1 payload = {"schedule_type": schedule_type} data = await self._request_zzz_record( "void_front_battle_period_abstract_info", uid, lang=lang, use_uid_in_payload=True, payload=payload ) return models.ThresholdSimulationInfo(**data["void_front_battle_abstract_info_brief"]) @typing.overload async def get_threshold_simulation( self, id: typing.Optional[int] = ..., uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[False] = ..., ) -> models.ThresholdSimulation: ... @typing.overload async def get_threshold_simulation( self, id: typing.Optional[int] = ..., uid: typing.Optional[int] = ..., *, previous: bool = ..., lang: typing.Optional[str] = ..., raw: typing.Literal[True] = ..., ) -> typing.Mapping[str, typing.Any]: ... async def get_threshold_simulation( self, id: typing.Optional[int] = None, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.ThresholdSimulation, typing.Mapping[str, typing.Any]]: """Get ZZZ Threshold Simulation stats. If no ID is given, the latest run will be fetched. """ schedule_type = 2 if previous else 1 if id is None: brief = await self.get_threshold_simulation_brief(uid, lang=lang, previous=previous) id = brief.id data = await self._request_zzz_record( "void_front_battle_period_detail", uid, lang=lang, payload={"void_front_id": id, "schedule_type": schedule_type}, use_uid_in_payload=True, ) data = data["void_front_battle_detail"] data = self._add_timezone_to_data(data, ("challenge_time",), game=types.Game.ZZZ, uid=uid) if raw: return data return models.ThresholdSimulation(**data) async def _get_chronicle_signal_page( self, end_id: int, banner_type: gacha_models.ZZZBannerType, *, lang: typing.Optional[str] = None, uid: typing.Optional[int] = None, ) -> typing.Sequence[gacha_models.SignalSearch]: """Get a single page of battle chronicle signal searches.""" uid = uid or await self._get_uid(types.Game.ZZZ) timezone = self.get_account_timezone(game=types.Game.ZZZ, uid=uid) if timezone is None: msg = "Cannot find account timezone." raise ValueError(msg) data = await self._request_zzz_record( "gacha_record", uid, lang=lang, payload={"gacha_type": banner_type.to_chronicle_type(), "end_id": end_id}, use_uid_in_payload=True, ) records = data.get("gacha_item_list", []) return [ gacha_models.SignalSearch.from_chronicle_data(i, uid=uid, banner_type=banner_type, tz_offset=timezone - 8) for i in records ] def chronicle_signal_history( self, banner_type: typing.Optional[typing.Union[int, typing.Sequence[int]]] = None, *, limit: typing.Optional[int] = None, lang: typing.Optional[str] = None, uid: typing.Optional[int] = None, end_id: int = 0, ) -> paginators.Paginator[gacha_models.SignalSearch]: """Get the signal search history of a user.""" banner_types = banner_type or list(gacha_models.ZZZBannerType) if not isinstance(banner_types, typing.Sequence): banner_types = [banner_types] iterators: list[paginators.Paginator[gacha_models.SignalSearch]] = [] for banner in banner_types: iterators.append( paginators.CursorPaginator( functools.partial( self._get_chronicle_signal_page, banner_type=gacha_models.ZZZBannerType(banner), lang=lang, uid=uid, ), limit=limit, end_id=end_id, ) ) if len(iterators) == 1: return iterators[0] return paginators.MergedPaginator(iterators, key=lambda wish: wish.time.timestamp()) async def get_zzz_event_calendar( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZEvent]: """Get ZZZ event calendar.""" data = await self._request_zzz_record("activity_calendar", uid, lang=lang, use_uid_in_payload=True) return [models.ZZZEvent(**item) for item in data["activity_list"]] async def get_zzz_gacha_calendar( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> models.ZZZGachaCalendar: """Get ZZZ gacha calendar.""" data = await self._request_zzz_record("gacha_calendar", uid, lang=lang, use_uid_in_payload=True) return models.ZZZGachaCalendar(**data) async def get_zzz_gacha_info( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> models.ZZZGachaInfo: """Get ZZZ gacha info.""" data = await self._request_zzz_record("cur_gacha_detail", uid, lang=lang, use_uid_in_payload=True) return models.ZZZGachaInfo(**data)ZZZ battle chronicle component.
Ancestors
Subclasses
Methods
def chronicle_signal_history(self,
banner_type: int | Sequence[int] | None = None,
*,
limit: int | None = None,
lang: str | None = None,
uid: int | None = None,
end_id: int = 0) ‑> Paginator[SignalSearch]-
Expand source code
def chronicle_signal_history( self, banner_type: typing.Optional[typing.Union[int, typing.Sequence[int]]] = None, *, limit: typing.Optional[int] = None, lang: typing.Optional[str] = None, uid: typing.Optional[int] = None, end_id: int = 0, ) -> paginators.Paginator[gacha_models.SignalSearch]: """Get the signal search history of a user.""" banner_types = banner_type or list(gacha_models.ZZZBannerType) if not isinstance(banner_types, typing.Sequence): banner_types = [banner_types] iterators: list[paginators.Paginator[gacha_models.SignalSearch]] = [] for banner in banner_types: iterators.append( paginators.CursorPaginator( functools.partial( self._get_chronicle_signal_page, banner_type=gacha_models.ZZZBannerType(banner), lang=lang, uid=uid, ), limit=limit, end_id=end_id, ) ) if len(iterators) == 1: return iterators[0] return paginators.MergedPaginator(iterators, key=lambda wish: wish.time.timestamp())Get the signal search history of a user.
async def get_all_zzz_agent_upgrade_guides(self,
uid: int | None = None,
*,
unlocked_only: bool = True,
lang: str | None = None) ‑> Sequence[ZZZAgentUpgradeGuide]-
Expand source code
async def get_all_zzz_agent_upgrade_guides( self, uid: typing.Optional[int] = None, *, unlocked_only: bool = True, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.ZZZAgentUpgradeGuide]: """Get the upgrade guides for all of the user's agents. The agents are fetched first, then their guides are requested in batches of 10 simultaneously. If ``unlocked_only`` is ``True`` (the default), only unlocked agents are included. """ agents = await self.get_zzz_upgrade_guide_agents(uid, lang=lang) if unlocked_only: agents = [agent for agent in agents if agent.unlocked] ids = [agent.id for agent in agents] batches = [ids[i : i + 10] for i in range(0, len(ids), 10)] tasks = [self.get_zzz_agent_upgrade_guide(batch, uid=uid, lang=lang) for batch in batches] results = await asyncio.gather(*tasks) return [guide for batch_result in results for guide in batch_result]Get the upgrade guides for all of the user's agents.
The agents are fetched first, then their guides are requested in batches of 10 simultaneously. If
unlocked_onlyisTrue(the default), only unlocked agents are included. async def get_annihilation_simulacrum(self,
uid: int | None = None,
*,
previous: bool = False,
lang: str | None = None,
raw: bool = False) ‑> AnnihilationSimulacrum | Mapping[str, Any]-
Expand source code
async def get_annihilation_simulacrum( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.AnnihilationSimulacrum, typing.Mapping[str, typing.Any]]: """Get ZZZ Annihilation Simulacrum stats.""" payload = {"schedule_type": 2 if previous else 1} data = await self._request_zzz_record( "holo_boss_detail", uid, lang=lang, payload=payload, use_uid_in_payload=True ) data = self._add_timezone_to_data(data, ("start_time", "end_time"), game=types.Game.ZZZ, uid=uid) if raw: return data return models.AnnihilationSimulacrum(**data)Get ZZZ Annihilation Simulacrum stats.
async def get_bangboos(self, uid: int | None = None, *, lang: str | None = None) ‑> Sequence[ZZZBaseBangboo]-
Expand source code
async def get_bangboos( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZBaseBangboo]: """Get all owned ZZZ bangboos.""" data = await self._request_zzz_record("buddy/info", uid, lang=lang) return [models.ZZZBaseBangboo(**item) for item in data["list"]]Get all owned ZZZ bangboos.
async def get_deadly_assault(self,
uid: int | None = None,
*,
previous: bool = False,
lang: str | None = None,
raw: bool = False) ‑> DeadlyAssault | Mapping[str, Any]-
Expand source code
async def get_deadly_assault( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.DeadlyAssault, typing.Mapping[str, typing.Any]]: """Get ZZZ Deadly Assault stats.""" payload = {"schedule_type": 2 if previous else 1} data = await self._request_zzz_record( "hadal_mem_detail_v2", uid, lang=lang, payload=payload, use_uid_in_payload=True ) data = self._add_timezone_to_data( data, ("start_time", "end_time", "challenge_time"), game=types.Game.ZZZ, uid=uid ) if raw: return data return models.DeadlyAssault(**data)Get ZZZ Deadly Assault stats.
async def get_lost_void_summary(self, uid: int | None = None, *, lang: str | None = None) ‑> LostVoidSummary-
Expand source code
async def get_lost_void_summary( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> models.LostVoidSummary: """Get ZZZ Lost Void summary.""" data = await self._request_zzz_record("abysss2_abstract", uid, lang=lang, use_uid_in_payload=True) return models.LostVoidSummary(**data)Get ZZZ Lost Void summary.
async def get_shiyu_defense(self,
uid: int | None = None,
*,
previous: bool = False,
lang: str | None = None,
raw: bool = False) ‑> ShiyuDefenseV1 | ShiyuDefenseV2 | Mapping[str, Any]-
Expand source code
async def get_shiyu_defense( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.ShiyuDefenseV1, models.ShiyuDefenseV2, typing.Mapping[str, typing.Any]]: """Get ZZZ Shiyu defense stats.""" payload = {"schedule_type": 2 if previous else 1} data = await self._request_zzz_record("hadal_info_v2", uid, lang=lang, payload=payload) version = data["hadal_ver"] # v1 or v2 key = f"hadal_info_{version}" if version == "v1": data = data[key] elif version == "v2": nickname = data["nick_name"] icon = data["icon"] data = data[key] data["nick_name"] = nickname data["icon"] = icon else: msg = f"Unknown Shiyu Defense version: {version!r}" raise ValueError(msg) data = self._add_timezone_to_data( data, ("hadal_begin_time", "hadal_end_time", "challenge_time", "floor_challenge_time"), game=types.Game.ZZZ, uid=uid, ) if raw: return data if version == "v2": return models.ShiyuDefenseV2(**data) return models.ShiyuDefenseV1(**data)Get ZZZ Shiyu defense stats.
async def get_threshold_simulation(self,
id: int | None = None,
uid: int | None = None,
*,
previous: bool = False,
lang: str | None = None,
raw: bool = False) ‑> ThresholdSimulation | Mapping[str, Any]-
Expand source code
async def get_threshold_simulation( self, id: typing.Optional[int] = None, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None, raw: bool = False, ) -> typing.Union[models.ThresholdSimulation, typing.Mapping[str, typing.Any]]: """Get ZZZ Threshold Simulation stats. If no ID is given, the latest run will be fetched. """ schedule_type = 2 if previous else 1 if id is None: brief = await self.get_threshold_simulation_brief(uid, lang=lang, previous=previous) id = brief.id data = await self._request_zzz_record( "void_front_battle_period_detail", uid, lang=lang, payload={"void_front_id": id, "schedule_type": schedule_type}, use_uid_in_payload=True, ) data = data["void_front_battle_detail"] data = self._add_timezone_to_data(data, ("challenge_time",), game=types.Game.ZZZ, uid=uid) if raw: return data return models.ThresholdSimulation(**data)Get ZZZ Threshold Simulation stats.
If no ID is given, the latest run will be fetched.
async def get_threshold_simulation_brief(self, uid: int | None = None, *, previous: bool = False, lang: str | None = None) ‑> ThresholdSimulationInfo-
Expand source code
async def get_threshold_simulation_brief( self, uid: typing.Optional[int] = None, *, previous: bool = False, lang: typing.Optional[str] = None ) -> models.ThresholdSimulationInfo: """Get ZZZ Threshold Simulation brief info.""" schedule_type = 2 if previous else 1 payload = {"schedule_type": schedule_type} data = await self._request_zzz_record( "void_front_battle_period_abstract_info", uid, lang=lang, use_uid_in_payload=True, payload=payload ) return models.ThresholdSimulationInfo(**data["void_front_battle_abstract_info_brief"])Get ZZZ Threshold Simulation brief info.
async def get_zzz_agent_info(self,
character_id: int | Sequence[int],
*,
uid: int | None = None,
lang: str | None = None) ‑> ZZZFullAgent | Sequence[ZZZFullAgent]-
Expand source code
async def get_zzz_agent_info( self, character_id: typing.Union[int, typing.Sequence[int]], *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Union[models.ZZZFullAgent, typing.Sequence[models.ZZZFullAgent]]: """Get a ZZZ character's detailed info.""" if isinstance(character_id, typing.Sequence): tasks = [ self._request_zzz_record("avatar/info", uid, lang=lang, payload={"id_list[]": character_id_}) for character_id_ in character_id ] results = await asyncio.gather(*tasks) return [models.ZZZFullAgent(**data["avatar_list"][0]) for data in results] data = await self._request_zzz_record("avatar/info", uid, lang=lang, payload={"id_list[]": character_id}) return models.ZZZFullAgent(**data["avatar_list"][0])Get a ZZZ character's detailed info.
async def get_zzz_agent_upgrade_guide(self,
character_id: int | Sequence[int],
*,
uid: int | None = None,
lang: str | None = None) ‑> Sequence[ZZZAgentUpgradeGuide]-
Expand source code
async def get_zzz_agent_upgrade_guide( self, character_id: typing.Union[int, typing.Sequence[int]], *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.ZZZAgentUpgradeGuide]: """Get detailed builds and recommended upgrade guides for ZZZ agents.""" if isinstance(character_id, int): character_id = [character_id] if len(character_id) > 10: raise ValueError("Cannot request more than 10 agents at once.") avatar_list = [ {"avatar_id": id_, "is_teaser": False, "teaser_need_weapon": False, "teaser_sp_skill": False} for id_ in character_id ] data = await self._request_upgrade_guide( "user/batch_avatar_detail_v2", uid, lang=lang, body={"avatar_list": avatar_list} ) return [models.ZZZAgentUpgradeGuide(**item) for item in data["list"]]Get detailed builds and recommended upgrade guides for ZZZ agents.
async def get_zzz_agents(self, uid: int | None = None, *, lang: str | None = None) ‑> Sequence[ZZZPartialAgent]-
Expand source code
async def get_zzz_agents( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZPartialAgent]: """Get all owned ZZZ characters (only brief info).""" data = await self._request_zzz_record("avatar/basic", uid, lang=lang) return [models.ZZZPartialAgent(**item) for item in data["avatar_list"]]Get all owned ZZZ characters (only brief info).
async def get_zzz_diary(self, uid: int | None = None, *, month: str | None = None, lang: str | None = None) ‑> ZZZDiary-
Expand source code
async def get_zzz_diary( self, uid: typing.Optional[int] = None, *, month: typing.Optional[str] = None, lang: typing.Optional[str] = None, ) -> models.ZZZDiary: """Get ZZZ inter-knot monthly earning data.""" data = await self._request_zzz_record( "month_info", uid, lang=lang, payload={"month": month or ""}, is_nap_ledger=True ) return models.ZZZDiary(**data)Get ZZZ inter-knot monthly earning data.
async def get_zzz_diary_detail(self,
month: str,
*,
type: ZZZCurrencyType,
page: int = 1,
page_size: int = 20,
uid: int | None = None,
lang: str | None = None) ‑> ZZZDiaryDetail-
Expand source code
async def get_zzz_diary_detail( self, month: str, *, type: models.ZZZCurrencyType, page: int = 1, page_size: int = 20, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> models.ZZZDiaryDetail: """Get ZZZ inter-knot monthly earning data.""" if not month: raise ValueError("month is required.") data = await self._request_zzz_record( "month_detail", uid, lang=lang, payload={"month": month, "current_page": page, "type": type.value, "page_size": page_size}, is_nap_ledger=True, ) return models.ZZZDiaryDetail(**data)Get ZZZ inter-knot monthly earning data.
async def get_zzz_event_calendar(self, uid: int | None = None, *, lang: str | None = None) ‑> Sequence[ZZZEvent]-
Expand source code
async def get_zzz_event_calendar( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZEvent]: """Get ZZZ event calendar.""" data = await self._request_zzz_record("activity_calendar", uid, lang=lang, use_uid_in_payload=True) return [models.ZZZEvent(**item) for item in data["activity_list"]]Get ZZZ event calendar.
async def get_zzz_gacha_calendar(self, uid: int | None = None, *, lang: str | None = None) ‑> ZZZGachaCalendar-
Expand source code
async def get_zzz_gacha_calendar( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> models.ZZZGachaCalendar: """Get ZZZ gacha calendar.""" data = await self._request_zzz_record("gacha_calendar", uid, lang=lang, use_uid_in_payload=True) return models.ZZZGachaCalendar(**data)Get ZZZ gacha calendar.
async def get_zzz_gacha_info(self, uid: int | None = None, *, lang: str | None = None) ‑> ZZZGachaInfo-
Expand source code
async def get_zzz_gacha_info( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> models.ZZZGachaInfo: """Get ZZZ gacha info.""" data = await self._request_zzz_record("cur_gacha_detail", uid, lang=lang, use_uid_in_payload=True) return models.ZZZGachaInfo(**data)Get ZZZ gacha info.
async def get_zzz_notes(self,
uid: int | None = None,
*,
lang: str | None = None,
autoauth: bool = True,
return_raw_data: bool = False) ‑> ZZZNotes | Mapping[str, Any]-
Expand source code
async def get_zzz_notes( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None, autoauth: bool = True, return_raw_data: bool = False, ) -> typing.Union[models.ZZZNotes, typing.Mapping[str, typing.Any]]: """Get ZZZ sticky notes (real-time notes).""" try: data = await self._request_zzz_record("note", uid, lang=lang) except errors.DataNotPublic as e: # error raised only when real-time notes are not enabled if uid and (await self._get_uid(types.Game.ZZZ)) != uid: raise errors.GenshinException(e.response, "Cannot view real-time notes of other users.") from e if not autoauth: raise errors.GenshinException(e.response, "Real-time notes are not enabled.") from e await self.update_settings(3, True, game=types.Game.ZZZ) data = await self._request_zzz_record("note", uid, lang=lang) if return_raw_data: return data return models.ZZZNotes(**data)Get ZZZ sticky notes (real-time notes).
async def get_zzz_upgrade_guide_agents(self, uid: int | None = None, *, lang: str | None = None) ‑> Sequence[ZZZUpgradeGuideAgent]-
Expand source code
async def get_zzz_upgrade_guide_agents( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None ) -> typing.Sequence[models.ZZZUpgradeGuideAgent]: """Get all agents available in the ZZZ agent upgrade guide tool.""" data = await self._request_upgrade_guide("user/avatar_basic_list", uid, lang=lang) return [models.ZZZUpgradeGuideAgent(**item) for item in data["list"]]Get all agents available in the ZZZ agent upgrade guide tool.
async def get_zzz_user(self, uid: int | None = None, *, lang: str | None = None) ‑> ZZZUserStats-
Expand source code
async def get_zzz_user( self, uid: typing.Optional[int] = None, *, lang: typing.Optional[str] = None, ) -> models.ZZZUserStats: """Get ZZZ user stats.""" data = await self._request_zzz_record("index", uid, lang=lang) return models.ZZZUserStats(**data)Get ZZZ user stats.
Inherited members
BaseBattleChronicleClient:authkeydebugdefault_gamedevice_fpdevice_idgamegenshin_accountsget_account_timezoneget_game_accountsget_record_cardget_record_cardshoyolab_idlangon_cookie_updateproxyregionrequestrequest_bbsrequest_game_recordrequest_hoyolabrequest_webstaticset_authkeyset_browser_cookiesset_cacheset_cookiesset_redis_cacheset_visibilityuidupdate_settings