From 47e6b7f750bfb44d75597d0e4a320184ffa9564b Mon Sep 17 00:00:00 2001 From: omg-xtao <100690902+omg-xtao@users.noreply.github.com> Date: Wed, 12 Jun 2024 19:59:16 +0800 Subject: [PATCH] :sparkles: Support run command specifying uid --- gram_core | 2 +- plugins/genshin/abyss.py | 19 ++++++----- plugins/genshin/abyss_team.py | 3 +- plugins/genshin/akasha.py | 7 ++-- plugins/genshin/avatar_list.py | 3 +- plugins/genshin/daily/material.py | 9 +++-- plugins/genshin/daily_note.py | 3 +- plugins/genshin/gcsim/plugin.py | 18 ++++++---- plugins/genshin/ledger.py | 14 ++++---- plugins/genshin/player_cards.py | 23 +++++++------ plugins/genshin/redeem/redeem.py | 5 +-- plugins/genshin/redeem/runner.py | 4 ++- plugins/genshin/reg_time.py | 3 +- plugins/genshin/stats.py | 11 +++--- plugins/genshin/wish_log.py | 56 ++++++++++++++++++------------- plugins/tools/genshin.py | 24 +++++++++---- 16 files changed, 121 insertions(+), 83 deletions(-) diff --git a/gram_core b/gram_core index db839a7a..c47d04c3 160000 --- a/gram_core +++ b/gram_core @@ -1 +1 @@ -Subproject commit db839a7ad8ebd96b8488b67acdb088c85b87c42e +Subproject commit c47d04c3502deaf239c61f1c179e592d3c71aa29 diff --git a/plugins/genshin/abyss.py b/plugins/genshin/abyss.py index f33bd075..f0d671e6 100644 --- a/plugins/genshin/abyss.py +++ b/plugins/genshin/abyss.py @@ -89,8 +89,10 @@ class AbyssPlugin(Plugin): @handler.command("abyss", block=False) @handler.message(filters.Regex(r"^深渊数据"), block=False) - async def command_start(self, update: Update, _: CallbackContext) -> None: # skipcq: PY-R1000 # + async def command_start(self, update: Update, context: CallbackContext) -> None: # skipcq: PY-R1000 # user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) + args = self.get_args(context) message = update.effective_message # 若查询帮助 @@ -108,7 +110,7 @@ class AbyssPlugin(Plugin): return # 解析参数 - floor, total, previous = get_args(message.text) + floor, total, previous = get_args(" ".join([i for i in args if not i.startswith("@")])) if floor > 12 or floor < 0: reply_msg = await message.reply_text("深渊层数输入错误,请重新输入。支持的参数为: 1-12 或 all") @@ -136,7 +138,7 @@ class AbyssPlugin(Plugin): if total: reply_text = await message.reply_text(f"{config.notice.bot_name}需要时间整理深渊数据,还请耐心等待哦~") try: - async with self.helper.genshin_or_public(user_id) as client: + async with self.helper.genshin_or_public(user_id, uid=uid, offset=offset) as client: if not client.public: await client.get_record_cards() abyss_data, avatar_data = await self.get_rendered_pic_data(client, client.player_id, previous) @@ -458,10 +460,11 @@ class AbyssPlugin(Plugin): @handler.message(filters.Regex(r"^深渊历史数据"), block=False) async def abyss_history_command_start(self, update: Update, _: CallbackContext) -> None: user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message self.log_user(update, logger.info, "查询深渊历史数据") - async with self.helper.genshin_or_public(user_id) as client: + async with self.helper.genshin_or_public(user_id, uid=uid, offset=offset) as client: await self.get_session_button_data(user_id, client.player_id, force=True) buttons = await self.gen_season_button(user_id, client.player_id) if not buttons: @@ -469,13 +472,13 @@ class AbyssPlugin(Plugin): return await message.reply_text("请选择要查询的深渊历史数据", reply_markup=InlineKeyboardMarkup(buttons)) - async def get_abyss_history_page(self, update: "Update", user_id: int, result: str): + async def get_abyss_history_page(self, update: "Update", user_id: int, uid: int, result: str): """翻页处理""" callback_query = update.callback_query self.log_user(update, logger.info, "切换深渊历史数据页 page[%s]", result) page = int(result.split("_")[1]) - async with self.helper.genshin_or_public(user_id) as client: + async with self.helper.genshin_or_public(user_id, uid=uid) as client: buttons = await self.gen_season_button(user_id, client.player_id, page) if not buttons: await callback_query.answer("还没有深渊历史数据哦~", show_alert=True) @@ -560,7 +563,7 @@ class AbyssPlugin(Plugin): ) return _detail, _result, _user_id, _uid - detail, result, user_id, _ = await get_abyss_history_callback(callback_query.data) + detail, result, user_id, uid = await get_abyss_history_callback(callback_query.data) if user.id != user_id: await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True) return @@ -568,7 +571,7 @@ class AbyssPlugin(Plugin): await callback_query.answer(text="此按钮不可用", show_alert=True) return if result.startswith("p_"): - await self.get_abyss_history_page(update, user_id, result) + await self.get_abyss_history_page(update, user_id, uid, result) return data_id = int(result) if detail: diff --git a/plugins/genshin/abyss_team.py b/plugins/genshin/abyss_team.py index f30de93d..c8787a61 100644 --- a/plugins/genshin/abyss_team.py +++ b/plugins/genshin/abyss_team.py @@ -34,6 +34,7 @@ class AbyssTeamPlugin(Plugin): @handler.message(filters.Regex(r"^深渊配队"), block=False) async def command_start(self, update: Update, _: CallbackContext) -> None: # skipcq: PY-R1000 # user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message if "help" in message.text or "帮助" in message.text: @@ -51,7 +52,7 @@ class AbyssTeamPlugin(Plugin): self.log_user(update, logger.info, "[bold]深渊配队推荐[/bold]请求", extra={"markup": True}) - client = await self.helper.get_genshin_client(user_id) + client = await self.helper.get_genshin_client(user_id, player_id=uid, offset=offset) await message.reply_chat_action(ChatAction.TYPING) team_data = await self.team_data.get_data() diff --git a/plugins/genshin/akasha.py b/plugins/genshin/akasha.py index 2425bf8b..7301833e 100644 --- a/plugins/genshin/akasha.py +++ b/plugins/genshin/akasha.py @@ -31,8 +31,8 @@ class AkashaPlugin(Plugin): self.template_service = template_service self.player_service = player_service - async def get_user_uid(self, user_id: int) -> Optional[int]: - player = await self.player_service.get(user_id) + async def get_user_uid(self, user_id: int, uid: int, offset: int) -> Optional[int]: + player = await self.player_service.get(user_id, player_id=uid, offset=offset) if player is None: return None return player.player_id @@ -96,7 +96,8 @@ class AkashaPlugin(Plugin): self.add_delete_message_job(reply_message) return avatar_name = roleToName(args[0]) - uid = await self.get_user_uid(user_id) + uid, offset = self.get_real_uid_or_offset(update) + uid = await self.get_user_uid(user_id, uid, offset) try: render_data = await self.get_avatar_board_render_data(avatar_name, uid) except NotImplementedError: diff --git a/plugins/genshin/avatar_list.py b/plugins/genshin/avatar_list.py index 68e0377d..dc71fe8a 100644 --- a/plugins/genshin/avatar_list.py +++ b/plugins/genshin/avatar_list.py @@ -175,13 +175,14 @@ class AvatarListPlugin(Plugin): async def avatar_list(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE"): user_id = await self.get_real_user_id(update) user_name = self.get_real_user_name(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message all_avatars = "全部" in message.text or "all" in message.text # 是否发送全部角色 self.log_user(update, logger.info, "[bold]练度统计[/bold]: all=%s", all_avatars, extra={"markup": True}) notice = None try: - async with self.helper.genshin(user_id) as client: + async with self.helper.genshin(user_id, player_id=uid, offset=offset) as client: notice = await message.reply_text(f"{config.notice.bot_name}需要收集整理数据,还请耐心等待哦~") self.add_delete_message_job(notice, delay=60) await message.reply_chat_action(ChatAction.TYPING) diff --git a/plugins/genshin/daily/material.py b/plugins/genshin/daily/material.py index ac67110d..cba0efd9 100644 --- a/plugins/genshin/daily/material.py +++ b/plugins/genshin/daily/material.py @@ -211,12 +211,14 @@ class DailyMaterial(Plugin): talents = [t for t in detail.talents if t.type in ["attack", "skill", "burst"]] return [t.level for t in talents] - async def _get_items_from_user(self, user_id: int) -> Tuple[Optional["GenshinClient"], "UserOwned"]: + async def _get_items_from_user( + self, user_id: int, uid: int, offset: int + ) -> Tuple[Optional["GenshinClient"], "UserOwned"]: """获取已经绑定的账号的角色、武器信息""" user_data = UserOwned() try: logger.debug("尝试获取已绑定的原神账号") - client = await self.helper.get_genshin_client(user_id) + client = await self.helper.get_genshin_client(user_id, player_id=uid, offset=offset) logger.debug("获取账号数据成功: UID=%s", client.player_id) characters = await client.get_genshin_characters(client.player_id) for character in characters: @@ -370,6 +372,7 @@ class DailyMaterial(Plugin): @handler.command("daily_material", block=False) async def daily_material(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE"): user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = typing.cast("Message", update.effective_message) args = self.get_args(context) now = datetime.now() @@ -410,7 +413,7 @@ class DailyMaterial(Plugin): await self._refresh_everyday_materials() # 尝试获取用户已绑定的原神账号信息 - client, user_owned = await self._get_items_from_user(user_id) + client, user_owned = await self._get_items_from_user(user_id, uid, offset) today_materials = self.everyday_materials.weekday(weekday) fragile_client = FragileGenshinClient(client) area_avatars: List["AreaData"] = [] diff --git a/plugins/genshin/daily_note.py b/plugins/genshin/daily_note.py index e5ecb07a..9485ddfd 100644 --- a/plugins/genshin/daily_note.py +++ b/plugins/genshin/daily_note.py @@ -105,11 +105,12 @@ class DailyNotePlugin(Plugin): async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> Optional[int]: message = update.effective_message user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) self.log_user(update, logger.info, "每日便签命令请求") try: # 获取当前用户的 genshin.Client - async with self.helper.genshin(user_id) as client: + async with self.helper.genshin(user_id, player_id=uid, offset=offset) as client: render_result = await self._get_daily_note(client) except DataNotPublic: reply_message = await message.reply_text( diff --git a/plugins/genshin/gcsim/plugin.py b/plugins/genshin/gcsim/plugin.py index 72111f03..fd731501 100644 --- a/plugins/genshin/gcsim/plugin.py +++ b/plugins/genshin/gcsim/plugin.py @@ -108,14 +108,17 @@ class GCSimPlugin(Plugin): return [fit for fit in fits if all(name in [str(i) for i in fit.characters] for name in names)] async def _get_uid_names( - self, user_id: int, args: List[str], reply: Optional["Message"] + self, + user_id: int, + args: List[str], + reply: Optional["Message"], + player_id: int, + offset: int, ) -> Tuple[Optional[int], List[str]]: """通过消息获取 uid,优先级:args > reply > self""" - uid, user_id_, names = None, user_id, [] + uid, user_id_, names = player_id, user_id, [] if args: for i in args: - if i is not None and i.isdigit() and len(i) == 9: - uid = int(i) if i is not None and roleToId(i) is not None: names.append(roleToName(i)) if reply: @@ -124,11 +127,11 @@ class GCSimPlugin(Plugin): except AttributeError: pass if not uid: - player_info = await self.player_service.get_player(user_id_) + player_info = await self.player_service.get_player(user_id_, offset=offset) if player_info is not None: uid = player_info.player_id if (not uid) and (user_id_ != user_id): - player_info = await self.player_service.get_player(user_id) + player_info = await self.player_service.get_player(user_id, offset=offset) if player_info is not None: uid = player_info.player_id return uid, names @@ -172,7 +175,8 @@ class GCSimPlugin(Plugin): self.add_delete_message_job(message) return - uid, names = await self._get_uid_names(user_id, args, message.reply_to_message) + uid, offset = self.get_real_uid_or_offset(update) + uid, names = await self._get_uid_names(user_id, args, message.reply_to_message, uid, offset) self.log_user(update, logger.info, "发出 gcsim 命令 UID[%s] NAMES[%s]", uid, " ".join(names)) if uid is None: raise PlayerNotFoundError(user_id) diff --git a/plugins/genshin/ledger.py b/plugins/genshin/ledger.py index 80f8b788..b50340a4 100644 --- a/plugins/genshin/ledger.py +++ b/plugins/genshin/ledger.py @@ -94,6 +94,7 @@ class LedgerPlugin(Plugin): @handler.message(filters=filters.Regex("^旅行札记查询(.*)"), block=False) async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message now = datetime.now() @@ -128,7 +129,7 @@ class LedgerPlugin(Plugin): self.log_user(update, logger.info, "查询旅行札记") await message.reply_chat_action(ChatAction.TYPING) try: - async with self.helper.genshin(user_id) as client: + async with self.helper.genshin(user_id, player_id=uid, offset=offset) as client: render_result = await self._start_get_ledger(client, month) except DataNotPublic: reply_message = await message.reply_text( @@ -236,10 +237,11 @@ class LedgerPlugin(Plugin): @handler.message(filters.Regex(r"^旅行札记历史数据"), block=False) async def ledger_history_command_start(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None: user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message self.log_user(update, logger.info, "查询旅行札记历史数据") - async with self.helper.genshin(user_id) as client: + async with self.helper.genshin(user_id, player_id=uid, offset=offset) as client: await self.get_session_button_data(user_id, client.player_id, force=True) buttons = await self.gen_season_button(user_id, client.player_id) if not buttons: @@ -255,13 +257,13 @@ class LedgerPlugin(Plugin): if reply_message.photo: self.kitsune = reply_message.photo[-1].file_id - async def get_ledger_history_page(self, update: "Update", user_id: int, result: str): + async def get_ledger_history_page(self, update: "Update", user_id: int, uid: int, result: str): """翻页处理""" callback_query = update.callback_query self.log_user(update, logger.info, "切换旅行札记历史数据页 page[%s]", result) page = int(result.split("_")[1]) - async with self.helper.genshin(user_id) as client: + async with self.helper.genshin(user_id, player_id=uid) as client: buttons = await self.gen_season_button(user_id, client.player_id, page) if not buttons: await callback_query.answer("还没有旅行札记历史数据哦~", show_alert=True) @@ -291,7 +293,7 @@ class LedgerPlugin(Plugin): ) return _result, _user_id, _uid - result, user_id, _ = await get_ledger_history_callback(callback_query.data) + result, user_id, uid = await get_ledger_history_callback(callback_query.data) if user.id != user_id: await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True) return @@ -299,7 +301,7 @@ class LedgerPlugin(Plugin): await callback_query.answer(text="此按钮不可用", show_alert=True) return if result.startswith("p_"): - await self.get_ledger_history_page(update, user_id, result) + await self.get_ledger_history_page(update, user_id, uid, result) return data_id = int(result) data = await self.history_data_ledger.get_by_id(data_id) diff --git a/plugins/genshin/player_cards.py b/plugins/genshin/player_cards.py index 753e5d0b..dae2cd53 100644 --- a/plugins/genshin/player_cards.py +++ b/plugins/genshin/player_cards.py @@ -132,28 +132,30 @@ class PlayerCards(Plugin): return await self.player_cards_file.load_history_info(uid) async def get_uid_and_ch( - self, user_id: int, args: List[str], reply: Optional["Message"] + self, + user_id: int, + args: List[str], + reply: Optional["Message"], + player_id: int, + offset: int, ) -> Tuple[Optional[int], Optional[str]]: """通过消息获取 uid,优先级:args > reply > self""" - uid, ch_name, user_id_ = None, None, user_id + uid, ch_name, user_id_ = player_id, None, user_id if args: for i in args: - if i is not None: - if i.isdigit() and len(i) == 9: - uid = int(i) - else: - ch_name = roleToName(i) + if i is not None and not i.startswith("@"): + ch_name = roleToName(i) if reply: try: user_id_ = reply.from_user.id except AttributeError: pass if not uid: - player_info = await self.player_service.get_player(user_id_) + player_info = await self.player_service.get_player(user_id_, offset=offset) if player_info is not None: uid = player_info.player_id if (not uid) and (user_id_ != user_id): - player_info = await self.player_service.get_player(user_id) + player_info = await self.player_service.get_player(user_id, offset=offset) if player_info is not None: uid = player_info.player_id return uid, ch_name @@ -177,7 +179,8 @@ class PlayerCards(Plugin): message = update.effective_message args = self.get_args(context) await message.reply_chat_action(ChatAction.TYPING) - uid, character_name = await self.get_uid_and_ch(user_id, args, message.reply_to_message) + uid, offset = self.get_real_uid_or_offset(update) + uid, character_name = await self.get_uid_and_ch(user_id, args, message.reply_to_message, uid, offset) if uid is None: raise PlayerNotFoundError(user_id) original_data = await self._load_history(uid) diff --git a/plugins/genshin/redeem/redeem.py b/plugins/genshin/redeem/redeem.py index 9a31b5e7..9079050c 100644 --- a/plugins/genshin/redeem/redeem.py +++ b/plugins/genshin/redeem/redeem.py @@ -91,7 +91,8 @@ class Redeem(Plugin): self.add_delete_message_job(reply_message) async def redeem_codes(self, update: Update, user_id: int, codes: List[str]): - async with self.genshin_helper.genshin(user_id) as client: + uid, offset = self.get_real_uid_or_offset(update) + async with self.genshin_helper.genshin(user_id, player_id=uid, offset=offset) as client: chinese = client.region == Region.CHINESE uid = client.player_id tasks = [] @@ -108,7 +109,7 @@ class Redeem(Plugin): if filters.ChatType.GROUPS.filter(message): self.add_delete_message_job(message) limit = self.max_code_in_pub_message - codes = [i for i in self.get_args(context) if i][:limit] + codes = [i for i in self.get_args(context) if not i.startswith("@")][:limit] self.log_user(update, logger.info, "兑换码兑换命令请求 codes[%s]", codes) if not codes: return diff --git a/plugins/genshin/redeem/runner.py b/plugins/genshin/redeem/runner.py index 7afdf7a9..a354ef77 100644 --- a/plugins/genshin/redeem/runner.py +++ b/plugins/genshin/redeem/runner.py @@ -78,7 +78,9 @@ class RedeemRunner: error = None try: async with self.genshin_helper.genshin( - result.user_id, region=RegionEnum.HOYOLAB if only_region else None + result.user_id, + region=RegionEnum.HOYOLAB if only_region else None, + player_id=result.uid, ) as client: client: "GenshinClient" result.uid = client.player_id diff --git a/plugins/genshin/reg_time.py b/plugins/genshin/reg_time.py index b5c2bf4a..f95b3c87 100644 --- a/plugins/genshin/reg_time.py +++ b/plugins/genshin/reg_time.py @@ -75,10 +75,11 @@ class RegTimePlugin(Plugin): @handler.message(filters.Regex(r"^原神账号注册时间$"), block=False) async def reg_time(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None: user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message self.log_user(update, logger.info, "原神注册时间命令请求") try: - async with self.helper.genshin(user_id) as client: + async with self.helper.genshin(user_id, player_id=uid, offset=offset) as client: reg_time = await self.get_reg_time_from_cache(client) await message.reply_text(f"你的原神账号注册时间为:{reg_time}") except SIMNetBadRequest as exc: diff --git a/plugins/genshin/stats.py b/plugins/genshin/stats.py index cd7207bb..dedb88ad 100644 --- a/plugins/genshin/stats.py +++ b/plugins/genshin/stats.py @@ -30,19 +30,16 @@ class PlayerStatsPlugins(Plugin): @handler.command("stats", player=True, block=False) @handler.message(filters.Regex("^玩家统计查询(.*)"), player=True, block=False) - async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> Optional[int]: + async def command_start(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> Optional[int]: user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message self.log_user(update, logger.info, "查询游戏用户命令请求") - uid: Optional[int] = None try: - args = context.args - if args is not None and len(args) == 9: - uid = int(args[0]) - async with self.helper.genshin_or_public(user_id) as client: + async with self.helper.genshin_or_public(user_id, uid=uid, offset=offset) as client: if not client.public: await client.get_record_cards() - render_result = await self.render(client, uid) + render_result = await self.render(client, client.player_id) except TooManyRequestPublicCookies: await message.reply_text("用户查询次数过多 请稍后重试") return diff --git a/plugins/genshin/wish_log.py b/plugins/genshin/wish_log.py index c25423aa..6a03a6af 100644 --- a/plugins/genshin/wish_log.py +++ b/plugins/genshin/wish_log.py @@ -90,16 +90,16 @@ class WishLogPlugin(Plugin.Conversation): 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: + async def get_player_id(self, user_id: int, player_id: int, offset: int) -> int: """获取绑定的游戏ID""" logger.debug("尝试获取已绑定的原神账号") - player = await self.players_service.get_player(uid) + player = await self.players_service.get_player(user_id, player_id=player_id, offset=offset) if player is None: - raise PlayerNotFoundError(uid) + raise PlayerNotFoundError(user_id) return player.player_id async def _refresh_user_data( - self, user: "User", data: dict = None, authkey: str = None, verify_uid: bool = True + self, user: "User", player_id: int, data: dict = None, authkey: str = None, verify_uid: bool = True ) -> str: """刷新用户数据 :param user: 用户 @@ -109,7 +109,6 @@ class WishLogPlugin(Plugin.Conversation): """ try: logger.debug("尝试获取已绑定的原神账号") - player_id = await self.get_player_id(user.id) if 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}条抽卡记录" @@ -132,7 +131,9 @@ class WishLogPlugin(Plugin.Conversation): logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id) return config.notice.user_not_found - async def import_from_file(self, user: "User", message: "Message", document: "Optional[Document]" = None) -> None: + async def import_from_file( + self, user: "User", player_id: int, message: "Message", document: "Optional[Document]" = None + ) -> None: if not document: document = message.document # TODO: 使用 mimetype 判断文件类型 @@ -178,16 +179,16 @@ class WishLogPlugin(Plugin.Conversation): reply = await message.reply_text("文件解析成功,正在导入数据") await message.reply_chat_action(ChatAction.TYPING) try: - text = await self._refresh_user_data(user, data=data, verify_uid=file_type == "json") + text = await self._refresh_user_data(user, player_id, data=data, verify_uid=file_type == "json") except Exception as exc: # pylint: disable=W0703 logger.error("文件解析失败 %s", repr(exc)) text = f"文件解析失败,请检查文件是否符合 UIGF {UIGF_VERSION} 标准" await reply.edit_text(text) - async def can_gen_authkey(self, uid: int) -> bool: - player_info = await self.players_service.get_player(uid, region=RegionEnum.HYPERION) + async def can_gen_authkey(self, user_id: int, player_id: int) -> bool: + player_info = await self.players_service.get_player(user_id, region=RegionEnum.HYPERION, player_id=player_id) if player_info is not None: - cookies = await self.cookie_service.get(uid, account_id=player_info.account_id) + cookies = await self.cookie_service.get(user_id, account_id=player_info.account_id) if ( cookies is not None and cookies.data @@ -214,23 +215,27 @@ class WishLogPlugin(Plugin.Conversation): @handler.command(command="gacha_log_import", filters=filters.ChatType.PRIVATE, block=False) @handler.message(filters=filters.Regex("^导入抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False) @handler.command(command="start", filters=filters.Regex("gacha_log_import$"), block=False) - async def command_start(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> int: + async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int: + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message user = update.effective_user + player_id = await self.get_player_id(user.id, uid, offset) + context.chat_data["uid"] = player_id logger.info("用户 %s[%s] 导入抽卡记录命令请求", user.full_name, user.id) keyboard = None - if await self.can_gen_authkey(user.id): + if await self.can_gen_authkey(user.id, player_id): keyboard = ReplyKeyboardMarkup([["自动导入"], ["退出"]], one_time_keyboard=True) await message.reply_text(self.IMPORT_HINT, parse_mode="html", reply_markup=keyboard) return INPUT_URL @conversation.state(state=INPUT_URL) @handler.message(filters=~filters.COMMAND, block=False) - async def import_data_from_message(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> int: + async def import_data_from_message(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int: message = update.effective_message user = update.effective_user + player_id = context.chat_data["uid"] if message.document: - await self.import_from_file(user, message) + await self.import_from_file(user, player_id, message) return ConversationHandler.END if not message.text: await message.reply_text("请发送文件或链接") @@ -249,7 +254,7 @@ class WishLogPlugin(Plugin.Conversation): authkey = from_url_get_authkey(message.text) reply = await message.reply_text(WAITING, reply_markup=ReplyKeyboardRemove()) await message.reply_chat_action(ChatAction.TYPING) - text = await self._refresh_user_data(user, authkey=authkey) + text = await self._refresh_user_data(user, player_id, authkey=authkey) try: await reply.delete() except BadRequest: @@ -262,11 +267,12 @@ class WishLogPlugin(Plugin.Conversation): @handler.command(command="gacha_log_delete", filters=filters.ChatType.PRIVATE, block=False) @handler.message(filters=filters.Regex("^删除抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False) async def command_start_delete(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int: + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message user = update.effective_user logger.info("用户 %s[%s] 删除抽卡记录命令请求", user.full_name, user.id) try: - player_id = await self.get_player_id(user.id) + player_id = await self.get_player_id(user.id, uid, offset) context.chat_data["uid"] = player_id except PlayerNotFoundError: logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id) @@ -296,6 +302,7 @@ class WishLogPlugin(Plugin.Conversation): @handler.command(command="wish_log_force_delete", block=False, admin=True) @handler.command(command="gacha_log_force_delete", block=False, admin=True) async def command_gacha_log_force_delete(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE"): + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message user = update.effective_user logger.info("用户 %s[%s] 强制删除抽卡记录命令请求", user.full_name, user.id) @@ -307,7 +314,7 @@ class WishLogPlugin(Plugin.Conversation): cid = int(args[0]) if cid < 0: raise ValueError("Invalid cid") - player_id = await self.get_player_id(cid) + player_id = await self.get_player_id(cid, uid, offset) _, status = await self.gacha_log.load_history_info(str(cid), str(player_id), only_status=True) if not status: await message.reply_text("该用户还没有导入抽卡记录") @@ -325,11 +332,12 @@ class WishLogPlugin(Plugin.Conversation): @handler.command(command="gacha_log_export", filters=filters.ChatType.PRIVATE, block=False) @handler.message(filters=filters.Regex("^导出抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False) async def command_start_export(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message user = update.effective_user logger.info("用户 %s[%s] 导出抽卡记录命令请求", user.full_name, user.id) try: - player_id = await self.get_player_id(user.id) + player_id = await self.get_player_id(user.id, uid, offset) await message.reply_chat_action(ChatAction.TYPING) path = await self.gacha_log.gacha_log_to_uigf(str(user.id), str(player_id)) await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT) @@ -411,9 +419,8 @@ class WishLogPlugin(Plugin.Conversation): buttons.append([InlineKeyboardButton("五星抽卡统计", callback_data=f"get_wish_log|{user_id}|{uid}|count|five")]) return buttons - async def wish_log_pool_choose(self, user_id: int, message: "Message"): + async def wish_log_pool_choose(self, user_id: int, player_id: int, message: "Message"): await message.reply_chat_action(ChatAction.TYPING) - player_id = await self.get_player_id(user_id) gacha_log, status = await self.gacha_log.load_history_info(str(user_id), str(player_id)) if not status: raise GachaLogNotFound @@ -431,9 +438,8 @@ class WishLogPlugin(Plugin.Conversation): if reply_message.photo: self.wish_photo = reply_message.photo[-1].file_id - async def wish_log_pool_send(self, user_id: int, pool_type: "BannerType", message: "Message"): + async def wish_log_pool_send(self, user_id: int, uid: int, pool_type: "BannerType", message: "Message"): await message.reply_chat_action(ChatAction.TYPING) - uid = await self.get_player_id(user_id) png_data = await self.rander_wish_log_analysis(user_id, uid, pool_type) if isinstance(png_data, str): reply = await message.reply_text(png_data) @@ -452,6 +458,7 @@ class WishLogPlugin(Plugin.Conversation): @handler.message(filters=filters.Regex("^抽卡记录?(武器|角色|常驻|)$"), block=False) async def command_start_analysis(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) message = update.effective_message pool_type = None if args := self.get_args(context): @@ -465,10 +472,11 @@ class WishLogPlugin(Plugin.Conversation): pool_type = BannerType.CHRONICLED self.log_user(update, logger.info, "抽卡记录命令请求 || 参数 %s", pool_type.name if pool_type else None) try: + player_id = await self.get_player_id(user_id, uid, offset) if pool_type is None: - await self.wish_log_pool_choose(user_id, message) + await self.wish_log_pool_choose(user_id, player_id, message) else: - await self.wish_log_pool_send(user_id, pool_type, message) + await self.wish_log_pool_send(user_id, player_id, pool_type, message) except GachaLogNotFound: self.log_user(update, logger.info, "未找到抽卡记录") buttons = [ diff --git a/plugins/tools/genshin.py b/plugins/tools/genshin.py index 767e7de1..f15dba83 100644 --- a/plugins/tools/genshin.py +++ b/plugins/tools/genshin.py @@ -218,8 +218,10 @@ class GenshinHelper(Plugin): raise ServiceNotFoundError(*filter(lambda x: x is None, temp)) @asynccontextmanager - async def genshin(self, user_id: int, region: Optional[RegionEnum] = None) -> GenshinClient: # skipcq: PY-R1000 # - player = await self.players_service.get_player(user_id, region) + async def genshin( # skipcq: PY-R1000 # + self, user_id: int, region: Optional[RegionEnum] = None, player_id: int = None, offset: int = 0 + ) -> GenshinClient: + player = await self.players_service.get_player(user_id, region, player_id, offset) if player is None: raise PlayerNotFoundError(user_id) @@ -304,8 +306,10 @@ class GenshinHelper(Plugin): await self.devices_service.update(devices) raise exc - async def get_genshin_client(self, user_id: int, region: Optional[RegionEnum] = None) -> GenshinClient: - player = await self.players_service.get_player(user_id, region) + async def get_genshin_client( + self, user_id: int, region: Optional[RegionEnum] = None, player_id: int = None, offset: int = 0 + ) -> GenshinClient: + player = await self.players_service.get_player(user_id, region, player_id, offset) if player is None: raise PlayerNotFoundError(user_id) @@ -383,17 +387,23 @@ class GenshinHelper(Plugin): @asynccontextmanager async def genshin_or_public( - self, user_id: int, region: Optional[RegionEnum] = None, uid: Optional[int] = None + self, + user_id: int, + region: Optional[RegionEnum] = None, + uid: Optional[int] = None, + offset: int = 0, ) -> GenshinClient: try: - async with self.genshin(user_id, region) as client: + async with self.genshin(user_id, region, uid, offset) as client: client.public = False if uid and recognize_game_biz(uid, client.game) != recognize_game_biz(client.player_id, client.game): # 如果 uid 和 player_id 服务器不一致,说明是跨服的,需要使用公共的 cookies raise CookiesNotFoundError(user_id) yield client - except CookiesNotFoundError: + except (CookiesNotFoundError, PlayerNotFoundError): if uid: + if uid < 10: + raise PlayerNotFoundError(user_id) region = RegionEnum.HYPERION if uid < 600000000 else RegionEnum.HOYOLAB async with self.public_genshin(user_id, region, uid) as client: try: