Support run command specifying uid

This commit is contained in:
omg-xtao 2024-06-12 19:59:16 +08:00 committed by GitHub
parent 710c3db50a
commit 47e6b7f750
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 121 additions and 83 deletions

@ -1 +1 @@
Subproject commit db839a7ad8ebd96b8488b67acdb088c85b87c42e Subproject commit c47d04c3502deaf239c61f1c179e592d3c71aa29

View File

@ -89,8 +89,10 @@ class AbyssPlugin(Plugin):
@handler.command("abyss", block=False) @handler.command("abyss", block=False)
@handler.message(filters.Regex(r"^深渊数据"), 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) 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 message = update.effective_message
# 若查询帮助 # 若查询帮助
@ -108,7 +110,7 @@ class AbyssPlugin(Plugin):
return 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: if floor > 12 or floor < 0:
reply_msg = await message.reply_text("深渊层数输入错误,请重新输入。支持的参数为: 1-12 或 all") reply_msg = await message.reply_text("深渊层数输入错误,请重新输入。支持的参数为: 1-12 或 all")
@ -136,7 +138,7 @@ class AbyssPlugin(Plugin):
if total: if total:
reply_text = await message.reply_text(f"{config.notice.bot_name}需要时间整理深渊数据,还请耐心等待哦~") reply_text = await message.reply_text(f"{config.notice.bot_name}需要时间整理深渊数据,还请耐心等待哦~")
try: 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: if not client.public:
await client.get_record_cards() await client.get_record_cards()
abyss_data, avatar_data = await self.get_rendered_pic_data(client, client.player_id, previous) 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) @handler.message(filters.Regex(r"^深渊历史数据"), block=False)
async def abyss_history_command_start(self, update: Update, _: CallbackContext) -> None: async def abyss_history_command_start(self, update: Update, _: CallbackContext) -> None:
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
self.log_user(update, logger.info, "查询深渊历史数据") 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) await self.get_session_button_data(user_id, client.player_id, force=True)
buttons = await self.gen_season_button(user_id, client.player_id) buttons = await self.gen_season_button(user_id, client.player_id)
if not buttons: if not buttons:
@ -469,13 +472,13 @@ class AbyssPlugin(Plugin):
return return
await message.reply_text("请选择要查询的深渊历史数据", reply_markup=InlineKeyboardMarkup(buttons)) 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 callback_query = update.callback_query
self.log_user(update, logger.info, "切换深渊历史数据页 page[%s]", result) self.log_user(update, logger.info, "切换深渊历史数据页 page[%s]", result)
page = int(result.split("_")[1]) 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) buttons = await self.gen_season_button(user_id, client.player_id, page)
if not buttons: if not buttons:
await callback_query.answer("还没有深渊历史数据哦~", show_alert=True) await callback_query.answer("还没有深渊历史数据哦~", show_alert=True)
@ -560,7 +563,7 @@ class AbyssPlugin(Plugin):
) )
return _detail, _result, _user_id, _uid 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: if user.id != user_id:
await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True) await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True)
return return
@ -568,7 +571,7 @@ class AbyssPlugin(Plugin):
await callback_query.answer(text="此按钮不可用", show_alert=True) await callback_query.answer(text="此按钮不可用", show_alert=True)
return return
if result.startswith("p_"): 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 return
data_id = int(result) data_id = int(result)
if detail: if detail:

View File

@ -34,6 +34,7 @@ class AbyssTeamPlugin(Plugin):
@handler.message(filters.Regex(r"^深渊配队"), 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, _: CallbackContext) -> None: # skipcq: PY-R1000 #
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
if "help" in message.text or "帮助" in message.text: 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}) 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) await message.reply_chat_action(ChatAction.TYPING)
team_data = await self.team_data.get_data() team_data = await self.team_data.get_data()

View File

@ -31,8 +31,8 @@ class AkashaPlugin(Plugin):
self.template_service = template_service self.template_service = template_service
self.player_service = player_service self.player_service = player_service
async def get_user_uid(self, user_id: int) -> Optional[int]: async def get_user_uid(self, user_id: int, uid: int, offset: int) -> Optional[int]:
player = await self.player_service.get(user_id) player = await self.player_service.get(user_id, player_id=uid, offset=offset)
if player is None: if player is None:
return None return None
return player.player_id return player.player_id
@ -96,7 +96,8 @@ class AkashaPlugin(Plugin):
self.add_delete_message_job(reply_message) self.add_delete_message_job(reply_message)
return return
avatar_name = roleToName(args[0]) 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: try:
render_data = await self.get_avatar_board_render_data(avatar_name, uid) render_data = await self.get_avatar_board_render_data(avatar_name, uid)
except NotImplementedError: except NotImplementedError:

