Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormhsanaei <ho3ein.sanaei@gmail.com>2025-09-20 12:11:30 +0300
committermhsanaei <ho3ein.sanaei@gmail.com>2025-09-20 14:10:57 +0300
commit37c17357fc45b9acec387f3097be5db074ce880d (patch)
treea3a5aa82c7483c0883070185372c491537173c25
parentb35d33966589f428053b77f51a92ec0214bd92fb (diff)
undo vnext for vmess
-rw-r--r--database/model/model.go8
-rw-r--r--sub/subJsonService.go68
-rw-r--r--sub/subService.go13
-rw-r--r--web/assets/js/model/outbound.js36
-rw-r--r--web/html/xray.html8
5 files changed, 80 insertions, 53 deletions
diff --git a/database/model/model.go b/database/model/model.go
index 720f0223..4ca39d87 100644
--- a/database/model/model.go
+++ b/database/model/model.go
@@ -119,11 +119,3 @@ type Client struct {
CreatedAt int64 `json:"created_at,omitempty"` // Creation 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
-}
diff --git a/sub/subJsonService.go b/sub/subJsonService.go
index f440ab65..86a7a405 100644
--- a/sub/subJsonService.go
+++ b/sub/subJsonService.go
@@ -174,12 +174,12 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client,
case "tls":
if newStream["security"] != "tls" {
newStream["security"] = "tls"
- newStream["tslSettings"] = map[string]any{}
+ newStream["tlsSettings"] = map[string]any{}
}
case "none":
if newStream["security"] != "none" {
newStream["security"] = "none"
- delete(newStream, "tslSettings")
+ delete(newStream, "tlsSettings")
}
}
streamSettings, _ := json.MarshalIndent(newStream, "", " ")
@@ -188,13 +188,9 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client,
switch inbound.Protocol {
case "vmess":
- newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client, ""))
+ newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client))
case "vless":
- var vlessSettings model.VLESSSettings
- _ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings)
-
- newOutbounds = append(newOutbounds,
- s.genVnext(inbound, streamSettings, client, vlessSettings.Encryption))
+ newOutbounds = append(newOutbounds, s.genVless(inbound, streamSettings, client))
case "trojan", "shadowsocks":
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
}
-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.Protocol = string(inbound.Protocol)
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.StreamSettings = streamSettings
- // Emit flattened settings inside Settings to match new Xray format
settings := make(map[string]any)
settings["address"] = inbound.Listen
settings["port"] = inbound.Port
settings["id"] = client.ID
- if inbound.Protocol == model.VLESS {
+ if client.Flow != "" {
settings["flow"] = client.Flow
- settings["encryption"] = encryption
}
- if inbound.Protocol == model.VMESS {
- settings["security"] = client.Security
+
+ // 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
}
- outbound.Settings = settings
+ outbound.Settings = settings
result, _ := json.MarshalIndent(outbound, "", " ")
return result
}
@@ -366,7 +392,17 @@ type Outbound struct {
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 {
Password string `json:"password"`
diff --git a/sub/subService.go b/sub/subService.go
index 9f28b35b..6204fdee 100644
--- a/sub/subService.go
+++ b/sub/subService.go
@@ -321,9 +321,6 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
if inbound.Protocol != model.VLESS {
return ""
}
- var vlessSettings model.VLESSSettings
- _ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings)
-
var stream map[string]any
json.Unmarshal([]byte(inbound.StreamSettings), &stream)
clients, _ := s.inboundService.GetClients(inbound)
@@ -338,11 +335,15 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
port := inbound.Port
streamNetwork := stream["network"].(string)
params := make(map[string]string)
- if vlessSettings.Encryption != "" {
- params["encryption"] = vlessSettings.Encryption
- }
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 {
case "tcp":
tcp, _ := stream["tcpSettings"].(map[string]any)
diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js
index 3e481dff..c727abae 100644
--- a/web/assets/js/model/outbound.js
+++ b/web/assets/js/model/outbound.js
@@ -686,14 +686,7 @@ class Outbound extends CommonClass {
if (this.stream?.sockopt)
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;
- // 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 {
protocol: this.protocol,
settings: settingsOut,
@@ -1031,21 +1024,28 @@ Outbound.VmessSettings = class extends CommonClass {
}
static fromJson(json = {}) {
- if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VmessSettings();
- return new Outbound.VmessSettings(
- json.address,
- json.port,
- json.id,
- json.security,
- );
+ if (!ObjectUtil.isArrEmpty(json.vnext)) {
+ const v = json.vnext[0] || {};
+ const u = ObjectUtil.isArrEmpty(v.users) ? {} : v.users[0];
+ return new Outbound.VmessSettings(
+ v.address,
+ v.port,
+ u.id,
+ u.security,
+ );
+ }
}
toJson() {
return {
- address: this.address,
- port: this.port,
- id: this.id,
- security: this.security,
+ vnext: [{
+ address: this.address,
+ port: this.port,
+ users: [{
+ id: this.id,
+ security: this.security
+ }]
+ }]
};
}
};
diff --git a/web/html/xray.html b/web/html/xray.html
index 258c81c9..266f9eef 100644
--- a/web/html/xray.html
+++ b/web/html/xray.html
@@ -534,13 +534,11 @@
serverObj = null;
switch (o.protocol) {
case Protocols.VMess:
- case Protocols.VLESS:
- if (o.settings && o.settings.address && o.settings.port) {
- return [o.settings.address + ':' + o.settings.port];
- }
+ serverObj = o.settings.vnext;
break;
+ case Protocols.VLESS:
case Protocols.HTTP:
- case Protocols.Mixed:
+ case Protocols.Socks:
case Protocols.Shadowsocks:
case Protocols.Trojan:
serverObj = o.settings.servers;