From f4872bd12e3948c76c2dc2f868bff59dcbbf9e6b Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Sat, 18 Apr 2026 02:12:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=BA=8C=E6=AC=A1=E5=B0=9D=E8=AF=95?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DVLESS=E8=8A=82=E7=82=B9=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/handler/node_api.go | 57 ++++++++++++++++++++++++++++++++++-- internal/service/node.go | 37 +++++++++++++---------- 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/internal/handler/node_api.go b/internal/handler/node_api.go index d69e21f..52dc63b 100644 --- a/internal/handler/node_api.go +++ b/internal/handler/node_api.go @@ -92,13 +92,64 @@ func NodeTrojanTidalabUser(c *gin.Context) { }) } +type UniProxyConfigResponse struct { + Protocol string `json:"protocol"` + ListenIP string `json:"listen_ip"` + ServerPort int `json:"server_port"` + Network any `json:"network"` + NetworkSettings any `json:"networkSettings"` + TLS int `json:"tls,omitempty"` + Flow any `json:"flow,omitempty"` + Cipher any `json:"cipher,omitempty"` + ServerKey any `json:"server_key,omitempty"` + Decryption any `json:"decryption,omitempty"` + TLSSettings any `json:"tls_settings,omitempty"` + Multiplex any `json:"multiplex,omitempty"` + Routes any `json:"routes,omitempty"` + CustomOutbounds any `json:"custom_outbounds,omitempty"` + CustomRoutes any `json:"custom_routes,omitempty"` + CertConfig any `json:"cert_config,omitempty"` + BaseConfig any `json:"base_config"` +} + func NodeConfig(c *gin.Context) { node := c.MustGet("node").(*model.Server) setNodeLastCheck(node) - config := service.BuildNodeConfigPayload(node) - config["base_config"] = service.BuildNodeBaseConfigPayload() - c.JSON(http.StatusOK, config) + payload := service.BuildNodeConfigPayload(node) + baseConfig := service.BuildNodeBaseConfigPayload() + + resp := UniProxyConfigResponse{ + Protocol: node.Type, + ListenIP: "0.0.0.0", + ServerPort: node.ServerPort, + Network: payload["network"], + NetworkSettings: payload["networkSettings"], + TLS: toIntDefault(payload["tls"]), + Flow: payload["flow"], + Cipher: payload["cipher"], + ServerKey: payload["server_key"], + Decryption: payload["decryption"], + TLSSettings: payload["tls_settings"], + Multiplex: payload["multiplex"], + Routes: payload["routes"], + CustomOutbounds: payload["custom_outbounds"], + CustomRoutes: payload["custom_routes"], + CertConfig: payload["cert_config"], + BaseConfig: baseConfig, + } + + c.JSON(http.StatusOK, resp) +} + +func toIntDefault(val any) int { + if val == nil { + return 0 + } + if i, ok := val.(int); ok { + return i + } + return 0 } func NodeTrojanTidalabConfig(c *gin.Context) { diff --git a/internal/service/node.go b/internal/service/node.go index 0258188..12193e5 100644 --- a/internal/service/node.go +++ b/internal/service/node.go @@ -357,14 +357,14 @@ func BuildNodeConfig(node *model.Server) NodeServerConfig { func BuildNodeConfigPayload(node *model.Server) map[string]any { settings := parseObject(node.ProtocolSettings) baseConfig := map[string]any{ - "protocol": node.Type, - "node_type": node.Type, - "nodeType": node.Type, - "listen_ip": "0.0.0.0", - "server_port": node.ServerPort, - "network": getMapAny(settings, "network"), - "networkSettings": getMapAny(settings, "network_settings"), - "network_settings": getMapAny(settings, "network_settings"), + "protocol": node.Type, + "listen_ip": "0.0.0.0", + "server_port": node.ServerPort, + "network": getMapAny(settings, "network"), + "networkSettings": getMapAny(settings, "network_settings"), + } + if val, ok := baseConfig["networkSettings"]; ok && (val == nil || isEmptyContainer(val)) { + baseConfig["networkSettings"] = nil } response := cloneNodePayload(baseConfig) @@ -384,7 +384,6 @@ func BuildNodeConfigPayload(node *model.Server) map[string]any { } case "vmess": response["tls"] = getMapInt(settings, "tls") - response["tlsSettings"] = getMapAny(settings, "tls_settings") response["multiplex"] = getMapAny(settings, "multiplex") case "trojan": response["host"] = node.Host @@ -393,10 +392,8 @@ func BuildNodeConfigPayload(node *model.Server) map[string]any { response["tls"] = getMapInt(settings, "tls") if getMapInt(settings, "tls") == 2 { response["tls_settings"] = getMapAny(settings, "reality_settings") - response["tlsSettings"] = getMapAny(settings, "reality_settings") } else { response["tls_settings"] = nil - response["tlsSettings"] = nil } case "vless": response["tls"] = getMapInt(settings, "tls") @@ -412,10 +409,8 @@ func BuildNodeConfigPayload(node *model.Server) map[string]any { } if getMapInt(settings, "tls") == 2 { response["tls_settings"] = getMapAny(settings, "reality_settings") - response["tlsSettings"] = getMapAny(settings, "reality_settings") } else { response["tls_settings"] = getMapAny(settings, "tls_settings") - response["tlsSettings"] = getMapAny(settings, "tls_settings") } case "hysteria": tls, _ := settings["tls"].(map[string]any) @@ -456,11 +451,9 @@ func BuildNodeConfigPayload(node *model.Server) map[string]any { case "naive": response["tls"] = getMapInt(settings, "tls") response["tls_settings"] = getMapAny(settings, "tls_settings") - response["tlsSettings"] = getMapAny(settings, "tls_settings") case "http": response["tls"] = getMapInt(settings, "tls") response["tls_settings"] = getMapAny(settings, "tls_settings") - response["tlsSettings"] = getMapAny(settings, "tls_settings") case "mieru": transport := getMapString(settings, "transport") if strings.TrimSpace(transport) == "" { @@ -771,3 +764,17 @@ func containsInt(values []int, target int) bool { } return false } +func isEmptyContainer(val any) bool { + if val == nil { + return true + } + switch typed := val.(type) { + case map[string]any: + return len(typed) == 0 + case []any: + return len(typed) == 0 + case json.RawMessage: + return len(typed) == 0 || string(typed) == "null" || string(typed) == "[]" || string(typed) == "{}" + } + return false +}