Browse Source

vnext removed

mhsanaei 1 day ago
parent
commit
1de7accd7c
6 changed files with 63 additions and 97 deletions
  1. 16 43
      sub/subJsonService.go
  2. 0 8
      sub/subService.go
  3. 36 32
      web/assets/js/model/outbound.js
  4. 1 1
      web/html/form/outbound.html
  5. 3 1
      web/html/xray.html
  6. 7 12
      web/web.go

+ 16 - 43
sub/subJsonService.go

@@ -292,34 +292,25 @@ func (s *SubJsonService) realityData(rData map[string]any) map[string]any {
 
 
 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, encryption string) json_util.RawMessage {
 	outbound := Outbound{}
 	outbound := Outbound{}
-	usersData := make([]UserVnext, 1)
-
-	usersData[0].ID = client.ID
-	usersData[0].Level = 8
-	if inbound.Protocol == model.VMESS {
-		usersData[0].Security = client.Security
-	}
-	if inbound.Protocol == model.VLESS {
-		usersData[0].Flow = client.Flow
-		usersData[0].Encryption = encryption
-	}
-
-	vnextData := make([]VnextSetting, 1)
-	vnextData[0] = VnextSetting{
-		Address: inbound.Listen,
-		Port:    inbound.Port,
-		Users:   usersData,
-	}
-
 	outbound.Protocol = string(inbound.Protocol)
 	outbound.Protocol = string(inbound.Protocol)
 	outbound.Tag = "proxy"
 	outbound.Tag = "proxy"
 	if s.mux != "" {
 	if s.mux != "" {
 		outbound.Mux = json_util.RawMessage(s.mux)
 		outbound.Mux = json_util.RawMessage(s.mux)
 	}
 	}
 	outbound.StreamSettings = streamSettings
 	outbound.StreamSettings = streamSettings
-	outbound.Settings = OutboundSettings{
-		Vnext: vnextData,
+	// 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 {
+		settings["flow"] = client.Flow
+		settings["encryption"] = encryption
+	}
+	if inbound.Protocol == model.VMESS {
+		settings["security"] = client.Security
 	}
 	}
+	outbound.Settings = settings
 
 
 	result, _ := json.MarshalIndent(outbound, "", "  ")
 	result, _ := json.MarshalIndent(outbound, "", "  ")
 	return result
 	return result
@@ -356,8 +347,8 @@ func (s *SubJsonService) genServer(inbound *model.Inbound, streamSettings json_u
 		outbound.Mux = json_util.RawMessage(s.mux)
 		outbound.Mux = json_util.RawMessage(s.mux)
 	}
 	}
 	outbound.StreamSettings = streamSettings
 	outbound.StreamSettings = streamSettings
-	outbound.Settings = OutboundSettings{
-		Servers: serverData,
+	outbound.Settings = map[string]any{
+		"servers": serverData,
 	}
 	}
 
 
 	result, _ := json.MarshalIndent(outbound, "", "  ")
 	result, _ := json.MarshalIndent(outbound, "", "  ")
@@ -369,28 +360,10 @@ type Outbound struct {
 	Tag            string               `json:"tag"`
 	Tag            string               `json:"tag"`
 	StreamSettings json_util.RawMessage `json:"streamSettings"`
 	StreamSettings json_util.RawMessage `json:"streamSettings"`
 	Mux            json_util.RawMessage `json:"mux,omitempty"`
 	Mux            json_util.RawMessage `json:"mux,omitempty"`
-	ProxySettings  map[string]any       `json:"proxySettings,omitempty"`
-	Settings       OutboundSettings     `json:"settings,omitempty"`
-}
-
-type OutboundSettings struct {
-	Vnext   []VnextSetting  `json:"vnext,omitempty"`
-	Servers []ServerSetting `json:"servers,omitempty"`
-}
-
-type VnextSetting struct {
-	Address string      `json:"address"`
-	Port    int         `json:"port"`
-	Users   []UserVnext `json:"users"`
+	Settings       map[string]any       `json:"settings,omitempty"`
 }
 }
 
 
