Skip to content

Commit

Permalink
feat: 增加全局开启关闭插件
Browse files Browse the repository at this point in the history
  • Loading branch information
yqchilde committed Dec 30, 2022
1 parent 3f82ad7 commit 21fa847
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 13 deletions.
68 changes: 59 additions & 9 deletions engine/control/control.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package control

import (
"errors"

"github.com/yqchilde/wxbot/engine/pkg/log"
)

Expand All @@ -15,7 +17,7 @@ type Control[CTX any] struct {
func (manager *Manager[CTX]) NewControl(service string, o *Options[CTX]) *Control[CTX] {
m := &Control[CTX]{
Service: service,
Cache: make(map[string]bool, 16),
Cache: make(map[string]bool),
Options: func() Options[CTX] {
if o == nil {
return Options[CTX]{}
Expand Down Expand Up @@ -56,17 +58,26 @@ func (m *Control[CTX]) Handler(gid, uid string) bool {

// Enable 使插件在某个群中启用
func (m *Control[CTX]) Enable(groupID string) error {
if groupID != "all" {
if isEnable, ok := m.IsEnabledAll(true); ok {
if isEnable {
return errors.New("该插件已在全局启用")
}
return errors.New("该插件已全局禁用,如需启用请先在关闭全局禁用")
}
}

c := PluginConfig{GroupID: groupID, Enable: true}
tx := m.Manager.D.Begin()
if err := tx.Table(m.Service).Where("gid = ?", groupID).Delete(&PluginConfig{}).Error; err != nil {
if err := tx.Table(m.Service).Delete(&PluginConfig{}, "gid = ?", groupID).Error; err != nil {
log.Errorf("(plugin) %s enable in %s failed: %v", m.Service, groupID, err)
tx.Rollback()
return err
return errors.New("启用失败")
}
if err := tx.Table(m.Service).Create(&c).Error; err != nil {
log.Errorf("(plugin) %s enable in %s failed: %v", m.Service, groupID, err)
tx.Rollback()
return err
return errors.New("启用失败")
}
tx.Commit()
m.Manager.Lock()
Expand All @@ -77,17 +88,26 @@ func (m *Control[CTX]) Enable(groupID string) error {

// Disable 使插件在某个群中禁用
func (m *Control[CTX]) Disable(groupID string) error {
if groupID != "all" {
if isEnable, ok := m.IsEnabledAll(false); ok {
if isEnable {
return errors.New("该插件已在全局禁用")
}
return errors.New("该插件已全局启用,如需启用请先在关闭全局启用")
}
}

c := PluginConfig{GroupID: groupID, Enable: false}
tx := m.Manager.D.Begin()
if err := tx.Table(m.Service).Where("gid = ?", groupID).Delete(&PluginConfig{}).Error; err != nil {
if err := tx.Table(m.Service).Delete(&PluginConfig{}, "gid = ?", groupID).Error; err != nil {
log.Errorf("(plugin) %s disable in %s failed: %v", m.Service, groupID, err)
tx.Rollback()
return err
return errors.New("禁用失败")
}
if err := tx.Table(m.Service).Create(&c).Error; err != nil {
log.Errorf("(plugin) %s disable in %s failed: %v", m.Service, groupID, err)
tx.Rollback()
return err
return errors.New("禁用失败")
}
tx.Commit()
m.Manager.Lock()
Expand All @@ -96,6 +116,18 @@ func (m *Control[CTX]) Disable(groupID string) error {
return nil
}

// CloseGlobalMode 关闭全局模式
func (m *Control[CTX]) CloseGlobalMode() error {
if err := m.Manager.D.Table(m.Service).Delete(&PluginConfig{}, "gid = ?", "all").Error; err != nil {
log.Errorf("(plugin) %s close global failed: %v", m.Service, err)
return errors.New("关闭失败")
}
m.Manager.Lock()
delete(m.Cache, "all")
m.Manager.Unlock()
return nil
}

// IsEnabledIn 查询开启群组
func (m *Control[CTX]) IsEnabledIn(gid string) bool {
m.Manager.RLock()
Expand All @@ -113,13 +145,31 @@ func (m *Control[CTX]) IsEnabledIn(gid string) bool {
m.Manager.Lock()
defer m.Manager.Unlock()
var c PluginConfig
if m.Manager.D.Table(m.Service).Where("gid = ?", "all").First(&c).Error == nil {
if m.Manager.D.Table(m.Service).First(&c, "gid = ?", "all").Error == nil {
m.Cache["all"] = c.Enable
return c.Enable
}
if m.Manager.D.Table(m.Service).Where("gid = ?", gid).First(&c).Error == nil {
if m.Manager.D.Table(m.Service).First(&c, "gid = ?", "all").Error == nil {
m.Cache[gid] = c.Enable
return c.Enable
}
return !m.Options.DisableOnDefault
}

// IsEnabledAll 查询是否全局开启
func (m *Control[CTX]) IsEnabledAll(enable bool) (isEnable bool, ok bool) {
m.Manager.RLock()
isEnable, ok = m.Cache["all"]
m.Manager.RUnlock()
if ok {
return isEnable == enable, ok
}
m.Manager.Lock()
defer m.Manager.Unlock()
var c PluginConfig
if m.Manager.D.Table(m.Service).First(&c, "gid = ?", "all").Error == nil {
m.Cache["all"] = c.Enable
return c.Enable == enable, ok
}
return false, ok
}
67 changes: 63 additions & 4 deletions engine/control/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func newControl(service string, o *Options[*robot.Ctx]) robot.Rule {

func init() {
once.Do(func() {
// 启用、禁用某个插件在某个群或某个私聊
robot.OnCommandGroup([]string{"启用", "禁用"}, robot.UserOrGroupAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *robot.Ctx) {
args := ctx.State["args"].(string)
if args == "" {
Expand All @@ -34,8 +35,8 @@ func init() {
grp := ctx.Event.FromUniqueID
switch ctx.State["command"].(string) {
case "启用":
if service.Enable(grp) != nil {
ctx.ReplyText("启用失败")
if err := service.Enable(grp); err != nil {
ctx.ReplyText(err.Error())
return
}
if service.Options.OnEnable != nil {
Expand All @@ -44,8 +45,8 @@ func init() {
ctx.ReplyText("启用成功")
}
case "禁用":
if service.Disable(grp) != nil {
ctx.ReplyText("禁用失败")
if err := service.Disable(grp); err != nil {
ctx.ReplyText(err.Error())
return
}
if service.Options.OnDisable != nil {
Expand All @@ -55,5 +56,63 @@ func init() {
}
}
})

// todo 启用、禁用全部插件在某个群或某个私聊
robot.OnCommandGroup([]string{"启用全部", "禁用全部"}, robot.UserOrGroupAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *robot.Ctx) {
})

// 启用、禁用某个插件在所有群和所有私聊
robot.OnCommandGroup([]string{"全局启用", "全局禁用"}, robot.UserOrGroupAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *robot.Ctx) {
args := ctx.State["args"].(string)
if args == "" {
return
}
service, ok := managers.Lookup(args)
if !ok {
ctx.ReplyTextAndAt("没有找到对应插件服务")
return
}
switch ctx.State["command"].(string) {
case "全局启用":
if service.Enable("all") != nil {
ctx.ReplyText("全局启用失败")
return
}
if service.Options.OnEnable != nil {
service.Options.OnEnable(ctx)
} else {
ctx.ReplyText("全局启用成功")
}
case "全局禁用":
if service.Disable("all") != nil {
ctx.ReplyText("全局禁用失败")
return
}
if service.Options.OnDisable != nil {
service.Options.OnDisable(ctx)
} else {
ctx.ReplyText("全局禁用成功")
}
}
})

// 开启、关闭某个插件的全局模式
robot.OnCommand("关闭全局模式", robot.UserOrGroupAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *robot.Ctx) {
args := ctx.State["args"].(string)
if args == "" {
return
}
service, ok := managers.Lookup(args)
if !ok {
ctx.ReplyTextAndAt("没有找到对应插件服务")
return
}
if err := service.CloseGlobalMode(); err != nil {
ctx.ReplyText(err.Error())
return
} else {
ctx.ReplyText("关闭全局模式成功")
}
})
})
}

0 comments on commit 21fa847

Please sign in to comment.