5 Commits 9c4fa23931 ... fbcab5bc52

Autor SHA1 Mensagem Data
  mhsanaei fbcab5bc52 login page - more width for lang 3 dias atrás
  mhsanaei 89c79c3ec3 more details - vmess security 3 dias atrás
  mhsanaei 566cd9e9c4 New - Allocate 3 dias atrás
  mhsanaei ad78cec7c7 fix mistake - security only for vmess 3 dias atrás
  mhsanaei 176ab5f48e New - DNS Outbound (nonIPQuery, blockTypes) 3 dias atrás

+ 2 - 0
database/model/model.go

@@ -46,6 +46,7 @@ type Inbound struct {
 	StreamSettings string   `json:"streamSettings" form:"streamSettings"`
 	Tag            string   `json:"tag" form:"tag" gorm:"unique"`
 	Sniffing       string   `json:"sniffing" form:"sniffing"`
+	Allocate       string   `json:"allocate" form:"allocate"`
 }
 
 type OutboundTraffics struct {
@@ -75,6 +76,7 @@ func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
 		StreamSettings: json_util.RawMessage(i.StreamSettings),
 		Tag:            i.Tag,
 		Sniffing:       json_util.RawMessage(i.Sniffing),
+		Allocate:       json_util.RawMessage(i.Allocate),
 	}
 }
 

+ 1 - 0
sub/default.json

@@ -23,6 +23,7 @@
         "destOverride": [
           "http",
           "tls",
+          "quic",
           "fakedns"
         ],
         "enabled": true

+ 11 - 1
web/assets/js/model/outbound.js

@@ -934,11 +934,19 @@ Outbound.BlackholeSettings = class extends CommonClass {
     }
 };
 Outbound.DNSSettings = class extends CommonClass {
-    constructor(network = 'udp', address = '1.1.1.1', port = 53) {
+    constructor(
+        network = 'udp',
+        address = '1.1.1.1',
+        port = 53,
+        nonIPQuery = 'drop',
+        blockTypes = []
+    ) {
         super();
         this.network = network;
         this.address = address;
         this.port = port;
+        this.nonIPQuery = nonIPQuery;
+        this.blockTypes = blockTypes;
     }
 
     static fromJson(json = {}) {
@@ -946,6 +954,8 @@ Outbound.DNSSettings = class extends CommonClass {
             json.network,
             json.address,
             json.port,
+            json.nonIPQuery,
+            json.blockTypes,
         );
     }
 };

+ 26 - 0
web/assets/js/model/xray.js

@@ -1197,6 +1197,27 @@ class Sniffing extends XrayCommonClass {
     }
 }
 
