mirror of
https://github.com/PaiGramTeam/SIMNet.git
synced 2024-11-22 06:17:57 +00:00
✨ Add more starrail func
This commit is contained in:
parent
a92a7f84f8
commit
9aaaec2d88
@ -69,7 +69,8 @@ class BaseClient(AsyncContextManager["BaseClient"]):
|
||||
write=5.0,
|
||||
pool=1.0,
|
||||
)
|
||||
cookies = Cookies(parse_cookie(cookies)) if isinstance(cookies, str) else cookies
|
||||
cookies = parse_cookie(cookies) if isinstance(cookies, str) else cookies
|
||||
cookies = Cookies(cookies)
|
||||
self.headers = Headers(headers)
|
||||
self.player_id = player_id
|
||||
self.account_id = account_id or cookies.account_id
|
||||
|
@ -87,7 +87,7 @@ class BaseChronicleClient(BaseClient):
|
||||
if game is None and switch_id == 3:
|
||||
game = Game.GENSHIN
|
||||
|
||||
game_id = {Game.HONKAI: 1, Game.GENSHIN: 2, Game.STARRAIL: 3}[game]
|
||||
game_id = {Game.HONKAI: 1, Game.GENSHIN: 2, Game.STARRAIL: 6}[game]
|
||||
|
||||
await self.request_game_record(
|
||||
"card/wapi/changeDataSwitch",
|
||||
|
@ -4,9 +4,11 @@ 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.characters import StarShipDetailCharacters
|
||||
from simnet.models.starrail.chronicle.challenge import StarRailChallenge
|
||||
from simnet.models.starrail.chronicle.characters import StarRailDetailCharacters
|
||||
from simnet.models.starrail.chronicle.notes import StarRailNote
|
||||
from simnet.models.starrail.chronicle.stats import StarRailUserStats
|
||||
from simnet.models.starrail.chronicle.rogue import StarRailRogue
|
||||
from simnet.models.starrail.chronicle.stats import StarRailUserStats, StarRailUserInfo
|
||||
from simnet.utils.enum_ import Game
|
||||
from simnet.utils.player import recognize_starrail_server, recognize_region
|
||||
|
||||
@ -92,6 +94,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
||||
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)
|
||||
@ -119,14 +122,14 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
||||
self._request_starrail_record("index", player_id, lang=lang),
|
||||
self._request_starrail_record("role/basicInfo", player_id, lang=lang),
|
||||
)
|
||||
index_data["info"] = basic_info
|
||||
return StarRailUserStats(**index_data)
|
||||
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,
|
||||
) -> StarShipDetailCharacters:
|
||||
) -> StarRailDetailCharacters:
|
||||
"""Get StarRail character information.
|
||||
|
||||
Args:
|
||||
@ -134,7 +137,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
||||
lang (Optional[str], optional): The language of the data. Defaults to None.
|
||||
|
||||
Returns:
|
||||
StarShipDetailCharacters: The requested character information.
|
||||
StarRailDetailCharacters: The requested character information.
|
||||
|
||||
Raises:
|
||||
BadRequest: If the request is invalid.
|
||||
@ -142,7 +145,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
||||
"""
|
||||
payload = {"need_wiki": "true"}
|
||||
data = await self._request_starrail_record("avatar/info", player_id, lang=lang, payload=payload)
|
||||
return StarShipDetailCharacters(**data)
|
||||
return StarRailDetailCharacters(**data)
|
||||
|
||||
async def get_record_card(
|
||||
self,
|
||||
@ -171,3 +174,51 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
||||
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_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)
|
||||
|
@ -1,19 +1,31 @@
|
||||
"""Starrail base character model."""
|
||||
from simnet.models.base import APIModel
|
||||
|
||||
|
||||
class BaseCharacter(APIModel):
|
||||
"""
|
||||
A class representing a character in a game.
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): The unique identifier of the character.
|
||||
name (:obj:`str`): The name of the character.
|
||||
element (:obj:`str`): The element that the character represents (e.g. fire, water, etc.).
|
||||
rarity (:obj:`int`): The rarity of the character (e.g. 1-5 stars).
|
||||
"""
|
||||
class StarRailBaseCharacter(APIModel):
|
||||
"""Base character model."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
element: str
|
||||
rarity: int
|
||||
icon: str
|
||||
|
||||
|
||||
class StarRailPartialCharacter(StarRailBaseCharacter):
|
||||
"""Character without any equipment."""
|
||||
|
||||
name: str
|
||||
level: int
|
||||
rank: int
|
||||
|
||||
|
||||
class FloorCharacter(StarRailBaseCharacter):
|
||||
"""Character in a floor."""
|
||||
|
||||
level: int
|
||||
|
||||
|
||||
class RogueCharacter(StarRailBaseCharacter):
|
||||
"""Rogue character model."""
|
||||
|
||||
level: int
|
||||
|
18
simnet/models/starrail/chronicle/base.py
Normal file
18
simnet/models/starrail/chronicle/base.py
Normal file
@ -0,0 +1,18 @@
|
||||
"""Starrail Chronicle Base Model."""
|
||||
import datetime
|
||||
|
||||
from simnet.models.base import APIModel
|
||||
|
||||
|
||||
class PartialTime(APIModel):
|
||||
"""Partial time model."""
|
||||
|
||||
year: int
|
||||
month: int
|
||||
day: int
|
||||
hour: int
|
||||
minute: int
|
||||
|
||||
@property
|
||||
def datetime(self) -> datetime.datetime:
|
||||
return datetime.datetime(self.year, self.month, self.day, self.hour, self.minute)
|
44
simnet/models/starrail/chronicle/challenge.py
Normal file
44
simnet/models/starrail/chronicle/challenge.py
Normal file
@ -0,0 +1,44 @@
|
||||
"""Starrail chronicle challenge."""
|
||||
from typing import List
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from simnet.models.base import APIModel
|
||||
from simnet.models.starrail.character import FloorCharacter
|
||||
|
||||
from .base import PartialTime
|
||||
|
||||
__all__ = ["StarRailFloor", "FloorNode", "StarRailChallenge"]
|
||||
|
||||
|
||||
class FloorNode(APIModel):
|
||||
"""Node for a floor."""
|
||||
|
||||
challenge_time: PartialTime
|
||||
avatars: List[FloorCharacter]
|
||||
|
||||
|
||||
class StarRailFloor(APIModel):
|
||||
"""Floor in a challenge."""
|
||||
|
||||
name: str
|
||||
round_num: int
|
||||
star_num: int
|
||||
node_1: FloorNode
|
||||
node_2: FloorNode
|
||||
is_chaos: bool
|
||||
|
||||
|
||||
class StarRailChallenge(APIModel):
|
||||
"""Challenge in a season."""
|
||||
|
||||
season: int = Field(alias="schedule_id")
|
||||
begin_time: PartialTime
|
||||
end_time: PartialTime
|
||||
|
||||
total_stars: int = Field(alias="star_num")
|
||||
max_floor: str
|
||||
total_battles: int = Field(alias="battle_num")
|
||||
has_data: bool
|
||||
|
||||
floors: List[StarRailFloor] = Field(alias="all_floor_detail")
|
@ -1,32 +1,21 @@
|
||||
from typing import Optional, List
|
||||
"""Starrail chronicle character."""
|
||||
from typing import List, Optional
|
||||
|
||||
from simnet.models.base import APIModel
|
||||
from simnet.models.starrail.character import BaseCharacter
|
||||
|
||||
from .. import character
|
||||
|
||||
__all__ = [
|
||||
"StarRailEquipment",
|
||||
"Rank",
|
||||
"Relic",
|
||||
"StarRailDetailCharacter",
|
||||
"StarRailDetailCharacters",
|
||||
]
|
||||
|
||||
|
||||
class PartialCharacter(BaseCharacter):
|
||||
"""A character without any equipment.
|
||||
|
||||
Attributes:
|
||||
level (int): The level of the character.
|
||||
rank (int): The rank of the character.
|
||||
"""
|
||||
|
||||
level: int
|
||||
rank: int
|
||||
|
||||
|
||||
class Equipment(APIModel):
|
||||
"""An equipment model used in StarRailDetailCharacter.
|
||||
|
||||
Attributes:
|
||||
id (int): The ID of the equipment.
|
||||
level (int): The level of the equipment.
|
||||
rank (int): The rank of the equipment.
|
||||
name (str): The name of the equipment.
|
||||
desc (str): The description of the equipment.
|
||||
icon (str): The icon of the equipment.
|
||||
"""
|
||||
class StarRailEquipment(APIModel):
|
||||
"""Character equipment."""
|
||||
|
||||
id: int
|
||||
level: int
|
||||
@ -37,17 +26,7 @@ class Equipment(APIModel):
|
||||
|
||||
|
||||
class Relic(APIModel):
|
||||
"""A relic model used in StarRailDetailCharacter.
|
||||
|
||||
Attributes:
|
||||
id (int): The ID of the relic.
|
||||
level (int): The level of the relic.
|
||||
pos (int): The position of the relic.
|
||||
name (str): The name of the relic.
|
||||
desc (str): The description of the relic.
|
||||
icon (str): The icon of the relic.
|
||||
rarity (int): The rarity of the relic.
|
||||
"""
|
||||
"""Character relic."""
|
||||
|
||||
id: int
|
||||
level: int
|
||||
@ -59,16 +38,7 @@ class Relic(APIModel):
|
||||
|
||||
|
||||
class Rank(APIModel):
|
||||
"""A rank model used in StarRailDetailCharacter.
|
||||
|
||||
Attributes:
|
||||
id (int): The ID of the rank.
|
||||
pos (int): The position of the rank.
|
||||
name (str): The name of the rank.
|
||||
icon (str): The icon of the rank.
|
||||
desc (str): The description of the rank.
|
||||
is_unlocked (bool): Whether the rank is unlocked.
|
||||
"""
|
||||
"""Character rank."""
|
||||
|
||||
id: int
|
||||
pos: int
|
||||
@ -78,29 +48,17 @@ class Rank(APIModel):
|
||||
is_unlocked: bool
|
||||
|
||||
|
||||
class StarRailDetailCharacter(PartialCharacter):
|
||||
"""A detailed character model used in StarShipDetailCharacters.
|
||||
|
||||
Attributes:
|
||||
image (str): The image of the character.
|
||||
equip (Optional[Equipment]): The equipment of the character, if any.
|
||||
relics (List[Relic]): The relics of the character.
|
||||
ornaments (List[Relic]): The ornaments of the character.
|
||||
ranks (List[Rank]): The ranks of the character.
|
||||
"""
|
||||
class StarRailDetailCharacter(character.StarRailPartialCharacter):
|
||||
"""StarRail character with equipment and relics."""
|
||||
|
||||
image: str
|
||||
equip: Optional[Equipment]
|
||||
equip: Optional[StarRailEquipment]
|
||||
relics: List[Relic]
|
||||
ornaments: List[Relic]
|
||||
ranks: List[Rank]
|
||||
|
||||
|
||||
class StarShipDetailCharacters(APIModel):
|
||||
"""A model containing a list of detailed characters used in the StarShipDetail API.
|
||||
|
||||
Attributes:
|
||||
avatar_list (List[StarRailDetailCharacter]): The list of detailed characters.
|
||||
"""
|
||||
class StarRailDetailCharacters(APIModel):
|
||||
"""StarRail characters."""
|
||||
|
||||
avatar_list: List[StarRailDetailCharacter]
|
||||
|
96
simnet/models/starrail/chronicle/rogue.py
Normal file
96
simnet/models/starrail/chronicle/rogue.py
Normal file
@ -0,0 +1,96 @@
|
||||
"""Starrail Rogue models."""
|
||||
from typing import List
|
||||
|
||||
from simnet.models.base import APIModel
|
||||
|
||||
from ..character import RogueCharacter
|
||||
from .base import PartialTime
|
||||
|
||||
|
||||
class RogueUserRole(APIModel):
|
||||
"""Rogue User info."""
|
||||
|
||||
nickname: str
|
||||
server: str
|
||||
level: int
|
||||
|
||||
|
||||
class RogueBasicInfo(APIModel):
|
||||
"""generalized rogue basic info."""
|
||||
|
||||
unlocked_buff_num: int
|
||||
unlocked_miracle_num: int
|
||||
unlocked_skill_points: int
|
||||
|
||||
|
||||
class RogueRecordBasic(APIModel):
|
||||
"""Basic record info."""
|
||||
|
||||
id: int
|
||||
finish_cnt: int
|
||||
schedule_begin: PartialTime
|
||||
schedule_end: PartialTime
|
||||
|
||||
|
||||
class RogueBuffType(APIModel):
|
||||
"""Rogue buff type."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
cnt: int
|
||||
|
||||
|
||||
class RogueBuffItem(APIModel):
|
||||
"""Rogue buff item."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
is_evoluted: bool
|
||||
rank: int
|
||||
|
||||
|
||||
class RogueBuff(APIModel):
|
||||
"""Rogue buff info."""
|
||||
|
||||
base_type: RogueBuffType
|
||||
items: List[RogueBuffItem]
|
||||
|
||||
|
||||
class RogueMiracle(APIModel):
|
||||
"""Rogue miracle info."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
icon: str
|
||||
|
||||
|
||||
class RogueRecordDetail(APIModel):
|
||||
"""Detailed record info."""
|
||||
|
||||
name: str
|
||||
finish_time: PartialTime
|
||||
score: int
|
||||
final_lineup: List[RogueCharacter]
|
||||
base_type_list: List[RogueBuffType]
|
||||
cached_avatars: List[RogueCharacter]
|
||||
buffs: List[RogueBuff]
|
||||
miracles: List[RogueMiracle]
|
||||
difficulty: int
|
||||
progress: int
|
||||
|
||||
|
||||
class RogueRecord(APIModel):
|
||||
"""generic record data."""
|
||||
|
||||
basic: RogueRecordBasic
|
||||
records: List[RogueRecordDetail]
|
||||
has_data: bool
|
||||
|
||||
|
||||
class StarRailRogue(APIModel):
|
||||
"""generic rogue data."""
|
||||
|
||||
role: RogueUserRole
|
||||
basic_info: RogueBasicInfo
|
||||
current_record: RogueRecord
|
||||
last_record: RogueRecord
|
@ -1,20 +1,22 @@
|
||||
from typing import List
|
||||
"""Starrail chronicle stats."""
|
||||
import typing
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from simnet.models.base import APIModel
|
||||
from simnet.models.starrail.chronicle.characters import PartialCharacter
|
||||
|
||||
from .. import character
|
||||
|
||||
__all__ = [
|
||||
"PartialStarRailUserStats",
|
||||
"StarRailUserInfo",
|
||||
"StarRailUserStats",
|
||||
"StarRailStats",
|
||||
]
|
||||
|
||||
|
||||
class Stats(APIModel):
|
||||
"""
|
||||
Statistics of user data.
|
||||
|
||||
Attributes:
|
||||
active_days (int): Number of days the user has been active.
|
||||
avatar_num (int): Number of avatars the user has.
|
||||
achievement_num (int): Number of achievements the user has earned.
|
||||
chest_num (int): Number of chests the user has opened.
|
||||
abyss_process (str): Progress of the user in the abyss mode.
|
||||
"""
|
||||
class StarRailStats(APIModel):
|
||||
"""Overall user stats."""
|
||||
|
||||
active_days: int
|
||||
avatar_num: int
|
||||
@ -24,28 +26,14 @@ class Stats(APIModel):
|
||||
|
||||
|
||||
class PartialStarRailUserStats(APIModel):
|
||||
"""
|
||||
Partial data of StarRail user, containing statistics and character information.
|
||||
"""User stats with characters without equipment."""
|
||||
|
||||
Attributes:
|
||||
stats (Stats): Statistics of user data.
|
||||
characters (List[PartialCharacter]): List of user's avatars/characters.
|
||||
"""
|
||||
|
||||
stats: Stats
|
||||
characters: List[PartialCharacter] = Field(alias="avatar_list")
|
||||
stats: StarRailStats
|
||||
characters: typing.Sequence[character.StarRailPartialCharacter] = Field(alias="avatar_list")
|
||||
|
||||
|
||||
class StarRailUserInfo(APIModel):
|
||||
"""
|
||||
Information of StarRail user.
|
||||
|
||||
Attributes:
|
||||
nickname (str): User's nickname.
|
||||
server (str): User's server.
|
||||
level (int): User's level.
|
||||
avatar (str): User's avatar url.
|
||||
"""
|
||||
"""User info."""
|
||||
|
||||
nickname: str
|
||||
server: str = Field(alias="region")
|
||||
@ -54,6 +42,6 @@ class StarRailUserInfo(APIModel):
|
||||
|
||||
|
||||
class StarRailUserStats(PartialStarRailUserStats):
|
||||
"""Complete data of StarRail user, containing statistics and character information."""
|
||||
"""User stats."""
|
||||
|
||||
info: StarRailUserInfo
|
||||
|
@ -11,7 +11,7 @@ UID_RANGE: Mapping[Game, Mapping[Region, Sequence[int]]] = {
|
||||
},
|
||||
Game.STARRAIL: {
|
||||
Region.OVERSEAS: (6, 7, 8, 9),
|
||||
Region.CHINESE: (1, 2),
|
||||
Region.CHINESE: (1, 2, 5),
|
||||
},
|
||||
Game.HONKAI: {
|
||||
Region.OVERSEAS: (1, 2),
|
||||
|
@ -45,3 +45,13 @@ class TestStarrailBattleChronicleClient:
|
||||
assert len(characters.avatar_list) > 0
|
||||
character = characters.avatar_list[-1]
|
||||
assert character.id > 0
|
||||
|
||||
@staticmethod
|
||||
async def test_get_starrail_challenge(starrail_client: "StarRailBattleChronicleClient"):
|
||||
challenge = await starrail_client.get_starrail_challenge()
|
||||
assert challenge.season > 0
|
||||
|
||||
@staticmethod
|
||||
async def test_get_starrail_rogue(starrail_client: "StarRailBattleChronicleClient"):
|
||||
rogue = await starrail_client.get_starrail_rogue()
|
||||
assert rogue.role is not None
|
||||
|
Loading…
Reference in New Issue
Block a user