添加enka备用api

This commit is contained in:
CMHopeSunshine 2023-02-21 20:06:03 +08:00
parent 33c5fbd2da
commit d73ec76dfc
5 changed files with 609 additions and 367 deletions

View File

@ -18,44 +18,65 @@ __plugin_meta__ = PluginMetadata(
description='米游社', description='米游社',
usage='mys签到', usage='mys签到',
extra={ extra={
'author': '惜月', 'author': '惜月',
'version': '3.0', 'version': '3.0',
'priority': 11, 'priority': 11,
'configs': { 'configs': {'签到开始小时': 0, '签到开始分钟': 5, '米游币开始小时': 0, '米游币开始分钟': 30},
'签到开始小时': 0, },
'签到开始分钟': 5,
'米游币开始小时': 0,
'米游币开始分钟': 30
}
}
) )
sign = on_command('mys签到', aliases={'米游社签到', 'mys自动签到', '米游社自动签到'}, priority=8, block=True, state={ sign = on_command(
'pm_name': '米游社签到', 'mys签到',
aliases={'米游社签到', 'mys自动签到', '米游社自动签到'},
priority=8,
block=True,
state={
'pm_name': '米游社签到',
'pm_description': '*执行米游社签到操作,或开启每日自动签到', 'pm_description': '*执行米游社签到操作,或开启每日自动签到',
'pm_usage': '米游社签到(uid)[on|off]', 'pm_usage': '米游社签到(uid)[on|off]',
'pm_priority': 1 'pm_priority': 1,
}) },
all_sign = on_command('全部重签', priority=8, block=True, permission=SUPERUSER, rule=to_me(), state={ )
'pm_name': '米游社全部重签', all_sign = on_command(
'全部重签',
priority=8,
block=True,
permission=SUPERUSER,
rule=to_me(),
state={
'pm_name': '米游社全部重签',
'pm_description': '重签全部米游社签到任务,需超级用户权限', 'pm_description': '重签全部米游社签到任务,需超级用户权限',
'pm_usage': '@Bot 全部重签', 'pm_usage': '@Bot 全部重签',
'pm_priority': 3 'pm_priority': 3,
}) },
)
get_coin = on_command('myb获取', aliases={'米游币获取', 'myb自动获取', '米游币自动获取', '米游币任务'}, priority=8, block=True, state={ get_coin = on_command(
'pm_name': '米游币获取', 'myb获取',
aliases={'米游币获取', 'myb自动获取', '米游币自动获取', '米游币任务'},
priority=8,
block=True,
state={
'pm_name': '米游币获取',
'pm_description': '*执行米游币任务操作,或开启每日自动获取米游币', 'pm_description': '*执行米游币任务操作,或开启每日自动获取米游币',
'pm_usage': '米游币获取(uid)[on|off]', 'pm_usage': '米游币获取(uid)[on|off]',
'pm_priority': 2 'pm_priority': 2,
}) },
)
all_coin = on_command('myb全部重做', priority=8, block=True, permission=SUPERUSER, rule=to_me(), state={ all_coin = on_command(
'pm_name': '米游币获取全部重做', 'myb全部重做',
priority=8,
block=True,
permission=SUPERUSER,
rule=to_me(),
state={
'pm_name': '米游币获取全部重做',
'pm_description': '重做全部米游币获取任务,需超级用户权限', 'pm_description': '重做全部米游币获取任务,需超级用户权限',
'pm_usage': '@Bot myb全部重做', 'pm_usage': '@Bot myb全部重做',
'pm_priority': 4 'pm_priority': 4,
}) },
)
signing_list = [] signing_list = []
@ -63,30 +84,44 @@ coin_getting_list = []
@sign.handle() @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 switch is None:
# 没有开关参数,手动执行米游社签到 # 没有开关参数,手动执行米游社签到
if f'{event.user_id}-{uid}' in signing_list: if f'{event.user_id}-{uid}' in signing_list:
await sign.finish('你已经在执行签到任务中,请勿重复发送', at_sender=True) await sign.finish('你已经在执行签到任务中,请勿重复发送', at_sender=True)
else: else:
await sign.send(f'开始为UID{uid}执行米游社签到,请稍等...', at_sender=True) 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}') signing_list.append(f'{event.user_id}-{uid}')
_, result = await mhy_bbs_sign(str(event.user_id), uid) try:
signing_list.remove(f'{event.user_id}-{uid}') _, 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) await sign.finish(result, at_sender=True)
else: else:
sub_data = { sub_data = {'user_id': event.user_id, 'uid': uid, 'sub_event': '米游社原神签到'}
'user_id': event.user_id,
'uid': uid,
'sub_event': '米游社原神签到'
}
if switch: if switch:
# switch为开启则添加订阅 # switch为开启则添加订阅
if await PrivateCookie.get_or_none(user_id=str(event.user_id), uid=uid): if await PrivateCookie.get_or_none(user_id=str(event.user_id), uid=uid):
await MihoyoBBSSub.update_or_create(**sub_data, defaults={ await MihoyoBBSSub.update_or_create(
'group_id': event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}) **sub_data,
logger.info('米游社原神签到', '', {'user_id': event.user_id, 'uid': uid}, '开启成功', True) 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) await sign.finish(f'UID{uid}开启米游社原神自动签到成功', at_sender=True)
else: else:
await sign.finish(f'UID{uid}尚未绑定Cookie请先使用ysb指令绑定吧', at_sender=True) await sign.finish(f'UID{uid}尚未绑定Cookie请先使用ysb指令绑定吧', at_sender=True)
@ -94,7 +129,9 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], uid=CommandUID
# switch为关闭则取消订阅 # switch为关闭则取消订阅
if sub := await MihoyoBBSSub.get_or_none(**sub_data): if sub := await MihoyoBBSSub.get_or_none(**sub_data):
await sub.delete() 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) await sign.finish(f'UID{uid}关闭米游社原神自动签到成功', at_sender=True)
else: else:
await sign.finish(f'UID{uid}尚未开启米游社原神自动签到,无需关闭!', at_sender=True) await sign.finish(f'UID{uid}尚未开启米游社原神自动签到,无需关闭!', at_sender=True)
@ -107,38 +144,61 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent]):
@get_coin.handle() @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 switch is None:
# 没有开关参数,手动执行米游币获取 # 没有开关参数,手动执行米游币获取
if f'{event.user_id}-{uid}' in coin_getting_list: if f'{event.user_id}-{uid}' in coin_getting_list:
await get_coin.finish('你已经在执行米游币获取任务中,请勿重复发送', at_sender=True) await get_coin.finish('你已经在执行米游币获取任务中,请勿重复发送', at_sender=True)
else: else:
await get_coin.send(f'开始为UID{uid}执行米游币获取,请稍等...', at_sender=True) 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}') coin_getting_list.append(f'{event.user_id}-{uid}')
result = await mhy_bbs_coin(str(event.user_id), uid) try:
coin_getting_list.remove(f'{event.user_id}-{uid}') 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) await get_coin.finish(result, at_sender=True)
else: else:
sub_data = { sub_data = {'user_id': event.user_id, 'uid': uid, 'sub_event': '米游币自动获取'}
'user_id': event.user_id,
'uid': uid,
'sub_event': '米游币自动获取'
}
if switch: if switch:
# switch为开启则添加订阅 # switch为开启则添加订阅
if (ck := await PrivateCookie.get_or_none(user_id=str(event.user_id), uid=uid)) and ck.stoken is not None: if (
await MihoyoBBSSub.update_or_create(**sub_data, defaults={ ck := await PrivateCookie.get_or_none(
'group_id': event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}) user_id=str(event.user_id), uid=uid
logger.info('米游币自动获取', '', {'user_id': event.user_id, 'uid': uid}, '开启成功', True) )
) 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) await sign.finish(f'UID{uid}开启米游币自动获取成功', at_sender=True)
else: 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: else:
# switch为关闭则取消订阅 # switch为关闭则取消订阅
if sub := await MihoyoBBSSub.get_or_none(**sub_data): if sub := await MihoyoBBSSub.get_or_none(**sub_data):
await sub.delete() 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) await sign.finish(f'UID{uid}关闭米游币自动获取成功', at_sender=True)
else: else:
await sign.finish(f'UID{uid}尚未开启米游币自动获取,无需关闭!', at_sender=True) await sign.finish(f'UID{uid}尚未开启米游币自动获取,无需关闭!', at_sender=True)

