Module genshin.client.components.hoyolab
Hoyolab component.
Classes
class HoyolabClient (cookies: Union[ForwardRef('http.cookies.BaseCookie[Any]'), Mapping[Any, Any], str, Sequence[Union[ForwardRef('http.cookies.BaseCookie[Any]'), Mapping[Any, Any], str]], ForwardRef(None)] = None, *, authkey: Optional[str] = None, lang: str = 'en-us', region: Region = Region.OVERSEAS, proxy: Optional[str] = None, game: Optional[Game] = None, uid: Optional[int] = None, hoyolab_id: Optional[int] = None, device_id: Optional[str] = None, device_fp: Optional[str] = None, headers: Union[Mapping[str, str], Mapping[multidict._multidict.istr, str], multidict._multidict.CIMultiDict, multidict._multidict.CIMultiDictProxy, Iterable[Tuple[Union[str, multidict._multidict.istr], str]], ForwardRef(None)] = None, cache: Optional[BaseCache] = None, debug: bool = False)
-
Hoyolab component.
Expand source code
class HoyolabClient(base.BaseClient): """Hoyolab component.""" async def _get_server_region(self, uid: int, game: types.Game) -> str: """Fetch the server region of an account from the API.""" data = await self.request( routes.GET_USER_REGION_URL.get_url(), params=dict(game_biz=utility.get_prod_game_biz(self.region, game)), cache=client_cache.cache_key("server_region", game=game, uid=uid, region=self.region), ) for account in data["list"]: if account["game_uid"] == str(uid): return account["region"] raise ValueError(f"Failed to recognize server for game {game!r} and uid {uid!r}") async def _request_announcements( self, game: types.Game, uid: int, *, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.Announcement]: """Get a list of game announcements.""" if game is types.Game.GENSHIN: params = dict( game="hk4e", game_biz="hk4e_global", bundle_id="hk4e_global", platform="pc", region=utility.recognize_genshin_server(uid), uid=uid, level=8, lang=lang or self.lang, ) url = routes.HK4E_URL.get_url() elif game is types.Game.ZZZ: params = dict( game="nap", game_biz="nap_global", bundle_id="nap_global", platform="pc", region=utility.recognize_zzz_server(uid), level=60, lang=lang or self.lang, uid=uid, ) url = routes.NAP_URL.get_url() elif game is types.Game.STARRAIL: params = dict( game="hkrpg", game_biz="hkrpg_global", bundle_id="hkrpg_global", platform="pc", region=utility.recognize_starrail_server(uid), uid=uid, level=70, lang=lang or self.lang, channel_id=1, ) url = routes.HKRPG_URL.get_url() else: msg = f"{game!r} is not supported yet." raise ValueError(msg) info, details = await asyncio.gather( self.request_hoyolab( url / "announcement/api/getAnnList", lang=lang, params=params, ), self.request_hoyolab( url / "announcement/api/getAnnContent", lang=lang, params=params, ), ) announcements: list[typing.Mapping[str, typing.Any]] = [] extra_list: list[typing.Mapping[str, typing.Any]] = ( info["pic_list"][0]["type_list"] if "pic_list" in info and info["pic_list"] else [] ) for sublist in info["list"] + extra_list: for info in sublist["list"]: detail = next((i for i in details["list"] if i["ann_id"] == info["ann_id"]), None) announcements.append({**info, **(detail or {})}) return [models.Announcement(**i) for i in announcements] async def search_users( self, keyword: str, *, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.PartialHoyolabUser]: """Search hoyolab users.""" data = await self.request_bbs( "community/search/wapi/search/user", lang=lang, params=dict(keyword=keyword, page_size=20), cache=client_cache.cache_key("search", keyword=keyword, lang=self.lang), ) return [models.PartialHoyolabUser(**i["user"]) for i in data["list"]] async def get_hoyolab_user( self, hoyolab_id: typing.Optional[int] = None, *, lang: typing.Optional[str] = None, ) -> models.FullHoyolabUser: """Get a hoyolab user.""" if self.region == types.Region.OVERSEAS: url = "/community/painter/wapi/user/full" elif self.region == types.Region.CHINESE: url = "/user/wapi/getUserFullInfo" else: raise TypeError(f"{self.region!r} is not a valid region.") data = await self.request_bbs( url=url, lang=lang, params=dict(uid=hoyolab_id) if hoyolab_id else None, cache=client_cache.cache_key("hoyolab", uid=hoyolab_id, lang=lang or self.lang), ) return models.FullHoyolabUser(**data["user_info"]) async def get_recommended_users(self, *, limit: int = 200) -> typing.Sequence[models.PartialHoyolabUser]: """Get a list of recommended active users.""" data = await self.request_bbs( "community/user/wapi/recommendActive", params=dict(page_size=limit), cache=client_cache.cache_key("recommended"), ) return [models.PartialHoyolabUser(**i["user"]) for i in data["list"]] async def get_genshin_announcements( self, *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.Announcement]: """Get a list of Genshin Impact announcements.""" if self.cookie_manager.multi: uid = uid or await self._get_uid(types.Game.GENSHIN) else: uid = uid or 900000005 return await self._request_announcements(types.Game.GENSHIN, uid, lang=lang) async def get_zzz_announcements( self, *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.Announcement]: """Get a list of Zenless Zone Zero announcements.""" if self.cookie_manager.multi: uid = uid or await self._get_uid(types.Game.ZZZ) else: uid = uid or 1300000000 return await self._request_announcements(types.Game.ZZZ, uid, lang=lang) async def get_starrail_announcements( self, *, uid: typing.Optional[int] = None, lang: typing.Optional[str] = None, ) -> typing.Sequence[models.Announcement]: """Get a list of Star Rail announcements.""" if self.cookie_manager.multi: uid = uid or await self._get_uid(types.Game.STARRAIL) else: uid = uid or 809162009 return await self._request_announcements(types.Game.STARRAIL, uid, lang=lang) @managers.requires_cookie_token async def redeem_code( self, code: str, uid: typing.Optional[int] = None, *, game: typing.Optional[types.Game] = None, lang: typing.Optional[str] = None, region: typing.Optional[str] = None, ) -> None: """Redeems a gift code for the current user.""" if game is None: if self.default_game is None: raise RuntimeError("No default game set.") game = self.default_game if game not in {types.Game.GENSHIN, types.Game.ZZZ, types.Game.STARRAIL, types.Game.TOT}: raise ValueError(f"{game} does not support code redemption.") uid = uid or await self._get_uid(game) try: region = region or utility.recognize_server(uid, game) except Exception: warnings.warn(f"Failed to recognize server for game {game!r} and uid {uid!r}, fetching from API now.") region = await self._get_server_region(uid, game) await self.request( routes.CODE_URL.get_url(self.region, game), params=dict( uid=uid, region=region, cdkey=code, game_biz=utility.get_prod_game_biz(self.region, game), lang=utility.create_short_lang_code(lang or self.lang), ), method="POST" if game is types.Game.STARRAIL else "GET", ) @managers.no_multi async def check_in_community(self) -> None: """Check in to the hoyolab community and claim your daily 5 community exp.""" raise RuntimeError("This API is deprecated.") @base.region_specific(types.Region.OVERSEAS) async def fetch_mi18n( self, filename: str, game: types.Game, *, lang: typing.Optional[str] = None ) -> typing.Mapping[str, str]: """Fetch a mi18n file.""" data = await self.request( routes.MI18N_URL.get_url(types.Region.OVERSEAS, game) / f"{filename}/{filename}-{lang or self.lang}.json", cache=client_cache.cache_key("mi18n", filename=filename, game=game, lang=lang or self.lang), ) return data
Ancestors
- BaseClient
- abc.ABC
Subclasses
Class variables
var logger : logging.Logger
Instance variables
var authkeys : dict[Game, str]
var cache : BaseCache
var custom_headers : multidict._multidict.CIMultiDict[str]
var uids : dict[Game, int]
Methods
async def check_in_community(self) ‑> None
-
Check in to the hoyolab community and claim your daily 5 community exp.
async def fetch_mi18n(self, filename: str, game: Game, *, lang: Optional[str] = None) ‑> Mapping[str, str]
-
Fetch a mi18n file.
async def get_genshin_announcements(self, *, uid: Optional[int] = None, lang: Optional[str] = None) ‑> Sequence[Announcement]
-
Get a list of Genshin Impact announcements.
async def get_hoyolab_user(self, hoyolab_id: Optional[int] = None, *, lang: Optional[str] = None) ‑> FullHoyolabUser
-
Get a hoyolab user.
async def get_recommended_users(self, *, limit: int = 200) ‑> Sequence[PartialHoyolabUser]
-
Get a list of recommended active users.
async def get_starrail_announcements(self, *, uid: Optional[int] = None, lang: Optional[str] = None) ‑> Sequence[Announcement]
-
Get a list of Star Rail announcements.
async def get_zzz_announcements(self, *, uid: Optional[int] = None, lang: Optional[str] = None) ‑> Sequence[Announcement]
-
Get a list of Zenless Zone Zero announcements.
async def redeem_code(self, code: str, uid: Optional[int] = None, *, game: Optional[Game] = None, lang: Optional[str] = None, region: Optional[str] = None) ‑> None
-
Redeems a gift code for the current user.
async def search_users(self, keyword: str, *, lang: Optional[str] = None) ‑> Sequence[PartialHoyolabUser]
-
Search hoyolab users.
Inherited members