-
-
Notifications
You must be signed in to change notification settings - Fork 773
Open
Labels
bugSomething isn't workingSomething isn't working
Description
发生了什么
插件代码如下:
from astrbot.api.event import filter, AstrMessageEvent, MessageEventResult
from astrbot.api.star import Context, Star, register
from astrbot.api import logger
@register("helloworld", "YourName", "一个简单的 Hello World 插件", "1.0.0")
class MyPlugin(Star):
def __init__(self, context: Context):
super().__init__(context)
async def initialize(self):
"""可选择实现异步的插件初始化方法,当实例化该插件类之后会自动调用该方法。"""
@filter.command_group("math")
@filter.permission_type(filter.PermissionType.ADMIN)
def math(self):
pass
@math.command("add")
async def add(self, event: AstrMessageEvent, a: int, b: int):
# /math add 1 2 -> 结果是: 3
yield event.plain_result(f"结果是: {a + b}")
@math.command("sub")
async def sub(self, event: AstrMessageEvent, a: int, b: int):
# /math sub 1 2 -> 结果是: -1
yield event.plain_result(f"结果是: {a - b}")
其中重点为:
@filter.command_group("math")
@filter.permission_type(filter.PermissionType.ADMIN)
def math(self):
对指令组进行了permission_type装饰器设置。
触发指令
/math
预期返回结果:
您(ID: astrbot)的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。
实际返回结果
插件 helloworld: 参数不足。math 指令组下有如下指令,请参考:
math
├── add (a(int),b(int))
├── sub (a(int),b(int))
经过排查发现astrbot/core/pipeline/waking_check/stage.py
中
AstrBot/astrbot/core/pipeline/waking_check/stage.py
Lines 125 to 159 in bd270ae
for filter in handler.event_filters: | |
try: | |
if isinstance(filter, PermissionTypeFilter): | |
if not filter.filter(event, self.ctx.astrbot_config): | |
permission_not_pass = True | |
permission_filter_raise_error = filter.raise_error | |
else: | |
if not filter.filter(event, self.ctx.astrbot_config): | |
passed = False | |
break | |
except Exception as e: | |
await event.send( | |
MessageEventResult().message( | |
f"插件 {star_map[handler.handler_module_path].name}: {e}" | |
) | |
) | |
event.stop_event() | |
passed = False | |
break | |
if passed: | |
if permission_not_pass: | |
if not permission_filter_raise_error: | |
# 跳过 | |
continue | |
if self.no_permission_reply: | |
await event.send( | |
MessageChain().message( | |
f"您(ID: {event.get_sender_id()})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。" | |
) | |
) | |
logger.info( | |
f"触发 {star_map[handler.handler_module_path].name} 时, 用户(ID={event.get_sender_id()}) 权限不足。" | |
) | |
event.stop_event() | |
return |
L125会有两个过滤器:
[astrbot.core.star.filter.permission.PermissionTypeFilter object, astrbot.core.star.filter.command_group.CommandGroupFilter object]
第一个过滤器在L128经过权限过滤器进行判断是否符合权限。不符合权限的话,则permission_not_pass为True.
紧接着进行第二个过滤器的判定,此时判定/math指令作为指令组命令,有没有提供后面的参数。没提供的话,则在
command_group.py
中(见下一行引用内容)抛出了ValueError,并被L135捕获,event.send输出对应的错误。AstrBot/astrbot/core/star/filter/command_group.py
Lines 109 to 118 in bd270ae
if event.message_str.strip() in complete_command_names: | |
tree = ( | |
self.group_name | |
+ "\n" | |
+ self.print_cmd_tree(self.sub_command_filters, event=event, cfg=cfg) | |
) | |
raise ValueError( | |
f"参数不足。{self.group_name} 指令组下有如下指令,请参考:\n" | |
+ tree | |
) |
此时,因为强制抛出了ValueError,并且被捕获,导致后面passed判定未否,则不处理。
因为过滤器的条件是AND,则任意一个条件不满足,则可以直接退出,所以这里建议在L128判定为真时直接break,跳过后续过滤器的判定,经测试此场景下返回结果与预期相符。
如果没问题的话,我将以上述解决方案提交一份pr来解决这个问题。
如何复现?
如上描述
AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
master分支(bd270ae)代码运行
无提供商
消息平台适配器:目前测试了旧版本的aiocqhttp和master最新版的webui对话,理论上是同一个问题。
操作系统
Windows
报错日志
无报错日志
你愿意提交 PR 吗?
- 是的,我愿意提交 PR!
Code of Conduct
- 我已阅读并同意遵守该项目的 行为准则。
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working