diff --git a/coolq/cqcode.go b/coolq/cqcode.go index edb6a70..6333899 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -155,7 +155,7 @@ func ToArrayMessage(e []message.IMessageElement, groupID int64) (r []MSG) { var m MSG switch o := elem.(type) { case *message.ReplyElement: - if RemoveReplyAt && len(e) > i+1 { + if RemoveReplyAt && i+1 < len(e) && e[i+1].Type() == message.At { elem, ok := e[i+1].(*message.AtElement) if ok && elem.Target == o.Sender { e[i+1] = nil @@ -180,7 +180,7 @@ func ToArrayMessage(e []message.IMessageElement, groupID int64) (r []MSG) { } else { m = MSG{ "type": "at", - "data": map[string]string{"qq": fmt.Sprint(o.Target)}, + "data": map[string]string{"qq": strconv.FormatInt(o.Target, 10)}, } } case *message.RedBagElement: @@ -234,12 +234,12 @@ func ToArrayMessage(e []message.IMessageElement, groupID int64) (r []MSG) { if isOk := strings.Contains(o.Content, " ] */ -func CQCodeEscapeText(raw string) string { - ret := raw - ret = strings.ReplaceAll(ret, "&", "&") - ret = strings.ReplaceAll(ret, "[", "[") - ret = strings.ReplaceAll(ret, "]", "]") - return ret +func CQCodeEscapeText(s string) string { + count := strings.Count(s, "&") + count += strings.Count(s, "[") + count += strings.Count(s, "]") + if count == 0 { + return s + } + + // Apply replacements to buffer. + var b strings.Builder + b.Grow(len(s) + count*4) + start := 0 + for i := 0; i < count; i++ { + j := start + strings.IndexFunc(s[start:], func(r rune) bool { + return r == '&' || r == '[' || r == ']' + }) + b.WriteString(s[start:j]) + switch s[j] { + case '&': + b.WriteString("&") + case '[': + b.WriteString("[") + case ']': + b.WriteString("]") + } + start = j + 1 + } + b.WriteString(s[start:]) + return b.String() } /*CQCodeEscapeValue 将字符串value中部分字符转义 diff --git a/coolq/cqcode_test.go b/coolq/cqcode_test.go index 8a25ed9..3edf7bb 100644 --- a/coolq/cqcode_test.go +++ b/coolq/cqcode_test.go @@ -2,8 +2,11 @@ package coolq import ( "fmt" + "strings" "testing" + "github.com/Mrs4s/MiraiGo/utils" + "github.com/stretchr/testify/assert" "github.com/tidwall/gjson" ) @@ -30,3 +33,32 @@ func BenchmarkCQBot_ConvertObjectMessage(b *testing.B) { bot.ConvertObjectMessage(benchArray, false) } } + +const bText = `123456789[]&987654321[]&987654321[]&987654321[]&987654321[]&987654321[]&` + +func BenchmarkCQCodeEscapeText(b *testing.B) { + for i := 0; i < b.N; i++ { + ret := bText + ret = CQCodeEscapeText(ret) + } +} + +func BenchmarkCQCodeEscapeTextBefore(b *testing.B) { + for i := 0; i < b.N; i++ { + ret := bText + ret = strings.ReplaceAll(ret, "&", "&") + ret = strings.ReplaceAll(ret, "[", "[") + ret = strings.ReplaceAll(ret, "]", "]") + } +} + +func TestCQCodeEscapeText(t *testing.T) { + for i := 0; i < 200; i++ { + rs := utils.RandomStringRange(3000, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890[]&") + ret := rs + ret = strings.ReplaceAll(ret, "&", "&") + ret = strings.ReplaceAll(ret, "[", "[") + ret = strings.ReplaceAll(ret, "]", "]") + assert.Equal(t, ret, CQCodeEscapeText(rs)) + } +} diff --git a/global/codec.go b/global/codec.go index 5437881..9ff78cb 100644 --- a/global/codec.go +++ b/global/codec.go @@ -2,7 +2,7 @@ package global import ( "crypto/md5" - "fmt" + "encoding/hex" "os" "os/exec" "path" @@ -19,7 +19,7 @@ func EncoderSilk(data []byte) ([]byte, error) { if err != nil { return nil, errors.Wrap(err, "calc md5 failed") } - tempName := fmt.Sprintf("%x", h.Sum(nil)) + tempName := hex.EncodeToString(h.Sum(nil)) if silkPath := path.Join("data/cache", tempName+".silk"); PathExists(silkPath) { return os.ReadFile(silkPath) } diff --git a/global/update/update.go b/global/update/update.go index 0b54b9d..b7028e5 100644 --- a/global/update/update.go +++ b/global/update/update.go @@ -7,7 +7,6 @@ import ( "fmt" "hash" "io" - "io/ioutil" "os" "path/filepath" @@ -42,7 +41,7 @@ func FromStream(updateWith io.Reader) (err error, errRecover error) { // no patch to apply, go on through bufBytes := bufio.NewReader(updateWith) updateWith = io.Reader(bufBytes) - newBytes, err = ioutil.ReadAll(updateWith) + newBytes, err = io.ReadAll(updateWith) if err != nil { return }