+class Allocate extends XrayCommonClass {
+    constructor(
+        strategy = "always",
+        refresh = 5,
+        concurrency = 3,
+    ) {
+        super();
+        this.strategy = strategy;
+        this.refresh = refresh;
+        this.concurrency = concurrency;
+    }
+
+    static fromJson(json = {}) {
+        return new Allocate(
+            json.strategy,
+            json.refresh,
+            json.concurrency,
+        );
+    }
+}
+
 class Inbound extends XrayCommonClass {
     constructor(
         port = RandomUtil.randomIntRange(10000, 60000),
@@ -1206,6 +1227,7 @@ class Inbound extends XrayCommonClass {
         streamSettings = new StreamSettings(),
         tag = '',
         sniffing = new Sniffing(),
+        allocate = new Allocate(),
         clientStats = '',
     ) {
         super();
@@ -1216,6 +1238,7 @@ class Inbound extends XrayCommonClass {
         this.stream = streamSettings;
         this.tag = tag;
         this.sniffing = sniffing;
+        this.allocate = allocate;
         this.clientStats = clientStats;
     }
     getClientStats() {
@@ -1406,6 +1429,7 @@ class Inbound extends XrayCommonClass {
         this.stream = new StreamSettings();
         this.tag = '';
         this.sniffing = new Sniffing();
+        this.allocate = new Allocate();
     }
 
     genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) {
@@ -1885,6 +1909,7 @@ class Inbound extends XrayCommonClass {
             StreamSettings.fromJson(json.streamSettings),
             json.tag,
             Sniffing.fromJson(json.sniffing),
+            Allocate.fromJson(json.allocate),
             json.clientStats
         )
     }
@@ -1902,6 +1927,7 @@ class Inbound extends XrayCommonClass {
             streamSettings: streamSettings,
             tag: this.tag,
             sniffing: this.sniffing.toJson(),
+            allocate: this.allocate.toJson(),
             clientStats: this.clientStats
         };
     }

+ 1 - 1
web/html/login.html

@@ -449,7 +449,7 @@
                     <a-row justify="center" class="centered">
                       <a-col :span="24">
                         <a-select ref="selectLang" v-model="lang"
-                                  @change="setLang(lang)" style="width: 150px;"
+                                  @change="setLang(lang)" style="width: 200px;"
                                   :dropdown-class-name="themeSwitcher.currentTheme">
                           <a-select-option :value="l.value" label="English" v-for="l in supportLangs">
                             <span role="img" aria-label="l.name" v-text="l.icon"></span>

+ 1 - 1
web/html/xui/client_bulk_modal.html

@@ -28,7 +28,7 @@
         <a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2">
             <a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
         </a-form-item>
-        <a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
+        <a-form-item label='{{ i18n "security" }}' v-if="inbound.protocol === Protocols.VMESS">
             <a-select v-model="clientsBulkModal.security" :dropdown-class-name="themeSwitcher.currentTheme">
                 <a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
             </a-select>

+ 16 - 0
web/html/xui/form/allocate.html

@@ -0,0 +1,16 @@
+{{define "form/allocate"}}
+<a-divider style="margin:5px 0 0;">Allocate</a-divider>
+<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
+    <a-form-item label='strategy'>
+      <a-select v-model="inbound.allocate.strategy" :dropdown-class-name="themeSwitcher.currentTheme">
+        <a-select-option v-for="s in ['always','random']" :value="s">[[ s ]]</a-select-option>
+      </a-select>
+    </a-form-item>
+    <a-form-item label='refresh'>
+      <a-input-number v-model.number="inbound.allocate.refresh" min="0"></a-input-number>
+    </a-form-item>
+    <a-form-item label='concurrency'>
+      <a-input-number v-model.number="inbound.allocate.concurrency" min="0"></a-input-number>
+    </a-form-item>
+</a-form>
+{{end}}

+ 1 - 1
web/html/xui/form/client.html

@@ -39,7 +39,7 @@
         </template>
         <a-input v-model.trim="client.id"></a-input>
     </a-form-item>
-    <a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
+    <a-form-item v-if="inbound.protocol === Protocols.VMESS" label='{{ i18n "security" }}'>
         <a-select v-model="client.security" :dropdown-class-name="themeSwitcher.currentTheme">
             <a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
         </a-select>

+ 6 - 0
web/html/xui/form/inbound.html

@@ -118,4 +118,10 @@
 <template>
     {{template "form/sniffing"}}
 </template>
+
+<!-- allocate -->
+<template>
+    {{template "form/allocate"}}
+</template>
+
 {{end}}

+ 17 - 5
web/html/xui/form/outbound.html

@@ -75,6 +75,14 @@
             <a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option>
           </a-select>
         </a-form-item>
+        <a-form-item label='non-IP queries'>
+          <a-select v-model="outbound.settings.nonIPQuery" :dropdown-class-name="themeSwitcher.currentTheme">
+            <a-select-option v-for="s in ['drop','skip']" :value="s">[[ s ]]</a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item v-if="outbound.settings.nonIPQuery === 'skip'" label='Block Types' >
+          <a-input v-model.number="outbound.settings.blockTypes"></a-input>
+        </a-form-item>
       </template>
 
       <!-- wireguard settings -->
@@ -179,11 +187,15 @@
         <a-form-item label='ID'>
           <a-input v-model.trim="outbound.settings.id"></a-input>
         </a-form-item>
-        <a-form-item label='Security'>
-          <a-select v-model="outbound.settings.security" :dropdown-class-name="themeSwitcher.currentTheme">
-            <a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
-          </a-select>
-        </a-form-item>
+
+        <!-- vmess settings -->
+        <template v-if="outbound.protocol === Protocols.VMess">
+          <a-form-item label='Security'>
+            <a-select v-model="outbound.settings.security" :dropdown-class-name="themeSwitcher.currentTheme">
+              <a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
+            </a-select>
+          </a-form-item>
+        </template>
 
         <!-- vless settings -->
         <template v-if="outbound.canEnableTlsFlow()">

+ 1 - 1
web/html/xui/form/protocol/vmess.html

@@ -10,7 +10,7 @@
             <tr class="client-table-header">
                 <th>{{ i18n "pages.inbounds.email" }}</th>
                 <th>ID</th>
-                <th>Security</th>
+                <th>{{ i18n "security" }}</th>
             </tr>
             <tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
                 <td>[[ client.email ]]</td>

+ 1 - 1
web/html/xui/form/sniffing.html

@@ -1,5 +1,5 @@
 {{define "form/sniffing"}}
-<a-divider style="margin:5px 0 0;"></a-divider>
+<a-divider style="margin:5px 0 0;">Sniffing</a-divider>
 <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
   <a-form-item>
     <span slot="label">

+ 6 - 0
web/html/xui/inbound_info_modal.html

@@ -139,6 +139,12 @@
             <a-tag>[[ infoModal.clientSettings.id ]]</a-tag>
           </td>
         </tr>
+        <tr v-if="dbInbound.isVMess">
+          <td>{{ i18n "security" }}</td>
+          <td>
+            <a-tag>[[ infoModal.clientSettings.security ]]</a-tag>
+          </td>
+        </tr>
         <tr v-if="infoModal.inbound.canEnableTlsFlow()">
           <td>Flow</td>
           <td v-if="infoModal.clientSettings.flow">

+ 3 - 0
web/html/xui/inbounds.html

@@ -935,6 +935,7 @@
                     settings: Inbound.Settings.getSettings(baseInbound.protocol).toString(),
                     streamSettings: baseInbound.stream.toString(),
                     sniffing: baseInbound.sniffing.toString(),
+                    allocate: baseInbound.allocate.toString(),
                 };
                 await this.submit('/panel/inbound/add', data, inModal);
             },
