mirror of
https://github.com/PaiGramTeam/MibooGram.git
synced 2024-11-22 07:08:04 +00:00
✨ support hoyolab verify
This commit is contained in:
parent
e634711648
commit
1f27aada4e
@ -4,58 +4,105 @@ import time
|
|||||||
from typing import Dict, Optional, Union
|
from typing import Dict, Optional, Union
|
||||||
|
|
||||||
from httpx import Cookies
|
from httpx import Cookies
|
||||||
|
from simnet import Region
|
||||||
|
from simnet.utils.ds import generate_dynamic_secret
|
||||||
|
|
||||||
from ..base.hyperionrequest import HyperionRequest
|
from ..base.hyperionrequest import HyperionRequest
|
||||||
from ...utility.devices import devices_methods
|
from ...utility.devices import devices_methods
|
||||||
from ...utility.helpers import get_ua, get_ds
|
from ...utility.helpers import get_ua
|
||||||
|
|
||||||
__all__ = ("Verify",)
|
__all__ = ("Verify",)
|
||||||
|
|
||||||
|
|
||||||
class Verify:
|
class Verify:
|
||||||
HOST = "api-takumi-record.mihoyo.com"
|
HOST = "api-takumi-record.mihoyo.com"
|
||||||
|
HOST_OVER = "sg-public-api.hoyolab.com"
|
||||||
VERIFICATION_HOST = "api.geetest.com"
|
VERIFICATION_HOST = "api.geetest.com"
|
||||||
CREATE_VERIFICATION_URL = "/game_record/app/card/wapi/createVerification"
|
CREATE_VERIFICATION_URL = "/game_record/app/card/wapi/createVerification"
|
||||||
VERIFY_VERIFICATION_URL = "/game_record/app/card/wapi/verifyVerification"
|
VERIFY_VERIFICATION_URL = "/game_record/app/card/wapi/verifyVerification"
|
||||||
REFERER_URL = "/game_record/app/genshin/api/dailyNote"
|
CREATE_VERIFICATION_URL1 = "/event/toolcomsrv/risk/createGeetest"
|
||||||
|
VERIFY_VERIFICATION_URL1 = "/event/toolcomsrv/risk/verifyGeetest"
|
||||||
|
REFERER_URL = "https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote"
|
||||||
|
REFERER_URL1 = "https://bbs-api-os.hoyolab.com/game_record/app/genshin/api/dailyNote"
|
||||||
|
APP_KEY = "hk4e_game_record"
|
||||||
GAME = "2"
|
GAME = "2"
|
||||||
AJAX_URL = "/ajax.php"
|
AJAX_URL = "/ajax.php"
|
||||||
|
|
||||||
USER_AGENT = get_ua()
|
def __init__(self, account_id: int = None, cookies: Union[Dict, Cookies] = None, region: Region = Region.CHINESE):
|
||||||
BBS_HEADERS = {
|
self.account_id = account_id
|
||||||
|
self.region = region
|
||||||
|
self.client = HyperionRequest(headers=self.get_bbs_headers(), cookies=cookies)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def create_url(self) -> str:
|
||||||
|
return (
|
||||||
|
self.get_url(self.HOST, self.CREATE_VERIFICATION_URL)
|
||||||
|
if self.miyoushe
|
||||||
|
else self.get_url(self.HOST_OVER, self.CREATE_VERIFICATION_URL1)
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def verify_url(self) -> str:
|
||||||
|
return (
|
||||||
|
self.get_url(self.HOST, self.VERIFY_VERIFICATION_URL)
|
||||||
|
if self.miyoushe
|
||||||
|
else self.get_url(self.HOST_OVER, self.VERIFY_VERIFICATION_URL1)
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def referer(self) -> str:
|
||||||
|
return self.REFERER_URL if self.miyoushe else self.REFERER_URL1
|
||||||
|
|
||||||
|
def get_ua(self, device: str = "Paimon Build"):
|
||||||
|
return (
|
||||||
|
f"Mozilla/5.0 (Linux; Android 12; {device}; wv) "
|
||||||
|
"AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.129 Mobile Safari/537.36 "
|
||||||
|
f"{'miHoYoBBS/' if self.miyoushe else 'miHoYoBBSOversea/2.55.0'}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def miyoushe(self) -> bool:
|
||||||
|
return self.region == Region.CHINESE
|
||||||
|
|
||||||
|
def get_bbs_headers(self) -> Dict[str, str]:
|
||||||
|
return {
|
||||||
"Accept": "application/json, text/plain, */*",
|
"Accept": "application/json, text/plain, */*",
|
||||||
"Accept-Encoding": "gzip, deflate",
|
"Accept-Encoding": "gzip, deflate",
|
||||||
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
|
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||||
"User-Agent": USER_AGENT,
|
"User-Agent": get_ua(),
|
||||||
"X-Requested-With": "com.mihoyo.hyperion",
|
"X-Requested-With": "com.mihoyo.hyperion" if self.miyoushe else "com.mihoyo.hoyolab",
|
||||||
"Referer": "https://webstatic.mihoyo.com/",
|
"Referer": "https://webstatic.mihoyo.com/" if self.miyoushe else "https://act.hoyolab.com/",
|
||||||
"x-rpc-page": "3.1.3_#/ys",
|
"x-rpc-page": "3.1.3_#/rpg",
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFICATION_HEADERS = {
|
|
||||||
"Accept": "*/*",
|
|
||||||
"X-Requested-With": "com.mihoyo.hyperion",
|
|
||||||
"User-Agent": USER_AGENT,
|
|
||||||
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, account_id: int = None, cookies: Union[Dict, Cookies] = None):
|
|
||||||
self.account_id = account_id
|
|
||||||
self.client = HyperionRequest(headers=self.BBS_HEADERS, cookies=cookies)
|
|
||||||
|
|
||||||
def get_verification_headers(self, referer: str):
|
def get_verification_headers(self, referer: str):
|
||||||
headers = self.VERIFICATION_HEADERS.copy()
|
headers = {
|
||||||
headers["Referer"] = referer
|
"Accept": "*/*",
|
||||||
|
"X-Requested-With": "com.mihoyo.hyperion" if self.miyoushe else "com.mihoyo.hoyolab",
|
||||||
|
"User-Agent": get_ua(),
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||||
|
"Referer": referer,
|
||||||
|
}
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
async def get_headers(self, data: dict = None, params: dict = None):
|
async def get_headers(self, data: dict = None, params: dict = None):
|
||||||
headers = self.BBS_HEADERS.copy()
|
headers = self.get_bbs_headers()
|
||||||
app_version, client_type, ds = get_ds(new_ds=True, data=data, params=params)
|
app_version, client_type, ds = generate_dynamic_secret(
|
||||||
|
region=self.region,
|
||||||
|
new_ds=self.miyoushe,
|
||||||
|
data=data,
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
headers["x-rpc-app_version"] = app_version
|
headers["x-rpc-app_version"] = app_version
|
||||||
headers["x-rpc-client_type"] = client_type
|
headers["x-rpc-client_type"] = client_type
|
||||||
headers["DS"] = ds
|
headers["DS"] = ds
|
||||||
headers["x-rpc-challenge_path"] = f"https://{self.HOST}{self.REFERER_URL}"
|
headers["x-rpc-challenge_path"] = self.referer
|
||||||
headers["x-rpc-challenge_game"] = self.GAME
|
headers["x-rpc-challenge_game"] = self.GAME
|
||||||
|
if not self.miyoushe:
|
||||||
|
headers["origin"] = "https://act.hoyolab.com"
|
||||||
|
headers["x-rpc-platform"] = "4"
|
||||||
|
headers["x-rpc-language"] = "zh-cn"
|
||||||
|
headers["x-rpc-challenge_trace"] = "undefined"
|
||||||
await devices_methods.update_device_headers(self.account_id, headers)
|
await devices_methods.update_device_headers(self.account_id, headers)
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
@ -64,15 +111,20 @@ class Verify:
|
|||||||
return f"https://{host}{url}"
|
return f"https://{host}{url}"
|
||||||
|
|
||||||
async def create(self, is_high: bool = False):
|
async def create(self, is_high: bool = False):
|
||||||
url = self.get_url(self.HOST, self.CREATE_VERIFICATION_URL)
|
url = self.create_url
|
||||||
params = {"is_high": "true" if is_high else "false"}
|
params = {"is_high": "true" if is_high else "false"}
|
||||||
|
if not self.miyoushe:
|
||||||
|
params["app_key"] = self.APP_KEY
|
||||||
|
|
||||||
headers = await self.get_headers(params=params)
|
headers = await self.get_headers(params=params)
|
||||||
response = await self.client.get(url, params=params, headers=headers)
|
response = await self.client.get(url, params=params, headers=headers)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def verify(self, challenge: str, validate: str):
|
async def verify(self, challenge: str, validate: str):
|
||||||
url = self.get_url(self.HOST, self.VERIFY_VERIFICATION_URL)
|
url = self.verify_url
|
||||||
data = {"geetest_challenge": challenge, "geetest_validate": validate, "geetest_seccode": f"{validate}|jordan"}
|
data = {"geetest_challenge": challenge, "geetest_validate": validate, "geetest_seccode": f"{validate}|jordan"}
|
||||||
|
if not self.miyoushe:
|
||||||
|
data["app_key"] = self.APP_KEY
|
||||||
|
|
||||||
headers = await self.get_headers(data=data)
|
headers = await self.get_headers(data=data)
|
||||||
response = await self.client.post(url, json=data, headers=headers)
|
response = await self.client.post(url, json=data, headers=headers)
|
||||||
|
@ -18,6 +18,7 @@ from core.services.players.services import PlayersService, PlayerInfoService
|
|||||||
from gram_core.services.devices import DevicesService
|
from gram_core.services.devices import DevicesService
|
||||||
from gram_core.services.devices.models import DevicesDataBase as Devices
|
from gram_core.services.devices.models import DevicesDataBase as Devices
|
||||||
from modules.apihelper.models.genshin.cookies import CookiesModel
|
from modules.apihelper.models.genshin.cookies import CookiesModel
|
||||||
|
from modules.apihelper.utility.devices import devices_methods
|
||||||
from utils.log import logger
|
from utils.log import logger
|
||||||
|
|
||||||
__all__ = ("AccountCookiesPlugin",)
|
__all__ = ("AccountCookiesPlugin",)
|
||||||
@ -66,6 +67,7 @@ class AccountCookiesPlugin(Plugin.Conversation):
|
|||||||
self.players_service = players_service
|
self.players_service = players_service
|
||||||
self.player_info_service = player_info_service
|
self.player_info_service = player_info_service
|
||||||
self.devices_service = devices_service
|
self.devices_service = devices_service
|
||||||
|
devices_methods.service = devices_service
|
||||||
|
|
||||||
# noinspection SpellCheckingInspection
|
# noinspection SpellCheckingInspection
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -39,6 +39,7 @@ class WebApp(Plugin):
|
|||||||
@handler.message(filters=filters.StatusUpdate.WEB_APP_DATA, block=False)
|
@handler.message(filters=filters.StatusUpdate.WEB_APP_DATA, block=False)
|
||||||
async def app(self, update: Update, _: CallbackContext):
|
async def app(self, update: Update, _: CallbackContext):
|
||||||
user = update.effective_user
|
user = update.effective_user
|
||||||
|
user_id = user.id
|
||||||
message = update.effective_message
|
message = update.effective_message
|
||||||
web_app_data = message.web_app_data
|
web_app_data = message.web_app_data
|
||||||
if web_app_data:
|
if web_app_data:
|
||||||
@ -50,9 +51,13 @@ class WebApp(Plugin):
|
|||||||
if result.code == 0:
|
if result.code == 0:
|
||||||
if result.path == "verify":
|
if result.path == "verify":
|
||||||
validate = result.data.get("geetest_validate")
|
validate = result.data.get("geetest_validate")
|
||||||
|
try:
|
||||||
|
user_id = int(result.data.get("user_id", user_id))
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
if validate is not None:
|
if validate is not None:
|
||||||
try:
|
try:
|
||||||
status = await self.challenge_system.pass_challenge(user.id, validate=validate)
|
status = await self.challenge_system.pass_challenge(user_id, validate=validate)
|
||||||
except ChallengeSystemException as exc:
|
except ChallengeSystemException as exc:
|
||||||
await message.reply_text(exc.message, reply_markup=ReplyKeyboardRemove())
|
await message.reply_text(exc.message, reply_markup=ReplyKeyboardRemove())
|
||||||
return
|
return
|
||||||
|
@ -19,17 +19,24 @@ class VerificationPlugins(Plugin):
|
|||||||
async def verify(self, update: Update, context: CallbackContext) -> None:
|
async def verify(self, update: Update, context: CallbackContext) -> None:
|
||||||
user = update.effective_user
|
user = update.effective_user
|
||||||
message = update.effective_message
|
message = update.effective_message
|
||||||
logger.info("用户 %s[%s] 发出verify命令", user.full_name, user.id)
|
args = self.get_args(context)
|
||||||
|
user_id = user.id
|
||||||
|
if args:
|
||||||
|
try:
|
||||||
|
user_id = int(args[0])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
logger.info("用户 %s[%s] 发出verify命令 user_id[%s]", user.full_name, user.id, user_id)
|
||||||
try:
|
try:
|
||||||
uid, gt, challenge = await self.challenge_system.create_challenge(
|
uid, gt, challenge = await self.challenge_system.create_challenge(
|
||||||
user.id, context.args is not None and len(context.args) < 1
|
user_id, context.args is not None and len(context.args) < 1
|
||||||
)
|
)
|
||||||
except ChallengeSystemException as exc:
|
except ChallengeSystemException as exc:
|
||||||
await message.reply_text(exc.message)
|
await message.reply_text(exc.message)
|
||||||
return
|
return
|
||||||
url = (
|
url = (
|
||||||
f"{config.pass_challenge_user_web}/webapp?"
|
f"{config.pass_challenge_user_web}/webapp?"
|
||||||
f"gt={gt}&username={context.bot.username}&command=verify&challenge={challenge}&uid={uid}"
|
f"gt={gt}&username={context.bot.username}&command=verify&challenge={challenge}&uid={uid}&user_id={user_id}"
|
||||||
)
|
)
|
||||||
await message.reply_text(
|
await message.reply_text(
|
||||||
"请尽快在10秒内完成手动验证\n或发送 /web_cancel 取消操作",
|
"请尽快在10秒内完成手动验证\n或发送 /web_cancel 取消操作",
|
||||||
|
@ -57,8 +57,6 @@ class ChallengeSystem(Plugin):
|
|||||||
raise ChallengeSystemException("用户未找到")
|
raise ChallengeSystemException("用户未找到")
|
||||||
except CookiesNotFoundError:
|
except CookiesNotFoundError:
|
||||||
raise ChallengeSystemException("无需验证")
|
raise ChallengeSystemException("无需验证")
|
||||||
if client.region != Region.CHINESE:
|
|
||||||
raise ChallengeSystemException("非法用户")
|
|
||||||
if need_verify:
|
if need_verify:
|
||||||
try:
|
try:
|
||||||
await client.get_genshin_notes()
|
await client.get_genshin_notes()
|
||||||
@ -70,7 +68,7 @@ class ChallengeSystem(Plugin):
|
|||||||
await client.shutdown()
|
await client.shutdown()
|
||||||
else:
|
else:
|
||||||
await client.shutdown()
|
await client.shutdown()
|
||||||
verify = Verify(cookies=client.cookies)
|
verify = Verify(client.account_id, cookies=client.cookies, region=client.region)
|
||||||
try:
|
try:
|
||||||
data = await verify.create()
|
data = await verify.create()
|
||||||
challenge = data["challenge"]
|
challenge = data["challenge"]
|
||||||
@ -95,8 +93,9 @@ class ChallengeSystem(Plugin):
|
|||||||
player = await self.players_service.get_player(user_id)
|
player = await self.players_service.get_player(user_id)
|
||||||
if player is None:
|
if player is None:
|
||||||
raise ChallengeSystemException("用户未找到")
|
raise ChallengeSystemException("用户未找到")
|
||||||
if player.region != RegionEnum.HYPERION:
|
region = Region.CHINESE
|
||||||
raise ChallengeSystemException("非法用户")
|
if player.region == RegionEnum.HOYOLAB:
|
||||||
|
region = Region.OVERSEAS
|
||||||
cookie_model = await self.cookies_service.get(player.user_id, player.account_id, player.region)
|
cookie_model = await self.cookies_service.get(player.user_id, player.account_id, player.region)
|
||||||
if cookie_model is None:
|
if cookie_model is None:
|
||||||
raise ChallengeSystemException("无需验证")
|
raise ChallengeSystemException("无需验证")
|
||||||
@ -104,7 +103,7 @@ class ChallengeSystem(Plugin):
|
|||||||
_, challenge = await self.get_challenge(player.player_id)
|
_, challenge = await self.get_challenge(player.player_id)
|
||||||
if challenge is None:
|
if challenge is None:
|
||||||
raise ChallengeSystemException("验证失效 请求已经过期")
|
raise ChallengeSystemException("验证失效 请求已经过期")
|
||||||
verify = Verify(cookies=Cookies(cookie_model.data))
|
verify = Verify(player.account_id, cookies=Cookies(cookie_model.data), region=region)
|
||||||
try:
|
try:
|
||||||
await verify.verify(challenge=challenge, validate=validate)
|
await verify.verify(challenge=challenge, validate=validate)
|
||||||
except ResponseException as exc:
|
except ResponseException as exc:
|
||||||
|
Loading…
Reference in New Issue
Block a user