Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta511 #519

Merged
merged 3 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
667 changes: 445 additions & 222 deletions Processor/ProcessInlineSearch.go

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2471,3 +2471,26 @@ func GetNoRetMsg() bool {
}
return instance.Settings.NoRetMsg
}

func GetForceSsl() bool {
mu.RLock()
defer mu.RUnlock()

if instance == nil {
fmt.Println("Warning: instance is nil when trying to ForceSSL value.")
return false
}
return instance.Settings.ForceSSL
}

func GetHttpPortAfterSsl() string {
mu.RLock()
defer mu.RUnlock()

if instance == nil {
fmt.Println("Warning: instance is nil when trying to get HttpPortAfterSSL.")
return "444" // 或者返回一个默认的 ImageLimit 值
}

return instance.Settings.HttpPortAfterSSL
}
10 changes: 10 additions & 0 deletions echo/echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ func (e *EchoMapping) GenerateKeyEventID(appid string, groupid int64) string {
return appid + "_" + strconv.FormatInt(groupid, 10)
}

func (e *EchoMapping) GenerateKeyEventIDV2(appid string, groupid string) string {
return appid + "_" + groupid
}

func (e *EchoMapping) GenerateKeyv3(appid string, s string) string {
return appid + "_" + s
}
Expand Down Expand Up @@ -181,6 +185,12 @@ func AddEvnetID(appid string, groupid int64, eventID string) {
globalEchoMapping.eventIDMapping.Store(key, eventID)
}

// 添加group对应的eventid
func AddEvnetIDv2(appid string, groupid string, eventID string) {
key := globalEchoMapping.GenerateKeyEventIDV2(appid, groupid)
globalEchoMapping.eventIDMapping.Store(key, eventID)
}

