Lanly109 / headimg_generator

基于HoshinoBot的制作头像相关的表情包插件,移植自nonebot-plugin-petpet
MIT License
50 stars 11 forks source link

新增一起,新增回复触发 #18

Closed kcn3388 closed 1 year ago

kcn3388 commented 1 year ago

可能有bug, 没全测

我使用的basic repo是这个,handler结构不一样,不确定这边有没有潜在bug

kcn3388 commented 1 year ago

冲突

kcn3388 commented 1 year ago

修复冲突

新特性:没有@用户时,视为@bot 同时因为trigger差异,现在添加了命令前缀,修改__init__.pycmd_prefix变量即可

Lanly109 commented 1 year ago

不好意思之前出差在外没时间处理这个,现在有时间了我看看,非常感谢您的PR!

Lanly109 commented 1 year ago

我稍微做了点修改,您看看如何?

kcn3388 commented 1 year ago

我稍微做了点修改,您看看如何?

  • 重写了下去除reply带来的at写法(原写法在一种情况: 回复 触发词 at别人,的回复格式中,会使得触发词的内容变为空使得下面args.pop(0)出错
  • 在过滤参数的时候顺带把触发词过滤掉,避免一些情况比如xcw 催刀 @xcw时把自定义名称去掉。但如果参数触发词之间没有空格的话(xcw催刀),我没有选择将这个触发词单独去掉(去掉的话会变成xcw,不去掉的话自定义名称就会变成xcw催刀而不是xcw),感觉这样容易会误伤正常文本
  • 回复消息的处理,原来的写法貌似需要开启go-cqhttp里的extra-reply-data: true,这样reply里才有qq的属性。这里稍微改麻烦了点,获取源信息来查看qq号。同时不用正则匹配,改用Message的解析方式,可以处理 回复消息多张图片的情况。
  • 至于帮助文案,因为我用了帮助网页版插件,以Servicehelp_属性作为帮助内容,在网页以Markdown语法渲染。并且图片生成又不能在bot运行时进行,才贴了个网址上去。至于怎么更好的处理我再思考思考
  1. 触发变空的情况你截个图给我看看?我自己测试的时候没出现 image
  2. 去掉触发词是触发插件的逻辑就是命令 + 空格 + args,避免误判
  3. 个人还是觉得应该开启go-cqhttp里的extra-reply-data: true,这个是go-cqhttp自带的特性,没必要舍近求远
  4. 帮助文案这一块,可以在生成图片时保存为静态文件,然后在加载插件时运行一次
Lanly109 commented 1 year ago
  1. 触发变空的情况你截个图给我看看?我自己测试的时候没出现

把回复里的@G36去掉试试

qwq

箭头标识数值相等

  1. 去掉触发词是触发插件的逻辑就是命令 + 空格 + args,避免误判

不过原来这里写法的话,就算不是命令 + 空格 + args这样的形式,也会被触发,以及会错误去掉参数而保留触发词

诶不过可以判断args[0]是不是触发词来保留原来的on_prefix特性

kcn3388 commented 1 year ago

image

还在改别的bug,你等下看看我最新的commit吧

kcn3388 commented 1 year ago

我稍微做了点修改,您看看如何?

  • 重写了下去除reply带来的at写法(原写法在一种情况: 回复 触发词 at别人,的回复格式中,会使得触发词的内容变为空使得下面args.pop(0)出错
  • 在过滤参数的时候顺带把触发词过滤掉,避免一些情况比如xcw 催刀 @xcw时把自定义名称去掉。但如果参数触发词之间没有空格的话(xcw催刀),我没有选择将这个触发词单独去掉(去掉的话会变成xcw,不去掉的话自定义名称就会变成xcw催刀而不是xcw),感觉这样容易会误伤正常文本
  • 回复消息的处理,原来的写法貌似需要开启go-cqhttp里的extra-reply-data: true,这样reply里才有qq的属性。这里稍微改麻烦了点,获取源信息来查看qq号。同时不用正则匹配,改用Message的解析方式,可以处理 回复消息多张图片的情况。
  • 至于帮助文案,因为我用了帮助网页版插件,以Servicehelp_属性作为帮助内容,在网页以Markdown语法渲染。并且图片生成又不能在bot运行时进行,才贴了个网址上去。至于怎么更好的处理我再思考思考
  1. 确实是我搞错了,onkeyword会捕捉全部字符,等下修
kcn3388 commented 1 year ago

我稍微做了点修改,您看看如何?

  • 重写了下去除reply带来的at写法(原写法在一种情况: 回复 触发词 at别人,的回复格式中,会使得触发词的内容变为空使得下面args.pop(0)出错
  • 在过滤参数的时候顺带把触发词过滤掉,避免一些情况比如xcw 催刀 @xcw时把自定义名称去掉。但如果参数触发词之间没有空格的话(xcw催刀),我没有选择将这个触发词单独去掉(去掉的话会变成xcw,不去掉的话自定义名称就会变成xcw催刀而不是xcw),感觉这样容易会误伤正常文本
  • 回复消息的处理,原来的写法貌似需要开启go-cqhttp里的extra-reply-data: true,这样reply里才有qq的属性。这里稍微改麻烦了点,获取源信息来查看qq号。同时不用正则匹配,改用Message的解析方式,可以处理 回复消息多张图片的情况。
  • 至于帮助文案,因为我用了帮助网页版插件,以Servicehelp_属性作为帮助内容,在网页以Markdown语法渲染。并且图片生成又不能在bot运行时进行,才贴了个网址上去。至于怎么更好的处理我再思考思考
  1. merged
  2. 无论有没有带空格,去除触发词(避免存在命令前缀时arg变的奇奇怪怪)
  3. 同样使用message,之后同普通触发,按消息先后处理
    • 如先at再图,第一处理at再处理图
    • 获取回复消息时,如果回复的消息本身是一条回复会转换为一条at,没想好这个怎么处理
    • 也由于这个问题,回复1在回复回复2时,触发的对象为回复2的发送者
Lanly109 commented 1 year ago
  1. 无论有没有带空格,去除触发词(避免存在命令前缀时arg变的奇奇怪怪)

关于触发词我觉得还是保留前缀的形式,也即在处理完参数args后,补上

        if args[0] not in [f"{cmd_prefix}{key}" for key in self.command.keywords]:
            return False

来保留前缀触发的形式。cmd_prefix的引入应该是为了避免keyword时易触发的情况,如果这样写的话就可以去掉cmd_prefix,这样写就好了。

        if args[0] not in self.command.keywords:
            return False
  1. 同样使用message,之后同普通触发,按消息先后处理
  • 如先at再图,第一处理at再处理图
  • 获取回复消息时,如果回复的消息本身是一条回复会转换为一条at,没想好这个怎么处理

    • 也由于这个问题,回复1在回复回复2时,触发的对象为回复2的发送者

关于回复信息的处理,我觉得就没必要弄的太复杂了。我认为引用回复只是为了引用图片,如果是某人头像就用at就好了,参数也无需用回复文本里的,这样各个功能的作用也明确。

kcn3388 commented 1 year ago
  1. 无论有没有带空格,去除触发词(避免存在命令前缀时arg变的奇奇怪怪)

关于触发词我觉得还是保留前缀的形式,也即在处理完参数args后,补上

        if args[0] not in [f"{cmd_prefix}{key}" for key in self.command.keywords]:
            return False

来保留前缀触发的形式。cmd_prefix的引入应该是为了避免keyword时易触发的情况,如果这样写的话就可以去掉cmd_prefix,这样写就好了。

        if args[0] not in self.command.keywords:
            return False
  1. 现在reply只识别图片
  2. 我坚持对命令前缀进行检测
    • 参数应该与命令进行分割,否则会出现下图这种奇葩图 Q06EJ~5CW49$TVIL W0FV1F
    • 使用on_keyword是因为on_prefix无法截取到回复信息
    • on_keyword是只要聊天中存在关键词就会触发,cmd_prefix一个是防止聊天即触发,另一个是防止与其他插件冲突,比如催刀会和插件版yobot冲突
Lanly109 commented 1 year ago
  1. 现在reply只识别图片
  2. 我坚持对命令前缀进行检测
  • 参数应该与命令进行分割,否则会出现下图这种奇葩图 Q06EJ~5CW49$TVIL W0FV1F
  • 使用on_keyword是因为on_prefix无法截取到回复信息
  • on_keyword是只要聊天中存在关键词就会触发,cmd_prefix一个是防止聊天即触发,另一个是防止与其他插件冲突,比如催刀会和插件版yobot冲突

我晓得你改用成on_keyword的原因,我也没说参数应该与命令合并在一起哈,我上面只是说我没选择处理这种情况。

kcn3388 commented 1 year ago

我晓得你改用成on_keyword的原因,我也没说参数应该与命令合并在一起哈,我上面只是说我没选择处理这种情况。

👌

Lanly109 commented 1 year ago

上面有个code review一直没回复哈,我稍微改了下写法,一般来说能用列表推导写法的就不用循环,速度更快点(

没其他问题的话我就merge了?

kcn3388 commented 1 year ago

上面有个code review一直没回复哈,我稍微改了下写法,一般来说能用列表推导写法的就不用循环,速度更快点(

没其他问题的话我就merge了?

model.py:

@dataclass
class Command:
    keywords: Tuple[str, ...]
    func: Func
    allow_gif: bool = False
    arg_num: int = 0
    prefix_keywords: List[str] = None

规范代码,将prefix放到最后就不需要修改data source

__init__.py line 132:

if args == [] or args[0] not in self.command.prefix_keywords:

if not args or args[0] not in self.command.prefix_keywords:

这样更简洁

__init__.py line 134:

sv.logger.info(f"Message {event.message_id} triggered {args[0].replace(cmd_prefix, '')}")

控制台信息更好看一点 image

Lanly109 commented 1 year ago

感谢建议。

不过on_keyword带来了一些麻烦之处,比如一个指令一起@xcw 玩,本意是想触发一起指令,参数是,即绘制图的文字是,但实际上它触发了顶、玩的那个指令,然后判断第一个文字一起不在触发词(顶|玩)里面,然后就return False,不绘制图了。

如果换成一起@xcw 完,就能触发到一起指令。

kcn3388 commented 1 year ago

感谢建议。

不过on_keyword带来了一些麻烦之处,比如一个指令一起@xcw 玩,本意是想触发一起指令,参数是,即绘制图的文字是,但实际上它触发了顶、玩的那个指令,然后判断第一个文字一起不在触发词(顶|玩)里面,然后就return False,不绘制图了。

如果换成一起@xcw 完,就能触发到一起指令。

这就是为什么要cmd_prefix的原因()

Lanly109 commented 1 year ago

感谢建议。 不过on_keyword带来了一些麻烦之处,比如一个指令一起@xcw 玩,本意是想触发一起指令,参数是,即绘制图的文字是,但实际上它触发了顶、玩的那个指令,然后判断第一个文字一起不在触发词(顶|玩)里面,然后就return False,不绘制图了。 如果换成一起@xcw 完,就能触发到一起指令。

这就是为什么要cmd_prefix的原因()

太对了

kcn3388 commented 1 year ago

太对了

这两天重新看了另外一个移植的repo,如果trigger改成on_message,也许可以解决必须要cmd_prefix`的问题

init.py

这个repo本身也已经提供了reply的解决方案

Lanly109 commented 1 year ago

太对了

这两天重新看了另外一个移植的repo,如果trigger改成on_message,也许可以解决必须要cmd_prefix`的问题

init.py

这个repo本身也已经提供了reply的解决方案

代码我之前也看过,但on_message的话会造成太多不必要的性能开销了

kcn3388 commented 1 year ago

太对了

这两天重新看了另外一个移植的repo,如果trigger改成on_message,也许可以解决必须要cmd_prefix`的问题 init.py 这个repo本身也已经提供了reply的解决方案

代码我之前也看过,但on_message的话会造成太多不必要的性能开销了

现在这个也挺耗性能的,相当于每一个command都新建一个on_keyword的触发器 想了一下,还有一种办法,再做一个命令前缀,然后进入触发函数,通过搜索keyword来确定调用哪个command,这样子实质就只新建了一个on_keyword的触发器 比如说:

头像表情包 玩 @sb