From a6ebe5722bc90f7c34a253fc479415a91bda3bf2 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sat, 29 Jun 2024 22:15:21 +0800 Subject: [PATCH 01/36] beta447 --- idmap/service.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/idmap/service.go b/idmap/service.go index 090b9382..53167f7d 100644 --- a/idmap/service.go +++ b/idmap/service.go @@ -113,7 +113,7 @@ func CleanBucket(bucketName string) { return fmt.Errorf("bucket %s not found", bucketName) } - // 使用游标遍历bucket + // 使用游标遍历bucket 正向键 k:v 32位openid:大宽int64 64位msgid:大宽int6 c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { // 检查键或值是否包含冒号 @@ -121,7 +121,7 @@ func CleanBucket(bucketName string) { continue // 忽略包含冒号的键值对 } - // 检查值id的长度 + // 检查值id的长度 这里是正向键 id := string(k) if len(id) != 32 { if err := c.Delete(); err != nil { @@ -131,14 +131,14 @@ func CleanBucket(bucketName string) { } } - // 再次遍历处理reverseKey的情况 + // 再次遍历处理reverseKey的情况 反向键 row-整数:string 32位openid/64位msgid for k, v := c.First(); k != nil; k, v = c.Next() { if strings.HasPrefix(string(k), "row-") { if bytes.Contains(k, []byte(":")) || bytes.Contains(v, []byte(":")) { continue // 忽略包含冒号的键值对 } - - id := string(b.Get(k)) + // 这里检查反向键是否是32位 + id := string(v) if len(id) != 32 { if err := b.Delete(k); err != nil { return err From 1d63faee49470d5c3e46efa92d5361ec9280fc28 Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 1 Jul 2024 22:02:27 +0800 Subject: [PATCH 02/36] beta448 --- idmap/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idmap/service.go b/idmap/service.go index 53167f7d..31c1fb48 100644 --- a/idmap/service.go +++ b/idmap/service.go @@ -117,7 +117,7 @@ func CleanBucket(bucketName string) { c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { // 检查键或值是否包含冒号 - if bytes.Contains(k, []byte(":")) || bytes.Contains(v, []byte(":")) { + if bytes.Contains(k, []byte(":")) || bytes.Contains(v, []byte(":")) || bytes.Contains(k, []byte("row-")) { continue // 忽略包含冒号的键值对 } From cd346278749fc6759658b94337e4510816055a57 Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 4 Jul 2024 14:47:07 +0800 Subject: [PATCH 03/36] beta449 --- config/config.go | 12 ++++++ handlers/avatar.go | 79 +++++++++++++++++++++++++++++++++++++ handlers/get_avatar.go | 5 +++ handlers/message_parser.go | 32 ++++++++++++--- structs/structs.go | 5 ++- template/config_template.go | 1 + 6 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 handlers/avatar.go diff --git a/config/config.go b/config/config.go index 887598e8..d6739645 100644 --- a/config/config.go +++ b/config/config.go @@ -2340,3 +2340,15 @@ func GetLinkNum() int { return instance.Settings.LinkNum } + +// 获取GetDoNotReplaceAppid的值 +func GetDoNotReplaceAppid() bool { + mu.Lock() + defer mu.Unlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to DoNotReplaceAppid value.") + return false + } + return instance.Settings.DoNotReplaceAppid +} diff --git a/handlers/avatar.go b/handlers/avatar.go new file mode 100644 index 00000000..508a402d --- /dev/null +++ b/handlers/avatar.go @@ -0,0 +1,79 @@ +package handlers + +import ( + "fmt" + "regexp" + + "github.com/hoshinonyaruko/gensokyo/config" + "github.com/hoshinonyaruko/gensokyo/idmap" + "github.com/hoshinonyaruko/gensokyo/mylog" +) + +func ProcessCQAvatar(groupID string, text string) string { + // 断言并获取 groupID 和 qq 号 + qqRegex := regexp.MustCompile(`\[CQ:avatar,qq=(\d+)\]`) + qqMatches := qqRegex.FindAllStringSubmatch(text, -1) + + for _, match := range qqMatches { + qqStr := match[1] // 提取 qq 号 + + var originalUserID string + var err error + if config.GetIdmapPro() { + // 如果UserID不是nil且配置为使用Pro版本,则调用RetrieveRowByIDv2Pro + _, originalUserID, err = idmap.RetrieveRowByIDv2Pro(groupID, qqStr) + if err != nil { + mylog.Printf("Error1 retrieving original GroupID: %v", err) + _, originalUserID, err = idmap.RetrieveRowByIDv2Pro("690426430", qqStr) + if err != nil { + mylog.Printf("Error reading private originalUserID: %v", err) + } + } + } else { + originalUserID, err = idmap.RetrieveRowByIDv2(qqStr) + if err != nil { + mylog.Printf("Error retrieving original UserID: %v", err) + } + } + + // 生成头像URL + avatarURL, _ := GenerateAvatarURLV2(originalUserID) + + // 替换文本中的 [CQ:avatar,qq=12345678] 为 [CQ:image,file=avatarurl] + replacement := fmt.Sprintf("[CQ:image,file=%s]", avatarURL) + text = qqRegex.ReplaceAllString(text, replacement) + } + + return text +} + +func GetAvatarCQCode(groupID, qqNumber string) (string, error) { + var originalUserID string + var err error + + if config.GetIdmapPro() { + // 如果配置为使用Pro版本,则调用RetrieveRowByIDv2Pro + _, originalUserID, err = idmap.RetrieveRowByIDv2Pro(groupID, qqNumber) + if err != nil { + mylog.Printf("Error retrieving original GroupID: %v", err) + return "", err + } + } else { + // 否则调用RetrieveRowByIDv2 + originalUserID, err = idmap.RetrieveRowByIDv2(qqNumber) + if err != nil { + mylog.Printf("Error retrieving original UserID: %v", err) + return "", err + } + } + + // 生成头像URL + avatarURL, err := GenerateAvatarURLV2(originalUserID) + if err != nil { + mylog.Printf("Error generating avatar URL: %v", err) + return "", err + } + + // 返回格式化后的字符串 + return fmt.Sprintf("[CQ:image,file=%s]", avatarURL), nil +} diff --git a/handlers/get_avatar.go b/handlers/get_avatar.go index edfabfaf..95360515 100644 --- a/handlers/get_avatar.go +++ b/handlers/get_avatar.go @@ -3,6 +3,7 @@ package handlers import ( "encoding/json" "fmt" + "strconv" "github.com/hoshinonyaruko/gensokyo/callapi" "github.com/hoshinonyaruko/gensokyo/config" @@ -15,6 +16,7 @@ type GetAvatarResponse struct { Message string `json:"message"` RetCode int `json:"retcode"` Echo interface{} `json:"echo"` + UserID int64 `json:"user_id"` } func init() { @@ -46,9 +48,12 @@ func GetAvatar(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.OpenAPI avatarurl, _ := GenerateAvatarURLV2(originalUserID) + useridstr := message.Params.UserID.(string) + response.Message = avatarurl response.RetCode = 0 response.Echo = message.Echo + response.UserID, _ = strconv.ParseInt(useridstr, 10, 64) outputMap := structToMap(response) diff --git a/handlers/message_parser.go b/handlers/message_parser.go index 9948a873..3c621dc2 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -416,6 +416,8 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac if config.GetEnableChangeWord() { messageText = acnode.CheckWordOUT(messageText) } + // 解析[CQ:avatar,qq=123456] + messageText = ProcessCQAvatar(paramsMessage.GroupID.(string), messageText) case []interface{}: //多个映射组成的切片 mylog.Printf("params.message is a slice (segment_type_koishi)\n") @@ -450,6 +452,9 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac case "at": qqNumber, _ := segmentMap["data"].(map[string]interface{})["qq"].(string) segmentContent = "[CQ:at,qq=" + qqNumber + "]" + case "avatar": + qqNumber, _ := segmentMap["data"].(map[string]interface{})["qq"].(string) + segmentContent, _ = GetAvatarCQCode(paramsMessage.GroupID.(string), qqNumber) case "markdown": mdContent, ok := segmentMap["data"].(map[string]interface{})["data"] if ok { @@ -518,6 +523,9 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac case "at": qqNumber, _ := message["data"].(map[string]interface{})["qq"].(string) messageText = "[CQ:at,qq=" + qqNumber + "]" + case "avatar": + qqNumber, _ := message["data"].(map[string]interface{})["qq"].(string) + messageText, _ = GetAvatarCQCode(paramsMessage.GroupID.(string), qqNumber) case "markdown": mdContent, ok := message["data"].(map[string]interface{})["data"] if ok { @@ -563,8 +571,9 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac default: mylog.Println("Unsupported message format: params.message field is not a string, map or slice") } + //处理at - messageText = transformMessageTextAt(messageText) + messageText = transformMessageTextAt(messageText, paramsMessage.GroupID.(string)) //mylog.Printf(messageText) @@ -635,9 +644,12 @@ func isIPAddress(address string) bool { } // at处理 -func transformMessageTextAt(messageText string) string { - // 首先,将AppID替换为BotID - messageText = strings.ReplaceAll(messageText, AppID, BotID) +func transformMessageTextAt(messageText string, groupid string) string { + // DoNotReplaceAppid=false(默认频道bot,需要自己at自己时,否则改成true) + if !config.GetDoNotReplaceAppid() { + // 首先,将AppID替换为BotID + messageText = strings.ReplaceAll(messageText, AppID, BotID) + } // 去除所有[CQ:reply,id=数字] todo 更好的处理办法 replyRE := regexp.MustCompile(`\[CQ:reply,id=\d+\]`) @@ -648,7 +660,13 @@ func transformMessageTextAt(messageText string) string { messageText = re.ReplaceAllStringFunc(messageText, func(m string) string { submatches := re.FindStringSubmatch(m) if len(submatches) > 1 { - realUserID, err := idmap.RetrieveRowByIDv2(submatches[1]) + var realUserID string + var err error + if config.GetIdmapPro() { + _, realUserID, err = idmap.RetrieveRowByIDv2Pro(groupid, submatches[1]) + } else { + realUserID, err = idmap.RetrieveRowByIDv2(submatches[1]) + } if err != nil { // 如果出错,也替换成相应的格式,但使用原始QQ号 mylog.Printf("Error retrieving user ID: %v", err) @@ -758,7 +776,7 @@ func RevertTransformedText(data interface{}, msgtype string, api openapi.OpenAPI //处理前 先去前后空 messageText = strings.TrimSpace(msg.Content) } - var originmessageText = messageText + //mylog.Printf("1[%v]", messageText) // 将messageText里的BotID替换成AppID @@ -802,6 +820,8 @@ func RevertTransformedText(data interface{}, msgtype string, api openapi.OpenAPI messageText = strings.TrimSpace(messageText) } } + + var originmessageText = messageText //mylog.Printf("2[%v]", messageText) // 检查是否需要移除前缀 diff --git a/structs/structs.go b/structs/structs.go index c524b209..624961c5 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -141,8 +141,9 @@ type Settings struct { EnableChangeWord bool `yaml:"enableChangeWord"` DefaultChangeWord string `yaml:"defaultChangeWord"` //错误临时修复类 - Fix11300 bool `yaml:"fix_11300"` - HttpOnlyBot bool `yaml:"http_only_bot"` + Fix11300 bool `yaml:"fix_11300"` + HttpOnlyBot bool `yaml:"http_only_bot"` + DoNotReplaceAppid bool `yaml:"do_not_replace_appid"` //内置指令 BindPrefix string `yaml:"bind_prefix"` MePrefix string `yaml:"me_prefix"` diff --git a/template/config_template.go b/template/config_template.go index a377af81..e1fdd9d0 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -184,6 +184,7 @@ settings: #错误临时修复类 fix_11300: false #修复11300报错,需要在develop_bot_id填入自己机器人的appid. 11300原因暂时未知,临时修复方案. http_only_bot : false #这个配置项会自动配置,请不要修改,保持false. + do_not_replace_appid : false #在频道内机器人尝试at自己回at不到,保持false.群内机器人有发送用户头像url的需求时,true(因为用户头像url包含了appid,如果false就会出错.) #内置指令类 bind_prefix : "/bind" #需设置 #增强配置项 master_id 可触发 From b790b29ec0acb0f1af93ce9f2272356912ee97c7 Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 4 Jul 2024 16:51:02 +0800 Subject: [PATCH 04/36] beta450 --- handlers/avatar.go | 71 +++++++++++++++++++++++++++++++++++++- handlers/message_parser.go | 21 ++++++++--- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/handlers/avatar.go b/handlers/avatar.go index 508a402d..dff391ad 100644 --- a/handlers/avatar.go +++ b/handlers/avatar.go @@ -27,6 +27,7 @@ func ProcessCQAvatar(groupID string, text string) string { _, originalUserID, err = idmap.RetrieveRowByIDv2Pro("690426430", qqStr) if err != nil { mylog.Printf("Error reading private originalUserID: %v", err) + return "" } } } else { @@ -47,6 +48,70 @@ func ProcessCQAvatar(groupID string, text string) string { return text } +func ProcessCQAvatarNoGroupID(text string) string { + // 断言并获取 groupID 和 qq 号 + qqRegex := regexp.MustCompile(`\[CQ:avatar,qq=(\d+)\]`) + qqMatches := qqRegex.FindAllStringSubmatch(text, -1) + + for _, match := range qqMatches { + qqStr := match[1] // 提取 qq 号 + + var originalUserID string + var err error + if config.GetIdmapPro() { + _, originalUserID, err = idmap.RetrieveRowByIDv2Pro("690426430", qqStr) + if err != nil { + mylog.Printf("Error reading private originalUserID: %v", err) + } + } else { + originalUserID, err = idmap.RetrieveRowByIDv2(qqStr) + if err != nil { + mylog.Printf("Error retrieving original UserID: %v", err) + } + } + + // 生成头像URL + avatarURL, _ := GenerateAvatarURLV2(originalUserID) + + // 替换文本中的 [CQ:avatar,qq=12345678] 为 [CQ:image,file=avatarurl] + replacement := fmt.Sprintf("[CQ:image,file=%s]", avatarURL) + text = qqRegex.ReplaceAllString(text, replacement) + } + + return text +} + +func GetAvatarCQCodeNoGroupID(qqNumber string) (string, error) { + var originalUserID string + var err error + + if config.GetIdmapPro() { + // 如果配置为使用Pro版本,则调用RetrieveRowByIDv2Pro + _, originalUserID, err = idmap.RetrieveRowByIDv2Pro("690426430", qqNumber) + if err != nil { + mylog.Printf("Error reading private originalUserID: %v", err) + return "", err + } + } else { + // 否则调用RetrieveRowByIDv2 + originalUserID, err = idmap.RetrieveRowByIDv2(qqNumber) + if err != nil { + mylog.Printf("Error retrieving original UserID: %v", err) + return "", err + } + } + + // 生成头像URL + avatarURL, err := GenerateAvatarURLV2(originalUserID) + if err != nil { + mylog.Printf("Error generating avatar URL: %v", err) + return "", err + } + + // 返回格式化后的字符串 + return fmt.Sprintf("[CQ:image,file=%s]", avatarURL), nil +} + func GetAvatarCQCode(groupID, qqNumber string) (string, error) { var originalUserID string var err error @@ -56,7 +121,11 @@ func GetAvatarCQCode(groupID, qqNumber string) (string, error) { _, originalUserID, err = idmap.RetrieveRowByIDv2Pro(groupID, qqNumber) if err != nil { mylog.Printf("Error retrieving original GroupID: %v", err) - return "", err + _, originalUserID, err = idmap.RetrieveRowByIDv2Pro("690426430", qqNumber) + if err != nil { + mylog.Printf("Error reading private originalUserID: %v", err) + return "", err + } } } else { // 否则调用RetrieveRowByIDv2 diff --git a/handlers/message_parser.go b/handlers/message_parser.go index 3c621dc2..1254dc8c 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -416,8 +416,13 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac if config.GetEnableChangeWord() { messageText = acnode.CheckWordOUT(messageText) } - // 解析[CQ:avatar,qq=123456] - messageText = ProcessCQAvatar(paramsMessage.GroupID.(string), messageText) + if paramsMessage.GroupID == nil { + // 解析[CQ:avatar,qq=123456] + messageText = ProcessCQAvatarNoGroupID(messageText) + } else { + // 解析[CQ:avatar,qq=123456] + messageText = ProcessCQAvatar(paramsMessage.GroupID.(string), messageText) + } case []interface{}: //多个映射组成的切片 mylog.Printf("params.message is a slice (segment_type_koishi)\n") @@ -454,7 +459,11 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac segmentContent = "[CQ:at,qq=" + qqNumber + "]" case "avatar": qqNumber, _ := segmentMap["data"].(map[string]interface{})["qq"].(string) - segmentContent, _ = GetAvatarCQCode(paramsMessage.GroupID.(string), qqNumber) + if paramsMessage.GroupID == nil { + segmentContent, _ = GetAvatarCQCodeNoGroupID(qqNumber) + } else { + segmentContent, _ = GetAvatarCQCode(paramsMessage.GroupID.(string), qqNumber) + } case "markdown": mdContent, ok := segmentMap["data"].(map[string]interface{})["data"] if ok { @@ -525,7 +534,11 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac messageText = "[CQ:at,qq=" + qqNumber + "]" case "avatar": qqNumber, _ := message["data"].(map[string]interface{})["qq"].(string) - messageText, _ = GetAvatarCQCode(paramsMessage.GroupID.(string), qqNumber) + if paramsMessage.GroupID == nil { + messageText, _ = GetAvatarCQCodeNoGroupID(qqNumber) + } else { + messageText, _ = GetAvatarCQCode(paramsMessage.GroupID.(string), qqNumber) + } case "markdown": mdContent, ok := message["data"].(map[string]interface{})["data"] if ok { From 7a9b56a5bab382951fef7c823e68b77e64d40cbe Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 4 Jul 2024 16:57:20 +0800 Subject: [PATCH 05/36] beta451 --- template/config_template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/config_template.go b/template/config_template.go index e1fdd9d0..4827a82d 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -42,7 +42,7 @@ settings: global_group_msg_rre_to_message : false # 是否将用户开关机器人资料页的机器人推送开关 产生的事件转换为文本信息并发送给应用端.false将使用onebotv11的notice类型上报. global_group_msg_reject_message : "机器人主动消息被关闭" # 当开启 global_group_msg_rre_to_message 时,机器人主动信息被关闭将上报的信息. 自行添加intent - GroupMsgRejectHandler global_group_msg_receive_message : "机器人主动消息被开启" # 建议设置为无规则复杂随机内容,避免用户指令内容碰撞. 自行添加 intent - GroupMsgReceiveHandler - hash_id : false # 使用hash来进行idmaps转换,可以让user_id不是123开始的递增值 + hash_id : true # 使用hash来进行idmaps转换,可以让user_id不是123开始的递增值 idmap_pro : false # 需开启hash_id配合,高级id转换增强,可以多个真实值bind到同一个虚拟值,对于每个用户,每个群\私聊\判断私聊\频道,都会产生新的虚拟值,但可以多次bind,bind到同一个数字.数据库负担会变大. #Gensokyo互联类 From e17d0d4ce838fc8a779309fa01e364618d87f680 Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 4 Jul 2024 18:40:56 +0800 Subject: [PATCH 06/36] beta452 --- ...7\260&\345\220\257\345\212\250gensokyo.md" | 0 handlers/message_parser.go | 52 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 "docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" diff --git "a/docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" "b/docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" new file mode 100644 index 00000000..e69de29b diff --git a/handlers/message_parser.go b/handlers/message_parser.go index 1254dc8c..0416a76c 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -585,8 +585,13 @@ func parseMessageContent(paramsMessage callapi.ParamsContent, message callapi.Ac mylog.Println("Unsupported message format: params.message field is not a string, map or slice") } - //处理at - messageText = transformMessageTextAt(messageText, paramsMessage.GroupID.(string)) + if paramsMessage.GroupID == nil { + //处理at + messageText = transformMessageTextAtNoGroupID(messageText) + } else { + //处理at + messageText = transformMessageTextAt(messageText, paramsMessage.GroupID.(string)) + } //mylog.Printf(messageText) @@ -698,6 +703,49 @@ func transformMessageTextAt(messageText string, groupid string) string { return messageText } +// at处理 +func transformMessageTextAtNoGroupID(messageText string) string { + // DoNotReplaceAppid=false(默认频道bot,需要自己at自己时,否则改成true) + if !config.GetDoNotReplaceAppid() { + // 首先,将AppID替换为BotID + messageText = strings.ReplaceAll(messageText, AppID, BotID) + } + + // 去除所有[CQ:reply,id=数字] todo 更好的处理办法 + replyRE := regexp.MustCompile(`\[CQ:reply,id=\d+\]`) + messageText = replyRE.ReplaceAllString(messageText, "") + + // 使用正则表达式来查找所有[CQ:at,qq=数字]的模式 + re := regexp.MustCompile(`\[CQ:at,qq=(\d+)\]`) + messageText = re.ReplaceAllStringFunc(messageText, func(m string) string { + submatches := re.FindStringSubmatch(m) + if len(submatches) > 1 { + var realUserID string + var err error + if config.GetIdmapPro() { + // 这是个魔法数 代表私聊 + _, realUserID, err = idmap.RetrieveRowByIDv2Pro("690426430", submatches[1]) + } else { + realUserID, err = idmap.RetrieveRowByIDv2(submatches[1]) + } + if err != nil { + // 如果出错,也替换成相应的格式,但使用原始QQ号 + mylog.Printf("Error retrieving user ID: %v", err) + return "<@!" + submatches[1] + ">" + } + + // 在这里检查 GetRemoveBotAtGroup 和 realUserID 的长度 + if config.GetRemoveBotAtGroup() && len(realUserID) == 32 { + return "" + } + + return "<@!" + realUserID + ">" + } + return m + }) + return messageText +} + // 链接处理 func transformMessageTextUrl(messageText string, message callapi.ActionMessage, client callapi.Client, api openapi.OpenAPI, apiv2 openapi.OpenAPI) string { // 是否处理url From 13181759dbe85cad3f5a6acde0b2698d323aab55 Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 4 Jul 2024 19:31:22 +0800 Subject: [PATCH 07/36] beta453 --- "docs/api\344\273\213\347\273\215.md" | 40 +++++ ...api\345\267\256\345\274\202-delete_msg.md" | 17 ++ ...7\346\241\243-markdown message segment.md" | 54 ++++++ ...1\243-markdown\345\256\232\344\271\211.md" | 167 ++++++++++++++++++ ...64\345\244\232\346\226\207\346\241\243.md" | 2 + ...7\260&\345\220\257\345\212\250gensokyo.md" | 56 ++++++ ...\351\242\235\345\244\226api-get_avatar.md" | 27 +++ readme.md | 2 + 8 files changed, 365 insertions(+) create mode 100644 "docs/api\344\273\213\347\273\215.md" create mode 100644 "docs/api\345\267\256\345\274\202-delete_msg.md" create mode 100644 "docs/\346\226\207\346\241\243-markdown message segment.md" create mode 100644 "docs/\346\226\207\346\241\243-markdown\345\256\232\344\271\211.md" create mode 100644 "docs/\346\233\264\345\244\232\346\226\207\346\241\243.md" create mode 100644 "docs/\351\242\235\345\244\226api-get_avatar.md" diff --git "a/docs/api\344\273\213\347\273\215.md" "b/docs/api\344\273\213\347\273\215.md" new file mode 100644 index 00000000..5f278dca --- /dev/null +++ "b/docs/api\344\273\213\347\273\215.md" @@ -0,0 +1,40 @@ +目前支持的API列表 + +具体api的定义请参考[onebot-11](https://github.com/botuniverse/onebot-11) + +### 支持的API列表 + +1. `/avatar` - avatar.go +2. `/delete_msg` - delete_msg.go +3. `/get_avatar` - get_avatar.go +4. `/get_friend_list` - get_friend_list.go +5. `/get_group_info` - get_group_info.go +6. `/get_group_list` - get_group_list.go +7. `/get_group_member_info` - get_group_member_info.go +8. `/get_group_member_list` - get_group_member_list.go +9. `/get_guild_channel_list` - get_guild_channel_list.go +10. `/get_guild_list` - get_guild_list.go +11. `/get_guild_service_profile` - get_guild_service_profile.go +12. `/get_login_info` - get_login_info.go +13. `/get_online_clients` - get_online_clients.go +14. `/get_status` - get_status.go +15. `/get_version_info` - get_version_info.go +16. `/handle_quick_operation` - handle_quick_operation.go +17. `/handle_quick_operation_async` - handle_quick_operation_async.go +18. `/mark_msg_as_read` - mark_msg_as_read.go +19. `/message_parser` - message_parser.go +20. `/put_interaction` - put_interaction.go +21. `/send_group_forward_msg` - send_group_forward_msg.go +22. `/send_group_msg` - send_group_msg.go +23. `/send_group_msg_async` - send_group_msg_async.go +24. `/send_group_msg_raw` - send_group_msg_raw.go +25. `/send_guild_channel_forum` - send_guild_channel_forum.go +26. `/send_guild_channel_msg` - send_guild_channel_msg.go +27. `/send_guild_private_msg` - send_guild_private_msg.go +28. `/send_msg` - send_msg.go +29. `/send_msg_async` - send_msg_async.go +30. `/send_private_msg` - send_private_msg.go +31. `/send_private_msg_async` - send_private_msg_async.go +32. `/send_private_msg_sse` - send_private_msg_sse.go +33. `/set_group_ban` - set_group_ban.go +34. `/set_group_whole_ban` - set_group_whole_ban.go \ No newline at end of file diff --git "a/docs/api\345\267\256\345\274\202-delete_msg.md" "b/docs/api\345\267\256\345\274\202-delete_msg.md" new file mode 100644 index 00000000..2bd6cd81 --- /dev/null +++ "b/docs/api\345\267\256\345\274\202-delete_msg.md" @@ -0,0 +1,17 @@ +# API: delete_msg + +撤回消息。 + +## 参数 + +| 字段名 | 数据类型 | 默认值 | 说明 | +|-------------|----------------|--------|-----------------------------------| +| message_id | number (int32) | - | 消息 ID | +| user_id | number | - | 对方 QQ 号(消息类型为 private 时需要) | +| group_id | number | - | 群号(消息类型为 group 时需要) | +| channel_id | number | - | 频道号(消息类型是 guild 时需要) | +| guild_id | number | - | 子频道号(消息类型是 guild_Private 时需要) | + +## 响应数据 + +无 \ No newline at end of file diff --git "a/docs/\346\226\207\346\241\243-markdown message segment.md" "b/docs/\346\226\207\346\241\243-markdown message segment.md" new file mode 100644 index 00000000..d03a2495 --- /dev/null +++ "b/docs/\346\226\207\346\241\243-markdown message segment.md" @@ -0,0 +1,54 @@ +```markdown +# Gensokyo Markdown Segment + +Gensokyo的Markdown Segment是对现有OneBot v11的扩展。 + +## Markdown卡片(文本形式) + +```json +{ + "type": "markdown", + "data": { + "data": "文本内容" + } +} +``` + +| 参数名 | 收 | 发 | 可能的值 | 说明 | +|----------|----|----|----------|-------------| +| data | ✓ | ✓ | - | md文本 | + +**文本内容为**: +- [链接](https://www.yuque.com/km57bt/hlhnxg/ddkv4a2lgcswitei) 中markdown的json字符串的base64(以base64://开头,文字处理为/u形式的unicode)或按以下规则处理后的,json实体化文本。 + +**转义**: +CQ 码由字符 [ 起始, 以 ] 结束, 并且以 , 分割各个参数。如果你的 CQ 码中, 参数值包括了这些字符, 那么它们应该被使用 HTML 特殊字符的编码方式进行转义。 + +字符 | 对应实体转义序列 +-----|------------------ +& | & +[ | [ +] | ] +, | , + +## Markdown卡片(object形式) + +```json +{ + "type": "markdown", + "data": { + "data": md object + } +} +``` + +| 参数名 | 收 | 发 | 可能的值 | 说明 | +|----------|----|----|----------|-------------| +| data | ✓ | ✓ | - | md object | + +**结构请参考**: +支持MessageSegment [链接](https://www.yuque.com/km57bt/hlhnxg/ddkv4a2lgcswitei) 与文本形式实际包含内容相同,但传参类型不同,不是string,而是你所组合的md卡片object(map)。 + +data下层应包含data(2层data),data.markdown,data.keyboard。 +同时与type同级的data字段是OneBot v11标准固定的,所以json结构会呈现data.data.markdown,data.data.keyboard双层结构。 +``` \ No newline at end of file diff --git "a/docs/\346\226\207\346\241\243-markdown\345\256\232\344\271\211.md" "b/docs/\346\226\207\346\241\243-markdown\345\256\232\344\271\211.md" new file mode 100644 index 00000000..c5eb6909 --- /dev/null +++ "b/docs/\346\226\207\346\241\243-markdown\345\256\232\344\271\211.md" @@ -0,0 +1,167 @@ +```markdown +## md cq码/segment格式 + +### CQ码格式 + +```markdown +[CQ:markdown,data=xxx] +``` + +推荐使用模板:[链接到模板](https://github.com/hoshinonyaruko/gensokyo-qqmd) + +- `data,xxx` 是经过base64编码的JSON数据,支持与其他CQ码拼接,可以组合成message segment形式。 + +官方文档:[开发者文档](https://bot.q.qq.com/wiki/develop) + +新文档:[API v2文档](https://bot.q.qq.com/wiki/develop/api-v2/) + +### 自定义md格式 + +```json +{ + "markdown": { + "content": "你好" + }, + "keyboard": { + "content": { + "rows": [ + { + "buttons": [ + { + "render_data": { + "label": "再来一张", + "visited_label": "正在绘图", + "style": 1 + }, + "action": { + "type": 2, + "permission": { + "type": 2, + "specify_role_ids": [ + "1", + "2", + "3" + ] + }, + "click_limit": 10, + "unsupport_tips": "编辑-兼容文本", + "data": "你好", + "at_bot_show_channel_list": false + } + } + ] + } + ] + } + }, + "msg_id": "123", + "timestamp": "123", + "msg_type": 2 +} +``` + +### 模板md格式 + +```json +{ + "markdown": { + "custom_template_id": "101993071_1658748972", + "params": [ + { + "key": "text", + "values": ["标题"] + }, + { + "key": "image", + "values": [ + "https://resource5-1255303497.cos.ap-guangzhou.myqcloud.com/abcmouse_word_watch/other/mkd_img.png" + ] + } + ] + }, + "keyboard": { + "content": { + "rows": [ + { + "buttons": [ + { + "render_data": { + "label": "再来一次", + "visited_label": "再来一次" + }, + "action": { + "type": 1, + "permission": { + "type": 1, + "specify_role_ids": [ + "1", + "2", + "3" + ] + }, + "click_limit": 10, + "unsupport_tips": "兼容文本", + "data": "data", + "at_bot_show_channel_list": true + } + } + ] + } + ] + } + } +} +``` + +### 按钮格式 + +```json +{ + "keyboard": { + "id": 1, + "rows": [ + { + "buttons": [ + { + "render_data": { + "label": "再来一次", + "visited_label": "再来一次" + }, + "action": { + "type": 1, + "permission": { + "type": 1, + "specify_role_ids": [ + "1", + "2", + "3" + ] + }, + "click_limit": 10, + "unsupport_tips": "兼容文本", + "data": "data", + "at_bot_show_channel_list": true + } + } + ] + } + ] + } +} +``` + +### 图文混排格式 + +```markdown +{{.text}}![{{.image_info}}]({{.image_url}}) +``` + +![{{.image_info}}]({{.image_url}}){{.text}} + +注意:在`{{}}`中不可以使用`![]()`这种Markdown格式的关键字。 + +![text #208px #320px](https://xxxxx.png) +``` + +详细文档请参考:[发消息含有消息按钮组件的消息](https://bot.q.qq.com/wiki/develop/api/openapi/message/post_keyboard_messages.html#%E5%8F%91%E9%80%81%E5%90%AB%E6%9C%89%E6%B6%88%E6%81%AF%E6%8C%89%E9%92%AE%E7%BB%84%E4%BB%B6%E7%9A%84%E6%B6%88%E6%81%AF) +``` \ No newline at end of file diff --git "a/docs/\346\233\264\345\244\232\346\226\207\346\241\243.md" "b/docs/\346\233\264\345\244\232\346\226\207\346\241\243.md" new file mode 100644 index 00000000..e149a183 --- /dev/null +++ "b/docs/\346\233\264\345\244\232\346\226\207\346\241\243.md" @@ -0,0 +1,2 @@ +文档陆续迁移中,更多文档可查看 +[yuque](https://www.yuque.com/km57bt/hlhnxg/mw7gm8dlpccd324e) \ No newline at end of file diff --git "a/docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" "b/docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" index e69de29b..edb128de 100644 --- "a/docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" +++ "b/docs/\350\265\267\346\255\245-\346\263\250\345\206\214QQ\345\274\200\346\224\276\345\271\263\345\217\260&\345\220\257\345\212\250gensokyo.md" @@ -0,0 +1,56 @@ +```markdown +# 创建QQ机器人并配置 + +首先,您需要在 [QQ开放平台](https://q.qq.com/qqbot/) 注册一个开发者账号,确保使用您的大号QQ进行注册,而非小号。 + +## 注册步骤 + +1. 登录 QQ 开放平台,使用大号QQ注册账号。 +2. 注册完成后,进入开发者控制台。 + +## 创建机器人 + +根据 [图文版教程](https://www.yuque.com/km57bt/hlhnxg/hoxlh53gg11h7r3l) 中的指导操作,创建您的机器人,并进行必要的配置。 + +## 设置Intent + +根据您的频道类型选择合适的Intent设置: + +### 私域频道 + +```yaml +text_intent: + - DirectMessageHandler + - CreateMessageHandler + - InteractionHandler + - GroupATMessageEventHandler + - C2CMessageEventHandler + - GroupMsgRejectHandler + - GroupMsgReceiveHandler + - GroupAddRobotEventHandler + - GroupDelRobotEventHandler +``` + +### 公域频道 + +```yaml +text_intent: + - DirectMessageHandler + - ATMessageEventHandler + - InteractionHandler + - GroupATMessageEventHandler + - C2CMessageEventHandler + - GroupMsgRejectHandler + - GroupMsgReceiveHandler + - GroupAddRobotEventHandler + - GroupDelRobotEventHandler +``` + +确保按照上述格式将Intent配置正确,这将确保机器人能够正确地处理消息和事件。 + +## 连接nb2和koishi + +完成上述基础配置后,您可以继续学习如何使用nb2和koishi等应用程序来开发您的自定义插件。 + +现在,您已经完成了基础配置和必要的设置,可以开始进行进一步的开发和集成了。 +``` \ No newline at end of file diff --git "a/docs/\351\242\235\345\244\226api-get_avatar.md" "b/docs/\351\242\235\345\244\226api-get_avatar.md" new file mode 100644 index 00000000..768ee75e --- /dev/null +++ "b/docs/\351\242\235\345\244\226api-get_avatar.md" @@ -0,0 +1,27 @@ +```markdown +# API: get_avatar + +获取用户头像。 + +## 返回值 + +```go +type GetAvatarResponse struct { + Message string `json:"message"` + RetCode int `json:"retcode"` + Echo interface{} `json:"echo"` + UserID int64 `json:"user_id"` +} +``` + +## 所需字段 + +- **group_id**: 群号(当获取群成员头像时需要) +- **user_id**: 用户 QQ 号(当获取私信头像时需要) + +## CQcode + +CQ头像码格式.支持message segment式传参,将at segment类比修改为avatar即可. +[CQ:avatar,qq=123456] + +``` \ No newline at end of file diff --git a/readme.md b/readme.md index b77013a7..b525998d 100644 --- a/readme.md +++ b/readme.md @@ -50,6 +50,8 @@ _✨ 基于 [OneBot](https://github.com/howmanybots/onebot/blob/master/README.md ## 介绍 gensokyo兼容 [OneBot-v11](https://github.com/botuniverse/onebot-11) ,并在其基础上做了一些扩展,详情请看 OneBot 的文档。 +Gensokyo文档(施工中):[起步](/docs/起步-注册QQ开放平台&启动gensokyo.md) + 可将官方的websocket和api转换至onebotv11标准, 支持连接koishi,nonebot2,trss,zerobot,MiraiCQ,hoshino.. From b7f291c0e52431d165ec2a7ab6db647ab6df33fe Mon Sep 17 00:00:00 2001 From: cosmo Date: Fri, 5 Jul 2024 00:35:34 +0800 Subject: [PATCH 08/36] beta454 --- handlers/send_group_msg.go | 588 +++++++++++++++++++++++++++++++++++ handlers/send_private_msg.go | 2 +- 2 files changed, 589 insertions(+), 1 deletion(-) diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index aff3fed9..014a8bb7 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -1263,6 +1263,594 @@ func generateGroupMessage(id string, eventid string, foundItems map[string][]str return nil } +// 上传富媒体信息 +func generatePrivateMessage(id string, eventid string, foundItems map[string][]string, messageText string, msgseq int, apiv2 openapi.OpenAPI, userid string) interface{} { + if imageURLs, ok := foundItems["local_image"]; ok && len(imageURLs) > 0 { + // 从本地路径读取图片 + imageData, err := os.ReadFile(imageURLs[0]) + if err != nil { + // 读入文件失败 + mylog.Printf("Error reading the image from path %s: %v", imageURLs[0], err) + // 返回文本信息,提示图片文件不存在 + return &dto.MessageToCreate{ + Content: "错误: 图片文件不存在", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + // 首先压缩图片 默认不压缩 + compressedData, err := images.CompressSingleImage(imageData) + if err != nil { + mylog.Printf("Error compressing image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 压缩图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + + // base64编码 + base64Encoded := base64.StdEncoding.EncodeToString(compressedData) + + if config.GetUploadPicV2Base64() { + // 直接上传图片返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessagePrivate(context.TODO(), base64Encoded, eventid, 1, false, "", userid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } + + // 上传base64编码的图片并获取其URL + imageURL, _, _, err := images.UploadBase64ImageToServer(base64Encoded, apiv2) + if err != nil { + mylog.Printf("Error uploading base64 encoded image: %v", err) + // 如果上传失败,也返回文本信息,提示上传失败 + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + + // 创建RichMediaMessage并返回,当作URL图片处理 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 1, // 1代表图片 + URL: imageURL, + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if RecordURLs, ok := foundItems["local_record"]; ok && len(RecordURLs) > 0 { + // 从本地路径读取语音 + RecordData, err := os.ReadFile(RecordURLs[0]) + if err != nil { + // 读入文件失败 + mylog.Printf("Error reading the record from path %s: %v", RecordURLs[0], err) + // 返回文本信息,提示语音文件不存在 + return &dto.MessageToCreate{ + Content: "错误: 语音文件不存在", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + //判断并转码 + if !silk.IsAMRorSILK(RecordData) { + mt, ok := silk.CheckAudio(bytes.NewReader(RecordData)) + if !ok { + mylog.Errorf("voice type error: " + mt) + return nil + } + RecordData = silk.EncoderSilk(RecordData) + mylog.Printf("音频转码ing") + } + + base64Encoded := base64.StdEncoding.EncodeToString(RecordData) + if config.GetUploadPicV2Base64() { + // 直接上传图片返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessagePrivate(context.TODO(), base64Encoded, eventid, 1, false, "", userid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传语音失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } + + // 将解码的语音数据转换回base64格式并上传 + imageURL, err := images.UploadBase64RecordToServer(base64Encoded) + if err != nil { + mylog.Printf("failed to upload base64 record: %v", err) + return nil + } + // 创建RichMediaMessage并返回 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 3, // 3代表语音 + URL: imageURL, + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if imageURLs, ok := foundItems["url_image"]; ok && len(imageURLs) > 0 { + var newpiclink string + if config.GetUrlPicTransfer() { + // 从URL下载图片 + resp, err := http.Get("http://" + imageURLs[0]) + if err != nil { + mylog.Printf("Error downloading the image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 下载图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + defer resp.Body.Close() + + // 读取图片数据 + imageData, err := io.ReadAll(resp.Body) + if err != nil { + mylog.Printf("Error reading the image data: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 读取图片数据失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + + // 转换为base64 + base64Encoded := base64.StdEncoding.EncodeToString(imageData) + + if config.GetUploadPicV2Base64() { + // 直接上传图片返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessagePrivate(context.TODO(), base64Encoded, eventid, 1, false, "", userid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } + + // 上传图片并获取新的URL + newURL, _, _, err := images.UploadBase64ImageToServer(base64Encoded, apiv2) + if err != nil { + mylog.Printf("Error uploading base64 encoded image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + // 将图片链接缩短 避免 url not allow + // if config.GetLotusValue() { + // // 连接到另一个gensokyo + // newURL = url.GenerateShortURL(newURL) + // } else { + // // 自己是主节点 + // newURL = url.GenerateShortURL(newURL) + // // 使用getBaseURL函数来获取baseUrl并与newURL组合 + // newURL = url.GetBaseURL() + "/url/" + newURL + // } + newpiclink = newURL + } else { + newpiclink = "http://" + imageURLs[0] + } + + // 发链接图片 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 1, // 1代表图片 + URL: newpiclink, // 新图片链接 + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if imageURLs, ok := foundItems["url_images"]; ok && len(imageURLs) > 0 { + var newpiclink string + if config.GetUrlPicTransfer() { + // 从URL下载图片 + resp, err := http.Get("https://" + imageURLs[0]) + if err != nil { + mylog.Printf("Error downloading the image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 下载图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + defer resp.Body.Close() + + // 读取图片数据 + imageData, err := io.ReadAll(resp.Body) + if err != nil { + mylog.Printf("Error reading the image data: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 读取图片数据失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + + // 转换为base64 + base64Encoded := base64.StdEncoding.EncodeToString(imageData) + + if config.GetUploadPicV2Base64() { + // 直接上传图片返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessagePrivate(context.TODO(), base64Encoded, eventid, 1, false, "", userid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } + + // 上传图片并获取新的URL + newURL, _, _, err := images.UploadBase64ImageToServer(base64Encoded, apiv2) + if err != nil { + mylog.Printf("Error uploading base64 encoded image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + // 将图片链接缩短 避免 url not allow + // if config.GetLotusValue() { + // // 连接到另一个gensokyo + // newURL = url.GenerateShortURL(newURL) + // } else { + // // 自己是主节点 + // newURL = url.GenerateShortURL(newURL) + // // 使用getBaseURL函数来获取baseUrl并与newURL组合 + // newURL = url.GetBaseURL() + "/url/" + newURL + // } + newpiclink = newURL + } else { + newpiclink = "https://" + imageURLs[0] + } + + // 发链接图片 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 1, // 1代表图片 + URL: newpiclink, // 新图片链接 + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if voiceURLs, ok := foundItems["base64_record"]; ok && len(voiceURLs) > 0 { + // 适配base64 slik + if base64_record, ok := foundItems["base64_record"]; ok && len(base64_record) > 0 { + // 解码base64语音数据 + fileRecordData, err := base64.StdEncoding.DecodeString(base64_record[0]) + if err != nil { + mylog.Printf("failed to decode base64 record: %v", err) + return nil + } + //判断并转码 + if !silk.IsAMRorSILK(fileRecordData) { + mt, ok := silk.CheckAudio(bytes.NewReader(fileRecordData)) + if !ok { + mylog.Errorf("voice type error: " + mt) + return nil + } + fileRecordData = silk.EncoderSilk(fileRecordData) + mylog.Printf("音频转码ing") + } + // 将解码的语音数据转换回base64格式并上传 + imageURL, err := images.UploadBase64RecordToServer(base64.StdEncoding.EncodeToString(fileRecordData)) + if err != nil { + mylog.Printf("failed to upload base64 record: %v", err) + return nil + } + // 创建RichMediaMessage并返回 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 3, // 3代表语音 + URL: imageURL, + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } + } else if imageURLs, ok := foundItems["url_record"]; ok && len(imageURLs) > 0 { + // 从URL下载语音 + resp, err := http.Get("http://" + imageURLs[0]) + if err != nil { + mylog.Printf("Error downloading the record: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 下载语音失败", + MsgID: id, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + defer resp.Body.Close() + + // 读取语音数据 + recordData, err := io.ReadAll(resp.Body) + if err != nil { + mylog.Printf("Error reading the record data: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 读取语音数据失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + //判断并转码 + if !silk.IsAMRorSILK(recordData) { + mt, ok := silk.CheckAudio(bytes.NewReader(recordData)) + if !ok { + mylog.Errorf("voice type error: " + mt) + return nil + } + recordData = silk.EncoderSilk(recordData) + mylog.Printf("音频转码ing") + } + // 转换为base64 + base64Encoded := base64.StdEncoding.EncodeToString(recordData) + + // 上传语音并获取新的URL + newURL, err := images.UploadBase64RecordToServer(base64Encoded) + if err != nil { + mylog.Printf("Error uploading base64 encoded image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传语音失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + + // 发链接语音 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 3, // 3代表语音 + URL: newURL, // 新语音链接 + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if imageURLs, ok := foundItems["url_records"]; ok && len(imageURLs) > 0 { + // 从URL下载语音 + resp, err := http.Get("https://" + imageURLs[0]) + if err != nil { + mylog.Printf("Error downloading the record: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 下载语音失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + defer resp.Body.Close() + + // 读取语音数据 + recordData, err := io.ReadAll(resp.Body) + if err != nil { + mylog.Printf("Error reading the record data: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 读取语音数据失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + //判断并转码 + if !silk.IsAMRorSILK(recordData) { + mt, ok := silk.CheckAudio(bytes.NewReader(recordData)) + if !ok { + mylog.Errorf("voice type error: " + mt) + return nil + } + recordData = silk.EncoderSilk(recordData) + mylog.Printf("音频转码ing") + } + // 转换为base64 + base64Encoded := base64.StdEncoding.EncodeToString(recordData) + + // 上传语音并获取新的URL + newURL, err := images.UploadBase64RecordToServer(base64Encoded) + if err != nil { + mylog.Printf("Error uploading base64 encoded image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传语音失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, + } + } + + // 发链接语音 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 3, // 3代表语音 + URL: newURL, // 新语音链接 + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if base64Image, ok := foundItems["base64_image"]; ok && len(base64Image) > 0 { + // todo 适配base64图片 + //因为QQ群没有 form方式上传,所以在gensokyo内置了图床,需公网,或以lotus方式连接位于公网的gensokyo + //要正确的开放对应的端口和设置正确的ip地址在config,这对于一般用户是有一些难度的 + // 解码base64图片数据 + fileImageData, err := base64.StdEncoding.DecodeString(base64Image[0]) + if err != nil { + mylog.Printf("failed to decode base64 image: %v", err) + return nil + } + + // 首先压缩图片 默认不压缩 + compressedData, err := images.CompressSingleImage(fileImageData) + if err != nil { + mylog.Printf("Error compressing image: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 压缩图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + + base64Encoded := base64.StdEncoding.EncodeToString(compressedData) + if config.GetUploadPicV2Base64() { + // 直接上传图片返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessagePrivate(context.TODO(), base64Encoded, eventid, 1, false, "", userid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传图片失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } + + // 将解码的图片数据转换回base64格式并上传 + imageURL, _, _, err := images.UploadBase64ImageToServer(base64Encoded, apiv2) + if err != nil { + mylog.Printf("failed to upload base64 image: %v", err) + return nil + } + // 创建RichMediaMessage并返回 + return &dto.RichMediaMessage{ + EventID: id, + FileType: 1, // 1代表图片 + URL: imageURL, + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if mdContent, ok := foundItems["markdown"]; ok && len(mdContent) > 0 { + // 解码base64 markdown数据 + mdData, err := base64.StdEncoding.DecodeString(mdContent[0]) + if err != nil { + mylog.Printf("failed to decode base64 md: %v", err) + return nil + } + markdown, keyboard, err := parseMDData(mdData) + if err != nil { + mylog.Printf("failed to parseMDData: %v", err) + return nil + } + return &dto.MessageToCreate{ + Content: "markdown", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + Markdown: markdown, + Keyboard: keyboard, + MsgType: 2, + } + } else if qqmusic, ok := foundItems["qqmusic"]; ok && len(qqmusic) > 0 { + // 转换qq音乐id到一个md + music_id := qqmusic[0] + markdown, keyboard, err := parseQQMuiscMDData(music_id) + if err != nil { + mylog.Printf("failed to parseMDData: %v", err) + return nil + } + if markdown != nil { + return &dto.MessageToCreate{ + Content: "markdown", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + Markdown: markdown, + Keyboard: keyboard, + MsgType: 2, + } + } else { + return &dto.MessageToCreate{ + Content: "markdown", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + Keyboard: keyboard, + MsgType: 2, + } + } + } else if videoURL, ok := foundItems["url_video"]; ok && len(videoURL) > 0 { + newvideolink := "http://" + videoURL[0] + // 发链接视频 http + return &dto.RichMediaMessage{ + EventID: id, + FileType: 2, // 2代表视频 + URL: newvideolink, // 新图片链接 + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else if videoURLs, ok := foundItems["url_videos"]; ok && len(videoURLs) > 0 { + newvideolink := "https://" + videoURLs[0] + // 发链接视频 https + return &dto.RichMediaMessage{ + EventID: id, + FileType: 2, // 2代表视频 + URL: newvideolink, // 新图片链接 + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + } else { + // 返回文本信息 + return &dto.MessageToCreate{ + Content: messageText, + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return nil +} + // 通过user_id获取类型 func GetMessageTypeByUserid(appID string, userID interface{}) string { // 从appID和userID生成key diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index 7c0923cc..74cef2cc 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -233,7 +233,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open if messageText != "" { msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, eventID, nil, messageText, msgseq+1, apiv2, message.Params.GroupID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, nil, messageText, msgseq+1, apiv2, message.Params.UserID.(string)) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) From f921895234f33ccde2f8789dd022e30dd17f6cac Mon Sep 17 00:00:00 2001 From: cosmo Date: Tue, 9 Jul 2024 15:57:34 +0800 Subject: [PATCH 09/36] beta455 --- Processor/ProcessC2CMessage.go | 31 ++++++++--- Processor/ProcessChannelDirectMessage.go | 29 ++++++++--- Processor/ProcessGroupMessage.go | 16 ++++-- Processor/ProcessGuildATMessage.go | 16 ++++-- Processor/ProcessGuildNormalMessage.go | 16 ++++-- Processor/ProcessThreadMessage.go | 16 ++++-- config/config.go | 12 +++++ echo/echo.go | 53 +++++++++++++++++++ handlers/delete_msg.go | 21 ++++++-- handlers/message_parser.go | 65 ++++++++++++++++++------ handlers/send_group_msg_raw.go | 10 +++- structs/structs.go | 1 + template/config_template.go | 1 + 13 files changed, 234 insertions(+), 53 deletions(-) diff --git a/Processor/ProcessC2CMessage.go b/Processor/ProcessC2CMessage.go index bfe31ab5..67c6f40b 100644 --- a/Processor/ProcessC2CMessage.go +++ b/Processor/ProcessC2CMessage.go @@ -67,11 +67,19 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { //收到私聊信息调用的具体还原步骤 //1,idmap还原真实userid, //发信息使用的是userid - - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - log.Fatalf("Error storing ID: %v", err) + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } + messageID := int(messageID64) if config.GetAutoBind() { if len(data.Attachments) > 0 && data.Attachments[0].URL != "" { @@ -205,10 +213,17 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { //框架内指令 p.HandleFrameworkCommand(messageText, data, "group_private") //映射str的messageID到int - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) //todo 判断array模式 然后对Message处理成array格式 diff --git a/Processor/ProcessChannelDirectMessage.go b/Processor/ProcessChannelDirectMessage.go index 5ada9175..6a0845f7 100644 --- a/Processor/ProcessChannelDirectMessage.go +++ b/Processor/ProcessChannelDirectMessage.go @@ -95,9 +95,17 @@ func (p *Processors) ProcessChannelDirectMessage(data *dto.WSDirectMessageData) //3,通过idmap用channelid获取guildid, //发信息使用的是guildid //todo 优化数据库读写次数 - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - log.Fatalf("Error storing ID: %v", err) + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) //转换at @@ -344,10 +352,17 @@ func (p *Processors) ProcessChannelDirectMessage(data *dto.WSDirectMessageData) //userid := int(userid64) //映射str的messageID到int - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) // 如果在Array模式下, 则处理Message为Segment格式 diff --git a/Processor/ProcessGroupMessage.go b/Processor/ProcessGroupMessage.go index 11195ec9..2cda94ca 100644 --- a/Processor/ProcessGroupMessage.go +++ b/Processor/ProcessGroupMessage.go @@ -3,6 +3,7 @@ package Processor import ( "fmt" + "log" "strconv" "time" @@ -78,10 +79,17 @@ func (p *Processors) ProcessGroupMessage(data *dto.WSGroupATMessageData) error { //框架内指令 p.HandleFrameworkCommand(messageText, data, "group") //映射str的messageID到int - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) if config.GetAutoBind() { diff --git a/Processor/ProcessGuildATMessage.go b/Processor/ProcessGuildATMessage.go index d9b8f1fc..82163320 100644 --- a/Processor/ProcessGuildATMessage.go +++ b/Processor/ProcessGuildATMessage.go @@ -3,6 +3,7 @@ package Processor import ( "fmt" + "log" "strconv" "time" @@ -195,10 +196,17 @@ func (p *Processors) ProcessGuildATMessage(data *dto.WSATMessageData) error { echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) //映射str的messageID到int - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) // 如果在Array模式下, 则处理Message为Segment格式 diff --git a/Processor/ProcessGuildNormalMessage.go b/Processor/ProcessGuildNormalMessage.go index fd01d02d..9c1f99fd 100644 --- a/Processor/ProcessGuildNormalMessage.go +++ b/Processor/ProcessGuildNormalMessage.go @@ -3,6 +3,7 @@ package Processor import ( "fmt" + "log" "strconv" "time" @@ -191,10 +192,17 @@ func (p *Processors) ProcessGuildNormalMessage(data *dto.WSMessageData) error { // 构造echostr,包括AppID,原始的s变量和当前时间戳 echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) //映射str的messageID到int - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) // 如果在Array模式下, 则处理Message为Segment格式 diff --git a/Processor/ProcessThreadMessage.go b/Processor/ProcessThreadMessage.go index 29533d04..9bc30546 100644 --- a/Processor/ProcessThreadMessage.go +++ b/Processor/ProcessThreadMessage.go @@ -4,6 +4,7 @@ package Processor import ( "encoding/json" "fmt" + "log" "strconv" "strings" "time" @@ -312,10 +313,17 @@ func (p *Processors) ProcessThreadMessage(data *dto.WSThreadData) error { // 构造echostr,包括AppID,原始的s变量和当前时间戳 echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) //映射str的messageID到int - messageID64, err := idmap.StoreCachev2(data.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } messageID := int(messageID64) // 如果在Array模式下, 则处理Message为Segment格式 diff --git a/config/config.go b/config/config.go index d6739645..029f00f0 100644 --- a/config/config.go +++ b/config/config.go @@ -2352,3 +2352,15 @@ func GetDoNotReplaceAppid() bool { } return instance.Settings.DoNotReplaceAppid } + +// 获取GetMemoryMsgid的值 +func GetMemoryMsgid() bool { + mu.Lock() + defer mu.Unlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to MemoryMsgid value.") + return false + } + return instance.Settings.MemoryMsgid +} diff --git a/echo/echo.go b/echo/echo.go index 86ffef5a..3fbec3ce 100644 --- a/echo/echo.go +++ b/echo/echo.go @@ -1,12 +1,14 @@ package echo import ( + "fmt" "math/rand" "strconv" "sync" "time" "github.com/hoshinonyaruko/gensokyo/config" + "github.com/hoshinonyaruko/gensokyo/idmap" "github.com/tencent-connect/botgo/dto" ) @@ -53,6 +55,12 @@ type globalMessageGroup struct { stack []MessageGroupPair } +// 使用 sync.Map 作为内存存储 +var ( + globalSyncMapMsgid sync.Map + globalReverseMapMsgid sync.Map // 用于存储反向键值对 +) + // 初始化一个全局栈实例 var globalMessageGroupStack = &globalMessageGroup{ stack: make([]MessageGroupPair, 0), @@ -273,3 +281,48 @@ func RemoveFromGlobalStack(index int) { globalMessageGroupStack.stack = append(globalMessageGroupStack.stack[:index], globalMessageGroupStack.stack[index+1:]...) } + +// StoreCacheInMemory 根据 ID 将映射存储在内存中的 sync.Map 中 +func StoreCacheInMemory(id string) (int64, error) { + var newRow int64 + + // 检查是否已存在映射 + if value, ok := globalSyncMapMsgid.Load(id); ok { + newRow = value.(int64) + return newRow, nil + } + + // 生成新的行号 + var err error + maxDigits := 18 // int64 的位数上限-1 + for digits := 9; digits <= maxDigits; digits++ { + newRow, err = idmap.GenerateRowID(id, digits) + if err != nil { + return 0, err + } + + // 检查新生成的行号是否重复 + if _, exists := globalSyncMapMsgid.LoadOrStore(id, newRow); !exists { + // 存储反向键值对 + globalReverseMapMsgid.Store(newRow, id) + // 找到了一个唯一的行号,可以跳出循环 + break + } + + // 如果到达了最大尝试次数还没有找到唯一的行号,则返回错误 + if digits == maxDigits { + return 0, fmt.Errorf("unable to find a unique row ID after %d attempts", maxDigits-8) + } + } + + return newRow, nil +} + +// GetIDFromRowID 根据行号获取原始 ID +func GetCacheIDFromMemoryByRowID(rowID string) (string, bool) { + introwID, _ := strconv.ParseInt(rowID, 10, 64) + if value, ok := globalReverseMapMsgid.Load(introwID); ok { + return value.(string), true + } + return "", false +} diff --git a/handlers/delete_msg.go b/handlers/delete_msg.go index f2830094..306875ed 100644 --- a/handlers/delete_msg.go +++ b/handlers/delete_msg.go @@ -6,6 +6,8 @@ import ( "fmt" "github.com/hoshinonyaruko/gensokyo/callapi" + "github.com/hoshinonyaruko/gensokyo/config" + "github.com/hoshinonyaruko/gensokyo/echo" "github.com/hoshinonyaruko/gensokyo/idmap" "github.com/hoshinonyaruko/gensokyo/mylog" "github.com/tencent-connect/botgo/openapi" @@ -16,12 +18,21 @@ func init() { } func DeleteMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.OpenAPI, message callapi.ActionMessage) (string, error) { - - //还原msgid - RealMsgID, err := idmap.RetrieveRowByCachev2(message.Params.MessageID.(string)) - if err != nil { - mylog.Printf("error retrieving real RChannelID: %v", err) + var RealMsgID string + var err error + + // 如果从内存取 + if config.GetMemoryMsgid() { + //还原msgid + RealMsgID, _ = echo.GetCacheIDFromMemoryByRowID(message.Params.MessageID.(string)) + } else { + //还原msgid + RealMsgID, err = idmap.RetrieveRowByCachev2(message.Params.MessageID.(string)) + if err != nil { + mylog.Printf("error retrieving real RChannelID: %v", err) + } } + //重新赋值 message.Params.MessageID = RealMsgID //撤回频道信息 diff --git a/handlers/message_parser.go b/handlers/message_parser.go index 0416a76c..6c7f9f32 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -146,11 +146,20 @@ func SendResponse(client callapi.Client, err error, message *callapi.ActionMessa // 设置响应值 response := ServerResponse{} if resp != nil { - messageID64, mapErr = idmap.StoreCachev2(resp.Message.ID) - if mapErr != nil { - mylog.Printf("Error storing ID: %v", mapErr) - return "", nil + if config.GetMemoryMsgid() { + messageID64, mapErr = echo.StoreCacheInMemory(resp.Message.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } + } else { + messageID64, mapErr = idmap.StoreCachev2(resp.Message.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } } + response.Data.MessageID = int(messageID64) // 发送成功 增加今日发信息数 botstats.RecordMessageSent() @@ -246,10 +255,18 @@ func SendGuildResponse(client callapi.Client, err error, message *callapi.Action // 设置响应值 response := ServerResponse{} if resp != nil { - messageID64, mapErr = idmap.StoreCachev2(resp.ID) - if mapErr != nil { - mylog.Printf("Error storing ID: %v", mapErr) - return "", nil + if config.GetMemoryMsgid() { + messageID64, mapErr = echo.StoreCacheInMemory(resp.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } + } else { + messageID64, mapErr = idmap.StoreCachev2(resp.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } } response.Data.MessageID = int(messageID64) // 发送成功 增加今日发信息数 @@ -304,10 +321,18 @@ func SendC2CResponse(client callapi.Client, err error, message *callapi.ActionMe // 设置响应值 response := ServerResponse{} if resp != nil { - messageID64, mapErr = idmap.StoreCachev2(resp.Message.ID) - if mapErr != nil { - mylog.Printf("Error storing ID: %v", mapErr) - return "", nil + if config.GetMemoryMsgid() { + messageID64, mapErr = echo.StoreCacheInMemory(resp.Message.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } + } else { + messageID64, mapErr = idmap.StoreCachev2(resp.Message.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } } response.Data.MessageID = int(messageID64) // 发送成功 增加今日发信息数 @@ -361,10 +386,18 @@ func SendGuildPrivateResponse(client callapi.Client, err error, message *callapi // 设置响应值 response := ServerResponse{} if resp != nil { - messageID64, mapErr = idmap.StoreCachev2(resp.ID) - if mapErr != nil { - mylog.Printf("Error storing ID: %v", mapErr) - return "", nil + if config.GetMemoryMsgid() { + messageID64, mapErr = echo.StoreCacheInMemory(resp.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } + } else { + messageID64, mapErr = idmap.StoreCachev2(resp.ID) + if mapErr != nil { + mylog.Printf("Error storing ID: %v", mapErr) + return "", nil + } } response.Data.MessageID = int(messageID64) } else { diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index bd9c0fb6..99713cfe 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -160,7 +160,15 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope if isNumeric(messageID) && messageID != "0" { // 当messageID是字符串形式的数字时,执行转换 - RealMsgID, err := idmap.RetrieveRowByCachev2(messageID) + var RealMsgID string + var err error + if config.GetMemoryMsgid() { + //从内存取 + RealMsgID, _ = echo.GetCacheIDFromMemoryByRowID(messageID) + } else { + RealMsgID, err = idmap.RetrieveRowByCachev2(messageID) + } + if err != nil { mylog.Printf("error retrieving real MessageID: %v", err) } else { diff --git a/structs/structs.go b/structs/structs.go index 624961c5..d81b4766 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -102,6 +102,7 @@ type Settings struct { SendError bool `yaml:"send_error"` SaveError bool `yaml:"save_error"` DowntimeMessage string `yaml:"downtime_message"` + MemoryMsgid bool `yaml:"memory_msgid"` //增长营销类 SelfIntroduce []string `yaml:"self_introduce"` //api修改 diff --git a/template/config_template.go b/template/config_template.go index 4827a82d..0ca4c670 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -134,6 +134,7 @@ settings: send_error : true #将报错用文本发出,避免机器人被审核报无响应 save_error : false #将保存保存在log文件夹,方便开发者定位发送错误. downtime_message : "我正在维护中~请不要担心,维护结束就回来~维护时间:(1小时)" + memory_msgid : false #当你的机器人单日信息量超过100万,就需要高性能SSD或者开启这个选项了.部分依赖msgid的功能可能会受影响(如delete_msg) #增长营销类(推荐gensokyo-broadcast项目) self_introduce : ["",""] #自我介绍,可设置多个随机发送,当不为空时,机器人被邀入群会发送自定义自我介绍 需手动添加新textintent - "GroupAddRobotEventHandler" - "GroupDelRobotEventHandler" From 24108c63b7f8ec13874573ed240668d55f4e9e47 Mon Sep 17 00:00:00 2001 From: cosmo Date: Tue, 9 Jul 2024 16:10:44 +0800 Subject: [PATCH 10/36] btea455 --- echo/echo.go | 37 +++++++++++++++++++++++++++++++++++++ main.go | 11 +++++++++++ 2 files changed, 48 insertions(+) diff --git a/echo/echo.go b/echo/echo.go index 3fbec3ce..9d4a91c6 100644 --- a/echo/echo.go +++ b/echo/echo.go @@ -59,6 +59,8 @@ type globalMessageGroup struct { var ( globalSyncMapMsgid sync.Map globalReverseMapMsgid sync.Map // 用于存储反向键值对 + cleanupTicker *time.Ticker + onceMsgid sync.Once ) // 初始化一个全局栈实例 @@ -326,3 +328,38 @@ func GetCacheIDFromMemoryByRowID(rowID string) (string, bool) { } return "", false } + +// StartCleanupRoutine 启动定时清理函数,每5分钟清空 globalSyncMapMsgid 和 globalReverseMapMsgid +func StartCleanupRoutine() { + onceMsgid.Do(func() { + cleanupTicker = time.NewTicker(5 * time.Minute) + + // 启动一个协程执行清理操作 + go func() { + for range cleanupTicker.C { + fmt.Println("Starting cleanup...") + + // 清空 sync.Map + globalSyncMapMsgid.Range(func(key, value interface{}) bool { + globalSyncMapMsgid.Delete(key) + return true + }) + + // 清空反向映射 sync.Map + globalReverseMapMsgid.Range(func(key, value interface{}) bool { + globalReverseMapMsgid.Delete(key) + return true + }) + + fmt.Println("Cleanup completed.") + } + }() + }) +} + +// StopCleanupRoutine 停止定时清理函数 +func StopCleanupRoutine() { + if cleanupTicker != nil { + cleanupTicker.Stop() + } +} diff --git a/main.go b/main.go index 6c3d089f..c534166c 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "github.com/hoshinonyaruko/gensokyo/acnode" "github.com/hoshinonyaruko/gensokyo/botstats" "github.com/hoshinonyaruko/gensokyo/config" + "github.com/hoshinonyaruko/gensokyo/echo" "github.com/hoshinonyaruko/gensokyo/handlers" "github.com/hoshinonyaruko/gensokyo/httpapi" "github.com/hoshinonyaruko/gensokyo/idmap" @@ -532,6 +533,11 @@ func main() { }() } + //杂七杂八的地方 + if conf.Settings.MemoryMsgid { + echo.StartCleanupRoutine() + } + // 使用color库输出天蓝色的文本 cyan := color.New(color.FgCyan) cyan.Printf("欢迎来到Gensokyo, 控制台地址: %s\n", webuiURL) @@ -554,6 +560,11 @@ func main() { } } + // 停止内存清理线程 + if conf.Settings.MemoryMsgid { + echo.StopCleanupRoutine() + } + // 关闭BoltDB数据库 url.CloseDB() idmap.CloseDB() From 7cdc968d4ca4f78019ce71d460b4bbcb65ac1088 Mon Sep 17 00:00:00 2001 From: cosmo Date: Tue, 9 Jul 2024 18:13:15 +0800 Subject: [PATCH 11/36] beta456 --- Processor/ProcessGuildATMessage.go | 2 + handlers/send_guild_channel_msg.go | 74 +++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/Processor/ProcessGuildATMessage.go b/Processor/ProcessGuildATMessage.go index 82163320..266923fb 100644 --- a/Processor/ProcessGuildATMessage.go +++ b/Processor/ProcessGuildATMessage.go @@ -296,6 +296,8 @@ func (p *Processors) ProcessGuildATMessage(data *dto.WSATMessageData) error { echo.AddMsgType(AppIDString, ChannelID64, "guild") //懒message_id池 echo.AddLazyMessageId(strconv.FormatInt(ChannelID64, 10), data.ID, time.Now()) + //测试 + echo.AddLazyMessageId(data.ChannelID, data.ID, time.Now()) //懒message_id池 //echo.AddLazyMessageId(strconv.FormatInt(userid64, 10), data.ID, time.Now()) //echo.AddLazyMessageIdv2(strconv.FormatInt(ChannelID64, 10), strconv.FormatInt(userid64, 10), data.ID, time.Now()) diff --git a/handlers/send_guild_channel_msg.go b/handlers/send_guild_channel_msg.go index 5975b293..4f475595 100644 --- a/handlers/send_guild_channel_msg.go +++ b/handlers/send_guild_channel_msg.go @@ -18,6 +18,7 @@ import ( "github.com/hoshinonyaruko/gensokyo/echo" "github.com/tencent-connect/botgo/dto" + "github.com/tencent-connect/botgo/dto/keyboard" "github.com/tencent-connect/botgo/openapi" ) @@ -163,10 +164,33 @@ func HandleSendGuildChannelMsg(client callapi.Client, api openapi.OpenAPI, apiv2 MsgType: 0, } newMessage.Timestamp = time.Now().Unix() // 设置时间戳 + var transmd bool + var md *dto.Markdown + var kb *keyboard.MessageKeyboard + //判断是否需要自动转换md + if config.GetTwoWayEcho() { + // 初始化 RichMediaMessage 结构体指针 + var richMediaMessage *dto.RichMediaMessage = &dto.RichMediaMessage{} + richMediaMessage.Content = messageText + richMediaMessage.URL = Reply.Image + md, kb, transmd = auto_md(message, messageText, richMediaMessage) + } - if _, err = api.PostMessage(context.TODO(), channelID.(string), newMessage); err != nil { - mylog.Printf("发送图文混合信息失败: %v", err) + if transmd { + newMessage.Content = "" + newMessage.Image = "" + newMessage.Markdown = md + newMessage.Keyboard = kb + newMessage.MsgType = 2 //md信息 + if _, err = api.PostMessage(context.TODO(), channelID.(string), newMessage); err != nil { + mylog.Printf("发送图文混合信息失败: %v", err) + } + } else { + if _, err = api.PostMessage(context.TODO(), channelID.(string), newMessage); err != nil { + mylog.Printf("发送图文混合信息失败: %v", err) + } } + // 检查是否是 40003 错误 if err != nil && strings.Contains(err.Error(), `"code":40003`) && len(newMessage.Image) > 0 { // 从 newMessage.Image 中提取图片地址 @@ -439,6 +463,52 @@ func GenerateReplyMessage(id string, foundItems map[string][]string, messageText MsgType: 0, // Default type for text } isBase64 = true + } else if qqmusic, ok := foundItems["qqmusic"]; ok && len(qqmusic) > 0 { + // 转换qq音乐id到一个md + music_id := qqmusic[0] + markdown, keyboard, err := parseQQMuiscMDData(music_id) + if err != nil { + mylog.Printf("failed to parseMDData: %v", err) + return nil, false + } + if markdown != nil { + msgtocreate := &dto.MessageToCreate{ + MsgID: id, + MsgSeq: msgseq, + Markdown: markdown, + Keyboard: keyboard, + MsgType: 2, + } + return msgtocreate, false + } else { + msgtocreate := &dto.MessageToCreate{ + MsgID: id, + MsgSeq: msgseq, + Keyboard: keyboard, + MsgType: 2, + } + return msgtocreate, false + } + } else if mdContent, ok := foundItems["markdown"]; ok && len(mdContent) > 0 { + // 解码base64 markdown数据 + mdData, err := base64.StdEncoding.DecodeString(mdContent[0]) + if err != nil { + mylog.Printf("failed to decode base64 md: %v", err) + return nil, false + } + markdown, keyboard, err := parseMDData(mdData) + if err != nil { + mylog.Printf("failed to parseMDData: %v", err) + return nil, false + } + msgtocreate := &dto.MessageToCreate{ + MsgID: id, + MsgSeq: msgseq, + Markdown: markdown, + Keyboard: keyboard, + MsgType: 2, + } + return msgtocreate, false } else { // 发文本信息 reply = dto.MessageToCreate{ From b5d784eae268a5a7a3dd19538a3f647897961236 Mon Sep 17 00:00:00 2001 From: cosmo Date: Tue, 9 Jul 2024 20:30:29 +0800 Subject: [PATCH 12/36] beta457 --- echo/echo.go | 173 ++++++++++++++++----------------------------------- 1 file changed, 53 insertions(+), 120 deletions(-) diff --git a/echo/echo.go b/echo/echo.go index 9d4a91c6..7125cc4f 100644 --- a/echo/echo.go +++ b/echo/echo.go @@ -13,34 +13,19 @@ import ( ) type EchoMapping struct { - mu sync.Mutex - msgTypeMapping map[string]string - msgIDMapping map[string]string - eventIDMapping map[string]string + msgTypeMapping sync.Map + msgIDMapping sync.Map + eventIDMapping sync.Map } // Int64ToIntMapping 用于存储 int64 到 int 的映射(递归计数器) type Int64ToIntMapping struct { - mu sync.Mutex - mapping map[int64]int + mapping sync.Map } -// IntToStringMappingSeq 用于存储 string 到 int 的映射(seq对应) +// StringToIntMappingSeq 用于存储 string 到 int 的映射(seq对应) type StringToIntMappingSeq struct { - mu sync.Mutex - mapping map[string]int -} - -// StringToInt64MappingSeq 用于存储 string 到 int64 的映射(file接口频率限制) -type StringToInt64MappingSeq struct { - mu sync.Mutex - mapping map[string]int64 -} - -// Int64Stack 用于存储 int64 的栈 -type Int64Stack struct { - mu sync.Mutex - stack []int64 + mapping sync.Map } // MessageGroupPair 用于存储 group 和 groupMessage @@ -68,27 +53,18 @@ var globalMessageGroupStack = &globalMessageGroup{ stack: make([]MessageGroupPair, 0), } -// 定义一个全局的 Int64Stack 实例 -var globalInt64Stack = &Int64Stack{ - stack: make([]int64, 0), -} - var globalEchoMapping = &EchoMapping{ - msgTypeMapping: make(map[string]string), - msgIDMapping: make(map[string]string), - eventIDMapping: make(map[string]string), + msgTypeMapping: sync.Map{}, + msgIDMapping: sync.Map{}, + eventIDMapping: sync.Map{}, } var globalInt64ToIntMapping = &Int64ToIntMapping{ - mapping: make(map[int64]int), + mapping: sync.Map{}, } var globalStringToIntMappingSeq = &StringToIntMappingSeq{ - mapping: make(map[string]int), -} - -var globalStringToInt64MappingSeq = &StringToInt64MappingSeq{ - mapping: make(map[string]int64), + mapping: sync.Map{}, } func (e *EchoMapping) GenerateKey(appid string, s int64) string { @@ -107,146 +83,103 @@ func (e *EchoMapping) GenerateKeyv3(appid string, s string) string { return appid + "_" + s } -// 添加echo对应的类型 +// 添加 echo 对应的类型 func AddMsgType(appid string, s int64, msgType string) { key := globalEchoMapping.GenerateKey(appid, s) - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - globalEchoMapping.msgTypeMapping[key] = msgType + globalEchoMapping.msgTypeMapping.Store(key, msgType) } // 添加echo对应的messageid func AddMsgIDv3(appid string, s string, msgID string) { key := globalEchoMapping.GenerateKeyv3(appid, s) - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - globalEchoMapping.msgIDMapping[key] = msgID + globalEchoMapping.msgIDMapping.Store(key, msgID) } // GetMsgIDv3 返回给定appid和s的msgID func GetMsgIDv3(appid string, s string) string { key := globalEchoMapping.GenerateKeyv3(appid, s) - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - - return globalEchoMapping.msgIDMapping[key] + value, ok := globalEchoMapping.msgIDMapping.Load(key) + if !ok { + return "" // 或者根据需要返回默认值或者错误处理 + } + return value.(string) } // 添加group和userid对应的messageid func AddMsgIDv2(appid string, groupid int64, userid int64, msgID string) { key := globalEchoMapping.GenerateKeyv2(appid, groupid, userid) - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - globalEchoMapping.msgIDMapping[key] = msgID + globalEchoMapping.msgIDMapping.Store(key, msgID) } // 添加group对应的eventid func AddEvnetID(appid string, groupid int64, eventID string) { key := globalEchoMapping.GenerateKeyEventID(appid, groupid) - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - globalEchoMapping.eventIDMapping[key] = eventID + globalEchoMapping.eventIDMapping.Store(key, eventID) } // 添加echo对应的messageid func AddMsgID(appid string, s int64, msgID string) { key := globalEchoMapping.GenerateKey(appid, s) - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - globalEchoMapping.msgIDMapping[key] = msgID + globalEchoMapping.msgIDMapping.Store(key, msgID) } // 根据给定的key获取消息类型 func GetMsgTypeByKey(key string) string { - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - return globalEchoMapping.msgTypeMapping[key] + value, _ := globalEchoMapping.msgTypeMapping.Load(key) + if value == nil { + return "" // 根据需要返回默认值或者进行错误处理 + } + return value.(string) } // 根据给定的key获取消息ID func GetMsgIDByKey(key string) string { - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - return globalEchoMapping.msgIDMapping[key] + value, _ := globalEchoMapping.msgIDMapping.Load(key) + if value == nil { + return "" // 根据需要返回默认值或者进行错误处理 + } + return value.(string) } // 根据给定的key获取EventID func GetEventIDByKey(key string) string { - globalEchoMapping.mu.Lock() - defer globalEchoMapping.mu.Unlock() - return globalEchoMapping.eventIDMapping[key] + value, _ := globalEchoMapping.eventIDMapping.Load(key) + if value == nil { + return "" // 根据需要返回默认值或者进行错误处理 + } + return value.(string) } // AddMapping 添加一个新的映射 func AddMapping(key int64, value int) { - globalInt64ToIntMapping.mu.Lock() - defer globalInt64ToIntMapping.mu.Unlock() - globalInt64ToIntMapping.mapping[key] = value + globalInt64ToIntMapping.mapping.Store(key, value) } // GetMapping 根据给定的 int64 键获取映射值 func GetMapping(key int64) int { - globalInt64ToIntMapping.mu.Lock() - defer globalInt64ToIntMapping.mu.Unlock() - return globalInt64ToIntMapping.mapping[key] + value, _ := globalInt64ToIntMapping.mapping.Load(key) + if value == nil { + return 0 // 根据需要返回默认值或者进行错误处理 + } + return value.(int) } -// AddMapping 添加一个新的映射 +// AddMappingSeq 添加一个新的映射 func AddMappingSeq(key string, value int) { - globalStringToIntMappingSeq.mu.Lock() - defer globalStringToIntMappingSeq.mu.Unlock() - globalStringToIntMappingSeq.mapping[key] = value + globalStringToIntMappingSeq.mapping.Store(key, value) } // GetMappingSeq 根据给定的 string 键获取映射值 func GetMappingSeq(key string) int { - if config.GetRamDomSeq() { - rng := rand.New(rand.NewSource(time.Now().UnixNano())) - return rng.Intn(10000) + 1 // 生成 1 到 10000 的随机数 - } else { - globalStringToIntMappingSeq.mu.Lock() - defer globalStringToIntMappingSeq.mu.Unlock() - return globalStringToIntMappingSeq.mapping[key] - } -} - -// AddMapping 添加一个新的映射 -func AddMappingFileTimeLimit(key string, value int64) { - globalStringToInt64MappingSeq.mu.Lock() - defer globalStringToInt64MappingSeq.mu.Unlock() - globalStringToInt64MappingSeq.mapping[key] = value -} - -// GetMapping 根据给定的 string 键获取映射值 -func GetMappingFileTimeLimit(key string) int64 { - globalStringToInt64MappingSeq.mu.Lock() - defer globalStringToInt64MappingSeq.mu.Unlock() - return globalStringToInt64MappingSeq.mapping[key] -} - -// Add 添加一个新的 int64 到全局栈中 -func AddFileTimeLimit(value int64) { - globalInt64Stack.mu.Lock() - defer globalInt64Stack.mu.Unlock() - - // 添加新元素到栈顶 - globalInt64Stack.stack = append(globalInt64Stack.stack, value) - - // 如果栈的大小超过 10,移除最早添加的元素 - if len(globalInt64Stack.stack) > 10 { - globalInt64Stack.stack = globalInt64Stack.stack[1:] - } -} - -// Get 获取全局栈顶的元素 -func GetFileTimeLimit() int64 { - globalInt64Stack.mu.Lock() - defer globalInt64Stack.mu.Unlock() - - if len(globalInt64Stack.stack) == 0 { - return 0 // 当栈为空时返回 0 + value, ok := globalStringToIntMappingSeq.mapping.Load(key) + if !ok { + if config.GetRamDomSeq() { + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + return rng.Intn(10000) + 1 // 生成 1 到 10000 的随机数 + } + return 0 // 或者根据需要返回默认值或者进行错误处理 } - return globalInt64Stack.stack[len(globalInt64Stack.stack)-1] + return value.(int) } // PushGlobalStack 向全局栈中添加一个新的 MessageGroupPair From 61e4001a9ab8f9fa7007f044eca2856d142e3e3f Mon Sep 17 00:00:00 2001 From: cosmo Date: Tue, 9 Jul 2024 20:44:04 +0800 Subject: [PATCH 13/36] beta458 --- Processor/Processor.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Processor/Processor.go b/Processor/Processor.go index 229d676a..f9c84318 100644 --- a/Processor/Processor.go +++ b/Processor/Processor.go @@ -579,7 +579,7 @@ func (p *Processors) HandleFrameworkCommand(messageText string, data interface{} } //link指令 - if Type == "group" && strings.HasPrefix(cleanedMessage, config.GetLinkPrefix()) { + if strings.HasPrefix(cleanedMessage, config.GetLinkPrefix()) { md, kb := generateMdByConfig() SendMessageMd(md, kb, data, Type, p.Api, p.Apiv2) } @@ -845,7 +845,6 @@ func SendMessageMd(md *dto.Markdown, kb *keyboard.MessageKeyboard, data interfac msgseq := echo.GetMappingSeq(msg.ID) echo.AddMappingSeq(msg.ID, msgseq+1) Message := &dto.MessageToCreate{ - Content: "markdown", MsgID: msg.ID, MsgSeq: msgseq, Markdown: md, @@ -889,7 +888,6 @@ func SendMessageMd(md *dto.Markdown, kb *keyboard.MessageKeyboard, data interfac msgseq := echo.GetMappingSeq(msg.ID) echo.AddMappingSeq(msg.ID, msgseq+1) Message := &dto.MessageToCreate{ - Content: "markdown", MsgID: msg.ID, MsgSeq: msgseq, Markdown: md, From 6d4116a5ee3f5fd64d440690e31f0e4aecad2226 Mon Sep 17 00:00:00 2001 From: cosmo Date: Tue, 9 Jul 2024 23:04:03 +0800 Subject: [PATCH 14/36] beta460 --- Processor/ProcessC2CMessage.go | 11 +++++++++-- Processor/ProcessGuildNormalMessage.go | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Processor/ProcessC2CMessage.go b/Processor/ProcessC2CMessage.go index 67c6f40b..6e6f5b99 100644 --- a/Processor/ProcessC2CMessage.go +++ b/Processor/ProcessC2CMessage.go @@ -147,14 +147,17 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { //其实不需要用AppIDString,因为gensokyo是单机器人框架 //可以试着开发一个,会很棒的 echo.AddMsgID(AppIDString, userid64, data.ID) + //懒message_id池 echo.AddLazyMessageId(strconv.FormatInt(userid64, 10), data.ID, time.Now()) + + //懒message_id池 + echo.AddLazyMessageId(data.Author.ID, data.ID, time.Now()) + //储存类型 echo.AddMsgType(AppIDString, userid64, "group_private") //储存当前群或频道号的类型 idmap.WriteConfigv2(fmt.Sprint(userid64), "type", "group_private") - //储存当前群或频道号的类型 私信不需要 - //idmap.WriteConfigv2(data.ChannelID, "type", "group_private") // 调试 PrintStructWithFieldNames(privateMsg) @@ -302,9 +305,13 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { echo.AddMsgType(AppIDString, userid64, "group_private") //储存当前群或频道号的类型 idmap.WriteConfigv2(fmt.Sprint(userid64), "type", "group_private") + //懒message_id池 echo.AddLazyMessageId(strconv.FormatInt(userid64, 10), data.ID, time.Now()) + //懒message_id池 + echo.AddLazyMessageId(data.Author.ID, data.ID, time.Now()) + //调试 PrintStructWithFieldNames(groupMsg) diff --git a/Processor/ProcessGuildNormalMessage.go b/Processor/ProcessGuildNormalMessage.go index 9c1f99fd..fd3125ff 100644 --- a/Processor/ProcessGuildNormalMessage.go +++ b/Processor/ProcessGuildNormalMessage.go @@ -302,6 +302,8 @@ func (p *Processors) ProcessGuildNormalMessage(data *dto.WSMessageData) error { echo.AddMsgType(AppIDString, ChannelID64, "guild") //懒message_id池 echo.AddLazyMessageId(strconv.FormatInt(ChannelID64, 10), data.ID, time.Now()) + //测试 + echo.AddLazyMessageId(data.ChannelID, data.ID, time.Now()) //懒message_id池 //echo.AddLazyMessageId(strconv.FormatInt(userid64, 10), data.ID, time.Now()) //echo.AddLazyMessageIdv2(strconv.FormatInt(ChannelID64, 10), strconv.FormatInt(userid64, 10), data.ID, time.Now()) From 2c1f1b7b1c13261ca4df6012fbbe71d04df72ce3 Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 11 Jul 2024 17:45:13 +0800 Subject: [PATCH 15/36] beta460 --- Processor/ProcessInlineSearch.go | 17 +- config/config.go | 24 + go.mod | 12 +- go.sum | 33 +- handlers/put_interaction.go | 28 + handlers/send_group_msg.go | 10 +- handlers/send_private_msg.go | 6 +- idmap/grpc.go | 147 ++ idmap/service.go | 202 ++- images/upload_api.go | 5 +- main.go | 41 +- proto/idmap.pb.go | 2524 ++++++++++++++++++++++++++++++ proto/idmap.proto | 179 +++ proto/idmap_grpc.pb.go | 677 ++++++++ structs/structs.go | 15 +- template/config_template.go | 3 + 16 files changed, 3865 insertions(+), 58 deletions(-) create mode 100644 idmap/grpc.go create mode 100644 proto/idmap.pb.go create mode 100644 proto/idmap.proto create mode 100644 proto/idmap_grpc.pb.go diff --git a/Processor/ProcessInlineSearch.go b/Processor/ProcessInlineSearch.go index 6e339119..3cdb23db 100644 --- a/Processor/ProcessInlineSearch.go +++ b/Processor/ProcessInlineSearch.go @@ -4,6 +4,7 @@ package Processor import ( "context" "fmt" + "log" "strconv" "sync" "time" @@ -136,10 +137,22 @@ func (p *Processors) ProcessInlineSearch(data *dto.WSInteractionData) error { IsBindedGroupId = idmap.CheckValuev2(GroupID64) } - //平台事件,不是真实信息,无需messageID - messageID64 := 123 + //映射str的messageID到int + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } messageID := int(messageID64) + var selfid64 int64 if config.GetUseUin() { selfid64 = config.GetUinint64() diff --git a/config/config.go b/config/config.go index 029f00f0..8aa180ef 100644 --- a/config/config.go +++ b/config/config.go @@ -2364,3 +2364,27 @@ func GetMemoryMsgid() bool { } return instance.Settings.MemoryMsgid } + +// 获取GetLotusGrpc的值 +func GetLotusGrpc() bool { + mu.Lock() + defer mu.Unlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to LotusGrpc value.") + return false + } + return instance.Settings.LotusGrpc +} + +// 获取LotusWithoutUploadPic的值 +func GetLotusWithoutUploadPic() bool { + mu.Lock() + defer mu.Unlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to LotusWithoutUploadPic value.") + return false + } + return instance.Settings.LotusWithoutUploadPic +} diff --git a/go.mod b/go.mod index f50fa170..793866d7 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/tencent-connect/botgo v0.1.6 github.com/tencentyun/cos-go-sdk-v5 v0.7.45 go.etcd.io/bbolt v1.3.9 + google.golang.org/grpc v1.65.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -33,6 +34,7 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/time v0.5.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect gopkg.in/ini.v1 v1.66.2 // indirect ) @@ -65,10 +67,10 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 - golang.org/x/sys v0.13.0 - golang.org/x/text v0.9.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 + golang.org/x/sys v0.20.0 + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 mvdan.cc/xurls v1.1.0 ) diff --git a/go.sum b/go.sum index 364603e8..187875f8 100644 --- a/go.sum +++ b/go.sum @@ -53,8 +53,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -158,8 +158,8 @@ golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -173,11 +173,11 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -189,13 +189,13 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -204,14 +204,17 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/handlers/put_interaction.go b/handlers/put_interaction.go index 7e3706ad..3a27c004 100644 --- a/handlers/put_interaction.go +++ b/handlers/put_interaction.go @@ -4,8 +4,12 @@ import ( "context" "encoding/json" "fmt" + "regexp" "github.com/hoshinonyaruko/gensokyo/callapi" + "github.com/hoshinonyaruko/gensokyo/config" + "github.com/hoshinonyaruko/gensokyo/echo" + "github.com/hoshinonyaruko/gensokyo/idmap" "github.com/hoshinonyaruko/gensokyo/mylog" "github.com/tencent-connect/botgo/openapi" ) @@ -30,6 +34,30 @@ func HandlePutInteraction(client callapi.Client, api openapi.OpenAPI, apiv2 open return "", fmt.Errorf("echo is not a string") } + // 检查字符串是否仅包含数字 将数字形式的interactionID转换为真实的形式 + isNumeric := func(s string) bool { + return regexp.MustCompile(`^\d+$`).MatchString(s) + } + + if isNumeric(interactionID) && interactionID != "0" { + // 当interactionID是字符串形式的数字时,执行转换 + var RealinteractionID string + var err error + if config.GetMemoryMsgid() { + //从内存取 + RealinteractionID, _ = echo.GetCacheIDFromMemoryByRowID(interactionID) + } else { + RealinteractionID, err = idmap.RetrieveRowByCachev2(interactionID) + } + + if err != nil { + mylog.Printf("error retrieving real interactionID: %v", err) + } else { + // 重新赋值,RealinteractionID的类型与message.Params.interactionID兼容 + interactionID = RealinteractionID + } + } + // 根据 PostType 解析出 code 的值 var code int switch message.PostType { diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index 014a8bb7..e66d1351 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -2045,10 +2045,12 @@ func auto_md(message callapi.ActionMessage, messageText string, richMediaMessage messageText = strings.ReplaceAll(messageText, "\r\n", "\r") // 将所有的\n替换为\r messageText = strings.ReplaceAll(messageText, "\n", "\r") - // 检查messageText是否以\r开头 - if !strings.HasPrefix(messageText, "\r") { - messageText = "\r" + messageText - } + + // // 检查messageText是否以\r开头 + // if !strings.HasPrefix(messageText, "\r") { + // messageText = "\r" + messageText + // } + if config.GetEntersAsBlock() { messageText = strings.ReplaceAll(messageText, "\r", " ") } diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index 74cef2cc..1eb52e4c 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -187,7 +187,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open singleItem[imageType] = []string{imageUrl} msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, message.Params.UserID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, message.Params.UserID.(string)) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -261,7 +261,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open //mylog.Println("singleItem:", singleItem) msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, message.Params.GroupID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, message.Params.UserID.(string)) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -328,7 +328,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open if config.GetSendError() { //把报错当作文本发出去 msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, eventID, nil, err.Error(), msgseq+1, apiv2, message.Params.GroupID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, nil, err.Error(), msgseq+1, apiv2, message.Params.UserID.(string)) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) if !ok { diff --git a/idmap/grpc.go b/idmap/grpc.go new file mode 100644 index 00000000..d48a0c4f --- /dev/null +++ b/idmap/grpc.go @@ -0,0 +1,147 @@ +package idmap + +import ( + "context" + + "github.com/hoshinonyaruko/gensokyo/proto" +) + +type Server struct { + proto.UnimplementedIDMapServiceServer +} + +func (s *Server) StoreIDV2(ctx context.Context, req *proto.StoreIDRequest) (*proto.StoreIDResponse, error) { + newRow, err := StoreIDv2(req.IdOrRow) + if err != nil { + return nil, err + } + return &proto.StoreIDResponse{Row: newRow}, nil +} + +func (s *Server) RetrieveRowByIDV2(ctx context.Context, req *proto.RetrieveRowByIDRequest) (*proto.RetrieveRowByIDResponse, error) { + id, err := RetrieveRowByIDv2(req.IdOrRow) + if err != nil { + return nil, err + } + return &proto.RetrieveRowByIDResponse{Id: id}, nil +} + +func (s *Server) WriteConfigV2(ctx context.Context, req *proto.WriteConfigRequest) (*proto.WriteConfigResponse, error) { + err := WriteConfigv2(req.Section, req.Subtype, req.Value) + if err != nil { + return nil, err + } + return &proto.WriteConfigResponse{Status: "success"}, nil +} + +func (s *Server) ReadConfigV2(ctx context.Context, req *proto.ReadConfigRequest) (*proto.ReadConfigResponse, error) { + value, err := ReadConfigv2(req.Section, req.Subtype) + if err != nil { + return nil, err + } + return &proto.ReadConfigResponse{Value: value}, nil +} + +func (s *Server) UpdateVirtualValueV2(ctx context.Context, req *proto.UpdateVirtualValueRequest) (*proto.UpdateVirtualValueResponse, error) { + err := UpdateVirtualValuev2(req.OldVirtualValue, req.NewVirtualValue) + if err != nil { + return nil, err + } + return &proto.UpdateVirtualValueResponse{Status: "success"}, nil +} + +func (s *Server) RetrieveRealValueV2(ctx context.Context, req *proto.RetrieveRealValueRequest) (*proto.RetrieveRealValueResponse, error) { + virtual, real, err := RetrieveRealValuev2(req.VirtualValue) + if err != nil { + return nil, err + } + return &proto.RetrieveRealValueResponse{Virtual: virtual, Real: real}, nil +} + +func (s *Server) RetrieveRealValueV2Pro(ctx context.Context, req *proto.RetrieveRealValueRequestPro) (*proto.RetrieveRealValueResponsePro, error) { + virtual, real, err := RetrieveRealValuePro(req.VirtualValue, req.VirtualValueSub) + if err != nil { + return nil, err + } + return &proto.RetrieveRealValueResponsePro{Virtual: virtual, Real: real}, nil +} + +func (s *Server) RetrieveVirtualValueV2(ctx context.Context, req *proto.RetrieveVirtualValueRequest) (*proto.RetrieveVirtualValueResponse, error) { + real, virtual, err := RetrieveVirtualValuev2(req.RealValue) + if err != nil { + return nil, err + } + return &proto.RetrieveVirtualValueResponse{Real: real, Virtual: virtual}, nil +} + +func (s *Server) StoreIDV2Pro(ctx context.Context, req *proto.StoreIDProRequest) (*proto.StoreIDProResponse, error) { + row, subRow, err := StoreIDv2Pro(req.IdOrRow, req.Subid) + if err != nil { + return nil, err + } + return &proto.StoreIDProResponse{Row: row, SubRow: subRow}, nil +} + +func (s *Server) RetrieveRowByIDV2Pro(ctx context.Context, req *proto.RetrieveRowByIDProRequest) (*proto.RetrieveRowByIDProResponse, error) { + id, subid, err := RetrieveRowByIDv2Pro(req.IdOrRow, req.Subid) + if err != nil { + return nil, err + } + return &proto.RetrieveRowByIDProResponse{Id: id, Subid: subid}, nil +} + +func (s *Server) RetrieveVirtualValueV2Pro(ctx context.Context, req *proto.RetrieveVirtualValueProRequest) (*proto.RetrieveVirtualValueProResponse, error) { + firstValue, secondValue, err := RetrieveVirtualValuev2Pro(req.IdOrRow, req.Subid) + if err != nil { + return nil, err + } + return &proto.RetrieveVirtualValueProResponse{FirstValue: firstValue, SecondValue: secondValue}, nil +} + +func (s *Server) UpdateVirtualValueV2Pro(ctx context.Context, req *proto.UpdateVirtualValueProRequest) (*proto.UpdateVirtualValueProResponse, error) { + err := UpdateVirtualValuev2Pro(req.OldVirtualValue_1, req.NewVirtualValue_1, req.OldVirtualValue_2, req.NewVirtualValue_2) + if err != nil { + return nil, err + } + return &proto.UpdateVirtualValueProResponse{Message: "Virtual values updated successfully"}, nil +} + +func (s *Server) SimplifiedStoreIDV2(ctx context.Context, req *proto.SimplifiedStoreIDRequest) (*proto.SimplifiedStoreIDResponse, error) { + row, err := SimplifiedStoreIDv2(req.IdOrRow) + if err != nil { + return nil, err + } + return &proto.SimplifiedStoreIDResponse{Row: row}, nil +} + +func (s *Server) FindSubKeysByIdPro(ctx context.Context, req *proto.FindSubKeysRequest) (*proto.FindSubKeysResponse, error) { + keys, err := FindSubKeysByIdPro(req.Id) + if err != nil { + return nil, err + } + return &proto.FindSubKeysResponse{Keys: keys}, nil +} + +func (s *Server) DeleteConfigV2(ctx context.Context, req *proto.DeleteConfigRequest) (*proto.DeleteConfigResponse, error) { + err := DeleteConfigv2(req.Section, req.Subtype) + if err != nil { + return nil, err + } + return &proto.DeleteConfigResponse{Status: "success"}, nil +} + +func (s *Server) StoreCacheV2(ctx context.Context, req *proto.StoreCacheRequest) (*proto.StoreCacheResponse, error) { + row, err := StoreCachev2(req.IdOrRow) + if err != nil { + return nil, err + } + return &proto.StoreCacheResponse{Row: row}, nil +} + +func (s *Server) RetrieveRowByCacheV2(ctx context.Context, req *proto.RetrieveRowByCacheRequest) (*proto.RetrieveRowByCacheResponse, error) { + id, err := RetrieveRowByCachev2(req.IdOrRow) + if err != nil { + return nil, err + } + return &proto.RetrieveRowByCacheResponse{Id: id}, nil +} diff --git a/idmap/service.go b/idmap/service.go index 31c1fb48..0c0ae205 100644 --- a/idmap/service.go +++ b/idmap/service.go @@ -2,6 +2,7 @@ package idmap import ( "bytes" + "context" "crypto/md5" "encoding/binary" "encoding/hex" @@ -19,10 +20,15 @@ import ( "github.com/hoshinonyaruko/gensokyo/config" "github.com/hoshinonyaruko/gensokyo/mylog" + proto "github.com/hoshinonyaruko/gensokyo/proto" "github.com/hoshinonyaruko/gensokyo/structs" "go.etcd.io/bbolt" ) +var ( + GrpcClient proto.IDMapServiceClient // 全局的 gRPC 客户端 +) + var ( // 用于存储临时指令的全局变量 TemporaryCommands []string @@ -434,7 +440,16 @@ func SimplifiedStoreID(id string) (int64, error) { // SimplifiedStoreID 根据a储存b 储存一半 func SimplifiedStoreIDv2(id string) (int64, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + //是否使用grpc + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.SimplifiedStoreIDRequest{IdOrRow: id} + resp, err := GrpcClient.SimplifiedStoreIDV2(context.Background(), req) + if err != nil { + return 0, fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Row, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -522,7 +537,16 @@ func StoreIDPro(id string, subid string) (int64, int64, error) { // StoreIDv2 根据a储存b func StoreIDv2(id string) (int64, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + //是否使用grpc + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.StoreIDRequest{IdOrRow: id} + resp, err := GrpcClient.StoreIDV2(context.Background(), req) + if err != nil { + return 0, fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Row, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -564,7 +588,15 @@ func StoreIDv2(id string) (int64, error) { // StoreCachev2 根据a储存b func StoreCachev2(id string) (int64, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.StoreCacheRequest{IdOrRow: id} + resp, err := GrpcClient.StoreCacheV2(context.Background(), req) + if err != nil { + return 0, fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Row, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -606,7 +638,15 @@ func StoreCachev2(id string) (int64, error) { // 群号 然后 用户号 func StoreIDv2Pro(id string, subid string) (int64, int64, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.StoreIDProRequest{IdOrRow: id, Subid: subid} + resp, err := GrpcClient.StoreIDV2Pro(context.Background(), req) + if err != nil { + return 0, 0, fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Row, resp.SubRow, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -691,7 +731,15 @@ func RetrieveRowByCache(rowid string) (string, error) { // 群号 然后 用户号 func RetrieveRowByIDv2Pro(newRowID string, newSubRowID string) (string, string, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveRowByIDProRequest{IdOrRow: newRowID, Subid: newSubRowID} + resp, err := GrpcClient.RetrieveRowByIDV2Pro(context.Background(), req) + if err != nil { + return "", "", fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Id, resp.Subid, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -772,8 +820,15 @@ func RetrieveRowByIDv2(rowid string) (string, error) { if portValue == "443" { protocol = "https" } - - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveRowByIDRequest{IdOrRow: rowid} + resp, err := GrpcClient.RetrieveRowByIDV2(context.Background(), req) + if err != nil { + return "", fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Id, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() @@ -814,8 +869,15 @@ func RetrieveRowByCachev2(rowid string) (string, error) { if portValue == "443" { protocol = "https" } - - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveRowByCacheRequest{IdOrRow: rowid} + resp, err := GrpcClient.RetrieveRowByCacheV2(context.Background(), req) + if err != nil { + return "", fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Id, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() @@ -870,7 +932,15 @@ func WriteConfig(sectionName, keyName, value string) error { // WriteConfigv2 根据a以b为类别储存c func WriteConfigv2(sectionName, keyName, value string) error { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.WriteConfigRequest{Section: sectionName, Subtype: keyName, Value: value} + _, err := GrpcClient.WriteConfigV2(context.Background(), req) + if err != nil { + return err + } + return nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -957,7 +1027,15 @@ func DeleteConfigv2(sectionName, keyName string) error { protocol = "https" } - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.DeleteConfigRequest{Section: sectionName, Subtype: keyName} + _, err := GrpcClient.DeleteConfigV2(context.Background(), req) + if err != nil { + return fmt.Errorf("gRPC call failed: %v", err) + } + return nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() @@ -997,8 +1075,15 @@ func ReadConfigv2(sectionName, keyName string) (string, error) { if portValue == "443" { protocol = "https" } - - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.ReadConfigRequest{Section: sectionName, Subtype: keyName} + resp, err := GrpcClient.ReadConfigV2(context.Background(), req) + if err != nil { + return "", fmt.Errorf("gRPC call failed: %v", err) + } + return resp.Value, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() @@ -1135,7 +1220,18 @@ func RetrieveVirtualValue(realValue string) (string, string, error) { // 更新真实值对应的虚拟值 func UpdateVirtualValuev2(oldRowValue, newRowValue int64) error { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.UpdateVirtualValueRequest{ + OldVirtualValue: oldRowValue, + NewVirtualValue: newRowValue, + } + _, err := GrpcClient.UpdateVirtualValueV2(context.Background(), req) + if err != nil { + return fmt.Errorf("gRPC call failed: %v", err) + } + return nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 构建请求URL serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -1162,7 +1258,17 @@ func UpdateVirtualValuev2(oldRowValue, newRowValue int64) error { // RetrieveRealValuev2 根据虚拟值获取真实值 func RetrieveRealValuev2(virtualValue int64) (string, string, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveRealValueRequest{ + VirtualValue: virtualValue, + } + resp, err := GrpcClient.RetrieveRealValueV2(context.Background(), req) + if err != nil { + return "", "", err + } + return resp.Virtual, resp.Real, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { serverDir := config.GetServer_dir() portValue := config.GetPortValue() protocol := "http" @@ -1197,7 +1303,17 @@ func RetrieveRealValuev2(virtualValue int64) (string, string, error) { // RetrieveVirtualValuev2 根据真实值获取虚拟值 func RetrieveVirtualValuev2(realValue string) (string, string, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveVirtualValueRequest{ + RealValue: realValue, + } + resp, err := GrpcClient.RetrieveVirtualValueV2(context.Background(), req) + if err != nil { + return "", "", err + } + return resp.Real, resp.Virtual, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -1239,7 +1355,19 @@ func RetrieveVirtualValuev2(realValue string) (string, string, error) { // 根据2个真实值 获取2个虚拟值 群号 然后 用户号 func RetrieveVirtualValuev2Pro(realValue string, realValueSub string) (string, string, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + //是否使用grpc + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveVirtualValueProRequest{ + IdOrRow: realValue, + Subid: realValueSub, + } + resp, err := GrpcClient.RetrieveVirtualValueV2Pro(context.Background(), req) + if err != nil { + return "", "", err + } + return resp.FirstValue, resp.SecondValue, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -1353,7 +1481,18 @@ func RetrieveRealValuePro(virtualValue1, virtualValue2 int64) (string, string, e // RetrieveRealValuesv2Pro 根据两个虚拟值获取两个真实值 群号 然后 用户号 func RetrieveRealValuesv2Pro(virtualValue int64, virtualValueSub int64) (string, string, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.RetrieveRealValueRequestPro{ + VirtualValue: virtualValue, + VirtualValueSub: virtualValueSub, + } + resp, err := GrpcClient.RetrieveRealValueV2Pro(context.Background(), req) + if err != nil { + return "", "", err + } + return resp.Virtual, resp.Real, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -1436,7 +1575,20 @@ func UpdateVirtualValuePro(oldVirtualValue1, newVirtualValue1, oldVirtualValue2, // UpdateVirtualValuev2Pro 根据配置更新两对虚拟值 旧群 新群 旧用户 新用户 func UpdateVirtualValuev2Pro(oldVirtualValue1, newVirtualValue1, oldVirtualValue2, newVirtualValue2 int64) error { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.UpdateVirtualValueProRequest{ + OldVirtualValue_1: oldVirtualValue1, + NewVirtualValue_1: newVirtualValue1, + OldVirtualValue_2: oldVirtualValue2, + NewVirtualValue_2: newVirtualValue2, + } + _, err := GrpcClient.UpdateVirtualValueV2Pro(context.Background(), req) + if err != nil { + return err + } + return nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 构建请求URL serverDir := config.GetServer_dir() portValue := config.GetPortValue() @@ -1526,7 +1678,17 @@ func FindSubKeysById(id string) ([]string, error) { // FindSubKeysByIdPro 根据1个值获取key中的k:v给出k获取所有v,通过网络调用 func FindSubKeysByIdPro(id string) ([]string, error) { - if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { + if config.GetLotusGrpc() && config.GetLotusValue() { + // 使用 gRPC 调用 + req := &proto.FindSubKeysRequest{ + Id: id, + } + resp, err := GrpcClient.FindSubKeysByIdPro(context.Background(), req) + if err != nil { + return nil, err + } + return resp.Keys, nil + } else if config.GetLotusValue() && !config.GetLotusWithoutIdmaps() { // 使用网络请求方式 serverDir := config.GetServer_dir() portValue := config.GetPortValue() diff --git a/images/upload_api.go b/images/upload_api.go index b46adbe9..67705aa6 100644 --- a/images/upload_api.go +++ b/images/upload_api.go @@ -181,7 +181,8 @@ func originalUploadBehavior(base64Image string) (string, error) { protocol = "https" } - if config.GetLotusValue() { + // 如果lotus为真 + if config.GetLotusValue() && !config.GetLotusWithoutUploadPic() { serverDir := config.GetServer_dir() url := fmt.Sprintf("%s://%s:%s/uploadpic", protocol, serverDir, serverPort) @@ -264,7 +265,7 @@ func originalUploadBehaviorRecord(base64Image string) (string, error) { protocol = "https" } - if config.GetLotusValue() { + if config.GetLotusValue() && !config.GetLotusWithoutUploadPic() { serverDir := config.GetServer_dir() url := fmt.Sprintf("%s://%s:%s/uploadrecord", protocol, serverDir, serverPort) diff --git a/main.go b/main.go index c534166c..30b362e8 100644 --- a/main.go +++ b/main.go @@ -7,10 +7,12 @@ import ( "flag" "fmt" "log" + "net" "net/http" "os" "os/signal" "runtime" + "strconv" "strings" "syscall" "time" @@ -32,8 +34,10 @@ import ( "github.com/hoshinonyaruko/gensokyo/url" "github.com/hoshinonyaruko/gensokyo/webui" "github.com/hoshinonyaruko/gensokyo/wsclient" + "google.golang.org/grpc" "github.com/gin-gonic/gin" + proto "github.com/hoshinonyaruko/gensokyo/proto" "github.com/tencent-connect/botgo" "github.com/tencent-connect/botgo/dto" "github.com/tencent-connect/botgo/event" @@ -395,7 +399,42 @@ func main() { hr = gin.New() hr.Use(gin.Recovery()) } - r.GET("/getid", server.GetIDHandler) + if !conf.Settings.LotusGrpc { + r.GET("/getid", server.GetIDHandler) + } else { + if conf.Settings.Lotus { + // 根据配置决定是否初始化 gRPC 客户端 + if config.GetLotusGrpc() { + serverDir := config.GetServer_dir() + port := conf.Settings.LotusGrpcPort + conn, err := grpc.NewClient(serverDir+":"+strconv.Itoa(port), grpc.WithInsecure()) + if err != nil { + panic(fmt.Sprintf("failed to connect to gRPC server: %v", err)) + } else { + fmt.Printf("成功连接到GRPC服务器: %v\n", serverDir+":50051") + } + //初始化idmap中的全局grpc变量 + idmap.GrpcClient = proto.NewIDMapServiceClient(conn) + } + } else { + // 初始化 gRPC 服务器 + port := conf.Settings.LotusGrpcPort + lis, err := net.Listen("tcp", ":"+strconv.Itoa(port)) // gRPC 监听地址 + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + + grpcServer := grpc.NewServer() + + // 注册 gRPC 服务 + proto.RegisterIDMapServiceServer(grpcServer, &idmap.Server{}) + + log.Println("Starting gRPC server on port :" + strconv.Itoa(port)) // gRPC 端口 + if err := grpcServer.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } + } + } r.GET("/updateport", server.HandleIpupdate) r.POST("/uploadpic", server.UploadBase64ImageHandler(rateLimiter)) r.POST("/uploadpicv2", server.UploadBase64ImageHandlerV2(rateLimiter, apiV2)) diff --git a/proto/idmap.pb.go b/proto/idmap.pb.go new file mode 100644 index 00000000..3c0db060 --- /dev/null +++ b/proto/idmap.pb.go @@ -0,0 +1,2524 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc v4.25.3 +// source: idmap.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 定义请求消息和响应消息 +type StoreIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` +} + +func (x *StoreIDRequest) Reset() { + *x = StoreIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StoreIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreIDRequest) ProtoMessage() {} + +func (x *StoreIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoreIDRequest.ProtoReflect.Descriptor instead. +func (*StoreIDRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{0} +} + +func (x *StoreIDRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +type StoreIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Row int64 `protobuf:"varint,1,opt,name=row,proto3" json:"row,omitempty"` +} + +func (x *StoreIDResponse) Reset() { + *x = StoreIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StoreIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreIDResponse) ProtoMessage() {} + +func (x *StoreIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoreIDResponse.ProtoReflect.Descriptor instead. +func (*StoreIDResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{1} +} + +func (x *StoreIDResponse) GetRow() int64 { + if x != nil { + return x.Row + } + return 0 +} + +type RetrieveRowByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` +} + +func (x *RetrieveRowByIDRequest) Reset() { + *x = RetrieveRowByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRowByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRowByIDRequest) ProtoMessage() {} + +func (x *RetrieveRowByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRowByIDRequest.ProtoReflect.Descriptor instead. +func (*RetrieveRowByIDRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{2} +} + +func (x *RetrieveRowByIDRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +type RetrieveRowByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *RetrieveRowByIDResponse) Reset() { + *x = RetrieveRowByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRowByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRowByIDResponse) ProtoMessage() {} + +func (x *RetrieveRowByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRowByIDResponse.ProtoReflect.Descriptor instead. +func (*RetrieveRowByIDResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{3} +} + +func (x *RetrieveRowByIDResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type WriteConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Section string `protobuf:"bytes,1,opt,name=section,proto3" json:"section,omitempty"` + Subtype string `protobuf:"bytes,2,opt,name=subtype,proto3" json:"subtype,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *WriteConfigRequest) Reset() { + *x = WriteConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WriteConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WriteConfigRequest) ProtoMessage() {} + +func (x *WriteConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WriteConfigRequest.ProtoReflect.Descriptor instead. +func (*WriteConfigRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{4} +} + +func (x *WriteConfigRequest) GetSection() string { + if x != nil { + return x.Section + } + return "" +} + +func (x *WriteConfigRequest) GetSubtype() string { + if x != nil { + return x.Subtype + } + return "" +} + +func (x *WriteConfigRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type WriteConfigResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *WriteConfigResponse) Reset() { + *x = WriteConfigResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WriteConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WriteConfigResponse) ProtoMessage() {} + +func (x *WriteConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WriteConfigResponse.ProtoReflect.Descriptor instead. +func (*WriteConfigResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{5} +} + +func (x *WriteConfigResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type ReadConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Section string `protobuf:"bytes,1,opt,name=section,proto3" json:"section,omitempty"` + Subtype string `protobuf:"bytes,2,opt,name=subtype,proto3" json:"subtype,omitempty"` +} + +func (x *ReadConfigRequest) Reset() { + *x = ReadConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadConfigRequest) ProtoMessage() {} + +func (x *ReadConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadConfigRequest.ProtoReflect.Descriptor instead. +func (*ReadConfigRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{6} +} + +func (x *ReadConfigRequest) GetSection() string { + if x != nil { + return x.Section + } + return "" +} + +func (x *ReadConfigRequest) GetSubtype() string { + if x != nil { + return x.Subtype + } + return "" +} + +type ReadConfigResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *ReadConfigResponse) Reset() { + *x = ReadConfigResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadConfigResponse) ProtoMessage() {} + +func (x *ReadConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadConfigResponse.ProtoReflect.Descriptor instead. +func (*ReadConfigResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{7} +} + +func (x *ReadConfigResponse) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type UpdateVirtualValueRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldVirtualValue int64 `protobuf:"varint,1,opt,name=old_virtual_value,json=oldVirtualValue,proto3" json:"old_virtual_value,omitempty"` + NewVirtualValue int64 `protobuf:"varint,2,opt,name=new_virtual_value,json=newVirtualValue,proto3" json:"new_virtual_value,omitempty"` +} + +func (x *UpdateVirtualValueRequest) Reset() { + *x = UpdateVirtualValueRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVirtualValueRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVirtualValueRequest) ProtoMessage() {} + +func (x *UpdateVirtualValueRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVirtualValueRequest.ProtoReflect.Descriptor instead. +func (*UpdateVirtualValueRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateVirtualValueRequest) GetOldVirtualValue() int64 { + if x != nil { + return x.OldVirtualValue + } + return 0 +} + +func (x *UpdateVirtualValueRequest) GetNewVirtualValue() int64 { + if x != nil { + return x.NewVirtualValue + } + return 0 +} + +type UpdateVirtualValueResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *UpdateVirtualValueResponse) Reset() { + *x = UpdateVirtualValueResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVirtualValueResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVirtualValueResponse) ProtoMessage() {} + +func (x *UpdateVirtualValueResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVirtualValueResponse.ProtoReflect.Descriptor instead. +func (*UpdateVirtualValueResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{9} +} + +func (x *UpdateVirtualValueResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type RetrieveRealValueRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VirtualValue int64 `protobuf:"varint,1,opt,name=virtual_value,json=virtualValue,proto3" json:"virtual_value,omitempty"` +} + +func (x *RetrieveRealValueRequest) Reset() { + *x = RetrieveRealValueRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRealValueRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRealValueRequest) ProtoMessage() {} + +func (x *RetrieveRealValueRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRealValueRequest.ProtoReflect.Descriptor instead. +func (*RetrieveRealValueRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{10} +} + +func (x *RetrieveRealValueRequest) GetVirtualValue() int64 { + if x != nil { + return x.VirtualValue + } + return 0 +} + +type RetrieveRealValueRequestPro struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VirtualValue int64 `protobuf:"varint,1,opt,name=virtual_value,json=virtualValue,proto3" json:"virtual_value,omitempty"` + VirtualValueSub int64 `protobuf:"varint,2,opt,name=virtual_value_sub,json=virtualValueSub,proto3" json:"virtual_value_sub,omitempty"` +} + +func (x *RetrieveRealValueRequestPro) Reset() { + *x = RetrieveRealValueRequestPro{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRealValueRequestPro) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRealValueRequestPro) ProtoMessage() {} + +func (x *RetrieveRealValueRequestPro) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRealValueRequestPro.ProtoReflect.Descriptor instead. +func (*RetrieveRealValueRequestPro) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{11} +} + +func (x *RetrieveRealValueRequestPro) GetVirtualValue() int64 { + if x != nil { + return x.VirtualValue + } + return 0 +} + +func (x *RetrieveRealValueRequestPro) GetVirtualValueSub() int64 { + if x != nil { + return x.VirtualValueSub + } + return 0 +} + +type RetrieveRealValueResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Virtual string `protobuf:"bytes,1,opt,name=virtual,proto3" json:"virtual,omitempty"` + Real string `protobuf:"bytes,2,opt,name=real,proto3" json:"real,omitempty"` +} + +func (x *RetrieveRealValueResponse) Reset() { + *x = RetrieveRealValueResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRealValueResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRealValueResponse) ProtoMessage() {} + +func (x *RetrieveRealValueResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRealValueResponse.ProtoReflect.Descriptor instead. +func (*RetrieveRealValueResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{12} +} + +func (x *RetrieveRealValueResponse) GetVirtual() string { + if x != nil { + return x.Virtual + } + return "" +} + +func (x *RetrieveRealValueResponse) GetReal() string { + if x != nil { + return x.Real + } + return "" +} + +type RetrieveRealValueResponsePro struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Virtual string `protobuf:"bytes,1,opt,name=virtual,proto3" json:"virtual,omitempty"` + Real string `protobuf:"bytes,2,opt,name=real,proto3" json:"real,omitempty"` +} + +func (x *RetrieveRealValueResponsePro) Reset() { + *x = RetrieveRealValueResponsePro{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRealValueResponsePro) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRealValueResponsePro) ProtoMessage() {} + +func (x *RetrieveRealValueResponsePro) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRealValueResponsePro.ProtoReflect.Descriptor instead. +func (*RetrieveRealValueResponsePro) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{13} +} + +func (x *RetrieveRealValueResponsePro) GetVirtual() string { + if x != nil { + return x.Virtual + } + return "" +} + +func (x *RetrieveRealValueResponsePro) GetReal() string { + if x != nil { + return x.Real + } + return "" +} + +type RetrieveVirtualValueRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RealValue string `protobuf:"bytes,1,opt,name=real_value,json=realValue,proto3" json:"real_value,omitempty"` +} + +func (x *RetrieveVirtualValueRequest) Reset() { + *x = RetrieveVirtualValueRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveVirtualValueRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveVirtualValueRequest) ProtoMessage() {} + +func (x *RetrieveVirtualValueRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveVirtualValueRequest.ProtoReflect.Descriptor instead. +func (*RetrieveVirtualValueRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{14} +} + +func (x *RetrieveVirtualValueRequest) GetRealValue() string { + if x != nil { + return x.RealValue + } + return "" +} + +type RetrieveVirtualValueResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Real string `protobuf:"bytes,1,opt,name=real,proto3" json:"real,omitempty"` + Virtual string `protobuf:"bytes,2,opt,name=virtual,proto3" json:"virtual,omitempty"` +} + +func (x *RetrieveVirtualValueResponse) Reset() { + *x = RetrieveVirtualValueResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveVirtualValueResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveVirtualValueResponse) ProtoMessage() {} + +func (x *RetrieveVirtualValueResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveVirtualValueResponse.ProtoReflect.Descriptor instead. +func (*RetrieveVirtualValueResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{15} +} + +func (x *RetrieveVirtualValueResponse) GetReal() string { + if x != nil { + return x.Real + } + return "" +} + +func (x *RetrieveVirtualValueResponse) GetVirtual() string { + if x != nil { + return x.Virtual + } + return "" +} + +type StoreIDProRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` + Subid string `protobuf:"bytes,2,opt,name=subid,proto3" json:"subid,omitempty"` +} + +func (x *StoreIDProRequest) Reset() { + *x = StoreIDProRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StoreIDProRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreIDProRequest) ProtoMessage() {} + +func (x *StoreIDProRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoreIDProRequest.ProtoReflect.Descriptor instead. +func (*StoreIDProRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{16} +} + +func (x *StoreIDProRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +func (x *StoreIDProRequest) GetSubid() string { + if x != nil { + return x.Subid + } + return "" +} + +type StoreIDProResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Row int64 `protobuf:"varint,1,opt,name=row,proto3" json:"row,omitempty"` + SubRow int64 `protobuf:"varint,2,opt,name=sub_row,json=subRow,proto3" json:"sub_row,omitempty"` +} + +func (x *StoreIDProResponse) Reset() { + *x = StoreIDProResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StoreIDProResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreIDProResponse) ProtoMessage() {} + +func (x *StoreIDProResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoreIDProResponse.ProtoReflect.Descriptor instead. +func (*StoreIDProResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{17} +} + +func (x *StoreIDProResponse) GetRow() int64 { + if x != nil { + return x.Row + } + return 0 +} + +func (x *StoreIDProResponse) GetSubRow() int64 { + if x != nil { + return x.SubRow + } + return 0 +} + +type RetrieveRowByIDProRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` + Subid string `protobuf:"bytes,2,opt,name=subid,proto3" json:"subid,omitempty"` +} + +func (x *RetrieveRowByIDProRequest) Reset() { + *x = RetrieveRowByIDProRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRowByIDProRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRowByIDProRequest) ProtoMessage() {} + +func (x *RetrieveRowByIDProRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRowByIDProRequest.ProtoReflect.Descriptor instead. +func (*RetrieveRowByIDProRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{18} +} + +func (x *RetrieveRowByIDProRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +func (x *RetrieveRowByIDProRequest) GetSubid() string { + if x != nil { + return x.Subid + } + return "" +} + +type RetrieveRowByIDProResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Subid string `protobuf:"bytes,2,opt,name=subid,proto3" json:"subid,omitempty"` +} + +func (x *RetrieveRowByIDProResponse) Reset() { + *x = RetrieveRowByIDProResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRowByIDProResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRowByIDProResponse) ProtoMessage() {} + +func (x *RetrieveRowByIDProResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRowByIDProResponse.ProtoReflect.Descriptor instead. +func (*RetrieveRowByIDProResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{19} +} + +func (x *RetrieveRowByIDProResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *RetrieveRowByIDProResponse) GetSubid() string { + if x != nil { + return x.Subid + } + return "" +} + +type RetrieveVirtualValueProRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` + Subid string `protobuf:"bytes,2,opt,name=subid,proto3" json:"subid,omitempty"` +} + +func (x *RetrieveVirtualValueProRequest) Reset() { + *x = RetrieveVirtualValueProRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveVirtualValueProRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveVirtualValueProRequest) ProtoMessage() {} + +func (x *RetrieveVirtualValueProRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveVirtualValueProRequest.ProtoReflect.Descriptor instead. +func (*RetrieveVirtualValueProRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{20} +} + +func (x *RetrieveVirtualValueProRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +func (x *RetrieveVirtualValueProRequest) GetSubid() string { + if x != nil { + return x.Subid + } + return "" +} + +type RetrieveVirtualValueProResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FirstValue string `protobuf:"bytes,1,opt,name=first_value,json=firstValue,proto3" json:"first_value,omitempty"` + SecondValue string `protobuf:"bytes,2,opt,name=second_value,json=secondValue,proto3" json:"second_value,omitempty"` +} + +func (x *RetrieveVirtualValueProResponse) Reset() { + *x = RetrieveVirtualValueProResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveVirtualValueProResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveVirtualValueProResponse) ProtoMessage() {} + +func (x *RetrieveVirtualValueProResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveVirtualValueProResponse.ProtoReflect.Descriptor instead. +func (*RetrieveVirtualValueProResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{21} +} + +func (x *RetrieveVirtualValueProResponse) GetFirstValue() string { + if x != nil { + return x.FirstValue + } + return "" +} + +func (x *RetrieveVirtualValueProResponse) GetSecondValue() string { + if x != nil { + return x.SecondValue + } + return "" +} + +type UpdateVirtualValueProRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldVirtualValue_1 int64 `protobuf:"varint,1,opt,name=old_virtual_value_1,json=oldVirtualValue1,proto3" json:"old_virtual_value_1,omitempty"` + NewVirtualValue_1 int64 `protobuf:"varint,2,opt,name=new_virtual_value_1,json=newVirtualValue1,proto3" json:"new_virtual_value_1,omitempty"` + OldVirtualValue_2 int64 `protobuf:"varint,3,opt,name=old_virtual_value_2,json=oldVirtualValue2,proto3" json:"old_virtual_value_2,omitempty"` + NewVirtualValue_2 int64 `protobuf:"varint,4,opt,name=new_virtual_value_2,json=newVirtualValue2,proto3" json:"new_virtual_value_2,omitempty"` +} + +func (x *UpdateVirtualValueProRequest) Reset() { + *x = UpdateVirtualValueProRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVirtualValueProRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVirtualValueProRequest) ProtoMessage() {} + +func (x *UpdateVirtualValueProRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVirtualValueProRequest.ProtoReflect.Descriptor instead. +func (*UpdateVirtualValueProRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{22} +} + +func (x *UpdateVirtualValueProRequest) GetOldVirtualValue_1() int64 { + if x != nil { + return x.OldVirtualValue_1 + } + return 0 +} + +func (x *UpdateVirtualValueProRequest) GetNewVirtualValue_1() int64 { + if x != nil { + return x.NewVirtualValue_1 + } + return 0 +} + +func (x *UpdateVirtualValueProRequest) GetOldVirtualValue_2() int64 { + if x != nil { + return x.OldVirtualValue_2 + } + return 0 +} + +func (x *UpdateVirtualValueProRequest) GetNewVirtualValue_2() int64 { + if x != nil { + return x.NewVirtualValue_2 + } + return 0 +} + +type UpdateVirtualValueProResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *UpdateVirtualValueProResponse) Reset() { + *x = UpdateVirtualValueProResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVirtualValueProResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVirtualValueProResponse) ProtoMessage() {} + +func (x *UpdateVirtualValueProResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVirtualValueProResponse.ProtoReflect.Descriptor instead. +func (*UpdateVirtualValueProResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{23} +} + +func (x *UpdateVirtualValueProResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type SimplifiedStoreIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` +} + +func (x *SimplifiedStoreIDRequest) Reset() { + *x = SimplifiedStoreIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SimplifiedStoreIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SimplifiedStoreIDRequest) ProtoMessage() {} + +func (x *SimplifiedStoreIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SimplifiedStoreIDRequest.ProtoReflect.Descriptor instead. +func (*SimplifiedStoreIDRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{24} +} + +func (x *SimplifiedStoreIDRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +type SimplifiedStoreIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Row int64 `protobuf:"varint,1,opt,name=row,proto3" json:"row,omitempty"` +} + +func (x *SimplifiedStoreIDResponse) Reset() { + *x = SimplifiedStoreIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SimplifiedStoreIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SimplifiedStoreIDResponse) ProtoMessage() {} + +func (x *SimplifiedStoreIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SimplifiedStoreIDResponse.ProtoReflect.Descriptor instead. +func (*SimplifiedStoreIDResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{25} +} + +func (x *SimplifiedStoreIDResponse) GetRow() int64 { + if x != nil { + return x.Row + } + return 0 +} + +type FindSubKeysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *FindSubKeysRequest) Reset() { + *x = FindSubKeysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindSubKeysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindSubKeysRequest) ProtoMessage() {} + +func (x *FindSubKeysRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindSubKeysRequest.ProtoReflect.Descriptor instead. +func (*FindSubKeysRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{26} +} + +func (x *FindSubKeysRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type FindSubKeysResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keys []string `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +} + +func (x *FindSubKeysResponse) Reset() { + *x = FindSubKeysResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindSubKeysResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindSubKeysResponse) ProtoMessage() {} + +func (x *FindSubKeysResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindSubKeysResponse.ProtoReflect.Descriptor instead. +func (*FindSubKeysResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{27} +} + +func (x *FindSubKeysResponse) GetKeys() []string { + if x != nil { + return x.Keys + } + return nil +} + +type DeleteConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Section string `protobuf:"bytes,1,opt,name=section,proto3" json:"section,omitempty"` + Subtype string `protobuf:"bytes,2,opt,name=subtype,proto3" json:"subtype,omitempty"` +} + +func (x *DeleteConfigRequest) Reset() { + *x = DeleteConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteConfigRequest) ProtoMessage() {} + +func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteConfigRequest.ProtoReflect.Descriptor instead. +func (*DeleteConfigRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{28} +} + +func (x *DeleteConfigRequest) GetSection() string { + if x != nil { + return x.Section + } + return "" +} + +func (x *DeleteConfigRequest) GetSubtype() string { + if x != nil { + return x.Subtype + } + return "" +} + +type DeleteConfigResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *DeleteConfigResponse) Reset() { + *x = DeleteConfigResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteConfigResponse) ProtoMessage() {} + +func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteConfigResponse.ProtoReflect.Descriptor instead. +func (*DeleteConfigResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{29} +} + +func (x *DeleteConfigResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type StoreCacheRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` +} + +func (x *StoreCacheRequest) Reset() { + *x = StoreCacheRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StoreCacheRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreCacheRequest) ProtoMessage() {} + +func (x *StoreCacheRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoreCacheRequest.ProtoReflect.Descriptor instead. +func (*StoreCacheRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{30} +} + +func (x *StoreCacheRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +type StoreCacheResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Row int64 `protobuf:"varint,1,opt,name=row,proto3" json:"row,omitempty"` +} + +func (x *StoreCacheResponse) Reset() { + *x = StoreCacheResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StoreCacheResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreCacheResponse) ProtoMessage() {} + +func (x *StoreCacheResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoreCacheResponse.ProtoReflect.Descriptor instead. +func (*StoreCacheResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{31} +} + +func (x *StoreCacheResponse) GetRow() int64 { + if x != nil { + return x.Row + } + return 0 +} + +type RetrieveRowByCacheRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdOrRow string `protobuf:"bytes,1,opt,name=id_or_row,json=idOrRow,proto3" json:"id_or_row,omitempty"` +} + +func (x *RetrieveRowByCacheRequest) Reset() { + *x = RetrieveRowByCacheRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRowByCacheRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRowByCacheRequest) ProtoMessage() {} + +func (x *RetrieveRowByCacheRequest) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRowByCacheRequest.ProtoReflect.Descriptor instead. +func (*RetrieveRowByCacheRequest) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{32} +} + +func (x *RetrieveRowByCacheRequest) GetIdOrRow() string { + if x != nil { + return x.IdOrRow + } + return "" +} + +type RetrieveRowByCacheResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *RetrieveRowByCacheResponse) Reset() { + *x = RetrieveRowByCacheResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_idmap_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetrieveRowByCacheResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetrieveRowByCacheResponse) ProtoMessage() {} + +func (x *RetrieveRowByCacheResponse) ProtoReflect() protoreflect.Message { + mi := &file_idmap_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetrieveRowByCacheResponse.ProtoReflect.Descriptor instead. +func (*RetrieveRowByCacheResponse) Descriptor() ([]byte, []int) { + return file_idmap_proto_rawDescGZIP(), []int{33} +} + +func (x *RetrieveRowByCacheResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +var File_idmap_proto protoreflect.FileDescriptor + +var file_idmap_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x69, 0x64, 0x6d, 0x61, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2c, 0x0a, + 0x0e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x22, 0x23, 0x0a, 0x0f, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x72, 0x6f, 0x77, + 0x22, 0x34, 0x0a, 0x16, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, + 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x64, + 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, + 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x22, 0x29, 0x0a, 0x17, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, + 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x22, 0x5e, 0x0a, 0x12, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x2d, 0x0a, 0x13, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x47, 0x0a, 0x11, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x12, 0x52, 0x65, 0x61, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x73, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6f, + 0x6c, 0x64, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, + 0x0a, 0x11, 0x6e, 0x65, 0x77, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x65, 0x77, 0x56, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x34, 0x0a, 0x1a, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x3f, 0x0a, 0x18, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, + 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x6e, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x75, + 0x62, 0x22, 0x49, 0x0a, 0x19, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x61, 0x6c, 0x22, 0x4c, 0x0a, 0x1c, + 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x61, 0x6c, 0x22, 0x3c, 0x0a, 0x1b, 0x52, 0x65, + 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x61, + 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4c, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x61, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x22, 0x45, 0x0a, 0x11, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, + 0x44, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, + 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x75, 0x62, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x75, 0x62, 0x69, 0x64, 0x22, 0x3f, 0x0a, + 0x12, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x03, 0x72, 0x6f, 0x77, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x5f, 0x72, 0x6f, 0x77, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x75, 0x62, 0x52, 0x6f, 0x77, 0x22, 0x4d, + 0x0a, 0x19, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, + 0x44, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, + 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x75, 0x62, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x75, 0x62, 0x69, 0x64, 0x22, 0x42, 0x0a, + 0x1a, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, 0x44, + 0x50, 0x72, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x75, 0x62, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x75, 0x62, 0x69, + 0x64, 0x22, 0x52, 0x0a, 0x1e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x75, 0x62, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x75, 0x62, 0x69, 0x64, 0x22, 0x65, 0x0a, 0x1f, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, + 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xda, 0x01, 0x0a, + 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, + 0x13, 0x6f, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x5f, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6f, 0x6c, 0x64, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x12, 0x2d, 0x0a, 0x13, + 0x6e, 0x65, 0x77, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x56, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x12, 0x2d, 0x0a, 0x13, 0x6f, + 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6f, 0x6c, 0x64, 0x56, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, + 0x77, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x32, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x56, 0x69, 0x72, 0x74, + 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x22, 0x39, 0x0a, 0x1d, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, + 0x72, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x36, 0x0a, 0x18, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x22, 0x2d, 0x0a, 0x19, + 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, + 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x6f, 0x77, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x72, 0x6f, 0x77, 0x22, 0x24, 0x0a, 0x12, 0x46, + 0x69, 0x6e, 0x64, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x22, 0x29, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x49, 0x0a, 0x13, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2e, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x2f, 0x0a, 0x11, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, + 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x22, 0x26, 0x0a, 0x12, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x72, 0x6f, 0x77, + 0x22, 0x37, 0x0a, 0x19, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, + 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x69, 0x64, 0x4f, 0x72, 0x52, 0x6f, 0x77, 0x22, 0x2c, 0x0a, 0x1a, 0x52, 0x65, 0x74, + 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x32, 0xe4, 0x09, 0x0a, 0x0c, 0x49, 0x44, 0x4d, 0x61, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x09, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x49, 0x44, 0x56, 0x32, 0x12, 0x0f, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x11, 0x52, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, 0x44, 0x56, 0x32, 0x12, 0x17, 0x2e, + 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, 0x44, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, + 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0d, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, + 0x32, 0x12, 0x13, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, + 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x12, 0x2e, 0x52, + 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x13, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x56, 0x32, 0x12, 0x1a, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x13, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, + 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x56, 0x32, 0x12, 0x19, 0x2e, + 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, + 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x16, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, + 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x56, 0x32, 0x50, 0x72, 0x6f, 0x12, 0x1c, + 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x1a, 0x1d, 0x2e, 0x52, + 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x12, 0x55, 0x0a, 0x16, 0x52, + 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x56, 0x32, 0x12, 0x1c, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, + 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x56, 0x32, 0x50, + 0x72, 0x6f, 0x12, 0x12, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x50, 0x72, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, + 0x50, 0x72, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x52, + 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, 0x44, 0x56, 0x32, + 0x50, 0x72, 0x6f, 0x12, 0x1a, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, + 0x77, 0x42, 0x79, 0x49, 0x44, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1b, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x49, + 0x44, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x19, + 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x56, 0x32, 0x50, 0x72, 0x6f, 0x12, 0x1f, 0x2e, 0x52, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x50, 0x72, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x52, 0x65, 0x74, + 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x50, 0x72, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x17, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x56, 0x32, 0x50, 0x72, 0x6f, 0x12, 0x1d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x6f, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x56, 0x32, 0x12, 0x19, 0x2e, + 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, + 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x75, 0x62, 0x4b, + 0x65, 0x79, 0x73, 0x42, 0x79, 0x49, 0x64, 0x50, 0x72, 0x6f, 0x12, 0x13, 0x2e, 0x46, 0x69, 0x6e, + 0x64, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x14, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x56, 0x32, 0x12, 0x12, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, + 0x14, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, 0x79, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x56, 0x32, 0x12, 0x1a, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, + 0x52, 0x6f, 0x77, 0x42, 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1b, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x52, 0x6f, 0x77, 0x42, + 0x79, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2a, + 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x73, + 0x68, 0x69, 0x6e, 0x6f, 0x6e, 0x79, 0x61, 0x72, 0x75, 0x6b, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x73, + 0x6f, 0x6b, 0x79, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_idmap_proto_rawDescOnce sync.Once + file_idmap_proto_rawDescData = file_idmap_proto_rawDesc +) + +func file_idmap_proto_rawDescGZIP() []byte { + file_idmap_proto_rawDescOnce.Do(func() { + file_idmap_proto_rawDescData = protoimpl.X.CompressGZIP(file_idmap_proto_rawDescData) + }) + return file_idmap_proto_rawDescData +} + +var file_idmap_proto_msgTypes = make([]protoimpl.MessageInfo, 34) +var file_idmap_proto_goTypes = []interface{}{ + (*StoreIDRequest)(nil), // 0: StoreIDRequest + (*StoreIDResponse)(nil), // 1: StoreIDResponse + (*RetrieveRowByIDRequest)(nil), // 2: RetrieveRowByIDRequest + (*RetrieveRowByIDResponse)(nil), // 3: RetrieveRowByIDResponse + (*WriteConfigRequest)(nil), // 4: WriteConfigRequest + (*WriteConfigResponse)(nil), // 5: WriteConfigResponse + (*ReadConfigRequest)(nil), // 6: ReadConfigRequest + (*ReadConfigResponse)(nil), // 7: ReadConfigResponse + (*UpdateVirtualValueRequest)(nil), // 8: UpdateVirtualValueRequest + (*UpdateVirtualValueResponse)(nil), // 9: UpdateVirtualValueResponse + (*RetrieveRealValueRequest)(nil), // 10: RetrieveRealValueRequest + (*RetrieveRealValueRequestPro)(nil), // 11: RetrieveRealValueRequestPro + (*RetrieveRealValueResponse)(nil), // 12: RetrieveRealValueResponse + (*RetrieveRealValueResponsePro)(nil), // 13: RetrieveRealValueResponsePro + (*RetrieveVirtualValueRequest)(nil), // 14: RetrieveVirtualValueRequest + (*RetrieveVirtualValueResponse)(nil), // 15: RetrieveVirtualValueResponse + (*StoreIDProRequest)(nil), // 16: StoreIDProRequest + (*StoreIDProResponse)(nil), // 17: StoreIDProResponse + (*RetrieveRowByIDProRequest)(nil), // 18: RetrieveRowByIDProRequest + (*RetrieveRowByIDProResponse)(nil), // 19: RetrieveRowByIDProResponse + (*RetrieveVirtualValueProRequest)(nil), // 20: RetrieveVirtualValueProRequest + (*RetrieveVirtualValueProResponse)(nil), // 21: RetrieveVirtualValueProResponse + (*UpdateVirtualValueProRequest)(nil), // 22: UpdateVirtualValueProRequest + (*UpdateVirtualValueProResponse)(nil), // 23: UpdateVirtualValueProResponse + (*SimplifiedStoreIDRequest)(nil), // 24: SimplifiedStoreIDRequest + (*SimplifiedStoreIDResponse)(nil), // 25: SimplifiedStoreIDResponse + (*FindSubKeysRequest)(nil), // 26: FindSubKeysRequest + (*FindSubKeysResponse)(nil), // 27: FindSubKeysResponse + (*DeleteConfigRequest)(nil), // 28: DeleteConfigRequest + (*DeleteConfigResponse)(nil), // 29: DeleteConfigResponse + (*StoreCacheRequest)(nil), // 30: StoreCacheRequest + (*StoreCacheResponse)(nil), // 31: StoreCacheResponse + (*RetrieveRowByCacheRequest)(nil), // 32: RetrieveRowByCacheRequest + (*RetrieveRowByCacheResponse)(nil), // 33: RetrieveRowByCacheResponse +} +var file_idmap_proto_depIdxs = []int32{ + 0, // 0: IDMapService.StoreIDV2:input_type -> StoreIDRequest + 2, // 1: IDMapService.RetrieveRowByIDV2:input_type -> RetrieveRowByIDRequest + 4, // 2: IDMapService.WriteConfigV2:input_type -> WriteConfigRequest + 6, // 3: IDMapService.ReadConfigV2:input_type -> ReadConfigRequest + 8, // 4: IDMapService.UpdateVirtualValueV2:input_type -> UpdateVirtualValueRequest + 10, // 5: IDMapService.RetrieveRealValueV2:input_type -> RetrieveRealValueRequest + 11, // 6: IDMapService.RetrieveRealValueV2Pro:input_type -> RetrieveRealValueRequestPro + 14, // 7: IDMapService.RetrieveVirtualValueV2:input_type -> RetrieveVirtualValueRequest + 16, // 8: IDMapService.StoreIDV2Pro:input_type -> StoreIDProRequest + 18, // 9: IDMapService.RetrieveRowByIDV2Pro:input_type -> RetrieveRowByIDProRequest + 20, // 10: IDMapService.RetrieveVirtualValueV2Pro:input_type -> RetrieveVirtualValueProRequest + 22, // 11: IDMapService.UpdateVirtualValueV2Pro:input_type -> UpdateVirtualValueProRequest + 24, // 12: IDMapService.SimplifiedStoreIDV2:input_type -> SimplifiedStoreIDRequest + 26, // 13: IDMapService.FindSubKeysByIdPro:input_type -> FindSubKeysRequest + 28, // 14: IDMapService.DeleteConfigV2:input_type -> DeleteConfigRequest + 30, // 15: IDMapService.StoreCacheV2:input_type -> StoreCacheRequest + 32, // 16: IDMapService.RetrieveRowByCacheV2:input_type -> RetrieveRowByCacheRequest + 1, // 17: IDMapService.StoreIDV2:output_type -> StoreIDResponse + 3, // 18: IDMapService.RetrieveRowByIDV2:output_type -> RetrieveRowByIDResponse + 5, // 19: IDMapService.WriteConfigV2:output_type -> WriteConfigResponse + 7, // 20: IDMapService.ReadConfigV2:output_type -> ReadConfigResponse + 9, // 21: IDMapService.UpdateVirtualValueV2:output_type -> UpdateVirtualValueResponse + 12, // 22: IDMapService.RetrieveRealValueV2:output_type -> RetrieveRealValueResponse + 13, // 23: IDMapService.RetrieveRealValueV2Pro:output_type -> RetrieveRealValueResponsePro + 15, // 24: IDMapService.RetrieveVirtualValueV2:output_type -> RetrieveVirtualValueResponse + 17, // 25: IDMapService.StoreIDV2Pro:output_type -> StoreIDProResponse + 19, // 26: IDMapService.RetrieveRowByIDV2Pro:output_type -> RetrieveRowByIDProResponse + 21, // 27: IDMapService.RetrieveVirtualValueV2Pro:output_type -> RetrieveVirtualValueProResponse + 23, // 28: IDMapService.UpdateVirtualValueV2Pro:output_type -> UpdateVirtualValueProResponse + 25, // 29: IDMapService.SimplifiedStoreIDV2:output_type -> SimplifiedStoreIDResponse + 27, // 30: IDMapService.FindSubKeysByIdPro:output_type -> FindSubKeysResponse + 29, // 31: IDMapService.DeleteConfigV2:output_type -> DeleteConfigResponse + 31, // 32: IDMapService.StoreCacheV2:output_type -> StoreCacheResponse + 33, // 33: IDMapService.RetrieveRowByCacheV2:output_type -> RetrieveRowByCacheResponse + 17, // [17:34] is the sub-list for method output_type + 0, // [0:17] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_idmap_proto_init() } +func file_idmap_proto_init() { + if File_idmap_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_idmap_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoreIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoreIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRowByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRowByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WriteConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WriteConfigResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadConfigResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVirtualValueRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVirtualValueResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRealValueRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRealValueRequestPro); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRealValueResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRealValueResponsePro); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveVirtualValueRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveVirtualValueResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoreIDProRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoreIDProResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRowByIDProRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRowByIDProResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveVirtualValueProRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveVirtualValueProResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVirtualValueProRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVirtualValueProResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SimplifiedStoreIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SimplifiedStoreIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindSubKeysRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindSubKeysResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteConfigResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoreCacheRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StoreCacheResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRowByCacheRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_idmap_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetrieveRowByCacheResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_idmap_proto_rawDesc, + NumEnums: 0, + NumMessages: 34, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_idmap_proto_goTypes, + DependencyIndexes: file_idmap_proto_depIdxs, + MessageInfos: file_idmap_proto_msgTypes, + }.Build() + File_idmap_proto = out.File + file_idmap_proto_rawDesc = nil + file_idmap_proto_goTypes = nil + file_idmap_proto_depIdxs = nil +} diff --git a/proto/idmap.proto b/proto/idmap.proto new file mode 100644 index 00000000..b94c0ac5 --- /dev/null +++ b/proto/idmap.proto @@ -0,0 +1,179 @@ +syntax = "proto3"; + +option go_package = "github.com/hoshinonyaruko/gensokyo/proto"; + +// 定义服务 +service IDMapService { + rpc StoreIDV2(StoreIDRequest) returns (StoreIDResponse); + rpc RetrieveRowByIDV2(RetrieveRowByIDRequest) returns (RetrieveRowByIDResponse); + rpc WriteConfigV2(WriteConfigRequest) returns (WriteConfigResponse); + rpc ReadConfigV2(ReadConfigRequest) returns (ReadConfigResponse); + rpc UpdateVirtualValueV2(UpdateVirtualValueRequest) returns (UpdateVirtualValueResponse); + rpc RetrieveRealValueV2(RetrieveRealValueRequest) returns (RetrieveRealValueResponse); + rpc RetrieveRealValueV2Pro(RetrieveRealValueRequestPro) returns (RetrieveRealValueResponsePro); + rpc RetrieveVirtualValueV2(RetrieveVirtualValueRequest) returns (RetrieveVirtualValueResponse); + rpc StoreIDV2Pro(StoreIDProRequest) returns (StoreIDProResponse); + rpc RetrieveRowByIDV2Pro(RetrieveRowByIDProRequest) returns (RetrieveRowByIDProResponse); + rpc RetrieveVirtualValueV2Pro(RetrieveVirtualValueProRequest) returns (RetrieveVirtualValueProResponse); + rpc UpdateVirtualValueV2Pro(UpdateVirtualValueProRequest) returns (UpdateVirtualValueProResponse); + rpc SimplifiedStoreIDV2(SimplifiedStoreIDRequest) returns (SimplifiedStoreIDResponse); + rpc FindSubKeysByIdPro(FindSubKeysRequest) returns (FindSubKeysResponse); + rpc DeleteConfigV2(DeleteConfigRequest) returns (DeleteConfigResponse); + rpc StoreCacheV2(StoreCacheRequest) returns (StoreCacheResponse); + rpc RetrieveRowByCacheV2(RetrieveRowByCacheRequest) returns (RetrieveRowByCacheResponse); +} + +// 定义请求消息和响应消息 +message StoreIDRequest { + string id_or_row = 1; +} + +message StoreIDResponse { + int64 row = 1; +} + +message RetrieveRowByIDRequest { + string id_or_row = 1; +} + +message RetrieveRowByIDResponse { + string id = 1; +} + +message WriteConfigRequest { + string section = 1; + string subtype = 2; + string value = 3; +} + +message WriteConfigResponse { + string status = 1; +} + +message ReadConfigRequest { + string section = 1; + string subtype = 2; +} + +message ReadConfigResponse { + string value = 1; +} + +message UpdateVirtualValueRequest { + int64 old_virtual_value = 1; + int64 new_virtual_value = 2; +} + +message UpdateVirtualValueResponse { + string status = 1; +} + +message RetrieveRealValueRequest { + int64 virtual_value = 1; +} + +message RetrieveRealValueRequestPro { + int64 virtual_value = 1; + int64 virtual_value_sub = 2; +} + +message RetrieveRealValueResponse { + string virtual = 1; + string real = 2; +} + +message RetrieveRealValueResponsePro { + string virtual = 1; + string real = 2; +} + +message RetrieveVirtualValueRequest { + string real_value = 1; +} + +message RetrieveVirtualValueResponse { + string real = 1; + string virtual = 2; +} + +message StoreIDProRequest { + string id_or_row = 1; + string subid = 2; +} + +message StoreIDProResponse { + int64 row = 1; + int64 sub_row = 2; +} + +message RetrieveRowByIDProRequest { + string id_or_row = 1; + string subid = 2; +} + +message RetrieveRowByIDProResponse { + string id = 1; + string subid = 2; +} + +message RetrieveVirtualValueProRequest { + string id_or_row = 1; + string subid = 2; +} + +message RetrieveVirtualValueProResponse { + string first_value = 1; + string second_value = 2; +} + +message UpdateVirtualValueProRequest { + int64 old_virtual_value_1 = 1; + int64 new_virtual_value_1 = 2; + int64 old_virtual_value_2 = 3; + int64 new_virtual_value_2 = 4; +} + +message UpdateVirtualValueProResponse { + string message = 1; +} + +message SimplifiedStoreIDRequest { + string id_or_row = 1; +} + +message SimplifiedStoreIDResponse { + int64 row = 1; +} + +message FindSubKeysRequest { + string id = 1; +} + +message FindSubKeysResponse { + repeated string keys = 1; +} + +message DeleteConfigRequest { + string section = 1; + string subtype = 2; +} + +message DeleteConfigResponse { + string status = 1; +} + +message StoreCacheRequest { + string id_or_row = 1; +} + +message StoreCacheResponse { + int64 row = 1; +} + +message RetrieveRowByCacheRequest { + string id_or_row = 1; +} + +message RetrieveRowByCacheResponse { + string id = 1; +} diff --git a/proto/idmap_grpc.pb.go b/proto/idmap_grpc.pb.go new file mode 100644 index 00000000..c062ef65 --- /dev/null +++ b/proto/idmap_grpc.pb.go @@ -0,0 +1,677 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// IDMapServiceClient is the client API for IDMapService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type IDMapServiceClient interface { + StoreIDV2(ctx context.Context, in *StoreIDRequest, opts ...grpc.CallOption) (*StoreIDResponse, error) + RetrieveRowByIDV2(ctx context.Context, in *RetrieveRowByIDRequest, opts ...grpc.CallOption) (*RetrieveRowByIDResponse, error) + WriteConfigV2(ctx context.Context, in *WriteConfigRequest, opts ...grpc.CallOption) (*WriteConfigResponse, error) + ReadConfigV2(ctx context.Context, in *ReadConfigRequest, opts ...grpc.CallOption) (*ReadConfigResponse, error) + UpdateVirtualValueV2(ctx context.Context, in *UpdateVirtualValueRequest, opts ...grpc.CallOption) (*UpdateVirtualValueResponse, error) + RetrieveRealValueV2(ctx context.Context, in *RetrieveRealValueRequest, opts ...grpc.CallOption) (*RetrieveRealValueResponse, error) + RetrieveRealValueV2Pro(ctx context.Context, in *RetrieveRealValueRequestPro, opts ...grpc.CallOption) (*RetrieveRealValueResponsePro, error) + RetrieveVirtualValueV2(ctx context.Context, in *RetrieveVirtualValueRequest, opts ...grpc.CallOption) (*RetrieveVirtualValueResponse, error) + StoreIDV2Pro(ctx context.Context, in *StoreIDProRequest, opts ...grpc.CallOption) (*StoreIDProResponse, error) + RetrieveRowByIDV2Pro(ctx context.Context, in *RetrieveRowByIDProRequest, opts ...grpc.CallOption) (*RetrieveRowByIDProResponse, error) + RetrieveVirtualValueV2Pro(ctx context.Context, in *RetrieveVirtualValueProRequest, opts ...grpc.CallOption) (*RetrieveVirtualValueProResponse, error) + UpdateVirtualValueV2Pro(ctx context.Context, in *UpdateVirtualValueProRequest, opts ...grpc.CallOption) (*UpdateVirtualValueProResponse, error) + SimplifiedStoreIDV2(ctx context.Context, in *SimplifiedStoreIDRequest, opts ...grpc.CallOption) (*SimplifiedStoreIDResponse, error) + FindSubKeysByIdPro(ctx context.Context, in *FindSubKeysRequest, opts ...grpc.CallOption) (*FindSubKeysResponse, error) + DeleteConfigV2(ctx context.Context, in *DeleteConfigRequest, opts ...grpc.CallOption) (*DeleteConfigResponse, error) + StoreCacheV2(ctx context.Context, in *StoreCacheRequest, opts ...grpc.CallOption) (*StoreCacheResponse, error) + RetrieveRowByCacheV2(ctx context.Context, in *RetrieveRowByCacheRequest, opts ...grpc.CallOption) (*RetrieveRowByCacheResponse, error) +} + +type iDMapServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewIDMapServiceClient(cc grpc.ClientConnInterface) IDMapServiceClient { + return &iDMapServiceClient{cc} +} + +func (c *iDMapServiceClient) StoreIDV2(ctx context.Context, in *StoreIDRequest, opts ...grpc.CallOption) (*StoreIDResponse, error) { + out := new(StoreIDResponse) + err := c.cc.Invoke(ctx, "/IDMapService/StoreIDV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveRowByIDV2(ctx context.Context, in *RetrieveRowByIDRequest, opts ...grpc.CallOption) (*RetrieveRowByIDResponse, error) { + out := new(RetrieveRowByIDResponse) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveRowByIDV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) WriteConfigV2(ctx context.Context, in *WriteConfigRequest, opts ...grpc.CallOption) (*WriteConfigResponse, error) { + out := new(WriteConfigResponse) + err := c.cc.Invoke(ctx, "/IDMapService/WriteConfigV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) ReadConfigV2(ctx context.Context, in *ReadConfigRequest, opts ...grpc.CallOption) (*ReadConfigResponse, error) { + out := new(ReadConfigResponse) + err := c.cc.Invoke(ctx, "/IDMapService/ReadConfigV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) UpdateVirtualValueV2(ctx context.Context, in *UpdateVirtualValueRequest, opts ...grpc.CallOption) (*UpdateVirtualValueResponse, error) { + out := new(UpdateVirtualValueResponse) + err := c.cc.Invoke(ctx, "/IDMapService/UpdateVirtualValueV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveRealValueV2(ctx context.Context, in *RetrieveRealValueRequest, opts ...grpc.CallOption) (*RetrieveRealValueResponse, error) { + out := new(RetrieveRealValueResponse) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveRealValueV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveRealValueV2Pro(ctx context.Context, in *RetrieveRealValueRequestPro, opts ...grpc.CallOption) (*RetrieveRealValueResponsePro, error) { + out := new(RetrieveRealValueResponsePro) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveRealValueV2Pro", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveVirtualValueV2(ctx context.Context, in *RetrieveVirtualValueRequest, opts ...grpc.CallOption) (*RetrieveVirtualValueResponse, error) { + out := new(RetrieveVirtualValueResponse) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveVirtualValueV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) StoreIDV2Pro(ctx context.Context, in *StoreIDProRequest, opts ...grpc.CallOption) (*StoreIDProResponse, error) { + out := new(StoreIDProResponse) + err := c.cc.Invoke(ctx, "/IDMapService/StoreIDV2Pro", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveRowByIDV2Pro(ctx context.Context, in *RetrieveRowByIDProRequest, opts ...grpc.CallOption) (*RetrieveRowByIDProResponse, error) { + out := new(RetrieveRowByIDProResponse) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveRowByIDV2Pro", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveVirtualValueV2Pro(ctx context.Context, in *RetrieveVirtualValueProRequest, opts ...grpc.CallOption) (*RetrieveVirtualValueProResponse, error) { + out := new(RetrieveVirtualValueProResponse) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveVirtualValueV2Pro", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) UpdateVirtualValueV2Pro(ctx context.Context, in *UpdateVirtualValueProRequest, opts ...grpc.CallOption) (*UpdateVirtualValueProResponse, error) { + out := new(UpdateVirtualValueProResponse) + err := c.cc.Invoke(ctx, "/IDMapService/UpdateVirtualValueV2Pro", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) SimplifiedStoreIDV2(ctx context.Context, in *SimplifiedStoreIDRequest, opts ...grpc.CallOption) (*SimplifiedStoreIDResponse, error) { + out := new(SimplifiedStoreIDResponse) + err := c.cc.Invoke(ctx, "/IDMapService/SimplifiedStoreIDV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) FindSubKeysByIdPro(ctx context.Context, in *FindSubKeysRequest, opts ...grpc.CallOption) (*FindSubKeysResponse, error) { + out := new(FindSubKeysResponse) + err := c.cc.Invoke(ctx, "/IDMapService/FindSubKeysByIdPro", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) DeleteConfigV2(ctx context.Context, in *DeleteConfigRequest, opts ...grpc.CallOption) (*DeleteConfigResponse, error) { + out := new(DeleteConfigResponse) + err := c.cc.Invoke(ctx, "/IDMapService/DeleteConfigV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) StoreCacheV2(ctx context.Context, in *StoreCacheRequest, opts ...grpc.CallOption) (*StoreCacheResponse, error) { + out := new(StoreCacheResponse) + err := c.cc.Invoke(ctx, "/IDMapService/StoreCacheV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iDMapServiceClient) RetrieveRowByCacheV2(ctx context.Context, in *RetrieveRowByCacheRequest, opts ...grpc.CallOption) (*RetrieveRowByCacheResponse, error) { + out := new(RetrieveRowByCacheResponse) + err := c.cc.Invoke(ctx, "/IDMapService/RetrieveRowByCacheV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// IDMapServiceServer is the server API for IDMapService service. +// All implementations must embed UnimplementedIDMapServiceServer +// for forward compatibility +type IDMapServiceServer interface { + StoreIDV2(context.Context, *StoreIDRequest) (*StoreIDResponse, error) + RetrieveRowByIDV2(context.Context, *RetrieveRowByIDRequest) (*RetrieveRowByIDResponse, error) + WriteConfigV2(context.Context, *WriteConfigRequest) (*WriteConfigResponse, error) + ReadConfigV2(context.Context, *ReadConfigRequest) (*ReadConfigResponse, error) + UpdateVirtualValueV2(context.Context, *UpdateVirtualValueRequest) (*UpdateVirtualValueResponse, error) + RetrieveRealValueV2(context.Context, *RetrieveRealValueRequest) (*RetrieveRealValueResponse, error) + RetrieveRealValueV2Pro(context.Context, *RetrieveRealValueRequestPro) (*RetrieveRealValueResponsePro, error) + RetrieveVirtualValueV2(context.Context, *RetrieveVirtualValueRequest) (*RetrieveVirtualValueResponse, error) + StoreIDV2Pro(context.Context, *StoreIDProRequest) (*StoreIDProResponse, error) + RetrieveRowByIDV2Pro(context.Context, *RetrieveRowByIDProRequest) (*RetrieveRowByIDProResponse, error) + RetrieveVirtualValueV2Pro(context.Context, *RetrieveVirtualValueProRequest) (*RetrieveVirtualValueProResponse, error) + UpdateVirtualValueV2Pro(context.Context, *UpdateVirtualValueProRequest) (*UpdateVirtualValueProResponse, error) + SimplifiedStoreIDV2(context.Context, *SimplifiedStoreIDRequest) (*SimplifiedStoreIDResponse, error) + FindSubKeysByIdPro(context.Context, *FindSubKeysRequest) (*FindSubKeysResponse, error) + DeleteConfigV2(context.Context, *DeleteConfigRequest) (*DeleteConfigResponse, error) + StoreCacheV2(context.Context, *StoreCacheRequest) (*StoreCacheResponse, error) + RetrieveRowByCacheV2(context.Context, *RetrieveRowByCacheRequest) (*RetrieveRowByCacheResponse, error) + mustEmbedUnimplementedIDMapServiceServer() +} + +// UnimplementedIDMapServiceServer must be embedded to have forward compatible implementations. +type UnimplementedIDMapServiceServer struct { +} + +func (UnimplementedIDMapServiceServer) StoreIDV2(context.Context, *StoreIDRequest) (*StoreIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StoreIDV2 not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveRowByIDV2(context.Context, *RetrieveRowByIDRequest) (*RetrieveRowByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveRowByIDV2 not implemented") +} +func (UnimplementedIDMapServiceServer) WriteConfigV2(context.Context, *WriteConfigRequest) (*WriteConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method WriteConfigV2 not implemented") +} +func (UnimplementedIDMapServiceServer) ReadConfigV2(context.Context, *ReadConfigRequest) (*ReadConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadConfigV2 not implemented") +} +func (UnimplementedIDMapServiceServer) UpdateVirtualValueV2(context.Context, *UpdateVirtualValueRequest) (*UpdateVirtualValueResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVirtualValueV2 not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveRealValueV2(context.Context, *RetrieveRealValueRequest) (*RetrieveRealValueResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveRealValueV2 not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveRealValueV2Pro(context.Context, *RetrieveRealValueRequestPro) (*RetrieveRealValueResponsePro, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveRealValueV2Pro not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveVirtualValueV2(context.Context, *RetrieveVirtualValueRequest) (*RetrieveVirtualValueResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveVirtualValueV2 not implemented") +} +func (UnimplementedIDMapServiceServer) StoreIDV2Pro(context.Context, *StoreIDProRequest) (*StoreIDProResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StoreIDV2Pro not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveRowByIDV2Pro(context.Context, *RetrieveRowByIDProRequest) (*RetrieveRowByIDProResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveRowByIDV2Pro not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveVirtualValueV2Pro(context.Context, *RetrieveVirtualValueProRequest) (*RetrieveVirtualValueProResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveVirtualValueV2Pro not implemented") +} +func (UnimplementedIDMapServiceServer) UpdateVirtualValueV2Pro(context.Context, *UpdateVirtualValueProRequest) (*UpdateVirtualValueProResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVirtualValueV2Pro not implemented") +} +func (UnimplementedIDMapServiceServer) SimplifiedStoreIDV2(context.Context, *SimplifiedStoreIDRequest) (*SimplifiedStoreIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SimplifiedStoreIDV2 not implemented") +} +func (UnimplementedIDMapServiceServer) FindSubKeysByIdPro(context.Context, *FindSubKeysRequest) (*FindSubKeysResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindSubKeysByIdPro not implemented") +} +func (UnimplementedIDMapServiceServer) DeleteConfigV2(context.Context, *DeleteConfigRequest) (*DeleteConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteConfigV2 not implemented") +} +func (UnimplementedIDMapServiceServer) StoreCacheV2(context.Context, *StoreCacheRequest) (*StoreCacheResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StoreCacheV2 not implemented") +} +func (UnimplementedIDMapServiceServer) RetrieveRowByCacheV2(context.Context, *RetrieveRowByCacheRequest) (*RetrieveRowByCacheResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetrieveRowByCacheV2 not implemented") +} +func (UnimplementedIDMapServiceServer) mustEmbedUnimplementedIDMapServiceServer() {} + +// UnsafeIDMapServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to IDMapServiceServer will +// result in compilation errors. +type UnsafeIDMapServiceServer interface { + mustEmbedUnimplementedIDMapServiceServer() +} + +func RegisterIDMapServiceServer(s grpc.ServiceRegistrar, srv IDMapServiceServer) { + s.RegisterService(&IDMapService_ServiceDesc, srv) +} + +func _IDMapService_StoreIDV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoreIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).StoreIDV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/StoreIDV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).StoreIDV2(ctx, req.(*StoreIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveRowByIDV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveRowByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveRowByIDV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveRowByIDV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveRowByIDV2(ctx, req.(*RetrieveRowByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_WriteConfigV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WriteConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).WriteConfigV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/WriteConfigV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).WriteConfigV2(ctx, req.(*WriteConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_ReadConfigV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReadConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).ReadConfigV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/ReadConfigV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).ReadConfigV2(ctx, req.(*ReadConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_UpdateVirtualValueV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVirtualValueRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).UpdateVirtualValueV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/UpdateVirtualValueV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).UpdateVirtualValueV2(ctx, req.(*UpdateVirtualValueRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveRealValueV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveRealValueRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveRealValueV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveRealValueV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveRealValueV2(ctx, req.(*RetrieveRealValueRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveRealValueV2Pro_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveRealValueRequestPro) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveRealValueV2Pro(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveRealValueV2Pro", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveRealValueV2Pro(ctx, req.(*RetrieveRealValueRequestPro)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveVirtualValueV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveVirtualValueRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveVirtualValueV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveVirtualValueV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveVirtualValueV2(ctx, req.(*RetrieveVirtualValueRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_StoreIDV2Pro_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoreIDProRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).StoreIDV2Pro(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/StoreIDV2Pro", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).StoreIDV2Pro(ctx, req.(*StoreIDProRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveRowByIDV2Pro_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveRowByIDProRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveRowByIDV2Pro(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveRowByIDV2Pro", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveRowByIDV2Pro(ctx, req.(*RetrieveRowByIDProRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveVirtualValueV2Pro_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveVirtualValueProRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveVirtualValueV2Pro(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveVirtualValueV2Pro", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveVirtualValueV2Pro(ctx, req.(*RetrieveVirtualValueProRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_UpdateVirtualValueV2Pro_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVirtualValueProRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).UpdateVirtualValueV2Pro(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/UpdateVirtualValueV2Pro", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).UpdateVirtualValueV2Pro(ctx, req.(*UpdateVirtualValueProRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_SimplifiedStoreIDV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SimplifiedStoreIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).SimplifiedStoreIDV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/SimplifiedStoreIDV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).SimplifiedStoreIDV2(ctx, req.(*SimplifiedStoreIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_FindSubKeysByIdPro_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindSubKeysRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).FindSubKeysByIdPro(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/FindSubKeysByIdPro", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).FindSubKeysByIdPro(ctx, req.(*FindSubKeysRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_DeleteConfigV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).DeleteConfigV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/DeleteConfigV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).DeleteConfigV2(ctx, req.(*DeleteConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_StoreCacheV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoreCacheRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).StoreCacheV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/StoreCacheV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).StoreCacheV2(ctx, req.(*StoreCacheRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IDMapService_RetrieveRowByCacheV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetrieveRowByCacheRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDMapServiceServer).RetrieveRowByCacheV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/IDMapService/RetrieveRowByCacheV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDMapServiceServer).RetrieveRowByCacheV2(ctx, req.(*RetrieveRowByCacheRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// IDMapService_ServiceDesc is the grpc.ServiceDesc for IDMapService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var IDMapService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "IDMapService", + HandlerType: (*IDMapServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "StoreIDV2", + Handler: _IDMapService_StoreIDV2_Handler, + }, + { + MethodName: "RetrieveRowByIDV2", + Handler: _IDMapService_RetrieveRowByIDV2_Handler, + }, + { + MethodName: "WriteConfigV2", + Handler: _IDMapService_WriteConfigV2_Handler, + }, + { + MethodName: "ReadConfigV2", + Handler: _IDMapService_ReadConfigV2_Handler, + }, + { + MethodName: "UpdateVirtualValueV2", + Handler: _IDMapService_UpdateVirtualValueV2_Handler, + }, + { + MethodName: "RetrieveRealValueV2", + Handler: _IDMapService_RetrieveRealValueV2_Handler, + }, + { + MethodName: "RetrieveRealValueV2Pro", + Handler: _IDMapService_RetrieveRealValueV2Pro_Handler, + }, + { + MethodName: "RetrieveVirtualValueV2", + Handler: _IDMapService_RetrieveVirtualValueV2_Handler, + }, + { + MethodName: "StoreIDV2Pro", + Handler: _IDMapService_StoreIDV2Pro_Handler, + }, + { + MethodName: "RetrieveRowByIDV2Pro", + Handler: _IDMapService_RetrieveRowByIDV2Pro_Handler, + }, + { + MethodName: "RetrieveVirtualValueV2Pro", + Handler: _IDMapService_RetrieveVirtualValueV2Pro_Handler, + }, + { + MethodName: "UpdateVirtualValueV2Pro", + Handler: _IDMapService_UpdateVirtualValueV2Pro_Handler, + }, + { + MethodName: "SimplifiedStoreIDV2", + Handler: _IDMapService_SimplifiedStoreIDV2_Handler, + }, + { + MethodName: "FindSubKeysByIdPro", + Handler: _IDMapService_FindSubKeysByIdPro_Handler, + }, + { + MethodName: "DeleteConfigV2", + Handler: _IDMapService_DeleteConfigV2_Handler, + }, + { + MethodName: "StoreCacheV2", + Handler: _IDMapService_StoreCacheV2_Handler, + }, + { + MethodName: "RetrieveRowByCacheV2", + Handler: _IDMapService_RetrieveRowByCacheV2_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "idmap.proto", +} diff --git a/structs/structs.go b/structs/structs.go index d81b4766..390ce9a5 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -34,12 +34,15 @@ type Settings struct { HashID bool `yaml:"hash_id"` IdmapPro bool `yaml:"idmap_pro"` //gensokyo互联类 - Server_dir string `yaml:"server_dir"` - Port string `yaml:"port"` - BackupPort string `yaml:"backup_port"` - Lotus bool `yaml:"lotus"` - LotusPassword string `yaml:"lotus_password"` - LotusWithoutIdmaps bool `yaml:"lotus_without_idmaps"` + Server_dir string `yaml:"server_dir"` + Port string `yaml:"port"` + BackupPort string `yaml:"backup_port"` + Lotus bool `yaml:"lotus"` + LotusPassword string `yaml:"lotus_password"` + LotusWithoutIdmaps bool `yaml:"lotus_without_idmaps"` + LotusWithoutUploadPic bool `yaml:"lotus_without_uploadpic"` + LotusGrpc bool `yaml:"lotus_grpc"` + LotusGrpcPort int `yaml:"lotus_grpc_port"` //增强配置 MasterID []string `yaml:"master_id"` RecordSampleRate int `yaml:"record_sampleRate"` diff --git a/template/config_template.go b/template/config_template.go index 0ca4c670..9c25bd11 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -52,6 +52,9 @@ settings: lotus: false # lotus特性默认为false,当为true时,将会连接到另一个lotus为false的gensokyo。使用它提供的图床和idmaps服务(场景:同一个机器人在不同服务器运行,或内网需要发送base64图)。如果需要发送base64图片,需要设置正确的公网server_dir和开放对应的port, lotus鉴权 设置后,从gsk需要保持相同密码来访问主gsk lotus_password : "" lotus_without_idmaps: false #lotus只通过url,图片上传,语音,不通过id转换,在本地当前gsk维护idmaps转换. + lotus_without_uploadpic : false #lotus只转换id,不进行图片上传. + lotus_grpc : false #实验特性,使用grpc进行lotus连接.提高性能. + lotus_grpc_port : 50051 #grpc的端口,连接与被连接需保持一致.并且在防火墙放通此端口. #增强配置项 master_id : ["1","2"] #群场景尚未开放获取管理员和列表能力,手动从日志中获取需要设置为管理,的user_id并填入(适用插件有权限判断场景) From 5c312cd34f4775a07694d7dd9e4eb5098e4cb66e Mon Sep 17 00:00:00 2001 From: cosmo Date: Fri, 12 Jul 2024 11:38:34 +0800 Subject: [PATCH 16/36] beta461 --- config/config.go | 582 ++++++++++++++++++------------------ structs/structs.go | 7 +- template/config_template.go | 3 +- wsclient/ws.go | 4 +- 4 files changed, 306 insertions(+), 290 deletions(-) diff --git a/config/config.go b/config/config.go index 8aa180ef..e2da9a17 100644 --- a/config/config.go +++ b/config/config.go @@ -20,7 +20,7 @@ import ( var ( instance *Config - mu sync.Mutex + mu sync.RWMutex ) type Config struct { @@ -585,8 +585,8 @@ func DeleteConfig() error { // 获取ws地址数组 func GetWsAddress() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.WsAddress } @@ -595,8 +595,8 @@ func GetWsAddress() []string { // 获取gensokyo服务的地址 func GetServer_dir() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get upload directory.") @@ -607,8 +607,8 @@ func GetServer_dir() string { // 获取DevBotid func GetDevBotid() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get DevBotid.") @@ -619,8 +619,8 @@ func GetDevBotid() string { // 获取GetForwardMsgLimit func GetForwardMsgLimit() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get GetForwardMsgLimit.") @@ -631,8 +631,8 @@ func GetForwardMsgLimit() int { // 获取Develop_Acdir服务的地址 func GetDevelop_Acdir() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get DevlopAcDir.") @@ -643,8 +643,8 @@ func GetDevelop_Acdir() string { // 获取lotus的值 func GetLotusValue() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get lotus value.") @@ -655,8 +655,8 @@ func GetLotusValue() bool { // 获取双向ehco func GetTwoWayEcho() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get lotus value.") @@ -667,8 +667,8 @@ func GetTwoWayEcho() bool { // 获取白名单开启状态 func GetWhitePrefixMode() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetWhitePrefixModes value.") @@ -679,8 +679,8 @@ func GetWhitePrefixMode() bool { // 获取白名单指令数组 func GetWhitePrefixs() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.WhitePrefixs } @@ -689,8 +689,8 @@ func GetWhitePrefixs() []string { // 获取黑名单开启状态 func GetBlackPrefixMode() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetBlackPrefixMode value.") @@ -701,8 +701,8 @@ func GetBlackPrefixMode() bool { // 获取黑名单指令数组 func GetBlackPrefixs() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.BlackPrefixs } @@ -711,8 +711,8 @@ func GetBlackPrefixs() []string { // 获取IPurl显示开启状态 func GetVisibleIP() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetVisibleIP value.") @@ -723,8 +723,8 @@ func GetVisibleIP() bool { // 修改 GetVisualkPrefixs 函数以返回新类型 func GetVisualkPrefixs() []structs.VisualPrefixConfig { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { var varvisualPrefixes []structs.VisualPrefixConfig for _, vp := range instance.Settings.VisualPrefixs { @@ -741,8 +741,8 @@ func GetVisualkPrefixs() []structs.VisualPrefixConfig { // 获取LazyMessageId状态 func GetLazyMessageId() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get LazyMessageId value.") @@ -753,8 +753,8 @@ func GetLazyMessageId() bool { // 获取HashID func GetHashIDValue() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get hashid value.") @@ -765,8 +765,8 @@ func GetHashIDValue() bool { // 获取RemoveAt的值 func GetRemoveAt() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get RemoveAt value.") @@ -777,8 +777,8 @@ func GetRemoveAt() bool { // 获取port的值 func GetPortValue() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get port value.") @@ -789,8 +789,8 @@ func GetPortValue() string { // 获取Array的值 func GetArrayValue() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get array value.") @@ -801,8 +801,8 @@ func GetArrayValue() bool { // 获取AppID func GetAppID() uint64 { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.AppID } @@ -811,8 +811,8 @@ func GetAppID() uint64 { // 获取AppID String func GetAppIDStr() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return fmt.Sprintf("%d", instance.Settings.AppID) } @@ -821,8 +821,8 @@ func GetAppIDStr() string { // 获取WsToken func GetWsToken() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.WsToken } @@ -831,8 +831,8 @@ func GetWsToken() []string { // 获取MasterID数组 func GetMasterID() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.MasterID } @@ -841,8 +841,8 @@ func GetMasterID() []string { // 获取port的值 func GetEnableWsServer() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get port value.") @@ -853,8 +853,8 @@ func GetEnableWsServer() bool { // 获取WsServerToken的值 func GetWsServerToken() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get WsServerToken value.") @@ -865,8 +865,8 @@ func GetWsServerToken() string { // 获取identify_file的值 func GetIdentifyFile() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get identify file name.") @@ -877,8 +877,8 @@ func GetIdentifyFile() bool { // 获取crt路径 func GetCrtPath() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get crt path.") @@ -889,8 +889,8 @@ func GetCrtPath() string { // 获取key路径 func GetKeyPath() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get key path.") @@ -901,8 +901,8 @@ func GetKeyPath() string { // 开发者日志 func GetDeveloperLog() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get developer log status.") @@ -957,8 +957,8 @@ func ComposeWebUIURLv2(useBackupPort bool) string { // GetServerUserName 获取服务器用户名 func GetServerUserName() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get server user name.") @@ -969,8 +969,8 @@ func GetServerUserName() string { // GetServerUserPassword 获取服务器用户密码 func GetServerUserPassword() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get server user password.") @@ -981,8 +981,8 @@ func GetServerUserPassword() string { // GetImageLimit 返回 ImageLimit 的值 func GetImageLimit() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get image limit value.") @@ -994,8 +994,8 @@ func GetImageLimit() int { // GetRemovePrefixValue 函数用于获取 remove_prefix 的配置值 func GetRemovePrefixValue() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get remove_prefix value.") @@ -1006,8 +1006,8 @@ func GetRemovePrefixValue() bool { // GetLotusPort retrieves the LotusPort setting from your singleton instance. func GetBackupPort() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get LotusPort.") @@ -1019,8 +1019,8 @@ func GetBackupPort() string { // 获取GetDevMsgID的值 func GetDevMsgID() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetDevMsgID value.") @@ -1031,8 +1031,8 @@ func GetDevMsgID() bool { // 获取GetSaveLogs的值 func GetSaveLogs() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetSaveLogs value.") @@ -1043,8 +1043,8 @@ func GetSaveLogs() bool { // 获取GetSaveLogs的值 func GetLogLevel() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetLogLevel value.") @@ -1055,8 +1055,8 @@ func GetLogLevel() int { // 获取GetBindPrefix的值 func GetBindPrefix() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetBindPrefix value.") @@ -1067,8 +1067,8 @@ func GetBindPrefix() string { // 获取GetMePrefix的值 func GetMePrefix() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetMePrefix value.") @@ -1079,8 +1079,8 @@ func GetMePrefix() string { // 获取FrpPort的值 func GetFrpPort() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetFrpPort value.") @@ -1091,8 +1091,8 @@ func GetFrpPort() string { // 获取GetRemoveBotAtGroup的值 func GetRemoveBotAtGroup() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetRemoveBotAtGroup value.") @@ -1103,8 +1103,8 @@ func GetRemoveBotAtGroup() bool { // 获取ImageLimitB的值 func GetImageLimitB() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to ImageLimitB value.") @@ -1115,8 +1115,8 @@ func GetImageLimitB() int { // GetRecordSampleRate 返回 RecordSampleRate的值 func GetRecordSampleRate() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetRecordSampleRate value.") @@ -1128,8 +1128,8 @@ func GetRecordSampleRate() int { // GetRecordBitRate 返回 RecordBitRate func GetRecordBitRate() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetRecordBitRate value.") @@ -1141,8 +1141,8 @@ func GetRecordBitRate() int { // 获取NoWhiteResponse的值 func GetNoWhiteResponse() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to NoWhiteResponse value.") @@ -1153,8 +1153,8 @@ func GetNoWhiteResponse() string { // 获取GetSendError的值 func GetSendError() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetSendError value.") @@ -1165,8 +1165,8 @@ func GetSendError() bool { // 获取GetSaveError的值 func GetSaveError() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetSaveError value.") @@ -1177,8 +1177,8 @@ func GetSaveError() bool { // 获取GetAddAtGroup的值 func GetAddAtGroup() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetAddGroupAt value.") @@ -1189,8 +1189,8 @@ func GetAddAtGroup() bool { // 获取GetUrlPicTransfer的值 func GetUrlPicTransfer() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetUrlPicTransfer value.") @@ -1201,8 +1201,8 @@ func GetUrlPicTransfer() bool { // 获取GetLotusPassword的值 func GetLotusPassword() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetLotusPassword value.") @@ -1213,8 +1213,8 @@ func GetLotusPassword() string { // 获取GetWsServerPath的值 func GetWsServerPath() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetWsServerPath value.") @@ -1225,8 +1225,8 @@ func GetWsServerPath() string { // 获取GetIdmapPro的值 func GetIdmapPro() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetIdmapPro value.") @@ -1237,8 +1237,8 @@ func GetIdmapPro() bool { // 获取GetCardAndNick的值 func GetCardAndNick() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetCardAndNick value.") @@ -1249,8 +1249,8 @@ func GetCardAndNick() string { // 获取GetAutoBind的值 func GetAutoBind() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetAutoBind value.") @@ -1261,8 +1261,8 @@ func GetAutoBind() bool { // 获取GetCustomBotName的值 func GetCustomBotName() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetCustomBotName value.") @@ -1273,8 +1273,8 @@ func GetCustomBotName() string { // 获取send_delay的值 func GetSendDelay() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetSendDelay value.") @@ -1285,8 +1285,8 @@ func GetSendDelay() int { // 获取GetAtoPCount的值 func GetAtoPCount() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to AtoPCount value.") @@ -1297,8 +1297,8 @@ func GetAtoPCount() int { // 获取GetReconnecTimes的值 func GetReconnecTimes() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to ReconnecTimes value.") @@ -1309,8 +1309,8 @@ func GetReconnecTimes() int { // 获取GetHeartBeatInterval的值 func GetHeartBeatInterval() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to HeartBeatInterval value.") @@ -1321,8 +1321,8 @@ func GetHeartBeatInterval() int { // 获取LaunchReconectTimes func GetLaunchReconectTimes() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to LaunchReconectTimes value.") @@ -1333,8 +1333,8 @@ func GetLaunchReconectTimes() int { // 获取GetUnlockPrefix func GetUnlockPrefix() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to UnlockPrefix value.") @@ -1345,8 +1345,8 @@ func GetUnlockPrefix() string { // 获取白名单例外群数组 func GetWhiteBypass() []int64 { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.WhiteBypass } @@ -1355,8 +1355,8 @@ func GetWhiteBypass() []int64 { // 获取GetTransferUrl的值 func GetTransferUrl() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetTransferUrl value.") @@ -1367,8 +1367,8 @@ func GetTransferUrl() bool { // 获取 HTTP 地址 func GetHttpAddress() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get HTTP address.") @@ -1379,8 +1379,8 @@ func GetHttpAddress() string { // 获取 HTTP 访问令牌 func GetHTTPAccessToken() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get HTTP access token.") @@ -1391,8 +1391,8 @@ func GetHTTPAccessToken() string { // 获取 HTTP 版本 func GetHttpVersion() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get HTTP version.") @@ -1403,8 +1403,8 @@ func GetHttpVersion() int { // 获取 HTTP 超时时间 func GetHttpTimeOut() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get HTTP timeout.") @@ -1415,8 +1415,8 @@ func GetHttpTimeOut() int { // 获取 POST URL 数组 func GetPostUrl() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get POST URL.") @@ -1427,8 +1427,8 @@ func GetPostUrl() []string { // 获取 POST 密钥数组 func GetPostSecret() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get POST secret.") @@ -1439,8 +1439,8 @@ func GetPostSecret() []string { // 获取 VisualPrefixsBypass func GetVisualPrefixsBypass() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to getVisualPrefixsBypass.") @@ -1451,8 +1451,8 @@ func GetVisualPrefixsBypass() []string { // 获取 POST 最大重试次数数组 func GetPostMaxRetries() []int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get POST max retries.") @@ -1463,8 +1463,8 @@ func GetPostMaxRetries() []int { // 获取 POST 重试间隔数组 func GetPostRetriesInterval() []int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get POST retries interval.") @@ -1475,8 +1475,8 @@ func GetPostRetriesInterval() []int { // 获取GetTransferUrl的值 func GetNativeOb11() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to NativeOb11 value.") @@ -1487,8 +1487,8 @@ func GetNativeOb11() bool { // 获取GetRamDomSeq的值 func GetRamDomSeq() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetRamDomSeq value.") @@ -1499,8 +1499,8 @@ func GetRamDomSeq() bool { // 获取GetUrlToQrimage的值 func GetUrlToQrimage() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetUrlToQrimage value.") @@ -1510,8 +1510,8 @@ func GetUrlToQrimage() bool { } func GetUseUin() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to UseUin value.") @@ -1522,8 +1522,8 @@ func GetUseUin() bool { // 获取GetQrSize的值 func GetQrSize() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to QrSize value.") @@ -1575,8 +1575,8 @@ func GetQrSize() int { // 获取GetWhiteBypassRevers的值 func GetWhiteBypassRevers() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetWhiteBypassRevers value.") @@ -1587,8 +1587,8 @@ func GetWhiteBypassRevers() bool { // 获取GetGuildUrlImageToBase64的值 func GetGuildUrlImageToBase64() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GuildUrlImageToBase64 value.") @@ -1599,8 +1599,8 @@ func GetGuildUrlImageToBase64() bool { // GetTencentBucketURL 获取 TencentBucketURL func GetTencentBucketURL() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get TencentBucketURL.") @@ -1621,8 +1621,8 @@ func GetTencentBucketURL() string { // GetTencentCosSecretid 获取 TencentCosSecretid func GetTencentCosSecretid() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get TencentCosSecretid.") @@ -1633,8 +1633,8 @@ func GetTencentCosSecretid() string { // GetTencentSecretKey 获取 TencentSecretKey func GetTencentSecretKey() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get TencentSecretKey.") @@ -1645,8 +1645,8 @@ func GetTencentSecretKey() string { // 获取GetTencentAudit的值 func GetTencentAudit() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to TencentAudit value.") @@ -1657,8 +1657,8 @@ func GetTencentAudit() bool { // 获取 Oss 模式 func GetOssType() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get ExtraPicAuditingType version.") @@ -1669,8 +1669,8 @@ func GetOssType() int { // 获取BaiduBOSBucketName func GetBaiduBOSBucketName() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get BaiduBOSBucketName.") @@ -1681,8 +1681,8 @@ func GetBaiduBOSBucketName() string { // 获取BaiduBCEAK func GetBaiduBCEAK() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get BaiduBCEAK.") @@ -1693,8 +1693,8 @@ func GetBaiduBCEAK() string { // 获取BaiduBCESK func GetBaiduBCESK() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get BaiduBCESK.") @@ -1705,8 +1705,8 @@ func GetBaiduBCESK() string { // 获取BaiduAudit func GetBaiduAudit() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get BaiduAudit.") @@ -1717,8 +1717,8 @@ func GetBaiduAudit() int { // 获取阿里云的oss地址 外网的 func GetAliyunEndpoint() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get AliyunEndpoint.") @@ -1755,8 +1755,8 @@ func GetRegionID() string { // GetAliyunAccessKeyId 获取阿里云OSS的AccessKeyId func GetAliyunAccessKeyId() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get AliyunAccessKeyId.") @@ -1767,8 +1767,8 @@ func GetAliyunAccessKeyId() string { // GetAliyunAccessKeySecret 获取阿里云OSS的AccessKeySecret func GetAliyunAccessKeySecret() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get AliyunAccessKeySecret.") @@ -1779,8 +1779,8 @@ func GetAliyunAccessKeySecret() string { // GetAliyunBucketName 获取阿里云OSS的AliyunBucketName func GetAliyunBucketName() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get AliyunBucketName.") @@ -1791,8 +1791,8 @@ func GetAliyunBucketName() string { // 获取GetAliyunAudit的值 func GetAliyunAudit() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to AliyunAudit value.") @@ -1803,8 +1803,8 @@ func GetAliyunAudit() bool { // 获取Alias的值 func GetAlias() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.Alias } @@ -1813,8 +1813,8 @@ func GetAlias() []string { // 获取SelfIntroduce的值 func GetSelfIntroduce() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.SelfIntroduce } @@ -1823,8 +1823,8 @@ func GetSelfIntroduce() []string { // 获取WhiteEnable的值 func GetWhiteEnable(index int) bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() // 检查instance或instance.Settings.WhiteEnable是否为nil if instance == nil || instance.Settings.WhiteEnable == nil { @@ -1845,8 +1845,8 @@ func GetWhiteEnable(index int) bool { // 获取IdentifyAppids的值 func GetIdentifyAppids() []int64 { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.IdentifyAppids } @@ -1855,8 +1855,8 @@ func GetIdentifyAppids() []int64 { // 获取 TransFormApiIds 的值 func GetTransFormApiIds() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to TransFormApiIds value.") @@ -1867,8 +1867,8 @@ func GetTransFormApiIds() bool { // 获取 CustomTemplateID 的值 func GetCustomTemplateID() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get CustomTemplateID.") @@ -1879,8 +1879,8 @@ func GetCustomTemplateID() string { // 获取 KeyBoardIDD 的值 func GetKeyBoardID() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get KeyBoardID.") @@ -1891,8 +1891,8 @@ func GetKeyBoardID() string { // 获取Uin int64 func GetUinint64() int64 { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.Uin } @@ -1901,8 +1901,8 @@ func GetUinint64() int64 { // 获取Uin String func GetUinStr() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return fmt.Sprintf("%d", instance.Settings.Uin) } @@ -1911,8 +1911,8 @@ func GetUinStr() string { // 获取 VV GetVwhitePrefixMode 的值 func GetVwhitePrefixMode() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to VwhitePrefixMode value.") @@ -1923,8 +1923,8 @@ func GetVwhitePrefixMode() bool { // 获取Enters的值 func GetEnters() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.Enters } @@ -1933,8 +1933,8 @@ func GetEnters() []string { // 获取EntersExcept func GetEntersExcept() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.EntersExcept } @@ -1943,8 +1943,8 @@ func GetEntersExcept() []string { // 获取 LinkPrefix func GetLinkPrefix() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get LinkPrefix.") @@ -1955,8 +1955,8 @@ func GetLinkPrefix() string { // 获取 LinkBots 数组 func GetLinkBots() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get LinkBots.") @@ -1967,8 +1967,8 @@ func GetLinkBots() []string { // 获取 LinkText func GetLinkText() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get LinkText.") @@ -1979,8 +1979,8 @@ func GetLinkText() string { // 获取 LinkPic func GetLinkPic() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get LinkPic.") @@ -1991,8 +1991,8 @@ func GetLinkPic() string { // 获取 GetMusicPrefix func GetMusicPrefix() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get MusicPrefix.") @@ -2003,8 +2003,8 @@ func GetMusicPrefix() string { // 获取 GetDisableWebui 的值 func GetDisableWebui() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetDisableWebui value.") @@ -2015,8 +2015,8 @@ func GetDisableWebui() bool { // 获取 GetBotForumTitle func GetBotForumTitle() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get BotForumTitle.") @@ -2027,8 +2027,8 @@ func GetBotForumTitle() string { // 获取 GetGlobalInteractionToMessage 的值 func GetGlobalInteractionToMessage() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GlobalInteractionToMessage value.") @@ -2039,8 +2039,8 @@ func GetGlobalInteractionToMessage() bool { // 获取 AutoPutInteraction 的值 func GetAutoPutInteraction() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to AutoPutInteraction value.") @@ -2051,8 +2051,8 @@ func GetAutoPutInteraction() bool { // 获取 PutInteractionDelay 延迟 func GetPutInteractionDelay() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get PutInteractionDelay.") @@ -2063,8 +2063,8 @@ func GetPutInteractionDelay() int { // 获取Fix11300开关 func GetFix11300() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to Fix11300 value.") @@ -2075,8 +2075,8 @@ func GetFix11300() bool { // 获取LotusWithoutIdmaps开关 func GetLotusWithoutIdmaps() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to LotusWithoutIdmaps value.") @@ -2087,8 +2087,8 @@ func GetLotusWithoutIdmaps() bool { // 获取GetGroupListAllGuilds开关 func GetGroupListAllGuilds() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetGroupListAllGuilds value.") @@ -2099,8 +2099,8 @@ func GetGroupListAllGuilds() bool { // 获取 GetGroupListGuilds 数量 func GetGetGroupListGuilds() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get GetGroupListGuilds.") @@ -2111,8 +2111,8 @@ func GetGetGroupListGuilds() string { // 获取GetGroupListReturnGuilds开关 func GetGroupListReturnGuilds() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GetGroupListReturnGuilds value.") @@ -2123,8 +2123,8 @@ func GetGroupListReturnGuilds() bool { // 获取 GetGroupListGuidsType 数量 func GetGroupListGuidsType() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get GetGroupListGuidsType.") @@ -2135,8 +2135,8 @@ func GetGroupListGuidsType() int { // 获取 GetGroupListDelay 数量 func GetGroupListDelay() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get GetGroupListDelay.") @@ -2147,8 +2147,8 @@ func GetGroupListDelay() int { // 获取GetGlobalServerTempQQguild开关 func GetGlobalServerTempQQguild() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GlobalServerTempQQguild value.") @@ -2159,8 +2159,8 @@ func GetGlobalServerTempQQguild() bool { // 获取ServerTempQQguild func GetServerTempQQguild() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to ServerTempQQguild value.") @@ -2171,8 +2171,8 @@ func GetServerTempQQguild() string { // 获取ServerTempQQguildPool func GetServerTempQQguildPool() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.ServerTempQQguildPool } @@ -2181,8 +2181,8 @@ func GetServerTempQQguildPool() []string { // 获取UploadPicV2Base64开关 func GetUploadPicV2Base64() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to UploadPicV2 value.") @@ -2193,8 +2193,8 @@ func GetUploadPicV2Base64() bool { // 获取 AutoWithdraw 数组 func GetAutoWithdraw() []string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get AutoWithdraw.") @@ -2205,8 +2205,8 @@ func GetAutoWithdraw() []string { // 获取 GetAutoWithdrawTime 数量 func GetAutoWithdrawTime() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to get AutoWithdrawTime.") @@ -2217,8 +2217,8 @@ func GetAutoWithdrawTime() int { // 获取DefaultChangeWord func GetDefaultChangeWord() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.DefaultChangeWord } @@ -2227,8 +2227,8 @@ func GetDefaultChangeWord() string { // 获取敏感词替换状态 func GetEnableChangeWord() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to EnableChangeWord.") @@ -2239,8 +2239,8 @@ func GetEnableChangeWord() bool { // 获取GlobalGroupMsgRejectReciveEventToMessage状态 func GetGlobalGroupMsgRejectReciveEventToMessage() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to GlobalGroupMsgRejectReciveEventToMessage.") @@ -2251,8 +2251,8 @@ func GetGlobalGroupMsgRejectReciveEventToMessage() bool { // 获取GlobalGroupMsgRejectMessage func GetGlobalGroupMsgRejectMessage() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.GlobalGroupMsgRejectMessage } @@ -2261,8 +2261,8 @@ func GetGlobalGroupMsgRejectMessage() string { // 获取GlobalGroupMsgRejectMessage func GetGlobalGroupMsgReceiveMessage() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.GlobalGroupMsgReceiveMessage } @@ -2271,8 +2271,8 @@ func GetGlobalGroupMsgReceiveMessage() string { // 获取EntersAsBlock状态 func GetEntersAsBlock() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to EntersAsBlock.") @@ -2283,8 +2283,8 @@ func GetEntersAsBlock() bool { // 获取NativeMD状态 func GetNativeMD() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to NativeMD.") @@ -2295,8 +2295,8 @@ func GetNativeMD() bool { // 获取DowntimeMessage func GetDowntimeMessage() string { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance != nil { return instance.Settings.DowntimeMessage } @@ -2305,8 +2305,8 @@ func GetDowntimeMessage() string { // 获取GetAutoLink的值 func GetAutoLink() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to AutoLink value.") @@ -2317,8 +2317,8 @@ func GetAutoLink() bool { // 获取GetLinkLines的值 func GetLinkLines() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to LinkLines value.") @@ -2330,8 +2330,8 @@ func GetLinkLines() int { // 获取GetLinkNum的值 func GetLinkNum() int { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to LinkNum value.") @@ -2343,8 +2343,8 @@ func GetLinkNum() int { // 获取GetDoNotReplaceAppid的值 func GetDoNotReplaceAppid() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to DoNotReplaceAppid value.") @@ -2355,8 +2355,8 @@ func GetDoNotReplaceAppid() bool { // 获取GetMemoryMsgid的值 func GetMemoryMsgid() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to MemoryMsgid value.") @@ -2367,8 +2367,8 @@ func GetMemoryMsgid() bool { // 获取GetLotusGrpc的值 func GetLotusGrpc() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to LotusGrpc value.") @@ -2379,8 +2379,8 @@ func GetLotusGrpc() bool { // 获取LotusWithoutUploadPic的值 func GetLotusWithoutUploadPic() bool { - mu.Lock() - defer mu.Unlock() + mu.RLock() + defer mu.RUnlock() if instance == nil { mylog.Println("Warning: instance is nil when trying to LotusWithoutUploadPic value.") @@ -2388,3 +2388,15 @@ func GetLotusWithoutUploadPic() bool { } return instance.Settings.LotusWithoutUploadPic } + +// 获取DisableErrorChan的值 +func GetDisableErrorChan() bool { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to DisableErrorChan value.") + return false + } + return instance.Settings.DisableErrorChan +} diff --git a/structs/structs.go b/structs/structs.go index 390ce9a5..b8b61106 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -120,9 +120,10 @@ type Settings struct { AutoPutInteraction bool `yaml:"auto_put_interaction"` PutInteractionDelay int `yaml:"put_interaction_delay"` //onebot修改 - TwoWayEcho bool `yaml:"twoway_echo"` - Array bool `yaml:"array"` - NativeOb11 bool `yaml:"native_ob11"` + TwoWayEcho bool `yaml:"twoway_echo"` + Array bool `yaml:"array"` + NativeOb11 bool `yaml:"native_ob11"` + DisableErrorChan bool `yaml:"disable_error_chan"` //url相关 VisibleIp bool `yaml:"visible_ip"` UrlToQrimage bool `yaml:"url_to_qrimage"` diff --git a/template/config_template.go b/template/config_template.go index 9c25bd11..f952046d 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -157,8 +157,9 @@ settings: #Onebot修改 twoway_echo : false #是否采用双向echo,根据机器人选择,獭獭\早苗 true 红色问答\椛椛 或者其他 请使用 false - array: false # 连接trss云崽请开启array + array: false #连接trss云崽请开启array,是否以segment形式上报信息. native_ob11 : false #如果你的机器人收到事件报错,请开启此选项增加兼容性 + disable_error_chan : false #禁用ws断开时候将信息放入补发频道,当信息非常多时可能导致冲垮应用端,可以设置本选项为true. #URL相关 visible_ip : false #转换url时,如果server_dir是ip true将以ip形式发出url 默认隐藏url 将server_dir配置为自己域名可以转换url diff --git a/wsclient/ws.go b/wsclient/ws.go index f635fd33..e0753463 100644 --- a/wsclient/ws.go +++ b/wsclient/ws.go @@ -45,7 +45,9 @@ func (client *WebSocketClient) SendMessage(message map[string]interface{}) error if err != nil { mylog.Println("Error sending message:", err) // 发送失败,将消息添加到切片 - client.sendFailures = append(client.sendFailures, message) + if !config.GetDisableErrorChan() { + client.sendFailures = append(client.sendFailures, message) + } return err } From 58304eb079fddcd4c9241ebf50988904750f50bf Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 14 Jul 2024 01:35:56 +0800 Subject: [PATCH 17/36] beta462 --- Processor/ProcessInlineSearch.go | 22 ++++++++++- acnode/acnode.go | 12 +++--- config/config.go | 12 ++++++ handlers/message_parser.go | 63 +++++++++++++++++--------------- handlers/send_group_msg.go | 36 +++++++++++++++++- structs/structs.go | 21 ++++++----- template/config_template.go | 1 + 7 files changed, 118 insertions(+), 49 deletions(-) diff --git a/Processor/ProcessInlineSearch.go b/Processor/ProcessInlineSearch.go index 3cdb23db..254c6d89 100644 --- a/Processor/ProcessInlineSearch.go +++ b/Processor/ProcessInlineSearch.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "strconv" + "strings" "sync" "time" @@ -53,10 +54,27 @@ func (p *Processors) ProcessInlineSearch(data *dto.WSInteractionData) error { // 构造echostr,包括AppID,原始的s变量和当前时间戳 echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) - //这里处理自动handle回调回应 + // 这里处理自动handle回调回应 if config.GetAutoPutInteraction() { - DelayedPutInteraction(p.Api, data.ID, fromuid, fromgid) + exceptions := config.GetPutInteractionExcept() // 会返回一个string[],即例外列表 + + shouldCall := true // 默认应该调用DelayedPutInteraction,除非下面的条件匹配 + + // 判断,data.Data.Resolved.ButtonData 是否以返回的string[]中的任意成员开头 + for _, prefix := range exceptions { + if strings.HasPrefix(data.Data.Resolved.ButtonData, prefix) { + shouldCall = false // 如果匹配到任何一个前缀,设置shouldCall为false + break // 找到匹配项,无需继续检查 + } + } + + // 如果data.Data.Resolved.ButtonData不以返回的string[]中的任意成员开头, + // 则调用DelayedPutInteraction,否则不调用 + if shouldCall { + DelayedPutInteraction(p.Api, data.ID, fromuid, fromgid) + } } + if config.GetIdmapPro() { //将真实id转为int userid64 GroupID64, userid64, err = idmap.StoreIDv2Pro(fromgid, fromuid) diff --git a/acnode/acnode.go b/acnode/acnode.go index ba4f917f..4efab6f6 100644 --- a/acnode/acnode.go +++ b/acnode/acnode.go @@ -354,12 +354,14 @@ func CheckWordOUT(word string) string { return "错误:缺少 'word' 参数" } + //不替换base64 + if strings.Contains(word, "base64://") { + // 当word包含特定字符串时原样返回 + //fmt.Printf("原样返回的文本:%s", word) + return word + } + if len([]rune(word)) > 5000 { - if strings.Contains(word, "[CQ:image,file=base64://") { - // 当word包含特定字符串时原样返回 - fmt.Printf("原样返回的文本:%s", word) - return word - } log.Printf("错误请求:字符数超过最大限制(5000字符)。内容:%s", word) return "错误:字符数超过最大限制(5000字符)" } diff --git a/config/config.go b/config/config.go index e2da9a17..61ad5fbf 100644 --- a/config/config.go +++ b/config/config.go @@ -2400,3 +2400,15 @@ func GetDisableErrorChan() bool { } return instance.Settings.DisableErrorChan } + +// 获取 PutInteractionExcept 数组 +func GetPutInteractionExcept() []string { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to get PutInteractionExcept.") + return nil + } + return instance.Settings.PutInteractionExcept +} diff --git a/handlers/message_parser.go b/handlers/message_parser.go index 6c7f9f32..d193dcc6 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -1089,43 +1089,46 @@ func RevertTransformedText(data interface{}, msgtype string, api openapi.OpenAPI } } - //如果二级指令白名单全部是*(忽略自身,那么不判断二级白名单是否匹配) - if allStarPrefixed { - if len(messageText) == len(matchedPrefix.Prefix) { + // 调用 GetVisualPrefixsBypass 获取前缀数组 + visualPrefixes := config.GetVisualPrefixsBypass() + // 判断 messageText 是否以数组中的任一前缀开头 + for _, prefix := range visualPrefixes { + if strings.HasPrefix(originmessageText, prefix) { matched = true + break + } + } + + if !matched { + //如果二级指令白名单全部是*(忽略自身,那么不判断二级白名单是否匹配) + if allStarPrefixed { + if len(messageText) == len(matchedPrefix.Prefix) { + matched = true + } else { + matched = false + } } else { - matched = false - // 调用 GetVisualPrefixsBypass 获取前缀数组 - visualPrefixes := config.GetVisualPrefixsBypass() - // 判断 messageText 是否以数组中的任一前缀开头 - for _, prefix := range visualPrefixes { - if strings.HasPrefix(originmessageText, prefix) { + // 遍历白名单数组,检查是否有匹配项 + for _, prefix := range allPrefixes { + trimmedPrefix := prefix + if strings.HasPrefix(prefix, "*") { + // 如果前缀以 * 开头,则移除 * + trimmedPrefix = strings.TrimPrefix(prefix, "*") + } else if strings.HasPrefix(prefix, "&") { + // 如果前缀以 & 开头,则移除 & 并从 trimmedPrefix 前端去除 matchedPrefix.Prefix + trimmedPrefix = strings.TrimPrefix(prefix, "&") + trimmedPrefix = strings.TrimPrefix(trimmedPrefix, matchedPrefix.Prefix) + } + + // 从trimmedPrefix中去除前后空格 + trimmedPrefix = strings.TrimSpace(trimmedPrefix) + // trimmedPrefix如果是""就会导致任意内容都是true,所以不能是"" + if strings.HasPrefix(messageText, trimmedPrefix) && trimmedPrefix != "" { matched = true break } } } - } else { - // 遍历白名单数组,检查是否有匹配项 - for _, prefix := range allPrefixes { - trimmedPrefix := prefix - if strings.HasPrefix(prefix, "*") { - // 如果前缀以 * 开头,则移除 * - trimmedPrefix = strings.TrimPrefix(prefix, "*") - } else if strings.HasPrefix(prefix, "&") { - // 如果前缀以 & 开头,则移除 & 并从 trimmedPrefix 前端去除 matchedPrefix.Prefix - trimmedPrefix = strings.TrimPrefix(prefix, "&") - trimmedPrefix = strings.TrimPrefix(trimmedPrefix, matchedPrefix.Prefix) - } - - // 从trimmedPrefix中去除前后空格(可能会有bug) - trimmedPrefix = strings.TrimSpace(trimmedPrefix) - // trimmedPrefix如果是""就会导致任意内容都是true,所以不能是"" - if strings.HasPrefix(messageText, trimmedPrefix) && trimmedPrefix != "" { - matched = true - break - } - } } // 如果没有匹配项,则将 messageText 置为对应的兜底回复 diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index e66d1351..450be103 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -990,8 +990,24 @@ func generateGroupMessage(id string, eventid string, foundItems map[string][]str fileRecordData = silk.EncoderSilk(fileRecordData) mylog.Printf("音频转码ing") } + base64Encoded := base64.StdEncoding.EncodeToString(fileRecordData) + if config.GetUploadPicV2Base64() { + // 直接上传语音返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessage(context.TODO(), base64Encoded, eventid, 1, false, "", groupid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传语音失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } // 将解码的语音数据转换回base64格式并上传 - imageURL, err := images.UploadBase64RecordToServer(base64.StdEncoding.EncodeToString(fileRecordData)) + imageURL, err := images.UploadBase64RecordToServer(base64Encoded) if err != nil { mylog.Printf("failed to upload base64 record: %v", err) return nil @@ -1578,8 +1594,24 @@ func generatePrivateMessage(id string, eventid string, foundItems map[string][]s fileRecordData = silk.EncoderSilk(fileRecordData) mylog.Printf("音频转码ing") } + base64Encoded := base64.StdEncoding.EncodeToString(fileRecordData) + if config.GetUploadPicV2Base64() { + // 直接上传语音返回 MessageToCreate type=7 + messageToCreate, err := images.CreateAndUploadMediaMessagePrivate(context.TODO(), base64Encoded, eventid, 1, false, "", userid, id, msgseq, apiv2) + if err != nil { + mylog.Printf("Error messageToCreate: %v", err) + return &dto.MessageToCreate{ + Content: "错误: 上传语音失败", + MsgID: id, + EventID: eventid, + MsgSeq: msgseq, + MsgType: 0, // 默认文本类型 + } + } + return messageToCreate + } // 将解码的语音数据转换回base64格式并上传 - imageURL, err := images.UploadBase64RecordToServer(base64.StdEncoding.EncodeToString(fileRecordData)) + imageURL, err := images.UploadBase64RecordToServer(base64Encoded) if err != nil { mylog.Printf("failed to upload base64 record: %v", err) return nil diff --git a/structs/structs.go b/structs/structs.go index b8b61106..e23552de 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -109,16 +109,17 @@ type Settings struct { //增长营销类 SelfIntroduce []string `yaml:"self_introduce"` //api修改 - GetGroupListAllGuilds bool `yaml:"get_g_list_all_guilds"` - GetGroupListGuilds string `yaml:"get_g_list_guilds"` - GetGroupListReturnGuilds bool `yaml:"get_g_list_return_guilds"` - GetGroupListGuidsType int `yaml:"get_g_list_guilds_type"` - GetGroupListDelay int `yaml:"get_g_list_delay"` - ForwardMsgLimit int `yaml:"forward_msg_limit"` - CustomBotName string `yaml:"custom_bot_name"` - TransFormApiIds bool `yaml:"transform_api_ids"` - AutoPutInteraction bool `yaml:"auto_put_interaction"` - PutInteractionDelay int `yaml:"put_interaction_delay"` + GetGroupListAllGuilds bool `yaml:"get_g_list_all_guilds"` + GetGroupListGuilds string `yaml:"get_g_list_guilds"` + GetGroupListReturnGuilds bool `yaml:"get_g_list_return_guilds"` + GetGroupListGuidsType int `yaml:"get_g_list_guilds_type"` + GetGroupListDelay int `yaml:"get_g_list_delay"` + ForwardMsgLimit int `yaml:"forward_msg_limit"` + CustomBotName string `yaml:"custom_bot_name"` + TransFormApiIds bool `yaml:"transform_api_ids"` + AutoPutInteraction bool `yaml:"auto_put_interaction"` + PutInteractionDelay int `yaml:"put_interaction_delay"` + PutInteractionExcept []string `yaml:"put_interaction_except"` //onebot修改 TwoWayEcho bool `yaml:"twoway_echo"` Array bool `yaml:"array"` diff --git a/template/config_template.go b/template/config_template.go index f952046d..8639f1d7 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -154,6 +154,7 @@ settings: transform_api_ids : true #对get_group_menmber_list\get_group_member_info\get_group_list生效,是否在其中返回转换后的值(默认转换,不转换请自行处理插件逻辑,比如调用gsk的http api转换) auto_put_interaction : false #自动回应按钮回调的/interactions/{interaction_id} 注本api需要邮件申请,详细方法参考群公告:196173384 put_interaction_delay : 0 #单位毫秒 表示回应已收到回调类型的按钮的毫秒数 会按用户进行区分 非全局delay + put_interaction_except : [] #自动回复按钮的例外,当你想要自己用api回复,回复特殊状态时,将指令前缀填入进去(根据按钮的data字段判断的) #Onebot修改 twoway_echo : false #是否采用双向echo,根据机器人选择,獭獭\早苗 true 红色问答\椛椛 或者其他 请使用 false From 7e7c9f3cec448b43aab6dcf10ff85693f5edf47a Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 15 Jul 2024 20:28:15 +0800 Subject: [PATCH 18/36] beta463 --- botgo/sessions/local/local.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/botgo/sessions/local/local.go b/botgo/sessions/local/local.go index 804e72d3..4ca45c9b 100644 --- a/botgo/sessions/local/local.go +++ b/botgo/sessions/local/local.go @@ -69,7 +69,8 @@ func (l *ChanManager) StartSingle(apInfo *dto.WebsocketAPSingle, token *token.To apInfo.ShardCount, startInterval) // 只启动一个分片 - + // 按照1数量初始化,用于启动连接的管理 + l.sessionChan = make(chan dto.Session, 1) session := dto.Session{ URL: apInfo.URL, Token: *token, @@ -80,9 +81,13 @@ func (l *ChanManager) StartSingle(apInfo *dto.WebsocketAPSingle, token *token.To ShardCount: apInfo.ShardCount, }, } + l.sessionChan <- session - time.Sleep(startInterval) - go l.newConnect(session) + for session := range l.sessionChan { + // MaxConcurrency 代表的是每 5s 可以连多少个请求 + time.Sleep(startInterval) + go l.newConnect(session) + } return nil } From 188f2505a1810c060f488e2fe995c10509092991 Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 15 Jul 2024 23:12:18 +0800 Subject: [PATCH 19/36] beta464 --- handlers/send_private_msg.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index 1eb52e4c..443e4f86 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -187,7 +187,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open singleItem[imageType] = []string{imageUrl} msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generatePrivateMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, message.Params.UserID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, UserID) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -233,7 +233,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open if messageText != "" { msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generatePrivateMessage(messageID, eventID, nil, messageText, msgseq+1, apiv2, message.Params.UserID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, nil, messageText, msgseq+1, apiv2, UserID) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) @@ -261,7 +261,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open //mylog.Println("singleItem:", singleItem) msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generatePrivateMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, message.Params.UserID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, singleItem, "", msgseq+1, apiv2, UserID) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -328,7 +328,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open if config.GetSendError() { //把报错当作文本发出去 msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generatePrivateMessage(messageID, eventID, nil, err.Error(), msgseq+1, apiv2, message.Params.UserID.(string)) + groupReply := generatePrivateMessage(messageID, eventID, nil, err.Error(), msgseq+1, apiv2, UserID) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) if !ok { From af0296d510f6c226488ecd9e952625aa11b8da3e Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 18 Jul 2024 18:47:42 +0800 Subject: [PATCH 20/36] beta465 --- Processor/ProcessGroupMessage.go | 339 ++++++++++++++++++++----------- Processor/Processor.go | 23 +++ config/config.go | 24 +++ handlers/get_group_list.go | 105 +++++++--- handlers/send_group_msg.go | 113 ++++++----- handlers/send_group_msg_raw.go | 44 ++-- handlers/send_msg.go | 60 +++--- handlers/send_private_msg.go | 75 ++++--- structs/structs.go | 2 + template/config_template.go | 2 + 10 files changed, 518 insertions(+), 269 deletions(-) diff --git a/Processor/ProcessGroupMessage.go b/Processor/ProcessGroupMessage.go index 2cda94ca..49276aeb 100644 --- a/Processor/ProcessGroupMessage.go +++ b/Processor/ProcessGroupMessage.go @@ -34,38 +34,42 @@ func (p *Processors) ProcessGroupMessage(data *dto.WSGroupATMessageData) error { var userid64 int64 var GroupID64 int64 var err error - if config.GetIdmapPro() { - //将真实id转为int userid64 - GroupID64, userid64, err = idmap.StoreIDv2Pro(data.GroupID, data.Author.ID) - if err != nil { - mylog.Fatalf("Error storing ID: %v", err) - } - //当参数不全 - _, _ = idmap.StoreIDv2(data.GroupID) - _, _ = idmap.StoreIDv2(data.Author.ID) - if !config.GetHashIDValue() { - mylog.Fatalf("避坑日志:你开启了高级id转换,请设置hash_id为true,并且删除idmaps并重启") - } - //补救措施 - idmap.SimplifiedStoreID(data.Author.ID) - //补救措施 - idmap.SimplifiedStoreID(data.GroupID) - //补救措施 - echo.AddMsgIDv3(AppIDString, data.GroupID, data.ID) - } else { - // 映射str的GroupID到int - GroupID64, err = idmap.StoreIDv2(data.GroupID) - if err != nil { - mylog.Errorf("failed to convert GroupID64 to int: %v", err) - return nil - } - // 映射str的userid到int - userid64, err = idmap.StoreIDv2(data.Author.ID) - if err != nil { - mylog.Printf("Error storing ID: %v", err) - return nil + + if !config.GetStringOb11() { + if config.GetIdmapPro() { + //将真实id转为int userid64 + GroupID64, userid64, err = idmap.StoreIDv2Pro(data.GroupID, data.Author.ID) + if err != nil { + mylog.Fatalf("Error storing ID: %v", err) + } + //当参数不全 + _, _ = idmap.StoreIDv2(data.GroupID) + _, _ = idmap.StoreIDv2(data.Author.ID) + if !config.GetHashIDValue() { + mylog.Fatalf("避坑日志:你开启了高级id转换,请设置hash_id为true,并且删除idmaps并重启") + } + //补救措施 + idmap.SimplifiedStoreID(data.Author.ID) + //补救措施 + idmap.SimplifiedStoreID(data.GroupID) + //补救措施 + echo.AddMsgIDv3(AppIDString, data.GroupID, data.ID) + } else { + // 映射str的GroupID到int + GroupID64, err = idmap.StoreIDv2(data.GroupID) + if err != nil { + mylog.Errorf("failed to convert GroupID64 to int: %v", err) + return nil + } + // 映射str的userid到int + userid64, err = idmap.StoreIDv2(data.Author.ID) + if err != nil { + mylog.Printf("Error storing ID: %v", err) + return nil + } } } + // 转换at messageText := handlers.RevertTransformedText(data, "group", p.Api, p.Apiv2, GroupID64, userid64, config.GetWhiteEnable(4)) if messageText == "" { @@ -78,123 +82,218 @@ func (p *Processors) ProcessGroupMessage(data *dto.WSGroupATMessageData) error { } //框架内指令 p.HandleFrameworkCommand(messageText, data, "group") + + var messageID int //映射str的messageID到int - var messageID64 int64 - if config.GetMemoryMsgid() { - messageID64, err = echo.StoreCacheInMemory(data.ID) - if err != nil { - log.Fatalf("Error storing ID: %v", err) - } - } else { - messageID64, err = idmap.StoreCachev2(data.ID) - if err != nil { - log.Fatalf("Error storing ID: %v", err) + if !config.GetStringOb11() { + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } } + messageID = int(messageID64) } - messageID := int(messageID64) + if config.GetAutoBind() { if len(data.Attachments) > 0 && data.Attachments[0].URL != "" { p.Autobind(data) } } + // 如果在Array模式下, 则处理Message为Segment格式 var segmentedMessages interface{} = messageText if config.GetArrayValue() { segmentedMessages = handlers.ConvertToSegmentedMessage(data) } + var IsBindedUserId, IsBindedGroupId bool - if config.GetHashIDValue() { - IsBindedUserId = idmap.CheckValue(data.Author.ID, userid64) - IsBindedGroupId = idmap.CheckValue(data.GroupID, GroupID64) - } else { - IsBindedUserId = idmap.CheckValuev2(userid64) - IsBindedGroupId = idmap.CheckValuev2(GroupID64) + if !config.GetStringOb11() { + if config.GetHashIDValue() { + IsBindedUserId = idmap.CheckValue(data.Author.ID, userid64) + IsBindedGroupId = idmap.CheckValue(data.GroupID, GroupID64) + } else { + IsBindedUserId = idmap.CheckValuev2(userid64) + IsBindedGroupId = idmap.CheckValuev2(GroupID64) + } } + var selfid64 int64 if config.GetUseUin() { selfid64 = config.GetUinint64() } else { selfid64 = int64(p.Settings.AppID) } + //mylog.Printf("回调测试-群:%v\n", segmentedMessages) - groupMsg := OnebotGroupMessage{ - RawMessage: messageText, - Message: segmentedMessages, - MessageID: messageID, - GroupID: GroupID64, - MessageType: "group", - PostType: "message", - SelfID: selfid64, - UserID: userid64, - Sender: Sender{ - UserID: userid64, - Sex: "0", - Age: 0, - Area: "0", - Level: "0", - }, - SubType: "normal", - Time: time.Now().Unix(), - } - //增强配置 - if !config.GetNativeOb11() { - groupMsg.RealMessageType = "group" - groupMsg.IsBindedUserId = IsBindedUserId - groupMsg.IsBindedGroupId = IsBindedGroupId - groupMsg.RealGroupID = data.GroupID - groupMsg.RealUserID = data.Author.ID - groupMsg.Avatar, _ = GenerateAvatarURLV2(data.Author.ID) - } - //根据条件判断是否增加nick和card - var CaN = config.GetCardAndNick() - if CaN != "" { - groupMsg.Sender.Nickname = CaN - groupMsg.Sender.Card = CaN - } - // 根据条件判断是否添加Echo字段 - if config.GetTwoWayEcho() { - groupMsg.Echo = echostr - //用向应用端(如果支持)发送echo,来确定客户端的send_msg对应的触发词原文 - echo.AddMsgIDv3(AppIDString, echostr, messageText) - } - // 获取MasterID数组 - masterIDs := config.GetMasterID() + var groupMsg OnebotGroupMessage + var groupMsgS OnebotGroupMessageS + var groupMsgMap map[string]interface{} - // 判断userid64是否在masterIDs数组里 - isMaster := false - for _, id := range masterIDs { - if strconv.FormatInt(userid64, 10) == id { - isMaster = true - break + // 是否使用string形式上报 + if !config.GetStringOb11() { + groupMsg = OnebotGroupMessage{ + RawMessage: messageText, + Message: segmentedMessages, + MessageID: messageID, + GroupID: GroupID64, + MessageType: "group", + PostType: "message", + SelfID: selfid64, + UserID: userid64, + Sender: Sender{ + UserID: userid64, + Sex: "0", + Age: 0, + Area: "0", + Level: "0", + }, + SubType: "normal", + Time: time.Now().Unix(), } - } + //增强配置 + if !config.GetNativeOb11() { + groupMsg.RealMessageType = "group" + groupMsg.IsBindedUserId = IsBindedUserId + groupMsg.IsBindedGroupId = IsBindedGroupId + groupMsg.RealGroupID = data.GroupID + groupMsg.RealUserID = data.Author.ID + groupMsg.Avatar, _ = GenerateAvatarURLV2(data.Author.ID) + } + //根据条件判断是否增加nick和card + var CaN = config.GetCardAndNick() + if CaN != "" { + groupMsg.Sender.Nickname = CaN + groupMsg.Sender.Card = CaN + } + // 根据条件判断是否添加Echo字段 + if config.GetTwoWayEcho() { + groupMsg.Echo = echostr + //用向应用端(如果支持)发送echo,来确定客户端的send_msg对应的触发词原文 + echo.AddMsgIDv3(AppIDString, echostr, messageText) + } + // 获取MasterID数组 + masterIDs := config.GetMasterID() + + // 判断userid64是否在masterIDs数组里 + isMaster := false + for _, id := range masterIDs { + if strconv.FormatInt(userid64, 10) == id { + isMaster = true + break + } + } + + // 根据isMaster的值为groupMsg的Sender赋值role字段 + if isMaster { + groupMsg.Sender.Role = "owner" + } else { + groupMsg.Sender.Role = "member" + } + // 将当前s和appid和message进行映射 + echo.AddMsgID(AppIDString, s, data.ID) + echo.AddMsgType(AppIDString, s, "group") + //为不支持双向echo的ob服务端映射 + echo.AddMsgID(AppIDString, GroupID64, data.ID) + //将当前的userid和groupid和msgid进行一个更稳妥的映射 + echo.AddMsgIDv2(AppIDString, GroupID64, userid64, data.ID) + //储存当前群或频道号的类型 + idmap.WriteConfigv2(fmt.Sprint(GroupID64), "type", "group") + //映射类型 + echo.AddMsgType(AppIDString, GroupID64, "group") + //懒message_id池 + echo.AddLazyMessageId(strconv.FormatInt(GroupID64, 10), data.ID, time.Now()) + //懒message_id池 + echo.AddLazyMessageIdv2(strconv.FormatInt(GroupID64, 10), strconv.FormatInt(userid64, 10), data.ID, time.Now()) + // 如果要使用string参数action + if config.GetStringAction() { + //懒message_id池 + echo.AddLazyMessageId(data.GroupID, data.ID, time.Now()) + //懒message_id池 + echo.AddLazyMessageIdv2(data.GroupID, data.Author.ID, data.ID, time.Now()) + } + // 调试 + PrintStructWithFieldNames(groupMsg) - // 根据isMaster的值为groupMsg的Sender赋值role字段 - if isMaster { - groupMsg.Sender.Role = "owner" + // Convert OnebotGroupMessage to map and send + groupMsgMap = structToMap(groupMsg) } else { - groupMsg.Sender.Role = "member" + groupMsgS = OnebotGroupMessageS{ + RawMessage: messageText, + Message: segmentedMessages, + MessageID: data.ID, + GroupID: data.GroupID, + MessageType: "group", + PostType: "message", + SelfID: selfid64, + UserID: data.Author.ID, + Sender: Sender{ + UserID: userid64, + Sex: "0", + Age: 0, + Area: "0", + Level: "0", + }, + SubType: "normal", + Time: time.Now().Unix(), + } + // 增强配置 + if !config.GetNativeOb11() { + groupMsgS.RealMessageType = "group" + groupMsgS.RealGroupID = data.GroupID + groupMsgS.RealUserID = data.Author.ID + groupMsgS.Avatar, _ = GenerateAvatarURLV2(data.Author.ID) + } + //根据条件判断是否增加nick和card + var CaN = config.GetCardAndNick() + if CaN != "" { + groupMsgS.Sender.Nickname = CaN + groupMsgS.Sender.Card = CaN + } + // 根据条件判断是否添加Echo字段 + if config.GetTwoWayEcho() { + groupMsgS.Echo = echostr + //用向应用端(如果支持)发送echo,来确定客户端的send_msg对应的触发词原文 + echo.AddMsgIDv3(AppIDString, echostr, messageText) + } + // 获取MasterID数组 + masterIDs := config.GetMasterID() + + // 判断userid64是否在masterIDs数组里 + isMaster := false + for _, id := range masterIDs { + if strconv.FormatInt(userid64, 10) == id { + isMaster = true + break + } + } + // 根据isMaster的值为groupMsg的Sender赋值role字段 + if isMaster { + groupMsgS.Sender.Role = "owner" + } else { + groupMsgS.Sender.Role = "member" + } + // 将当前s和appid和message进行映射 + echo.AddMsgID(AppIDString, s, data.ID) + echo.AddMsgType(AppIDString, s, "group") + //储存当前群或频道号的类型 + idmap.WriteConfigv2(data.GroupID, "type", "group") + //懒message_id池 + echo.AddLazyMessageId(data.GroupID, data.ID, time.Now()) + //懒message_id池 + echo.AddLazyMessageIdv2(data.GroupID, data.Author.ID, data.ID, time.Now()) + // 调试 + PrintStructWithFieldNames(groupMsgS) + // Convert OnebotGroupMessage to map and send + groupMsgMap = structToMap(groupMsgS) } - // 将当前s和appid和message进行映射 - echo.AddMsgID(AppIDString, s, data.ID) - echo.AddMsgType(AppIDString, s, "group") - //为不支持双向echo的ob服务端映射 - echo.AddMsgID(AppIDString, GroupID64, data.ID) - //将当前的userid和groupid和msgid进行一个更稳妥的映射 - echo.AddMsgIDv2(AppIDString, GroupID64, userid64, data.ID) - //储存当前群或频道号的类型 - idmap.WriteConfigv2(fmt.Sprint(GroupID64), "type", "group") - //映射类型 - echo.AddMsgType(AppIDString, GroupID64, "group") - //懒message_id池 - echo.AddLazyMessageId(strconv.FormatInt(GroupID64, 10), data.ID, time.Now()) - //懒message_id池 - echo.AddLazyMessageIdv2(strconv.FormatInt(GroupID64, 10), strconv.FormatInt(userid64, 10), data.ID, time.Now()) - // 调试 - PrintStructWithFieldNames(groupMsg) - - // Convert OnebotGroupMessage to map and send - groupMsgMap := structToMap(groupMsg) + //上报信息到onebotv11应用端(正反ws) go p.BroadcastMessageToAll(groupMsgMap, p.Apiv2, data) return nil diff --git a/Processor/Processor.go b/Processor/Processor.go index f9c84318..9e1ad1bc 100644 --- a/Processor/Processor.go +++ b/Processor/Processor.go @@ -99,6 +99,29 @@ type OnebotGroupMessage struct { IsBindedUserId bool `json:"is_binded_user_id,omitempty"` //当前用户号号是否是binded后的 } +type OnebotGroupMessageS struct { + RawMessage string `json:"raw_message"` + MessageID string `json:"message_id"` + GroupID string `json:"group_id"` // Can be either string or int depending on p.Settings.CompleteFields + MessageType string `json:"message_type"` + PostType string `json:"post_type"` + SelfID int64 `json:"self_id"` // Can be either string or int + Sender Sender `json:"sender"` + SubType string `json:"sub_type"` + Time int64 `json:"time"` + Avatar string `json:"avatar,omitempty"` + Echo string `json:"echo,omitempty"` + Message interface{} `json:"message"` // For array format + MessageSeq int `json:"message_seq"` + Font int `json:"font"` + UserID string `json:"user_id"` + RealMessageType string `json:"real_message_type,omitempty"` //当前信息的真实类型 group group_private guild guild_private + RealUserID string `json:"real_user_id,omitempty"` //当前真实uid + RealGroupID string `json:"real_group_id,omitempty"` //当前真实gid + IsBindedGroupId bool `json:"is_binded_group_id,omitempty"` //当前群号是否是binded后的 + IsBindedUserId bool `json:"is_binded_user_id,omitempty"` //当前用户号号是否是binded后的 +} + // 私聊信息事件 type OnebotPrivateMessage struct { RawMessage string `json:"raw_message"` diff --git a/config/config.go b/config/config.go index 61ad5fbf..a3fe549a 100644 --- a/config/config.go +++ b/config/config.go @@ -2401,6 +2401,30 @@ func GetDisableErrorChan() bool { return instance.Settings.DisableErrorChan } +// 获取StringOb11的值 +func GetStringOb11() bool { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to StringOb11 value.") + return false + } + return instance.Settings.StringOb11 +} + +// 获取StringAction的值 +func GetStringAction() bool { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to StringAction value.") + return false + } + return instance.Settings.StringAction +} + // 获取 PutInteractionExcept 数组 func GetPutInteractionExcept() []string { mu.RLock() diff --git a/handlers/get_group_list.go b/handlers/get_group_list.go index 6c43590d..f947b968 100644 --- a/handlers/get_group_list.go +++ b/handlers/get_group_list.go @@ -3,6 +3,7 @@ package handlers import ( "context" "encoding/json" + "regexp" "strconv" "time" @@ -46,6 +47,16 @@ type Group struct { MemberCount int32 `json:"member_count"` } +type GroupString struct { + GroupCreateTime int32 `json:"group_create_time"` + GroupID string `json:"group_id"` + GroupLevel int32 `json:"group_level"` + GroupMemo string `json:"group_memo"` + GroupName string `json:"group_name"` + MaxMemberCount int32 `json:"max_member_count"` + MemberCount int32 `json:"member_count"` +} + type GroupList struct { Data []Group `json:"data"` Message string `json:"message"` @@ -54,9 +65,19 @@ type GroupList struct { Echo interface{} `json:"echo"` } +type GroupListString struct { + Data []GroupString `json:"data"` + Message string `json:"message"` + RetCode int `json:"retcode"` + Status string `json:"status"` + Echo interface{} `json:"echo"` +} + func GetGroupList(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.OpenAPI, message callapi.ActionMessage) (string, error) { //群还不支持,这里取得是频道的,如果后期支持了群,那都请求,一起返回 var groupList GroupList + var groupListString GroupListString + var outputMap map[string]interface{} // 初始化 groupList.Data 为一个空数组 groupList.Data = []Group{} @@ -129,35 +150,71 @@ func GetGroupList(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Open // 当前时间的 10 位 Unix 时间戳 currentTimestamp := int32(time.Now().Unix()) - for _, idStr := range groupIDs { - groupID, err := strconv.ParseInt(idStr, 10, 64) - if err != nil { - mylog.Printf("Error converting group ID %s to int64: %v", idStr, err) - continue - } + // 判断是否string返回 + if !config.GetStringOb11() { + for _, idStr := range groupIDs { + groupID, err := strconv.ParseInt(idStr, 10, 64) + if err != nil { + mylog.Printf("Error converting group ID %s to int64: %v", idStr, err) + continue + } - group := Group{ - GroupCreateTime: currentTimestamp, // 使用当前时间的时间戳 - GroupID: groupID, - GroupLevel: 0, - GroupMemo: "", - GroupName: "", - MaxMemberCount: 0, - MemberCount: 0, - } + group := Group{ + GroupCreateTime: currentTimestamp, // 使用当前时间的时间戳 + GroupID: groupID, + GroupLevel: 0, + GroupMemo: "", + GroupName: "", + MaxMemberCount: 0, + MemberCount: 0, + } - groupList.Data = append(groupList.Data, group) - } - groupList.Message = "" - groupList.RetCode = 0 - groupList.Status = "ok" + groupList.Data = append(groupList.Data, group) + } + groupList.Message = "" + groupList.RetCode = 0 + groupList.Status = "ok" - if message.Echo == "" { - groupList.Echo = "0" + if message.Echo == "" { + groupList.Echo = "0" + } else { + groupList.Echo = message.Echo + } + outputMap = structToMap(groupList) } else { - groupList.Echo = message.Echo + // 检查字符串是否仅包含数字 将数字形式的interactionID转换为真实的形式 + isNumeric := func(s string) bool { + return regexp.MustCompile(`^\d+$`).MatchString(s) + } + for _, idStr := range groupIDs { + var originalGroupID string + if isNumeric(idStr) { + originalGroupID, _ = idmap.RetrieveRowByIDv2(idStr) + } else { + originalGroupID = idStr + } + group := GroupString{ + GroupCreateTime: currentTimestamp, // 使用当前时间的时间戳 + GroupID: originalGroupID, + GroupLevel: 0, + GroupMemo: "", + GroupName: "", + MaxMemberCount: 0, + MemberCount: 0, + } + groupListString.Data = append(groupListString.Data, group) + } + groupListString.Message = "" + groupListString.RetCode = 0 + groupListString.Status = "ok" + + if message.Echo == "" { + groupListString.Echo = "0" + } else { + groupListString.Echo = message.Echo + } + outputMap = structToMap(groupListString) } - outputMap := structToMap(groupList) //mylog.Printf("getGroupList(频道): %+v\n", outputMap) diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index 450be103..cbf10425 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -66,18 +66,21 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap } } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) - } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUseridV2(message.Params.UserID) + if len(message.Params.GroupID.(string)) != 32 { + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) + } + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUseridV2(message.Params.UserID) + } } + // New checks for UserID and GroupID being nil or 0 if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) && (message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) { @@ -95,10 +98,20 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap var err error var retmsg string - if message.Params.GroupID != "" { - idInt64, err = ConvertToInt64(message.Params.GroupID) - } else if message.Params.UserID != "" { - idInt64, err = ConvertToInt64(message.Params.UserID) + if len(message.Params.GroupID.(string)) == 32 { + if message.Params.GroupID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) + } else if message.Params.UserID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) + } + // 临时的 + msgType = "group" + } else { + if message.Params.GroupID != "" { + idInt64, err = ConvertToInt64(message.Params.GroupID) + } else if message.Params.UserID != "" { + idInt64, err = ConvertToInt64(message.Params.UserID) + } } //设置递归 对直接向gsk发送action时有效果 @@ -153,48 +166,52 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap mylog.Println("echo取群组发信息对应的message_id:", messageID) } } + var originalGroupID, originalUserID string - // 检查UserID是否为nil - if message.Params.UserID != nil && config.GetIdmapPro() && message.Params.UserID.(string) != "" && message.Params.UserID.(string) != "0" { - // 如果UserID不是nil且配置为使用Pro版本,则调用RetrieveRowByIDv2Pro - originalGroupID, originalUserID, err = idmap.RetrieveRowByIDv2Pro(message.Params.GroupID.(string), message.Params.UserID.(string)) - if err != nil { - mylog.Printf("Error1 retrieving original GroupID: %v", err) - } - mylog.Printf("测试,通过idmaps-pro获取的originalGroupID:%v", originalGroupID) - if originalGroupID == "" { - originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) + if len(message.Params.GroupID.(string)) != 32 { + // 检查UserID是否为nil + if message.Params.UserID != nil && config.GetIdmapPro() && message.Params.UserID.(string) != "" && message.Params.UserID.(string) != "0" { + // 如果UserID不是nil且配置为使用Pro版本,则调用RetrieveRowByIDv2Pro + originalGroupID, originalUserID, err = idmap.RetrieveRowByIDv2Pro(message.Params.GroupID.(string), message.Params.UserID.(string)) if err != nil { - mylog.Printf("Error2 retrieving original GroupID: %v", err) - return "", nil + mylog.Printf("Error1 retrieving original GroupID: %v", err) + } + mylog.Printf("测试,通过idmaps-pro获取的originalGroupID:%v", originalGroupID) + if originalGroupID == "" { + originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) + if err != nil { + mylog.Printf("Error2 retrieving original GroupID: %v", err) + return "", nil + } + mylog.Printf("测试,通过idmaps获取的originalGroupID:%v", originalGroupID) } - mylog.Printf("测试,通过idmaps获取的originalGroupID:%v", originalGroupID) - } - } else { - // 如果UserID是nil或配置不使用Pro版本,则调用RetrieveRowByIDv2 - originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) - if err != nil { - mylog.Printf("Error retrieving original GroupID: %v", err) - } - // 检查 message.Params.UserID 是否为 nil - if message.Params.UserID == nil { - //mylog.Println("UserID is nil") } else { - // 进行类型断言,确认 UserID 不是 nil - userID, ok := message.Params.UserID.(string) - if !ok { - mylog.Println("UserID is not a string") - // 处理类型断言失败的情况 + // 如果UserID是nil或配置不使用Pro版本,则调用RetrieveRowByIDv2 + originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) + if err != nil { + mylog.Printf("Error retrieving original GroupID: %v", err) + } + // 检查 message.Params.UserID 是否为 nil + if message.Params.UserID == nil { + //mylog.Println("UserID is nil") } else { - originalUserID, err = idmap.RetrieveRowByIDv2(userID) - if err != nil { - mylog.Printf("Error retrieving original UserID: %v", err) + // 进行类型断言,确认 UserID 不是 nil + userID, ok := message.Params.UserID.(string) + if !ok { + mylog.Println("UserID is not a string") + // 处理类型断言失败的情况 + } else { + originalUserID, err = idmap.RetrieveRowByIDv2(userID) + if err != nil { + mylog.Printf("Error retrieving original UserID: %v", err) + } } } } + message.Params.GroupID = originalGroupID + message.Params.UserID = originalUserID } - message.Params.GroupID = originalGroupID - message.Params.UserID = originalUserID + //2000是群主动 此时不能被动转主动 if SSM { //mylog.Printf("正在使用Msgid:%v 补发之前失败的主动信息,请注意AtoP不要设置超过3,否则可能会影响正常信息发送", messageID) diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index 99713cfe..a11defc5 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -56,33 +56,47 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope } } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) - } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUseridV2(message.Params.UserID) + if len(message.Params.GroupID.(string)) != 32 { + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) + } + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUseridV2(message.Params.UserID) + } } + // New checks for UserID and GroupID being nil or 0 if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) && (message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) { mylog.Printf("send_group_msgs接收到错误action: %v", message) return "", nil } + mylog.Printf("send_group_msg获取到信息类型:%v", msgType) var idInt64 int64 var err error var retmsg string - if message.Params.GroupID != "" { - idInt64, err = ConvertToInt64(message.Params.GroupID) - } else if message.Params.UserID != "" { - idInt64, err = ConvertToInt64(message.Params.UserID) + if len(message.Params.GroupID.(string)) == 32 { + if message.Params.GroupID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) + } else if message.Params.UserID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) + } + // 临时的 + msgType = "group" + } else { + if message.Params.GroupID != "" { + idInt64, err = ConvertToInt64(message.Params.GroupID) + } else if message.Params.UserID != "" { + idInt64, err = ConvertToInt64(message.Params.UserID) + } } //设置递归 对直接向gsk发送action时有效果 diff --git a/handlers/send_msg.go b/handlers/send_msg.go index a2e67a14..ce61d397 100644 --- a/handlers/send_msg.go +++ b/handlers/send_msg.go @@ -53,18 +53,21 @@ func HandleSendMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Ope } } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) - } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUseridV2(message.Params.UserID) + if len(message.Params.GroupID.(string)) != 32 { + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) + } + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUseridV2(message.Params.UserID) + } } + // New checks for UserID and GroupID being nil or 0 if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) && (message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) { @@ -72,31 +75,23 @@ func HandleSendMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Ope return "", nil } - var idInt64, idInt642 int64 + var idInt64 int64 var err error - var tempErr error - - if message.Params.GroupID != "" { - idInt64, tempErr = ConvertToInt64(message.Params.GroupID) - if tempErr != nil { - err = tempErr + if len(message.Params.GroupID.(string)) == 32 { + if message.Params.GroupID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) + } else if message.Params.UserID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) } - idInt642, tempErr = ConvertToInt64(message.Params.UserID) - if tempErr != nil { - err = tempErr - } - - } else if message.Params.UserID != "" { - idInt64, tempErr = ConvertToInt64(message.Params.UserID) - if tempErr != nil { - err = tempErr - } - idInt642, tempErr = ConvertToInt64(message.Params.GroupID) - if tempErr != nil { - err = tempErr + // 临时的 + msgType = "group" + } else { + if message.Params.GroupID != "" { + idInt64, err = ConvertToInt64(message.Params.GroupID) + } else if message.Params.UserID != "" { + idInt64, err = ConvertToInt64(message.Params.UserID) } - } //设置递归 对直接向gsk发送action时有效果 @@ -172,7 +167,6 @@ func HandleSendMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Ope //重置递归类型 if echo.GetMapping(idInt64) <= 0 { echo.AddMsgType(config.GetAppIDStr(), idInt64, "") - echo.AddMsgType(config.GetAppIDStr(), idInt642, "") } echo.AddMapping(idInt64, echo.GetMapping(idInt64)-1) diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index 443e4f86..a82374fc 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -56,18 +56,21 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open } } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) - } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) - } - if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { - msgType = GetMessageTypeByUseridV2(message.Params.UserID) - } - if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { - msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) + if len(message.Params.GroupID.(string)) != 32 { + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) + } + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) + } + if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { + msgType = GetMessageTypeByUseridV2(message.Params.UserID) + } + if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { + msgType = GetMessageTypeByGroupidV2(message.Params.GroupID) + } } + // New checks for UserID and GroupID being nil or 0 if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) && (message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) { @@ -78,10 +81,20 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open var idInt64 int64 var err error - if message.Params.UserID != "" { - idInt64, err = ConvertToInt64(message.Params.UserID) - } else if message.Params.GroupID != "" { - idInt64, err = ConvertToInt64(message.Params.GroupID) + if len(message.Params.GroupID.(string)) == 32 { + if message.Params.GroupID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) + } else if message.Params.UserID != "" { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) + } + // 临时的 + msgType = "private" + } else { + if message.Params.GroupID != "" { + idInt64, err = ConvertToInt64(message.Params.GroupID) + } else if message.Params.UserID != "" { + idInt64, err = ConvertToInt64(message.Params.UserID) + } } //设置递归 对直接向gsk发送action时有效果 @@ -107,22 +120,26 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open case "group_private", "group": //私聊信息 var UserID string - if config.GetIdmapPro() { - //还原真实的userid - //mylog.Printf("group_private:%v", message.Params.UserID.(string)) - _, UserID, err = idmap.RetrieveRowByIDv2Pro("690426430", message.Params.UserID.(string)) - if err != nil { - mylog.Printf("Error reading config: %v", err) - return "", nil + if len(message.Params.UserID.(string)) != 32 { + if config.GetIdmapPro() { + //还原真实的userid + //mylog.Printf("group_private:%v", message.Params.UserID.(string)) + _, UserID, err = idmap.RetrieveRowByIDv2Pro("690426430", message.Params.UserID.(string)) + if err != nil { + mylog.Printf("Error reading config: %v", err) + return "", nil + } + mylog.Printf("测试,通过Proid获取的UserID:%v", UserID) + } else { + //还原真实的userid + UserID, err = idmap.RetrieveRowByIDv2(message.Params.UserID.(string)) + if err != nil { + mylog.Printf("Error reading config: %v", err) + return "", nil + } } - mylog.Printf("测试,通过Proid获取的UserID:%v", UserID) } else { - //还原真实的userid - UserID, err = idmap.RetrieveRowByIDv2(message.Params.UserID.(string)) - if err != nil { - mylog.Printf("Error reading config: %v", err) - return "", nil - } + UserID = message.Params.UserID.(string) } // 解析消息内容 diff --git a/structs/structs.go b/structs/structs.go index e23552de..0342f095 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -125,6 +125,8 @@ type Settings struct { Array bool `yaml:"array"` NativeOb11 bool `yaml:"native_ob11"` DisableErrorChan bool `yaml:"disable_error_chan"` + StringOb11 bool `yaml:"string_ob11"` + StringAction bool `yaml:"string_action"` //url相关 VisibleIp bool `yaml:"visible_ip"` UrlToQrimage bool `yaml:"url_to_qrimage"` diff --git a/template/config_template.go b/template/config_template.go index 8639f1d7..13db38e5 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -161,6 +161,8 @@ settings: array: false #连接trss云崽请开启array,是否以segment形式上报信息. native_ob11 : false #如果你的机器人收到事件报错,请开启此选项增加兼容性 disable_error_chan : false #禁用ws断开时候将信息放入补发频道,当信息非常多时可能导致冲垮应用端,可以设置本选项为true. + string_ob11 : false #api不再返回转换后的int类型,而是直接转换,需应用端适配. + string_action : false #开启后将兼容action调用中使用string形式的user_id和group_id. #URL相关 visible_ip : false #转换url时,如果server_dir是ip true将以ip形式发出url 默认隐藏url 将server_dir配置为自己域名可以转换url From 500135c5b48972ae777389c5d88b13a6b70403fe Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 21 Jul 2024 18:30:25 +0800 Subject: [PATCH 21/36] beta467 --- main.go | 2 +- structs/structs.go | 1 + template/config_template.go | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 30b362e8..43b1d859 100644 --- a/main.go +++ b/main.go @@ -282,7 +282,7 @@ func main() { // 指定需要启动的分片数为 2 的话可以手动修改 wsInfo if conf.Settings.ShardCount == 1 { go func() { - wsInfo.Shards = 1 + wsInfo.Shards = uint32(conf.Settings.ShardNum) if err = botgo.NewSessionManager().Start(wsInfo, token, &intent); err != nil { log.Fatalln(err) } diff --git a/structs/structs.go b/structs/structs.go index 0342f095..685424c9 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -21,6 +21,7 @@ type Settings struct { ShardCount int `yaml:"shard_count"` ShardID int `yaml:"shard_id"` UseUin bool `yaml:"use_uin"` + ShardNum int `yaml:"shard_num"` //事件订阅类 TextIntent []string `yaml:"text_intent"` //转换类 diff --git a/template/config_template.go b/template/config_template.go index 13db38e5..d63d60e0 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -18,6 +18,7 @@ settings: client_secret: "" # 你的客户端密钥 shard_count: 1 #分片数量 默认1 shard_id: 0 #当前分片id 默认从0开始,详细请看 https://bot.q.qq.com/wiki/develop/api/gateway/reference.html + shard_num: 1 #接口调用超过频率限制时,如果不想要多开gsk,尝试调大.gsk会尝试连接到n个分片处理信息. n为你所配置的值.与 shard_count和shard_id互不相干. #事件订阅 text_intent: # 请根据公域 私域来选择intent,错误的intent将连接失败 From c1a588c9a2968739cf4c6d65ef291e10558fc562 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 21 Jul 2024 19:09:01 +0800 Subject: [PATCH 22/36] beta468 --- botgo/sessions/multi/multi.go | 97 +++++++++++++++++++++++++++++++++++ main.go | 9 +++- 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 botgo/sessions/multi/multi.go diff --git a/botgo/sessions/multi/multi.go b/botgo/sessions/multi/multi.go new file mode 100644 index 00000000..5dfeadbc --- /dev/null +++ b/botgo/sessions/multi/multi.go @@ -0,0 +1,97 @@ +package multi + +import ( + "sync" + "time" + + "github.com/tencent-connect/botgo/dto" + "github.com/tencent-connect/botgo/log" + "github.com/tencent-connect/botgo/sessions/manager" + "github.com/tencent-connect/botgo/token" + "github.com/tencent-connect/botgo/websocket" +) + +type ShardManager struct { + Sessions []dto.Session + SessionChans []chan dto.Session + Clients []websocket.WebSocket + APInfo *dto.WebsocketAP + Token *token.Token + Intents *dto.Intent + StartInterval time.Duration + wg sync.WaitGroup +} + +func NewShardManager(apInfo *dto.WebsocketAP, token *token.Token, intents *dto.Intent) *ShardManager { + m := &ShardManager{ + APInfo: apInfo, + Token: token, + Intents: intents, + Sessions: make([]dto.Session, apInfo.Shards), + Clients: make([]websocket.WebSocket, apInfo.Shards), + SessionChans: make([]chan dto.Session, apInfo.Shards), + } + for i := range m.Sessions { + m.SessionChans[i] = make(chan dto.Session, 1) + } + m.StartInterval = manager.CalcInterval(apInfo.SessionStartLimit.MaxConcurrency) + return m +} + +func (sm *ShardManager) StartAllShards() { + for i := uint32(0); i < sm.APInfo.Shards; i++ { + sm.StartShard(i) + } + sm.wg.Wait() +} + +func (sm *ShardManager) StartShard(shardID uint32) { + sm.wg.Add(1) + go func() { + defer sm.wg.Done() + session := dto.Session{ + URL: sm.APInfo.URL, + Token: *sm.Token, + Intent: *sm.Intents, + LastSeq: 0, + Shards: dto.ShardConfig{ + ShardID: shardID, + ShardCount: sm.APInfo.Shards, + }, + } + sm.Sessions[shardID] = session + sm.SessionChans[shardID] <- session + + for session := range sm.SessionChans[shardID] { + time.Sleep(sm.StartInterval) + sm.newConnect(session, shardID) + } + }() +} + +func (sm *ShardManager) newConnect(session dto.Session, shardID uint32) { + wsClient := websocket.ClientImpl.New(session) + sm.Clients[shardID] = wsClient + if err := wsClient.Connect(); err != nil { + log.Error(err) + sm.SessionChans[shardID] <- session // Reconnect + return + } + if session.ID != "" { + err := wsClient.Resume() + if err != nil { + log.Errorf("[ws/session] Resume error: %+v", err) + return + } + } else { + err := wsClient.Identify() + if err != nil { + log.Errorf("[ws/session] Identify error: %+v", err) + return + } + } + if err := wsClient.Listening(); err != nil { + log.Errorf("[ws/session] Listening error: %+v", err) + sm.SessionChans[shardID] <- session // Reconnect + } +} diff --git a/main.go b/main.go index 43b1d859..dfa86835 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,7 @@ import ( "github.com/hoshinonyaruko/gensokyo/url" "github.com/hoshinonyaruko/gensokyo/webui" "github.com/hoshinonyaruko/gensokyo/wsclient" + "github.com/tencent-connect/botgo/sessions/multi" "google.golang.org/grpc" "github.com/gin-gonic/gin" @@ -283,8 +284,12 @@ func main() { if conf.Settings.ShardCount == 1 { go func() { wsInfo.Shards = uint32(conf.Settings.ShardNum) - if err = botgo.NewSessionManager().Start(wsInfo, token, &intent); err != nil { - log.Fatalln(err) + if wsInfo.Shards == 1 { + if err = botgo.NewSessionManager().Start(wsInfo, token, &intent); err != nil { + log.Fatalln(err) + } + } else { + multi.NewShardManager(wsInfo, token, &intent).StartAllShards() } }() log.Printf("不使用分片,所有信息都由当前gensokyo处理...\n") From 1df8e1538c710c800e325e30c9c54747f7d8d998 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 21 Jul 2024 20:27:50 +0800 Subject: [PATCH 23/36] beta469 --- botgo/sessions/multi/multi.go | 1 + 1 file changed, 1 insertion(+) diff --git a/botgo/sessions/multi/multi.go b/botgo/sessions/multi/multi.go index 5dfeadbc..3409b0cc 100644 --- a/botgo/sessions/multi/multi.go +++ b/botgo/sessions/multi/multi.go @@ -40,6 +40,7 @@ func NewShardManager(apInfo *dto.WebsocketAP, token *token.Token, intents *dto.I func (sm *ShardManager) StartAllShards() { for i := uint32(0); i < sm.APInfo.Shards; i++ { + time.Sleep(sm.StartInterval) sm.StartShard(i) } sm.wg.Wait() From f57ab7b03b58aabb0adc6d74fcdc0545dabd3926 Mon Sep 17 00:00:00 2001 From: cosmo Date: Fri, 26 Jul 2024 10:49:21 +0800 Subject: [PATCH 24/36] beta470 --- Processor/ProcessGroupAddBot.go | 32 ++++++++++++++----- Processor/ProcessInlineSearch.go | 55 ++++++++++++++++++++++++++++++++ Processor/Processor.go | 24 +++++++------- handlers/send_group_msg.go | 16 ++++++---- handlers/send_group_msg_raw.go | 16 ++++++---- handlers/send_private_msg.go | 12 +++---- 6 files changed, 114 insertions(+), 41 deletions(-) diff --git a/Processor/ProcessGroupAddBot.go b/Processor/ProcessGroupAddBot.go index 70f0fa73..d0348b6a 100644 --- a/Processor/ProcessGroupAddBot.go +++ b/Processor/ProcessGroupAddBot.go @@ -25,18 +25,22 @@ type GroupRequestEvent struct { SubType string `json:"sub_type"` Time int64 `json:"time"` UserID int64 `json:"user_id"` + RealUserID string `json:"real_user_id,omitempty"` //当前真实uid + RealGroupID string `json:"real_group_id,omitempty"` //当前真实gid } // GroupNoticeEvent 表示群通知事件的数据结构 type GroupNoticeEvent struct { - GroupID int64 `json:"group_id"` - NoticeType string `json:"notice_type"` - OperatorID int64 `json:"operator_id"` - PostType string `json:"post_type"` - SelfID int64 `json:"self_id"` - SubType string `json:"sub_type"` - Time int64 `json:"time"` - UserID int64 `json:"user_id"` + GroupID int64 `json:"group_id"` + NoticeType string `json:"notice_type"` + OperatorID int64 `json:"operator_id"` + PostType string `json:"post_type"` + SelfID int64 `json:"self_id"` + SubType string `json:"sub_type"` + Time int64 `json:"time"` + UserID int64 `json:"user_id"` + RealUserID string `json:"real_user_id,omitempty"` //当前真实uid + RealGroupID string `json:"real_group_id,omitempty"` //当前真实gid } // 定义了一个符合 Client 接口的 SelfIntroduceClient 结构体 @@ -113,6 +117,12 @@ func (p *Processors) ProcessGroupAddBot(data *dto.GroupAddBotEvent) error { Time: timestampInt64, UserID: userid64, } + //增强配置 + if !config.GetNativeOb11() { + Request.RealUserID = data.OpMemberOpenID + Request.RealGroupID = data.GroupOpenID + } + Notice = GroupNoticeEvent{ GroupID: GroupID64, NoticeType: "group_increase", @@ -123,6 +133,12 @@ func (p *Processors) ProcessGroupAddBot(data *dto.GroupAddBotEvent) error { Time: timestampInt64, UserID: userid64, } + //增强配置 + if !config.GetNativeOb11() { + Notice.RealUserID = data.OpMemberOpenID + Notice.RealGroupID = data.GroupOpenID + } + groupMsgMap := structToMap(Request) //上报信息到onebotv11应用端(正反ws) go p.BroadcastMessageToAll(groupMsgMap, p.Apiv2, data) diff --git a/Processor/ProcessInlineSearch.go b/Processor/ProcessInlineSearch.go index 254c6d89..2f5ed8b9 100644 --- a/Processor/ProcessInlineSearch.go +++ b/Processor/ProcessInlineSearch.go @@ -119,6 +119,11 @@ func (p *Processors) ProcessInlineSearch(data *dto.WSInteractionData) error { UserID: userid64, Data: data, } + //增强配置 + if !config.GetNativeOb11() { + notice.RealUserID = fromuid + notice.RealGroupID = fromgid + } //调试 PrintStructWithFieldNames(notice) @@ -260,6 +265,31 @@ func (p *Processors) ProcessInlineSearch(data *dto.WSInteractionData) error { // 储存和群号相关的eventid fmt.Printf("测试:储存eventid:[%v]LongGroupID64[%v]\n", data.EventID, LongGroupID64) echo.AddEvnetID(AppIDString, LongGroupID64, data.EventID) + + // 上报事件 + notice := &OnebotInteractionNotice{ + GroupID: GroupID64, + NoticeType: "interaction", + PostType: "notice", + SelfID: selfid64, + SubType: "create", + Time: time.Now().Unix(), + UserID: userid64, + Data: data, + } + //增强配置 + if !config.GetNativeOb11() { + notice.RealUserID = fromuid + notice.RealGroupID = fromgid + } + //调试 + PrintStructWithFieldNames(notice) + + // Convert OnebotGroupMessage to map and send + noticeMap := structToMap(notice) + + //上报信息到onebotv11应用端(正反ws) + go p.BroadcastMessageToAll(noticeMap, p.Apiv2, data) } else if data.UserOpenID != "" { //私聊回调 newdata := ConvertInteractionToMessage(data) @@ -338,6 +368,31 @@ func (p *Processors) ProcessInlineSearch(data *dto.WSInteractionData) error { // 储存和用户ID相关的eventid echo.AddEvnetID(AppIDString, LongUserID64, data.EventID) + + // 上报事件 + notice := &OnebotInteractionNotice{ + GroupID: GroupID64, + NoticeType: "interaction", + PostType: "notice", + SelfID: selfid64, + SubType: "create", + Time: time.Now().Unix(), + UserID: userid64, + Data: data, + } + //增强配置 + if !config.GetNativeOb11() { + notice.RealUserID = fromuid + notice.RealGroupID = fromgid + } + //调试 + PrintStructWithFieldNames(notice) + + // Convert OnebotGroupMessage to map and send + noticeMap := structToMap(notice) + + //上报信息到onebotv11应用端(正反ws) + go p.BroadcastMessageToAll(noticeMap, p.Apiv2, data) } else { // TODO: 区分频道和频道私信 如果有人提需求 // 频道回调 diff --git a/Processor/Processor.go b/Processor/Processor.go index 9e1ad1bc..e6b8a66a 100644 --- a/Processor/Processor.go +++ b/Processor/Processor.go @@ -101,8 +101,8 @@ type OnebotGroupMessage struct { type OnebotGroupMessageS struct { RawMessage string `json:"raw_message"` - MessageID string `json:"message_id"` - GroupID string `json:"group_id"` // Can be either string or int depending on p.Settings.CompleteFields + MessageID string `json:"message_id"` + GroupID string `json:"group_id"` // Can be either string or int depending on p.Settings.CompleteFields MessageType string `json:"message_type"` PostType string `json:"post_type"` SelfID int64 `json:"self_id"` // Can be either string or int @@ -114,7 +114,7 @@ type OnebotGroupMessageS struct { Message interface{} `json:"message"` // For array format MessageSeq int `json:"message_seq"` Font int `json:"font"` - UserID string `json:"user_id"` + UserID string `json:"user_id"` RealMessageType string `json:"real_message_type,omitempty"` //当前信息的真实类型 group group_private guild guild_private RealUserID string `json:"real_user_id,omitempty"` //当前真实uid RealGroupID string `json:"real_group_id,omitempty"` //当前真实gid @@ -145,14 +145,16 @@ type OnebotPrivateMessage struct { // onebotv11标准扩展 type OnebotInteractionNotice struct { - GroupID int64 `json:"group_id,omitempty"` - NoticeType string `json:"notice_type,omitempty"` - PostType string `json:"post_type,omitempty"` - SelfID int64 `json:"self_id,omitempty"` - SubType string `json:"sub_type,omitempty"` - Time int64 `json:"time,omitempty"` - UserID int64 `json:"user_id,omitempty"` - Data *dto.WSInteractionData `json:"data,omitempty"` + GroupID int64 `json:"group_id,omitempty"` + NoticeType string `json:"notice_type,omitempty"` + PostType string `json:"post_type,omitempty"` + SelfID int64 `json:"self_id,omitempty"` + SubType string `json:"sub_type,omitempty"` + Time int64 `json:"time,omitempty"` + UserID int64 `json:"user_id,omitempty"` + Data *dto.WSInteractionData `json:"data,omitempty"` + RealUserID string `json:"real_user_id,omitempty"` //当前真实uid + RealGroupID string `json:"real_group_id,omitempty"` //当前真实gid } // onebotv11标准扩展 diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index cbf10425..ac5508c9 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -66,7 +66,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap } } - if len(message.Params.GroupID.(string)) != 32 { + if message.Params.GroupID != nil && len(message.Params.GroupID.(string)) != 32 { if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) } @@ -99,13 +99,13 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap var retmsg string if len(message.Params.GroupID.(string)) == 32 { - if message.Params.GroupID != "" { - idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) - } else if message.Params.UserID != "" { - idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) - } + idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) // 临时的 msgType = "group" + } else if len(message.Params.UserID.(string)) == 32 { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) + // 临时的 + msgType = "group_private" } else { if message.Params.GroupID != "" { idInt64, err = ConvertToInt64(message.Params.GroupID) @@ -643,7 +643,9 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap retmsg, _ = HandleSendGuildChannelPrivateMsg(client, api, apiv2, message, &value, &RChannelID) case "group_private": //用userid还原出openid 这是虚拟成群的群聊私聊信息 - message.Params.UserID = message.Params.GroupID.(string) + if message.Params.GroupID != nil && message.Params.GroupID.(string) != "" { + message.Params.UserID = message.Params.GroupID.(string) + } retmsg, _ = HandleSendPrivateMsg(client, api, apiv2, message) case "forum": //用GroupID给ChannelID赋值,因为我们是把频道虚拟成了群 diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index a11defc5..11f81d37 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -56,7 +56,7 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope } } - if len(message.Params.GroupID.(string)) != 32 { + if message.Params.GroupID != nil && len(message.Params.GroupID.(string)) != 32 { if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) { msgType = GetMessageTypeByGroupid(config.GetAppIDStr(), message.Params.GroupID) } @@ -84,13 +84,13 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope var retmsg string if len(message.Params.GroupID.(string)) == 32 { - if message.Params.GroupID != "" { - idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) - } else if message.Params.UserID != "" { - idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) - } + idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) // 临时的 msgType = "group" + } else if len(message.Params.UserID.(string)) == 32 { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) + // 临时的 + msgType = "group_private" } else { if message.Params.GroupID != "" { idInt64, err = ConvertToInt64(message.Params.GroupID) @@ -476,7 +476,9 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope retmsg, _ = HandleSendGuildChannelPrivateMsg(client, api, apiv2, message, &value, &RChannelID) case "group_private": //用userid还原出openid 这是虚拟成群的群聊私聊信息 - message.Params.UserID = message.Params.GroupID.(string) + if message.Params.GroupID != nil && message.Params.GroupID.(string) != "" { + message.Params.UserID = message.Params.GroupID.(string) + } retmsg, _ = HandleSendPrivateMsg(client, api, apiv2, message) case "forum": //用GroupID给ChannelID赋值,因为我们是把频道虚拟成了群 diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index a82374fc..b33a9005 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -56,7 +56,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open } } - if len(message.Params.GroupID.(string)) != 32 { + if message.Params.UserID != nil && len(message.Params.UserID.(string)) != 32 { if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) { msgType = GetMessageTypeByUserid(config.GetAppIDStr(), message.Params.UserID) } @@ -81,14 +81,10 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open var idInt64 int64 var err error - if len(message.Params.GroupID.(string)) == 32 { - if message.Params.GroupID != "" { - idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) - } else if message.Params.UserID != "" { - idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) - } + if len(message.Params.UserID.(string)) == 32 { + idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) // 临时的 - msgType = "private" + msgType = "group_private" } else { if message.Params.GroupID != "" { idInt64, err = ConvertToInt64(message.Params.GroupID) From cd21ad9d1be5b32b7ea2408d5d99636a270a287e Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 1 Aug 2024 23:09:03 +0800 Subject: [PATCH 25/36] beta471 --- Processor/ProcessInlineSearch.go | 7 +- botgo/websocket/client/client.go | 109 ++++++++++++++++++++++++++++++- echo/echo.go | 64 ++++++++++++++++++ handlers/send_group_msg_raw.go | 68 +++++++++---------- 4 files changed, 212 insertions(+), 36 deletions(-) diff --git a/Processor/ProcessInlineSearch.go b/Processor/ProcessInlineSearch.go index 2f5ed8b9..ef0ccdbe 100644 --- a/Processor/ProcessInlineSearch.go +++ b/Processor/ProcessInlineSearch.go @@ -360,8 +360,11 @@ func (p *Processors) ProcessInlineSearch(data *dto.WSInteractionData) error { // Convert OnebotGroupMessage to map and send privateMsgMap := structToMap(privateMsg) - //上报信息到onebotv11应用端(正反ws) - go p.BroadcastMessageToAll(privateMsgMap, p.Apiv2, data) + + if privateMsg.RawMessage != "" { + //上报信息到onebotv11应用端(正反ws) + go p.BroadcastMessageToAll(privateMsgMap, p.Apiv2, data) + } // 转换appid AppIDString := strconv.FormatUint(p.Settings.AppID, 10) diff --git a/botgo/websocket/client/client.go b/botgo/websocket/client/client.go index 8bdd3559..099c495b 100644 --- a/botgo/websocket/client/client.go +++ b/botgo/websocket/client/client.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "os/signal" + "sync" "sync/atomic" "syscall" "time" @@ -26,6 +27,18 @@ const DefaultQueueSize = 10000 // 定义全局变量 var global_s int64 +// PayloadWithTimestamp 存储带时间戳的 WSPayload +type PayloadWithTimestamp struct { + Payload *dto.WSPayload + Timestamp time.Time +} + +var dataMap sync.Map + +func init() { + StartCleanupRoutine() +} + // Setup 依赖注册 func Setup() { websocket.Register(&Client{}) @@ -187,6 +200,33 @@ func (c *Client) Session() *dto.Session { return c.session } +// func (c *Client) readMessageToQueue() { +// for { +// _, message, err := c.conn.ReadMessage() +// if err != nil { +// log.Errorf("%s read message failed, %v, message %s", c.session, err, string(message)) +// close(c.messageQueue) +// c.closeChan <- err +// return +// } +// payload := &dto.WSPayload{} +// if err := json.Unmarshal(message, payload); err != nil { +// log.Errorf("%s json failed, %v", c.session, err) +// continue +// } +// // 更新 global_s 的值 +// atomic.StoreInt64(&global_s, payload.S) + +// payload.RawMessage = message +// log.Infof("%s receive %s message, %s", c.session, dto.OPMeans(payload.OPCode), string(message)) +// // 处理内置的一些事件,如果处理成功,则这个事件不再投递给业务 +// if c.isHandleBuildIn(payload) { +// continue +// } +// c.messageQueue <- payload +// } +// } + func (c *Client) readMessageToQueue() { for { _, message, err := c.conn.ReadMessage() @@ -201,19 +241,58 @@ func (c *Client) readMessageToQueue() { log.Errorf("%s json failed, %v", c.session, err) continue } - // 更新 global_s 的值 atomic.StoreInt64(&global_s, payload.S) payload.RawMessage = message log.Infof("%s receive %s message, %s", c.session, dto.OPMeans(payload.OPCode), string(message)) + + // 计算数据的哈希值 + dataHash := calculateDataHash(payload.Data) + + // 检查是否已存在相同的 Data + if existingPayload, ok := getDataFromSyncMap(dataHash); ok { + // 如果已存在相同的 Data,则丢弃当前消息 + log.Infof("%s discard duplicate message with DataHash: %v", c.session, existingPayload) + continue + } + + // 将新的 payload 存入 sync.Map + storeDataToSyncMap(dataHash, payload) + // 处理内置的一些事件,如果处理成功,则这个事件不再投递给业务 if c.isHandleBuildIn(payload) { continue } + c.messageQueue <- payload } } +func getDataFromSyncMap(dataHash string) (*dto.WSPayload, bool) { + value, ok := dataMap.Load(dataHash) + if !ok { + return nil, false + } + payloadWithTimestamp, ok := value.(*PayloadWithTimestamp) + if !ok { + return nil, false + } + return payloadWithTimestamp.Payload, true +} + +func storeDataToSyncMap(dataHash string, payload *dto.WSPayload) { + payloadWithTimestamp := &PayloadWithTimestamp{ + Payload: payload, + Timestamp: time.Now(), + } + dataMap.Store(dataHash, payloadWithTimestamp) +} + +func calculateDataHash(data interface{}) string { + dataBytes, _ := json.Marshal(data) + return string(dataBytes) // 这里直接转换为字符串,可以使用更复杂的算法 +} + // 在全局范围通过atomic访问s值与message_id的映射 func GetGlobalS() int64 { return atomic.LoadInt64(&global_s) @@ -297,3 +376,31 @@ func (c *Client) readyHandler(payload *dto.WSPayload) { event.DefaultHandlers.Ready(payload, readyData) } } + +const cleanupInterval = 5 * time.Minute // 清理间隔时间 + +func StartCleanupRoutine() { + go func() { + for { + <-time.After(cleanupInterval) + cleanupDataMap() + } + }() +} + +func cleanupDataMap() { + now := time.Now() + dataMap.Range(func(key, value interface{}) bool { + payloadWithTimestamp, ok := value.(*PayloadWithTimestamp) + if !ok { + return true + } + + // 检查时间戳,清理超过一定时间的数据 + if now.Sub(payloadWithTimestamp.Timestamp) > cleanupInterval { + dataMap.Delete(key) + } + + return true + }) +} diff --git a/echo/echo.go b/echo/echo.go index 7125cc4f..461662e2 100644 --- a/echo/echo.go +++ b/echo/echo.go @@ -12,6 +12,70 @@ import ( "github.com/tencent-connect/botgo/dto" ) +func init() { + // 在 init 函数中运行清理逻辑 + startCleanupRoutine() +} + +func startCleanupRoutine() { + cleanupTicker = time.NewTicker(30 * time.Minute) + go func() { + for { + <-cleanupTicker.C + cleanupGlobalMaps() + } + }() +} + +func cleanupGlobalMaps() { + cleanupSyncMap(&globalSyncMapMsgid) + cleanupSyncMap(&globalReverseMapMsgid) + cleanupMessageGroupStack(globalMessageGroupStack) + cleanupEchoMapping(globalEchoMapping) + cleanupInt64ToIntMapping(globalInt64ToIntMapping) + cleanupStringToIntMappingSeq(globalStringToIntMappingSeq) +} + +func cleanupSyncMap(m *sync.Map) { + m.Range(func(key, value interface{}) bool { + m.Delete(key) + return true + }) +} + +func cleanupMessageGroupStack(stack *globalMessageGroup) { + stack.stack = make([]MessageGroupPair, 0) +} + +func cleanupEchoMapping(mapping *EchoMapping) { + mapping.msgTypeMapping.Range(func(key, value interface{}) bool { + mapping.msgTypeMapping.Delete(key) + return true + }) + mapping.msgIDMapping.Range(func(key, value interface{}) bool { + mapping.msgIDMapping.Delete(key) + return true + }) + mapping.eventIDMapping.Range(func(key, value interface{}) bool { + mapping.eventIDMapping.Delete(key) + return true + }) +} + +func cleanupInt64ToIntMapping(mapping *Int64ToIntMapping) { + mapping.mapping.Range(func(key, value interface{}) bool { + mapping.mapping.Delete(key) + return true + }) +} + +func cleanupStringToIntMappingSeq(mapping *StringToIntMappingSeq) { + mapping.mapping.Range(func(key, value interface{}) bool { + mapping.mapping.Delete(key) + return true + }) +} + type EchoMapping struct { msgTypeMapping sync.Map msgIDMapping sync.Map diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index 11f81d37..5f91a6f7 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -123,47 +123,49 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope var SSM bool var originalGroupID, originalUserID string - // 检查UserID是否为nil - if message.Params.UserID != nil && config.GetIdmapPro() && message.Params.UserID.(string) != "" && message.Params.UserID.(string) != "0" { - // 如果UserID不是nil且配置为使用Pro版本,则调用RetrieveRowByIDv2Pro - originalGroupID, originalUserID, err = idmap.RetrieveRowByIDv2Pro(message.Params.GroupID.(string), message.Params.UserID.(string)) - if err != nil { - mylog.Printf("Error1 retrieving original GroupID: %v", err) - } - mylog.Printf("测试,通过idmaps-pro获取的originalGroupID:%v", originalGroupID) - if originalGroupID == "" { - originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) + if len(message.Params.GroupID.(string)) != 32 { + // 检查UserID是否为nil + if message.Params.UserID != nil && config.GetIdmapPro() && message.Params.UserID.(string) != "" && message.Params.UserID.(string) != "0" { + // 如果UserID不是nil且配置为使用Pro版本,则调用RetrieveRowByIDv2Pro + originalGroupID, originalUserID, err = idmap.RetrieveRowByIDv2Pro(message.Params.GroupID.(string), message.Params.UserID.(string)) if err != nil { - mylog.Printf("Error2 retrieving original GroupID: %v", err) - return "", nil + mylog.Printf("Error1 retrieving original GroupID: %v", err) + } + mylog.Printf("测试,通过idmaps-pro获取的originalGroupID:%v", originalGroupID) + if originalGroupID == "" { + originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) + if err != nil { + mylog.Printf("Error2 retrieving original GroupID: %v", err) + return "", nil + } + mylog.Printf("测试,通过idmaps获取的originalGroupID:%v", originalGroupID) } - mylog.Printf("测试,通过idmaps获取的originalGroupID:%v", originalGroupID) - } - } else { - // 如果UserID是nil或配置不使用Pro版本,则调用RetrieveRowByIDv2 - originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) - if err != nil { - mylog.Printf("Error retrieving original GroupID: %v", err) - } - // 检查 message.Params.UserID 是否为 nil - if message.Params.UserID == nil { - //mylog.Println("UserID is nil") } else { - // 进行类型断言,确认 UserID 不是 nil - userID, ok := message.Params.UserID.(string) - if !ok { - mylog.Println("UserID is not a string") - // 处理类型断言失败的情况 + // 如果UserID是nil或配置不使用Pro版本,则调用RetrieveRowByIDv2 + originalGroupID, err = idmap.RetrieveRowByIDv2(message.Params.GroupID.(string)) + if err != nil { + mylog.Printf("Error retrieving original GroupID: %v", err) + } + // 检查 message.Params.UserID 是否为 nil + if message.Params.UserID == nil { + //mylog.Println("UserID is nil") } else { - originalUserID, err = idmap.RetrieveRowByIDv2(userID) - if err != nil { - mylog.Printf("Error retrieving original UserID: %v", err) + // 进行类型断言,确认 UserID 不是 nil + userID, ok := message.Params.UserID.(string) + if !ok { + mylog.Println("UserID is not a string") + // 处理类型断言失败的情况 + } else { + originalUserID, err = idmap.RetrieveRowByIDv2(userID) + if err != nil { + mylog.Printf("Error retrieving original UserID: %v", err) + } } } } + message.Params.GroupID = originalGroupID + message.Params.UserID = originalUserID } - message.Params.GroupID = originalGroupID - message.Params.UserID = originalUserID // 检查字符串是否仅包含数字 isNumeric := func(s string) bool { From 603927233216758d3e975ab7ab7d182117c9cbee Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 1 Aug 2024 23:43:32 +0800 Subject: [PATCH 26/36] beta472 --- botgo/websocket/client/client.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/botgo/websocket/client/client.go b/botgo/websocket/client/client.go index 099c495b..c1c55275 100644 --- a/botgo/websocket/client/client.go +++ b/botgo/websocket/client/client.go @@ -246,19 +246,22 @@ func (c *Client) readMessageToQueue() { payload.RawMessage = message log.Infof("%s receive %s message, %s", c.session, dto.OPMeans(payload.OPCode), string(message)) - // 计算数据的哈希值 - dataHash := calculateDataHash(payload.Data) + // 不过滤心跳事件 + if payload.OPCode != 11 { + // 计算数据的哈希值 + dataHash := calculateDataHash(payload.Data) + + // 检查是否已存在相同的 Data + if existingPayload, ok := getDataFromSyncMap(dataHash); ok { + // 如果已存在相同的 Data,则丢弃当前消息 + log.Infof("%s discard duplicate message with DataHash: %v", c.session, existingPayload) + continue + } - // 检查是否已存在相同的 Data - if existingPayload, ok := getDataFromSyncMap(dataHash); ok { - // 如果已存在相同的 Data,则丢弃当前消息 - log.Infof("%s discard duplicate message with DataHash: %v", c.session, existingPayload) - continue + // 将新的 payload 存入 sync.Map + storeDataToSyncMap(dataHash, payload) } - // 将新的 payload 存入 sync.Map - storeDataToSyncMap(dataHash, payload) - // 处理内置的一些事件,如果处理成功,则这个事件不再投递给业务 if c.isHandleBuildIn(payload) { continue From c45b450a01d0de86540e9e580551f031e6ec9fe1 Mon Sep 17 00:00:00 2001 From: cosmo Date: Fri, 2 Aug 2024 01:52:02 +0800 Subject: [PATCH 27/36] beta473 --- handlers/send_group_msg.go | 2 +- handlers/send_group_msg_raw.go | 2 +- handlers/send_private_msg.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index ac5508c9..696ff3a6 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -102,7 +102,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) // 临时的 msgType = "group" - } else if len(message.Params.UserID.(string)) == 32 { + } else if message.Params.UserID != nil && len(message.Params.UserID.(string)) == 32 { idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) // 临时的 msgType = "group_private" diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index 5f91a6f7..601e0038 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -87,7 +87,7 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope idInt64, err = idmap.GenerateRowID(message.Params.GroupID.(string), 9) // 临时的 msgType = "group" - } else if len(message.Params.UserID.(string)) == 32 { + } else if message.Params.UserID != nil && len(message.Params.UserID.(string)) == 32 { idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) // 临时的 msgType = "group_private" diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index b33a9005..fb929d93 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -81,7 +81,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open var idInt64 int64 var err error - if len(message.Params.UserID.(string)) == 32 { + if message.Params.UserID != nil && len(message.Params.UserID.(string)) == 32 { idInt64, err = idmap.GenerateRowID(message.Params.UserID.(string), 9) // 临时的 msgType = "group_private" From f89d6c5d8d53aa31d33765851e08897b2b0e4e0e Mon Sep 17 00:00:00 2001 From: cosmo Date: Sat, 3 Aug 2024 13:06:13 +0800 Subject: [PATCH 28/36] beta473 --- Processor/ProcessGroupDelBot.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Processor/ProcessGroupDelBot.go b/Processor/ProcessGroupDelBot.go index 59e8fc39..b0dfa77e 100644 --- a/Processor/ProcessGroupDelBot.go +++ b/Processor/ProcessGroupDelBot.go @@ -70,6 +70,11 @@ func (p *Processors) ProcessGroupDelBot(data *dto.GroupAddBotEvent) error { Time: timestampInt64, UserID: userid64, } + //增强配置 + if !config.GetNativeOb11() { + Notice.RealUserID = data.OpMemberOpenID + Notice.RealGroupID = data.GroupOpenID + } groupMsgMap := structToMap(Notice) //上报信息到onebotv11应用端(正反ws) go p.BroadcastMessageToAll(groupMsgMap, p.Apiv2, data) From b54fdee40e32f0698ec7302627b38ba52445e36f Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 5 Aug 2024 21:14:37 +0800 Subject: [PATCH 29/36] beta475 --- config/config.go | 271 +++++++++++++++++++----------------- handlers/message_parser.go | 12 ++ mylog/mylog.go | 23 ++- structs/structs.go | 7 +- sys/safelunch.go | 6 +- template/config_template.go | 1 + 6 files changed, 182 insertions(+), 138 deletions(-) diff --git a/config/config.go b/config/config.go index a3fe549a..35b7fcda 100644 --- a/config/config.go +++ b/config/config.go @@ -11,7 +11,6 @@ import ( "sync" "time" - "github.com/hoshinonyaruko/gensokyo/mylog" "github.com/hoshinonyaruko/gensokyo/structs" "github.com/hoshinonyaruko/gensokyo/sys" "github.com/hoshinonyaruko/gensokyo/template" @@ -546,7 +545,7 @@ func DeleteConfig() error { // 获取当前执行的可执行文件的路径 exePath, err := os.Executable() if err != nil { - mylog.Println("Error getting executable path:", err) + fmt.Println("Error getting executable path:", err) return err } @@ -558,14 +557,14 @@ func DeleteConfig() error { // 删除配置文件 if err := os.Remove(configPath); err != nil { - mylog.Println("Error removing config file:", err) + fmt.Println("Error removing config file:", err) return err } // 获取内网IP地址 ip, err := sys.GetLocalIP() if err != nil { - mylog.Println("Error retrieving the local IP address:", err) + fmt.Println("Error retrieving the local IP address:", err) return err } @@ -574,7 +573,7 @@ func DeleteConfig() error { // 创建一个新的配置文件模板 写到配置 if err := os.WriteFile(configPath, []byte(configData), 0644); err != nil { - mylog.Println("Error writing config.yml:", err) + fmt.Println("Error writing config.yml:", err) return err } @@ -599,7 +598,7 @@ func GetServer_dir() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get upload directory.") + fmt.Println("Warning: instance is nil when trying to get upload directory.") return "" } return instance.Settings.Server_dir @@ -611,7 +610,7 @@ func GetDevBotid() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get DevBotid.") + fmt.Println("Warning: instance is nil when trying to get DevBotid.") return "1234" } return instance.Settings.DevBotid @@ -623,7 +622,7 @@ func GetForwardMsgLimit() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get GetForwardMsgLimit.") + fmt.Println("Warning: instance is nil when trying to get GetForwardMsgLimit.") return 3 } return instance.Settings.ForwardMsgLimit @@ -635,7 +634,7 @@ func GetDevelop_Acdir() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get DevlopAcDir.") + fmt.Println("Warning: instance is nil when trying to get DevlopAcDir.") return "" } return instance.Settings.DevlopAcDir @@ -647,7 +646,7 @@ func GetLotusValue() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get lotus value.") + fmt.Println("Warning: instance is nil when trying to get lotus value.") return false } return instance.Settings.Lotus @@ -659,7 +658,7 @@ func GetTwoWayEcho() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get lotus value.") + fmt.Println("Warning: instance is nil when trying to get lotus value.") return false } return instance.Settings.TwoWayEcho @@ -671,7 +670,7 @@ func GetWhitePrefixMode() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetWhitePrefixModes value.") + fmt.Println("Warning: instance is nil when trying to GetWhitePrefixModes value.") return false } return instance.Settings.WhitePrefixMode @@ -693,7 +692,7 @@ func GetBlackPrefixMode() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetBlackPrefixMode value.") + fmt.Println("Warning: instance is nil when trying to GetBlackPrefixMode value.") return false } return instance.Settings.BlackPrefixMode @@ -715,7 +714,7 @@ func GetVisibleIP() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetVisibleIP value.") + fmt.Println("Warning: instance is nil when trying to GetVisibleIP value.") return false } return instance.Settings.VisibleIp @@ -745,7 +744,7 @@ func GetLazyMessageId() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get LazyMessageId value.") + fmt.Println("Warning: instance is nil when trying to get LazyMessageId value.") return false } return instance.Settings.LazyMessageId @@ -757,7 +756,7 @@ func GetHashIDValue() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get hashid value.") + fmt.Println("Warning: instance is nil when trying to get hashid value.") return false } return instance.Settings.HashID @@ -769,7 +768,7 @@ func GetRemoveAt() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get RemoveAt value.") + fmt.Println("Warning: instance is nil when trying to get RemoveAt value.") return false } return instance.Settings.RemoveAt @@ -781,7 +780,7 @@ func GetPortValue() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get port value.") + fmt.Println("Warning: instance is nil when trying to get port value.") return "" } return instance.Settings.Port @@ -793,7 +792,7 @@ func GetArrayValue() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get array value.") + fmt.Println("Warning: instance is nil when trying to get array value.") return false } return instance.Settings.Array @@ -845,7 +844,7 @@ func GetEnableWsServer() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get port value.") + fmt.Println("Warning: instance is nil when trying to get port value.") return false } return instance.Settings.EnableWsServer @@ -857,7 +856,7 @@ func GetWsServerToken() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get WsServerToken value.") + fmt.Println("Warning: instance is nil when trying to get WsServerToken value.") return "" } return instance.Settings.WsServerToken @@ -869,7 +868,7 @@ func GetIdentifyFile() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get identify file name.") + fmt.Println("Warning: instance is nil when trying to get identify file name.") return false } return instance.Settings.IdentifyFile @@ -881,7 +880,7 @@ func GetCrtPath() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get crt path.") + fmt.Println("Warning: instance is nil when trying to get crt path.") return "" } return instance.Settings.Crt @@ -893,7 +892,7 @@ func GetKeyPath() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get key path.") + fmt.Println("Warning: instance is nil when trying to get key path.") return "" } return instance.Settings.Key @@ -905,7 +904,7 @@ func GetDeveloperLog() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get developer log status.") + fmt.Println("Warning: instance is nil when trying to get developer log status.") return false } return instance.Settings.DeveloperLog @@ -961,7 +960,7 @@ func GetServerUserName() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get server user name.") + fmt.Println("Warning: instance is nil when trying to get server user name.") return "" } return instance.Settings.Username @@ -973,7 +972,7 @@ func GetServerUserPassword() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get server user password.") + fmt.Println("Warning: instance is nil when trying to get server user password.") return "" } return instance.Settings.Password @@ -985,7 +984,7 @@ func GetImageLimit() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get image limit value.") + fmt.Println("Warning: instance is nil when trying to get image limit value.") return 0 // 或者返回一个默认的 ImageLimit 值 } @@ -998,7 +997,7 @@ func GetRemovePrefixValue() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get remove_prefix value.") + fmt.Println("Warning: instance is nil when trying to get remove_prefix value.") return false // 或者可能是默认值,取决于您的应用程序逻辑 } return instance.Settings.RemovePrefix @@ -1010,7 +1009,7 @@ func GetBackupPort() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get LotusPort.") + fmt.Println("Warning: instance is nil when trying to get LotusPort.") return "" } @@ -1023,7 +1022,7 @@ func GetDevMsgID() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetDevMsgID value.") + fmt.Println("Warning: instance is nil when trying to GetDevMsgID value.") return false } return instance.Settings.DevMessgeID @@ -1035,7 +1034,7 @@ func GetSaveLogs() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetSaveLogs value.") + fmt.Println("Warning: instance is nil when trying to GetSaveLogs value.") return false } return instance.Settings.SaveLogs @@ -1047,7 +1046,7 @@ func GetLogLevel() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetLogLevel value.") + fmt.Println("Warning: instance is nil when trying to GetLogLevel value.") return 2 } return instance.Settings.LogLevel @@ -1059,7 +1058,7 @@ func GetBindPrefix() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetBindPrefix value.") + fmt.Println("Warning: instance is nil when trying to GetBindPrefix value.") return "/bind" } return instance.Settings.BindPrefix @@ -1071,7 +1070,7 @@ func GetMePrefix() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetMePrefix value.") + fmt.Println("Warning: instance is nil when trying to GetMePrefix value.") return "/me" } return instance.Settings.MePrefix @@ -1083,7 +1082,7 @@ func GetFrpPort() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetFrpPort value.") + fmt.Println("Warning: instance is nil when trying to GetFrpPort value.") return "0" } return instance.Settings.FrpPort @@ -1095,7 +1094,7 @@ func GetRemoveBotAtGroup() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetRemoveBotAtGroup value.") + fmt.Println("Warning: instance is nil when trying to GetRemoveBotAtGroup value.") return false } return instance.Settings.RemoveBotAtGroup @@ -1107,7 +1106,7 @@ func GetImageLimitB() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to ImageLimitB value.") + fmt.Println("Warning: instance is nil when trying to ImageLimitB value.") return 100 } return instance.Settings.ImageLimitB @@ -1119,7 +1118,7 @@ func GetRecordSampleRate() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetRecordSampleRate value.") + fmt.Println("Warning: instance is nil when trying to GetRecordSampleRate value.") return 0 // 或者返回一个默认的 ImageLimit 值 } @@ -1132,7 +1131,7 @@ func GetRecordBitRate() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetRecordBitRate value.") + fmt.Println("Warning: instance is nil when trying to GetRecordBitRate value.") return 0 // 或者返回一个默认的 ImageLimit 值 } @@ -1145,7 +1144,7 @@ func GetNoWhiteResponse() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to NoWhiteResponse value.") + fmt.Println("Warning: instance is nil when trying to NoWhiteResponse value.") return "" } return instance.Settings.NoWhiteResponse @@ -1157,7 +1156,7 @@ func GetSendError() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetSendError value.") + fmt.Println("Warning: instance is nil when trying to GetSendError value.") return true } return instance.Settings.SendError @@ -1169,7 +1168,7 @@ func GetSaveError() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetSaveError value.") + fmt.Println("Warning: instance is nil when trying to GetSaveError value.") return true } return instance.Settings.SaveError @@ -1181,7 +1180,7 @@ func GetAddAtGroup() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetAddGroupAt value.") + fmt.Println("Warning: instance is nil when trying to GetAddGroupAt value.") return true } return instance.Settings.AddAtGroup @@ -1193,7 +1192,7 @@ func GetUrlPicTransfer() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetUrlPicTransfer value.") + fmt.Println("Warning: instance is nil when trying to GetUrlPicTransfer value.") return true } return instance.Settings.UrlPicTransfer @@ -1205,7 +1204,7 @@ func GetLotusPassword() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetLotusPassword value.") + fmt.Println("Warning: instance is nil when trying to GetLotusPassword value.") return "" } return instance.Settings.LotusPassword @@ -1217,7 +1216,7 @@ func GetWsServerPath() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetWsServerPath value.") + fmt.Println("Warning: instance is nil when trying to GetWsServerPath value.") return "" } return instance.Settings.WsServerPath @@ -1229,7 +1228,7 @@ func GetIdmapPro() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetIdmapPro value.") + fmt.Println("Warning: instance is nil when trying to GetIdmapPro value.") return false } return instance.Settings.IdmapPro @@ -1241,7 +1240,7 @@ func GetCardAndNick() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetCardAndNick value.") + fmt.Println("Warning: instance is nil when trying to GetCardAndNick value.") return "" } return instance.Settings.CardAndNick @@ -1253,7 +1252,7 @@ func GetAutoBind() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetAutoBind value.") + fmt.Println("Warning: instance is nil when trying to GetAutoBind value.") return false } return instance.Settings.AutoBind @@ -1265,7 +1264,7 @@ func GetCustomBotName() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetCustomBotName value.") + fmt.Println("Warning: instance is nil when trying to GetCustomBotName value.") return "Gensokyo全域机器人" } return instance.Settings.CustomBotName @@ -1277,7 +1276,7 @@ func GetSendDelay() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetSendDelay value.") + fmt.Println("Warning: instance is nil when trying to GetSendDelay value.") return 300 } return instance.Settings.SendDelay @@ -1289,7 +1288,7 @@ func GetAtoPCount() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to AtoPCount value.") + fmt.Println("Warning: instance is nil when trying to AtoPCount value.") return 5 } return instance.Settings.AtoPCount @@ -1301,7 +1300,7 @@ func GetReconnecTimes() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to ReconnecTimes value.") + fmt.Println("Warning: instance is nil when trying to ReconnecTimes value.") return 50 } return instance.Settings.ReconnecTimes @@ -1313,7 +1312,7 @@ func GetHeartBeatInterval() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to HeartBeatInterval value.") + fmt.Println("Warning: instance is nil when trying to HeartBeatInterval value.") return 5 } return instance.Settings.HeartBeatInterval @@ -1325,7 +1324,7 @@ func GetLaunchReconectTimes() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to LaunchReconectTimes value.") + fmt.Println("Warning: instance is nil when trying to LaunchReconectTimes value.") return 3 } return instance.Settings.LaunchReconectTimes @@ -1337,7 +1336,7 @@ func GetUnlockPrefix() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to UnlockPrefix value.") + fmt.Println("Warning: instance is nil when trying to UnlockPrefix value.") return "/unlock" } return instance.Settings.UnlockPrefix @@ -1359,7 +1358,7 @@ func GetTransferUrl() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetTransferUrl value.") + fmt.Println("Warning: instance is nil when trying to GetTransferUrl value.") return false } return instance.Settings.TransferUrl @@ -1371,7 +1370,7 @@ func GetHttpAddress() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get HTTP address.") + fmt.Println("Warning: instance is nil when trying to get HTTP address.") return "" } return instance.Settings.HttpAddress @@ -1383,7 +1382,7 @@ func GetHTTPAccessToken() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get HTTP access token.") + fmt.Println("Warning: instance is nil when trying to get HTTP access token.") return "" } return instance.Settings.AccessToken @@ -1395,7 +1394,7 @@ func GetHttpVersion() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get HTTP version.") + fmt.Println("Warning: instance is nil when trying to get HTTP version.") return 11 } return instance.Settings.HttpVersion @@ -1407,7 +1406,7 @@ func GetHttpTimeOut() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get HTTP timeout.") + fmt.Println("Warning: instance is nil when trying to get HTTP timeout.") return 5 } return instance.Settings.HttpTimeOut @@ -1419,7 +1418,7 @@ func GetPostUrl() []string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get POST URL.") + fmt.Println("Warning: instance is nil when trying to get POST URL.") return nil } return instance.Settings.PostUrl @@ -1431,7 +1430,7 @@ func GetPostSecret() []string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get POST secret.") + fmt.Println("Warning: instance is nil when trying to get POST secret.") return nil } return instance.Settings.PostSecret @@ -1443,7 +1442,7 @@ func GetVisualPrefixsBypass() []string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to getVisualPrefixsBypass.") + fmt.Println("Warning: instance is nil when trying to getVisualPrefixsBypass.") return nil } return instance.Settings.VisualPrefixsBypass @@ -1455,7 +1454,7 @@ func GetPostMaxRetries() []int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get POST max retries.") + fmt.Println("Warning: instance is nil when trying to get POST max retries.") return nil } return instance.Settings.PostMaxRetries @@ -1467,7 +1466,7 @@ func GetPostRetriesInterval() []int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get POST retries interval.") + fmt.Println("Warning: instance is nil when trying to get POST retries interval.") return nil } return instance.Settings.PostRetriesInterval @@ -1479,7 +1478,7 @@ func GetNativeOb11() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to NativeOb11 value.") + fmt.Println("Warning: instance is nil when trying to NativeOb11 value.") return false } return instance.Settings.NativeOb11 @@ -1491,7 +1490,7 @@ func GetRamDomSeq() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetRamDomSeq value.") + fmt.Println("Warning: instance is nil when trying to GetRamDomSeq value.") return false } return instance.Settings.RamDomSeq @@ -1503,7 +1502,7 @@ func GetUrlToQrimage() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetUrlToQrimage value.") + fmt.Println("Warning: instance is nil when trying to GetUrlToQrimage value.") return false } return instance.Settings.UrlToQrimage @@ -1514,7 +1513,7 @@ func GetUseUin() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to UseUin value.") + fmt.Println("Warning: instance is nil when trying to UseUin value.") return false } return instance.Settings.UseUin @@ -1526,7 +1525,7 @@ func GetQrSize() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to QrSize value.") + fmt.Println("Warning: instance is nil when trying to QrSize value.") return 200 } return instance.Settings.QrSize @@ -1579,7 +1578,7 @@ func GetWhiteBypassRevers() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetWhiteBypassRevers value.") + fmt.Println("Warning: instance is nil when trying to GetWhiteBypassRevers value.") return false } return instance.Settings.WhiteBypassRevers @@ -1591,7 +1590,7 @@ func GetGuildUrlImageToBase64() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GuildUrlImageToBase64 value.") + fmt.Println("Warning: instance is nil when trying to GuildUrlImageToBase64 value.") return false } return instance.Settings.GuildUrlImageToBase64 @@ -1603,7 +1602,7 @@ func GetTencentBucketURL() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get TencentBucketURL.") + fmt.Println("Warning: instance is nil when trying to get TencentBucketURL.") return "" } @@ -1612,7 +1611,7 @@ func GetTencentBucketURL() string { // 构建并返回URL if bucketName == "" || bucketRegion == "" { - mylog.Println("Warning: Tencent bucket name or region is not configured.") + fmt.Println("Warning: Tencent bucket name or region is not configured.") return "" } @@ -1625,7 +1624,7 @@ func GetTencentCosSecretid() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get TencentCosSecretid.") + fmt.Println("Warning: instance is nil when trying to get TencentCosSecretid.") return "" } return instance.Settings.TencentCosSecretid @@ -1637,7 +1636,7 @@ func GetTencentSecretKey() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get TencentSecretKey.") + fmt.Println("Warning: instance is nil when trying to get TencentSecretKey.") return "" } return instance.Settings.TencentSecretKey @@ -1649,7 +1648,7 @@ func GetTencentAudit() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to TencentAudit value.") + fmt.Println("Warning: instance is nil when trying to TencentAudit value.") return false } return instance.Settings.TencentAudit @@ -1661,7 +1660,7 @@ func GetOssType() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get ExtraPicAuditingType version.") + fmt.Println("Warning: instance is nil when trying to get ExtraPicAuditingType version.") return 0 } return instance.Settings.OssType @@ -1673,7 +1672,7 @@ func GetBaiduBOSBucketName() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get BaiduBOSBucketName.") + fmt.Println("Warning: instance is nil when trying to get BaiduBOSBucketName.") return "" } return instance.Settings.BaiduBOSBucketName @@ -1685,7 +1684,7 @@ func GetBaiduBCEAK() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get BaiduBCEAK.") + fmt.Println("Warning: instance is nil when trying to get BaiduBCEAK.") return "" } return instance.Settings.BaiduBCEAK @@ -1697,7 +1696,7 @@ func GetBaiduBCESK() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get BaiduBCESK.") + fmt.Println("Warning: instance is nil when trying to get BaiduBCESK.") return "" } return instance.Settings.BaiduBCESK @@ -1709,7 +1708,7 @@ func GetBaiduAudit() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get BaiduAudit.") + fmt.Println("Warning: instance is nil when trying to get BaiduAudit.") return 0 } return instance.Settings.BaiduAudit @@ -1721,7 +1720,7 @@ func GetAliyunEndpoint() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get AliyunEndpoint.") + fmt.Println("Warning: instance is nil when trying to get AliyunEndpoint.") return "" } return instance.Settings.AliyunEndpoint @@ -1759,7 +1758,7 @@ func GetAliyunAccessKeyId() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get AliyunAccessKeyId.") + fmt.Println("Warning: instance is nil when trying to get AliyunAccessKeyId.") return "" } return instance.Settings.AliyunAccessKeyId @@ -1771,7 +1770,7 @@ func GetAliyunAccessKeySecret() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get AliyunAccessKeySecret.") + fmt.Println("Warning: instance is nil when trying to get AliyunAccessKeySecret.") return "" } return instance.Settings.AliyunAccessKeySecret @@ -1783,7 +1782,7 @@ func GetAliyunBucketName() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get AliyunBucketName.") + fmt.Println("Warning: instance is nil when trying to get AliyunBucketName.") return "" } return instance.Settings.AliyunBucketName @@ -1795,7 +1794,7 @@ func GetAliyunAudit() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to AliyunAudit value.") + fmt.Println("Warning: instance is nil when trying to AliyunAudit value.") return false } return instance.Settings.AliyunAudit @@ -1859,7 +1858,7 @@ func GetTransFormApiIds() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to TransFormApiIds value.") + fmt.Println("Warning: instance is nil when trying to TransFormApiIds value.") return false } return instance.Settings.TransFormApiIds @@ -1871,7 +1870,7 @@ func GetCustomTemplateID() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get CustomTemplateID.") + fmt.Println("Warning: instance is nil when trying to get CustomTemplateID.") return "" } return instance.Settings.CustomTemplateID @@ -1883,7 +1882,7 @@ func GetKeyBoardID() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get KeyBoardID.") + fmt.Println("Warning: instance is nil when trying to get KeyBoardID.") return "" } return instance.Settings.KeyBoardID @@ -1915,7 +1914,7 @@ func GetVwhitePrefixMode() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to VwhitePrefixMode value.") + fmt.Println("Warning: instance is nil when trying to VwhitePrefixMode value.") return false } return instance.Settings.VwhitePrefixMode @@ -1947,7 +1946,7 @@ func GetLinkPrefix() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get LinkPrefix.") + fmt.Println("Warning: instance is nil when trying to get LinkPrefix.") return "" } return instance.Settings.LinkPrefix @@ -1959,7 +1958,7 @@ func GetLinkBots() []string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get LinkBots.") + fmt.Println("Warning: instance is nil when trying to get LinkBots.") return nil } return instance.Settings.LinkBots @@ -1971,7 +1970,7 @@ func GetLinkText() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get LinkText.") + fmt.Println("Warning: instance is nil when trying to get LinkText.") return "" } return instance.Settings.LinkText @@ -1983,7 +1982,7 @@ func GetLinkPic() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get LinkPic.") + fmt.Println("Warning: instance is nil when trying to get LinkPic.") return "" } return instance.Settings.LinkPic @@ -1995,7 +1994,7 @@ func GetMusicPrefix() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get MusicPrefix.") + fmt.Println("Warning: instance is nil when trying to get MusicPrefix.") return "" } return instance.Settings.MusicPrefix @@ -2007,7 +2006,7 @@ func GetDisableWebui() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetDisableWebui value.") + fmt.Println("Warning: instance is nil when trying to GetDisableWebui value.") return false } return instance.Settings.DisableWebui @@ -2019,7 +2018,7 @@ func GetBotForumTitle() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get BotForumTitle.") + fmt.Println("Warning: instance is nil when trying to get BotForumTitle.") return "" } return instance.Settings.BotForumTitle @@ -2031,7 +2030,7 @@ func GetGlobalInteractionToMessage() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GlobalInteractionToMessage value.") + fmt.Println("Warning: instance is nil when trying to GlobalInteractionToMessage value.") return false } return instance.Settings.GlobalInteractionToMessage @@ -2043,7 +2042,7 @@ func GetAutoPutInteraction() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to AutoPutInteraction value.") + fmt.Println("Warning: instance is nil when trying to AutoPutInteraction value.") return false } return instance.Settings.AutoPutInteraction @@ -2055,7 +2054,7 @@ func GetPutInteractionDelay() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get PutInteractionDelay.") + fmt.Println("Warning: instance is nil when trying to get PutInteractionDelay.") return 0 } return instance.Settings.PutInteractionDelay @@ -2067,7 +2066,7 @@ func GetFix11300() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to Fix11300 value.") + fmt.Println("Warning: instance is nil when trying to Fix11300 value.") return false } return instance.Settings.Fix11300 @@ -2079,7 +2078,7 @@ func GetLotusWithoutIdmaps() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to LotusWithoutIdmaps value.") + fmt.Println("Warning: instance is nil when trying to LotusWithoutIdmaps value.") return false } return instance.Settings.LotusWithoutIdmaps @@ -2091,7 +2090,7 @@ func GetGroupListAllGuilds() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetGroupListAllGuilds value.") + fmt.Println("Warning: instance is nil when trying to GetGroupListAllGuilds value.") return false } return instance.Settings.GetGroupListAllGuilds @@ -2103,7 +2102,7 @@ func GetGetGroupListGuilds() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get GetGroupListGuilds.") + fmt.Println("Warning: instance is nil when trying to get GetGroupListGuilds.") return "10" } return instance.Settings.GetGroupListGuilds @@ -2115,7 +2114,7 @@ func GetGroupListReturnGuilds() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GetGroupListReturnGuilds value.") + fmt.Println("Warning: instance is nil when trying to GetGroupListReturnGuilds value.") return false } return instance.Settings.GetGroupListReturnGuilds @@ -2127,7 +2126,7 @@ func GetGroupListGuidsType() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get GetGroupListGuidsType.") + fmt.Println("Warning: instance is nil when trying to get GetGroupListGuidsType.") return 0 } return instance.Settings.GetGroupListGuidsType @@ -2139,7 +2138,7 @@ func GetGroupListDelay() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get GetGroupListDelay.") + fmt.Println("Warning: instance is nil when trying to get GetGroupListDelay.") return 0 } return instance.Settings.GetGroupListDelay @@ -2151,7 +2150,7 @@ func GetGlobalServerTempQQguild() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GlobalServerTempQQguild value.") + fmt.Println("Warning: instance is nil when trying to GlobalServerTempQQguild value.") return false } return instance.Settings.GlobalServerTempQQguild @@ -2163,7 +2162,7 @@ func GetServerTempQQguild() string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to ServerTempQQguild value.") + fmt.Println("Warning: instance is nil when trying to ServerTempQQguild value.") return "0" } return instance.Settings.ServerTempQQguild @@ -2185,7 +2184,7 @@ func GetUploadPicV2Base64() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to UploadPicV2 value.") + fmt.Println("Warning: instance is nil when trying to UploadPicV2 value.") return false } return instance.Settings.UploadPicV2Base64 @@ -2197,7 +2196,7 @@ func GetAutoWithdraw() []string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get AutoWithdraw.") + fmt.Println("Warning: instance is nil when trying to get AutoWithdraw.") return nil } return instance.Settings.AutoWithdraw @@ -2209,7 +2208,7 @@ func GetAutoWithdrawTime() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get AutoWithdrawTime.") + fmt.Println("Warning: instance is nil when trying to get AutoWithdrawTime.") return 0 } return instance.Settings.AutoWithdrawTime @@ -2231,7 +2230,7 @@ func GetEnableChangeWord() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to EnableChangeWord.") + fmt.Println("Warning: instance is nil when trying to EnableChangeWord.") return false } return instance.Settings.EnableChangeWord @@ -2243,7 +2242,7 @@ func GetGlobalGroupMsgRejectReciveEventToMessage() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to GlobalGroupMsgRejectReciveEventToMessage.") + fmt.Println("Warning: instance is nil when trying to GlobalGroupMsgRejectReciveEventToMessage.") return false } return instance.Settings.GlobalGroupMsgRejectReciveEventToMessage @@ -2275,7 +2274,7 @@ func GetEntersAsBlock() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to EntersAsBlock.") + fmt.Println("Warning: instance is nil when trying to EntersAsBlock.") return false } return instance.Settings.EntersAsBlock @@ -2287,7 +2286,7 @@ func GetNativeMD() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to NativeMD.") + fmt.Println("Warning: instance is nil when trying to NativeMD.") return false } return instance.Settings.NativeMD @@ -2309,7 +2308,7 @@ func GetAutoLink() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to AutoLink value.") + fmt.Println("Warning: instance is nil when trying to AutoLink value.") return false } return instance.Settings.AutoLink @@ -2321,7 +2320,7 @@ func GetLinkLines() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to LinkLines value.") + fmt.Println("Warning: instance is nil when trying to LinkLines value.") return 2 //默认2个一行 } @@ -2334,7 +2333,7 @@ func GetLinkNum() int { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to LinkNum value.") + fmt.Println("Warning: instance is nil when trying to LinkNum value.") return 6 //默认6个 } @@ -2347,7 +2346,7 @@ func GetDoNotReplaceAppid() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to DoNotReplaceAppid value.") + fmt.Println("Warning: instance is nil when trying to DoNotReplaceAppid value.") return false } return instance.Settings.DoNotReplaceAppid @@ -2359,7 +2358,7 @@ func GetMemoryMsgid() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to MemoryMsgid value.") + fmt.Println("Warning: instance is nil when trying to MemoryMsgid value.") return false } return instance.Settings.MemoryMsgid @@ -2371,7 +2370,7 @@ func GetLotusGrpc() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to LotusGrpc value.") + fmt.Println("Warning: instance is nil when trying to LotusGrpc value.") return false } return instance.Settings.LotusGrpc @@ -2383,7 +2382,7 @@ func GetLotusWithoutUploadPic() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to LotusWithoutUploadPic value.") + fmt.Println("Warning: instance is nil when trying to LotusWithoutUploadPic value.") return false } return instance.Settings.LotusWithoutUploadPic @@ -2395,7 +2394,7 @@ func GetDisableErrorChan() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to DisableErrorChan value.") + fmt.Println("Warning: instance is nil when trying to DisableErrorChan value.") return false } return instance.Settings.DisableErrorChan @@ -2407,7 +2406,7 @@ func GetStringOb11() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to StringOb11 value.") + fmt.Println("Warning: instance is nil when trying to StringOb11 value.") return false } return instance.Settings.StringOb11 @@ -2419,7 +2418,7 @@ func GetStringAction() bool { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to StringAction value.") + fmt.Println("Warning: instance is nil when trying to StringAction value.") return false } return instance.Settings.StringAction @@ -2431,8 +2430,20 @@ func GetPutInteractionExcept() []string { defer mu.RUnlock() if instance == nil { - mylog.Println("Warning: instance is nil when trying to get PutInteractionExcept.") + fmt.Println("Warning: instance is nil when trying to get PutInteractionExcept.") return nil } return instance.Settings.PutInteractionExcept } + +// 获取 LogSuffixPerMins +func GetLogSuffixPerMins() int { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + fmt.Println("Warning: instance is nil when trying to get LogSuffixPerMins.") + return 0 + } + return instance.Settings.LogSuffixPerMins +} diff --git a/handlers/message_parser.go b/handlers/message_parser.go index d193dcc6..d7190533 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -866,6 +866,18 @@ func RevertTransformedText(data interface{}, msgtype string, api openapi.OpenAPI messageText = " " } + //一个斜杠后跟一个空格的,用户也不希望去掉 + if msg.Content == "/ " { + menumsg = true + messageText = " " + } + + //一个空格一个斜杠后跟一个空格的,用户也不希望去掉 + if msg.Content == " / " { + menumsg = true + messageText = " " + } + if !menumsg { //处理前 先去前后空 messageText = strings.TrimSpace(msg.Content) diff --git a/mylog/mylog.go b/mylog/mylog.go index 748c8120..44ff9b65 100644 --- a/mylog/mylog.go +++ b/mylog/mylog.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/gorilla/websocket" + "github.com/hoshinonyaruko/gensokyo/config" ) type LogLevel int @@ -87,12 +88,30 @@ func NewMyLogAdapter(level LogLevel, enableFileLog bool) *MyLogAdapter { } } +// 获取当前日志文件名 +func getCurrentLogFilename() string { + suffixMins := config.GetLogSuffixPerMins() + baseFilename := time.Now().Format("2006-01-02") + if suffixMins == 0 { + return baseFilename + ".log" + } + + currentTime := time.Now() + currentMinutes := currentTime.Hour()*60 + currentTime.Minute() // 当前时间的总分钟数 + windowStartMinutes := (currentMinutes / suffixMins) * suffixMins // 计算当前时间窗口的起始分钟数 + windowStartHour := windowStartMinutes / 60 + windowStartMinute := windowStartMinutes % 60 + + suffix := fmt.Sprintf("%02d-%02d", windowStartHour, windowStartMinute) // 格式化时间窗口后缀 + return fmt.Sprintf("%s-%s.log", baseFilename, suffix) +} + // 文件日志记录函数 func (adapter *MyLogAdapter) logToFile(level, message string) { if !adapter.EnableFileLog { return } - filename := time.Now().Format("2006-01-02") + ".log" // 按日期命名文件 + filename := getCurrentLogFilename() filepath := adapter.FileLogPath + "/" + filename file, err := os.OpenFile(filepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) @@ -113,7 +132,7 @@ func LogToFile(level, message string) { if !enableFileLogGlobal { return } - filename := time.Now().Format("2006-01-02") + ".log" + filename := getCurrentLogFilename() filepath := logPath + "/" + filename file, err := os.OpenFile(filepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) diff --git a/structs/structs.go b/structs/structs.go index 685424c9..c89dfa04 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -70,9 +70,10 @@ type Settings struct { Crt string `yaml:"crt"` Key string `yaml:"key"` //日志类 - DeveloperLog bool `yaml:"developer_log"` - LogLevel int `yaml:"log_level"` - SaveLogs bool `yaml:"save_logs"` + DeveloperLog bool `yaml:"developer_log"` + LogLevel int `yaml:"log_level"` + SaveLogs bool `yaml:"save_logs"` + LogSuffixPerMins int `yaml:"log_suffix_per_mins"` //webui相关 DisableWebui bool `yaml:"disable_webui"` Username string `yaml:"server_user_name"` diff --git a/sys/safelunch.go b/sys/safelunch.go index 3e20ebc5..b5254f9a 100644 --- a/sys/safelunch.go +++ b/sys/safelunch.go @@ -4,12 +4,12 @@ package sys import ( + "fmt" "os" "path/filepath" "syscall" "unsafe" - "github.com/hoshinonyaruko/gensokyo/mylog" "golang.org/x/sys/windows" ) @@ -65,7 +65,7 @@ func NoMoreDoubleClick() error { return err } if err != nil { - mylog.Printf("打开gensokyo.bat失败: %v", err) + fmt.Printf("打开gensokyo.bat失败: %v", err) return nil } _ = f.Truncate(0) @@ -74,7 +74,7 @@ func NoMoreDoubleClick() error { exPath := filepath.Base(ex) _, err = f.WriteString("%Created by gensokyo. DO NOT EDIT ME!%\nstart cmd /K \"" + exPath + "\"") if err != nil { - mylog.Printf("写入gensokyo.bat失败: %v", err) + fmt.Printf("写入gensokyo.bat失败: %v", err) return nil } f.Close() diff --git a/template/config_template.go b/template/config_template.go index d63d60e0..e8711214 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -90,6 +90,7 @@ settings: developer_log : false #开启开发者日志 默认关闭 log_level : 1 # 0=debug 1=info 2=warning 3=error 默认1 save_logs : false #自动储存日志 + log_suffix_per_mins : 0 #默认0,代表不切分日志文件,设置60代表每60分钟储存一个日志文件,如果你的日志文件太大打不开,可以设置这个到合适的时间范围. #webui设置 disable_webui: false #禁用webui From a30a6973b233199b928bc5dd83bc5cfb91b52760 Mon Sep 17 00:00:00 2001 From: cosmo Date: Thu, 8 Aug 2024 14:31:56 +0800 Subject: [PATCH 30/36] beta476 --- botgo/event/event.go | 25 +++++++ botgo/websocket/client/client.go | 112 +------------------------------ 2 files changed, 26 insertions(+), 111 deletions(-) diff --git a/botgo/event/event.go b/botgo/event/event.go index e4c094e6..90b0326a 100644 --- a/botgo/event/event.go +++ b/botgo/event/event.go @@ -2,12 +2,34 @@ package event import ( "encoding/json" + "sync" + "time" "github.com/tidwall/gjson" // 由于回包的 d 类型不确定,gjson 用于从回包json中提取 d 并进行针对性的解析 "github.com/tencent-connect/botgo/dto" ) +func init() { + // Start a goroutine for periodic cleaning + go cleanProcessedIDs() +} + +func cleanProcessedIDs() { + ticker := time.NewTicker(5 * time.Minute) // Adjust the interval as needed + defer ticker.Stop() + + for range ticker.C { + // Clean processedIDs, remove entries which are no longer needed + processedIDs.Range(func(key, value interface{}) bool { + processedIDs.Delete(key) + return true + }) + } +} + +var processedIDs sync.Map + var eventParseFuncMap = map[dto.OPCode]map[dto.EventType]eventParseFunc{ dto.WSDispatchEvent: { dto.EventGuildCreate: guildHandler, @@ -218,6 +240,9 @@ func groupAtMessageHandler(payload *dto.WSPayload, message []byte) error { if err := ParseData(message, data); err != nil { return err } + if _, loaded := processedIDs.LoadOrStore(data.ID, struct{}{}); loaded { + return nil + } if DefaultHandlers.GroupATMessage != nil { return DefaultHandlers.GroupATMessage(payload, data) } diff --git a/botgo/websocket/client/client.go b/botgo/websocket/client/client.go index c1c55275..8bdd3559 100644 --- a/botgo/websocket/client/client.go +++ b/botgo/websocket/client/client.go @@ -7,7 +7,6 @@ import ( "fmt" "os" "os/signal" - "sync" "sync/atomic" "syscall" "time" @@ -27,18 +26,6 @@ const DefaultQueueSize = 10000 // 定义全局变量 var global_s int64 -// PayloadWithTimestamp 存储带时间戳的 WSPayload -type PayloadWithTimestamp struct { - Payload *dto.WSPayload - Timestamp time.Time -} - -var dataMap sync.Map - -func init() { - StartCleanupRoutine() -} - // Setup 依赖注册 func Setup() { websocket.Register(&Client{}) @@ -200,33 +187,6 @@ func (c *Client) Session() *dto.Session { return c.session } -// func (c *Client) readMessageToQueue() { -// for { -// _, message, err := c.conn.ReadMessage() -// if err != nil { -// log.Errorf("%s read message failed, %v, message %s", c.session, err, string(message)) -// close(c.messageQueue) -// c.closeChan <- err -// return -// } -// payload := &dto.WSPayload{} -// if err := json.Unmarshal(message, payload); err != nil { -// log.Errorf("%s json failed, %v", c.session, err) -// continue -// } -// // 更新 global_s 的值 -// atomic.StoreInt64(&global_s, payload.S) - -// payload.RawMessage = message -// log.Infof("%s receive %s message, %s", c.session, dto.OPMeans(payload.OPCode), string(message)) -// // 处理内置的一些事件,如果处理成功,则这个事件不再投递给业务 -// if c.isHandleBuildIn(payload) { -// continue -// } -// c.messageQueue <- payload -// } -// } - func (c *Client) readMessageToQueue() { for { _, message, err := c.conn.ReadMessage() @@ -241,61 +201,19 @@ func (c *Client) readMessageToQueue() { log.Errorf("%s json failed, %v", c.session, err) continue } + // 更新 global_s 的值 atomic.StoreInt64(&global_s, payload.S) payload.RawMessage = message log.Infof("%s receive %s message, %s", c.session, dto.OPMeans(payload.OPCode), string(message)) - - // 不过滤心跳事件 - if payload.OPCode != 11 { - // 计算数据的哈希值 - dataHash := calculateDataHash(payload.Data) - - // 检查是否已存在相同的 Data - if existingPayload, ok := getDataFromSyncMap(dataHash); ok { - // 如果已存在相同的 Data,则丢弃当前消息 - log.Infof("%s discard duplicate message with DataHash: %v", c.session, existingPayload) - continue - } - - // 将新的 payload 存入 sync.Map - storeDataToSyncMap(dataHash, payload) - } - // 处理内置的一些事件,如果处理成功,则这个事件不再投递给业务 if c.isHandleBuildIn(payload) { continue } - c.messageQueue <- payload } } -func getDataFromSyncMap(dataHash string) (*dto.WSPayload, bool) { - value, ok := dataMap.Load(dataHash) - if !ok { - return nil, false - } - payloadWithTimestamp, ok := value.(*PayloadWithTimestamp) - if !ok { - return nil, false - } - return payloadWithTimestamp.Payload, true -} - -func storeDataToSyncMap(dataHash string, payload *dto.WSPayload) { - payloadWithTimestamp := &PayloadWithTimestamp{ - Payload: payload, - Timestamp: time.Now(), - } - dataMap.Store(dataHash, payloadWithTimestamp) -} - -func calculateDataHash(data interface{}) string { - dataBytes, _ := json.Marshal(data) - return string(dataBytes) // 这里直接转换为字符串,可以使用更复杂的算法 -} - // 在全局范围通过atomic访问s值与message_id的映射 func GetGlobalS() int64 { return atomic.LoadInt64(&global_s) @@ -379,31 +297,3 @@ func (c *Client) readyHandler(payload *dto.WSPayload) { event.DefaultHandlers.Ready(payload, readyData) } } - -const cleanupInterval = 5 * time.Minute // 清理间隔时间 - -func StartCleanupRoutine() { - go func() { - for { - <-time.After(cleanupInterval) - cleanupDataMap() - } - }() -} - -func cleanupDataMap() { - now := time.Now() - dataMap.Range(func(key, value interface{}) bool { - payloadWithTimestamp, ok := value.(*PayloadWithTimestamp) - if !ok { - return true - } - - // 检查时间戳,清理超过一定时间的数据 - if now.Sub(payloadWithTimestamp.Timestamp) > cleanupInterval { - dataMap.Delete(key) - } - - return true - }) -} From ab805cc3fd384f27a70f37b79007a4164ea178d6 Mon Sep 17 00:00:00 2001 From: cosmo Date: Fri, 9 Aug 2024 07:23:06 +0800 Subject: [PATCH 31/36] beta478 --- Processor/ProcessC2CMessage.go | 4 ++++ Processor/ProcessGroupMessage.go | 4 ++++ readme.md | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Processor/ProcessC2CMessage.go b/Processor/ProcessC2CMessage.go index 6e6f5b99..cbf40c07 100644 --- a/Processor/ProcessC2CMessage.go +++ b/Processor/ProcessC2CMessage.go @@ -28,6 +28,10 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { //sourece是源头频道 //GuildID := data.GuildID + if data.Author.ID == "" { + mylog.Printf("出现ID为空未知错误.%v\n", data) + } + //获取当前的s值 当前ws连接所收到的信息条数 s := client.GetGlobalS() if !p.Settings.GlobalPrivateToChannel { diff --git a/Processor/ProcessGroupMessage.go b/Processor/ProcessGroupMessage.go index 49276aeb..a943eb60 100644 --- a/Processor/ProcessGroupMessage.go +++ b/Processor/ProcessGroupMessage.go @@ -35,6 +35,10 @@ func (p *Processors) ProcessGroupMessage(data *dto.WSGroupATMessageData) error { var GroupID64 int64 var err error + if data.Author.ID == "" { + mylog.Printf("出现ID为空未知错误.%v\n", data) + } + if !config.GetStringOb11() { if config.GetIdmapPro() { //将真实id转为int userid64 diff --git a/readme.md b/readme.md index b525998d..85bdd8ff 100644 --- a/readme.md +++ b/readme.md @@ -75,7 +75,7 @@ Gensokyo文档(施工中):[起步](/docs/起步-注册QQ开放平台&启动genso ## 特别鸣谢 - [`mnixry/nonebot-plugin-gocqhttp`](https://github.com/mnixry/nonebot-plugin-gocqhttp/): 本项目采用了mnixry编写的前端,并实现了与它对应的,基于qq官方api的后端api. -- 感谢 Parker Liang 提供的技术指导和支持. +- 特别鸣谢[`dk 盾`](https://www.dkdun.cn/),友情赞助服务器资源 ### 接口 From 6debefd052c60b3da6d4807f959b5e5aa85b807f Mon Sep 17 00:00:00 2001 From: cosmo Date: Sat, 17 Aug 2024 16:57:48 +0800 Subject: [PATCH 32/36] beta479 --- Processor/ProcessC2CMessage.go | 1 + Processor/ProcessGroupMessage.go | 1 + botgo/sessions/multi/multi.go | 16 +++++++++- handlers/send_private_msg_sse.go | 5 ++- main.go | 11 +++++++ mylog/mylog.go | 54 +++++++++++++++++++++++--------- 6 files changed, 72 insertions(+), 16 deletions(-) diff --git a/Processor/ProcessC2CMessage.go b/Processor/ProcessC2CMessage.go index cbf40c07..0bc4854b 100644 --- a/Processor/ProcessC2CMessage.go +++ b/Processor/ProcessC2CMessage.go @@ -30,6 +30,7 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { if data.Author.ID == "" { mylog.Printf("出现ID为空未知错误.%v\n", data) + return nil } //获取当前的s值 当前ws连接所收到的信息条数 diff --git a/Processor/ProcessGroupMessage.go b/Processor/ProcessGroupMessage.go index a943eb60..127ce343 100644 --- a/Processor/ProcessGroupMessage.go +++ b/Processor/ProcessGroupMessage.go @@ -37,6 +37,7 @@ func (p *Processors) ProcessGroupMessage(data *dto.WSGroupATMessageData) error { if data.Author.ID == "" { mylog.Printf("出现ID为空未知错误.%v\n", data) + return nil } if !config.GetStringOb11() { diff --git a/botgo/sessions/multi/multi.go b/botgo/sessions/multi/multi.go index 3409b0cc..7e6db5d3 100644 --- a/botgo/sessions/multi/multi.go +++ b/botgo/sessions/multi/multi.go @@ -1,6 +1,7 @@ package multi import ( + "fmt" "sync" "time" @@ -93,6 +94,19 @@ func (sm *ShardManager) newConnect(session dto.Session, shardID uint32) { } if err := wsClient.Listening(); err != nil { log.Errorf("[ws/session] Listening error: %+v", err) - sm.SessionChans[shardID] <- session // Reconnect + currentSession := wsClient.Session() + // 对于不能够进行重连的session,需要清空 session id 与 seq + if manager.CanNotResume(err) { + currentSession.ID = "" + currentSession.LastSeq = 0 + } + // 一些错误不能够鉴权,比如机器人被封禁,这里就直接退出了 + if manager.CanNotIdentify(err) { + msg := fmt.Sprintf("can not identify because server return %+v, so process exit", err) + log.Errorf(msg) + panic(msg) // 当机器人被下架,或者封禁,将不能再连接,所以 panic + } + // 将 session 放到 session chan 中,用于启动新的连接,当前连接退出 + sm.SessionChans[shardID] <- *currentSession // Reconnect } } diff --git a/handlers/send_private_msg_sse.go b/handlers/send_private_msg_sse.go index 44cbe02c..2a7dacd3 100644 --- a/handlers/send_private_msg_sse.go +++ b/handlers/send_private_msg_sse.go @@ -109,6 +109,7 @@ func HandleSendPrivateMsgSSE(client callapi.Client, api openapi.OpenAPI, apiv2 o // 输出反序列化后的对象,确认是否成功转换 fmt.Printf("Recovered InterfaceBody: %+v\n", messageBody) + // 使用 echo 获取消息ID var messageID string if config.GetLazyMessageId() { @@ -135,7 +136,9 @@ func HandleSendPrivateMsgSSE(client callapi.Client, api openapi.OpenAPI, apiv2 o // 获取并打印相关ID relatedID := GetRelatedID(messageID) - fmt.Println("相关ID:", relatedID) + + //fmt.Println("相关ID:", relatedID) + dtoSSE := generateMessageSSE(messageBody, messageID, relatedID) mylog.Printf("私聊发信息sse:%v", dtoSSE) diff --git a/main.go b/main.go index dfa86835..1ba44aeb 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,8 @@ import ( "syscall" "time" + _ "net/http/pprof" + "github.com/fatih/color" "github.com/fsnotify/fsnotify" "github.com/hoshinonyaruko/gensokyo/Processor" @@ -125,6 +127,7 @@ func main() { //logger logLevel := mylog.GetLogLevelFromConfig(config.GetLogLevel()) loggerAdapter := mylog.NewMyLogAdapter(logLevel, config.GetSaveLogs()) + mylog.SetLogLevel(logLevel) botgo.SetLogger(loggerAdapter) if *m { @@ -577,6 +580,14 @@ func main() { }() } + // 启动一个用于 pprof 的 HTTP 服务器 + go func() { + log.Println("pprof server running on :6060") + if err := http.ListenAndServe("localhost:6060", nil); err != nil { + log.Fatalf("pprof server failed: %s", err) + } + }() + //杂七杂八的地方 if conf.Settings.MemoryMsgid { echo.StartCleanupRoutine() diff --git a/mylog/mylog.go b/mylog/mylog.go index 44ff9b65..bc8c812f 100644 --- a/mylog/mylog.go +++ b/mylog/mylog.go @@ -23,6 +23,8 @@ const ( LogLevelError ) +var currentLevel = LogLevelInfo // 默认日志级别为 INFO + type Client struct { conn *websocket.Conn send chan EnhancedLogEntry @@ -249,32 +251,56 @@ type EnhancedLogEntry struct { // 日志频道,所有的 WebSocket 客户端都会在此监听日志事件 var logChannel = make(chan EnhancedLogEntry, 1000) +func SetLogLevel(level LogLevel) { + if level >= LogLevelDebug && level <= LogLevelError { + currentLevel = level + } else { + log.Printf("Invalid log level: %d", level) + } +} + func Println(v ...interface{}) { - log.Println(v...) - message := fmt.Sprint(v...) - emitLog("INFO", message) - LogToFile("INFO", message) + if currentLevel <= LogLevelInfo { + log.Println(v...) + message := fmt.Sprint(v...) + emitLog("INFO", message) + LogToFile("INFO", message) + } } func Printf(format string, v ...interface{}) { - log.Printf(format, v...) - message := fmt.Sprintf(format, v...) - emitLog("INFO", message) - LogToFile("INFO", message) + if currentLevel <= LogLevelInfo { + log.Printf(format, v...) + message := fmt.Sprintf(format, v...) + emitLog("INFO", message) + LogToFile("INFO", message) + } +} + +func Warnf(format string, v ...interface{}) { + if currentLevel <= LogLevelWarn { + log.Printf(format, v...) + message := fmt.Sprintf(format, v...) + emitLog("WARN", message) + LogToFile("WARN", message) + } } func Errorf(format string, v ...interface{}) { - log.Printf(format, v...) - message := fmt.Sprintf(format, v...) - emitLog("ERROR", message) - LogToFile("ERROR", message) + if currentLevel <= LogLevelError { + log.Printf(format, v...) + message := fmt.Sprintf(format, v...) + emitLog("ERROR", message) + LogToFile("ERROR", message) + } } func Fatalf(format string, v ...interface{}) { log.Printf(format, v...) message := fmt.Sprintf(format, v...) - emitLog("Fatal", message) - LogToFile("Fatal", message) + emitLog("FATAL", message) + LogToFile("FATAL", message) + os.Exit(1) // Fatal logs usually terminate the program } func emitLog(level, message string) { From 9cc7e5d6692b4cb2fc36a779e0c2b7eb5a06c3b8 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sat, 17 Aug 2024 16:58:43 +0800 Subject: [PATCH 33/36] beta479 --- main.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 1ba44aeb..911e2395 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,7 @@ import ( "syscall" "time" - _ "net/http/pprof" + // _ "net/http/pprof" "github.com/fatih/color" "github.com/fsnotify/fsnotify" @@ -580,13 +580,13 @@ func main() { }() } - // 启动一个用于 pprof 的 HTTP 服务器 - go func() { - log.Println("pprof server running on :6060") - if err := http.ListenAndServe("localhost:6060", nil); err != nil { - log.Fatalf("pprof server failed: %s", err) - } - }() + // // 启动一个用于 pprof 的 HTTP 服务器 + // go func() { + // log.Println("pprof server running on :6060") + // if err := http.ListenAndServe("localhost:6060", nil); err != nil { + // log.Fatalf("pprof server failed: %s", err) + // } + // }() //杂七杂八的地方 if conf.Settings.MemoryMsgid { From c0fe93c01eb8304e678dd79370ea4a52cf161286 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 18 Aug 2024 13:14:24 +0800 Subject: [PATCH 34/36] beta480 --- config/config.go | 13 +++++++++++++ handlers/send_group_msg.go | 28 +++++++++++++++++++++++----- handlers/send_group_msg_raw.go | 29 +++++++++++++++++++++++++---- structs/structs.go | 1 + template/config_template.go | 1 + 5 files changed, 63 insertions(+), 9 deletions(-) diff --git a/config/config.go b/config/config.go index 35b7fcda..e1f395fa 100644 --- a/config/config.go +++ b/config/config.go @@ -2447,3 +2447,16 @@ func GetLogSuffixPerMins() int { } return instance.Settings.LogSuffixPerMins } + +// 获取ThreadsRetMsg的值 +func GetThreadsRetMsg() bool { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + fmt.Println("Warning: instance is nil when trying to ThreadsRetMsg value.") + return false + } + return instance.Settings.ThreadsRetMsg +} + diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index 696ff3a6..62398698 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -377,8 +377,12 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } - // 发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + // 发送成功回执 + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } delete(foundItems, imageType) // 从foundItems中删除已处理的图片项 messageText = "" @@ -432,7 +436,12 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } + } var resp *dto.GroupMessageResponse // 遍历foundItems并发送每种信息 @@ -502,7 +511,11 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } continue // 跳过这个项,继续下一个 } @@ -592,7 +605,12 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap } } //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } + } } case "guild": diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index 601e0038..72d97f66 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -298,7 +298,11 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope } // 发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } delete(foundItems, imageType) // 从foundItems中删除已处理的图片项 messageText = "" @@ -331,7 +335,12 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope echo.PushGlobalStack(pair) } //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } + } var resp *dto.GroupMessageResponse // 遍历foundItems并发送每种信息 @@ -367,7 +376,13 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope echo.PushGlobalStack(pair) } //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + //发送成功回执 + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } + } continue // 跳过这个项,继续下一个 } @@ -427,7 +442,13 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope } } //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + //发送成功回执 + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } + } } case "guild": diff --git a/structs/structs.go b/structs/structs.go index c89dfa04..24272df2 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -108,6 +108,7 @@ type Settings struct { SaveError bool `yaml:"save_error"` DowntimeMessage string `yaml:"downtime_message"` MemoryMsgid bool `yaml:"memory_msgid"` + ThreadsRetMsg bool `yaml:"threads_ret_msg"` //增长营销类 SelfIntroduce []string `yaml:"self_introduce"` //api修改 diff --git a/template/config_template.go b/template/config_template.go index e8711214..0d6113cd 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -140,6 +140,7 @@ settings: save_error : false #将保存保存在log文件夹,方便开发者定位发送错误. downtime_message : "我正在维护中~请不要担心,维护结束就回来~维护时间:(1小时)" memory_msgid : false #当你的机器人单日信息量超过100万,就需要高性能SSD或者开启这个选项了.部分依赖msgid的功能可能会受影响(如delete_msg) + threads_ret_msg : false #异步,并发发送回执信息 仅ws可用. #增长营销类(推荐gensokyo-broadcast项目) self_introduce : ["",""] #自我介绍,可设置多个随机发送,当不为空时,机器人被邀入群会发送自定义自我介绍 需手动添加新textintent - "GroupAddRobotEventHandler" - "GroupDelRobotEventHandler" From 91cf223272f730817af420cc3cc21def593a3663 Mon Sep 17 00:00:00 2001 From: cosmo Date: Sun, 18 Aug 2024 19:19:37 +0800 Subject: [PATCH 35/36] beta481 --- botgo/websocket/client/client.go | 12 +++++--- config/config.go | 11 +++++++ handlers/send_group_msg.go | 51 +++++++++++++++++++------------ handlers/send_group_msg_raw.go | 52 ++++++++++++++++++++------------ main.go | 34 ++++++++++++++------- structs/structs.go | 1 + template/config_template.go | 1 + 7 files changed, 107 insertions(+), 55 deletions(-) diff --git a/botgo/websocket/client/client.go b/botgo/websocket/client/client.go index 8bdd3559..f671aa0e 100644 --- a/botgo/websocket/client/client.go +++ b/botgo/websocket/client/client.go @@ -235,10 +235,14 @@ func (c *Client) listenMessageAndHandle() { c.readyHandler(payload) continue } - // 解析具体事件,并投递给业务注册的 handler - if err := event.ParseAndHandle(payload); err != nil { - log.Errorf("%s parseAndHandle failed, %v", c.session, err) - } + + // 性能不够 报错也没用 就扬了 + go event.ParseAndHandle(payload) + + // // 解析具体事件,并投递给业务注册的 handler + // if err := event.ParseAndHandle(payload); err != nil { + // log.Errorf("%s parseAndHandle failed, %v", c.session, err) + // } } log.Infof("%s message queue is closed", c.session) } diff --git a/config/config.go b/config/config.go index e1f395fa..09b5ffbc 100644 --- a/config/config.go +++ b/config/config.go @@ -2460,3 +2460,14 @@ func GetThreadsRetMsg() bool { return instance.Settings.ThreadsRetMsg } +// 获取NoRetMsg的值 +func GetNoRetMsg() bool { + mu.RLock() + defer mu.RUnlock() + + if instance == nil { + fmt.Println("Warning: instance is nil when trying to NoRetMsg value.") + return false + } + return instance.Settings.NoRetMsg +} diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index 62398698..25c7d72d 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -377,11 +377,13 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { - // 发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if !config.GetNoRetMsg() { + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + // 发送成功回执 + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } delete(foundItems, imageType) // 从foundItems中删除已处理的图片项 @@ -435,11 +437,14 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap } else if err != nil && strings.Contains(err.Error(), "context deadline exceeded") { postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } - //发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + + if !config.GetNoRetMsg() { + //发送成功回执 + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } } @@ -510,11 +515,14 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap } else if err != nil && strings.Contains(err.Error(), "context deadline exceeded") { postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } - //发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + + if !config.GetNoRetMsg() { + //发送成功回执 + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } } continue // 跳过这个项,继续下一个 @@ -604,11 +612,14 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap postGroupMessageWithRetry(apiv2, message.Params.GroupID.(string), groupMessage) } } - //发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + + if !config.GetNoRetMsg() { + //发送成功回执 + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } } diff --git a/handlers/send_group_msg_raw.go b/handlers/send_group_msg_raw.go index 72d97f66..5dcd64e0 100644 --- a/handlers/send_group_msg_raw.go +++ b/handlers/send_group_msg_raw.go @@ -297,11 +297,14 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope echo.PushGlobalStack(pair) } - // 发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if !config.GetNoRetMsg() { + // 发送成功回执 + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } + } delete(foundItems, imageType) // 从foundItems中删除已处理的图片项 @@ -334,11 +337,14 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope pair.GroupMessage = groupMessage echo.PushGlobalStack(pair) } - //发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + + if !config.GetNoRetMsg() { + //发送成功回执 + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } } @@ -375,12 +381,15 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope pair.GroupMessage = groupMessage echo.PushGlobalStack(pair) } - //发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { + + if !config.GetNoRetMsg() { //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + //发送成功回执 + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } } @@ -441,12 +450,15 @@ func HandleSendGroupMsgRaw(client callapi.Client, api openapi.OpenAPI, apiv2 ope echo.PushGlobalStack(pair) } } - //发送成功回执 - if config.GetThreadsRetMsg() { - go SendResponse(client, err, &message, resp, api, apiv2) - } else { + + if !config.GetNoRetMsg() { //发送成功回执 - retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + if config.GetThreadsRetMsg() { + go SendResponse(client, err, &message, resp, api, apiv2) + } else { + //发送成功回执 + retmsg, _ = SendResponse(client, err, &message, resp, api, apiv2) + } } } diff --git a/main.go b/main.go index 911e2395..3dc697e1 100644 --- a/main.go +++ b/main.go @@ -663,7 +663,9 @@ func ATMessageEventHandler() event.ATMessageEventHandler { data.Author.Username = acnode.CheckWordIN(data.Author.Username) } } - return p.ProcessGuildATMessage(data) + + go p.ProcessGuildATMessage(data) + return nil } } @@ -701,7 +703,8 @@ func DirectMessageHandler() event.DirectMessageEventHandler { data.Author.Username = acnode.CheckWordIN(data.Author.Username) } } - return p.ProcessChannelDirectMessage(data) + go p.ProcessChannelDirectMessage(data) + return nil } } @@ -715,7 +718,8 @@ func CreateMessageHandler() event.MessageEventHandler { data.Author.Username = acnode.CheckWordIN(data.Author.Username) } } - return p.ProcessGuildNormalMessage(data) + go p.ProcessGuildNormalMessage(data) + return nil } } @@ -723,7 +727,8 @@ func CreateMessageHandler() event.MessageEventHandler { func InteractionHandler() event.InteractionEventHandler { return func(event *dto.WSPayload, data *dto.WSInteractionData) error { mylog.Printf("收到按钮回调:%v", data) - return p.ProcessInlineSearch(data) + go p.ProcessInlineSearch(data) + return nil } } @@ -731,7 +736,8 @@ func InteractionHandler() event.InteractionEventHandler { func ThreadEventHandler() event.ThreadEventHandler { return func(event *dto.WSPayload, data *dto.WSThreadData) error { mylog.Printf("收到帖子事件:%v", data) - return p.ProcessThreadMessage(data) + go p.ProcessThreadMessage(data) + return nil } } @@ -745,7 +751,8 @@ func GroupATMessageEventHandler() event.GroupATMessageEventHandler { data.Author.Username = acnode.CheckWordIN(data.Author.Username) } } - return p.ProcessGroupMessage(data) + go p.ProcessGroupMessage(data) + return nil } } @@ -759,35 +766,40 @@ func C2CMessageEventHandler() event.C2CMessageEventHandler { data.Author.Username = acnode.CheckWordIN(data.Author.Username) } } - return p.ProcessC2CMessage(data) + go p.ProcessC2CMessage(data) + return nil } } // GroupAddRobotEventHandler 实现处理 群机器人新增 事件的回调 func GroupAddRobotEventHandler() event.GroupAddRobotEventHandler { return func(event *dto.WSPayload, data *dto.GroupAddBotEvent) error { - return p.ProcessGroupAddBot(data) + go p.ProcessGroupAddBot(data) + return nil } } // GroupDelRobotEventHandler 实现处理 群机器人删除 事件的回调 func GroupDelRobotEventHandler() event.GroupDelRobotEventHandler { return func(event *dto.WSPayload, data *dto.GroupAddBotEvent) error { - return p.ProcessGroupDelBot(data) + go p.ProcessGroupDelBot(data) + return nil } } // GroupMsgRejectHandler 实现处理 群请求关闭机器人主动推送 事件的回调 func GroupMsgRejectHandler() event.GroupMsgRejectHandler { return func(event *dto.WSPayload, data *dto.GroupMsgRejectEvent) error { - return p.ProcessGroupMsgReject(data) + go p.ProcessGroupMsgReject(data) + return nil } } // GroupMsgReceiveHandler 实现处理 群请求开启机器人主动推送 事件的回调 func GroupMsgReceiveHandler() event.GroupMsgReceiveHandler { return func(event *dto.WSPayload, data *dto.GroupMsgReceiveEvent) error { - return p.ProcessGroupMsgRecive(data) + go p.ProcessGroupMsgRecive(data) + return nil } } diff --git a/structs/structs.go b/structs/structs.go index 24272df2..1bea9414 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -109,6 +109,7 @@ type Settings struct { DowntimeMessage string `yaml:"downtime_message"` MemoryMsgid bool `yaml:"memory_msgid"` ThreadsRetMsg bool `yaml:"threads_ret_msg"` + NoRetMsg bool `yaml:"no_ret_msg"` //增长营销类 SelfIntroduce []string `yaml:"self_introduce"` //api修改 diff --git a/template/config_template.go b/template/config_template.go index 0d6113cd..56064b5b 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -141,6 +141,7 @@ settings: downtime_message : "我正在维护中~请不要担心,维护结束就回来~维护时间:(1小时)" memory_msgid : false #当你的机器人单日信息量超过100万,就需要高性能SSD或者开启这个选项了.部分依赖msgid的功能可能会受影响(如delete_msg) threads_ret_msg : false #异步,并发发送回执信息 仅ws可用. + no_ret_msg : false #当你的信息量达到1000万/天的时候,并且你的业务不需要获取回调信息,此时直接屏蔽是最好的选择,可以提升50%收发性能. 需应用端适配!!! #增长营销类(推荐gensokyo-broadcast项目) self_introduce : ["",""] #自我介绍,可设置多个随机发送,当不为空时,机器人被邀入群会发送自定义自我介绍 需手动添加新textintent - "GroupAddRobotEventHandler" - "GroupDelRobotEventHandler" From a3aa6c189c2da38f326190678f9ac2038050f3d4 Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 19 Aug 2024 01:34:23 +0800 Subject: [PATCH 36/36] beta482 --- Processor/ProcessC2CMessage.go | 364 +++++++++++++++++++------------ handlers/send_msg.go | 22 ++ handlers/send_private_msg_sse.go | 69 +++--- httpapi/httpapi.go | 142 +++++++++++- 4 files changed, 420 insertions(+), 177 deletions(-) diff --git a/Processor/ProcessC2CMessage.go b/Processor/ProcessC2CMessage.go index 0bc4854b..2b62b304 100644 --- a/Processor/ProcessC2CMessage.go +++ b/Processor/ProcessC2CMessage.go @@ -182,158 +182,250 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error { idmap.StoreUserInfo(data.Author.ID, userdata) } else { //将私聊信息转化为群信息(特殊需求情况下) + if !config.GetStringOb11() { + //转换appid + AppIDString := strconv.FormatUint(p.Settings.AppID, 10) + // 获取当前时间的13位毫秒级时间戳 + currentTimeMillis := time.Now().UnixNano() / 1e6 + // 构造echostr,包括AppID,原始的s变量和当前时间戳 + echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) + //把userid作为群号 + //映射str的userid到int + var userid64 int64 + var err error + var magic int64 + if config.GetIdmapPro() { + //将真实id转为int userid64 + magic, userid64, err = idmap.StoreIDv2Pro("group_private", data.Author.ID) + mylog.Printf("魔法数字:%v", magic) //690426430 + if err != nil { + mylog.Fatalf("Error storing ID: %v", err) + } + //当参数不全,降级时 + _, _ = idmap.StoreIDv2(data.Author.ID) + //补救措施 + idmap.SimplifiedStoreID(data.Author.ID) + } else { + //将真实id转为int userid64 + userid64, err = idmap.StoreIDv2(data.Author.ID) + if err != nil { + mylog.Fatalf("Error storing ID: %v", err) + } + } + //转换at + messageText := handlers.RevertTransformedText(data, "group_private", p.Api, p.Apiv2, userid64, userid64, config.GetWhiteEnable(5)) + if messageText == "" { + mylog.Printf("信息被自定义黑白名单拦截") + return nil + } + //框架内指令 + p.HandleFrameworkCommand(messageText, data, "group_private") + //映射str的messageID到int + var messageID64 int64 + if config.GetMemoryMsgid() { + messageID64, err = echo.StoreCacheInMemory(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } else { + messageID64, err = idmap.StoreCachev2(data.ID) + if err != nil { + log.Fatalf("Error storing ID: %v", err) + } + } + messageID := int(messageID64) + //todo 判断array模式 然后对Message处理成array格式 + IsBindedUserId := idmap.CheckValue(data.Author.ID, userid64) - //转换appid - AppIDString := strconv.FormatUint(p.Settings.AppID, 10) - // 获取当前时间的13位毫秒级时间戳 - currentTimeMillis := time.Now().UnixNano() / 1e6 - // 构造echostr,包括AppID,原始的s变量和当前时间戳 - echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) - //把userid作为群号 - //映射str的userid到int - var userid64 int64 - var err error - var magic int64 - if config.GetIdmapPro() { - //将真实id转为int userid64 - magic, userid64, err = idmap.StoreIDv2Pro("group_private", data.Author.ID) - mylog.Printf("魔法数字:%v", magic) //690426430 - if err != nil { - mylog.Fatalf("Error storing ID: %v", err) + var selfid64 int64 + if config.GetUseUin() { + selfid64 = config.GetUinint64() + } else { + selfid64 = int64(p.Settings.AppID) } - //当参数不全,降级时 - _, _ = idmap.StoreIDv2(data.Author.ID) - //补救措施 - idmap.SimplifiedStoreID(data.Author.ID) - } else { - //将真实id转为int userid64 - userid64, err = idmap.StoreIDv2(data.Author.ID) - if err != nil { - mylog.Fatalf("Error storing ID: %v", err) + + groupMsg := OnebotGroupMessage{ + RawMessage: messageText, + Message: messageText, + MessageID: messageID, + GroupID: userid64, + MessageType: "group", + PostType: "message", + SelfID: selfid64, + UserID: userid64, + Sender: Sender{ + UserID: userid64, + TinyID: "0", + Sex: "0", + Age: 0, + Area: "0", + Level: "0", + }, + SubType: "normal", + Time: time.Now().Unix(), } - } - //转换at - messageText := handlers.RevertTransformedText(data, "group_private", p.Api, p.Apiv2, userid64, userid64, config.GetWhiteEnable(5)) - if messageText == "" { - mylog.Printf("信息被自定义黑白名单拦截") - return nil - } - //框架内指令 - p.HandleFrameworkCommand(messageText, data, "group_private") - //映射str的messageID到int - var messageID64 int64 - if config.GetMemoryMsgid() { - messageID64, err = echo.StoreCacheInMemory(data.ID) - if err != nil { - log.Fatalf("Error storing ID: %v", err) + //增强配置 + if !config.GetNativeOb11() { + groupMsg.RealMessageType = "group_private" + groupMsg.IsBindedUserId = IsBindedUserId + groupMsg.RealUserID = data.Author.ID + groupMsg.Avatar, _ = GenerateAvatarURLV2(data.Author.ID) } - } else { - messageID64, err = idmap.StoreCachev2(data.ID) - if err != nil { - log.Fatalf("Error storing ID: %v", err) + //根据条件判断是否增加nick和card + var CaN = config.GetCardAndNick() + if CaN != "" { + groupMsg.Sender.Nickname = CaN + groupMsg.Sender.Card = CaN } - } - messageID := int(messageID64) - //todo 判断array模式 然后对Message处理成array格式 - IsBindedUserId := idmap.CheckValue(data.Author.ID, userid64) + // 根据条件判断是否添加Echo字段 + if config.GetTwoWayEcho() { + groupMsg.Echo = echostr + //用向应用端(如果支持)发送echo,来确定客户端的send_msg对应的触发词原文 + echo.AddMsgIDv3(AppIDString, echostr, messageText) + } + // 获取MasterID数组 + masterIDs := config.GetMasterID() - var selfid64 int64 - if config.GetUseUin() { - selfid64 = config.GetUinint64() - } else { - selfid64 = int64(p.Settings.AppID) - } + // 判断userid64是否在masterIDs数组里 + isMaster := false + for _, id := range masterIDs { + if strconv.FormatInt(userid64, 10) == id { + isMaster = true + break + } + } - groupMsg := OnebotGroupMessage{ - RawMessage: messageText, - Message: messageText, - MessageID: messageID, - GroupID: userid64, - MessageType: "group", - PostType: "message", - SelfID: selfid64, - UserID: userid64, - Sender: Sender{ - UserID: userid64, - TinyID: "0", - Sex: "0", - Age: 0, - Area: "0", - Level: "0", - }, - SubType: "normal", - Time: time.Now().Unix(), - } - //增强配置 - if !config.GetNativeOb11() { - groupMsg.RealMessageType = "group_private" - groupMsg.IsBindedUserId = IsBindedUserId - groupMsg.RealUserID = data.Author.ID - groupMsg.Avatar, _ = GenerateAvatarURLV2(data.Author.ID) - } - //根据条件判断是否增加nick和card - var CaN = config.GetCardAndNick() - if CaN != "" { - groupMsg.Sender.Nickname = CaN - groupMsg.Sender.Card = CaN - } - // 根据条件判断是否添加Echo字段 - if config.GetTwoWayEcho() { - groupMsg.Echo = echostr - //用向应用端(如果支持)发送echo,来确定客户端的send_msg对应的触发词原文 - echo.AddMsgIDv3(AppIDString, echostr, messageText) - } - // 获取MasterID数组 - masterIDs := config.GetMasterID() - - // 判断userid64是否在masterIDs数组里 - isMaster := false - for _, id := range masterIDs { - if strconv.FormatInt(userid64, 10) == id { - isMaster = true - break + // 根据isMaster的值为groupMsg的Sender赋值role字段 + if isMaster { + groupMsg.Sender.Role = "owner" + } else { + groupMsg.Sender.Role = "member" } - } + //将当前s和appid和message进行映射 + echo.AddMsgID(AppIDString, s, data.ID) + echo.AddMsgType(AppIDString, s, "group_private") + //为不支持双向echo的ob服务端映射 + echo.AddMsgID(AppIDString, userid64, data.ID) + //映射类型 + echo.AddMsgType(AppIDString, userid64, "group_private") + //储存当前群或频道号的类型 + idmap.WriteConfigv2(fmt.Sprint(userid64), "type", "group_private") + + //懒message_id池 + echo.AddLazyMessageId(strconv.FormatInt(userid64, 10), data.ID, time.Now()) - // 根据isMaster的值为groupMsg的Sender赋值role字段 - if isMaster { - groupMsg.Sender.Role = "owner" + //懒message_id池 + echo.AddLazyMessageId(data.Author.ID, data.ID, time.Now()) + + //调试 + PrintStructWithFieldNames(groupMsg) + + // Convert OnebotGroupMessage to map and send + groupMsgMap := structToMap(groupMsg) + //上报信息到onebotv11应用端(正反ws) + go p.BroadcastMessageToAll(groupMsgMap, p.Apiv2, data) + + //组合FriendData + struserid := strconv.FormatInt(userid64, 10) + userdata := structs.FriendData{ + Nickname: "", + Remark: "", + UserID: struserid, + } + //缓存私信好友列表 + idmap.StoreUserInfo(data.Author.ID, userdata) } else { - groupMsg.Sender.Role = "member" - } - //将当前s和appid和message进行映射 - echo.AddMsgID(AppIDString, s, data.ID) - echo.AddMsgType(AppIDString, s, "group_private") - //为不支持双向echo的ob服务端映射 - echo.AddMsgID(AppIDString, userid64, data.ID) - //映射类型 - echo.AddMsgType(AppIDString, userid64, "group_private") - //储存当前群或频道号的类型 - idmap.WriteConfigv2(fmt.Sprint(userid64), "type", "group_private") + //转换appid + AppIDString := strconv.FormatUint(p.Settings.AppID, 10) + // 获取当前时间的13位毫秒级时间戳 + currentTimeMillis := time.Now().UnixNano() / 1e6 + // 构造echostr,包括AppID,原始的s变量和当前时间戳 + echostr := fmt.Sprintf("%s_%d_%d", AppIDString, s, currentTimeMillis) - //懒message_id池 - echo.AddLazyMessageId(strconv.FormatInt(userid64, 10), data.ID, time.Now()) + var selfid64 int64 + if config.GetUseUin() { + selfid64 = config.GetUinint64() + } else { + selfid64 = int64(p.Settings.AppID) + } - //懒message_id池 - echo.AddLazyMessageId(data.Author.ID, data.ID, time.Now()) + //转换at + messageText := handlers.RevertTransformedText(data, "group_private", p.Api, p.Apiv2, 0, 0, config.GetWhiteEnable(5)) + if messageText == "" { + mylog.Printf("信息被自定义黑白名单拦截") + return nil + } - //调试 - PrintStructWithFieldNames(groupMsg) + groupMsg := OnebotGroupMessageS{ + RawMessage: messageText, + Message: messageText, + MessageID: data.ID, + GroupID: data.Author.ID, + MessageType: "group", + PostType: "message", + SelfID: selfid64, + UserID: data.Author.ID, + Sender: Sender{ + UserID: 0, + TinyID: "0", + Sex: "0", + Age: 0, + Area: "0", + Level: "0", + }, + SubType: "normal", + Time: time.Now().Unix(), + } - // Convert OnebotGroupMessage to map and send - groupMsgMap := structToMap(groupMsg) - //上报信息到onebotv11应用端(正反ws) - go p.BroadcastMessageToAll(groupMsgMap, p.Apiv2, data) + //增强配置 + if !config.GetNativeOb11() { + groupMsg.RealMessageType = "group_private" + groupMsg.RealUserID = data.Author.ID + groupMsg.Avatar, _ = GenerateAvatarURLV2(data.Author.ID) + } + //根据条件判断是否增加nick和card + var CaN = config.GetCardAndNick() + if CaN != "" { + groupMsg.Sender.Nickname = CaN + groupMsg.Sender.Card = CaN + } - //组合FriendData - struserid := strconv.FormatInt(userid64, 10) - userdata := structs.FriendData{ - Nickname: "", - Remark: "", - UserID: struserid, + // 根据条件判断是否添加Echo字段 + if config.GetTwoWayEcho() { + groupMsg.Echo = echostr + // 用向应用端(如果支持)发送echo,来确定客户端的send_msg对应的触发词原文 + echo.AddMsgIDv3(AppIDString, echostr, data.Content) + } + + //将当前s和appid和message进行映射 + echo.AddMsgID(AppIDString, s, data.ID) + echo.AddMsgType(AppIDString, s, "group_private") + + echo.AddMsgIDv3(AppIDString, data.Author.ID, data.ID) + + //储存当前群或频道号的类型 + idmap.WriteConfigv2(data.Author.ID, "type", "group_private") + + //懒message_id池 + echo.AddLazyMessageId(data.Author.ID, data.ID, time.Now()) + + //调试 + PrintStructWithFieldNames(groupMsg) + + // Convert OnebotGroupMessage to map and send + groupMsgMap := structToMap(groupMsg) + //上报信息到onebotv11应用端(正反ws) + go p.BroadcastMessageToAll(groupMsgMap, p.Apiv2, data) + + //组合FriendData + userdata := structs.FriendData{ + Nickname: "", + Remark: "", + UserID: data.Author.ID, + } + //缓存私信好友列表 + idmap.StoreUserInfo(data.Author.ID, userdata) } - //缓存私信好友列表 - idmap.StoreUserInfo(data.Author.ID, userdata) } return nil diff --git a/handlers/send_msg.go b/handlers/send_msg.go index ce61d397..cc06add9 100644 --- a/handlers/send_msg.go +++ b/handlers/send_msg.go @@ -218,6 +218,28 @@ func GetMessageIDByUseridOrGroupid(appID string, userID interface{}) string { return messageid } +// 通过user_id获取messageID +func GetMessageIDByUseridOrGroupidSP(appID string, userID interface{}) string { + // 从appID和userID生成key + var userIDStr string + switch u := userID.(type) { + case int: + userIDStr = strconv.Itoa(u) + case int64: + userIDStr = strconv.FormatInt(u, 10) + case float64: + userIDStr = strconv.FormatFloat(u, 'f', 0, 64) + case string: + userIDStr = u + default: + // 可能需要处理其他类型或报错 + return "" + } + + messageid := echo.GetMsgIDv3(appID, userIDStr) + return messageid +} + // 通过user_id获取EventID 私聊,群,频道,通用 userID可以是三者之一 这是不需要区分群+用户的 只需要精准到群 私聊只需要精准到用户 idmap不开启的用户使用 func GetEventIDByUseridOrGroupid(appID string, userID interface{}) string { // 从appID和userID生成key diff --git a/handlers/send_private_msg_sse.go b/handlers/send_private_msg_sse.go index 2a7dacd3..bdbe478c 100644 --- a/handlers/send_private_msg_sse.go +++ b/handlers/send_private_msg_sse.go @@ -8,7 +8,6 @@ import ( "github.com/hoshinonyaruko/gensokyo/callapi" "github.com/hoshinonyaruko/gensokyo/config" - "github.com/hoshinonyaruko/gensokyo/echo" "github.com/hoshinonyaruko/gensokyo/idmap" "github.com/hoshinonyaruko/gensokyo/mylog" "github.com/hoshinonyaruko/gensokyo/structs" @@ -72,24 +71,29 @@ func HandleSendPrivateMsgSSE(client callapi.Client, api openapi.OpenAPI, apiv2 o var resp *dto.C2CMessageResponse - //私聊信息 var UserID string - if config.GetIdmapPro() { - //还原真实的userid - //mylog.Printf("group_private:%v", message.Params.UserID.(string)) - _, UserID, err = idmap.RetrieveRowByIDv2Pro("690426430", message.Params.UserID.(string)) - if err != nil { - mylog.Printf("Error reading config: %v", err) - return "", nil + + if message.Params.UserID != nil && len(message.Params.UserID.(string)) != 32 { + //私聊信息 + if config.GetIdmapPro() { + //还原真实的userid + //mylog.Printf("group_private:%v", message.Params.UserID.(string)) + _, UserID, err = idmap.RetrieveRowByIDv2Pro("690426430", message.Params.UserID.(string)) + if err != nil { + mylog.Printf("Error reading config: %v", err) + return "", nil + } + mylog.Printf("测试,通过Proid获取的UserID:%v", UserID) + } else { + //还原真实的userid + UserID, err = idmap.RetrieveRowByIDv2(message.Params.UserID.(string)) + if err != nil { + mylog.Printf("Error reading config: %v", err) + return "", nil + } } - mylog.Printf("测试,通过Proid获取的UserID:%v", UserID) } else { - //还原真实的userid - UserID, err = idmap.RetrieveRowByIDv2(message.Params.UserID.(string)) - if err != nil { - mylog.Printf("Error reading config: %v", err) - return "", nil - } + UserID = message.Params.UserID.(string) } // 首先,将message.Params.Message序列化成JSON字符串 @@ -112,40 +116,27 @@ func HandleSendPrivateMsgSSE(client callapi.Client, api openapi.OpenAPI, apiv2 o // 使用 echo 获取消息ID var messageID string - if config.GetLazyMessageId() { - //由于实现了Params的自定义unmarshell 所以可以类型安全的断言为string - messageID = echo.GetLazyMessagesId(UserID) - mylog.Printf("GetLazyMessagesId: %v", messageID) - } - if messageID == "" { - if echoStr, ok := message.Echo.(string); ok { - messageID = echo.GetMsgIDByKey(echoStr) - mylog.Println("echo取私聊发信息对应的message_id:", messageID) - } - } + // 如果messageID仍然为空,尝试使用config.GetAppID和UserID的组合来获取messageID - // 如果messageID为空,通过函数获取 if messageID == "" { - messageID = GetMessageIDByUseridOrGroupid(config.GetAppIDStr(), UserID) - mylog.Println("通过GetMessageIDByUserid函数获取的message_id:", messageID) - } - if messageID == "2000" { - messageID = "" - mylog.Println("通过lazymsgid发送群私聊主动信息,每月可发送1次") + if config.GetStringOb11() { + messageID = GetMessageIDByUseridOrGroupidSP(config.GetAppIDStr(), UserID) + mylog.Errorf("通过GetMessageIDByUserid函数获取的message_id:" + messageID) + } else { + messageID = GetMessageIDByUseridOrGroupid(config.GetAppIDStr(), UserID) + mylog.Errorf("通过GetMessageIDByUserid函数获取的message_id:" + messageID) + } + } // 获取并打印相关ID relatedID := GetRelatedID(messageID) - //fmt.Println("相关ID:", relatedID) - dtoSSE := generateMessageSSE(messageBody, messageID, relatedID) - mylog.Printf("私聊发信息sse:%v", dtoSSE) - resp, err = apiv2.PostC2CMessageSSE(context.TODO(), UserID, dtoSSE) if err != nil { - mylog.Printf("发送文本私聊信息失败: %v", err) + mylog.Errorf("发送文本私聊信息失败: %v", err) //如果失败 防止进入递归 return "", nil } diff --git a/httpapi/httpapi.go b/httpapi/httpapi.go index 9f536cb0..bce146ca 100644 --- a/httpapi/httpapi.go +++ b/httpapi/httpapi.go @@ -29,9 +29,14 @@ func CombinedMiddleware(api openapi.OpenAPI, apiV2 openapi.OpenAPI) gin.HandlerF return } } + // 检查路径和处理对应的请求 if c.Request.URL.Path == "/send_group_msg" { - handleSendGroupMessage(c, api, apiV2) + if config.GetStringOb11() { + handleSendGroupMessageSP(c, api, apiV2) + } else { + handleSendGroupMessage(c, api, apiV2) + } return } if c.Request.URL.Path == "/send_group_msg_raw" { @@ -43,7 +48,11 @@ func CombinedMiddleware(api openapi.OpenAPI, apiV2 openapi.OpenAPI) gin.HandlerF return } if c.Request.URL.Path == "/send_private_msg_sse" { - handleSendPrivateMessageSSE(c, api, apiV2) + if config.GetStringOb11() { + handleSendPrivateMessageSSESP(c, api, apiV2) + } else { + handleSendPrivateMessageSSE(c, api, apiV2) + } return } if c.Request.URL.Path == "/send_guild_channel_msg" { @@ -131,6 +140,57 @@ func handleSendGroupMessage(c *gin.Context, api openapi.OpenAPI, apiV2 openapi.O c.String(http.StatusOK, retmsg) } +// handleSendGroupMessage 处理发送群聊消息的请求 +func handleSendGroupMessageSP(c *gin.Context, api openapi.OpenAPI, apiV2 openapi.OpenAPI) { + var retmsg string + var req struct { + GroupID string `json:"group_id" form:"group_id"` + UserID *string `json:"user_id,omitempty" form:"user_id"` + Message string `json:"message" form:"message"` + AutoEscape bool `json:"auto_escape" form:"auto_escape"` + } + + // 根据请求方法解析参数 + if c.Request.Method == http.MethodGet { + // 从URL查询参数解析 + if err := c.ShouldBindQuery(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + } else { + // 从JSON或表单数据解析 + if err := c.ShouldBind(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + } + + // 使用解析后的参数处理请求 + client := &HttpAPIClient{} + // 创建 ActionMessage 实例 + message := callapi.ActionMessage{ + Action: "send_group_msg", + Params: callapi.ParamsContent{ + GroupID: req.GroupID, // 注意这里需要转换类型,因为 GroupID 是 int64 + Message: req.Message, + }, + } + // 如果 UserID 存在,则加入到参数中 + if req.UserID != nil { + message.Params.UserID = *req.UserID + } + // 调用处理函数 + retmsg, err := handlers.HandleSendGroupMsg(client, api, apiV2, message) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 返回处理结果 + c.Header("Content-Type", "application/json") + c.String(http.StatusOK, retmsg) +} + // handleSendGroupMessageRaw 处理发送群聊消息的请求 func handleSendGroupMessageRaw(c *gin.Context, api openapi.OpenAPI, apiV2 openapi.OpenAPI) { var retmsg string @@ -234,6 +294,84 @@ func handleSendPrivateMessage(c *gin.Context, api openapi.OpenAPI, apiV2 openapi c.String(http.StatusOK, retmsg) } +// handleSendPrivateMessageSSE 处理发送私聊SSE消息的请求 +func handleSendPrivateMessageSSESP(c *gin.Context, api openapi.OpenAPI, apiV2 openapi.OpenAPI) { + // 根据请求方法解析参数 + if c.Request.Method == http.MethodGet { + var req struct { + GroupID string `json:"group_id" form:"group_id"` + UserID string `json:"user_id" form:"user_id"` + Message string `json:"message" form:"message"` + AutoEscape bool `json:"auto_escape" form:"auto_escape"` + } + // 从URL查询参数解析 + if err := c.ShouldBindQuery(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + var InterfaceBody structs.InterfaceBody + if err := json.Unmarshal([]byte(req.Message), &InterfaceBody); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid message format"}) + return + } + + client := &HttpAPIClient{} + // 创建 ActionMessage 实例 + message := callapi.ActionMessage{ + Action: "send_private_msg_sse", + Params: callapi.ParamsContent{ + GroupID: req.GroupID, // 注意这里需要转换类型,因为 GroupID 是 int64 + UserID: req.UserID, + Message: InterfaceBody, + }, + } + // 调用处理函数 + retmsg, err := handlers.HandleSendPrivateMsgSSE(client, api, apiV2, message) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 返回处理结果 + c.Header("Content-Type", "application/json") + c.String(http.StatusOK, retmsg) + } else { + var req struct { + GroupID string `json:"group_id" form:"group_id"` + UserID string `json:"user_id" form:"user_id"` + Message interface{} `json:"message" form:"message"` + AutoEscape bool `json:"auto_escape" form:"auto_escape"` + } + // 从JSON或表单数据解析 + if err := c.ShouldBind(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + client := &HttpAPIClient{} + // 创建 ActionMessage 实例 + message := callapi.ActionMessage{ + Action: "send_private_msg_sse", + Params: callapi.ParamsContent{ + GroupID: req.GroupID, // 注意这里需要转换类型,因为 GroupID 是 int64 + UserID: req.UserID, + Message: req.Message, + }, + } + // 调用处理函数 + retmsg, err := handlers.HandleSendPrivateMsgSSE(client, api, apiV2, message) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 返回处理结果 + c.Header("Content-Type", "application/json") + c.String(http.StatusOK, retmsg) + } + +} + // handleSendPrivateMessageSSE 处理发送私聊SSE消息的请求 func handleSendPrivateMessageSSE(c *gin.Context, api openapi.OpenAPI, apiV2 openapi.OpenAPI) { // 根据请求方法解析参数