diff --git a/modules/apihelper/client/components/authclient.py b/modules/apihelper/client/components/authclient.py index f0a938b..acfb912 100644 --- a/modules/apihelper/client/components/authclient.py +++ b/modules/apihelper/client/components/authclient.py @@ -11,7 +11,7 @@ from qrcode.image.pure import PyPNGImage from ...logger import logger from ...models.genshin.cookies import CookiesModel -from ...utility.helpers import get_device_id, get_ds +from ...utility.helpers import get_device_id, get_ds, update_device_headers __all__ = ("AuthClient",) @@ -87,13 +87,12 @@ class AuthClient: "Accept": "application/json", "x-rpc-game_biz": "bbs_cn", "x-rpc-sys_version": "11", - "x-rpc-device_id": get_device_id(self.USER_AGENT), - "x-rpc-device_fp": "".join(random.choices((ascii_letters + digits), k=13)), "x-rpc-device_name": "Chrome 108.0.0.0", "x-rpc-device_model": "Windows 10 64-bit", "x-rpc-app_id": "bll8iq97cem8", "User-Agent": "okhttp/4.8.0", } + update_device_headers(self.user_id, headers) app_version, client_type, ds_sign = get_ds(new_ds=True, data=data) headers["x-rpc-app_version"] = app_version headers["x-rpc-client_type"] = client_type diff --git a/modules/apihelper/client/components/verify.py b/modules/apihelper/client/components/verify.py index eeb1fec..a6dcfea 100644 --- a/modules/apihelper/client/components/verify.py +++ b/modules/apihelper/client/components/verify.py @@ -4,7 +4,7 @@ import time from typing import Dict, Optional from ..base.hyperionrequest import HyperionRequest -from ...utility.helpers import get_ua, get_device_id, get_ds +from ...utility.helpers import get_ua, get_ds, update_device_headers __all__ = ("Verify",) @@ -14,6 +14,8 @@ class Verify: VERIFICATION_HOST = "api.geetest.com" CREATE_VERIFICATION_URL = "/game_record/app/card/wapi/createVerification" VERIFY_VERIFICATION_URL = "/game_record/app/card/wapi/verifyVerification" + REFERER_URL = "/game_record/app/genshin/api/dailyNote" + GAME = "2" AJAX_URL = "/ajax.php" USER_AGENT = get_ua() @@ -24,7 +26,6 @@ class Verify: "User-Agent": USER_AGENT, "X-Requested-With": "com.mihoyo.hyperion", "Referer": "https://webstatic.mihoyo.com/", - "x-rpc-device_id": get_device_id(USER_AGENT), "x-rpc-page": "3.1.3_#/ys", } @@ -35,7 +36,8 @@ class Verify: "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", } - def __init__(self, cookies: Dict = None): + def __init__(self, account_id: int = None, cookies: Dict = None): + self.account_id = account_id self.client = HyperionRequest(headers=self.BBS_HEADERS, cookies=cookies) def get_verification_headers(self, referer: str): @@ -49,6 +51,9 @@ class Verify: headers["x-rpc-app_version"] = app_version headers["x-rpc-client_type"] = client_type headers["DS"] = ds + headers["x-rpc-challenge_path"] = f"https://{self.HOST}{self.REFERER_URL}" + headers["x-rpc-challenge_game"] = self.GAME + update_device_headers(self.account_id, headers) return headers @staticmethod diff --git a/modules/apihelper/utility/helpers.py b/modules/apihelper/utility/helpers.py index 601d476..99d6d8d 100644 --- a/modules/apihelper/utility/helpers.py +++ b/modules/apihelper/utility/helpers.py @@ -4,9 +4,9 @@ import random import string import time import uuid -from typing import Any, Mapping, Optional +from typing import Any, Mapping, Optional, Dict -__all__ = ("get_device_id", "hex_digest", "get_ds", "get_recognize_server", "get_ua") +__all__ = ("get_device_id", "hex_digest", "get_ds", "get_recognize_server", "get_ua", "update_device_headers") RECOGNIZE_SERVER = { "1": "cn_gf01", @@ -23,6 +23,14 @@ def get_device_id(name: str = ""): return str(uuid.uuid3(uuid.NAMESPACE_URL, name)) +def update_device_headers(account_id: int, headers: Dict = None) -> Dict[str, str]: + account_id = account_id or 0 + headers = headers or {} + headers["x-rpc-device_id"] = get_device_id(str(account_id)) + headers["x-rpc-device_fp"] = hex_digest(headers["x-rpc-device_id"])[:13] + return headers + + def hex_digest(text): _md5 = hashlib.md5() # nosec B303 _md5.update(text.encode()) diff --git a/plugins/tools/challenge.py b/plugins/tools/challenge.py index e8f1b1c..385777d 100644 --- a/plugins/tools/challenge.py +++ b/plugins/tools/challenge.py @@ -61,7 +61,7 @@ class ChallengeSystem(Plugin): raise exc else: raise ChallengeSystemException("账户正常,无需验证") - verify = Verify(cookies=client.cookie_manager.cookies) + verify = Verify(account_id=client.hoyolab_id, cookies=client.cookie_manager.cookies) try: data = await verify.create() challenge = data["challenge"] @@ -91,7 +91,7 @@ class ChallengeSystem(Plugin): _, challenge = await self.get_challenge(client.uid) if challenge is None: raise ChallengeSystemException("验证失效 请求已经过期") - verify = Verify(cookies=client.cookie_manager.cookies) + verify = Verify(account_id=client.hoyolab_id, cookies=client.cookie_manager.cookies) try: await verify.verify(challenge=challenge, validate=validate) except ResponseException as exc: diff --git a/plugins/tools/sign.py b/plugins/tools/sign.py index a5c9028..d3c50eb 100644 --- a/plugins/tools/sign.py +++ b/plugins/tools/sign.py @@ -148,6 +148,7 @@ class SignSystem(Plugin): gt = request_daily_reward.get("gt", "") challenge = request_daily_reward.get("challenge", "") logger.warning("UID[%s] 触发验证码\ngt[%s]\nchallenge[%s]", client.uid, gt, challenge) + self.verify.account_id = client.hoyolab_id validate = await self.verify.ajax( referer=RecognizeSystem.REFERER, gt=gt, diff --git a/utils/genshin.py b/utils/genshin.py index 2610d65..d35fd76 100644 --- a/utils/genshin.py +++ b/utils/genshin.py @@ -4,7 +4,7 @@ from genshin import Client from genshin.client.routes import InternationalRoute # noqa F401 from genshin.utility import recognize_genshin_server -from modules.apihelper.utility.helpers import hex_digest, get_ds +from modules.apihelper.utility.helpers import hex_digest, get_ds, update_device_headers AUTHKEY_API = "https://api-takumi.mihoyo.com/binding/api/genAuthKey" HK4E_LOGIN_URL = InternationalRoute( @@ -15,7 +15,6 @@ GACHA_HEADERS = { "User-Agent": "okhttp/4.8.0", "x-rpc-sys_version": "12", "x-rpc-channel": "mihoyo", - "x-rpc-device_id": "", "x-rpc-device_name": "", "x-rpc-device_model": "", "Referer": "https://app.mihoyo.com", @@ -37,8 +36,8 @@ async def get_authkey_by_stoken(client: Client) -> Optional[str]: "region": recognize_genshin_server(client.uid), } device_id = hex_digest(str(client.uid)) - headers["x-rpc-device_id"] = device_id device = f"Paimon Build {device_id[:5]}" + update_device_headers(client.hoyolab_id, headers) headers["x-rpc-device_name"] = device headers["x-rpc-device_model"] = device app_version, client_type, ds_sign = get_ds() diff --git a/utils/patch/genshin.py b/utils/patch/genshin.py index 301b0b1..85fd3b4 100644 --- a/utils/patch/genshin.py +++ b/utils/patch/genshin.py @@ -9,7 +9,8 @@ from genshin import constants, types, utility from genshin.client import routes from genshin.utility import generate_dynamic_secret, ds -from modules.apihelper.utility.helpers import get_ds, get_ua, get_device_id, hex_digest +from modules.apihelper.utility.helpers import get_ds, get_ua, get_device_id, hex_digest, update_device_headers +from utils.log import logger from utils.patch.methods import patch, patchable DEVICE_ID = get_device_id() @@ -108,7 +109,7 @@ class CalculatorClient: class BaseClient: @patchable async def request_hoyolab( - self, + self: "genshin.Client", url: aiohttp.typedefs.StrOrURL, *, lang: typing.Optional[str] = None, @@ -151,11 +152,11 @@ class BaseClient: "User-Agent": ua, "X_Requested_With": "com.mihoyo.hoyolab", "Referer": "https://webstatic.mihoyo.com", - "x-rpc-device_id": get_device_id(device_id), "x-rpc-app_version": app_version, "x-rpc-client_type": client_type, "ds": ds_sign, } + update_device_headers(self.hoyolab_id, headers) else: raise TypeError(f"{region!r} is not a valid region.") @@ -164,7 +165,7 @@ class BaseClient: @patchable async def request( - self, + self: "genshin.Client", url: aiohttp.typedefs.StrOrURL, *, method: typing.Optional[str] = None, @@ -189,6 +190,8 @@ class BaseClient: headers = dict(headers or {}) headers.setdefault("User-Agent", self.USER_AGENT) + update_device_headers(self.hoyolab_id, headers) + logger.debug("Account ID: %s Header: %s" % (self.hoyolab_id, headers)) if method is None: method = "POST" if data else "GET" @@ -218,7 +221,7 @@ class BaseClient: @patchable async def request_bbs( - self, + self: "genshin.Client", url: aiohttp.typedefs.StrOrURL, *, lang: typing.Optional[str] = None, @@ -256,12 +259,12 @@ class BaseClient: add_headers = { "User-Agent": ua, "Referer": "https://www.miyoushe.com/ys/", - "x-rpc-device_id": get_device_id(device_id), "x-rpc-app_version": app_version, "x-rpc-client_type": "4", "ds": ds_sign, } headers.update(add_headers) + update_device_headers(self.hoyolab_id, headers) elif self.region == types.Region.OVERSEAS: headers.update(ds.get_ds_headers(data=data, params=params, region=region, lang=lang or self.lang)) headers["Referer"] = str(routes.BBS_REFERER_URL.get_url(self.region)) @@ -276,7 +279,7 @@ class BaseClient: class DailyRewardClient: @patchable async def request_daily_reward( - self, + self: "genshin.Client", endpoint: str, *, game: typing.Optional[types.Game] = None, @@ -331,7 +334,6 @@ class DailyRewardClient: "bbs_auth_required=true&act_id=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon" ) headers["x-rpc-device_name"] = device - headers["x-rpc-device_id"] = get_device_id(device_id) headers["x-rpc-app_version"] = app_version headers["x-rpc-client_type"] = client_type headers["x-rpc-sys_version"] = "12" @@ -347,7 +349,7 @@ class DailyRewardClient: headers["x-rpc-challenge"] = challenge headers["x-rpc-validate"] = validate headers["x-rpc-seccode"] = f"{validate}|jordan" - + update_device_headers(self.hoyolab_id, headers) else: raise TypeError(f"{self.region!r} is not a valid region.")