2022-08-04 13:19:17 +00:00
|
|
|
|
from typing import List
|
|
|
|
|
|
|
|
|
|
import genshin
|
2022-11-14 15:26:37 +00:00
|
|
|
|
from genshin import GenshinException, InvalidCookies, TooManyRequests, types, Game
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
from utils.log import logger
|
|
|
|
|
from utils.models.base import RegionEnum
|
2022-08-04 13:19:17 +00:00
|
|
|
|
from .cache import PublicCookiesCache
|
2022-09-08 01:08:37 +00:00
|
|
|
|
from .error import TooManyRequestPublicCookies, CookieServiceError
|
2022-08-04 13:19:17 +00:00
|
|
|
|
from .models import CookiesStatusEnum
|
2022-09-08 01:08:37 +00:00
|
|
|
|
from .repositories import CookiesNotFoundError, CookiesRepository
|
2022-07-26 10:07:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CookiesService:
|
2022-08-04 13:18:23 +00:00
|
|
|
|
def __init__(self, cookies_repository: CookiesRepository) -> None:
|
|
|
|
|
self._repository: CookiesRepository = cookies_repository
|
2022-07-26 10:07:31 +00:00
|
|
|
|
|
2022-08-05 12:11:46 +00:00
|
|
|
|
async def update_cookies(self, user_id: int, cookies: dict, region: RegionEnum):
|
2022-08-04 13:18:23 +00:00
|
|
|
|
await self._repository.update_cookies(user_id, cookies, region)
|
2022-07-26 10:07:31 +00:00
|
|
|
|
|
2022-08-05 12:11:46 +00:00
|
|
|
|
async def add_cookies(self, user_id: int, cookies: dict, region: RegionEnum):
|
2022-08-04 13:18:23 +00:00
|
|
|
|
await self._repository.add_cookies(user_id, cookies, region)
|
|
|
|
|
|
|
|
|
|
async def get_cookies(self, user_id: int, region: RegionEnum):
|
|
|
|
|
return await self._repository.get_cookies(user_id, region)
|
2022-07-26 10:07:31 +00:00
|
|
|
|
|
2022-11-30 03:25:19 +00:00
|
|
|
|
async def del_cookies(self, user_id: int, region: RegionEnum):
|
|
|
|
|
return await self._repository.del_cookies(user_id, region)
|
|
|
|
|
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
|
|
|
|
class PublicCookiesService:
|
|
|
|
|
def __init__(self, cookies_repository: CookiesRepository, public_cookies_cache: PublicCookiesCache):
|
|
|
|
|
self._cache = public_cookies_cache
|
|
|
|
|
self._repository: CookiesRepository = cookies_repository
|
|
|
|
|
self.count: int = 0
|
2022-09-08 01:08:37 +00:00
|
|
|
|
self.user_times_limiter = 3 * 3
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
|
|
|
|
async def refresh(self):
|
|
|
|
|
"""刷新公共Cookies 定时任务
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
user_list: List[int] = []
|
|
|
|
|
cookies_list = await self._repository.get_all_cookies(RegionEnum.HYPERION) # 从数据库获取2
|
|
|
|
|
for cookies in cookies_list:
|
2022-12-14 15:57:37 +00:00
|
|
|
|
if cookies.status is None or cookies.status == CookiesStatusEnum.STATUS_SUCCESS:
|
|
|
|
|
user_list.append(cookies.user_id)
|
|
|
|
|
if len(user_list) > 0:
|
|
|
|
|
add, count = await self._cache.add_public_cookies(user_list, RegionEnum.HYPERION)
|
|
|
|
|
logger.info(f"国服公共Cookies池已经添加[{add}]个 当前成员数为[{count}]")
|
2022-08-04 13:19:17 +00:00
|
|
|
|
user_list.clear()
|
|
|
|
|
cookies_list = await self._repository.get_all_cookies(RegionEnum.HOYOLAB)
|
|
|
|
|
for cookies in cookies_list:
|
2022-12-14 15:57:37 +00:00
|
|
|
|
if cookies.status is None or cookies.status == CookiesStatusEnum.STATUS_SUCCESS:
|
2022-12-10 12:18:05 +00:00
|
|
|
|
user_list.append(cookies.user_id)
|
2022-12-14 15:57:37 +00:00
|
|
|
|
if len(user_list) > 0:
|
|
|
|
|
add, count = await self._cache.add_public_cookies(user_list, RegionEnum.HOYOLAB)
|
|
|
|
|
logger.info(f"国际服公共Cookies池已经添加[{add}]个 当前成员数为[{count}]")
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
|
|
|
|
async def get_cookies(self, user_id: int, region: RegionEnum = RegionEnum.NULL):
|
|
|
|
|
"""获取公共Cookies
|
|
|
|
|
:param user_id: 用户ID
|
|
|
|
|
:param region: 注册的服务器
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2022-09-08 01:08:37 +00:00
|
|
|
|
user_times = await self._cache.incr_by_user_times(user_id)
|
|
|
|
|
if int(user_times) > self.user_times_limiter:
|
2022-10-09 05:45:50 +00:00
|
|
|
|
logger.warning(f"用户 [{user_id}] 使用公共Cookie次数已经到达上限")
|
2022-10-09 02:43:28 +00:00
|
|
|
|
raise TooManyRequestPublicCookies(user_id)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
while True:
|
2022-09-08 01:08:37 +00:00
|
|
|
|
public_id, count = await self._cache.get_public_cookies(region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
try:
|
|
|
|
|
cookies = await self._repository.get_cookies(public_id, region)
|
|
|
|
|
except CookiesNotFoundError:
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await self._cache.delete_public_cookies(public_id, region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
continue
|
|
|
|
|
if region == RegionEnum.HYPERION:
|
|
|
|
|
client = genshin.Client(cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.CHINESE)
|
|
|
|
|
elif region == RegionEnum.HOYOLAB:
|
2022-10-09 02:43:28 +00:00
|
|
|
|
client = genshin.Client(
|
|
|
|
|
cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.OVERSEAS, lang="zh-cn"
|
|
|
|
|
)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
else:
|
2022-09-08 01:08:37 +00:00
|
|
|
|
raise CookieServiceError
|
2022-08-04 13:19:17 +00:00
|
|
|
|
try:
|
2023-01-14 14:45:06 +00:00
|
|
|
|
record_card = (await client.get_record_cards())[0]
|
2022-11-14 15:26:37 +00:00
|
|
|
|
if record_card.game == Game.GENSHIN and region == RegionEnum.HYPERION:
|
|
|
|
|
await client.get_partial_genshin_user(record_card.uid)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
except InvalidCookies as exc:
|
2022-11-14 15:26:37 +00:00
|
|
|
|
if exc.retcode in (10001, -100):
|
|
|
|
|
logger.warning("用户 [%s] Cookies无效", public_id)
|
|
|
|
|
elif exc.retcode == 10103:
|
|
|
|
|
logger.warning("用户 [%s] Cookie有效,但没有绑定到游戏帐户", public_id)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
else:
|
2022-11-14 15:26:37 +00:00
|
|
|
|
logger.warning("Cookies无效 ")
|
2022-09-08 01:08:37 +00:00
|
|
|
|
logger.exception(exc)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
cookies.status = CookiesStatusEnum.INVALID_COOKIES
|
|
|
|
|
await self._repository.update_cookies_ex(cookies, region)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await self._cache.delete_public_cookies(cookies.user_id, region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
continue
|
2022-09-08 01:08:37 +00:00
|
|
|
|
except TooManyRequests:
|
2022-11-14 15:26:37 +00:00
|
|
|
|
logger.warning("用户 [%s] 查询次数太多或操作频繁", public_id)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
cookies.status = CookiesStatusEnum.TOO_MANY_REQUESTS
|
|
|
|
|
await self._repository.update_cookies_ex(cookies, region)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await self._cache.delete_public_cookies(cookies.user_id, region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
continue
|
|
|
|
|
except GenshinException as exc:
|
2022-11-14 15:26:37 +00:00
|
|
|
|
if exc.retcode == 1034:
|
|
|
|
|
logger.warning("用户 [%s] 触发验证", public_id)
|
|
|
|
|
else:
|
|
|
|
|
logger.warning("用户 [%s] 获取账号信息发生错误,错误信息为", public_id)
|
|
|
|
|
logger.exception(exc)
|
|
|
|
|
await self._cache.delete_public_cookies(cookies.user_id, region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
continue
|
2022-11-14 15:26:37 +00:00
|
|
|
|
except Exception as exc:
|
|
|
|
|
await self._cache.delete_public_cookies(cookies.user_id, region)
|
|
|
|
|
raise exc
|
|
|
|
|
logger.info("用户 user_id[%s] 请求用户 user_id[%s] 的公共Cookies 该Cookie使用次数为%s次 ", user_id, public_id, count)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
return cookies
|