Compare commits

...

5 Commits

12 changed files with 567 additions and 437 deletions

4
.gitignore vendored
View File

@ -3,4 +3,6 @@ data/
**/.DS_Store
.idea/
.vscode/
ProjectWIND
ProjectWIND
ProjectWIND.exe
*/*abandoned*

View File

@ -9,7 +9,22 @@ import (
"runtime"
)
var logLevel = 2
func SetLogLevel(level int) {
if level < 0 {
level = 0
}
if level > 5 {
level = 5
}
logLevel = level
}
func Trace(text string, msg ...interface{}) {
if logLevel > 0 {
return
}
var pc uintptr
var file string
var line int
@ -27,25 +42,40 @@ func Trace(text string, msg ...interface{}) {
}
func Debug(text string, msg ...interface{}) {
if logLevel > 1 {
return
}
log.Printf("[Debug] %s\n", fmt.Sprintf(text, msg...))
}
func Info(text string, msg ...interface{}) {
if logLevel > 2 {
return
}
msgText := fmt.Sprintf(text, msg...)
log.Println("[Info] ", msgText)
}
func Notice(text string, msg ...interface{}) {
if logLevel > 3 {
return
}
msgText := fmt.Sprintf(text, msg...)
log.Println("[Notice]", msgText)
}
func Warn(text string, msg ...interface{}) {
if logLevel > 4 {
return
}
msgText := fmt.Sprintf(text, msg...)
log.Println("[Warn] ", msgText)
}
func Error(text string, msg ...interface{}) {
if logLevel > 5 {
return
}
msgText := fmt.Sprintf(text, msg...)
log.Println("[Error] ", msgText)
}

View File

@ -6,21 +6,26 @@ import (
"fmt"
)
//database模块
// //数据库部分允许字符串变量的读写操作,允许读取配置项操作
// 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) varSet(app wba.AppInfo, datamap string, unit string, id string, key string, value string) (errno database.Errno) {
return database.Set(app.AppKey.Name, datamap, unit, id, key, value)
}
func (dbi *databaseInfo) SetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
func (dbi *databaseInfo) SetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) (isSuccess bool) {
id := fmt.Sprintf("%d", msg.UserId)
dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
eno := dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
func (dbi *databaseInfo) SetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) {
func (dbi *databaseInfo) SetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string, value string) (isSuccess bool) {
var id string
if msg.MessageType == "group" {
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
@ -28,15 +33,25 @@ 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.AppKey.Name, "group", id, key, value)
eno := dbi.varSet(app, app.AppKey.Name, "group", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
func (dbi *databaseInfo) SetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) {
func (dbi *databaseInfo) SetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) (isSuccess bool) {
id := fmt.Sprintf("%d", msg.UserId)
dbi.varSet(app, datamap, "user", id, key, value)
eno := dbi.varSet(app, datamap, "user", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
func (dbi *databaseInfo) SetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) {
func (dbi *databaseInfo) SetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string, value string) (isSuccess bool) {
var id string
if msg.MessageType == "group" {
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
@ -44,51 +59,91 @@ func (dbi *databaseInfo) SetOutGroupVariable(app wba.AppInfo, datamap string, ms
if msg.MessageType == "private" {
id = "user_" + fmt.Sprintf("%d", msg.UserId)
}
dbi.varSet(app, datamap, "group", id, key, value)
eno := dbi.varSet(app, datamap, "group", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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) UnsafelySetUserVariable(app wba.AppInfo, id string, key string, value string) (isSuccess bool) {
eno := dbi.varSet(app, app.AppKey.Name, "user", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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) UnsafelySetGroupVariable(app wba.AppInfo, id string, key string, value string) (isSuccess bool) {
eno := dbi.varSet(app, app.AppKey.Name, "group", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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) UnsafelySetGlobalVariable(app wba.AppInfo, id string, key string, value string) (isSuccess bool) {
eno := dbi.varSet(app, app.AppKey.Name, "global", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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) UnsafelySetOutUserVariable(app wba.AppInfo, datamap string, id string, key string, value string) (isSuccess bool) {
eno := dbi.varSet(app, datamap, "user", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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) UnsafelySetOutGroupVariable(app wba.AppInfo, datamap string, id string, key string, value string) (isSuccess bool) {
eno := dbi.varSet(app, datamap, "group", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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) UnsafelySetOutGlobalVariable(app wba.AppInfo, datamap string, id string, key string, value string) (isSuccess bool) {
eno := dbi.varSet(app, datamap, "global", id, key, value)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
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
func (dbi *databaseInfo) varGet(app wba.AppInfo, datamap string, unit string, id string, key string) (value string, errno database.Errno) {
res, eno := database.Get(app.AppKey.Name, datamap, unit, id, key, false)
if eno.Code != 0 {
return "", eno
}
resStr, ok := res.(string)
if !ok {
return "", database.Errno{Code: 303, Condition: "获取数据时类型断言错误"}
}
return resStr, eno
}
func (dbi *databaseInfo) GetUserVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (value string, isSuccess bool) {
id := fmt.Sprintf("%d", msg.UserId)
res, eno := dbi.varGet(app, app.AppKey.Name, "user", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return resStr, true
return res, 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) {
func (dbi *databaseInfo) GetGroupVariable(app wba.AppInfo, msg wba.MessageEventInfo, key string) (vaule string, isSuccess bool) {
var id string
if msg.MessageType == "group" {
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
@ -96,15 +151,25 @@ 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.AppKey.Name, "group", id, key)
res, eno := dbi.varGet(app, app.AppKey.Name, "group", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
func (dbi *databaseInfo) GetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (string, bool) {
func (dbi *databaseInfo) GetOutUserVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (vaule string, isSuccess bool) {
id := fmt.Sprintf("%d", msg.UserId)
return dbi.varGet(app, datamap, "user", id, key)
res, eno := dbi.varGet(app, datamap, "user", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
func (dbi *databaseInfo) GetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (string, bool) {
func (dbi *databaseInfo) GetOutGroupVariable(app wba.AppInfo, datamap string, msg wba.MessageEventInfo, key string) (vaule string, isSuccess bool) {
var id string
if msg.MessageType == "group" {
id = "group_" + fmt.Sprintf("%d", msg.GroupId)
@ -112,96 +177,150 @@ func (dbi *databaseInfo) GetOutGroupVariable(app wba.AppInfo, datamap string, ms
if msg.MessageType == "private" {
id = "user_" + fmt.Sprintf("%d", msg.UserId)
}
return dbi.varGet(app, datamap, "group", id, key)
res, eno := dbi.varGet(app, datamap, "group", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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) UnsafelyGetUserVariable(app wba.AppInfo, id string, key string) (vaule string, isSuccess bool) {
res, eno := dbi.varGet(app, app.AppKey.Name, "user", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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) UnsafelyGetGroupVariable(app wba.AppInfo, id string, key string) (vaule string, isSuccess bool) {
res, eno := dbi.varGet(app, app.AppKey.Name, "group", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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) UnsafelyGetGlobalVariable(app wba.AppInfo, id string, key string) (vaule string, isSuccess bool) {
res, eno := dbi.varGet(app, app.AppKey.Name, "global", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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) UnsafelyGetOutUserVariable(app wba.AppInfo, datamap string, id string, key string) (vaule string, isSuccess bool) {
res, eno := dbi.varGet(app, datamap, "user", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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) UnsafelyGetOutGroupVariable(app wba.AppInfo, datamap string, id string, key string) (vaule string, isSuccess bool) {
res, eno := dbi.varGet(app, datamap, "group", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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) UnsafelyGetOutGlobalVariable(app wba.AppInfo, datamap string, id string, key string) (vaule string, isSuccess bool) {
res, eno := dbi.varGet(app, datamap, "global", id, key)
if eno.Code != 0 {
eno.Log()
return "", false
}
return res, true
}
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 {
func (dbi *databaseInfo) GetIntConfig(app wba.AppInfo, datamap string, key string) (value int64, isSuccess bool) {
res, eno := database.Get(app.AppKey.Name, datamap, "config", "number", key, true)
if eno.Code != 0 {
return 0, false
}
resInt, ok := res.(int64)
if !ok {
eno = database.Errno{Code: 303, Condition: "获取配置时类型断言错误"}
eno.Log()
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 {
func (dbi *databaseInfo) GetStringConfig(app wba.AppInfo, datamap string, key string) (value string, isSuccess bool) {
res, eno := database.Get(app.AppKey.Name, datamap, "config", "string", key, true)
if eno.Code != 0 {
eno.Log()
return "", false
}
resStr, ok := res.(string)
if !ok {
eno := database.Errno{Code: 303, Condition: "获取配置时类型断言错误"}
eno.Log()
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 {
func (dbi *databaseInfo) GetFloatConfig(app wba.AppInfo, datamap string, key string) (value float64, isSuccess bool) {
res, eno := database.Get(app.AppKey.Name, datamap, "config", "float", key, true)
if eno.Code != 0 {
eno.Log()
return 0, false
}
resFloat, ok := res.(float64)
if !ok {
eno := database.Errno{Code: 303, Condition: "获取配置时类型断言错误"}
eno.Log()
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 {
func (dbi *databaseInfo) GetIntSliceConfig(app wba.AppInfo, datamap string, key string) (value []int64, isSuccess bool) {
res, eno := database.Get(app.AppKey.Name, datamap, "config", "number_slice", key, true)
if eno.Code != 0 {
eno.Log()
return nil, false
}
resSlice, ok := res.([]int64)
if !ok {
eno := database.Errno{Code: 303, Condition: "获取配置时类型断言错误"}
eno.Log()
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 {
func (dbi *databaseInfo) GetStringSliceConfig(app wba.AppInfo, datamap string, key string) (value []string, isSuccess bool) {
res, eno := database.Get(app.AppKey.Name, datamap, "config", "string_slice", key, true)
if eno.Code != 0 {
eno.Log()
return nil, false
}
resSlice, ok := res.([]string)
if !ok {
eno := database.Errno{Code: 303, Condition: "获取配置时类型断言错误"}
eno.Log()
return nil, false
}
return resSlice, true
}
func (dbi *databaseInfo) UnsafelyCreatePublicDatamap(app wba.AppInfo, datamapId string) {
func (dbi *databaseInfo) UnsafelyCreatePublicDatamap(app wba.AppInfo, datamapId string) (isSuccess bool) {
appName := app.AppKey.Name
database.CreatePublicDatamap(appName, datamapId)
eno := database.CreatePublicDatamap(appName, datamapId)
if eno.Code != 0 {
eno.Log()
return false
}
return true
}
var DatabaseApi databaseInfo

View File

@ -3,13 +3,42 @@ package core
import (
"ProjectWIND/LOG"
"ProjectWIND/wba"
"fmt"
"github.com/dop251/goja"
"os"
"path/filepath"
"reflect"
"strings"
"sync"
)
var runtimePool = sync.Pool{
New: func() interface{} {
rt := goja.New()
rt.SetFieldNameMapper(CamelCaseFieldNameMapper{})
_ = rt.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...)
},
})
// 创建JS可用的wbaObj对象
windObj := rt.NewObject()
_ = rt.Set("wind", windObj)
_ = windObj.Set("newApp", wba.NewApp)
_ = windObj.Set("withName", wba.WithSelector)
_ = windObj.Set("withDescription", wba.WithDescription)
_ = windObj.Set("withWebUrl", wba.WithWebUrl)
_ = windObj.Set("withLicense", wba.WithLicense)
_ = rt.Set("wsp", ProtocolApi)
_ = rt.Set("wsd", DatabaseApi)
_ = rt.Set("wst", ToolsApi)
return rt
},
}
type CamelCaseFieldNameMapper struct{}
func (CamelCaseFieldNameMapper) FieldName(_ reflect.Type, f reflect.StructField) string {
@ -76,16 +105,12 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
return 1, 0
}
runtime := goja.New()
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...)
},
})
runtime := runtimePool.Get().(*goja.Runtime)
defer runtimePool.Put(runtime)
// 重置runtime状态
runtime.ClearInterrupt()
runtime.SetRandSource(nil)
// 添加错误捕获
safeRun := func(fn func() error) {
@ -105,150 +130,37 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i
return err
})
// 创建JS可用的wbaObj对象
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.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)
// 获取app对象
var jsApp goja.Value
func() {
defer func() {
if r := recover(); r != nil {
LOG.Error("获取app对象时发生panic: %v", r)
}
}()
jsApp = runtime.Get("app")
}()
// 获取AppInit函数
appInitVal := runtime.Get("AppInit")
if appInitVal == nil || goja.IsUndefined(appInitVal) {
LOG.Error("应用 %s 缺少AppInit函数", pluginPath)
return 1, 0
}
appInitFunc, ok := goja.AssertFunction(appInitVal)
if !ok {
LOG.Error("应用 %s 的AppInit不是有效函数", pluginPath)
if jsApp == nil || goja.IsUndefined(jsApp) {
LOG.Error("应用 %s 缺少app对象", pluginPath)
return 1, 0
}
// 调用AppInit获取应用实例
jsApp, err := appInitFunc(goja.Undefined())
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(jsApp, &appInfo); err != nil {
err = func() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("应用信息转换时发生panic: %v", r)
}
}()
return runtime.ExportTo(jsApp, &appInfo)
}()
if err != nil {
LOG.Error("应用信息转换失败: %v", err)
return 1, 0
}
// 初始化map字段
if appInfo.CmdMap == nil {
appInfo.CmdMap = make(map[string]wba.Cmd)

View File

@ -29,22 +29,25 @@ func (app *AppInfo) GetCmd() map[string]wba.Cmd {
return app.CmdMap
}
func NewCmd(name string, help string, solve func(args []string, msg wba.MessageEventInfo)) wba.Cmd {
func NewCmd(name string, help string, solve func(args []string, msg wba.MessageEventInfo), appKey wba.AppKey) wba.Cmd {
return wba.Cmd{
Name: name,
Desc: help,
Solve: solve,
Name: name,
Desc: help,
Solve: solve,
AppKey: appKey,
}
}
var AppKeyOfCore = wba.AppKey{
Name: "core",
Level: 0,
Version: "1.0.0",
Selector: "core",
Option: "core",
}
var AppCore = AppInfo{
AppKey: wba.AppKey{
Name: "core",
Level: 0,
Version: "1.0.0",
Selector: "core",
Option: "core",
},
AppKey: AppKeyOfCore,
CmdMap: CmdListInfo{
"bot": NewCmd(
"bot",
@ -53,6 +56,7 @@ var AppCore = AppInfo{
ProtocolApi.SendMsg(msg, "WIND 0.1.0", false)
LOG.Info("发送核心版本信息:(至:%v-%v:%v-%v)", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname)
},
AppKeyOfCore,
),
"help": NewCmd(
"help",
@ -61,6 +65,7 @@ var AppCore = AppInfo{
ProtocolApi.SendMsg(msg, "帮助信息", false)
LOG.Info("发送帮助信息:(至:%v-%v:%v-%v)", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname)
},
AppKeyOfCore,
),
},
}

View File

@ -45,4 +45,10 @@ type Cmmand struct {
App AppKey
Solve func(*wba.Context)
}
```
```
## 原理说明
在每次接收指令时,核心会从核心表中的配置数据根据当前工作会话获取相关配置,若为空时,使用默认配置。
配置会设置每个选择器的选项及其子元素的禁用状态。也就是说所有指令集将以默认开启的状态被加载。

View File

@ -3,7 +3,7 @@ package database
import (
"ProjectWIND/LOG"
"encoding/json"
"errors"
"fmt"
"os"
"os/signal"
"path/filepath"
@ -14,6 +14,11 @@ import (
const address = "./data/database/datamaps.wdb"
const core = "./data/core.json"
type Errno struct {
Code int
Condition string
}
type unit struct {
Id string
Data map[string]string
@ -45,6 +50,24 @@ type Database struct {
Datamaps map[string]Datamap
}
func (eno *Errno) Log() {
// 记录错误日志
switch eno.Code / 100 {
case 1:
LOG.Fatal(eno.Condition)
case 2:
LOG.Error(eno.Condition)
case 3:
LOG.Warn(eno.Condition)
case 4:
LOG.Info(eno.Condition)
case 5:
LOG.Notice(eno.Condition)
case 6:
LOG.Debug(eno.Condition)
}
}
func newDatamap(id string) Datamap {
// 创建数据表
db := &Datamap{
@ -73,124 +96,120 @@ func newDatabase() Database {
return *db
}
func (this *Database) addDatamap(id string) {
func (dbh *Database) addDatamap(id string) {
// 创建新数据表
db := newDatamap(id)
this.Datamaps[id] = db
dbh.Datamaps[id] = db
}
func folderCheck(filename string) {
func folderCheck(filename string) (Error Errno) {
if _, err := os.Stat(filename); os.IsNotExist(err) {
err := os.MkdirAll(filename, 0755)
if err != nil {
LOG.Fatal("创建文件夹时出错: %v", err)
return Errno{101, fmt.Sprintf("创建文件夹时出错:%v", err)}
}
}
return Errno{0, ""}
}
func fileCheck(filename string) {
func fileCheck(filename string) (Error Errno) {
// 检查并创建文件
dir := filepath.Dir(filename)
folderCheck(dir)
eno := Errno{0, ""}
if _, err := os.Stat(filename); os.IsNotExist(err) {
file, err := os.Create(filename)
if err != nil {
LOG.Fatal("创建文件时出错: %v", err)
return Errno{101, fmt.Sprintf("创建文件时出错: %v", err)}
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
LOG.Fatal("创建文件时出错: %v", err)
eno = Errno{302, fmt.Sprintf("关闭文件时出错: %v", err)}
}
}(file)
}
return eno
}
func writeContent(f *os.File, str string) error {
func writeContent(f *os.File, str string) (errno Errno) {
// 写入内容到文件
if f == nil {
// log.Printf("[Error]file is nil")
LOG.Error("文件不存在")
return errors.New("file is nil")
return Errno{101, "文件不存在"}
}
_, err := f.Write([]byte(str))
if err != nil {
LOG.Error("无法写入到文件: %v", err)
return err
return Errno{101, fmt.Sprintf("无法写入到文件: %v", err)}
}
return nil
return Errno{0, ""}
}
func printContent(file string) (string, error) {
func printContent(file string) (text string, errno Errno) {
// 读取文件内容
bytes, err := os.ReadFile(file)
if err == nil {
return string(bytes), nil
return string(bytes), Errno{0, ""}
} else {
return "", err
return "", Errno{101, fmt.Sprintf("读取文件时出错: %v", err)}
}
}
func getCorePassword() string {
func getCorePassword() (pass string, errno Errno) {
// 获取核心密码
filename := core
fileCheck(filename)
dataJson, err := printContent(filename)
if err != nil {
LOG.Error("读取文件时出错 %s: %v", filename, err)
return ""
if err.Code != 0 {
return "", Errno{101, fmt.Sprintf("读取文件时出错 %s: %v", filename, err)}
}
config := make(map[string]string)
err = json.Unmarshal([]byte(dataJson), config)
if err != nil {
LOG.Error("反序列化时出错: %v", err)
return ""
err2 := json.Unmarshal([]byte(dataJson), config)
if err2 != nil {
return "", Errno{201, fmt.Sprintf("反序列化时出错: %v", err2)}
}
password, ok := config["password"]
if !ok {
LOG.Warn("core.json中未找到配置密码项")
return ""
return "", Errno{601, "core.json中未找到配置密码项"}
}
return password
return password, Errno{0, ""}
}
func saveData(db *Database) error {
func saveData(db *Database) (errno Errno) {
// 保存数据到文件
dataJson, err := json.Marshal(db)
if err != nil {
LOG.Error("序列化数据时出错: %v", err)
return err
return Errno{201, fmt.Sprintf("序列化数据时出错: %v", err)}
}
filename := address
file, err := os.Create(filename)
if err != nil {
LOG.Error("创建文件时出错 %s: %v", filename, err)
return err
return Errno{101, fmt.Sprintf("创建文件时出错 %s: %v", filename, err)}
}
writeContent(file, string(dataJson))
return nil
err2 := writeContent(file, string(dataJson))
if err2.Code != 0 {
return err2
}
return Errno{0, ""}
}
func loadData(db *Database) error {
func loadData(db *Database) (errno Errno) {
// 读取配置文件
filename := address
fileCheck(filename)
dataJson, err := printContent(filename)
if err != nil {
LOG.Error("读文件时出错 %s: %v", filename, err)
if err.Code != 0 {
return err
}
err = json.Unmarshal([]byte(dataJson), db)
if err != nil {
LOG.Warn("反序列化数据时出错: %v", err)
return err
err2 := json.Unmarshal([]byte(dataJson), db)
if err2 != nil {
return Errno{201, fmt.Sprintf("反序列化数据时出错: %v", err2)}
}
return nil
return Errno{0, ""}
}
var DB *Database
func dataSet(datamap string, unit string, id string, key string, value interface{}, isAllowed bool, isMaster bool) {
func dataSet(datamap string, unit string, id string, key string, value interface{}, isAllowed bool, isMaster bool) (errno Errno) {
// 修改数据
dm, ok := DB.Datamaps[datamap]
if !ok {
@ -199,66 +218,57 @@ func dataSet(datamap string, unit string, id string, key string, value interface
dm = DB.Datamaps[datamap]
}
if !isAllowed && !isMaster && dm.Permission != "private" {
LOG.Warn("访问权限不足")
return
return Errno{301, "访问权限不足"}
}
if !isMaster && dm.Permission == "master" {
LOG.Warn("访问权限不足")
return
return Errno{301, "访问权限不足"}
}
switch unit {
case "config":
switch id {
case "number":
valueInt64, ok := value.(int64) // 断言value为int64类型
valueInt64, ok := value.(int64)
if !ok {
LOG.Error("配置值无法被断言为int64类型")
return
return Errno{303, "设置的配置值无法被断言为int64类型"}
}
dm.Configs.Number[key] = valueInt64 // 使用断言后的int64值
dm.Configs.Number[key] = valueInt64
case "string":
valueStr, ok := value.(string) // 断言value为string类型
valueStr, ok := value.(string)
if !ok {
LOG.Error("配置值无法被断言为string类型")
return
return Errno{303, "设置的配置值无法被断言为string类型"}
}
dm.Configs.String[key] = valueStr // 使用断言后的string值
dm.Configs.String[key] = valueStr
case "float":
valueFloat64, ok := value.(float64) // 断言value为float64类型
valueFloat64, ok := value.(float64)
if !ok {
LOG.Error("配置值无法被断言为float64类型")
return
return Errno{303, "设置的配置值无法被断言为float64类型"}
}
dm.Configs.Float[key] = valueFloat64 // 使用断言后的float64值
dm.Configs.Float[key] = valueFloat64
case "number_slice":
valueInt64Slice, ok := value.([]int64) // 断言value为[]int64类型
valueInt64Slice, ok := value.([]int64)
if !ok {
LOG.Error("配置值无法被断言为[]int64类型")
return
return Errno{303, "设置的配置值无法被断言为[]int64类型"}
}
dm.Configs.Number_Slice[key] = valueInt64Slice // 使用断言后的[]int64值
dm.Configs.Number_Slice[key] = valueInt64Slice
case "string_slice":
valueStrSlice, ok := value.([]string) // 断言value为[]string类型
valueStrSlice, ok := value.([]string)
if !ok {
LOG.Error("配置值无法被断言为[]string类型")
return
return Errno{303, "设置的配置值无法被断言为[]string类型"}
}
dm.Configs.String_Slice[key] = valueStrSlice // 使用断言后的[]string值
dm.Configs.String_Slice[key] = valueStrSlice
case "hash":
valueStr, ok := value.(string) // 断言value为string类型
valueStr, ok := value.(string)
if !ok {
LOG.Error("配置值无法被断言为string类型")
return
return Errno{303, "设置的配置值无法被断言为string类型"}
}
dm.Configs.Hash = valueStr // 使用断言后的string值
dm.Configs.Hash = valueStr
default:
LOG.Error("不合法的配置项类型 %s", id)
return Errno{304, "不合法的配置项类型"}
}
case "user":
valueStr, ok := value.(string) // 断言value为string类型
valueStr, ok := value.(string)
if !ok {
LOG.Error("变量值无法被断言为string类型")
return
return Errno{303, "变量值无法被断言为string类型"}
}
user, ok := dm.Users[id]
if !ok {
@ -271,12 +281,11 @@ func dataSet(datamap string, unit string, id string, key string, value interface
if user.Data == nil {
user.Data = make(map[string]string)
}
user.Data[key] = valueStr // 使用断言后的string值
user.Data[key] = valueStr
case "group":
valueStr, ok := value.(string) // 断言value为string类型
valueStr, ok := value.(string)
if !ok {
LOG.Error("变量值无法被断言为string类型")
return
return Errno{303, "变量值无法被断言为string类型"}
}
group, ok := dm.Groups[id]
if !ok {
@ -289,12 +298,11 @@ func dataSet(datamap string, unit string, id string, key string, value interface
if group.Data == nil {
group.Data = make(map[string]string)
}
group.Data[key] = valueStr // 使用断言后的string值
group.Data[key] = valueStr
case "global":
valueStr, ok := value.(string) // 断言value为string类型
valueStr, ok := value.(string)
if !ok {
LOG.Error("变量值无法被断言为string类型")
return
return Errno{303, "变量值无法被断言为string类型"}
}
global, ok := dm.Global[id]
if !ok {
@ -309,23 +317,21 @@ func dataSet(datamap string, unit string, id string, key string, value interface
}
global.Data[key] = valueStr // 使用断言后的string值
default:
LOG.Error("不合法的数据单元 %s", unit)
return Errno{304, "不合法的数据单元"}
}
return Errno{0, ""}
}
func dataGet(datamap string, unit string, id string, key string, isAllowed bool, isMaster bool) (interface{}, bool) {
func dataGet(datamap string, unit string, id string, key string, isAllowed bool, isMaster bool) (res interface{}, errno Errno) {
dm, ok := DB.Datamaps[datamap]
if !ok {
LOG.Warn("数据表不存在 %s", datamap)
return "", false
return "", Errno{601, fmt.Sprintf("数据表 %s 不存在", datamap)}
}
if !isAllowed && !isMaster && dm.Permission != "private" {
LOG.Warn("访问权限不足")
return "", false
return "", Errno{301, "访问权限不足"}
}
if !isMaster && dm.Permission == "master" {
LOG.Warn("访问权限不足")
return "", false
return "", Errno{301, "访问权限不足"}
}
switch unit {
case "config":
@ -333,95 +339,79 @@ func dataGet(datamap string, unit string, id string, key string, isAllowed bool,
case "number":
value, ok := dm.Configs.Number[key]
if !ok {
LOG.Warn("配置项不存在%s", key)
return 0, false
return 0, Errno{601, fmt.Sprintf("配置项不存在%s", key)}
}
return value, true
return value, Errno{0, ""}
case "string":
value, ok := dm.Configs.String[key]
if !ok {
LOG.Warn("配置项不存在%s", key)
return "", false
return "", Errno{601, fmt.Sprintf("配置项不存在%s", key)}
}
return value, true
return value, Errno{0, ""}
case "float":
value, ok := dm.Configs.Float[key]
if !ok {
LOG.Warn("配置项不存在%s", key)
return 0.0, false
return 0.0, Errno{601, fmt.Sprintf("配置项不存在%s", key)}
}
return value, true
return value, Errno{0, ""}
case "number_slice":
value, ok := dm.Configs.Number_Slice[key]
if !ok {
LOG.Warn("配置项不存在%s", key)
return []int64{}, false
return []int64{}, Errno{601, fmt.Sprintf("配置项不存在%s", key)}
}
return value, true
return value, Errno{0, ""}
case "string_slice":
value, ok := dm.Configs.String_Slice[key]
if !ok {
LOG.Warn("配置项不存在%s", key)
return []string{}, false
return []string{}, Errno{601, fmt.Sprintf("配置项不存在%s", key)}
}
return value, true
return value, Errno{0, ""}
case "hash":
return dm.Configs.Hash, true
return dm.Configs.Hash, Errno{0, ""}
default:
LOG.Error("不合法的配置项类型 %s", id)
return "", false
return "", Errno{304, "不合法的配置项类型"}
}
case "user":
user, ok := dm.Users[id]
if !ok {
LOG.Warn("用户 %s 不存在", id)
return "", false
return "", Errno{601, fmt.Sprintf("用户 %s 不存在", id)}
}
if user.Data == nil {
LOG.Warn("用户 %s 的数据显示为nil", id)
return "", false
return "", Errno{601, fmt.Sprintf("用户 %s 的数据显示为nil", id)}
}
value, ok := user.Data[key]
if !ok {
LOG.Warn("用户 %s 的数据中键 %s 不存在", id, key)
return "", false
return "", Errno{601, fmt.Sprintf("用户 %s 的数据中键 %s 不存在", id, key)}
}
return value, true
return value, Errno{0, ""}
case "group":
group, ok := dm.Groups[id]
if !ok {
LOG.Warn("群组 %s 的数据不存在", id)
return "", false
return "", Errno{601, fmt.Sprintf("群组 %s 不存在", id)}
}
if group.Data == nil {
LOG.Warn("群组 %s 的数据显示为nil", id)
return "", false
return "", Errno{601, fmt.Sprintf("群组 %s 的数据显示为nil", id)}
}
value, ok := group.Data[key]
if !ok {
LOG.Warn("群组 %s 的数据中键 %s 不存在", id, key)
return "", false
return "", Errno{601, fmt.Sprintf("群组 %s 的数据中键 %s 不存在", id, key)}
}
return value, true
return value, Errno{0, ""}
case "global":
global, ok := dm.Global[id]
if !ok {
LOG.Warn("全局变量 %s 的数据不存在", id)
return "", false
return "", Errno{601, fmt.Sprintf("全局变量 %s 不存在", id)}
}
if global.Data == nil {
LOG.Warn("全局变量 %s 的数据显示为nil", id)
return "", false
return "", Errno{601, fmt.Sprintf("全局变量 %s 的数据显示为nil", id)}
}
value, ok := global.Data[key]
if !ok {
LOG.Warn("全局变量 %s 的数据中键 %s 不存在", id, key)
return "", false
return "", Errno{601, fmt.Sprintf("全局变量 %s 的数据中键 %s 不存在", id, key)}
}
return value, true
return value, Errno{0, ""}
default:
LOG.Error("Invalid unit %s", unit)
return "", false
return "", Errno{304, "不合法的数据单元"}
}
}
@ -462,25 +452,38 @@ func Start() {
}
}()
select {} // 阻塞
select {}
}
func CreatePublicDatamap(appName string, id string) {
// 修改数据表权限(核心)
func MasterSetDatamapPermission(datamap string, premission string) {
db, ok := DB.Datamaps[datamap]
if !ok {
eno := Errno{601, fmt.Sprintf("数据表 %s 不存在", datamap)}
eno.Log()
return
}
db.Permission = premission
DB.Datamaps[datamap] = db
}
func CreatePublicDatamap(appName string, id string) (errno Errno) {
// 查询权限
hash := getCorePassword()
hash, eno := getCorePassword()
if eno.Code != 0 {
return eno
}
if hash == "" {
// 删除数据表哈希
dataSet(appName, "config", "hash", "", "", true, true)
}
datahash, ok := dataGet(appName, "config", "hash", "", true, true)
if !ok {
// LOG.Error("[Error]:Error while get hash of %s", appName)
LOG.Error("获取应用数据表 %s 的密钥时出错", appName)
return
datahash, eno := dataGet(appName, "config", "hash", "", true, true)
if eno.Code != 0 {
return eno
}
if hash != datahash {
LOG.Warn("应用 %s 没有创建公开数据表的权限", appName)
return
eno := Errno{301, "应用没有创建公开数据表的权限"}
return eno
}
// 创建公开数据表
@ -490,8 +493,10 @@ func CreatePublicDatamap(appName string, id string) {
db.Permission = "public"
DB.Datamaps[id] = db
} else {
LOG.Info("数据表 %s 已经存在", id)
eno := Errno{601, fmt.Sprintf("数据表 %s 已经存在", id)}
return eno
}
return Errno{0, ""}
}
func MasterCreatePublicDatamap(id string) {
@ -502,7 +507,8 @@ func MasterCreatePublicDatamap(id string) {
db.Permission = "master"
DB.Datamaps[id] = db
} else {
LOG.Info("数据表 %s 已经存在", id)
eno := Errno{601, fmt.Sprintf("数据表 %s 已经存在", id)}
eno.Log()
}
}
@ -514,74 +520,104 @@ func MasterCreateMasterDatamap(id string) {
db.Permission = "public"
DB.Datamaps[id] = db
} else {
LOG.Info("数据表 %s 已经存在", id)
eno := Errno{601, fmt.Sprintf("数据表 %s 已经存在", id)}
eno.Log()
}
}
// 修改数据(核心)
func MasterSet(datamap string, unit string, id string, key string, value interface{}) {
dataSet(datamap, unit, id, key, value, true, true)
eno := dataSet(datamap, unit, id, key, value, true, true)
if eno.Code != 0 {
eno.Log()
}
}
// 查询数据(核心)
func MasterGet(datamap string, unit string, id string, key string) (interface{}, bool) {
return dataGet(datamap, unit, id, key, true, true)
val, eno := dataGet(datamap, unit, id, key, true, true)
if eno.Code != 0 {
eno.Log()
return "", false
}
return val, true
}
func Get(appName string, datamap string, unit string, id string, key string, isGettingConfig bool) (interface{}, bool) {
func Get(appName string, datamap string, unit string, id string, key string, isGettingConfig bool) (value interface{}, errno Errno) {
// 查询数据
if unit == "config" && id == "hash" {
// app不允许访问hash数据
LOG.Error("应用 %s 不允许访问数据库密钥", appName)
return "", false
eno := Errno{301, fmt.Sprintf("应用 %s 不允许访问配置项信息", appName)}
eno.Log()
}
if !isGettingConfig && unit == "config" {
// 不允许在非config数据表中访问config数据
LOG.Error("应用 %s 不能在常规读写中访问配置项信息,请使用配置项读取功能", appName)
return "", false
eno := Errno{301, fmt.Sprintf("应用 %s 不能在常规读写中访问配置项信息,请使用配置项读取功能", appName)}
eno.Log()
}
if appName != datamap {
// 需要master密码来访问其他app的数据
hash := getCorePassword()
hash, eno := getCorePassword()
if eno.Code != 0 {
return "", eno
}
if hash == "" {
// 删除数据表哈希
dataSet(appName, "config", "hash", "", "", true, true)
}
datahash, ok := dataGet(appName, "config", "hash", "", true, true)
if !ok {
LOG.Error("获取应用数据表 %s 的密钥时出错", appName)
datahash, eno := dataGet(appName, "config", "hash", "", true, true)
if eno.Code != 0 {
eno.Log()
}
if hash != datahash {
LOG.Warn("应用 %s 未被允许获取数据表 %s 的信息", appName, datamap)
return dataGet(appName, unit, id, key, false, false)
value, eno := dataGet(appName, unit, id, key, false, false)
if eno.Code != 0 {
return value, eno
}
return value, Errno{0, ""}
}
}
return dataGet(appName, unit, id, key, true, true)
value, eno := dataGet(appName, unit, id, key, true, false)
if eno.Code != 0 {
return value, eno
}
return value, Errno{0, ""}
}
func Set(appName string, datamap string, unit string, id string, key string, value interface{}) {
func Set(appName string, datamap string, unit string, id string, key string, value interface{}) (errno Errno) {
// 修改数据
if unit == "config" {
// app不允许修改config数据
LOG.Error("应用 %s 不允许修改配置项信息", appName)
return
return Errno{301, fmt.Sprintf("应用 %s 不允许修改配置项信息", appName)}
}
if appName != datamap {
// 需要master密码来访问其他app的数据
hash := getCorePassword()
hash, eno := getCorePassword()
if eno.Code != 0 {
return eno
}
if hash == "" {
// 删除数据表哈希
dataSet(appName, "config", "hash", "", "", true, true)
eno := dataSet(appName, "config", "hash", "", "", true, true)
if eno.Code != 0 {
return eno
}
}
datahash, ok := dataGet(appName, "config", "hash", "", true, true)
if !ok {
LOG.Error("获取应用数据表 %s 的密钥时出错", appName)
datahash, eno := dataGet(appName, "config", "hash", "", true, true)
if eno.Code != 0 {
return eno
}
if hash != datahash {
LOG.Warn("应用 %s 未被允许修改数据表 %s 的信息", appName, datamap)
dataSet(appName, unit, id, key, value, false, false)
eno := dataSet(appName, unit, id, key, value, false, false)
if eno.Code != 0 {
return eno
}
return Errno{0, ""}
}
}
dataSet(appName, unit, id, key, value, true, false)
eno := dataSet(appName, unit, id, key, value, true, false)
if eno.Code != 0 {
return eno
}
return Errno{0, ""}
}

31
note/design_user_sys.md Normal file
View File

@ -0,0 +1,31 @@
# 用户系统设计
## 文件目录架构
```
wd:data
├── public
│ ├── app
│ │ ├── app1.js
│ │ └── app2.js
│ ├── images
│ │ ├── image1.jpg
│ │ └── image2.jpg
│ ├── files
│ │ ├── file1.txt
│ │ └── file2.txt
│ └── aduio
│ ├── audio1.mp3
│ └── audio2.wav
├── database
│ └── root.db
├── log
│ └── WIND_CORE_20250426114514.log
├── home
│ ├── user A
│ │ ├── coc
│ └── user B
│ ├── dnd
├── config
```

View File

@ -32,7 +32,7 @@ TODO:
- [ ] 配置文件
- [ ] 插件管理
- [x] 基础事件处理
- [ ] 指令管理
- [x] 指令管理
- [ ] 定时任务管理
- [ ] API管理
- [ ] web ui

View File

@ -1,7 +1,5 @@
package typed
import "ProjectWIND/wba"
type CoreConfigInfo struct {
CoreName string `json:"core_name"`
Protocol Protocol `json:"protocol"`
@ -17,12 +15,3 @@ type Protocol struct {
Token string `json:"token"`
Enable bool `json:"enable"`
}
type SessionWorkSpace struct {
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"`
}

View File

@ -93,23 +93,23 @@ 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
}
func (ai *AppInfo) NewCmd(name string, description string, solve func(args []string, msg MessageEventInfo)) Cmd {
//func (ai *AppInfo) NewCmd(name string, description string, solve func(args []string, msg MessageEventInfo)) Cmd {
// return Cmd{
// Name: name,
// Desc: description,
// Solve: solve,
// AppKey: ai.AppKey,
// }
//}
func (ai *AppInfo) NewCmd() Cmd {
return Cmd{
Name: name,
Desc: description,
Solve: solve,
Name: "",
Desc: "",
Solve: nil,
AppKey: ai.AppKey,
}
}

View File

@ -250,7 +250,7 @@ type WindStandardDataBaseAPI interface {
// - msg: 消息事件信息。
// - key: 变量名称。
// - value: 变量值。
SetUserVariable(app AppInfo, msg MessageEventInfo, key string, value string)
SetUserVariable(app AppInfo, msg MessageEventInfo, key string, value string) bool
// SetGroupVariable 设置群组变量
// 参数:
@ -258,7 +258,7 @@ type WindStandardDataBaseAPI interface {
// - msg: 消息事件信息。
// - key: 变量名称。
// - value: 变量值。
SetGroupVariable(app AppInfo, msg MessageEventInfo, key string, value string)
SetGroupVariable(app AppInfo, msg MessageEventInfo, key string, value string) bool
// SetOutUserVariable [需要master权限]设置其他数据库中的用户变量
// 参数:
@ -267,7 +267,7 @@ type WindStandardDataBaseAPI interface {
// - key: 变量名称。
// - value: 变量值。
// - datamap: 数据表名称。
SetOutUserVariable(app AppInfo, datamap string, msg MessageEventInfo, key string, value string)
SetOutUserVariable(app AppInfo, datamap string, msg MessageEventInfo, key string, value string) bool
// SetOutGroupVariable [需要master权限]设置其他数据库中的群组变量
// 参数:
@ -276,7 +276,7 @@ type WindStandardDataBaseAPI interface {
// - key: 变量名称。
// - value: 变量值。
// - datamap: 数据表名称。
SetOutGroupVariable(app AppInfo, datamap string, msg MessageEventInfo, key string, value string)
SetOutGroupVariable(app AppInfo, datamap string, msg MessageEventInfo, key string, value string) bool
// UnsafelySetUserVariable [不安全][需要master权限]设置用户变量
// 参数:
@ -284,7 +284,7 @@ type WindStandardDataBaseAPI interface {
// - id: 数据单元 ID。
// - key: 变量名称。
// - value: 变量值。
UnsafelySetUserVariable(app AppInfo, id string, key string, value string)
UnsafelySetUserVariable(app AppInfo, id string, key string, value string) bool
// UnsafelySetGroupVariable [不安全][需要master权限]设置群组变量
// 参数:
@ -292,7 +292,7 @@ type WindStandardDataBaseAPI interface {
// - id: 数据单元 ID。
// - key: 变量名称。
// - value: 变量值。
UnsafelySetGroupVariable(app AppInfo, id string, key string, value string)
UnsafelySetGroupVariable(app AppInfo, id string, key string, value string) bool
// UnsafelySetGlobalVariable [不安全][需要master权限]设置全局变量
// 参数:
@ -300,7 +300,7 @@ type WindStandardDataBaseAPI interface {
// - id: 数据单元 ID。
// - key: 变量名称。
// - value: 变量值。
UnsafelySetGlobalVariable(app AppInfo, id string, key string, value string)
UnsafelySetGlobalVariable(app AppInfo, id string, key string, value string) bool
// UnsafelySetOutUserVariable [不安全][需要master权限]设置其他数据库中的用户变量
// 参数:
@ -309,7 +309,7 @@ type WindStandardDataBaseAPI interface {
// - key: 变量名称。
// - value: 变量值。
// - datamap: 数据表名称。
UnsafelySetOutUserVariable(app AppInfo, datamap string, id string, key string, value string)
UnsafelySetOutUserVariable(app AppInfo, datamap string, id string, key string, value string) bool
// UnsafelySetOutGroupVariable [不安全][需要master权限]设置其他数据库中的群组变量
// 参数:
@ -318,7 +318,7 @@ type WindStandardDataBaseAPI interface {
// - key: 变量名称。
// - value: 变量值。
// - datamap: 数据表名称。
UnsafelySetOutGroupVariable(app AppInfo, datamap string, id string, key string, value string)
UnsafelySetOutGroupVariable(app AppInfo, datamap string, id string, key string, value string) bool
// UnsafelySetOutGlobalVariable [不安全][需要master权限]设置其他数据库中的全局变量
// 参数:
@ -327,7 +327,7 @@ type WindStandardDataBaseAPI interface {
// - key: 变量名称。
// - value: 变量值。
// - datamap: 数据表名称。
UnsafelySetOutGlobalVariable(app AppInfo, datamap string, id string, key string, value string)
UnsafelySetOutGlobalVariable(app AppInfo, datamap string, id string, key string, value string) bool
// GetUserVariable 获取用户变量
// 参数:
@ -458,5 +458,5 @@ type WindStandardDataBaseAPI interface {
// 参数:
// - app: 应用信息。
// - datamapId: 数据表名称。
UnsafelyCreatePublicDatamap(app AppInfo, datamapId string)
UnsafelyCreatePublicDatamap(app AppInfo, datamapId string) bool
}