diff --git a/LittlePaimon/plugins/Paimon_Autobbs/__init__.py b/LittlePaimon/plugins/Paimon_Autobbs/__init__.py index b462ad7..d8a8be6 100644 --- a/LittlePaimon/plugins/Paimon_Autobbs/__init__.py +++ b/LittlePaimon/plugins/Paimon_Autobbs/__init__.py @@ -18,44 +18,65 @@ __plugin_meta__ = PluginMetadata( description='米游社', usage='mys签到', extra={ - 'author': '惜月', - 'version': '3.0', + 'author': '惜月', + 'version': '3.0', 'priority': 11, - 'configs': { - '签到开始小时': 0, - '签到开始分钟': 5, - '米游币开始小时': 0, - '米游币开始分钟': 30 - } - } + 'configs': {'签到开始小时': 0, '签到开始分钟': 5, '米游币开始小时': 0, '米游币开始分钟': 30}, + }, ) -sign = on_command('mys签到', aliases={'米游社签到', 'mys自动签到', '米游社自动签到'}, priority=8, block=True, state={ - 'pm_name': '米游社签到', +sign = on_command( + 'mys签到', + aliases={'米游社签到', 'mys自动签到', '米游社自动签到'}, + priority=8, + block=True, + state={ + 'pm_name': '米游社签到', 'pm_description': '*执行米游社签到操作,或开启每日自动签到', - 'pm_usage': '米游社签到(uid)[on|off]', - 'pm_priority': 1 - }) -all_sign = on_command('全部重签', priority=8, block=True, permission=SUPERUSER, rule=to_me(), state={ - 'pm_name': '米游社全部重签', + 'pm_usage': '米游社签到(uid)[on|off]', + 'pm_priority': 1, + }, +) +all_sign = on_command( + '全部重签', + priority=8, + block=True, + permission=SUPERUSER, + rule=to_me(), + state={ + 'pm_name': '米游社全部重签', 'pm_description': '重签全部米游社签到任务,需超级用户权限', - 'pm_usage': '@Bot 全部重签', - 'pm_priority': 3 - }) + 'pm_usage': '@Bot 全部重签', + 'pm_priority': 3, + }, +) -get_coin = on_command('myb获取', aliases={'米游币获取', 'myb自动获取', '米游币自动获取', '米游币任务'}, priority=8, block=True, state={ - 'pm_name': '米游币获取', +get_coin = on_command( + 'myb获取', + aliases={'米游币获取', 'myb自动获取', '米游币自动获取', '米游币任务'}, + priority=8, + block=True, + state={ + 'pm_name': '米游币获取', 'pm_description': '*执行米游币任务操作,或开启每日自动获取米游币', - 'pm_usage': '米游币获取(uid)[on|off]', - 'pm_priority': 2 - }) + 'pm_usage': '米游币获取(uid)[on|off]', + 'pm_priority': 2, + }, +) -all_coin = on_command('myb全部重做', priority=8, block=True, permission=SUPERUSER, rule=to_me(), state={ - 'pm_name': '米游币获取全部重做', +all_coin = on_command( + 'myb全部重做', + priority=8, + block=True, + permission=SUPERUSER, + rule=to_me(), + state={ + 'pm_name': '米游币获取全部重做', 'pm_description': '重做全部米游币获取任务,需超级用户权限', - 'pm_usage': '@Bot myb全部重做', - 'pm_priority': 4 - }) + 'pm_usage': '@Bot myb全部重做', + 'pm_priority': 4, + }, +) signing_list = [] @@ -63,30 +84,44 @@ coin_getting_list = [] @sign.handle() -async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], uid=CommandUID(), switch=CommandSwitch()): +async def _( + event: Union[GroupMessageEvent, PrivateMessageEvent], + uid=CommandUID(), + switch=CommandSwitch(), +): if switch is None: # 没有开关参数,手动执行米游社签到 if f'{event.user_id}-{uid}' in signing_list: await sign.finish('你已经在执行签到任务中,请勿重复发送', at_sender=True) else: await sign.send(f'开始为UID{uid}执行米游社签到,请稍等...', at_sender=True) - logger.info('米游社原神签到', '', {'user_id': event.user_id, 'uid': uid, '执行签到': ''}) + logger.info( + '米游社原神签到', '', {'user_id': event.user_id, 'uid': uid, '执行签到': ''} + ) signing_list.append(f'{event.user_id}-{uid}') - _, result = await mhy_bbs_sign(str(event.user_id), uid) - signing_list.remove(f'{event.user_id}-{uid}') + try: + _, result = await mhy_bbs_sign(str(event.user_id), uid) + except Exception as e: + result = f'UID{uid}签到失败,报错信息:{str(e)}' + finally: + signing_list.remove(f'{event.user_id}-{uid}') await sign.finish(result, at_sender=True) else: - sub_data = { - 'user_id': event.user_id, - 'uid': uid, - 'sub_event': '米游社原神签到' - } + sub_data = {'user_id': event.user_id, 'uid': uid, 'sub_event': '米游社原神签到'} if switch: # switch为开启,则添加订阅 if await PrivateCookie.get_or_none(user_id=str(event.user_id), uid=uid): - await MihoyoBBSSub.update_or_create(**sub_data, defaults={ - 'group_id': event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}) - logger.info('米游社原神签到', '', {'user_id': event.user_id, 'uid': uid}, '开启成功', True) + await MihoyoBBSSub.update_or_create( + **sub_data, + defaults={ + 'group_id': event.group_id + if isinstance(event, GroupMessageEvent) + else event.user_id + }, + ) + logger.info( + '米游社原神签到', '', {'user_id': event.user_id, 'uid': uid}, '开启成功', True + ) await sign.finish(f'UID{uid}开启米游社原神自动签到成功', at_sender=True) else: await sign.finish(f'UID{uid}尚未绑定Cookie!请先使用ysb指令绑定吧!', at_sender=True) @@ -94,7 +129,9 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], uid=CommandUID # switch为关闭,则取消订阅 if sub := await MihoyoBBSSub.get_or_none(**sub_data): await sub.delete() - logger.info('米游社原神签到', '', {'user_id': event.user_id, 'uid': uid}, '关闭成功', True) + logger.info( + '米游社原神签到', '', {'user_id': event.user_id, 'uid': uid}, '关闭成功', True + ) await sign.finish(f'UID{uid}关闭米游社原神自动签到成功', at_sender=True) else: await sign.finish(f'UID{uid}尚未开启米游社原神自动签到,无需关闭!', at_sender=True) @@ -107,38 +144,61 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent]): @get_coin.handle() -async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], uid=CommandUID(), switch=CommandSwitch()): +async def _( + event: Union[GroupMessageEvent, PrivateMessageEvent], + uid=CommandUID(), + switch=CommandSwitch(), +): if switch is None: # 没有开关参数,手动执行米游币获取 if f'{event.user_id}-{uid}' in coin_getting_list: await get_coin.finish('你已经在执行米游币获取任务中,请勿重复发送', at_sender=True) else: await get_coin.send(f'开始为UID{uid}执行米游币获取,请稍等...', at_sender=True) - logger.info('米游币自动获取', '', {'user_id': event.user_id, 'uid': uid, '执行获取': ''}) + logger.info( + '米游币自动获取', '', {'user_id': event.user_id, 'uid': uid, '执行获取': ''} + ) coin_getting_list.append(f'{event.user_id}-{uid}') - result = await mhy_bbs_coin(str(event.user_id), uid) - coin_getting_list.remove(f'{event.user_id}-{uid}') + try: + result = await mhy_bbs_coin(str(event.user_id), uid) + except Exception as e: + result = f'UID{uid}米游币执行失败,报错信息:{str(e)}' + finally: + coin_getting_list.remove(f'{event.user_id}-{uid}') await get_coin.finish(result, at_sender=True) else: - sub_data = { - 'user_id': event.user_id, - 'uid': uid, - 'sub_event': '米游币自动获取' - } + sub_data = {'user_id': event.user_id, 'uid': uid, 'sub_event': '米游币自动获取'} if switch: # switch为开启,则添加订阅 - if (ck := await PrivateCookie.get_or_none(user_id=str(event.user_id), uid=uid)) and ck.stoken is not None: - await MihoyoBBSSub.update_or_create(**sub_data, defaults={ - 'group_id': event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}) - logger.info('米游币自动获取', '', {'user_id': event.user_id, 'uid': uid}, '开启成功', True) + if ( + ck := await PrivateCookie.get_or_none( + user_id=str(event.user_id), uid=uid + ) + ) and ck.stoken is not None: + await MihoyoBBSSub.update_or_create( + **sub_data, + defaults={ + 'group_id': event.group_id + if isinstance(event, GroupMessageEvent) + else event.user_id + }, + ) + logger.info( + '米游币自动获取', '', {'user_id': event.user_id, 'uid': uid}, '开启成功', True + ) await sign.finish(f'UID{uid}开启米游币自动获取成功', at_sender=True) else: - await get_coin.finish(f'UID{uid}尚未绑定Cookie或Cookie中没有login_ticket!请先使用ysb指令绑定吧!', at_sender=True) + await get_coin.finish( + f'UID{uid}尚未绑定Cookie或Cookie中没有login_ticket!请先使用ysb指令绑定吧!', + at_sender=True, + ) else: # switch为关闭,则取消订阅 if sub := await MihoyoBBSSub.get_or_none(**sub_data): await sub.delete() - logger.info('米游币自动获取', '', {'user_id': event.user_id, 'uid': uid}, '关闭成功', True) + logger.info( + '米游币自动获取', '', {'user_id': event.user_id, 'uid': uid}, '关闭成功', True + ) await sign.finish(f'UID{uid}关闭米游币自动获取成功', at_sender=True) else: await sign.finish(f'UID{uid}尚未开启米游币自动获取,无需关闭!', at_sender=True) diff --git a/LittlePaimon/plugins/Paimon_Gacha_Log/__init__.py b/LittlePaimon/plugins/Paimon_Gacha_Log/__init__.py index 1fb4e51..8bdfb30 100644 --- a/LittlePaimon/plugins/Paimon_Gacha_Log/__init__.py +++ b/LittlePaimon/plugins/Paimon_Gacha_Log/__init__.py @@ -1,49 +1,83 @@ from typing import Union from nonebot import on_command -from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, PrivateMessageEvent +from nonebot.adapters.onebot.v11 import ( + Bot, + MessageEvent, + GroupMessageEvent, + PrivateMessageEvent, +) from nonebot.plugin import PluginMetadata from LittlePaimon.utils import logger from LittlePaimon.utils.message import CommandPlayer -from .data_source import get_gacha_log_img, get_gacha_log_data, create_import_command, gacha_log_to_UIGF +from .data_source import ( + get_gacha_log_img, + get_gacha_log_data, + create_import_command, + gacha_log_to_UIGF, +) __plugin_meta__ = PluginMetadata( name="原神抽卡记录分析", description="小派蒙的原神抽卡记录模块", usage='', extra={ - 'type': '原神抽卡记录', - "author": "惜月 <277073121@qq.com>", - "version": "3.0.0", + 'type': '原神抽卡记录', + "author": "惜月 <277073121@qq.com>", + "version": "3.0.0", 'priority': 10, }, ) -update_log = on_command('更新抽卡记录', aliases={'抽卡记录更新', '获取抽卡记录'}, priority=12, block=True, state={ - 'pm_name': '更新抽卡记录', - 'pm_description': '*通过stoken更新原神抽卡记录', - 'pm_usage': '更新抽卡记录(uid)', - 'pm_priority': 1 -}) -show_log = on_command('查看抽卡记录', aliases={'抽卡记录', '查询抽卡记录'}, priority=12, block=True, state={ - 'pm_name': '查看抽卡记录', - 'pm_description': '*查看你的抽卡记录分析', - 'pm_usage': '查看抽卡记录(uid)', - 'pm_priority': 2 -}) -import_log = on_command('导入抽卡记录', aliases={'抽卡记录导入'}, priority=12, block=True, state={ - 'pm_name': '导入抽卡记录', - 'pm_description': '导入符合UIGF标准的抽卡记录json文件,发送命令后,于5分钟内上传json文件即可', - 'pm_usage': '导入抽卡记录', - 'pm_priority': 3 -}) -export_log = on_command('导出抽卡记录', aliases={'抽卡记录导出'}, priority=12, block=True, state={ - 'pm_name': '导出抽卡记录', - 'pm_description': '导出符合UIGF标准的抽卡记录json文件', - 'pm_usage': '导出抽卡记录', - 'pm_priority': 4 -}) +update_log = on_command( + '更新抽卡记录', + aliases={'抽卡记录更新', '获取抽卡记录'}, + priority=12, + block=True, + state={ + 'pm_name': '更新抽卡记录', + 'pm_description': '*通过stoken更新原神抽卡记录', + 'pm_usage': '更新抽卡记录(uid)', + 'pm_priority': 1, + }, +) +show_log = on_command( + '查看抽卡记录', + aliases={'抽卡记录', '查询抽卡记录'}, + priority=12, + block=True, + state={ + 'pm_name': '查看抽卡记录', + 'pm_description': '*查看你的抽卡记录分析', + 'pm_usage': '查看抽卡记录(uid)', + 'pm_priority': 2, + }, +) +import_log = on_command( + '导入抽卡记录', + aliases={'抽卡记录导入'}, + priority=12, + block=True, + state={ + 'pm_name': '导入抽卡记录', + 'pm_description': '导入符合UIGF标准的抽卡记录json文件,发送命令后,于5分钟内上传json文件即可', + 'pm_usage': '导入抽卡记录', + 'pm_priority': 3, + }, +) +export_log = on_command( + '导出抽卡记录', + aliases={'抽卡记录导出'}, + priority=12, + block=True, + state={ + 'pm_name': '导出抽卡记录', + 'pm_description': '导出符合UIGF标准的抽卡记录json文件', + 'pm_usage': '导出抽卡记录', + 'pm_priority': 4, + }, +) running_update = [] running_show = [] @@ -62,7 +96,8 @@ async def _(event: MessageEvent, player=CommandPlayer(1)): except Exception as e: logger.info('原神抽卡记录', f'➤➤更新抽卡记录时出现错误:{e}') await update_log.send(f'更新抽卡记录时出现错误:{e}') - running_update.remove(f'{player[0].user_id}-{player[0].uid}') + finally: + running_update.remove(f'{player[0].user_id}-{player[0].uid}') @show_log.handle() @@ -70,16 +105,25 @@ async def _(event: MessageEvent, player=CommandPlayer(1)): if f'{player[0].user_id}-{player[0].uid}' in running_show: await update_log.finish(f'UID{player[0].uid}已经在绘制抽卡记录分析中,请勿重复发送') else: - logger.info('原神抽卡记录', '➤', {'用户': player[0].user_id, 'UID': player[0].uid}, '开始绘制抽卡记录图片', True) + logger.info( + '原神抽卡记录', + '➤', + {'用户': player[0].user_id, 'UID': player[0].uid}, + '开始绘制抽卡记录图片', + True, + ) running_show.append(f'{player[0].user_id}-{player[0].uid}') await update_log.send(f'开始为UID{player[0].uid}绘制抽卡记录分析,请稍候...') try: - result = await get_gacha_log_img(player[0].user_id, player[0].uid, event.sender.nickname) + result = await get_gacha_log_img( + player[0].user_id, player[0].uid, event.sender.nickname + ) await show_log.send(result, at_sender=True) except Exception as e: logger.info('原神抽卡记录', f'➤➤绘制抽卡记录图片时出现错误:{e}') await update_log.send(f'绘制抽卡记录分析时出现错误:{e}') - running_show.remove(f'{player[0].user_id}-{player[0].uid}') + finally: + running_show.remove(f'{player[0].user_id}-{player[0].uid}') @import_log.handle() @@ -89,15 +133,23 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent]): @export_log.handle() -async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], bot: Bot, player=CommandPlayer(1)): +async def _( + event: Union[GroupMessageEvent, PrivateMessageEvent], + bot: Bot, + player=CommandPlayer(1), +): state, msg, path = gacha_log_to_UIGF(player[0].user_id, player[0].uid) if not state: await export_log.finish(msg, at_sender=True) else: try: if isinstance(event, GroupMessageEvent): - await bot.upload_group_file(group_id=event.group_id, file=str(path.absolute()), name=path.name) + await bot.upload_group_file( + group_id=event.group_id, file=str(path.absolute()), name=path.name + ) else: - await bot.upload_private_file(user_id=event.user_id, file=str(path.absolute()), name=path.name) + await bot.upload_private_file( + user_id=event.user_id, file=str(path.absolute()), name=path.name + ) except Exception as e: await export_log.finish(f'上传文件失败,错误信息:{e}', at_sender=True) diff --git a/LittlePaimon/plugins/Paimon_Info/__init__.py b/LittlePaimon/plugins/Paimon_Info/__init__.py index 79d54da..9fd3175 100644 --- a/LittlePaimon/plugins/Paimon_Info/__init__.py +++ b/LittlePaimon/plugins/Paimon_Info/__init__.py @@ -25,71 +25,124 @@ __plugin_meta__ = PluginMetadata( description='原神信息查询', usage='...', extra={ - 'author': '惜月', - 'version': '3.0', + 'author': '惜月', + 'version': '3.0', 'priority': 1, - } + }, ) def has_raw_rule(event: MessageEvent) -> bool: - return bool(event.reply and (YSC_TEMP_IMG_PATH / f'{event.reply.message_id}.jpg').exists()) + return bool( + event.reply and (YSC_TEMP_IMG_PATH / f'{event.reply.message_id}.jpg').exists() + ) -ys = on_command('ys', aliases={'原神卡片', '个人卡片'}, priority=10, block=True, state={ - 'pm_name': 'ys', - 'pm_description': '查看原神个人信息卡片', - 'pm_usage': 'ys(uid)', - 'pm_priority': 1 -}) -ysa = on_command('ysa', aliases={'角色背包', '练度统计'}, priority=10, block=True, state={ - 'pm_name': 'ysa', - 'pm_description': '查看角色背包及练度排行', - 'pm_usage': 'ysa(uid)', - 'pm_priority': 2 -}) -ysc = on_command('ysc', aliases={'角色图', '角色卡片'}, priority=10, block=True, state={ - 'pm_name': 'ysc', - 'pm_description': '随机角色同人图+角色信息卡片', - 'pm_usage': 'ysc(uid)<角色名>', - 'pm_priority': 4 -}) -ysd = on_command('ysd', aliases={'角色详情', '角色信息', '角色面板'}, priority=10, block=True, state={ - 'pm_name': 'ysd', - 'pm_description': '查看指定角色的详细面板数据及伤害计算', - 'pm_usage': 'ysd(uid)<角色名>', - 'pm_priority': 5 -}) -update_info = on_command('udi', aliases={'更新角色信息', '更新面板', '更新玩家信息'}, priority=10, block=True, state={ - 'pm_name': 'udi', - 'pm_description': '更新你的原神玩家和角色数据,绑定cookie后数据更详细,加上"天赋"可以更新天赋等级', - 'pm_usage': '更新角色信息[天赋](uid)', - 'pm_priority': 6 -}) -add_alias = on_command('设置别名', priority=10, block=True, state={ - 'pm_name': '角色别名设置', - 'pm_description': '设置专属于你的角色别名,例如【设置别名钟离 老公】', - 'pm_usage': '设置别名<角色> <别名>', - 'pm_priority': 7 -}) -delete_alias = on_command('删除别名', priority=10, block=True, state={ - 'pm_name': '角色别名删除', - 'pm_description': '删除你已设置的角色别名', - 'pm_usage': '删除别名<别名>', - 'pm_priority': 8 -}) -show_alias = on_command('查看别名', priority=10, block=True, state={ - 'pm_name': '角色别名查看', - 'pm_description': '查看你已设置的角色别名', - 'pm_usage': '查看别名', - 'pm_priority': 9 -}) -raw_img_cmd = on_command('原图', priority=10, block=True, rule=Rule(has_raw_rule), state={ - 'pm_name': 'ysc原图', - 'pm_description': '获取ysc指令卡片中的原神同人图', - 'pm_usage': '(回复ysc消息) 原图', - 'pm_priority': 10 -}) +ys = on_command( + 'ys', + aliases={'原神卡片', '个人卡片'}, + priority=10, + block=True, + state={ + 'pm_name': 'ys', + 'pm_description': '查看原神个人信息卡片', + 'pm_usage': 'ys(uid)', + 'pm_priority': 1, + }, +) +ysa = on_command( + 'ysa', + aliases={'角色背包', '练度统计'}, + priority=10, + block=True, + state={ + 'pm_name': 'ysa', + 'pm_description': '查看角色背包及练度排行', + 'pm_usage': 'ysa(uid)', + 'pm_priority': 2, + }, +) +ysc = on_command( + 'ysc', + aliases={'角色图', '角色卡片'}, + priority=10, + block=True, + state={ + 'pm_name': 'ysc', + 'pm_description': '随机角色同人图+角色信息卡片', + 'pm_usage': 'ysc(uid)<角色名>', + 'pm_priority': 4, + }, +) +ysd = on_command( + 'ysd', + aliases={'角色详情', '角色信息', '角色面板'}, + priority=10, + block=True, + state={ + 'pm_name': 'ysd', + 'pm_description': '查看指定角色的详细面板数据及伤害计算', + 'pm_usage': 'ysd(uid)<角色名>', + 'pm_priority': 5, + }, +) +update_info = on_command( + 'udi', + aliases={'更新角色信息', '更新面板', '更新玩家信息'}, + priority=10, + block=True, + state={ + 'pm_name': 'udi', + 'pm_description': '更新你的原神玩家和角色数据,绑定cookie后数据更详细,加上"天赋"可以更新天赋等级', + 'pm_usage': '更新角色信息[天赋](uid)', + 'pm_priority': 6, + }, +) +add_alias = on_command( + '设置别名', + priority=10, + block=True, + state={ + 'pm_name': '角色别名设置', + 'pm_description': '设置专属于你的角色别名,例如【设置别名钟离 老公】', + 'pm_usage': '设置别名<角色> <别名>', + 'pm_priority': 7, + }, +) +delete_alias = on_command( + '删除别名', + priority=10, + block=True, + state={ + 'pm_name': '角色别名删除', + 'pm_description': '删除你已设置的角色别名', + 'pm_usage': '删除别名<别名>', + 'pm_priority': 8, + }, +) +show_alias = on_command( + '查看别名', + priority=10, + block=True, + state={ + 'pm_name': '角色别名查看', + 'pm_description': '查看你已设置的角色别名', + 'pm_usage': '查看别名', + 'pm_priority': 9, + }, +) +raw_img_cmd = on_command( + '原图', + priority=10, + block=True, + rule=Rule(has_raw_rule), + state={ + 'pm_name': 'ysc原图', + 'pm_description': '获取ysc指令卡片中的原神同人图', + 'pm_usage': '(回复ysc消息) 原图', + 'pm_priority': 10, + }, +) @ys.handle() @@ -128,7 +181,9 @@ async def _(event: MessageEvent, players=CommandPlayer(2)): await ysa.send(f'UID{player.uid}正在绘制角色背包,请勿重复发送指令') else: running_ysa.append(f'{player.user_id}-{player.uid}') - logger.info('原神角色背包', '➤ ', {'用户': players[0].user_id, 'UID': players[0].uid}) + logger.info( + '原神角色背包', '➤ ', {'用户': players[0].user_id, 'UID': players[0].uid} + ) gim = GenshinInfoManager(player.user_id, player.uid) player_info, characters_list = await gim.get_chara_bag() if isinstance(player_info, str): @@ -151,7 +206,11 @@ async def _(event: MessageEvent, players=CommandPlayer(2)): @ysc.handle() -async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), characters=CommandCharacter()): +async def _( + event: MessageEvent, + players=CommandPlayer(only_cn=False), + characters=CommandCharacter(), +): logger.info('原神角色卡片', '开始执行') msg = Message() temp_img = None @@ -164,7 +223,9 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character character_info = await gim.get_character(name=character) if not character_info: logger.info('原神角色卡片', '➤➤', {'角色': character}, '没有该角色信息,发送随机图', True) - msg += MessageSegment.image(f'https://genshin-res.cherishmoon.fun/img?name={character}') + msg += MessageSegment.image( + f'https://genshin-res.cherishmoon.fun/img?name={character}' + ) else: img, temp_img = await draw_chara_card(character_info) logger.info('原神角色卡片', '➤➤', {'角色': character}, '制图完成', True) @@ -177,15 +238,21 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character logger.info('原神角色卡片', '➤', {'用户': player.user_id, 'UID': player.uid}) character_info = await gim.get_character(name=characters[0]) if not character_info: - logger.info('原神角色卡片', '➤➤', {'角色': characters[0]}, '没有该角色信息,发送随机图', True) - msg += MessageSegment.image(f'https://genshin-res.cherishmoon.fun/img?name={characters[0]}') + logger.info( + '原神角色卡片', '➤➤', {'角色': characters[0]}, '没有该角色信息,发送随机图', True + ) + msg += MessageSegment.image( + f'https://genshin-res.cherishmoon.fun/img?name={characters[0]}' + ) else: img, temp_img = await draw_chara_card(character_info) logger.info('原神角色卡片', '➤➤', {'角色': characters[0]}, '制图完成', True) msg += img send_result = await ysd.send(msg, at_sender=True) if temp_img: - temp_img.convert('RGB').save(YSC_TEMP_IMG_PATH / f'{send_result["message_id"]}.jpg', ) + temp_img.convert('RGB').save( + YSC_TEMP_IMG_PATH / f'{send_result["message_id"]}.jpg', + ) @raw_img_cmd.handle() @@ -195,7 +262,11 @@ async def _(event: MessageEvent): @ysd.handle() -async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), characters=CommandCharacter()): +async def _( + event: MessageEvent, + players=CommandPlayer(only_cn=False), + characters=CommandCharacter(), +): logger.info('原神角色面板', '开始执行') msg = Message() try: @@ -203,9 +274,13 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character # 当查询对象只有一个时,查询所有角色 gim = GenshinInfoManager(players[0].user_id, players[0].uid) await LastQuery.update_last_query(players[0].user_id, players[0].uid) - logger.info('原神角色面板', '➤', {'用户': players[0].user_id, 'UID': players[0].uid}) + logger.info( + '原神角色面板', '➤', {'用户': players[0].user_id, 'UID': players[0].uid} + ) for character in characters: - character_info = await gim.get_character(name=character, data_source='enka') + character_info = await gim.get_character( + name=character, data_source='enka' + ) if not character_info: logger.info('原神角色面板', '➤➤', {'角色': character}, '没有该角色信息', False) msg += f'\n暂无你{character}信息,请在游戏内展柜放置该角色' @@ -219,7 +294,9 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character gim = GenshinInfoManager(player.user_id, player.uid) await LastQuery.update_last_query(player.user_id, player.uid) logger.info('原神角色面板', '➤', {'用户': player.user_id, 'UID': player.uid}) - character_info = await gim.get_character(name=characters[0], data_source='enka') + character_info = await gim.get_character( + name=characters[0], data_source='enka' + ) if not character_info: msg += f'\n暂无{player.uid}的{characters[0]}信息,请在游戏内展柜放置该角色' else: @@ -240,7 +317,9 @@ running_udi = [] async def _(event: MessageEvent, state: T_State, uid=CommandUID()): msg = state['clear_msg'] if not freq_limiter.check(f'udi{uid}'): - await update_info.finish(f'UID{uid}: 更新信息冷却剩余{freq_limiter.left(f"udi{uid}")}秒\n', at_sender=True) + await update_info.finish( + f'UID{uid}: 更新信息冷却剩余{freq_limiter.left(f"udi{uid}")}秒\n', at_sender=True + ) elif f'{event.user_id}-{uid}' in running_udi: await update_info.finish(f'UID{uid}正在更新信息中,请勿重复发送指令') else: @@ -249,14 +328,15 @@ async def _(event: MessageEvent, state: T_State, uid=CommandUID()): include_talent = any(i in msg for i in ['全部', '技能', '天赋', 'talent', 'all']) await update_info.send('开始更新原神信息,请稍后...') logger.info('原神信息', '➤开始更新', {'用户': event.user_id, 'UID': uid}) - freq_limiter.start(f'udi{uid}', 180) + freq_limiter.start(f'udi{uid}', 60) gim = GenshinInfoManager(str(event.user_id), uid) result = await gim.update_all(include_talent) except KeyError as e: result = f'更新失败,缺少{e}的数据,可能是Enka.Network接口出现问题' except Exception as e: result = f'更新失败,错误信息:{e}' - running_udi.remove(f'{event.user_id}-{uid}') + finally: + running_udi.remove(f'{event.user_id}-{uid}') await update_info.finish(f'UID{uid}:\n{result}', at_sender=True) @@ -271,10 +351,19 @@ async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()): state['alias'] = Message(msg[1]) -@add_alias.got('alias', prompt=Message.template('你想把{chara}设置为你的谁呢?'), - parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}吧')]) -async def _(event: MessageEvent, chara: str = ArgPlainText('chara'), alias: str = ArgPlainText('alias')): - await PlayerAlias.update_or_create(user_id=str(event.user_id), alias=alias, defaults={'character': chara}) +@add_alias.got( + 'alias', + prompt=Message.template('你想把{chara}设置为你的谁呢?'), + parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}吧')], +) +async def _( + event: MessageEvent, + chara: str = ArgPlainText('chara'), + alias: str = ArgPlainText('alias'), +): + await PlayerAlias.update_or_create( + user_id=str(event.user_id), alias=alias, defaults={'character': chara} + ) await add_alias.finish(f'设置成功,{NICKNAME}知道{chara}是你的{alias}啦..') @@ -283,14 +372,20 @@ async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()): if msg: state['alias'] = msg elif aliases := await PlayerAlias.filter(user_id=str(event.user_id)).all(): - state['msg'] = '你已设置以下别名:\n' + '\n'.join( - [f'{i.alias} -> {i.character}' for i in aliases]) + '\n请输入你想删除的别名或发送"全部"删除全部别名' + state['msg'] = ( + '你已设置以下别名:\n' + + '\n'.join([f'{i.alias} -> {i.character}' for i in aliases]) + + '\n请输入你想删除的别名或发送"全部"删除全部别名' + ) else: await delete_alias.finish('你还没有设置任何别名哦') -@delete_alias.got('alias', prompt=Message.template('{msg}'), - parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}吧')]) +@delete_alias.got( + 'alias', + prompt=Message.template('{msg}'), + parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}吧')], +) async def _(event: MessageEvent, msg: str = ArgPlainText('alias')): if msg == '全部': await PlayerAlias.filter(user_id=str(event.user_id)).delete() @@ -305,7 +400,10 @@ async def _(event: MessageEvent, msg: str = ArgPlainText('alias')): @show_alias.handle() async def _(event: MessageEvent): if aliases := await PlayerAlias.filter(user_id=str(event.user_id)).all(): - await show_alias.finish('你已设以下别名:' + '\n'.join(f'{alias.alias}->{alias.character}' for alias in aliases), - at_sender=True) + await show_alias.finish( + '你已设以下别名:' + + '\n'.join(f'{alias.alias}->{alias.character}' for alias in aliases), + at_sender=True, + ) else: await show_alias.finish('你还没有设置过角色别名哦', at_sender=True) diff --git a/LittlePaimon/utils/__init__.py b/LittlePaimon/utils/__init__.py index 39ae4c5..4e3c5dc 100644 --- a/LittlePaimon/utils/__init__.py +++ b/LittlePaimon/utils/__init__.py @@ -4,7 +4,7 @@ from nonebot import get_driver from .logger import logger from .scheduler import scheduler -__version__ = '3.0.6' +__version__ = '3.0.8' DRIVER = get_driver() try: @@ -20,11 +20,4 @@ try: except Exception: NICKNAME = '派蒙' -__all__ = [ - 'logger', - 'scheduler', - 'DRIVER', - 'SUPERUSERS', - 'NICKNAME', - '__version__' -] +__all__ = ['logger', 'scheduler', 'DRIVER', 'SUPERUSERS', 'NICKNAME', '__version__'] diff --git a/LittlePaimon/utils/api.py b/LittlePaimon/utils/api.py index fc0ba9b..135f345 100644 --- a/LittlePaimon/utils/api.py +++ b/LittlePaimon/utils/api.py @@ -16,20 +16,34 @@ from .requests import aiorequests # MIHOYO_API = 'https://api-takumi-record.mihoyo.com/' # MIHOYO_API_OLD = 'https://api-takumi.mihoyo.com/' -ABYSS_API = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/spiralAbyss' -PLAYER_CARD_API = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index' -CHARACTER_DETAIL_API = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character' -CHARACTER_SKILL_API = 'https://api-takumi.mihoyo.com/event/e20200928calculate/v1/sync/avatar/detail' +ABYSS_API = ( + 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/spiralAbyss' +) +PLAYER_CARD_API = ( + 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index' +) +CHARACTER_DETAIL_API = ( + 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character' +) +CHARACTER_SKILL_API = ( + 'https://api-takumi.mihoyo.com/event/e20200928calculate/v1/sync/avatar/detail' +) MONTH_INFO_API = 'https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo' -DAILY_NOTE_API = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote' -GAME_RECORD_API = 'https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard' +DAILY_NOTE_API = ( + 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote' +) +GAME_RECORD_API = ( + 'https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard' +) SIGN_INFO_API = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/info' SIGN_REWARD_API = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/home' SIGN_ACTION_API = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign' AUTHKEY_API = 'https://api-takumi.mihoyo.com/binding/api/genAuthKey' STOKEN_API = 'https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket' COOKIE_TOKEN_API = 'https://api-takumi.mihoyo.com/auth/api/getCookieAccountInfoBySToken' -LOGIN_TICKET_INFO_API = 'https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket' +LOGIN_TICKET_INFO_API = ( + 'https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket' +) def md5(text: str) -> str: @@ -51,7 +65,7 @@ def random_hex(length: int) -> str: :param length: 长度 :return: 随机字符串 """ - result = hex(random.randint(0, 16 ** length)).replace('0x', '').upper() + result = hex(random.randint(0, 16**length)).replace('0x', '').upper() if len(result) < length: result = '0' * (length - len(result)) + result return result @@ -110,14 +124,14 @@ def mihoyo_headers(cookie, q='', b=None) -> dict: :return: headers """ return { - 'DS': get_ds(q, b), - 'Origin': 'https://webstatic.mihoyo.com', - 'Cookie': cookie, + 'DS': get_ds(q, b), + 'Origin': 'https://webstatic.mihoyo.com', + 'Cookie': cookie, 'x-rpc-app_version': "2.11.1", - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS ' - 'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS ' + 'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/' + 'Referer': 'https://webstatic.mihoyo.com/', } @@ -129,17 +143,17 @@ def mihoyo_sign_headers(cookie: str, extra_headers: Optional[dict] = None) -> di :return: headers """ header = { - 'User_Agent': 'Mozilla/5.0 (Linux; Android 12; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) ' - 'Version/4.0 Chrome/103.0.5060.129 Mobile Safari/537.36 miHoYoBBS/2.35.2', - 'Cookie': cookie, - 'x-rpc-device_id': random_hex(32), - 'Origin': 'https://webstatic.mihoyo.com', - 'X_Requested_With': 'com.mihoyo.hyperion', - 'DS': get_old_version_ds(mhy_bbs=True), + 'User_Agent': 'Mozilla/5.0 (Linux; Android 12; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'Version/4.0 Chrome/103.0.5060.129 Mobile Safari/537.36 miHoYoBBS/2.35.2', + 'Cookie': cookie, + 'x-rpc-device_id': random_hex(32), + 'Origin': 'https://webstatic.mihoyo.com', + 'X_Requested_With': 'com.mihoyo.hyperion', + 'DS': get_old_version_ds(mhy_bbs=True), 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id' - '=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon', - 'x-rpc-app_version': '2.35.2' + 'Referer': 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id' + '=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon', + 'x-rpc-app_version': '2.35.2', } if extra_headers: header.update(extra_headers) @@ -165,7 +179,10 @@ async def check_retcode(data: dict, cookie_info, user_id: str, uid: str) -> bool logger.info('原神Cookie', f'用户{user_id}的私人cookie{uid}疑似失效') elif cookie_info.status == 0: await cookie_info.delete() - logger.info('原神Cookie', f'用户{user_id}的私人cookie{uid}连续失效,已删除') + logger.info( + '原神Cookie', + f'用户{user_id}的私人cookie{uid}连续失效,已删除', + ) elif isinstance(cookie_info, PublicCookie): await CookieCache.filter(cookie=cookie_info.cookie).delete() await cookie_info.delete() @@ -173,14 +190,18 @@ async def check_retcode(data: dict, cookie_info, user_id: str, uid: str) -> bool else: await PublicCookie.filter(cookie=cookie_info.cookie).delete() await cookie_info.delete() - logger.info('原神Cookie', f'UID{cookie_info.uid}使用的缓存cookie已失效,已删除') + logger.info( + '原神Cookie', f'UID{cookie_info.uid}使用的缓存cookie已失效,已删除' + ) return False elif data['retcode'] == 10101: cookie_info.status = 2 if isinstance(cookie_info, PrivateCookie): cookie_info.status = 2 await cookie_info.save() - logger.info('原神Cookie', f'用户{user_id}的私人cookie{uid}已达到每日30次查询上限') + logger.info( + '原神Cookie', f'用户{user_id}的私人cookie{uid}已达到每日30次查询上限' + ) elif isinstance(cookie_info, PublicCookie): cookie_info.status = 2 await cookie_info.save() @@ -188,18 +209,21 @@ async def check_retcode(data: dict, cookie_info, user_id: str, uid: str) -> bool else: await PublicCookie.filter(cookie=cookie_info.cookie).update(status=2) await cookie_info.delete() - logger.info('原神Cookie', f'UID{cookie_info.uid}使用的缓存cookie已达到每日30次查询上限') + logger.info( + '原神Cookie', f'UID{cookie_info.uid}使用的缓存cookie已达到每日30次查询上限' + ) return False else: if isinstance(cookie_info, PublicCookie) and data['retcode'] != 1034: - await CookieCache.update_or_create(uid=uid, defaults={'cookie': cookie_info.cookie}) + await CookieCache.update_or_create( + uid=uid, defaults={'cookie': cookie_info.cookie} + ) return True -async def get_cookie(user_id: str, - uid: str, - check: bool = True, - own: bool = False) -> Union[None, PrivateCookie, PublicCookie, CookieCache]: +async def get_cookie( + user_id: str, uid: str, check: bool = True, own: bool = False +) -> Union[None, PrivateCookie, PublicCookie, CookieCache]: """ 获取可用的cookie :param user_id: 用户id @@ -208,12 +232,16 @@ async def get_cookie(user_id: str, :param own: 是否只获取和uid对应的cookie """ query = Q(status=1) | Q(status=0) if check else Q(status=1) - if private_cookie := await PrivateCookie.filter(Q(Q(query) & Q(user_id=user_id) & Q(uid=uid))).first(): + if private_cookie := await PrivateCookie.filter( + Q(Q(query) & Q(user_id=user_id) & Q(uid=uid)) + ).first(): return private_cookie elif not own: if cache_cookie := await CookieCache.get_or_none(uid=uid): return cache_cookie - elif private_cookie := await PrivateCookie.filter(Q(Q(query) & Q(user_id=user_id))).first(): + elif private_cookie := await PrivateCookie.filter( + Q(Q(query) & Q(user_id=user_id)) + ).first(): return private_cookie else: return await PublicCookie.filter(Q(query)).first() @@ -223,17 +251,17 @@ async def get_cookie(user_id: str, async def get_bind_game_info(cookie: str, mys_id: str): """ - 通过cookie,获取米游社绑定的原神游戏信息 - :param cookie: cookie - :param mys_id: 米游社id - :return: 原神信息 + 通过cookie,获取米游社绑定的原神游戏信息 + :param cookie: cookie + :param mys_id: 米游社id + :return: 原神信息 """ with contextlib.suppress(Exception): - data = await aiorequests.get(url=GAME_RECORD_API, - headers=mihoyo_headers(cookie, f'uid={mys_id}'), - params={ - 'uid': mys_id - }) + data = await aiorequests.get( + url=GAME_RECORD_API, + headers=mihoyo_headers(cookie, f'uid={mys_id}'), + params={'uid': mys_id}, + ) data = data.json() nb_logger.debug(data) if data['retcode'] == 0: @@ -242,10 +270,11 @@ async def get_bind_game_info(cookie: str, mys_id: str): async def get_mihoyo_public_data( - uid: str, - user_id: Optional[str], - mode: Literal['abyss', 'player_card', 'role_detail'], - schedule_type: Optional[str] = '1'): + uid: str, + user_id: Optional[str], + mode: Literal['abyss', 'player_card', 'role_detail'], + schedule_type: Optional[str] = '1', +): server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01' check = True while True: @@ -254,32 +283,33 @@ async def get_mihoyo_public_data( if not cookie_info: return '当前没有可使用的cookie,请绑定私人cookie或联系超级管理员添加公共cookie,' if mode == 'abyss': - data = await aiorequests.get(url=ABYSS_API, - headers=mihoyo_headers( - q=f'role_id={uid}&schedule_type={schedule_type}&server={server_id}', - cookie=cookie_info.cookie), - params={ - "schedule_type": schedule_type, - "role_id": uid, - "server": server_id} - ) + data = await aiorequests.get( + url=ABYSS_API, + headers=mihoyo_headers( + q=f'role_id={uid}&schedule_type={schedule_type}&server={server_id}', + cookie=cookie_info.cookie, + ), + params={ + "schedule_type": schedule_type, + "role_id": uid, + "server": server_id, + }, + ) elif mode == 'player_card': - data = await aiorequests.get(url=PLAYER_CARD_API, - headers=mihoyo_headers(q=f'role_id={uid}&server={server_id}', - cookie=cookie_info.cookie), - params={ - 'server': server_id, - 'role_id': uid - }) + data = await aiorequests.get( + url=PLAYER_CARD_API, + headers=mihoyo_headers( + q=f'role_id={uid}&server={server_id}', cookie=cookie_info.cookie + ), + params={'server': server_id, 'role_id': uid}, + ) elif mode == 'role_detail': - json_data = { - "server": server_id, - "role_id": uid, - "character_ids": [] - } - data = await aiorequests.post(url=CHARACTER_DETAIL_API, - headers=mihoyo_headers(b=json_data, cookie=cookie_info.cookie), - json=json_data) + json_data = {"server": server_id, "role_id": uid, "character_ids": []} + data = await aiorequests.post( + url=CHARACTER_DETAIL_API, + headers=mihoyo_headers(b=json_data, cookie=cookie_info.cookie), + json=json_data, + ) else: data = None data = data.json() if data else {'retcode': 999} @@ -289,65 +319,65 @@ async def get_mihoyo_public_data( async def get_mihoyo_private_data( - uid: str, - user_id: Optional[str], - mode: Literal['role_skill', 'month_info', 'daily_note', 'sign_info', 'sign_action'], - role_id: Optional[str] = None, - month: Optional[str] = None): + uid: str, + user_id: Optional[str], + mode: Literal['role_skill', 'month_info', 'daily_note', 'sign_info', 'sign_action'], + role_id: Optional[str] = None, + month: Optional[str] = None, +): server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01' cookie_info = await get_cookie(user_id, uid, True, True) if not cookie_info: - return '未绑定私人cookie,绑定方法二选一:\n1.通过米游社扫码绑定:\n请发送指令[原神扫码绑定]\n2.获取cookie的教程:\ndocs.qq.com/doc/DQ3JLWk1vQVllZ2Z1\n获取后,使用[ysb cookie]指令绑定' \ - + (f'或前往{config.CookieWeb_url}网页添加绑定' if config.CookieWeb_enable else '') + return ( + '未绑定私人cookie,绑定方法二选一:\n1.通过米游社扫码绑定:\n请发送指令[原神扫码绑定]\n2.获取cookie的教程:\ndocs.qq.com/doc/DQ3JLWk1vQVllZ2Z1\n获取后,使用[ysb cookie]指令绑定' + + (f'或前往{config.CookieWeb_url}网页添加绑定' if config.CookieWeb_enable else '') + ) if mode == 'role_skill': - data = await aiorequests.get(url=CHARACTER_SKILL_API, - headers=mihoyo_headers(q=f'uid={uid}®ion={server_id}&avatar_id={role_id}', - cookie=cookie_info.cookie), - params={ - "region": server_id, - "uid": uid, - "avatar_id": role_id}) + data = await aiorequests.get( + url=CHARACTER_SKILL_API, + headers=mihoyo_headers( + q=f'uid={uid}®ion={server_id}&avatar_id={role_id}', + cookie=cookie_info.cookie, + ), + params={"region": server_id, "uid": uid, "avatar_id": role_id}, + ) elif mode == 'month_info': - data = await aiorequests.get(url=MONTH_INFO_API, - headers=mihoyo_headers(q=f'month={month}&bind_uid={uid}&bind_region={server_id}', - cookie=cookie_info.cookie), - params={ - "month": month, - "bind_uid": uid, - "bind_region": server_id - }) + data = await aiorequests.get( + url=MONTH_INFO_API, + headers=mihoyo_headers( + q=f'month={month}&bind_uid={uid}&bind_region={server_id}', + cookie=cookie_info.cookie, + ), + params={"month": month, "bind_uid": uid, "bind_region": server_id}, + ) elif mode == 'daily_note': - data = await aiorequests.get(url=DAILY_NOTE_API, - headers=mihoyo_headers(q=f'role_id={uid}&server={server_id}', - cookie=cookie_info.cookie), - params={ - "server": server_id, - "role_id": uid - }) + data = await aiorequests.get( + url=DAILY_NOTE_API, + headers=mihoyo_headers( + q=f'role_id={uid}&server={server_id}', cookie=cookie_info.cookie + ), + params={"server": server_id, "role_id": uid}, + ) elif mode == 'sign_info': - data = await aiorequests.get(url=SIGN_INFO_API, - headers={ - 'x-rpc-app_version': '2.11.1', - 'x-rpc-client_type': '5', - 'Origin': 'https://webstatic.mihoyo.com', - 'Referer': 'https://webstatic.mihoyo.com/', - 'Cookie': cookie_info.cookie, - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS ' - 'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - }, - params={ - 'act_id': 'e202009291139501', - 'region': server_id, - 'uid': uid - }) + data = await aiorequests.get( + url=SIGN_INFO_API, + headers={ + 'x-rpc-app_version': '2.11.1', + 'x-rpc-client_type': '5', + 'Origin': 'https://webstatic.mihoyo.com', + 'Referer': 'https://webstatic.mihoyo.com/', + 'Cookie': cookie_info.cookie, + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS ' + 'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + }, + params={'act_id': 'e202009291139501', 'region': server_id, 'uid': uid}, + ) elif mode == 'sign_action': - data = await aiorequests.post(url=SIGN_ACTION_API, - headers=mihoyo_sign_headers(cookie_info.cookie), - json={ - 'act_id': 'e202009291139501', - 'uid': uid, - 'region': server_id - }) + data = await aiorequests.post( + url=SIGN_ACTION_API, + headers=mihoyo_sign_headers(cookie_info.cookie), + json={'act_id': 'e202009291139501', 'uid': uid, 'region': server_id}, + ) else: data = None data = data.json() if data else {'retcode': 999} @@ -361,16 +391,14 @@ async def get_mihoyo_private_data( async def get_sign_reward_list() -> dict: headers = { 'x-rpc-app_version': '2.11.1', - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (' - 'KHTML, like Gecko) miHoYoBBS/2.11.1', + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (' + 'KHTML, like Gecko) miHoYoBBS/2.11.1', 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/' + 'Referer': 'https://webstatic.mihoyo.com/', } - resp = await aiorequests.get(url=SIGN_REWARD_API, - headers=headers, - params={ - 'act_id': 'e202009291139501' - }) + resp = await aiorequests.get( + url=SIGN_REWARD_API, headers=headers, params={'act_id': 'e202009291139501'} + ) data = resp.json() nb_logger.debug(data) return data @@ -378,19 +406,17 @@ async def get_sign_reward_list() -> dict: async def get_stoken_by_login_ticket(login_ticket: str, mys_id: str) -> Optional[str]: with contextlib.suppress(Exception): - data = await aiorequests.get(STOKEN_API, - headers={ - 'x-rpc-app_version': '2.11.2', - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/', - 'Origin': 'https://webstatic.mihoyo.com', - }, - params={ - 'login_ticket': login_ticket, - 'token_types': '3', - 'uid': mys_id - }) + data = await aiorequests.get( + STOKEN_API, + headers={ + 'x-rpc-app_version': '2.11.2', + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/', + 'Origin': 'https://webstatic.mihoyo.com', + }, + params={'login_ticket': login_ticket, 'token_types': '3', 'uid': mys_id}, + ) data = data.json() return data['data']['list'][0]['token'] return None @@ -398,25 +424,26 @@ async def get_stoken_by_login_ticket(login_ticket: str, mys_id: str) -> Optional async def get_cookie_token_by_stoken(stoken: str, mys_id: str) -> Optional[str]: with contextlib.suppress(Exception): - data = await aiorequests.get(COOKIE_TOKEN_API, - headers={ - 'x-rpc-app_version': '2.11.2', - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/', - 'Origin': 'https://webstatic.mihoyo.com', - 'Cookie': f'stuid={mys_id};stoken={stoken}' - }, - params={ - 'uid': mys_id, - 'stoken': stoken - }) + data = await aiorequests.get( + COOKIE_TOKEN_API, + headers={ + 'x-rpc-app_version': '2.11.2', + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/', + 'Origin': 'https://webstatic.mihoyo.com', + 'Cookie': f'stuid={mys_id};stoken={stoken}', + }, + params={'uid': mys_id, 'stoken': stoken}, + ) data = data.json() return data['data']['cookie_token'] return None -async def get_authkey_by_stoken(user_id: str, uid: str) -> Tuple[Optional[str], bool, Optional[PrivateCookie]]: +async def get_authkey_by_stoken( + user_id: str, uid: str +) -> Tuple[Optional[str], bool, Optional[PrivateCookie]]: """ 根据stoken获取authkey @@ -427,30 +454,38 @@ async def get_authkey_by_stoken(user_id: str, uid: str) -> Tuple[Optional[str], server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01' cookie_info = await get_cookie(user_id, uid, True, True) if not cookie_info: - return '未绑定私人cookie,绑定方法二选一:\n1.通过米游社扫码绑定:\n请发送指令[原神扫码绑定]\n2.获取cookie的教程:\ndocs.qq.com/doc/DQ3JLWk1vQVllZ2Z1\n获取后,使用[ysb cookie]指令绑定' \ - + (f'或前往{config.CookieWeb_url}网页添加绑定' if config.CookieWeb_enable else ''), False, cookie_info + return ( + '未绑定私人cookie,绑定方法二选一:\n1.通过米游社扫码绑定:\n请发送指令[原神扫码绑定]\n2.获取cookie的教程:\ndocs.qq.com/doc/DQ3JLWk1vQVllZ2Z1\n获取后,使用[ysb cookie]指令绑定' + + (f'或前往{config.CookieWeb_url}网页添加绑定' if config.CookieWeb_enable else ''), + False, + cookie_info, + ) if not cookie_info.stoken: return 'cookie中没有stoken字段,请重新绑定', False, cookie_info headers = { - 'Cookie': cookie_info.stoken, - 'DS': get_old_version_ds(True), - 'User-Agent': 'okhttp/4.8.0', - 'x-rpc-app_version': '2.35.2', - 'x-rpc-sys_version': '12', - 'x-rpc-client_type': '5', - 'x-rpc-channel': 'mihoyo', - 'x-rpc-device_id': random_hex(32), - 'x-rpc-device_name': random_text(random.randint(1, 10)), + 'Cookie': cookie_info.stoken, + 'DS': get_old_version_ds(True), + 'User-Agent': 'okhttp/4.8.0', + 'x-rpc-app_version': '2.35.2', + 'x-rpc-sys_version': '12', + 'x-rpc-client_type': '5', + 'x-rpc-channel': 'mihoyo', + 'x-rpc-device_id': random_hex(32), + 'x-rpc-device_name': random_text(random.randint(1, 10)), 'x-rpc-device_model': 'Mi 10', - 'Referer': 'https://app.mihoyo.com', - 'Host': 'api-takumi.mihoyo.com'} - data = await aiorequests.post(url=AUTHKEY_API, - headers=headers, - json={ - 'auth_appid': 'webview_gacha', - 'game_biz': 'hk4e_cn', - 'game_uid': uid, - 'region': server_id}) + 'Referer': 'https://app.mihoyo.com', + 'Host': 'api-takumi.mihoyo.com', + } + data = await aiorequests.post( + url=AUTHKEY_API, + headers=headers, + json={ + 'auth_appid': 'webview_gacha', + 'game_biz': 'hk4e_cn', + 'game_uid': uid, + 'region': server_id, + }, + ) data = data.json() if data.get('data') is not None and 'authkey' in data['data']: return data['data']['authkey'], True, cookie_info @@ -458,16 +493,20 @@ async def get_authkey_by_stoken(user_id: str, uid: str) -> Tuple[Optional[str], return None, False, cookie_info -async def get_enka_data(uid): +async def get_enka_data(uid: str): urls = [ 'https://enka.network/api/uid/{uid}', - 'https://enka.microgg.cn/api/uid/{uid}' + 'https://profile.microgg.cn/api/uid/{uid}', # 以下两个api由小灰灰提供 + 'https://enka.microgg.cn/api/uid/{uid}', ] for url in urls: with contextlib.suppress(Exception): - resp = await aiorequests.get(url=url.format(uid=uid), - headers={'User-Agent': 'LittlePaimon/3.0'}, - follow_redirects=True) + resp = await aiorequests.get( + url=url.format(uid=uid), + headers={'User-Agent': 'LittlePaimon/3.0'}, + follow_redirects=True, + ) data = resp.json() nb_logger.debug(data) - return data + if 'playerInfo' in data: + return data