mirror of
https://github.com/XrayR-project/XrayR.git
synced 2025-07-30 06:04:31 +00:00
Compare commits
12 Commits
v0.9.4
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e00514674c | ||
![]() |
b1f5ccfee8 | ||
![]() |
2f88334373 | ||
![]() |
35e726e766 | ||
![]() |
4bbf3c9899 | ||
![]() |
9391c759c9 | ||
![]() |
eb16b709e2 | ||
![]() |
1f09502613 | ||
![]() |
0ae73a0eca | ||
![]() |
63c1a18a7d | ||
![]() |
34726d1659 | ||
![]() |
5edc68d475 |
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
|||||||
- build
|
- build
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4.1.7
|
||||||
with:
|
with:
|
||||||
name: digests
|
name: digests
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
|
@@ -2,92 +2,71 @@ package gov2panel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/XrayR-project/XrayR/api"
|
||||||
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
"github.com/bitly/go-simplejson"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/gogf/gf/v2/net/gclient"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/infra/conf"
|
"github.com/xtls/xray-core/infra/conf"
|
||||||
|
|
||||||
"github.com/XrayR-project/XrayR/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIClient create an api client to the panel.
|
// APIClient API config
|
||||||
type APIClient struct {
|
type APIClient struct {
|
||||||
client *resty.Client
|
ctx context.Context
|
||||||
APIHost string
|
APIHost string
|
||||||
NodeID int
|
NodeID int
|
||||||
Key string
|
Key string
|
||||||
NodeType string
|
NodeType string
|
||||||
EnableVless bool
|
EnableVless bool
|
||||||
VlessFlow string
|
VlessFlow string
|
||||||
SpeedLimit float64
|
Timeout int
|
||||||
DeviceLimit int
|
SpeedLimit float64
|
||||||
|
DeviceLimit int
|
||||||
|
RuleListPath string
|
||||||
|
DisableCustomConfig bool
|
||||||
|
|
||||||
LocalRuleList []api.DetectRule
|
LocalRuleList []api.DetectRule
|
||||||
resp atomic.Value
|
|
||||||
eTags map[string]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New create an api instance
|
// New create an api instance
|
||||||
func New(apiConfig *api.Config) *APIClient {
|
func New(apiConfig *api.Config) *APIClient {
|
||||||
client := resty.New()
|
|
||||||
client.SetRetryCount(3)
|
//https://goframe.org/pages/viewpage.action?pageId=1114381
|
||||||
if apiConfig.Timeout > 0 {
|
|
||||||
client.SetTimeout(time.Duration(apiConfig.Timeout) * time.Second)
|
|
||||||
} else {
|
|
||||||
client.SetTimeout(5 * time.Second)
|
|
||||||
}
|
|
||||||
client.OnError(func(req *resty.Request, err error) {
|
|
||||||
if v, ok := err.(*resty.ResponseError); ok {
|
|
||||||
// v.Response contains the last response from the server
|
|
||||||
// v.Err contains the original error
|
|
||||||
log.Print(v.Err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
client.SetBaseURL(apiConfig.APIHost)
|
|
||||||
// Create Key for each requests
|
|
||||||
client.SetQueryParams(map[string]string{
|
|
||||||
"node_id": strconv.Itoa(apiConfig.NodeID),
|
|
||||||
"node_type": strings.ToLower(apiConfig.NodeType),
|
|
||||||
"token": apiConfig.Key,
|
|
||||||
})
|
|
||||||
// Read local rule list
|
|
||||||
localRuleList := readLocalRuleList(apiConfig.RuleListPath)
|
|
||||||
apiClient := &APIClient{
|
apiClient := &APIClient{
|
||||||
client: client,
|
ctx: context.Background(),
|
||||||
NodeID: apiConfig.NodeID,
|
APIHost: apiConfig.APIHost,
|
||||||
Key: apiConfig.Key,
|
NodeID: apiConfig.NodeID,
|
||||||
APIHost: apiConfig.APIHost,
|
Key: apiConfig.Key,
|
||||||
NodeType: apiConfig.NodeType,
|
NodeType: apiConfig.NodeType,
|
||||||
EnableVless: apiConfig.EnableVless,
|
EnableVless: apiConfig.EnableVless,
|
||||||
VlessFlow: apiConfig.VlessFlow,
|
VlessFlow: apiConfig.VlessFlow,
|
||||||
SpeedLimit: apiConfig.SpeedLimit,
|
Timeout: apiConfig.Timeout,
|
||||||
DeviceLimit: apiConfig.DeviceLimit,
|
DeviceLimit: apiConfig.DeviceLimit,
|
||||||
LocalRuleList: localRuleList,
|
RuleListPath: apiConfig.RuleListPath,
|
||||||
eTags: make(map[string]string),
|
DisableCustomConfig: apiConfig.DisableCustomConfig,
|
||||||
|
|
||||||
|
LocalRuleList: readLocalRuleList(apiConfig.RuleListPath), //加载本地路由规则
|
||||||
}
|
}
|
||||||
return apiClient
|
return apiClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// readLocalRuleList reads the local rule list file
|
// readLocalRuleList reads the local rule list file
|
||||||
func readLocalRuleList(path string) (LocalRuleList []api.DetectRule) {
|
func readLocalRuleList(path string) (LocalRuleList []api.DetectRule) {
|
||||||
LocalRuleList = make([]api.DetectRule, 0)
|
|
||||||
|
|
||||||
|
LocalRuleList = make([]api.DetectRule, 0)
|
||||||
if path != "" {
|
if path != "" {
|
||||||
// open the file
|
// open the file
|
||||||
file, err := os.Open(path)
|
file, err := os.Open(path)
|
||||||
defer file.Close()
|
|
||||||
// handle errors while opening
|
// handle errors while opening
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error when opening file: %s", err)
|
log.Printf("Error when opening file: %s", err)
|
||||||
@@ -108,96 +87,77 @@ func readLocalRuleList(path string) (LocalRuleList []api.DetectRule) {
|
|||||||
log.Fatalf("Error while reading file: %s", err)
|
log.Fatalf("Error while reading file: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
return LocalRuleList
|
return LocalRuleList
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe return a description of the client
|
|
||||||
func (c *APIClient) Describe() api.ClientInfo {
|
|
||||||
return api.ClientInfo{APIHost: c.APIHost, NodeID: c.NodeID, Key: c.Key, NodeType: c.NodeType}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug set the client debug for client
|
|
||||||
func (c *APIClient) Debug() {
|
|
||||||
c.client.SetDebug(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *APIClient) assembleURL(path string) string {
|
|
||||||
return c.APIHost + path
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *APIClient) parseResponse(res *resty.Response, path string, err error) (*simplejson.Json, error) {
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("request %s failed: %v", c.assembleURL(path), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.StatusCode() > 399 {
|
|
||||||
return nil, fmt.Errorf("request %s failed: %s, %v", c.assembleURL(path), res.String(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rtn, err := simplejson.NewJson(res.Body())
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("ret %s invalid", res.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNodeInfo will pull NodeInfo Config from panel
|
|
||||||
func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) {
|
func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) {
|
||||||
server := new(serverConfig)
|
|
||||||
path := "/api/server/config"
|
|
||||||
|
|
||||||
res, err := c.client.R().
|
apiPath := "/api/server/config"
|
||||||
SetHeader("If-None-Match", c.eTags["node"]).
|
reslutJson, err := c.sendRequest(
|
||||||
ForceContentType("application/json").
|
nil,
|
||||||
Get(path)
|
"POST",
|
||||||
|
apiPath,
|
||||||
// Etag identifier for a specific version of a resource. StatusCode = 304 means no changed
|
g.Map{})
|
||||||
if res.StatusCode() == 304 {
|
|
||||||
return nil, errors.New(api.NodeNotModified)
|
|
||||||
}
|
|
||||||
// update etag
|
|
||||||
if res.Header().Get("Etag") != "" && res.Header().Get("Etag") != c.eTags["node"] {
|
|
||||||
c.eTags["node"] = res.Header().Get("Etag")
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeInfoResp, err := c.parseResponse(res, path, err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
b, _ := nodeInfoResp.Encode()
|
|
||||||
json.Unmarshal(b, server)
|
|
||||||
|
|
||||||
if gconv.Uint32(server.Port) == 0 {
|
if reslutJson.Get("data").String() == "" {
|
||||||
|
return nil, errors.New("gov2panel node config data is null")
|
||||||
|
}
|
||||||
|
|
||||||
|
if reslutJson.Get("data.port").Int() == 0 {
|
||||||
return nil, errors.New("server port must > 0")
|
return nil, errors.New("server port must > 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.resp.Store(server)
|
nodeInfo = new(api.NodeInfo)
|
||||||
|
err = reslutJson.Get("data").Scan(nodeInfo)
|
||||||
switch c.NodeType {
|
|
||||||
case "V2ray", "Vmess", "Vless":
|
|
||||||
nodeInfo, err = c.parseV2rayNodeResponse(server)
|
|
||||||
case "Trojan":
|
|
||||||
nodeInfo, err = c.parseTrojanNodeResponse(server)
|
|
||||||
case "Shadowsocks":
|
|
||||||
nodeInfo, err = c.parseSSNodeResponse(server)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unsupported node type: %s", c.NodeType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse node info failed: %s, \nError: %v", res.String(), err)
|
return nil, fmt.Errorf("parse node info failed: \nError: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
routes := make([]route, 0)
|
||||||
|
err = reslutJson.Get("data.routes").Scan(&routes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parse node routes failed: \nError: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeInfo.NodeType = c.NodeType
|
||||||
|
nodeInfo.NodeID = c.NodeID
|
||||||
|
nodeInfo.EnableVless = c.EnableVless
|
||||||
|
nodeInfo.VlessFlow = c.VlessFlow
|
||||||
|
|
||||||
|
nodeInfo.AlterID = 0
|
||||||
|
|
||||||
|
nodeInfo.NameServerConfig = parseDNSConfig(routes)
|
||||||
|
|
||||||
return nodeInfo, nil
|
return nodeInfo, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDNSConfig(routes []route) (nameServerList []*conf.NameServerConfig) {
|
||||||
|
|
||||||
|
nameServerList = make([]*conf.NameServerConfig, 0)
|
||||||
|
for i := range routes {
|
||||||
|
if routes[i].Action == "dns" {
|
||||||
|
nameServerList = append(nameServerList, &conf.NameServerConfig{
|
||||||
|
Address: &conf.Address{Address: net.ParseAddress(routes[i].ActionValue)},
|
||||||
|
Domains: routes[i].Match,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserList will pull user form panel
|
// GetUserList will pull user form panel
|
||||||
func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
|
func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
|
||||||
var users []*user
|
|
||||||
path := "/api/server/user"
|
apiPath := "/api/server/user"
|
||||||
|
|
||||||
switch c.NodeType {
|
switch c.NodeType {
|
||||||
case "V2ray", "Trojan", "Shadowsocks", "Vmess", "Vless":
|
case "V2ray", "Trojan", "Shadowsocks", "Vmess", "Vless":
|
||||||
@@ -206,29 +166,17 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
|
|||||||
return nil, fmt.Errorf("unsupported node type: %s", c.NodeType)
|
return nil, fmt.Errorf("unsupported node type: %s", c.NodeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.client.R().
|
reslutJson, err := c.sendRequest(
|
||||||
SetHeader("If-None-Match", c.eTags["users"]).
|
nil,
|
||||||
ForceContentType("application/json").
|
"GET",
|
||||||
Get(path)
|
apiPath,
|
||||||
|
g.Map{})
|
||||||
// Etag identifier for a specific version of a resource. StatusCode = 304 means no changed
|
|
||||||
if res.StatusCode() == 304 {
|
|
||||||
return nil, errors.New(api.UserNotModified)
|
|
||||||
}
|
|
||||||
// update etag
|
|
||||||
if res.Header().Get("Etag") != "" && res.Header().Get("Etag") != c.eTags["users"] {
|
|
||||||
c.eTags["users"] = res.Header().Get("Etag")
|
|
||||||
}
|
|
||||||
|
|
||||||
usersResp, err := c.parseResponse(res, path, err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
b, _ := usersResp.Get("users").Encode()
|
|
||||||
json.Unmarshal(b, &users)
|
var users []*user
|
||||||
if len(users) == 0 {
|
reslutJson.Get("data.users").Scan(&users)
|
||||||
return nil, errors.New("users is null")
|
|
||||||
}
|
|
||||||
|
|
||||||
userList := make([]api.UserInfo, len(users))
|
userList := make([]api.UserInfo, len(users))
|
||||||
for i := 0; i < len(users); i++ {
|
for i := 0; i < len(users); i++ {
|
||||||
@@ -255,148 +203,126 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
|
|||||||
return &userList, nil
|
return &userList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReportUserTraffic reports the user traffic
|
func (c *APIClient) ReportNodeStatus(nodeStatus *api.NodeStatus) (err error) {
|
||||||
func (c *APIClient) ReportUserTraffic(userTraffic *[]api.UserTraffic) error {
|
return
|
||||||
path := "/api/server/push"
|
}
|
||||||
|
|
||||||
res, err := c.client.R().SetBody(userTraffic).ForceContentType("application/json").Post(path)
|
func (c *APIClient) ReportNodeOnlineUsers(onlineUser *[]api.OnlineUser) (err error) {
|
||||||
_, err = c.parseResponse(res, path, err)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportUserTraffic reports the user traffic
|
||||||
|
func (c *APIClient) ReportUserTraffic(userTraffic *[]api.UserTraffic) (err error) {
|
||||||
|
apiPath := "/api/server/push"
|
||||||
|
reslutJson, err := c.sendRequest(
|
||||||
|
nil,
|
||||||
|
"POST",
|
||||||
|
apiPath,
|
||||||
|
g.Map{
|
||||||
|
"data": userTraffic,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if reslutJson.Get("code").Int() != 0 {
|
||||||
}
|
return errors.New(reslutJson.Get("message").String())
|
||||||
|
}
|
||||||
// GetNodeRule implements the API interface
|
|
||||||
func (c *APIClient) GetNodeRule() (*[]api.DetectRule, error) {
|
return
|
||||||
routes := c.resp.Load().(*serverConfig).Routes
|
}
|
||||||
|
|
||||||
ruleList := c.LocalRuleList
|
func (c *APIClient) Describe() api.ClientInfo {
|
||||||
|
return api.ClientInfo{APIHost: c.APIHost, NodeID: c.NodeID, Key: c.Key, NodeType: c.NodeType}
|
||||||
for i := range routes {
|
}
|
||||||
if routes[i].Action == "block" {
|
|
||||||
|
// GetNodeRule implements the API interface
|
||||||
ruleList = append(ruleList, api.DetectRule{
|
func (c *APIClient) GetNodeRule() (*[]api.DetectRule, error) {
|
||||||
ID: i,
|
ruleList := c.LocalRuleList
|
||||||
Pattern: regexp.MustCompile(strings.Join(routes[i].Match, "|")),
|
|
||||||
})
|
apiPath := "/api/server/config"
|
||||||
}
|
reslutJson, err := c.sendRequest(
|
||||||
}
|
nil,
|
||||||
|
"POST",
|
||||||
return &ruleList, nil
|
apiPath,
|
||||||
}
|
g.Map{})
|
||||||
|
if err != nil {
|
||||||
// ReportNodeStatus implements the API interface
|
return nil, err
|
||||||
func (c *APIClient) ReportNodeStatus(nodeStatus *api.NodeStatus) (err error) {
|
}
|
||||||
return nil
|
|
||||||
}
|
routes := make([]route, 0)
|
||||||
|
err = reslutJson.Get("data.routes").Scan(&routes)
|
||||||
// ReportNodeOnlineUsers implements the API interface
|
if err != nil {
|
||||||
func (c *APIClient) ReportNodeOnlineUsers(onlineUserList *[]api.OnlineUser) error {
|
return nil, fmt.Errorf("parse node routes failed: \nError: %v", err)
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
|
for i := range routes {
|
||||||
// ReportIllegal implements the API interface
|
if routes[i].Action == "block" {
|
||||||
func (c *APIClient) ReportIllegal(detectResultList *[]api.DetectResult) error {
|
for _, v := range routes[i].Match {
|
||||||
return nil
|
ruleList = append(ruleList, api.DetectRule{
|
||||||
}
|
ID: i,
|
||||||
|
Pattern: regexp.MustCompile(v),
|
||||||
// parseTrojanNodeResponse parse the response for the given nodeInfo format
|
})
|
||||||
func (c *APIClient) parseTrojanNodeResponse(s *serverConfig) (*api.NodeInfo, error) {
|
}
|
||||||
// Create GeneralNodeInfo
|
|
||||||
nodeInfo := &api.NodeInfo{
|
}
|
||||||
NodeType: c.NodeType,
|
}
|
||||||
NodeID: c.NodeID,
|
|
||||||
Port: gconv.Uint32(s.Port),
|
return &ruleList, nil
|
||||||
TransportProtocol: "tcp",
|
|
||||||
EnableTLS: true,
|
}
|
||||||
Host: s.Host,
|
|
||||||
ServiceName: s.Sni,
|
func (c *APIClient) ReportIllegal(detectResultList *[]api.DetectResult) (err error) {
|
||||||
NameServerConfig: s.parseDNSConfig(),
|
return
|
||||||
}
|
}
|
||||||
return nodeInfo, nil
|
|
||||||
}
|
func (c *APIClient) Debug() {
|
||||||
|
|
||||||
// parseSSNodeResponse parse the response for the given nodeInfo format
|
}
|
||||||
func (c *APIClient) parseSSNodeResponse(s *serverConfig) (*api.NodeInfo, error) {
|
|
||||||
var header json.RawMessage
|
// request 统一请求接口
|
||||||
|
func (c *APIClient) sendRequest(headerM map[string]string, method string, url string, data g.Map) (reslutJson *gjson.Json, err error) {
|
||||||
if s.Obfs == "http" {
|
url = c.APIHost + url
|
||||||
path := "/"
|
|
||||||
if p := s.ObfsSettings.Path; p != "" {
|
client := gclient.New()
|
||||||
if strings.HasPrefix(p, "/") {
|
|
||||||
path = p
|
var gResponse *gclient.Response
|
||||||
} else {
|
|
||||||
path += p
|
if c.Timeout > 0 {
|
||||||
}
|
client.SetTimeout(time.Duration(c.Timeout) * time.Second) //方法用于设置当前请求超时时间
|
||||||
}
|
} else {
|
||||||
h := simplejson.New()
|
client.SetTimeout(5 * time.Second)
|
||||||
h.Set("type", "http")
|
}
|
||||||
h.SetPath([]string{"request", "path"}, path)
|
client.Retry(3, 10*time.Second) //方法用于设置请求失败时重连次数和重连间隔。
|
||||||
header, _ = h.Encode()
|
|
||||||
}
|
client.SetHeaderMap(headerM)
|
||||||
// Create GeneralNodeInfo
|
client.SetHeader("Content-Type", "application/json")
|
||||||
return &api.NodeInfo{
|
|
||||||
NodeType: c.NodeType,
|
data["token"] = c.Key
|
||||||
NodeID: c.NodeID,
|
data["node_id"] = c.NodeID
|
||||||
Port: gconv.Uint32(s.Port),
|
|
||||||
TransportProtocol: "tcp",
|
switch method {
|
||||||
CypherMethod: s.Encryption,
|
case "GET":
|
||||||
ServerKey: s.ServerKey, // shadowsocks2022 share key
|
gResponse, err = client.Get(c.ctx, url, data)
|
||||||
NameServerConfig: s.parseDNSConfig(),
|
case "POST":
|
||||||
Header: header,
|
gResponse, err = client.Post(c.ctx, url, data)
|
||||||
}, nil
|
default:
|
||||||
}
|
err = fmt.Errorf("unsupported method: %s", method)
|
||||||
|
return
|
||||||
// parseV2rayNodeResponse parse the response for the given nodeInfo format
|
}
|
||||||
func (c *APIClient) parseV2rayNodeResponse(s *serverConfig) (*api.NodeInfo, error) {
|
|
||||||
var (
|
if err != nil {
|
||||||
header json.RawMessage
|
return
|
||||||
enableTLS bool
|
}
|
||||||
)
|
defer gResponse.Close()
|
||||||
|
|
||||||
switch s.Net {
|
reslutJson = gjson.New(gResponse.ReadAllString())
|
||||||
case "tcp":
|
if reslutJson == nil {
|
||||||
if s.Header != nil {
|
err = fmt.Errorf("http reslut to json, err : %s", gResponse.ReadAllString())
|
||||||
if httpHeader, err := s.Header.MarshalJSON(); err != nil {
|
}
|
||||||
return nil, err
|
if reslutJson.Get("code").Int() != 0 {
|
||||||
} else {
|
err = errors.New(reslutJson.Get("message").String())
|
||||||
header = httpHeader
|
return
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.TLS == "tls" {
|
|
||||||
enableTLS = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create GeneralNodeInfo
|
|
||||||
return &api.NodeInfo{
|
|
||||||
NodeType: c.NodeType,
|
|
||||||
NodeID: c.NodeID,
|
|
||||||
Port: gconv.Uint32(s.Port),
|
|
||||||
AlterID: 0,
|
|
||||||
TransportProtocol: s.Net,
|
|
||||||
EnableTLS: enableTLS,
|
|
||||||
Path: s.Path,
|
|
||||||
Host: s.Host,
|
|
||||||
EnableVless: c.EnableVless,
|
|
||||||
VlessFlow: c.VlessFlow,
|
|
||||||
ServiceName: s.Sni,
|
|
||||||
Header: header,
|
|
||||||
NameServerConfig: s.parseDNSConfig(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverConfig) parseDNSConfig() (nameServerList []*conf.NameServerConfig) {
|
|
||||||
for i := range s.Routes {
|
|
||||||
if s.Routes[i].Action == "dns" {
|
|
||||||
nameServerList = append(nameServerList, &conf.NameServerConfig{
|
|
||||||
Address: &conf.Address{Address: net.ParseAddress(s.Routes[i].ActionValue)},
|
|
||||||
Domains: s.Routes[i].Match,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@@ -5,56 +5,31 @@ import (
|
|||||||
|
|
||||||
"github.com/XrayR-project/XrayR/api"
|
"github.com/XrayR-project/XrayR/api"
|
||||||
"github.com/XrayR-project/XrayR/api/gov2panel"
|
"github.com/XrayR-project/XrayR/api/gov2panel"
|
||||||
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateClient() api.API {
|
func CreateClient() api.API {
|
||||||
apiConfig := &api.Config{
|
apiConfig := &api.Config{
|
||||||
APIHost: "http://localhost:8080",
|
APIHost: "http://localhost:8080",
|
||||||
Key: "123456",
|
Key: "123456",
|
||||||
NodeID: 1,
|
NodeID: 90,
|
||||||
NodeType: "V2ray",
|
NodeType: "V2ray",
|
||||||
}
|
}
|
||||||
client := gov2panel.New(apiConfig)
|
client := gov2panel.New(apiConfig)
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetV2rayNodeInfo(t *testing.T) {
|
func TestGetNodeInfo(t *testing.T) {
|
||||||
client := CreateClient()
|
client := CreateClient()
|
||||||
nodeInfo, err := client.GetNodeInfo()
|
nodeInfo, err := client.GetNodeInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
t.Log(nodeInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetSSNodeInfo(t *testing.T) {
|
nodeInfoJson := gjson.New(nodeInfo)
|
||||||
apiConfig := &api.Config{
|
t.Log(nodeInfoJson.String())
|
||||||
APIHost: "http://127.0.0.1:668",
|
t.Log(nodeInfoJson.String())
|
||||||
Key: "qwertyuiopasdfghjkl",
|
|
||||||
NodeID: 1,
|
|
||||||
NodeType: "Shadowsocks",
|
|
||||||
}
|
|
||||||
client := gov2panel.New(apiConfig)
|
|
||||||
nodeInfo, err := client.GetNodeInfo()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
t.Log(nodeInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetTrojanNodeInfo(t *testing.T) {
|
|
||||||
apiConfig := &api.Config{
|
|
||||||
APIHost: "http://127.0.0.1:668",
|
|
||||||
Key: "qwertyuiopasdfghjkl",
|
|
||||||
NodeID: 1,
|
|
||||||
NodeType: "Trojan",
|
|
||||||
}
|
|
||||||
client := gov2panel.New(apiConfig)
|
|
||||||
nodeInfo, err := client.GetNodeInfo()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
t.Log(nodeInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUserList(t *testing.T) {
|
func TestGetUserList(t *testing.T) {
|
||||||
@@ -65,6 +40,7 @@ func TestGetUserList(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Log(len(*userList))
|
||||||
t.Log(userList)
|
t.Log(userList)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,24 +50,30 @@ func TestReportReportUserTraffic(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
t.Log(userList)
|
||||||
generalUserTraffic := make([]api.UserTraffic, len(*userList))
|
generalUserTraffic := make([]api.UserTraffic, len(*userList))
|
||||||
for i, userInfo := range *userList {
|
for i, userInfo := range *userList {
|
||||||
generalUserTraffic[i] = api.UserTraffic{
|
generalUserTraffic[i] = api.UserTraffic{
|
||||||
UID: userInfo.UID,
|
UID: userInfo.UID,
|
||||||
Upload: 1111,
|
Upload: 1073741824,
|
||||||
Download: 2222,
|
Download: 1073741824,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// client.Debug()
|
|
||||||
|
t.Log(gconv.String(generalUserTraffic))
|
||||||
|
client = CreateClient()
|
||||||
err = client.ReportUserTraffic(&generalUserTraffic)
|
err = client.ReportUserTraffic(&generalUserTraffic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetNodeRule(t *testing.T) {
|
func TestGetNodeRule(t *testing.T) {
|
||||||
|
|
||||||
client := CreateClient()
|
client := CreateClient()
|
||||||
client.Debug()
|
client.Debug()
|
||||||
|
|
||||||
ruleList, err := client.GetNodeRule()
|
ruleList, err := client.GetNodeRule()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
@@ -1,35 +1,9 @@
|
|||||||
package gov2panel
|
package gov2panel
|
||||||
|
|
||||||
import "encoding/json"
|
type user struct {
|
||||||
|
Id int `json:"id"`
|
||||||
type serverConfig struct {
|
Uuid string `json:"uuid"`
|
||||||
v2ray
|
SpeedLimit int `json:"speed_limit"`
|
||||||
shadowsocks
|
|
||||||
//---
|
|
||||||
Routes []route `json:"routes"`
|
|
||||||
Header *json.RawMessage `json:"header"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type v2ray struct {
|
|
||||||
Port string `json:"port"`
|
|
||||||
Scy string `json:"scy"`
|
|
||||||
Net string `json:"net"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Host string `json:"host"`
|
|
||||||
Path string `json:"path"`
|
|
||||||
TLS string `json:"tls"`
|
|
||||||
Sni string `json:"sni"`
|
|
||||||
Alpn string `json:"alpn"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type shadowsocks struct {
|
|
||||||
Encryption string `json:"encryption"`
|
|
||||||
Obfs string `json:"obfs"`
|
|
||||||
ObfsSettings struct {
|
|
||||||
Path string `json:"path"`
|
|
||||||
Host string `json:"host"`
|
|
||||||
} `json:"obfs_settings"`
|
|
||||||
ServerKey string `json:"server_key"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type route struct {
|
type route struct {
|
||||||
@@ -38,9 +12,3 @@ type route struct {
|
|||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
ActionValue string `json:"action_value"`
|
ActionValue string `json:"action_value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type user struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Uuid string `json:"uuid"`
|
|
||||||
SpeedLimit int `json:"speed_limit"`
|
|
||||||
}
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package v2raysocks
|
package v2raysocks
|
||||||
|
|
||||||
type UserTraffic struct {
|
type UserTraffic struct {
|
||||||
UID int `json:"user_id"`
|
UID int `json:"uid"`
|
||||||
Upload int64 `json:"u"`
|
Upload int64 `json:"u"`
|
||||||
Download int64 `json:"d"`
|
Download int64 `json:"d"`
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,10 @@ type NodeOnline struct {
|
|||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IllegalItem struct {
|
||||||
|
UID int `json:"uid"`
|
||||||
|
}
|
||||||
|
|
||||||
type REALITYConfig struct {
|
type REALITYConfig struct {
|
||||||
Dest string `json:"dest,omitempty"`
|
Dest string `json:"dest,omitempty"`
|
||||||
ProxyProtocolVer uint64 `json:"proxy_protocol_ver,omitempty"`
|
ProxyProtocolVer uint64 `json:"proxy_protocol_ver,omitempty"`
|
||||||
|
@@ -159,8 +159,8 @@ func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) {
|
|||||||
res, err := c.client.R().
|
res, err := c.client.R().
|
||||||
SetHeader("If-None-Match", c.eTags["config"]).
|
SetHeader("If-None-Match", c.eTags["config"]).
|
||||||
SetQueryParams(map[string]string{
|
SetQueryParams(map[string]string{
|
||||||
"act": "config",
|
"act": "config",
|
||||||
"nodetype": nodeType,
|
"node_type": nodeType,
|
||||||
}).
|
}).
|
||||||
ForceContentType("application/json").
|
ForceContentType("application/json").
|
||||||
Get(c.APIHost)
|
Get(c.APIHost)
|
||||||
@@ -213,8 +213,8 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
|
|||||||
res, err := c.client.R().
|
res, err := c.client.R().
|
||||||
SetHeader("If-None-Match", c.eTags["user"]).
|
SetHeader("If-None-Match", c.eTags["user"]).
|
||||||
SetQueryParams(map[string]string{
|
SetQueryParams(map[string]string{
|
||||||
"act": "user",
|
"act": "user",
|
||||||
"nodetype": nodeType,
|
"node_type": nodeType,
|
||||||
}).
|
}).
|
||||||
ForceContentType("application/json").
|
ForceContentType("application/json").
|
||||||
Get(c.APIHost)
|
Get(c.APIHost)
|
||||||
@@ -239,22 +239,21 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
|
|||||||
user.UID = response.Get("data").GetIndex(i).Get("id").MustInt()
|
user.UID = response.Get("data").GetIndex(i).Get("id").MustInt()
|
||||||
switch c.NodeType {
|
switch c.NodeType {
|
||||||
case "Shadowsocks":
|
case "Shadowsocks":
|
||||||
user.Email = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("secret").MustString()
|
user.Email = response.Get("data").GetIndex(i).Get("secret").MustString()
|
||||||
user.Passwd = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("secret").MustString()
|
user.Passwd = response.Get("data").GetIndex(i).Get("secret").MustString()
|
||||||
user.Method = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("cipher").MustString()
|
user.Method = response.Get("data").GetIndex(i).Get("cipher").MustString()
|
||||||
user.SpeedLimit = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("speed_limit").MustUint64() * 1000000 / 8
|
user.SpeedLimit = response.Get("data").GetIndex(i).Get("st").MustUint64() * 1000000 / 8
|
||||||
user.DeviceLimit = response.Get("data").GetIndex(i).Get("shadowsocks_user").Get("device_limit").MustInt()
|
user.DeviceLimit = response.Get("data").GetIndex(i).Get("dt").MustInt()
|
||||||
case "Trojan":
|
case "Trojan":
|
||||||
user.UUID = response.Get("data").GetIndex(i).Get("trojan_user").Get("password").MustString()
|
user.UUID = response.Get("data").GetIndex(i).Get("password").MustString()
|
||||||
user.Email = response.Get("data").GetIndex(i).Get("trojan_user").Get("password").MustString()
|
user.Email = response.Get("data").GetIndex(i).Get("password").MustString()
|
||||||
user.SpeedLimit = response.Get("data").GetIndex(i).Get("trojan_user").Get("speed_limit").MustUint64() * 1000000 / 8
|
user.SpeedLimit = response.Get("data").GetIndex(i).Get("st").MustUint64() * 1000000 / 8
|
||||||
user.DeviceLimit = response.Get("data").GetIndex(i).Get("trojan_user").Get("device_limit").MustInt()
|
user.DeviceLimit = response.Get("data").GetIndex(i).Get("dt").MustInt()
|
||||||
case "V2ray", "Vmess", "Vless":
|
case "V2ray", "Vmess", "Vless":
|
||||||
user.UUID = response.Get("data").GetIndex(i).Get("v2ray_user").Get("uuid").MustString()
|
user.UUID = response.Get("data").GetIndex(i).Get("uuid").MustString()
|
||||||
user.Email = response.Get("data").GetIndex(i).Get("v2ray_user").Get("email").MustString()
|
user.Email = user.UUID + "@x.com"
|
||||||
user.AlterID = uint16(response.Get("data").GetIndex(i).Get("v2ray_user").Get("alter_id").MustUint64())
|
user.SpeedLimit = response.Get("data").GetIndex(i).Get("st").MustUint64() * 1000000 / 8
|
||||||
user.SpeedLimit = response.Get("data").GetIndex(i).Get("v2ray_user").Get("speed_limit").MustUint64() * 1000000 / 8
|
user.DeviceLimit = response.Get("data").GetIndex(i).Get("dt").MustInt()
|
||||||
user.DeviceLimit = response.Get("data").GetIndex(i).Get("v2ray_user").Get("device_limit").MustInt()
|
|
||||||
}
|
}
|
||||||
if c.SpeedLimit > 0 {
|
if c.SpeedLimit > 0 {
|
||||||
user.SpeedLimit = uint64((c.SpeedLimit * 1000000) / 8)
|
user.SpeedLimit = uint64((c.SpeedLimit * 1000000) / 8)
|
||||||
@@ -283,8 +282,8 @@ func (c *APIClient) ReportUserTraffic(userTraffic *[]api.UserTraffic) error {
|
|||||||
res, err := c.client.R().
|
res, err := c.client.R().
|
||||||
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
||||||
SetQueryParams(map[string]string{
|
SetQueryParams(map[string]string{
|
||||||
"act": "submit",
|
"act": "submit",
|
||||||
"nodetype": strings.ToLower(c.NodeType),
|
"node_type": strings.ToLower(c.NodeType),
|
||||||
}).
|
}).
|
||||||
SetBody(data).
|
SetBody(data).
|
||||||
ForceContentType("application/json").
|
ForceContentType("application/json").
|
||||||
@@ -327,8 +326,8 @@ func (c *APIClient) ReportNodeStatus(nodeStatus *api.NodeStatus) (err error) {
|
|||||||
res, err := c.client.R().
|
res, err := c.client.R().
|
||||||
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
||||||
SetQueryParams(map[string]string{
|
SetQueryParams(map[string]string{
|
||||||
"act": "nodestatus",
|
"act": "nodestatus",
|
||||||
"nodetype": strings.ToLower(c.NodeType),
|
"node_type": strings.ToLower(c.NodeType),
|
||||||
}).
|
}).
|
||||||
SetBody(systemload).
|
SetBody(systemload).
|
||||||
ForceContentType("application/json").
|
ForceContentType("application/json").
|
||||||
@@ -350,8 +349,8 @@ func (c *APIClient) ReportNodeOnlineUsers(onlineUserList *[]api.OnlineUser) erro
|
|||||||
res, err := c.client.R().
|
res, err := c.client.R().
|
||||||
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
||||||
SetQueryParams(map[string]string{
|
SetQueryParams(map[string]string{
|
||||||
"act": "onlineusers",
|
"act": "onlineusers",
|
||||||
"nodetype": strings.ToLower(c.NodeType),
|
"node_type": strings.ToLower(c.NodeType),
|
||||||
}).
|
}).
|
||||||
SetBody(data).
|
SetBody(data).
|
||||||
ForceContentType("application/json").
|
ForceContentType("application/json").
|
||||||
@@ -365,6 +364,26 @@ func (c *APIClient) ReportNodeOnlineUsers(onlineUserList *[]api.OnlineUser) erro
|
|||||||
|
|
||||||
// ReportIllegal implements the API interface
|
// ReportIllegal implements the API interface
|
||||||
func (c *APIClient) ReportIllegal(detectResultList *[]api.DetectResult) error {
|
func (c *APIClient) ReportIllegal(detectResultList *[]api.DetectResult) error {
|
||||||
|
data := make([]IllegalItem, len(*detectResultList))
|
||||||
|
for i, r := range *detectResultList {
|
||||||
|
data[i] = IllegalItem{
|
||||||
|
UID: r.UID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.client.R().
|
||||||
|
SetQueryParam("node_id", strconv.Itoa(c.NodeID)).
|
||||||
|
SetQueryParams(map[string]string{
|
||||||
|
"act": "illegal",
|
||||||
|
"node_type": strings.ToLower(c.NodeType),
|
||||||
|
}).
|
||||||
|
SetBody(data).
|
||||||
|
ForceContentType("application/json").
|
||||||
|
Post(c.APIHost)
|
||||||
|
_, err = c.parseResponse(res, "", err)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +442,7 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
|
|||||||
var enableTLS bool
|
var enableTLS bool
|
||||||
var enableVless bool
|
var enableVless bool
|
||||||
var enableReality bool
|
var enableReality bool
|
||||||
var alterID uint16 = 0
|
var vlessFlow string
|
||||||
|
|
||||||
tmpInboundInfo := nodeInfoResponse.Get("inbounds").MustArray()
|
tmpInboundInfo := nodeInfoResponse.Get("inbounds").MustArray()
|
||||||
marshalByte, _ := json.Marshal(tmpInboundInfo[0].(map[string]interface{}))
|
marshalByte, _ := json.Marshal(tmpInboundInfo[0].(map[string]interface{}))
|
||||||
@@ -436,6 +455,12 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
|
|||||||
case "ws":
|
case "ws":
|
||||||
path = inboundInfo.Get("streamSettings").Get("wsSettings").Get("path").MustString()
|
path = inboundInfo.Get("streamSettings").Get("wsSettings").Get("path").MustString()
|
||||||
host = inboundInfo.Get("streamSettings").Get("wsSettings").Get("headers").Get("Host").MustString()
|
host = inboundInfo.Get("streamSettings").Get("wsSettings").Get("headers").Get("Host").MustString()
|
||||||
|
case "httpupgrade":
|
||||||
|
host = inboundInfo.Get("streamSettings").Get("httpupgradeSettings").Get("Host").MustString()
|
||||||
|
path = inboundInfo.Get("streamSettings").Get("httpupgradeSettings").Get("path").MustString()
|
||||||
|
case "splithttp":
|
||||||
|
host = inboundInfo.Get("streamSettings").Get("splithttpSettings").Get("Host").MustString()
|
||||||
|
path = inboundInfo.Get("streamSettings").Get("splithttpSettings").Get("path").MustString()
|
||||||
case "grpc":
|
case "grpc":
|
||||||
if data, ok := inboundInfo.Get("streamSettings").Get("grpcSettings").CheckGet("serviceName"); ok {
|
if data, ok := inboundInfo.Get("streamSettings").Get("grpcSettings").CheckGet("serviceName"); ok {
|
||||||
serviceName = data.MustString()
|
serviceName = data.MustString()
|
||||||
@@ -448,12 +473,11 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
|
|||||||
header = httpHeader
|
header = httpHeader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enableTLS = inboundInfo.Get("streamSettings").Get("security").MustString() == "tls"
|
enableTLS = inboundInfo.Get("streamSettings").Get("security").MustString() == "tls"
|
||||||
enableVless = inboundInfo.Get("streamSettings").Get("security").MustString() == "reality"
|
enableVless = inboundInfo.Get("protocol").MustString() == "vless"
|
||||||
enableReality = enableVless
|
enableReality = inboundInfo.Get("streamSettings").Get("security").MustString() == "reality"
|
||||||
|
|
||||||
realityConfig := new(api.REALITYConfig)
|
realityConfig := new(api.REALITYConfig)
|
||||||
if enableVless {
|
if enableVless {
|
||||||
@@ -470,19 +494,26 @@ func (c *APIClient) ParseV2rayNodeResponse(nodeInfoResponse *simplejson.Json) (*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XTLS only supports TLS and REALITY directly for now
|
||||||
|
if transportProtocol == "tcp" && enableReality {
|
||||||
|
vlessFlow = "xtls-rprx-vision"
|
||||||
|
} else {
|
||||||
|
vlessFlow = c.VlessFlow
|
||||||
|
}
|
||||||
|
|
||||||
// Create GeneralNodeInfo
|
// Create GeneralNodeInfo
|
||||||
// AlterID will be updated after next sync
|
// AlterID will be updated after next sync
|
||||||
nodeInfo := &api.NodeInfo{
|
nodeInfo := &api.NodeInfo{
|
||||||
NodeType: c.NodeType,
|
NodeType: c.NodeType,
|
||||||
NodeID: c.NodeID,
|
NodeID: c.NodeID,
|
||||||
Port: port,
|
Port: port,
|
||||||
AlterID: alterID,
|
AlterID: 0,
|
||||||
TransportProtocol: transportProtocol,
|
TransportProtocol: transportProtocol,
|
||||||
EnableTLS: enableTLS,
|
EnableTLS: enableTLS,
|
||||||
Path: path,
|
Path: path,
|
||||||
Host: host,
|
Host: host,
|
||||||
EnableVless: enableVless,
|
EnableVless: enableVless,
|
||||||
VlessFlow: c.VlessFlow,
|
VlessFlow: vlessFlow,
|
||||||
ServiceName: serviceName,
|
ServiceName: serviceName,
|
||||||
Header: header,
|
Header: header,
|
||||||
EnableREALITY: enableReality,
|
EnableREALITY: enableReality,
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "0.9.4"
|
version = "0.9.5"
|
||||||
codename = "XrayR"
|
codename = "XrayR"
|
||||||
intro = "A Xray backend that supports many panels"
|
intro = "A Xray backend that supports many panels"
|
||||||
)
|
)
|
||||||
|
@@ -149,8 +149,8 @@ func (l *LegoCMD) RenewCert() (CertPath string, KeyPath string, ok bool, err err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkCertFile(domain string) (string, string, error) {
|
func checkCertFile(domain string) (string, string, error) {
|
||||||
keyPath := path.Join(defaultPath, "certificates", fmt.Sprintf("%s.key", domain))
|
keyPath := path.Join(defaultPath, "certificates", fmt.Sprintf("%s.key", sanitizedDomain(domain)))
|
||||||
certPath := path.Join(defaultPath, "certificates", fmt.Sprintf("%s.crt", domain))
|
certPath := path.Join(defaultPath, "certificates", fmt.Sprintf("%s.crt", sanitizedDomain(domain)))
|
||||||
if _, err := os.Stat(keyPath); os.IsNotExist(err) {
|
if _, err := os.Stat(keyPath); os.IsNotExist(err) {
|
||||||
return "", "", fmt.Errorf("cert key failed: %s", domain)
|
return "", "", fmt.Errorf("cert key failed: %s", domain)
|
||||||
}
|
}
|
||||||
|
28
go.mod
28
go.mod
@@ -6,8 +6,8 @@ require (
|
|||||||
dario.cat/mergo v1.0.0
|
dario.cat/mergo v1.0.0
|
||||||
github.com/bitly/go-simplejson v0.5.1
|
github.com/bitly/go-simplejson v0.5.1
|
||||||
github.com/deckarep/golang-set v1.8.0
|
github.com/deckarep/golang-set v1.8.0
|
||||||
github.com/eko/gocache/lib/v4 v4.1.5
|
github.com/eko/gocache/lib/v4 v4.1.6
|
||||||
github.com/eko/gocache/store/go_cache/v4 v4.2.1
|
github.com/eko/gocache/store/go_cache/v4 v4.2.2
|
||||||
github.com/eko/gocache/store/redis/v4 v4.2.1
|
github.com/eko/gocache/store/redis/v4 v4.2.1
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.7.0
|
||||||
github.com/go-acme/lego/v4 v4.16.1
|
github.com/go-acme/lego/v4 v4.16.1
|
||||||
@@ -15,19 +15,19 @@ require (
|
|||||||
github.com/gogf/gf/v2 v2.7.0
|
github.com/gogf/gf/v2 v2.7.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/r3labs/diff/v2 v2.15.1
|
github.com/r3labs/diff/v2 v2.15.1
|
||||||
github.com/redis/go-redis/v9 v9.5.1
|
github.com/redis/go-redis/v9 v9.7.0
|
||||||
github.com/sagernet/sing v0.4.1
|
github.com/sagernet/sing v0.4.1
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||||
github.com/shirou/gopsutil/v3 v3.24.2
|
github.com/shirou/gopsutil/v3 v3.24.5
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/spf13/viper v1.18.2
|
github.com/spf13/viper v1.18.2
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/xtls/xray-core v1.8.20
|
github.com/xtls/xray-core v1.8.20
|
||||||
golang.org/x/crypto v0.25.0
|
golang.org/x/crypto v0.28.0
|
||||||
golang.org/x/net v0.27.0
|
golang.org/x/net v0.27.0
|
||||||
golang.org/x/time v0.5.0
|
golang.org/x/time v0.7.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.36.4
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -85,6 +85,7 @@ require (
|
|||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||||
github.com/civo/civogo v0.3.63 // indirect
|
github.com/civo/civogo v0.3.63 // indirect
|
||||||
|
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||||
github.com/cloudflare/circl v1.3.9 // indirect
|
github.com/cloudflare/circl v1.3.9 // indirect
|
||||||
github.com/cloudflare/cloudflare-go v0.90.0 // indirect
|
github.com/cloudflare/cloudflare-go v0.90.0 // indirect
|
||||||
github.com/cpu/goacmedns v0.1.1 // indirect
|
github.com/cpu/goacmedns v0.1.1 // indirect
|
||||||
@@ -95,6 +96,7 @@ require (
|
|||||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||||
github.com/dnsimple/dnsimple-go v1.7.0 // indirect
|
github.com/dnsimple/dnsimple-go v1.7.0 // indirect
|
||||||
github.com/exoscale/egoscale v1.19.0 // indirect
|
github.com/exoscale/egoscale v1.19.0 // indirect
|
||||||
|
github.com/fatih/color v1.16.0 // indirect
|
||||||
github.com/fatih/structs v1.1.0 // indirect
|
github.com/fatih/structs v1.1.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/flosch/pongo2/v4 v4.0.2 // indirect
|
github.com/flosch/pongo2/v4 v4.0.2 // indirect
|
||||||
@@ -135,6 +137,7 @@ require (
|
|||||||
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect
|
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect
|
||||||
github.com/gorilla/css v1.0.1 // indirect
|
github.com/gorilla/css v1.0.1 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
github.com/grokify/html-strip-tags-go v0.0.1 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
@@ -173,6 +176,7 @@ require (
|
|||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/microcosm-cc/bluemonday v1.0.26 // indirect
|
github.com/microcosm-cc/bluemonday v1.0.26 // indirect
|
||||||
github.com/miekg/dns v1.1.61 // indirect
|
github.com/miekg/dns v1.1.61 // indirect
|
||||||
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
||||||
@@ -192,6 +196,7 @@ require (
|
|||||||
github.com/nrdcg/nodion v0.1.0 // indirect
|
github.com/nrdcg/nodion v0.1.0 // indirect
|
||||||
github.com/nrdcg/porkbun v0.3.0 // indirect
|
github.com/nrdcg/porkbun v0.3.0 // indirect
|
||||||
github.com/nzdjb/go-metaname v1.0.0 // indirect
|
github.com/nzdjb/go-metaname v1.0.0 // indirect
|
||||||
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
|
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
||||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
||||||
@@ -212,6 +217,7 @@ require (
|
|||||||
github.com/quic-go/quic-go v0.45.1 // indirect
|
github.com/quic-go/quic-go v0.45.1 // indirect
|
||||||
github.com/refraction-networking/utls v1.6.7 // indirect
|
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||||
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sacloud/api-client-go v0.2.10 // indirect
|
github.com/sacloud/api-client-go v0.2.10 // indirect
|
||||||
github.com/sacloud/go-http v0.1.8 // indirect
|
github.com/sacloud/go-http v0.1.8 // indirect
|
||||||
@@ -273,9 +279,9 @@ require (
|
|||||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
||||||
golang.org/x/mod v0.18.0 // indirect
|
golang.org/x/mod v0.18.0 // indirect
|
||||||
golang.org/x/oauth2 v0.20.0 // indirect
|
golang.org/x/oauth2 v0.20.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
golang.org/x/sys v0.26.0 // indirect
|
||||||
golang.org/x/text v0.16.0 // indirect
|
golang.org/x/text v0.19.0 // indirect
|
||||||
golang.org/x/tools v0.22.0 // indirect
|
golang.org/x/tools v0.22.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||||
|
54
go.sum
54
go.sum
@@ -820,7 +820,7 @@ github.com/cpu/goacmedns v0.1.1 h1:DM3H2NiN2oam7QljgGY5ygy4yDXhK5Z4JUnqaugs2C4=
|
|||||||
github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobeGqugQ=
|
github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobeGqugQ=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -843,10 +843,10 @@ github.com/dnsimple/dnsimple-go v1.7.0 h1:JKu9xJtZ3SqOC+BuYgAWeab7+EEx0sz422vu8j
|
|||||||
github.com/dnsimple/dnsimple-go v1.7.0/go.mod h1:EKpuihlWizqYafSnQHGCd/gyvy3HkEQJ7ODB4KdV8T8=
|
github.com/dnsimple/dnsimple-go v1.7.0/go.mod h1:EKpuihlWizqYafSnQHGCd/gyvy3HkEQJ7ODB4KdV8T8=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/eko/gocache/lib/v4 v4.1.5 h1:CeMQmdIzwBKKLRjk3FCDXzNFsQTyqJ01JLI7Ib0C9r8=
|
github.com/eko/gocache/lib/v4 v4.1.6 h1:5WWIGISKhE7mfkyF+SJyWwqa4Dp2mkdX8QsZpnENqJI=
|
||||||
github.com/eko/gocache/lib/v4 v4.1.5/go.mod h1:XaNfCwW8KYW1bRZ/KoHA1TugnnkMz0/gT51NDIu7LSY=
|
github.com/eko/gocache/lib/v4 v4.1.6/go.mod h1:HFxC8IiG2WeRotg09xEnPD72sCheJiTSr4Li5Ameg7g=
|
||||||
github.com/eko/gocache/store/go_cache/v4 v4.2.1 h1:3xSksOamzCf+YZXz9l67gr6jOj3AA4hnk0mV4z3Jwbs=
|
github.com/eko/gocache/store/go_cache/v4 v4.2.2 h1:tAI9nl6TLoJyKG1ujF0CS0n/IgTEMl+NivxtR5R3/hw=
|
||||||
github.com/eko/gocache/store/go_cache/v4 v4.2.1/go.mod h1:rd6tUbaBOdqgi5xT3+OGeU7lQuhVJGTapNWFlZou524=
|
github.com/eko/gocache/store/go_cache/v4 v4.2.2/go.mod h1:T9zkHokzr8K9EiC7RfMbDg6HSwaV6rv3UdcNu13SGcA=
|
||||||
github.com/eko/gocache/store/redis/v4 v4.2.1 h1:uPAgZIn7knH6a55tO4ETN9V93VD3Rcyx0ZIyozEqC0I=
|
github.com/eko/gocache/store/redis/v4 v4.2.1 h1:uPAgZIn7knH6a55tO4ETN9V93VD3Rcyx0ZIyozEqC0I=
|
||||||
github.com/eko/gocache/store/redis/v4 v4.2.1/go.mod h1:JoLkNA5yeGNQUwINAM9529cDNQCo88WwiKlO9e/+39I=
|
github.com/eko/gocache/store/redis/v4 v4.2.1/go.mod h1:JoLkNA5yeGNQUwINAM9529cDNQCo88WwiKlO9e/+39I=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
@@ -1292,7 +1292,6 @@ github.com/liquidweb/liquidweb-cli v0.7.0 h1:7j1r1U0MZa1TXiWo3IMU5V1YQwnBHMVxU+x
|
|||||||
github.com/liquidweb/liquidweb-cli v0.7.0/go.mod h1:+uU7L6BhaQtgo4cYKhhsP5UNCq/imNvjBjlf76Vqpb0=
|
github.com/liquidweb/liquidweb-cli v0.7.0/go.mod h1:+uU7L6BhaQtgo4cYKhhsP5UNCq/imNvjBjlf76Vqpb0=
|
||||||
github.com/liquidweb/liquidweb-go v1.6.4 h1:6S0m3hHSpiLqGD7AFSb7lH/W/qr1wx+tKil9fgIbjMc=
|
github.com/liquidweb/liquidweb-go v1.6.4 h1:6S0m3hHSpiLqGD7AFSb7lH/W/qr1wx+tKil9fgIbjMc=
|
||||||
github.com/liquidweb/liquidweb-go v1.6.4/go.mod h1:B934JPIIcdA+uTq2Nz5PgOtG6CuCaEvQKe/Ge/5GgZ4=
|
github.com/liquidweb/liquidweb-go v1.6.4/go.mod h1:B934JPIIcdA+uTq2Nz5PgOtG6CuCaEvQKe/Ge/5GgZ4=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
|
||||||
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI=
|
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI=
|
||||||
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
||||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||||
@@ -1464,7 +1463,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
|||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||||
@@ -1513,8 +1511,8 @@ github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjC
|
|||||||
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||||
github.com/r3labs/diff/v2 v2.15.1 h1:EOrVqPUzi+njlumoqJwiS/TgGgmZo83619FNDB9xQUg=
|
github.com/r3labs/diff/v2 v2.15.1 h1:EOrVqPUzi+njlumoqJwiS/TgGgmZo83619FNDB9xQUg=
|
||||||
github.com/r3labs/diff/v2 v2.15.1/go.mod h1:I8noH9Fc2fjSaMxqF3G2lhDdC0b+JXCfyx85tWFM9kc=
|
github.com/r3labs/diff/v2 v2.15.1/go.mod h1:I8noH9Fc2fjSaMxqF3G2lhDdC0b+JXCfyx85tWFM9kc=
|
||||||
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
|
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||||
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||||
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||||
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
@@ -1565,8 +1563,8 @@ github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1
|
|||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y=
|
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
|
||||||
github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk=
|
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||||
@@ -1635,8 +1633,8 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
|||||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
@@ -1685,10 +1683,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.878 h1:Bgzv
|
|||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.878/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.878/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.878 h1:M+xjSie8aQLDFdjHszCkz0m8TKJDg5sf2rjfxv8jYIQ=
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.878 h1:M+xjSie8aQLDFdjHszCkz0m8TKJDg5sf2rjfxv8jYIQ=
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.878/go.mod h1:h6PMyIaU05XQ3bX3KLKixsZfwd6kS4RWU5QSC48OV6Y=
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.878/go.mod h1:h6PMyIaU05XQ3bX3KLKixsZfwd6kS4RWU5QSC48OV6Y=
|
||||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
|
||||||
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
|
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
|
||||||
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
|
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
|
||||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
|
||||||
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
|
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
|
||||||
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
|
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
@@ -1842,8 +1838,8 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0
|
|||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@@ -2036,8 +2032,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -2153,12 +2149,11 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -2172,8 +2167,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|||||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -2193,8 +2188,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -2202,8 +2197,9 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
|
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||||
|
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -2580,8 +2576,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
|||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
Reference in New Issue
Block a user