@@ -980,6 +981,7 @@
                 };
                 if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString();
                 data.sniffing = inbound.sniffing.toString();
+                data.allocate = inbound.allocate.toString();
 
                 await this.submit('/panel/inbound/add', data, inModal);
             },
@@ -999,6 +1001,7 @@
                 };
                 if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString();
                 data.sniffing = inbound.sniffing.toString();
+                data.allocate = inbound.allocate.toString();
 
                 await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal);
             },

+ 1 - 0
web/service/inbound.go

@@ -331,6 +331,7 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
 	oldInbound.Settings = inbound.Settings
 	oldInbound.StreamSettings = inbound.StreamSettings
 	oldInbound.Sniffing = inbound.Sniffing
+	oldInbound.Allocate = inbound.Allocate
 	if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
 		oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port)
 	} else {

+ 4 - 0
xray/inbound.go

@@ -14,6 +14,7 @@ type InboundConfig struct {
 	StreamSettings json_util.RawMessage `json:"streamSettings"`
 	Tag            string               `json:"tag"`
 	Sniffing       json_util.RawMessage `json:"sniffing"`
+	Allocate       json_util.RawMessage `json:"allocate"`
 }
 
 func (c *InboundConfig) Equals(other *InboundConfig) bool {
@@ -38,5 +39,8 @@ func (c *InboundConfig) Equals(other *InboundConfig) bool {
 	if !bytes.Equal(c.Sniffing, other.Sniffing) {
 		return false
 	}
+	if !bytes.Equal(c.Allocate, other.Allocate) {
+		return false
+	}
 	return true
 }