diff --git a/.gitignore b/.gitignore index b6b2eb3..d865b72 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,5 @@ develop/core dist/ core/dist .verysync -test \ No newline at end of file +test +.sillyplus \ No newline at end of file diff --git a/core/adapter.go b/core/adapter.go index 51de15f..cb56ef1 100644 --- a/core/adapter.go +++ b/core/adapter.go @@ -180,7 +180,7 @@ func (f *Factory) Init(botplt, botid string) { if botid != "" { botid = fmt.Sprintf("(%s)", botid) } - console.Log("%s机器人%s已初始化。", botplt, botid) + console.Log("%s机器人%s已初始化", botplt, botid) } func (f *Factory) IsAdapter(botid string) bool { @@ -208,7 +208,7 @@ func (f *Factory) Destroy() { } else { botid = f.botid } - console.Log("%s机器人%s已销毁。", strings.ToUpper(f.botplt), botid) + console.Log("%s机器人%s已销毁", strings.ToUpper(f.botplt), botid) } func (f *Factory) Push(msg map[string]string) (string, error) { diff --git a/core/api_auth.go b/core/api_auth.go index 8ae5f68..13e92aa 100644 --- a/core/api_auth.go +++ b/core/api_auth.go @@ -15,6 +15,7 @@ import ( var authBucket = MakeBucket("auths") var auths = []*Auth{} +var password = "" func init() { storage.Watch(sillyGirl, "name", func(old, new, key string) *storage.Final { @@ -34,13 +35,18 @@ func init() { } return nil }) - var password = sillyGirl.GetString("password") + password = sillyGirl.GetString("password") var name = sillyGirl.GetString("name", "傻妞") - if password == "" { - password = utils.GenUUID() - console.Info("可视化面板临时账号密码:%s %s", name, password) - } + // if password == "" { + // password = utils.GenUUID() + // console.Info("可视化面板临时账号密码:%s %s", name, password) + // } storage.Watch(sillyGirl, "password", func(old, new, key string) *storage.Final { + if new == "" { + return &storage.Final{ + Now: new, + } + } password, _ = EncryptByAes([]byte(new)) return &storage.Final{ Now: password, @@ -183,6 +189,9 @@ func checkTempAuth(uuid string) bool { } func RequireAuth(c *gin.Context) { + if password == "" { + return + } token, _ := c.Cookie("token") _, err := CheckAuth(token) if err != nil && !checkTempAuth(token) { diff --git a/core/base_sender.go b/core/base_sender.go index a411f81..8184187 100644 --- a/core/base_sender.go +++ b/core/base_sender.go @@ -521,7 +521,7 @@ func (s *BaseSender) Await(message common.Sender, callback func(common.Sender) i return v } } - c.Result <- fmt.Sprintf("请从%s中选择一个。", strings.Join(vv, "、")) + c.Result <- fmt.Sprintf("请从%s中选择一个", strings.Join(vv, "、")) } else if vv, ok := result.(Range); ok { ct := s.GetContent() n := utils.Int(ct) @@ -531,7 +531,7 @@ func (s *BaseSender) Await(message common.Sender, callback func(common.Sender) i return n } } - c.Result <- fmt.Sprintf("请从%d~%d中选择一个整数。", vv[0], vv[1]) + c.Result <- fmt.Sprintf("请从%d~%d中选择一个整数", vv[0], vv[1]) } else { c.Result <- result return s.GetContent() diff --git a/core/bucket.go b/core/bucket.go index 5bf15db..a137204 100644 --- a/core/bucket.go +++ b/core/bucket.go @@ -32,19 +32,19 @@ func MakeBucket(name string) storage.Bucket { MakeBucketlocker.Lock() defer MakeBucketlocker.Unlock() if bkt == nil { - utils.ReadYaml(utils.ExecPath+"/conf/", &Config, "https://raw.githubusercontent.com/cdle/sillyplus/main/conf/demo_config.yaml") + // utils.ReadYaml(utils.ExecPath+"/conf/", &Config, "https://raw.githubusercontent.com/cdle/sillyplus/main/conf/demo_config.yaml") utils.SlaveMode = Config.SlaveMode HttpPort = Config.HttpPort if !Config.EnableRedis { bkt = boltdb.Initsillyplus() Get = boltdb.Get Set = boltdb.Set - logs.Info("默认使用boltdb进行数据存储。") + logs.Info("默认使用boltdb进行数据存储") } else { bkt = redis.Initsillyplus(Config.RedisAddr, Config.RedisPassword) Get = redis.Get Set = redis.Set - logs.Info("已使用redis进行数据存储。") + logs.Info("已使用redis进行数据存储") } for _, name := range bkt.Buckets() { b := bkt.Copy(name) diff --git a/core/carry.go b/core/carry.go index 3b227c5..4b96b94 100644 --- a/core/carry.go +++ b/core/carry.go @@ -203,7 +203,7 @@ func init() { func init() { setCgs() storage.Watch(CarryGroups, nil, func(old, new, key string) *storage.Final { - console.Log("已更新搬运数据。") + console.Log("已更新搬运数据") ocg := CarryGroup{} ncg := CarryGroup{} json.Unmarshal([]byte(old), &ocg) @@ -215,7 +215,7 @@ func init() { for i, cg := range tmp { if cg.ID == ocg.ID { tmp = append(tmp[:i], tmp[i+1:]...) - RemListenOnGroup(cg.ID, fmt.Sprintf("已为采集群(%s)关闭监听模式。", cg.ID)) + RemListenOnGroup(cg.ID, fmt.Sprintf("已为采集群(%s)关闭监听模式", cg.ID)) break } } @@ -229,12 +229,12 @@ func init() { tmp[i] = ncg if ncg.In { if ncg.Enable { - AddListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)开启监听模式。", ncg.ID)) + AddListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)开启监听模式", ncg.ID)) } else { - RemListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)关闭监听模式。", ncg.ID)) + RemListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)关闭监听模式", ncg.ID)) } } else { - RemListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)关闭监听模式。", ncg.ID)) + RemListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)关闭监听模式", ncg.ID)) } break } @@ -247,7 +247,7 @@ func init() { if ncg.ID != "" { tmp = append(tmp, ncg) if ncg.In && ncg.Enable { - AddListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)开启监听模式。", ncg.ID)) + AddListenOnGroup(ncg.ID, fmt.Sprintf("已为采集群(%s)开启监听模式", ncg.ID)) } } else { return nil @@ -270,7 +270,7 @@ func setCgs() { return nil } if cg.In { - AddListenOnGroup(cg.ID, fmt.Sprintf("已为采集群(%s)开启监听模式。", cg.ID)) + AddListenOnGroup(cg.ID, fmt.Sprintf("已为采集群(%s)开启监听模式", cg.ID)) } cgs = append(cgs, cg) return nil diff --git a/core/function.go b/core/function.go index a751241..3f161d4 100644 --- a/core/function.go +++ b/core/function.go @@ -389,7 +389,7 @@ func AddCommand(cmds []*common.Function) { }) if err == nil { cmds[j].CronId = int(cronId) - // console["log"]("脚本%s添加定时器。", cmds[j].Title) + // console["log"]("脚本%s添加定时器", cmds[j].Title) } else { console.Error("脚本%s定时器错误,%v", cmds[j].Title, err) } diff --git a/core/init.go b/core/init.go index b54d671..0334ac0 100644 --- a/core/init.go +++ b/core/init.go @@ -1,10 +1,15 @@ package core import ( + "fmt" "os" + "regexp" + "runtime" + "syscall" "time" "github.com/beego/beego/v2/adapter/httplib" + "github.com/cdle/sillyplus/core/storage" "github.com/cdle/sillyplus/utils" ) @@ -18,8 +23,105 @@ func Init() { } // utils.ReadYaml(utils.ExecPath+"/conf/", &Config, "https://raw.githubusercontent.com/cdle/sillyplus/main/conf/demo_config.yaml") initToHandleMessage() - + sillyGirl.Set("compiled_at", compiled_at) + console.Log("编译版本:%s", compiled_at) sillyGirl.Set("started_at", time.Now().Format("2006-01-02 15:04:05")) + storage.Watch(sillyGirl, "compiled_at", func(old, new, key string) *storage.Final { + if old != new { + console.Debug("正在从 cdle/binary 获取版本号...") + data, err := httplib.Get("https://raw.githubusercontent.com/cdle/binary/main/compile_time.go").Bytes() + if err != nil { + console.Error("获取版本号错误:%s", err) + return &storage.Final{ + Error: fmt.Errorf("貌似网络不太行啊:%s", err), + } + } + latest_version := regexp.MustCompile(`\d{13}`).FindString(string(data)) + if latest_version <= compiled_at { + console.Debug("当前版本 %s 已是最新,无需升级", compiled_at) + return &storage.Final{ + Message: fmt.Sprintf("当前版本 %s 已是最新,无需升级", compiled_at), + } + } + console.Debug("正在从 cdle/binary 获取最新版本 %s 编译文件...", latest_version) + qurl := "https://raw.githubusercontent.com/cdle/binary/master/sillyGirl_linux_" + runtime.GOARCH + "_" + latest_version + if runtime.GOARCH == "windows" { + qurl += ".exe" + } + req := httplib.Get(qurl) + req.SetTimeout(time.Minute*5, time.Minute*5) + data, err = req.Bytes() + if err != nil { + console.Error("获取最新编译文件错误:%s", err) + return &storage.Final{ + Error: fmt.Errorf("升级时貌似网络不太行啊:%v", err), + } + } + if len(data) < 2646140 { + console.Error("获取最新编译文件错误:%v", len(data)) + return &storage.Final{ + Error: fmt.Errorf("升级时貌似网络不太行啊!%v", len(data)), + } + } + console.Debug("正在创建编译文件...") + filename := utils.ExecPath + "/" + utils.ProcessName + ready := filename + ".ready" + if f, err := os.OpenFile(ready, syscall.O_CREAT, 0777); err != nil { + console.Error("创建编译文件错误:%v", err) + return &storage.Final{ + Error: fmt.Errorf("创建编译文件错误:%v", err), + } + } else { + _, err := f.Write(data) + f.Close() + if err != nil { + des := err.Error() + if err = os.WriteFile(ready, data, 0777); err != nil { + console.Error("写入编译文件错误:%s || %s", des, err) + return &storage.Final{ + Error: fmt.Errorf("写入编译文件错误:%s || %s", des, err), + } + } + } + } + console.Debug("正在删除旧程序错误...") + if err = os.RemoveAll(filename); err != nil { + console.Error("删除旧程序错误:%v", err) + return &storage.Final{ + Error: fmt.Errorf("删除旧程序错误:%v", err), + } + } + console.Debug("正在移动新程序错误...") + if err = os.Rename(ready, filename); err != nil { + console.Error("移动新程序错误:%v", err) + return &storage.Final{ + Error: fmt.Errorf("移动新程序错误:%v", err), + } + } + go func() { + console.Debug("正在重启...") + time.Sleep(time.Second) + utils.Daemon() + }() + return &storage.Final{ + Message: "升级成功,即将重启!", + } + } + return nil + }) + storage.Watch(sillyGirl, "started_at", func(old, new, key string) *storage.Final { + if old != new { + go func() { + time.Sleep(time.Second) + utils.Daemon() + }() + return &storage.Final{ + Message: "马上重启!", + } + } + return nil + }) + api_key := sillyGirl.GetString("api_key") if api_key == "" { api_key := time.Now().UnixNano() @@ -40,7 +142,4 @@ func Init() { initWebPluginList() go initPluginList() initPluginPublish() - if compiled_at != "" { - console.Log("编译时间戳,", compiled_at) - } } diff --git a/core/node_request.go b/core/node_request.go index cb972fd..e0eb7fa 100644 --- a/core/node_request.go +++ b/core/node_request.go @@ -3,7 +3,6 @@ package core import ( "bytes" "fmt" - "io/ioutil" "net/http" u "net/url" "strconv" @@ -15,147 +14,8 @@ import ( "github.com/goccy/go-json" ) -func request(wt interface{}, handles ...func(error, map[string]interface{}, interface{}) interface{}) interface{} { - var method = "get" - var url = "" - var req *http.Request - - var headers map[string]interface{} - // var formData map[string]interface{} - var isJson bool - var isJsonBody bool - var body string - var allow_redirects bool = true - // var useproxy bool - // var timeout time.Duration = 0 - var goroutine = false - var uuid = "" - switch wt := wt.(type) { - case string: - url = wt - default: - props := wt.(map[string]interface{}) - for i := range props { - switch strings.ToLower(i) { - // case "timeout": - // timeout = time.Duration(utils.Int64(props[i])) * time.Millisecond - case "headers": - headers = props[i].(map[string]interface{}) - case "method": - method = strings.ToLower(props[i].(string)) - case "url": - if f, ok := props[i].(func(i goja.FunctionCall) goja.Value); ok { - url = f(goja.FunctionCall{}).ToString().String() - } else { - url = props[i].(string) - } - case "json": - isJson = props[i].(bool) - case "uuid": - uuid = props[i].(string) - case "goroutine": - goroutine = true - case "datatype": - switch props[i].(type) { - case string: - switch strings.ToLower(props[i].(string)) { - case "json": - isJson = true - } - } - case "allowredirects": - allow_redirects = props[i].(bool) - case "body": - if v, ok := props[i].(string); !ok { - d, _ := json.Marshal(props[i]) - body = string(d) - isJsonBody = true - } else { - body = v - } - // case "formdata": - // formData = props[i].(map[string]interface{}) - // case "useproxy": - // useproxy = props[i].(bool) - } - } - } - method = strings.ToUpper(method) - req, _ = http.NewRequest(method, url, bytes.NewBuffer([]byte(body))) - // if timeout != 0 { - // req.SetTimeout(timeout, timeout) - // } - - if isJsonBody { - req.Header.Set("Content-Type", "application/json") - } - for i := range headers { - req.Header.Set(i, fmt.Sprint(headers[i])) - } - // for i := range formData { - // req.Param(i, fmt.Sprint(formData[i])) - // } - - // if useproxy && Transport != nil { - // req.SetTransport(Transport) - // } - - rspObj := map[string]interface{}{} - var rsp *http.Response - var err error - // if !allow_redirects { - // req.SetCheckRedirect(func(req *http.Request, via []*http.Request) error { - // return http.ErrUseLastResponse - // }) - // } - var dddd = func() interface{} { - client := &http.Client{} - if !allow_redirects { - client.CheckRedirect = func(req *http.Request, via []*http.Request) error { - return http.ErrUseLastResponse - } - } - rsp, err = client.Do(req) - var bd interface{} - if err == nil { - defer rsp.Body.Close() - rspObj["status"] = rsp.StatusCode - rspObj["statusCode"] = rsp.StatusCode - data, _ := ioutil.ReadAll(rsp.Body) - if isJson { - var v interface{} - json.Unmarshal(data, &v) - bd = v - } else { - bd = string(data) - } - rspObj["body"] = bd - h := make(map[string][]string) - for k := range rsp.Header { - h[k] = rsp.Header[k] - } - rspObj["headers"] = h - } else { - rspObj["error"] = err.Error() - } - if uuid != "" { - rspObj["uuid"] = uuid - } - if len(handles) > 0 { - return handles[0](err, rspObj, bd) - } else { - return rspObj - } - } - if goroutine { - go dddd() - } else { - return dddd() - } - return nil -} - -func fetch(vm *goja.Runtime, resolve func(result interface{}), reject func(reason interface{}), wts ...interface{}) { +func fetch(vm *goja.Runtime, resolve func(result interface{}), reject func(reason interface{}), wts ...interface{}) interface{} { + var block = resolve == nil var method = "get" var url = "" var req *http.Request @@ -233,8 +93,15 @@ func fetch(vm *goja.Runtime, resolve func(result interface{}), reject func(reaso var err error transport, err = GetTransport(url, user, password) if err != nil { - reject(Error(vm, "proxy config error "+err.Error())) - return + info := "proxy config error " + err.Error() + console.Error() + if block { + panic(Error(vm, info)) + } else { + reject(Error(vm, info)) + // return nil + } + return nil } } } @@ -313,8 +180,19 @@ func fetch(vm *goja.Runtime, resolve func(result interface{}), reject func(reaso return goja.Undefined() }, }) - resolve(rspObj) + if block { + return rspObj + } else { + resolve(rspObj) + + } } else { - reject(Error(vm, err)) + if block { + return rspObj + } else { + reject(Error(vm, err)) + + } } + return nil } diff --git a/core/plugin_core.go b/core/plugin_core.go index 4fcf0d6..5d6707e 100644 --- a/core/plugin_core.go +++ b/core/plugin_core.go @@ -112,7 +112,7 @@ func initPlugins() { break } else { return &storage.Final{ - Error: errors.New("订阅源异常。"), + Error: errors.New("订阅源异常"), } } } @@ -127,7 +127,7 @@ func initPlugins() { su.SetValue("author", "佚名") } if su.GetValue("description") == "" { - su.SetValue("description", "🐒这个人很懒什么都没有留下。") + su.SetValue("description", "🐒这个人很懒什么都没有留下") } //module title := su.GetValue("title") if title == "" { @@ -183,7 +183,7 @@ func initPlugins() { if su.script != new { fin.Message = su.script } else if title != (&ScriptUtils{script: old}).GetValue("title") { - fin.Message = "标题变更。" + fin.Message = "标题变更" } new = su.script } @@ -435,7 +435,7 @@ func initPlugin(data string, uuid string) (*common.Function, error) { err = err2 } if err == nil && len(rules) == 0 && cron != "" { - err = fmt.Errorf("无效的脚本%s。", title) + err = fmt.Errorf("无效的脚本%s", title) } if web { onStart = true @@ -472,8 +472,6 @@ func initPlugin(data string, uuid string) (*common.Function, error) { vm.Set("message", goja.Undefined()) vm.Set("res", goja.Undefined()) vm.Set("req", goja.Undefined()) - vm.Set("response", goja.Undefined()) - vm.Set("request", goja.Undefined()) vm.Set("sender", ss) vm.Set("s", ss) vm.Set("InitAdapter", func(plt, botid string) *Factory { diff --git a/core/plugin_publish.go b/core/plugin_publish.go index 9c4267a..c702f1a 100644 --- a/core/plugin_publish.go +++ b/core/plugin_publish.go @@ -26,7 +26,7 @@ func CheckPluginAddress(address string) error { rr := RequestPluginResult{} json.Unmarshal(data, &rr) if !rr.Success { - return errors.New("无效的地址。") + return errors.New("无效的地址") } return nil } @@ -73,7 +73,7 @@ func publicScript(str string) string { su.SetValue("author", "佚名") } if su.GetValue("description") == "" { - su.SetValue("description", "🐒这个人很懒什么都没有留下。") + su.SetValue("description", "🐒这个人很懒什么都没有留下") } if su.GetValue("public") == "true" { su.SetValue("public", "false") diff --git a/core/plugin_utils.go b/core/plugin_utils.go index 5269aac..e192331 100644 --- a/core/plugin_utils.go +++ b/core/plugin_utils.go @@ -377,6 +377,9 @@ func SetPluginMethod(vm *goja.Runtime, uuid string, on_start bool) { }() return promise }) + vm.Set("request", func(wts ...interface{}) interface{} { + return fetch(vm, nil, nil, wts...) + }) // for _, method := range []string{"get", "post", "delete", "put", "fetch"} { // vm.Set(method, ) // } @@ -398,7 +401,6 @@ func SetPluginMethod(vm *goja.Runtime, uuid string, on_start bool) { }() return promise }) - vm.Set("request", request) vm.Set("getReplyMessage", func(plt string, bots_id []string) *goja.Promise { return GetReplyMessage(vm, plt, bots_id) }) diff --git a/core/reboot.go b/core/reboot.go index 3c075a7..24bc84b 100644 --- a/core/reboot.go +++ b/core/reboot.go @@ -18,7 +18,7 @@ func initReboot() { if tp == "fake" { return } - msg := "重启完成。" + msg := "重启完成" for i := 0; i < 10; i++ { dapter, _ := GetAdapter(tp, "") if dapter != nil { diff --git a/core/storage/boltdb/init.go b/core/storage/boltdb/init.go index 3709f34..baf7fda 100644 --- a/core/storage/boltdb/init.go +++ b/core/storage/boltdb/init.go @@ -6,7 +6,6 @@ import ( "fmt" "os" "reflect" - "runtime" "time" "github.com/boltdb/bolt" @@ -56,29 +55,22 @@ func Get(key string) string { var Buckets = []Bucket{} func Initsillyplus() storage.Bucket { - var err error - if runtime.GOOS == "darwin" { - db, err = bolt.Open("./sillyGirl.db", 0600, nil) + bd := utils.GetDataHome() + "sillyGirl.db" + _, err := os.Stat(bd) + if err != nil { + f, err := os.Create(bd) if err != nil { - panic(err) - } - } else { - bd := utils.GetDataHome() + "sillyGirl.db" - _, err := os.Stat(bd) - if err != nil { - f, err := os.Create(bd) - if err != nil { - logs.Info("傻妞无法创建数据文件 %s ,请手动创建。", bd) - os.Exit(0) - } - f.Close() - } - db, err = bolt.Open(bd, 0600, nil) - if err != nil { - logs.Info("傻妞无法创建数据文件 %s ,请手动创建。", bd) + logs.Info("傻妞无法创建数据文件 %s ,请手动创建", bd) os.Exit(0) } + f.Close() } + db, err = bolt.Open(bd, 0600, nil) + if err != nil { + logs.Info("傻妞无法创建数据文件 %s ,请手动创建", bd) + os.Exit(0) + } + v := &Bucket{ name: "sillyplus", } diff --git a/core/web.go b/core/web.go index 7214bcb..91bf2f3 100644 --- a/core/web.go +++ b/core/web.go @@ -100,9 +100,6 @@ func init() { }, func(vm *goja.Runtime) { vm.Set("res", res) vm.Set("req", req) - vm.Set("response", res) - vm.Set("request", req) - }) } } @@ -261,7 +258,7 @@ func init() { } } - c.String(404, "页面被喵咪劫走了。") // + c.String(404, "页面被喵咪劫走了") // //开启代理模式 // handleHTTP(c.Writer, c.Request) @@ -288,7 +285,7 @@ func init() { var ch = make(chan error, 1) srvs = append(srvs, srv) go func() { - logs.Info("Http服务(%s)重新运行。", port) + logs.Info("Http服务(%s)重新运行", port) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { logs.Error("Http服务(%s)运行失败:%s", port, err.Error()) ch <- err @@ -304,7 +301,7 @@ func init() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srvs[0].Shutdown(ctx); err == nil { - logs.Info("Http服务(%s)关闭。", old) + logs.Info("Http服务(%s)关闭", old) } srvs = srvs[1:] } @@ -313,44 +310,13 @@ func init() { } }) go func() { - logs.Info("Http服务(%s)开始运行。", port) + logs.Info("Http服务(%s)开始运行", port) if err := srvs[0].ListenAndServe(); err != nil && err != http.ErrServerClosed { - logs.Error("Http服务运行失败:%s。", err.Error()) + logs.Error("Http服务运行失败:%s", err.Error()) } }() } -// var httpProxys = MakeBucket("httpProxys") - -func handleHTTP(w http.ResponseWriter, req *http.Request) { - // console.Info("%s", utils.JsonMarshal(req.Header)) - // u, err := url.Parse("addr") - // if err != nil { - // core.Logs.Warn("can't connect to the http proxy:", err) - // return - // } - // Transport = &http.Transport{Proxy: http.ProxyURL(u)} - // resp, err := Transport.RoundTrip(req) - // fmt.Println("====") - resp, err := http.DefaultTransport.RoundTrip(req) - if err != nil { - http.Error(w, err.Error(), http.StatusServiceUnavailable) - return - } - defer resp.Body.Close() - copyHeader(w.Header(), resp.Header) - w.WriteHeader(resp.StatusCode) - io.Copy(w, resp.Body) -} - -func copyHeader(dst, src http.Header) { - for k, vv := range src { - for _, v := range vv { - dst.Add(k, v) - } - } -} - type Req struct { Method string Path string diff --git a/main.go b/main.go index 4752c4b..ad15082 100644 --- a/main.go +++ b/main.go @@ -35,7 +35,7 @@ func main() { } } if t { - core.Logs.Info("Terminal机器人已连接。") + core.Logs.Info("Terminal机器人已连接") scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { data := scanner.Text() @@ -48,7 +48,7 @@ func main() { } core.Logs.Info("Terminal机器人异常,请检查运行环境设置,如果是docker环境,请附加-it参数") } else { - core.Logs.Info("Terminal机器人不可用,运行带-t参数即可启用。") + core.Logs.Info("Terminal机器人不可用,运行带-t参数即可启用") } } select {} diff --git a/utils/init.go b/utils/init.go index f2a0611..b7a4a26 100644 --- a/utils/init.go +++ b/utils/init.go @@ -19,7 +19,6 @@ import ( // "github.com/cdle/sillyplus/core/logs" "github.com/cdle/sillyplus/core/logs" "github.com/google/uuid" - "gopkg.in/yaml.v2" ) var SlaveMode bool @@ -71,12 +70,19 @@ var Int64 = func(s interface{}) int64 { } func init() { + err := KillPeer() + if err != nil { + logs.Warn("结束进程失败:", err) + } + err = os.WriteFile(GetPidFile(), []byte(fmt.Sprintf("%d", os.Getpid())), 0o644) + if err != nil { + logs.Warn("写入进程ID失败:", err) + } for _, arg := range os.Args { if arg == "-d" { Daemon() } } - KillPeer() } var GetDataHome = func() string { @@ -85,6 +91,12 @@ var GetDataHome = func() string { os.MkdirAll(`C:\ProgramData\sillyplus\`, os.ModePerm) } return `C:\ProgramData\sillyplus\` + } else if runtime.GOOS == "darwin" { + i := ExecPath + "/.sillyplus/" + if _, err := os.Stat(i); err != nil { + os.MkdirAll(i, os.ModePerm) + } + return i } else { if _, err := os.Stat(`/etc/sillyplus/`); err != nil { os.MkdirAll(`/etc/sillyplus/`, os.ModePerm) @@ -93,37 +105,41 @@ var GetDataHome = func() string { } } -func KillPeer() { - pids, err := ppid() - if err == nil { - if len(pids) == 0 { - return - } else { - exec.Command("sh", "-c", "kill -9 "+strings.Join(pids, " ")).Output() - } - } else { - return +func KillProcess(pid int) error { + var cmd *exec.Cmd + switch runtime.GOOS { + case "linux", "darwin": + cmd = exec.Command("kill", "-TERM", strconv.Itoa(pid)) + case "windows": + cmd = exec.Command("taskkill", "/F", "/PID", strconv.Itoa(pid)) + default: + return fmt.Errorf("unsupported operating system: %v", runtime.GOOS) } + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if _, ok := err.(*exec.ExitError); ok { + return nil + } + if err != nil { + return fmt.Errorf("failed to kill process %d: %v", pid, err) + } + return nil +} + +func KillPeer() error { + id, err := GetPidFromFile(GetPidFile()) + if err != nil { + return err + } + if id != 0 { + return KillProcess(id) + } + return nil } var ProcessName = getProcessName() -func ppid() ([]string, error) { - pid := fmt.Sprint(os.Getpid()) - pids := []string{} - rtn, err := exec.Command("sh", "-c", "pidof "+ProcessName).Output() - if err != nil { - return pids, err - } - re := regexp.MustCompile(`[\d]+`) - for _, v := range re.FindAll(rtn, -1) { - if string(v) != pid { - pids = append(pids, string(v)) - } - } - return pids, nil -} - var ExecPath, _ = filepath.Abs(filepath.Dir(os.Args[0])) var getProcessName = func() string { @@ -134,18 +150,26 @@ var getProcessName = func() string { } var GetPidFile = func() string { - if runtime.GOOS == "windows" { - return fmt.Sprintf("%s\\%s", ExecPath, "sillyplus.pid") - } - return "/var/run/sillyplus.pid" + return GetDataHome() + "sillyplus.pid" } -var Runnings = []func(){} +func GetPidFromFile(pidFile string) (int, error) { + if _, err := os.Stat(pidFile); err != nil { + return 0, nil + } + data, err := ioutil.ReadFile(pidFile) + if err != nil { + return 0, err + } + pidStr := strings.TrimSpace(string(data)) + pid, err := strconv.Atoi(pidStr) + if err != nil { + return 0, err + } + return pid, nil +} func Daemon() { - for _, bs := range Runnings { - bs() - } args := os.Args[1:] execArgs := make([]string, 0) l := len(args) @@ -164,7 +188,7 @@ func Daemon() { panic(err) } logs.Info("程序以静默形式运行") - err = os.WriteFile(GetPidFile(), []byte(fmt.Sprintf("%d", proc.Process.Pid)), 0o644) + // err = os.WriteFile(GetPidFile(), []byte(fmt.Sprintf("%d", proc.Process.Pid)), 0o644) if err != nil { logs.Info(err) } @@ -236,31 +260,6 @@ func JsonMarshal(v interface{}) (d []byte) { return } -func ReadYaml(confDir string, conf interface{}, _ string) { - path := confDir + "config.yaml" - if _, err := os.Stat(confDir); err != nil { - os.MkdirAll(confDir, os.ModePerm) - } - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0777) - if err != nil { - return - } - s, _ := ioutil.ReadAll(f) - if len(s) == 0 { - return - } - f.Close() - content, err := ioutil.ReadFile(path) - if err != nil { - logs.Warn("解析配置文件%s读取错误: %v", path, err) - return - } - if yaml.Unmarshal(content, conf) != nil { - logs.Warn("解析配置文件%s出错: %v", path, err) - return - } -} - func Str2Ints(str string) []int { is := []int{} for _, v := range Str2IntStr(str) {