mirror of
https://github.com/PaiGramTeam/SIMNet.git
synced 2024-11-25 07:36:28 +00:00
463 lines
18 KiB
Python
463 lines
18 KiB
Python
import asyncio
|
|
from typing import Optional, Mapping, Dict, Any, Union, List
|
|
|
|
from simnet.client.components.chronicle.base import BaseChronicleClient
|
|
from simnet.client.routes import RECORD_URL
|
|
from simnet.errors import BadRequest, DataNotPublic
|
|
from simnet.models.lab.record import RecordCard
|
|
from simnet.models.starrail.chronicle.achievement import StarRailAchievementInfo
|
|
from simnet.models.starrail.chronicle.act_calendar import StarRailActCalendar
|
|
from simnet.models.starrail.chronicle.challenge import StarRailChallenge
|
|
from simnet.models.starrail.chronicle.challenge_boss import StarRailChallengeBoss
|
|
from simnet.models.starrail.chronicle.challenge_story import StarRailChallengeStory
|
|
from simnet.models.starrail.chronicle.characters import StarRailDetailCharacters
|
|
from simnet.models.starrail.chronicle.notes import StarRailNote, StarRailNoteWidget, StarRailNoteOverseaWidget
|
|
from simnet.models.starrail.chronicle.rogue import StarRailRogue, StarRailRogueLocust, StarRailRogueNous
|
|
from simnet.models.starrail.chronicle.rogue_tourn import StarRailRogueTourn
|
|
from simnet.models.starrail.chronicle.stats import StarRailUserStats, StarRailUserInfo
|
|
from simnet.models.starrail.diary import StarRailLedgerMonthInfo
|
|
from simnet.utils.enums import Game, Region
|
|
from simnet.utils.player import recognize_starrail_server, recognize_region
|
|
|
|
__all__ = ("StarRailBattleChronicleClient",)
|
|
|
|
|
|
class StarRailBattleChronicleClient(BaseChronicleClient):
|
|
"""A client for retrieving data from StarRail's battle chronicle component.
|
|
|
|
This class is used to retrieve various data objects from StarRail's battle chronicle component,
|
|
including real-time notes, user statistics, and character information.
|
|
"""
|
|
|
|
async def _request_starrail_record(
|
|
self,
|
|
endpoint: str,
|
|
player_id: Optional[int] = None,
|
|
endpoint_type: str = "api",
|
|
method: str = "GET",
|
|
lang: Optional[str] = None,
|
|
payload: Optional[Dict[str, Any]] = None,
|
|
) -> Mapping[str, Any]:
|
|
"""Get an arbitrary object from StarRail's battle chronicle.
|
|
|
|
Args:
|
|
endpoint (str): The endpoint of the object to retrieve.
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
method (str, optional): The HTTP method to use. Defaults to "GET".
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
payload (Optional[Dict[str, Any]], optional): The request payload. Defaults to None.
|
|
|
|
Returns:
|
|
Mapping[str, Any]: The requested object.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(payload or {})
|
|
|
|
player_id = player_id or self.player_id
|
|
payload = dict(role_id=player_id, server=recognize_starrail_server(player_id), **payload)
|
|
|
|
data, params = None, None
|
|
if method == "POST":
|
|
data = payload
|
|
else:
|
|
params = payload
|
|
|
|
return await self.request_game_record(
|
|
endpoint,
|
|
endpoint_type=endpoint_type,
|
|
lang=lang,
|
|
game=Game.STARRAIL,
|
|
region=recognize_region(player_id, game=Game.STARRAIL),
|
|
params=params,
|
|
data=data,
|
|
)
|
|
|
|
async def get_starrail_notes(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
autoauth: bool = True,
|
|
) -> StarRailNote:
|
|
"""Get StarRail's real-time notes.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
autoauth (bool, optional): Whether to automatically authenticate the user. Defaults to True.
|
|
|
|
Returns:
|
|
StarRailNote: The requested real-time notes.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
try:
|
|
data = await self._request_starrail_record("note", player_id, lang=lang)
|
|
except DataNotPublic as e:
|
|
# error raised only when real-time notes are not enabled
|
|
if player_id and self.player_id != player_id:
|
|
raise BadRequest(e.response, "Cannot view real-time notes of other users.") from e
|
|
if not autoauth:
|
|
raise BadRequest(e.response, "Real-time notes are not enabled.") from e
|
|
await self.update_settings(3, True, game=Game.STARRAIL)
|
|
data = await self._request_starrail_record("note", player_id, lang=lang)
|
|
|
|
return StarRailNote(**data)
|
|
|
|
async def get_starrail_user(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
*,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailUserStats:
|
|
"""Get StarRail user statistics.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailUserStats: The requested user statistics.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
index_data, basic_info = await asyncio.gather(
|
|
self._request_starrail_record("index", player_id, lang=lang),
|
|
self._request_starrail_record("role/basicInfo", player_id, lang=lang),
|
|
)
|
|
basic_data = StarRailUserInfo(**basic_info)
|
|
return StarRailUserStats(**index_data, info=basic_data)
|
|
|
|
async def get_starrail_characters(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailDetailCharacters:
|
|
"""Get StarRail character information.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailDetailCharacters: The requested character information.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = {"need_wiki": "true"}
|
|
data = await self._request_starrail_record("avatar/info", player_id, lang=lang, payload=payload)
|
|
return StarRailDetailCharacters(**data)
|
|
|
|
async def get_record_card(
|
|
self,
|
|
account_id: Optional[int] = None,
|
|
*,
|
|
lang: Optional[str] = None,
|
|
) -> Optional[RecordCard]:
|
|
"""Get a starrail player record cards.
|
|
|
|
Args:
|
|
account_id: Optional[int], the user's account ID, defaults to None
|
|
lang: Optional[str], the language version of the request, defaults to None
|
|
|
|
Returns:
|
|
Starrail user record cards.
|
|
|
|
Returns:
|
|
Optional[RecordCard]: RecordCard objects.
|
|
"""
|
|
account_id = account_id or self.account_id
|
|
|
|
record_cards = await self.get_record_cards(account_id, lang=lang)
|
|
|
|
for record_card in record_cards:
|
|
if record_card.game == Game.STARRAIL:
|
|
return record_card
|
|
|
|
return None
|
|
|
|
async def get_starrail_challenge(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
previous: bool = False,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailChallenge:
|
|
"""Get starrail challenge runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
previous (bool, optional): Whether to get previous runs. Defaults to False.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailChallenge: The requested challenge runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(schedule_type=2 if previous else 1, need_all="true")
|
|
data = await self._request_starrail_record("challenge", player_id, lang=lang, payload=payload)
|
|
return StarRailChallenge(**data)
|
|
|
|
async def get_starrail_challenge_story(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
previous: bool = False,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailChallengeStory:
|
|
"""Get starrail challenge story runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
previous (bool, optional): Whether to get previous runs. Defaults to False.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailChallengeStory: The requested challenge story runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(schedule_type=2 if previous else 1, need_all="true", type="story")
|
|
data = await self._request_starrail_record("challenge_story", player_id, lang=lang, payload=payload)
|
|
return StarRailChallengeStory(**data)
|
|
|
|
async def get_starrail_challenge_boss(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
previous: bool = False,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailChallengeBoss:
|
|
"""Get starrail challenge boss runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
previous (bool, optional): Whether to get previous runs. Defaults to False.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailChallengeBoss: The requested challenge boss runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(schedule_type=2 if previous else 1, need_all="true", type="boss")
|
|
data = await self._request_starrail_record("challenge_boss", player_id, lang=lang, payload=payload)
|
|
return StarRailChallengeBoss(**data)
|
|
|
|
async def get_starrail_rogue(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
schedule_type: int = 3,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailRogue:
|
|
"""Get starrail rogue runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
schedule_type (int, optional): The schedule type. Defaults to 3.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailRogue: The requested rogue runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(schedule_type=schedule_type, need_detail="true")
|
|
data = await self._request_starrail_record("rogue", player_id, lang=lang, payload=payload)
|
|
return StarRailRogue(**data)
|
|
|
|
async def get_starrail_rogue_locust(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailRogueLocust:
|
|
"""Get starrail rogue locust runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailRogueLocust: The requested rogue locust runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(need_detail="true")
|
|
data = await self._request_starrail_record("rogue_locust", player_id, lang=lang, payload=payload)
|
|
return StarRailRogueLocust(**data)
|
|
|
|
async def get_starrail_rogue_nous(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailRogueNous:
|
|
"""Get starrail rogue nous runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailRogueNous: The requested rogue nous runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(need_detail="true")
|
|
data = await self._request_starrail_record("rogue_nous", player_id, lang=lang, payload=payload)
|
|
return StarRailRogueNous(**data)
|
|
|
|
async def get_starrail_rogue_tourn(
|
|
self,
|
|
player_id: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailRogueTourn:
|
|
"""Get starrail rogue tourn runs.
|
|
|
|
Args:
|
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailRogueTourn: The requested rogue tourn runs.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
payload = dict(need_detail="true")
|
|
data = await self._request_starrail_record("rogue_tourn", player_id, lang=lang, payload=payload)
|
|
return StarRailRogueTourn(**data)
|
|
|
|
async def get_starrail_act_calendar(
|
|
self,
|
|
uid: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailActCalendar:
|
|
"""Get starrail act calendar.
|
|
|
|
Args:
|
|
uid (Optional[int], optional): The player ID. Defaults to None.
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailActCalendar: The requested act calendar info.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
data = await self._request_starrail_record("get_act_calender", uid, lang=lang)
|
|
return StarRailActCalendar(**data)
|
|
|
|
async def get_starrail_notes_by_stoken(
|
|
self,
|
|
lang: Optional[str] = None,
|
|
) -> Union[StarRailNoteWidget, StarRailNoteOverseaWidget]:
|
|
"""Get StarRail's real-time notes.
|
|
|
|
Args:
|
|
lang (Optional[str], optional): The language of the data. Defaults to None.
|
|
|
|
Returns:
|
|
StarRailNoteWidget (Union[StarRailNoteWidget, StarRailNoteOverseaWidget]): The requested real-time notes.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
"""
|
|
stoken = self.cookies.get("stoken")
|
|
if stoken is None:
|
|
raise ValueError("stoken not found in cookies.")
|
|
stuid = self.cookies.get("stuid")
|
|
if stuid is None and self.account_id is None:
|
|
raise ValueError("account_id or stuid not found")
|
|
if self.account_id is not None and stuid is None:
|
|
self.cookies.set("stuid", str(self.account_id))
|
|
if self.region == Region.OVERSEAS:
|
|
route = RECORD_URL.get_url(self.region, self.game) / "../community/apihub/api/hsr_widget"
|
|
data = await self.request_lab(route, lang=lang)
|
|
model = StarRailNoteOverseaWidget
|
|
else:
|
|
data = await self._request_starrail_record("widget", endpoint_type="aapi", lang=lang)
|
|
model = StarRailNoteWidget
|
|
return model(**data)
|
|
|
|
async def set_starrail_avatar_recommend_property(
|
|
self,
|
|
avatar_id: int,
|
|
recommend_relic_properties: List[int] = None,
|
|
) -> None:
|
|
"""Set StarRail avatar recommend properties.
|
|
|
|
Args:
|
|
avatar_id (int): The avatar ID.
|
|
recommend_relic_properties (List[int], optional): The recommend relic properties. Defaults to None.
|
|
|
|
Raises:
|
|
InternalDatabaseError: If the request is invalid.
|
|
"""
|
|
payload = dict(
|
|
avatar_id=avatar_id,
|
|
recommend_relic_properties=recommend_relic_properties or [],
|
|
)
|
|
await self._request_starrail_record("setAvatarRecommendRelicProperty", method="POST", payload=payload)
|
|
|
|
async def get_starrail_ledger_month_info(
|
|
self,
|
|
uid: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailLedgerMonthInfo:
|
|
"""Get StarRail ledger month 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:
|
|
StarRailLedgerMonthInfo: 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("get_ledger_month_info", uid, lang=lang)
|
|
return StarRailLedgerMonthInfo(**data)
|
|
|
|
async def get_starrail_achievement_info(
|
|
self,
|
|
uid: Optional[int] = None,
|
|
lang: Optional[str] = None,
|
|
) -> StarRailAchievementInfo:
|
|
"""Get StarRail achievement 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:
|
|
StarRailAchievementInfo: The requested achievement info.
|
|
|
|
Raises:
|
|
BadRequest: If the request is invalid.
|
|
DataNotPublic: If the requested data is not public.
|
|
"""
|
|
data = await self._request_starrail_record("achievement_info", uid, lang=lang)
|
|
return StarRailAchievementInfo(**data)
|