// 添加echo对应的messageid
func AddMsgID(appid string, s int64, msgID string) {
key := globalEchoMapping.GenerateKey(appid, s)
Expand Down
226 changes: 156 additions & 70 deletions echo/messageidmap.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package echo

import (
"math/rand"
"strconv"
"strings"
"sync"
Expand All @@ -13,13 +12,13 @@ import (
)

type messageRecord struct {
messageID string
timestamp time.Time
messageID string
timestamp time.Time
usageCount int // 新增字段,记录使用次数,默认为0
}

type messageStore struct {
mu sync.RWMutex
records map[string][]messageRecord
records sync.Map // 使用 sync.Map 代替普通 map
}

var instance *messageStore
Expand All @@ -28,99 +27,186 @@ var once sync.Once
// 惰性初始化
func initInstance() *messageStore {
once.Do(func() {
instance = &messageStore{
records: make(map[string][]messageRecord),
}
instance = &messageStore{}
})
return instance
}

// AddLazyMessageId 添加 message_id 和它的时间戳到指定群号
func AddLazyMessageId(groupID, messageID string, timestamp time.Time) {
store := initInstance()
store.mu.Lock()
defer store.mu.Unlock()
store.records[groupID] = append(store.records[groupID], messageRecord{messageID: messageID, timestamp: timestamp})

// 初始化 messageRecord
record := messageRecord{
messageID: messageID,
timestamp: timestamp,
usageCount: 0, // 默认使用次数为 0
}

// 从 sync.Map 获取现有记录
value, ok := store.records.Load(groupID)
if ok {
// 如果已有记录,追加新记录
records := value.([]messageRecord)
store.records.Store(groupID, append(records, record))
} else {
// 如果没有记录,初始化新记录
store.records.Store(groupID, []messageRecord{record})
}
}

// AddLazyMessageId 添加 message_id 和它的时间戳到指定群号
// AddLazyMessageIdv2 添加 message_id 和它的时间戳到指定群号
func AddLazyMessageIdv2(groupID, userID, messageID string, timestamp time.Time) {
store := initInstance()
store.mu.Lock()
defer store.mu.Unlock()

// 组合键
key := groupID + "." + userID
store.records[key] = append(store.records[key], messageRecord{messageID: messageID, timestamp: timestamp})

// 初始化 messageRecord,并设置 usageCount 为 0
record := messageRecord{
messageID: messageID,
timestamp: timestamp,
usageCount: 0, // 默认使用次数为0
}

// 通过 sync.Map 读取现有数据
value, ok := store.records.Load(key)
if ok {
// 如果已存在,追加新记录
existingRecords := value.([]messageRecord)
store.records.Store(key, append(existingRecords, record))
} else {
// 如果不存在,初始化记录
store.records.Store(key, []messageRecord{record})
}
}

// GetRecentMessages 获取指定群号中最近5分钟内的 message_id~
// GetLazyMessagesId 获取指定群号中最近 4 分钟内的 message_id
func GetLazyMessagesId(groupID string) string {
store := initInstance()
store.mu.RLock()
defer store.mu.RUnlock()

fiveMinutesAgo := time.Now().Add(-4 * time.Minute)
var recentMessages []string
for _, record := range store.records[groupID] {
if record.timestamp.After(fiveMinutesAgo) {
recentMessages = append(recentMessages, record.messageID)
}

// 获取当前时间和时间窗口
now := time.Now()
fourMinutesAgo := now.Add(-4 * time.Minute)

// 从 sync.Map 获取记录
value, ok := store.records.Load(groupID)
if !ok {
return generateDefaultMessageID(groupID)
}
var randomMessageID string
if len(recentMessages) > 0 {
randomIndex := rand.Intn(len(recentMessages))
randomMessageID = recentMessages[randomIndex]
} else {
groupIDint64, err := idmap.StoreIDv2(groupID)
if err != nil {
mylog.Printf("Error storing ID 75: %v", err)
return "2000" //主动信息(不知道消息类型,按2000,纯主动信息处理)
}
msgType := GetMessageTypeByGroupidv2(config.GetAppIDStr(), groupIDint64)
if strings.HasPrefix(msgType, "guild") {
randomMessageID = "1000" // 频道主动信息
} else {
randomMessageID = "2000" //群主动信息

// 类型断言并筛选最近 4 分钟的消息
records, ok := value.([]messageRecord)
if !ok || len(records) == 0 {
return generateDefaultMessageID(groupID)
}

var selectedRecord *messageRecord
var validRecords []messageRecord

// 筛选最近 4 分钟的消息,同时找出使用次数为0且时间最近的记录
for i := range records {
record := records[i]
if record.timestamp.After(fourMinutesAgo) {
// 添加到有效记录中
validRecords = append(validRecords, record)

// 优先选择 usageCount == 0 且时间最近的记录
if record.usageCount == 0 {
if selectedRecord == nil || record.timestamp.After(selectedRecord.timestamp) {
selectedRecord = &validRecords[len(validRecords)-1] // 指向新增的有效记录
}
} else if selectedRecord == nil {
// 如果没有 usageCount == 0 的,选择时间最近的
selectedRecord = &validRecords[len(validRecords)-1]
}
}
}
return randomMessageID

// 如果找到合适的记录,更新其 usageCount
if selectedRecord != nil {
selectedRecord.usageCount++
}

// 更新有效记录到 sync.Map(仅更新一次)
store.records.Store(groupID, validRecords)

// 返回选中的 messageID 或生成默认消息ID
if selectedRecord != nil {
return selectedRecord.messageID
}

return generateDefaultMessageID(groupID)
}

// GetLazyMessagesIdv2 获取指定群号和用户ID中最近5分钟内的 message_id
func GetLazyMessagesIdv2(groupID, userID string) string { //1
func GetLazyMessagesIdv2(groupID, userID string) string {
store := initInstance()
store.mu.RLock()
defer store.mu.RUnlock()

// 构建复合键
now := time.Now() // 统一时间基准
fourMinutesAgo := now.Add(-4 * time.Minute)
key := groupID + "." + userID

fiveMinutesAgo := time.Now().Add(-4 * time.Minute)
var recentMessages []string
for _, record := range store.records[key] {
if record.timestamp.After(fiveMinutesAgo) {
recentMessages = append(recentMessages, record.messageID)
}
// 获取记录
value, ok := store.records.Load(key)
if !ok {
// 如果没有找到记录,生成默认消息ID
return generateDefaultMessageID(groupID)
}

var randomMessageID string
if len(recentMessages) > 0 {
randomIndex := rand.Intn(len(recentMessages))
randomMessageID = recentMessages[randomIndex]
} else {
// 如果没有找到最近消息,处理默认行为
groupIDint64, err := idmap.StoreIDv2(groupID)
if err != nil {
mylog.Printf("Error storing ID 75: %v", err)
return "2000" //主动信息(不知道消息类型,按2000,纯主动信息处理)
}
msgType := GetMessageTypeByGroupidv2(config.GetAppIDStr(), groupIDint64)
if strings.HasPrefix(msgType, "guild") {
randomMessageID = "1000" // 频道主动信息
} else {
randomMessageID = "2000" //群主动信息
// 类型断言并检查记录是否为空
records, ok := value.([]messageRecord)
if !ok || len(records) == 0 {
return generateDefaultMessageID(groupID)
}

// 筛选最近 4 分钟的记录并找最优记录,同时清理过期记录
var selectedRecord *messageRecord
var validRecords []messageRecord

for i := range records {
record := records[i]
if record.timestamp.After(fourMinutesAgo) {
// 保留有效记录
validRecords = append(validRecords, record)

// 优先选择 usageCount == 0 且时间最近的
if record.usageCount == 0 {
if selectedRecord == nil || record.timestamp.After(selectedRecord.timestamp) {
selectedRecord = &validRecords[len(validRecords)-1] // 指向新增的有效记录
}
} else if selectedRecord == nil {
// 如果没有 usageCount == 0 的,选择时间最近的
selectedRecord = &validRecords[len(validRecords)-1] // 指向新增的有效记录
}
}
}
return randomMessageID

// 如果找到合适的记录,更新其 usageCount
if selectedRecord != nil {
selectedRecord.usageCount++ // 更新选中记录的 usageCount
}

// 更新有效记录到 sync.Map(仅更新一次)
store.records.Store(key, validRecords)

// 返回选中的 messageID 或生成默认消息ID
if selectedRecord != nil {
return selectedRecord.messageID
}
return generateDefaultMessageID(groupID)
}

// 生成默认消息ID的逻辑拆分为独立函数
func generateDefaultMessageID(groupID string) string {
groupIDint64, err := idmap.StoreIDv2(groupID)
if err != nil {
mylog.Printf("Error storing ID: %v", err)
return "2000"
}
msgType := GetMessageTypeByGroupidv2(config.GetAppIDStr(), groupIDint64)
if strings.HasPrefix(msgType, "guild") {
return "1000"
}
return "2000"
}

// 通过group_id获取类型
Expand Down
6 changes: 5 additions & 1 deletion handlers/send_group_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,11 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap
if messageID == "2000" {
messageID = ""
mylog.Println("通过lazymessage_id模式发送群聊/频道主动信息,群聊每月仅4次机会,如果本信息非主动推送信息,请提交issue")
eventID = GetEventIDByUseridOrGroupid(config.GetAppIDStr(), message.Params.GroupID)
if len(message.Params.GroupID.(string)) != 32 {
eventID = GetEventIDByUseridOrGroupid(config.GetAppIDStr(), message.Params.GroupID)
}else{
eventID = GetEventIDByUseridOrGroupidv2(config.GetAppIDStr(), message.Params.GroupID)
}
mylog.Printf("尝试获取当前是否有eventID可用,如果有则不消耗主动次数:%v", eventID)
}
mylog.Printf("群组发信息使用messageID:[%v]", messageID)
Expand Down
25 changes: 25 additions & 0 deletions handlers/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,31 @@ func GetEventIDByUseridOrGroupid(appID string, userID interface{}) string {
return eventid
}

// 通过user_id获取EventID 私聊,群,频道,通用 userID可以是三者之一 这是不需要区分群+用户的 只需要精准到群 私聊只需要精准到用户 idmap不开启的用户使用
func GetEventIDByUseridOrGroupidv2(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 ""
}

key := appID + "_" + userIDStr
mylog.Printf("GetEventIDByUseridOrGroupid_key:%v", key)
eventid := echo.GetEventIDByKey(key)

return eventid
}

// 通过user_id获取messageID
func GetMessageIDByUseridAndGroupid(appID string, userID interface{}, groupID interface{}) string {
// 从appID和userID生成key
Expand Down
6 changes: 5 additions & 1 deletion handlers/send_private_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open
if messageID == "2000" {
messageID = ""
mylog.Println("通过lazymsgid发送群私聊主动信息,每月可发送1次")
eventID = GetEventIDByUseridOrGroupid(config.GetAppIDStr(), message.Params.UserID)
if len(message.Params.UserID.(string)) != 32 {
eventID = GetEventIDByUseridOrGroupid(config.GetAppIDStr(), message.Params.UserID)
} else {
eventID = GetEventIDByUseridOrGroupidv2(config.GetAppIDStr(), message.Params.UserID)
}
mylog.Printf("尝试获取当前是否有eventID可用,如果有则不消耗主动次数:%v", eventID)
}
//开发环境用 私聊不可用1000
Expand Down
Loading
Loading