forked from ProjectWIND/ProjectWIND
add:完善指令处理模块
This commit is contained in:
parent
995fba34b4
commit
9e47650032
207
core/api_wsd.go
Normal file
207
core/api_wsd.go
Normal file
@ -0,0 +1,207 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"ProjectWIND/database"
|
||||
"ProjectWIND/wba"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//database模块
|
||||
// //数据库部分允许字符串变量的读写操作,允许读取配置项操作
|
||||
|
||||
type databaseInfo struct{}
|
||||
|
||||
func (dbi *databaseInfo) varSet(app wba.AppInfo, datamap string, unit string, id string, key string, value string) {
|
||||
database.Set(app.AppKey.Name, datamap, unit, id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
dbi.varSet(app, app.AppKey.Name, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
dbi.varSet(app, datamap, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
dbi.varSet(app, datamap, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetUserVariable(app wba.AppInfo, id string, key string, value string) {
|
||||
dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetGroupVariable(app wba.AppInfo, id string, key string, value string) {
|
||||
dbi.varSet(app, app.AppKey.Name, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetGlobalVariable(app wba.AppInfo, id string, key string, value string) {
|
||||
dbi.varSet(app, app.AppKey.Name, "global", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetOutUserVariable(app wba.AppInfo, datamap string, id string, key string, value string) {
|
||||
dbi.varSet(app, datamap, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetOutGroupVariable(app wba.AppInfo, datamap string, id string, key string, value string) {
|
||||
dbi.varSet(app, datamap, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetOutGlobalVariable(app wba.AppInfo, datamap string, id string, key string, value string) {
|
||||
dbi.varSet(app, datamap, "global", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) varGet(app wba.AppInfo, datamap string, unit string, id string, key string) (string, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, unit, id, key, false)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
resStr, ok := res.(string)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return resStr, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
return dbi.varGet(app, app.AppKey.Name, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
return dbi.varGet(app, app.AppKey.Name, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
return dbi.varGet(app, datamap, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
return dbi.varGet(app, datamap, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetUserVariable(app wba.AppInfo, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, app.AppKey.Name, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetGroupVariable(app wba.AppInfo, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, app.AppKey.Name, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetGlobalVariable(app wba.AppInfo, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, app.AppKey.Name, "global", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetOutUserVariable(app wba.AppInfo, datamap string, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, datamap, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetOutGroupVariable(app wba.AppInfo, datamap string, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, datamap, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetOutGlobalVariable(app wba.AppInfo, datamap string, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, datamap, "global", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetIntConfig(app wba.AppInfo, datamap string, key string) (int64, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "number", key, true)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
resInt, ok := res.(int64)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return resInt, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetStringConfig(app wba.AppInfo, datamap string, key string) (string, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "string", key, true)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
resStr, ok := res.(string)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return resStr, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetFloatConfig(app wba.AppInfo, datamap string, key string) (float64, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "float", key, true)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
resFloat, ok := res.(float64)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return resFloat, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetIntSliceConfig(app wba.AppInfo, datamap string, key string) ([]int64, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "number_slice", key, true)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
resSlice, ok := res.([]int64)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return resSlice, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetStringSliceConfig(app wba.AppInfo, datamap string, key string) ([]string, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "string_slice", key, true)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
resSlice, ok := res.([]string)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return resSlice, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyCreatePublicDatamap(app wba.AppInfo, datamapId string) {
|
||||
appName := app.AppKey.Name
|
||||
database.CreatePublicDatamap(appName, datamapId)
|
||||
}
|
||||
|
||||
var DatabaseApi databaseInfo
|
@ -2,15 +2,12 @@ package core
|
||||
|
||||
import (
|
||||
"ProjectWIND/LOG"
|
||||
"ProjectWIND/database"
|
||||
"ProjectWIND/wba"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type apiInfo struct{}
|
||||
type protocolAPI struct{}
|
||||
|
||||
//一、Protocol模块
|
||||
|
||||
@ -41,7 +38,7 @@ type apiInfo struct{}
|
||||
// - message: 要发送的消息内容,类型为字符串
|
||||
//
|
||||
// - autoEscape: 是否自动转义(解析消息内容中的CQ码),可选值为 true 和 false
|
||||
func (a *apiInfo) UnsafelySendMsg(messageType string, groupId int64, userId int64, message string, autoEscape bool) {
|
||||
func (p *protocolAPI) UnsafelySendMsg(messageType string, groupId int64, userId int64, message string, autoEscape bool) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "send_msg"
|
||||
@ -84,7 +81,7 @@ func (a *apiInfo) UnsafelySendMsg(messageType string, groupId int64, userId int6
|
||||
// - message: 要发送的消息内容,类型为字符串
|
||||
//
|
||||
// - autoEscape: 是否自动转义(解析消息内容中的CQ码),可选值为 true 和 false
|
||||
func (a *apiInfo) UnsafelySendPrivateMsg(userId int64, message string, autoEscape bool) {
|
||||
func (p *protocolAPI) UnsafelySendPrivateMsg(userId int64, message string, autoEscape bool) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "send_private_msg"
|
||||
@ -112,7 +109,7 @@ func (a *apiInfo) UnsafelySendPrivateMsg(userId int64, message string, autoEscap
|
||||
// - message: 要发送的消息内容,类型为字符串
|
||||
//
|
||||
// - autoEscape: 是否自动转义(解析消息内容中的CQ码),可选值为 true 和 false
|
||||
func (a *apiInfo) UnsafelySendGroupMsg(groupId int64, message string, autoEscape bool) {
|
||||
func (p *protocolAPI) UnsafelySendGroupMsg(groupId int64, message string, autoEscape bool) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "send_group_msg"
|
||||
@ -138,7 +135,7 @@ func (a *apiInfo) UnsafelySendGroupMsg(groupId int64, message string, autoEscape
|
||||
// - message: 要发送的消息内容,类型为字符串
|
||||
//
|
||||
// - autoEscape: 是否自动转义(解析消息内容中的CQ码),可选值为 true 和 false
|
||||
func (a *apiInfo) SendMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
|
||||
func (p *protocolAPI) SendMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
|
||||
@ -182,7 +179,7 @@ func (a *apiInfo) SendMsg(msg wba.MessageEventInfo, message string, autoEscape b
|
||||
// - message: 要发送的消息内容,类型为字符串
|
||||
//
|
||||
// - autoEscape: 是否自动转义,可选值为 true 和 false
|
||||
func (a *apiInfo) SendPrivateMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
|
||||
func (p *protocolAPI) SendPrivateMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "send_private_msg"
|
||||
@ -208,7 +205,7 @@ func (a *apiInfo) SendPrivateMsg(msg wba.MessageEventInfo, message string, autoE
|
||||
// - message: 要发送的消息内容,类型为字符串
|
||||
//
|
||||
// - autoEscape: 是否自动转义,可选值为 true 和 false
|
||||
func (a *apiInfo) SendGroupMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
|
||||
func (p *protocolAPI) SendGroupMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
|
||||
// 构建发送消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "send_group_msg"
|
||||
@ -232,7 +229,7 @@ func (a *apiInfo) SendGroupMsg(msg wba.MessageEventInfo, message string, autoEsc
|
||||
// 参数:
|
||||
//
|
||||
// - messageId: 要撤回的消息ID
|
||||
func (a *apiInfo) UnsafelyDeleteMsg(messageId int32) {
|
||||
func (p *protocolAPI) UnsafelyDeleteMsg(messageId int32) {
|
||||
// 构建删除消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "delete_msg"
|
||||
@ -251,7 +248,7 @@ func (a *apiInfo) UnsafelyDeleteMsg(messageId int32) {
|
||||
// 参数:
|
||||
//
|
||||
// - msg: 原始消息事件信息
|
||||
func (a *apiInfo) DeleteMsg(msg wba.MessageEventInfo) {
|
||||
func (p *protocolAPI) DeleteMsg(msg wba.MessageEventInfo) {
|
||||
// 构建删除消息的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "delete_msg"
|
||||
@ -272,7 +269,7 @@ func (a *apiInfo) DeleteMsg(msg wba.MessageEventInfo) {
|
||||
// - userId: 要赞的用户ID
|
||||
//
|
||||
// - times: 赞的次数
|
||||
func (a *apiInfo) SendLike(userId int64, times int) {
|
||||
func (p *protocolAPI) SendLike(userId int64, times int) {
|
||||
// 构建发送赞的JSON数据
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "send_like"
|
||||
@ -296,7 +293,7 @@ func (a *apiInfo) SendLike(userId int64, times int) {
|
||||
// - userId: 用户ID
|
||||
//
|
||||
// - rejectAddRequest: 是否拒绝该用户的后续加群请求,可选值为 true 和 false
|
||||
func (a *apiInfo) SetGroupKick(groupId int64, userId int64, rejectAddRequest bool) {
|
||||
func (p *protocolAPI) SetGroupKick(groupId int64, userId int64, rejectAddRequest bool) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_kick"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -320,7 +317,7 @@ func (a *apiInfo) SetGroupKick(groupId int64, userId int64, rejectAddRequest boo
|
||||
// - userId: 用户ID
|
||||
//
|
||||
// - duration: 禁言时长,单位为秒,0表示取消禁言
|
||||
func (a *apiInfo) SetGroupBan(groupId int64, userId int64, duration int32) {
|
||||
func (p *protocolAPI) SetGroupBan(groupId int64, userId int64, duration int32) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_ban"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -342,7 +339,7 @@ func (a *apiInfo) SetGroupBan(groupId int64, userId int64, duration int32) {
|
||||
// - groupId: 群号
|
||||
//
|
||||
// - enable: 是否启用全员禁言,可选值为 true 和 false
|
||||
func (a *apiInfo) SetGroupWholeBan(groupId int64, enable bool) {
|
||||
func (p *protocolAPI) SetGroupWholeBan(groupId int64, enable bool) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_whole_ban"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -365,7 +362,7 @@ func (a *apiInfo) SetGroupWholeBan(groupId int64, enable bool) {
|
||||
// - userId: 用户ID
|
||||
//
|
||||
// - enable: 是否设置为管理员,可选值为 true 和 false
|
||||
func (a *apiInfo) SetGroupAdmin(groupId int64, userId int64, enable bool) {
|
||||
func (p *protocolAPI) SetGroupAdmin(groupId int64, userId int64, enable bool) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_admin"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -389,7 +386,7 @@ func (a *apiInfo) SetGroupAdmin(groupId int64, userId int64, enable bool) {
|
||||
// - userId: 用户ID
|
||||
//
|
||||
// - card: 新的群名片
|
||||
func (a *apiInfo) SetGroupCard(groupId int64, userId int64, card string) {
|
||||
func (p *protocolAPI) SetGroupCard(groupId int64, userId int64, card string) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_card"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -411,7 +408,7 @@ func (a *apiInfo) SetGroupCard(groupId int64, userId int64, card string) {
|
||||
// - groupId: 群号
|
||||
//
|
||||
// - groupName: 新的群名称
|
||||
func (a *apiInfo) SetGroupName(groupId int64, groupName string) {
|
||||
func (p *protocolAPI) SetGroupName(groupId int64, groupName string) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_name"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -432,7 +429,7 @@ func (a *apiInfo) SetGroupName(groupId int64, groupName string) {
|
||||
// - groupId: 群号
|
||||
//
|
||||
// - isDismiss: 是否解散群聊,仅当退出的是群主时有效,可选值为 true 和 false
|
||||
func (a *apiInfo) SetGroupLeave(groupId int64, isDismiss bool) {
|
||||
func (p *protocolAPI) SetGroupLeave(groupId int64, isDismiss bool) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_leave"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -455,7 +452,7 @@ func (a *apiInfo) SetGroupLeave(groupId int64, isDismiss bool) {
|
||||
// - userId: 用户ID
|
||||
//
|
||||
// - specialTitle: 新的专属头衔
|
||||
func (a *apiInfo) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string) {
|
||||
func (p *protocolAPI) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_special_title"
|
||||
messageData.Params.GroupId = groupId
|
||||
@ -480,7 +477,7 @@ func (a *apiInfo) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle
|
||||
// - approve: 是否同意请求,可选值为 true 和 false
|
||||
//
|
||||
// - remark: 设置好友的备注信息
|
||||
func (a *apiInfo) SetFriendAddRequest(flag string, approve bool, remark string) {
|
||||
func (p *protocolAPI) SetFriendAddRequest(flag string, approve bool, remark string) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_friend_add_request"
|
||||
messageData.Params.Flag = flag
|
||||
@ -506,7 +503,7 @@ func (a *apiInfo) SetFriendAddRequest(flag string, approve bool, remark string)
|
||||
// - approve: 是否同意请求,可选值为 true 和 false
|
||||
//
|
||||
// - reason: 拒绝请求的原因,仅当 approve 为 false 时有效
|
||||
func (a *apiInfo) SetGroupAddRequest(flag string, subType string, approve bool, reason string) {
|
||||
func (p *protocolAPI) SetGroupAddRequest(flag string, subType string, approve bool, reason string) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_group_add_request"
|
||||
messageData.Params.Flag = flag
|
||||
@ -523,7 +520,7 @@ func (a *apiInfo) SetGroupAddRequest(flag string, subType string, approve bool,
|
||||
}
|
||||
|
||||
// SetRestart 重启
|
||||
func (a *apiInfo) SetRestart(delay int32) {
|
||||
func (p *protocolAPI) SetRestart(delay int32) {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "set_restart"
|
||||
messageData.Params.Delay = delay
|
||||
@ -537,7 +534,7 @@ func (a *apiInfo) SetRestart(delay int32) {
|
||||
}
|
||||
|
||||
// CleanCache 清理缓存
|
||||
func (a *apiInfo) CleanCache() {
|
||||
func (p *protocolAPI) CleanCache() {
|
||||
var messageData wba.APIRequestInfo
|
||||
messageData.Action = "clean_cache"
|
||||
_, err := wsAPI(messageData)
|
||||
@ -552,7 +549,7 @@ func (a *apiInfo) CleanCache() {
|
||||
// 2.有响应API,需添加echo字段,统一返回响应结构体
|
||||
|
||||
// GetLoginInfo 获取登录信息
|
||||
func (a *apiInfo) GetLoginInfo() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetLoginInfo() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取登录信息(GetLoginInfo)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -571,7 +568,7 @@ func (a *apiInfo) GetLoginInfo() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetVersionInfo 获取协议信息
|
||||
func (a *apiInfo) GetVersionInfo() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetVersionInfo() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取协议信息(GetVersionInfo)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -590,7 +587,7 @@ func (a *apiInfo) GetVersionInfo() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetMsg 获取消息
|
||||
func (a *apiInfo) GetMsg(messageId int32) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetMsg(messageId int32) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取消息(GetMsg)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -610,7 +607,7 @@ func (a *apiInfo) GetMsg(messageId int32) (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetForwardMsg 获取合并转发消息
|
||||
func (a *apiInfo) GetForwardMsg(id string) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetForwardMsg(id string) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取合并转发消息(GetForwardMsg)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -630,7 +627,7 @@ func (a *apiInfo) GetForwardMsg(id string) (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetStrangerInfo 获取陌生人信息
|
||||
func (a *apiInfo) GetStrangerInfo(userId int64, noCache bool) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetStrangerInfo(userId int64, noCache bool) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取陌生人信息(GetStrangerInfo)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -651,7 +648,7 @@ func (a *apiInfo) GetStrangerInfo(userId int64, noCache bool) (Response wba.APIR
|
||||
}
|
||||
|
||||
// GetFriendList 获取好友列表
|
||||
func (a *apiInfo) GetFriendList() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetFriendList() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取好友列表(GetFriendList)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -670,7 +667,7 @@ func (a *apiInfo) GetFriendList() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetGroupList 获取群列表
|
||||
func (a *apiInfo) GetGroupList() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetGroupList() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取群列表(GetGroupList)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -689,7 +686,7 @@ func (a *apiInfo) GetGroupList() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetGroupInfo 获取群信息
|
||||
func (a *apiInfo) GetGroupInfo(groupId int64, noCache bool) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetGroupInfo(groupId int64, noCache bool) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取群信息(GetGroupInfo)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -710,7 +707,7 @@ func (a *apiInfo) GetGroupInfo(groupId int64, noCache bool) (Response wba.APIRes
|
||||
}
|
||||
|
||||
// GetGroupMemberInfo 获取群成员信息
|
||||
func (a *apiInfo) GetGroupMemberInfo(groupId int64, userId int64, noCache bool) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetGroupMemberInfo(groupId int64, userId int64, noCache bool) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取群成员信息(GetGroupMemberInfo)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -732,7 +729,7 @@ func (a *apiInfo) GetGroupMemberInfo(groupId int64, userId int64, noCache bool)
|
||||
}
|
||||
|
||||
// GetGroupMemberList 获取群成员列表
|
||||
func (a *apiInfo) GetGroupMemberList(groupId int64) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetGroupMemberList(groupId int64) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取群成员列表(GetGroupMemberList)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -752,7 +749,7 @@ func (a *apiInfo) GetGroupMemberList(groupId int64) (Response wba.APIResponseInf
|
||||
}
|
||||
|
||||
// GetGroupHonorInfo 获取群荣誉信息
|
||||
func (a *apiInfo) GetGroupHonorInfo(groupId int64, Type string) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetGroupHonorInfo(groupId int64, Type string) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取群荣誉信息(GetGroupHonorInfo)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -773,7 +770,7 @@ func (a *apiInfo) GetGroupHonorInfo(groupId int64, Type string) (Response wba.AP
|
||||
}
|
||||
|
||||
// GetCookies 获取Cookies
|
||||
func (a *apiInfo) GetCookies(domain string) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetCookies(domain string) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取Cookies(GetCookies)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -793,7 +790,7 @@ func (a *apiInfo) GetCookies(domain string) (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetCSRFToken 获取CSRF Token
|
||||
func (a *apiInfo) GetCSRFToken() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetCSRFToken() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取CSRF Token(GetCSRFToken)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -812,7 +809,7 @@ func (a *apiInfo) GetCSRFToken() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetCredentials 获取登录令牌
|
||||
func (a *apiInfo) GetCredentials(domain string) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetCredentials(domain string) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取登录令牌(GetCredentials)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -832,7 +829,7 @@ func (a *apiInfo) GetCredentials(domain string) (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetRecord 获取语音
|
||||
func (a *apiInfo) GetRecord(file string, outFormat string) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetRecord(file string, outFormat string) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取语音(GetRecord)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -853,7 +850,7 @@ func (a *apiInfo) GetRecord(file string, outFormat string) (Response wba.APIResp
|
||||
}
|
||||
|
||||
// GetImage 获取图片
|
||||
func (a *apiInfo) GetImage(file string) (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetImage(file string) (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取图片(GetImage)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -873,7 +870,7 @@ func (a *apiInfo) GetImage(file string) (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// CanSendImage 检查是否可以发送图片
|
||||
func (a *apiInfo) CanSendImage() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) CanSendImage() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("检查是否可以发送图片(CanSendImage)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -892,7 +889,7 @@ func (a *apiInfo) CanSendImage() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// CanSendRecord 检查是否可以发送语音
|
||||
func (a *apiInfo) CanSendRecord() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) CanSendRecord() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("检查是否可以发送语音(CanSendRecord)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -911,7 +908,7 @@ func (a *apiInfo) CanSendRecord() (Response wba.APIResponseInfo) {
|
||||
}
|
||||
|
||||
// GetStatus 获取状态
|
||||
func (a *apiInfo) GetStatus() (Response wba.APIResponseInfo) {
|
||||
func (p *protocolAPI) GetStatus() (Response wba.APIResponseInfo) {
|
||||
LOG.Info("获取状态(GetStatus)")
|
||||
var messageData wba.APIRequestInfo
|
||||
var err error
|
||||
@ -929,273 +926,6 @@ func (a *apiInfo) GetStatus() (Response wba.APIResponseInfo) {
|
||||
return Response
|
||||
}
|
||||
|
||||
//二、LOG模块
|
||||
|
||||
/*
|
||||
关于LOG模块的说明
|
||||
|
||||
1.日志模块级别分为TRACE、DEBUG、INFO、NOTICE、WARN、ERROR五个级别,默认级别为INFO。
|
||||
|
||||
2.日志模块提供LogWith方法,可以自定义日志级别。
|
||||
|
||||
3.日志模块提供Log方法,默认日志级别为INFO。
|
||||
*/
|
||||
|
||||
// LogWith 打印日志(带级别)
|
||||
//
|
||||
// 参数:
|
||||
// - level: 日志级别,支持"TRACE"、"DEBUG"、"INFO"、"NOTICE"、 "WARN"、"ERROR"
|
||||
// - content: 日志内容
|
||||
// - args: 可选参数,用于格式化日志内容
|
||||
//
|
||||
// 返回值:
|
||||
// - 无
|
||||
func (a *apiInfo) LogWith(level string, content string, args ...interface{}) {
|
||||
level = strings.ToLower(level)
|
||||
switch level {
|
||||
case "trace":
|
||||
LOG.Trace(content, args...)
|
||||
return
|
||||
case "debug":
|
||||
LOG.Debug(content, args...)
|
||||
return
|
||||
case "notice":
|
||||
LOG.Notice(content, args...)
|
||||
return
|
||||
case "warn":
|
||||
LOG.Warn(content, args...)
|
||||
return
|
||||
case "error":
|
||||
LOG.Error(content, args...)
|
||||
return
|
||||
default:
|
||||
LOG.Info(content, args...)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Log 打印日志
|
||||
//
|
||||
// 参数:
|
||||
// - content: 日志内容
|
||||
// - args: 可选参数,用于格式化日志内容
|
||||
func (a *apiInfo) Log(content string, args ...interface{}) {
|
||||
LOG.Info(content, args...)
|
||||
}
|
||||
|
||||
// MsgUnmarshal 解析消息
|
||||
//
|
||||
// 参数:
|
||||
// - messageJSON: 从数据库中获取的JSON序列化后的消息字符串
|
||||
//
|
||||
// 返回值:
|
||||
// - wba.MessageEventInfo: 解析后的消息事件信息,解析失败时返回空结构体
|
||||
func (a *apiInfo) MsgUnmarshal(messageJSON string) (msg wba.MessageEventInfo) {
|
||||
err := json.Unmarshal([]byte(messageJSON), &msg)
|
||||
if err != nil {
|
||||
return wba.MessageEventInfo{}
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
//database模块
|
||||
// //数据库部分允许字符串变量的读写操作,允许读取配置项操作
|
||||
|
||||
type databaseInfo struct{}
|
||||
|
||||
func (dbi *databaseInfo) varSet(app wba.AppInfo, datamap string, unit string, id string, key string, value string) {
|
||||
database.Set(app.AppKey.Name, datamap, unit, id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
dbi.varSet(app, app.AppKey.Name, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
dbi.varSet(app, datamap, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) SetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
dbi.varSet(app, datamap, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetUserVariable(app wba.AppInfo, id string, key string, value string) {
|
||||
dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetGroupVariable(app wba.AppInfo, id string, key string, value string) {
|
||||
dbi.varSet(app, app.AppKey.Name, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetGlobalVariable(app wba.AppInfo, id string, key string, value string) {
|
||||
dbi.varSet(app, app.AppKey.Name, "global", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetOutUserVariable(app wba.AppInfo, datamap string, id string, key string, value string) {
|
||||
dbi.varSet(app, datamap, "user", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetOutGroupVariable(app wba.AppInfo, datamap string, id string, key string, value string) {
|
||||
dbi.varSet(app, datamap, "group", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelySetOutGlobalVariable(app wba.AppInfo, datamap string, id string, key string, value string) {
|
||||
dbi.varSet(app, datamap, "global", id, key, value)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) varGet(app wba.AppInfo, datamap string, unit string, id string, key string) (string, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, unit, id, key, false)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
resStr, ok := res.(string)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return resStr, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
return dbi.varGet(app, app.AppKey.Name, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
return dbi.varGet(app, app.AppKey.Name, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
id := fmt.Sprintf("%d", msg.UserId)
|
||||
return dbi.varGet(app, datamap, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (string, bool) {
|
||||
var id string
|
||||
if msg.MessageType == "group" {
|
||||
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
|
||||
}
|
||||
if msg.MessageType == "private" {
|
||||
id = "user_" + fmt.Sprintf("%d", msg.UserId)
|
||||
}
|
||||
return dbi.varGet(app, datamap, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetUserVariable(app wba.AppInfo, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, app.AppKey.Name, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetGroupVariable(app wba.AppInfo, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, app.AppKey.Name, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetGlobalVariable(app wba.AppInfo, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, app.AppKey.Name, "global", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetOutUserVariable(app wba.AppInfo, datamap string, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, datamap, "user", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetOutGroupVariable(app wba.AppInfo, datamap string, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, datamap, "group", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyGetOutGlobalVariable(app wba.AppInfo, datamap string, id string, key string) (string, bool) {
|
||||
return dbi.varGet(app, datamap, "global", id, key)
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetIntConfig(app wba.AppInfo, datamap string, key string) (int64, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "number", key, true)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
resInt, ok := res.(int64)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return resInt, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetStringConfig(app wba.AppInfo, datamap string, key string) (string, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "string", key, true)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
resStr, ok := res.(string)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return resStr, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetFloatConfig(app wba.AppInfo, datamap string, key string) (float64, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "float", key, true)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
resFloat, ok := res.(float64)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return resFloat, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetIntSliceConfig(app wba.AppInfo, datamap string, key string) ([]int64, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "number_slice", key, true)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
resSlice, ok := res.([]int64)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return resSlice, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) GetStringSliceConfig(app wba.AppInfo, datamap string, key string) ([]string, bool) {
|
||||
res, ok := database.Get(app.AppKey.Name, datamap, "config", "string_slice", key, true)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
resSlice, ok := res.([]string)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return resSlice, true
|
||||
}
|
||||
|
||||
func (dbi *databaseInfo) UnsafelyCreatePublicDatamap(app wba.AppInfo, datamapId string) {
|
||||
appName := app.AppKey.Name
|
||||
database.CreatePublicDatamap(appName, datamapId)
|
||||
}
|
||||
|
||||
// 文件管理模块
|
||||
//TODO: 文件管理模块待实现
|
||||
|
||||
@ -1204,8 +934,7 @@ func (dbi *databaseInfo) UnsafelyCreatePublicDatamap(app wba.AppInfo, datamapId
|
||||
|
||||
//核心信息调用模块
|
||||
|
||||
var AppApi apiInfo
|
||||
var DatabaseApi databaseInfo
|
||||
var ProtocolApi protocolAPI
|
||||
|
||||
func GenerateUUID() (string, error) {
|
||||
uuid := make([]byte, 16)
|
143
core/api_wst.go
Normal file
143
core/api_wst.go
Normal file
@ -0,0 +1,143 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"ProjectWIND/LOG"
|
||||
"ProjectWIND/wba"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type toolsAPI struct{}
|
||||
|
||||
//二、LOG模块
|
||||
|
||||
/*
|
||||
关于LOG模块的说明
|
||||
|
||||
1.日志模块级别分为TRACE、DEBUG、INFO、NOTICE、WARN、ERROR五个级别,默认级别为INFO。
|
||||
|
||||
2.日志模块提供LogWith方法,可以自定义日志级别。
|
||||
|
||||
3.日志模块提供Log方法,默认日志级别为INFO。
|
||||
*/
|
||||
|
||||
// LogWith 打印日志(带级别)
|
||||
//
|
||||
// 参数:
|
||||
// - level: 日志级别,支持"TRACE"、"DEBUG"、"INFO"、"NOTICE"、 "WARN"、"ERROR"
|
||||
// - content: 日志内容
|
||||
// - args: 可选参数,用于格式化日志内容
|
||||
//
|
||||
// 返回值:
|
||||
// - 无
|
||||
func (t *toolsAPI) LogWith(level string, content string, args ...interface{}) {
|
||||
level = strings.ToLower(level)
|
||||
switch level {
|
||||
case "trace":
|
||||
LOG.Trace(content, args...)
|
||||
return
|
||||
case "debug":
|
||||
LOG.Debug(content, args...)
|
||||
return
|
||||
case "notice":
|
||||
LOG.Notice(content, args...)
|
||||
return
|
||||
case "warn":
|
||||
LOG.Warn(content, args...)
|
||||
return
|
||||
case "error":
|
||||
LOG.Error(content, args...)
|
||||
return
|
||||
default:
|
||||
LOG.Info(content, args...)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Log 打印日志
|
||||
//
|
||||
// 参数:
|
||||
// - content: 日志内容
|
||||
// - args: 可选参数,用于格式化日志内容
|
||||
func (t *toolsAPI) Log(content string, args ...interface{}) {
|
||||
LOG.Info(content, args...)
|
||||
}
|
||||
|
||||
// MsgUnmarshal 解析消息
|
||||
//
|
||||
// 参数:
|
||||
// - messageJSON: 从数据库中获取的JSON序列化后的消息字符串
|
||||
//
|
||||
// 返回值:
|
||||
// - wba.MessageEventInfo: 解析后的消息事件信息,解析失败时返回空结构体
|
||||
func (t *toolsAPI) MsgUnmarshal(messageJSON string) (msg wba.MessageEventInfo) {
|
||||
err := json.Unmarshal([]byte(messageJSON), &msg)
|
||||
if err != nil {
|
||||
return wba.MessageEventInfo{}
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func (t *toolsAPI) SessionLabelAnalysis(sessionLabel wba.SessionLabel) wba.SessionInfo {
|
||||
platform := strings.Split(sessionLabel, ":")[0]
|
||||
sessionTypeAndId := strings.Split(sessionLabel, ":")[1]
|
||||
sessionType := strings.Split(sessionTypeAndId, "-")[0]
|
||||
sessionId := strings.Split(sessionTypeAndId, "-")[1]
|
||||
Id, err := strconv.ParseInt(sessionId, 10, 64)
|
||||
if err != nil {
|
||||
return wba.SessionInfo{}
|
||||
}
|
||||
return wba.SessionInfo{
|
||||
Platform: platform,
|
||||
SessionType: sessionType,
|
||||
SessionId: Id,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *toolsAPI) VersionCompare(version1, version2 wba.VersionLabel) int {
|
||||
version1Info := VersionLabelAnalysis(version1)
|
||||
version2Info := VersionLabelAnalysis(version2)
|
||||
if version1Info.BigVersion < version2Info.BigVersion {
|
||||
return -1
|
||||
} else if version1Info.BigVersion > version2Info.BigVersion {
|
||||
return 1
|
||||
} else {
|
||||
if version1Info.SmallVersion < version2Info.SmallVersion {
|
||||
return -1
|
||||
} else if version1Info.SmallVersion > version2Info.SmallVersion {
|
||||
return 1
|
||||
} else {
|
||||
if version1Info.FixVersion < version2Info.FixVersion {
|
||||
return -1
|
||||
} else if version1Info.FixVersion > version2Info.FixVersion {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func VersionLabelAnalysis(versionLabel wba.VersionLabel) wba.VersionInfo {
|
||||
version := strings.Split(versionLabel, ".")
|
||||
bigVersion, err := strconv.ParseUint(version[0], 10, 8)
|
||||
if err != nil {
|
||||
return wba.VersionInfo{}
|
||||
}
|
||||
smallVersion, err := strconv.ParseUint(version[1], 10, 8)
|
||||
if err != nil {
|
||||
return wba.VersionInfo{}
|
||||
}
|
||||
fixVersion, err := strconv.ParseUint(version[2], 10, 8)
|
||||
if err != nil {
|
||||
return wba.VersionInfo{}
|
||||
}
|
||||
return wba.VersionInfo{
|
||||
BigVersion: uint8(bigVersion),
|
||||
SmallVersion: uint8(smallVersion),
|
||||
FixVersion: uint8(fixVersion),
|
||||
}
|
||||
}
|
||||
|
||||
var ToolsApi toolsAPI
|
@ -3,21 +3,45 @@ package core
|
||||
import (
|
||||
"ProjectWIND/LOG"
|
||||
"ProjectWIND/wba"
|
||||
"github.com/dop251/goja"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
)
|
||||
|
||||
var CmdMap = make([]map[string]wba.Cmd, 4)
|
||||
type CamelCaseFieldNameMapper struct{}
|
||||
|
||||
func (CamelCaseFieldNameMapper) FieldName(_ reflect.Type, f reflect.StructField) string {
|
||||
name := f.Name
|
||||
if len(name) == 0 {
|
||||
return name
|
||||
}
|
||||
// 首字母小写
|
||||
return strings.ToLower(name[:1]) + name[1:]
|
||||
}
|
||||
|
||||
func (CamelCaseFieldNameMapper) MethodName(_ reflect.Type, m reflect.Method) string {
|
||||
name := m.Name
|
||||
if len(name) == 0 {
|
||||
return name
|
||||
}
|
||||
// 首字母小写
|
||||
return strings.ToLower(name[:1]) + name[1:]
|
||||
}
|
||||
|
||||
var GlobalCmdAgentSelector = wba.NewCmdAgentSelector()
|
||||
var CmdMap = make(map[wba.AppKey]wba.CmdList)
|
||||
var AppMap = make(map[wba.AppKey]wba.AppInfo)
|
||||
var ScheduledTaskMap = make(map[wba.AppKey]map[string]wba.ScheduledTaskInfo)
|
||||
|
||||
// ReloadApps 重新加载应用
|
||||
func ReloadApps() (total int, success int) {
|
||||
// 清空AppMap和CmdMap
|
||||
CmdMap = make([]map[string]wba.Cmd, 4)
|
||||
CmdMap = make(map[wba.AppKey]wba.CmdList)
|
||||
AppMap = make(map[wba.AppKey]wba.AppInfo)
|
||||
ScheduledTaskMap = make(map[wba.AppKey]map[string]wba.ScheduledTaskInfo)
|
||||
GlobalCmdAgentSelector = wba.NewCmdAgentSelector()
|
||||
appsDir := "./data/app/"
|
||||
appFiles, err := os.ReadDir(appsDir)
|
||||
total = 0
|
||||
@ -32,7 +56,8 @@ func ReloadApps() (total int, success int) {
|
||||
total += totalDelta
|
||||
success += successDelta
|
||||
}
|
||||
CmdMap[0] = AppCore.CmdMap
|
||||
CmdMap[AppCore.AppKey] = AppCore.CmdMap
|
||||
GlobalCmdAgentSelector.AddCmdMap(CmdMap)
|
||||
return total, success
|
||||
}
|
||||
|
||||
@ -52,103 +77,124 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
|
||||
}
|
||||
|
||||
runtime := goja.New()
|
||||
_, err = runtime.RunString(string(jsCode))
|
||||
if err != nil {
|
||||
LOG.Error("执行应用 %s 失败: %v", pluginPath, err)
|
||||
return 1, 0
|
||||
runtime.SetFieldNameMapper(CamelCaseFieldNameMapper{})
|
||||
runtime.Set("console", map[string]interface{}{
|
||||
"log": func(v ...interface{}) {
|
||||
LOG.Info("JS log: %v", v...)
|
||||
},
|
||||
"error": func(v ...interface{}) {
|
||||
LOG.Error("JS error: %v", v...)
|
||||
},
|
||||
})
|
||||
|
||||
// 添加错误捕获
|
||||
safeRun := func(fn func() error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
LOG.Error("JS执行错误: %v", r)
|
||||
}
|
||||
}()
|
||||
if err := fn(); err != nil {
|
||||
LOG.Error("JS执行错误: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 修改JS代码执行部分
|
||||
safeRun(func() error {
|
||||
_, err := runtime.RunString(string(jsCode))
|
||||
return err
|
||||
})
|
||||
|
||||
// 创建JS可用的wbaObj对象
|
||||
wbaObj := runtime.NewObject()
|
||||
wsp := runtime.NewObject()
|
||||
wsd := runtime.NewObject()
|
||||
wst := runtime.NewObject()
|
||||
//wsp := runtime.NewObject()
|
||||
//wsd := runtime.NewObject()
|
||||
//wst := runtime.NewObject()
|
||||
_ = runtime.Set("wba", wbaObj)
|
||||
_ = wbaObj.Set("NewApp", wba.NewApp)
|
||||
_ = wbaObj.Set("WithName", wba.WithName)
|
||||
_ = wbaObj.Set("WithAuthor", wba.WithAuthor)
|
||||
_ = wbaObj.Set("WithVersion", wba.WithVersion)
|
||||
_ = wbaObj.Set("WithDescription", wba.WithDescription)
|
||||
_ = wbaObj.Set("WithWebUrl", wba.WithWebUrl)
|
||||
_ = wbaObj.Set("WithLicense", wba.WithLicense)
|
||||
_ = wbaObj.Set("WithAppType", wba.WithAppType)
|
||||
_ = wbaObj.Set("WithRule", wba.WithRule)
|
||||
_ = wbaObj.Set("wsp", wsp)
|
||||
_ = wbaObj.Set("wsd", wsd)
|
||||
_ = wbaObj.Set("wst", wst)
|
||||
//WSP注册
|
||||
_ = wsp.Set("UnsafelySendMsg", AppApi.UnsafelySendMsg)
|
||||
_ = wsp.Set("UnsafelySendPrivateMsg", AppApi.UnsafelySendPrivateMsg)
|
||||
_ = wsp.Set("UnsafelySendGroupMsg", AppApi.UnsafelySendGroupMsg)
|
||||
_ = wsp.Set("SendMsg", AppApi.SendMsg)
|
||||
_ = wsp.Set("SendPrivateMsg", AppApi.SendPrivateMsg)
|
||||
_ = wsp.Set("SendGroupMsg", AppApi.SendGroupMsg)
|
||||
_ = wsp.Set("UnsafelyDeleteMsg", AppApi.UnsafelyDeleteMsg)
|
||||
_ = wsp.Set("DeleteMsg", AppApi.DeleteMsg)
|
||||
_ = wsp.Set("SendLike", AppApi.SendLike)
|
||||
_ = wsp.Set("SetGroupKick", AppApi.SetGroupKick)
|
||||
_ = wsp.Set("SetGroupBan", AppApi.SetGroupBan)
|
||||
_ = wsp.Set("SetGroupWholeBan", AppApi.SetGroupWholeBan)
|
||||
_ = wsp.Set("SetGroupAdmin", AppApi.SetGroupAdmin)
|
||||
_ = wsp.Set("SetGroupLeave", AppApi.SetGroupLeave)
|
||||
_ = wsp.Set("SetGroupCard", AppApi.SetGroupCard)
|
||||
_ = wsp.Set("SetGroupName", AppApi.SetGroupName)
|
||||
_ = wsp.Set("SetGroupSpecialTitle", AppApi.SetGroupSpecialTitle)
|
||||
_ = wsp.Set("SetFriendAddRequest", AppApi.SetFriendAddRequest)
|
||||
_ = wsp.Set("SetGroupAddRequest", AppApi.SetGroupAddRequest)
|
||||
_ = wsp.Set("GetLoginInfo", AppApi.GetLoginInfo)
|
||||
_ = wsp.Set("GetVersionInfo", AppApi.GetVersionInfo)
|
||||
_ = wsp.Set("GetMsg", AppApi.GetMsg)
|
||||
_ = wsp.Set("GetGroupInfo", AppApi.GetGroupInfo)
|
||||
_ = wsp.Set("GetForwardMsg", AppApi.GetForwardMsg)
|
||||
_ = wsp.Set("GetStrangerInfo", AppApi.GetStrangerInfo)
|
||||
_ = wsp.Set("GetGroupList", AppApi.GetGroupList)
|
||||
_ = wsp.Set("GetGroupMemberList", AppApi.GetGroupMemberList)
|
||||
_ = wsp.Set("GetFriendList", AppApi.GetFriendList)
|
||||
_ = wsp.Set("GetGroupMemberInfo", AppApi.GetGroupMemberInfo)
|
||||
_ = wsp.Set("GetGroupHonorInfo", AppApi.GetGroupHonorInfo)
|
||||
_ = wsp.Set("GetStatus", AppApi.GetStatus)
|
||||
_ = wsp.Set("GetCookies", AppApi.GetCookies)
|
||||
_ = wsp.Set("GetCSRFToken", AppApi.GetCSRFToken)
|
||||
_ = wsp.Set("GetCredentials", AppApi.GetCredentials)
|
||||
_ = wsp.Set("GetImage", AppApi.GetImage)
|
||||
_ = wsp.Set("GetRecord", AppApi.GetRecord)
|
||||
_ = wsp.Set("CanSendImage", AppApi.CanSendImage)
|
||||
_ = wsp.Set("CanSendRecord", AppApi.CanSendRecord)
|
||||
_ = wsp.Set("SetRestart", AppApi.SetRestart)
|
||||
_ = wsp.Set("CleanCache", AppApi.CleanCache)
|
||||
_ = wsp.Set("GetVersionInfo", AppApi.GetVersionInfo)
|
||||
//WST注册
|
||||
_ = wst.Set("LogWith", AppApi.LogWith)
|
||||
_ = wst.Set("Log", AppApi.Log)
|
||||
_ = wst.Set("MsgMarshal", AppApi.MsgUnmarshal)
|
||||
//WSD注册
|
||||
_ = wsd.Set("SetUserVariable", DatabaseApi.SetUserVariable)
|
||||
_ = wsd.Set("SetGroupVariable", DatabaseApi.SetGroupVariable)
|
||||
_ = wsd.Set("SetOutUserVariable", DatabaseApi.SetOutUserVariable)
|
||||
_ = wsd.Set("SetOutGroupVariable", DatabaseApi.SetOutGroupVariable)
|
||||
_ = wsd.Set("UnsafelySetUserVariable", DatabaseApi.UnsafelySetUserVariable)
|
||||
_ = wsd.Set("UnsafelySetGroupVariable", DatabaseApi.UnsafelySetGroupVariable)
|
||||
_ = wsd.Set("UnsafelySetGlobalVariable", DatabaseApi.UnsafelySetGlobalVariable)
|
||||
_ = wsd.Set("UnsafelySetOutUserVariable", DatabaseApi.UnsafelySetOutUserVariable)
|
||||
_ = wsd.Set("UnsafelySetOutGroupVariable", DatabaseApi.UnsafelySetOutGroupVariable)
|
||||
_ = wsd.Set("UnsafelySetOutGlobalVariable", DatabaseApi.UnsafelySetOutGlobalVariable)
|
||||
_ = wsd.Set("GetUserVariable", DatabaseApi.GetUserVariable)
|
||||
_ = wsd.Set("GetGroupVariable", DatabaseApi.GetGroupVariable)
|
||||
_ = wsd.Set("GetOutUserVariable", DatabaseApi.GetOutUserVariable)
|
||||
_ = wsd.Set("GetOutGroupVariable", DatabaseApi.GetOutGroupVariable)
|
||||
_ = wsd.Set("UnsafelyGetUserVariable", DatabaseApi.UnsafelyGetUserVariable)
|
||||
_ = wsd.Set("UnsafelyGetGroupVariable", DatabaseApi.UnsafelyGetGroupVariable)
|
||||
_ = wsd.Set("UnsafelyGetGlobalVariable", DatabaseApi.UnsafelyGetGlobalVariable)
|
||||
_ = wsd.Set("UnsafelyGetOutUserVariable", DatabaseApi.UnsafelyGetOutUserVariable)
|
||||
_ = wsd.Set("UnsafelyGetOutGroupVariable", DatabaseApi.UnsafelyGetOutGroupVariable)
|
||||
_ = wsd.Set("UnsafelyGetOutGlobalVariable", DatabaseApi.UnsafelyGetOutGlobalVariable)
|
||||
_ = wsd.Set("GetIntConfig", DatabaseApi.GetIntConfig)
|
||||
_ = wsd.Set("GetFloatConfig", DatabaseApi.GetFloatConfig)
|
||||
_ = wsd.Set("GetStringConfig", DatabaseApi.GetStringConfig)
|
||||
_ = wsd.Set("GetIntSliceConfig", DatabaseApi.GetIntSliceConfig)
|
||||
_ = wsd.Set("GetStringSliceConfig", DatabaseApi.GetStringSliceConfig)
|
||||
_ = wsd.Set("UnsafelyCreatePublicDatamap", DatabaseApi.UnsafelyCreatePublicDatamap)
|
||||
_ = wbaObj.Set("newApp", wba.NewApp)
|
||||
_ = wbaObj.Set("withName", wba.WithSelector)
|
||||
_ = wbaObj.Set("withDescription", wba.WithDescription)
|
||||
_ = wbaObj.Set("withWebUrl", wba.WithWebUrl)
|
||||
_ = wbaObj.Set("withLicense", wba.WithLicense)
|
||||
_ = wbaObj.Set("wsp", ProtocolApi)
|
||||
_ = wbaObj.Set("wsd", DatabaseApi)
|
||||
_ = wbaObj.Set("wst", ToolsApi)
|
||||
//_ = wbaObj.Set("wsp", wsp)
|
||||
//_ = wbaObj.Set("wsd", wsd)
|
||||
//_ = wbaObj.Set("wst", wst)
|
||||
////WSP注册
|
||||
//_ = wsp.Set("unsafelySendMsg", ProtocolApi.UnsafelySendMsg)
|
||||
//_ = wsp.Set("unsafelySendPrivateMsg", ProtocolApi.UnsafelySendPrivateMsg)
|
||||
//_ = wsp.Set("unsafelySendGroupMsg", ProtocolApi.UnsafelySendGroupMsg)
|
||||
//_ = wsp.Set("sendMsg", ProtocolApi.SendMsg)
|
||||
//_ = wsp.Set("sendPrivateMsg", ProtocolApi.SendPrivateMsg)
|
||||
//_ = wsp.Set("sendGroupMsg", ProtocolApi.SendGroupMsg)
|
||||
//_ = wsp.Set("unsafelyDeleteMsg", ProtocolApi.UnsafelyDeleteMsg)
|
||||
//_ = wsp.Set("deleteMsg", ProtocolApi.DeleteMsg)
|
||||
//_ = wsp.Set("sendLike", ProtocolApi.SendLike)
|
||||
//_ = wsp.Set("setGroupKick", ProtocolApi.SetGroupKick)
|
||||
//_ = wsp.Set("setGroupBan", ProtocolApi.SetGroupBan)
|
||||
//_ = wsp.Set("setGroupWholeBan", ProtocolApi.SetGroupWholeBan)
|
||||
//_ = wsp.Set("setGroupAdmin", ProtocolApi.SetGroupAdmin)
|
||||
//_ = wsp.Set("setGroupLeave", ProtocolApi.SetGroupLeave)
|
||||
//_ = wsp.Set("setGroupCard", ProtocolApi.SetGroupCard)
|
||||
//_ = wsp.Set("setGroupName", ProtocolApi.SetGroupName)
|
||||
//_ = wsp.Set("setGroupSpecialTitle", ProtocolApi.SetGroupSpecialTitle)
|
||||
//_ = wsp.Set("setFriendAddRequest", ProtocolApi.SetFriendAddRequest)
|
||||
//_ = wsp.Set("setGroupAddRequest", ProtocolApi.SetGroupAddRequest)
|
||||
//_ = wsp.Set("getLoginInfo", ProtocolApi.GetLoginInfo)
|
||||
//_ = wsp.Set("getVersionInfo", ProtocolApi.GetVersionInfo)
|
||||
//_ = wsp.Set("getMsg", ProtocolApi.GetMsg)
|
||||
//_ = wsp.Set("getGroupInfo", ProtocolApi.GetGroupInfo)
|
||||
//_ = wsp.Set("getForwardMsg", ProtocolApi.GetForwardMsg)
|
||||
//_ = wsp.Set("getStrangerInfo", ProtocolApi.GetStrangerInfo)
|
||||
//_ = wsp.Set("getGroupList", ProtocolApi.GetGroupList)
|
||||
//_ = wsp.Set("getGroupMemberList", ProtocolApi.GetGroupMemberList)
|
||||
//_ = wsp.Set("getFriendList", ProtocolApi.GetFriendList)
|
||||
//_ = wsp.Set("getGroupMemberInfo", ProtocolApi.GetGroupMemberInfo)
|
||||
//_ = wsp.Set("getGroupHonorInfo", ProtocolApi.GetGroupHonorInfo)
|
||||
//_ = wsp.Set("getStatus", ProtocolApi.GetStatus)
|
||||
//_ = wsp.Set("getCookies", ProtocolApi.GetCookies)
|
||||
//_ = wsp.Set("getCSRFToken", ProtocolApi.GetCSRFToken)
|
||||
//_ = wsp.Set("getCredentials", ProtocolApi.GetCredentials)
|
||||
//_ = wsp.Set("getImage", ProtocolApi.GetImage)
|
||||
//_ = wsp.Set("getRecord", ProtocolApi.GetRecord)
|
||||
//_ = wsp.Set("canSendImage", ProtocolApi.CanSendImage)
|
||||
//_ = wsp.Set("canSendRecord", ProtocolApi.CanSendRecord)
|
||||
//_ = wsp.Set("cetRestart", ProtocolApi.SetRestart)
|
||||
//_ = wsp.Set("cleanCache", ProtocolApi.CleanCache)
|
||||
//_ = wsp.Set("getVersionInfo", ProtocolApi.GetVersionInfo)
|
||||
////WST注册
|
||||
//_ = wst.Set("logWith", ToolsApi.LogWith)
|
||||
//_ = wst.Set("log", ToolsApi.Log)
|
||||
//_ = wst.Set("msgMarshal", ToolsApi.MsgUnmarshal)
|
||||
////WSD注册
|
||||
//_ = wsd.Set("setUserVariable", DatabaseApi.SetUserVariable)
|
||||
//_ = wsd.Set("setGroupVariable", DatabaseApi.SetGroupVariable)
|
||||
//_ = wsd.Set("setOutUserVariable", DatabaseApi.SetOutUserVariable)
|
||||
//_ = wsd.Set("setOutGroupVariable", DatabaseApi.SetOutGroupVariable)
|
||||
//_ = wsd.Set("unsafelySetUserVariable", DatabaseApi.UnsafelySetUserVariable)
|
||||
//_ = wsd.Set("unsafelySetGroupVariable", DatabaseApi.UnsafelySetGroupVariable)
|
||||
//_ = wsd.Set("unsafelySetGlobalVariable", DatabaseApi.UnsafelySetGlobalVariable)
|
||||
//_ = wsd.Set("unsafelySetOutUserVariable", DatabaseApi.UnsafelySetOutUserVariable)
|
||||
//_ = wsd.Set("unsafelySetOutGroupVariable", DatabaseApi.UnsafelySetOutGroupVariable)
|
||||
//_ = wsd.Set("unsafelySetOutGlobalVariable", DatabaseApi.UnsafelySetOutGlobalVariable)
|
||||
//_ = wsd.Set("getUserVariable", DatabaseApi.GetUserVariable)
|
||||
//_ = wsd.Set("getGroupVariable", DatabaseApi.GetGroupVariable)
|
||||
//_ = wsd.Set("getOutUserVariable", DatabaseApi.GetOutUserVariable)
|
||||
//_ = wsd.Set("getOutGroupVariable", DatabaseApi.GetOutGroupVariable)
|
||||
//_ = wsd.Set("unsafelyGetUserVariable", DatabaseApi.UnsafelyGetUserVariable)
|
||||
//_ = wsd.Set("unsafelyGetGroupVariable", DatabaseApi.UnsafelyGetGroupVariable)
|
||||
//_ = wsd.Set("unsafelyGetGlobalVariable", DatabaseApi.UnsafelyGetGlobalVariable)
|
||||
//_ = wsd.Set("unsafelyGetOutUserVariable", DatabaseApi.UnsafelyGetOutUserVariable)
|
||||
//_ = wsd.Set("unsafelyGetOutGroupVariable", DatabaseApi.UnsafelyGetOutGroupVariable)
|
||||
//_ = wsd.Set("unsafelyGetOutGlobalVariable", DatabaseApi.UnsafelyGetOutGlobalVariable)
|
||||
//_ = wsd.Set("getIntConfig", DatabaseApi.GetIntConfig)
|
||||
//_ = wsd.Set("getFloatConfig", DatabaseApi.GetFloatConfig)
|
||||
//_ = wsd.Set("getStringConfig", DatabaseApi.GetStringConfig)
|
||||
//_ = wsd.Set("getIntSliceConfig", DatabaseApi.GetIntSliceConfig)
|
||||
//_ = wsd.Set("getStringSliceConfig", DatabaseApi.GetStringSliceConfig)
|
||||
//_ = wsd.Set("unsafelyCreatePublicDatamap", DatabaseApi.UnsafelyCreatePublicDatamap)
|
||||
|
||||
// 获取AppInit函数
|
||||
appInitVal := runtime.Get("AppInit")
|
||||
@ -169,49 +215,68 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
|
||||
return 1, 0
|
||||
}
|
||||
|
||||
// 调用Init方法
|
||||
initVal := jsApp.ToObject(runtime).Get("Init")
|
||||
initFunc, ok := goja.AssertFunction(initVal)
|
||||
if !ok {
|
||||
LOG.Error("应用 %s 缺少有效的Init方法", pluginPath)
|
||||
return 1, 0
|
||||
}
|
||||
|
||||
_, err = initFunc(wbaObj)
|
||||
if err != nil {
|
||||
LOG.Trace("应用初始化失败: %v", err)
|
||||
return 1, 0
|
||||
}
|
||||
|
||||
// 调用Get方法
|
||||
getVal := jsApp.ToObject(runtime).Get("Get")
|
||||
getFunc, ok := goja.AssertFunction(getVal)
|
||||
if !ok {
|
||||
LOG.Error("应用 %s 缺少有效的Get方法", pluginPath)
|
||||
return 1, 0
|
||||
}
|
||||
|
||||
appInfoVal, err := getFunc(jsApp)
|
||||
if err != nil {
|
||||
LOG.Error("获取应用信息失败: %v", err)
|
||||
return 1, 0
|
||||
}
|
||||
//// 调用Init方法
|
||||
//initVal := jsApp.ToObject(runtime).Get("Init")
|
||||
//initFunc, ok := goja.AssertFunction(initVal)
|
||||
//if !ok {
|
||||
// LOG.Error("应用 %s 缺少有效的Init方法 %#v", pluginPath, initFunc)
|
||||
// return 1, 0
|
||||
//}
|
||||
//
|
||||
//_, err = initFunc(wbaObj)
|
||||
//if err != nil {
|
||||
// LOG.Trace("应用初始化失败: %v", err)
|
||||
// return 1, 0
|
||||
//}
|
||||
//
|
||||
//// 调用Get方法
|
||||
//getVal := jsApp.ToObject(runtime).Get("Get")
|
||||
//getFunc, ok := goja.AssertFunction(getVal)
|
||||
//if !ok {
|
||||
// LOG.Error("应用 %s 缺少有效的Get方法", pluginPath)
|
||||
// return 1, 0
|
||||
//}
|
||||
//
|
||||
//appInfoVal, err := getFunc(jsApp)
|
||||
//if err != nil {
|
||||
// LOG.Error("获取应用信息失败: %v", err)
|
||||
// return 1, 0
|
||||
//}
|
||||
|
||||
// 转换应用信息
|
||||
var appInfo wba.AppInfo
|
||||
if err := runtime.ExportTo(appInfoVal, &appInfo); err != nil {
|
||||
if err := runtime.ExportTo(jsApp, &appInfo); err != nil {
|
||||
LOG.Error("应用信息转换失败: %v", err)
|
||||
return 1, 0
|
||||
}
|
||||
// 初始化map字段
|
||||
if appInfo.CmdMap == nil {
|
||||
appInfo.CmdMap = make(map[string]wba.Cmd)
|
||||
}
|
||||
if appInfo.ScheduledTasks == nil {
|
||||
appInfo.ScheduledTasks = make(map[string]wba.ScheduledTaskInfo)
|
||||
}
|
||||
|
||||
AppMap[wba.AppKey{Name: appInfo.AppKey.Name, Type: appInfo.AppKey.Type, Version: appInfo.AppKey.Version, Level: checkAppLevel(appInfo)}] = appInfo
|
||||
cmdIndex := AppTypeToInt(appInfo.AppKey.Type)
|
||||
// 合并命令
|
||||
CmdMap[cmdIndex] = mergeMaps(CmdMap[cmdIndex], appInfo.CmdMap)
|
||||
AppMap[appInfo.AppKey] = appInfo
|
||||
|
||||
CmdMap[appInfo.AppKey] = appInfo.CmdMap
|
||||
|
||||
ScheduledTaskMap[appInfo.AppKey] = appInfo.ScheduledTasks
|
||||
|
||||
// 注册定时任务
|
||||
for _, task := range appInfo.ScheduledTasks {
|
||||
RegisterCron(appInfo.AppKey.Name, task)
|
||||
taskCopy := task
|
||||
RegisterCron(appInfo.AppKey.Name, wba.ScheduledTaskInfo{
|
||||
Name: taskCopy.Name,
|
||||
Desc: taskCopy.Desc,
|
||||
Cron: taskCopy.Cron,
|
||||
Task: func() {
|
||||
safeRun(func() error {
|
||||
taskCopy.Task()
|
||||
return nil
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
LOG.Info("JS应用 %s 加载成功", pluginPath)
|
||||
@ -219,31 +284,3 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
|
||||
}
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func mergeMaps(map1, map2 map[string]wba.Cmd) map[string]wba.Cmd {
|
||||
// 合并map1和map2到map3中
|
||||
map3 := make(map[string]wba.Cmd)
|
||||
for key, value := range map1 {
|
||||
map3[key] = value
|
||||
}
|
||||
for key, value := range map2 {
|
||||
map3[key] = value
|
||||
}
|
||||
return map3
|
||||
}
|
||||
|
||||
func AppTypeToInt(appType string) int32 {
|
||||
appType = strings.ToLower(appType)
|
||||
switch appType {
|
||||
case "system":
|
||||
return 1
|
||||
case "rule":
|
||||
return 2
|
||||
default:
|
||||
return 3
|
||||
}
|
||||
}
|
||||
|
||||
func checkAppLevel(appInfo wba.AppInfo) int32 {
|
||||
return 0
|
||||
}
|
||||
|
@ -3,35 +3,27 @@ package core
|
||||
import (
|
||||
"ProjectWIND/LOG"
|
||||
"ProjectWIND/wba"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type CmdListInfo map[string]wba.Cmd
|
||||
|
||||
type AppInfo struct {
|
||||
CmdMap map[string]wba.Cmd
|
||||
AppKey wba.AppKey
|
||||
}
|
||||
|
||||
func (app AppInfo) Get() AppInfo {
|
||||
return app
|
||||
}
|
||||
|
||||
func (app *AppInfo) Run(cmd string, args []string, msg wba.MessageEventInfo) error {
|
||||
_, ok := app.CmdMap[cmd]
|
||||
if !ok {
|
||||
return errors.New("cmd not found")
|
||||
}
|
||||
app.CmdMap[cmd].Solve(args, msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *AppInfo) Init(Api wba.WindStandardProtocolAPI) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *AppInfo) InitWSD(Api wba.WindStandardDataBaseAPI) error {
|
||||
return nil
|
||||
}
|
||||
//func (app AppInfo) Get() AppInfo {
|
||||
// return app
|
||||
//}
|
||||
//
|
||||
//func (app *AppInfo) Run(cmd string, args []string, msg wba.MessageEventInfo) error {
|
||||
// _, ok := app.CmdMap[cmd]
|
||||
// if !ok {
|
||||
// return errors.New("cmd not found")
|
||||
// }
|
||||
// app.CmdMap[cmd].Solve(args, msg)
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func (app *AppInfo) GetCmd() map[string]wba.Cmd {
|
||||
return app.CmdMap
|
||||
@ -46,14 +38,29 @@ func NewCmd(name string, help string, solve func(args []string, msg wba.MessageE
|
||||
}
|
||||
|
||||
var AppCore = AppInfo{
|
||||
AppKey: wba.AppKey{
|
||||
Name: "core",
|
||||
Level: 0,
|
||||
Version: "1.0.0",
|
||||
Selector: "core",
|
||||
Option: "core",
|
||||
},
|
||||
CmdMap: CmdListInfo{
|
||||
"bot": NewCmd(
|
||||
"bot",
|
||||
"显示WIND版本信息",
|
||||
func(args []string, msg wba.MessageEventInfo) {
|
||||
AppApi.SendMsg(msg, "WIND 0.1.0", false)
|
||||
ProtocolApi.SendMsg(msg, "WIND 0.1.0", false)
|
||||
LOG.Info("发送核心版本信息:(至:%v-%v:%v-%v)", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname)
|
||||
},
|
||||
),
|
||||
"help": NewCmd(
|
||||
"help",
|
||||
"显示帮助信息",
|
||||
func(args []string, msg wba.MessageEventInfo) {
|
||||
ProtocolApi.SendMsg(msg, "帮助信息", false)
|
||||
LOG.Info("发送帮助信息:(至:%v-%v:%v-%v)", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname)
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package core
|
||||
import (
|
||||
"ProjectWIND/LOG"
|
||||
"ProjectWIND/database"
|
||||
"ProjectWIND/typed"
|
||||
"ProjectWIND/wba"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -19,8 +18,14 @@ func HandleMessage(msgJson []byte) {
|
||||
}
|
||||
// 处理消息
|
||||
LOG.Info("收到消息:(来自:%v-%v:%v-%v)%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, msg.RawMessage)
|
||||
CmdHandle(msg)
|
||||
fmt.Printf("%#v\n", msg.Message)
|
||||
isCmd, ok, err := CmdHandle(msg)
|
||||
if err != nil {
|
||||
LOG.Error("命令处理失败: %v", err)
|
||||
}
|
||||
if !isCmd && ok {
|
||||
// 处理消息
|
||||
// TODO: 处理消息
|
||||
}
|
||||
}
|
||||
|
||||
func HandleNotice(msgJson []byte) {
|
||||
@ -50,102 +55,60 @@ func HandleMetaEvent(msgJson []byte) {
|
||||
// TODO: 处理元事件
|
||||
}
|
||||
|
||||
func CmdSplit(msg wba.MessageEventInfo) (string, []string) {
|
||||
//text := msg.RawMessage
|
||||
//if strings.HasPrefix(text, fmt.Sprintf("[CQ:at,qq=%d]", msg.SelfId)) {
|
||||
// text = strings.TrimPrefix(text, fmt.Sprintf("[CQ:at,qq=%d]", msg.SelfId))
|
||||
//} else {
|
||||
// if !statusCheck(msg) {
|
||||
// return "", []string{}
|
||||
// }
|
||||
//}
|
||||
////检查有无application.CmdMap中的命令前缀
|
||||
//for _, prefix := range cmdPrefix {
|
||||
// if strings.HasPrefix(text, prefix) {
|
||||
// text = strings.TrimPrefix(text, prefix)
|
||||
// for cmdList := range CmdMap {
|
||||
// for cmd := range CmdMap[cmdList] {
|
||||
// if strings.HasPrefix(text, cmd) {
|
||||
// text = strings.TrimPrefix(text, cmd)
|
||||
// text = strings.TrimPrefix(text, " ")
|
||||
// return cmd, strings.Split(text, " ")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
return "", []string{}
|
||||
}
|
||||
|
||||
func CmdHandle(msg wba.MessageEventInfo) {
|
||||
func CmdHandle(msg wba.MessageEventInfo) (isCmd bool, ok bool, err error) {
|
||||
// 获取消息的原始文本
|
||||
text := msg.GetText()
|
||||
// 初始化会话工作状态
|
||||
WorkStatus := typed.SessionWorkSpace{}
|
||||
|
||||
if msg.MessageType == "group" {
|
||||
// 如果消息类型是群消息
|
||||
// 从数据库中获取工作状态信息
|
||||
WorkStatusJson, ok := database.MasterGet("WorkStatus", "global", strconv.FormatInt(msg.SelfId, 10), strconv.FormatInt(msg.GroupId, 10))
|
||||
// 尝试将获取到的工作状态信息反序列化为 WorkStatus 结构体
|
||||
err := json.Unmarshal([]byte(WorkStatusJson.(string)), &WorkStatus)
|
||||
// 如果获取失败或反序列化失败
|
||||
if !ok || err != nil {
|
||||
// 初始化一个新的工作状态
|
||||
WorkStatus = typed.SessionWorkSpace{
|
||||
SessionId: fmt.Sprintf("%d-%d", msg.SelfId, msg.GroupId),
|
||||
Rule: "coc",
|
||||
Enable: true,
|
||||
AppEnable: make(map[wba.AppKey]bool),
|
||||
CmdEnable: make(map[string]bool),
|
||||
WorkLevel: 0,
|
||||
}
|
||||
// 将新的工作状态序列化为 JSON 字符串
|
||||
WorkStatusJson, err := json.Marshal(WorkStatus)
|
||||
if err != nil {
|
||||
// 如果序列化失败,记录错误信息
|
||||
LOG.Error("命令处理过程中,WorkStatusJson序列化失败: %v", err)
|
||||
}
|
||||
// 将序列化后的工作状态保存到数据库中
|
||||
database.MasterSet("WorkStatus", "global", strconv.FormatInt(msg.SelfId, 10), strconv.FormatInt(msg.GroupId, 10), string(WorkStatusJson))
|
||||
}
|
||||
session := wba.SessionInfo{}
|
||||
session = session.Load("QQ", msg)
|
||||
// 从数据库加载配置
|
||||
conf, ok := database.MasterGet("GCAS_Config", session.SessionType, strconv.FormatInt(session.SessionId, 10), "GCAS_Config")
|
||||
if !ok {
|
||||
conf = "{}"
|
||||
}
|
||||
if err = GlobalCmdAgentSelector.LoadConfig(session, conf.(string)); err != nil {
|
||||
LOG.Error("加载配置失败: %v", err)
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
// 调用 CmdSplit 函数将消息文本拆分为命令和参数
|
||||
cmd, args := CmdSplit(msg)
|
||||
|
||||
// 检查是否找到了有效的命令
|
||||
if cmd != "" {
|
||||
// 遍历命令映射表 CmdMap
|
||||
for _, cmdList := range CmdMap {
|
||||
for cmdKey, Cmd := range cmdList {
|
||||
// 如果找到了匹配的命令
|
||||
if cmdKey == cmd {
|
||||
// 检查会话工作状态
|
||||
if WorkStatus.SessionId != "" {
|
||||
if !WorkStatus.Enable {
|
||||
// 如果会话未启用,忽略该命令
|
||||
LOG.Debug("忽略指令:%s,当前会话中bot未启用", cmd)
|
||||
continue
|
||||
}
|
||||
// 检查 APP 或命令是否启用,以及工作级别和规则是否匹配
|
||||
if !WorkStatus.AppEnable[Cmd.AppKey] || !WorkStatus.CmdEnable[cmd] || WorkStatus.WorkLevel > Cmd.AppKey.Level || (WorkStatus.Rule != Cmd.AppKey.Rule && WorkStatus.Rule != "none") {
|
||||
// 如果不满足条件,忽略该命令
|
||||
LOG.Debug("忽略指令:%s,当前会话中APP或命令未启用", cmd)
|
||||
continue
|
||||
}
|
||||
}
|
||||
// 执行命令
|
||||
Cmd.Solve(args, msg)
|
||||
// 记录执行的命令和参数
|
||||
LOG.Info("执行命令:%v %v", cmd, args)
|
||||
}
|
||||
// 检查命令前缀
|
||||
for _, prefix := range cmdPrefix {
|
||||
if strings.HasPrefix(text, prefix) {
|
||||
// 解析命令
|
||||
text = strings.TrimPrefix(text, prefix)
|
||||
cmdSlice := strings.Split(text, " ")
|
||||
if text == "" {
|
||||
return false, true, nil
|
||||
}
|
||||
cmd := cmdSlice[0]
|
||||
args := cmdSlice[1:]
|
||||
|
||||
result, count := GlobalCmdAgentSelector.FindCmd(cmd, true)
|
||||
if count == 0 {
|
||||
LOG.Debug("未找到命令: %s", cmd)
|
||||
return false, true, nil
|
||||
}
|
||||
|
||||
// 执行找到的第一个匹配命令
|
||||
cmdFunc := result[0]
|
||||
if err := safeExecuteCmd(cmdFunc, args, msg); err != nil {
|
||||
LOG.Error("执行命令失败: %v", err)
|
||||
return true, false, err
|
||||
}
|
||||
return true, true, nil
|
||||
}
|
||||
} else {
|
||||
// 如果未找到有效的命令,记录未找到命令的信息
|
||||
LOG.Info("未找到命令:%v", strings.Split(text, " ")[0])
|
||||
}
|
||||
return false, true, nil
|
||||
}
|
||||
|
||||
func safeExecuteCmd(cmdFunc wba.Cmd, args []string, msg wba.MessageEventInfo) (err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("%v", r)
|
||||
}
|
||||
}()
|
||||
cmdFunc.Solve(args, msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
var cmdPrefix = []string{"/", "!", "/", "!", ".", "。"}
|
||||
|
48
core/selector_doc.md
Normal file
48
core/selector_doc.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Selector设计思路与使用说明
|
||||
|
||||
## 问题背景
|
||||
|
||||
在骰子执行指令时,我们经常遇到这样一些问题:
|
||||
- 不同的插件可能使用相同的指令(很多跑团对应规则都有同名的指令),但是参数和功能完全不同,导致指令无法正常执行。并且当其中有系统级指令时,可能会导致其他严重问题,此时需要一个机制来区分指令。
|
||||
- 当我们在进行trpg时日志开启后,可能需要屏蔽某些无关的指令和自定义回复,此时需要一个机制来过滤指令和回复(即权限控制)。
|
||||
- 在不同的群聊中,各种插件的开启情况各不相同,此时需要一个机制来管理不同组群插件的开启和关闭情况(包括前两条中的权限控制问题)。
|
||||
|
||||
为解决上述问题,我们设计了一个指令选择器,用于管理和选择指令。
|
||||
|
||||
## 设计思路
|
||||
|
||||
选择器的设计思路如下:
|
||||
- 每个组群有一个独立的总选择器(Agent Selector),用于管理该组群的指令和回复。
|
||||
- 每个选择器有若干个层级(Level),在查找可用指令(Cmd)时,从最高层级(0)开始查找,直到找到可用指令为止。
|
||||
- 每个层级有若干个选择器(Selector),每个选择器中包含若干个选项(Option),每个选项对应一个指令集(CmdSet)。每个选择器只能同时选择一个选项,选择后其余选项中的指令集将被屏蔽。
|
||||
- 指令集是由若干个应用(App)中的指令组成的,一个应用只能归属于一个指令集,一个指令集可以包含多个应用的指令。
|
||||
|
||||
数据结构如下:
|
||||
```go
|
||||
type AgentSelector struct {
|
||||
Session wba.Session
|
||||
Selectors []Selector
|
||||
}
|
||||
|
||||
type Selector struct {
|
||||
Level int
|
||||
Name string
|
||||
Options []*Option
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
Name string
|
||||
CmdSets map[string]CmdSet
|
||||
}
|
||||
|
||||
type CmdSet struct {
|
||||
map[string]wba.Command
|
||||
}
|
||||
|
||||
type Cmmand struct {
|
||||
Name string
|
||||
Desc string
|
||||
App AppKey
|
||||
Solve func(*wba.Context)
|
||||
}
|
||||
```
|
@ -44,9 +44,9 @@ func WebSocketHandler(protocol typed.Protocol) error {
|
||||
}
|
||||
}(conn)
|
||||
LOG.Info("已连接到WebSocket服务器: %v", u.String())
|
||||
ProtocolInfo := AppApi.GetVersionInfo()
|
||||
ProtocolInfo := ProtocolApi.GetVersionInfo()
|
||||
LOG.Info("协议端信息: %v-%v", ProtocolInfo.Data.AppName, ProtocolInfo.Data.AppVersion)
|
||||
logInfo := AppApi.GetLoginInfo()
|
||||
logInfo := ProtocolApi.GetLoginInfo()
|
||||
LOG.Info("连接到账号: %v(%v)", logInfo.Data.Nickname, logInfo.Data.UserId)
|
||||
|
||||
// 定义通道,缓存消息和消息类型,防止消息处理阻塞
|
||||
|
50
wba/app.go
50
wba/app.go
@ -1,5 +1,7 @@
|
||||
package wba
|
||||
|
||||
import "strings"
|
||||
|
||||
type AppInfo struct {
|
||||
AppKey AppKey
|
||||
Author string
|
||||
@ -64,6 +66,13 @@ func WithLevel(level uint8) AppInfoOption {
|
||||
}
|
||||
}
|
||||
|
||||
func toCamelCase(s string) string {
|
||||
if s == "" {
|
||||
return s
|
||||
}
|
||||
return strings.ToLower(s[:1]) + s[1:]
|
||||
}
|
||||
|
||||
func NewApp(name string, version string, author string, opts ...AppInfoOption) AppInfo {
|
||||
Ext := AppInfo{
|
||||
AppKey: AppKey{
|
||||
@ -84,6 +93,15 @@ func NewApp(name string, version string, author string, opts ...AppInfoOption) A
|
||||
for _, opt := range opts {
|
||||
opt(&Ext)
|
||||
}
|
||||
|
||||
// 添加JS风格方法
|
||||
Ext.API = map[string]interface{}{
|
||||
toCamelCase("NewCmd"): Ext.NewCmd,
|
||||
toCamelCase("AddCmd"): Ext.AddCmd,
|
||||
toCamelCase("NewScheduledTask"): Ext.NewScheduledTask,
|
||||
toCamelCase("AddScheduledTask"): Ext.AddScheduledTask,
|
||||
}
|
||||
|
||||
return Ext
|
||||
}
|
||||
|
||||
@ -127,7 +145,7 @@ type AppKey struct {
|
||||
Option OptionLabel `json:"option"`
|
||||
}
|
||||
|
||||
// Priority 是一个整数类型,用于表示命令的优先级。只能是不小于1的整数。
|
||||
// Priority 是一个整数类型,用于表示命令的优先级。只能是不小于1且不大于4的整数。
|
||||
type Priority = uint8
|
||||
|
||||
// VersionLabel 是一个字符串类型,用于表示版本标签。
|
||||
@ -142,15 +160,45 @@ type OptionLabel = string
|
||||
// SessionLabel 是一个字符串类型,用于表示聊天会话的标签,格式为[平台:类型-ID],如"QQ:group-1145141919810"
|
||||
type SessionLabel = string
|
||||
|
||||
// CmdSetLabel 是一个字符串类型,用于表示命令集的标签。
|
||||
type CmdSetLabel = string
|
||||
|
||||
// CmdLabel 是一个字符串类型,用于表示命令的标签。
|
||||
type CmdLabel = string
|
||||
|
||||
// CmdList 是一个字符串到 wba.Cmd 的映射,用于存储命令的列表。
|
||||
type CmdList = map[string]Cmd
|
||||
|
||||
// SessionInfo 是一个结构体,用于存储会话信息。
|
||||
//
|
||||
// 字段:
|
||||
// - Platform: 表示会话的平台,如"QQ"、"Telegram"等。
|
||||
// - SessionType: 表示会话的类型,如"group"、"private"等。
|
||||
// - SessionId: 表示会话的ID,如群号、私聊号等。
|
||||
type SessionInfo struct {
|
||||
Platform string
|
||||
SessionType string
|
||||
SessionId int64
|
||||
}
|
||||
|
||||
func (s *SessionInfo) Load(platform string, msg MessageEventInfo) SessionInfo {
|
||||
s.Platform = platform
|
||||
s.SessionType = msg.MessageType
|
||||
if s.SessionType == "group" {
|
||||
s.SessionId = msg.GroupId
|
||||
}
|
||||
if s.SessionType == "private" {
|
||||
s.SessionId = msg.UserId
|
||||
}
|
||||
return *s
|
||||
}
|
||||
|
||||
// VersionInfo 是一个结构体,用于存储版本信息。
|
||||
//
|
||||
// 字段:
|
||||
// - BigVersion: 表示大版本号。
|
||||
// - SmallVersion: 表示小版本号。
|
||||
// - FixVersion: 表示修复版本号。
|
||||
type VersionInfo struct {
|
||||
BigVersion uint8
|
||||
SmallVersion uint8
|
||||
|
360
wba/selector.go
Normal file
360
wba/selector.go
Normal file
@ -0,0 +1,360 @@
|
||||
package wba
|
||||
|
||||
import (
|
||||
"ProjectWIND/LOG"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type CmdAgentSelector struct {
|
||||
Session SessionInfo
|
||||
Selectors [4]map[SelectorLabel]Selector
|
||||
cmdTable map[CmdLabel]map[CmdSetLabel]struct{}
|
||||
cmdSetTable map[CmdSetLabel]map[OptionLabel]struct{}
|
||||
optionTable map[OptionLabel][]map[SelectorLabel]struct{}
|
||||
}
|
||||
|
||||
type Selector struct {
|
||||
Level Priority
|
||||
Name SelectorLabel
|
||||
Options map[OptionLabel]Option
|
||||
currentOption OptionLabel
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
Name string
|
||||
CmdSets map[CmdSetLabel]CmdSet
|
||||
}
|
||||
|
||||
type CmdSet struct {
|
||||
Name CmdSetLabel
|
||||
Cmds map[CmdLabel]CmdInfo
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
type CmdInfo struct {
|
||||
Name CmdLabel
|
||||
Cmd Cmd
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// NewCmdAgentSelector 创建一个新的 CmdAgentSelector 实例并初始化。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - session: 所属会话信息。
|
||||
func NewCmdAgentSelector() CmdAgentSelector {
|
||||
c := CmdAgentSelector{
|
||||
Session: SessionInfo{},
|
||||
Selectors: [4]map[SelectorLabel]Selector{},
|
||||
cmdTable: make(map[CmdLabel]map[CmdSetLabel]struct{}),
|
||||
cmdSetTable: make(map[CmdSetLabel]map[OptionLabel]struct{}),
|
||||
optionTable: make(map[OptionLabel][]map[SelectorLabel]struct{}),
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Selectors[i] = make(map[SelectorLabel]Selector)
|
||||
c.optionTable[fmt.Sprintf("%d", i)] = make([]map[SelectorLabel]struct{}, 4)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (a *CmdAgentSelector) LoadConfig(session SessionInfo, config string) error {
|
||||
a.Session = session
|
||||
conf := CmdAgentSelector{}
|
||||
err := json.Unmarshal([]byte(config), &conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
for selectorName, selector := range a.Selectors[i] {
|
||||
selector.currentOption = conf.Selectors[i][selectorName].currentOption
|
||||
for optionName, option := range selector.Options {
|
||||
for cmdSetName, cmdSet := range option.CmdSets {
|
||||
for cmdName, cmd := range cmdSet.Cmds {
|
||||
cmd.Enabled = conf.Selectors[i][selectorName].Options[optionName].CmdSets[cmdSetName].Cmds[cmdName].Enabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddCmdMap 添加一个命令映射(map[AppKey]CmdList)到 CmdAgentSelector 中。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - cmdMap: 命令映射,键为 AppKey,值为 CmdList。
|
||||
func (a *CmdAgentSelector) AddCmdMap(cmdMap map[AppKey]CmdList) {
|
||||
for appKey, cmds := range cmdMap {
|
||||
a.AddCmdSet(appKey, cmds)
|
||||
}
|
||||
}
|
||||
|
||||
// AddCmdSet 添加一个命令集(即APP)到 CmdAgentSelector 中。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - appKey: 应用键,包含应用名称、级别、选择器和选项。
|
||||
// - cmds: 命令列表,键为命令名称,值为 CmdInfo。
|
||||
func (a *CmdAgentSelector) AddCmdSet(appKey AppKey, cmds CmdList) {
|
||||
|
||||
for cmdName, cmd := range cmds {
|
||||
// 确保所有必要的map已初始化
|
||||
if a.cmdTable == nil {
|
||||
a.cmdTable = make(map[CmdLabel]map[CmdSetLabel]struct{})
|
||||
}
|
||||
if a.cmdSetTable == nil {
|
||||
a.cmdSetTable = make(map[CmdSetLabel]map[OptionLabel]struct{})
|
||||
}
|
||||
if a.optionTable == nil {
|
||||
a.optionTable = make(map[OptionLabel][]map[SelectorLabel]struct{})
|
||||
}
|
||||
|
||||
// 初始化嵌套map
|
||||
if a.cmdTable[cmdName] == nil {
|
||||
a.cmdTable[cmdName] = make(map[CmdSetLabel]struct{})
|
||||
}
|
||||
if a.cmdSetTable[appKey.Name] == nil {
|
||||
a.cmdSetTable[appKey.Name] = make(map[OptionLabel]struct{})
|
||||
}
|
||||
if a.optionTable[appKey.Option] == nil {
|
||||
a.optionTable[appKey.Option] = make([]map[SelectorLabel]struct{}, 4)
|
||||
}
|
||||
if a.optionTable[appKey.Option][appKey.Level] == nil {
|
||||
a.optionTable[appKey.Option][appKey.Level] = make(map[SelectorLabel]struct{})
|
||||
}
|
||||
|
||||
// 确保Selector层级的map已初始化
|
||||
if a.Selectors[appKey.Level] == nil {
|
||||
a.Selectors[appKey.Level] = make(map[SelectorLabel]Selector)
|
||||
}
|
||||
if a.Selectors[appKey.Level][appKey.Selector].Options == nil {
|
||||
selector := a.Selectors[appKey.Level][appKey.Selector]
|
||||
selector.Options = make(map[OptionLabel]Option)
|
||||
a.Selectors[appKey.Level][appKey.Selector] = selector
|
||||
}
|
||||
if a.Selectors[appKey.Level][appKey.Selector].Options[appKey.Option].CmdSets == nil {
|
||||
selector := a.Selectors[appKey.Level][appKey.Selector]
|
||||
option := selector.Options[appKey.Option]
|
||||
option.CmdSets = make(map[CmdSetLabel]CmdSet)
|
||||
selector.Options[appKey.Option] = option
|
||||
a.Selectors[appKey.Level][appKey.Selector] = selector
|
||||
}
|
||||
if a.Selectors[appKey.Level][appKey.Selector].Options[appKey.Option].CmdSets[appKey.Name].Cmds == nil {
|
||||
selector := a.Selectors[appKey.Level][appKey.Selector]
|
||||
option := selector.Options[appKey.Option]
|
||||
cmdSet := option.CmdSets[appKey.Name]
|
||||
cmdSet.Cmds = make(map[CmdLabel]CmdInfo)
|
||||
option.CmdSets[appKey.Name] = cmdSet
|
||||
selector.Options[appKey.Option] = option
|
||||
a.Selectors[appKey.Level][appKey.Selector] = selector
|
||||
}
|
||||
a.cmdTable[cmdName][appKey.Name] = struct{}{}
|
||||
a.cmdSetTable[appKey.Name][appKey.Option] = struct{}{}
|
||||
a.optionTable[appKey.Option][appKey.Level][appKey.Selector] = struct{}{}
|
||||
a.Selectors[appKey.Level][appKey.Selector].Options[appKey.Option].CmdSets[appKey.Name].Cmds[cmdName] = CmdInfo{
|
||||
Cmd: cmd,
|
||||
Enabled: true,
|
||||
}
|
||||
LOG.Debug("add cmd: %s, app: %s, option: %s, cmdSet: %s", cmdName, appKey.Name, appKey.Option, appKey.Selector)
|
||||
}
|
||||
a.Selectors[appKey.Level][appKey.Selector].Options[appKey.Option].CmdSets[appKey.Name] = CmdSet{
|
||||
Name: appKey.Name,
|
||||
Cmds: a.Selectors[appKey.Level][appKey.Selector].Options[appKey.Option].CmdSets[appKey.Name].Cmds,
|
||||
Enabled: true,
|
||||
}
|
||||
if a.Selectors[appKey.Level][appKey.Selector].currentOption == "" {
|
||||
a.Selectors[appKey.Level][appKey.Selector] = Selector{
|
||||
Level: appKey.Level,
|
||||
Name: appKey.Selector,
|
||||
Options: a.Selectors[appKey.Level][appKey.Selector].Options,
|
||||
currentOption: appKey.Option,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FindCmd 根据命令名称和是否只查找启用的命令,查找符合条件的命令。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - cmdName: 要查找的命令名称。
|
||||
// - onlyEnabled: 是否只查找启用的命令。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - result: 找到的命令列表(越靠前的优先级越高)。
|
||||
// - count: 找到的命令数量。
|
||||
func (a *CmdAgentSelector) FindCmd(cmdName string, onlyEnabled bool) (result []Cmd, count int) {
|
||||
result = make([]Cmd, 0)
|
||||
count = 0
|
||||
cmdSets := a.cmdTable[cmdName]
|
||||
for cmdSet := range cmdSets {
|
||||
options := a.cmdSetTable[cmdSet]
|
||||
for option := range options {
|
||||
selectors := a.optionTable[option]
|
||||
for i := 0; i < len(a.Selectors); i++ {
|
||||
for selector := range selectors[i] {
|
||||
if option != a.Selectors[i][selector].currentOption && onlyEnabled {
|
||||
continue
|
||||
}
|
||||
cmdInfo := a.Selectors[i][selector].Options[option].CmdSets[cmdSet].Cmds[cmdName]
|
||||
if onlyEnabled && !cmdInfo.Enabled {
|
||||
continue
|
||||
}
|
||||
result = append(result, cmdInfo.Cmd)
|
||||
count++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return result, count
|
||||
}
|
||||
|
||||
// FindCmdSet 根据命令集名称和是否只查找启用的命令集,查找符合条件的命令集。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - cmdSetName: 要查找的命令集名称。
|
||||
// - onlyEnabled: 是否只查找启用的命令集。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - result: 找到的命令集列表(越靠前的优先级越高)。
|
||||
// - count: 找到的命令集数量。
|
||||
func (a *CmdAgentSelector) FindCmdSet(cmdSetName string, onlyEnabled bool) (result []CmdSet, count int) {
|
||||
result = make([]CmdSet, 0)
|
||||
count = 0
|
||||
options := a.cmdSetTable[cmdSetName]
|
||||
for option := range options {
|
||||
selectors := a.optionTable[option]
|
||||
for i := 0; i < len(a.Selectors); i++ {
|
||||
for selector := range selectors[i] {
|
||||
if option != a.Selectors[i][selector].currentOption && onlyEnabled {
|
||||
continue
|
||||
}
|
||||
cmdSet := a.Selectors[i][selector].Options[option].CmdSets[cmdSetName]
|
||||
result = append(result, cmdSet)
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, count
|
||||
}
|
||||
|
||||
// FindOption 根据选项名称,查找符合条件的选项。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - optionName: 要查找的选项名称。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - result: 找到的选项列表(越靠前的优先级越高)。
|
||||
// - count: 找到的选项数量。
|
||||
func (a *CmdAgentSelector) FindOption(optionName string) (result []Option, count int) {
|
||||
result = make([]Option, 0)
|
||||
count = 0
|
||||
selectors := a.optionTable[optionName]
|
||||
for i := 0; i < len(a.Selectors); i++ {
|
||||
for selector := range selectors[i] {
|
||||
if optionName != a.Selectors[i][selector].currentOption {
|
||||
continue
|
||||
}
|
||||
option := a.Selectors[i][selector].Options[optionName]
|
||||
result = append(result, option)
|
||||
count++
|
||||
}
|
||||
}
|
||||
return result, count
|
||||
}
|
||||
|
||||
// FindSelector 根据选择器名称,查找符合条件的选择器。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - selectorName: 要查找的选择器名称。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - result: 找到的选择器列表(越靠前的优先级越高)。
|
||||
// - count: 找到的选择器数量。
|
||||
func (a *CmdAgentSelector) FindSelector(selectorName string) (result []Selector, count int) {
|
||||
result = make([]Selector, 0)
|
||||
count = 0
|
||||
selectors := a.optionTable[selectorName]
|
||||
for i := 0; i < len(a.Selectors); i++ {
|
||||
for selector := range selectors[i] {
|
||||
if selectorName != a.Selectors[i][selector].currentOption {
|
||||
continue
|
||||
}
|
||||
selector := a.Selectors[i][selector]
|
||||
result = append(result, selector)
|
||||
count++
|
||||
}
|
||||
}
|
||||
return result, count
|
||||
}
|
||||
|
||||
// GetCurrentOption 获取当前选择器的当前选项。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - level: 选择器的级别。
|
||||
// - selectorName: 选择器的名称。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - result: 当前选项,当isExist为false时,此结果为 Option 对应的空值。
|
||||
// - isExist: 是否存在当前选项。
|
||||
func (a *CmdAgentSelector) GetCurrentOption(level int, selectorName string) (result Option, isExist bool) {
|
||||
result, ok := a.Selectors[level][selectorName].Options[a.Selectors[level][selectorName].currentOption]
|
||||
if !ok {
|
||||
return Option{}, false
|
||||
}
|
||||
return result, true
|
||||
}
|
||||
|
||||
// ToggleCmd 切换命令的启用状态。
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - enabled: 要设置的启用状态。
|
||||
// - level: 选择器的级别。
|
||||
// - selectorName: 选择器的名称。
|
||||
// - optionName: 选项的名称。
|
||||
// - cmdSetName: 命令集的名称。
|
||||
// - cmdName: 命令的名称。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - state: 命令的启用状态。
|
||||
// - preState: 命令的之前的启用状态。
|
||||
// - err: 错误信息,当发生错误时返回。
|
||||
func (a *CmdAgentSelector) ToggleCmd(enabled bool, level Priority, selectorName SelectorLabel, optionName OptionLabel, cmdSetName CmdSetLabel, cmdName CmdLabel) (state bool, preState bool, err error) {
|
||||
if level < 0 || level > 3 {
|
||||
return false, false, fmt.Errorf("level must be between 0 and 3")
|
||||
}
|
||||
selector, ok := a.Selectors[level][selectorName]
|
||||
if !ok {
|
||||
return false, false, fmt.Errorf("selector %s not found", selectorName)
|
||||
}
|
||||
option, ok := selector.Options[optionName]
|
||||
if !ok {
|
||||
return false, false, fmt.Errorf("option %s not found", optionName)
|
||||
}
|
||||
cmdSet, ok := option.CmdSets[cmdName]
|
||||
if !ok {
|
||||
return false, false, fmt.Errorf("cmdSet %s not found", cmdName)
|
||||
}
|
||||
cmdInfo, ok := cmdSet.Cmds[cmdName]
|
||||
if !ok {
|
||||
return false, false, fmt.Errorf("cmd %s not found", cmdName)
|
||||
}
|
||||
preState = cmdInfo.Enabled
|
||||
cmdInfo.Enabled = enabled
|
||||
a.Selectors[level][selectorName].Options[optionName].CmdSets[cmdSetName].Cmds[cmdName] = cmdInfo
|
||||
return enabled, preState, nil
|
||||
}
|
@ -2,8 +2,6 @@ package wba
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type WindStandardTools interface {
|
||||
@ -11,63 +9,54 @@ type WindStandardTools interface {
|
||||
//
|
||||
// 参数:
|
||||
//
|
||||
// - message: 要解析的消息字符串。
|
||||
// - message: 要解析的消息JSON字符串。
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// - msg: 解析后的消息结构体。
|
||||
MsgUnmarshal(message string) (msg MessageEventInfo)
|
||||
|
||||
// LogWith 使用指定日志级别记录日志,支持可变参数占位符。
|
||||
//
|
||||
// 参数:
|
||||
// - level: 日志级别: "trace", "debug", "info", "notice", "warn", "error"。
|
||||
// - log: 日志内容。
|
||||
// - args: 可变参数,用于格式化日志内容。
|
||||
// - level: 日志级别: "trace", "debug", "info", "notice", "warn", "error"。
|
||||
// - log: 日志内容。
|
||||
// - args: 可变参数,用于格式化日志内容。
|
||||
LogWith(level string, log string, args ...interface{})
|
||||
|
||||
// Log 记录日志,级别为 "info",支持可变参数占位符。
|
||||
//
|
||||
// 参数:
|
||||
// - log: 日志内容。
|
||||
// - args: 可变参数,用于格式化日志内容。
|
||||
// - log: 日志内容。
|
||||
// - args: 可变参数,用于格式化日志内容。
|
||||
Log(log string, args ...interface{})
|
||||
|
||||
// VersionLabelAnalysis 解析版本标签为 VersionInfo 结构体。
|
||||
//
|
||||
// 参数:
|
||||
// - versionLabel: 版本标签字符串,格式为 "大版本.小版本.修复版本"。
|
||||
// 返回值:
|
||||
// - versionInfo: 解析后的版本信息结构体。
|
||||
VersionLabelAnalysis(versionLabel VersionLabel) (versionInfo VersionInfo)
|
||||
|
||||
// VersionCompare 比较两个版本标签的大小。
|
||||
//
|
||||
// 参数:
|
||||
// - version1: 第一个版本标签字符串。
|
||||
// - version2: 第二个版本标签字符串。
|
||||
// 返回值:
|
||||
// - result: 比较结果,-1表示version1小于version2,0表示version1等于version2,1表示version1大于version2。
|
||||
VersionCompare(version1, version2 VersionLabel) (result int)
|
||||
|
||||
// SessionLabelAnalysis 解析会话标签为 SessionInfo 结构体。
|
||||
//
|
||||
// 参数:
|
||||
// - sessionLabel: 会话标签字符串,格式为 "平台:会话类型-会话ID"。
|
||||
// 返回值:
|
||||
// - sessionInfo: 解析后的会话信息结构体。
|
||||
SessionLabelAnalysis(sessionLabel SessionLabel) (sessionInfo SessionInfo)
|
||||
}
|
||||
|
||||
func (v VersionInfo) String() string {
|
||||
return fmt.Sprintf("%d.%d.%d", v.BigVersion, v.SmallVersion, v.FixVersion)
|
||||
}
|
||||
|
||||
func VersionLabelAnalysis(versionLabel VersionLabel) VersionInfo {
|
||||
version := strings.Split(versionLabel, ".")
|
||||
bigVersion, err := strconv.ParseUint(version[0], 10, 8)
|
||||
if err != nil {
|
||||
return VersionInfo{}
|
||||
}
|
||||
smallVersion, err := strconv.ParseUint(version[1], 10, 8)
|
||||
if err != nil {
|
||||
return VersionInfo{}
|
||||
}
|
||||
fixVersion, err := strconv.ParseUint(version[2], 10, 8)
|
||||
if err != nil {
|
||||
return VersionInfo{}
|
||||
}
|
||||
return VersionInfo{
|
||||
BigVersion: uint8(bigVersion),
|
||||
SmallVersion: uint8(smallVersion),
|
||||
FixVersion: uint8(fixVersion),
|
||||
}
|
||||
}
|
||||
|
||||
func SessionLabelAnalysis(sessionLabel SessionLabel) SessionInfo {
|
||||
platform := strings.Split(sessionLabel, ":")[0]
|
||||
sessionTypeAndId := strings.Split(sessionLabel, ":")[1]
|
||||
sessionType := strings.Split(sessionTypeAndId, "-")[0]
|
||||
sessionId := strings.Split(sessionTypeAndId, "-")[1]
|
||||
Id, err := strconv.ParseInt(sessionId, 10, 64)
|
||||
if err != nil {
|
||||
return SessionInfo{}
|
||||
}
|
||||
return SessionInfo{
|
||||
Platform: platform,
|
||||
SessionType: sessionType,
|
||||
SessionId: Id,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user