From c27ebadbc47572c1b3f5398faae74bebf66a2197 Mon Sep 17 00:00:00 2001 From: XYenon Date: Mon, 10 Aug 2020 13:59:46 +0800 Subject: [PATCH 01/78] Add support for post_message_format: array --- coolq/api.go | 2 +- coolq/bot.go | 2 +- coolq/cqcode.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ coolq/event.go | 21 ++++++++++++--- docs/config.md | 3 ++- global/config.go | 18 +++++++------ main.go | 15 ++++++++--- 7 files changed, 113 insertions(+), 18 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 1350ee5..22c124f 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -446,7 +446,7 @@ func (bot *CQBot) CQGetForwardMessage(resId string) MSG { "nickname": n.SenderName, }, "time": n.Time, - "content": ToStringMessage(n.Message, 0, false), + "content": ToFormattedMessage(n.Message, 0, false), }) } return OK(MSG{ diff --git a/coolq/bot.go b/coolq/bot.go index a63b5a3..c3827c7 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -154,7 +154,7 @@ func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage) int32 { "group-name": m.GroupName, "sender": m.Sender, "time": m.Time, - "message": ToStringMessage(m.Elements, m.GroupCode, true), + "message": ToFormattedMessage(m.Elements, m.GroupCode, true), } id := ToGlobalId(m.GroupCode, m.Id) if bot.db != nil { diff --git a/coolq/cqcode.go b/coolq/cqcode.go index fde5dc6..1303b89 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -23,6 +23,76 @@ var matchReg = regexp.MustCompile(`\[CQ:\w+?.*?]`) var typeReg = regexp.MustCompile(`\[CQ:(\w+)`) var paramReg = regexp.MustCompile(`,([\w\-.]+?)=([^,\]]+)`) +func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []MSG) { + ur := false + if len(raw) != 0 { + ur = raw[0] + } + for _, elem := range e { + m := MSG{} + switch o := elem.(type) { + case *message.TextElement: + m = MSG{ + "type": "text", + "data": map[string]string{"text": CQCodeEscapeText(o.Content)}, + } + case *message.AtElement: + if o.Target == 0 { + m = MSG{ + "type": "at", + "data": map[string]string{"qq": "all"}, + } + } else { + m = MSG{ + "type": "at", + "data": map[string]string{"qq": fmt.Sprint(o.Target)}, + } + } + case *message.ReplyElement: + m = MSG{ + "type": "reply", + "data": map[string]string{"id": fmt.Sprint(ToGlobalId(code, o.ReplySeq))}, + } + case *message.ForwardElement: + m = MSG{ + "type": "forward", + "data": map[string]string{"id": o.ResId}, + } + case *message.FaceElement: + m = MSG{ + "type": "face", + "data": map[string]string{"id": fmt.Sprint(o.Index)}, + } + case *message.VoiceElement: + if ur { + m = MSG{ + "type": "record", + "data": map[string]string{"file": o.Name}, + } + } else { + m = MSG{ + "type": "record", + "data": map[string]string{"file": o.Name, "url": o.Url}, + } + } + case *message.ImageElement: + if ur { + m = MSG{ + "type": "image", + "data": map[string]string{"file": o.Filename}, + } + } else { + m = MSG{ + "type": "image", + "data": map[string]string{"file": o.Filename, "url": o.Url}, + } + } + } + r = append(r, m) + } + return +} + func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r string) { ur := false if len(raw) != 0 { diff --git a/coolq/event.go b/coolq/event.go index 7838ea3..61f44ed 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -14,6 +14,21 @@ import ( "time" ) +var format = "string" + +func SetMessageFormat(f string) { + format = f +} + +func ToFormattedMessage(e []message.IMessageElement, code int64, raw ...bool) (r interface{}) { + if format == "string" { + r = ToStringMessage(e, code, raw...) + } else if format == "array" { + r = ToArrayMessage(e, code, raw...) + } + return +} + func (bot *CQBot) privateMessageEvent(c *client.QQClient, m *message.PrivateMessage) { checkMedia(m.Elements) cqm := ToStringMessage(m.Elements, 0, true) @@ -24,7 +39,7 @@ func (bot *CQBot) privateMessageEvent(c *client.QQClient, m *message.PrivateMess "sub_type": "friend", "message_id": ToGlobalId(m.Sender.Uin, m.Id), "user_id": m.Sender.Uin, - "message": ToStringMessage(m.Elements, 0, false), + "message": ToFormattedMessage(m.Elements, 0, false), "raw_message": cqm, "font": 0, "self_id": c.Uin, @@ -72,7 +87,7 @@ func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) "anonymous": nil, "font": 0, "group_id": m.GroupCode, - "message": ToStringMessage(m.Elements, m.GroupCode, false), + "message": ToFormattedMessage(m.Elements, m.GroupCode, false), "message_id": id, "message_type": "group", "post_type": "message", @@ -128,7 +143,7 @@ func (bot *CQBot) tempMessageEvent(c *client.QQClient, m *message.TempMessage) { "sub_type": "group", "message_id": m.Id, "user_id": m.Sender.Uin, - "message": ToStringMessage(m.Elements, 0, false), + "message": ToFormattedMessage(m.Elements, 0, false), "raw_message": cqm, "font": 0, "self_id": c.Uin, diff --git a/docs/config.md b/docs/config.md index 6428cba..dcaa77e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -28,7 +28,8 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为: "enabled": true, "host": "0.0.0.0", "port": 5700, - "post_urls": {"url:port": "secret"} + "post_urls": {"url:port": "secret"}, + "post_message_format": "string" }, "ws_config": { "enabled": true, diff --git a/global/config.go b/global/config.go index 267cd5b..ba94521 100644 --- a/global/config.go +++ b/global/config.go @@ -40,10 +40,11 @@ type CQHttpApiConfig struct { } type GoCQHttpConfig struct { - Enabled bool `json:"enabled"` - Host string `json:"host"` - Port uint16 `json:"port"` - PostUrls map[string]string `json:"post_urls"` + Enabled bool `json:"enabled"` + Host string `json:"host"` + Port uint16 `json:"port"` + PostUrls map[string]string `json:"post_urls"` + PostMessageFormat string `json:"post_message_format"` } type GoCQWebsocketConfig struct { @@ -66,10 +67,11 @@ func DefaultConfig() *JsonConfig { ReLogin: true, ReLoginDelay: 3, HttpConfig: &GoCQHttpConfig{ - Enabled: true, - Host: "0.0.0.0", - Port: 5700, - PostUrls: map[string]string{}, + Enabled: true, + Host: "0.0.0.0", + Port: 5700, + PostUrls: map[string]string{}, + PostMessageFormat: "string", }, WSConfig: &GoCQWebsocketConfig{ Enabled: true, diff --git a/main.go b/main.go index 8b2cbeb..1085e51 100644 --- a/main.go +++ b/main.go @@ -91,10 +91,11 @@ func main() { Uin: uin, Password: pwd, HttpConfig: &global.GoCQHttpConfig{ - Enabled: true, - Host: "0.0.0.0", - Port: 5700, - PostUrls: map[string]string{}, + Enabled: true, + Host: "0.0.0.0", + Port: 5700, + PostUrls: map[string]string{}, + PostMessageFormat: "string", }, WSConfig: &global.GoCQWebsocketConfig{ Enabled: true, @@ -193,6 +194,12 @@ func main() { b := coolq.NewQQBot(cli, conf) if conf.HttpConfig != nil && conf.HttpConfig.Enabled { server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b) + if conf.HttpConfig.PostMessageFormat != "string" && conf.HttpConfig.PostMessageFormat != "array" { + log.Errorf("http_config.post_message_format 配置错误") + return + } else { + coolq.SetMessageFormat(conf.HttpConfig.PostMessageFormat) + } for k, v := range conf.HttpConfig.PostUrls { server.NewHttpClient().Run(k, v, b) } From 5c4f586c36e5f51b88d9f12b0f88ca9d8a558112 Mon Sep 17 00:00:00 2001 From: XYenon Date: Mon, 10 Aug 2020 19:44:54 +0800 Subject: [PATCH 02/78] Use string format in db --- coolq/bot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/bot.go b/coolq/bot.go index c3827c7..a63b5a3 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -154,7 +154,7 @@ func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage) int32 { "group-name": m.GroupName, "sender": m.Sender, "time": m.Time, - "message": ToFormattedMessage(m.Elements, m.GroupCode, true), + "message": ToStringMessage(m.Elements, m.GroupCode, true), } id := ToGlobalId(m.GroupCode, m.Id) if bot.db != nil { From 72a7430841845589e68dc7957f33a0267a17e9e3 Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Mon, 10 Aug 2020 20:43:31 +0800 Subject: [PATCH 03/78] add api type check --- server/http.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/server/http.go b/server/http.go index b191a62..15b9e8f 100644 --- a/server/http.go +++ b/server/http.go @@ -235,8 +235,8 @@ func (s *httpServer) SendMessage(c *gin.Context) { func (s *httpServer) SendPrivateMessage(c *gin.Context) { uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64) - msg := getParam(c, "message") - if gjson.Valid(msg) { + msg, t := getParamWithType(c, "message") + if t == gjson.JSON { c.JSON(200, s.bot.CQSendPrivateMessage(uid, gjson.Parse(msg))) return } @@ -245,8 +245,8 @@ func (s *httpServer) SendPrivateMessage(c *gin.Context) { func (s *httpServer) SendGroupMessage(c *gin.Context) { gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64) - msg := getParam(c, "message") - if gjson.Valid(msg) { + msg, t := getParamWithType(c, "message") + if t == gjson.JSON { c.JSON(200, s.bot.CQSendGroupMessage(gid, gjson.Parse(msg))) return } @@ -372,14 +372,19 @@ func getParamOrDefault(c *gin.Context, k, def string) string { } func getParam(c *gin.Context, k string) string { + p, _ := getParamWithType(c, k) + return p +} + +func getParamWithType(c *gin.Context, k string) (string, gjson.Type) { if q := c.Query(k); q != "" { - return q + return q, gjson.Null } if c.Request.Method == "POST" { if h := c.Request.Header.Get("Content-Type"); h != "" { if h == "application/x-www-form-urlencoded" { if p, ok := c.GetPostForm(k); ok { - return p + return p, gjson.Null } } if h == "application/json" { @@ -388,20 +393,20 @@ func getParam(c *gin.Context, k string) string { if res.Exists() { switch res.Type { case gjson.JSON: - return res.Raw + return res.Raw, gjson.JSON case gjson.String: - return res.Str + return res.Str, gjson.String case gjson.Number: - return strconv.FormatInt(res.Int(), 10) // 似乎没有需要接受 float 类型的api + return strconv.FormatInt(res.Int(), 10), gjson.Number // 似乎没有需要接受 float 类型的api case gjson.True: - return "true" + return "true", gjson.True case gjson.False: - return "false" + return "false", gjson.False } } } } } } - return "" + return "", gjson.Null } From a075f41a51a743e560c497ea6f7c80c494636fcd Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 11 Aug 2020 15:19:54 +0800 Subject: [PATCH 04/78] http post timeout setting supported. close #77 --- global/config.go | 1 + main.go | 2 +- server/http.go | 15 ++++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/global/config.go b/global/config.go index ba94521..2c6ca75 100644 --- a/global/config.go +++ b/global/config.go @@ -43,6 +43,7 @@ type GoCQHttpConfig struct { Enabled bool `json:"enabled"` Host string `json:"host"` Port uint16 `json:"port"` + Timeout int32 `json:"timeout"` PostUrls map[string]string `json:"post_urls"` PostMessageFormat string `json:"post_message_format"` } diff --git a/main.go b/main.go index 1085e51..322414a 100644 --- a/main.go +++ b/main.go @@ -201,7 +201,7 @@ func main() { coolq.SetMessageFormat(conf.HttpConfig.PostMessageFormat) } for k, v := range conf.HttpConfig.PostUrls { - server.NewHttpClient().Run(k, v, b) + server.NewHttpClient().Run(k, v, conf.HttpConfig.Timeout, b) } } if conf.WSConfig != nil && conf.WSConfig.Enabled { diff --git a/server/http.go b/server/http.go index 15b9e8f..10504e2 100644 --- a/server/http.go +++ b/server/http.go @@ -21,9 +21,10 @@ type httpServer struct { } type httpClient struct { - bot *coolq.CQBot - secret string - addr string + bot *coolq.CQBot + secret string + addr string + timeout int32 } var HttpServer = &httpServer{} @@ -163,10 +164,14 @@ func NewHttpClient() *httpClient { return &httpClient{} } -func (c *httpClient) Run(addr, secret string, bot *coolq.CQBot) { +func (c *httpClient) Run(addr, secret string, timeout int32, bot *coolq.CQBot) { c.bot = bot c.secret = secret c.addr = addr + c.timeout = timeout + if c.timeout < 5 { + c.timeout = 5 + } bot.OnEventPush(c.onBotPushEvent) log.Infof("HTTP POST上报器已启动: %v", addr) } @@ -184,7 +189,7 @@ func (c *httpClient) onBotPushEvent(m coolq.MSG) { h["X-Signature"] = "sha1=" + hex.EncodeToString(mac.Sum(nil)) } return h - }()).SetTimeout(time.Second * 5).Do() + }()).SetTimeout(time.Second * time.Duration(c.timeout)).Do() if err != nil { log.Warnf("上报Event数据到 %v 失败: %v", c.addr, err) return From 6c0e78b60c190502f54187efd918b9b81d80db53 Mon Sep 17 00:00:00 2001 From: yyuueexxiinngg Date: Tue, 11 Aug 2020 15:22:26 +0800 Subject: [PATCH 05/78] Remove content escape when using array post message format. --- coolq/cqcode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 1303b89..31276d1 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -34,7 +34,7 @@ func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []M case *message.TextElement: m = MSG{ "type": "text", - "data": map[string]string{"text": CQCodeEscapeText(o.Content)}, + "data": map[string]string{"text": o.Content}, } case *message.AtElement: if o.Target == 0 { From 129622dd24356382bdb01ba3e73f53c828f8c53d Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 11 Aug 2020 17:32:09 +0800 Subject: [PATCH 06/78] fix reverse push issue. --- server/websocket.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/websocket.go b/server/websocket.go index a1a9e8f..9ffe744 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -172,6 +172,7 @@ func (c *websocketClient) listenApi(conn *wsc.Conn, u bool) { ret["echo"] = j.Get("echo").Value() } c.pushLock.Lock() + log.Debugf("准备发送API %v 处理结果: %v", t, ret.ToJson()) _, _ = conn.Write([]byte(ret.ToJson())) c.pushLock.Unlock() } @@ -191,7 +192,6 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { defer c.pushLock.Unlock() if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) - _ = c.eventConn.SetWriteDeadline(time.Now().Add(time.Second * 3)) if _, err := c.eventConn.Write([]byte(m.ToJson())); err != nil { _ = c.eventConn.Close() if c.conf.ReverseReconnectInterval != 0 { @@ -204,7 +204,6 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { } if c.universalConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.universalConn.RemoteAddr().String(), m.ToJson()) - _ = c.universalConn.SetWriteDeadline(time.Now().Add(time.Second * 3)) _, _ = c.universalConn.Write([]byte(m.ToJson())) } } From 23d436972c23cbcfd7c2929f50b7fc09153b809e Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 11 Aug 2020 17:35:03 +0800 Subject: [PATCH 07/78] save captcha to local file. close #71 --- main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 322414a..203f33c 100644 --- a/main.go +++ b/main.go @@ -166,9 +166,10 @@ func main() { if !rsp.Success { switch rsp.Error { case client.NeedCaptcha: + _ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, 0677) img, _, _ := image.Decode(bytes.NewReader(rsp.CaptchaImage)) fmt.Println(asciiart.New("image", img).Art) - log.Warn("请输入验证码: (Enter 提交)") + log.Warn("请输入验证码 (captcha.jpg): (Enter 提交)") text, _ := console.ReadString('\n') rsp, err = cli.SubmitCaptcha(strings.ReplaceAll(text, "\n", ""), rsp.CaptchaSign) continue From 1967e687af14466d6654e61fa214acb96c95a83a Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 11 Aug 2020 17:38:33 +0800 Subject: [PATCH 08/78] fix perm error. --- main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 203f33c..f8134dc 100644 --- a/main.go +++ b/main.go @@ -37,12 +37,12 @@ func init() { log.SetOutput(io.MultiWriter(os.Stderr, w)) } if !global.PathExists(global.IMAGE_PATH) { - if err := os.MkdirAll(global.IMAGE_PATH, 0677); err != nil { + if err := os.MkdirAll(global.IMAGE_PATH, os.ModePerm); err != nil { log.Fatalf("创建图片缓存文件夹失败: %v", err) } } if !global.PathExists(global.VOICE_PATH) { - if err := os.MkdirAll(global.VOICE_PATH, 06777); err != nil { + if err := os.MkdirAll(global.VOICE_PATH, os.ModePerm); err != nil { log.Fatalf("创建语音缓存文件夹失败: %v", err) } } @@ -130,7 +130,7 @@ func main() { if !global.PathExists("device.json") { log.Warn("虚拟设备信息不存在, 将自动生成随机设备.") client.GenRandomDevice() - _ = ioutil.WriteFile("device.json", client.SystemDeviceInfo.ToJson(), 0777) + _ = ioutil.WriteFile("device.json", client.SystemDeviceInfo.ToJson(), os.ModePerm) log.Info("已生成设备信息并保存到 device.json 文件.") } else { log.Info("将使用 device.json 内的设备信息运行Bot.") @@ -166,7 +166,7 @@ func main() { if !rsp.Success { switch rsp.Error { case client.NeedCaptcha: - _ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, 0677) + _ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, os.ModePerm) img, _, _ := image.Decode(bytes.NewReader(rsp.CaptchaImage)) fmt.Println(asciiart.New("image", img).Art) log.Warn("请输入验证码 (captcha.jpg): (Enter 提交)") From 782a3e2a39effcd73fd6159468fcab689e497189 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 11 Aug 2020 17:47:16 +0800 Subject: [PATCH 09/78] add default 'http_config.post_message_format' value. --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index f8134dc..c44f818 100644 --- a/main.go +++ b/main.go @@ -196,8 +196,8 @@ func main() { if conf.HttpConfig != nil && conf.HttpConfig.Enabled { server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b) if conf.HttpConfig.PostMessageFormat != "string" && conf.HttpConfig.PostMessageFormat != "array" { - log.Errorf("http_config.post_message_format 配置错误") - return + log.Warnf("http_config.post_message_format 配置错误, 将自动使用 string") + coolq.SetMessageFormat("string") } else { coolq.SetMessageFormat(conf.HttpConfig.PostMessageFormat) } From 69675aa0f9c5428c79f0dacccbaff6fc458bb7c5 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 12 Aug 2020 05:01:16 +0800 Subject: [PATCH 10/78] fix #75. --- server/http.go | 8 ++++++++ server/websocket.go | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/server/http.go b/server/http.go index 10504e2..dc28bf9 100644 --- a/server/http.go +++ b/server/http.go @@ -229,6 +229,14 @@ func (s *httpServer) GetGroupMemberInfo(c *gin.Context) { } func (s *httpServer) SendMessage(c *gin.Context) { + if getParam(c, "message_type") == "private" { + s.SendPrivateMessage(c) + return + } + if getParam(c, "message_type") == "group" { + s.SendGroupMessage(c) + return + } if getParam(c, "group_id") != "" { s.SendGroupMessage(c) return diff --git a/server/websocket.go b/server/websocket.go index 9ffe744..6b558ca 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -331,6 +331,12 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{ ) }, "send_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { + if p.Get("message_type").Str == "private" { + return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message")) + } + if p.Get("message_type").Str == "group" { + return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message")) + } if p.Get("group_id").Int() != 0 { return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message")) } From f1ffa17d2014a60cea148c11598e97fc1bcc374f Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 12 Aug 2020 09:19:00 +0800 Subject: [PATCH 11/78] update MiraiGo. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index fa9f430..c77515b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200810032556-a425f9d1b98e + github.com/Mrs4s/MiraiGo v0.0.0-20200812011522-ee1117893fad github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 diff --git a/go.sum b/go.sum index 8db1332..26d3602 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/Mrs4s/MiraiGo v0.0.0-20200809221224-7a84cfae6795 h1:Bu4k9ZS/IIy9Shwd9 github.com/Mrs4s/MiraiGo v0.0.0-20200809221224-7a84cfae6795/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/Mrs4s/MiraiGo v0.0.0-20200810032556-a425f9d1b98e h1:5LYDouOL9ZgTL5PwZuuSlFYSfboRQjnXqRIlhviRcGE= github.com/Mrs4s/MiraiGo v0.0.0-20200810032556-a425f9d1b98e/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200812011522-ee1117893fad h1:mOz8SozY2NEjXivlOrTwGPsbukcpLYpi/rv0/ASM/Hg= +github.com/Mrs4s/MiraiGo v0.0.0-20200812011522-ee1117893fad/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 5683db63246592d6cf512456c6f5013f5b671775 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 12 Aug 2020 09:33:25 +0800 Subject: [PATCH 12/78] fix #80. --- coolq/event.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/event.go b/coolq/event.go index 61f44ed..33252e7 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -316,7 +316,7 @@ func (bot *CQBot) groupJoinReqEvent(c *client.QQClient, e *client.UserJoinGroupR "sub_type": "add", "group_id": e.GroupCode, "user_id": e.RequesterUin, - "comment": "", + "comment": e.Message, "flag": flag, "time": time.Now().Unix(), "self_id": c.Uin, From bb03315930080aa50c82d12c6b010bf52b3e9787 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 12 Aug 2020 09:52:32 +0800 Subject: [PATCH 13/78] try to support escape again. #9 --- coolq/cqcode.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 31276d1..47bc99d 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -118,13 +118,13 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st if ur { r += fmt.Sprintf(`[CQ:record,file=%s]`, o.Name) } else { - r += fmt.Sprintf(`[CQ:record,file=%s,url=%s]`, o.Name, o.Url) + r += fmt.Sprintf(`[CQ:record,file=%s,url=%s]`, o.Name, CQCodeEscapeValue(o.Url)) } case *message.ImageElement: if ur { r += fmt.Sprintf(`[CQ:image,file=%s]`, o.Filename) } else { - r += fmt.Sprintf(`[CQ:image,file=%s,url=%s]`, o.Filename, o.Url) + r += fmt.Sprintf(`[CQ:image,file=%s,url=%s]`, o.Filename, CQCodeEscapeValue(o.Url)) } } } @@ -145,7 +145,7 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa ps := paramReg.FindAllStringSubmatch(code, -1) d := make(map[string]string) for _, p := range ps { - d[p[1]] = p[2] + d[p[1]] = CQCodeUnescapeValue(p[2]) } if t == "reply" && group { if len(r) > 0 { @@ -399,6 +399,12 @@ func CQCodeEscapeText(raw string) string { return ret } +func CQCodeEscapeValue(value string) string { + ret := CQCodeEscapeText(value) + ret = strings.ReplaceAll(ret, ",", ",") + return ret +} + func CQCodeUnescapeText(content string) string { ret := content ret = strings.ReplaceAll(ret, "[", "[") @@ -406,3 +412,9 @@ func CQCodeUnescapeText(content string) string { ret = strings.ReplaceAll(ret, "&", "&") return ret } + +func CQCodeUnescapeValue(content string) string { + ret := CQCodeUnescapeText(content) + ret = strings.ReplaceAll(ret, ",", ",") + return ret +} From a49a57b96411fd3549248cdf3ce335f0a0de094e Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Wed, 12 Aug 2020 12:23:48 +0800 Subject: [PATCH 14/78] adjust unescape order --- coolq/cqcode.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 47bc99d..f885439 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -414,7 +414,7 @@ func CQCodeUnescapeText(content string) string { } func CQCodeUnescapeValue(content string) string { - ret := CQCodeUnescapeText(content) - ret = strings.ReplaceAll(ret, ",", ",") + ret := strings.ReplaceAll(content, ",", ",") + ret = CQCodeUnescapeText(ret) return ret } From 611d16d79e3b805a870bb0121998446f332dd64c Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 13 Aug 2020 11:14:21 +0800 Subject: [PATCH 15/78] update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index e9944d0..27d1981 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,16 @@ +# 关于ISSUE + +以下ISSUE会被直接关闭 +- 提交BUG不使用Template +- 询问已知问题 +- 提问找不到重点 +- 重复提问 + +> 请注意, 开发者并没有义务回复您的问题. 您应该具备基本的提问技巧。 + # 性能 在关闭数据库的情况下, 加载25个好友128个群运行24小时后内存使用为10MB左右. 开启数据库后内存使用将根据消息量增加10-20MB, 如果系统内存小于128M建议关闭数据库使用. From 1418e36baba8113ed393f5185dbf727a88ca33bc Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 13 Aug 2020 17:18:16 +0800 Subject: [PATCH 16/78] cq code 'video' supported. --- coolq/api.go | 2 +- coolq/cqcode.go | 18 ++++++++++++++++++ coolq/event.go | 25 +++++++++++++++++++------ global/fs.go | 2 ++ go.mod | 2 +- go.sum | 8 ++------ main.go | 5 +++++ 7 files changed, 48 insertions(+), 14 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 22c124f..4699fc4 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -439,7 +439,7 @@ func (bot *CQBot) CQGetForwardMessage(resId string) MSG { } var r []MSG for _, n := range m.Nodes { - checkMedia(n.Message) + bot.checkMedia(n.Message) r = append(r, MSG{ "sender": MSG{ "user_id": n.SenderId, diff --git a/coolq/cqcode.go b/coolq/cqcode.go index f885439..2785b4d 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -75,6 +75,18 @@ func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []M "data": map[string]string{"file": o.Name, "url": o.Url}, } } + case *message.ShortVideoElement: + if ur { + m = MSG{ + "type": "video", + "data": map[string]string{"file": o.Name}, + } + } else { + m = MSG{ + "type": "video", + "data": map[string]string{"file": o.Name, "url": o.Url}, + } + } case *message.ImageElement: if ur { m = MSG{ @@ -120,6 +132,12 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st } else { r += fmt.Sprintf(`[CQ:record,file=%s,url=%s]`, o.Name, CQCodeEscapeValue(o.Url)) } + case *message.ShortVideoElement: + if ur { + r += fmt.Sprintf(`[CQ:video,file=%s]`, o.Name) + } else { + r += fmt.Sprintf(`[CQ:video,file=%s,url=%s]`, o.Name, CQCodeEscapeValue(o.Url)) + } case *message.ImageElement: if ur { r += fmt.Sprintf(`[CQ:image,file=%s]`, o.Filename) diff --git a/coolq/event.go b/coolq/event.go index 33252e7..f1aa697 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -8,6 +8,7 @@ import ( "github.com/Mrs4s/go-cqhttp/global" log "github.com/sirupsen/logrus" "io/ioutil" + "os" "path" "strconv" "strings" @@ -30,7 +31,7 @@ func ToFormattedMessage(e []message.IMessageElement, code int64, raw ...bool) (r } func (bot *CQBot) privateMessageEvent(c *client.QQClient, m *message.PrivateMessage) { - checkMedia(m.Elements) + bot.checkMedia(m.Elements) cqm := ToStringMessage(m.Elements, 0, true) log.Infof("收到好友 %v(%v) 的消息: %v", m.Sender.DisplayName(), m.Sender.Uin, cqm) fm := MSG{ @@ -55,7 +56,7 @@ func (bot *CQBot) privateMessageEvent(c *client.QQClient, m *message.PrivateMess } func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) { - checkMedia(m.Elements) + bot.checkMedia(m.Elements) for _, elem := range m.Elements { if file, ok := elem.(*message.GroupFileElement); ok { log.Infof("群 %v(%v) 内 %v(%v) 上传了文件: %v", m.GroupName, m.GroupCode, m.Sender.DisplayName(), m.Sender.Uin, file.Name) @@ -133,7 +134,7 @@ func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) } func (bot *CQBot) tempMessageEvent(c *client.QQClient, m *message.TempMessage) { - checkMedia(m.Elements) + bot.checkMedia(m.Elements) cqm := ToStringMessage(m.Elements, 0, true) bot.tempMsgCache.Store(m.Sender.Uin, m.GroupCode) log.Infof("收到来自群 %v(%v) 内 %v(%v) 的临时会话消息: %v", m.GroupName, m.GroupCode, m.Sender.DisplayName(), m.Sender.Uin, cqm) @@ -362,7 +363,7 @@ func (bot *CQBot) groupDecrease(groupCode, userUin int64, operator *client.Group } } -func checkMedia(e []message.IMessageElement) { +func (bot *CQBot) checkMedia(e []message.IMessageElement) { for _, elem := range e { switch i := elem.(type) { case *message.ImageElement: @@ -373,7 +374,7 @@ func checkMedia(e []message.IMessageElement) { w.WriteUInt32(uint32(i.Size)) w.WriteString(i.Filename) w.WriteString(i.Url) - }), 0777) + }), os.ModePerm) } i.Filename = filename case *message.VoiceElement: @@ -385,8 +386,20 @@ func checkMedia(e []message.IMessageElement) { log.Warnf("语音文件 %v 下载失败: %v", i.Name, err) continue } - _ = ioutil.WriteFile(path.Join(global.VOICE_PATH, i.Name), b, 0777) + _ = ioutil.WriteFile(path.Join(global.VOICE_PATH, i.Name), b, os.ModePerm) } + case *message.ShortVideoElement: + filename := hex.EncodeToString(i.Md5) + ".video" + if !global.PathExists(path.Join(global.VIDEO_PATH, filename)) { + _ = ioutil.WriteFile(path.Join(global.VIDEO_PATH, filename), binary.NewWriterF(func(w *binary.Writer) { + w.Write(i.Md5) + w.WriteUInt32(uint32(i.Size)) + w.WriteString(i.Name) + w.Write(i.Uuid) + }), os.ModePerm) + } + i.Name = filename + i.Url = bot.Client.GetShortVideoUrl(i.Uuid, i.Md5) } } } diff --git a/global/fs.go b/global/fs.go index 4104511..952ee57 100644 --- a/global/fs.go +++ b/global/fs.go @@ -11,6 +11,8 @@ var IMAGE_PATH = path.Join("data", "images") var VOICE_PATH = path.Join("data", "voices") +var VIDEO_PATH = path.Join("data", "videos") + func PathExists(path string) bool { _, err := os.Stat(path) return err == nil || os.IsExist(err) diff --git a/go.mod b/go.mod index c77515b..355ba1e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200812011522-ee1117893fad + github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 diff --git a/go.sum b/go.sum index 26d3602..0168a9c 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200809221224-7a84cfae6795 h1:Bu4k9ZS/IIy9Shwd9lS/C2P/2I8fYUwg1OpRF91hr1w= -github.com/Mrs4s/MiraiGo v0.0.0-20200809221224-7a84cfae6795/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200810032556-a425f9d1b98e h1:5LYDouOL9ZgTL5PwZuuSlFYSfboRQjnXqRIlhviRcGE= -github.com/Mrs4s/MiraiGo v0.0.0-20200810032556-a425f9d1b98e/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200812011522-ee1117893fad h1:mOz8SozY2NEjXivlOrTwGPsbukcpLYpi/rv0/ASM/Hg= -github.com/Mrs4s/MiraiGo v0.0.0-20200812011522-ee1117893fad/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df h1:ERLrnv7bONrg4NqvC8AWhtEgCZk97uCZdRpQS4gF8UE= +github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/main.go b/main.go index c44f818..8457a9e 100644 --- a/main.go +++ b/main.go @@ -46,6 +46,11 @@ func init() { log.Fatalf("创建语音缓存文件夹失败: %v", err) } } + if !global.PathExists(global.VIDEO_PATH) { + if err := os.MkdirAll(global.VIDEO_PATH, os.ModePerm); err != nil { + log.Fatalf("创建视频缓存文件夹失败: %v", err) + } + } if global.PathExists("cqhttp.json") { log.Info("发现 cqhttp.json 将在五秒后尝试导入配置,按 Ctrl+C 取消.") log.Warn("警告: 该操作会删除 cqhttp.json 并覆盖 config.json 文件.") From 5e498203196e2ac43cce8d5b73f565e6c4412691 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 13 Aug 2020 17:21:54 +0800 Subject: [PATCH 17/78] update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 27d1981..4cd982b 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ - [CQ:image] - [CQ:record] +- [CQ:video] - [CQ:face] - [CQ:at] - [CQ:share] From 3c04573e82d15acd841b1515995cb00691a0d018 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 13 Aug 2020 20:07:21 +0800 Subject: [PATCH 18/78] fix #89. --- coolq/bot.go | 2 +- global/config.go | 12 ++++++------ main.go | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index a63b5a3..e7649b3 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -85,7 +85,7 @@ func (bot *CQBot) GetGroupMessage(mid int32) MSG { if err == nil { return m } - log.Warnf("获取信息时出现错误: %v", err) + log.Warnf("获取信息时出现错误: %v id: %v", err, mid) } return nil } diff --git a/global/config.go b/global/config.go index 2c6ca75..8d18016 100644 --- a/global/config.go +++ b/global/config.go @@ -17,6 +17,7 @@ type JsonConfig struct { HttpConfig *GoCQHttpConfig `json:"http_config"` WSConfig *GoCQWebsocketConfig `json:"ws_config"` ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"` + PostMessageFormat string `json:"post_message_format"` Debug bool `json:"debug"` } @@ -40,12 +41,11 @@ type CQHttpApiConfig struct { } type GoCQHttpConfig struct { - Enabled bool `json:"enabled"` - Host string `json:"host"` - Port uint16 `json:"port"` - Timeout int32 `json:"timeout"` - PostUrls map[string]string `json:"post_urls"` - PostMessageFormat string `json:"post_message_format"` + Enabled bool `json:"enabled"` + Host string `json:"host"` + Port uint16 `json:"port"` + Timeout int32 `json:"timeout"` + PostUrls map[string]string `json:"post_urls"` } type GoCQWebsocketConfig struct { diff --git a/main.go b/main.go index 8457a9e..6eee6cf 100644 --- a/main.go +++ b/main.go @@ -96,18 +96,18 @@ func main() { Uin: uin, Password: pwd, HttpConfig: &global.GoCQHttpConfig{ - Enabled: true, - Host: "0.0.0.0", - Port: 5700, - PostUrls: map[string]string{}, - PostMessageFormat: "string", + Enabled: true, + Host: "0.0.0.0", + Port: 5700, + PostUrls: map[string]string{}, }, WSConfig: &global.GoCQWebsocketConfig{ Enabled: true, Host: "0.0.0.0", Port: 6700, }, - Debug: os.Getenv("DEBUG") == "true", + PostMessageFormat: "string", + Debug: os.Getenv("DEBUG") == "true", } if post != "" { conf.HttpConfig.PostUrls[post] = os.Getenv("HTTP_SECRET") @@ -200,11 +200,11 @@ func main() { b := coolq.NewQQBot(cli, conf) if conf.HttpConfig != nil && conf.HttpConfig.Enabled { server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b) - if conf.HttpConfig.PostMessageFormat != "string" && conf.HttpConfig.PostMessageFormat != "array" { + if conf.PostMessageFormat != "string" && conf.PostMessageFormat != "array" { log.Warnf("http_config.post_message_format 配置错误, 将自动使用 string") coolq.SetMessageFormat("string") } else { - coolq.SetMessageFormat(conf.HttpConfig.PostMessageFormat) + coolq.SetMessageFormat(conf.PostMessageFormat) } for k, v := range conf.HttpConfig.PostUrls { server.NewHttpClient().Run(k, v, conf.HttpConfig.Timeout, b) From edf6180e1c4403fd482c2587aa5e382ca1a41ef7 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 13 Aug 2020 20:09:57 +0800 Subject: [PATCH 19/78] fix ci failed. --- global/config.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/global/config.go b/global/config.go index 8d18016..e41f7c4 100644 --- a/global/config.go +++ b/global/config.go @@ -64,15 +64,15 @@ type GoCQReverseWebsocketConfig struct { func DefaultConfig() *JsonConfig { return &JsonConfig{ - EnableDB: true, - ReLogin: true, - ReLoginDelay: 3, + EnableDB: true, + ReLogin: true, + ReLoginDelay: 3, + PostMessageFormat: "string", HttpConfig: &GoCQHttpConfig{ - Enabled: true, - Host: "0.0.0.0", - Port: 5700, - PostUrls: map[string]string{}, - PostMessageFormat: "string", + Enabled: true, + Host: "0.0.0.0", + Port: 5700, + PostUrls: map[string]string{}, }, WSConfig: &GoCQWebsocketConfig{ Enabled: true, From 50eee15a67f9ea34e42062cf075fcb05f17a5602 Mon Sep 17 00:00:00 2001 From: Arnie97 Date: Thu, 13 Aug 2020 20:53:42 +0800 Subject: [PATCH 20/78] remove os.ModePerm --- coolq/bot.go | 2 +- coolq/event.go | 7 +++---- global/fs.go | 2 +- main.go | 10 +++++----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index e7649b3..926a3cf 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -191,7 +191,7 @@ func (bot *CQBot) dispatchEventMessage(m MSG) { fn(m) end := time.Now() if end.Sub(start) > time.Second*5 { - log.Debugf("警告: 事件处理耗时超过 5 秒 (%v秒), 请检查应用是否有堵塞.", end.Sub(start)/time.Second) + log.Debugf("警告: 事件处理耗时超过 5 秒 (%v), 请检查应用是否有堵塞.", end.Sub(start)) } }() } diff --git a/coolq/event.go b/coolq/event.go index f1aa697..142e096 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -8,7 +8,6 @@ import ( "github.com/Mrs4s/go-cqhttp/global" log "github.com/sirupsen/logrus" "io/ioutil" - "os" "path" "strconv" "strings" @@ -374,7 +373,7 @@ func (bot *CQBot) checkMedia(e []message.IMessageElement) { w.WriteUInt32(uint32(i.Size)) w.WriteString(i.Filename) w.WriteString(i.Url) - }), os.ModePerm) + }), 0644) } i.Filename = filename case *message.VoiceElement: @@ -386,7 +385,7 @@ func (bot *CQBot) checkMedia(e []message.IMessageElement) { log.Warnf("语音文件 %v 下载失败: %v", i.Name, err) continue } - _ = ioutil.WriteFile(path.Join(global.VOICE_PATH, i.Name), b, os.ModePerm) + _ = ioutil.WriteFile(path.Join(global.VOICE_PATH, i.Name), b, 0644) } case *message.ShortVideoElement: filename := hex.EncodeToString(i.Md5) + ".video" @@ -396,7 +395,7 @@ func (bot *CQBot) checkMedia(e []message.IMessageElement) { w.WriteUInt32(uint32(i.Size)) w.WriteString(i.Name) w.Write(i.Uuid) - }), os.ModePerm) + }), 0644) } i.Name = filename i.Url = bot.Client.GetShortVideoUrl(i.Uuid, i.Md5) diff --git a/global/fs.go b/global/fs.go index 952ee57..ec19a6f 100644 --- a/global/fs.go +++ b/global/fs.go @@ -27,7 +27,7 @@ func ReadAllText(path string) string { } func WriteAllText(path, text string) { - _ = ioutil.WriteFile(path, []byte(text), 0777) + _ = ioutil.WriteFile(path, []byte(text), 0644) } func Check(err error) { diff --git a/main.go b/main.go index 6eee6cf..70170fe 100644 --- a/main.go +++ b/main.go @@ -37,17 +37,17 @@ func init() { log.SetOutput(io.MultiWriter(os.Stderr, w)) } if !global.PathExists(global.IMAGE_PATH) { - if err := os.MkdirAll(global.IMAGE_PATH, os.ModePerm); err != nil { + if err := os.MkdirAll(global.IMAGE_PATH, 0755); err != nil { log.Fatalf("创建图片缓存文件夹失败: %v", err) } } if !global.PathExists(global.VOICE_PATH) { - if err := os.MkdirAll(global.VOICE_PATH, os.ModePerm); err != nil { + if err := os.MkdirAll(global.VOICE_PATH, 0755); err != nil { log.Fatalf("创建语音缓存文件夹失败: %v", err) } } if !global.PathExists(global.VIDEO_PATH) { - if err := os.MkdirAll(global.VIDEO_PATH, os.ModePerm); err != nil { + if err := os.MkdirAll(global.VIDEO_PATH, 0755); err != nil { log.Fatalf("创建视频缓存文件夹失败: %v", err) } } @@ -135,7 +135,7 @@ func main() { if !global.PathExists("device.json") { log.Warn("虚拟设备信息不存在, 将自动生成随机设备.") client.GenRandomDevice() - _ = ioutil.WriteFile("device.json", client.SystemDeviceInfo.ToJson(), os.ModePerm) + _ = ioutil.WriteFile("device.json", client.SystemDeviceInfo.ToJson(), 0644) log.Info("已生成设备信息并保存到 device.json 文件.") } else { log.Info("将使用 device.json 内的设备信息运行Bot.") @@ -171,7 +171,7 @@ func main() { if !rsp.Success { switch rsp.Error { case client.NeedCaptcha: - _ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, os.ModePerm) + _ = ioutil.WriteFile("captcha.jpg", rsp.CaptchaImage, 0644) img, _, _ := image.Decode(bytes.NewReader(rsp.CaptchaImage)) fmt.Println(asciiart.New("image", img).Art) log.Warn("请输入验证码 (captcha.jpg): (Enter 提交)") From 9af61a336bc0b33ce02a2999f8266b0d2da02d47 Mon Sep 17 00:00:00 2001 From: Arnie97 Date: Thu, 13 Aug 2020 23:36:16 +0800 Subject: [PATCH 21/78] support silk audio --- global/fs.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/global/fs.go b/global/fs.go index ec19a6f..19cc758 100644 --- a/global/fs.go +++ b/global/fs.go @@ -1,17 +1,22 @@ package global import ( - log "github.com/sirupsen/logrus" + "bytes" "io/ioutil" "os" "path" + + log "github.com/sirupsen/logrus" ) -var IMAGE_PATH = path.Join("data", "images") +var ( + IMAGE_PATH = path.Join("data", "images") + VOICE_PATH = path.Join("data", "voices") + VIDEO_PATH = path.Join("data", "videos") -var VOICE_PATH = path.Join("data", "voices") - -var VIDEO_PATH = path.Join("data", "videos") + HEADER_AMR = []byte("#!AMR") + HEADER_SILK = []byte("\x02#!SILK_V3") +) func PathExists(path string) bool { _, err := os.Stat(path) @@ -37,8 +42,5 @@ func Check(err error) { } func IsAMR(b []byte) bool { - if len(b) <= 6 { - return false - } - return b[0] == 0x23 && b[1] == 0x21 && b[2] == 0x41 && b[3] == 0x4D && b[4] == 0x52 // amr file header + return bytes.HasPrefix(b, HEADER_AMR) || bytes.HasPrefix(b, HEADER_SILK) } From b290a0a5962a690a9d241af5985745a83458a3e0 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 14 Aug 2020 08:28:37 +0800 Subject: [PATCH 22/78] try to fix group image upload failed. #65 --- coolq/bot.go | 2 +- main.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index e7649b3..2ad7ed3 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -94,7 +94,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int var newElem []message.IMessageElement for _, elem := range m.Elements { if i, ok := elem.(*message.ImageElement); ok { - gm, err := bot.Client.UploadGroupImage(groupId, i.Data) + gm, err := bot.Client.UploadGroupImage(114514, i.Data) if err != nil { log.Warnf("警告: 群 %v 消息图片上传失败: %v", groupId, err) continue diff --git a/main.go b/main.go index 6eee6cf..1744cff 100644 --- a/main.go +++ b/main.go @@ -198,14 +198,14 @@ func main() { global.Check(cli.ReloadGroupList()) log.Infof("共加载 %v 个群.", len(cli.GroupList)) b := coolq.NewQQBot(cli, conf) + if conf.PostMessageFormat != "string" && conf.PostMessageFormat != "array" { + log.Warnf("post_message_format 配置错误, 将自动使用 string") + coolq.SetMessageFormat("string") + } else { + coolq.SetMessageFormat(conf.PostMessageFormat) + } if conf.HttpConfig != nil && conf.HttpConfig.Enabled { server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b) - if conf.PostMessageFormat != "string" && conf.PostMessageFormat != "array" { - log.Warnf("http_config.post_message_format 配置错误, 将自动使用 string") - coolq.SetMessageFormat("string") - } else { - coolq.SetMessageFormat(conf.PostMessageFormat) - } for k, v := range conf.HttpConfig.PostUrls { server.NewHttpClient().Run(k, v, conf.HttpConfig.Timeout, b) } From f325b26e1aeffd0993f3a0bf8760f73f353c2da3 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 14 Aug 2020 13:41:48 +0800 Subject: [PATCH 23/78] doc update. close #102 --- docs/config.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index dcaa77e..2ba5612 100644 --- a/docs/config.md +++ b/docs/config.md @@ -24,12 +24,13 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为: "access_token": "", "relogin": false, "relogin_delay": 0, + "post_message_format": "string", "http_config": { "enabled": true, "host": "0.0.0.0", "port": 5700, + "timeout": 5, "post_urls": {"url:port": "secret"}, - "post_message_format": "string" }, "ws_config": { "enabled": true, From 1a1f860dbee798cdd5df0bec4d2e7892515e0b96 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 15 Aug 2020 16:07:56 +0800 Subject: [PATCH 24/78] fix #108. --- server/websocket.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/server/websocket.go b/server/websocket.go index 6b558ca..0e5d00d 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -179,11 +179,9 @@ func (c *websocketClient) listenApi(conn *wsc.Conn, u bool) { } if c.conf.ReverseReconnectInterval != 0 { time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) - if u { - c.connectUniversal() - return + if !u { + c.connectApi() } - c.connectApi() } } @@ -204,7 +202,15 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { } if c.universalConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.universalConn.RemoteAddr().String(), m.ToJson()) - _, _ = c.universalConn.Write([]byte(m.ToJson())) + if _, err := c.universalConn.Write([]byte(m.ToJson())); err != nil { + _ = c.universalConn.Close() + if c.conf.ReverseReconnectInterval != 0 { + go func() { + time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) + c.connectUniversal() + }() + } + } } } From 1fac06f58a7841994e7fad12ab3b1d303fc0d1b5 Mon Sep 17 00:00:00 2001 From: dujiajun <836737136@qq.com> Date: Sat, 15 Aug 2020 23:47:29 +0800 Subject: [PATCH 25/78] fix #103 --- coolq/api.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 4699fc4..960830f 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -404,12 +404,12 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { } case "request": reqType := context.Get("request_type").Str - if context.Get("approve").Bool() { + if operation.Get("approve").Exists() { if reqType == "friend" { - bot.CQProcessFriendRequest(context.Get("flag").Str, true) + bot.CQProcessFriendRequest(context.Get("flag").Str, operation.Get("approve").Bool()) } if reqType == "group" { - bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, true) + bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, operation.Get("approve").Bool()) } } } From be8b68c8e9c5f148f3dc99d7c214cdf90bc12ed9 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 16 Aug 2020 19:27:43 +0800 Subject: [PATCH 26/78] update MiraiGo & async loading supported. close #111 --- global/config.go | 1 + go.mod | 2 +- go.sum | 2 ++ main.go | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/global/config.go b/global/config.go index e41f7c4..3a51bf8 100644 --- a/global/config.go +++ b/global/config.go @@ -14,6 +14,7 @@ type JsonConfig struct { AccessToken string `json:"access_token"` ReLogin bool `json:"relogin"` ReLoginDelay int `json:"relogin_delay"` + AsyncLoad bool `json:"async_load"` HttpConfig *GoCQHttpConfig `json:"http_config"` WSConfig *GoCQWebsocketConfig `json:"ws_config"` ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"` diff --git a/go.mod b/go.mod index 355ba1e..8006fb6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df + github.com/Mrs4s/MiraiGo v0.0.0-20200816111850-988a766ae224 github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 diff --git a/go.sum b/go.sum index 0168a9c..f5e2344 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df h1:ERLrnv7bONrg4NqvC8AWhtEgCZk97uCZdRpQS4gF8UE= github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200816111850-988a766ae224 h1:tlWc7RpBCh5VhT0H6wzm/knxj2PpAV3J7wQyieF0nkk= +github.com/Mrs4s/MiraiGo v0.0.0-20200816111850-988a766ae224/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/main.go b/main.go index f957ad9..c40dbbb 100644 --- a/main.go +++ b/main.go @@ -195,7 +195,7 @@ func main() { global.Check(cli.ReloadFriendList()) log.Infof("共加载 %v 个好友.", len(cli.FriendList)) log.Infof("开始加载群列表...") - global.Check(cli.ReloadGroupList()) + global.Check(cli.ReloadGroupList(conf.AsyncLoad)) log.Infof("共加载 %v 个群.", len(cli.GroupList)) b := coolq.NewQQBot(cli, conf) if conf.PostMessageFormat != "string" && conf.PostMessageFormat != "array" { From 22d9ddb4ea055d3621ebe1c4920049bc1c69aac7 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 16 Aug 2020 19:31:40 +0800 Subject: [PATCH 27/78] try to fix #115. --- coolq/bot.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coolq/bot.go b/coolq/bot.go index 7af88ad..ba27714 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -12,6 +12,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/xujiajun/nutsdb" "hash/crc32" + "math/rand" "path" "sync" "time" @@ -94,7 +95,8 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int var newElem []message.IMessageElement for _, elem := range m.Elements { if i, ok := elem.(*message.ImageElement); ok { - gm, err := bot.Client.UploadGroupImage(114514, i.Data) + _, _ = bot.Client.UploadGroupImage(int64(rand.Intn(11451419198)), i.Data) + gm, err := bot.Client.UploadGroupImage(groupId, i.Data) if err != nil { log.Warnf("警告: 群 %v 消息图片上传失败: %v", groupId, err) continue From 00d80d5dfce6da4c3e62f2682d24a684cfc599a3 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 16 Aug 2020 19:35:38 +0800 Subject: [PATCH 28/78] fix #107. --- coolq/api.go | 8 +++++++- coolq/bot.go | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 960830f..2fa0bee 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -124,7 +124,13 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}) MSG { // fix at display for _, e := range elem { if at, ok := e.(*message.AtElement); ok && at.Target != 0 { - at.Display = "@" + bot.Client.FindGroup(groupId).FindMember(at.Target).DisplayName() + at.Display = "@" + func() string { + mem := bot.Client.FindGroup(groupId).FindMember(at.Target) + if mem != nil { + return mem.DisplayName() + } + return strconv.FormatInt(at.Target, 10) + }() } } mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) diff --git a/coolq/bot.go b/coolq/bot.go index ba27714..c095bf7 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -95,7 +95,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int var newElem []message.IMessageElement for _, elem := range m.Elements { if i, ok := elem.(*message.ImageElement); ok { - _, _ = bot.Client.UploadGroupImage(int64(rand.Intn(11451419198)), i.Data) + _, _ = bot.Client.UploadGroupImage(int64(rand.Intn(11451419)), i.Data) gm, err := bot.Client.UploadGroupImage(groupId, i.Data) if err != nil { log.Warnf("警告: 群 %v 消息图片上传失败: %v", groupId, err) From 4820eb2fecdd929da3dca7dc43136b2961be2b49 Mon Sep 17 00:00:00 2001 From: Richard Chien Date: Mon, 17 Aug 2020 13:46:11 +0800 Subject: [PATCH 29/78] support "auto_escape" in api and quick operation --- coolq/api.go | 30 ++++++++++++++++++--------- global/param.go | 50 +++++++++++++++++++++++++++++++++++++++++++++ server/http.go | 11 ++++++---- server/websocket.go | 13 ++++++------ 4 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 global/param.go diff --git a/coolq/api.go b/coolq/api.go index 2fa0bee..cb65d72 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -96,7 +96,7 @@ func (bot *CQBot) CQGetGroupMemberInfo(groupId, userId int64, noCache bool) MSG } // https://cqhttp.cc/docs/4.15/#/API?id=send_group_msg-%E5%8F%91%E9%80%81%E7%BE%A4%E6%B6%88%E6%81%AF -func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}) MSG { +func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bool) MSG { var str string if m, ok := i.(gjson.Result); ok { if m.Type == gjson.JSON { @@ -113,14 +113,18 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}) MSG { } return m.Raw }() - } - if s, ok := i.(string); ok { + } else if s, ok := i.(string); ok { str = s } if str == "" { return Failed(100) } - elem := bot.ConvertStringMessage(str, true) + var elem []message.IMessageElement + if autoEscape { + elem = append(elem, message.NewText(str)) + } else { + elem = bot.ConvertStringMessage(str, true) + } // fix at display for _, e := range elem { if at, ok := e.(*message.AtElement); ok && at.Target != 0 { @@ -211,7 +215,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupId int64, m gjson.Result) MSG { } // https://cqhttp.cc/docs/4.15/#/API?id=send_private_msg-%E5%8F%91%E9%80%81%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF -func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}) MSG { +func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}, autoEscape bool) MSG { var str string if m, ok := i.(gjson.Result); ok { if m.Type == gjson.JSON { @@ -228,14 +232,18 @@ func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}) MSG { } return m.Raw }() - } - if s, ok := i.(string); ok { + } else if s, ok := i.(string); ok { str = s } if str == "" { return Failed(100) } - elem := bot.ConvertStringMessage(str, false) + var elem []message.IMessageElement + if autoEscape { + elem = append(elem, message.NewText(str)) + } else { + elem = bot.ConvertStringMessage(str, false) + } mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem}) if mid == -1 { return Failed(100) @@ -374,6 +382,7 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { msgType := context.Get("message_type").Str reply := operation.Get("reply") if reply.Exists() { + autoEscape := global.EnsureBool(operation.Get("auto_escape"), false) /* at := true if operation.Get("at_sender").Exists() { @@ -382,10 +391,11 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { */ // TODO: 处理at字段 if msgType == "group" { - bot.CQSendGroupMessage(context.Get("group_id").Int(), reply) + bot.CQSendGroupMessage(context.Get("group_id").Int(), reply, autoEscape) } if msgType == "private" { - bot.CQSendPrivateMessage(context.Get("user_id").Int(), reply) + // TODO: 处理auto_escape + bot.CQSendPrivateMessage(context.Get("user_id").Int(), reply, autoEscape) } } if msgType == "group" { diff --git a/global/param.go b/global/param.go new file mode 100644 index 0000000..259d4af --- /dev/null +++ b/global/param.go @@ -0,0 +1,50 @@ +package global + +import ( + "github.com/tidwall/gjson" + "strings" +) + +var trueSet = map[string]struct{}{ + "true": struct{}{}, + "yes": struct{}{}, + "1": struct{}{}, +} + +var falseSet = map[string]struct{}{ + "false": struct{}{}, + "no": struct{}{}, + "0": struct{}{}, +} + +func EnsureBool(p interface{}, defaultVal bool) bool { + var str string + if b, ok := p.(bool); ok { + return b + } + if j, ok := p.(gjson.Result); ok { + if !j.Exists() { + return defaultVal + } + if j.Type == gjson.True { + return true + } + if j.Type == gjson.False { + return false + } + if j.Type != gjson.String { + return defaultVal + } + str = j.Str + } else if s, ok := p.(string); ok { + str = s + } + str = strings.ToLower(str) + if _, ok := trueSet[str]; ok { + return true + } + if _, ok := falseSet[str]; ok { + return false + } + return defaultVal +} diff --git a/server/http.go b/server/http.go index dc28bf9..2e81d52 100644 --- a/server/http.go +++ b/server/http.go @@ -9,6 +9,7 @@ import ( "time" "github.com/Mrs4s/go-cqhttp/coolq" + "github.com/Mrs4s/go-cqhttp/global" "github.com/gin-gonic/gin" "github.com/guonaihong/gout" log "github.com/sirupsen/logrus" @@ -249,21 +250,23 @@ func (s *httpServer) SendMessage(c *gin.Context) { func (s *httpServer) SendPrivateMessage(c *gin.Context) { uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64) msg, t := getParamWithType(c, "message") + autoEscape := global.EnsureBool(getParam(c, "auto_escape"), false) if t == gjson.JSON { - c.JSON(200, s.bot.CQSendPrivateMessage(uid, gjson.Parse(msg))) + c.JSON(200, s.bot.CQSendPrivateMessage(uid, gjson.Parse(msg), autoEscape)) return } - c.JSON(200, s.bot.CQSendPrivateMessage(uid, msg)) + c.JSON(200, s.bot.CQSendPrivateMessage(uid, msg, autoEscape)) } func (s *httpServer) SendGroupMessage(c *gin.Context) { gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64) msg, t := getParamWithType(c, "message") + autoEscape := global.EnsureBool(getParam(c, "auto_escape"), false) if t == gjson.JSON { - c.JSON(200, s.bot.CQSendGroupMessage(gid, gjson.Parse(msg))) + c.JSON(200, s.bot.CQSendGroupMessage(gid, gjson.Parse(msg), autoEscape)) return } - c.JSON(200, s.bot.CQSendGroupMessage(gid, msg)) + c.JSON(200, s.bot.CQSendGroupMessage(gid, msg, autoEscape)) } func (s *httpServer) SendGroupForwardMessage(c *gin.Context) { diff --git a/server/websocket.go b/server/websocket.go index 0e5d00d..18ba3e7 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -337,28 +337,29 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{ ) }, "send_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { + autoEscape := global.EnsureBool(p.Get("auto_escape"), false) if p.Get("message_type").Str == "private" { - return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message")) + return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message"), autoEscape) } if p.Get("message_type").Str == "group" { - return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message")) + return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message"), autoEscape) } if p.Get("group_id").Int() != 0 { - return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message")) + return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message"), autoEscape) } if p.Get("user_id").Int() != 0 { - return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message")) + return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message"), autoEscape) } return coolq.MSG{} }, "send_group_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { - return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message")) + return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message"), global.EnsureBool(p.Get("auto_escape"), false)) }, "send_group_forward_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { return bot.CQSendGroupForwardMessage(p.Get("group_id").Int(), p.Get("messages")) }, "send_private_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { - return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message")) + return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message"), global.EnsureBool(p.Get("auto_escape"), false)) }, "delete_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { return bot.CQDeleteMessage(int32(p.Get("message_id").Int())) From 99b414530ab82ac1bc460ecdbd2b374be44ce038 Mon Sep 17 00:00:00 2001 From: Richard Chien Date: Mon, 17 Aug 2020 14:10:33 +0800 Subject: [PATCH 30/78] remove todo comment --- coolq/api.go | 1 - 1 file changed, 1 deletion(-) diff --git a/coolq/api.go b/coolq/api.go index cb65d72..9ada387 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -394,7 +394,6 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { bot.CQSendGroupMessage(context.Get("group_id").Int(), reply, autoEscape) } if msgType == "private" { - // TODO: 处理auto_escape bot.CQSendPrivateMessage(context.Get("user_id").Int(), reply, autoEscape) } } From d1da08a376d427a93483c5cc3b938a547726254f Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 18 Aug 2020 13:22:11 +0800 Subject: [PATCH 31/78] fix at. --- coolq/api.go | 27 +++++++++++++++------------ global/param.go | 12 ++++++------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 9ada387..33d9dab 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -98,9 +98,23 @@ func (bot *CQBot) CQGetGroupMemberInfo(groupId, userId int64, noCache bool) MSG // https://cqhttp.cc/docs/4.15/#/API?id=send_group_msg-%E5%8F%91%E9%80%81%E7%BE%A4%E6%B6%88%E6%81%AF func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bool) MSG { var str string + fixAt := func(elem []message.IMessageElement) { + for _, e := range elem { + if at, ok := e.(*message.AtElement); ok && at.Target != 0 { + at.Display = "@" + func() string { + mem := bot.Client.FindGroup(groupId).FindMember(at.Target) + if mem != nil { + return mem.DisplayName() + } + return strconv.FormatInt(at.Target, 10) + }() + } + } + } if m, ok := i.(gjson.Result); ok { if m.Type == gjson.JSON { elem := bot.ConvertObjectMessage(m, true) + fixAt(elem) mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) if mid == -1 { return Failed(100) @@ -125,18 +139,7 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bo } else { elem = bot.ConvertStringMessage(str, true) } - // fix at display - for _, e := range elem { - if at, ok := e.(*message.AtElement); ok && at.Target != 0 { - at.Display = "@" + func() string { - mem := bot.Client.FindGroup(groupId).FindMember(at.Target) - if mem != nil { - return mem.DisplayName() - } - return strconv.FormatInt(at.Target, 10) - }() - } - } + fixAt(elem) mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) if mid == -1 { return Failed(100) diff --git a/global/param.go b/global/param.go index 259d4af..25e138f 100644 --- a/global/param.go +++ b/global/param.go @@ -6,15 +6,15 @@ import ( ) var trueSet = map[string]struct{}{ - "true": struct{}{}, - "yes": struct{}{}, - "1": struct{}{}, + "true": {}, + "yes": {}, + "1": {}, } var falseSet = map[string]struct{}{ - "false": struct{}{}, - "no": struct{}{}, - "0": struct{}{}, + "false": {}, + "no": {}, + "0": {}, } func EnsureBool(p interface{}, defaultVal bool) bool { From 568b0e479f92555a7c4e90eb72f9e4fb5024dcc6 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 18 Aug 2020 17:06:59 +0800 Subject: [PATCH 32/78] update MiraiGo. --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 8006fb6..b9813dc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200816111850-988a766ae224 + github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847 github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 diff --git a/go.sum b/go.sum index f5e2344..eec3b22 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df h1:ERLrnv7bONrg4NqvC8AWhtEgCZk97uCZdRpQS4gF8UE= -github.com/Mrs4s/MiraiGo v0.0.0-20200813091456-988a010b51df/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200816111850-988a766ae224 h1:tlWc7RpBCh5VhT0H6wzm/knxj2PpAV3J7wQyieF0nkk= -github.com/Mrs4s/MiraiGo v0.0.0-20200816111850-988a766ae224/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847 h1:ZnCHrRSLvN+a7ndOFPJF/FIg80JM6WxiOGC1TPTarEk= +github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 8c71dbff68631c9345af8a87bc6cc76d1c2c337f Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 19 Aug 2020 16:04:30 +0800 Subject: [PATCH 33/78] honor api supported. --- coolq/api.go | 55 +++++++++++++++++++++++++++++++++++++++++++++ coolq/bot.go | 4 ++++ go.mod | 2 +- go.sum | 2 ++ server/http.go | 9 ++++++-- server/websocket.go | 3 +++ 6 files changed, 72 insertions(+), 3 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 33d9dab..fe64af5 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -376,6 +376,61 @@ func (bot *CQBot) CQDeleteMessage(messageId int32) MSG { return OK(nil) } +// https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_honor_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E8%8D%A3%E8%AA%89%E4%BF%A1%E6%81%AF +func (bot *CQBot) CQGetGroupHonorInfo(groupId int64, t string) MSG { + msg := MSG{"group_id": groupId} + convertMem := func(memList []client.HonorMemberInfo) (ret []MSG) { + for _, mem := range memList { + ret = append(ret, MSG{ + "user_id": mem.Uin, + "nickname": mem.Name, + "avatar": mem.Avatar, + "description": mem.Desc, + }) + } + return + } + if t == "talkative" || t == "all" { + if honor, err := bot.Client.GetGroupHonorInfo(groupId, client.Talkative); err == nil { + if honor.CurrentTalkative.Uin != 0 { + msg["current_talkative"] = MSG{ + "user_id": honor.CurrentTalkative.Uin, + "nickname": honor.CurrentTalkative.Name, + "avatar": honor.CurrentTalkative.Avatar, + "day_count": honor.CurrentTalkative.DayCount, + } + } + msg["talkative_list"] = convertMem(honor.TalkativeList) + } + } + + if t == "performer" || t == "all" { + if honor, err := bot.Client.GetGroupHonorInfo(groupId, client.Performer); err == nil { + msg["performer_lis"] = convertMem(honor.ActorList) + } + } + + if t == "legend" || t == "all" { + if honor, err := bot.Client.GetGroupHonorInfo(groupId, client.Legend); err == nil { + msg["legend_list"] = convertMem(honor.LegendList) + } + } + + if t == "strong_newbie" || t == "all" { + if honor, err := bot.Client.GetGroupHonorInfo(groupId, client.StrongNewbie); err == nil { + msg["strong_newbie_list"] = convertMem(honor.StrongNewbieList) + } + } + + if t == "emotion" || t == "all" { + if honor, err := bot.Client.GetGroupHonorInfo(groupId, client.Emotion); err == nil { + msg["emotion_list"] = convertMem(honor.EmotionList) + } + } + + return OK(msg) +} + // https://cqhttp.cc/docs/4.15/#/API?id=-handle_quick_operation-%E5%AF%B9%E4%BA%8B%E4%BB%B6%E6%89%A7%E8%A1%8C%E5%BF%AB%E9%80%9F%E6%93%8D%E4%BD%9C // https://github.com/richardchien/coolq-http-api/blob/master/src/cqhttp/plugins/web/http.cpp#L376 func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { diff --git a/coolq/bot.go b/coolq/bot.go index c095bf7..70c13bc 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -117,6 +117,10 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int } m.Elements = newElem ret := bot.Client.SendGroupMessage(groupId, m) + if ret.Id == -1 { + log.Warnf("警告: 群 %v 消息发送失败, 账号可能被风控.", groupId) + return -1 + } return bot.InsertGroupMessage(ret) } diff --git a/go.mod b/go.mod index b9813dc..45ed455 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847 + github.com/Mrs4s/MiraiGo v0.0.0-20200819041545-3561e5f156ce github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 diff --git a/go.sum b/go.sum index eec3b22..77e375c 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847 h1:ZnCHrRSLvN+a7ndOFPJF/FIg80JM6WxiOGC1TPTarEk= github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200819041545-3561e5f156ce h1:rqefWaA8Xrk6qxFBbEQaySOUXH614DIR7cFmU5jVAQY= +github.com/Mrs4s/MiraiGo v0.0.0-20200819041545-3561e5f156ce/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/server/http.go b/server/http.go index 2e81d52..6bac8bf 100644 --- a/server/http.go +++ b/server/http.go @@ -134,12 +134,12 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) { s.engine.Any("/set_group_leave_async", s.SetGroupLeave) s.engine.Any("/get_image", s.GetImage) - s.engine.Any("/get_image_async", s.GetImage) s.engine.Any("/get_forward_msg", s.GetForwardMessage) s.engine.Any("/get_group_msg", s.GetGroupMessage) - s.engine.Any("/get_group_msg_async", s.GetGroupMessage) + + s.engine.Any("/get_group_honor_info", s.GetGroupHonorInfo) s.engine.Any("/can_send_image", s.CanSendImage) s.engine.Any("/can_send_image_async", s.CanSendImage) @@ -285,6 +285,11 @@ func (s *httpServer) GetGroupMessage(c *gin.Context) { c.JSON(200, s.bot.CQGetGroupMessage(int32(mid))) } +func (s *httpServer) GetGroupHonorInfo(c *gin.Context) { + gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64) + c.JSON(200, s.bot.CQGetGroupHonorInfo(gid, getParam(c, "type"))) +} + func (s *httpServer) ProcessFriendRequest(c *gin.Context) { flag := getParam(c, "flag") approve := getParamOrDefault(c, "approve", "true") diff --git a/server/websocket.go b/server/websocket.go index 18ba3e7..4668d9f 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -422,6 +422,9 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{ "get_group_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { return bot.CQGetGroupMessage(int32(p.Get("message_id").Int())) }, + "get_group_honor_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { + return bot.CQGetGroupHonorInfo(p.Get("group_id").Int(), p.Get("type").Str) + }, "can_send_image": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { return bot.CQCanSendImage() }, From 08694f5ae83fded906d15cacecf212b8d3f5965d Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 19 Aug 2020 18:37:12 +0800 Subject: [PATCH 34/78] heartbeat event supported. close #131 --- coolq/bot.go | 13 +++++++++ server/websocket.go | 66 ++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index 70c13bc..32f81da 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -64,6 +64,19 @@ func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot { bot.Client.OnNewFriendAdded(bot.friendAddedEvent) bot.Client.OnGroupInvited(bot.groupInvitedEvent) bot.Client.OnUserWantJoinGroup(bot.groupJoinReqEvent) + go func() { + for { + time.Sleep(time.Second * 5) + bot.dispatchEventMessage(MSG{ + "time": time.Now().Unix(), + "self_id": bot.Client.Uin, + "post_type": "meta_event", + "meta_event_type": "heartbeat", + "status": nil, + "interval": 5000, + }) + } + }() return bot } diff --git a/server/websocket.go b/server/websocket.go index 4668d9f..770fdfc 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -7,7 +7,6 @@ import ( "github.com/gorilla/websocket" log "github.com/sirupsen/logrus" "github.com/tidwall/gjson" - wsc "golang.org/x/net/websocket" "net/http" "strconv" "strings" @@ -29,8 +28,8 @@ type websocketClient struct { bot *coolq.CQBot pushLock *sync.Mutex - universalConn *wsc.Conn - eventConn *wsc.Conn + universalConn *websocket.Conn + eventConn *websocket.Conn } var WebsocketServer = &websocketServer{} @@ -79,18 +78,15 @@ func (c *websocketClient) Run() { func (c *websocketClient) connectApi() { log.Infof("开始尝试连接到反向Websocket API服务器: %v", c.conf.ReverseApiUrl) - wsConf, err := wsc.NewConfig(c.conf.ReverseApiUrl, c.conf.ReverseApiUrl) - if err != nil { - log.Warnf("连接到反向Websocket API服务器 %v 时出现致命错误: %v", c.conf.ReverseApiUrl, err) - return + header := http.Header{ + "X-Client-Role": []string{"API"}, + "X-Self-ID": []string{strconv.FormatInt(c.bot.Client.Uin, 10)}, + "User-Agent": []string{"CQHttp/4.15.0"}, } - wsConf.Header["X-Client-Role"] = []string{"API"} - wsConf.Header["X-Self-ID"] = []string{strconv.FormatInt(c.bot.Client.Uin, 10)} - wsConf.Header["User-Agent"] = []string{"CQHttp/4.15.0"} if c.token != "" { - wsConf.Header["Authorization"] = []string{"Token " + c.token} + header["Authorization"] = []string{"Token " + c.token} } - conn, err := wsc.DialConfig(wsConf) + conn, _, err := websocket.DefaultDialer.Dial(c.conf.ReverseApiUrl, header) if err != nil { log.Warnf("连接到反向Websocket API服务器 %v 时出现错误: %v", c.conf.ReverseApiUrl, err) if c.conf.ReverseReconnectInterval != 0 { @@ -105,20 +101,17 @@ func (c *websocketClient) connectApi() { func (c *websocketClient) connectEvent() { log.Infof("开始尝试连接到反向Websocket Event服务器: %v", c.conf.ReverseEventUrl) - wsConf, err := wsc.NewConfig(c.conf.ReverseEventUrl, c.conf.ReverseEventUrl) - if err != nil { - log.Warnf("连接到反向Websocket Event服务器 %v 时出现致命错误: %v", c.conf.ReverseApiUrl, err) - return + header := http.Header{ + "X-Client-Role": []string{"Event"}, + "X-Self-ID": []string{strconv.FormatInt(c.bot.Client.Uin, 10)}, + "User-Agent": []string{"CQHttp/4.15.0"}, } - wsConf.Header["X-Client-Role"] = []string{"Event"} - wsConf.Header["X-Self-ID"] = []string{strconv.FormatInt(c.bot.Client.Uin, 10)} - wsConf.Header["User-Agent"] = []string{"CQHttp/4.15.0"} if c.token != "" { - wsConf.Header["Authorization"] = []string{"Token " + c.token} + header["Authorization"] = []string{"Token " + c.token} } - conn, err := wsc.DialConfig(wsConf) + conn, _, err := websocket.DefaultDialer.Dial(c.conf.ReverseEventUrl, header) if err != nil { - log.Warnf("连接到反向Websocket API服务器 %v 时出现错误: %v", c.conf.ReverseApiUrl, err) + log.Warnf("连接到反向Websocket Event服务器 %v 时出现错误: %v", c.conf.ReverseEventUrl, err) if c.conf.ReverseReconnectInterval != 0 { time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) c.connectApi() @@ -131,18 +124,15 @@ func (c *websocketClient) connectEvent() { func (c *websocketClient) connectUniversal() { log.Infof("开始尝试连接到反向Websocket Universal服务器: %v", c.conf.ReverseUrl) - wsConf, err := wsc.NewConfig(c.conf.ReverseUrl, c.conf.ReverseUrl) - if err != nil { - log.Warnf("连接到反向Websocket Universal服务器 %v 时出现致命错误: %v", c.conf.ReverseUrl, err) - return + header := http.Header{ + "X-Client-Role": []string{"Universal"}, + "X-Self-ID": []string{strconv.FormatInt(c.bot.Client.Uin, 10)}, + "User-Agent": []string{"CQHttp/4.15.0"}, } - wsConf.Header["X-Client-Role"] = []string{"Universal"} - wsConf.Header["X-Self-ID"] = []string{strconv.FormatInt(c.bot.Client.Uin, 10)} - wsConf.Header["User-Agent"] = []string{"CQHttp/4.15.0"} if c.token != "" { - wsConf.Header["Authorization"] = []string{"Token " + c.token} + header["Authorization"] = []string{"Token " + c.token} } - conn, err := wsc.DialConfig(wsConf) + conn, _, err := websocket.DefaultDialer.Dial(c.conf.ReverseUrl, header) if err != nil { log.Warnf("连接到反向Websocket Universal服务器 %v 时出现错误: %v", c.conf.ReverseUrl, err) if c.conf.ReverseReconnectInterval != 0 { @@ -155,12 +145,12 @@ func (c *websocketClient) connectUniversal() { c.universalConn = conn } -func (c *websocketClient) listenApi(conn *wsc.Conn, u bool) { +func (c *websocketClient) listenApi(conn *websocket.Conn, u bool) { defer conn.Close() for { - var buf []byte - err := wsc.Message.Receive(conn, &buf) + _, buf, err := conn.ReadMessage() if err != nil { + log.Warnf("监听反向WS API时出现错误: %v", err) break } j := gjson.ParseBytes(buf) @@ -173,7 +163,7 @@ func (c *websocketClient) listenApi(conn *wsc.Conn, u bool) { } c.pushLock.Lock() log.Debugf("准备发送API %v 处理结果: %v", t, ret.ToJson()) - _, _ = conn.Write([]byte(ret.ToJson())) + _ = conn.WriteJSON(ret) c.pushLock.Unlock() } } @@ -190,7 +180,8 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { defer c.pushLock.Unlock() if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) - if _, err := c.eventConn.Write([]byte(m.ToJson())); err != nil { + if err := c.eventConn.WriteJSON(m.ToJson()); err != nil { + log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.eventConn.RemoteAddr().String(), err) _ = c.eventConn.Close() if c.conf.ReverseReconnectInterval != 0 { go func() { @@ -202,7 +193,8 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { } if c.universalConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.universalConn.RemoteAddr().String(), m.ToJson()) - if _, err := c.universalConn.Write([]byte(m.ToJson())); err != nil { + if err := c.universalConn.WriteJSON(m); err != nil { + log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.universalConn.RemoteAddr().String(), err) _ = c.universalConn.Close() if c.conf.ReverseReconnectInterval != 0 { go func() { From a6bcd96415106eb3b7624c29eab67ee365c53607 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 20 Aug 2020 01:59:31 +0800 Subject: [PATCH 35/78] fix event push error. --- coolq/cqcode.go | 2 +- global/fs.go | 3 ++- server/websocket.go | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 2785b4d..e869bf4 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -385,7 +385,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. } data = b } - if !global.IsAMR(data) { + if !global.IsAMRorSILK(data) { return nil, errors.New("unsupported voice file format (please use AMR file for now)") } return &message.VoiceElement{Data: data}, nil diff --git a/global/fs.go b/global/fs.go index 19cc758..f3dc6b0 100644 --- a/global/fs.go +++ b/global/fs.go @@ -13,6 +13,7 @@ var ( IMAGE_PATH = path.Join("data", "images") VOICE_PATH = path.Join("data", "voices") VIDEO_PATH = path.Join("data", "videos") + CACHE_PATH = path.Join("data", "cache") HEADER_AMR = []byte("#!AMR") HEADER_SILK = []byte("\x02#!SILK_V3") @@ -41,6 +42,6 @@ func Check(err error) { } } -func IsAMR(b []byte) bool { +func IsAMRorSILK(b []byte) bool { return bytes.HasPrefix(b, HEADER_AMR) || bytes.HasPrefix(b, HEADER_SILK) } diff --git a/server/websocket.go b/server/websocket.go index 770fdfc..f127026 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -114,7 +114,7 @@ func (c *websocketClient) connectEvent() { log.Warnf("连接到反向Websocket Event服务器 %v 时出现错误: %v", c.conf.ReverseEventUrl, err) if c.conf.ReverseReconnectInterval != 0 { time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) - c.connectApi() + c.connectEvent() } return } @@ -180,7 +180,7 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { defer c.pushLock.Unlock() if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) - if err := c.eventConn.WriteJSON(m.ToJson()); err != nil { + if err := c.eventConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.eventConn.RemoteAddr().String(), err) _ = c.eventConn.Close() if c.conf.ReverseReconnectInterval != 0 { From 51696e8054a23ba91eedfc1702af8074bcc5cc55 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 20 Aug 2020 02:12:54 +0800 Subject: [PATCH 36/78] /get_group_list supported no_cache param. --- coolq/api.go | 5 ++++- server/http.go | 3 ++- server/websocket.go | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index fe64af5..d49313e 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -34,8 +34,11 @@ func (bot *CQBot) CQGetFriendList() MSG { } // https://cqhttp.cc/docs/4.15/#/API?id=get_group_list-%E8%8E%B7%E5%8F%96%E7%BE%A4%E5%88%97%E8%A1%A8 -func (bot *CQBot) CQGetGroupList() MSG { +func (bot *CQBot) CQGetGroupList(noCache bool) MSG { var gs []MSG + if noCache { + _ = bot.Client.ReloadGroupList() + } for _, g := range bot.Client.GroupList { gs = append(gs, MSG{ "group_id": g.Code, diff --git a/server/http.go b/server/http.go index 6bac8bf..6a27bb0 100644 --- a/server/http.go +++ b/server/http.go @@ -209,7 +209,8 @@ func (s *httpServer) GetFriendList(c *gin.Context) { } func (s *httpServer) GetGroupList(c *gin.Context) { - c.JSON(200, s.bot.CQGetGroupList()) + nc := getParamOrDefault(c, "no_cache", "false") + c.JSON(200, s.bot.CQGetGroupList(nc == "true")) } func (s *httpServer) GetGroupInfo(c *gin.Context) { diff --git a/server/websocket.go b/server/websocket.go index f127026..45a4f3c 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -314,7 +314,7 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{ return bot.CQGetFriendList() }, "get_group_list": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { - return bot.CQGetGroupList() + return bot.CQGetGroupList(p.Get("no_cache").Bool()) }, "get_group_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { return bot.CQGetGroupInfo(p.Get("group_id").Int()) From c9a914b5d5cae2928db3ea8b256f0b56404bee40 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 20 Aug 2020 02:30:44 +0800 Subject: [PATCH 37/78] fix #141. --- coolq/bot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/bot.go b/coolq/bot.go index 32f81da..026d3c7 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -130,7 +130,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int } m.Elements = newElem ret := bot.Client.SendGroupMessage(groupId, m) - if ret.Id == -1 { + if ret == nil || ret.Id == -1 { log.Warnf("警告: 群 %v 消息发送失败, 账号可能被风控.", groupId) return -1 } From b7572f8d2ce806b66a8903d9a38da813de1d4a6d Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 20 Aug 2020 02:31:51 +0800 Subject: [PATCH 38/78] fix log. --- coolq/bot.go | 1 - 1 file changed, 1 deletion(-) diff --git a/coolq/bot.go b/coolq/bot.go index 026d3c7..a49bdac 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -131,7 +131,6 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int m.Elements = newElem ret := bot.Client.SendGroupMessage(groupId, m) if ret == nil || ret.Id == -1 { - log.Warnf("警告: 群 %v 消息发送失败, 账号可能被风控.", groupId) return -1 } return bot.InsertGroupMessage(ret) From 470efa07ab1d172877032c26fc2b2a775119a8eb Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 20 Aug 2020 03:05:46 +0800 Subject: [PATCH 39/78] url cache supported. --- coolq/cqcode.go | 14 ++++++++++++++ go.mod | 2 +- go.sum | 6 ++---- main.go | 5 +++++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index e869bf4..b899906 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -1,6 +1,7 @@ package coolq import ( + "crypto/md5" "encoding/base64" "encoding/hex" "errors" @@ -261,10 +262,23 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. case "image": f := d["file"] if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") { + cache := d["cache"] + if cache == "" { + cache = "1" + } + hash := md5.Sum([]byte(f)) + cacheFile := path.Join(global.CACHE_PATH, hex.EncodeToString(hash[:])+".cache") + if global.PathExists(cacheFile) && cache == "1" { + b, err := ioutil.ReadFile(cacheFile) + if err == nil { + return message.NewImage(b), nil + } + } b, err := global.GetBytes(f) if err != nil { return nil, err } + _ = ioutil.WriteFile(cacheFile, b, 0644) return message.NewImage(b), nil } if strings.HasPrefix(f, "base64") { diff --git a/go.mod b/go.mod index 45ed455..2f80a01 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200819041545-3561e5f156ce + github.com/Mrs4s/MiraiGo v0.0.0-20200819185537-8d1e5fb04c17 github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 diff --git a/go.sum b/go.sum index 77e375c..8fa8862 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847 h1:ZnCHrRSLvN+a7ndOFPJF/FIg80JM6WxiOGC1TPTarEk= -github.com/Mrs4s/MiraiGo v0.0.0-20200817175311-ac7fc7ad2847/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200819041545-3561e5f156ce h1:rqefWaA8Xrk6qxFBbEQaySOUXH614DIR7cFmU5jVAQY= -github.com/Mrs4s/MiraiGo v0.0.0-20200819041545-3561e5f156ce/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200819185537-8d1e5fb04c17 h1:sY4lwW34serGKnD26hP7ZLpnJ4NfVYKdS2SJIW1Mezs= +github.com/Mrs4s/MiraiGo v0.0.0-20200819185537-8d1e5fb04c17/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/main.go b/main.go index c40dbbb..bee7ab8 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,11 @@ func init() { log.Fatalf("创建视频缓存文件夹失败: %v", err) } } + if !global.PathExists(global.CACHE_PATH) { + if err := os.MkdirAll(global.CACHE_PATH, 0755); err != nil { + log.Fatalf("创建发送图片缓存文件夹失败: %v", err) + } + } if global.PathExists("cqhttp.json") { log.Info("发现 cqhttp.json 将在五秒后尝试导入配置,按 Ctrl+C 取消.") log.Warn("警告: 该操作会删除 cqhttp.json 并覆盖 config.json 文件.") From 322b70c6b5c70c6d4fec7f53f9e13407f09904ac Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Thu, 20 Aug 2020 03:33:55 +0800 Subject: [PATCH 40/78] fix bug. --- coolq/bot.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index a49bdac..62018ee 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -151,16 +151,23 @@ func (bot *CQBot) SendPrivateMessage(target int64, m *message.SendingMessage) in newElem = append(newElem, elem) } m.Elements = newElem - var id int32 + var id int32 = -1 if bot.Client.FindFriend(target) != nil { - id = bot.Client.SendPrivateMessage(target, m).Id + msg := bot.Client.SendPrivateMessage(target, m) + if msg != nil { + id = msg.Id + } } else { if code, ok := bot.tempMsgCache.Load(target); ok { - id = bot.Client.SendTempMessage(code.(int64), target, m).Id - } else { - return -1 + msg := bot.Client.SendTempMessage(code.(int64), target, m) + if msg != nil { + id = msg.Id + } } } + if id == -1 { + return -1 + } return ToGlobalId(target, id) } From 739d486b09cadd60793733541834265e0a56bde1 Mon Sep 17 00:00:00 2001 From: xuthus5 Date: Thu, 20 Aug 2020 22:14:31 +0800 Subject: [PATCH 41/78] add:go-cqhttp_version --- build.sh | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++ coolq/api.go | 16 ++++--- 2 files changed, 140 insertions(+), 6 deletions(-) create mode 100644 build.sh diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..7bc1ae1 --- /dev/null +++ b/build.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# +# automatically generated in linux environment +# +# automatically generate version information: +# go build -ldflags "-X path.varname=varvalue" -o filename . +# +# shell use e.g: +# ./build.sh v1.0.0 +# /get_version_info => version:v1.0.0 +# +# all comb to compile +# $GOOS $GOARCH +# android arm +# darwin 386 +# darwin amd64 +# darwin arm +# darwin arm64 +# dragonfly amd64 +# freebsd 386 +# freebsd amd64 +# freebsd arm +# linux 386 +# linux amd64 +# linux arm +# linux arm64 +# linux ppc64 +# linux ppc64le +# linux mips +# linux mipsle +# linux mips64 +# linux mips64le +# netbsd 386 +# netbsd amd64 +# netbsd arm +# openbsd 386 +# openbsd amd64 +# openbsd arm +# plan9 386 +# plan9 amd64 +# solaris amd64 +# windows 386 +# windows amd64 + +function build_linux32() { + export GOOS=linux + export GOARCH=386 + filename=go-cqhttp-"$1"-linux-386 + go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . + tar zcvf "$filename".tar.gz "$filename" --remove-files + md5sum "$filename".tar.gz > "$filename".tar.gz.md5 + mv "$filename".tar.gz ./dist + mv "$filename".tar.gz.md5 ./dist +} + +function build_linux64() { + export GOOS=linux + export GOARCH=amd64 + filename=go-cqhttp-"$1"-linux-amd64 + go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . + tar zcvf "$filename".tar.gz "$filename" --remove-files + md5sum "$filename".tar.gz > "$filename".tar.gz.md5 + mv "$filename".tar.gz ./dist + mv "$filename".tar.gz.md5 ./dist +} + +function build_win32() { + export GOOS=windows + export GOARCH=386 + filename=go-cqhttp-"$1"-windows-386 + go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . + tar zcvf "$filename".tar.gz "$filename" --remove-files + md5sum "$filename".tar.gz > "$filename".tar.gz.md5 + mv "$filename".tar.gz ./dist + mv "$filename".tar.gz.md5 ./dist +} + +function build_win64() { + export GOOS=windows + export GOARCH=amd64 + filename=go-cqhttp-"$1"-windows-amd64 + go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . + tar zcvf "$filename".tar.gz "$filename" + md5sum "$filename".tar.gz > "$filename".tar.gz.md5 + mv "$filename".tar.gz ./dist + mv "$filename".tar.gz.md5 ./dist +} + +function build_darwin32() { + export GOOS=darwin + export GOARCH=386 + filename=go-cqhttp-"$1"-darwin-386 + go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o go-cqhttp-"$1"-darwin-386 . + tar zcvf "$filename".tar.gz "$filename" --remove-files + md5sum "$filename".tar.gz > "$filename".tar.gz.md5 + mv "$filename".tar.gz ./dist + mv "$filename".tar.gz.md5 ./dist +} + +function build_darwin64() { + export GOOS=darwin + export GOARCH=amd64 + filename=go-cqhttp-"$1"-darwin-amd64 + go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o go-cqhttp-"$1"-darwin-amd64 . + tar zcvf "$filename".tar.gz "$filename" --remove-files + md5sum "$filename".tar.gz > "$filename".tar.gz.md5 + mv "$filename".tar.gz ./dist + mv "$filename".tar.gz.md5 ./dist +} + +function main() { + if [ ! -d 'dist' ];then + mkdir dist + fi + + #build_linux32 $1 + build_linux64 $1 + #build_win32 $1 + #build_win64 $1 + #build_darwin32 $1 + #build_darwin64 $1 + +} + + +if [ -n "$1" ]; then + main $1 +else + echo "No version info input...exit!" +fi \ No newline at end of file diff --git a/coolq/api.go b/coolq/api.go index d49313e..17c9e25 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -1,20 +1,23 @@ package coolq import ( - "github.com/Mrs4s/MiraiGo/binary" - "github.com/Mrs4s/MiraiGo/client" - "github.com/Mrs4s/MiraiGo/message" - "github.com/Mrs4s/go-cqhttp/global" - log "github.com/sirupsen/logrus" - "github.com/tidwall/gjson" "io/ioutil" "os" "path" "runtime" "strconv" "time" + + "github.com/Mrs4s/MiraiGo/binary" + "github.com/Mrs4s/MiraiGo/client" + "github.com/Mrs4s/MiraiGo/message" + "github.com/Mrs4s/go-cqhttp/global" + log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" ) +var version = "unknown" + // https://cqhttp.cc/docs/4.15/#/API?id=get_login_info-%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E5%8F%B7%E4%BF%A1%E6%81%AF func (bot *CQBot) CQGetLoginInfo() MSG { return OK(MSG{"user_id": bot.Client.Uin, "nickname": bot.Client.Nickname}) @@ -578,6 +581,7 @@ func (bot *CQBot) CQGetVersionInfo() MSG { "plugin_build_configuration": "release", "runtime_version": runtime.Version(), "runtime_os": runtime.GOOS, + "version": version, }) } From 5ec4e3331d74a6b0e80da3d3229e71bf81e11f1a Mon Sep 17 00:00:00 2001 From: xuthus5 Date: Fri, 21 Aug 2020 00:50:45 +0800 Subject: [PATCH 42/78] fix:action --- .github/workflows/release.yml | 5 +- build.sh | 130 ---------------------------------- 2 files changed, 4 insertions(+), 131 deletions(-) delete mode 100644 build.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e67cffa..888004f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,8 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Set RELEASE_VERSION env + run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF:10} - uses: wangyoucao577/go-release-action@master env: CGO_ENABLED: 0 @@ -24,4 +26,5 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} - ldflags: "-w -s" + ldflags: -w -s -X "github.com/Mrs4s/go-cqhttp/coolq.version=${{ env.RELEASE_VERSION }}" + \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100644 index 7bc1ae1..0000000 --- a/build.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env bash -# -# automatically generated in linux environment -# -# automatically generate version information: -# go build -ldflags "-X path.varname=varvalue" -o filename . -# -# shell use e.g: -# ./build.sh v1.0.0 -# /get_version_info => version:v1.0.0 -# -# all comb to compile -# $GOOS $GOARCH -# android arm -# darwin 386 -# darwin amd64 -# darwin arm -# darwin arm64 -# dragonfly amd64 -# freebsd 386 -# freebsd amd64 -# freebsd arm -# linux 386 -# linux amd64 -# linux arm -# linux arm64 -# linux ppc64 -# linux ppc64le -# linux mips -# linux mipsle -# linux mips64 -# linux mips64le -# netbsd 386 -# netbsd amd64 -# netbsd arm -# openbsd 386 -# openbsd amd64 -# openbsd arm -# plan9 386 -# plan9 amd64 -# solaris amd64 -# windows 386 -# windows amd64 - -function build_linux32() { - export GOOS=linux - export GOARCH=386 - filename=go-cqhttp-"$1"-linux-386 - go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . - tar zcvf "$filename".tar.gz "$filename" --remove-files - md5sum "$filename".tar.gz > "$filename".tar.gz.md5 - mv "$filename".tar.gz ./dist - mv "$filename".tar.gz.md5 ./dist -} - -function build_linux64() { - export GOOS=linux - export GOARCH=amd64 - filename=go-cqhttp-"$1"-linux-amd64 - go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . - tar zcvf "$filename".tar.gz "$filename" --remove-files - md5sum "$filename".tar.gz > "$filename".tar.gz.md5 - mv "$filename".tar.gz ./dist - mv "$filename".tar.gz.md5 ./dist -} - -function build_win32() { - export GOOS=windows - export GOARCH=386 - filename=go-cqhttp-"$1"-windows-386 - go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . - tar zcvf "$filename".tar.gz "$filename" --remove-files - md5sum "$filename".tar.gz > "$filename".tar.gz.md5 - mv "$filename".tar.gz ./dist - mv "$filename".tar.gz.md5 ./dist -} - -function build_win64() { - export GOOS=windows - export GOARCH=amd64 - filename=go-cqhttp-"$1"-windows-amd64 - go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o "$filename" . - tar zcvf "$filename".tar.gz "$filename" - md5sum "$filename".tar.gz > "$filename".tar.gz.md5 - mv "$filename".tar.gz ./dist - mv "$filename".tar.gz.md5 ./dist -} - -function build_darwin32() { - export GOOS=darwin - export GOARCH=386 - filename=go-cqhttp-"$1"-darwin-386 - go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o go-cqhttp-"$1"-darwin-386 . - tar zcvf "$filename".tar.gz "$filename" --remove-files - md5sum "$filename".tar.gz > "$filename".tar.gz.md5 - mv "$filename".tar.gz ./dist - mv "$filename".tar.gz.md5 ./dist -} - -function build_darwin64() { - export GOOS=darwin - export GOARCH=amd64 - filename=go-cqhttp-"$1"-darwin-amd64 - go build -ldflags "-X github.com/Mrs4s/go-cqhttp/coolq.version=$1" -o go-cqhttp-"$1"-darwin-amd64 . - tar zcvf "$filename".tar.gz "$filename" --remove-files - md5sum "$filename".tar.gz > "$filename".tar.gz.md5 - mv "$filename".tar.gz ./dist - mv "$filename".tar.gz.md5 ./dist -} - -function main() { - if [ ! -d 'dist' ];then - mkdir dist - fi - - #build_linux32 $1 - build_linux64 $1 - #build_win32 $1 - #build_win64 $1 - #build_darwin32 $1 - #build_darwin64 $1 - -} - - -if [ -n "$1" ]; then - main $1 -else - echo "No version info input...exit!" -fi \ No newline at end of file From cb9599271a64a265cd51aafc79a8d2fed41009dd Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 21 Aug 2020 19:24:06 +0800 Subject: [PATCH 43/78] update MiraiGo. --- coolq/api.go | 8 ++++---- go.mod | 3 +-- go.sum | 4 ++-- server/http.go | 2 +- server/websocket.go | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index d49313e..797aa2e 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -342,7 +342,7 @@ func (bot *CQBot) CQProcessFriendRequest(flag string, approve bool) MSG { } // https://cqhttp.cc/docs/4.15/#/API?id=set_group_add_request-%E5%A4%84%E7%90%86%E5%8A%A0%E7%BE%A4%E8%AF%B7%E6%B1%82%EF%BC%8F%E9%82%80%E8%AF%B7 -func (bot *CQBot) CQProcessGroupRequest(flag, subType string, approve bool) MSG { +func (bot *CQBot) CQProcessGroupRequest(flag, subType, reason string, approve bool) MSG { if subType == "add" { req, ok := bot.joinReqCache.Load(flag) if !ok { @@ -352,7 +352,7 @@ func (bot *CQBot) CQProcessGroupRequest(flag, subType string, approve bool) MSG if approve { req.(*client.UserJoinGroupRequest).Accept() } else { - req.(*client.UserJoinGroupRequest).Reject() + req.(*client.UserJoinGroupRequest).Reject(false, reason) } return OK(nil) } @@ -362,7 +362,7 @@ func (bot *CQBot) CQProcessGroupRequest(flag, subType string, approve bool) MSG if approve { req.(*client.GroupInvitedRequest).Accept() } else { - req.(*client.GroupInvitedRequest).Reject() + req.(*client.GroupInvitedRequest).Reject(false, reason) } return OK(nil) } @@ -485,7 +485,7 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { bot.CQProcessFriendRequest(context.Get("flag").Str, operation.Get("approve").Bool()) } if reqType == "group" { - bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, operation.Get("approve").Bool()) + bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, context.Get("reason").Str, operation.Get("approve").Bool()) } } } diff --git a/go.mod b/go.mod index 2f80a01..6e33a80 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200819185537-8d1e5fb04c17 + github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 @@ -15,6 +15,5 @@ require ( github.com/tidwall/gjson v1.6.0 github.com/xujiajun/nutsdb v0.5.0 github.com/yinghau76/go-ascii-art v0.0.0-20190517192627-e7f465a30189 - golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect ) diff --git a/go.sum b/go.sum index 8fa8862..8223b29 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200819185537-8d1e5fb04c17 h1:sY4lwW34serGKnD26hP7ZLpnJ4NfVYKdS2SJIW1Mezs= -github.com/Mrs4s/MiraiGo v0.0.0-20200819185537-8d1e5fb04c17/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 h1:50yz9Xgup7WgFAxeen/GQ0fCX3YUvv+ipGktZIznDuU= +github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/server/http.go b/server/http.go index 6a27bb0..772d0a5 100644 --- a/server/http.go +++ b/server/http.go @@ -304,7 +304,7 @@ func (s *httpServer) ProcessGroupRequest(c *gin.Context) { subType = getParam(c, "type") } approve := getParamOrDefault(c, "approve", "true") - c.JSON(200, s.bot.CQProcessGroupRequest(flag, subType, approve == "true")) + c.JSON(200, s.bot.CQProcessGroupRequest(flag, subType, getParam(c, "reason"), approve == "true")) } func (s *httpServer) SetGroupCard(c *gin.Context) { diff --git a/server/websocket.go b/server/websocket.go index 45a4f3c..83ecc4e 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -372,7 +372,7 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{ if p.Get("approve").Exists() { apr = p.Get("approve").Bool() } - return bot.CQProcessGroupRequest(p.Get("flag").Str, subType, apr) + return bot.CQProcessGroupRequest(p.Get("flag").Str, subType, p.Get("reason").Str, apr) }, "set_group_card": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG { return bot.CQSetGroupCard(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("card").Str) From 196cffb099e6dd3f272cca37a9ee95b49a761827 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 21 Aug 2020 19:27:07 +0800 Subject: [PATCH 44/78] ws async supported. close #122 --- global/config.go | 1 - main.go | 2 +- server/websocket.go | 34 +++++++++++++++++++--------------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/global/config.go b/global/config.go index 3a51bf8..e41f7c4 100644 --- a/global/config.go +++ b/global/config.go @@ -14,7 +14,6 @@ type JsonConfig struct { AccessToken string `json:"access_token"` ReLogin bool `json:"relogin"` ReLoginDelay int `json:"relogin_delay"` - AsyncLoad bool `json:"async_load"` HttpConfig *GoCQHttpConfig `json:"http_config"` WSConfig *GoCQWebsocketConfig `json:"ws_config"` ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"` diff --git a/main.go b/main.go index bee7ab8..a3d2af6 100644 --- a/main.go +++ b/main.go @@ -200,7 +200,7 @@ func main() { global.Check(cli.ReloadFriendList()) log.Infof("共加载 %v 个好友.", len(cli.FriendList)) log.Infof("开始加载群列表...") - global.Check(cli.ReloadGroupList(conf.AsyncLoad)) + global.Check(cli.ReloadGroupList()) log.Infof("共加载 %v 个群.", len(cli.GroupList)) b := coolq.NewQQBot(cli, conf) if conf.PostMessageFormat != "string" && conf.PostMessageFormat != "array" { diff --git a/server/websocket.go b/server/websocket.go index 83ecc4e..d61afd5 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -157,14 +157,16 @@ func (c *websocketClient) listenApi(conn *websocket.Conn, u bool) { t := strings.ReplaceAll(j.Get("action").Str, "_async", "") log.Debugf("反向WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw) if f, ok := wsApi[t]; ok { - ret := f(c.bot, j.Get("params")) - if j.Get("echo").Exists() { - ret["echo"] = j.Get("echo").Value() - } - c.pushLock.Lock() - log.Debugf("准备发送API %v 处理结果: %v", t, ret.ToJson()) - _ = conn.WriteJSON(ret) - c.pushLock.Unlock() + go func() { + ret := f(c.bot, j.Get("params")) + if j.Get("echo").Exists() { + ret["echo"] = j.Get("echo").Value() + } + c.pushLock.Lock() + log.Debugf("准备发送API %v 处理结果: %v", t, ret.ToJson()) + _ = conn.WriteJSON(ret) + c.pushLock.Unlock() + }() } } if c.conf.ReverseReconnectInterval != 0 { @@ -276,13 +278,15 @@ func (s *websocketServer) listenApi(c *websocket.Conn) { t := strings.ReplaceAll(j.Get("action").Str, "_async", "") //TODO: async support log.Debugf("WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw) if f, ok := wsApi[t]; ok { - ret := f(s.bot, j.Get("params")) - if j.Get("echo").Exists() { - ret["echo"] = j.Get("echo").Value() - } - s.pushLock.Lock() - _ = c.WriteJSON(ret) - s.pushLock.Unlock() + go func() { + ret := f(s.bot, j.Get("params")) + if j.Get("echo").Exists() { + ret["echo"] = j.Get("echo").Value() + } + s.pushLock.Lock() + _ = c.WriteJSON(ret) + s.pushLock.Unlock() + }() } } } From c3da6f29e2f41e8daee685a761e4216b08576851 Mon Sep 17 00:00:00 2001 From: wfjsw Date: Fri, 21 Aug 2020 20:33:55 +0800 Subject: [PATCH 45/78] ignore go vendor --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48b8bf9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vendor/ From c500bfc55c732b3fa36c9abdb8430c05db31ed1d Mon Sep 17 00:00:00 2001 From: wfjsw Date: Fri, 21 Aug 2020 20:47:33 +0800 Subject: [PATCH 46/78] reduce websocket conn lock contention (cherry-picked from commit dac8933..83772e2) --- go.mod | 4 ++ go.sum | 20 ++++++ server/websocket.go | 145 +++++++++++++++++++++++++------------------- 3 files changed, 106 insertions(+), 63 deletions(-) diff --git a/go.mod b/go.mod index 6e33a80..b88b975 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,18 @@ go 1.14 require ( github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 + github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.1.1 + github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect + github.com/jonboulle/clockwork v0.2.0 // indirect github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible github.com/lestrrat-go/strftime v1.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/sirupsen/logrus v1.6.0 github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 + github.com/tebeka/strftime v0.1.5 // indirect github.com/tidwall/gjson v1.6.0 github.com/xujiajun/nutsdb v0.5.0 github.com/yinghau76/go-ascii-art v0.0.0-20190517192627-e7f465a30189 diff --git a/go.sum b/go.sum index 8223b29..67b62f7 100644 --- a/go.sum +++ b/go.sum @@ -7,14 +7,18 @@ github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -41,14 +45,21 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/guonaihong/gout v0.1.1 h1:2i3eqQ1KUhTlj7AFeIHqVUFku5QwUhwE2wNgYTVpbxQ= github.com/guonaihong/gout v0.1.1/go.mod h1:vXvv5Kxr70eM5wrp4F0+t9lnLWmq+YPW2GByll2f/EA= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= +github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= +github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= @@ -56,6 +67,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV3kxNJJno9iKFWGxSDE13Kl66Q= github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= @@ -64,13 +76,16 @@ github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -80,9 +95,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk= github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA= +github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg= +github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig= github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= @@ -132,6 +150,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -151,6 +170,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= diff --git a/server/websocket.go b/server/websocket.go index d61afd5..4d5d280 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -2,24 +2,25 @@ package server import ( "fmt" - "github.com/Mrs4s/go-cqhttp/coolq" - "github.com/Mrs4s/go-cqhttp/global" - "github.com/gorilla/websocket" - log "github.com/sirupsen/logrus" - "github.com/tidwall/gjson" "net/http" "strconv" "strings" "sync" "time" + + "github.com/Mrs4s/go-cqhttp/coolq" + "github.com/Mrs4s/go-cqhttp/global" + "github.com/gorilla/websocket" + log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" ) type websocketServer struct { - bot *coolq.CQBot - token string - eventConn []*websocket.Conn - pushLock *sync.Mutex - handshake string + bot *coolq.CQBot + token string + eventConn []*websocketConn + eventConnMutex sync.Mutex + handshake string } type websocketClient struct { @@ -27,9 +28,13 @@ type websocketClient struct { token string bot *coolq.CQBot - pushLock *sync.Mutex - universalConn *websocket.Conn - eventConn *websocket.Conn + universalConn *websocketConn + eventConn *websocketConn +} + +type websocketConn struct { + *websocket.Conn + sync.Mutex } var WebsocketServer = &websocketServer{} @@ -41,7 +46,6 @@ var upgrader = websocket.Upgrader{ func (s *websocketServer) Run(addr, authToken string, b *coolq.CQBot) { s.token = authToken - s.pushLock = new(sync.Mutex) s.bot = b s.handshake = fmt.Sprintf(`{"_post_method":2,"meta_event_type":"lifecycle","post_type":"meta_event","self_id":%d,"sub_type":"connect","time":%d}`, s.bot.Client.Uin, time.Now().Unix()) @@ -56,7 +60,7 @@ func (s *websocketServer) Run(addr, authToken string, b *coolq.CQBot) { } func NewWebsocketClient(conf *global.GoCQReverseWebsocketConfig, authToken string, b *coolq.CQBot) *websocketClient { - return &websocketClient{conf: conf, token: authToken, bot: b, pushLock: new(sync.Mutex)} + return &websocketClient{conf: conf, token: authToken, bot: b} } func (c *websocketClient) Run() { @@ -96,7 +100,8 @@ func (c *websocketClient) connectApi() { return } log.Infof("已连接到反向Websocket API服务器 %v", c.conf.ReverseApiUrl) - go c.listenApi(conn, false) + wrappedConn := &websocketConn{Conn: conn} + go c.listenApi(wrappedConn, false) } func (c *websocketClient) connectEvent() { @@ -119,7 +124,7 @@ func (c *websocketClient) connectEvent() { return } log.Infof("已连接到反向Websocket Event服务器 %v", c.conf.ReverseEventUrl) - c.eventConn = conn + c.eventConn = &websocketConn{Conn: conn} } func (c *websocketClient) connectUniversal() { @@ -141,11 +146,12 @@ func (c *websocketClient) connectUniversal() { } return } - go c.listenApi(conn, true) - c.universalConn = conn + wrappedConn := &websocketConn{Conn: conn} + go c.listenApi(wrappedConn, true) + c.universalConn = wrappedConn } -func (c *websocketClient) listenApi(conn *websocket.Conn, u bool) { +func (c *websocketClient) listenApi(conn *websocketConn, u bool) { defer conn.Close() for { _, buf, err := conn.ReadMessage() @@ -153,35 +159,23 @@ func (c *websocketClient) listenApi(conn *websocket.Conn, u bool) { log.Warnf("监听反向WS API时出现错误: %v", err) break } - j := gjson.ParseBytes(buf) - t := strings.ReplaceAll(j.Get("action").Str, "_async", "") - log.Debugf("反向WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw) - if f, ok := wsApi[t]; ok { - go func() { - ret := f(c.bot, j.Get("params")) - if j.Get("echo").Exists() { - ret["echo"] = j.Get("echo").Value() - } - c.pushLock.Lock() - log.Debugf("准备发送API %v 处理结果: %v", t, ret.ToJson()) - _ = conn.WriteJSON(ret) - c.pushLock.Unlock() - }() - } + + go conn.handleRequest(c.bot, buf) + } if c.conf.ReverseReconnectInterval != 0 { time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) if !u { - c.connectApi() + go c.connectApi() } } } func (c *websocketClient) onBotPushEvent(m coolq.MSG) { - c.pushLock.Lock() - defer c.pushLock.Unlock() if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) + c.eventConn.Lock() + defer c.eventConn.Unlock() if err := c.eventConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.eventConn.RemoteAddr().String(), err) _ = c.eventConn.Close() @@ -195,6 +189,8 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { } if c.universalConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.universalConn.RemoteAddr().String(), m.ToJson()) + c.universalConn.Lock() + defer c.universalConn.Unlock() if err := c.universalConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.universalConn.RemoteAddr().String(), err) _ = c.universalConn.Close() @@ -222,10 +218,19 @@ func (s *websocketServer) event(w http.ResponseWriter, r *http.Request) { return } err = c.WriteMessage(websocket.TextMessage, []byte(s.handshake)) - if err == nil { - log.Infof("接受 Websocket 连接: %v (/event)", r.RemoteAddr) - s.eventConn = append(s.eventConn, c) + if err != nil { + log.Warnf("Websocket 握手时出现错误: %v", err) + c.Close() + return } + + log.Infof("接受 Websocket 连接: %v (/event)", r.RemoteAddr) + + conn := &websocketConn{Conn: c} + + s.eventConnMutex.Lock() + s.eventConn = append(s.eventConn, conn) + s.eventConnMutex.Unlock() } func (s *websocketServer) api(w http.ResponseWriter, r *http.Request) { @@ -242,7 +247,8 @@ func (s *websocketServer) api(w http.ResponseWriter, r *http.Request) { return } log.Infof("接受 Websocket 连接: %v (/api)", r.RemoteAddr) - go s.listenApi(c) + conn := &websocketConn{Conn: c} + go s.listenApi(conn) } func (s *websocketServer) any(w http.ResponseWriter, r *http.Request) { @@ -259,42 +265,55 @@ func (s *websocketServer) any(w http.ResponseWriter, r *http.Request) { return } err = c.WriteMessage(websocket.TextMessage, []byte(s.handshake)) - if err == nil { - log.Infof("接受 Websocket 连接: %v (/)", r.RemoteAddr) - s.eventConn = append(s.eventConn, c) - s.listenApi(c) + if err != nil { + log.Warnf("Websocket 握手时出现错误: %v", err) + c.Close() + return } + + log.Infof("接受 Websocket 连接: %v (/)", r.RemoteAddr) + conn := &websocketConn{Conn: c} + s.eventConn = append(s.eventConn, conn) + s.listenApi(conn) } -func (s *websocketServer) listenApi(c *websocket.Conn) { +func (s *websocketServer) listenApi(c *websocketConn) { defer c.Close() for { t, payload, err := c.ReadMessage() if err != nil { break } + if t == websocket.TextMessage { - j := gjson.ParseBytes(payload) - t := strings.ReplaceAll(j.Get("action").Str, "_async", "") //TODO: async support - log.Debugf("WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw) - if f, ok := wsApi[t]; ok { - go func() { - ret := f(s.bot, j.Get("params")) - if j.Get("echo").Exists() { - ret["echo"] = j.Get("echo").Value() - } - s.pushLock.Lock() - _ = c.WriteJSON(ret) - s.pushLock.Unlock() - }() - } + go c.handleRequest(s.bot, payload) } } } +func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) { + defer func() { + if err := recover(); err != nil { + log.Printf("处置WS命令时发生无法恢复的异常:%v", err) + c.Close() + } + }() + + j := gjson.ParseBytes(payload) + t := strings.ReplaceAll(j.Get("action").Str, "_async", "") + log.Debugf("WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw) + if f, ok := wsApi[t]; ok { + ret := f(bot, j.Get("params")) + if j.Get("echo").Exists() { + ret["echo"] = j.Get("echo").Value() + } + c.Lock() + defer c.Unlock() + _ = c.WriteJSON(ret) + } +} + func (s *websocketServer) onBotPushEvent(m coolq.MSG) { - s.pushLock.Lock() - defer s.pushLock.Unlock() pos := 0 for _, conn := range s.eventConn { log.Debugf("向WS客户端 %v 推送Event: %v", conn.RemoteAddr().String(), m.ToJson()) From f8d74a6ac910932a0a953f90eb4508e601aac9fe Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 21 Aug 2020 22:28:11 +0800 Subject: [PATCH 47/78] update debug. --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index a3d2af6..87b0cc8 100644 --- a/main.go +++ b/main.go @@ -136,6 +136,7 @@ func main() { if conf.Debug { log.SetLevel(log.DebugLevel) log.Warnf("已开启Debug模式.") + log.Debugf("开发交流群: 192548878") } if !global.PathExists("device.json") { log.Warn("虚拟设备信息不存在, 将自动生成随机设备.") From 894a5d964158189a0d7419a71618f1a0b4faa6c7 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 01:21:04 +0800 Subject: [PATCH 48/78] fix Content-Type. --- coolq/api.go | 1 + coolq/bot.go | 4 ++++ go.mod | 2 +- go.sum | 2 ++ server/http.go | 4 ++-- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index fdfd6c4..f506725 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -137,6 +137,7 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bo str = s } if str == "" { + log.Warnf("群消息发送失败: 信息为空. MSG: %v", i) return Failed(100) } var elem []message.IMessageElement diff --git a/coolq/bot.go b/coolq/bot.go index 62018ee..5e96967 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -131,6 +131,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int m.Elements = newElem ret := bot.Client.SendGroupMessage(groupId, m) if ret == nil || ret.Id == -1 { + log.Warnf("群消息发送失败: 账号可能被风控.") return -1 } return bot.InsertGroupMessage(ret) @@ -227,6 +228,9 @@ func formatGroupName(group *client.GroupInfo) string { } func formatMemberName(mem *client.GroupMemberInfo) string { + if mem == nil { + return "未知" + } return fmt.Sprintf("%s(%d)", mem.DisplayName(), mem.Uin) } diff --git a/go.mod b/go.mod index b88b975..22ef6f6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 + github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 67b62f7..34d2711 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 h1:50yz9Xgup7WgFAxeen/GQ0fCX3YUvv+ipGktZIznDuU= github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 h1:LVzj3ahW0LYJQMDcDm+MRPevKEFg8+VJ9iOGjF4yNOo= +github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/server/http.go b/server/http.go index 772d0a5..998730f 100644 --- a/server/http.go +++ b/server/http.go @@ -404,12 +404,12 @@ func getParamWithType(c *gin.Context, k string) (string, gjson.Type) { } if c.Request.Method == "POST" { if h := c.Request.Header.Get("Content-Type"); h != "" { - if h == "application/x-www-form-urlencoded" { + if strings.Contains(h, "application/x-www-form-urlencoded") { if p, ok := c.GetPostForm(k); ok { return p, gjson.Null } } - if h == "application/json" { + if strings.Contains(h, "application/json") { if obj, ok := c.Get("json_body"); ok { res := obj.(gjson.Result).Get(k) if res.Exists() { From fa0a2d80f8a8f4b4f9ee49547e86ac4cd5c88181 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 02:27:23 +0800 Subject: [PATCH 49/78] update MiraiGo. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 22ef6f6..e8c0fed 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 + github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 34d2711..ebab85a 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 h1:50yz9Xgup7WgFAxee github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 h1:LVzj3ahW0LYJQMDcDm+MRPevKEFg8+VJ9iOGjF4yNOo= github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 h1:z2oaXbvOmu7/O666OkUeH5SGUjyQ3wUSNjtTOagY8Sk= +github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 3709f5c7b937f35f3826af4e6d11a555a71941ad Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 02:44:00 +0800 Subject: [PATCH 50/78] clear. --- coolq/bot.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index 5e96967..1e5121d 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -12,7 +12,6 @@ import ( log "github.com/sirupsen/logrus" "github.com/xujiajun/nutsdb" "hash/crc32" - "math/rand" "path" "sync" "time" @@ -108,7 +107,6 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int var newElem []message.IMessageElement for _, elem := range m.Elements { if i, ok := elem.(*message.ImageElement); ok { - _, _ = bot.Client.UploadGroupImage(int64(rand.Intn(11451419)), i.Data) gm, err := bot.Client.UploadGroupImage(groupId, i.Data) if err != nil { log.Warnf("警告: 群 %v 消息图片上传失败: %v", groupId, err) From 9f060ce2ede463727ef78fe1b6c04c5b14fafa36 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 03:02:19 +0800 Subject: [PATCH 51/78] fix lock & http server error. --- server/http.go | 9 ++++++++- server/websocket.go | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/server/http.go b/server/http.go index 998730f..fcf2935 100644 --- a/server/http.go +++ b/server/http.go @@ -4,6 +4,7 @@ import ( "crypto/hmac" "crypto/sha1" "encoding/hex" + "os" "strconv" "strings" "time" @@ -157,7 +158,13 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) { go func() { log.Infof("CQ HTTP 服务器已启动: %v", addr) - log.Fatal(s.engine.Run(addr)) + err := s.engine.Run(addr) + if err != nil { + log.Error(err) + log.Infof("请检查端口是否被占用.") + time.Sleep(time.Second * 5) + os.Exit(1) + } }() } diff --git a/server/websocket.go b/server/websocket.go index 4d5d280..42fdf30 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -314,6 +314,8 @@ func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) { } func (s *websocketServer) onBotPushEvent(m coolq.MSG) { + s.eventConnMutex.Lock() + s.eventConnMutex.Unlock() pos := 0 for _, conn := range s.eventConn { log.Debugf("向WS客户端 %v 推送Event: %v", conn.RemoteAddr().String(), m.ToJson()) From 5e6b3e09f721513aeef2f62c61698834b4ffe492 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 03:21:43 +0800 Subject: [PATCH 52/78] kusa. --- server/websocket.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/websocket.go b/server/websocket.go index 42fdf30..ea7e6a4 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -315,7 +315,7 @@ func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) { func (s *websocketServer) onBotPushEvent(m coolq.MSG) { s.eventConnMutex.Lock() - s.eventConnMutex.Unlock() + defer s.eventConnMutex.Unlock() pos := 0 for _, conn := range s.eventConn { log.Debugf("向WS客户端 %v 推送Event: %v", conn.RemoteAddr().String(), m.ToJson()) From 2259e7ccbab221f8dad9639f2741e15b9fcb094b Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 03:28:38 +0800 Subject: [PATCH 53/78] deadline update. --- server/websocket.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/websocket.go b/server/websocket.go index ea7e6a4..7faea24 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -176,6 +176,7 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) c.eventConn.Lock() defer c.eventConn.Unlock() + _ = c.eventConn.SetWriteDeadline(time.Now().Add(time.Second * 15)) if err := c.eventConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.eventConn.RemoteAddr().String(), err) _ = c.eventConn.Close() @@ -191,6 +192,7 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { log.Debugf("向WS服务器 %v 推送Event: %v", c.universalConn.RemoteAddr().String(), m.ToJson()) c.universalConn.Lock() defer c.universalConn.Unlock() + _ = c.universalConn.SetWriteDeadline(time.Now().Add(time.Second * 15)) if err := c.universalConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.universalConn.RemoteAddr().String(), err) _ = c.universalConn.Close() From 2949f68532633f438bac7d80216ce7ab6d6b226c Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 22 Aug 2020 13:24:32 +0800 Subject: [PATCH 54/78] =?UTF-8?q?=E5=8F=8D=E5=90=91WS=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- global/filter.go | 248 ++++++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 + server/websocket.go | 6 ++ 4 files changed, 257 insertions(+) create mode 100644 global/filter.go diff --git a/global/filter.go b/global/filter.go new file mode 100644 index 0000000..c439bd2 --- /dev/null +++ b/global/filter.go @@ -0,0 +1,248 @@ +package global + +import ( + "bytes" + "github.com/buger/jsonparser" + log "github.com/sirupsen/logrus" + "io/ioutil" + "regexp" + "sync" +) + +type Filter interface { + Eval(payload []byte) bool +} + +type OperationNode struct { + key string + filter Filter +} + +type NotOperator struct { + operand_ Filter +} + +func notOperatorConstruct(argument []byte) *NotOperator { + op := new(NotOperator) + op.operand_ = GetOperatorFactory().Generate("and", argument) + return op +} + +func (notOperator NotOperator) Eval(payload []byte) bool { + log.Debug("not "+string(payload)) + return !(notOperator.operand_).Eval(payload) +} + +type AndOperator struct { + operands []OperationNode +} + +func andOperatorConstruct(argument []byte) *AndOperator { + op := new(AndOperator) + _ = jsonparser.ObjectEach(argument, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error { + if key[0] == '.' { + // is an operator + // ".foo": { + // "bar": "baz" + // } + opKey := string(key[1:]) + op.operands = append(op.operands, OperationNode{"", GetOperatorFactory().Generate(opKey, value)}) + } else if value[0] == '{' { + // is an normal key with an object as the value + // "foo": { + // ".bar": "baz" + // } + opKey := string(key) + op.operands = append(op.operands, OperationNode{opKey, GetOperatorFactory().Generate("and", value)}) + } else { + // is an normal key with a non-object as the value + // "foo": "bar" + opKey := string(key) + op.operands = append(op.operands, OperationNode{opKey, GetOperatorFactory().Generate("eq", value)}) + } + return nil + }) + return op +} + +func (andOperator *AndOperator) Eval(payload []byte) bool { + log.Debug("and "+string(payload)) + res := true + nodesLength := len(andOperator.operands) + for i := 0; i < nodesLength ; i++ { + + if len(andOperator.operands[i].key) == 0 { + // is an operator + res = res && andOperator.operands[i].filter.Eval(payload) + } else { + // is an normal key + val, _, _, _ := jsonparser.Get(payload, andOperator.operands[i].key) + res = res && andOperator.operands[i].filter.Eval(val) + } + + if res == false { + break + } + } + return res +} + +type OrOperator struct { + operands []Filter +} + +func orOperatorConstruct(argument []byte) *OrOperator { + op := new(OrOperator) + _, _ = jsonparser.ArrayEach(argument, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { + op.operands = append(op.operands, GetOperatorFactory().Generate("and", value)) + }) + return op +} + +func (orOperator OrOperator) Eval(payload []byte) bool { + log.Debug("or "+string(payload)) + res:= false + nodesLength := len(orOperator.operands) + for i := 0; i < nodesLength ; i++ { + res = res || orOperator.operands[i].Eval(payload) + + if res == true { + break + } + } + return res +} + +type EqualOperator struct { + value []byte +} + +func equalOperatorConstruct(argument []byte) *EqualOperator { + op := new(EqualOperator) + op.value = argument + return op +} + +func (equalOperator EqualOperator) Eval(payload []byte) bool { + log.Debug("eq "+string(payload)) + return bytes.Equal(payload, equalOperator.value) +} + +type NotEqualOperator struct { + value []byte +} + +func notEqualOperatorConstruct(argument []byte) *NotEqualOperator { + op := new(NotEqualOperator) + op.value = argument + return op +} + +func (notEqualOperator NotEqualOperator) Eval(payload []byte) bool { + log.Debug("neq "+string(payload)) + return !bytes.Equal(payload, notEqualOperator.value) +} + + +type InOperator struct { + operands [][]byte +} + +func inOperatorConstruct(argument []byte) *InOperator { + op := new(InOperator) + _, _ = jsonparser.ArrayEach(argument, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { + op.operands = append(op.operands, value) + }) + return op +} + +func (inOperator InOperator) Eval(payload []byte) bool { + log.Debug("in "+string(payload)) + res := false + for _, v := range inOperator.operands { + res = res || bytes.Equal(payload, v) + if res == true { + break + } + } + return res +} + +type ContainsOperator struct { + operand []byte +} + +func containsOperatorConstruct(argument []byte) *ContainsOperator { + op := new(ContainsOperator) + op.operand = argument + return op +} + +func (containsOperator ContainsOperator) Eval(payload []byte) bool { + log.Debug("contains "+string(payload)) + return bytes.Contains(payload, containsOperator.operand) +} + +type RegexOperator struct { + regex string +} + +func regexOperatorConstruct(argument []byte) *RegexOperator { + op := new(RegexOperator) + op.regex = string(argument) + return op +} + +func (containsOperator RegexOperator) Eval(payload []byte) bool { + log.Debug("regex "+string(payload)) + matched, _ := regexp.Match(containsOperator.regex, payload) + return matched +} +// 单例工厂 +type operatorFactory struct{ +} + +var instance *operatorFactory = &operatorFactory{} + +func GetOperatorFactory() *operatorFactory { + return instance +} + +func (o operatorFactory) Generate(opName string, argument []byte) Filter { + switch opName { + case "not": + return notOperatorConstruct(argument) + case "and": + return andOperatorConstruct(argument) + case "or": + return orOperatorConstruct(argument) + case "neq": + return notEqualOperatorConstruct(argument) + case "eq": + return equalOperatorConstruct(argument) + case "in": + return inOperatorConstruct(argument) + case "contains": + return containsOperatorConstruct(argument) + case "regex": + return regexOperatorConstruct(argument) + default: + log.Warnf("the operator '%s' is not supported", opName) + return nil + } +} + +var filter = new(Filter) +var once sync.Once // 过滤器单例模式 + +func GetFilter() *Filter { + once.Do(func() { + f, err := ioutil.ReadFile("filter.json") + if err != nil { + filter = nil + } else { + *filter = GetOperatorFactory().Generate("and", f) + } + }) + return filter +} \ No newline at end of file diff --git a/go.mod b/go.mod index e8c0fed..8dcdefe 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.14 require ( github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 + github.com/buger/jsonparser v1.0.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index ebab85a..dd1f0b7 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 h1:LVzj3ahW0LYJQMDcD github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 h1:z2oaXbvOmu7/O666OkUeH5SGUjyQ3wUSNjtTOagY8Sk= github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/buger/jsonparser v1.0.0 h1:etJTGF5ESxjI0Ic2UaLQs2LQQpa8G9ykQScukbh4L8A= +github.com/buger/jsonparser v1.0.0/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/server/websocket.go b/server/websocket.go index 7faea24..d64093b 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -172,6 +172,12 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) { } func (c *websocketClient) onBotPushEvent(m coolq.MSG) { + payload := []byte(m.ToJson()) + filter := global.GetFilter() + if filter != nil && (*filter).Eval(payload) == false { + log.Debug("Event filtered!") + return + } if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) c.eventConn.Lock() From 5868b68437c11ea752c3227e893f256f5f7479cf Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 22 Aug 2020 16:14:26 +0800 Subject: [PATCH 55/78] =?UTF-8?q?=E4=B8=8E=E5=8E=9F=E7=89=88event=20filter?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- global/filter.go | 169 ++++++++++++++++++++++++-------------------- go.mod | 1 - go.sum | 2 - server/websocket.go | 3 +- 4 files changed, 96 insertions(+), 79 deletions(-) diff --git a/global/filter.go b/global/filter.go index c439bd2..e7fdad6 100644 --- a/global/filter.go +++ b/global/filter.go @@ -1,16 +1,16 @@ package global import ( - "bytes" - "github.com/buger/jsonparser" log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" "io/ioutil" "regexp" + "strings" "sync" ) type Filter interface { - Eval(payload []byte) bool + Eval(payload gjson.Result) bool } type OperationNode struct { @@ -22,14 +22,17 @@ type NotOperator struct { operand_ Filter } -func notOperatorConstruct(argument []byte) *NotOperator { +func notOperatorConstruct(argument gjson.Result) *NotOperator { + if !argument.IsObject() { + log.Error("the argument of 'not' operator must be an object") + } op := new(NotOperator) op.operand_ = GetOperatorFactory().Generate("and", argument) return op } -func (notOperator NotOperator) Eval(payload []byte) bool { - log.Debug("not "+string(payload)) +func (notOperator NotOperator) Eval(payload gjson.Result) bool { + log.Debug("not " + payload.Str) return !(notOperator.operand_).Eval(payload) } @@ -37,47 +40,49 @@ type AndOperator struct { operands []OperationNode } -func andOperatorConstruct(argument []byte) *AndOperator { +func andOperatorConstruct(argument gjson.Result) *AndOperator { + if !argument.IsObject() { + log.Error("the argument of 'and' operator must be an object") + } op := new(AndOperator) - _ = jsonparser.ObjectEach(argument, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error { - if key[0] == '.' { + argument.ForEach(func(key, value gjson.Result) bool { + if key.Str[0] == '.' { // is an operator // ".foo": { // "bar": "baz" // } - opKey := string(key[1:]) + opKey := key.Str[1:] op.operands = append(op.operands, OperationNode{"", GetOperatorFactory().Generate(opKey, value)}) - } else if value[0] == '{' { + } else if value.IsObject() { // is an normal key with an object as the value // "foo": { // ".bar": "baz" // } - opKey := string(key) + opKey := key.Str op.operands = append(op.operands, OperationNode{opKey, GetOperatorFactory().Generate("and", value)}) } else { // is an normal key with a non-object as the value // "foo": "bar" - opKey := string(key) + opKey := key.Str op.operands = append(op.operands, OperationNode{opKey, GetOperatorFactory().Generate("eq", value)}) } - return nil + return true }) return op } -func (andOperator *AndOperator) Eval(payload []byte) bool { - log.Debug("and "+string(payload)) +func (andOperator *AndOperator) Eval(payload gjson.Result) bool { + log.Debug("and " + payload.Str) res := true - nodesLength := len(andOperator.operands) - for i := 0; i < nodesLength ; i++ { + for _, operand := range andOperator.operands { - if len(andOperator.operands[i].key) == 0 { + if len(operand.key) == 0 { // is an operator - res = res && andOperator.operands[i].filter.Eval(payload) + res = res && operand.filter.Eval(payload) } else { // is an normal key - val, _, _, _ := jsonparser.Get(payload, andOperator.operands[i].key) - res = res && andOperator.operands[i].filter.Eval(val) + val := payload.Get(operand.key) + res = res && operand.filter.Eval(val) } if res == false { @@ -91,20 +96,23 @@ type OrOperator struct { operands []Filter } -func orOperatorConstruct(argument []byte) *OrOperator { +func orOperatorConstruct(argument gjson.Result) *OrOperator { + if !argument.IsArray() { + log.Error("the argument of 'or' operator must be an array") + } op := new(OrOperator) - _, _ = jsonparser.ArrayEach(argument, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { + argument.ForEach(func(_, value gjson.Result) bool { op.operands = append(op.operands, GetOperatorFactory().Generate("and", value)) + return true }) return op } -func (orOperator OrOperator) Eval(payload []byte) bool { - log.Debug("or "+string(payload)) +func (orOperator OrOperator) Eval(payload gjson.Result) bool { + log.Debug("or "+ payload.Str) res:= false - nodesLength := len(orOperator.operands) - for i := 0; i < nodesLength ; i++ { - res = res || orOperator.operands[i].Eval(payload) + for _, operand := range orOperator.operands { + res = res || operand.Eval(payload) if res == true { break @@ -114,88 +122,99 @@ func (orOperator OrOperator) Eval(payload []byte) bool { } type EqualOperator struct { - value []byte + value gjson.Result } -func equalOperatorConstruct(argument []byte) *EqualOperator { +func equalOperatorConstruct(argument gjson.Result) *EqualOperator { op := new(EqualOperator) op.value = argument return op } -func (equalOperator EqualOperator) Eval(payload []byte) bool { - log.Debug("eq "+string(payload)) - return bytes.Equal(payload, equalOperator.value) +func (equalOperator EqualOperator) Eval(payload gjson.Result) bool { + log.Debug("eq "+ payload.Str + "==" + equalOperator.value.Str) + return payload.Str == equalOperator.value.Str } type NotEqualOperator struct { - value []byte + value gjson.Result } -func notEqualOperatorConstruct(argument []byte) *NotEqualOperator { +func notEqualOperatorConstruct(argument gjson.Result) *NotEqualOperator { op := new(NotEqualOperator) op.value = argument return op } -func (notEqualOperator NotEqualOperator) Eval(payload []byte) bool { - log.Debug("neq "+string(payload)) - return !bytes.Equal(payload, notEqualOperator.value) +func (notEqualOperator NotEqualOperator) Eval(payload gjson.Result) bool { + log.Debug("neq " + payload.Str) + return !(payload.Str == notEqualOperator.value.Str) } type InOperator struct { - operands [][]byte + operand gjson.Result } -func inOperatorConstruct(argument []byte) *InOperator { - op := new(InOperator) - _, _ = jsonparser.ArrayEach(argument, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { - op.operands = append(op.operands, value) - }) - return op -} - -func (inOperator InOperator) Eval(payload []byte) bool { - log.Debug("in "+string(payload)) - res := false - for _, v := range inOperator.operands { - res = res || bytes.Equal(payload, v) - if res == true { - break - } +func inOperatorConstruct(argument gjson.Result) *InOperator { + if argument.IsObject() { + log.Error("the argument of 'in' operator must be an array or a string") } - return res -} - -type ContainsOperator struct { - operand []byte -} - -func containsOperatorConstruct(argument []byte) *ContainsOperator { - op := new(ContainsOperator) + op := new(InOperator) op.operand = argument return op } -func (containsOperator ContainsOperator) Eval(payload []byte) bool { - log.Debug("contains "+string(payload)) - return bytes.Contains(payload, containsOperator.operand) +func (inOperator InOperator) Eval(payload gjson.Result) bool { + log.Debug("in " + payload.Str) + if inOperator.operand.IsArray() { + res := false + inOperator.operand.ForEach(func(key, value gjson.Result) bool { + res = res || value.Str == payload.Str + return true + }) + return res + } + return strings.Contains(inOperator.operand.Str, payload.Str) +} + +type ContainsOperator struct { + operand string +} + +func containsOperatorConstruct(argument gjson.Result) *ContainsOperator { + if argument.IsArray() || argument.IsObject() { + log.Error("the argument of 'contains' operator must be a string") + } + op := new(ContainsOperator) + op.operand = argument.Str + return op +} + +func (containsOperator ContainsOperator) Eval(payload gjson.Result) bool { + log.Debug("contains "+ payload.Str) + if payload.IsObject() || payload.IsArray() { + return false + } + return strings.Contains(payload.String(), containsOperator.operand) } type RegexOperator struct { regex string } -func regexOperatorConstruct(argument []byte) *RegexOperator { +func regexOperatorConstruct(argument gjson.Result) *RegexOperator { + if argument.IsArray() || argument.IsObject() { + log.Error("the argument of 'regex' operator must be a string") + } op := new(RegexOperator) - op.regex = string(argument) + op.regex = argument.Str return op } -func (containsOperator RegexOperator) Eval(payload []byte) bool { - log.Debug("regex "+string(payload)) - matched, _ := regexp.Match(containsOperator.regex, payload) +func (containsOperator RegexOperator) Eval(payload gjson.Result) bool { + log.Debug("regex " + payload.Str) + matched, _ := regexp.MatchString(containsOperator.regex, payload.Str) return matched } // 单例工厂 @@ -208,7 +227,7 @@ func GetOperatorFactory() *operatorFactory { return instance } -func (o operatorFactory) Generate(opName string, argument []byte) Filter { +func (o operatorFactory) Generate(opName string, argument gjson.Result) Filter { switch opName { case "not": return notOperatorConstruct(argument) @@ -241,7 +260,7 @@ func GetFilter() *Filter { if err != nil { filter = nil } else { - *filter = GetOperatorFactory().Generate("and", f) + *filter = GetOperatorFactory().Generate("and", gjson.ParseBytes(f)) } }) return filter diff --git a/go.mod b/go.mod index 8dcdefe..e8c0fed 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.14 require ( github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 - github.com/buger/jsonparser v1.0.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index dd1f0b7..ebab85a 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,6 @@ github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 h1:LVzj3ahW0LYJQMDcD github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 h1:z2oaXbvOmu7/O666OkUeH5SGUjyQ3wUSNjtTOagY8Sk= github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/buger/jsonparser v1.0.0 h1:etJTGF5ESxjI0Ic2UaLQs2LQQpa8G9ykQScukbh4L8A= -github.com/buger/jsonparser v1.0.0/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/server/websocket.go b/server/websocket.go index d64093b..7510776 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -172,7 +172,8 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) { } func (c *websocketClient) onBotPushEvent(m coolq.MSG) { - payload := []byte(m.ToJson()) + log.Infof(m.ToJson()) + payload := gjson.Parse(m.ToJson()) filter := global.GetFilter() if filter != nil && (*filter).Eval(payload) == false { log.Debug("Event filtered!") From 2b92035fdc2837f7913f6ab545d5ff0e6ed6b814 Mon Sep 17 00:00:00 2001 From: wdvxdr1123 <34832863+wdvxdr1123@users.noreply.github.com> Date: Sat, 22 Aug 2020 16:24:17 +0800 Subject: [PATCH 56/78] remove unnecessary info --- server/websocket.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/websocket.go b/server/websocket.go index 7510776..ce96143 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -172,7 +172,6 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) { } func (c *websocketClient) onBotPushEvent(m coolq.MSG) { - log.Infof(m.ToJson()) payload := gjson.Parse(m.ToJson()) filter := global.GetFilter() if filter != nil && (*filter).Eval(payload) == false { From b3c706cb7033305041be1935844b2e7ae8ef24fc Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sat, 22 Aug 2020 18:30:08 +0800 Subject: [PATCH 57/78] update MiraiGo. --- go.mod | 2 +- go.sum | 25 ++----------------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index e8c0fed..6c2503a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 + github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index ebab85a..1f99ea3 100644 --- a/go.sum +++ b/go.sum @@ -1,28 +1,21 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5 h1:50yz9Xgup7WgFAxeen/GQ0fCX3YUvv+ipGktZIznDuU= -github.com/Mrs4s/MiraiGo v0.0.0-20200821111822-80481f0022d5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5 h1:LVzj3ahW0LYJQMDcDm+MRPevKEFg8+VJ9iOGjF4yNOo= -github.com/Mrs4s/MiraiGo v0.0.0-20200821164244-fe8e98b9d8c5/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106 h1:z2oaXbvOmu7/O666OkUeH5SGUjyQ3wUSNjtTOagY8Sk= -github.com/Mrs4s/MiraiGo v0.0.0-20200821182324-7654a7a2a106/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7 h1:X6ebQxHSXRXDa3ZkMSFYnUhEIKdn6iPUmcFf2pl46oA= +github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -49,29 +42,22 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/guonaihong/gout v0.1.1 h1:2i3eqQ1KUhTlj7AFeIHqVUFku5QwUhwE2wNgYTVpbxQ= github.com/guonaihong/gout v0.1.1/go.mod h1:vXvv5Kxr70eM5wrp4F0+t9lnLWmq+YPW2GByll2f/EA= -github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= -github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV3kxNJJno9iKFWGxSDE13Kl66Q= github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= @@ -80,16 +66,13 @@ github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -99,11 +82,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk= github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA= -github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg= github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig= github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -154,7 +135,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -174,7 +154,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= From 7d1ed2577ed4de7b9a71e6bf0f01737b4cbbaece Mon Sep 17 00:00:00 2001 From: F0ur Date: Sat, 22 Aug 2020 23:06:53 +0800 Subject: [PATCH 58/78] fix(ws): fix eventConn panic when ws connect close --- server/websocket.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/server/websocket.go b/server/websocket.go index ce96143..784e1c2 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -324,18 +324,21 @@ func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) { func (s *websocketServer) onBotPushEvent(m coolq.MSG) { s.eventConnMutex.Lock() defer s.eventConnMutex.Unlock() - pos := 0 - for _, conn := range s.eventConn { + for i, l := 0, len(s.eventConn); i 0 { - pos++ + next := i +1 + if next >= l { + next = l -1 } + s.eventConn[i], s.eventConn[next] = s.eventConn[next], s.eventConn[i] + s.eventConn = append(s.eventConn[:next], s.eventConn[next+1:]...) + i-- + l-- + conn = nil } - pos++ } } From 8a8ce4049d73aa59b1b8dd3b8c5e1bd15b62f2b3 Mon Sep 17 00:00:00 2001 From: F0ur Date: Sat, 22 Aug 2020 23:09:22 +0800 Subject: [PATCH 59/78] perf: format code --- server/websocket.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/websocket.go b/server/websocket.go index 784e1c2..bae7439 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -324,14 +324,14 @@ func (c *websocketConn) handleRequest(bot *coolq.CQBot, payload []byte) { func (s *websocketServer) onBotPushEvent(m coolq.MSG) { s.eventConnMutex.Lock() defer s.eventConnMutex.Unlock() - for i, l := 0, len(s.eventConn); i= l { - next = l -1 + next = l - 1 } s.eventConn[i], s.eventConn[next] = s.eventConn[next], s.eventConn[i] s.eventConn = append(s.eventConn[:next], s.eventConn[next+1:]...) From d6961fc69b36eb3f7653082868156ab38c04adbd Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 01:46:02 +0800 Subject: [PATCH 60/78] move reply pos. --- coolq/cqcode.go | 11 +++++++++-- go.sum | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index b899906..db02c3a 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -111,6 +111,15 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st if len(raw) != 0 { ur = raw[0] } + // 方便 + m := &message.SendingMessage{Elements: e} + reply := m.FirstOrNil(func(e message.IMessageElement) bool { + _, ok := e.(*message.ReplyElement) + return ok + }) + if reply != nil { + r += fmt.Sprintf("[CQ:reply,id=%d]", ToGlobalId(code, reply.(*message.ReplyElement).ReplySeq)) + } for _, elem := range e { switch o := elem.(type) { case *message.TextElement: @@ -121,8 +130,6 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st continue } r += fmt.Sprintf("[CQ:at,qq=%d]", o.Target) - case *message.ReplyElement: - r += fmt.Sprintf("[CQ:reply,id=%d]", ToGlobalId(code, o.ReplySeq)) case *message.ForwardElement: r += fmt.Sprintf("[CQ:forward,id=%s]", o.ResId) case *message.FaceElement: diff --git a/go.sum b/go.sum index 1f99ea3..8fa5199 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,7 @@ github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUB github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= From 8ae2c1c9be36a90768215b55622a037e195a5e91 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 03:16:48 +0800 Subject: [PATCH 61/78] music supported. --- coolq/cqcode.go | 32 ++++++++++++++++++++++++++++++++ global/net.go | 9 +++++++++ go.mod | 2 +- go.sum | 2 ++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index db02c3a..5e8f6ae 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -425,6 +425,38 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. return message.NewAt(t), nil case "share": return message.NewUrlShare(d["url"], d["title"], d["content"], d["image"]), nil + case "music": + if d["type"] == "qq" { + info, err := global.QQMusicSongInfo(d["id"]) + if err != nil { + return nil, err + } + if !info.Get("track_info").Exists() { + return nil, errors.New("song not found") + } + aid := strconv.FormatInt(info.Get("track_info.album.id").Int(), 10) + name := info.Get("track_info.name").Str + if len(aid) < 2 { + return nil, errors.New("song error") + } + xml := fmt.Sprintf(``, + name, d["id"], aid[:len(aid)-2], aid, name, "", info.Get("track_info.singer.name").Str) + return &message.ServiceElement{ + Id: 60, + Content: xml, + SubType: "music", + }, nil + } + if d["type"] == "custom" { + xml := fmt.Sprintf(``, + d["title"], d["url"], d["image"], d["audio"], d["title"], d["content"]) + return &message.ServiceElement{ + Id: 60, + Content: xml, + SubType: "music", + }, nil + } + return nil, errors.New("unsupported music type: " + d["type"]) default: return nil, errors.New("unsupported cq code: " + t) } diff --git a/global/net.go b/global/net.go index e250ef6..40aeab8 100644 --- a/global/net.go +++ b/global/net.go @@ -3,6 +3,7 @@ package global import ( "bytes" "compress/gzip" + "github.com/tidwall/gjson" "io/ioutil" "net/http" "strings" @@ -32,3 +33,11 @@ func GetBytes(url string) ([]byte, error) { } return body, nil } + +func QQMusicSongInfo(id string) (gjson.Result, error) { + d, err := GetBytes(`https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data={%22comm%22:{%22ct%22:24,%22cv%22:0},%22songinfo%22:{%22method%22:%22get_song_detail_yqq%22,%22param%22:{%22song_type%22:0,%22song_mid%22:%22%22,%22song_id%22:` + id + `},%22module%22:%22music.pf_song_detail_svr%22}}`) + if err != nil { + return gjson.Result{}, err + } + return gjson.ParseBytes(d).Get("songinfo.data"), nil +} diff --git a/go.mod b/go.mod index 6c2503a..dde6bdf 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7 + github.com/Mrs4s/MiraiGo v0.0.0-20200822190748-ce670caee0a8 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 8fa5199..1ab0776 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7 h1:X6ebQxHSXRXDa3ZkMSFYnUhEIKdn6iPUmcFf2pl46oA= github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200822190748-ce670caee0a8 h1:29b2Y1TehWby+jEXC7kjOvXk/PxwZ1BeFAKwOzTaW7M= +github.com/Mrs4s/MiraiGo v0.0.0-20200822190748-ce670caee0a8/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 84a826815df745c104aef3c055eb2aef200af951 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 03:34:42 +0800 Subject: [PATCH 62/78] fix #164. --- server/websocket.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/server/websocket.go b/server/websocket.go index bae7439..b940ac2 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -180,33 +180,31 @@ func (c *websocketClient) onBotPushEvent(m coolq.MSG) { } if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) - c.eventConn.Lock() - defer c.eventConn.Unlock() + conn := c.eventConn + conn.Lock() + defer conn.Unlock() _ = c.eventConn.SetWriteDeadline(time.Now().Add(time.Second * 15)) if err := c.eventConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.eventConn.RemoteAddr().String(), err) _ = c.eventConn.Close() if c.conf.ReverseReconnectInterval != 0 { - go func() { - time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) - c.connectEvent() - }() + time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) + c.connectEvent() } } } if c.universalConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.universalConn.RemoteAddr().String(), m.ToJson()) - c.universalConn.Lock() - defer c.universalConn.Unlock() + conn := c.universalConn + conn.Lock() + defer conn.Unlock() _ = c.universalConn.SetWriteDeadline(time.Now().Add(time.Second * 15)) if err := c.universalConn.WriteJSON(m); err != nil { log.Warnf("向WS服务器 %v 推送Event时出现错误: %v", c.universalConn.RemoteAddr().String(), err) _ = c.universalConn.Close() if c.conf.ReverseReconnectInterval != 0 { - go func() { - time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) - c.connectUniversal() - }() + time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval)) + c.connectUniversal() } } } From 6b256c8b82f40e83deffc2386eb66d96acf83223 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 13:52:07 +0800 Subject: [PATCH 63/78] fix #168. --- server/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/http.go b/server/http.go index fcf2935..168856b 100644 --- a/server/http.go +++ b/server/http.go @@ -41,7 +41,7 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) { c.Status(404) return } - if c.Request.Method == "POST" && c.Request.Header.Get("Content-Type") == "application/json" { + if c.Request.Method == "POST" && strings.Contains(c.Request.Header.Get("Content-Type"), "application/json") { d, err := c.GetRawData() if err != nil { log.Warnf("获取请求 %v 的Body时出现错误: %v", c.Request.RequestURI, err) From fc1680aa2ef265b6b99c0191b9d55db801ee3007 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 15:58:29 +0800 Subject: [PATCH 64/78] update MiraiGo. fix #170 --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index dde6bdf..7787836 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200822190748-ce670caee0a8 + github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 1ab0776..2b27edc 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7 h1:X6ebQxHSXRXDa3ZkMSFYnUhEIKdn6iPUmcFf2pl46oA= -github.com/Mrs4s/MiraiGo v0.0.0-20200822102558-4dc018de2be7/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200822190748-ce670caee0a8 h1:29b2Y1TehWby+jEXC7kjOvXk/PxwZ1BeFAKwOzTaW7M= -github.com/Mrs4s/MiraiGo v0.0.0-20200822190748-ce670caee0a8/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d h1:F7ssNQDHqB7NZVwTeADRY+AxKT3eeSlBzfzeZYTUfxM= +github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 37ea92b92805490e405e99b58d9dcd8d11bf0ad5 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 19:58:02 +0800 Subject: [PATCH 65/78] fix #167. --- coolq/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/api.go b/coolq/api.go index f506725..bdd6719 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -489,7 +489,7 @@ func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { bot.CQProcessFriendRequest(context.Get("flag").Str, operation.Get("approve").Bool()) } if reqType == "group" { - bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, context.Get("reason").Str, operation.Get("approve").Bool()) + bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, operation.Get("reason").Str, operation.Get("approve").Bool()) } } } From 4e2fb91d8ffd6470dbea2aa38e932eed1c5a2a30 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Sun, 23 Aug 2020 20:13:01 +0800 Subject: [PATCH 66/78] image download supported. --- coolq/api.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index bdd6719..ea4aefa 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -503,11 +503,19 @@ func (bot *CQBot) CQGetImage(file string) MSG { if b, err := ioutil.ReadFile(path.Join(global.IMAGE_PATH, file)); err == nil { r := binary.NewReader(b) r.ReadBytes(16) - return OK(MSG{ + msg := MSG{ "size": r.ReadInt32(), "filename": r.ReadString(), "url": r.ReadString(), - }) + } + local := path.Join(global.CACHE_PATH, file+"."+path.Ext(msg["filename"].(string))) + if !global.PathExists(local) { + if data, err := global.GetBytes(msg["url"].(string)); err == nil { + _ = ioutil.WriteFile(local, data, 0644) + } + } + msg["file"] = local + return OK(msg) } return Failed(100) } From 15085d0a6bc2417ad4470f1d0d364ae840c1ab9c Mon Sep 17 00:00:00 2001 From: scjtqs Date: Mon, 24 Aug 2020 02:04:32 +0800 Subject: [PATCH 67/78] =?UTF-8?q?=E5=BC=80=E6=94=BE=E8=87=AA=E7=94=B1xml?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E5=BC=80=E5=8F=91=E8=80=85=E8=87=AA=E8=A1=8C=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=92=8C=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + coolq/api.go | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ docs/cqhttp.md | 56 +++++++++++++++++++++++++++++ server/http.go | 25 +++++++++++++ 4 files changed, 180 insertions(+) diff --git a/.gitignore b/.gitignore index 48b8bf9..31e3ac6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor/ +.idea diff --git a/coolq/api.go b/coolq/api.go index f506725..7e212ae 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -622,3 +622,101 @@ func convertGroupMemberInfo(groupId int64, m *client.GroupMemberInfo) MSG { "card_changeable": false, } } + +func (bot *CQBot) Send_private_msg_xml(userId int64, i interface{}, ResId int64) MSG { + var str string + if m, ok := i.(gjson.Result); ok { + if m.Type == gjson.JSON { + elem := bot.ConvertObjectMessage(m, true) + mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem}) + if mid == -1 { + return Failed(100) + } + return OK(MSG{"message_id": mid}) + } + str = func() string { + if m.Str != "" { + return m.Str + } + return m.Raw + }() + } else if s, ok := i.(string); ok { + str = s + } + if str == "" { + return Failed(100) + } + var elem []message.IMessageElement + println(str) + elem = append(elem, NewXmlMsg(str,ResId)) + + mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem}) + if mid == -1 { + return Failed(100) + } + return OK(MSG{"message_id": mid}) +} + +func NewXmlMsg(template string,ResId int64) *message.ServiceElement{ + var serviceid string + if ResId == 0{ + serviceid ="2" //默认值2 + }else{ + serviceid = strconv.FormatInt(ResId,10) + } + //println(serviceid) + return &message.ServiceElement{ + Id: int32(ResId), + Content: template, + ResId: serviceid, + SubType: "xml", + } +} + +func (bot *CQBot) CQSendGroupMessage_XML(groupId int64, i interface{}, ResId int64) MSG { + var str string + fixAt := func(elem []message.IMessageElement) { + for _, e := range elem { + if at, ok := e.(*message.AtElement); ok && at.Target != 0 { + at.Display = "@" + func() string { + mem := bot.Client.FindGroup(groupId).FindMember(at.Target) + if mem != nil { + return mem.DisplayName() + } + return strconv.FormatInt(at.Target, 10) + }() + } + } + } + if m, ok := i.(gjson.Result); ok { + if m.Type == gjson.JSON { + elem := bot.ConvertObjectMessage(m, true) + fixAt(elem) + mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) + if mid == -1 { + return Failed(100) + } + return OK(MSG{"message_id": mid}) + } + str = func() string { + if m.Str != "" { + return m.Str + } + return m.Raw + }() + } else if s, ok := i.(string); ok { + str = s + } + if str == "" { + return Failed(100) + } + var elem []message.IMessageElement + println(str) + elem = append(elem, NewXmlMsg(str,ResId)) + //fixAt(elem) + mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) + if mid == -1 { + return Failed(100) + } + return OK(MSG{"message_id": mid}) +} diff --git a/docs/cqhttp.md b/docs/cqhttp.md index 8cddcc7..5737ac4 100644 --- a/docs/cqhttp.md +++ b/docs/cqhttp.md @@ -258,3 +258,59 @@ Type: `node` | `user_id` | int64 | | 好友id | | `message_id` | int64 | | 被撤回的消息id | + +## 自定义xml结构化消息发送,请自行承担风险 +### 发送好友消息 + +终结点: `/send_private_msg_xml` 或者 `send_private_msg_xml_async` + +**参数** + +| 字段 | 类型 | 说明 | +| -------- | ------ | ---- | +| user_id | int64 | qq号 | +| message | string | xml数据 | +| serviceid | int | 服务Id,一般xml中也有,不填默认为2 | + +### 发送群消息 + +终结点: `/send_group_msg_xml` 或者 `send_group_msg_xml_async` + +**参数** + +| 字段 | 类型 | 说明 | +| -------- | ------ | ---- | +| group_id | int64 | 群号 | +| message | string | xml数据 | +| serviceid | int | 服务Id,一般xml中也有,不填默认为2 | + + +###一些xml样例 +#### qq音乐 +```xml + +``` +#### 网易音乐 +```xml + +``` + +#### 卡片消息1 +```xml + + +生死8秒!女司机高速急刹,他一个操作救下一车性命 + + +``` + +#### 卡片消息2 +```xml + + + +test title + + + +``` \ No newline at end of file diff --git a/server/http.go b/server/http.go index fcf2935..ee13557 100644 --- a/server/http.go +++ b/server/http.go @@ -155,6 +155,10 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) { s.engine.Any("/get_version_info_async", s.GetVersionInfo) s.engine.Any("/.handle_quick_operation", s.HandleQuickOperation) + s.engine.Any("/send_private_msg_xml", s.Send_private_msg_xml) + s.engine.Any("/send_private_msg_xml_async", s.Send_private_msg_xml) + s.engine.Any("/send_group_msg_xml", s.SendGroupMessage_xml) + s.engine.Any("/send_group_msg_xml_async", s.SendGroupMessage_xml) go func() { log.Infof("CQ HTTP 服务器已启动: %v", addr) @@ -400,6 +404,7 @@ func getParamOrDefault(c *gin.Context, k, def string) string { return def } + func getParam(c *gin.Context, k string) string { p, _ := getParamWithType(c, k) return p @@ -439,3 +444,23 @@ func getParamWithType(c *gin.Context, k string) (string, gjson.Type) { } return "", gjson.Null } +func (s *httpServer) Send_private_msg_xml(c *gin.Context) { + uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64) + msg, t := getParamWithType(c, "message") + resId, _ := strconv.ParseInt(getParam(c, "serviceid"), 10, 64) + if t == gjson.JSON { + c.JSON(200, s.bot.Send_private_msg_xml(uid, gjson.Parse(msg), resId)) + return + } + c.JSON(200, s.bot.Send_private_msg_xml(uid, msg, resId)) +} +func (s *httpServer) SendGroupMessage_xml(c *gin.Context) { + gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64) + msg, t := getParamWithType(c, "message") + resId, _ := strconv.ParseInt(getParam(c, "serviceid"), 10, 64) + if t == gjson.JSON { + c.JSON(200, s.bot.CQSendGroupMessage_XML(gid, gjson.Parse(msg), resId)) + return + } + c.JSON(200, s.bot.CQSendGroupMessage_XML(gid, msg, resId)) +} From 9acf5982099352c903c893599969d450259c474c Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Mon, 24 Aug 2020 02:43:55 +0800 Subject: [PATCH 68/78] update MiraiGo. fix #118 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7787836..839ecb5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d + github.com/Mrs4s/MiraiGo v0.0.0-20200823184203-93de1f445681 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 2b27edc..d78d29d 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d h1:F7ssNQDHqB7NZVwTeADRY+AxKT3eeSlBzfzeZYTUfxM= github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200823184203-93de1f445681 h1:hnaJH7BGD+Sb2Xb59SLpRy+f8B3Rx29Qy53ZM0AbIsE= +github.com/Mrs4s/MiraiGo v0.0.0-20200823184203-93de1f445681/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 8874ed039270879a14d39e8f9420c3d57a0f6fbb Mon Sep 17 00:00:00 2001 From: scjtqs Date: Mon, 24 Aug 2020 04:32:02 +0800 Subject: [PATCH 69/78] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20CQ:xml=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coolq/api.go | 98 ---------------------------------------------- coolq/cqcode.go | 26 +++++++++++++ docs/cqhttp.md | 101 +++++++++++++++++++++--------------------------- global/net.go | 18 +++++++++ server/http.go | 24 ------------ 5 files changed, 89 insertions(+), 178 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 7e212ae..f506725 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -622,101 +622,3 @@ func convertGroupMemberInfo(groupId int64, m *client.GroupMemberInfo) MSG { "card_changeable": false, } } - -func (bot *CQBot) Send_private_msg_xml(userId int64, i interface{}, ResId int64) MSG { - var str string - if m, ok := i.(gjson.Result); ok { - if m.Type == gjson.JSON { - elem := bot.ConvertObjectMessage(m, true) - mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem}) - if mid == -1 { - return Failed(100) - } - return OK(MSG{"message_id": mid}) - } - str = func() string { - if m.Str != "" { - return m.Str - } - return m.Raw - }() - } else if s, ok := i.(string); ok { - str = s - } - if str == "" { - return Failed(100) - } - var elem []message.IMessageElement - println(str) - elem = append(elem, NewXmlMsg(str,ResId)) - - mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem}) - if mid == -1 { - return Failed(100) - } - return OK(MSG{"message_id": mid}) -} - -func NewXmlMsg(template string,ResId int64) *message.ServiceElement{ - var serviceid string - if ResId == 0{ - serviceid ="2" //默认值2 - }else{ - serviceid = strconv.FormatInt(ResId,10) - } - //println(serviceid) - return &message.ServiceElement{ - Id: int32(ResId), - Content: template, - ResId: serviceid, - SubType: "xml", - } -} - -func (bot *CQBot) CQSendGroupMessage_XML(groupId int64, i interface{}, ResId int64) MSG { - var str string - fixAt := func(elem []message.IMessageElement) { - for _, e := range elem { - if at, ok := e.(*message.AtElement); ok && at.Target != 0 { - at.Display = "@" + func() string { - mem := bot.Client.FindGroup(groupId).FindMember(at.Target) - if mem != nil { - return mem.DisplayName() - } - return strconv.FormatInt(at.Target, 10) - }() - } - } - } - if m, ok := i.(gjson.Result); ok { - if m.Type == gjson.JSON { - elem := bot.ConvertObjectMessage(m, true) - fixAt(elem) - mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) - if mid == -1 { - return Failed(100) - } - return OK(MSG{"message_id": mid}) - } - str = func() string { - if m.Str != "" { - return m.Str - } - return m.Raw - }() - } else if s, ok := i.(string); ok { - str = s - } - if str == "" { - return Failed(100) - } - var elem []message.IMessageElement - println(str) - elem = append(elem, NewXmlMsg(str,ResId)) - //fixAt(elem) - mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem}) - if mid == -1 { - return Failed(100) - } - return OK(MSG{"message_id": mid}) -} diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 5e8f6ae..f7c6294 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -196,6 +196,22 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa } } } + if(t == "xml"){ + //xml需要实体化,发送的时候不能转回去 + x := make(map[string]string) + //循环遍历Map + for _, p := range ps { + x[p[1]] = p[2] + } + resId := x["resid"] + template := x["data"] + println(template) + i, _ := strconv.ParseInt(resId, 10, 64) + msg :=global.NewXmlMsg(template,i) + r=append(r,msg) + continue + } + elem, err := bot.ToElement(t, d, group) if err != nil { log.Warnf("转换CQ码到MiraiGo Element时出现错误: %v 将原样发送.", err) @@ -236,6 +252,16 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message. } } } + if t =="xml"{ + //xml需要实体化,发送的时候不能转回去 + resId := e.Get("data").Get("resid").Str + template := e.Get("data").Get("data").Str + println(template) + i, _ := strconv.ParseInt(resId, 10, 64) + msg :=global.NewXmlMsg(template,i) + r=append(r,msg) + return + } d := make(map[string]string) e.Get("data").ForEach(func(key, value gjson.Result) bool { d[key.Str] = value.Str diff --git a/docs/cqhttp.md b/docs/cqhttp.md index 5737ac4..a0f5c42 100644 --- a/docs/cqhttp.md +++ b/docs/cqhttp.md @@ -119,6 +119,51 @@ Type: `node` ] ```` +### xml支持 + +Type: `xml` + +范围: **发送** + +参数: + +| 参数名 | 类型 | 说明 | +| ------ | ------ | ------------------------------------------------------------ | +| data | string | xml内容,xml中的value部分,记得实体化处理| +| resid | int32 | 可以不填| + +示例: `[CQ:xml,data=xxxx]` + +####一些xml样例 +####ps:重要:xml中的value部分,记得html实体化处理后,再打加入到cq码中 +#### qq音乐 +```xml + +``` +#### 网易音乐 +```xml + +``` + +#### 卡片消息1 +```xml + + +生死8秒!女司机高速急刹,他一个操作救下一车性命 + + +``` + +#### 卡片消息2 +```xml + + + +test title + + + +``` ## API @@ -258,59 +303,3 @@ Type: `node` | `user_id` | int64 | | 好友id | | `message_id` | int64 | | 被撤回的消息id | - -## 自定义xml结构化消息发送,请自行承担风险 -### 发送好友消息 - -终结点: `/send_private_msg_xml` 或者 `send_private_msg_xml_async` - -**参数** - -| 字段 | 类型 | 说明 | -| -------- | ------ | ---- | -| user_id | int64 | qq号 | -| message | string | xml数据 | -| serviceid | int | 服务Id,一般xml中也有,不填默认为2 | - -### 发送群消息 - -终结点: `/send_group_msg_xml` 或者 `send_group_msg_xml_async` - -**参数** - -| 字段 | 类型 | 说明 | -| -------- | ------ | ---- | -| group_id | int64 | 群号 | -| message | string | xml数据 | -| serviceid | int | 服务Id,一般xml中也有,不填默认为2 | - - -###一些xml样例 -#### qq音乐 -```xml - -``` -#### 网易音乐 -```xml - -``` - -#### 卡片消息1 -```xml - - -生死8秒!女司机高速急刹,他一个操作救下一车性命 - - -``` - -#### 卡片消息2 -```xml - - - -test title - - - -``` \ No newline at end of file diff --git a/global/net.go b/global/net.go index 40aeab8..d3cf1a7 100644 --- a/global/net.go +++ b/global/net.go @@ -3,9 +3,11 @@ package global import ( "bytes" "compress/gzip" + "github.com/Mrs4s/MiraiGo/message" "github.com/tidwall/gjson" "io/ioutil" "net/http" + "strconv" "strings" ) @@ -41,3 +43,19 @@ func QQMusicSongInfo(id string) (gjson.Result, error) { } return gjson.ParseBytes(d).Get("songinfo.data"), nil } + +func NewXmlMsg(template string,ResId int64) *message.ServiceElement{ + var serviceid string + if ResId == 0{ + serviceid ="2" //默认值2 + }else{ + serviceid = strconv.FormatInt(ResId,10) + } + //println(serviceid) + return &message.ServiceElement{ + Id: int32(ResId), + Content: template, + ResId: serviceid, + SubType: "xml", + } +} diff --git a/server/http.go b/server/http.go index ee13557..f6a229b 100644 --- a/server/http.go +++ b/server/http.go @@ -155,10 +155,6 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) { s.engine.Any("/get_version_info_async", s.GetVersionInfo) s.engine.Any("/.handle_quick_operation", s.HandleQuickOperation) - s.engine.Any("/send_private_msg_xml", s.Send_private_msg_xml) - s.engine.Any("/send_private_msg_xml_async", s.Send_private_msg_xml) - s.engine.Any("/send_group_msg_xml", s.SendGroupMessage_xml) - s.engine.Any("/send_group_msg_xml_async", s.SendGroupMessage_xml) go func() { log.Infof("CQ HTTP 服务器已启动: %v", addr) @@ -444,23 +440,3 @@ func getParamWithType(c *gin.Context, k string) (string, gjson.Type) { } return "", gjson.Null } -func (s *httpServer) Send_private_msg_xml(c *gin.Context) { - uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64) - msg, t := getParamWithType(c, "message") - resId, _ := strconv.ParseInt(getParam(c, "serviceid"), 10, 64) - if t == gjson.JSON { - c.JSON(200, s.bot.Send_private_msg_xml(uid, gjson.Parse(msg), resId)) - return - } - c.JSON(200, s.bot.Send_private_msg_xml(uid, msg, resId)) -} -func (s *httpServer) SendGroupMessage_xml(c *gin.Context) { - gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64) - msg, t := getParamWithType(c, "message") - resId, _ := strconv.ParseInt(getParam(c, "serviceid"), 10, 64) - if t == gjson.JSON { - c.JSON(200, s.bot.CQSendGroupMessage_XML(gid, gjson.Parse(msg), resId)) - return - } - c.JSON(200, s.bot.CQSendGroupMessage_XML(gid, msg, resId)) -} From 248ba84a0c39e8f7b202aadd3b3b6d5c02f7b432 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Mon, 24 Aug 2020 14:47:24 +0800 Subject: [PATCH 70/78] fix bug. --- coolq/cqcode.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 5e8f6ae..4d01fd4 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -329,6 +329,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. } var size int32 var hash []byte + var url string if path.Ext(rawPath) == ".cqimg" { for _, line := range strings.Split(global.ReadAllText(rawPath), "\n") { kv := strings.SplitN(line, "=", 2) @@ -344,8 +345,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. r := binary.NewReader(b) hash = r.ReadBytes(16) size = r.ReadInt32() + r.ReadString() + url = r.ReadString() } if size == 0 { + if url != "" { + return bot.ToElement(t, map[string]string{"file": url}, group) + } return nil, errors.New("img size is 0") } if len(hash) != 16 { From 03cc0dba9509d3dc044c2ec70c4cdbe4028d83f8 Mon Sep 17 00:00:00 2001 From: scjtqs Date: Mon, 24 Aug 2020 16:01:21 +0800 Subject: [PATCH 71/78] =?UTF-8?q?=E7=A7=BB=E5=8A=A8xml=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coolq/cqcode.go | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index f7c6294..d59b097 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -196,22 +196,6 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa } } } - if(t == "xml"){ - //xml需要实体化,发送的时候不能转回去 - x := make(map[string]string) - //循环遍历Map - for _, p := range ps { - x[p[1]] = p[2] - } - resId := x["resid"] - template := x["data"] - println(template) - i, _ := strconv.ParseInt(resId, 10, 64) - msg :=global.NewXmlMsg(template,i) - r=append(r,msg) - continue - } - elem, err := bot.ToElement(t, d, group) if err != nil { log.Warnf("转换CQ码到MiraiGo Element时出现错误: %v 将原样发送.", err) @@ -252,16 +236,6 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message. } } } - if t =="xml"{ - //xml需要实体化,发送的时候不能转回去 - resId := e.Get("data").Get("resid").Str - template := e.Get("data").Get("data").Str - println(template) - i, _ := strconv.ParseInt(resId, 10, 64) - msg :=global.NewXmlMsg(template,i) - r=append(r,msg) - return - } d := make(map[string]string) e.Get("data").ForEach(func(key, value gjson.Result) bool { d[key.Str] = value.Str @@ -483,6 +457,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. }, nil } return nil, errors.New("unsupported music type: " + d["type"]) + case "xml": + resId := d["resid"] + template := CQCodeEscapeValue(d["data"]) + println(template) + i, _ := strconv.ParseInt(resId, 10, 64) + msg :=global.NewXmlMsg(template,i) + return msg,nil default: return nil, errors.New("unsupported cq code: " + t) } From cb9436601ff40bfb84ac25cf62855beb2e6ecec4 Mon Sep 17 00:00:00 2001 From: scjtqs Date: Mon, 24 Aug 2020 16:16:36 +0800 Subject: [PATCH 72/78] =?UTF-8?q?=E7=A7=BB=E5=8A=A8xml=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coolq/cqcode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index d59b097..d22c56d 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -460,7 +460,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. case "xml": resId := d["resid"] template := CQCodeEscapeValue(d["data"]) - println(template) + //println(template) i, _ := strconv.ParseInt(resId, 10, 64) msg :=global.NewXmlMsg(template,i) return msg,nil From 801fa9a2046907cff59854186a678cb8b94a3fc4 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Mon, 24 Aug 2020 20:05:10 +0800 Subject: [PATCH 73/78] update event filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对所有通信方式支持事件过滤器 --- coolq/bot.go | 7 +++++++ server/websocket.go | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index 1e5121d..f0b2106 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -10,6 +10,7 @@ import ( "github.com/Mrs4s/MiraiGo/message" "github.com/Mrs4s/go-cqhttp/global" log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" "github.com/xujiajun/nutsdb" "hash/crc32" "path" @@ -208,6 +209,12 @@ func (bot *CQBot) Release() { } func (bot *CQBot) dispatchEventMessage(m MSG) { + payload := gjson.Parse(m.ToJson()) + filter := global.GetFilter() + if filter != nil && (*filter).Eval(payload) == false { + log.Debug("Event filtered!") + return + } for _, f := range bot.events { fn := f go func() { diff --git a/server/websocket.go b/server/websocket.go index b940ac2..8dab69a 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -172,12 +172,6 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) { } func (c *websocketClient) onBotPushEvent(m coolq.MSG) { - payload := gjson.Parse(m.ToJson()) - filter := global.GetFilter() - if filter != nil && (*filter).Eval(payload) == false { - log.Debug("Event filtered!") - return - } if c.eventConn != nil { log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson()) conn := c.eventConn From e319f2645e78eeab8aa49977f37bc04bc37a74f7 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 25 Aug 2020 00:50:03 +0800 Subject: [PATCH 74/78] update MiraiGo & more debug & fmt code. --- coolq/cqcode.go | 4 ++-- go.mod | 2 +- go.sum | 6 ++---- main.go | 10 ++++++++++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index cce76d7..4c5e8b4 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -468,8 +468,8 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. template := CQCodeEscapeValue(d["data"]) //println(template) i, _ := strconv.ParseInt(resId, 10, 64) - msg :=global.NewXmlMsg(template,i) - return msg,nil + msg := global.NewXmlMsg(template, i) + return msg, nil default: return nil, errors.New("unsupported cq code: " + t) } diff --git a/go.mod b/go.mod index 839ecb5..ca48111 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200823184203-93de1f445681 + github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index d78d29d..0d18f62 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d h1:F7ssNQDHqB7NZVwTeADRY+AxKT3eeSlBzfzeZYTUfxM= -github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200823184203-93de1f445681 h1:hnaJH7BGD+Sb2Xb59SLpRy+f8B3Rx29Qy53ZM0AbIsE= -github.com/Mrs4s/MiraiGo v0.0.0-20200823184203-93de1f445681/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58 h1:bQDlJSgZmQh9fOMF7yWwL6w2HDm2YUmJlW871WQ404U= +github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/main.go b/main.go index 87b0cc8..4410f00 100644 --- a/main.go +++ b/main.go @@ -171,6 +171,16 @@ func main() { time.Sleep(time.Second * 5) log.Info("开始尝试登录并同步消息...") cli := client.NewClient(conf.Uin, conf.Password) + cli.OnLog(func(c *client.QQClient, e *client.LogEvent) { + switch e.Type { + case "INFO": + log.Info("Protocol -> " + e.Message) + case "ERROR": + log.Error("Protocol -> " + e.Message) + case "DEBUG": + log.Debug("Protocol -> " + e.Message) + } + }) rsp, err := cli.Login() for { global.Check(err) From 174bb0bbe115427380cadc90e55acaf1c6e752db Mon Sep 17 00:00:00 2001 From: F0ur Date: Tue, 25 Aug 2020 15:17:20 +0800 Subject: [PATCH 75/78] feat(music): add netease(163) music for [CQ:music] --- coolq/cqcode.go | 32 +++++++++++++++++++++++++++----- global/net.go | 24 +++++++++++++++++------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 4c5e8b4..f3a6fe6 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -6,11 +6,6 @@ import ( "encoding/hex" "errors" "fmt" - "github.com/Mrs4s/MiraiGo/binary" - "github.com/Mrs4s/MiraiGo/message" - "github.com/Mrs4s/go-cqhttp/global" - log "github.com/sirupsen/logrus" - "github.com/tidwall/gjson" "io/ioutil" "net/url" "path" @@ -18,6 +13,12 @@ import ( "runtime" "strconv" "strings" + + "github.com/Mrs4s/MiraiGo/binary" + "github.com/Mrs4s/MiraiGo/message" + "github.com/Mrs4s/go-cqhttp/global" + log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" ) var matchReg = regexp.MustCompile(`\[CQ:\w+?.*?]`) @@ -453,6 +454,27 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message. SubType: "music", }, nil } + if d["type"] == "163" { + info, err := global.NeteaseMusicSongInfo(d["id"]) + if err != nil { + return nil, err + } + if !info.Exists() { + return nil, errors.New("song not found") + } + name := info.Get("name").Str + artistName := "" + if info.Get("artists.0").Exists() { + artistName = info.Get("artists.0.name").Str + } + xml := fmt.Sprintf(``, + name, d["id"], info.Get("album.picUrl").Str, d["id"], name, artistName) + return &message.ServiceElement{ + Id: 60, + Content: xml, + SubType: "music", + }, nil + } if d["type"] == "custom" { xml := fmt.Sprintf(``, d["title"], d["url"], d["image"], d["audio"], d["title"], d["content"]) diff --git a/global/net.go b/global/net.go index d3cf1a7..e394efd 100644 --- a/global/net.go +++ b/global/net.go @@ -3,12 +3,14 @@ package global import ( "bytes" "compress/gzip" - "github.com/Mrs4s/MiraiGo/message" - "github.com/tidwall/gjson" + "fmt" "io/ioutil" "net/http" "strconv" "strings" + + "github.com/Mrs4s/MiraiGo/message" + "github.com/tidwall/gjson" ) func GetBytes(url string) ([]byte, error) { @@ -44,12 +46,20 @@ func QQMusicSongInfo(id string) (gjson.Result, error) { return gjson.ParseBytes(d).Get("songinfo.data"), nil } -func NewXmlMsg(template string,ResId int64) *message.ServiceElement{ +func NeteaseMusicSongInfo(id string) (gjson.Result, error) { + d, err := GetBytes(fmt.Sprintf("http://music.163.com/api/song/detail/?id=%s&ids=%%5B%s%%5D", id, id)) + if err != nil { + return gjson.Result{}, err + } + return gjson.ParseBytes(d).Get("songs.0"), nil +} + +func NewXmlMsg(template string, ResId int64) *message.ServiceElement { var serviceid string - if ResId == 0{ - serviceid ="2" //默认值2 - }else{ - serviceid = strconv.FormatInt(ResId,10) + if ResId == 0 { + serviceid = "2" //默认值2 + } else { + serviceid = strconv.FormatInt(ResId, 10) } //println(serviceid) return &message.ServiceElement{ From bda02d895a08ed920aed4ceb56dac4abfdcf15b8 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 25 Aug 2020 17:05:44 +0800 Subject: [PATCH 76/78] update MiraiGo. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ca48111..6694dd6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58 + github.com/Mrs4s/MiraiGo v0.0.0-20200824170850-16fc454f752b github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 0d18f62..148c90a 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58 h1:bQDlJSgZmQh9fOMF7yWwL6w2HDm2YUmJlW871WQ404U= github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200824170850-16fc454f752b h1:dYpx9kjDmSCVyu0Mr86GDou0Wz5iXYcMwYL52G5wz70= +github.com/Mrs4s/MiraiGo v0.0.0-20200824170850-16fc454f752b/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 02355db0f160c6018e45685c7987f2319db9e9e3 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 25 Aug 2020 17:26:08 +0800 Subject: [PATCH 77/78] update config. close #190 --- coolq/bot.go | 4 +++- coolq/cqcode.go | 10 ++++++++-- docs/config.md | 33 ++++++++++++++++++++------------- global/config.go | 29 ++++++++++++++++------------- main.go | 2 ++ 5 files changed, 49 insertions(+), 29 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index f0b2106..6f36aa2 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -31,6 +31,8 @@ type CQBot struct { type MSG map[string]interface{} +var ForceFragmented = false + func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot { bot := &CQBot{ Client: cli, @@ -128,7 +130,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int newElem = append(newElem, elem) } m.Elements = newElem - ret := bot.Client.SendGroupMessage(groupId, m) + ret := bot.Client.SendGroupMessage(groupId, m, ForceFragmented) if ret == nil || ret.Id == -1 { log.Warnf("群消息发送失败: 账号可能被风控.") return -1 diff --git a/coolq/cqcode.go b/coolq/cqcode.go index f3a6fe6..726129d 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -25,6 +25,8 @@ var matchReg = regexp.MustCompile(`\[CQ:\w+?.*?]`) var typeReg = regexp.MustCompile(`\[CQ:(\w+)`) var paramReg = regexp.MustCompile(`,([\w\-.]+?)=([^,\]]+)`) +var IgnoreInvalidCQCode = false + func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []MSG) { ur := false if len(raw) != 0 { @@ -199,8 +201,12 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa } elem, err := bot.ToElement(t, d, group) if err != nil { - log.Warnf("转换CQ码到MiraiGo Element时出现错误: %v 将原样发送.", err) - r = append(r, message.NewText(code)) + if !IgnoreInvalidCQCode { + log.Warnf("转换CQ码 %v 到MiraiGo Element时出现错误: %v 将原样发送.", code, err) + r = append(r, message.NewText(code)) + } else { + log.Warnf("转换CQ码 %v 到MiraiGo Element时出现错误: %v 将忽略.", code, err) + } continue } r = append(r, elem) diff --git a/docs/config.md b/docs/config.md index 2ba5612..245800f 100644 --- a/docs/config.md +++ b/docs/config.md @@ -25,12 +25,14 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为: "relogin": false, "relogin_delay": 0, "post_message_format": "string", + "ignore_invalid_cqcode": false, + "force_fragmented": true, "http_config": { "enabled": true, "host": "0.0.0.0", "port": 5700, - "timeout": 5, - "post_urls": {"url:port": "secret"}, + "timeout": 5, + "post_urls": {"url:port": "secret"} }, "ws_config": { "enabled": true, @@ -51,18 +53,23 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为: | 字段 | 类型 | 说明 | | ------------------ | -------- | ------------------------------------------------------------------- | -| uin | int64 | 登录用QQ号 | -| password | string | 登录用密码 | -| encrypt_password | bool | 是否对密码进行加密. | -| password_encrypted | string | 加密后的密码(请勿修改) | -| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用 **回复/撤回** 等上下文相关接口 | -| access_token | string | 同CQHTTP的 `access_token` 用于身份验证 | -| relogin | bool | 是否自动重新登录 | -| relogin_delay | int | 重登录延时(秒) | -| http_config | object | HTTP API配置 | -| ws_config | object | Websocket API 配置 | -| ws_reverse_servers | object[] | 反向 Websocket API 配置 | +| uin | int64 | 登录用QQ号 | +| password | string | 登录用密码 | +| encrypt_password | bool | 是否对密码进行加密. | +| password_encrypted | string | 加密后的密码(请勿修改) | +| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用 **回复/撤回** 等上下文相关接口 | +| access_token | string | 同CQHTTP的 `access_token` 用于身份验证 | +| relogin | bool | 是否自动重新登录 | +| relogin_delay | int | 重登录延时(秒) | +| post_message_format | string | 上报信息类型 | +| ignore_invalid_cqcode| bool | 是否忽略错误的CQ码 | +| force_fragmented | bool | 是否强制分片发送群长消息 | +| http_config | object | HTTP API配置 | +| ws_config | object | Websocket API 配置 | +| ws_reverse_servers | object[] | 反向 Websocket API 配置 | > 注: 开启密码加密后程序将在每次启动时要求输入解密密钥, 密钥错误会导致登录时提示密码错误. > 解密后密码将储存在内存中,用于自动重连等功能. 所以此加密并不能防止内存读取. > 解密密钥在使用完成后并不会留存在内存中, 所以可用相对简单的字符串作为密钥 + +> 注2: 分片发送为原酷Q发送长消息的老方案, 发送速度更优/兼容性更好。关闭后将优先使用新方案, 能发送更长的消息, 但发送速度更慢,在部分老客户端将无法解析. \ No newline at end of file diff --git a/global/config.go b/global/config.go index e41f7c4..5f13ac4 100644 --- a/global/config.go +++ b/global/config.go @@ -6,19 +6,21 @@ import ( ) type JsonConfig struct { - Uin int64 `json:"uin"` - Password string `json:"password"` - EncryptPassword bool `json:"encrypt_password"` - PasswordEncrypted string `json:"password_encrypted"` - EnableDB bool `json:"enable_db"` - AccessToken string `json:"access_token"` - ReLogin bool `json:"relogin"` - ReLoginDelay int `json:"relogin_delay"` - HttpConfig *GoCQHttpConfig `json:"http_config"` - WSConfig *GoCQWebsocketConfig `json:"ws_config"` - ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"` - PostMessageFormat string `json:"post_message_format"` - Debug bool `json:"debug"` + Uin int64 `json:"uin"` + Password string `json:"password"` + EncryptPassword bool `json:"encrypt_password"` + PasswordEncrypted string `json:"password_encrypted"` + EnableDB bool `json:"enable_db"` + AccessToken string `json:"access_token"` + ReLogin bool `json:"relogin"` + ReLoginDelay int `json:"relogin_delay"` + IgnoreInvalidCQCode bool `json:"ignore_invalid_cqcode"` + ForceFragmented bool `json:"force_fragmented"` + HttpConfig *GoCQHttpConfig `json:"http_config"` + WSConfig *GoCQWebsocketConfig `json:"ws_config"` + ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"` + PostMessageFormat string `json:"post_message_format"` + Debug bool `json:"debug"` } type CQHttpApiConfig struct { @@ -68,6 +70,7 @@ func DefaultConfig() *JsonConfig { ReLogin: true, ReLoginDelay: 3, PostMessageFormat: "string", + ForceFragmented: true, HttpConfig: &GoCQHttpConfig{ Enabled: true, Host: "0.0.0.0", diff --git a/main.go b/main.go index 4410f00..b45d6e3 100644 --- a/main.go +++ b/main.go @@ -220,6 +220,8 @@ func main() { } else { coolq.SetMessageFormat(conf.PostMessageFormat) } + coolq.IgnoreInvalidCQCode = conf.IgnoreInvalidCQCode + coolq.ForceFragmented = conf.ForceFragmented if conf.HttpConfig != nil && conf.HttpConfig.Enabled { server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b) for k, v := range conf.HttpConfig.PostUrls { From 174ebfae9db41dc32dac181355b8745ddc2473dc Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 25 Aug 2020 20:18:18 +0800 Subject: [PATCH 78/78] update MiraiGo. --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 6694dd6..426ba6c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp go 1.14 require ( - github.com/Mrs4s/MiraiGo v0.0.0-20200824170850-16fc454f752b + github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect github.com/gin-gonic/gin v1.6.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index 148c90a..ef1cb9a 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58 h1:bQDlJSgZmQh9fOMF7yWwL6w2HDm2YUmJlW871WQ404U= -github.com/Mrs4s/MiraiGo v0.0.0-20200824164833-834baa5b6b58/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= -github.com/Mrs4s/MiraiGo v0.0.0-20200824170850-16fc454f752b h1:dYpx9kjDmSCVyu0Mr86GDou0Wz5iXYcMwYL52G5wz70= -github.com/Mrs4s/MiraiGo v0.0.0-20200824170850-16fc454f752b/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= +github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839 h1:TDhaPfWcubIMKDz1HU+N07SwIUjj7oVUQ7EXZBbDUxs= +github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=