一般性的,一个插件除了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,希望能有更合适的方式实现。