diff --git a/cmd/api-generator/main.go b/cmd/api-generator/main.go index da48236..031e493 100644 --- a/cmd/api-generator/main.go +++ b/cmd/api-generator/main.go @@ -76,12 +76,10 @@ func (g *generator) genRouter(routers []Router) { g.WriteString("import (\n\n") g.WriteString("\"github.com/Mrs4s/go-cqhttp/coolq\"\n") g.WriteString("\"github.com/Mrs4s/go-cqhttp/global\"\n") + g.WriteString("\"github.com/Mrs4s/go-cqhttp/internal/onebot\"\n") g.WriteString(")\n\n") - g.WriteString(`func (c *Caller) call(action string, version uint16, p Getter) global.MSG { - var converter coolq.IDConverter = func(id any) any { - return coolq.ConvertIDWithVersion(id,version) - } - if version == 12 { + g.WriteString(`func (c *Caller) call(action string, spec *onebot.Spec, p Getter) global.MSG { + if spec.Version == 12 { switch action { `) for _, router := range routers { @@ -89,7 +87,7 @@ func (g *generator) genRouter(routers []Router) { } io.WriteString(g.out, `}}`) io.WriteString(g.out, "\n") - g.WriteString(`if version == 11 { + g.WriteString(`if spec.Version == 11 { switch action { `) for _, router := range routers { @@ -141,14 +139,14 @@ func (g *generator) router(router Router, pathVersion int) { if len(router.Version) == 1 { // 目前来说只需要判断一个版本的情况 check := make([]string, 0, len(router.Version)) for _, ver := range router.Version { - check = append(check, fmt.Sprintf("version != %v", ver)) + check = append(check, fmt.Sprintf("spec.Version != %v", ver)) } fmt.Fprintf(g.out, "if %v {\n", strings.Join(check, " && ")) fmt.Fprintf(g.out, "return coolq.Failed(405, \"VERSION_ERROR\", \"API版本不匹配\")}\n") } for i, p := range router.Params { - if p.Name == "version" || p.Name == "converter" { + if p.Name == "spec" { continue } if p.Default == "" { @@ -166,12 +164,8 @@ func (g *generator) router(router Router, pathVersion int) { if i != 0 { g.WriteString(", ") } - if p.Name == "version" { - fmt.Fprintf(g.out, "version") - continue - } - if p.Name == "converter" { - fmt.Fprintf(g.out, "converter") + if p.Name == "spec" { + fmt.Fprintf(g.out, "spec") continue } fmt.Fprintf(g.out, "p%d", i) @@ -183,7 +177,7 @@ func conv(v, t string) string { switch t { default: panic("unknown type: " + t) - case "gjson.Result", "IDConverter": + case "gjson.Result", "*onebot.Spec", "IDConverter": return v case "int64": return v + ".Int()" diff --git a/coolq/api.go b/coolq/api.go index a11947b..e08bada 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -328,13 +328,13 @@ func (bot *CQBot) CQGetTopicChannelFeeds(guildID, channelID uint64) global.MSG { // // https://git.io/Jtz1L // @route(get_friend_list) -func (bot *CQBot) CQGetFriendList(version uint16) global.MSG { +func (bot *CQBot) CQGetFriendList(spec *onebot.Spec) global.MSG { fs := make([]global.MSG, 0, len(bot.Client.FriendList)) for _, f := range bot.Client.FriendList { fs = append(fs, global.MSG{ "nickname": f.Nickname, "remark": f.Remark, - "user_id": ConvertIDWithVersion(f.Uin, version), + "user_id": spec.ConvertID(f.Uin), }) } return OK(fs) @@ -400,14 +400,14 @@ func (bot *CQBot) CQDeleteFriend(uin int64) global.MSG { // // https://git.io/Jtz1t // @route(get_group_list) -func (bot *CQBot) CQGetGroupList(noCache bool, converter IDConverter) global.MSG { +func (bot *CQBot) CQGetGroupList(noCache bool, spec *onebot.Spec) global.MSG { gs := make([]global.MSG, 0, len(bot.Client.GroupList)) if noCache { _ = bot.Client.ReloadGroupList() } for _, g := range bot.Client.GroupList { gs = append(gs, global.MSG{ - "group_id": converter(g.Code), + "group_id": spec.ConvertID(g.Code), "group_name": g.Name, "group_create_time": g.GroupCreateTime, "group_level": g.GroupLevel, @@ -422,7 +422,7 @@ func (bot *CQBot) CQGetGroupList(noCache bool, converter IDConverter) global.MSG // // https://git.io/Jtz1O // @route(get_group_info) -func (bot *CQBot) CQGetGroupInfo(groupID int64, noCache bool, converter IDConverter) global.MSG { +func (bot *CQBot) CQGetGroupInfo(groupID int64, noCache bool, spec *onebot.Spec) global.MSG { group := bot.Client.FindGroup(groupID) if group == nil || noCache { group, _ = bot.Client.GetGroupInfo(groupID) @@ -436,7 +436,7 @@ func (bot *CQBot) CQGetGroupInfo(groupID int64, noCache bool, converter IDConver for _, g := range info { if g.Code == groupID { return OK(global.MSG{ - "group_id": converter(g.Code), + "group_id": spec.ConvertID(g.Code), "group_name": g.Name, "group_memo": g.Memo, "group_create_time": 0, @@ -448,7 +448,7 @@ func (bot *CQBot) CQGetGroupInfo(groupID int64, noCache bool, converter IDConver } } else { return OK(global.MSG{ - "group_id": converter(group.Code), + "group_id": spec.ConvertID(group.Code), "group_name": group.Name, "group_create_time": group.GroupCreateTime, "group_level": group.GroupLevel, @@ -1445,7 +1445,7 @@ func (bot *CQBot) CQGetStrangerInfo(userID int64) global.MSG { // CQHandleQuickOperation 隐藏API-对事件执行快速操作 // // https://git.io/Jtz15 -// @route(".handle_quick_operation") +// @route11(".handle_quick_operation") func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) global.MSG { postType := context.Get("post_type").Str @@ -1903,8 +1903,8 @@ func (bot *CQBot) CQSetGroupAnonymousBan(groupID int64, flag string, duration in // // https://git.io/JtzMe // @route(get_status) -func (bot *CQBot) CQGetStatus(version uint16) global.MSG { - if version == 11 { +func (bot *CQBot) CQGetStatus(spec *onebot.Spec) global.MSG { + if spec.Version == 11 { return OK(global.MSG{ "app_initialized": true, "app_enabled": true, @@ -2108,10 +2108,9 @@ func (bot *CQBot) CQReloadEventFilter(file string) global.MSG { // CQGetSupportedActions 获取支持的动作列表 // -// @route12(get_supported_actions) -func (bot *CQBot) CQGetSupportedActions() global.MSG { - // TODO: fix v11 - return OK(onebot.V12.SupportedActions) +// @route(get_supported_actions) +func (bot *CQBot) CQGetSupportedActions(spec *onebot.Spec) global.MSG { + return OK(spec.SupportedActions) } // OK 生成成功返回值 diff --git a/coolq/bot.go b/coolq/bot.go index 74ee116..89cf8d1 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -26,6 +26,7 @@ import ( "github.com/Mrs4s/go-cqhttp/global" "github.com/Mrs4s/go-cqhttp/internal/base" "github.com/Mrs4s/go-cqhttp/internal/mime" + "github.com/Mrs4s/go-cqhttp/internal/onebot" ) // CQBot CQBot结构体,存储Bot实例相关配置 @@ -114,7 +115,7 @@ func NewQQBot(cli *client.QQClient) *CQBot { for { <-t.C bot.dispatchEvent("meta_event/heartbeat", global.MSG{ - "status": bot.CQGetStatus(11)["data"], + "status": bot.CQGetStatus(onebot.V11)["data"], "interval": base.HeartbeatInterval.Milliseconds(), }) } diff --git a/coolq/converter.go b/coolq/converter.go index 5ec30c4..30720e2 100644 --- a/coolq/converter.go +++ b/coolq/converter.go @@ -1,7 +1,6 @@ package coolq import ( - "fmt" "strconv" "strings" @@ -13,9 +12,6 @@ import ( "github.com/Mrs4s/go-cqhttp/global" ) -// IDConverter id 转换 -type IDConverter func(id any) any - func convertGroupMemberInfo(groupID int64, m *client.GroupMemberInfo) global.MSG { sex := "unknown" if m.Gender == 1 { // unknown = 0xff @@ -224,11 +220,3 @@ func toStringMessage(m []message.IMessageElement, source message.Source) string func fU64(v uint64) string { return strconv.FormatUint(v, 10) } - -// ConvertIDWithVersion id 转换 -func ConvertIDWithVersion(v any, version uint16) any { - if version == 12 { - return fmt.Sprint(v) - } - return v -} diff --git a/internal/onebot/spec.go b/internal/onebot/spec.go index c1eb377..49afe73 100644 --- a/internal/onebot/spec.go +++ b/internal/onebot/spec.go @@ -1,6 +1,8 @@ // Package onebot defines onebot protocol struct and some spec info. package onebot +import "fmt" + //go:generate go run github.com/Mrs4s/go-cqhttp/cmd/api-generator -pkg onebot -path=./../../coolq/api.go,./../../coolq/api_v12.go -supported -o supported.go // Spec OneBot Specification @@ -9,15 +11,21 @@ type Spec struct { SupportedActions []string } -/* // TODO: Use this variable +// V11 OneBot V11 var V11 = &Spec{ Version: 11, SupportedActions: supportedV11, } -*/ // V12 OneBot V12 var V12 = &Spec{ Version: 12, SupportedActions: supportedV12, } + +func (s *Spec) ConvertID(id any) any { + if s.Version == 12 { + return fmt.Sprint(id) + } + return id +} diff --git a/internal/onebot/supported.go b/internal/onebot/supported.go index fe4aed1..d5357d7 100644 --- a/internal/onebot/supported.go +++ b/internal/onebot/supported.go @@ -54,6 +54,7 @@ var supportedV11 = []string{ "get_online_clients", "get_status", "get_stranger_info", + "get_supported_actions", "get_topic_channel_feeds", "get_unidirectional_friend_list", "get_version_info", @@ -91,7 +92,6 @@ var supportedV11 = []string{ var supportedV12 = []string{ ".get_word_slices", - ".handle_quick_operation", ".ocr_image", "ocr_image", "_del_group_notice", @@ -139,6 +139,7 @@ var supportedV12 = []string{ "get_online_clients", "get_status", "get_user_info", + "get_supported_actions", "get_topic_channel_feeds", "get_unidirectional_friend_list", "mark_msg_as_read", diff --git a/modules/api/api.go b/modules/api/api.go index 76b9206..acac76d 100644 --- a/modules/api/api.go +++ b/modules/api/api.go @@ -5,21 +5,17 @@ package api import ( "github.com/Mrs4s/go-cqhttp/coolq" "github.com/Mrs4s/go-cqhttp/global" + "github.com/Mrs4s/go-cqhttp/internal/onebot" ) -func (c *Caller) call(action string, version uint16, p Getter) global.MSG { - var converter coolq.IDConverter = func(id any) any { - return coolq.ConvertIDWithVersion(id, version) - } - if version == 12 { +func (c *Caller) call(action string, spec *onebot.Spec, p Getter) global.MSG { + if spec.Version == 12 { switch action { case "get_self_info": return c.bot.CQGetLoginInfo() case "get_user_info": p0 := p.Get("user_id").Int() return c.bot.CQGetStrangerInfo(p0) - case "get_supported_actions": - return c.bot.CQGetSupportedActions() case "get_version": return c.bot.CQGetVersion() case "send_message": @@ -30,8 +26,12 @@ func (c *Caller) call(action string, version uint16, p Getter) global.MSG { return c.bot.CQSendMessageV12(p0, p1, p2, p3) } } - if version == 11 { + if spec.Version == 11 { switch action { + case ".handle_quick_operation": + p0 := p.Get("context") + p1 := p.Get("operation") + return c.bot.CQHandleQuickOperation(p0, p1) case "can_send_image": return c.bot.CQCanSendImage() case "can_send_record": @@ -81,10 +81,6 @@ func (c *Caller) call(action string, version uint16, p Getter) global.MSG { case ".get_word_slices": p0 := p.Get("content").String() return c.bot.CQGetWordSlices(p0) - case ".handle_quick_operation": - p0 := p.Get("context") - p1 := p.Get("operation") - return c.bot.CQHandleQuickOperation(p0, p1) case ".ocr_image", "ocr_image": p0 := p.Get("image").String() return c.bot.CQOcrImage(p0) @@ -159,7 +155,7 @@ func (c *Caller) call(action string, version uint16, p Getter) global.MSG { p0 := p.Get("[message_id,id].0").String() return c.bot.CQGetForwardMessage(p0) case "get_friend_list": - return c.bot.CQGetFriendList(version) + return c.bot.CQGetFriendList(spec) case "get_group_at_all_remain": p0 := p.Get("group_id").Int() return c.bot.CQGetAtAllRemain(p0) @@ -182,10 +178,10 @@ func (c *Caller) call(action string, version uint16, p Getter) global.MSG { case "get_group_info": p0 := p.Get("group_id").Int() p1 := p.Get("no_cache").Bool() - return c.bot.CQGetGroupInfo(p0, p1, converter) + return c.bot.CQGetGroupInfo(p0, p1, spec) case "get_group_list": p0 := p.Get("no_cache").Bool() - return c.bot.CQGetGroupList(p0, converter) + return c.bot.CQGetGroupList(p0, spec) case "get_group_member_info": p0 := p.Get("group_id").Int() p1 := p.Get("user_id").Int() @@ -240,7 +236,9 @@ func (c *Caller) call(action string, version uint16, p Getter) global.MSG { p0 := p.Get("no_cache").Bool() return c.bot.CQGetOnlineClients(p0) case "get_status": - return c.bot.CQGetStatus(version) + return c.bot.CQGetStatus(spec) + case "get_supported_actions": + return c.bot.CQGetSupportedActions(spec) case "get_topic_channel_feeds": p0 := p.Get("guild_id").Uint() p1 := p.Get("channel_id").Uint() diff --git a/modules/api/caller.go b/modules/api/caller.go index 8a47bd4..4dfeacf 100644 --- a/modules/api/caller.go +++ b/modules/api/caller.go @@ -6,6 +6,7 @@ import ( "github.com/Mrs4s/go-cqhttp/coolq" "github.com/Mrs4s/go-cqhttp/global" + "github.com/Mrs4s/go-cqhttp/internal/onebot" ) //go:generate go run github.com/Mrs4s/go-cqhttp/cmd/api-generator -pkg api -path=./../../coolq/api.go,./../../coolq/api_v12.go -o api.go @@ -25,13 +26,13 @@ type Caller struct { } // Call specific API -func (c *Caller) Call(action string, version uint16, p Getter) global.MSG { +func (c *Caller) Call(action string, spec *onebot.Spec, p Getter) global.MSG { for _, fn := range c.handlers { if ret := fn(action, p); ret != nil { return ret } } - return c.call(action, version, p) + return c.call(action, spec, p) } // Use add handlers to the API caller diff --git a/server/http.go b/server/http.go index 9766130..98c59e3 100644 --- a/server/http.go +++ b/server/http.go @@ -26,6 +26,7 @@ import ( "github.com/Mrs4s/go-cqhttp/coolq" "github.com/Mrs4s/go-cqhttp/global" + "github.com/Mrs4s/go-cqhttp/internal/onebot" "github.com/Mrs4s/go-cqhttp/modules/api" "github.com/Mrs4s/go-cqhttp/modules/config" "github.com/Mrs4s/go-cqhttp/modules/filter" @@ -58,7 +59,7 @@ type httpServerPost struct { type httpServer struct { api *api.Caller accessToken string - version uint16 + spec *onebot.Spec // onebot spec } // HTTPClient 反向HTTP上报客户端 @@ -158,7 +159,7 @@ func (s *httpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request switch request.Method { case http.MethodPost: // todo: msg pack - if s.version == 12 && strings.Contains(contentType, "application/msgpack") { + if s.spec.Version == 12 && strings.Contains(contentType, "application/msgpack") { log.Warnf("请求 %v 数据类型暂不支持: MsgPack", request.RequestURI) writer.WriteHeader(http.StatusUnsupportedMediaType) return @@ -204,12 +205,12 @@ func (s *httpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request if request.URL.Path == "/" { action := strings.TrimSuffix(ctx.Get("action").Str, "_async") log.Debugf("HTTPServer接收到API调用: %v", action) - response = s.api.Call(action, s.version, ctx.Get("params")) + response = s.api.Call(action, s.spec, ctx.Get("params")) } else { action := strings.TrimPrefix(request.URL.Path, "/") action = strings.TrimSuffix(action, "_async") log.Debugf("HTTPServer接收到API调用: %v", action) - response = s.api.Call(action, s.version, &ctx) + response = s.api.Call(action, s.spec, &ctx) } writer.Header().Set("Content-Type", "application/json; charset=utf-8") @@ -259,11 +260,15 @@ func runHTTP(bot *coolq.CQBot, node yaml.Node) { case conf.Disabled: return } - if conf.Version != 11 && conf.Version != 12 { - conf.Version = 11 - } network, addr := "tcp", conf.Address - s := &httpServer{accessToken: conf.AccessToken, version: conf.Version} + s := &httpServer{accessToken: conf.AccessToken} + switch conf.Version { + default: + // default v11 + s.spec = onebot.V11 + case 12: + s.spec = onebot.V12 + } switch { case conf.Address != "": uri, err := url.Parse(conf.Address) diff --git a/server/websocket.go b/server/websocket.go index 71d68bb..f5ef674 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -22,6 +22,7 @@ import ( "github.com/Mrs4s/go-cqhttp/coolq" "github.com/Mrs4s/go-cqhttp/global" + "github.com/Mrs4s/go-cqhttp/internal/onebot" "github.com/Mrs4s/go-cqhttp/modules/api" "github.com/Mrs4s/go-cqhttp/modules/config" "github.com/Mrs4s/go-cqhttp/modules/filter" @@ -476,7 +477,7 @@ func (c *wsConn) handleRequest(_ *coolq.CQBot, payload []byte) { t := strings.TrimSuffix(j.Get("action").Str, "_async") params := j.Get("params") log.Debugf("WS接收到API调用: %v 参数: %v", t, params.Raw) - ret := c.apiCaller.Call(t, 11, params) + ret := c.apiCaller.Call(t, onebot.V11, params) if j.Get("echo").Exists() { ret["echo"] = j.Get("echo").Value() }