View File

@ -175,13 +175,14 @@ class AvatarListPlugin(Plugin):
async def avatar_list(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE"): async def avatar_list(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE"):
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
user_name = self.get_real_user_name(update) user_name = self.get_real_user_name(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
all_avatars = "全部" in message.text or "all" in message.text # 是否发送全部角色 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}) self.log_user(update, logger.info, "[bold]练度统计[/bold]: all=%s", all_avatars, extra={"markup": True})
notice = None notice = None
try: 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}需要收集整理数据,还请耐心等待哦~") notice = await message.reply_text(f"{config.notice.bot_name}需要收集整理数据,还请耐心等待哦~")
self.add_delete_message_job(notice, delay=60) self.add_delete_message_job(notice, delay=60)
await message.reply_chat_action(ChatAction.TYPING) await message.reply_chat_action(ChatAction.TYPING)

View File

@ -211,12 +211,14 @@ class DailyMaterial(Plugin):
talents = [t for t in detail.talents if t.type in ["attack", "skill", "burst"]] talents = [t for t in detail.talents if t.type in ["attack", "skill", "burst"]]
return [t.level for t in talents] 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() user_data = UserOwned()
try: try:
logger.debug("尝试获取已绑定的原神账号") 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) logger.debug("获取账号数据成功: UID=%s", client.player_id)
characters = await client.get_genshin_characters(client.player_id) characters = await client.get_genshin_characters(client.player_id)
for character in characters: for character in characters:
@ -370,6 +372,7 @@ class DailyMaterial(Plugin):
@handler.command("daily_material", block=False) @handler.command("daily_material", block=False)
async def daily_material(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE"): async def daily_material(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE"):
user_id = await self.get_real_user_id(update) 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) message = typing.cast("Message", update.effective_message)
args = self.get_args(context) args = self.get_args(context)
now = datetime.now() now = datetime.now()
@ -410,7 +413,7 @@ class DailyMaterial(Plugin):
await self._refresh_everyday_materials() 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) today_materials = self.everyday_materials.weekday(weekday)
fragile_client = FragileGenshinClient(client) fragile_client = FragileGenshinClient(client)
area_avatars: List["AreaData"] = [] area_avatars: List["AreaData"] = []

View File

@ -105,11 +105,12 @@ class DailyNotePlugin(Plugin):
async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> Optional[int]: async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> Optional[int]:
message = update.effective_message message = update.effective_message
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
self.log_user(update, logger.info, "每日便签命令请求") self.log_user(update, logger.info, "每日便签命令请求")
try: try:
# 获取当前用户的 genshin.Client # 获取当前用户的 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) render_result = await self._get_daily_note(client)
except DataNotPublic: except DataNotPublic:
reply_message = await message.reply_text( reply_message = await message.reply_text(

View File

@ -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)] 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( 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]]: ) -> Tuple[Optional[int], List[str]]:
"""通过消息获取 uid优先级args > reply > self""" """通过消息获取 uid优先级args > reply > self"""
uid, user_id_, names = None, user_id, [] uid, user_id_, names = player_id, user_id, []
if args: if args:
for i in 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: if i is not None and roleToId(i) is not None:
names.append(roleToName(i)) names.append(roleToName(i))
if reply: if reply:
@ -124,11 +127,11 @@ class GCSimPlugin(Plugin):
except AttributeError: except AttributeError:
pass pass
if not uid: 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: if player_info is not None:
uid = player_info.player_id uid = player_info.player_id
if (not uid) and (user_id_ != user_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: if player_info is not None:
uid = player_info.player_id uid = player_info.player_id
return uid, names return uid, names
@ -172,7 +175,8 @@ class GCSimPlugin(Plugin):
self.add_delete_message_job(message) self.add_delete_message_job(message)
return 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)) self.log_user(update, logger.info, "发出 gcsim 命令 UID[%s] NAMES[%s]", uid, " ".join(names))
if uid is None: if uid is None:
raise PlayerNotFoundError(user_id) raise PlayerNotFoundError(user_id)

View File

