diff --git a/.gitignore b/.gitignore index 20aa7b4..7843357 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,6 @@ temp.yaml bin **/config/config.yaml v1.0.0/ -manifest/config/local.yaml +config/local.yaml +main.exe~ +download/ diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 0a6a461..7943aa8 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -2,6 +2,7 @@ package cmd import ( "context" + "fmt" "time" "github.com/ayflying/p2p/internal/consts" @@ -13,6 +14,7 @@ import ( "github.com/gogf/gf/v2/os/gcmd" "github.com/gogf/gf/v2/os/gctx" "github.com/gogf/gf/v2/os/gtimer" + "github.com/gogf/gf/v2/util/grand" ) func init() { @@ -47,7 +49,24 @@ var ( }) addr := g.Cfg().MustGet(ctx, "ws.address").String() ws := parser.GetOpt("ws", addr).String() - //port := parser.GetOpt("port", 0).Int() + if ws == "" { + listVar := g.Cfg().MustGet(ctx, "p2p.list") + var p2pItem []struct { + Host string `json:"host"` + Port int `json:"port"` + SSL bool `json:"ssl"` + Ws string `json:"ws"` + } + listVar.Scan(&p2pItem) + key := grand.Intn(len(p2pItem) - 1) + wsData := p2pItem[key] + ws = fmt.Sprintf("ws://%s:%d/ws", wsData.Host, wsData.Port) + } + + port := parser.GetOpt("port", 0).Int() + if port > 0 { + s.SetPort(port) + } s.Group("/", func(group *ghttp.RouterGroup) { group.Middleware(ghttp.MiddlewareHandlerResponse) @@ -66,8 +85,6 @@ var ( } }) - //s.SetPort(port) - // 延迟启动 gtimer.SetTimeout(ctx, time.Second*5, func(ctx context.Context) { g.Log().Debug(ctx, "开始执行客户端") @@ -75,12 +92,6 @@ var ( err = service.P2P().Start(ws) g.Log().Debugf(ctx, "当前监听端口:%v", s.GetListenedPort()) - //addrs, _ := net.InterfaceAddrs() - //for _, addr := range addrs { - // if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil { - // g.Log().Infof(ctx, "访问地址:http://%v:%d", ipnet.IP.String(), s.GetListenedPort()) - // } - //} }) diff --git a/internal/cmd/p2p.go b/internal/cmd/p2p.go index 581b9bb..f70b0fb 100644 --- a/internal/cmd/p2p.go +++ b/internal/cmd/p2p.go @@ -74,9 +74,6 @@ var ( case "client": // 获取客户端模式所需的参数 g.Log().Debug(ctx, "开始执行client") - //addrs := []string{"/ip4/127.0.0.1/tcp/51888", "/ip4/192.168.50.173/tcp/51888"} - //addr := "/ip4/192.168.50.173/tcp/51888/p2p/12D3KooWJKBB9bF9MjqgsFYUUsPBG249FDq7a3ZdaYc9iw8G78JQ" - //addrs := "WyIvaXA0LzEyNy4wLjAuMS90Y3AvNTE4ODgiLCIvaXA0LzE5Mi4xNjguNTAuMTczL3RjcC81MTg4OCJd" wsStr := "ws://192.168.50.173:51888/ws" err = service.P2P().Start(wsStr) case "dht": diff --git a/internal/cmd/update.go b/internal/cmd/update.go index 012b9ec..bc9fc43 100644 --- a/internal/cmd/update.go +++ b/internal/cmd/update.go @@ -41,13 +41,14 @@ var ( // 拼接操作系统和架构(格式:OS_ARCH) platform := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH) - var versionFile = make(map[string]string) + rootDir := "server_update" + var versionFile = make(map[string]string) var filePath = path.Join(pathMain, version, platform, name) dirList, _ := gfile.ScanDir(path.Join(pathMain, version), "*", false) for _, v := range dirList { updatePlatform := gfile.Name(v) - updateFilePath := path.Join("server_update", name, version, updatePlatform) + updateFilePath := path.Join(rootDir, name, version, updatePlatform) var obj bytes.Buffer g.Log().Debugf(ctx, "读取目录成功:%v", v) @@ -70,14 +71,14 @@ var ( // 写入文件版本文件 fileByte := gjson.MustEncode(versionFile) - service.S3().PutObject(ctx, bytes.NewReader(fileByte), path.Join("server_update", name, "version.json")) + service.S3().PutObject(ctx, bytes.NewReader(fileByte), path.Join(rootDir, name, "version.json")) if err != nil { g.Log().Error(ctx, err) } } g.Log().Debugf(ctx, "当前获取到的地址为:%v", filePath) - versionUrl := service.S3().GetCdnUrl(path.Join("server_update", name, "version.json")) + versionUrl := service.S3().GetCdnUrl(path.Join(rootDir, name)) listVar := g.Cfg().MustGet(ctx, "p2p.list") var p2pItem []struct { Host string `json:"host"` @@ -96,7 +97,8 @@ var ( g.Log().Debugf(ctx, "开始上传到服务器:%v,file=%v", url, versionUrl) _, err := g.Client().Get(ctx, url, systemV1.UpdateReq{ - Url: versionUrl, + Url: versionUrl, + Version: version, }) if err != nil { g.Log().Error(ctx, err) diff --git a/internal/controller/system/system_v1_update.go b/internal/controller/system/system_v1_update.go index 6040eda..6d8df31 100644 --- a/internal/controller/system/system_v1_update.go +++ b/internal/controller/system/system_v1_update.go @@ -2,73 +2,66 @@ package system import ( "context" - "log" - "os" - "os/exec" - "path/filepath" - "time" + "net/url" + "path" "github.com/ayflying/p2p/api/system/v1" + "github.com/ayflying/p2p/internal/service" "github.com/gogf/gf/v2/crypto/gsha1" + "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gcmd" + "github.com/gogf/gf/v2/os/gfile" ) func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) { - getRunFile := gcmd.GetArg(0).String() - fileSha, err := gsha1.EncryptFile(getRunFile) - g.Dump(fileSha) - g.Dump(getRunFile) + g.Log().Debugf(ctx, "当前文件哈希值:%v", fileSha) - go func() { - log.Println("5秒后开始重启...") - time.Sleep(5 * time.Second) + versionUrl, _ := url.JoinPath(req.Url, "version.json") + resp, err := g.Client().Get(ctx, versionUrl) + var version map[string]string + gjson.DecodeTo(resp.ReadAll(), &version) - if err = restartSelf(); err != nil { - log.Fatalf("重启失败:%v", err) + for k, _ := range version { + //downloadUrl, _ := url.QueryUnescape(v) + downloadUrl, _ := url.JoinPath(req.Url, req.Version, k+".gz") + fileByte, err2 := g.Client().Get(ctx, downloadUrl) + if err2 != nil { + g.Log().Error(ctx, err2) + continue } - }() + putFile := path.Join("download", gfile.Basename(downloadUrl)) + err2 = gfile.PutBytes(putFile, fileByte.ReadAll()) + if err2 != nil { + g.Log().Error(ctx, err2) + continue + } + } + //更新文件 + err = service.System().Update(ctx) + type DataType struct { + File []byte `json:"file"` + Name string `json:"name"` + } + + var msgData = struct { + Files []*DataType `json:"files"` + }{} + + msgData.Files = []*DataType{} + + files, _ := gfile.ScanDir("download", ".*gz") + + for _, v := range files { + msgData.Files = append(msgData.Files, &DataType{ + File: gfile.GetBytes(v), + Name: gfile.Basename(v), + }) + } + + service.P2P().SendAll("update", msgData) return } - -// restartSelf 实现 Windows 平台下的程序自重启 -func restartSelf() error { - // 1. 获取当前程序的绝对路径 - exePath, err := os.Executable() - if err != nil { - return err - } - // 处理路径中的符号链接(确保路径正确) - exePath, err = filepath.EvalSymlinks(exePath) - if err != nil { - return err - } - - // 2. 获取命令行参数(os.Args[0] 是程序名,实际参数从 os.Args[1:] 开始) - args := os.Args[1:] - - // 3. 构建新进程命令(路径为当前程序,参数为原参数) - cmd := exec.Command(exePath, args...) - // 设置新进程的工作目录与当前进程一致 - cmd.Dir, err = os.Getwd() - if err != nil { - return err - } - - // 新进程的输出继承当前进程的标准输出(可选,根据需求调整) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - - // 4. 启动新进程(非阻塞,Start() 后立即返回) - if err := cmd.Start(); err != nil { - return err - } - - // 5. 新进程启动成功后,退出当前进程 - os.Exit(0) - return nil // 理论上不会执行到这里 -} diff --git a/internal/logic/logic.go b/internal/logic/logic.go index abc1b01..becac9d 100644 --- a/internal/logic/logic.go +++ b/internal/logic/logic.go @@ -8,4 +8,5 @@ import ( _ "github.com/ayflying/p2p/internal/logic/os" _ "github.com/ayflying/p2p/internal/logic/p2p" _ "github.com/ayflying/p2p/internal/logic/s3" + _ "github.com/ayflying/p2p/internal/logic/system" ) diff --git a/internal/logic/p2p/client.go b/internal/logic/p2p/client.go index a5f7c7d..ae34181 100644 --- a/internal/logic/p2p/client.go +++ b/internal/logic/p2p/client.go @@ -5,13 +5,14 @@ import ( "encoding/json" "fmt" "net" + "path" "strconv" "time" - "github.com/ayflying/p2p/internal/service" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/os/gtimer" "github.com/gogf/gf/v2/util/grand" @@ -420,18 +421,23 @@ func (s *sP2P) receiveGatewayMessages(ctx context.Context) { glog.Errorf(ctx, "网关错误: %s", data.Error) case MsgUpdate: //更新节点信息 var msgData struct { - Server string `json:"server"` - Version string `json:"version"` + Files []struct { + File []byte `json:"file"` + Name string `json:"name"` + } `json:"files"` } //var msgData *dataType json.Unmarshal(msg.Data, &msgData) + for _, v := range msgData.Files { + err = gfile.PutBytes(path.Join("download", v.Name), v.File) + } // 更新器路径(假设与主程序同目录) //updaterPath := filepath.Join(filepath.Dir(selfPath), "updater.exe") g.Log().Infof(ctx, "更新节点信息: %v", data) - // 调用不同系统的更新服务 - service.OS().Update(msgData.Version, msgData.Server) + //// 调用不同系统的更新服务 + //service.OS().Update(msgData.Version, msgData.Server) } } diff --git a/internal/logic/p2p/gateway.go b/internal/logic/p2p/gateway.go index e88f5f8..9edeaf1 100644 --- a/internal/logic/p2p/gateway.go +++ b/internal/logic/p2p/gateway.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "net" "strings" "time" @@ -66,14 +65,14 @@ func (s *sP2P) GatewayStart(ctx context.Context, group *ghttp.RouterGroup) (err _, data, _err := ws.ReadMessage() if _err != nil { //g.Log().Errorf(ctx, "读取消息失败: %v", err) - //s.sendError(ws, err.Error()) + //s.SendError(ws, err.Error()) break } - var msg GatewayMessage + var msg *GatewayMessage if err = json.Unmarshal(data, &msg); err != nil { //g.Log().Error(ctx, "消息格式错误") - s.sendError(ws, "消息格式错误") + s.SendError(ws, "消息格式错误") continue } @@ -96,7 +95,7 @@ func (s *sP2P) GatewayStart(ctx context.Context, group *ghttp.RouterGroup) (err } // 处理注册请求 -func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg GatewayMessage) { +func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg *GatewayMessage) { if msg.From == "" { g.Log().Error(ctx, "客户端ID不能为空") return @@ -108,22 +107,22 @@ func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg Gat } if err := json.Unmarshal(msg.Data, &data); err != nil { - s.sendError(conn, "注册数据格式错误") + s.SendError(conn, "注册数据格式错误") return } - // 追加公网ip - publicIp, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) - ParseIP := net.ParseIP(publicIp) - var ipType string - if ParseIP.To4() != nil { - ipType = "ip4" - } else { - ipType = "ip6" - } - port2 := 53533 - data.Addrs = append(data.Addrs, fmt.Sprintf("/%s/%s/tcp/%d", ipType, publicIp, port2)) - data.Addrs = append(data.Addrs, fmt.Sprintf("/%s/%s/udp/%d/quic-v1", ipType, publicIp, port2)) + //// 追加公网ip + //publicIp, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) + //ParseIP := net.ParseIP(publicIp) + //var ipType string + //if ParseIP.To4() != nil { + // ipType = "ip4" + //} else { + // ipType = "ip6" + //} + //port2 := 53533 + //data.Addrs = append(data.Addrs, fmt.Sprintf("/%s/%s/tcp/%d", ipType, publicIp, port2)) + //data.Addrs = append(data.Addrs, fmt.Sprintf("/%s/%s/udp/%d/quic-v1", ipType, publicIp, port2)) // 过滤回环地址 data.Addrs = s.filterLoopbackAddrs(data.Addrs) @@ -144,12 +143,12 @@ func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg Gat glog.Infof(ctx, "客户端 ip=%s,%s 注册成功,PeerID: %s", conn.RemoteAddr(), msg.From, data.PeerID) // 发送注册成功响应 - err := s.sendMessage(conn, GatewayMessage{ + err := s.sendMessage(conn, &GatewayMessage{ Type: MsgTypeRegisterAck, Data: json.RawMessage(`{"success": true, "message": "注册成功"}`), }) if err != nil { - s.sendError(conn, err.Error()) + s.SendError(conn, err.Error()) } } @@ -178,15 +177,41 @@ func (s *sP2P) cleanupClients(ctx context.Context) { } // 发送错误消息 -func (s *sP2P) sendError(conn *websocket.Conn, errMsg string) { - s.sendMessage(conn, GatewayMessage{ +func (s *sP2P) SendError(conn *websocket.Conn, errMsg string) { + s.sendMessage(conn, &GatewayMessage{ Type: "error", Data: json.RawMessage(fmt.Sprintf(`{"error": "%s"}`, errMsg)), }) } +// SendAll 发送消息给所有客户端 +func (s *sP2P) SendAll(typ string, data any) (err error) { + for _, client := range s.Clients { + conn := client.Conn + err = s.sendMessage(conn, &GatewayMessage{ + Type: MsgType(typ), + Data: gjson.MustEncode(data), + }) + if err != nil { + g.Log().Error(gctx.New(), err) + } + } + + return +} + +// Send 发送消息给指定客户端 +func (s *sP2P) Send(conn *websocket.Conn, typ string, data any) (err error) { + err = s.sendMessage(conn, &GatewayMessage{ + Type: MsgType(typ), + Data: gjson.MustEncode(data), + }) + + return +} + // 发送消息 -func (s *sP2P) sendMessage(conn *websocket.Conn, msg GatewayMessage) error { +func (s *sP2P) sendMessage(conn *websocket.Conn, msg *GatewayMessage) error { data, err := json.Marshal(msg) if err != nil { glog.Errorf(gctx.New(), "序列化消息失败: %v", err) @@ -196,9 +221,9 @@ func (s *sP2P) sendMessage(conn *websocket.Conn, msg GatewayMessage) error { } // 处理发现请求 -func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg GatewayMessage) { +func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg *GatewayMessage) { if msg.From == "" { - s.sendError(conn, "消息缺少发送方ID(from)") + s.SendError(conn, "消息缺少发送方ID(from)") return } @@ -207,12 +232,12 @@ func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg Gat } if err := json.Unmarshal(msg.Data, &data); err != nil { - s.sendError(conn, "发现请求格式错误,需包含target_id") + s.SendError(conn, "发现请求格式错误,需包含target_id") return } if data.TargetID == "" { - s.sendError(conn, "目标ID不能为空") + s.SendError(conn, "目标ID不能为空") return } @@ -225,7 +250,7 @@ func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg Gat s.lock.RUnlock() //if !fromExists { - // s.sendError(conn, "请先注册") + // s.SendError(conn, "请先注册") // return //} @@ -236,11 +261,10 @@ func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg Gat if targetClient == nil { // 目标不存在 - s.sendMessage(conn, GatewayMessage{ + s.sendMessage(conn, &GatewayMessage{ Type: MsgTypeDiscoverAck, From: "gateway", To: msg.From, - //Data: json.RawMessage(`{"found": false}`), Data: gjson.MustEncode(g.Map{ "found": false, }), @@ -249,7 +273,7 @@ func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg Gat } // 向请求方发送目标信息 - s.sendMessage(conn, GatewayMessage{ + s.sendMessage(conn, &GatewayMessage{ Type: MsgTypeDiscoverAck, From: "gateway", // 发送方是网关 To: msg.From, // 接收方是原请求方 @@ -262,7 +286,7 @@ func (s *sP2P) handleDiscover(ctx context.Context, conn *websocket.Conn, msg Gat }) // 向目标方发送打洞请求(协调时机) - s.sendMessage(targetClient.Conn, GatewayMessage{ + s.sendMessage(targetClient.Conn, &GatewayMessage{ Type: MsgTypePunchRequest, From: msg.From, // 发送方是原请求方 To: data.TargetID, // 接收方是目标方 diff --git a/internal/logic/p2p/p2p.go b/internal/logic/p2p/p2p.go index 8e8bd21..3d3efe4 100644 --- a/internal/logic/p2p/p2p.go +++ b/internal/logic/p2p/p2p.go @@ -26,8 +26,8 @@ var ( // 常量定义 const ( - ProtocolID string = "/ay" - DefaultPort = 51888 + ProtocolID string = "/ay" + //DefaultPort = 51888 ) var ( diff --git a/internal/logic/s3/s3.go b/internal/logic/s3/s3.go index 440d314..23bc837 100644 --- a/internal/logic/s3/s3.go +++ b/internal/logic/s3/s3.go @@ -58,7 +58,10 @@ func New(_name ...string) *sS3 { if len(_name) > 0 { name = _name[0] } else { - getName, _ := g.Cfg("local").Get(gctx.New(), "s3.type") + getName, err := g.Cfg("local").Get(gctx.New(), "s3.type") + if err != nil { + return nil + } name = getName.String() } diff --git a/internal/logic/system/system.go b/internal/logic/system/system.go new file mode 100644 index 0000000..8dcf66e --- /dev/null +++ b/internal/logic/system/system.go @@ -0,0 +1,17 @@ +package system + +import ( + "github.com/ayflying/p2p/internal/service" +) + +type sSystem struct{} + +func New() *sSystem { + return &sSystem{} +} + +func init() { + service.RegisterSystem(New()) +} + +func (system *sSystem) Init() {} diff --git a/internal/logic/system/update.go b/internal/logic/system/update.go new file mode 100644 index 0000000..2c4721d --- /dev/null +++ b/internal/logic/system/update.go @@ -0,0 +1,98 @@ +package system + +import ( + "context" + "fmt" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "runtime" + "time" + + "github.com/ayflying/p2p/internal/service" + "github.com/gogf/gf/v2/encoding/gcompress" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gcmd" +) + +func (s *sSystem) Update(ctx context.Context) (err error) { + //拼接操作系统和架构(格式:OS_ARCH) + platform := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH) + + runFile := gcmd.GetArg(0).String() + oldFile, err := service.System().RenameRunningFile(runFile) + g.Log().Debugf(ctx, "执行文件改名为%v", oldFile) + gz := path.Join("download", platform+".gz") + err = gcompress.UnGzipFile(gz, runFile) + + go func() { + log.Println("5秒后开始重启...") + time.Sleep(5 * time.Second) + + if err = service.System().RestartSelf(); err != nil { + log.Fatalf("重启失败:%v", err) + } + }() + return +} + +// RestartSelf 实现 Windows 平台下的程序自重启 +func (s *sSystem) RestartSelf() error { + // 1. 获取当前程序的绝对路径 + exePath, err := os.Executable() + if err != nil { + return err + } + // 处理路径中的符号链接(确保路径正确) + exePath, err = filepath.EvalSymlinks(exePath) + if err != nil { + return err + } + + // 2. 获取命令行参数(os.Args[0] 是程序名,实际参数从 os.Args[1:] 开始) + args := os.Args[1:] + + // 3. 构建新进程命令(路径为当前程序,参数为原参数) + cmd := exec.Command(exePath, args...) + // 设置新进程的工作目录与当前进程一致 + cmd.Dir, err = os.Getwd() + if err != nil { + return err + } + + // 新进程的输出继承当前进程的标准输出(可选,根据需求调整) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + + // 4. 启动新进程(非阻塞,Start() 后立即返回) + if err := cmd.Start(); err != nil { + return err + } + + // 5. 新进程启动成功后,退出当前进程 + os.Exit(0) + return nil // 理论上不会执行到这里 +} + +// RenameRunningFile 重命名正在运行的程序文件(如 p2p.exe → p2p.exe~) +func (s *sSystem) RenameRunningFile(exePath string) (string, error) { + // 目标备份文件名(p2p.exe → p2p.exe~) + backupPath := exePath + "~" + + // 先删除已存在的备份文件(若有) + if _, err := os.Stat(backupPath); err == nil { + if err := os.Remove(backupPath); err != nil { + return "", fmt.Errorf("删除旧备份文件失败: %v", err) + } + } + + // 重命名正在运行的 exe 文件 + // 关键:Windows 允许对锁定的文件执行重命名操作 + if err := os.Rename(exePath, backupPath); err != nil { + return "", fmt.Errorf("重命名运行中文件失败: %v", err) + } + return backupPath, nil +} diff --git a/internal/service/p_2_p.go b/internal/service/p_2_p.go index 9d69ebd..f8a610c 100644 --- a/internal/service/p_2_p.go +++ b/internal/service/p_2_p.go @@ -9,6 +9,7 @@ import ( "context" "github.com/gogf/gf/v2/net/ghttp" + "github.com/gorilla/websocket" "github.com/libp2p/go-libp2p/core/host" ) @@ -28,6 +29,12 @@ type ( // FindFromDHT 从 DHT 查找数据(从网络节点获取) FindFromDHT(ctx context.Context, key string) (string, error) GatewayStart(ctx context.Context, group *ghttp.RouterGroup) (err error) + // 发送错误消息 + SendError(conn *websocket.Conn, errMsg string) + // SendAll 发送消息给所有客户端 + SendAll(typ string, data any) (err error) + // Send 发送消息给指定客户端 + Send(conn *websocket.Conn, typ string, data any) (err error) // 只获取IPv4公网IP(过滤IPv6结果) GetIPv4PublicIP() (string, error) } diff --git a/internal/service/system.go b/internal/service/system.go new file mode 100644 index 0000000..66bf346 --- /dev/null +++ b/internal/service/system.go @@ -0,0 +1,36 @@ +// ================================================================================ +// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. +// You can delete these comments if you wish manually maintain this interface file. +// ================================================================================ + +package service + +import ( + "context" +) + +type ( + ISystem interface { + Init() + Update(ctx context.Context) (err error) + // RestartSelf 实现 Windows 平台下的程序自重启 + RestartSelf() error + // RenameRunningFile 重命名正在运行的程序文件(如 p2p.exe → p2p.exe~) + RenameRunningFile(exePath string) (string, error) + } +) + +var ( + localSystem ISystem +) + +func System() ISystem { + if localSystem == nil { + panic("implement not found for interface ISystem, forgot register?") + } + return localSystem +} + +func RegisterSystem(i ISystem) { + localSystem = i +} diff --git a/main.go b/main.go index 500d25c..4c7df4c 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,15 @@ package main import ( + "fmt" + "os" + _ "github.com/ayflying/p2p/internal/logic" _ "github.com/ayflying/p2p/internal/packed" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gcmd" "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/os/gtime" //步骤1:加载驱动 _ "github.com/gogf/gf/contrib/nosql/redis/v2" @@ -17,9 +23,39 @@ var ( ) func main() { + g.Log().Infof(ctx, "启动文件最后修改时间:%v", gtime.New(gfile.MTime(gcmd.GetArg(0).String())).String()) + g.Dump("v1.0.0.2") + if ok := gfile.Exists("runtime"); !ok { gfile.Mkdir("runtime") } + //daili() + cmd.Main.Run(ctx) } + +func daili() { + + // 读取HTTP代理环境变量(小写/大写通常都兼容,部分系统可能用大写) + httpProxy := os.Getenv("http_proxy") + if httpProxy == "" { + httpProxy = os.Getenv("HTTP_PROXY") + } + + // 读取HTTPS代理环境变量 + httpsProxy := os.Getenv("https_proxy") + if httpsProxy == "" { + httpsProxy = os.Getenv("HTTPS_PROXY") + } + + // 读取无代理列表(不使用代理的域名/IP) + noProxy := os.Getenv("no_proxy") + if noProxy == "" { + noProxy = os.Getenv("NO_PROXY") + } + + fmt.Printf("HTTP 代理: %s\n", httpProxy) + fmt.Printf("HTTPS 代理: %s\n", httpsProxy) + fmt.Printf("无代理列表: %s\n", noProxy) +}