github.com/fumiama/NanoBot@v0.0.0-20231122134259-c22d8183efca/rule.go (about)

     1  package nano
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/FloatTech/floatbox/process"
    10  	ctrl "github.com/FloatTech/zbpctrl"
    11  	"github.com/wdvxdr1123/ZeroBot/extension"
    12  	"github.com/wdvxdr1123/ZeroBot/extension/rate"
    13  )
    14  
    15  func newctrl(service string, o *ctrl.Options[*Ctx]) Rule {
    16  	c := m.NewControl(service, o)
    17  	return func(ctx *Ctx) bool {
    18  		ctx.State["manager"] = c
    19  		if ctx.Message != nil {
    20  			gid := ctx.GroupID()
    21  			uid := ctx.UserID()
    22  			if gid == 0 || uid == 0 {
    23  				return false
    24  			}
    25  			return c.Handler(int64(gid), int64(uid))
    26  		}
    27  		return false
    28  	}
    29  }
    30  
    31  func Lookup(service string) (*ctrl.Control[*Ctx], bool) {
    32  	return m.Lookup(service)
    33  }
    34  
    35  // respLimiterManager 请求响应限速器管理
    36  //
    37  //	每 1d 4次触发
    38  var respLimiterManager = rate.NewManager[string](time.Hour*24, 4)
    39  
    40  func init() {
    41  	process.NewCustomOnce(&m).Do(func() {
    42  		OnMessageCommandGroup([]string{
    43  			"响应", "response", "沉默", "silence",
    44  		}, UserOrGrpAdmin).SetBlock(true).Limit(func(ctx *Ctx) *rate.Limiter {
    45  			return respLimiterManager.Load(ctx.Message.ChannelID)
    46  		}).secondPriority().Handle(func(ctx *Ctx) {
    47  			grp := ctx.GroupID()
    48  			if grp == 0 {
    49  				return
    50  			}
    51  
    52  			msg := ""
    53  			switch ctx.State["command"] {
    54  			case "响应", "response":
    55  				if m.CanResponse(int64(grp)) {
    56  					msg = ctx.GetReady().User.Username + "已经在工作了哦~"
    57  					break
    58  				}
    59  				err := m.Response(int64(grp))
    60  				if err == nil {
    61  					msg = ctx.GetReady().User.Username + "将开始在此工作啦~"
    62  				} else {
    63  					msg = "ERROR: " + err.Error()
    64  				}
    65  			case "沉默", "silence":
    66  				if !m.CanResponse(int64(grp)) {
    67  					msg = ctx.GetReady().User.Username + "已经在休息了哦~"
    68  					break
    69  				}
    70  				err := m.Silence(int64(grp))
    71  				if err == nil {
    72  					msg = ctx.GetReady().User.Username + "将开始休息啦~"
    73  				} else {
    74  					msg = "ERROR: " + err.Error()
    75  				}
    76  			default:
    77  				msg = "ERROR: bad command\"" + fmt.Sprint(ctx.State["command"]) + "\""
    78  			}
    79  			_, _ = ctx.SendPlainMessage(false, msg)
    80  		})
    81  
    82  		OnMessageCommandGroup([]string{
    83  			"全局响应", "allresponse", "全局沉默", "allsilence",
    84  		}, SuperUserPermission).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
    85  			msg := ""
    86  			cmd := ctx.State["command"].(string)
    87  			switch {
    88  			case strings.Contains(cmd, "响应") || strings.Contains(cmd, "response"):
    89  				err := m.Response(0)
    90  				if err == nil {
    91  					msg = ctx.GetReady().User.Username + "将开始在此工作啦~"
    92  				} else {
    93  					msg = "ERROR: " + err.Error()
    94  				}
    95  			case strings.Contains(cmd, "沉默") || strings.Contains(cmd, "silence"):
    96  				err := m.Silence(0)
    97  				if err == nil {
    98  					msg = ctx.GetReady().User.Username + "将开始休息啦~"
    99  				} else {
   100  					msg = "ERROR: " + err.Error()
   101  				}
   102  			default:
   103  				msg = "ERROR: bad command\"" + cmd + "\""
   104  			}
   105  			_, _ = ctx.SendPlainMessage(false, msg)
   106  		})
   107  
   108  		OnMessageCommandGroup([]string{
   109  			"启用", "enable", "禁用", "disable",
   110  		}, UserOrGrpAdmin).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   111  			grp := ctx.GroupID()
   112  			if grp == 0 {
   113  				return
   114  			}
   115  			if !m.CanResponse(int64(grp)) {
   116  				return
   117  			}
   118  			model := extension.CommandModel{}
   119  			_ = ctx.Parse(&model)
   120  			service, ok := Lookup(model.Args)
   121  			if !ok {
   122  				_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   123  				return
   124  			}
   125  			if strings.Contains(model.Command, "启用") || strings.Contains(model.Command, "enable") {
   126  				service.Enable(int64(grp))
   127  				if service.Options.OnEnable != nil {
   128  					service.Options.OnEnable(ctx)
   129  				} else {
   130  					_, _ = ctx.SendPlainMessage(false, "已启用服务: ", model.Args)
   131  				}
   132  			} else {
   133  				service.Disable(int64(grp))
   134  				if service.Options.OnDisable != nil {
   135  					service.Options.OnDisable(ctx)
   136  				} else {
   137  					_, _ = ctx.SendPlainMessage(false, "已禁用服务: ", model.Args)
   138  				}
   139  			}
   140  		})
   141  
   142  		OnMessageCommandGroup([]string{
   143  			"全局启用", "allenable", "全局禁用", "alldisable",
   144  		}, OnlyToMe, SuperUserPermission).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   145  			model := extension.CommandModel{}
   146  			_ = ctx.Parse(&model)
   147  			service, ok := Lookup(model.Args)
   148  			if !ok {
   149  				_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   150  				return
   151  			}
   152  			if strings.Contains(model.Command, "启用") || strings.Contains(model.Command, "enable") {
   153  				service.Enable(0)
   154  				_, _ = ctx.SendPlainMessage(false, "已全局启用服务: ", model.Args)
   155  			} else {
   156  				service.Disable(0)
   157  				_, _ = ctx.SendPlainMessage(false, "已全局禁用服务: ", model.Args)
   158  			}
   159  		})
   160  
   161  		OnMessageCommandGroup([]string{"还原", "reset"}, UserOrGrpAdmin).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   162  			grp := ctx.GroupID()
   163  			if grp == 0 {
   164  				return
   165  			}
   166  			if !m.CanResponse(int64(grp)) {
   167  				return
   168  			}
   169  			model := extension.CommandModel{}
   170  			_ = ctx.Parse(&model)
   171  			service, ok := Lookup(model.Args)
   172  			if !ok {
   173  				_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   174  				return
   175  			}
   176  			service.Reset(int64(grp))
   177  			_, _ = ctx.SendPlainMessage(false, "已还原服务的默认启用状态: ", model.Args)
   178  		})
   179  
   180  		OnMessageCommandGroup([]string{
   181  			"禁止", "ban", "允许", "permit",
   182  		}, AdminPermission).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   183  			grp := ctx.GroupID()
   184  			if grp == 0 {
   185  				return
   186  			}
   187  			if !m.CanResponse(int64(grp)) {
   188  				return
   189  			}
   190  			model := extension.CommandModel{}
   191  			_ = ctx.Parse(&model)
   192  			args := strings.Split(model.Args, " ")
   193  			if len(args) >= 2 {
   194  				service, ok := Lookup(args[0])
   195  				if !ok {
   196  					_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   197  					return
   198  				}
   199  				msg := "*" + args[0] + "报告*"
   200  				issu := SuperUserPermission(ctx)
   201  				if strings.Contains(model.Command, "允许") || strings.Contains(model.Command, "permit") {
   202  					for _, usr := range args[1:] {
   203  						uid, err := strconv.ParseInt(usr, 10, 64)
   204  						if err == nil {
   205  							if issu {
   206  								service.Permit(uid, int64(grp))
   207  								msg += "\n+ 已允许" + usr
   208  							} else {
   209  								member, err := ctx.GetGuildMemberOf(ctx.Message.GuildID, usr)
   210  								if err == nil && !member.Pending {
   211  									service.Permit(uid, int64(grp))
   212  									msg += "\n+ 已允许" + usr
   213  								} else {
   214  									msg += "\nx " + usr + " 不在本群"
   215  								}
   216  							}
   217  						}
   218  					}
   219  				} else {
   220  					for _, usr := range args[1:] {
   221  						uid, err := strconv.ParseInt(usr, 10, 64)
   222  						if err == nil {
   223  							if issu {
   224  								service.Ban(uid, int64(grp))
   225  								msg += "\n- 已禁止" + usr
   226  							} else {
   227  								member, err := ctx.GetGuildMemberOf(ctx.Message.GuildID, usr)
   228  								if err == nil && !member.Pending {
   229  									service.Ban(uid, int64(grp))
   230  									msg += "\n- 已禁止" + usr
   231  								} else {
   232  									msg += "\nx " + usr + " 不在本群"
   233  								}
   234  							}
   235  						}
   236  					}
   237  				}
   238  				_, _ = ctx.SendPlainMessage(false, msg)
   239  				return
   240  			}
   241  			_, _ = ctx.SendPlainMessage(false, "参数错误!")
   242  		})
   243  
   244  		OnMessageCommandGroup([]string{
   245  			"全局禁止", "allban", "全局允许", "allpermit",
   246  		}, SuperUserPermission).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   247  			model := extension.CommandModel{}
   248  			_ = ctx.Parse(&model)
   249  			args := strings.Split(model.Args, " ")
   250  			if len(args) >= 2 {
   251  				service, ok := Lookup(args[0])
   252  				if !ok {
   253  					_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   254  					return
   255  				}
   256  				msg := "*" + args[0] + "全局报告*"
   257  				if strings.Contains(model.Command, "允许") || strings.Contains(model.Command, "permit") {
   258  					for _, usr := range args[1:] {
   259  						uid, err := strconv.ParseInt(usr, 10, 64)
   260  						if err == nil {
   261  							service.Permit(uid, 0)
   262  							msg += "\n+ 已允许" + usr
   263  						}
   264  					}
   265  				} else {
   266  					for _, usr := range args[1:] {
   267  						uid, err := strconv.ParseInt(usr, 10, 64)
   268  						if err == nil {
   269  							service.Ban(uid, 0)
   270  							msg += "\n- 已禁止" + usr
   271  						}
   272  					}
   273  				}
   274  				_, _ = ctx.SendPlainMessage(false, msg)
   275  				return
   276  			}
   277  			_, _ = ctx.SendPlainMessage(false, "参数错误!")
   278  		})
   279  
   280  		OnMessageCommandGroup([]string{
   281  			"封禁", "block", "解封", "unblock",
   282  		}, SuperUserPermission).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   283  			model := extension.CommandModel{}
   284  			_ = ctx.Parse(&model)
   285  			args := strings.Split(model.Args, " ")
   286  			if len(args) >= 1 {
   287  				msg := "*报告*"
   288  				if strings.Contains(model.Command, "解") || strings.Contains(model.Command, "un") {
   289  					for _, usr := range args {
   290  						uid, err := strconv.ParseInt(usr, 10, 64)
   291  						if err == nil {
   292  							if m.DoUnblock(uid) == nil {
   293  								msg += "\n- 已解封" + usr
   294  							}
   295  						}
   296  					}
   297  				} else {
   298  					for _, usr := range args {
   299  						uid, err := strconv.ParseInt(usr, 10, 64)
   300  						if err == nil {
   301  							if m.DoBlock(uid) == nil {
   302  								msg += "\n+ 已封禁" + usr
   303  							}
   304  						}
   305  					}
   306  				}
   307  				_, _ = ctx.SendPlainMessage(false, msg)
   308  				return
   309  			}
   310  			_, _ = ctx.SendPlainMessage(false, "参数错误!")
   311  		})
   312  
   313  		OnMessageCommandGroup([]string{
   314  			"改变默认启用状态", "allflip",
   315  		}, SuperUserPermission).SetBlock(true).secondPriority().Handle(func(ctx *Ctx) {
   316  			model := extension.CommandModel{}
   317  			_ = ctx.Parse(&model)
   318  			service, ok := Lookup(model.Args)
   319  			if !ok {
   320  				_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   321  				return
   322  			}
   323  			err := service.Flip()
   324  			if err != nil {
   325  				_, _ = ctx.SendPlainMessage(false, "ERROR: ", err)
   326  				return
   327  			}
   328  			_, _ = ctx.SendPlainMessage(false, "已改变全局默认启用状态: ", model.Args)
   329  		})
   330  
   331  		OnMessageCommandGroup([]string{"用法", "usage"}, UserOrGrpAdmin).SetBlock(true).secondPriority().
   332  			Handle(func(ctx *Ctx) {
   333  				grp := ctx.GroupID()
   334  				if grp == 0 {
   335  					return
   336  				}
   337  				model := extension.CommandModel{}
   338  				_ = ctx.Parse(&model)
   339  				service, ok := Lookup(model.Args)
   340  				if !ok {
   341  					_, _ = ctx.SendPlainMessage(false, "没有找到指定服务!")
   342  					return
   343  				}
   344  				if service.Options.Help != "" {
   345  					_, _ = ctx.SendPlainMessage(false, service.EnableMarkIn(int64(grp)), " ", service)
   346  				} else {
   347  					_, _ = ctx.SendPlainMessage(false, "该服务无帮助!")
   348  				}
   349  			})
   350  
   351  		OnMessageCommandGroup([]string{"服务列表", "service_list"}, UserOrGrpAdmin).SetBlock(true).secondPriority().
   352  			Handle(func(ctx *Ctx) {
   353  				grp := ctx.GroupID()
   354  				if grp == 0 {
   355  					return
   356  				}
   357  				m.RLock()
   358  				msg := make([]any, 1, len(m.M)*4+1)
   359  				m.RUnlock()
   360  				msg[0] = "--------服务列表--------\n发送\"/用法 name\"查看详情\n发送\"/响应\"启用会话"
   361  				ForEachByPrio(func(i int, service *ctrl.Control[*Ctx]) bool {
   362  					msg = append(msg, "\n", i+1, ": ", service.EnableMarkIn(int64(grp)), service.Service)
   363  					return true
   364  				})
   365  				_, _ = ctx.SendPlainMessage(false, msg...)
   366  			})
   367  
   368  		OnMessageCommandGroup([]string{"服务详情", "service_detail"}, UserOrGrpAdmin).SetBlock(true).secondPriority().
   369  			Handle(func(ctx *Ctx) {
   370  				grp := ctx.GroupID()
   371  				if grp == 0 {
   372  					return
   373  				}
   374  				m.RLock()
   375  				msgs := make([]any, 1, len(m.M)*7+1)
   376  				m.RUnlock()
   377  				msgs[0] = "---服务详情---\n"
   378  				ForEachByPrio(func(i int, service *ctrl.Control[*Ctx]) bool {
   379  					msgs = append(msgs, i+1, ": ", service.EnableMarkIn(int64(grp)), service.Service, "\n", service, "\n\n")
   380  					return true
   381  				})
   382  				_, _ = ctx.SendPlainMessage(false, msgs...)
   383  			})
   384  	})
   385  }