View File

@ -1,49 +1,83 @@
from typing import Union from typing import Union
from nonebot import on_command 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 nonebot.plugin import PluginMetadata
from LittlePaimon.utils import logger from LittlePaimon.utils import logger
from LittlePaimon.utils.message import CommandPlayer 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( __plugin_meta__ = PluginMetadata(
name="原神抽卡记录分析", name="原神抽卡记录分析",
description="小派蒙的原神抽卡记录模块", description="小派蒙的原神抽卡记录模块",
usage='', usage='',
extra={ extra={
'type': '原神抽卡记录', 'type': '原神抽卡记录',
"author": "惜月 <277073121@qq.com>", "author": "惜月 <277073121@qq.com>",
"version": "3.0.0", "version": "3.0.0",
'priority': 10, 'priority': 10,
}, },
) )
update_log = on_command('更新抽卡记录', aliases={'抽卡记录更新', '获取抽卡记录'}, priority=12, block=True, state={ update_log = on_command(
'pm_name': '更新抽卡记录', '更新抽卡记录',
'pm_description': '*通过stoken更新原神抽卡记录', aliases={'抽卡记录更新', '获取抽卡记录'},
'pm_usage': '更新抽卡记录(uid)', priority=12,
'pm_priority': 1 block=True,
}) state={
show_log = on_command('查看抽卡记录', aliases={'抽卡记录', '查询抽卡记录'}, priority=12, block=True, state={ 'pm_name': '更新抽卡记录',
'pm_name': '查看抽卡记录', 'pm_description': '*通过stoken更新原神抽卡记录',
'pm_description': '*查看你的抽卡记录分析', 'pm_usage': '更新抽卡记录(uid)',
'pm_usage': '查看抽卡记录(uid)', 'pm_priority': 1,
'pm_priority': 2 },
}) )
import_log = on_command('导入抽卡记录', aliases={'抽卡记录导入'}, priority=12, block=True, state={ show_log = on_command(
'pm_name': '导入抽卡记录', '查看抽卡记录',
'pm_description': '导入符合UIGF标准的抽卡记录json文件发送命令后于5分钟内上传json文件即可', aliases={'抽卡记录', '查询抽卡记录'},
'pm_usage': '导入抽卡记录', priority=12,
'pm_priority': 3 block=True,
}) state={
export_log = on_command('导出抽卡记录', aliases={'抽卡记录导出'}, priority=12, block=True, state={ 'pm_name': '查看抽卡记录',
'pm_name': '导出抽卡记录', 'pm_description': '*查看你的抽卡记录分析',
'pm_description': '导出符合UIGF标准的抽卡记录json文件', 'pm_usage': '查看抽卡记录(uid)',
'pm_usage': '导出抽卡记录', 'pm_priority': 2,
'pm_priority': 4 },
}) )
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_update = []
running_show = [] running_show = []
@ -62,7 +96,8 @@ async def _(event: MessageEvent, player=CommandPlayer(1)):
except Exception as e: except Exception as e:
logger.info('原神抽卡记录', f'➤➤更新抽卡记录时出现错误:<r>{e}</r>') logger.info('原神抽卡记录', f'➤➤更新抽卡记录时出现错误:<r>{e}</r>')
await update_log.send(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() @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: if f'{player[0].user_id}-{player[0].uid}' in running_show:
await update_log.finish(f'UID{player[0].uid}已经在绘制抽卡记录分析中,请勿重复发送') await update_log.finish(f'UID{player[0].uid}已经在绘制抽卡记录分析中,请勿重复发送')
else: 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}') running_show.append(f'{player[0].user_id}-{player[0].uid}')
await update_log.send(f'开始为UID{player[0].uid}绘制抽卡记录分析,请稍候...') await update_log.send(f'开始为UID{player[0].uid}绘制抽卡记录分析,请稍候...')
try: 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) await show_log.send(result, at_sender=True)
except Exception as e: except Exception as e:
logger.info('原神抽卡记录', f'➤➤绘制抽卡记录图片时出现错误:<r>{e}</r>') logger.info('原神抽卡记录', f'➤➤绘制抽卡记录图片时出现错误:<r>{e}</r>')
await update_log.send(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() @import_log.handle()
@ -89,15 +133,23 @@ async def _(event: Union[GroupMessageEvent, PrivateMessageEvent]):
@export_log.handle() @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) state, msg, path = gacha_log_to_UIGF(player[0].user_id, player[0].uid)
if not state: if not state:
await export_log.finish(msg, at_sender=True) await export_log.finish(msg, at_sender=True)
else: else:
try: try:
if isinstance(event, GroupMessageEvent): 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: 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: except Exception as e:
await export_log.finish(f'上传文件失败,错误信息:{e}', at_sender=True) await export_log.finish(f'上传文件失败,错误信息:{e}', at_sender=True)

