mirror of
https://github.com/ayflying/p2p.git
synced 2026-03-05 01:39:23 +00:00
Compare commits
20 Commits
v0.0.5
...
d3e5787508
| Author | SHA1 | Date | |
|---|---|---|---|
| d3e5787508 | |||
| 413df78f51 | |||
| 07c5527243 | |||
|
|
680d36e526 | ||
|
|
0a5432406a | ||
|
|
7b16777411 | ||
|
|
69b4380e38 | ||
|
|
e856543529 | ||
|
|
4bed53dc16 | ||
| 14f98a6009 | |||
| 610ae3aab2 | |||
| 4c4db5e9e2 | |||
| 01cd7ae6e3 | |||
| 8d41c1ba62 | |||
| 22b4402737 | |||
| 8b943b0cca | |||
| 03f762e910 | |||
| 84723248cd | |||
| d3f3687201 | |||
| 63f5bef038 |
22
.github/workflows/release.yml
vendored
22
.github/workflows/release.yml
vendored
@@ -14,18 +14,24 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
# runs-on指定了运行作业的虚拟机环境类型
|
||||||
|
# 即使使用container,runs-on仍然是必要的配置
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
# 移除容器配置以避免Docker Hub拉取超时问题
|
||||||
|
# 直接在GitHub托管的runner环境中执行任务
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4 # 使用最新稳定的v4版本
|
||||||
|
|
||||||
|
# GitHub Actions的runner环境通常已预装Go,Setup Go步骤会处理版本管理
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24.x'
|
go-version: 'stable' # 使用最新稳定版本的Go,无需手动更新版本号
|
||||||
|
|
||||||
- name: Install gf CLI
|
- name: Install gf CLI
|
||||||
run: |
|
run: |
|
||||||
|
# 直接下载GF CLI,不使用缓存以避免超时问题
|
||||||
|
echo "Downloading GF CLI"
|
||||||
curl -L -o gf https://github.com/gogf/gf/releases/latest/download/gf_linux_amd64
|
curl -L -o gf https://github.com/gogf/gf/releases/latest/download/gf_linux_amd64
|
||||||
chmod +x gf
|
chmod +x gf
|
||||||
mkdir -p "$HOME/bin"
|
mkdir -p "$HOME/bin"
|
||||||
@@ -39,7 +45,7 @@ jobs:
|
|||||||
run: gf build -ew -v "${{ github.ref_name }}"
|
run: gf build -ew -v "${{ github.ref_name }}"
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4 # 使用v4版本
|
||||||
with:
|
with:
|
||||||
name: p2p-${{ github.ref_name }}
|
name: p2p-${{ github.ref_name }}
|
||||||
path: |
|
path: |
|
||||||
@@ -47,13 +53,17 @@ jobs:
|
|||||||
|
|
||||||
release:
|
release:
|
||||||
needs: build
|
needs: build
|
||||||
|
# runs-on指定了运行作业的虚拟机环境类型
|
||||||
|
# 即使使用container,runs-on仍然是必要的配置
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
# 移除容器配置以避免Docker Hub拉取超时问题
|
||||||
|
# 直接在GitHub托管的runner环境中执行任务
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4 # 使用v4版本
|
||||||
with:
|
with:
|
||||||
name: p2p-${{ github.ref_name }}
|
name: p2p-${{ github.ref_name }}
|
||||||
path: bin
|
path: bin
|
||||||
@@ -84,7 +94,7 @@ jobs:
|
|||||||
ls -al dist
|
ls -al dist
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2 # 更新到最新稳定的v2版本
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
tag_name: ${{ github.ref_name }}
|
tag_name: ${{ github.ref_name }}
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,8 +16,9 @@ manifest/output/
|
|||||||
temp/
|
temp/
|
||||||
temp.yaml
|
temp.yaml
|
||||||
bin
|
bin
|
||||||
**/config/config.yaml
|
|
||||||
v1.0.0/
|
v1.0.0/
|
||||||
config/local.yaml
|
config/local.yaml
|
||||||
main.exe~
|
main.exe~
|
||||||
download/
|
download/
|
||||||
|
version.txt
|
||||||
|
internal/packed/build_pack_data.go
|
||||||
|
|||||||
@@ -1,11 +1 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import "github.com/gogf/gf/v2/frame/g"
|
|
||||||
|
|
||||||
type UpdateReq struct {
|
|
||||||
g.Meta `path:"/system/update" tags:"system" method:"get" sm:"更新服务端"`
|
|
||||||
Url string `json:"url" dc:"更新地址"`
|
|
||||||
Version string `json:"version" dc:"当前版本"`
|
|
||||||
}
|
|
||||||
type UpdateRes struct {
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,50 +1,42 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/icza/icox" // 替换为icox库
|
|
||||||
"github.com/nfnt/resize"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// 1. 读取PNG文件
|
//// 1. 读取PNG文件
|
||||||
inputPath := "manifest/images/logo.png" // 输入PNG路径
|
//inputPath := "manifest/images/logo.png" // 输入PNG路径
|
||||||
outputPath := "manifest/images/favicon.ico" // 输出ICO路径
|
//outputPath := "manifest/images/favicon.ico" // 输出ICO路径
|
||||||
|
//
|
||||||
pngFile, err := os.Open(inputPath)
|
//pngFile, err := os.Open(inputPath)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
panic("无法打开PNG文件: " + err.Error())
|
// panic("无法打开PNG文件: " + err.Error())
|
||||||
}
|
//}
|
||||||
defer pngFile.Close()
|
//defer pngFile.Close()
|
||||||
|
//
|
||||||
// 2. 解码PNG为image.Image对象
|
//// 2. 解码PNG为image.Image对象
|
||||||
img, _, err := image.Decode(pngFile)
|
//img, _, err := image.Decode(pngFile)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
panic("PNG解码失败: " + err.Error())
|
// panic("PNG解码失败: " + err.Error())
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// 3. 定义ICO需要包含的尺寸(常见尺寸)
|
//// 3. 定义ICO需要包含的尺寸(常见尺寸)
|
||||||
sizes := []uint{16, 32, 64, 128} // 可根据需求添加更多尺寸
|
//sizes := []uint{16, 32, 64, 128} // 可根据需求添加更多尺寸
|
||||||
var icoImages []image.Image
|
//var icoImages []image.Image
|
||||||
|
//
|
||||||
// 4. 缩放图像到每个目标尺寸并收集
|
//// 4. 缩放图像到每个目标尺寸并收集
|
||||||
for _, size := range sizes {
|
//for _, size := range sizes {
|
||||||
// 使用Lanczos3算法缩放(高质量)
|
// // 使用Lanczos3算法缩放(高质量)
|
||||||
resized := resize.Resize(size, size, img, resize.Lanczos3)
|
// resized := resize.Resize(size, size, img, resize.Lanczos3)
|
||||||
icoImages = append(icoImages, resized)
|
// icoImages = append(icoImages, resized)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// 5. 编码为ICO并写入文件(关键修改:使用icox.Encode)
|
//// 5. 编码为ICO并写入文件(关键修改:使用icox.Encode)
|
||||||
icoFile, err := os.Create(outputPath)
|
//icoFile, err := os.Create(outputPath)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
panic("无法创建ICO文件: " + err.Error())
|
// panic("无法创建ICO文件: " + err.Error())
|
||||||
}
|
//}
|
||||||
defer icoFile.Close()
|
//defer icoFile.Close()
|
||||||
|
//
|
||||||
// icox.Encode直接支持多尺寸切片[]image.Image
|
//// icox.Encode直接支持多尺寸切片[]image.Image
|
||||||
if err := icox.Encode(icoFile, icoImages); err != nil {
|
//if err := icox.Encode(icoFile, icoImages); err != nil {
|
||||||
panic("ICO编码失败: " + err.Error())
|
// panic("ICO编码失败: " + err.Error())
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
18
go.mod
18
go.mod
@@ -1,19 +1,19 @@
|
|||||||
module github.com/ayflying/p2p
|
module github.com/ayflying/p2p
|
||||||
|
|
||||||
go 1.24.0
|
go 1.24.8
|
||||||
|
|
||||||
|
toolchain go1.24.9
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9
|
github.com/ayflying/update-github-release v0.0.7
|
||||||
github.com/dop251/goja v0.0.0-20250630131328-58d95d85e994
|
github.com/dop251/goja v0.0.0-20250630131328-58d95d85e994
|
||||||
github.com/getlantern/systray v1.2.2
|
github.com/getlantern/systray v1.2.2
|
||||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.3
|
github.com/gogf/gf/v2 v2.9.4
|
||||||
github.com/gogf/gf/v2 v2.9.3
|
|
||||||
github.com/google/uuid v1.6.0
|
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/libp2p/go-libp2p v0.43.0
|
github.com/libp2p/go-libp2p v0.43.0
|
||||||
github.com/libp2p/go-libp2p-kad-dht v0.35.1
|
github.com/libp2p/go-libp2p-kad-dht v0.35.1
|
||||||
|
github.com/minio/minio-go/v7 v7.0.95
|
||||||
github.com/multiformats/go-multiaddr v0.16.1
|
github.com/multiformats/go-multiaddr v0.16.1
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -24,7 +24,6 @@ require (
|
|||||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
|
||||||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/emirpasic/gods v1.18.1 // indirect
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
@@ -47,6 +46,7 @@ require (
|
|||||||
github.com/goccy/go-json v0.10.5 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/google/gopacket v1.1.19 // indirect
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect
|
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||||
github.com/huin/goupnp v1.3.0 // indirect
|
github.com/huin/goupnp v1.3.0 // indirect
|
||||||
@@ -81,7 +81,6 @@ require (
|
|||||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
||||||
github.com/minio/crc64nvme v1.0.2 // indirect
|
github.com/minio/crc64nvme v1.0.2 // indirect
|
||||||
github.com/minio/md5-simd v1.1.2 // indirect
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
github.com/minio/minio-go/v7 v7.0.95 // indirect
|
|
||||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||||
@@ -97,7 +96,7 @@ require (
|
|||||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
|
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
|
||||||
github.com/olekukonko/errors v1.1.0 // indirect
|
github.com/olekukonko/errors v1.1.0 // indirect
|
||||||
github.com/olekukonko/ll v0.1.1 // indirect
|
github.com/olekukonko/ll v0.1.1 // indirect
|
||||||
github.com/olekukonko/tablewriter v1.0.9 // indirect
|
github.com/olekukonko/tablewriter v1.1.0 // indirect
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
||||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
||||||
github.com/philhofer/fwd v1.2.0 // indirect
|
github.com/philhofer/fwd v1.2.0 // indirect
|
||||||
@@ -128,7 +127,6 @@ require (
|
|||||||
github.com/quic-go/qpack v0.5.1 // indirect
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
github.com/quic-go/quic-go v0.54.0 // indirect
|
github.com/quic-go/quic-go v0.54.0 // indirect
|
||||||
github.com/quic-go/webtransport-go v0.9.0 // indirect
|
github.com/quic-go/webtransport-go v0.9.0 // indirect
|
||||||
github.com/redis/go-redis/v9 v9.12.1 // indirect
|
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/rs/xid v1.6.0 // indirect
|
github.com/rs/xid v1.6.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
|||||||
24
go.sum
24
go.sum
@@ -10,21 +10,17 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy
|
|||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9 h1:1ltqoej5GtaWF8jaiA49HwsZD459jqm9YFz9ZtMFpQA=
|
|
||||||
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I=
|
|
||||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
|
github.com/ayflying/update-github-release v0.0.7 h1:ymeiJf71oQveuWedgOYChbVG1pc4dxOc2QDupG+7ltY=
|
||||||
|
github.com/ayflying/update-github-release v0.0.7/go.mod h1:9ctXuagiEKABWLaS4ocRCUcnN77jdYm7zir7NQ+rIeM=
|
||||||
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
||||||
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
|
||||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
|
||||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
|
||||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@@ -42,8 +38,6 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
|
|||||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
|
||||||
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||||
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/dop251/goja v0.0.0-20250630131328-58d95d85e994 h1:aQYWswi+hRL2zJqGacdCZx32XjKYV8ApXFGntw79XAM=
|
github.com/dop251/goja v0.0.0-20250630131328-58d95d85e994 h1:aQYWswi+hRL2zJqGacdCZx32XjKYV8ApXFGntw79XAM=
|
||||||
@@ -98,10 +92,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
|||||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.3 h1:VTbeHq8XpBCWFIwBGmuBl+jP8AepULnpgNz8GPBKBRQ=
|
github.com/gogf/gf/v2 v2.9.4 h1:6vleEWypot9WBPncP2GjbpgAUeG6Mzb1YESb9nPMkjY=
|
||||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.3/go.mod h1:gcidgAYn4IWbx08QUThg7jw6bz3KklXI9/5zg8jnVHY=
|
github.com/gogf/gf/v2 v2.9.4/go.mod h1:Ukl+5HUH9S7puBmNLR4L1zUqeRwi0nrW4OigOknEztU=
|
||||||
github.com/gogf/gf/v2 v2.9.3 h1:qjN4s55FfUzxZ1AE8vUHNDX3V0eIOUGXhF2DjRTVZQ4=
|
|
||||||
github.com/gogf/gf/v2 v2.9.3/go.mod h1:w6rcfD13SmO7FKI80k9LSLiSMGqpMYp50Nfkrrc2sEE=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||||
@@ -273,16 +265,14 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
|
||||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
|
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
|
||||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
|
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
|
||||||
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
|
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
|
||||||
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||||
github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc=
|
github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc=
|
||||||
github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo=
|
github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo=
|
||||||
github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8=
|
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
|
||||||
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
|
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
|
||||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||||
@@ -355,8 +345,6 @@ github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQB
|
|||||||
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||||
github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70=
|
github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70=
|
||||||
github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao=
|
github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao=
|
||||||
github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg=
|
|
||||||
github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
|||||||
37
internal/boot/boot.go
Normal file
37
internal/boot/boot.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package boot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
updateGithub "github.com/ayflying/update-github-release"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/gcron"
|
||||||
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Boot() {
|
||||||
|
|
||||||
|
getDev, _ := g.Cfg().GetWithEnv(gctx.New(), "dev")
|
||||||
|
if !getDev.Bool() {
|
||||||
|
url := "https://api.github.com/repos/ayflying/p2p/releases/latest"
|
||||||
|
var update = updateGithub.New(url)
|
||||||
|
// 每天0点检查更新
|
||||||
|
gcron.Add(gctx.New(), "0 0 0 * * *", func(ctx context.Context) {
|
||||||
|
err := update.CheckUpdate(true)
|
||||||
|
if err != nil {
|
||||||
|
g.Log().Errorf(ctx, "检查更新失败:%v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
//在协程中检查更新,预防主程序阻塞
|
||||||
|
err := update.CheckUpdate(true)
|
||||||
|
if err != nil {
|
||||||
|
g.Log().Errorf(gctx.New(), "检查更新失败:%v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
} else {
|
||||||
|
g.Log().Debugf(gctx.New(), "开发模式,不检查更新")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ayflying/p2p/internal/boot"
|
||||||
"github.com/ayflying/p2p/internal/consts"
|
"github.com/ayflying/p2p/internal/consts"
|
||||||
"github.com/ayflying/p2p/internal/controller/p2p"
|
"github.com/ayflying/p2p/internal/controller/p2p"
|
||||||
"github.com/ayflying/p2p/internal/controller/system"
|
|
||||||
"github.com/ayflying/p2p/internal/service"
|
"github.com/ayflying/p2p/internal/service"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/net/ghttp"
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
err := Main.AddCommand(&Main, &Debug, &Update)
|
err := Main.AddCommand(&Main, &Debug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.Log().Error(gctx.GetInitCtx(), err)
|
g.Log().Error(gctx.GetInitCtx(), err)
|
||||||
return
|
return
|
||||||
@@ -32,6 +32,10 @@ var (
|
|||||||
Brief: "start http server",
|
Brief: "start http server",
|
||||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||||
g.Log().Debug(ctx, "开始执行main")
|
g.Log().Debug(ctx, "开始执行main")
|
||||||
|
|
||||||
|
// 初始化服务器
|
||||||
|
boot.Boot()
|
||||||
|
|
||||||
Version, err := g.Cfg("hack").Get(ctx, "gfcli.build.version")
|
Version, err := g.Cfg("hack").Get(ctx, "gfcli.build.version")
|
||||||
g.Log().Debugf(ctx, "当前启动的版本为:%v", Version)
|
g.Log().Debugf(ctx, "当前启动的版本为:%v", Version)
|
||||||
|
|
||||||
@@ -69,7 +73,6 @@ var (
|
|||||||
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
||||||
group.Bind(
|
group.Bind(
|
||||||
p2p.NewV1(),
|
p2p.NewV1(),
|
||||||
system.NewV1(),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"path"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
systemV1 "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/gcompress"
|
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
|
||||||
"github.com/gogf/gf/v2/os/gcfg"
|
|
||||||
"github.com/gogf/gf/v2/os/gcmd"
|
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Update = gcmd.Command{
|
|
||||||
Name: "update",
|
|
||||||
Usage: "update",
|
|
||||||
Brief: "更新版本",
|
|
||||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
|
||||||
g.Log().Info(ctx, "准备上传更新文件")
|
|
||||||
//加载编辑配置文件
|
|
||||||
g.Cfg("hack").GetAdapter().(*gcfg.AdapterFile).SetFileName("hack/config.yaml")
|
|
||||||
//获取文件名
|
|
||||||
getName, err := g.Cfg("hack").Get(ctx, "gfcli.build.name")
|
|
||||||
name := getName.String()
|
|
||||||
|
|
||||||
getPath, err := g.Cfg("hack").Get(ctx, "gfcli.build.path")
|
|
||||||
pathMain := getPath.String()
|
|
||||||
|
|
||||||
//获取版本号
|
|
||||||
getVersion, err := g.Cfg("hack").Get(ctx, "gfcli.build.version")
|
|
||||||
version := getVersion.String()
|
|
||||||
|
|
||||||
// 拼接操作系统和架构(格式:OS_ARCH)
|
|
||||||
platform := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH)
|
|
||||||
|
|
||||||
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(rootDir, name, version, updatePlatform)
|
|
||||||
|
|
||||||
var obj bytes.Buffer
|
|
||||||
g.Log().Debugf(ctx, "读取目录成功:%v", v)
|
|
||||||
fileMian := path.Join(v, name)
|
|
||||||
g.Log().Debugf(ctx, "判断当前文件是否存在:%v", fileMian)
|
|
||||||
if gfile.IsFile(fileMian) {
|
|
||||||
// 写入文件哈希
|
|
||||||
versionFile[updatePlatform] = gsha1.MustEncryptFile(fileMian)
|
|
||||||
err = gcompress.GzipPathWriter(fileMian, &obj)
|
|
||||||
service.S3().PutObject(ctx, &obj, updateFilePath+".gz")
|
|
||||||
g.Log().Debugf(ctx, "成功上传文件到:%v", updateFilePath+".gz")
|
|
||||||
}
|
|
||||||
if gfile.IsFile(fileMian + ".exe") {
|
|
||||||
// 写入文件哈希
|
|
||||||
versionFile[updatePlatform] = gsha1.MustEncryptFile(fileMian + ".exe")
|
|
||||||
err = gcompress.GzipPathWriter(fileMian+".exe", &obj)
|
|
||||||
service.S3().PutObject(ctx, &obj, updateFilePath+".gz")
|
|
||||||
g.Log().Debugf(ctx, "成功上传文件到:%v", updateFilePath+".gz")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写入文件版本文件
|
|
||||||
fileByte := gjson.MustEncode(versionFile)
|
|
||||||
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(rootDir, name))
|
|
||||||
listVar := g.Cfg().MustGet(ctx, "message.list")
|
|
||||||
var p2pItem []struct {
|
|
||||||
Host string `json:"host"`
|
|
||||||
Port int `json:"port"`
|
|
||||||
SSL bool `json:"ssl"`
|
|
||||||
Ws string `json:"ws"`
|
|
||||||
}
|
|
||||||
listVar.Scan(&p2pItem)
|
|
||||||
for _, v := range p2pItem {
|
|
||||||
|
|
||||||
url := "http"
|
|
||||||
if v.SSL == true {
|
|
||||||
url = "https"
|
|
||||||
}
|
|
||||||
url = fmt.Sprintf("%s://%s:%d/system/update", url, v.Host, v.Port)
|
|
||||||
|
|
||||||
g.Log().Debugf(ctx, "开始上传到服务器:%v,file=%v", url, versionUrl)
|
|
||||||
_, err := g.Client().Get(ctx, url, systemV1.UpdateReq{
|
|
||||||
Url: versionUrl,
|
|
||||||
Version: version,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
g.Log().Error(ctx, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}}
|
|
||||||
)
|
|
||||||
@@ -4,12 +4,4 @@
|
|||||||
|
|
||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ayflying/p2p/api/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ControllerV1 struct{}
|
type ControllerV1 struct{}
|
||||||
|
|
||||||
func NewV1() system.ISystemV1 {
|
|
||||||
return &ControllerV1{}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"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.Log().Debugf(ctx, "当前文件哈希值:%v", fileSha)
|
|
||||||
|
|
||||||
versionUrl, _ := url.JoinPath(req.Url, "version.json")
|
|
||||||
resp, err := g.Client().Get(ctx, versionUrl)
|
|
||||||
var version map[string]string
|
|
||||||
gjson.DecodeTo(resp.ReadAll(), &version)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataType struct {
|
|
||||||
File []byte `json:"file"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//var GatewayMessage *message.GatewayMessage
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
//更新自己的文件
|
|
||||||
//err = service.System().Update(ctx)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -12,17 +12,29 @@ import (
|
|||||||
"github.com/gogf/gf/v2/os/gcmd"
|
"github.com/gogf/gf/v2/os/gcmd"
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
"github.com/gogf/gf/v2/os/gfile"
|
||||||
|
"github.com/gogf/gf/v2/os/gres"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 引入 Windows API 函数
|
// 引入 Windows API 函数
|
||||||
var (
|
var (
|
||||||
user32 = syscall.NewLazyDLL("user32.dll")
|
user32 = syscall.NewLazyDLL("user32.dll")
|
||||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
showWindow = user32.NewProc("ShowWindow")
|
showWindow = user32.NewProc("ShowWindow")
|
||||||
getConsoleWnd = kernel32.NewProc("GetConsoleWindow")
|
getConsoleWnd = kernel32.NewProc("GetConsoleWindow")
|
||||||
|
freeConsole = kernel32.NewProc("FreeConsole")
|
||||||
|
attachConsole = kernel32.NewProc("AttachConsole")
|
||||||
|
allocConsole = kernel32.NewProc("AllocConsole")
|
||||||
|
setConsoleCtrlHandler = kernel32.NewProc("SetConsoleCtrlHandler")
|
||||||
|
consoleCtrlHandler uintptr
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ctrlCloseEvent = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *sOS) start() {
|
func (s *sOS) start() {
|
||||||
|
// 注册控制台关闭事件处理:点击叉叉仅隐藏控制台而不退出程序
|
||||||
|
s.setupConsoleCloseHandler()
|
||||||
|
|
||||||
// 系统托盘初始化(设置图标、右键菜单)
|
// 系统托盘初始化(设置图标、右键菜单)
|
||||||
go systray.Run(s.onSystrayReady, s.onSystrayExit)
|
go systray.Run(s.onSystrayReady, s.onSystrayExit)
|
||||||
@@ -30,9 +42,21 @@ func (s *sOS) start() {
|
|||||||
|
|
||||||
// 系统托盘初始化(设置图标、右键菜单)
|
// 系统托盘初始化(设置图标、右键菜单)
|
||||||
func (s *sOS) onSystrayReady() {
|
func (s *sOS) onSystrayReady() {
|
||||||
//s.hideConsole()
|
// s.hideConsole()
|
||||||
|
var iconByte []byte
|
||||||
|
if !gfile.Exists(s.systray.Icon) {
|
||||||
|
iconByte = gres.GetContent(s.systray.Icon)
|
||||||
|
gfile.PutBytes(s.systray.Icon, iconByte)
|
||||||
|
}
|
||||||
|
iconByte = gfile.GetBytes(s.systray.Icon)
|
||||||
|
|
||||||
|
//if gres.Contains(s.systray.Icon) {
|
||||||
|
// iconByte = gres.GetContent(s.systray.Icon)
|
||||||
|
// gfile.PutBytes(s.systray.Icon, iconByte)
|
||||||
|
//} else {
|
||||||
|
// iconByte = gfile.GetBytes(s.systray.Icon)
|
||||||
|
//}
|
||||||
|
|
||||||
iconByte := gfile.GetBytes(s.systray.Icon)
|
|
||||||
systray.SetIcon(iconByte)
|
systray.SetIcon(iconByte)
|
||||||
systray.SetTitle(s.systray.Title)
|
systray.SetTitle(s.systray.Title)
|
||||||
systray.SetTooltip(s.systray.Tooltip)
|
systray.SetTooltip(s.systray.Tooltip)
|
||||||
@@ -46,6 +70,7 @@ func (s *sOS) onSystrayReady() {
|
|||||||
select {
|
select {
|
||||||
case <-mQuit.ClickedCh:
|
case <-mQuit.ClickedCh:
|
||||||
systray.Quit()
|
systray.Quit()
|
||||||
|
|
||||||
case <-mShow.ClickedCh:
|
case <-mShow.ClickedCh:
|
||||||
// 显示窗口
|
// 显示窗口
|
||||||
s.showConsole()
|
s.showConsole()
|
||||||
@@ -77,13 +102,12 @@ func (s *sOS) update(version, server string) {
|
|||||||
|
|
||||||
// 隐藏控制台窗口
|
// 隐藏控制台窗口
|
||||||
func (s *sOS) hideConsole() {
|
func (s *sOS) hideConsole() {
|
||||||
// 获取当前控制台窗口句柄
|
// 仅隐藏控制台窗口(保留现有缓冲区以便后续显示时保留历史日志)
|
||||||
hWnd, _, _ := getConsoleWnd.Call()
|
hWnd, _, _ := getConsoleWnd.Call()
|
||||||
if hWnd == 0 {
|
if hWnd != 0 {
|
||||||
return // 无控制台窗口(如编译为GUI子系统时)
|
// SW_HIDE = 0:隐藏窗口
|
||||||
|
showWindow.Call(hWnd, 0)
|
||||||
}
|
}
|
||||||
// SW_HIDE = 0:隐藏窗口
|
|
||||||
showWindow.Call(hWnd, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示控制台窗口
|
// 显示控制台窗口
|
||||||
@@ -91,8 +115,40 @@ func (s *sOS) showConsole() {
|
|||||||
// 获取当前控制台窗口句柄
|
// 获取当前控制台窗口句柄
|
||||||
hWnd, _, _ := getConsoleWnd.Call()
|
hWnd, _, _ := getConsoleWnd.Call()
|
||||||
if hWnd == 0 {
|
if hWnd == 0 {
|
||||||
|
// 如果当前进程没有控制台,尝试附加到父进程控制台
|
||||||
|
// ATTACH_PARENT_PROCESS = (DWORD)-1
|
||||||
|
ret, _, _ := attachConsole.Call(uintptr(^uint32(0)))
|
||||||
|
if ret == 0 {
|
||||||
|
// 附加失败则分配一个新的控制台窗口
|
||||||
|
allocConsole.Call()
|
||||||
|
}
|
||||||
|
// 重新获取控制台窗口句柄
|
||||||
|
hWnd, _, _ = getConsoleWnd.Call()
|
||||||
|
}
|
||||||
|
if hWnd != 0 {
|
||||||
|
// SW_SHOW = 5:显示窗口
|
||||||
|
showWindow.Call(hWnd, 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册控制台关闭事件处理器,将关闭事件转换为隐藏行为
|
||||||
|
func (s *sOS) setupConsoleCloseHandler() {
|
||||||
|
if consoleCtrlHandler != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// SW_SHOW = 5:显示窗口
|
consoleCtrlHandler = syscall.NewCallback(func(ctrlType uint32) uintptr {
|
||||||
showWindow.Call(hWnd, 5)
|
if ctrlType == ctrlCloseEvent {
|
||||||
|
// 用户点击控制台窗口的关闭按钮(X):仅隐藏,不退出
|
||||||
|
hWnd, _, _ := getConsoleWnd.Call()
|
||||||
|
if hWnd != 0 {
|
||||||
|
// SW_HIDE = 0
|
||||||
|
showWindow.Call(hWnd, 0)
|
||||||
|
}
|
||||||
|
// 返回 TRUE 表示事件已处理,阻止默认终止行为
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
// 其他事件交由系统默认处理
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
setConsoleCtrlHandler.Call(consoleCtrlHandler, uintptr(1))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ func (s *sP2P) register() error {
|
|||||||
addrs[i] = addr.String()
|
addrs[i] = addr.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ports, _ := s.getLocalTCPPorts(s.client.host)
|
||||||
// 构建注册消息
|
// 构建注册消息
|
||||||
msg := GatewayMessage{
|
msg := GatewayMessage{
|
||||||
Type: MsgTypeRegister,
|
Type: MsgTypeRegister,
|
||||||
@@ -185,6 +186,7 @@ func (s *sP2P) register() error {
|
|||||||
Data: gjson.MustEncode(g.Map{
|
Data: gjson.MustEncode(g.Map{
|
||||||
"peer_id": s.client.host.ID().String(),
|
"peer_id": s.client.host.ID().String(),
|
||||||
"addrs": addrs,
|
"addrs": addrs,
|
||||||
|
"ports": ports,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -104,6 +105,7 @@ func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg *Ga
|
|||||||
var data struct {
|
var data struct {
|
||||||
PeerID string `json:"peer_id"`
|
PeerID string `json:"peer_id"`
|
||||||
Addrs []string `json:"addrs"`
|
Addrs []string `json:"addrs"`
|
||||||
|
Ports []int `json:"ports"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(msg.Data, &data); err != nil {
|
if err := json.Unmarshal(msg.Data, &data); err != nil {
|
||||||
@@ -111,18 +113,20 @@ func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg *Ga
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//// 追加公网ip
|
// 追加公网ip
|
||||||
//publicIp, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
publicIp, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
||||||
//ParseIP := net.ParseIP(publicIp)
|
ParseIP := net.ParseIP(publicIp)
|
||||||
//var ipType string
|
var ipType string
|
||||||
//if ParseIP.To4() != nil {
|
if ParseIP.To4() != nil {
|
||||||
// ipType = "ip4"
|
ipType = "ip4"
|
||||||
//} else {
|
} else {
|
||||||
// ipType = "ip6"
|
ipType = "ip6"
|
||||||
//}
|
}
|
||||||
//port2 := 53533
|
//port2 := 53533
|
||||||
//data.Addrs = append(data.Addrs, fmt.Sprintf("/%s/%s/tcp/%d", ipType, publicIp, port2))
|
for _, port2 := range data.Ports {
|
||||||
//data.Addrs = append(data.Addrs, fmt.Sprintf("/%s/%s/udp/%d/quic-v1", ipType, publicIp, port2))
|
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)
|
data.Addrs = s.filterLoopbackAddrs(data.Addrs)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -80,46 +79,6 @@ func init() {
|
|||||||
ip, _ = service.P2P().GetIPv4PublicIP()
|
ip, _ = service.P2P().GetIPv4PublicIP()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取公网IP并判断类型(ipv4/ipv6)
|
|
||||||
func (s *sP2P) getPublicIPAndType() (ip string, ipType string, err error) {
|
|
||||||
// 公网IP查询接口(多个备用)
|
|
||||||
|
|
||||||
client := http.Client{Timeout: 5 * time.Second}
|
|
||||||
for _, api := range ipAPIs {
|
|
||||||
resp, err := client.Get(api)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
// 读取响应(纯IP字符串)
|
|
||||||
buf := make([]byte, 128)
|
|
||||||
n, err := resp.Body.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ip = strings.TrimSpace(string(buf[:n]))
|
|
||||||
if ip == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断IP类型
|
|
||||||
parsedIP := net.ParseIP(ip)
|
|
||||||
if parsedIP == nil {
|
|
||||||
continue // 无效IP格式
|
|
||||||
}
|
|
||||||
|
|
||||||
if parsedIP.To4() != nil {
|
|
||||||
return ip, "ipv4", nil // IPv4
|
|
||||||
} else if parsedIP.To16() != nil {
|
|
||||||
return ip, "ipv6", nil // IPv6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", "", fmt.Errorf("所有公网IP查询接口均失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 只获取IPv4公网IP(过滤IPv6结果)
|
// 只获取IPv4公网IP(过滤IPv6结果)
|
||||||
func (s *sP2P) GetIPv4PublicIP() (string, error) {
|
func (s *sP2P) GetIPv4PublicIP() (string, error) {
|
||||||
ctx := gctx.New()
|
ctx := gctx.New()
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type T struct {
|
|
||||||
Url string `json:"url"`
|
|
||||||
AssetsUrl string `json:"assets_url"`
|
|
||||||
UploadUrl string `json:"upload_url"`
|
|
||||||
HtmlUrl string `json:"html_url"`
|
|
||||||
Id int `json:"id"`
|
|
||||||
Author *Author `json:"author"`
|
|
||||||
NodeId string `json:"node_id"`
|
|
||||||
TagName string `json:"tag_name"`
|
|
||||||
TargetCommitish string `json:"target_commitish"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Draft bool `json:"draft"`
|
|
||||||
Immutable bool `json:"immutable"`
|
|
||||||
Prerelease bool `json:"prerelease"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
PublishedAt time.Time `json:"published_at"`
|
|
||||||
Assets []*Assets
|
|
||||||
TarballUrl string `json:"tarball_url"`
|
|
||||||
ZipballUrl string `json:"zipball_url"`
|
|
||||||
Body string `json:"body"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Author struct {
|
|
||||||
Login string `json:"login"`
|
|
||||||
Id int `json:"id"`
|
|
||||||
NodeId string `json:"node_id"`
|
|
||||||
AvatarUrl string `json:"avatar_url"`
|
|
||||||
GravatarId string `json:"gravatar_id"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
HtmlUrl string `json:"html_url"`
|
|
||||||
FollowersUrl string `json:"followers_url"`
|
|
||||||
FollowingUrl string `json:"following_url"`
|
|
||||||
GistsUrl string `json:"gists_url"`
|
|
||||||
StarredUrl string `json:"starred_url"`
|
|
||||||
SubscriptionsUrl string `json:"subscriptions_url"`
|
|
||||||
OrganizationsUrl string `json:"organizations_url"`
|
|
||||||
ReposUrl string `json:"repos_url"`
|
|
||||||
EventsUrl string `json:"events_url"`
|
|
||||||
ReceivedEventsUrl string `json:"received_events_url"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
UserViewType string `json:"user_view_type"`
|
|
||||||
SiteAdmin bool `json:"site_admin"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Assets struct {
|
|
||||||
Url string `json:"url"`
|
|
||||||
Id int `json:"id"`
|
|
||||||
NodeId string `json:"node_id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Label string `json:"label"`
|
|
||||||
Uploader *Uploader `json:"uploader"`
|
|
||||||
ContentType string `json:"content_type"`
|
|
||||||
State string `json:"state"`
|
|
||||||
Size int `json:"size"`
|
|
||||||
Digest string `json:"digest"`
|
|
||||||
DownloadCount int `json:"download_count"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
BrowserDownloadUrl string `json:"browser_download_url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Uploader struct {
|
|
||||||
Login string `json:"login"`
|
|
||||||
Id int `json:"id"`
|
|
||||||
NodeId string `json:"node_id"`
|
|
||||||
AvatarUrl string `json:"avatar_url"`
|
|
||||||
GravatarId string `json:"gravatar_id"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
HtmlUrl string `json:"html_url"`
|
|
||||||
FollowersUrl string `json:"followers_url"`
|
|
||||||
FollowingUrl string `json:"following_url"`
|
|
||||||
GistsUrl string `json:"gists_url"`
|
|
||||||
StarredUrl string `json:"starred_url"`
|
|
||||||
SubscriptionsUrl string `json:"subscriptions_url"`
|
|
||||||
OrganizationsUrl string `json:"organizations_url"`
|
|
||||||
ReposUrl string `json:"repos_url"`
|
|
||||||
EventsUrl string `json:"events_url"`
|
|
||||||
ReceivedEventsUrl string `json:"received_events_url"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
UserViewType string `json:"user_view_type"`
|
|
||||||
SiteAdmin bool `json:"site_admin"`
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,5 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/ayflying/p2p/internal/service"
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
|
||||||
"github.com/gogf/gf/v2/os/gcron"
|
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sSystem struct{}
|
type sSystem struct{}
|
||||||
|
|
||||||
func New() *sSystem {
|
func New() *sSystem {
|
||||||
@@ -16,25 +7,7 @@ func New() *sSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
service.RegisterSystem(New())
|
|
||||||
|
|
||||||
getDev, _ := g.Cfg().GetWithEnv(gctx.New(), "dev")
|
|
||||||
if !getDev.Bool() {
|
|
||||||
// 每天0点检查更新
|
|
||||||
gcron.Add(gctx.New(), "0 0 0 * * *", func(ctx context.Context) {
|
|
||||||
err := service.System().CheckUpdate()
|
|
||||||
if err != nil {
|
|
||||||
g.Log().Errorf(ctx, "检查更新失败:%v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
err := service.System().CheckUpdate()
|
|
||||||
if err != nil {
|
|
||||||
g.Log().Errorf(gctx.New(), "检查更新失败:%v", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g.Log().Debugf(gctx.New(), "开发模式,不检查更新")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sSystem) Init() {}
|
func (s *sSystem) Init() {}
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"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/net/ghttp"
|
|
||||||
"github.com/gogf/gf/v2/os/gcmd"
|
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 本地版本号(建议从编译参数注入,如 -ldflags "-X main.version=v0.1.3")
|
|
||||||
const versionFile = "version.txt"
|
|
||||||
|
|
||||||
var localVersion = "v0.0.0"
|
|
||||||
|
|
||||||
// 对应 GitHub API 响应的核心字段(按需精简)
|
|
||||||
type GitHubRelease struct {
|
|
||||||
Url string `json:"url"`
|
|
||||||
AssetsUrl string `json:"assets_url"`
|
|
||||||
UploadUrl string `json:"upload_url"`
|
|
||||||
HtmlUrl string `json:"html_url"`
|
|
||||||
Id int `json:"id"`
|
|
||||||
TagName string `json:"tag_name"`
|
|
||||||
Assets []*Assets `json:"assets"`
|
|
||||||
NodeId string `json:"node_id"`
|
|
||||||
TargetCommitish string `json:"target_commitish"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Draft bool `json:"draft"`
|
|
||||||
Immutable bool `json:"immutable"`
|
|
||||||
Prerelease bool `json:"prerelease"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
PublishedAt time.Time `json:"published_at"`
|
|
||||||
TarballUrl string `json:"tarball_url"`
|
|
||||||
ZipballUrl string `json:"zipball_url"`
|
|
||||||
Body string `json:"body"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sSystem) Update(ctx context.Context, gzFile string) (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)
|
|
||||||
if gzFile == "" {
|
|
||||||
gzFile = path.Join("download", platform+".gz")
|
|
||||||
}
|
|
||||||
//结束后删除压缩包
|
|
||||||
defer gfile.RemoveFile(gzFile)
|
|
||||||
|
|
||||||
ext := gfile.Ext(gzFile)
|
|
||||||
if ext == ".zip" {
|
|
||||||
g.Log().Debugf(ctx, "zip解压%v到%v", gzFile, gfile.Dir(runFile))
|
|
||||||
err = gcompress.UnZipFile(gzFile, gfile.Dir(runFile))
|
|
||||||
} else {
|
|
||||||
g.Log().Debugf(ctx, "gzip解压%v到%v", gzFile, runFile)
|
|
||||||
err = gcompress.UnGzipFile(gzFile, runFile)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
ctx := gctx.New()
|
|
||||||
// 判断是否为linux平台
|
|
||||||
if runtime.GOOS == "linux" {
|
|
||||||
err := ghttp.RestartAllServer(ctx, os.Args[0])
|
|
||||||
if err != nil {
|
|
||||||
g.Log().Errorf(ctx, "重启失败:%v", err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 重命名正在运行的程序文件(如 message.exe → message.exe~)
|
|
||||||
func (s *sSystem) RenameRunningFile(exePath string) (string, error) {
|
|
||||||
// 目标备份文件名(message.exe → message.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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简化版版本对比(仅适用于 vX.Y.Z 格式)
|
|
||||||
func (s *sSystem) isNewVersion(local, latest string) bool {
|
|
||||||
// 移除前缀 "v",按 "." 分割成数字切片
|
|
||||||
localParts := strings.Split(strings.TrimPrefix(local, "v"), ".")
|
|
||||||
latestParts := strings.Split(strings.TrimPrefix(latest, "v"), ".")
|
|
||||||
|
|
||||||
// 逐段对比版本号(如 0.1.3 vs 0.1.4 → 后者更新)
|
|
||||||
for i := 0; i < len(localParts) && i < len(latestParts); i++ {
|
|
||||||
if localParts[i] < latestParts[i] {
|
|
||||||
return true
|
|
||||||
} else if localParts[i] > latestParts[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 若前缀相同,长度更长的版本更新(如 0.1 vs 0.1.1)
|
|
||||||
return len(localParts) < len(latestParts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sSystem) getLatestVersion() (string, []*Assets, error) {
|
|
||||||
apiURL := "https://api.github.com/repos/ayflying/p2p/releases/latest"
|
|
||||||
resp, err := http.Get(apiURL)
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, fmt.Errorf("请求失败:%v", err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return "", nil, fmt.Errorf("API 响应错误:%d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
var release GitHubRelease
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
|
|
||||||
return "", nil, fmt.Errorf("解析响应失败:%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return release.TagName, release.Assets, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sSystem) CheckUpdate() (err error) {
|
|
||||||
ctx := gctx.New()
|
|
||||||
latestVersion, assets, err := s.getLatestVersion()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("检查更新失败:%v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
localVersion = gfile.GetContents(versionFile)
|
|
||||||
|
|
||||||
if s.isNewVersion(localVersion, latestVersion) {
|
|
||||||
g.Log().Printf(ctx, "发现新版本:%s(当前版本:%s)", latestVersion, localVersion)
|
|
||||||
//拼接操作系统和架构(格式:OS_ARCH)
|
|
||||||
platform := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH)
|
|
||||||
//name := fmt.Sprintf("p2p_%s_%s.tar.gz", latestVersion, platform)
|
|
||||||
fmt.Println("下载链接:")
|
|
||||||
for _, asset := range assets {
|
|
||||||
if strings.Contains(fmt.Sprintf("_%s.", asset.Name), platform) {
|
|
||||||
fmt.Printf("- %s\n", asset.BrowserDownloadUrl)
|
|
||||||
|
|
||||||
// 下载更新文件
|
|
||||||
fileDownload, err2 := g.Client().Get(ctx, asset.BrowserDownloadUrl)
|
|
||||||
if err2 != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
updateFile := path.Join("download", asset.Name)
|
|
||||||
err = gfile.PutBytes(updateFile, fileDownload.ReadAll())
|
|
||||||
|
|
||||||
err = s.Update(ctx, updateFile)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 保存最新版本号到文件
|
|
||||||
gfile.PutContents(versionFile, latestVersion)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Printf("当前已是最新版本:%s\n", localVersion)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1 +1,2 @@
|
|||||||
package packed
|
package packed
|
||||||
|
|
||||||
|
|||||||
5
main.go
5
main.go
@@ -10,9 +10,8 @@ import (
|
|||||||
"github.com/gogf/gf/v2/os/gcmd"
|
"github.com/gogf/gf/v2/os/gcmd"
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
"github.com/gogf/gf/v2/os/gfile"
|
||||||
"github.com/gogf/gf/v2/os/gtime"
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
|
|
||||||
//步骤1:加载驱动
|
//步骤1:加载驱动
|
||||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
//_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||||
|
|
||||||
"github.com/ayflying/p2p/internal/cmd"
|
"github.com/ayflying/p2p/internal/cmd"
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
@@ -24,7 +23,7 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
g.Log().Infof(ctx, "启动文件最后修改时间:%v", gtime.New(gfile.MTime(gcmd.GetArg(0).String())).String())
|
g.Log().Infof(ctx, "启动文件最后修改时间:%v", gtime.New(gfile.MTime(gcmd.GetArg(0).String())).String())
|
||||||
g.Dump("v1.0.0.2")
|
//g.Dump("v1.0.0.2")
|
||||||
|
|
||||||
if ok := gfile.Exists("runtime"); !ok {
|
if ok := gfile.Exists("runtime"); !ok {
|
||||||
gfile.Mkdir("runtime")
|
gfile.Mkdir("runtime")
|
||||||
|
|||||||
46
manifest/config/config.yaml
Normal file
46
manifest/config/config.yaml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
module:
|
||||||
|
server: true
|
||||||
|
client: true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# https://goframe.org/docs/web/server-config-file-template
|
||||||
|
server:
|
||||||
|
address: "51888"
|
||||||
|
# openapiPath: "/api.json"
|
||||||
|
# swaggerPath: "/swagger"
|
||||||
|
dumpRouterMap: false
|
||||||
|
graceful: true
|
||||||
|
|
||||||
|
# https://goframe.org/docs/core/glog-config
|
||||||
|
logger:
|
||||||
|
level : "all"
|
||||||
|
stdout: true
|
||||||
|
|
||||||
|
# https://goframe.org/docs/core/gdb-config-file
|
||||||
|
database:
|
||||||
|
default:
|
||||||
|
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
default:
|
||||||
|
address: "ay.cname.com:6379"
|
||||||
|
db: 15
|
||||||
|
pass: "12345678"
|
||||||
|
cache:
|
||||||
|
address: "ay.cname.com:6379"
|
||||||
|
db: 15
|
||||||
|
pass: "12345678"
|
||||||
|
|
||||||
|
p2p:
|
||||||
|
list:
|
||||||
|
- host: "host.yunloli.cn"
|
||||||
|
port: 51888
|
||||||
|
ssl: false
|
||||||
|
ws: ws
|
||||||
|
- host: "ay.cname.com"
|
||||||
|
port: 51888
|
||||||
|
ssl: false
|
||||||
|
ws: ws
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user