@ -94,6 +94,7 @@ class LedgerPlugin(Plugin):
@handler.message(filters=filters.Regex("^旅行札记查询(.*)"), block=False) @handler.message(filters=filters.Regex("^旅行札记查询(.*)"), block=False)
async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None:
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
now = datetime.now() now = datetime.now()
@ -128,7 +129,7 @@ class LedgerPlugin(Plugin):
self.log_user(update, logger.info, "查询旅行札记") self.log_user(update, logger.info, "查询旅行札记")
await message.reply_chat_action(ChatAction.TYPING) await message.reply_chat_action(ChatAction.TYPING)
try: 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) render_result = await self._start_get_ledger(client, month)
except DataNotPublic: except DataNotPublic:
reply_message = await message.reply_text( reply_message = await message.reply_text(
@ -236,10 +237,11 @@ class LedgerPlugin(Plugin):
@handler.message(filters.Regex(r"^旅行札记历史数据"), block=False) @handler.message(filters.Regex(r"^旅行札记历史数据"), block=False)
async def ledger_history_command_start(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None: async def ledger_history_command_start(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None:
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
self.log_user(update, logger.info, "查询旅行札记历史数据") 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) await self.get_session_button_data(user_id, client.player_id, force=True)
buttons = await self.gen_season_button(user_id, client.player_id) buttons = await self.gen_season_button(user_id, client.player_id)
if not buttons: if not buttons:
@ -255,13 +257,13 @@ class LedgerPlugin(Plugin):
if reply_message.photo: if reply_message.photo:
self.kitsune = reply_message.photo[-1].file_id 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 callback_query = update.callback_query
self.log_user(update, logger.info, "切换旅行札记历史数据页 page[%s]", result) self.log_user(update, logger.info, "切换旅行札记历史数据页 page[%s]", result)
page = int(result.split("_")[1]) 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) buttons = await self.gen_season_button(user_id, client.player_id, page)
if not buttons: if not buttons:
await callback_query.answer("还没有旅行札记历史数据哦~", show_alert=True) await callback_query.answer("还没有旅行札记历史数据哦~", show_alert=True)
@ -291,7 +293,7 @@ class LedgerPlugin(Plugin):
) )
return _result, _user_id, _uid 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: if user.id != user_id:
await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True) await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True)
return return
@ -299,7 +301,7 @@ class LedgerPlugin(Plugin):
await callback_query.answer(text="此按钮不可用", show_alert=True) await callback_query.answer(text="此按钮不可用", show_alert=True)
return return
if result.startswith("p_"): 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 return
data_id = int(result) data_id = int(result)
data = await self.history_data_ledger.get_by_id(data_id) data = await self.history_data_ledger.get_by_id(data_id)

View File

