diff --git a/modules/gacha_log/log.py b/modules/gacha_log/log.py index 8ea705fd..f682fda5 100644 --- a/modules/gacha_log/log.py +++ b/modules/gacha_log/log.py @@ -9,9 +9,10 @@ from typing import Dict, IO, List, Optional, Tuple, Union, TYPE_CHECKING import aiofiles from openpyxl import load_workbook -from simnet import GenshinClient +from simnet import GenshinClient, Region from simnet.errors import AuthkeyTimeout, InvalidAuthkey from simnet.models.genshin.wish import BannerType +from simnet.utils.player import recognize_genshin_server from metadata.pool.pool import get_pool_by_id from metadata.shortname import roleToId, weaponToId @@ -222,19 +223,26 @@ class GachaLog: except Exception as exc: raise GachaLogException from exc - async def get_gacha_log_data(self, user_id: int, client: GenshinClient, authkey: str) -> int: + @staticmethod + def get_game_client(player_id: int) -> GenshinClient: + if recognize_genshin_server(player_id) in ["cn_gf01", "cn_qd01"]: + return GenshinClient(player_id=player_id, region=Region.CHINESE, lang="zh-cn") + return GenshinClient(player_id=player_id, region=Region.OVERSEAS, lang="zh-cn") + + async def get_gacha_log_data(self, user_id: int, player_id: int, authkey: str) -> int: """使用authkey获取抽卡记录数据,并合并旧数据 :param user_id: 用户id - :param client: GenshinClient + :param player_id: 玩家id :param authkey: authkey :return: 更新结果 """ new_num = 0 - gacha_log, _ = await self.load_history_info(str(user_id), str(client.player_id)) + gacha_log, _ = await self.load_history_info(str(user_id), str(player_id)) if gacha_log.get_import_type == ImportType.PAIMONMOE: raise GachaLogMixedProvider # 将唯一 id 放入临时数据中,加快查找速度 temp_id_data = {pool_name: [i.id for i in pool_data] for pool_name, pool_data in gacha_log.item_list.items()} + client = self.get_game_client(player_id) try: for pool_id, pool_name in GACHA_TYPE_LIST.items(): wish_history = await client.wish_history(pool_id.value, authkey=authkey) @@ -263,11 +271,13 @@ class GachaLog: raise GachaLogAuthkeyTimeout from exc except InvalidAuthkey as exc: raise GachaLogInvalidAuthkey from exc + finally: + await client.shutdown() for i in gacha_log.item_list.values(): i.sort(key=lambda x: (x.time, x.id)) gacha_log.update_time = datetime.datetime.now() gacha_log.import_type = ImportType.UIGF.value - await self.save_gacha_log_info(str(user_id), str(client.player_id), gacha_log) + await self.save_gacha_log_info(str(user_id), str(player_id), gacha_log) return new_num @staticmethod diff --git a/modules/pay_log/log.py b/modules/pay_log/log.py index 335b55fa..108d9af0 100644 --- a/modules/pay_log/log.py +++ b/modules/pay_log/log.py @@ -3,9 +3,10 @@ from pathlib import Path from typing import Tuple, Optional, List, Dict import aiofiles -from simnet import GenshinClient +from simnet import GenshinClient, Region from simnet.errors import AuthkeyTimeout, InvalidAuthkey from simnet.models.genshin.transaction import TransactionKind, BaseTransaction +from simnet.utils.player import recognize_genshin_server from modules.pay_log.error import PayLogAuthkeyTimeout, PayLogInvalidAuthkey, PayLogNotFound from modules.pay_log.models import PayLog as PayLogModel, BaseInfo @@ -111,21 +112,28 @@ class PayLog: # 写入数据 await self.save_json(save_path, info) + @staticmethod + def get_game_client(player_id: int) -> GenshinClient: + if recognize_genshin_server(player_id) in ["cn_gf01", "cn_qd01"]: + return GenshinClient(player_id=player_id, region=Region.CHINESE, lang="zh-cn") + return GenshinClient(player_id=player_id, region=Region.OVERSEAS, lang="zh-cn") + async def get_log_data( self, user_id: int, - client: GenshinClient, + player_id: int, authkey: str, ) -> int: """使用 authkey 获取历史记录数据,并合并旧数据 :param user_id: 用户id - :param client: GenshinClient + :param player_id: 游戏id :param authkey: authkey :return: 更新结果 """ new_num = 0 - pay_log, have_old = await self.load_history_info(str(user_id), str(client.player_id)) + pay_log, have_old = await self.load_history_info(str(user_id), str(player_id)) history_ids = [i.id for i in pay_log.list] + client = self.get_game_client(player_id) try: transaction_log = await client.transaction_log(authkey=authkey, kind=TransactionKind.CRYSTAL.value) for data in transaction_log: @@ -136,6 +144,8 @@ class PayLog: raise PayLogAuthkeyTimeout from exc except InvalidAuthkey as exc: raise PayLogInvalidAuthkey from exc + finally: + await client.shutdown() if new_num > 0 or have_old: pay_log.list.sort(key=lambda x: (x.time, x.id), reverse=True) pay_log.info.update_now() diff --git a/plugins/genshin/pay_log.py b/plugins/genshin/pay_log.py index 0bfaac97..2d3569e3 100644 --- a/plugins/genshin/pay_log.py +++ b/plugins/genshin/pay_log.py @@ -13,7 +13,6 @@ from core.services.template.services import TemplateService from modules.gacha_log.helpers import from_url_get_authkey from modules.pay_log.error import PayLogNotFound, PayLogAccountNotFound, PayLogInvalidAuthkey, PayLogAuthkeyTimeout from modules.pay_log.log import PayLog -from plugins.tools.genshin import GenshinHelper from plugins.tools.player_info import PlayerInfoSystem from utils.log import logger @@ -33,14 +32,20 @@ class PayLogPlugin(Plugin.Conversation): players_service: PlayersService, cookie_service: CookiesService, player_info: PlayerInfoSystem, - genshin_helper: GenshinHelper, ): self.template_service = template_service self.players_service = players_service self.cookie_service = cookie_service self.pay_log = PayLog() self.player_info = player_info - self.genshin_helper = genshin_helper + + async def get_player_id(self, uid: int) -> int: + """获取绑定的游戏ID""" + logger.debug("尝试获取已绑定的原神账号") + player = await self.players_service.get_player(uid) + if player is None: + raise PlayerNotFoundError(uid) + return player.player_id async def _refresh_user_data(self, user: User, authkey: str = None) -> str: """刷新用户数据 @@ -49,9 +54,8 @@ class PayLogPlugin(Plugin.Conversation): :return: 返回信息 """ try: - logger.debug("尝试获取已绑定的原神账号") - client = await self.genshin_helper.get_genshin_client(user.id) - new_num = await self.pay_log.get_log_data(user.id, client, authkey) + player_id = await self.get_player_id(user.id) + new_num = await self.pay_log.get_log_data(user.id, player_id, authkey) return "更新完成,本次没有新增数据" if new_num == 0 else f"更新完成,本次共新增{new_num}条充值记录" except PayLogNotFound: return "派蒙没有找到你的充值记录,快去充值吧~" @@ -192,11 +196,9 @@ class PayLogPlugin(Plugin.Conversation): user = update.effective_user logger.info("用户 %s[%s] 导出充值记录命令请求", user.full_name, user.id) try: - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError await message.reply_chat_action(ChatAction.TYPING) - path = self.pay_log.get_file_path(str(user.id), str(player_info.player_id)) + player_id = await self.get_player_id(user.id) + path = self.pay_log.get_file_path(str(user.id), str(player_id)) if not path.exists(): raise PayLogNotFound await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT) @@ -219,13 +221,11 @@ class PayLogPlugin(Plugin.Conversation): user = update.effective_user logger.info("用户 %s[%s] 充值记录统计命令请求", user.full_name, user.id) try: - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError await message.reply_chat_action(ChatAction.TYPING) - data = await self.pay_log.get_analysis(user.id, player_info.player_id) + player_id = await self.get_player_id(user.id) + data = await self.pay_log.get_analysis(user.id, player_id) await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) - name_card = await self.player_info.get_name_card(player_info.player_id, user) + name_card = await self.player_info.get_name_card(player_id, user) data["name_card"] = name_card png_data = await self.template_service.render( "genshin/pay_log/pay_log.jinja2", data, full_page=True, query_selector=".container" diff --git a/plugins/genshin/wish_log.py b/plugins/genshin/wish_log.py index aa343e1f..56050d81 100644 --- a/plugins/genshin/wish_log.py +++ b/plugins/genshin/wish_log.py @@ -28,7 +28,6 @@ from modules.gacha_log.error import ( ) from modules.gacha_log.helpers import from_url_get_authkey from modules.gacha_log.log import GachaLog -from plugins.tools.genshin import GenshinHelper from plugins.tools.player_info import PlayerInfoSystem from utils.log import logger @@ -55,7 +54,6 @@ class WishLogPlugin(Plugin.Conversation): assets: AssetsService, cookie_service: CookiesService, player_info: PlayerInfoSystem, - genshin_helper: GenshinHelper, ): self.template_service = template_service self.players_service = players_service @@ -64,13 +62,20 @@ class WishLogPlugin(Plugin.Conversation): self.zh_dict = None self.gacha_log = GachaLog() self.player_info = player_info - self.genshin_helper = genshin_helper async def initialize(self) -> None: await update_paimon_moe_zh(False) async with async_open(GACHA_LOG_PAIMON_MOE_PATH, "r", encoding="utf-8") as load_f: self.zh_dict = jsonlib.loads(await load_f.read()) + async def get_player_id(self, uid: int) -> int: + """获取绑定的游戏ID""" + logger.debug("尝试获取已绑定的原神账号") + player = await self.players_service.get_player(uid) + if player is None: + raise PlayerNotFoundError(uid) + return player.player_id + async def _refresh_user_data( self, user: User, data: dict = None, authkey: str = None, verify_uid: bool = True ) -> str: @@ -82,12 +87,12 @@ class WishLogPlugin(Plugin.Conversation): """ try: logger.debug("尝试获取已绑定的原神账号") - client = await self.genshin_helper.get_genshin_client(user.id) + player_id = await self.get_player_id(user.id) if authkey: - new_num = await self.gacha_log.get_gacha_log_data(user.id, client, authkey) + new_num = await self.gacha_log.get_gacha_log_data(user.id, player_id, authkey) return "更新完成,本次没有新增数据" if new_num == 0 else f"更新完成,本次共新增{new_num}条抽卡记录" if data: - new_num = await self.gacha_log.import_gacha_log_data(user.id, client.player_id, data, verify_uid) + new_num = await self.gacha_log.import_gacha_log_data(user.id, player_id, data, verify_uid) return "更新完成,本次没有新增数据" if new_num == 0 else f"更新完成,本次共新增{new_num}条抽卡记录" except GachaLogNotFound: return "派蒙没有找到你的抽卡记录,快来私聊派蒙导入吧~" @@ -227,15 +232,13 @@ class WishLogPlugin(Plugin.Conversation): user = update.effective_user logger.info("用户 %s[%s] 删除抽卡记录命令请求", user.full_name, user.id) try: - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError - context.chat_data["uid"] = player_info.player_id + player_id = await self.get_player_id(user.id) + context.chat_data["uid"] = player_id except PlayerNotFoundError: logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id) await message.reply_text("未查询到您所绑定的账号信息,请先绑定账号") return ConversationHandler.END - _, status = await self.gacha_log.load_history_info(str(user.id), str(player_info.player_id), only_status=True) + _, status = await self.gacha_log.load_history_info(str(user.id), str(player_id), only_status=True) if not status: await message.reply_text("你还没有导入抽卡记录哦~") return ConversationHandler.END @@ -258,6 +261,7 @@ class WishLogPlugin(Plugin.Conversation): async def command_gacha_log_force_delete(self, update: Update, context: CallbackContext): message = update.effective_message user = update.effective_user + logger.info("用户 %s[%s] 强制删除抽卡记录命令请求", user.full_name, user.id) args = self.get_args(context) if not args: await message.reply_text("请指定用户ID") @@ -266,14 +270,12 @@ class WishLogPlugin(Plugin.Conversation): cid = int(args[0]) if cid < 0: raise ValueError("Invalid cid") - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError - _, status = await self.gacha_log.load_history_info(str(cid), str(player_info.player_id), only_status=True) + player_id = await self.get_player_id(cid) + _, status = await self.gacha_log.load_history_info(str(cid), str(player_id), only_status=True) if not status: await message.reply_text("该用户还没有导入抽卡记录") return - status = await self.gacha_log.remove_history_info(str(cid), str(player_info.player_id)) + status = await self.gacha_log.remove_history_info(str(cid), str(player_id)) await message.reply_text("抽卡记录已强制删除" if status else "抽卡记录删除失败") except GachaLogNotFound: await message.reply_text("该用户还没有导入抽卡记录") @@ -289,11 +291,9 @@ class WishLogPlugin(Plugin.Conversation): user = update.effective_user logger.info("用户 %s[%s] 导出抽卡记录命令请求", user.full_name, user.id) try: - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError + player_id = await self.get_player_id(user.id) await message.reply_chat_action(ChatAction.TYPING) - path = await self.gacha_log.gacha_log_to_uigf(str(user.id), str(player_info.player_id)) + path = await self.gacha_log.gacha_log_to_uigf(str(user.id), str(player_id)) await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT) await message.reply_document(document=open(path, "rb+"), caption="抽卡记录导出文件 - UIGF V2.2") except GachaLogNotFound: @@ -323,18 +323,16 @@ class WishLogPlugin(Plugin.Conversation): pool_type = BannerType.STANDARD logger.info("用户 %s[%s] 抽卡记录命令请求 || 参数 %s", user.full_name, user.id, pool_type.name) try: - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError + player_id = await self.get_player_id(user.id) await message.reply_chat_action(ChatAction.TYPING) - data = await self.gacha_log.get_analysis(user.id, player_info.player_id, pool_type, self.assets_service) + data = await self.gacha_log.get_analysis(user.id, player_id, pool_type, self.assets_service) if isinstance(data, str): reply_message = await message.reply_text(data) if filters.ChatType.GROUPS.filter(message): self.add_delete_message_job(reply_message, delay=300) self.add_delete_message_job(message, delay=300) else: - name_card = await self.player_info.get_name_card(player_info.player_id, user) + name_card = await self.player_info.get_name_card(player_id, user) await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) data["name_card"] = name_card png_data = await self.template_service.render( @@ -382,24 +380,20 @@ class WishLogPlugin(Plugin.Conversation): all_five = True logger.info("用户 %s[%s] 抽卡统计命令请求 || 参数 %s || 仅五星 %s", user.full_name, user.id, pool_type.name, all_five) try: - player_info = await self.players_service.get_player(user.id) - if player_info is None: - raise PlayerNotFoundError + player_id = await self.get_player_id(user.id) group = filters.ChatType.GROUPS.filter(message) await message.reply_chat_action(ChatAction.TYPING) if all_five: - data = await self.gacha_log.get_all_five_analysis(user.id, player_info.player_id, self.assets_service) + data = await self.gacha_log.get_all_five_analysis(user.id, player_id, self.assets_service) else: - data = await self.gacha_log.get_pool_analysis( - user.id, player_info.player_id, pool_type, self.assets_service, group - ) + data = await self.gacha_log.get_pool_analysis(user.id, player_id, pool_type, self.assets_service, group) if isinstance(data, str): reply_message = await message.reply_text(data) if filters.ChatType.GROUPS.filter(message): self.add_delete_message_job(reply_message) self.add_delete_message_job(message) else: - name_card = await self.player_info.get_name_card(player_info.player_id, user) + name_card = await self.player_info.get_name_card(player_id, user) document = False if data["hasMore"] and not group: document = True