This commit is contained in:
cdle
2023-06-04 14:30:54 +08:00
parent 2099b1af7a
commit 55c0895161
17 changed files with 248 additions and 304 deletions
+2 -1
View File
@@ -29,4 +29,5 @@ develop/core
dist/
core/dist
.verysync
test
test
.sillyplus
+2 -2
View File
@@ -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) {
+14 -5
View File
@@ -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) {
+2 -2
View File
@@ -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()
+3 -3
View File
@@ -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)
+7 -7
View File
@@ -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
+1 -1
View File
@@ -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)
}
+103 -4
View File
@@ -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)
}
}
+24 -146
View File
@@ -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
}
+4 -6
View File
@@ -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 {
+2 -2
View File
@@ -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")
+3 -1
View File
@@ -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)
})
+1 -1
View File
@@ -18,7 +18,7 @@ func initReboot() {
if tp == "fake" {
return
}
msg := "重启完成"
msg := "重启完成"
for i := 0; i < 10; i++ {
dapter, _ := GetAdapter(tp, "")
if dapter != nil {
+12 -20
View File
@@ -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",
}
+5 -39
View File
@@ -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
+2 -2
View File
@@ -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 {}
+61 -62
View File
@@ -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) {