From 0e4b1cdc1b2a2fcf11e86eb20c42ca8120e09232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B4=9B=E6=B0=B4=E5=B1=85=E5=AE=A4?= Date: Mon, 28 Nov 2022 22:45:29 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Use=20`Client.get=5Fhoyolab=5Fuser`?= =?UTF-8?q?=20to=20get=20hoyolab=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/genshin/cookies.py | 24 ++++++++------------ utils/patch/genshin.py | 46 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/plugins/genshin/cookies.py b/plugins/genshin/cookies.py index 9bdf9cda..d0a34247 100644 --- a/plugins/genshin/cookies.py +++ b/plugins/genshin/cookies.py @@ -3,7 +3,7 @@ from http.cookies import SimpleCookie, CookieError from typing import Optional, Dict import genshin -from genshin import InvalidCookies, GenshinException, DataNotPublic +from genshin import InvalidCookies, GenshinException, DataNotPublic, types from genshin.models import GenshinAccount from telegram import Update, ReplyKeyboardRemove, ReplyKeyboardMarkup, TelegramObject from telegram.ext import CallbackContext, filters, ConversationHandler @@ -34,10 +34,6 @@ class AddUserCommandData(TelegramObject): sign_in_client: Optional[SignIn] = None -class GetAccountIdException(Exception): - pass - - CHECK_SERVER, CHECK_PHONE, CHECK_CAPTCHA, INPUT_COOKIES, COMMAND_RESULT = range(10100, 10105) @@ -322,11 +318,13 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation): try: if "account_mid_v2" in cookies: logger.info("检测到用户 %s[%s] 使用 V2 Cookie 正在尝试获取 account_id", user.full_name, user.id) - account_id = await SignIn.get_v2_account_id(client) - if account_id is None: - raise GetAccountIdException - logger.success("获取用户 %s[%s] account_id[%s] 成功", user.full_name, user.id, account_id) - add_user_command_data.cookies["account_id"] = account_id + if client.region == types.Region.CHINESE: + account_info = await client.get_hoyolab_user(-1) + account_id = account_info.hoyolab_uid + add_user_command_data.cookies["account_id"] = str(account_id) + logger.success("获取用户 %s[%s] account_id[%s] 成功", user.full_name, user.id, account_id) + else: + logger.warning("用户 %s[%s] region 也许是不正确的", user.full_name, user.id, client.region.name) genshin_accounts = await client.genshin_accounts() except DataNotPublic: logger.info("用户 %s[%s] 账号疑似被注销", user.full_name, user.id) @@ -342,13 +340,9 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation): f"获取账号信息发生错误,错误信息为 {exc.original},请检查Cookie或者账号是否正常", reply_markup=ReplyKeyboardRemove() ) return ConversationHandler.END - except GetAccountIdException: - logger.info("用户 %s[%s] 获取账号ID发生错误", user.full_name, user.id) - await message.reply_text("获取账号ID发生错误,请检查Cookie或者账号是否正常", reply_markup=ReplyKeyboardRemove()) - return ConversationHandler.END except (AttributeError, ValueError) as exc: logger.warning("用户 %s[%s] Cookies错误", user.full_name, user.id) - logger.debug("Cookies错误", exc_info=exc) + logger.debug("用户 %s[%s] Cookies错误" % (user.full_name, user.id), exc_info=exc) await message.reply_text("Cookies错误,请检查是否正确", reply_markup=ReplyKeyboardRemove()) return ConversationHandler.END with contextlib.suppress(Exception): diff --git a/utils/patch/genshin.py b/utils/patch/genshin.py index 5aa2792a..7d9d8ec1 100644 --- a/utils/patch/genshin.py +++ b/utils/patch/genshin.py @@ -3,9 +3,9 @@ import typing import aiohttp.typedefs import genshin # pylint: disable=W0406 import yarl -from genshin import constants, types, utility +from genshin import constants, types, utility, models from genshin.client import routes -from genshin.utility import ds +from genshin.utility import ds, generate_dynamic_secret from modules.apihelper.helpers import get_ds, get_ua, get_device_id, hex_digest from utils.patch.methods import patch, patchable @@ -247,3 +247,45 @@ class DailyRewardClient: kwargs.pop("validate", None) return await self.request(url, method=method, params=params, headers=headers, **kwargs) + + +@patch(genshin.client.components.hoyolab.HoyolabClient) # noqa +class HoyolabClient: + @patchable + async def get_hoyolab_user( + self, hoyolab_id: int, *, lang: typing.Optional[str] = None + ) -> models.PartialHoyolabUser: + """Get a hoyolab user.""" + # todo: use routes.py instead of putting full urls in methods + if self.region == types.Region.OVERSEAS: + if hoyolab_id <= 0: + raise TypeError(f"{hoyolab_id} is not a valid hoyolab id.") + url = "https://bbs-api-os.hoyolab.com/community/painter/wapi/user/full" + data = await self.request_hoyolab(url, params=dict(uid=hoyolab_id), lang=lang) + return models.FullHoyolabUser(**data["user_info"]) + elif self.region == types.Region.CHINESE: + url = "https://bbs-api.mihoyo.com/user/wapi/getUserFullInfo" + account_id = self.cookie_manager.user_id + if account_id: + device_id = hex_digest(str(account_id)) + else: + account_mid_v2 = get_account_mid_v2(self.cookie_manager.cookies) + if account_mid_v2: + device_id = hex_digest(account_mid_v2) + else: + device_id = DEVICE_ID + _ds = generate_dynamic_secret("ulInCDohgEs557j0VsPDYnQaaz6KJcv5") + _ua = get_ua(device="Paimon Build " + device_id[0:5], version="2.36.1") + ua = get_ua(device="Paimon Build " + device_id[0:5], version="2.40.0") + headers = { + "User-Agent": ua, + "Referer": "https://bbs.mihoyo.com/", + "x-rpc-device_id": get_device_id(_ua), + "x-rpc-app_version": "2.40.0", + "x-rpc-client_type": "4", + "ds": _ds, + } + data = await self.request(url, method="GET", params=dict(gids=2), headers=headers) + return models.PartialHoyolabUser(**data["user_info"]) + else: + raise TypeError(f"{self.region!r} is not a valid region.")