2023-03-14 01:27:22 +00:00
|
|
|
from typing import Tuple, Optional
|
|
|
|
|
2023-07-18 09:29:31 +00:00
|
|
|
from simnet import Region
|
2023-07-20 04:08:07 +00:00
|
|
|
from simnet.client.cookies import Cookies
|
2023-07-18 09:29:31 +00:00
|
|
|
from simnet.errors import BadRequest as SIMNetBadRequest
|
2023-03-14 01:27:22 +00:00
|
|
|
|
2023-07-19 12:28:19 +00:00
|
|
|
from core.basemodel import RegionEnum
|
2023-03-14 01:27:22 +00:00
|
|
|
from core.dependence.redisdb import RedisDB
|
|
|
|
from core.plugin import Plugin
|
|
|
|
from core.services.cookies import CookiesService
|
2023-07-18 09:29:31 +00:00
|
|
|
from core.services.players import PlayersService
|
2023-03-14 01:27:22 +00:00
|
|
|
from modules.apihelper.client.components.verify import Verify
|
|
|
|
from modules.apihelper.error import ResponseException, APIHelperException
|
2023-07-18 09:29:31 +00:00
|
|
|
from plugins.tools.genshin import PlayerNotFoundError, CookiesNotFoundError, GenshinHelper
|
2023-03-14 01:27:22 +00:00
|
|
|
from utils.log import logger
|
|
|
|
|
|
|
|
__all__ = ("ChallengeSystemException", "ChallengeSystem")
|
|
|
|
|
|
|
|
|
|
|
|
class ChallengeSystemException(Exception):
|
|
|
|
def __init__(self, message: str):
|
|
|
|
self.message = message
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
|
|
|
|
class ChallengeSystem(Plugin):
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
cookies_service: CookiesService,
|
|
|
|
redis: RedisDB,
|
|
|
|
genshin_helper: GenshinHelper,
|
2023-07-18 09:29:31 +00:00
|
|
|
player: PlayersService,
|
2023-03-14 01:27:22 +00:00
|
|
|
) -> None:
|
|
|
|
self.cookies_service = cookies_service
|
|
|
|
self.genshin_helper = genshin_helper
|
|
|
|
self.cache = redis.client
|
|
|
|
self.qname = "plugin:challenge:"
|
2023-07-18 09:29:31 +00:00
|
|
|
self.players_service = player
|
2023-03-14 01:27:22 +00:00
|
|
|
|
|
|
|
async def get_challenge(self, uid: int) -> Tuple[Optional[str], Optional[str]]:
|
|
|
|
data = await self.cache.get(f"{self.qname}{uid}")
|
|
|
|
if not data:
|
|
|
|
return None, None
|
|
|
|
data = data.decode("utf-8").split("|")
|
|
|
|
return data[0], data[1]
|
|
|
|
|
|
|
|
async def set_challenge(self, uid: int, gt: str, challenge: str):
|
|
|
|
await self.cache.set(f"{self.qname}{uid}", f"{gt}|{challenge}")
|
|
|
|
await self.cache.expire(f"{self.qname}{uid}", 10 * 60)
|
|
|
|
|
|
|
|
async def create_challenge(
|
|
|
|
self, user_id: int, need_verify: bool = True, ajax: bool = False
|
|
|
|
) -> Tuple[Optional[int], Optional[str], Optional[str]]:
|
|
|
|
try:
|
|
|
|
client = await self.genshin_helper.get_genshin_client(user_id)
|
|
|
|
except PlayerNotFoundError:
|
|
|
|
raise ChallengeSystemException("用户未找到")
|
2023-03-15 08:03:44 +00:00
|
|
|
except CookiesNotFoundError:
|
|
|
|
raise ChallengeSystemException("无需验证")
|
2023-03-14 01:27:22 +00:00
|
|
|
if client.region != Region.CHINESE:
|
|
|
|
raise ChallengeSystemException("非法用户")
|
|
|
|
if need_verify:
|
|
|
|
try:
|
|
|
|
await client.get_genshin_notes()
|
2023-07-18 09:29:31 +00:00
|
|
|
except SIMNetBadRequest as exc:
|
2023-03-14 01:27:22 +00:00
|
|
|
if exc.retcode != 1034:
|
|
|
|
raise exc
|
2023-03-14 02:45:26 +00:00
|
|
|
else:
|
2023-03-15 08:03:44 +00:00
|
|
|
raise ChallengeSystemException("账户正常,无需验证")
|
2023-07-18 09:29:31 +00:00
|
|
|
finally:
|
|
|
|
await client.shutdown()
|
|
|
|
else:
|
|
|
|
await client.shutdown()
|
|
|
|
verify = Verify(cookies=client.cookies)
|
2023-03-14 01:27:22 +00:00
|
|
|
try:
|
|
|
|
data = await verify.create()
|
|
|
|
challenge = data["challenge"]
|
|
|
|
gt = data["gt"]
|
|
|
|
except ResponseException as exc:
|
|
|
|
logger.warning("用户 %s 创建验证失效 API返回 [%s]%s", user_id, exc.code, exc.message)
|
|
|
|
raise ChallengeSystemException(f"创建验证失败 错误信息为 [{exc.code}]{exc.message} 请稍后重试")
|
|
|
|
if ajax:
|
|
|
|
try:
|
|
|
|
validate = await verify.ajax(referer="https://webstatic.mihoyo.com/", gt=gt, challenge=challenge)
|
|
|
|
if validate:
|
|
|
|
await verify.verify(challenge, validate)
|
2023-07-18 09:29:31 +00:00
|
|
|
return client.player_id, "ajax", "ajax"
|
2023-03-14 01:27:22 +00:00
|
|
|
except APIHelperException as exc:
|
|
|
|
logger.warning("用户 %s ajax 验证失效 错误信息为 %s", user_id, str(exc))
|
2023-07-18 09:29:31 +00:00
|
|
|
await self.set_challenge(client.player_id, gt, challenge)
|
|
|
|
return client.player_id, gt, challenge
|
2023-03-14 01:27:22 +00:00
|
|
|
|
|
|
|
async def pass_challenge(self, user_id: int, validate: str, challenge: Optional[str] = None) -> bool:
|
2023-07-18 09:29:31 +00:00
|
|
|
player = await self.players_service.get_player(user_id)
|
|
|
|
if player is None:
|
2023-03-14 01:27:22 +00:00
|
|
|
raise ChallengeSystemException("用户未找到")
|
2023-07-19 12:28:19 +00:00
|
|
|
if player.region != RegionEnum.HYPERION:
|
2023-03-14 01:27:22 +00:00
|
|
|
raise ChallengeSystemException("非法用户")
|
2023-07-18 09:29:31 +00:00
|
|
|
cookie_model = await self.cookies_service.get(player.user_id, player.account_id, player.region)
|
|
|
|
if cookie_model is None:
|
|
|
|
raise ChallengeSystemException("无需验证")
|
2023-03-14 01:27:22 +00:00
|
|
|
if challenge is None:
|
2023-07-18 09:29:31 +00:00
|
|
|
_, challenge = await self.get_challenge(player.player_id)
|
2023-03-14 01:27:22 +00:00
|
|
|
if challenge is None:
|
|
|
|
raise ChallengeSystemException("验证失效 请求已经过期")
|
2023-07-20 04:08:07 +00:00
|
|
|
verify = Verify(cookies=Cookies(cookie_model.data))
|
2023-03-14 01:27:22 +00:00
|
|
|
try:
|
|
|
|
await verify.verify(challenge=challenge, validate=validate)
|
|
|
|
except ResponseException as exc:
|
|
|
|
logger.warning("用户 %s 验证失效 API返回 [%s]%s", user_id, exc.code, exc.message)
|
|
|
|
if "拼图已过期" in exc.message:
|
|
|
|
raise ChallengeSystemException("验证失败,拼图已过期,请稍后重试或更换使用环境进行验证")
|
|
|
|
raise ChallengeSystemException(f"验证失败,错误信息为 [{exc.code}]{exc.message},请稍后重试")
|
|
|
|
return True
|