diff --git a/adapters/qq/main.go b/adapters/qq/main.go index b38728c..564d07f 100644 --- a/adapters/qq/main.go +++ b/adapters/qq/main.go @@ -240,12 +240,15 @@ func init() { for { _, data, err := ws.ReadMessage() if err != nil { + ws.Close() break } + if debug { logs.Debug("QQ接收消息:", string(data)) } + { res := &GroupList{} json.Unmarshal(data, res) @@ -282,6 +285,7 @@ func init() { if msg.SelfID == msg.UserID { continue } + msg.RawMessage = strings.ReplaceAll(msg.RawMessage, "\\r", "\n") msg.RawMessage = regexp.MustCompile(`[\n\r]+`).ReplaceAllString(msg.RawMessage, "\n") content := msg.RawMessage @@ -297,10 +301,12 @@ func init() { "message_id": fmt.Sprint(msg.MessageID), "content": content, } + if debug { logs.Debug("QQ处理消息:", string(utils.JsonMarshal(_msg))) } - adapter.Receive(msg) + adapter.Receive(_msg) + } }) }() diff --git a/core/node_static.go b/core/node_static.go new file mode 100644 index 0000000..19124a8 --- /dev/null +++ b/core/node_static.go @@ -0,0 +1,52 @@ +package core + +import ( + "io/ioutil" + "net/http" + "os" + "path/filepath" + "sync" + + "github.com/gin-gonic/gin" +) + +var statics sync.Map + +func addStatic(uuid, path string) { + statics.Store(uuid, path) +} + +func remStatic(uuid string) { + statics.Delete(uuid) +} + +func FindFile(c *gin.Context) { + // 获取文件名 + filename := c.Param("filename") + + statics.Range(func(_, value any) bool { + path := value.(string) + // 拼接文件路径 + filepath := filepath.Join(path, filename) + // 判断文件是否存在 + _, err := os.Stat(filepath) + if err == nil { + // 文件存在,读取文件内容并返回 + file, err := ioutil.ReadFile(filepath) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + return true + } + // 根据文件类型设置Content-Type + contentType := http.DetectContentType(file) + c.Header("Content-Type", contentType) + + // 返回文件内容 + c.Data(http.StatusOK, contentType, file) + return false + } + return true + }) + // 如果文件不存在,返回404错误 + c.AbortWithStatus(http.StatusNotFound) +} diff --git a/core/node_temp.go b/core/node_temp.go new file mode 100644 index 0000000..8e1e789 --- /dev/null +++ b/core/node_temp.go @@ -0,0 +1,133 @@ +package core + +import ( + "encoding/json" + "io/ioutil" + "sync" + "time" + + "github.com/cdle/sillyplus/utils" +) + +var temp *PersistentKeyValueStore +var tempPath = utils.GetDataHome() + "temp.json" + +type PersistentKeyValueStore struct { + sync.RWMutex + data map[string]Value +} + +type Value struct { + Data interface{} `json:"data"` + ExpiredAt time.Time `json:"expired_at"` +} + +func NewPersistentKeyValueStore() *PersistentKeyValueStore { + return &PersistentKeyValueStore{ + data: make(map[string]Value), + } +} + +func (s *PersistentKeyValueStore) Set(key string, value interface{}, dur int) error { + s.Lock() + defer s.Unlock() + if dur == 0 { + dur = 86400 + } + expiredAt := time.Now().Add(time.Duration(dur) * time.Second) + s.data[key] = Value{ + Data: value, + ExpiredAt: expiredAt, + } + go func() { + jsonBytes, err := json.Marshal(s.data) + if err == nil { + ioutil.WriteFile(tempPath, jsonBytes, 0644) + } + }() + return nil +} + +func (s *PersistentKeyValueStore) Get(key string) interface{} { + s.RLock() + defer s.RUnlock() + value, ok := s.data[key] + if !ok || time.Now().After(value.ExpiredAt) { + return nil + } + return value.Data +} + +func (s *PersistentKeyValueStore) Delete(key string) error { + s.Lock() + defer s.Unlock() + delete(s.data, key) + // Serialize data to JSON and write to file + jsonBytes, err := json.Marshal(s.data) + if err != nil { + return err + } + err = ioutil.WriteFile(tempPath, jsonBytes, 0644) + if err != nil { + return err + } + return nil +} + +func (s *PersistentKeyValueStore) LoadFromFile() error { + s.Lock() + defer s.Unlock() + + // Read data from file + jsonBytes, err := ioutil.ReadFile(tempPath) + if err != nil { + return err + } + // Deserialize JSON data + err = json.Unmarshal(jsonBytes, &s.data) + if err != nil { + return err + } + // Delete expired data + now := time.Now() + for key, value := range s.data { + if now.After(value.ExpiredAt) { + delete(s.data, key) + } + } + // Serialize data to JSON and write to file + jsonBytes, err = json.Marshal(s.data) + if err != nil { + return err + } + err = ioutil.WriteFile(tempPath, jsonBytes, 0644) + if err != nil { + return err + } + return nil +} + +func init() { + temp = NewPersistentKeyValueStore() + // Load data from file + temp.LoadFromFile() + // if err != nil { + // fmt.Println("Failed to load data from file:", err) + // } + // // Set a key-value pair + // err = store.Set("foo", map[string]interface{}{ + // "bar": "baz", + // }, 1000) + // if err != nil { + // fmt.Println("Failed to set key-value pair:", err) + // } + // // Get a value + // value := store.Get("foo") + // fmt.Println(value) + + // // Delete a key-value pair + // err = store.Delete("foo") + // if err != nil { + // fmt.Println("Failed to delete key-value pair:", err) + // } +} diff --git a/core/plugin_core.go b/core/plugin_core.go index c8fde51..15f247d 100644 --- a/core/plugin_core.go +++ b/core/plugin_core.go @@ -205,6 +205,7 @@ func initPlugins() { CancelPluginWebs(key) CancelPluginlistening(key) CancelHttpListen(key) + remStatic(key) storage.DisableHandle(key) if new != "" { AddCommand([]*common.Function{f}) diff --git a/core/plugin_utils.go b/core/plugin_utils.go index 3280d28..70507c0 100644 --- a/core/plugin_utils.go +++ b/core/plugin_utils.go @@ -262,6 +262,9 @@ func SetPluginMethod(vm *goja.Runtime, uuid string, on_start bool) { }) }) } + o.Set("static", func(path string) { + addStatic(uuid, path) + }) return o }) // registry.RegisterNativeModule("express", func(runtime *goja.Runtime, module *goja.Object) { @@ -410,6 +413,26 @@ func SetPluginMethod(vm *goja.Runtime, uuid string, on_start bool) { } return Script(str) }) + vm.Set("Temp", func(pre string, sec int) interface{} { + return map[string]interface{}{ + "set": func(key string, value interface{}, num int) { + if sec != 0 && num == 0 { + num = sec + } + temp.Set(pre+"_"+key, value, num) + }, + "get": func(key string, def interface{}) interface{} { + v := temp.Get(pre + "_" + key) + if v == nil { + v = def + } + return v + }, + "delete": func(key string) { + temp.Delete(pre + "_" + key) + }, + } + }) } func EncryptPlugin(script string) string { diff --git a/core/web.go b/core/web.go index 089497b..8715729 100644 --- a/core/web.go +++ b/core/web.go @@ -48,6 +48,7 @@ func init() { // Server.Use(gin.Recovery()) Server.Use(Cors()) Server.Use(gzip.Gzip(gzip.DefaultCompression)) + Server.GET("/api/file/:filename", FindFile) Server.NoRoute(func(c *gin.Context) { if c.Request.URL.Path != "/api/web_chat" { logs.Debug(c.Request.URL.Path)