-type UserVnext struct {
-	Encryption string `json:"encryption,omitempty"`
-	Flow       string `json:"flow,omitempty"`
-	ID         string `json:"id"`
-	Security   string `json:"security,omitempty"`
-	Level      int    `json:"level"`
-}
+// Legacy vnext-related structs removed for flattened schema
 
 
 type ServerSetting struct {
 type ServerSetting struct {
 	Password string `json:"password"`
 	Password string `json:"password"`

+ 0 - 8
sub/subService.go

@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"fmt"
 	"net"
 	"net"
 	"net/url"
 	"net/url"
-	"strconv"
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
@@ -1139,10 +1138,3 @@ func getHostFromXFH(s string) (string, error) {
 	}
 	}
 	return s, nil
 	return s, nil
 }
 }
-
-func parseInt64(s string) (int64, error) {
-	// handle potential quotes
-	s = strings.Trim(s, "\"'")
-	n, err := strconv.ParseInt(s, 10, 64)
-	return n, err
-}

+ 36 - 32
web/assets/js/model/outbound.js

@@ -219,7 +219,7 @@ class KcpStreamSettings extends CommonClass {
 
 
 class WsStreamSettings extends CommonClass {
 class WsStreamSettings extends CommonClass {
     constructor(
     constructor(
-        path = '/', 
+        path = '/',
         host = '',
         host = '',
         heartbeatPeriod = 0,
         heartbeatPeriod = 0,
 
 
@@ -647,10 +647,6 @@ class Outbound extends CommonClass {
         ].includes(this.protocol);
         ].includes(this.protocol);
     }
     }
 
 
-    hasVnext() {
-        return [Protocols.VMess, Protocols.VLESS].includes(this.protocol);
-    }
-
     hasServers() {
     hasServers() {
         return [Protocols.Trojan, Protocols.Shadowsocks, Protocols.Socks, Protocols.HTTP].includes(this.protocol);
         return [Protocols.Trojan, Protocols.Shadowsocks, Protocols.Socks, Protocols.HTTP].includes(this.protocol);
     }
     }
@@ -690,13 +686,22 @@ 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;
+        // 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 {
-            tag: this.tag == '' ? undefined : this.tag,
             protocol: this.protocol,
             protocol: this.protocol,
-            settings: this.settings instanceof CommonClass ? this.settings.toJson() : this.settings,
-            streamSettings: stream,
-            sendThrough: this.sendThrough != "" ? this.sendThrough : undefined,
-            mux: this.mux?.enabled ? this.mux : undefined,
+            settings: settingsOut,
+            // Only include tag, streamSettings, sendThrough, mux if present and not empty
+            ...(this.tag ? { tag: this.tag } : {}),
+            ...(stream ? { streamSettings: stream } : {}),
+            ...(this.sendThrough ? { sendThrough: this.sendThrough } : {}),
+            ...(this.mux?.enabled ? { mux: this.mux } : {}),
         };
         };
     }
     }
 
 