View File

@ -25,71 +25,124 @@ __plugin_meta__ = PluginMetadata(
description='原神信息查询', description='原神信息查询',
usage='...', usage='...',
extra={ extra={
'author': '惜月', 'author': '惜月',
'version': '3.0', 'version': '3.0',
'priority': 1, 'priority': 1,
} },
) )
def has_raw_rule(event: MessageEvent) -> bool: 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={ ys = on_command(
'pm_name': 'ys', 'ys',
'pm_description': '查看原神个人信息卡片', aliases={'原神卡片', '个人卡片'},
'pm_usage': 'ys(uid)', priority=10,
'pm_priority': 1 block=True,
}) state={
ysa = on_command('ysa', aliases={'角色背包', '练度统计'}, priority=10, block=True, state={ 'pm_name': 'ys',
'pm_name': 'ysa', 'pm_description': '查看原神个人信息卡片',
'pm_description': '查看角色背包及练度排行', 'pm_usage': 'ys(uid)',
'pm_usage': 'ysa(uid)', 'pm_priority': 1,
'pm_priority': 2 },
}) )
ysc = on_command('ysc', aliases={'角色图', '角色卡片'}, priority=10, block=True, state={ ysa = on_command(
'pm_name': 'ysc', 'ysa',
'pm_description': '随机角色同人图+角色信息卡片', aliases={'角色背包', '练度统计'},
'pm_usage': 'ysc(uid)<角色名>', priority=10,
'pm_priority': 4 block=True,
}) state={
ysd = on_command('ysd', aliases={'角色详情', '角色信息', '角色面板'}, priority=10, block=True, state={ 'pm_name': 'ysa',
'pm_name': 'ysd', 'pm_description': '查看角色背包及练度排行',
'pm_description': '查看指定角色的详细面板数据及伤害计算', 'pm_usage': 'ysa(uid)',
'pm_usage': 'ysd(uid)<角色名>', 'pm_priority': 2,
'pm_priority': 5 },
}) )
update_info = on_command('udi', aliases={'更新角色信息', '更新面板', '更新玩家信息'}, priority=10, block=True, state={ ysc = on_command(
'pm_name': 'udi', 'ysc',
'pm_description': '更新你的原神玩家和角色数据绑定cookie后数据更详细加上"天赋"可以更新天赋等级', aliases={'角色图', '角色卡片'},
'pm_usage': '更新角色信息[天赋](uid)', priority=10,
'pm_priority': 6 block=True,
}) state={
add_alias = on_command('设置别名', priority=10, block=True, state={ 'pm_name': 'ysc',
'pm_name': '角色别名设置', 'pm_description': '随机角色同人图+角色信息卡片',
'pm_description': '设置专属于你的角色别名,例如【设置别名钟离 老公】', 'pm_usage': 'ysc(uid)<角色名>',
'pm_usage': '设置别名<角色> <别名>', 'pm_priority': 4,
'pm_priority': 7 },
}) )
delete_alias = on_command('删除别名', priority=10, block=True, state={ ysd = on_command(
'pm_name': '角色别名删除', 'ysd',
'pm_description': '删除你已设置的角色别名', aliases={'角色详情', '角色信息', '角色面板'},
'pm_usage': '删除别名<别名>', priority=10,
'pm_priority': 8 block=True,
}) state={
show_alias = on_command('查看别名', priority=10, block=True, state={ 'pm_name': 'ysd',
'pm_name': '角色别名查看', 'pm_description': '查看指定角色的详细面板数据及伤害计算',
'pm_description': '查看你已设置的角色别名', 'pm_usage': 'ysd(uid)<角色名>',
'pm_usage': '查看别名', 'pm_priority': 5,
'pm_priority': 9 },
}) )
raw_img_cmd = on_command('原图', priority=10, block=True, rule=Rule(has_raw_rule), state={ update_info = on_command(
'pm_name': 'ysc原图', 'udi',
'pm_description': '获取ysc指令卡片中的原神同人图', aliases={'更新角色信息', '更新面板', '更新玩家信息'},
'pm_usage': '(回复ysc消息) 原图', priority=10,
'pm_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() @ys.handle()
@ -128,7 +181,9 @@ async def _(event: MessageEvent, players=CommandPlayer(2)):
await ysa.send(f'UID{player.uid}正在绘制角色背包,请勿重复发送指令') await ysa.send(f'UID{player.uid}正在绘制角色背包,请勿重复发送指令')
else: else:
running_ysa.append(f'{player.user_id}-{player.uid}') 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) gim = GenshinInfoManager(player.user_id, player.uid)
player_info, characters_list = await gim.get_chara_bag() player_info, characters_list = await gim.get_chara_bag()
if isinstance(player_info, str): if isinstance(player_info, str):
@ -151,7 +206,11 @@ async def _(event: MessageEvent, players=CommandPlayer(2)):
@ysc.handle() @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('原神角色卡片', '开始执行') logger.info('原神角色卡片', '开始执行')
msg = Message() msg = Message()
temp_img = None 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) character_info = await gim.get_character(name=character)
if not character_info: if not character_info:
logger.info('原神角色卡片', '➤➤', {'角色': character}, '没有该角色信息,发送随机图', True) 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: else:
img, temp_img = await draw_chara_card(character_info) img, temp_img = await draw_chara_card(character_info)
logger.info('原神角色卡片', '➤➤', {'角色': character}, '制图完成', True) 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}) logger.info('原神角色卡片', '', {'用户': player.user_id, 'UID': player.uid})
character_info = await gim.get_character(name=characters[0]) character_info = await gim.get_character(name=characters[0])
if not character_info: if not character_info:
logger.info('原神角色卡片', '➤➤', {'角色': characters[0]}, '没有该角色信息,发送随机图', True) logger.info(
msg += MessageSegment.image(f'https://genshin-res.cherishmoon.fun/img?name={characters[0]}') '原神角色卡片', '➤➤', {'角色': characters[0]}, '没有该角色信息,发送随机图', True
)
msg += MessageSegment.image(
f'https://genshin-res.cherishmoon.fun/img?name={characters[0]}'
)
else: else:
img, temp_img = await draw_chara_card(character_info) img, temp_img = await draw_chara_card(character_info)
logger.info('原神角色卡片', '➤➤', {'角色': characters[0]}, '制图完成', True) logger.info('原神角色卡片', '➤➤', {'角色': characters[0]}, '制图完成', True)
msg += img msg += img
send_result = await ysd.send(msg, at_sender=True) send_result = await ysd.send(msg, at_sender=True)
if temp_img: 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() @raw_img_cmd.handle()
@ -195,7 +262,11 @@ async def _(event: MessageEvent):
@ysd.handle() @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('原神角色面板', '开始执行') logger.info('原神角色面板', '开始执行')
msg = Message() msg = Message()
try: try:
@ -203,9 +274,13 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character
# 当查询对象只有一个时,查询所有角色 # 当查询对象只有一个时,查询所有角色
gim = GenshinInfoManager(players[0].user_id, players[0].uid) gim = GenshinInfoManager(players[0].user_id, players[0].uid)
await LastQuery.update_last_query(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: 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: if not character_info:
logger.info('原神角色面板', '➤➤', {'角色': character}, '没有该角色信息', False) logger.info('原神角色面板', '➤➤', {'角色': character}, '没有该角色信息', False)
msg += f'\n暂无你{character}信息,请在游戏内展柜放置该角色' 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) gim = GenshinInfoManager(player.user_id, player.uid)
await LastQuery.update_last_query(player.user_id, player.uid) await LastQuery.update_last_query(player.user_id, player.uid)
logger.info('原神角色面板', '', {'用户': player.user_id, 'UID': 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: if not character_info:
msg += f'\n暂无{player.uid}{characters[0]}信息,请在游戏内展柜放置该角色' msg += f'\n暂无{player.uid}{characters[0]}信息,请在游戏内展柜放置该角色'
else: else:
@ -240,7 +317,9 @@ running_udi = []
async def _(event: MessageEvent, state: T_State, uid=CommandUID()): async def _(event: MessageEvent, state: T_State, uid=CommandUID()):
msg = state['clear_msg'] msg = state['clear_msg']
if not freq_limiter.check(f'udi{uid}'): 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: elif f'{event.user_id}-{uid}' in running_udi:
await update_info.finish(f'UID{uid}正在更新信息中,请勿重复发送指令') await update_info.finish(f'UID{uid}正在更新信息中,请勿重复发送指令')
else: 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']) include_talent = any(i in msg for i in ['全部', '技能', '天赋', 'talent', 'all'])
await update_info.send('开始更新原神信息,请稍后...') await update_info.send('开始更新原神信息,请稍后...')
logger.info('原神信息', '➤开始更新', {'用户': event.user_id, 'UID': uid}) 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) gim = GenshinInfoManager(str(event.user_id), uid)
result = await gim.update_all(include_talent) result = await gim.update_all(include_talent)
except KeyError as e: except KeyError as e:
result = f'更新失败,缺少{e}的数据可能是Enka.Network接口出现问题' result = f'更新失败,缺少{e}的数据可能是Enka.Network接口出现问题'
except Exception as e: except Exception as e:
result = f'更新失败,错误信息:{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) 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]) state['alias'] = Message(msg[1])
@add_alias.got('alias', prompt=Message.template('你想把{chara}设置为你的谁呢?'), @add_alias.got(
parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}')]) 'alias',
async def _(event: MessageEvent, chara: str = ArgPlainText('chara'), alias: str = ArgPlainText('alias')): prompt=Message.template('你想把{chara}设置为你的谁呢?'),
await PlayerAlias.update_or_create(user_id=str(event.user_id), alias=alias, defaults={'character': 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}啦..') await add_alias.finish(f'设置成功,{NICKNAME}知道{chara}是你的{alias}啦..')
@ -283,14 +372,20 @@ async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
if msg: if msg:
state['alias'] = msg state['alias'] = msg
elif aliases := await PlayerAlias.filter(user_id=str(event.user_id)).all(): elif aliases := await PlayerAlias.filter(user_id=str(event.user_id)).all():
state['msg'] = '你已设置以下别名:\n' + '\n'.join( state['msg'] = (
[f'{i.alias} -> {i.character}' for i in aliases]) + '\n请输入你想删除的别名或发送"全部"删除全部别名' '你已设置以下别名:\n'
+ '\n'.join([f'{i.alias} -> {i.character}' for i in aliases])
+ '\n请输入你想删除的别名或发送"全部"删除全部别名'
)
else: else:
await delete_alias.finish('你还没有设置任何别名哦') await delete_alias.finish('你还没有设置任何别名哦')
@delete_alias.got('alias', prompt=Message.template('{msg}'), @delete_alias.got(
parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}')]) 'alias',
prompt=Message.template('{msg}'),
parameterless=[HandleCancellation(f'好吧,有事再找{NICKNAME}')],
)
async def _(event: MessageEvent, msg: str = ArgPlainText('alias')): async def _(event: MessageEvent, msg: str = ArgPlainText('alias')):
if msg == '全部': if msg == '全部':
await PlayerAlias.filter(user_id=str(event.user_id)).delete() 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() @show_alias.handle()
async def _(event: MessageEvent): async def _(event: MessageEvent):
if aliases := await PlayerAlias.filter(user_id=str(event.user_id)).all(): 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), await show_alias.finish(
at_sender=True) '你已设以下别名:'
+ '\n'.join(f'{alias.alias}->{alias.character}' for alias in aliases),
at_sender=True,
)
else: else:
await show_alias.finish('你还没有设置过角色别名哦', at_sender=True) await show_alias.finish('你还没有设置过角色别名哦', at_sender=True)

View File

@ -4,7 +4,7 @@ from nonebot import get_driver
from .logger import logger from .logger import logger
from .scheduler import scheduler from .scheduler import scheduler
__version__ = '3.0.6' __version__ = '3.0.8'
DRIVER = get_driver() DRIVER = get_driver()
try: try:
@ -20,11 +20,4 @@ try:
except Exception: except Exception:
NICKNAME = '派蒙' NICKNAME = '派蒙'
__all__ = [ __all__ = ['logger', 'scheduler', 'DRIVER', 'SUPERUSERS', 'NICKNAME', '__version__']
'logger',
'scheduler',
'DRIVER',
'SUPERUSERS',
'NICKNAME',
'__version__'
]

View File

@ -16,20 +16,34 @@ from .requests import aiorequests
# MIHOYO_API = 'https://api-takumi-record.mihoyo.com/' # MIHOYO_API = 'https://api-takumi-record.mihoyo.com/'
# MIHOYO_API_OLD = 'https://api-takumi.mihoyo.com/' # MIHOYO_API_OLD = 'https://api-takumi.mihoyo.com/'
ABYSS_API = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/spiralAbyss' ABYSS_API = (
PLAYER_CARD_API = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index' 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/spiralAbyss'
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' 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' 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' DAILY_NOTE_API = (
GAME_RECORD_API = 'https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard' '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_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_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' SIGN_ACTION_API = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign'
AUTHKEY_API = 'https://api-takumi.mihoyo.com/binding/api/genAuthKey' AUTHKEY_API = 'https://api-takumi.mihoyo.com/binding/api/genAuthKey'
STOKEN_API = 'https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket' STOKEN_API = 'https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket'
COOKIE_TOKEN_API = 'https://api-takumi.mihoyo.com/auth/api/getCookieAccountInfoBySToken' 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: def md5(text: str) -> str:
@ -51,7 +65,7 @@ def random_hex(length: int) -> str:
:param length: 长度 :param length: 长度
:return: 随机字符串 :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: if len(result) < length:
result = '0' * (length - len(result)) + result result = '0' * (length - len(result)) + result
return result return result
@ -110,14 +124,14 @@ def mihoyo_headers(cookie, q='', b=None) -> dict:
:return: headers :return: headers
""" """
return { return {
'DS': get_ds(q, b), 'DS': get_ds(q, b),
'Origin': 'https://webstatic.mihoyo.com', 'Origin': 'https://webstatic.mihoyo.com',
'Cookie': cookie, 'Cookie': cookie,
'x-rpc-app_version': "2.11.1", 'x-rpc-app_version': "2.11.1",
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS ' '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) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1',
'x-rpc-client_type': '5', '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 :return: headers
""" """
header = { header = {
'User_Agent': 'Mozilla/5.0 (Linux; Android 12; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) ' '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', 'Version/4.0 Chrome/103.0.5060.129 Mobile Safari/537.36 miHoYoBBS/2.35.2',
'Cookie': cookie, 'Cookie': cookie,
'x-rpc-device_id': random_hex(32), 'x-rpc-device_id': random_hex(32),
'Origin': 'https://webstatic.mihoyo.com', 'Origin': 'https://webstatic.mihoyo.com',
'X_Requested_With': 'com.mihoyo.hyperion', 'X_Requested_With': 'com.mihoyo.hyperion',
'DS': get_old_version_ds(mhy_bbs=True), 'DS': get_old_version_ds(mhy_bbs=True),
'x-rpc-client_type': '5', 'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id' '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', '=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon',
'x-rpc-app_version': '2.35.2' 'x-rpc-app_version': '2.35.2',
} }
if extra_headers: if extra_headers:
header.update(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'用户<m>{user_id}</m>的私人cookie<m>{uid}</m>疑似失效') logger.info('原神Cookie', f'用户<m>{user_id}</m>的私人cookie<m>{uid}</m>疑似失效')
elif cookie_info.status == 0: elif cookie_info.status == 0:
await cookie_info.delete() await cookie_info.delete()
logger.info('原神Cookie', f'用户<m>{user_id}</m>的私人cookie<m>{uid}</m>连续失效,<r>已删除</r>') logger.info(
'原神Cookie',
f'用户<m>{user_id}</m>的私人cookie<m>{uid}</m>连续失效,<r>已删除</r>',
)
elif isinstance(cookie_info, PublicCookie): elif isinstance(cookie_info, PublicCookie):
await CookieCache.filter(cookie=cookie_info.cookie).delete() await CookieCache.filter(cookie=cookie_info.cookie).delete()
await cookie_info.delete() await cookie_info.delete()
@ -173,14 +190,18 @@ async def check_retcode(data: dict, cookie_info, user_id: str, uid: str) -> bool
else: else:
await PublicCookie.filter(cookie=cookie_info.cookie).delete() await PublicCookie.filter(cookie=cookie_info.cookie).delete()
await cookie_info.delete() await cookie_info.delete()
logger.info('原神Cookie', f'UID<m>{cookie_info.uid}</m>使用的缓存cookie已失效<r>已删除</r>') logger.info(
'原神Cookie', f'UID<m>{cookie_info.uid}</m>使用的缓存cookie已失效<r>已删除</r>'
)
return False return False
elif data['retcode'] == 10101: elif data['retcode'] == 10101:
cookie_info.status = 2 cookie_info.status = 2
if isinstance(cookie_info, PrivateCookie): if isinstance(cookie_info, PrivateCookie):
cookie_info.status = 2 cookie_info.status = 2
await cookie_info.save() await cookie_info.save()
logger.info('原神Cookie', f'用户<m>{user_id}</m>的私人cookie<m>{uid}</m>已达到每日30次查询上限') logger.info(
'原神Cookie', f'用户<m>{user_id}</m>的私人cookie<m>{uid}</m>已达到每日30次查询上限'
)
elif isinstance(cookie_info, PublicCookie): elif isinstance(cookie_info, PublicCookie):
cookie_info.status = 2 cookie_info.status = 2
await cookie_info.save() await cookie_info.save()
@ -188,18 +209,21 @@ async def check_retcode(data: dict, cookie_info, user_id: str, uid: str) -> bool
else: else:
await PublicCookie.filter(cookie=cookie_info.cookie).update(status=2) await PublicCookie.filter(cookie=cookie_info.cookie).update(status=2)
await cookie_info.delete() await cookie_info.delete()
logger.info('原神Cookie', f'UID<m>{cookie_info.uid}</m>使用的缓存cookie已达到每日30次查询上限') logger.info(
'原神Cookie', f'UID<m>{cookie_info.uid}</m>使用的缓存cookie已达到每日30次查询上限'
)
return False return False
else: else:
if isinstance(cookie_info, PublicCookie) and data['retcode'] != 1034: 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 return True
async def get_cookie(user_id: str, async def get_cookie(
uid: str, user_id: str, uid: str, check: bool = True, own: bool = False
check: bool = True, ) -> Union[None, PrivateCookie, PublicCookie, CookieCache]:
own: bool = False) -> Union[None, PrivateCookie, PublicCookie, CookieCache]:
""" """
获取可用的cookie 获取可用的cookie
:param user_id: 用户id :param user_id: 用户id
@ -208,12 +232,16 @@ async def get_cookie(user_id: str,
:param own: 是否只获取和uid对应的cookie :param own: 是否只获取和uid对应的cookie
""" """
query = Q(status=1) | Q(status=0) if check else Q(status=1) 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 return private_cookie
elif not own: elif not own:
if cache_cookie := await CookieCache.get_or_none(uid=uid): if cache_cookie := await CookieCache.get_or_none(uid=uid):
return cache_cookie 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 return private_cookie
else: else:
return await PublicCookie.filter(Q(query)).first() 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): async def get_bind_game_info(cookie: str, mys_id: str):
""" """
通过cookie获取米游社绑定的原神游戏信息 通过cookie获取米游社绑定的原神游戏信息
:param cookie: cookie :param cookie: cookie
:param mys_id: 米游社id :param mys_id: 米游社id
:return: 原神信息 :return: 原神信息
""" """
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
data = await aiorequests.get(url=GAME_RECORD_API, data = await aiorequests.get(
headers=mihoyo_headers(cookie, f'uid={mys_id}'), url=GAME_RECORD_API,
params={ headers=mihoyo_headers(cookie, f'uid={mys_id}'),
'uid': mys_id params={'uid': mys_id},
}) )
data = data.json() data = data.json()
nb_logger.debug(data) nb_logger.debug(data)
if data['retcode'] == 0: 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( async def get_mihoyo_public_data(
uid: str, uid: str,
user_id: Optional[str], user_id: Optional[str],
mode: Literal['abyss', 'player_card', 'role_detail'], mode: Literal['abyss', 'player_card', 'role_detail'],
schedule_type: Optional[str] = '1'): schedule_type: Optional[str] = '1',
):
server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01' server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01'
check = True check = True
while True: while True:
@ -254,32 +283,33 @@ async def get_mihoyo_public_data(
if not cookie_info: if not cookie_info:
return '当前没有可使用的cookie请绑定私人cookie或联系超级管理员添加公共cookie' return '当前没有可使用的cookie请绑定私人cookie或联系超级管理员添加公共cookie'
if mode == 'abyss': if mode == 'abyss':
data = await aiorequests.get(url=ABYSS_API, data = await aiorequests.get(
headers=mihoyo_headers( url=ABYSS_API,
q=f'role_id={uid}&schedule_type={schedule_type}&server={server_id}', headers=mihoyo_headers(
cookie=cookie_info.cookie), q=f'role_id={uid}&schedule_type={schedule_type}&server={server_id}',
params={ cookie=cookie_info.cookie,
"schedule_type": schedule_type, ),
"role_id": uid, params={
"server": server_id} "schedule_type": schedule_type,
) "role_id": uid,
"server": server_id,
},
)
elif mode == 'player_card': elif mode == 'player_card':
data = await aiorequests.get(url=PLAYER_CARD_API, data = await aiorequests.get(
headers=mihoyo_headers(q=f'role_id={uid}&server={server_id}', url=PLAYER_CARD_API,
cookie=cookie_info.cookie), headers=mihoyo_headers(
params={ q=f'role_id={uid}&server={server_id}', cookie=cookie_info.cookie
'server': server_id, ),
'role_id': uid params={'server': server_id, 'role_id': uid},
}) )
elif mode == 'role_detail': elif mode == 'role_detail':
json_data = { json_data = {"server": server_id, "role_id": uid, "character_ids": []}
"server": server_id, data = await aiorequests.post(
"role_id": uid, url=CHARACTER_DETAIL_API,
"character_ids": [] headers=mihoyo_headers(b=json_data, cookie=cookie_info.cookie),
} json=json_data,
data = await aiorequests.post(url=CHARACTER_DETAIL_API, )
headers=mihoyo_headers(b=json_data, cookie=cookie_info.cookie),
json=json_data)
else: else:
data = None data = None
data = data.json() if data else {'retcode': 999} data = data.json() if data else {'retcode': 999}
@ -289,65 +319,65 @@ async def get_mihoyo_public_data(
async def get_mihoyo_private_data( async def get_mihoyo_private_data(
uid: str, uid: str,
user_id: Optional[str], user_id: Optional[str],
mode: Literal['role_skill', 'month_info', 'daily_note', 'sign_info', 'sign_action'], mode: Literal['role_skill', 'month_info', 'daily_note', 'sign_info', 'sign_action'],
role_id: Optional[str] = None, role_id: Optional[str] = None,
month: Optional[str] = None): month: Optional[str] = None,
):
server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01' server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01'
cookie_info = await get_cookie(user_id, uid, True, True) cookie_info = await get_cookie(user_id, uid, True, True)
if not cookie_info: if not cookie_info:
return '未绑定私人cookie绑定方法二选一\n1.通过米游社扫码绑定:\n请发送指令[原神扫码绑定]\n2.获取cookie的教程\ndocs.qq.com/doc/DQ3JLWk1vQVllZ2Z1\n获取后,使用[ysb cookie]指令绑定' \ return (
+ (f'或前往{config.CookieWeb_url}网页添加绑定' if config.CookieWeb_enable else '') '未绑定私人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': if mode == 'role_skill':
data = await aiorequests.get(url=CHARACTER_SKILL_API, data = await aiorequests.get(
headers=mihoyo_headers(q=f'uid={uid}&region={server_id}&avatar_id={role_id}', url=CHARACTER_SKILL_API,
cookie=cookie_info.cookie), headers=mihoyo_headers(
params={ q=f'uid={uid}&region={server_id}&avatar_id={role_id}',
"region": server_id, cookie=cookie_info.cookie,
"uid": uid, ),
"avatar_id": role_id}) params={"region": server_id, "uid": uid, "avatar_id": role_id},
)
elif mode == 'month_info': elif mode == 'month_info':
data = await aiorequests.get(url=MONTH_INFO_API, data = await aiorequests.get(
headers=mihoyo_headers(q=f'month={month}&bind_uid={uid}&bind_region={server_id}', url=MONTH_INFO_API,
cookie=cookie_info.cookie), headers=mihoyo_headers(
params={ q=f'month={month}&bind_uid={uid}&bind_region={server_id}',
"month": month, cookie=cookie_info.cookie,
"bind_uid": uid, ),
"bind_region": server_id params={"month": month, "bind_uid": uid, "bind_region": server_id},
}) )
elif mode == 'daily_note': elif mode == 'daily_note':
data = await aiorequests.get(url=DAILY_NOTE_API, data = await aiorequests.get(
headers=mihoyo_headers(q=f'role_id={uid}&server={server_id}', url=DAILY_NOTE_API,
cookie=cookie_info.cookie), headers=mihoyo_headers(
params={ q=f'role_id={uid}&server={server_id}', cookie=cookie_info.cookie
"server": server_id, ),
"role_id": uid params={"server": server_id, "role_id": uid},
}) )
elif mode == 'sign_info': elif mode == 'sign_info':
data = await aiorequests.get(url=SIGN_INFO_API, data = await aiorequests.get(
headers={ url=SIGN_INFO_API,
'x-rpc-app_version': '2.11.1', headers={
'x-rpc-client_type': '5', 'x-rpc-app_version': '2.11.1',
'Origin': 'https://webstatic.mihoyo.com', 'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/', 'Origin': 'https://webstatic.mihoyo.com',
'Cookie': cookie_info.cookie, 'Referer': 'https://webstatic.mihoyo.com/',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS ' 'Cookie': cookie_info.cookie,
'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',
params={ },
'act_id': 'e202009291139501', params={'act_id': 'e202009291139501', 'region': server_id, 'uid': uid},
'region': server_id, )
'uid': uid
})
elif mode == 'sign_action': elif mode == 'sign_action':
data = await aiorequests.post(url=SIGN_ACTION_API, data = await aiorequests.post(
headers=mihoyo_sign_headers(cookie_info.cookie), url=SIGN_ACTION_API,
json={ headers=mihoyo_sign_headers(cookie_info.cookie),
'act_id': 'e202009291139501', json={'act_id': 'e202009291139501', 'uid': uid, 'region': server_id},
'uid': uid, )
'region': server_id
})
else: else:
data = None data = None
data = data.json() if data else {'retcode': 999} 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: async def get_sign_reward_list() -> dict:
headers = { headers = {
'x-rpc-app_version': '2.11.1', '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 (' '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', 'KHTML, like Gecko) miHoYoBBS/2.11.1',
'x-rpc-client_type': '5', 'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/' 'Referer': 'https://webstatic.mihoyo.com/',
} }
resp = await aiorequests.get(url=SIGN_REWARD_API, resp = await aiorequests.get(
headers=headers, url=SIGN_REWARD_API, headers=headers, params={'act_id': 'e202009291139501'}
params={ )
'act_id': 'e202009291139501'
})
data = resp.json() data = resp.json()
nb_logger.debug(data) nb_logger.debug(data)
return 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]: async def get_stoken_by_login_ticket(login_ticket: str, mys_id: str) -> Optional[str]:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
data = await aiorequests.get(STOKEN_API, data = await aiorequests.get(
headers={ STOKEN_API,
'x-rpc-app_version': '2.11.2', headers={
'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-app_version': '2.11.2',
'x-rpc-client_type': '5', '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',
'Referer': 'https://webstatic.mihoyo.com/', 'x-rpc-client_type': '5',
'Origin': 'https://webstatic.mihoyo.com', 'Referer': 'https://webstatic.mihoyo.com/',
}, 'Origin': 'https://webstatic.mihoyo.com',
params={ },
'login_ticket': login_ticket, params={'login_ticket': login_ticket, 'token_types': '3', 'uid': mys_id},
'token_types': '3', )
'uid': mys_id
})
data = data.json() data = data.json()
return data['data']['list'][0]['token'] return data['data']['list'][0]['token']
return None 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]: async def get_cookie_token_by_stoken(stoken: str, mys_id: str) -> Optional[str]:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
data = await aiorequests.get(COOKIE_TOKEN_API, data = await aiorequests.get(
headers={ COOKIE_TOKEN_API,
'x-rpc-app_version': '2.11.2', headers={
'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-app_version': '2.11.2',
'x-rpc-client_type': '5', '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',
'Referer': 'https://webstatic.mihoyo.com/', 'x-rpc-client_type': '5',
'Origin': 'https://webstatic.mihoyo.com', 'Referer': 'https://webstatic.mihoyo.com/',
'Cookie': f'stuid={mys_id};stoken={stoken}' 'Origin': 'https://webstatic.mihoyo.com',
}, 'Cookie': f'stuid={mys_id};stoken={stoken}',
params={ },
'uid': mys_id, params={'uid': mys_id, 'stoken': stoken},
'stoken': stoken )
})
data = data.json() data = data.json()
return data['data']['cookie_token'] return data['data']['cookie_token']
return None 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 根据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' server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01'
cookie_info = await get_cookie(user_id, uid, True, True) cookie_info = await get_cookie(user_id, uid, True, True)
if not cookie_info: if not cookie_info:
return '未绑定私人cookie绑定方法二选一\n1.通过米游社扫码绑定:\n请发送指令[原神扫码绑定]\n2.获取cookie的教程\ndocs.qq.com/doc/DQ3JLWk1vQVllZ2Z1\n获取后,使用[ysb cookie]指令绑定' \ return (
+ (f'或前往{config.CookieWeb_url}网页添加绑定' if config.CookieWeb_enable else ''), False, cookie_info '未绑定私人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: if not cookie_info.stoken:
return 'cookie中没有stoken字段请重新绑定', False, cookie_info return 'cookie中没有stoken字段请重新绑定', False, cookie_info
headers = { headers = {
'Cookie': cookie_info.stoken, 'Cookie': cookie_info.stoken,
'DS': get_old_version_ds(True), 'DS': get_old_version_ds(True),
'User-Agent': 'okhttp/4.8.0', 'User-Agent': 'okhttp/4.8.0',
'x-rpc-app_version': '2.35.2', 'x-rpc-app_version': '2.35.2',
'x-rpc-sys_version': '12', 'x-rpc-sys_version': '12',
'x-rpc-client_type': '5', 'x-rpc-client_type': '5',
'x-rpc-channel': 'mihoyo', 'x-rpc-channel': 'mihoyo',
'x-rpc-device_id': random_hex(32), 'x-rpc-device_id': random_hex(32),
'x-rpc-device_name': random_text(random.randint(1, 10)), 'x-rpc-device_name': random_text(random.randint(1, 10)),
'x-rpc-device_model': 'Mi 10', 'x-rpc-device_model': 'Mi 10',
'Referer': 'https://app.mihoyo.com', 'Referer': 'https://app.mihoyo.com',
'Host': 'api-takumi.mihoyo.com'} 'Host': 'api-takumi.mihoyo.com',
data = await aiorequests.post(url=AUTHKEY_API, }
headers=headers, data = await aiorequests.post(
json={ url=AUTHKEY_API,
'auth_appid': 'webview_gacha', headers=headers,
'game_biz': 'hk4e_cn', json={
'game_uid': uid, 'auth_appid': 'webview_gacha',
'region': server_id}) 'game_biz': 'hk4e_cn',
'game_uid': uid,
'region': server_id,
},
)
data = data.json() data = data.json()
if data.get('data') is not None and 'authkey' in data['data']: if data.get('data') is not None and 'authkey' in data['data']:
return data['data']['authkey'], True, cookie_info 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 return None, False, cookie_info
async def get_enka_data(uid): async def get_enka_data(uid: str):
urls = [ urls = [
'https://enka.network/api/uid/{uid}', '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: for url in urls:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
resp = await aiorequests.get(url=url.format(uid=uid), resp = await aiorequests.get(
headers={'User-Agent': 'LittlePaimon/3.0'}, url=url.format(uid=uid),
follow_redirects=True) headers={'User-Agent': 'LittlePaimon/3.0'},
follow_redirects=True,
)
data = resp.json() data = resp.json()
nb_logger.debug(data) nb_logger.debug(data)
return data if 'playerInfo' in data:
return data