修复JSON返回值
Some checks failed
build / build (api, amd64, linux) (push) Failing after -51s
build / build (api, arm64, linux) (push) Failing after -52s
build / build (api.exe, amd64, windows) (push) Failing after -51s

This commit is contained in:
CN-JS-HuiBai
2026-04-18 01:00:28 +08:00
parent f9c34fcf87
commit 515b5ae9de
2 changed files with 158 additions and 1 deletions

View File

@@ -96,7 +96,8 @@ func NodeConfig(c *gin.Context) {
node := c.MustGet("node").(*model.Server)
setNodeLastCheck(node)
config := service.BuildNodeConfig(node)
config := service.BuildNodeConfigPayload(node)
config["base_config"] = service.BuildNodeBaseConfigPayload()
c.JSON(http.StatusOK, config)
}

View File

@@ -351,6 +351,162 @@ func BuildNodeConfig(node *model.Server) NodeServerConfig {
return response
}
func BuildNodeConfigPayload(node *model.Server) map[string]any {
settings := parseObject(node.ProtocolSettings)
baseConfig := map[string]any{
"protocol": node.Type,
"listen_ip": "0.0.0.0",
"server_port": node.ServerPort,
"network": getMapAny(settings, "network"),
"networkSettings": getMapAny(settings, "network_settings"),
}
response := cloneNodePayload(baseConfig)
switch node.Type {
case "shadowsocks":
response["cipher"] = getMapAny(settings, "cipher")
response["plugin"] = getMapAny(settings, "plugin")
response["plugin_opts"] = getMapAny(settings, "plugin_opts")
switch getMapString(settings, "cipher") {
case "2022-blake3-aes-128-gcm":
response["server_key"] = serverKey(node.CreatedAt, 16)
case "2022-blake3-aes-256-gcm":
response["server_key"] = serverKey(node.CreatedAt, 32)
default:
response["server_key"] = nil
}
case "vmess":
response["tls"] = getMapInt(settings, "tls")
response["multiplex"] = getMapAny(settings, "multiplex")
case "trojan":
response["host"] = node.Host
response["server_name"] = getMapAny(settings, "server_name")
response["multiplex"] = getMapAny(settings, "multiplex")
response["tls"] = getMapInt(settings, "tls")
if getMapInt(settings, "tls") == 2 {
response["tls_settings"] = getMapAny(settings, "reality_settings")
} else {
response["tls_settings"] = nil
}
case "vless":
response["tls"] = getMapInt(settings, "tls")
response["flow"] = getMapAny(settings, "flow")
response["multiplex"] = getMapAny(settings, "multiplex")
response["decryption"] = nil
if encryption, ok := settings["encryption"].(map[string]any); ok {
if enabled, ok := encryption["enabled"].(bool); ok && enabled {
response["decryption"] = encryption["decryption"]
}
}
if getMapInt(settings, "tls") == 2 {
response["tls_settings"] = getMapAny(settings, "reality_settings")
} else {
response["tls_settings"] = getMapAny(settings, "tls_settings")
}
case "hysteria":
tls, _ := settings["tls"].(map[string]any)
obfs, _ := settings["obfs"].(map[string]any)
bandwidth, _ := settings["bandwidth"].(map[string]any)
version := getMapInt(settings, "version")
response["version"] = version
response["host"] = node.Host
response["server_name"] = getMapAny(tls, "server_name")
response["up_mbps"] = mapAnyInt(bandwidth, "up")
response["down_mbps"] = mapAnyInt(bandwidth, "down")
switch version {
case 1:
response["obfs"] = getMapAny(obfs, "password")
case 2:
if open, ok := obfs["open"].(bool); ok && open {
response["obfs"] = getMapAny(obfs, "type")
} else {
response["obfs"] = nil
}
response["obfs-password"] = getMapAny(obfs, "password")
}
case "tuic":
tls, _ := settings["tls"].(map[string]any)
response["version"] = getMapInt(settings, "version")
response["server_name"] = getMapAny(tls, "server_name")
response["congestion_control"] = getMapAny(settings, "congestion_control")
response["tls_settings"] = getMapAny(settings, "tls_settings")
response["auth_timeout"] = "3s"
response["zero_rtt_handshake"] = false
response["heartbeat"] = "3s"
case "anytls":
tls, _ := settings["tls"].(map[string]any)
response["server_name"] = getMapAny(tls, "server_name")
response["padding_scheme"] = getMapAny(settings, "padding_scheme")
case "socks":
// Base config already matches the original XBoard payload for socks.
case "naive":
response["tls"] = getMapInt(settings, "tls")
response["tls_settings"] = getMapAny(settings, "tls_settings")
case "http":
response["tls"] = getMapInt(settings, "tls")
response["tls_settings"] = getMapAny(settings, "tls_settings")
case "mieru":
transport := getMapString(settings, "transport")
if strings.TrimSpace(transport) == "" {
transport = "TCP"
}
response["transport"] = transport
response["traffic_pattern"] = getMapAny(settings, "traffic_pattern")
}
if routeIDs := parseIntSlice(node.RouteIDs); len(routeIDs) > 0 {
var routes []model.ServerRoute
if err := database.DB.Select("id", "`match`", "action", "action_value").Where("id IN ?", routeIDs).Find(&routes).Error; err == nil {
response["routes"] = routes
}
}
if customOutbounds := parseGenericJSON(node.CustomOutbounds); hasNodePayloadValue(customOutbounds) {
response["custom_outbounds"] = customOutbounds
}
if customRoutes := parseGenericJSON(node.CustomRoutes); hasNodePayloadValue(customRoutes) {
response["custom_routes"] = customRoutes
}
if certConfig := parseObject(node.CertConfig); len(certConfig) > 0 && getMapString(certConfig, "cert_mode") != "none" {
response["cert_config"] = certConfig
}
return response
}
func BuildNodeBaseConfigPayload() map[string]any {
return map[string]any{
"push_interval": MustGetInt("server_push_interval", 60),
"pull_interval": MustGetInt("server_pull_interval", 60),
}
}
func cloneNodePayload(values map[string]any) map[string]any {
result := make(map[string]any, len(values))
for key, value := range values {
result[key] = value
}
return result
}
func hasNodePayloadValue(value any) bool {
switch typed := value.(type) {
case nil:
return false
case string:
return strings.TrimSpace(typed) != ""
case []any:
return len(typed) > 0
case []map[string]any:
return len(typed) > 0
case map[string]any:
return len(typed) > 0
default:
return true
}
}
func ApplyTrafficDelta(userID int, node *model.Server, upload, download int64) {
rate := CurrentRate(node)
scaledUpload := int64(math.Round(float64(upload) * rate))