diff --git a/nonebot_plugin_tetris_stats/games/__init__.py b/nonebot_plugin_tetris_stats/games/__init__.py index d8e00ea..ca4ede1 100644 --- a/nonebot_plugin_tetris_stats/games/__init__.py +++ b/nonebot_plugin_tetris_stats/games/__init__.py @@ -1,40 +1,53 @@ -from typing import Any +from collections.abc import Callable from nonebot.adapters import Bot -from nonebot.exception import FinishedException from nonebot.matcher import Matcher from nonebot.message import run_postprocessor -from nonebot_plugin_alconna import AlcMatches, AlconnaMatcher, At +from nonebot.typing import T_Handler +from nonebot_plugin_alconna import AlcMatches, Alconna, At, CommandMeta, on_alconna +from .. import ns from ..utils.exception import MessageFormatError, NeedCatchError +alc = on_alconna( + Alconna( + ['tetris-stats', 'tstats'], + namespace=ns, + meta=CommandMeta( + description='俄罗斯方块相关游戏数据查询', + fuzzy_match=True, + ), + ), + skip_for_unmatch=False, + auto_send_output=True, + use_origin=True, +) -def add_default_handlers(matcher: type[AlconnaMatcher]) -> None: - @matcher.assign('query') + +def add_block_handlers(handler: Callable[[T_Handler], T_Handler]) -> None: + @handler async def _(bot: Bot, matcher: Matcher, target: At): if isinstance(target, At) and target.target == bot.self_id: await matcher.finish('不能查询bot的信息') - @matcher.handle() - async def _(matcher: Matcher, account: MessageFormatError): - await matcher.finish(str(account)) - - @matcher.handle() - async def _(matcher: Matcher, matches: AlcMatches): - if matches.head_matched and matches.options != {} or matches.main_args == {}: - await matcher.finish( - (f'{matches.error_info!r}\n' if matches.error_info is not None else '') - + f'输入"{matches.header_result} --help"查看帮助' - ) - - @matcher.handle() - def _(other: Any): # noqa: ANN401, ARG001 - raise FinishedException - from . import tetrio, top, tos # noqa: F401, E402 +@alc.handle() +async def _(matcher: Matcher, account: MessageFormatError): + await matcher.finish(str(account)) + + +@alc.handle() +async def _(matcher: Matcher, matches: AlcMatches): + if matches.head_matched and matches.options != {} or matches.main_args == {}: + await matcher.finish( + (f'{matches.error_info!r}\n' if matches.error_info is not None else '') + + f'输入"{matches.header_result} --help"查看帮助' + ) + + @run_postprocessor async def _(matcher: Matcher, exception: NeedCatchError): await matcher.send(str(exception)) diff --git a/nonebot_plugin_tetris_stats/games/tetrio/__init__.py b/nonebot_plugin_tetris_stats/games/tetrio/__init__.py index caea223..1657a0a 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/__init__.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/__init__.py @@ -1,14 +1,13 @@ -from arclet.alconna import Alconna, AllParam, Arg, ArgFlag, Args, CommandMeta, Option -from nonebot_plugin_alconna import At, on_alconna +from arclet.alconna import Arg, ArgFlag, Args, Option, Subcommand +from nonebot_plugin_alconna import At -from ... import ns from ...utils.exception import MessageFormatError from ...utils.typing import Me -from .. import add_default_handlers -from ..constant import BIND_COMMAND, QUERY_COMMAND +from .. import add_block_handlers, alc from .api import Player -from .api.typing import Rank +from .api.typing import ValidRank from .constant import USER_ID, USER_NAME +from .typing import Template def get_player(user_id_or_name: str) -> Player | MessageFormatError: @@ -19,69 +18,62 @@ def get_player(user_id_or_name: str) -> Player | MessageFormatError: return MessageFormatError('用户名/ID不合法') -alc = on_alconna( - Alconna( - 'io', - Option( - BIND_COMMAND[0], +alc.command.add( + Subcommand( + 'TETR.IO', + Subcommand( + 'bind', Args( Arg( 'account', get_player, - notice='IO 用户名 / ID', + notice='TETR.IO 用户名 / ID', flags=[ArgFlag.HIDDEN], ) ), - alias=BIND_COMMAND[1:], - compact=True, - dest='bind', - help_text='绑定 IO 账号', + help_text='绑定 TETR.IO 账号', ), - Option( - QUERY_COMMAND[0], + Subcommand( + 'query', Args( Arg( 'target', At | Me, - notice='@想要查询的人 | 自己', + notice='@想要查询的人 / 自己', flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL], ), Arg( 'account', get_player, - notice='IO 用户名 / ID', + notice='TETR.IO 用户名 / ID', flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL], ), ), - alias=QUERY_COMMAND[1:], - compact=True, - dest='query', - help_text='查询 IO 游戏信息', + Option( + '--template', + Arg('template', Template), + alias=['-T'], + help_text='要使用的查询模板', + ), + help_text='查询 TETR.IO 游戏信息', ), - Option( + Subcommand( 'rank', - Args(Arg('rank', Rank, notice='IO 段位')), - alias={'Rank', 'RANK', '段位'}, - compact=True, - dest='rank', - help_text='查询 IO 段位信息', + Args(Arg('rank', ValidRank, notice='TETR.IO 段位')), + help_text='查询 TETR.IO 段位信息', ), - Arg('other', AllParam, flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL]), - meta=CommandMeta( - description='查询 TETR.IO 的信息', - example='io绑定scdhh\nio查我\niorankx', - compact=True, - fuzzy_match=True, - ), - namespace=ns, - ), - skip_for_unmatch=False, - auto_send_output=True, - aliases={'IO'}, + dest='TETRIO', + help_text='TETR.IO 游戏相关指令', + ) ) -alc.shortcut('fkosk', {'command': 'io查', 'args': ['我'], 'fuzzy': False, 'humanized': 'An Easter egg!'}) +alc.shortcut('(?i:io)(?i:绑|绑定|bind)', {'command': 'tstats TETR.IO bind', 'humanized': 'io绑定'}) +alc.shortcut('(?i:io)(?i:查|查询|query|stats)', {'command': 'tstats TETR.IO query', 'humanized': 'io查'}) + +alc.shortcut( + 'fkosk', {'command': 'tstats TETR.IO query', 'args': ['我'], 'fuzzy': False, 'humanized': 'An Easter egg!'} +) + +add_block_handlers(alc.assign('TETRIO.query')) from . import bind, query, rank # noqa: F401, E402 - -add_default_handlers(alc) diff --git a/nonebot_plugin_tetris_stats/games/tetrio/api/typing.py b/nonebot_plugin_tetris_stats/games/tetrio/api/typing.py index 7e4e9dc..d901d0b 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/api/typing.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/api/typing.py @@ -1,6 +1,6 @@ from typing import Literal -Rank = Literal[ +ValidRank = Literal[ 'x', 'u', 'ss', @@ -18,5 +18,6 @@ Rank = Literal[ 'c-', 'd+', 'd', - 'z', # 未定级 ] + +Rank = ValidRank | Literal['z'] # 未定级 diff --git a/nonebot_plugin_tetris_stats/games/tetrio/bind.py b/nonebot_plugin_tetris_stats/games/tetrio/bind.py index e398471..0474bb6 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/bind.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/bind.py @@ -19,7 +19,7 @@ from .api import Player from .constant import GAME_TYPE -@alc.assign('bind') +@alc.assign('TETRIO.bind') async def _(nb_user: User, account: Player, event_session: EventSession, bot_info: UserInfo = BotUserInfo()): # noqa: B008 async with trigger( session_persist_id=await get_session_persist_id(event_session), diff --git a/nonebot_plugin_tetris_stats/games/tetrio/query.py b/nonebot_plugin_tetris_stats/games/tetrio/query.py index bff31c7..1b87e68 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/query.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/query.py @@ -47,7 +47,7 @@ UTC = timezone.utc driver = get_driver() -@alc.assign('query') +@alc.assign('TETRIO.query') async def _(event: Event, matcher: Matcher, target: At | Me, event_session: EventSession): async with trigger( session_persist_id=await get_session_persist_id(event_session), @@ -77,7 +77,7 @@ async def _(event: Event, matcher: Matcher, target: At | Me, event_session: Even await message.finish() -@alc.assign('query') +@alc.assign('TETRIO.query') async def _(account: Player, event_session: EventSession): async with trigger( session_persist_id=await get_session_persist_id(event_session), diff --git a/nonebot_plugin_tetris_stats/games/tetrio/rank.py b/nonebot_plugin_tetris_stats/games/tetrio/rank.py index 1827d55..c103e41 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/rank.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/rank.py @@ -37,7 +37,7 @@ UTC = timezone.utc driver = get_driver() -@alc.assign('rank') +@alc.assign('TETRIO.rank') async def _(matcher: Matcher, rank: Rank, event_session: EventSession): async with trigger( session_persist_id=await get_session_persist_id(event_session), diff --git a/nonebot_plugin_tetris_stats/games/tetrio/typing.py b/nonebot_plugin_tetris_stats/games/tetrio/typing.py new file mode 100644 index 0000000..c755632 --- /dev/null +++ b/nonebot_plugin_tetris_stats/games/tetrio/typing.py @@ -0,0 +1,3 @@ +from typing import Literal + +Template = Literal['v1', 'v2'] diff --git a/nonebot_plugin_tetris_stats/games/top/__init__.py b/nonebot_plugin_tetris_stats/games/top/__init__.py index b58ca50..1f3a0b5 100644 --- a/nonebot_plugin_tetris_stats/games/top/__init__.py +++ b/nonebot_plugin_tetris_stats/games/top/__init__.py @@ -1,11 +1,9 @@ -from arclet.alconna import Alconna, AllParam, Arg, ArgFlag, Args, CommandMeta, Option -from nonebot_plugin_alconna import At, on_alconna +from arclet.alconna import Arg, ArgFlag, Args, Subcommand +from nonebot_plugin_alconna import At -from ... import ns from ...utils.exception import MessageFormatError from ...utils.typing import Me -from .. import add_default_handlers -from ..constant import BIND_COMMAND, QUERY_COMMAND +from .. import add_block_handlers, alc from .api import Player from .constant import USER_NAME @@ -16,31 +14,28 @@ def get_player(name: str) -> Player | MessageFormatError: return MessageFormatError('用户名/ID不合法') -alc = on_alconna( - Alconna( - 'top', - Option( - BIND_COMMAND[0], +alc.command.add( + Subcommand( + 'TOP', + Subcommand( + 'bind', Args( Arg( 'account', get_player, - notice='TOP 用户名', + notice='TOP 用户名 / ID', flags=[ArgFlag.HIDDEN], ) ), - alias=BIND_COMMAND[1:], - compact=True, - dest='bind', help_text='绑定 TOP 账号', ), - Option( - QUERY_COMMAND[0], + Subcommand( + 'query', Args( Arg( 'target', At | Me, - notice='@想要查询的人 | 自己', + notice='@想要查询的人 / 自己', flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL], ), Arg( @@ -50,25 +45,15 @@ alc = on_alconna( flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL], ), ), - alias=QUERY_COMMAND[1:], - compact=True, - dest='query', help_text='查询 TOP 游戏信息', ), - Arg('other', AllParam, flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL]), - meta=CommandMeta( - description='查询 TetrisOnline波兰服 的信息', - example='top绑定scdhh\ntop查我', - compact=True, - fuzzy_match=True, - ), - namespace=ns, - ), - skip_for_unmatch=False, - auto_send_output=True, - aliases={'TOP'}, + help_text='TOP 游戏相关指令', + ) ) -from . import bind, query # noqa: E402, F401 +alc.shortcut('(?i:top)(?i:绑|绑定|bind)', {'command': 'tstats TOP bind', 'humanized': 'top绑定'}) +alc.shortcut('(?i:top)(?i:查|查询|query|stats)', {'command': 'tstats TOP query', 'humanized': 'top查'}) -add_default_handlers(alc) +add_block_handlers(alc.assign('TOP.query')) + +from . import bind, query # noqa: E402, F401 diff --git a/nonebot_plugin_tetris_stats/games/top/bind.py b/nonebot_plugin_tetris_stats/games/top/bind.py index d1cae02..63cf992 100644 --- a/nonebot_plugin_tetris_stats/games/top/bind.py +++ b/nonebot_plugin_tetris_stats/games/top/bind.py @@ -18,7 +18,7 @@ from .api import Player from .constant import GAME_TYPE -@alc.assign('bind') +@alc.assign('TOP.bind') async def _( nb_user: User, account: Player, diff --git a/nonebot_plugin_tetris_stats/games/top/query.py b/nonebot_plugin_tetris_stats/games/top/query.py index 9d8fd2c..557f237 100644 --- a/nonebot_plugin_tetris_stats/games/top/query.py +++ b/nonebot_plugin_tetris_stats/games/top/query.py @@ -17,7 +17,7 @@ from .api.schemas.user_profile import UserProfile from .constant import GAME_TYPE -@alc.assign('query') +@alc.assign('TOP.query') async def _(event: Event, matcher: Matcher, target: At | Me, event_session: EventSession): async with trigger( session_persist_id=await get_session_persist_id(event_session), @@ -39,7 +39,7 @@ async def _(event: Event, matcher: Matcher, target: At | Me, event_session: Even await (message + make_query_text(await Player(user_name=bind.game_account, trust=True).get_profile())).finish() -@alc.assign('query') +@alc.assign('TOP.query') async def _(account: Player, event_session: EventSession): async with trigger( session_persist_id=await get_session_persist_id(event_session), diff --git a/nonebot_plugin_tetris_stats/games/tos/__init__.py b/nonebot_plugin_tetris_stats/games/tos/__init__.py index 6c91522..b186e2a 100644 --- a/nonebot_plugin_tetris_stats/games/tos/__init__.py +++ b/nonebot_plugin_tetris_stats/games/tos/__init__.py @@ -1,11 +1,9 @@ -from arclet.alconna import Alconna, AllParam, Arg, ArgFlag, Args, CommandMeta, Option -from nonebot_plugin_alconna import At, on_alconna +from arclet.alconna import Arg, ArgFlag, Args, Subcommand +from nonebot_plugin_alconna import At -from ... import ns from ...utils.exception import MessageFormatError from ...utils.typing import Me -from .. import add_default_handlers -from ..constant import BIND_COMMAND, QUERY_COMMAND +from .. import add_block_handlers, alc from .api import Player from .constant import USER_NAME @@ -21,31 +19,28 @@ def get_player(teaid_or_name: str) -> Player | MessageFormatError: return MessageFormatError('用户名/ID不合法') -alc = on_alconna( - Alconna( - '茶服', - Option( - BIND_COMMAND[0], +alc.command.add( + Subcommand( + 'TOS', + Subcommand( + 'bind', Args( Arg( 'account', get_player, - notice='茶服 用户名 / TeaID', + notice='茶服 用户名 / ID', flags=[ArgFlag.HIDDEN], ) ), - alias=BIND_COMMAND[1:], - compact=True, - dest='bind', help_text='绑定 茶服 账号', ), - Option( - QUERY_COMMAND[0], + Subcommand( + 'query', Args( Arg( 'target', At | Me, - notice='@想要查询的人 | 自己', + notice='@想要查询的人 / 自己', flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL], ), Arg( @@ -54,28 +49,16 @@ alc = on_alconna( notice='茶服 用户名 / TeaID', flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL], ), - # 如果放在一个 Union Args 里, 验证顺序不能保证, 可能出错 ), - alias=QUERY_COMMAND[1:], - compact=True, - dest='query', help_text='查询 茶服 游戏信息', ), - Arg('other', AllParam, flags=[ArgFlag.HIDDEN, ArgFlag.OPTIONAL]), - meta=CommandMeta( - description='查询 TetrisOnline茶服 的信息', - example='茶服查我', - compact=True, - fuzzy_match=True, - ), - namespace=ns, - ), - skip_for_unmatch=False, - auto_send_output=True, - aliases={'tos', 'TOS'}, + help_text='茶服 游戏相关指令', + ) ) +alc.shortcut('(?i:tos|茶服)(?i:绑|绑定|bind)', {'command': 'tstats TOS bind', 'humanized': '茶服绑定'}) +alc.shortcut('(?i:tos|茶服)(?i:查|查询|query|stats)', {'command': 'tstats TOS query', 'humanized': '茶服查'}) + +add_block_handlers(alc.assign('TOS.query')) from . import bind, query # noqa: E402, F401 - -add_default_handlers(alc) diff --git a/nonebot_plugin_tetris_stats/games/tos/bind.py b/nonebot_plugin_tetris_stats/games/tos/bind.py index 2183b19..3215c7b 100644 --- a/nonebot_plugin_tetris_stats/games/tos/bind.py +++ b/nonebot_plugin_tetris_stats/games/tos/bind.py @@ -18,7 +18,7 @@ from .api import Player from .constant import GAME_TYPE -@alc.assign('bind') +@alc.assign('TOS.bind') async def _( nb_user: User, account: Player, diff --git a/nonebot_plugin_tetris_stats/games/tos/query.py b/nonebot_plugin_tetris_stats/games/tos/query.py index 074bc04..d5a8e54 100644 --- a/nonebot_plugin_tetris_stats/games/tos/query.py +++ b/nonebot_plugin_tetris_stats/games/tos/query.py @@ -34,7 +34,7 @@ from .constant import GAME_TYPE def add_special_handlers( teaid_prefix: Literal['onebot-', 'kook-', 'discord-', 'qqguild-'], match_event: type[Event] ) -> None: - @alc.assign('query') + @alc.assign('TOS.query') async def _( event: Event, target: At | Me, @@ -98,7 +98,7 @@ except ImportError: pass -@alc.assign('query') +@alc.assign('TOS.query') async def _( event: Event, matcher: Matcher, @@ -132,7 +132,7 @@ async def _( await (message + make_query_text(user_info, game_data)).finish() -@alc.assign('query') +@alc.assign('TOS.query') async def _(account: Player, event_session: EventSession, event_user_info: UserInfo = EventUserInfo()): # noqa: B008 async with trigger( session_persist_id=await get_session_persist_id(event_session),