diff --git a/plugins/genshin/sign.py b/plugins/genshin/sign.py index d465cac5..b4222b78 100644 --- a/plugins/genshin/sign.py +++ b/plugins/genshin/sign.py @@ -85,7 +85,7 @@ class Sign(Plugin, BasePlugin): "callback": f"geetest_{int(time.time() * 1000)}", }, headers=header, - timeout=20, + timeout=30, ) text = req.text logger.debug(f"ajax 返回:{text}") @@ -94,6 +94,7 @@ class Sign(Plugin, BasePlugin): text = re.findall(r"^.*?\((\{.*?)\)$", text)[0] data = json.loads(text) if "success" in data["status"] and "success" in data["data"]["result"]: + logger.info("签到 ajax 请求成功") return { "x-rpc-challenge": challenge, "x-rpc-validate": data["data"]["validate"], @@ -101,8 +102,10 @@ class Sign(Plugin, BasePlugin): } except JSONDecodeError: logger.warning("签到 ajax 请求 JSON 解析失败") - except TimeoutException: + except TimeoutException as exc: logger.warning("签到 ajax 请求超时") + if not config.pass_challenge_api: + raise exc except (KeyError, IndexError): logger.warning("签到 ajax 请求数据错误") except RuntimeError: @@ -123,28 +126,30 @@ class Sign(Plugin, BasePlugin): resp = await client.post( config.pass_challenge_api, params=pass_challenge_params, - timeout=45, + timeout=60, ) - logger.info(f"签到请求返回:{resp.text}") + logger.debug(f"签到 recognize 请求返回:{resp.text}") data = resp.json() status = data.get("status") if status is not None and status != 0: - logger.error(f"签到请求解析错误:{data.get('msg')}") + logger.error(f"签到 recognize 请求解析错误:{data.get('msg')}") if data.get("code", 0) != 0: raise RuntimeError + logger.info("签到 recognize 请求 解析成功") return { "x-rpc-challenge": data["data"]["challenge"], "x-rpc-validate": data["data"]["validate"], "x-rpc-seccode": f'{data["data"]["validate"]}|jordan', } except JSONDecodeError: - logger.warning("签到请求 JSON 解析失败") - except TimeoutException: - logger.warning("签到请求超时") + logger.warning("签到 recognize 请求 JSON 解析失败") + except TimeoutException as exc: + logger.warning("签到 recognize 请求超时") + raise exc except KeyError: - logger.warning("签到请求数据错误") + logger.warning("签到 recognize 请求数据错误") except RuntimeError: - logger.warning("签到请求失败") + logger.warning("签到 recognize 请求失败") return None @staticmethod @@ -183,6 +188,8 @@ class Sign(Plugin, BasePlugin): logger.warning(f"UID {client.uid} 签到失败,触发验证码风控") return f"UID {client.uid} 签到失败,触发验证码风控,请尝试重新签到。" logger.info(f"UID {client.uid} 签到成功") + except TimeoutException: + return "签到失败了呜呜呜 ~ 服务器连接超时 服务器熟啦 ~ " except AlreadyClaimed: logger.info(f"UID {client.uid} 已经签到") result = "今天旅行者已经签到过了~" diff --git a/plugins/jobs/sign.py b/plugins/jobs/sign.py index 8c24129f..e498a014 100644 --- a/plugins/jobs/sign.py +++ b/plugins/jobs/sign.py @@ -1,9 +1,11 @@ import asyncio import datetime +import secrets import time from aiohttp import ClientConnectorError from genshin import Game, GenshinException, AlreadyClaimed, InvalidCookies +from httpx import TimeoutException from telegram.constants import ParseMode from telegram.error import BadRequest, Forbidden from telegram.ext import CallbackContext @@ -32,6 +34,7 @@ class SignJob(Plugin): self.sign_service = sign_service self.cookies_service = cookies_service self.user_service = user_service + self.random = secrets.SystemRandom() @staticmethod async def single_sign(user_id: int) -> str: @@ -82,12 +85,19 @@ class SignJob(Plugin): @job.run_daily(time=datetime.time(hour=0, minute=1, second=0), name="SignJob") async def sign(self, context: CallbackContext): - logger.info("正在执行自动签到") + if context.job.name == "SignJob": + logger.info("正在执行自动签到") + if context.job.name == "SignAgainJob": + logger.info("正在执行自动重签") sign_list = await self.sign_service.get_all() for sign_db in sign_list: - if sign_db.status != SignStatusEnum.STATUS_SUCCESS: - continue user_id = sign_db.user_id + if sign_db.status != SignStatusEnum.STATUS_SUCCESS: + if sign_db.status == SignStatusEnum.TIMEOUT_ERROR: + if context.job.name == "SignAgainJob": + logger.info(f"用户 [{user_id}] 即将执行重签") + else: + continue try: text = await self.single_sign(user_id) except InvalidCookies: @@ -99,9 +109,13 @@ class SignJob(Plugin): except GenshinException as exc: text = f"自动签到执行失败,API返回信息为 {str(exc)}" sign_db.status = SignStatusEnum.GENSHIN_EXCEPTION - except ClientConnectorError: + except TimeoutException: text = "签到失败了呜呜呜 ~ 服务器连接超时 服务器熟啦 ~ " sign_db.status = SignStatusEnum.TIMEOUT_ERROR + except ClientConnectorError as exc: + logger.warning(f"aiohttp 请求错误 {repr(exc)}") + text = "签到失败了呜呜呜 ~ 链接服务器发生错误 服务器熟啦 ~ " + sign_db.status = SignStatusEnum.TIMEOUT_ERROR except NeedChallenge: text = "签到失败,触发验证码风控,自动签到自动关闭" sign_db.status = SignStatusEnum.NEED_CHALLENGE @@ -113,7 +127,7 @@ class SignJob(Plugin): text = f'NOTICE {sign_db.user_id}\n\n{text}' try: await context.bot.send_message(sign_db.chat_id, text, parse_mode=ParseMode.HTML) - await asyncio.sleep(5) # 回复延迟5S避免触发洪水防御 + await asyncio.sleep(10 + self.random.random() * 50) # 回复延迟 [10, 60) 避免触发洪水防御 except BadRequest as exc: logger.error(f"执行自动签到时发生错误 用户UID[{user_id}]") logger.exception(exc) @@ -129,3 +143,5 @@ class SignJob(Plugin): sign_db.time_updated = datetime.datetime.now() await self.sign_service.update(sign_db) logger.info("执行自动签到完成") + if context.job.name == "SignJob": + context.job_queue.run_once(self.sign, when=datetime.time(hour=0, minute=1, second=0), name="SignAgainJob")