From d5a6de5231e4a2681c1585f9d805c592547bae24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sat, 11 Jun 2022 18:25:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20tome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- context.go | 1 + event.go | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++ rules.go | 20 +-------- 3 files changed, 125 insertions(+), 19 deletions(-) diff --git a/context.go b/context.go index ba194fb..e2a3c4f 100644 --- a/context.go +++ b/context.go @@ -14,6 +14,7 @@ type Ctx struct { Caller *TelegramClient Message *tgba.Message ma *Matcher + IsToMe bool } // decoder 反射获取的数据 diff --git a/event.go b/event.go index e4e76e1..4ebe849 100644 --- a/event.go +++ b/event.go @@ -2,9 +2,13 @@ package rei import ( "reflect" + "strings" + base14 "github.com/fumiama/go-base16384" tgba "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus" + "github.com/wdvxdr1123/ZeroBot/utils/helper" ) // Event ... @@ -65,6 +69,125 @@ func (tc *TelegramClient) processEvent(update tgba.Update) { } func match(ctx *Ctx, matchers []*Matcher) { + if ctx.Message != nil && ctx.Message.Text != "" { // 确保无空 + ctx.IsToMe = func(ctx *Ctx) bool { + if ctx.Message.Chat.IsPrivate() { + return true + } + name := ctx.Caller.Self.String() + if strings.HasPrefix(ctx.Message.Text, name) { + logrus.Debugln("[event] message before process:", ctx.Message.Text) + if len(ctx.Message.Entities) > 0 { + n := len(name) + c := 0 + i := 0 + for _, e := range ctx.Message.Entities { + c += e.Length + if c >= n { + break + } + i++ + } + if i > 0 { + switch { + case c < n: + ctx.Message.Entities = nil + case c == n: + if i+1 < len(ctx.Message.Entities) { + ctx.Message.Entities = ctx.Message.Entities[i+1:] + ctx.Message.Entities[0].Offset = 0 + } + default: + ctx.Message.Entities = ctx.Message.Entities[i:] + ctx.Message.Entities[0].Length -= c - n + ctx.Message.Entities[0].Offset = 0 + } + if len(ctx.Message.Entities) > 1 { + o := ctx.Message.Entities[0].Length + for _, e := range ctx.Message.Entities[1:] { + e.Offset = o + o += e.Length + } + } + } + } + ctx.Message.Text = ctx.Message.Text[len(name):] + logrus.Debugln("[event] message after process:", ctx.Message.Text) + return true + } + u16txt, err := base14.UTF82UTF16BE(helper.StringToBytes(ctx.Message.Text)) + if err != nil { + return false + } + for i, e := range ctx.Message.Entities { + if e.IsMention() && e.Length > 0 { + a := 2 * (e.Offset + 1) + b := 2 * (e.Offset + e.Length) + if a < b && a < len(u16txt) && b <= len(u16txt) { + n, err := base14.UTF16BE2UTF8(u16txt[a:b]) + if err != nil { + continue + } + if helper.BytesToString(n) == name { + logrus.Debugln("[event] message before process:", ctx.Message.Text) + n, err = base14.UTF16BE2UTF8(append(u16txt[:2*e.Offset], u16txt[b:]...)) + if err != nil { + continue + } + ctx.Message.Text = helper.BytesToString(n) + o := e.Offset + ctx.Message.Entities = append(ctx.Message.Entities[:i], ctx.Message.Entities[i+1:]...) + for _, e1 := range ctx.Message.Entities[i:] { + e1.Offset = o + o += e1.Length + } + if ctx.Message.Text[0] == ' ' { + n := 0 + for c := range ctx.Message.Text { + if c == ' ' { + n++ + } else { + break + } + } + ctx.Message.Text = ctx.Message.Text[n:] + u16txt = u16txt[2*n:] + for _, e1 := range ctx.Message.Entities { + if e1.Offset >= n { + e1.Offset -= n + } + } + } + if ctx.Message.Text[len(ctx.Message.Text)-1] == ' ' { + n := 0 + for i := len(ctx.Message.Text) - 1; i >= 0; i-- { + if ctx.Message.Text[i] == ' ' { + n++ + } else { + break + } + } + ctx.Message.Text = ctx.Message.Text[:len(ctx.Message.Text)-n] + if len(ctx.Message.Entities) > 0 { + elast := ctx.Message.Entities[len(ctx.Message.Entities)-n] + if elast.Offset+elast.Length == len(u16txt)/2 { + if elast.Length > n { + elast.Length -= n + } else { + ctx.Message.Entities = ctx.Message.Entities[:len(ctx.Message.Entities)-1] + } + } + } + } + logrus.Debugln("[event] message after process:", ctx.Message.Text) + return true + } + } + } + } + return false + }(ctx) + } loop: for _, matcher := range matchers { for k := range ctx.State { // Clear State diff --git a/rules.go b/rules.go index 3c51522..b5c37f9 100644 --- a/rules.go +++ b/rules.go @@ -194,25 +194,7 @@ func ShellRule(cmd string, model interface{}) Rule { // OnlyToMe only triggered in conditions of @bot or begin with the nicknames func OnlyToMe(ctx *Ctx) bool { - msg, ok := ctx.Value.(*tgba.Message) - if !ok || msg.Text == "" { // 确保无空 - return false - } - if msg.Chat.IsPrivate() { - return true - } - name := ctx.Caller.Self.String() - if strings.HasPrefix(msg.Text, name) { - return true - } - n := 0 - for _, e := range msg.Entities { - if e.IsMention() && e.Length > 0 && msg.Text[n+1:n+e.Length] == name { - return true - } - n += e.Length - } - return false + return ctx.IsToMe } // CheckUser only triggered by specific person