outbound.html 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. {{define "form/outbound"}}
  2. <!-- base -->
  3. <a-tabs
  4. :active-key="outModal.activeKey"
  5. :style="{ padding: '0', backgroundColor: 'transparent' }"
  6. @change="(activeKey) => {outModal.toggleJson(activeKey == '2'); }"
  7. >
  8. <a-tab-pane key="1" tab="Form">
  9. <a-form
  10. :colon="false"
  11. :label-col="{ md: {span:8} }"
  12. :wrapper-col="{ md: {span:14} }"
  13. >
  14. <a-form-item label='{{ i18n "protocol" }}'>
  15. <a-select
  16. v-model="outbound.protocol"
  17. :dropdown-class-name="themeSwitcher.currentTheme"
  18. >
  19. <a-select-option v-for="x,y in Protocols" :value="x"
  20. >[[ y ]]</a-select-option
  21. >
  22. </a-select>
  23. </a-form-item>
  24. <a-form-item
  25. label='{{ i18n "pages.xray.outbound.tag" }}'
  26. has-feedback
  27. :validate-status="outModal.duplicateTag? 'warning' : 'success'"
  28. >
  29. <a-input
  30. v-model.trim="outbound.tag"
  31. @change="outModal.check()"
  32. placeholder='{{ i18n "pages.xray.outbound.tagDesc" }}'
  33. ></a-input>
  34. </a-form-item>
  35. <a-form-item label='{{ i18n "pages.xray.outbound.sendThrough" }}'>
  36. <a-input v-model="outbound.sendThrough"></a-input>
  37. </a-form-item>
  38. <!-- freedom settings-->
  39. <template v-if="outbound.protocol === Protocols.Freedom">
  40. <a-form-item label="Strategy">
  41. <a-select
  42. v-model="outbound.settings.domainStrategy"
  43. :dropdown-class-name="themeSwitcher.currentTheme"
  44. >
  45. <a-select-option v-for="s in OutboundDomainStrategies" :value="s"
  46. >[[ s ]]</a-select-option
  47. >
  48. </a-select>
  49. </a-form-item>
  50. <a-form-item label="Redirect">
  51. <a-input v-model="outbound.settings.redirect"></a-input>
  52. </a-form-item>
  53. <a-form-item label="IPs Blocked">
  54. <a-select
  55. mode="tags"
  56. v-model="outbound.settings.ipsBlocked"
  57. :style="{ width: '100%' }"
  58. :dropdown-class-name="themeSwitcher.currentTheme"
  59. :token-separators="[',']"
  60. placeholder="IP/CIDR/geoip:*/ext:*"
  61. >
  62. </a-select>
  63. </a-form-item>
  64. <a-form-item label="Fragment">
  65. <a-switch
  66. :checked="Object.keys(outbound.settings.fragment).length >0"
  67. @change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}"
  68. >
  69. </a-switch>
  70. </a-form-item>
  71. <template v-if="Object.keys(outbound.settings.fragment).length >0">
  72. <a-form-item label="Packets">
  73. <a-select
  74. v-model="outbound.settings.fragment.packets"
  75. :dropdown-class-name="themeSwitcher.currentTheme"
  76. >
  77. <a-select-option v-for="s in ['1-3','tlshello']" :value="s"
  78. >[[ s ]]</a-select-option
  79. >
  80. </a-select>
  81. </a-form-item>
  82. <a-form-item label="Length">
  83. <a-input v-model.trim="outbound.settings.fragment.length"></a-input>
  84. </a-form-item>
  85. <a-form-item label="Interval">
  86. <a-input
  87. v-model.trim="outbound.settings.fragment.interval"
  88. ></a-input>
  89. </a-form-item>
  90. <a-form-item label="Max Split">
  91. <a-input
  92. v-model.trim="outbound.settings.fragment.maxSplit"
  93. ></a-input>
  94. </a-form-item>
  95. </template>
  96. <!-- Switch for Noises -->
  97. <a-form-item label="Noises">
  98. <a-switch
  99. :checked="outbound.settings.noises.length > 0"
  100. @change="checked => outbound.settings.noises = checked ? [new Outbound.FreedomSettings.Noise()] : []"
  101. >
  102. </a-switch>
  103. </a-form-item>
  104. <!-- Add Noise Button -->
  105. <template v-if="outbound.settings.noises.length > 0">
  106. <a-form-item label="Noises">
  107. <a-button
  108. icon="plus"
  109. type="primary"
  110. size="small"
  111. @click="outbound.settings.addNoise()"
  112. ></a-button>
  113. </a-form-item>
  114. <!-- Noise Configurations -->
  115. <a-form
  116. v-for="(noise, index) in outbound.settings.noises"
  117. :key="index"
  118. :colon="false"
  119. :label-col="{ md: {span:8} }"
  120. :wrapper-col="{ md: {span:14} }"
  121. >
  122. <a-divider :style="{ margin: '0' }">
  123. Noise [[ index + 1 ]]
  124. <a-icon
  125. v-if="outbound.settings.noises.length > 1"
  126. type="delete"
  127. @click="() => outbound.settings.delNoise(index)"
  128. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  129. ></a-icon>
  130. </a-divider>
  131. <a-form-item label="Type">
  132. <a-select
  133. v-model="noise.type"
  134. :dropdown-class-name="themeSwitcher.currentTheme"
  135. >
  136. <a-select-option
  137. v-for="s in ['rand','base64','str', 'hex']"
  138. :value="s"
  139. >[[ s ]]</a-select-option
  140. >
  141. </a-select>
  142. </a-form-item>
  143. <a-form-item label="Packet">
  144. <a-input v-model.trim="noise.packet"></a-input>
  145. </a-form-item>
  146. <a-form-item label="Delay">
  147. <a-input v-model.trim="noise.delay"></a-input>
  148. </a-form-item>
  149. <a-form-item label="Apply To">
  150. <a-select
  151. v-model="noise.applyTo"
  152. :dropdown-class-name="themeSwitcher.currentTheme"
  153. >
  154. <a-select-option v-for="s in ['ip','ipv4','ipv6']" :value="s"
  155. >[[ s ]]</a-select-option
  156. >
  157. </a-select>
  158. </a-form-item>
  159. </a-form>
  160. </template>
  161. </template>
  162. <!-- blackhole settings -->
  163. <template v-if="outbound.protocol === Protocols.Blackhole">
  164. <a-form-item label="Response Type">
  165. <a-select
  166. v-model="outbound.settings.type"
  167. :dropdown-class-name="themeSwitcher.currentTheme"
  168. >
  169. <a-select-option v-for="s in ['', 'none','http']" :value="s"
  170. >[[ s ]]</a-select-option
  171. >
  172. </a-select>
  173. </a-form-item>
  174. </template>
  175. <!-- dns settings -->
  176. <template v-if="outbound.protocol === Protocols.DNS">
  177. <a-form-item label='{{ i18n "pages.inbounds.network" }}'>
  178. <a-select
  179. v-model="outbound.settings.network"
  180. :dropdown-class-name="themeSwitcher.currentTheme"
  181. >
  182. <a-select-option v-for="s in ['udp','tcp']" :value="s"
  183. >[[ s ]]</a-select-option
  184. >
  185. </a-select>
  186. </a-form-item>
  187. <a-form-item label="Rules">
  188. <a-button
  189. icon="plus"
  190. type="primary"
  191. size="small"
  192. @click="outbound.settings.addRule()"
  193. ></a-button>
  194. </a-form-item>
  195. <a-form
  196. v-for="(rule, index) in outbound.settings.rules"
  197. :colon="false"
  198. :label-col="{ md: {span:8} }"
  199. :wrapper-col="{ md: {span:14} }"
  200. >
  201. <a-divider :style="{ margin: '0' }">
  202. Rule [[ index + 1 ]]
  203. <a-icon
  204. type="delete"
  205. @click="() => outbound.settings.delRule(index)"
  206. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  207. ></a-icon>
  208. </a-divider>
  209. <a-form-item label="Action">
  210. <a-select
  211. v-model="rule.action"
  212. :dropdown-class-name="themeSwitcher.currentTheme"
  213. >
  214. <a-select-option v-for="action in DNSRuleActions" :value="action"
  215. >[[ action ]]</a-select-option
  216. >
  217. </a-select>
  218. </a-form-item>
  219. <a-form-item>
  220. <template slot="label">
  221. <a-tooltip>
  222. <template slot="title">
  223. <span>Single qtype (e.g. 28) or list/range (e.g. 1,3,23-24)</span>
  224. </template>
  225. QType
  226. <a-icon type="question-circle"></a-icon>
  227. </a-tooltip>
  228. </template>
  229. <a-input
  230. v-model.trim="rule.qtype"
  231. placeholder="1,3,23-24"
  232. ></a-input>
  233. </a-form-item>
  234. <a-form-item>
  235. <template slot="label">
  236. <a-tooltip>
  237. <template slot="title">
  238. <span>Comma-separated domain rules, e.g. domain:example.com,full:example.com</span>
  239. </template>
  240. Domain
  241. <a-icon type="question-circle"></a-icon>
  242. </a-tooltip>
  243. </template>
  244. <a-input
  245. v-model.trim="rule.domain"
  246. placeholder="domain:example.com,full:example.com"
  247. ></a-input>
  248. </a-form-item>
  249. </a-form>
  250. </template>
  251. <!-- wireguard settings -->
  252. <template v-if="outbound.protocol === Protocols.Wireguard">
  253. <a-form-item>
  254. <template slot="label">
  255. <a-tooltip>
  256. <template slot="title">
  257. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  258. </template>
  259. {{ i18n "pages.xray.outbound.address" }}
  260. <a-icon type="question-circle"></a-icon>
  261. </a-tooltip>
  262. </template>
  263. <a-input v-model.trim="outbound.settings.address"></a-input>
  264. </a-form-item>
  265. <a-form-item>
  266. <template slot="label">
  267. <a-tooltip>
  268. <template slot="title">
  269. <span>{{ i18n "reset" }}</span>
  270. </template>
  271. {{ i18n "pages.xray.wireguard.secretKey" }}
  272. <a-icon
  273. type="sync"
  274. @click="[outbound.settings.pubKey, outbound.settings.secretKey] = Object.values(Wireguard.generateKeypair())"
  275. >
  276. </a-icon>
  277. </a-tooltip>
  278. </template>
  279. <a-input v-model.trim="outbound.settings.secretKey"></a-input>
  280. </a-form-item>
  281. <a-form-item label='{{ i18n "pages.xray.wireguard.publicKey" }}'>
  282. <a-input disabled v-model="outbound.settings.pubKey"></a-input>
  283. </a-form-item>
  284. <a-form-item label='{{ i18n "pages.xray.wireguard.domainStrategy" }}'>
  285. <a-select
  286. v-model="outbound.settings.domainStrategy"
  287. :dropdown-class-name="themeSwitcher.currentTheme"
  288. >
  289. <a-select-option
  290. v-for="wds in ['', ...WireguardDomainStrategy]"
  291. :value="wds"
  292. >[[ wds ]]</a-select-option
  293. >
  294. </a-select>
  295. </a-form-item>
  296. <a-form-item label="MTU">
  297. <a-input-number
  298. v-model.number="outbound.settings.mtu"
  299. min="0"
  300. ></a-input-number>
  301. </a-form-item>
  302. <a-form-item label="Workers">
  303. <a-input-number
  304. v-model.number="outbound.settings.workers"
  305. min="0"
  306. ></a-input-number>
  307. </a-form-item>
  308. <a-form-item label="No Kernel Tun">
  309. <a-switch v-model="outbound.settings.noKernelTun"></a-switch>
  310. </a-form-item>
  311. <a-form-item>
  312. <template slot="label">
  313. <a-tooltip>
  314. <template slot="title">
  315. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  316. </template>
  317. Reserved <a-icon type="question-circle"></a-icon>
  318. </a-tooltip>
  319. </template>
  320. <a-input v-model="outbound.settings.reserved"></a-input>
  321. </a-form-item>
  322. <a-form-item label="Peers">
  323. <a-button
  324. icon="plus"
  325. type="primary"
  326. size="small"
  327. @click="outbound.settings.addPeer()"
  328. ></a-button>
  329. </a-form-item>
  330. <a-form
  331. v-for="(peer, index) in outbound.settings.peers"
  332. :colon="false"
  333. :label-col="{ md: {span:8} }"
  334. :wrapper-col="{ md: {span:14} }"
  335. >
  336. <a-divider :style="{ margin: '0' }">
  337. Peer [[ index + 1 ]]
  338. <a-icon
  339. v-if="outbound.settings.peers.length>1"
  340. type="delete"
  341. @click="() => outbound.settings.delPeer(index)"
  342. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  343. ></a-icon>
  344. </a-divider>
  345. <a-form-item label='{{ i18n "pages.xray.wireguard.endpoint" }}'>
  346. <a-input v-model.trim="peer.endpoint"></a-input>
  347. </a-form-item>
  348. <a-form-item label='{{ i18n "pages.xray.wireguard.publicKey" }}'>
  349. <a-input v-model.trim="peer.publicKey"></a-input>
  350. </a-form-item>
  351. <a-form-item label='{{ i18n "pages.xray.wireguard.psk" }}'>
  352. <a-input v-model.trim="peer.psk"></a-input>
  353. </a-form-item>
  354. <a-form-item>
  355. <template slot="label">
  356. {{ i18n "pages.xray.wireguard.allowedIPs" }}
  357. <a-button
  358. icon="plus"
  359. type="primary"
  360. size="small"
  361. @click="peer.allowedIPs.push('')"
  362. ></a-button>
  363. </template>
  364. <template
  365. v-for="(aip, index) in peer.allowedIPs"
  366. :style="{ marginBottom: '10px' }"
  367. >
  368. <a-input v-model.trim="peer.allowedIPs[index]">
  369. <a-button
  370. icon="minus"
  371. v-if="peer.allowedIPs.length>1"
  372. slot="addonAfter"
  373. size="small"
  374. @click="peer.allowedIPs.splice(index, 1)"
  375. ></a-button>
  376. </a-input>
  377. </template>
  378. </a-form-item>
  379. <a-form-item label="Keep Alive">
  380. <a-input-number
  381. v-model.number="peer.keepAlive"
  382. :min="0"
  383. ></a-input-number>
  384. </a-form-item>
  385. </a-form>
  386. </template>
  387. <!-- Address + Port -->
  388. <template v-if="outbound.hasAddressPort()">
  389. <a-form-item label='{{ i18n "pages.inbounds.address" }}'>
  390. <a-input v-model.trim="outbound.settings.address"></a-input>
  391. </a-form-item>
  392. <a-form-item label='{{ i18n "pages.inbounds.port" }}'>
  393. <a-input-number
  394. v-model.number="outbound.settings.port"
  395. :min="1"
  396. :max="65532"
  397. ></a-input-number>
  398. </a-form-item>
  399. </template>
  400. <!-- VLESS/VMess user settings -->
  401. <template
  402. v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)"
  403. >
  404. <a-form-item label="ID">
  405. <a-input v-model.trim="outbound.settings.id"></a-input>
  406. </a-form-item>
  407. <!-- vmess settings -->
  408. <template v-if="outbound.protocol === Protocols.VMess">
  409. <a-form-item label="Security">
  410. <a-select
  411. v-model="outbound.settings.security"
  412. :dropdown-class-name="themeSwitcher.currentTheme"
  413. >
  414. <a-select-option v-for="key in USERS_SECURITY" :value="key"
  415. >[[ key ]]</a-select-option
  416. >
  417. </a-select>
  418. </a-form-item>
  419. </template>
  420. <!-- vless settings -->
  421. <template v-if="outbound.protocol === Protocols.VLESS">
  422. <a-form-item label="encryption">
  423. <a-input v-model.trim="outbound.settings.encryption"></a-input>
  424. </a-form-item>
  425. </template>
  426. <template v-if="outbound.canEnableTlsFlow()">
  427. <a-form-item label="Flow">
  428. <a-select
  429. v-model="outbound.settings.flow"
  430. :dropdown-class-name="themeSwitcher.currentTheme"
  431. >
  432. <a-select-option value selected
  433. >{{ i18n "none" }}</a-select-option
  434. >
  435. <a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key"
  436. >[[ key ]]</a-select-option
  437. >
  438. </a-select>
  439. </a-form-item>
  440. </template>
  441. <!-- XTLS Vision Advanced Settings -->
  442. <template v-if="outbound.canEnableVisionSeed()">
  443. <a-form-item label="Vision Pre-Connect">
  444. <a-input-number
  445. v-model.number="outbound.settings.testpre"
  446. :min="0"
  447. :max="10"
  448. :style="{ width: '100%' }"
  449. placeholder="0"
  450. ></a-input-number>
  451. </a-form-item>
  452. <a-form-item label="Vision Seed">
  453. <a-row :gutter="8">
  454. <a-col :span="6">
  455. <a-input-number
  456. v-model.number="outbound.settings.testseed[0]"
  457. :min="0"
  458. :max="9999"
  459. :style="{ width: '100%' }"
  460. placeholder="900"
  461. addon-before="[0]"
  462. ></a-input-number>
  463. </a-col>
  464. <a-col :span="6">
  465. <a-input-number
  466. v-model.number="outbound.settings.testseed[1]"
  467. :min="0"
  468. :max="9999"
  469. :style="{ width: '100%' }"
  470. placeholder="500"
  471. addon-before="[1]"
  472. ></a-input-number>
  473. </a-col>
  474. <a-col :span="6">
  475. <a-input-number
  476. v-model.number="outbound.settings.testseed[2]"
  477. :min="0"
  478. :max="9999"
  479. :style="{ width: '100%' }"
  480. placeholder="900"
  481. addon-before="[2]"
  482. ></a-input-number>
  483. </a-col>
  484. <a-col :span="6">
  485. <a-input-number
  486. v-model.number="outbound.settings.testseed[3]"
  487. :min="0"
  488. :max="9999"
  489. :style="{ width: '100%' }"
  490. placeholder="256"
  491. addon-before="[3]"
  492. ></a-input-number>
  493. </a-col>
  494. </a-row>
  495. </a-form-item>
  496. </template>
  497. </template>
  498. <!-- Servers (trojan/shadowsocks/socks/http) settings -->
  499. <template v-if="outbound.hasServers()">
  500. <!-- http / socks -->
  501. <template v-if="outbound.hasUsername()">
  502. <a-form-item label='{{ i18n "username" }}'>
  503. <a-input v-model.trim="outbound.settings.user"></a-input>
  504. </a-form-item>
  505. <a-form-item label='{{ i18n "password" }}'>
  506. <a-input v-model.trim="outbound.settings.pass"></a-input>
  507. </a-form-item>
  508. </template>
  509. <!-- trojan/shadowsocks -->
  510. <template
  511. v-if="[Protocols.Trojan, Protocols.Shadowsocks].includes(outbound.protocol)"
  512. >
  513. <a-form-item label='{{ i18n "password" }}'>
  514. <a-input v-model.trim="outbound.settings.password"></a-input>
  515. </a-form-item>
  516. </template>
  517. <!-- shadowsocks -->
  518. <template v-if="outbound.protocol === Protocols.Shadowsocks">
  519. <a-form-item label='{{ i18n "encryption" }}'>
  520. <a-select
  521. v-model="outbound.settings.method"
  522. :dropdown-class-name="themeSwitcher.currentTheme"
  523. >
  524. <a-select-option
  525. v-for="(method, method_name) in SSMethods"
  526. :value="method"
  527. >[[ method_name ]]</a-select-option
  528. >
  529. </a-select>
  530. </a-form-item>
  531. <a-form-item label="UDP over TCP">
  532. <a-switch v-model="outbound.settings.uot"></a-switch>
  533. </a-form-item>
  534. <a-form-item label="UoTVersion">
  535. <a-input-number
  536. v-model.number="outbound.settings.UoTVersion"
  537. :min="1"
  538. :max="2"
  539. ></a-input-number>
  540. </a-form-item>
  541. </template>
  542. </template>
  543. <!-- hysteria settings -->
  544. <template v-if="outbound.protocol === Protocols.Hysteria">
  545. <a-form-item label="Version">
  546. <a-input-number
  547. v-model.number="outbound.settings.version"
  548. :min="2"
  549. :max="2"
  550. disabled
  551. ></a-input-number>
  552. </a-form-item>
  553. </template>
  554. <!-- stream settings -->
  555. <template v-if="outbound.canEnableStream()">
  556. <a-form-item label='{{ i18n "transmission" }}'>
  557. <a-select
  558. v-model="outbound.stream.network"
  559. @change="streamNetworkChange"
  560. :dropdown-class-name="themeSwitcher.currentTheme"
  561. >
  562. <a-select-option value="tcp">TCP (RAW)</a-select-option>
  563. <a-select-option value="kcp">mKCP</a-select-option>
  564. <a-select-option value="ws">WebSocket</a-select-option>
  565. <a-select-option value="grpc">gRPC</a-select-option>
  566. <a-select-option value="httpupgrade">HTTPUpgrade</a-select-option>
  567. <a-select-option value="xhttp">XHTTP</a-select-option>
  568. <a-select-option
  569. v-if="outbound.protocol === Protocols.Hysteria"
  570. value="hysteria"
  571. >Hysteria2</a-select-option
  572. >
  573. </a-select>
  574. </a-form-item>
  575. <template v-if="outbound.stream.network === 'tcp'">
  576. <a-form-item label='HTTP {{ i18n "camouflage" }}'>
  577. <a-switch
  578. :checked="outbound.stream.tcp.type === 'http'"
  579. @change="checked => outbound.stream.tcp.type = checked ? 'http' : 'none'"
  580. ></a-switch>
  581. </a-form-item>
  582. <template v-if="outbound.stream.tcp.type == 'http'">
  583. <a-form-item label='{{ i18n "host" }}'>
  584. <a-input v-model.trim="outbound.stream.tcp.host"></a-input>
  585. </a-form-item>
  586. <a-form-item label='{{ i18n "path" }}'>
  587. <a-input v-model.trim="outbound.stream.tcp.path"></a-input>
  588. </a-form-item>
  589. </template>
  590. </template>
  591. <!-- kcp -->
  592. <template v-if="outbound.stream.network === 'kcp'">
  593. <a-form-item label="MTU">
  594. <a-input-number
  595. v-model.number="outbound.stream.kcp.mtu"
  596. min="0"
  597. ></a-input-number>
  598. </a-form-item>
  599. <a-form-item label="TTI (ms)">
  600. <a-input-number
  601. v-model.number="outbound.stream.kcp.tti"
  602. min="0"
  603. ></a-input-number>
  604. </a-form-item>
  605. <a-form-item label="Uplink (MB/s)">
  606. <a-input-number
  607. v-model.number="outbound.stream.kcp.upCap"
  608. min="0"
  609. ></a-input-number>
  610. </a-form-item>
  611. <a-form-item label="Downlink (MB/s)">
  612. <a-input-number
  613. v-model.number="outbound.stream.kcp.downCap"
  614. min="0"
  615. ></a-input-number>
  616. </a-form-item>
  617. <a-form-item label="CWND Multiplier">
  618. <a-input-number
  619. v-model.number="outbound.stream.kcp.cwndMultiplier"
  620. min="1"
  621. ></a-input-number>
  622. </a-form-item>
  623. <a-form-item label="Max Sending Window">
  624. <a-input-number
  625. v-model.number="outbound.stream.kcp.maxSendingWindow"
  626. min="0"
  627. ></a-input-number>
  628. </a-form-item>
  629. </template>
  630. <!-- ws -->
  631. <template v-if="outbound.stream.network === 'ws'">
  632. <a-form-item label='{{ i18n "host" }}'>
  633. <a-input v-model="outbound.stream.ws.host"></a-input>
  634. </a-form-item>
  635. <a-form-item label='{{ i18n "path" }}'>
  636. <a-input v-model.trim="outbound.stream.ws.path"></a-input>
  637. </a-form-item>
  638. <a-form-item label="Heartbeat Period">
  639. <a-input-number
  640. v-model.number="outbound.stream.ws.heartbeatPeriod"
  641. :min="0"
  642. ></a-input-number>
  643. </a-form-item>
  644. </template>
  645. <!-- grpc -->
  646. <template v-if="outbound.stream.network === 'grpc'">
  647. <a-form-item label="Service Name">
  648. <a-input v-model.trim="outbound.stream.grpc.serviceName"></a-input>
  649. </a-form-item>
  650. <a-form-item label="Authority">
  651. <a-input v-model.trim="outbound.stream.grpc.authority"></a-input>
  652. </a-form-item>
  653. <a-form-item label="Multi Mode">
  654. <a-switch v-model="outbound.stream.grpc.multiMode"></a-switch>
  655. </a-form-item>
  656. </template>
  657. <!-- httpupgrade -->
  658. <template v-if="outbound.stream.network === 'httpupgrade'">
  659. <a-form-item label='{{ i18n "host" }}'>
  660. <a-input v-model="outbound.stream.httpupgrade.host"></a-input>
  661. </a-form-item>
  662. <a-form-item label='{{ i18n "path" }}'>
  663. <a-input v-model.trim="outbound.stream.httpupgrade.path"></a-input>
  664. </a-form-item>
  665. </template>
  666. <!-- xhttp -->
  667. <template v-if="outbound.stream.network === 'xhttp'">
  668. <a-form-item label='{{ i18n "host" }}'>
  669. <a-input v-model="outbound.stream.xhttp.host"></a-input>
  670. </a-form-item>
  671. <a-form-item label='{{ i18n "path" }}'>
  672. <a-input v-model.trim="outbound.stream.xhttp.path"></a-input>
  673. </a-form-item>
  674. <a-form-item label="Mode">
  675. <a-select
  676. v-model="outbound.stream.xhttp.mode"
  677. :dropdown-class-name="themeSwitcher.currentTheme"
  678. >
  679. <a-select-option v-for="key in MODE_OPTION" :value="key"
  680. >[[ key ]]</a-select-option
  681. >
  682. </a-select>
  683. </a-form-item>
  684. <a-form-item
  685. label="No gRPC Header"
  686. v-if="outbound.stream.xhttp.mode === 'stream-up' || outbound.stream.xhttp.mode === 'stream-one'"
  687. >
  688. <a-switch v-model="outbound.stream.xhttp.noGRPCHeader"></a-switch>
  689. </a-form-item>
  690. <a-form-item
  691. label="Min Upload Interval (Ms)"
  692. v-if="outbound.stream.xhttp.mode === 'packet-up'"
  693. >
  694. <a-input
  695. v-model.trim="outbound.stream.xhttp.scMinPostsIntervalMs"
  696. ></a-input>
  697. </a-form-item>
  698. <a-form-item
  699. label="Max Concurrency"
  700. v-if="!outbound.stream.xhttp.xmux.maxConnections"
  701. >
  702. <a-input
  703. v-model="outbound.stream.xhttp.xmux.maxConcurrency"
  704. ></a-input>
  705. </a-form-item>
  706. <a-form-item
  707. label="Max Connections"
  708. v-if="!outbound.stream.xhttp.xmux.maxConcurrency"
  709. >
  710. <a-input
  711. v-model="outbound.stream.xhttp.xmux.maxConnections"
  712. ></a-input>
  713. </a-form-item>
  714. <a-form-item label="Max Reuse Times">
  715. <a-input
  716. v-model="outbound.stream.xhttp.xmux.cMaxReuseTimes"
  717. ></a-input>
  718. </a-form-item>
  719. <a-form-item label="Max Request Times">
  720. <a-input
  721. v-model="outbound.stream.xhttp.xmux.hMaxRequestTimes"
  722. ></a-input>
  723. </a-form-item>
  724. <a-form-item label="Max Reusable Secs">
  725. <a-input
  726. v-model="outbound.stream.xhttp.xmux.hMaxReusableSecs"
  727. ></a-input>
  728. </a-form-item>
  729. <a-form-item label="Keep Alive Period">
  730. <a-input-number
  731. v-model.number="outbound.stream.xhttp.xmux.hKeepAlivePeriod"
  732. ></a-input-number>
  733. </a-form-item>
  734. </template>
  735. <!-- hysteria -->
  736. <template v-if="outbound.stream.network === 'hysteria'">
  737. <a-form-item label="Auth Password">
  738. <a-input v-model.trim="outbound.stream.hysteria.auth"></a-input>
  739. </a-form-item>
  740. <a-form-item label="Congestion">
  741. <a-select
  742. v-model="outbound.stream.hysteria.congestion"
  743. :dropdown-class-name="themeSwitcher.currentTheme"
  744. >
  745. <a-select-option value>BBR (Auto)</a-select-option>
  746. <a-select-option value="brutal">Brutal</a-select-option>
  747. </a-select>
  748. </a-form-item>
  749. <a-form-item label="Upload Speed">
  750. <a-input
  751. v-model.trim="outbound.stream.hysteria.up"
  752. placeholder="0 (BBR mode), e.g., 100 mbps"
  753. ></a-input>
  754. </a-form-item>
  755. <a-form-item label="Download Speed">
  756. <a-input
  757. v-model.trim="outbound.stream.hysteria.down"
  758. placeholder="0 (BBR mode), e.g., 100 mbps"
  759. ></a-input>
  760. </a-form-item>
  761. <a-form-item label="UDP Hop Port">
  762. <a-input
  763. v-model.trim="outbound.stream.hysteria.udphopPort"
  764. placeholder="e.g., 1145-1919 or 11,13,15-17"
  765. ></a-input>
  766. </a-form-item>
  767. <a-form-item
  768. label="UDP Hop Interval Min (s)"
  769. v-if="outbound.stream.hysteria.udphopPort"
  770. >
  771. <a-input-number
  772. v-model.number="outbound.stream.hysteria.udphopIntervalMin"
  773. :min="5"
  774. ></a-input-number>
  775. </a-form-item>
  776. <a-form-item
  777. label="UDP Hop Interval Max (s)"
  778. v-if="outbound.stream.hysteria.udphopPort"
  779. >
  780. <a-input-number
  781. v-model.number="outbound.stream.hysteria.udphopIntervalMax"
  782. :min="5"
  783. ></a-input-number>
  784. </a-form-item>
  785. <a-form-item label="Init Stream Receive">
  786. <a-input-number
  787. v-model.number="outbound.stream.hysteria.initStreamReceiveWindow"
  788. ></a-input-number>
  789. </a-form-item>
  790. <a-form-item label="Max Stream Receive">
  791. <a-input-number
  792. v-model.number="outbound.stream.hysteria.maxStreamReceiveWindow"
  793. ></a-input-number>
  794. </a-form-item>
  795. <a-form-item label="Init Connection Receive">
  796. <a-input-number
  797. v-model.number="outbound.stream.hysteria.initConnectionReceiveWindow"
  798. ></a-input-number>
  799. </a-form-item>
  800. <a-form-item label="Max Connection Receive">
  801. <a-input-number
  802. v-model.number="outbound.stream.hysteria.maxConnectionReceiveWindow"
  803. ></a-input-number>
  804. </a-form-item>
  805. <a-form-item label="Max Idle Timeout (s)">
  806. <a-input-number
  807. v-model.number="outbound.stream.hysteria.maxIdleTimeout"
  808. :min="4"
  809. :max="120"
  810. ></a-input-number>
  811. </a-form-item>
  812. <a-form-item label="Keep Alive Period (s)">
  813. <a-input-number
  814. v-model.number="outbound.stream.hysteria.keepAlivePeriod"
  815. :min="0"
  816. :max="60"
  817. ></a-input-number>
  818. </a-form-item>
  819. <a-form-item label="Disable Path MTU Dis">
  820. <a-switch
  821. v-model="outbound.stream.hysteria.disablePathMTUDiscovery"
  822. ></a-switch>
  823. </a-form-item>
  824. </template>
  825. </template>
  826. <!-- finalmask settings -->
  827. <template v-if="outbound.canEnableStream()">
  828. <!-- TCP Masks – for raw/tcp/httpupgrade/ws/grpc/xhttp -->
  829. <a-form-item
  830. label="TCP Masks"
  831. v-if="['raw', 'tcp', 'httpupgrade', 'ws', 'grpc', 'xhttp'].includes(outbound.stream.network)"
  832. >
  833. <a-button
  834. icon="plus"
  835. type="primary"
  836. size="small"
  837. @click="outbound.stream.addTcpMask('fragment')"
  838. ></a-button>
  839. </a-form-item>
  840. <template v-if="outbound.stream.finalmask.tcp && outbound.stream.finalmask.tcp.length > 0">
  841. <a-form
  842. v-for="(mask, index) in outbound.stream.finalmask.tcp"
  843. :key="index"
  844. :colon="false"
  845. :label-col="{ md: {span:8} }"
  846. :wrapper-col="{ md: {span:14} }"
  847. >
  848. <a-divider :style="{ margin: '0' }">
  849. TCP Mask [[ index + 1 ]]
  850. <a-icon
  851. type="delete"
  852. @click="() => outbound.stream.delTcpMask(index)"
  853. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  854. ></a-icon>
  855. </a-divider>
  856. <a-form-item label="Type">
  857. <a-select
  858. v-model="mask.type"
  859. @change="(type) => { mask.settings = mask._getDefaultSettings(type, {}); }"
  860. :dropdown-class-name="themeSwitcher.currentTheme"
  861. >
  862. <a-select-option value="fragment">Fragment</a-select-option>
  863. <a-select-option value="header-custom">Header Custom</a-select-option>
  864. <a-select-option value="sudoku">Sudoku</a-select-option>
  865. </a-select>
  866. </a-form-item>
  867. <!-- Fragment -->
  868. <template v-if="mask.type === 'fragment'">
  869. <a-form-item label="Packets">
  870. <a-select v-model="mask.settings.packets" :dropdown-class-name="themeSwitcher.currentTheme">
  871. <a-select-option value="tlshello">tlshello</a-select-option>
  872. <a-select-option value="1-3">1-3</a-select-option>
  873. <a-select-option value="1-5">1-5</a-select-option>
  874. </a-select>
  875. </a-form-item>
  876. <a-form-item label="Length">
  877. <a-input v-model.trim="mask.settings.length" placeholder="e.g. 100-200" />
  878. </a-form-item>
  879. <a-form-item label="Delay">
  880. <a-input v-model.trim="mask.settings.delay" placeholder="e.g. 10-20" />
  881. </a-form-item>
  882. <a-form-item label="Max Split">
  883. <a-input v-model.trim="mask.settings.maxSplit" placeholder="e.g. 3-6" />
  884. </a-form-item>
  885. </template>
  886. <!-- Sudoku (TCP) -->
  887. <template v-if="mask.type === 'sudoku'">
  888. <a-form-item label="Password">
  889. <a-input v-model.trim="mask.settings.password" placeholder="Obfuscation password" />
  890. </a-form-item>
  891. <a-form-item label="ASCII">
  892. <a-input v-model.trim="mask.settings.ascii" placeholder="ASCII" />
  893. </a-form-item>
  894. <a-form-item label="Custom Table">
  895. <a-input v-model.trim="mask.settings.customTable" placeholder="Custom Table" />
  896. </a-form-item>
  897. <a-form-item label="Custom Tables">
  898. <a-input v-model.trim="mask.settings.customTables" placeholder="Custom Tables" />
  899. </a-form-item>
  900. <a-form-item label="Padding Min">
  901. <a-input-number v-model.number="mask.settings.paddingMin" :min="0" />
  902. </a-form-item>
  903. <a-form-item label="Padding Max">
  904. <a-input-number v-model.number="mask.settings.paddingMax" :min="0" />
  905. </a-form-item>
  906. </template>
  907. <!-- Header Custom (TCP) – clients/servers are 2D arrays of groups -->
  908. <template v-if="mask.type === 'header-custom'">
  909. <!-- Clients -->
  910. <a-form-item label="Clients">
  911. <a-icon type="plus" @click="mask.settings.clients.push([{delay: 0, rand: 0, randRange: '0-255', type: 'array', packet: []}])" />
  912. </a-form-item>
  913. <template v-for="(group, gi) in mask.settings.clients" :key="'cg'+gi">
  914. <a-divider :style="{ margin: '0' }">
  915. Clients Group [[ gi + 1 ]]
  916. <a-icon type="delete" @click="mask.settings.clients.splice(gi, 1)" :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }" />
  917. <a-icon type="plus" @click="group.push({delay: 0, rand: 0, randRange: '0-255', type: 'array', packet: []})" :style="{ marginLeft: '8px' }" />
  918. </a-divider>
  919. <template v-for="(item, ii) in group" :key="'ci'+ii">
  920. <a-divider :style="{ margin: '0', fontSize: '12px' }">
  921. Item [[ ii + 1 ]]
  922. <a-icon type="delete" @click="() => { group.splice(ii, 1); if(group.length === 0) mask.settings.clients.splice(gi, 1); }" :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }" />
  923. </a-divider>
  924. <a-form-item label='{{ i18n "pages.xray.outbound.type" }}'>
  925. <a-select v-model="item.type" :dropdown-class-name="themeSwitcher.currentTheme"
  926. @change="t => { if(t === 'array') { item.rand = 0; item.packet = []; } else { item.packet = ''; } }">
  927. <a-select-option value="array">Array</a-select-option>
  928. <a-select-option value="str">String</a-select-option>
  929. <a-select-option value="hex">Hex</a-select-option>
  930. <a-select-option value="base64">Base64</a-select-option>
  931. </a-select>
  932. </a-form-item>
  933. <a-form-item label="Delay (ms)">
  934. <a-input-number v-model.number="item.delay" :min="0" />
  935. </a-form-item>
  936. <template v-if="item.type === 'array'">
  937. <a-form-item label="Rand">
  938. <a-input-number v-model.number="item.rand" :min="0" />
  939. </a-form-item>
  940. <a-form-item label="Rand Range">
  941. <a-input v-model.trim="item.randRange" placeholder="0-255" />
  942. </a-form-item>
  943. </template>
  944. <a-form-item v-else label="Packet">
  945. <a-input v-model.trim="item.packet" placeholder="binary data" />
  946. </a-form-item>
  947. </template>
  948. </template>
  949. <!-- Servers -->
  950. <a-form-item label="Servers">
  951. <a-icon type="plus" @click="mask.settings.servers.push([{delay: 0, rand: 0, randRange: '0-255', type: 'array', packet: []}])" />
  952. </a-form-item>
  953. <template v-for="(group, gi) in mask.settings.servers" :key="'sg'+gi">
  954. <a-divider :style="{ margin: '0' }">
  955. Servers Group [[ gi + 1 ]]
  956. <a-icon type="delete" @click="mask.settings.servers.splice(gi, 1)" :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }" />
  957. <a-icon type="plus" @click="group.push({delay: 0, rand: 0, randRange: '0-255', type: 'array', packet: []})" :style="{ marginLeft: '8px' }" />
  958. </a-divider>
  959. <template v-for="(item, ii) in group" :key="'si'+ii">
  960. <a-divider :style="{ margin: '0', fontSize: '12px' }">
  961. Item [[ ii + 1 ]]
  962. <a-icon type="delete" @click="() => { group.splice(ii, 1); if(group.length === 0) mask.settings.servers.splice(gi, 1); }" :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }" />
  963. </a-divider>
  964. <a-form-item label='{{ i18n "pages.xray.outbound.type" }}'>
  965. <a-select v-model="item.type" :dropdown-class-name="themeSwitcher.currentTheme"
  966. @change="t => { if(t === 'array') { item.rand = 0; item.packet = []; } else { item.packet = ''; } }">
  967. <a-select-option value="array">Array</a-select-option>
  968. <a-select-option value="str">String</a-select-option>
  969. <a-select-option value="hex">Hex</a-select-option>
  970. <a-select-option value="base64">Base64</a-select-option>
  971. </a-select>
  972. </a-form-item>
  973. <a-form-item label="Delay (ms)">
  974. <a-input-number v-model.number="item.delay" :min="0" />
  975. </a-form-item>
  976. <template v-if="item.type === 'array'">
  977. <a-form-item label="Rand">
  978. <a-input-number v-model.number="item.rand" :min="0" />
  979. </a-form-item>
  980. <a-form-item label="Rand Range">
  981. <a-input v-model.trim="item.randRange" placeholder="0-255" />
  982. </a-form-item>
  983. </template>
  984. <a-form-item label="Packet" v-else>
  985. <a-input v-model.trim="item.packet" placeholder="binary data" />
  986. </a-form-item>
  987. </template>
  988. </template>
  989. </template>
  990. </a-form>
  991. </template>
  992. <a-form-item
  993. label="UDP Masks"
  994. v-if="outbound.stream.network === 'kcp' || outbound.protocol === Protocols.Hysteria"
  995. >
  996. <a-button
  997. icon="plus"
  998. type="primary"
  999. size="small"
  1000. @click="outbound.stream.addUdpMask(outbound.protocol === Protocols.Hysteria ? 'salamander' : 'mkcp-aes128gcm')"
  1001. ></a-button>
  1002. </a-form-item>
  1003. <template
  1004. v-if="outbound.stream.finalmask.udp && outbound.stream.finalmask.udp.length > 0"
  1005. >
  1006. <a-form
  1007. v-for="(mask, index) in outbound.stream.finalmask.udp"
  1008. :key="index"
  1009. :colon="false"
  1010. :label-col="{ md: {span:8} }"
  1011. :wrapper-col="{ md: {span:14} }"
  1012. >
  1013. <a-divider :style="{ margin: '0' }">
  1014. UDP Mask [[ index + 1 ]]
  1015. <a-icon
  1016. type="delete"
  1017. @click="() => outbound.stream.delUdpMask(index)"
  1018. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  1019. ></a-icon>
  1020. </a-divider>
  1021. <a-form-item label="Type">
  1022. <a-select
  1023. v-model="mask.type"
  1024. @change="(type) => { mask.settings = mask._getDefaultSettings(type, {}); if(outbound.stream.network === 'kcp') { outbound.stream.kcp.mtu = type === 'xdns' ? 900 : 1350; } }"
  1025. :dropdown-class-name="themeSwitcher.currentTheme"
  1026. >
  1027. <a-select-option
  1028. v-if="outbound.protocol === Protocols.Hysteria"
  1029. value="salamander"
  1030. >
  1031. Salamander (Hysteria2)</a-select-option
  1032. >
  1033. <template v-else>
  1034. <a-select-option value="mkcp-aes128gcm"
  1035. >mKCP AES-128-GCM</a-select-option
  1036. >
  1037. <a-select-option value="header-dns"
  1038. >Header DNS</a-select-option
  1039. >
  1040. <a-select-option value="header-dtls"
  1041. >Header DTLS 1.2</a-select-option
  1042. >
  1043. <a-select-option value="header-srtp"
  1044. >Header SRTP</a-select-option
  1045. >
  1046. <a-select-option value="header-utp"
  1047. >Header uTP</a-select-option
  1048. >
  1049. <a-select-option value="header-wechat"
  1050. >Header WeChat Video</a-select-option
  1051. >
  1052. <a-select-option value="header-wireguard"
  1053. >Header WireGuard</a-select-option
  1054. >
  1055. <a-select-option value="mkcp-original"
  1056. >mKCP Original</a-select-option
  1057. >
  1058. <a-select-option value="xdns">xDNS</a-select-option>
  1059. <a-select-option value="xicmp">xICMP</a-select-option>
  1060. <a-select-option value="header-custom">Header Custom</a-select-option>
  1061. <a-select-option value="noise">Noise</a-select-option>
  1062. </template>
  1063. </a-select>
  1064. </a-form-item>
  1065. <a-form-item
  1066. label="Password"
  1067. v-if="['salamander', 'mkcp-aes128gcm'].includes(mask.type)"
  1068. >
  1069. <a-input
  1070. v-model.trim="mask.settings.password"
  1071. placeholder="Obfuscation password"
  1072. ></a-input>
  1073. </a-form-item>
  1074. <a-form-item label="Domain" v-if="mask.type === 'header-dns'">
  1075. <a-input
  1076. v-model.trim="mask.settings.domain"
  1077. placeholder="e.g., www.example.com"
  1078. ></a-input>
  1079. </a-form-item>
  1080. <template v-if="mask.type === 'xdns'">
  1081. <a-form-item label="Resolvers">
  1082. <a-select
  1083. mode="tags"
  1084. v-model="mask.settings.resolvers"
  1085. :style="{ width: '100%' }"
  1086. :token-separators="[',']"
  1087. placeholder="e.g., xxx+udp://8.8.8.8:53"
  1088. ></a-select>
  1089. </a-form-item>
  1090. </template>
  1091. <template v-if="mask.type === 'noise'">
  1092. <a-form-item label="Reset">
  1093. <a-input-number v-model.number="mask.settings.reset" :min="0" />
  1094. </a-form-item>
  1095. <a-form-item label="Noise">
  1096. <a-icon
  1097. type="plus"
  1098. type="primary"
  1099. size="small"
  1100. @click="mask.settings.noise.push({rand: 0, randRange: '0-255', type: 'array', packet: [], delay: ''})"
  1101. />
  1102. </a-form-item>
  1103. <template v-for="(n, index) in mask.settings.noise" :key="index">
  1104. <a-divider :style="{ margin: '0' }">
  1105. Noise [[ index + 1 ]]
  1106. <a-icon
  1107. type="delete"
  1108. @click="() => mask.settings.noise.splice(index, 1)"
  1109. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  1110. ></a-icon>
  1111. </a-divider>
  1112. <a-form-item label="Type">
  1113. <a-select
  1114. v-model="n.type"
  1115. :dropdown-class-name="themeSwitcher.currentTheme"
  1116. @change="t => { if(t === 'array') n.packet = []; else n.packet = ''; }"
  1117. >
  1118. <a-select-option value="array">Array</a-select-option>
  1119. <a-select-option value="str">String</a-select-option>
  1120. <a-select-option value="hex">Hex</a-select-option>
  1121. <a-select-option value="base64">Base64</a-select-option>
  1122. </a-select>
  1123. </a-form-item>
  1124. <template v-if="n.type === 'array'">
  1125. <a-form-item label="Rand">
  1126. <a-input v-model.trim="n.rand" placeholder="0 or 1-8192" />
  1127. </a-form-item>
  1128. <a-form-item label="Rand Range">
  1129. <a-input
  1130. v-model.trim="n.randRange"
  1131. placeholder="0-255"
  1132. ></a-input>
  1133. </a-form-item>
  1134. </template>
  1135. <a-form-item label="Packet" v-else>
  1136. <a-input v-model.trim="n.packet" placeholder="binary data" />
  1137. </a-form-item>
  1138. <a-form-item label="Delay">
  1139. <a-input v-model.trim="n.delay" placeholder="10-20" />
  1140. </a-form-item>
  1141. </template>
  1142. </template>
  1143. <template v-if="mask.type === 'header-custom'">
  1144. <a-form-item label="Client">
  1145. <a-icon
  1146. type="plus"
  1147. size="small"
  1148. @click="mask.settings.client.push({rand: 0, randRange: '0-255', type: 'array', packet: []})"
  1149. />
  1150. </a-form-item>
  1151. <template v-for="(c, index) in mask.settings.client" :key="index">
  1152. <a-divider :style="{ margin: '0' }">
  1153. Client [[ index + 1 ]]
  1154. <a-icon
  1155. type="delete"
  1156. @click="mask.settings.client.splice(index, 1)"
  1157. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  1158. ></a-icon>
  1159. </a-divider>
  1160. <a-form-item label="Type">
  1161. <a-select
  1162. v-model="c.type"
  1163. :dropdown-class-name="themeSwitcher.currentTheme"
  1164. @change="t => { if(t === 'array') c.packet = []; else c.packet = ''; }"
  1165. >
  1166. <a-select-option value="array">Array</a-select-option>
  1167. <a-select-option value="str">String</a-select-option>
  1168. <a-select-option value="hex">Hex</a-select-option>
  1169. <a-select-option value="base64">Base64</a-select-option>
  1170. </a-select>
  1171. </a-form-item>
  1172. <template v-if="c.type === 'array'">
  1173. <a-form-item label="Rand">
  1174. <a-input-number v-model.number="c.rand" :min="0"></a-input-number>
  1175. </a-form-item>
  1176. <a-form-item label="Rand Range">
  1177. <a-input v-model.trim="c.randRange" placeholder="0-255"></a-input>
  1178. </a-form-item>
  1179. </template>
  1180. <a-form-item label="Packet" v-else>
  1181. <a-input v-model.trim="c.packet" placeholder="binary data" />
  1182. </a-form-item>
  1183. </template>
  1184. <a-divider :style="{ margin: '0' }"></a-divider>
  1185. <a-form-item label="Server">
  1186. <a-icon
  1187. type="plus"
  1188. size="small"
  1189. @click="mask.settings.server.push({rand: 0, randRange: '0-255', type: 'array', packet: []})"
  1190. />
  1191. </a-form-item>
  1192. <template v-for="(s, index) in mask.settings.server" :key="index">
  1193. <a-divider :style="{ margin: '0' }">
  1194. Server [[ index + 1 ]]
  1195. <a-icon
  1196. type="delete"
  1197. @click="mask.settings.server.splice(index, 1)"
  1198. :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
  1199. ></a-icon>
  1200. </a-divider>
  1201. <a-form-item label="Type">
  1202. <a-select
  1203. v-model="s.type"
  1204. :dropdown-class-name="themeSwitcher.currentTheme"
  1205. @change="t => { if(t === 'array') s.packet = []; else s.packet = ''; }"
  1206. >
  1207. <a-select-option value="array">Array</a-select-option>
  1208. <a-select-option value="str">String</a-select-option>
  1209. <a-select-option value="hex">Hex</a-select-option>
  1210. <a-select-option value="base64">Base64</a-select-option>
  1211. </a-select>
  1212. </a-form-item>
  1213. <template v-if="s.type === 'array'">
  1214. <a-form-item label="Rand">
  1215. <a-input-number v-model.number="s.rand" :min="0"></a-input-number>
  1216. </a-form-item>
  1217. <a-form-item label="Rand Range">
  1218. <a-input v-model.trim="s.randRange" placeholder="0-255"></a-input>
  1219. </a-form-item>
  1220. </template>
  1221. <a-form-item label="Packet" v-else>
  1222. <a-input v-model.trim="s.packet" placeholder="binary data" />
  1223. </a-form-item>
  1224. </template>
  1225. </template>
  1226. <template v-if="mask.type === 'xicmp'">
  1227. <a-form-item label="IP">
  1228. <a-input
  1229. v-model.trim="mask.settings.ip"
  1230. placeholder="0.0.0.0"
  1231. ></a-input>
  1232. </a-form-item>
  1233. <a-form-item label="ID">
  1234. <a-input-number
  1235. v-model.number="mask.settings.id"
  1236. :min="0"
  1237. ></a-input-number>
  1238. </a-form-item>
  1239. </template>
  1240. </a-form>
  1241. </template>
  1242. <!-- quicParams – only for xhttp H3 and hysteria -->
  1243. <template v-if="outbound.stream.network === 'xhttp' || outbound.protocol === Protocols.Hysteria">
  1244. <a-form-item label="QUIC Params">
  1245. <a-switch v-model="outbound.stream.finalmask.enableQuicParams"></a-switch>
  1246. </a-form-item>
  1247. <template v-if="outbound.stream.finalmask.enableQuicParams">
  1248. <a-form-item label="Congestion">
  1249. <a-select
  1250. v-model="outbound.stream.finalmask.quicParams.congestion"
  1251. :dropdown-class-name="themeSwitcher.currentTheme"
  1252. >
  1253. <a-select-option value="reno">Reno</a-select-option>
  1254. <a-select-option value="bbr">BBR</a-select-option>
  1255. <a-select-option value="brutal">Brutal</a-select-option>
  1256. <a-select-option value="force-brutal">Force Brutal</a-select-option>
  1257. </a-select>
  1258. </a-form-item>
  1259. <a-form-item label="Debug">
  1260. <a-switch v-model="outbound.stream.finalmask.quicParams.debug"></a-switch>
  1261. </a-form-item>
  1262. <template v-if="['brutal','force-brutal'].includes(outbound.stream.finalmask.quicParams.congestion)">
  1263. <a-form-item label="Brutal Up">
  1264. <a-input v-model.trim="outbound.stream.finalmask.quicParams.brutalUp" placeholder="e.g. 60 mbps" />
  1265. </a-form-item>
  1266. <a-form-item label="Brutal Down">
  1267. <a-input v-model.trim="outbound.stream.finalmask.quicParams.brutalDown" placeholder="e.g. 60 mbps" />
  1268. </a-form-item>
  1269. </template>
  1270. <a-form-item label="UDP Hop">
  1271. <a-switch v-model="outbound.stream.finalmask.quicParams.hasUdpHop"></a-switch>
  1272. </a-form-item>
  1273. <template v-if="outbound.stream.finalmask.quicParams.hasUdpHop">
  1274. <a-form-item label="Hop Ports">
  1275. <a-input v-model.trim="outbound.stream.finalmask.quicParams.udpHop.ports" placeholder="e.g. 20000-50000" />
  1276. </a-form-item>
  1277. <a-form-item label="Hop Interval (s)">
  1278. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.udpHop.interval" :min="5" />
  1279. </a-form-item>
  1280. </template>
  1281. <a-form-item label="Max Idle Timeout (s)">
  1282. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxIdleTimeout" :min="4" :max="120" />
  1283. </a-form-item>
  1284. <a-form-item label="Keep Alive Period (s)">
  1285. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.keepAlivePeriod" :min="0" :max="60" />
  1286. </a-form-item>
  1287. <a-form-item label="Disable Path MTU Dis">
  1288. <a-switch v-model="outbound.stream.finalmask.quicParams.disablePathMTUDiscovery"></a-switch>
  1289. </a-form-item>
  1290. <a-form-item label="Max Incoming Streams">
  1291. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxIncomingStreams" :min="0" placeholder="0 = default" />
  1292. </a-form-item>
  1293. <a-form-item label="Init Stream Window">
  1294. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.initStreamReceiveWindow" :min="0" placeholder="0 = default" />
  1295. </a-form-item>
  1296. <a-form-item label="Max Stream Window">
  1297. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxStreamReceiveWindow" :min="0" placeholder="0 = default" />
  1298. </a-form-item>
  1299. <a-form-item label="Init Conn Window">
  1300. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.initConnectionReceiveWindow" :min="0" placeholder="0 = default" />
  1301. </a-form-item>
  1302. <a-form-item label="Max Conn Window">
  1303. <a-input-number v-model.number="outbound.stream.finalmask.quicParams.maxConnectionReceiveWindow" :min="0" placeholder="0 = default" />
  1304. </a-form-item>
  1305. </template>
  1306. </template>
  1307. </template>
  1308. <!-- tls settings -->
  1309. <template v-if="outbound.canEnableTls()">
  1310. <a-form-item label='{{ i18n "security" }}'>
  1311. <a-radio-group
  1312. v-model="outbound.stream.security"
  1313. button-style="solid"
  1314. >
  1315. <a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
  1316. <a-radio-button value="tls">TLS</a-radio-button>
  1317. <a-radio-button v-if="outbound.canEnableReality()" value="reality"
  1318. >Reality</a-radio-button
  1319. >
  1320. </a-radio-group>
  1321. </a-form-item>
  1322. <template v-if="outbound.stream.isTls">
  1323. <a-form-item label="SNI" placeholder="Server Name Indication">
  1324. <a-input v-model.trim="outbound.stream.tls.serverName"></a-input>
  1325. </a-form-item>
  1326. <a-form-item label="uTLS">
  1327. <a-select
  1328. v-model="outbound.stream.tls.fingerprint"
  1329. :dropdown-class-name="themeSwitcher.currentTheme"
  1330. >
  1331. <a-select-option value>None</a-select-option>
  1332. <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key"
  1333. >[[ key ]]</a-select-option
  1334. >
  1335. </a-select>
  1336. </a-form-item>
  1337. <a-form-item label="ALPN">
  1338. <a-select
  1339. mode="multiple"
  1340. :dropdown-class-name="themeSwitcher.currentTheme"
  1341. v-model="outbound.stream.tls.alpn"
  1342. >
  1343. <a-select-option v-for="alpn in ALPN_OPTION" :value="alpn"
  1344. >[[ alpn ]]</a-select-option
  1345. >
  1346. </a-select>
  1347. </a-form-item>
  1348. <a-form-item label="ECH Config List">
  1349. <a-input v-model.trim="outbound.stream.tls.echConfigList"></a-input>
  1350. </a-form-item>
  1351. <a-form-item label="verify Peer Cert By Name">
  1352. <a-input
  1353. v-model.trim="outbound.stream.tls.verifyPeerCertByName"
  1354. placeholder="cloudflare-dns.com"
  1355. ></a-input>
  1356. </a-form-item>
  1357. <a-form-item label=" pinned Peer Cert Sha256">
  1358. <a-input
  1359. v-model.trim="outbound.stream.tls.pinnedPeerCertSha256"
  1360. placeholder="Enter SHA256 fingerprints (base64)"
  1361. >
  1362. </a-input>
  1363. </a-form-item>
  1364. </template>
  1365. <!-- reality settings -->
  1366. <template v-if="outbound.stream.isReality">
  1367. <a-form-item label="SNI">
  1368. <a-input
  1369. v-model.trim="outbound.stream.reality.serverName"
  1370. ></a-input>
  1371. </a-form-item>
  1372. <a-form-item label="uTLS">
  1373. <a-select
  1374. v-model="outbound.stream.reality.fingerprint"
  1375. :dropdown-class-name="themeSwitcher.currentTheme"
  1376. >
  1377. <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key"
  1378. >[[ key ]]</a-select-option
  1379. >
  1380. </a-select>
  1381. </a-form-item>
  1382. <a-form-item label="Short ID">
  1383. <a-input v-model.trim="outbound.stream.reality.shortId"></a-input>
  1384. </a-form-item>
  1385. <a-form-item label="SpiderX">
  1386. <a-input v-model.trim="outbound.stream.reality.spiderX"></a-input>
  1387. </a-form-item>
  1388. <a-form-item label="Public Key">
  1389. <a-textarea
  1390. v-model.trim="outbound.stream.reality.publicKey"
  1391. ></a-textarea>
  1392. </a-form-item>
  1393. <a-form-item label="mldsa65 Verify">
  1394. <a-textarea
  1395. v-model.trim="outbound.stream.reality.mldsa65Verify"
  1396. ></a-textarea>
  1397. </a-form-item>
  1398. </template>
  1399. </template>
  1400. <!-- sockopt settings -->
  1401. <a-form-item label="Sockopts">
  1402. <a-switch v-model="outbound.stream.sockoptSwitch"></a-switch>
  1403. </a-form-item>
  1404. <template v-if="outbound.stream.sockoptSwitch">
  1405. <a-form-item label="Dialer Proxy">
  1406. <a-select
  1407. v-model="outbound.stream.sockopt.dialerProxy"
  1408. :dropdown-class-name="themeSwitcher.currentTheme"
  1409. >
  1410. <a-select-option v-for="tag in ['', ...outModal.tags]" :value="tag"
  1411. >[[ tag ]]</a-select-option
  1412. >
  1413. </a-select>
  1414. </a-form-item>
  1415. <a-form-item label="Address Port Strategy">
  1416. <a-select
  1417. v-model="outbound.stream.sockopt.addressPortStrategy"
  1418. :dropdown-class-name="themeSwitcher.currentTheme"
  1419. >
  1420. <a-select-option v-for="key in Address_Port_Strategy" :value="key"
  1421. >[[ key ]]</a-select-option
  1422. >
  1423. </a-select>
  1424. </a-form-item>
  1425. <a-form-item label="Keep Alive Interval">
  1426. <a-input-number
  1427. v-model.number="outbound.stream.sockopt.tcpKeepAliveInterval"
  1428. :min="0"
  1429. ></a-input-number>
  1430. </a-form-item>
  1431. <a-form-item label="TCP Fast Open">
  1432. <a-switch v-model="outbound.stream.sockopt.tcpFastOpen"></a-switch>
  1433. </a-form-item>
  1434. <a-form-item label="Multipath TCP">
  1435. <a-switch v-model.trim="outbound.stream.sockopt.tcpMptcp"></a-switch>
  1436. </a-form-item>
  1437. <a-form-item label="Penetrate">
  1438. <a-switch v-model="outbound.stream.sockopt.penetrate"></a-switch>
  1439. </a-form-item>
  1440. <a-form-item label="Trusted X-Forwarded-For">
  1441. <a-select
  1442. mode="tags"
  1443. v-model="outbound.stream.sockopt.trustedXForwardedFor"
  1444. :style="{ width: '100%' }"
  1445. :dropdown-class-name="themeSwitcher.currentTheme"
  1446. >
  1447. <a-select-option value="CF-Connecting-IP"
  1448. >CF-Connecting-IP</a-select-option
  1449. >
  1450. <a-select-option value="X-Real-IP">X-Real-IP</a-select-option>
  1451. <a-select-option value="True-Client-IP"
  1452. >True-Client-IP</a-select-option
  1453. >
  1454. <a-select-option value="X-Client-IP">X-Client-IP</a-select-option>
  1455. </a-select>
  1456. </a-form-item>
  1457. </template>
  1458. <!-- mux settings -->
  1459. <template v-if="outbound.canEnableMux()">
  1460. <a-form-item label="Mux">
  1461. <a-switch v-model="outbound.mux.enabled"></a-switch>
  1462. </a-form-item>
  1463. <template v-if="outbound.mux.enabled">
  1464. <a-form-item label="Concurrency">
  1465. <a-input-number
  1466. v-model.number="outbound.mux.concurrency"
  1467. :min="-1"
  1468. :max="1024"
  1469. ></a-input-number>
  1470. </a-form-item>
  1471. <a-form-item label="xudp Concurrency">
  1472. <a-input-number
  1473. v-model.number="outbound.mux.xudpConcurrency"
  1474. :min="-1"
  1475. :max="1024"
  1476. ></a-input-number>
  1477. </a-form-item>
  1478. <a-form-item label="xudp UDP 443">
  1479. <a-select
  1480. v-model="outbound.mux.xudpProxyUDP443"
  1481. :dropdown-class-name="themeSwitcher.currentTheme"
  1482. >
  1483. <a-select-option
  1484. v-for="c in ['reject', 'allow', 'skip']"
  1485. :value="c"
  1486. >[[ c ]]</a-select-option
  1487. >
  1488. </a-select>
  1489. </a-form-item>
  1490. </template>
  1491. </template>
  1492. </a-form>
  1493. </a-tab-pane>
  1494. <a-tab-pane key="2" tab="JSON" force-render="true">
  1495. <a-space direction="vertical" :size="10" :style="{ marginTop: '10px' }">
  1496. <a-input
  1497. addon-before='{{ i18n "pages.xray.outbound.link" }}'
  1498. v-model.trim="outModal.link"
  1499. placeholder="vmess:// vless:// trojan:// ss:// hysteria2://"
  1500. >
  1501. <a-icon slot="addonAfter" type="form" @click="convertLink"></a-icon>
  1502. </a-input>
  1503. <textarea
  1504. :style="{ position: 'absolute', left: '-800px' }"
  1505. id="outboundJson"
  1506. ></textarea>
  1507. </a-space>
  1508. </a-tab-pane>
  1509. </a-tabs>
  1510. {{end}}