x
This commit is contained in:
+28
-13
@@ -53,6 +53,7 @@ type Factory struct {
|
||||
msgChan chan MsgChan
|
||||
demo *CustomSender
|
||||
reply func(map[string]interface{}) string
|
||||
action func(map[string]interface{}) string
|
||||
lm chan bool
|
||||
nm int64
|
||||
isAdmin func(string) bool
|
||||
@@ -354,6 +355,23 @@ func (f *Factory) SetReplyHandler(function func(map[string]interface{}) string)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Factory) SetActionHandler(function func(map[string]interface{}) string) {
|
||||
f.action = func(m map[string]interface{}) string {
|
||||
if f.uuid != "" {
|
||||
mutex := GetMutex(f.uuid)
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
}
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
pluginConsole(f.uuid).Error("Sender(\""+f.botplt+"\").SetAction error:", err)
|
||||
}
|
||||
}()
|
||||
return function(m)
|
||||
}
|
||||
}
|
||||
|
||||
// func (f *Factory) GetReplies() {
|
||||
|
||||
// }
|
||||
@@ -535,7 +553,7 @@ func (f *Factory) SetIsAdmin(function func(string) bool) {
|
||||
func (f *Factory) Sender2(options map[string]string) *CustomSender {
|
||||
var demo = *f.demo
|
||||
sender := &demo
|
||||
sender.SetID()
|
||||
// sender.SetID()
|
||||
if options != nil {
|
||||
fsp := &common.FakerSenderParams{}
|
||||
if v, ok := options[CONETNT]; ok {
|
||||
@@ -570,8 +588,8 @@ func (f *Factory) Sender() interface{} {
|
||||
func (f *Factory) Receive(props map[string]interface{}) *CustomSender {
|
||||
var demo = *f.demo
|
||||
sender := &demo
|
||||
sender.SetID()
|
||||
console.Log("senderId", sender.GetID())
|
||||
// sender.SetID()
|
||||
// console.Log("senderId", sender.GetID())
|
||||
emf := map[string]interface{}{}
|
||||
for i := range props {
|
||||
h := false
|
||||
@@ -653,6 +671,9 @@ func (sender *CustomSender) GetBotID() string {
|
||||
type PUSH string
|
||||
|
||||
func (sender *CustomSender) Action(options map[string]interface{}) (interface{}, error) {
|
||||
if sender.f.action != nil {
|
||||
return sender.f.action(options), nil
|
||||
}
|
||||
var platform = sender.f.botplt
|
||||
var any *common.Function
|
||||
var one *common.Function
|
||||
@@ -692,6 +713,7 @@ func (sender *CustomSender) Action(options map[string]interface{}) (interface{},
|
||||
vm.Set("action", proxy)
|
||||
vm.Set("adapter", sender.f)
|
||||
})
|
||||
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
@@ -918,16 +940,9 @@ func (sender *CustomSender) GetID() string {
|
||||
return sender.id
|
||||
}
|
||||
|
||||
var test = "4d6371a8-2778-11ee-a3c2-821680fbbf6b"
|
||||
|
||||
func (sender *CustomSender) SetID() {
|
||||
if test != "" {
|
||||
sender.id = test
|
||||
test = ""
|
||||
} else {
|
||||
sender.id = utils.GenUUID()
|
||||
}
|
||||
|
||||
func (sender *CustomSender) SetID() string {
|
||||
sender.id = utils.GenUUID()
|
||||
sender.CreatedAt = time.Now()
|
||||
senders.Store(sender.id, sender)
|
||||
return sender.id
|
||||
}
|
||||
|
||||
+10
-1
@@ -162,6 +162,14 @@ type BaseSender struct {
|
||||
emf map[string]interface{}
|
||||
id string
|
||||
CreatedAt time.Time
|
||||
plugin_id string
|
||||
}
|
||||
|
||||
func (sender *BaseSender) SetPluginID(plugin_id string) {
|
||||
sender.plugin_id = plugin_id
|
||||
}
|
||||
func (sender *BaseSender) GetPluginID() string {
|
||||
return sender.plugin_id
|
||||
}
|
||||
|
||||
func (sender *BaseSender) SetLevel(l int) {
|
||||
@@ -379,10 +387,11 @@ func (sender *BaseSender) GetID() string {
|
||||
return sender.id
|
||||
}
|
||||
|
||||
func (sender *BaseSender) SetID() {
|
||||
func (sender *BaseSender) SetID() string {
|
||||
sender.id = utils.GenUUID()
|
||||
sender.CreatedAt = time.Now()
|
||||
senders.Store(sender.id, sender)
|
||||
return sender.id
|
||||
}
|
||||
|
||||
func (sender *BaseSender) GetTime() time.Time {
|
||||
|
||||
@@ -3,9 +3,11 @@ package common
|
||||
import "time"
|
||||
|
||||
type Sender interface {
|
||||
SetPluginID(string)
|
||||
GetPluginID() string
|
||||
GetID() string
|
||||
GetTime() time.Time
|
||||
SetID()
|
||||
SetID() string
|
||||
GetUserID() string
|
||||
GetChatID() string
|
||||
GetBotID() string
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ func init() {
|
||||
}
|
||||
s := grpc.NewServer()
|
||||
srpc.RegisterSillyGirlServiceServer(s, &SillyGirlService{})
|
||||
log.Printf("grpc server listening at %v", lis.Addr())
|
||||
// log.Printf("grpc server listening at %v", lis.Addr())
|
||||
if err := s.Serve(lis); err != nil {
|
||||
log.Fatalf("failed to serve: %v", err)
|
||||
}
|
||||
|
||||
+34
-10
@@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -13,8 +14,13 @@ import (
|
||||
func (sg *SillyGirlService) AdapterRegist(stream srpc.SillyGirlService_AdapterRegistServer) error {
|
||||
var adapter *Factory
|
||||
var echos sync.Map
|
||||
// defer func() {
|
||||
// fmt.Println("test defer")
|
||||
// }()
|
||||
for {
|
||||
// fmt.Println("test for")
|
||||
req, err := stream.Recv()
|
||||
// fmt.Println("test fored", err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -41,6 +47,24 @@ func (sg *SillyGirlService) AdapterRegist(stream srpc.SillyGirlService_AdapterRe
|
||||
}
|
||||
return ""
|
||||
})
|
||||
adapter.action = func(m map[string]interface{}) string {
|
||||
m["__type__"] = "action"
|
||||
echo := utils.GenUUID()
|
||||
ch := make(chan string)
|
||||
echos.Store(echo, ch)
|
||||
defer echos.Delete(echo)
|
||||
m["echo"] = echo
|
||||
stream.Send(&srpc.Default{
|
||||
Value: string(utils.JsonMarshal(m)),
|
||||
})
|
||||
select {
|
||||
case v := <-ch:
|
||||
return v
|
||||
case <-time.After(time.Second * 5):
|
||||
}
|
||||
return ""
|
||||
}
|
||||
// fmt.Println("test start")
|
||||
} else {
|
||||
echo := req.GetBotId()
|
||||
message_id := req.GetPlatform()
|
||||
@@ -63,7 +87,7 @@ func (sg *SillyGirlService) AdapterReceive(ctx context.Context, req *srpc.Adapte
|
||||
adapter, err := GetAdapter(bot_id, platform)
|
||||
if err == nil {
|
||||
s := adapter.Receive(msgs)
|
||||
return &srpc.Default{Value: s.GetID()}, nil
|
||||
return &srpc.Default{Value: s.SetID()}, nil
|
||||
}
|
||||
return &srpc.Default{Value: ""}, err
|
||||
}
|
||||
@@ -73,17 +97,17 @@ func (sg *SillyGirlService) AdapterPush(ctx context.Context, req *srpc.AdapterRe
|
||||
bot_id := req.GetBotId()
|
||||
platform := req.GetPlatform()
|
||||
json.Unmarshal([]byte(req.Value), &msgs)
|
||||
adapter, err := GetAdapter(bot_id, platform)
|
||||
adapter, err := GetAdapter(platform, bot_id)
|
||||
if err == nil {
|
||||
result := adapter.Push(msgs)
|
||||
message_id := result["message_id"]
|
||||
error := result["error"]
|
||||
if error != "" {
|
||||
return &srpc.Default{Value: ""}, err
|
||||
errst := result["error"]
|
||||
if errst != "" {
|
||||
return &srpc.Default{Value: ""}, errors.New(errst)
|
||||
}
|
||||
return &srpc.Default{Value: message_id}, err
|
||||
return &srpc.Default{Value: message_id}, nil
|
||||
}
|
||||
return &srpc.Default{Value: ""}, err
|
||||
return &srpc.Default{Value: ""}, nil
|
||||
}
|
||||
|
||||
func (sg *SillyGirlService) AdapterSender(ctx context.Context, req *srpc.AdapterRequest) (*srpc.Default, error) {
|
||||
@@ -91,10 +115,10 @@ func (sg *SillyGirlService) AdapterSender(ctx context.Context, req *srpc.Adapter
|
||||
bot_id := req.GetBotId()
|
||||
platform := req.GetPlatform()
|
||||
json.Unmarshal([]byte(req.Value), &msgs)
|
||||
adapter, err := GetAdapter(bot_id, platform)
|
||||
adapter, err := GetAdapter(platform, bot_id)
|
||||
if err == nil {
|
||||
s := adapter.Sender2(msgs)
|
||||
return &srpc.Default{Value: s.GetID()}, nil
|
||||
return &srpc.Default{Value: s.SetID()}, nil
|
||||
}
|
||||
return &srpc.Default{Value: ""}, err
|
||||
}
|
||||
@@ -102,7 +126,7 @@ func (sg *SillyGirlService) AdapterSender(ctx context.Context, req *srpc.Adapter
|
||||
func (sg *SillyGirlService) AdapterDestroy(ctx context.Context, req *srpc.AdapterRequest) (*srpc.Empty, error) {
|
||||
bot_id := req.GetBotId()
|
||||
platform := req.GetPlatform()
|
||||
adapter, err := GetAdapter(bot_id, platform)
|
||||
adapter, err := GetAdapter(platform, bot_id)
|
||||
if err == nil {
|
||||
adapter.Destroy()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,11 @@ package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cdle/sillyplus/core/storage"
|
||||
"github.com/cdle/sillyplus/proto3/srpc"
|
||||
"github.com/cdle/sillyplus/utils"
|
||||
)
|
||||
@@ -11,6 +15,57 @@ type SillyGirlService struct {
|
||||
srpc.UnsafeSillyGirlServiceServer
|
||||
}
|
||||
|
||||
func (sg *SillyGirlService) BucketWatch(stream srpc.SillyGirlService_BucketWatchServer) error {
|
||||
var watcher func(old, new, key string) *storage.Final
|
||||
var echos sync.Map
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if watcher == nil {
|
||||
watcher = func(old, new, key string) *storage.Final {
|
||||
echo := utils.GenUUID()
|
||||
ch := make(chan *storage.Final)
|
||||
echos.Store(echo, ch)
|
||||
defer echos.Delete(echo)
|
||||
stream.Send(&srpc.BucketWatchResponse{
|
||||
Echo: echo,
|
||||
Old: old,
|
||||
Now: new,
|
||||
Key: key,
|
||||
})
|
||||
select {
|
||||
case v := <-ch:
|
||||
return v
|
||||
case <-time.After(time.Second * 5):
|
||||
}
|
||||
return nil
|
||||
}
|
||||
storage.Watch(MakeBucket(req.Name), req.Key, watcher, req.PluginId)
|
||||
} else {
|
||||
echo := req.Echo
|
||||
v, ok := echos.Load(echo)
|
||||
var fn *storage.Final
|
||||
if req.Error != "VOID" {
|
||||
fn = &storage.Final{
|
||||
Now: req.Now,
|
||||
Message: req.Message,
|
||||
}
|
||||
if req.Error != "" {
|
||||
fn.Error = errors.New(req.Error)
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
select {
|
||||
case v.(chan *storage.Final) <- fn:
|
||||
case <-time.After(time.Millisecond):
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get implements BucketServiceServer.Get.
|
||||
func (sg *SillyGirlService) BucketGet(ctx context.Context, req *srpc.BucketKeyRequest) (*srpc.Default, error) {
|
||||
value := MakeBucket(req.Name).GetString(req.Key)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/cdle/sillyplus/utils"
|
||||
)
|
||||
|
||||
type Language struct {
|
||||
Name string // node
|
||||
Version string // 20230725
|
||||
Os string // linux
|
||||
Arch string // amd64
|
||||
Links []string // 下载链接
|
||||
}
|
||||
|
||||
var languages = []Language{
|
||||
{
|
||||
Name: "node",
|
||||
Version: "20230725",
|
||||
Os: "linux",
|
||||
Arch: "amd64",
|
||||
Links: []string{"https://gitee.com/sillybot/binary/releases/download/20230725/node_linux_amd64"},
|
||||
},
|
||||
{
|
||||
Name: "node",
|
||||
Version: "20230725",
|
||||
Os: "darwin",
|
||||
Arch: "arm64",
|
||||
Links: []string{"https://gitee.com/sillybot/binary/releases/download/20230725/node_darwin_arm64"},
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
for _, item := range languages {
|
||||
if !(item.Os == runtime.GOOS && item.Arch == runtime.GOARCH) {
|
||||
continue
|
||||
}
|
||||
func() {
|
||||
dir := utils.ExecPath + "/language/" + item.Name
|
||||
data, _ := os.ReadFile(dir + "/version")
|
||||
if string(data) == item.Version {
|
||||
return
|
||||
}
|
||||
os.MkdirAll(utils.ExecPath+"/language/"+item.Name, 0755)
|
||||
resp, err := http.Get(item.Links[0])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
f, err := os.OpenFile(dir+"/"+item.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = io.Copy(f, resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
os.WriteFile(dir+"/version", []byte(item.Version), 0755)
|
||||
}()
|
||||
}
|
||||
}
|
||||
+95
-16
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -8,6 +9,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/cdle/sillyplus/core/common"
|
||||
"github.com/cdle/sillyplus/core/storage"
|
||||
@@ -22,6 +24,8 @@ func init() {
|
||||
go initNodePlugins()
|
||||
}
|
||||
|
||||
var processes sync.Map
|
||||
|
||||
func initNodePlugins() {
|
||||
root := utils.ExecPath + "/plugins"
|
||||
plugins := []string{root}
|
||||
@@ -40,7 +44,7 @@ func initNodePlugins() {
|
||||
plugins = append(plugins, path)
|
||||
}
|
||||
case 2:
|
||||
if (files[1] == "main.ts" || files[1] == "main.js") && !info.IsDir() {
|
||||
if (files[1] == "main.js") && !info.IsDir() { //files[1] == "main.ts" ||
|
||||
AddNodePlugin(path, files[0])
|
||||
}
|
||||
}
|
||||
@@ -52,9 +56,7 @@ func initNodePlugins() {
|
||||
return
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
// 要监控的文件夹路径
|
||||
|
||||
for _, dir := range plugins {
|
||||
err = watcher.Add(dir)
|
||||
if err != nil {
|
||||
@@ -77,12 +79,14 @@ func initNodePlugins() {
|
||||
switch len(files) {
|
||||
case 1:
|
||||
plugin_dir = true
|
||||
fmt.Println("目录事件")
|
||||
// fmt.Println("目录事件")
|
||||
plugin_name = files[0]
|
||||
case 2:
|
||||
if files[1] == "main.ts" || files[1] == "main.js" {
|
||||
plugin_index = true
|
||||
fmt.Println("入口文件事件")
|
||||
if files[1] == "main.js" {
|
||||
plugin_index = true
|
||||
}
|
||||
// fmt.Println("入口文件事件")
|
||||
}
|
||||
plugin_name = files[0]
|
||||
}
|
||||
@@ -131,10 +135,10 @@ func RemNodePlugin(name string) error {
|
||||
pluginLock.Lock()
|
||||
defer pluginLock.Unlock()
|
||||
key := nameUuid(name)
|
||||
fmt.Println("rem", key, name)
|
||||
// fmt.Println("rem", key, name)
|
||||
for i := range Functions {
|
||||
if Functions[i].UUID == key {
|
||||
fmt.Println("pl", key)
|
||||
// fmt.Println("pl", key)
|
||||
DestroyAdapterByUUID(key)
|
||||
Functions[i].Running = false
|
||||
if len(Functions[i].CronIds) != 0 {
|
||||
@@ -177,16 +181,91 @@ func AddNodePlugin(path, name string) error {
|
||||
f.Suffix = ".ts"
|
||||
f.Type = "typescript"
|
||||
f.Handle = func(s common.Sender, f func(vm *goja.Runtime)) interface{} {
|
||||
cmd := exec.Command("node", "/Users/a1-6/.nvm/versions/node/v18.16.1/lib/node_modules/ts-node/dist/bin.js", path)
|
||||
cmd.Env = append(cmd.Env, "SENDER_ID="+s.GetID())
|
||||
// 执行命令,并捕获其输出
|
||||
output, err := cmd.Output()
|
||||
s.SetPluginID(uuid)
|
||||
plt := s.GetImType()
|
||||
// , "/Users/a1-6/.nvm/versions/node/v18.16.1/lib/node_modules/ts-node/dist/bin.js",
|
||||
cmd := exec.Command(utils.ExecPath+"/language/node/node", path)
|
||||
// cmd := exec.Command(utils.ExecPath+"/language/node/node", path)
|
||||
id := s.SetID()
|
||||
cmd.Env = append(cmd.Env, "SENDER_ID="+id)
|
||||
cmd.Env = append(cmd.Env, "PLUGIN_ID="+uuid)
|
||||
|
||||
// 获取标准输出和标准错误输出的管道
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Println("命令执行失败:", err)
|
||||
return nil
|
||||
// fmt.Printf("获取标准输出管道失败:%v\n", err)
|
||||
// os.Exit(1)
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
// fmt.Printf("获取标准错误输出管道失败:%v\n", err)
|
||||
// os.Exit(1)
|
||||
}
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
|
||||
// file, err := os.Create("output.log")
|
||||
// if err != nil {
|
||||
// fmt.Printf("创建文件失败:%v\n", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// defer file.Close()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
// 处理标准输出
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
for scanner.Scan() {
|
||||
data := scanner.Text()
|
||||
fmt.Println("log", data)
|
||||
// if _, err := file.WriteString(data + "\n"); err != nil {
|
||||
// fmt.Printf("写入文件失败:%v\n", err)
|
||||
// }
|
||||
}
|
||||
}()
|
||||
// 处理标准错误输出
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
scanner := bufio.NewScanner(stderr)
|
||||
for scanner.Scan() {
|
||||
data := scanner.Text()
|
||||
fmt.Fprintln(os.Stderr, "err "+data)
|
||||
// if _, err := file.WriteString(data + "\n"); err != nil {
|
||||
// fmt.Printf("写入文件失败:%v\n", err)
|
||||
// }
|
||||
}
|
||||
}()
|
||||
processes.Store(cmd, s)
|
||||
if (plt) != "*" {
|
||||
senders.Store(id, s)
|
||||
defer senders.Delete(id)
|
||||
defer processes.Delete(cmd)
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
fmt.Println("命令执行失败:", err)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
processes.Range(func(key, value any) bool {
|
||||
p := key.(*exec.Cmd)
|
||||
if p == cmd {
|
||||
return true
|
||||
}
|
||||
s := value.(common.Sender)
|
||||
if s.GetPluginID() == uuid {
|
||||
p.Process.Kill()
|
||||
}
|
||||
return true
|
||||
})
|
||||
go func() {
|
||||
defer processes.Delete(cmd)
|
||||
err = cmd.Wait()
|
||||
}()
|
||||
}
|
||||
// 输出命令的输出结果
|
||||
fmt.Println(string(output))
|
||||
return nil
|
||||
}
|
||||
for _, cb := range cbs {
|
||||
|
||||
+133
-53
@@ -4,6 +4,9 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -14,23 +17,30 @@ import (
|
||||
|
||||
var senders sync.Map
|
||||
|
||||
func init() {
|
||||
//垃圾回收
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(time.Minute)
|
||||
senders.Range(func(key, value any) bool {
|
||||
s := value.(common.Sender)
|
||||
if s.GetTime().Add(time.Minute * 20).Before(time.Now()) {
|
||||
senders.Delete(s.GetID())
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
// func init() {
|
||||
// //垃圾回收
|
||||
// go func() {
|
||||
// for {
|
||||
// time.Sleep(time.Minute)
|
||||
// senders.Range(func(key, value any) bool {
|
||||
// s := value.(common.Sender)
|
||||
// if s.GetTime().Add(time.Minute * 20).Before(time.Now()) {
|
||||
// senders.Delete(s.GetID())
|
||||
// }
|
||||
// return true
|
||||
// })
|
||||
// }
|
||||
// }()
|
||||
// }
|
||||
|
||||
func GetSender(uuid string) (common.Sender, error) {
|
||||
if uuid == "" {
|
||||
return &CustomSender{
|
||||
f: &Factory{
|
||||
botid: "*",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
v, ok := senders.Load(uuid)
|
||||
if !ok {
|
||||
return nil, errors.New("not found sender")
|
||||
@@ -121,47 +131,96 @@ func (sg *SillyGirlService) SenderContinue(ctx context.Context, req *srpc.Sender
|
||||
}
|
||||
|
||||
// todo
|
||||
func (sg *SillyGirlService) SenderListen(ctx context.Context, req *srpc.SenderListenRequest) (*srpc.Default, error) {
|
||||
s, err := GetSender(req.Uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
options := []interface{}{}
|
||||
var carry = &Carry{
|
||||
ListenPrivate: req.ListenPrivate,
|
||||
ListenGroup: req.ListenGroup,
|
||||
RequireAdmin: req.RequireAdmin,
|
||||
AllowPlatforms: req.AllowPlatforms,
|
||||
ProhibitPlatforms: req.ProhibitPlatforms,
|
||||
AllowGroups: req.AllowGroups,
|
||||
ProhibitGroups: req.ProhibitGroups,
|
||||
AllowUsers: req.AllowUsers,
|
||||
ProhibitUsers: req.ProhibitUsers,
|
||||
UserID: s.GetUserID(),
|
||||
ChatID: s.GetChatID(),
|
||||
}
|
||||
|
||||
if req.Timeout != 0 {
|
||||
options = append(options, time.Duration(req.Timeout)*time.Millisecond)
|
||||
}
|
||||
if len(req.Rules) != 0 {
|
||||
for _, rule := range req.Rules {
|
||||
_rs := formatRule(rule)
|
||||
if len(_rs) != 0 {
|
||||
carry.Function.Rules = append(carry.Function.Rules, _rs...)
|
||||
} else {
|
||||
carry.Function.Rules = append(carry.Function.Rules, rule)
|
||||
func (sg *SillyGirlService) SenderListen(stream srpc.SillyGirlService_SenderListenServer) error {
|
||||
var carry *Carry
|
||||
var echos sync.Map
|
||||
var persistent bool
|
||||
// defer fmt.Println("已关闭,", "===")
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
// fmt.Println("carry", carry, err)
|
||||
if err == io.EOF {
|
||||
break // 如果流已经关闭,则退出循环
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if carry != nil {
|
||||
echo := req.GetUuid()
|
||||
value := req.GetValue()
|
||||
// fmt.Println("echo", echo, "value", value)
|
||||
v, ok := echos.Load(echo)
|
||||
if ok {
|
||||
select {
|
||||
case v.(chan string) <- value:
|
||||
case <-time.After(time.Millisecond):
|
||||
}
|
||||
}
|
||||
// if !persistent {
|
||||
// return nil
|
||||
// }
|
||||
continue
|
||||
}
|
||||
s, err := GetSender(req.Uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options := []interface{}{}
|
||||
carry = &Carry{
|
||||
ListenPrivate: req.ListenPrivate,
|
||||
ListenGroup: req.ListenGroup,
|
||||
RequireAdmin: req.RequireAdmin,
|
||||
AllowPlatforms: req.AllowPlatforms,
|
||||
ProhibitPlatforms: req.ProhibitPlatforms,
|
||||
AllowGroups: req.AllowGroups,
|
||||
ProhibitGroups: req.ProhibitGroups,
|
||||
AllowUsers: req.AllowUsers,
|
||||
ProhibitUsers: req.ProhibitUsers,
|
||||
UserID: s.GetUserID(),
|
||||
ChatID: s.GetChatID(),
|
||||
UUID: req.PluginId,
|
||||
}
|
||||
if req.Timeout != 0 {
|
||||
options = append(options, time.Duration(req.Timeout)*time.Millisecond)
|
||||
}
|
||||
if len(req.Rules) != 0 {
|
||||
for _, rule := range req.Rules {
|
||||
_rs := formatRule(rule)
|
||||
if len(_rs) != 0 {
|
||||
carry.Function.Rules = append(carry.Function.Rules, _rs...)
|
||||
} else {
|
||||
carry.Function.Rules = append(carry.Function.Rules, rule)
|
||||
}
|
||||
}
|
||||
}
|
||||
options = append(options, carry)
|
||||
if req.Persistent {
|
||||
persistent = req.Persistent
|
||||
options = append(options, "persistent")
|
||||
}
|
||||
go s.Await(s, func(s common.Sender) interface{} {
|
||||
id := s.SetID()
|
||||
defer senders.Delete(id)
|
||||
echo := utils.GenUUID()
|
||||
ch := make(chan string)
|
||||
echos.Store(echo, ch)
|
||||
defer echos.Delete(echo)
|
||||
stream.Send(&srpc.SenderListenResponse{Echo: echo, Uuid: id})
|
||||
value := <-ch
|
||||
if !persistent {
|
||||
if strings.HasPrefix(value, "go_again_") {
|
||||
value = strings.Replace(value, "go_again_", "", 1)
|
||||
return GoAgain(value)
|
||||
} else {
|
||||
stream.Send(&srpc.SenderListenResponse{Echo: "END"})
|
||||
}
|
||||
} else {
|
||||
value = strings.Replace(value, "go_again_", "", 1)
|
||||
}
|
||||
return value
|
||||
}, options...)
|
||||
}
|
||||
options = append(options, carry)
|
||||
id := ""
|
||||
s.Await(s, func(s common.Sender) interface{} {
|
||||
id = s.GetID()
|
||||
return nil
|
||||
}, options...)
|
||||
return &srpc.Default{Value: id}, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sg *SillyGirlService) SenderEvent(ctx context.Context, req *srpc.SenderRequest) (*srpc.Default, error) {
|
||||
@@ -181,6 +240,21 @@ func (sg *SillyGirlService) SenderReply(ctx context.Context, req *srpc.ReplyRequ
|
||||
return &srpc.Default{Value: message_id}, err
|
||||
}
|
||||
|
||||
func (sg *SillyGirlService) SenderParam(ctx context.Context, req *srpc.ReplyRequest) (*srpc.Default, error) {
|
||||
s, err := GetSender(req.Uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value := ""
|
||||
i := utils.Int(req.Content)
|
||||
if fmt.Sprint(i) == req.Content {
|
||||
value = s.Get(i - 1)
|
||||
} else {
|
||||
value = s.Get(req.Content)
|
||||
}
|
||||
return &srpc.Default{Value: value}, err
|
||||
}
|
||||
|
||||
func (sg *SillyGirlService) SenderAction(ctx context.Context, req *srpc.ReplyRequest) (*srpc.Default, error) {
|
||||
s, err := GetSender(req.Uuid)
|
||||
if err != nil {
|
||||
@@ -194,3 +268,9 @@ func (sg *SillyGirlService) SenderAction(ctx context.Context, req *srpc.ReplyReq
|
||||
result, err := s.Action(params)
|
||||
return &srpc.Default{Value: string(utils.JsonMarshal(result))}, err
|
||||
}
|
||||
|
||||
func (sg *SillyGirlService) SenderDestroy(ctx context.Context, req *srpc.ReplyRequest) (*srpc.Empty, error) {
|
||||
// fmt.Println("删除", req.Uuid)
|
||||
senders.Delete(req.Uuid)
|
||||
return &srpc.Empty{}, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
|
||||
"github.com/cdle/sillyplus/core/common"
|
||||
"github.com/cdle/sillyplus/core/logs"
|
||||
"github.com/cdle/sillyplus/proto3/srpc"
|
||||
"github.com/cdle/sillyplus/utils"
|
||||
"github.com/dop251/goja"
|
||||
// "golang.org/x/image/webp"
|
||||
@@ -47,6 +49,21 @@ type Console struct {
|
||||
var console = &Console{}
|
||||
var Logs = &Console{}
|
||||
|
||||
func (sg *SillyGirlService) Console(ctx context.Context, req *srpc.ConsoleRequest) (*srpc.Empty, error) {
|
||||
log := &Console{
|
||||
UUID: req.PluginId,
|
||||
}
|
||||
switch req.Type {
|
||||
case "info", "log":
|
||||
log.Info(req.Content)
|
||||
case "error":
|
||||
log.Error(req.Content)
|
||||
case "debug":
|
||||
log.Debug(req.Content)
|
||||
}
|
||||
return &srpc.Empty{}, nil
|
||||
}
|
||||
|
||||
func pluginConsole(uuid string) *Console {
|
||||
return &Console{
|
||||
UUID: uuid,
|
||||
|
||||
Reference in New Issue
Block a user