diff --git a/LittlePaimon/plugins/Paimon_Wiki/__init__.py b/LittlePaimon/plugins/Paimon_Wiki/__init__.py index d44abae..ad48d15 100644 --- a/LittlePaimon/plugins/Paimon_Wiki/__init__.py +++ b/LittlePaimon/plugins/Paimon_Wiki/__init__.py @@ -2,10 +2,19 @@ import datetime import re from nonebot import on_regex, on_command -from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment, GroupMessageEvent, PrivateMessageEvent, \ - Bot +from nonebot.adapters.onebot.v11 import ( + MessageEvent, + Message, + MessageSegment, + GroupMessageEvent, + PrivateMessageEvent, + Bot, +) from nonebot.adapters.onebot.v11.exception import ActionFailed -from nonebot.adapters.onebot.v11.helpers import HandleCancellation, convert_chinese_to_bool +from nonebot.adapters.onebot.v11.helpers import ( + HandleCancellation, + convert_chinese_to_bool, +) from nonebot.params import RegexDict, ArgPlainText, CommandArg, Arg from nonebot.permission import SUPERUSER from nonebot.plugin import PluginMetadata @@ -23,7 +32,13 @@ from LittlePaimon.utils.path import JSON_DATA from .draw_daily_material import draw_material from .draw_map import init_map, draw_map, get_full_map from .SereniteaPot import draw_pot_materials -from .Atlas import get_match_card, get_card_resources, get_match_specialty, get_all_specialty, get_atlas_full_path +from .Atlas import ( + get_match_card, + get_card_resources, + get_match_specialty, + get_all_specialty, + get_atlas_full_path, +) from .wiki_api import API __plugin_meta__ = PluginMetadata( @@ -31,15 +46,29 @@ __plugin_meta__ = PluginMetadata( description='原神WIKI百科', usage='', extra={ - 'author': '惜月', - 'version': '3.0', + 'author': '惜月', + 'version': '3.0', 'priority': 3, - } + }, ) cancel = [HandleCancellation(f'好吧,有需要再找{NICKNAME}')] -BASE_TYPE = ['角色', '天赋', '培养', '命座', '技能', '武器', '圣遗物', '原魔', '怪物', '七圣召唤', '原牌', '卡牌', - '特产', '材料'] +BASE_TYPE = [ + '角色', + '天赋', + '培养', + '命座', + '技能', + '武器', + '圣遗物', + '原魔', + '怪物', + '七圣召唤', + '原牌', + '卡牌', + '特产', + '材料', +] BASE_TYPE_RE = '(' + '|'.join(BASE_TYPE) + ')' IMG_TYPE = ['图鉴', '攻略', '材料', '参考面板', '收益曲线'] IMG_TYPE_RE = '(' + '|'.join(IMG_TYPE) + ')' @@ -51,39 +80,61 @@ total_wiki = on_regex( priority=9, block=True, state={ - 'pm_name': '原神WIKI', + 'pm_name': '原神WIKI', 'pm_description': '支持查询:角色的图鉴、攻略、材料、参考面板、收益曲线,武器、圣遗物、原魔、七圣召唤图鉴,今日|周几材料' - '\n示例:钟离攻略、护摩图鉴、今日材料', - 'pm_usage': '<对象名><图鉴|攻略|材料>', - 'pm_priority': 1 - }) -material_map_full = on_command('材料地图', priority=8, block=True, state={ - 'pm_name': '材料地图', - 'pm_description': '查看多个材料大地图采集点。\n示例:材料地图 鸣草 鬼兜虫 提瓦特', - 'pm_usage': '材料地图<材料名列表>[地图]', - 'pm_priority': 3 -}) -generate_map = on_command('生成地图', priority=1, block=True, permission=SUPERUSER, state={ - 'pm_name': '生成地图', - 'pm_description': '生成材料图鉴等所需要的地图资源,仅超级用户可用。', - 'pm_usage': '生成地图', - 'pm_priority': 4 -}) -pot_material = on_command('尘歌壶摹本', aliases={'摹本材料', '尘歌壶材料', '尘歌壶摹本材料'}, priority=11, block=True, - state={ - 'pm_name': '尘歌壶摹本材料', - 'pm_description': '查看尘歌壶摹本所需要的材料总览', - 'pm_usage': '尘歌壶材料<摹数>', - 'pm_priority': 5 - }) -card_wiki_list = on_command('七圣召唤列表', aliases={'七圣召唤卡牌列表', '原牌列表', '原石传说列表'}, priority=11, - rule=fullmatch_rule, block=True, state={ - 'pm_name': '七圣召唤图鉴列表', + '\n示例:钟离攻略、护摩图鉴、今日材料', + 'pm_usage': '<对象名><图鉴|攻略|材料>', + 'pm_priority': 1, + }, +) +material_map_full = on_command( + '材料地图', + priority=8, + block=True, + state={ + 'pm_name': '材料地图', + 'pm_description': '查看多个材料大地图采集点。\n示例:材料地图 鸣草 鬼兜虫 提瓦特', + 'pm_usage': '材料地图<材料名列表>[地图]', + 'pm_priority': 3, + }, +) +generate_map = on_command( + '生成地图', + priority=1, + block=True, + permission=SUPERUSER, + state={ + 'pm_name': '生成地图', + 'pm_description': '生成材料图鉴等所需要的地图资源,仅超级用户可用。', + 'pm_usage': '生成地图', + 'pm_priority': 4, + }, +) +pot_material = on_command( + '尘歌壶摹本', + aliases={'摹本材料', '尘歌壶材料', '尘歌壶摹本材料'}, + priority=11, + block=True, + state={ + 'pm_name': '尘歌壶摹本材料', + 'pm_description': '查看尘歌壶摹本所需要的材料总览', + 'pm_usage': '尘歌壶材料<摹数>', + 'pm_priority': 5, + }, +) +card_wiki_list = on_command( + '七圣召唤列表', + aliases={'七圣召唤卡牌列表', '原牌列表', '原石传说列表'}, + priority=11, + rule=fullmatch_rule, + block=True, + state={ + 'pm_name': '七圣召唤图鉴列表', 'pm_description': '查看已支持查询的七圣召唤卡牌图鉴列表', - 'pm_usage': '原牌列表', - 'pm_priority': 6 - }) - + 'pm_usage': '原牌列表', + 'pm_priority': 6, + }, +) @material_map_full.handle() @@ -98,16 +149,21 @@ async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()): state['names'] = params -@material_map_full.got('names', prompt='请输入要查询的材料名称,或回答【取消】退出', - parameterless=cancel) +@material_map_full.got('names', prompt='请输入要查询的材料名称,或回答【取消】退出', parameterless=cancel) async def _(event: MessageEvent, map_: str = Arg('map'), names=Arg('names')): if isinstance(names, Message): names = names.extract_plain_text().split(' ') - if not freq_limiter.check(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}'): + if not freq_limiter.check( + f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}' + ): await material_map_full.finish( f'材料地图查询冷却中,剩余{freq_limiter.left(f"材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}")}秒', - at_sender=True) - freq_limiter.start(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}', 15) + at_sender=True, + ) + freq_limiter.start( + f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}', + 15, + ) if len(names) > 3: names = names[:3] await material_map_full.send(MessageBuild.Text(f'开始查找{"、".join(names)}的资源点,请稍候...')) @@ -115,8 +171,10 @@ async def _(event: MessageEvent, map_: str = Arg('map'), names=Arg('names')): await material_map_full.finish(result, at_sender=True) -@generate_map.got('confirm', - prompt=f'生成材料地图资源要求大量内存,如果内存不足,可能会导致{NICKNAME}崩溃,请确认你的机器内存充足,回答【是|否】继续执行!') +@generate_map.got( + 'confirm', + prompt=f'生成材料地图资源要求大量内存,如果内存不足,可能会导致{NICKNAME}崩溃,请确认你的机器内存充足,回答【是|否】继续执行!', +) async def _(event: MessageEvent): if convert_chinese_to_bool(event.message): await generate_map.send('开始生成地图资源,这可能需要较长时间...') @@ -174,7 +232,13 @@ week_str = ['周一', '周二', '周三', '周四', '周五', '周六'] @total_wiki.got('name', prompt=Message.template('你要查询谁的{type}呢?'), parameterless=cancel) -async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type'), name: str = ArgPlainText('name')): +async def _( + bot: Bot, + event: MessageEvent, + state: T_State, + type: str = Arg('type'), + name: str = ArgPlainText('name'), +): if not name: if state['times'] == 2: await total_wiki.finish('旅行者似乎不太能理解,下次再问我吧' + MessageSegment.face(146)) @@ -197,40 +261,70 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type await total_wiki.finish('周日所有材料都可以刷哦!', at_sender=True) else: await total_wiki.send('开始获取每日材料,请稍候...') - await total_wiki.finish(await draw_material(str(event.user_id), week_str[day]), at_sender=True) + await total_wiki.finish( + await draw_material(str(event.user_id), week_str[day]), at_sender=True + ) else: matches = {} if type == '参考面板' and name in {'火', '水', '冰', '雷', '风', '岩', '草'}: - await total_wiki.finish(MessageSegment.image(API[type].format(proxy=config.github_proxy, name=name))) + await total_wiki.finish( + MessageSegment.image( + API[type].format(proxy=config.github_proxy, name=name) + ) + ) elif type.startswith('角色') or type in {'参考面板', '收益曲线'}: if name == '全部': matches = load_json(JSON_DATA / '类型.json')['角色']['元素类型'] elif re.match('^[火水冰雷风岩草](元素|属性|系)?$', name): - matches = {'角色': load_json(JSON_DATA / '类型.json')['角色']['元素类型'][name[0]]} - elif re.match('^' + '|'.join(WEAPON_TYPE_ALIAS.keys()) + '$', name): - matches = {'角色': load_json(JSON_DATA / '类型.json')['角色']['武器类型'][WEAPON_TYPE_ALIAS[name]]} - elif alias := await PlayerAlias.get_or_none(user_id=str(event.user_id), alias=name): + matches = { + '角色': load_json(JSON_DATA / '类型.json')['角色']['元素类型'][name[0]] + } + elif name in WEAPON_TYPE_ALIAS.keys(): + matches = { + '角色': load_json(JSON_DATA / '类型.json')['角色']['武器类型'][ + WEAPON_TYPE_ALIAS[name] + ] + } + elif alias := await PlayerAlias.get_or_none( + user_id=str(event.user_id), alias=name + ): final_name = alias.character matches = {} try: await total_wiki.finish( - MessageSegment.image(API[type].format(proxy=config.github_proxy, name=final_name))) + MessageSegment.image( + API[type].format(proxy=config.github_proxy, name=final_name) + ) + ) except ActionFailed: await total_wiki.finish( - MessageBuild.Text(f'{final_name}的{type}发送失败,可能是网络问题或者不存在该资源')) + MessageBuild.Text(f'{final_name}的{type}发送失败,可能是网络问题或者不存在该资源') + ) else: matches = get_match_alias(name, '角色') elif type.startswith('武器'): if name == '全部': matches = load_json(JSON_DATA / '类型.json')['武器'] - elif re.match('^' + '|'.join(WEAPON_TYPE_ALIAS.keys()) + '$', name): - matches = {'武器': load_json(JSON_DATA / '类型.json')['武器'][WEAPON_TYPE_ALIAS[name]]} + elif name in WEAPON_TYPE_ALIAS.keys(): + matches = { + '武器': load_json(JSON_DATA / '类型.json')['武器'][ + WEAPON_TYPE_ALIAS[name] + ] + } else: matches = get_match_alias(name, '武器') elif type.startswith('原魔'): - matches = {'原魔': list(load_json(JSON_DATA / 'alias.json')['原魔'].keys())} if name == '全部' else get_match_alias(name, '原魔') + matches = ( + {'原魔': list(load_json(JSON_DATA / 'alias.json')['原魔'].keys())} + if name == '全部' + else get_match_alias(name, '原魔') + ) elif type.startswith('圣遗物'): - matches = {'圣遗物': list(load_json(JSON_DATA / 'alias.json')['圣遗物'].keys())} if name == '全部' else get_match_alias(name, '圣遗物') + matches = ( + {'圣遗物': list(load_json(JSON_DATA / 'alias.json')['圣遗物'].keys())} + if name == '全部' + else get_match_alias(name, '圣遗物') + ) elif type.startswith('七圣召唤'): if name == '全部': matches = await get_match_card(name) @@ -240,17 +334,30 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type matches = {'特产': s} else: if re.match('^[火水冰雷风岩草](元素|属性|系)?$', name): - matches = {'角色': load_json(JSON_DATA / '类型.json')['角色']['元素类型'][name[0]]} - elif re.match('^' + '|'.join(WEAPON_TYPE_ALIAS.keys()) + '$', name): - matches = {'角色': load_json(JSON_DATA / '类型.json')['角色']['武器类型'][WEAPON_TYPE_ALIAS[name]], - '武器': load_json(JSON_DATA / '类型.json')['武器'][WEAPON_TYPE_ALIAS[name]]} - elif alias := await PlayerAlias.get_or_none(user_id=str(event.user_id), alias=name): + matches = { + '角色': load_json(JSON_DATA / '类型.json')['角色']['元素类型'][name[0]] + } + elif name in WEAPON_TYPE_ALIAS.keys(): + matches = { + '角色': load_json(JSON_DATA / '类型.json')['角色']['武器类型'][ + WEAPON_TYPE_ALIAS[name] + ], + '武器': load_json(JSON_DATA / '类型.json')['武器'][ + WEAPON_TYPE_ALIAS[name] + ], + } + elif alias := await PlayerAlias.get_or_none( + user_id=str(event.user_id), alias=name + ): final_name = alias.character if type in {'材料', '攻略', '图鉴'}: type = f'角色{type}' try: await total_wiki.finish( - MessageSegment.image(API[type].format(proxy=config.github_proxy, name=final_name))) + MessageSegment.image( + API[type].format(proxy=config.github_proxy, name=final_name) + ) + ) except ActionFailed: await total_wiki.finish(f'{final_name}的{type}发送失败,可能是网络问题或者不存在该资源') else: @@ -271,19 +378,27 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type if type in {'材料', '攻略', '图鉴'}: type = f'{temp_type}图鉴' if temp_type != '角色' else f'{temp_type}{type}' if type in {'七圣召唤图鉴', '武器图鉴'}: - final_name = await get_atlas_full_path(final_name, 'card' if type == '七圣召唤图鉴' else 'weapon') + final_name = await get_atlas_full_path( + final_name, 'card' if type == '七圣召唤图鉴' else 'weapon' + ) try: await total_wiki.finish( - MessageSegment.image(API[type].format(proxy=config.github_proxy, name=final_name))) + MessageSegment.image( + API[type].format(proxy=config.github_proxy, name=final_name) + ) + ) except ActionFailed: await total_wiki.finish(f'{final_name}的{type}发送失败,可能是网络问题或者不存在该资源') else: send_flag = False - if sum(len(value) for value in matches.values()) >= 15 and isinstance(event, ( - PrivateMessageEvent, GroupMessageEvent)): + if sum(len(value) for value in matches.values()) >= 15 and isinstance( + event, (PrivateMessageEvent, GroupMessageEvent) + ): if len(matches) == 1: - matches = {i: matches[list(matches.keys())[0]][i:i + 5] for i in - range(0, len(matches[list(matches.keys())[0]]), 5)} + matches = { + i: matches[list(matches.keys())[0]][i : i + 5] + for i in range(0, len(matches[list(matches.keys())[0]]), 5) + } index = 1 msg = [] for key, value in matches.items(): @@ -291,17 +406,51 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type for v in value: temp_msg += f'{index}.{v}\n' index += 1 - msg.append({'type': 'node', 'data': {'name': NICKNAME, 'uin': event.self_id, 'content': temp_msg.strip()}}) - msg.insert(0, {'type': 'node', - 'data': {'name': NICKNAME, 'uin': event.self_id, 'content': f'你要查询哪个的{type}呢?'}}) - msg.append({'type': 'node', 'data': {'name': NICKNAME, 'uin': event.self_id, - 'content': '回答\"序号\"查询或回答\"取消\"取消查询'}}) + msg.append( + { + 'type': 'node', + 'data': { + 'name': NICKNAME, + 'uin': event.self_id, + 'content': temp_msg.strip(), + }, + } + ) + msg.insert( + 0, + { + 'type': 'node', + 'data': { + 'name': NICKNAME, + 'uin': event.self_id, + 'content': f'你要查询哪个的{type}呢?', + }, + }, + ) + msg.append( + { + 'type': 'node', + 'data': { + 'name': NICKNAME, + 'uin': event.self_id, + 'content': '回答\"序号\"查询或回答\"取消\"取消查询', + }, + } + ) try: send_flag = True if isinstance(event, GroupMessageEvent): - await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msg) + await bot.call_api( + 'send_group_forward_msg', + group_id=event.group_id, + messages=msg, + ) elif isinstance(event, PrivateMessageEvent): - await bot.call_api('send_private_forward_msg', user_id=event.user_id, messages=msg) + await bot.call_api( + 'send_private_forward_msg', + user_id=event.user_id, + messages=msg, + ) except ActionFailed: send_flag = False if not send_flag: @@ -309,7 +458,11 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type msg = f'你要查询的{type}是:\n' for key, value in matches.items(): for v in value: - msg += f'{index}.{v}({key})\n' if len(matches) > 1 else f'{index}.{v}\n' + msg += ( + f'{index}.{v}({key})\n' + if len(matches) > 1 + else f'{index}.{v}\n' + ) index += 1 msg += '回答\"序号\"查询或回答\"取消\"取消查询' await total_wiki.send(msg) @@ -317,9 +470,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State, type: str = Arg('type @total_wiki.got('choice', parameterless=cancel) -async def _(state: T_State, matches: dict = Arg('matches'), choice: str = ArgPlainText('choice'), - type: str = Arg('type')): - if choice.isdigit() and 1 <= int(choice) <= sum(len(value) for value in matches.values()): +async def _( + state: T_State, + matches: dict = Arg('matches'), + choice: str = ArgPlainText('choice'), + type: str = Arg('type'), +): + if choice.isdigit() and 1 <= int(choice) <= sum( + len(value) for value in matches.values() + ): choice_num = int(choice) else: choice_num = None @@ -340,17 +499,24 @@ async def _(state: T_State, matches: dict = Arg('matches'), choice: str = ArgPla break if final_name: if type in {'七圣召唤图鉴', '武器图鉴'}: - final_name = await get_atlas_full_path(final_name, 'card' if type == '七圣召唤图鉴' else 'weapon') + final_name = await get_atlas_full_path( + final_name, 'card' if type == '七圣召唤图鉴' else 'weapon' + ) try: await total_wiki.finish( - MessageSegment.image(API[type].format(proxy=config.github_proxy, name=final_name))) + MessageSegment.image( + API[type].format(proxy=config.github_proxy, name=final_name) + ) + ) except ActionFailed: await total_wiki.finish(f'{final_name}的{type}发送失败,可能是网络问题或者不存在该资源') elif state['times'] == 2: await total_wiki.finish('旅行者似乎不太能理解,下次再问我吧' + MessageSegment.face(146)) else: state['times'] = state['times'] + 1 - await total_wiki.reject(f'请旅行者从上面的{type}中选一个问{NICKNAME}或回答\"取消\"可以取消查询', at_sender=True) + await total_wiki.reject( + f'请旅行者从上面的{type}中选一个问{NICKNAME}或回答\"取消\"可以取消查询', at_sender=True + ) @card_wiki_list.handle() @@ -359,18 +525,42 @@ async def _(bot: Bot, event: MessageEvent): if not result: await card_wiki_list.finish('读取七圣召唤卡牌列表失败') msg = [ - {'type': 'node', 'data': {'name': NICKNAME, 'uin': event.self_id, 'content': f'{type}:\n' + '\n'.join(cards)}} - for type, cards in result.items()] - msg.insert(0, {'type': 'node', 'data': {'name': NICKNAME, 'uin': event.self_id, 'content': '七圣召唤卡牌列表如下'}}) + { + 'type': 'node', + 'data': { + 'name': NICKNAME, + 'uin': event.self_id, + 'content': f'{type}:\n' + '\n'.join(cards), + }, + } + for type, cards in result.items() + ] + msg.insert( + 0, + { + 'type': 'node', + 'data': {'name': NICKNAME, 'uin': event.self_id, 'content': '七圣召唤卡牌列表如下'}, + }, + ) try: if isinstance(event, GroupMessageEvent): - await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msg) + await bot.call_api( + 'send_group_forward_msg', group_id=event.group_id, messages=msg + ) elif isinstance(event, PrivateMessageEvent): - await bot.call_api('send_private_forward_msg', user_id=event.user_id, messages=msg) + await bot.call_api( + 'send_private_forward_msg', user_id=event.user_id, messages=msg + ) else: msg = '七圣召唤卡牌列表:\n' for type, cards in result.items(): - msg += f'{type}:\n' + '\n'.join([' '.join(cards[i:i + 3]) for i in range(0, len(cards), 3)]) + '\n' + msg += ( + f'{type}:\n' + + '\n'.join( + [' '.join(cards[i : i + 3]) for i in range(0, len(cards), 3)] + ) + + '\n' + ) await card_wiki_list.send(msg) except ActionFailed: await card_wiki_list.finish('七圣召唤卡牌列表发送失败,账号可能被风控')