已解决 把Permissions系统用于Command以外的权限控制,需要新的Permittee子类?
-
一般性的,一个插件除了Command为入口的功能,还可能包括其他途径触发的功能:
- Event为入口的功能
- 由定时器触发的功能
这些其他途径触发的功能,如果需要做权限控制,或者说服务开关控制,一个方案是自行实现配置文件。如屏蔽消息的思路提到的关闭EventHandler对某个群的服务:
// onGroupMessage(GroupMessageEvent event) if(this.main.getConfig().isBlackList(sender.getSenderID())) { return; } // do sth
以及关闭定时器对某个群的服务:
// on MyTimer run() bot.getGroups().foreach(group -> { if(timerConfig.isBlackList(group .getID())) { return; } // do sth })
该方案的缺点是需要自行实现和维护多个XXXConfig,需要在文档多个地方说明,增加一个群时涉及多个配置文件……
故考虑复用Permissions系统,用PermissionId对应EventHandler/Timer的开关,拥有权限则表示启用服务。这样把插件内所有的功能的权限控制/开关,都统一交给Permissions系统,用一份配置文件管理,可动态授权……
// on init val PERMISSION_A = PermissionService.INSTANCE.register(permissionId("eventHandlerA"), "对应eventHandlerA开关"); val PERMISSION_B = PermissionService.INSTANCE.register(permissionId("timerB"), "对应timerB开关");
则PermissionService.yml会形如:
grantedPermissionMap: 'myPlugin:eventHandlerA': - 'g111111' # 表示只有111111群的群员可以使用eventHandlerA 'myPlugin:timerB': - 'g222222' # timerB只定时服务222222群
EventHandler的判断变为:
// onGroupMessage(GroupMessageEvent event) Permittee permittee = permitteeFromGroupId(event.getGroupId()); if(!permittee.hasPermission(PERMISSION_A) return; // do sth
Timer的判断改变为:
// on MyTimer run() bot.getGroups().foreach(group -> { Permittee permittee = permitteeFromGroupId(group .getID()); if(!permittee.hasPermission(PERMISSION_B) return; // do sth })
目前的问题是:如何实现permitteeFromGroupId(),重点是返回哪个permittee子类?
Command为入口
已经有了CommandSender;我倾向于Event为入口
,由Timer触发
也分别有平级的一支子类,然而console文档指出注意:请不要自主实现 Permittee
。虽然可以让他们也构造某个CommandSender子类,但毕竟这样的调用确实不是
来自command,希望能有更合适的方式实现。 -
-
@karlatemp 多谢,用起来了
-
贴一下该设计在mirai-fleet-prinzeugen插件实际使用的例子。
'hundun.fleet.prinzeugen.cos:INSTANCE'
对应本帖讨论的自定义权限。授权后的config/Console/PermissionService.yml内容示例:
grantedPermissionMap:
'hundun.fleet.prinzeugen:*': # 常规Command权限
- 'm111111.*' # 允许111111群的任意群员使用本插件的所有Command
'hundun.fleet.prinzeugen.cos:INSTANCE': # 特殊权限,表示本插件(Event功能和定时器功能)的开关
- m111111.222222 # bot账号222222在群1111111启用本插件注册特殊权限(源码简化后展示):
// on init Permission characterCosPermission = registerCosPermission(); protected Permission registerCosPermission() { String newHost = "hundun.fleet.prinzeugen.cos"; String newName = "INSTANCE"; Permission newParent = Permission.getRootPermission(); try { return PermissionService.Companion.getInstance().register( new PermissionId(newHost, newName), "略", newParent ); } catch (PermissionRegistryConflictException e) { plugin.getLogger().error(e); return null; } }
检查特殊权限(源码简化后展示):
protected boolean checkCosPermission(Bot bot, Group group) { Permission targetPermission = characterCosPermission; ExactMember exactGroup = new ExactMember(group.getId(), bot.getId()); return PermissionService.testPermission(targetPermission, exactGroup); }