@ -132,16 +132,18 @@ class PlayerCards(Plugin):
return await self.player_cards_file.load_history_info(uid) return await self.player_cards_file.load_history_info(uid)
async def get_uid_and_ch( 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]]: ) -> Tuple[Optional[int], Optional[str]]:
"""通过消息获取 uid优先级args > reply > self""" """通过消息获取 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: if args:
for i in args: for i in args:
if i is not None: if i is not None and not i.startswith("@"):
if i.isdigit() and len(i) == 9:
uid = int(i)
else:
ch_name = roleToName(i) ch_name = roleToName(i)
if reply: if reply:
try: try:
@ -149,11 +151,11 @@ class PlayerCards(Plugin):
except AttributeError: except AttributeError:
pass pass
if not uid: 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: if player_info is not None:
uid = player_info.player_id uid = player_info.player_id
if (not uid) and (user_id_ != user_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: if player_info is not None:
uid = player_info.player_id uid = player_info.player_id
return uid, ch_name return uid, ch_name
@ -177,7 +179,8 @@ class PlayerCards(Plugin):
message = update.effective_message message = update.effective_message
args = self.get_args(context) args = self.get_args(context)
await message.reply_chat_action(ChatAction.TYPING) 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: if uid is None:
raise PlayerNotFoundError(user_id) raise PlayerNotFoundError(user_id)
original_data = await self._load_history(uid) original_data = await self._load_history(uid)

View File

@ -91,7 +91,8 @@ class Redeem(Plugin):
self.add_delete_message_job(reply_message) self.add_delete_message_job(reply_message)
async def redeem_codes(self, update: Update, user_id: int, codes: List[str]): 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 chinese = client.region == Region.CHINESE
uid = client.player_id uid = client.player_id
tasks = [] tasks = []
@ -108,7 +109,7 @@ class Redeem(Plugin):
if filters.ChatType.GROUPS.filter(message): if filters.ChatType.GROUPS.filter(message):
self.add_delete_message_job(message) self.add_delete_message_job(message)
limit = self.max_code_in_pub_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) self.log_user(update, logger.info, "兑换码兑换命令请求 codes[%s]", codes)
if not codes: if not codes:
return return

View File

@ -78,7 +78,9 @@ class RedeemRunner:
error = None error = None
try: try:
async with self.genshin_helper.genshin( 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: ) as client:
client: "GenshinClient" client: "GenshinClient"
result.uid = client.player_id result.uid = client.player_id

View File

@ -75,10 +75,11 @@ class RegTimePlugin(Plugin):
@handler.message(filters.Regex(r"^原神账号注册时间$"), block=False) @handler.message(filters.Regex(r"^原神账号注册时间$"), block=False)
async def reg_time(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None: async def reg_time(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None:
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
self.log_user(update, logger.info, "原神注册时间命令请求") self.log_user(update, logger.info, "原神注册时间命令请求")
try: 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) reg_time = await self.get_reg_time_from_cache(client)
await message.reply_text(f"你的原神账号注册时间为:{reg_time}") await message.reply_text(f"你的原神账号注册时间为:{reg_time}")
except SIMNetBadRequest as exc: except SIMNetBadRequest as exc:

View File

@ -30,19 +30,16 @@ class PlayerStatsPlugins(Plugin):
@handler.command("stats", player=True, block=False) @handler.command("stats", player=True, block=False)
@handler.message(filters.Regex("^玩家统计查询(.*)"), 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) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
self.log_user(update, logger.info, "查询游戏用户命令请求") self.log_user(update, logger.info, "查询游戏用户命令请求")
uid: Optional[int] = None
try: try:
args = context.args async with self.helper.genshin_or_public(user_id, uid=uid, offset=offset) as client:
if args is not None and len(args) == 9:
uid = int(args[0])
async with self.helper.genshin_or_public(user_id) as client:
if not client.public: if not client.public:
await client.get_record_cards() await client.get_record_cards()
render_result = await self.render(client, uid) render_result = await self.render(client, client.player_id)
except TooManyRequestPublicCookies: except TooManyRequestPublicCookies:
await message.reply_text("用户查询次数过多 请稍后重试") await message.reply_text("用户查询次数过多 请稍后重试")
return return

View File

@ -90,16 +90,16 @@ class WishLogPlugin(Plugin.Conversation):
async with async_open(GACHA_LOG_PAIMON_MOE_PATH, "r", encoding="utf-8") as load_f: 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()) 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""" """获取绑定的游戏ID"""
logger.debug("尝试获取已绑定的原神账号") 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: if player is None:
raise PlayerNotFoundError(uid) raise PlayerNotFoundError(user_id)
return player.player_id return player.player_id
async def _refresh_user_data( 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: ) -> str:
"""刷新用户数据 """刷新用户数据
:param user: 用户 :param user: 用户
@ -109,7 +109,6 @@ class WishLogPlugin(Plugin.Conversation):
""" """
try: try:
logger.debug("尝试获取已绑定的原神账号") logger.debug("尝试获取已绑定的原神账号")
player_id = await self.get_player_id(user.id)
if authkey: if authkey:
new_num = await self.gacha_log.get_gacha_log_data(user.id, player_id, 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}条抽卡记录" 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) logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id)
return config.notice.user_not_found 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: if not document:
document = message.document document = message.document
# TODO: 使用 mimetype 判断文件类型 # TODO: 使用 mimetype 判断文件类型
@ -178,16 +179,16 @@ class WishLogPlugin(Plugin.Conversation):
reply = await message.reply_text("文件解析成功,正在导入数据") reply = await message.reply_text("文件解析成功,正在导入数据")
await message.reply_chat_action(ChatAction.TYPING) await message.reply_chat_action(ChatAction.TYPING)
try: 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 except Exception as exc: # pylint: disable=W0703
logger.error("文件解析失败 %s", repr(exc)) logger.error("文件解析失败 %s", repr(exc))
text = f"文件解析失败,请检查文件是否符合 UIGF {UIGF_VERSION} 标准" text = f"文件解析失败,请检查文件是否符合 UIGF {UIGF_VERSION} 标准"
await reply.edit_text(text) await reply.edit_text(text)
async def can_gen_authkey(self, uid: int) -> bool: async def can_gen_authkey(self, user_id: int, player_id: int) -> bool:
player_info = await self.players_service.get_player(uid, region=RegionEnum.HYPERION) player_info = await self.players_service.get_player(user_id, region=RegionEnum.HYPERION, player_id=player_id)
if player_info is not None: 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 ( if (
cookies is not None cookies is not None
and cookies.data and cookies.data
@ -214,23 +215,27 @@ class WishLogPlugin(Plugin.Conversation):
@handler.command(command="gacha_log_import", filters=filters.ChatType.PRIVATE, block=False) @handler.command(command="gacha_log_import", filters=filters.ChatType.PRIVATE, block=False)
@handler.message(filters=filters.Regex("^导入抽卡记录(.*)") & 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) @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 message = update.effective_message
user = update.effective_user 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) logger.info("用户 %s[%s] 导入抽卡记录命令请求", user.full_name, user.id)
keyboard = None 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) keyboard = ReplyKeyboardMarkup([["自动导入"], ["退出"]], one_time_keyboard=True)
await message.reply_text(self.IMPORT_HINT, parse_mode="html", reply_markup=keyboard) await message.reply_text(self.IMPORT_HINT, parse_mode="html", reply_markup=keyboard)
return INPUT_URL return INPUT_URL
@conversation.state(state=INPUT_URL) @conversation.state(state=INPUT_URL)
@handler.message(filters=~filters.COMMAND, block=False) @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 message = update.effective_message
user = update.effective_user user = update.effective_user
player_id = context.chat_data["uid"]
if message.document: if message.document:
await self.import_from_file(user, message) await self.import_from_file(user, player_id, message)
return ConversationHandler.END return ConversationHandler.END
if not message.text: if not message.text:
await message.reply_text("请发送文件或链接") await message.reply_text("请发送文件或链接")
@ -249,7 +254,7 @@ class WishLogPlugin(Plugin.Conversation):
authkey = from_url_get_authkey(message.text) authkey = from_url_get_authkey(message.text)
reply = await message.reply_text(WAITING, reply_markup=ReplyKeyboardRemove()) reply = await message.reply_text(WAITING, reply_markup=ReplyKeyboardRemove())
await message.reply_chat_action(ChatAction.TYPING) 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: try:
await reply.delete() await reply.delete()
except BadRequest: except BadRequest:
@ -262,11 +267,12 @@ class WishLogPlugin(Plugin.Conversation):
@handler.command(command="gacha_log_delete", filters=filters.ChatType.PRIVATE, block=False) @handler.command(command="gacha_log_delete", filters=filters.ChatType.PRIVATE, block=False)
@handler.message(filters=filters.Regex("^删除抽卡记录(.*)") & 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: 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 message = update.effective_message
user = update.effective_user user = update.effective_user
logger.info("用户 %s[%s] 删除抽卡记录命令请求", user.full_name, user.id) logger.info("用户 %s[%s] 删除抽卡记录命令请求", user.full_name, user.id)
try: 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 context.chat_data["uid"] = player_id
except PlayerNotFoundError: except PlayerNotFoundError:
logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id) 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="wish_log_force_delete", block=False, admin=True)
@handler.command(command="gacha_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"): 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 message = update.effective_message
user = update.effective_user user = update.effective_user
logger.info("用户 %s[%s] 强制删除抽卡记录命令请求", user.full_name, user.id) logger.info("用户 %s[%s] 强制删除抽卡记录命令请求", user.full_name, user.id)
@ -307,7 +314,7 @@ class WishLogPlugin(Plugin.Conversation):
cid = int(args[0]) cid = int(args[0])
if cid < 0: if cid < 0:
raise ValueError("Invalid cid") 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) _, status = await self.gacha_log.load_history_info(str(cid), str(player_id), only_status=True)
if not status: if not status:
await message.reply_text("该用户还没有导入抽卡记录") 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.command(command="gacha_log_export", filters=filters.ChatType.PRIVATE, block=False)
@handler.message(filters=filters.Regex("^导出抽卡记录(.*)") & 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: 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 message = update.effective_message
user = update.effective_user user = update.effective_user
logger.info("用户 %s[%s] 导出抽卡记录命令请求", user.full_name, user.id) logger.info("用户 %s[%s] 导出抽卡记录命令请求", user.full_name, user.id)
try: 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) await message.reply_chat_action(ChatAction.TYPING)
path = await self.gacha_log.gacha_log_to_uigf(str(user.id), str(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_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")]) buttons.append([InlineKeyboardButton("五星抽卡统计", callback_data=f"get_wish_log|{user_id}|{uid}|count|five")])
return buttons 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) 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)) gacha_log, status = await self.gacha_log.load_history_info(str(user_id), str(player_id))
if not status: if not status:
raise GachaLogNotFound raise GachaLogNotFound
@ -431,9 +438,8 @@ class WishLogPlugin(Plugin.Conversation):
if reply_message.photo: if reply_message.photo:
self.wish_photo = reply_message.photo[-1].file_id 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) 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) png_data = await self.rander_wish_log_analysis(user_id, uid, pool_type)
if isinstance(png_data, str): if isinstance(png_data, str):
reply = await message.reply_text(png_data) reply = await message.reply_text(png_data)
@ -452,6 +458,7 @@ class WishLogPlugin(Plugin.Conversation):
@handler.message(filters=filters.Regex("^抽卡记录?(武器|角色|常驻|)$"), block=False) @handler.message(filters=filters.Regex("^抽卡记录?(武器|角色|常驻|)$"), block=False)
async def command_start_analysis(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: async def command_start_analysis(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None:
user_id = await self.get_real_user_id(update) user_id = await self.get_real_user_id(update)
uid, offset = self.get_real_uid_or_offset(update)
message = update.effective_message message = update.effective_message
pool_type = None pool_type = None
if args := self.get_args(context): if args := self.get_args(context):
@ -465,10 +472,11 @@ class WishLogPlugin(Plugin.Conversation):
pool_type = BannerType.CHRONICLED pool_type = BannerType.CHRONICLED
self.log_user(update, logger.info, "抽卡记录命令请求 || 参数 %s", pool_type.name if pool_type else None) self.log_user(update, logger.info, "抽卡记录命令请求 || 参数 %s", pool_type.name if pool_type else None)
try: try:
player_id = await self.get_player_id(user_id, uid, offset)
if pool_type is None: 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: 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: except GachaLogNotFound:
self.log_user(update, logger.info, "未找到抽卡记录") self.log_user(update, logger.info, "未找到抽卡记录")
buttons = [ buttons = [

View File

@ -218,8 +218,10 @@ class GenshinHelper(Plugin):
raise ServiceNotFoundError(*filter(lambda x: x is None, temp)) raise ServiceNotFoundError(*filter(lambda x: x is None, temp))
@asynccontextmanager @asynccontextmanager
async def genshin(self, user_id: int, region: Optional[RegionEnum] = None) -> GenshinClient: # skipcq: PY-R1000 # async def genshin( # skipcq: PY-R1000 #
player = await self.players_service.get_player(user_id, region) 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: if player is None:
raise PlayerNotFoundError(user_id) raise PlayerNotFoundError(user_id)
@ -304,8 +306,10 @@ class GenshinHelper(Plugin):
await self.devices_service.update(devices) await self.devices_service.update(devices)
raise exc raise exc
async def get_genshin_client(self, user_id: int, region: Optional[RegionEnum] = None) -> GenshinClient: async def get_genshin_client(
player = await self.players_service.get_player(user_id, region) 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: if player is None:
raise PlayerNotFoundError(user_id) raise PlayerNotFoundError(user_id)
@ -383,17 +387,23 @@ class GenshinHelper(Plugin):
@asynccontextmanager @asynccontextmanager
async def genshin_or_public( 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: ) -> GenshinClient:
try: try:
async with self.genshin(user_id, region) as client: async with self.genshin(user_id, region, uid, offset) as client:
client.public = False client.public = False
if uid and recognize_game_biz(uid, client.game) != recognize_game_biz(client.player_id, client.game): if uid and recognize_game_biz(uid, client.game) != recognize_game_biz(client.player_id, client.game):
# 如果 uid 和 player_id 服务器不一致,说明是跨服的,需要使用公共的 cookies # 如果 uid 和 player_id 服务器不一致,说明是跨服的,需要使用公共的 cookies
raise CookiesNotFoundError(user_id) raise CookiesNotFoundError(user_id)
yield client yield client
except CookiesNotFoundError: except (CookiesNotFoundError, PlayerNotFoundError):
if uid: if uid:
if uid < 10:
raise PlayerNotFoundError(user_id)
region = RegionEnum.HYPERION if uid < 600000000 else RegionEnum.HOYOLAB region = RegionEnum.HYPERION if uid < 600000000 else RegionEnum.HOYOLAB
async with self.public_genshin(user_id, region, uid) as client: async with self.public_genshin(user_id, region, uid) as client:
try: try: