undo vnext for vmess
Some checks are pending
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (push) Waiting to run

This commit is contained in:
mhsanaei 2025-09-20 11:11:30 +02:00
parent b35d339665
commit 37c17357fc
No known key found for this signature in database
GPG key ID: D875CD086CF668A0
5 changed files with 80 additions and 53 deletions

View file

@ -119,11 +119,3 @@ type Client struct {
CreatedAt int64 `json:"created_at,omitempty"` // Creation timestamp CreatedAt int64 `json:"created_at,omitempty"` // Creation timestamp
UpdatedAt int64 `json:"updated_at,omitempty"` // Last update timestamp UpdatedAt int64 `json:"updated_at,omitempty"` // Last update timestamp
} }
// VLESSSettings contains VLESS protocol-specific configuration settings.
type VLESSSettings struct {
Clients []Client `json:"clients"` // List of VLESS clients
Decryption string `json:"decryption"` // Decryption method
Encryption string `json:"encryption"` // Encryption method (usually "none" for VLESS)
Fallbacks []any `json:"fallbacks"` // Fallback configurations
}

View file

@ -174,12 +174,12 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client,
case "tls": case "tls":
if newStream["security"] != "tls" { if newStream["security"] != "tls" {
newStream["security"] = "tls" newStream["security"] = "tls"
newStream["tslSettings"] = map[string]any{} newStream["tlsSettings"] = map[string]any{}
} }
case "none": case "none":
if newStream["security"] != "none" { if newStream["security"] != "none" {
newStream["security"] = "none" newStream["security"] = "none"
delete(newStream, "tslSettings") delete(newStream, "tlsSettings")
} }
} }
streamSettings, _ := json.MarshalIndent(newStream, "", " ") streamSettings, _ := json.MarshalIndent(newStream, "", " ")
@ -188,13 +188,9 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client,
switch inbound.Protocol { switch inbound.Protocol {
case "vmess": case "vmess":
newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client, "")) newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client))
case "vless": case "vless":
var vlessSettings model.VLESSSettings newOutbounds = append(newOutbounds, s.genVless(inbound, streamSettings, client))
_ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings)
newOutbounds = append(newOutbounds,
s.genVnext(inbound, streamSettings, client, vlessSettings.Encryption))
case "trojan", "shadowsocks": case "trojan", "shadowsocks":
newOutbounds = append(newOutbounds, s.genServer(inbound, streamSettings, client)) newOutbounds = append(newOutbounds, s.genServer(inbound, streamSettings, client))
} }
@ -293,7 +289,35 @@ func (s *SubJsonService) realityData(rData map[string]any) map[string]any {
return rltyData return rltyData
} }
func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client, encryption string) json_util.RawMessage { func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client) json_util.RawMessage {
outbound := Outbound{}
usersData := make([]UserVnext, 1)
usersData[0].ID = client.ID
usersData[0].Email = client.Email
usersData[0].Security = client.Security
vnextData := make([]VnextSetting, 1)
vnextData[0] = VnextSetting{
Address: inbound.Listen,
Port: inbound.Port,
Users: usersData,
}
outbound.Protocol = string(inbound.Protocol)
outbound.Tag = "proxy"
if s.mux != "" {
outbound.Mux = json_util.RawMessage(s.mux)
}
outbound.StreamSettings = streamSettings
outbound.Settings = map[string]any{
"vnext": vnextData,
}
result, _ := json.MarshalIndent(outbound, "", " ")
return result
}
func (s *SubJsonService) genVless(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client) json_util.RawMessage {
outbound := Outbound{} outbound := Outbound{}
outbound.Protocol = string(inbound.Protocol) outbound.Protocol = string(inbound.Protocol)
outbound.Tag = "proxy" outbound.Tag = "proxy"
@ -301,20 +325,22 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut
outbound.Mux = json_util.RawMessage(s.mux) outbound.Mux = json_util.RawMessage(s.mux)
} }
outbound.StreamSettings = streamSettings outbound.StreamSettings = streamSettings
// Emit flattened settings inside Settings to match new Xray format
settings := make(map[string]any) settings := make(map[string]any)
settings["address"] = inbound.Listen settings["address"] = inbound.Listen
settings["port"] = inbound.Port settings["port"] = inbound.Port
settings["id"] = client.ID settings["id"] = client.ID
if inbound.Protocol == model.VLESS { if client.Flow != "" {
settings["flow"] = client.Flow settings["flow"] = client.Flow
}
// Add encryption for VLESS outbound from inbound settings
var inboundSettings map[string]any
json.Unmarshal([]byte(inbound.Settings), &inboundSettings)
if encryption, ok := inboundSettings["encryption"].(string); ok {
settings["encryption"] = encryption settings["encryption"] = encryption
} }
if inbound.Protocol == model.VMESS {
settings["security"] = client.Security
}
outbound.Settings = settings
outbound.Settings = settings
result, _ := json.MarshalIndent(outbound, "", " ") result, _ := json.MarshalIndent(outbound, "", " ")
return result return result
} }
@ -366,7 +392,17 @@ type Outbound struct {
Settings map[string]any `json:"settings,omitempty"` Settings map[string]any `json:"settings,omitempty"`
} }
// Legacy vnext-related structs removed for flattened schema type VnextSetting struct {
Address string `json:"address"`
Port int `json:"port"`
Users []UserVnext `json:"users"`
}
type UserVnext struct {
ID string `json:"id"`
Email string `json:"email,omitempty"`
Security string `json:"security,omitempty"`
}
type ServerSetting struct { type ServerSetting struct {
Password string `json:"password"` Password string `json:"password"`

View file

@ -321,9 +321,6 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
if inbound.Protocol != model.VLESS { if inbound.Protocol != model.VLESS {
return "" return ""
} }
var vlessSettings model.VLESSSettings
_ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings)
var stream map[string]any var stream map[string]any
json.Unmarshal([]byte(inbound.StreamSettings), &stream) json.Unmarshal([]byte(inbound.StreamSettings), &stream)
clients, _ := s.inboundService.GetClients(inbound) clients, _ := s.inboundService.GetClients(inbound)
@ -338,11 +335,15 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
port := inbound.Port port := inbound.Port
streamNetwork := stream["network"].(string) streamNetwork := stream["network"].(string)
params := make(map[string]string) params := make(map[string]string)
if vlessSettings.Encryption != "" {
params["encryption"] = vlessSettings.Encryption
}
params["type"] = streamNetwork params["type"] = streamNetwork
// Add encryption parameter for VLESS from inbound settings
var settings map[string]any
json.Unmarshal([]byte(inbound.Settings), &settings)
if encryption, ok := settings["encryption"].(string); ok {
params["encryption"] = encryption
}
switch streamNetwork { switch streamNetwork {
case "tcp": case "tcp":
tcp, _ := stream["tcpSettings"].(map[string]any) tcp, _ := stream["tcpSettings"].(map[string]any)

View file

@ -686,14 +686,7 @@ class Outbound extends CommonClass {
if (this.stream?.sockopt) if (this.stream?.sockopt)
stream = { sockopt: this.stream.sockopt.toJson() }; stream = { sockopt: this.stream.sockopt.toJson() };
} }
// For VMess/VLESS, emit settings as a flat object
let settingsOut = this.settings instanceof CommonClass ? this.settings.toJson() : this.settings; let settingsOut = this.settings instanceof CommonClass ? this.settings.toJson() : this.settings;
// Remove undefined/null keys
if (settingsOut && typeof settingsOut === 'object') {
Object.keys(settingsOut).forEach(k => {
if (settingsOut[k] === undefined || settingsOut[k] === null) delete settingsOut[k];
});
}
return { return {
protocol: this.protocol, protocol: this.protocol,
settings: settingsOut, settings: settingsOut,
@ -1031,21 +1024,28 @@ Outbound.VmessSettings = class extends CommonClass {
} }
static fromJson(json = {}) { static fromJson(json = {}) {
if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VmessSettings(); if (!ObjectUtil.isArrEmpty(json.vnext)) {
return new Outbound.VmessSettings( const v = json.vnext[0] || {};
json.address, const u = ObjectUtil.isArrEmpty(v.users) ? {} : v.users[0];
json.port, return new Outbound.VmessSettings(
json.id, v.address,
json.security, v.port,
); u.id,
u.security,
);
}
} }
toJson() { toJson() {
return { return {
address: this.address, vnext: [{
port: this.port, address: this.address,
id: this.id, port: this.port,
security: this.security, users: [{
id: this.id,
security: this.security
}]
}]
}; };
} }
}; };

View file

@ -534,13 +534,11 @@
serverObj = null; serverObj = null;
switch (o.protocol) { switch (o.protocol) {
case Protocols.VMess: case Protocols.VMess:
case Protocols.VLESS: serverObj = o.settings.vnext;
if (o.settings && o.settings.address && o.settings.port) {
return [o.settings.address + ':' + o.settings.port];
}
break; break;
case Protocols.VLESS:
case Protocols.HTTP: case Protocols.HTTP:
case Protocols.Mixed: case Protocols.Socks:
case Protocols.Shadowsocks: case Protocols.Shadowsocks:
case Protocols.Trojan: case Protocols.Trojan:
serverObj = o.settings.servers; serverObj = o.settings.servers;