modify:底层接口变动

This commit is contained in:
Sheyiyuan 2025-04-01 01:20:35 +08:00
parent c9d36abe4a
commit 93538afaeb
8 changed files with 409 additions and 200 deletions

View File

@ -5,6 +5,7 @@ import (
"ProjectWIND/database"
"ProjectWIND/wba"
"crypto/rand"
"encoding/json"
"fmt"
"strings"
)
@ -26,6 +27,20 @@ type apiInfo struct{}
//1.无响应API,使用ws协议处理
// UnsafelySendMsg 发送消息(自动判断消息类型)
//
// 注意该API不安全除非你知道你在做什么。
//
// 参数:
//
// - messageType: 消息类型,可选值为 "private" 和 "group
//
// - groupId: 群号当messageType为"group"时必填
//
// - userId: 用户ID当messageType为"private"时必填
//
// - message: 要发送的消息内容,类型为字符串
//
// - autoEscape: 是否自动转义解析消息内容中的CQ码可选值为 true 和 false
func (a *apiInfo) UnsafelySendMsg(messageType string, groupId int64, userId int64, message string, autoEscape bool) {
// 构建发送消息的JSON数据
var messageData wba.APIRequestInfo
@ -59,6 +74,16 @@ func (a *apiInfo) UnsafelySendMsg(messageType string, groupId int64, userId int6
}
// UnsafelySendPrivateMsg 发送私聊消息
//
// 注意该API不安全除非你知道你在做什么。
//
// 参数:
//
// - userId: 用户ID
//
// - message: 要发送的消息内容,类型为字符串
//
// - autoEscape: 是否自动转义解析消息内容中的CQ码可选值为 true 和 false
func (a *apiInfo) UnsafelySendPrivateMsg(userId int64, message string, autoEscape bool) {
// 构建发送消息的JSON数据
var messageData wba.APIRequestInfo
@ -77,6 +102,16 @@ func (a *apiInfo) UnsafelySendPrivateMsg(userId int64, message string, autoEscap
}
// UnsafelySendGroupMsg 发送群消息
//
// 注意该API不安全除非你知道你在做什么。
//
// 参数:
//
// - groupId: 群号
//
// - message: 要发送的消息内容,类型为字符串
//
// - autoEscape: 是否自动转义解析消息内容中的CQ码可选值为 true 和 false
func (a *apiInfo) UnsafelySendGroupMsg(groupId int64, message string, autoEscape bool) {
// 构建发送消息的JSON数据
var messageData wba.APIRequestInfo
@ -95,6 +130,14 @@ func (a *apiInfo) UnsafelySendGroupMsg(groupId int64, message string, autoEscape
}
// SendMsg 回复消息(自动判断消息类型)
//
// 参数:
//
// - msg: 消息事件信息
//
// - message: 要发送的消息内容,类型为字符串
//
// - autoEscape: 是否自动转义解析消息内容中的CQ码可选值为 true 和 false
func (a *apiInfo) SendMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
// 构建发送消息的JSON数据
var messageData wba.APIRequestInfo
@ -131,6 +174,14 @@ func (a *apiInfo) SendMsg(msg wba.MessageEventInfo, message string, autoEscape b
}
// SendPrivateMsg 回复私聊消息
//
// 参数:
//
// - msg: 原始消息事件信息
//
// - message: 要发送的消息内容,类型为字符串
//
// - autoEscape: 是否自动转义,可选值为 true 和 false
func (a *apiInfo) SendPrivateMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
// 构建发送消息的JSON数据
var messageData wba.APIRequestInfo
@ -149,6 +200,14 @@ func (a *apiInfo) SendPrivateMsg(msg wba.MessageEventInfo, message string, autoE
}
// SendGroupMsg 回复群消息
//
// 参数:
//
// - msg: 原始消息事件信息
//
// - message: 要发送的消息内容,类型为字符串
//
// - autoEscape: 是否自动转义,可选值为 true 和 false
func (a *apiInfo) SendGroupMsg(msg wba.MessageEventInfo, message string, autoEscape bool) {
// 构建发送消息的JSON数据
var messageData wba.APIRequestInfo
@ -167,6 +226,12 @@ func (a *apiInfo) SendGroupMsg(msg wba.MessageEventInfo, message string, autoEsc
}
// UnsafelyDeleteMsg 撤回消息
//
// 注意该API不安全除非你知道你在做什么。
//
// 参数:
//
// - messageId: 要撤回的消息ID
func (a *apiInfo) UnsafelyDeleteMsg(messageId int32) {
// 构建删除消息的JSON数据
var messageData wba.APIRequestInfo
@ -182,6 +247,10 @@ func (a *apiInfo) UnsafelyDeleteMsg(messageId int32) {
}
// DeleteMsg 撤回消息
//
// 参数:
//
// - msg: 原始消息事件信息
func (a *apiInfo) DeleteMsg(msg wba.MessageEventInfo) {
// 构建删除消息的JSON数据
var messageData wba.APIRequestInfo
@ -197,6 +266,12 @@ func (a *apiInfo) DeleteMsg(msg wba.MessageEventInfo) {
}
// SendLike 发送赞
//
// 参数:
//
// - userId: 要赞的用户ID
//
// - times: 赞的次数
func (a *apiInfo) SendLike(userId int64, times int) {
// 构建发送赞的JSON数据
var messageData wba.APIRequestInfo
@ -213,6 +288,14 @@ func (a *apiInfo) SendLike(userId int64, times int) {
}
// SetGroupKick 将指定用户移出群聊(需要群主或管理员权限)
//
// 参数:
//
// - groupId: 群号
//
// - userId: 用户ID
//
// - rejectAddRequest: 是否拒绝该用户的后续加群请求,可选值为 true 和 false
func (a *apiInfo) SetGroupKick(groupId int64, userId int64, rejectAddRequest bool) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_kick"
@ -229,6 +312,14 @@ func (a *apiInfo) SetGroupKick(groupId int64, userId int64, rejectAddRequest boo
}
// SetGroupBan 将指定用户禁言(需要群主或管理员权限)
//
// 参数:
//
// - groupId: 群号
//
// - userId: 用户ID
//
// - duration: 禁言时长单位为秒0表示取消禁言
func (a *apiInfo) SetGroupBan(groupId int64, userId int64, duration int32) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_ban"
@ -245,6 +336,12 @@ func (a *apiInfo) SetGroupBan(groupId int64, userId int64, duration int32) {
}
// SetGroupWholeBan 设置全员禁言(需要群主或管理员权限)
//
// 参数:
//
// - groupId: 群号
//
// - enable: 是否启用全员禁言,可选值为 true 和 false
func (a *apiInfo) SetGroupWholeBan(groupId int64, enable bool) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_whole_ban"
@ -260,6 +357,14 @@ func (a *apiInfo) SetGroupWholeBan(groupId int64, enable bool) {
}
// SetGroupAdmin 设置群管理员(需要群主权限)
//
// 参数:
//
// - groupId: 群号
//
// - userId: 用户ID
//
// - enable: 是否设置为管理员,可选值为 true 和 false
func (a *apiInfo) SetGroupAdmin(groupId int64, userId int64, enable bool) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_admin"
@ -275,7 +380,15 @@ func (a *apiInfo) SetGroupAdmin(groupId int64, userId int64, enable bool) {
return
}
// SetGroupCard 设置群名片(需要群主或管理员权限)
// SetGroupCard 设置群名片(可能需要群主或管理员权限)
//
// 参数:
//
// - groupId: 群号
//
// - userId: 用户ID
//
// - card: 新的群名片
func (a *apiInfo) SetGroupCard(groupId int64, userId int64, card string) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_card"
@ -292,6 +405,12 @@ func (a *apiInfo) SetGroupCard(groupId int64, userId int64, card string) {
}
// SetGroupName 设置群名称(可能需要群主或管理员权限)
//
// 参数:
//
// - groupId: 群号
//
// - groupName: 新的群名称
func (a *apiInfo) SetGroupName(groupId int64, groupName string) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_name"
@ -307,6 +426,12 @@ func (a *apiInfo) SetGroupName(groupId int64, groupName string) {
}
// SetGroupLeave 退出群聊
//
// 参数:
//
// - groupId: 群号
//
// - isDismiss: 是否解散群聊,仅当退出的是群主时有效,可选值为 true 和 false
func (a *apiInfo) SetGroupLeave(groupId int64, isDismiss bool) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_leave"
@ -322,6 +447,14 @@ func (a *apiInfo) SetGroupLeave(groupId int64, isDismiss bool) {
}
// SetGroupSpecialTitle 设置群专属头衔(需要群主权限)
//
// 参数:
//
// - groupId: 群号
//
// - userId: 用户ID
//
// - specialTitle: 新的专属头衔
func (a *apiInfo) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_special_title"
@ -339,6 +472,14 @@ func (a *apiInfo) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle
}
// SetFriendAddRequest 处理加好友请求
//
// 参数:
//
// - flag: 请求标识,由上报的事件中获得
//
// - approve: 是否同意请求,可选值为 true 和 false
//
// - remark: 设置好友的备注信息
func (a *apiInfo) SetFriendAddRequest(flag string, approve bool, remark string) {
var messageData wba.APIRequestInfo
messageData.Action = "set_friend_add_request"
@ -355,6 +496,16 @@ func (a *apiInfo) SetFriendAddRequest(flag string, approve bool, remark string)
}
// SetGroupAddRequest 处理加群请求/邀请
//
// 参数:
//
// - flag: 请求标识,由上报的事件中获得
//
// - subType: 子类型,可能是 "invite" 或 "add", 由上报的事件中获得
//
// - approve: 是否同意请求,可选值为 true 和 false
//
// - reason: 拒绝请求的原因,仅当 approve 为 false 时有效
func (a *apiInfo) SetGroupAddRequest(flag string, subType string, approve bool, reason string) {
var messageData wba.APIRequestInfo
messageData.Action = "set_group_add_request"
@ -398,7 +549,7 @@ func (a *apiInfo) CleanCache() {
return
}
// 2.有响应API需添加echo字段
// 2.有响应API需添加echo字段,统一返回响应结构体
// GetLoginInfo 获取登录信息
func (a *apiInfo) GetLoginInfo() (Response wba.APIResponseInfo) {
@ -783,13 +934,22 @@ func (a *apiInfo) GetStatus() (Response wba.APIResponseInfo) {
/*
关于LOG模块的说明
1.日志模块使用go-logging库日志级别分为DEBUGInfoWarnError
1.日志模块级别分为TRACEDEBUGINFONOTICEWARNERROR五个级别默认级别为INFO
2.日志模块提供LogWith方法可以自定义日志级别调用级别为DEBUG时会打印输出调用者的文件名函数名行号
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 {
@ -814,22 +974,42 @@ func (a *apiInfo) LogWith(level string, content string, args ...interface{}) {
}
}
// 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.Name, datamap, unit, id, key, value)
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.Name, "user", id, key, value)
dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
}
func (dbi *databaseInfo) SetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
@ -840,7 +1020,7 @@ func (dbi *databaseInfo) SetGroupVariable(app wba.AppInfo, msg wba.MessageEventI
if msg.MessageType == "private" {
id = "user_" + fmt.Sprintf("%d", msg.UserId)
}
dbi.varSet(app, app.Name, "group", id, key, value)
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) {
@ -860,15 +1040,15 @@ func (dbi *databaseInfo) SetOutGroupVariable(app wba.AppInfo, datamap string, ms
}
func (dbi *databaseInfo) UnsafelySetUserVariable(app wba.AppInfo, id string, key string, value string) {
dbi.varSet(app, app.Name, "user", id, key, value)
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.Name, "group", id, key, value)
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.Name, "global", id, key, value)
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) {
@ -884,7 +1064,7 @@ func (dbi *databaseInfo) UnsafelySetOutGlobalVariable(app wba.AppInfo, datamap s
}
func (dbi *databaseInfo) varGet(app wba.AppInfo, datamap string, unit string, id string, key string) (string, bool) {
res, ok := database.Get(app.Name, datamap, unit, id, key, false)
res, ok := database.Get(app.AppKey.Name, datamap, unit, id, key, false)
if !ok {
return "", false
}
@ -897,7 +1077,7 @@ func (dbi *databaseInfo) varGet(app wba.AppInfo, datamap string, unit string, id
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.Name, "user", id, key)
return dbi.varGet(app, app.AppKey.Name, "user", id, key)
}
func (dbi *databaseInfo) GetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (string, bool) {
@ -908,7 +1088,7 @@ func (dbi *databaseInfo) GetGroupVariable(app wba.AppInfo, msg wba.MessageEventI
if msg.MessageType == "private" {
id = "user_" + fmt.Sprintf("%d", msg.UserId)
}
return dbi.varGet(app, app.Name, "group", id, key)
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) {
@ -928,15 +1108,15 @@ func (dbi *databaseInfo) GetOutGroupVariable(app wba.AppInfo, datamap string, ms
}
func (dbi *databaseInfo) UnsafelyGetUserVariable(app wba.AppInfo, id string, key string) (string, bool) {
return dbi.varGet(app, app.Name, "user", id, key)
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.Name, "group", id, key)
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.Name, "global", id, key)
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) {
@ -952,7 +1132,7 @@ func (dbi *databaseInfo) UnsafelyGetOutGlobalVariable(app wba.AppInfo, datamap s
}
func (dbi *databaseInfo) GetIntConfig(app wba.AppInfo, datamap string, key string) (int64, bool) {
res, ok := database.Get(app.Name, datamap, "config", "number", key, true)
res, ok := database.Get(app.AppKey.Name, datamap, "config", "number", key, true)
if !ok {
return 0, false
}
@ -964,7 +1144,7 @@ func (dbi *databaseInfo) GetIntConfig(app wba.AppInfo, datamap string, key strin
}
func (dbi *databaseInfo) GetStringConfig(app wba.AppInfo, datamap string, key string) (string, bool) {
res, ok := database.Get(app.Name, datamap, "config", "string", key, true)
res, ok := database.Get(app.AppKey.Name, datamap, "config", "string", key, true)
if !ok {
return "", false
}
@ -976,7 +1156,7 @@ func (dbi *databaseInfo) GetStringConfig(app wba.AppInfo, datamap string, key st
}
func (dbi *databaseInfo) GetFloatConfig(app wba.AppInfo, datamap string, key string) (float64, bool) {
res, ok := database.Get(app.Name, datamap, "config", "float", key, true)
res, ok := database.Get(app.AppKey.Name, datamap, "config", "float", key, true)
if !ok {
return 0, false
}
@ -988,7 +1168,7 @@ func (dbi *databaseInfo) GetFloatConfig(app wba.AppInfo, datamap string, key str
}
func (dbi *databaseInfo) GetIntSliceConfig(app wba.AppInfo, datamap string, key string) ([]int64, bool) {
res, ok := database.Get(app.Name, datamap, "config", "number_slice", key, true)
res, ok := database.Get(app.AppKey.Name, datamap, "config", "number_slice", key, true)
if !ok {
return nil, false
}
@ -1000,7 +1180,7 @@ func (dbi *databaseInfo) GetIntSliceConfig(app wba.AppInfo, datamap string, key
}
func (dbi *databaseInfo) GetStringSliceConfig(app wba.AppInfo, datamap string, key string) ([]string, bool) {
res, ok := database.Get(app.Name, datamap, "config", "string_slice", key, true)
res, ok := database.Get(app.AppKey.Name, datamap, "config", "string_slice", key, true)
if !ok {
return nil, false
}
@ -1012,7 +1192,7 @@ func (dbi *databaseInfo) GetStringSliceConfig(app wba.AppInfo, datamap string, k
}
func (dbi *databaseInfo) UnsafelyCreatePublicDatamap(app wba.AppInfo, datamapId string) {
appName := app.Name
appName := app.AppKey.Name
database.CreatePublicDatamap(appName, datamapId)
}

View File

@ -2,7 +2,6 @@ package core
import (
"ProjectWIND/LOG"
"ProjectWIND/typed"
"ProjectWIND/wba"
"os"
"path/filepath"
@ -12,12 +11,13 @@ import (
)
var CmdMap = make([]map[string]wba.Cmd, 4)
var AppMap = make(map[typed.AppKey]wba.AppInfo)
var AppMap = make(map[wba.AppKey]wba.AppInfo)
// ReloadApps 重新加载应用
func ReloadApps() (total int, success int) {
// 清空AppMap和CmdMap
CmdMap = make([]map[string]wba.Cmd, 4)
AppMap = make(map[typed.AppKey]wba.AppInfo)
AppMap = make(map[wba.AppKey]wba.AppInfo)
appsDir := "./data/app/"
appFiles, err := os.ReadDir(appsDir)
total = 0
@ -36,6 +36,7 @@ func ReloadApps() (total int, success int) {
return total, success
}
// reloadAPP 重新加载单个应用
func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta int) {
if file.IsDir() {
return 0, 0
@ -61,6 +62,7 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
wbaObj := 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)
@ -73,6 +75,8 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
_ = 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)
@ -113,8 +117,12 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
_ = wsp.Set("CanSendRecord", AppApi.CanSendRecord)
_ = wsp.Set("SetRestart", AppApi.SetRestart)
_ = wsp.Set("CleanCache", AppApi.CleanCache)
_ = wsp.Set("GetLoginInfo", AppApi.LogWith)
_ = 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)
@ -196,14 +204,14 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
return 1, 0
}
AppMap[typed.AppKey{AppName: appInfo.Name, AppType: appInfo.AppType, AppVersion: appInfo.Version, AppLevel: checkAppLevel(appInfo)}] = appInfo
cmdIndex := AppTypeToInt(appInfo.AppType)
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)
// 注册定时任务
for _, task := range appInfo.ScheduledTasks {
RegisterCron(appInfo.Name, task)
RegisterCron(appInfo.AppKey.Name, task)
}
LOG.Info("JS应用 %s 加载成功", pluginPath)

View File

@ -2,9 +2,12 @@ package core
import (
"ProjectWIND/LOG"
"ProjectWIND/database"
"ProjectWIND/typed"
"ProjectWIND/wba"
"encoding/json"
"fmt"
"strconv"
"strings"
)
@ -16,17 +19,8 @@ func HandleMessage(msgJson []byte) {
}
// 处理消息
LOG.Info("收到消息:(来自:%v-%v:%v-%v)%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, msg.RawMessage)
cmd, args := CmdSplit(msg)
for _, cmdList := range CmdMap {
_, ok := cmdList[cmd]
if ok {
LOG.Debug("执行命令:%v %v", cmd, args)
cmdList[cmd].Solve(args, msg)
break
}
}
// TODO: 处理消息内容
CmdHandle(msg)
fmt.Printf("%#v\n", msg.Message)
}
func HandleNotice(msgJson []byte) {
@ -57,35 +51,101 @@ func HandleMetaEvent(msgJson []byte) {
}
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, " ")
}
}
}
}
}
//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 statusCheck(msg wba.MessageEventInfo) bool {
//TODO: 检查当前组群工作状态
return false
func CmdHandle(msg wba.MessageEventInfo) {
// 获取消息的原始文本
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))
}
}
// 调用 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)
}
}
}
} else {
// 如果未找到有效的命令,记录未找到命令的信息
LOG.Info("未找到命令:%v", strings.Split(text, " ")[0])
}
}
var cmdPrefix = []string{"/", "!", "", "", ".", "。"}

View File

@ -10,11 +10,10 @@ import (
)
func WebServer(port string) *server.Hertz {
// 创建自定义日志记录器实例
customLogger := &LOG.CustomLogger{}
// 设置自定义日志记录器
hlog.SetLogger(customLogger)
hlog.SetLevel(hlog.LevelFatal)
h := server.Default(server.WithHostPorts("0.0.0.0:" + port))
LOG.Info("WebUI已启动监听端口%v", port)
h.Use(LoggingMiddleware())
h.GET("/index", func(ctx context.Context, c *app.RequestContext) {
//返回webui/index.html
@ -41,6 +40,6 @@ func LoggingMiddleware() app.HandlerFunc {
// 获取请求处理状态码
statusCode := ctx.Response.StatusCode()
// 在请求处理后记录结束信息
hlog.Debugf("收到网络请求 | IP: %s | Path: %s | Status: %d ", clientIP, fullPath, statusCode)
LOG.Debug("收到网络请求 | IP: %s | Path: %s | Status: %d ", clientIP, fullPath, statusCode)
}
}

View File

@ -4,6 +4,7 @@ import (
"ProjectWIND/LOG"
"encoding/json"
"errors"
"fmt"
"os"
"os/signal"
"path/filepath"
@ -155,7 +156,7 @@ func getCorePassword() string {
return ""
}
config := make(map[string]string)
err = json.Unmarshal([]byte(dataJson), config)
err = json.Unmarshal([]byte(dataJson), &config)
if err != nil {
LOG.Error("[Error]Error while unmarshal data: %v", err)
return ""
@ -467,6 +468,7 @@ func Start() {
select {
case <-dataChan:
// 接收到信号,保存数据并退出程序
fmt.Println("")
LOG.Info("Received signal, saving data and exiting...")
saveData(DB)
os.Exit(0)
@ -588,79 +590,3 @@ func Set(appName string, datamap string, unit string, id string, key string, val
}
dataSet(appName, unit, id, key, value, true, false)
}
// func VarSet(app wba.AppInfo, datamap string, unit string, id string, key string, value string) {
// Set(app.Name, datamap, unit, id, key, value)
// }
// func VarGet(app wba.AppInfo, datamap string, unit string, id string, key string) (string, bool) {
// res, ok := Get(app.Name, datamap, unit, id, key, false)
// if !ok {
// return "", false
// }
// resStr, ok := res.(string)
// if !ok {
// return "", false
// }
// return resStr, true
// }
// func GetIntConfig(app wba.AppInfo, datamap string, key string) (int64, bool) {
// res, ok := Get(app.Name, datamap, "config", "number", key, true)
// if !ok {
// return 0, false
// }
// resInt, ok := res.(int64)
// if !ok {
// return 0, false
// }
// return resInt, true
// }
// func GetStringConfig(app wba.AppInfo, datamap string, key string) (string, bool) {
// res, ok := Get(app.Name, datamap, "config", "string", key, true)
// if !ok {
// return "", false
// }
// resStr, ok := res.(string)
// if !ok {
// return "", false
// }
// return resStr, true
// }
// func GetFloatConfig(app wba.AppInfo, datamap string, key string) (float64, bool) {
// res, ok := Get(app.Name, datamap, "config", "float", key, true)
// if !ok {
// return 0, false
// }
// resFloat, ok := res.(float64)
// if !ok {
// return 0, false
// }
// return resFloat, true
// }
// func GetIntSliceConfig(app wba.AppInfo, datamap string, key string) ([]int64, bool) {
// res, ok := Get(app.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 GetStringSliceConfig(app wba.AppInfo, datamap string, key string) ([]string, bool) {
// res, ok := Get(app.Name, datamap, "config", "string_slice", key, true)
// if !ok {
// return nil, false
// }
// resSlice, ok := res.([]string)
// if !ok {
// return nil, false
// }
// return resSlice, true
// }

View File

@ -1,5 +1,7 @@
package typed
import "ProjectWIND/wba"
type CoreConfigInfo struct {
CoreName string `json:"core_name"`
Protocol Protocol `json:"protocol"`
@ -16,19 +18,11 @@ type Protocol struct {
Enable bool `json:"enable"`
}
type AppKey struct {
AppName string `json:"app_name"`
AppType string `json:"app_type"`
AppLevel int32 `json:"app_level"`
AppVersion string `json:"app_version"`
}
type SessionWorkSpace struct {
SessionId string `json:"session_id"`
SessionType string `json:"session_type"`
Rule string `json:"rule"`
Enable bool `json:"enable"`
AppEnable map[AppKey]bool `json:"app_enable"`
CmdEnable map[string]bool `json:"cmd_enable"`
WorkLevel int32 `json:"work_level"`
SessionId string `json:"session_id"`
Rule string `json:"rule"`
Enable bool `json:"enable"`
AppEnable map[wba.AppKey]bool `json:"app_enable"`
CmdEnable map[string]bool `json:"cmd_enable"`
WorkLevel int32 `json:"work_level"`
}

5
wba/tool.go Normal file
View File

@ -0,0 +1,5 @@
package wba
type WindStandardTools interface {
MsgUnmarshal(message string) (msg MessageEventInfo)
}

View File

@ -1,13 +1,14 @@
package wba
import (
"encoding/json"
"fmt"
)
type APP interface {
Get() AppInfo
Init(api WindStandardProtocolAPI) error
InitWSD(api WindStandardDataBaseAPI) error
//Init(api WindStandardProtocolAPI) error
//InitWSD(api WindStandardDataBaseAPI) error
}
// WindStandardProtocolAPI Wind标准协议API,提供了onebot11标准中的API接口。
@ -477,7 +478,7 @@ type WindStandardDataBaseAPI interface {
// 返回: 配置值,是否存在。
GetStringSliceConfig(app AppInfo, datamap string, key string) ([]string, bool)
// CreatePublicDatamap [不安全][需要master权限]创建公共数据表
// UnsafelyCreatePublicDatamap [不安全][需要master权限]创建公共数据表
// 参数:
// - app: 应用信息。
// - datamapId: 数据表名称。
@ -485,15 +486,11 @@ type WindStandardDataBaseAPI interface {
}
type AppInfo struct {
Name string
Version string
AppKey AppKey
Author string
Description string
Namespace string
Homepage string
License string
AppType string
Rule string
CmdMap map[string]Cmd
MessageEventHandler func(msg MessageEventInfo)
NoticeEventHandler func(msg NoticeEventInfo)
@ -533,13 +530,13 @@ type AppInfoOption func(ei *AppInfo)
func WithName(name string) AppInfoOption {
return func(ei *AppInfo) {
ei.Name = name
ei.AppKey.Name = name
}
}
func WithVersion(version string) AppInfoOption {
return func(ei *AppInfo) {
ei.Version = version
ei.AppKey.Version = version
}
}
@ -569,26 +566,28 @@ func WithLicense(license string) AppInfoOption {
func WithAppType(appType string) AppInfoOption {
return func(ei *AppInfo) {
ei.AppType = appType
ei.AppKey.Type = appType
}
}
func WithRule(rule string) AppInfoOption {
return func(ei *AppInfo) {
ei.Rule = fmt.Sprintf("rule_%s", rule)
ei.AppKey.Rule = fmt.Sprintf("rule_%s", rule)
}
}
func NewApp(opts ...AppInfoOption) AppInfo {
Ext := AppInfo{
Name: "WSP",
Version: "v1.0.0",
Author: "WSP",
AppKey: AppKey{
Name: "WSP",
Version: "v1.0.0",
Type: "fun",
Rule: "none",
},
Author: "WIND",
Description: "A simple and easy-to-use bot framework",
Homepage: "https://github.com/Sheyiyuan/wind_app_model",
License: "MIT",
AppType: "fun",
Rule: "none",
CmdMap: make(map[string]Cmd),
ScheduledTasks: map[string]ScheduledTaskInfo{},
API: map[string]interface{}{},
@ -601,10 +600,10 @@ func NewApp(opts ...AppInfoOption) AppInfo {
func (ai *AppInfo) NewCmd(name string, description string, solve func(args []string, msg MessageEventInfo)) Cmd {
return Cmd{
Name: name,
Desc: description,
Solve: solve,
Rule: ai.Rule,
Name: name,
Desc: description,
Solve: solve,
AppKey: ai.AppKey,
}
}
@ -618,10 +617,10 @@ func (ai *AppInfo) NewScheduledTask(name string, description string, cron string
}
type Cmd struct {
Name string
Desc string
Solve func(args []string, msg MessageEventInfo)
Rule string
Name string
Desc string
Solve func(args []string, msg MessageEventInfo)
AppKey AppKey
}
type MessageEventInfo struct {
@ -709,20 +708,22 @@ type MessageInfo struct {
}
type MessageDataInfo struct {
Type string `json:"type,omitempty"`
Text string `json:"text,omitempty"`
Id string `json:"id,omitempty"`
File string `json:"file,omitempty"`
Url string `json:"url,omitempty"`
Magic string `json:"magic,omitempty"`
Qq string `json:"qq,omitempty"`
Title string `json:"title,omitempty"`
Content string `json:"content,omitempty"`
Image string `json:"image,omitempty"`
Audio string `json:"audio,omitempty"`
Lat string `json:"lat,omitempty"`
Lon string `json:"lon,omitempty"`
Data string `json:"data,omitempty"`
Type string `json:"type,omitempty"`
Text string `json:"text,omitempty"`
Id string `json:"id,omitempty"`
File string `json:"file,omitempty"`
Url string `json:"url,omitempty"`
Magic string `json:"magic,omitempty"`
Qq string `json:"qq,omitempty"`
Title string `json:"title,omitempty"`
Content any `json:"content,omitempty"` // Content string or []MessageDataInfo
Image string `json:"image,omitempty"`
Audio string `json:"audio,omitempty"`
Lat string `json:"lat,omitempty"`
Lon string `json:"lon,omitempty"`
Data string `json:"data,omitempty"`
UserId int64 `json:"user_id,omitempty"`
Nickname string `json:"name,omitempty"`
}
type ParamsInfo struct {
@ -864,3 +865,39 @@ type ScheduledTaskInfo struct {
var WSP WindStandardProtocolAPI
var WSD WindStandardDataBaseAPI
type AppKey struct {
Name string `json:"name"`
Type string `json:"type"`
Level int32 `json:"level"`
Version string `json:"version"`
Rule string `json:"rule"`
}
func (msg *MessageEventInfo) GetAt() []string {
var at []string
for _, v := range msg.Message {
if v.Type == "at" {
at = append(at, v.Data.Qq)
}
}
return at
}
func (msg *MessageEventInfo) GetText() string {
var text string
for _, v := range msg.Message {
if v.Type == "text" {
text += v.Data.Text
}
}
return text
}
func (msg *MessageEventInfo) JsonMarshal() string {
jsonData, err := json.Marshal(msg)
if err != nil {
return ""
}
return string(jsonData)
}