@@ -908,7 +913,7 @@ Outbound.FreedomSettings = class extends CommonClass {
     toJson() {
     toJson() {
         return {
         return {
             domainStrategy: ObjectUtil.isEmpty(this.domainStrategy) ? undefined : this.domainStrategy,
             domainStrategy: ObjectUtil.isEmpty(this.domainStrategy) ? undefined : this.domainStrategy,
-            redirect: ObjectUtil.isEmpty(this.redirect) ? undefined: this.redirect,
+            redirect: ObjectUtil.isEmpty(this.redirect) ? undefined : this.redirect,
             fragment: Object.keys(this.fragment).length === 0 ? undefined : this.fragment,
             fragment: Object.keys(this.fragment).length === 0 ? undefined : this.fragment,
             noises: this.noises.length === 0 ? undefined : Outbound.FreedomSettings.Noise.toJsonArray(this.noises),
             noises: this.noises.length === 0 ? undefined : Outbound.FreedomSettings.Noise.toJsonArray(this.noises),
         };
         };
@@ -1026,22 +1031,21 @@ Outbound.VmessSettings = class extends CommonClass {
     }
     }
 
 
     static fromJson(json = {}) {
     static fromJson(json = {}) {
-        if (ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VmessSettings();
+        if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VmessSettings();
         return new Outbound.VmessSettings(
         return new Outbound.VmessSettings(
-            json.vnext[0].address,
-            json.vnext[0].port,
-            json.vnext[0].users[0].id,
-            json.vnext[0].users[0].security,
+            json.address,
+            json.port,
+            json.id,
+            json.security,
         );
         );
     }
     }
 
 
     toJson() {
     toJson() {
         return {
         return {
-            vnext: [{
-                address: this.address,
-                port: this.port,
-                users: [{ id: this.id, security: this.security }],
-            }],
+            address: this.address,
+            port: this.port,
+            id: this.id,
+            security: this.security,
         };
         };
     }
     }
 };
 };
@@ -1056,23 +1060,23 @@ Outbound.VLESSSettings = class extends CommonClass {
     }
     }
 
 
     static fromJson(json = {}) {
     static fromJson(json = {}) {
-        if (ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VLESSSettings();
+        if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VLESSSettings();
         return new Outbound.VLESSSettings(
         return new Outbound.VLESSSettings(
-            json.vnext[0].address,
-            json.vnext[0].port,
-            json.vnext[0].users[0].id,
-            json.vnext[0].users[0].flow,
-            json.vnext[0].users[0].encryption,
+            json.address,
+            json.port,
+            json.id,
+            json.flow,
+            json.encryption
         );
         );
     }
     }
 
 
     toJson() {
     toJson() {
         return {
         return {
-            vnext: [{
-                address: this.address,
-                port: this.port,
-                users: [{ id: this.id, flow: this.flow, encryption: this.encryption }],
-            }],
+            address: this.address,
+            port: this.port,
+            id: this.id,
+            flow: this.flow,
+            encryption: this.encryption,
         };
         };
     }
     }
 };
 };

+ 1 - 1
web/html/form/outbound.html

@@ -210,7 +210,7 @@
         </a-form-item>
         </a-form-item>
       </template>
       </template>
 
 
-      <!-- Vnext (vless/vmess) settings -->
+  <!-- VLESS/VMess user settings -->
       <template v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)">
       <template v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)">
         <a-form-item label='ID'>
         <a-form-item label='ID'>
           <a-input v-model.trim="outbound.settings.id"></a-input>
           <a-input v-model.trim="outbound.settings.id"></a-input>

+ 3 - 1
web/html/xray.html

@@ -535,7 +535,9 @@
         switch (o.protocol) {
         switch (o.protocol) {
           case Protocols.VMess:
           case Protocols.VMess:
           case Protocols.VLESS:
           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.HTTP:
           case Protocols.HTTP:
           case Protocols.Mixed:
           case Protocols.Mixed:

+ 7 - 12
web/web.go

@@ -289,18 +289,13 @@ func (s *Server) startTask() {
 	// check client ips from log file every day
 	// check client ips from log file every day
 	s.cron.AddJob("@daily", job.NewClearLogsJob())
 	s.cron.AddJob("@daily", job.NewClearLogsJob())
 
 
-	// Periodic traffic resets
-	logger.Info("Scheduling periodic traffic reset jobs")
-	{
-		// Inbound traffic reset jobs
-		// Run once a day, midnight
-		s.cron.AddJob("@daily", job.NewPeriodicTrafficResetJob("daily"))
-		// Run once a week, midnight between Sat/Sun
-		s.cron.AddJob("@weekly", job.NewPeriodicTrafficResetJob("weekly"))
-		// Run once a month, midnight, first of month
-		s.cron.AddJob("@monthly", job.NewPeriodicTrafficResetJob("monthly"))
-
-	}
+	// Inbound traffic reset jobs
+	// Run once a day, midnight
+	s.cron.AddJob("@daily", job.NewPeriodicTrafficResetJob("daily"))
+	// Run once a week, midnight between Sat/Sun
+	s.cron.AddJob("@weekly", job.NewPeriodicTrafficResetJob("weekly"))
+	// Run once a month, midnight, first of month
+	s.cron.AddJob("@monthly", job.NewPeriodicTrafficResetJob("monthly"))
 
 
 	// Make a traffic condition every day, 8:30
 	// Make a traffic condition every day, 8:30
 	var entry cron.EntryID
 	var entry cron.EntryID