107 lines
3.5 KiB
Python
107 lines
3.5 KiB
Python
|
"""Automatic sign-in for hoyolab's daily rewards.
|
||
|
|
||
|
Automatically claims the next daily reward in the daily check-in rewards.
|
||
|
"""
|
||
|
from typing import Any, Dict, Iterator, List, Mapping, NamedTuple, Optional
|
||
|
from urllib.parse import urljoin
|
||
|
|
||
|
from .caching import permanent_cache
|
||
|
from .genshinstats import fetch_endpoint
|
||
|
from .hoyolab import get_game_accounts
|
||
|
from .utils import recognize_server
|
||
|
|
||
|
__all__ = [
|
||
|
"fetch_daily_endpoint",
|
||
|
"get_daily_reward_info",
|
||
|
"get_claimed_rewards",
|
||
|
"get_monthly_rewards",
|
||
|
"claim_daily_reward",
|
||
|
]
|
||
|
|
||
|
OS_URL = "https://hk4e-api-os.mihoyo.com/event/sol/" # overseas
|
||
|
OS_ACT_ID = "e202102251931481"
|
||
|
CN_URL = "https://api-takumi.mihoyo.com/event/bbs_sign_reward/" # chinese
|
||
|
CN_ACT_ID = "e202009291139501"
|
||
|
|
||
|
|
||
|
class DailyRewardInfo(NamedTuple):
|
||
|
signed_in: bool
|
||
|
claimed_rewards: int
|
||
|
|
||
|
|
||
|
def fetch_daily_endpoint(endpoint: str, chinese: bool = False, **kwargs) -> Dict[str, Any]:
|
||
|
"""Fetch an enpoint for daily rewards"""
|
||
|
url, act_id = (CN_URL, CN_ACT_ID) if chinese else (OS_URL, OS_ACT_ID)
|
||
|
kwargs.setdefault("params", {})["act_id"] = act_id
|
||
|
url = urljoin(url, endpoint)
|
||
|
|
||
|
return fetch_endpoint(url, **kwargs)
|
||
|
|
||
|
|
||
|
def get_daily_reward_info(
|
||
|
chinese: bool = False, cookie: Mapping[str, Any] = None
|
||
|
) -> DailyRewardInfo:
|
||
|
"""Fetches daily award info for the currently logged-in user.
|
||
|
|
||
|
Returns a tuple - whether the user is logged in, how many total rewards the user has claimed so far
|
||
|
"""
|
||
|
data = fetch_daily_endpoint("info", chinese, cookie=cookie)
|
||
|
return DailyRewardInfo(data["is_sign"], data["total_sign_day"])
|
||
|
|
||
|
|
||
|
@permanent_cache("chinese", "lang")
|
||
|
def get_monthly_rewards(
|
||
|
chinese: bool = False, lang: str = "en-us", cookie: Mapping[str, Any] = None
|
||
|
) -> List[Dict[str, Any]]:
|
||
|
"""Gets a list of avalible rewards for the current month"""
|
||
|
return fetch_daily_endpoint("home", chinese, cookie=cookie, params=dict(lang=lang))["awards"]
|
||
|
|
||
|
|
||
|
def get_claimed_rewards(
|
||
|
chinese: bool = False, cookie: Mapping[str, Any] = None
|
||
|
) -> Iterator[Dict[str, Any]]:
|
||
|
"""Gets all claimed awards for the currently logged-in user"""
|
||
|
current_page = 1
|
||
|
while True:
|
||
|
data = fetch_daily_endpoint(
|
||
|
"award", chinese, cookie=cookie, params=dict(current_page=current_page)
|
||
|
)["list"]
|
||
|
yield from data
|
||
|
if len(data) < 10:
|
||
|
break
|
||
|
current_page += 1
|
||
|
|
||
|
|
||
|
def claim_daily_reward(
|
||
|
uid: int = None, chinese: bool = False, lang: str = "en-us", cookie: Mapping[str, Any] = None
|
||
|
) -> Optional[Dict[str, Any]]:
|
||
|
"""Signs into hoyolab and claims the daily rewards.
|
||
|
|
||
|
Chinese and overseas servers work a bit differently,
|
||
|
so you must specify whether you want to claim rewards for chinese accounts.
|
||
|
|
||
|
When claiming rewards for other users you may add a cookie argument.
|
||
|
|
||
|
Returns the claimed reward or None if the reward cannot be claimed yet.
|
||
|
"""
|
||
|
signed_in, claimed_rewards = get_daily_reward_info(chinese, cookie)
|
||
|
if signed_in:
|
||
|
return None
|
||
|
|
||
|
params = {}
|
||
|
|
||
|
if chinese:
|
||
|
if uid is None:
|
||
|
accounts = get_game_accounts(chinese=True, cookie=cookie)
|
||
|
params["game_uid"] = accounts[0]["game_uid"]
|
||
|
params["region"] = accounts[0]["region"]
|
||
|
else:
|
||
|
params["game_uid"] = uid
|
||
|
params["region"] = recognize_server(uid)
|
||
|
|
||
|
params["lang"] = lang
|
||
|
|
||
|
fetch_daily_endpoint("sign", chinese, cookie=cookie, method="POST", params=params)
|
||
|
rewards = get_monthly_rewards(chinese, lang, cookie)
|
||
|
return rewards[claimed_rewards]
|