MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接

    [壶言鉴权]一个能帮助你快速开发Mirai插件的前置插件

    插件发布
    3
    4
    820
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • Moyuyanli
      Moyuyanli 摸鱼 最后由 Moyuyanli 编辑

      HuYanAuthorize 壶言鉴权

      仓库地址:github

      最新版:1.3.0

      说明

      一个用于针对简化mirai插件开发的前置插件,简化的内容为:

      核心特性

      • 自动化消息监听: 使用 @EventComponent 和 @MessageAuthorize 自动化注册监听器。
      • 编译期优化 (KSP): 支持使用 KSP 在编译期生成注册代码,消除运行时反射开销,提升启动速度。
      • 多维度权限系统: 针对用户 (Friend)、群 (Group)、群成员 (GroupMember)、群管理 (GroupAdmin) 提供独立权限控制。
      • 权限分组与继承: 权限通过分组管理,支持组间继承。
      • 灵活的消息匹配: 支持文本、正则、以及自定义逻辑匹配。
      • 指令前缀支持: 全局或局部配置指令触发前缀。
      • 轻量化: 移除外部依赖 (如 Hutool),减少插件体积。

      快速开始

      1. 添加依赖

      在 settings.gradle.kts 中添加仓库:

      dependencyResolutionManagement {
          repositories {
              // 壶言私服 - 国内加速镜像代理 (推荐)
              maven("https://nexus.chahuyun.cn/repository/maven-public/")
              // KSP 插件与常规依赖来源 (备用)
              google()
              mavenCentral()
          }
      }
      

      在子项目的 build.gradle.kts 中添加插件和依赖:

      plugins {
          // 引入 KSP 插件 (版本需与 Kotlin 版本匹配,如 Kotlin 1.9.20 对应 1.9.20-1.0.14)
          id("com.google.devtools.ksp") version "1.9.20-1.0.14"
      }
      
      dependencies {
          // 核心库
          compileOnly("cn.chahuyun:HuYanAuthorize:1.2.7")
          
          // 启用 KSP 编译期加速 (可选,需要同时引入上面的 ksp 插件)
          ksp("cn.chahuyun:huyan-authorize-ksp:1.2.7")
      }
      

      2. 启用插件

      在插件的 onEnable 方法中:

      override fun onEnable() {
          // 注册本插件的消息监听包
          AuthorizeServer.registerEvents(this, "your.package.name")
      }
      

      3. 编写监听器

      创建一个带有 @EventComponent 注解的类,并在方法上使用 @MessageAuthorize:

      @EventComponent
      class MyListener {
      
          @MessageAuthorize(text = ["你好"])
          suspend fun onHello(event: MessageEvent) {
              event.subject.sendMessage("你好啊!")
          }
      
          @MessageAuthorize(
              text = ["admin"],
              userPermissions = ["admin_code"] // 需要拥有 admin_code 权限
          )
          suspend fun onAdmin(event: MessageEvent) {
              event.subject.sendMessage("管理员你好!")
          }
      }
      

      消息鉴权api

      MessageAuthorize注解的所有可操作属性

      text 匹配文本

      text: Array<String>

      用于匹配的文本。

      • 在默认模式下,有任何一个String字符串,于其中一个相同,即匹配成功。
      • 在正则模式下,取第一个匹配。

      custom 自定义匹配

      custom: KClass<out CustomPattern>

      自定义匹配规则。

      实现CustomPattern接口即可。

      在匹配方式设置为CUSTOM时启用,启用时将忽略text的配置。

      messageMatching 消息匹配方式

      messageMatching: MessageMatchingEnum

      消息的匹配方式,有:

      • TEXT 文本匹配
      • REGULAR 正则匹配
      • CUSTOM 自定义匹配

      messageConversion 消息转换方式

      messageConversion: MessageConversionEnum

      用于在匹配消息的时候,消息转换为string的方式。

      • CONTENT contentToString()
      • MIRAI_CODE serializeToMiraiCode()
      • JSON serializeToJsonString()

      userPermissions 用户权限

      userPermissions: Array<String>

      需要用户拥有的权限。

      自己的权限需要进行注册,注册方式请查看权限注册。

      userPermissionsMatching 用户权限匹配方式

      userPermissionsMatching: PermissionMatchingEnum

      如果需要用户权限有多个,多个权限之间的匹配方式.

      • or 或,满足一个即匹配成功
      • and 且,都满足才匹配成功

      groupPermissions 群权限

      groupPermissions: Array<String>

      要求的群权限,跟用户同理,只不过要求的是群的权限。

      groupPermissionsMatching 群权限匹配方式

      groupPermissionsMatching:PermissionMatchingEnum

      同上面

      userInGroupPermissionsAssociation 用户与群权限的匹配方式

      userInGroupPermissionsAssociation: PermissionMatchingEnum

      如果某一条指令,即要求用户权限,又要求群权限。

      这里可以控制两种权限的合并方式。

      同上面用户的匹配方式。

      priority 优先级

      消息响应优先级,跟mirai的消息注册一样,一般不建议修改。

      concurrency 消息的处理方式

      消息的处理方式,跟mirai的消息注册一样,一般不建议修改。

      权限

      权限是本插件的核心,用于对整个消息注册做控制。

      采用的是code形式,是String字符串。

      本插件默认权限:

      • owner 主人权限,最高权限,类比root
      • admin 管理员权限,比root低

      不可使用的code:

      • null 表明无权限

      使用方法:

      AuthPerm.OWNER
      AuthPerm.ADMIN
      AuthPerm.NULL
      

      自定义注册权限

      fun registerPermCode(plugin: JvmPlugin, vararg perms: Perm)
      注册权限很简单。

      权限可以一次性注册多个。

      java

          PermissionServer.INSTANCE.registerPermCode(this,new Perm("test","一个测试的权限")...);
      
          PermissionServer.registerPermCode(this, Perm("test", "一个测试的权限"))
      

      注册成功后,会打印debug日志显示是否注册成功,或者该权限是否被别的插件注册。

      然后就可以在MessageAuthorize中的权限列表使用了。

      注意:

      • 这里注册用的权限是新建的,仅供于注册用
      • 想要使用注册后的权限,请使用下面的工具获取

      操作权限

      权限的实现分两部分,一部分是权限组(PermGroup),权限组有权限(Perm)和用户(User)。

      对于权限组,在依赖插件中如果手动操作了权限组,可以使用PermGroup自己的save()方法保存,或者使用工具操作权限组。

      操作权限组指令:

      指令 含义 案例 案例含义
      +perm (权限组名称) [权限code] 创建一个权限组,并添加对应的权限,权限组必填,code选填。 +perm 测试组 admin 添加或修改一个名叫测试组的权限组,并为测试组添加权限admmin。
      +perm (权限组名称) [%父权限组名称] 继承一个权限组,从父权限组哪里继承权限。指令能添加和修改权限组,并且能共用。 +perm 测试组 %主人 admin 添加或修改一个名叫测试组的权限组,继承主人权限组的所有权限,并添加admin权限。
      -perm (权限组名称) [权限code] 删除一个权限或权限组,当不填权限code时,会尝试删除整个权限组。 -perm 测试组 admin 删除权限组测试组的权限admin。
      =perm [权限组名称] 查询权限组信息,也可以查询单独一个权限组的信息。 =perm 查询所有权限组信息

      用户操作指令:

      用户分为四类用户,他们有不同的作用域。

      全局用户

      这个用户是作用于所有位置的一个单qq用户。

      指令 含义 案例 案例含义
      +global (@user) (权限组名称) 添加这个用户到对应权限组,这里可以at,可以直接填qq。 +global @放空 主人 添加放空到主人权限组
      -global (@user) (权限组名称) 还没写

      群成员用户

      这个用户作用于指定群的某个一群成员用户。

      指令 含义 案例 案例含义
      +member (@user) (权限组名称) 添加这个群成员到对应权限组,这里只能at,并且得在群里操作 +member @放空 主人 添加群成员放空到主人权限组
      -member (@user) (权限组名称) 还没写

      群管理用户

      这个用户是对于一个群的群主和管理员的用户。

      指令 含义 案例 案例含义
      +admin (权限组名称) 添加这个群的管理员到对应权限组,只能在群里操作 +admin 主人 添加本群管理员到主人权限组
      -admin (权限组名称) 还没写

      群用户

      这个用户跟上面三个不一样,这个代表的是这个群拥有的权限,而不是这个群里面所有人拥有的权限。

      指令 含义 案例 案例含义
      +group (权限组名称) 添加这个群到对应权限组,只能在群里操作 +group 主人 添加本群到主人权限组
      -group (权限组名称) 还没写

      其他api

      还开发一些好用的工具类,供大家使用。

      消息事件注册(PermissionServer)

      PermissionServer.kt

      带指令前缀的注册

      fun registerMessageEvent(plugin: JvmPlugin, packageName: String, prefix: String)

      指令前缀可为""。

      权限操作工具类(PermUtil)

      PermUtil.kt

      获取一个权限

      fun takePerm(code: String): Perm

      只能获取已经注册过的权限,未注册的权限会抛错。

      PermUtil.takePerm("admin")
      

      获取一个权限组

      fun talkPermGroupByName(name: String): PermGroup

      获取一个权限组,不存在则新建。

      PermUtil.talkPermGroupByName("测试组")
      

      检查这个用户有没有这个权限

      fun checkUserHasPerm(user: User, code: String): Boolean

      用户的获取请看下面

          //获取一个群用户
      val group = User.group(group.id)
      PermUtil.checkUserHasPerm(group, "admin")
      

      将这个用户添加到对应的权限组

      fun addUserToPermGroupByName(user: User, name: String): Boolean

      PermUtil.addUserToPermGroupByName(group, "测试组")
      

      将这个权限添加到对于的权限组

      fun addPermToPermGroupByName(perm: Perm, name: String): Boolea
      fun addPermToPermGroupByPermGroup(perm: Perm, permGroup: PermGroup): Boolean

      将这个用户从对应的权限组删除

      fun delUserFromPermGroupByName(user: User, name: String): Boolean

      用户的操作(User)

      UserUtil.kt

      获取用户

      • fun globalUser(userId: Long): User 查询或新建一个全局用户
      • fun group(groupId: Long): User 查询或新建一个群用户
      • fun groupAdmin(groupId: Long): User 查询或新建一个群管理用户
      • fun member(groupId: Long, userId: Long): User 查询或新建一个群成员用户

      kotlin

          UserUtil.group(390444068)
      UserUtil.member(390444068, 572490972)
      

      java

          UserUtil.INSTANCE.group(390444068L);
          UserUtil.INSTANCE.
      
      member(390444068L,572490972L);
      

      消息工具类(MessageUtil)

      MessageUtil.kt

      这个类比较简单,具体看看源码就明白了,但是好用!

      日志工具类(Log)

      Log.kt

      使用方法:

      在插件的onEnable方法中:

      Log.init(this)
      

      即可加载完成。

      然后在需要打印日志的地方直接:

      Log.info("这是一条日志")
      
      Log.INSTANCE.info("这是%s日志","一个");
      

      对于java,自带格式化。

      如果觉得不优雅,可以只引入他的INSTANCE。

      错误工具(ExceptionHandle)

      ExceptionHandle.kt

      对于消息注册方法,我做了一个错误收集。

      fun init(
          plugin: JvmPlugin,
          packageName: String,
          exceptionHandle: ExceptionHandleApi = ExceptionHandle()
      )
      

      这是一个消息注册的重载方法,只需要传递自己实现的错误接口即可拿到错误。

      获取主人

      对于依赖于本插件的插件,可以实现共用一个主人,就算是换代,换配置,主人依然可以保存。

      主人信息存在于数据库,如果config没有设置,会尝试从数据库找之前设置的主人来同步。
      如果config已经设置,会自动通过config的信息同步到数据。

          HuYanAuthorize.INSTANCE.getOwner()
      
      HuYanAuthorize.Companion.getINSTANCE().
      
      getOwner();
      

      指令

      命令前缀 命令 含义 案例
      #hya owner 设置主人 #hya owner 572490972
      v 查询当前插件版本 #hya v
      1 条回复 最后回复 回复 引用 1
      • wendaoming
        wendaoming 最后由 编辑

        支持

        Moyuyanli 1 条回复 最后回复 回复 引用 0
        • Moyuyanli
          Moyuyanli 摸鱼 @wendaoming 最后由 编辑

          @wendaoming 嘿

          1 条回复 最后回复 回复 引用 0
          • Anstiya
            Anstiya 摸鱼 最后由 编辑

            此回复已被删除!
            1 条回复 最后回复 回复 引用 0
            • 1 / 1
            • First post
              Last post
            Powered by Mamoe Technologies & NodeBB | 友情链接 | 服务监控 | Contact