Compare commits

...

48 Commits

Author SHA1 Message Date
mhsanaei
80cfbefd75 v2.4.3 2024-10-01 09:41:12 +02:00
mhsanaei
f2ee18235f update dependencies 2024-10-01 09:40:03 +02:00
mhsanaei
f48df1e5c0 Xray Core v24.9.30 2024-10-01 09:35:06 +02:00
mhsanaei
b24855082e RAW as an alias of TCP 2024-10-01 09:34:13 +02:00
Vyacheslav Scherbinin
27434f3235 Fix toasts (#2571)
* Add space to toast status messages

* Removed opening space from translations
2024-09-30 17:06:38 +02:00
mhsanaei
cdb6eac0e6 Reality - min,max client (not active) 2024-09-27 14:57:04 +02:00
mhsanaei
9e13513205 Temporarily disabled Allocate 2024-09-27 14:37:57 +02:00
mhsanaei
b09f52357c update block and direct connection 2024-09-27 13:34:12 +02:00
mhsanaei
ac08e86747 inbound - better view 2024-09-26 16:20:35 +02:00
mhsanaei
c9c8abe97b refactor: split XTLS and Reality form tls into separate files 2024-09-26 16:01:58 +02:00
mhsanaei
0b8beafc89 DNS - Expect IPs 2024-09-26 13:08:54 +02:00
mhsanaei
8b6e3491c4 base install for amzn 2024-09-26 12:19:18 +02:00
dependabot[bot]
6cf2b56f9b Bump github.com/valyala/fasthttp from 1.55.0 to 1.56.0 (#2566)
Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) from 1.55.0 to 1.56.0.
- [Release notes](https://github.com/valyala/fasthttp/releases)
- [Commits](https://github.com/valyala/fasthttp/compare/v1.55.0...v1.56.0)

---
updated-dependencies:
- dependency-name: github.com/valyala/fasthttp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-25 13:07:10 +02:00
mhsanaei
19b95829e0 OS Support - AlmaLinux 8.0 + 2024-09-25 11:31:07 +02:00
mhsanaei
4bea427c79 minor change 2024-09-25 10:40:21 +02:00
Sanaei
da7e4d51d6 OS Support - Amazon Linux + AlmaLinux 8 2024-09-25 10:13:54 +02:00
mhsanaei
43713fbdf8 v2.4.2 2024-09-24 15:15:29 +02:00
mhsanaei
dc29e858c9 Xray Core v24.9.19 2024-09-24 15:15:19 +02:00
mhsanaei
c30c6f08f3 Direct Sub Json - geoIP, geoSite 2024-09-24 15:11:16 +02:00
mhsanaei
7c892ac051 Iplimit - warning improved 2024-09-24 13:24:10 +02:00
mhsanaei
75dd7b93f5 update dependencies 2024-09-24 12:19:08 +02:00
mhsanaei
d5de8e1bf3 removeNoise - hide when only one noise 2024-09-24 12:18:42 +02:00
mhsanaei
16b4795956 removed - timeout 2024-09-24 12:00:37 +02:00
Pavel Kogen
e5835c299c OS Support - Amazon Linux (#2564) 2024-09-24 11:53:12 +02:00
mhsanaei
4fdef3cfde add or remove noise 2024-09-24 11:38:10 +02:00
dependabot[bot]
cf6a8bd463 Bump google.golang.org/grpc from 1.66.2 to 1.67.0 (#2563)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.66.2 to 1.67.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.66.2...v1.67.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-20 11:45:21 +02:00
mhsanaei
59a84e844c HTTP - Allow Transparent 2024-09-17 11:37:24 +02:00
mhsanaei
6b0c9a5fad update noise to noises
+ type
2024-09-17 09:51:57 +02:00
mhsanaei
77edea5419 v2.4.1 2024-09-16 17:30:53 +02:00
mhsanaei
521870df0a minor changes 2024-09-16 16:49:00 +02:00
mhsanaei
dc1c1eb998 Xray Core v24.9.16 2024-09-16 16:48:44 +02:00
mhsanaei
e78427245a New - splithttp (xmux) 2024-09-16 16:47:59 +02:00
mhsanaei
fbcab5bc52 login page - more width for lang 2024-09-16 13:52:21 +02:00
mhsanaei
89c79c3ec3 more details - vmess security 2024-09-16 13:51:36 +02:00
mhsanaei
566cd9e9c4 New - Allocate 2024-09-16 11:41:21 +02:00
mhsanaei
ad78cec7c7 fix mistake - security only for vmess 2024-09-16 10:37:02 +02:00
mhsanaei
176ab5f48e New - DNS Outbound (nonIPQuery, blockTypes) 2024-09-16 10:30:51 +02:00
laperuz92
9c4fa23931 Some README updates (#2562)
* Update README.ru_RU.md

Fixed some typos here and there

* Add info about docker image autoupdate

* Update Russian translation

* Add info on Portuguese (Brazip) translation
2024-09-13 11:25:57 +02:00
mhsanaei
2938694c45 geosite:category-ru and ir 2024-09-13 11:15:55 +02:00
mhsanaei
88d0fb9753 Reality - maxTimediff 2024-09-13 09:39:57 +02:00
mhsanaei
d23a7f81ef freedom - default value for timeout
I've seen many users make the mistake of not setting the timeout value in Xray, which causes errors. Then, they mistakenly assume that 3x-ui has a bug.
2024-09-13 09:21:37 +02:00
mhsanaei
2e363445fc update dependencies 2024-09-12 11:58:21 +02:00
mhsanaei
33d983bc20 New - maskAddress , dnslog 2024-09-12 11:44:13 +02:00
mhsanaei
3e7c7831bc Email Validation - new pattern
@ included
2024-09-12 10:07:53 +02:00
mhsanaei
374d49eb92 Iplimit - improved
Ensure accurate extraction of email.
Access logs are needed when the IP limit feature is active.
2024-09-12 09:44:17 +02:00
mhsanaei
663cf5649f Session - default 60 minute (minimum) 2024-09-12 09:41:24 +02:00
dependabot[bot]
095ebccbb0 Bump google.golang.org/grpc from 1.66.0 to 1.66.1 (#2558)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.66.0 to 1.66.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.66.0...v1.66.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-10 11:19:10 +02:00
dependabot[bot]
f4bb6b0517 Bump gorm.io/gorm from 1.25.11 to 1.25.12 (#2543)
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.25.11 to 1.25.12.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/compare/v1.25.11...v1.25.12)

---
updated-dependencies:
- dependency-name: gorm.io/gorm
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 17:58:47 +02:00
56 changed files with 1039 additions and 890 deletions

View File

@@ -83,7 +83,7 @@ jobs:
cd x-ui/bin cd x-ui/bin
# Download dependencies # Download dependencies
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v24.9.7/" Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v24.9.30/"
if [ "${{ matrix.platform }}" == "amd64" ]; then if [ "${{ matrix.platform }}" == "amd64" ]; then
wget ${Xray_URL}Xray-linux-64.zip wget ${Xray_URL}Xray-linux-64.zip
unzip Xray-linux-64.zip unzip Xray-linux-64.zip

View File

@@ -27,7 +27,7 @@ case $1 in
esac esac
mkdir -p build/bin mkdir -p build/bin
cd build/bin cd build/bin
wget "https://github.com/XTLS/Xray-core/releases/download/v24.9.7/Xray-linux-${ARCH}.zip" wget "https://github.com/XTLS/Xray-core/releases/download/v24.9.30/Xray-linux-${ARCH}.zip"
unzip "Xray-linux-${ARCH}.zip" unzip "Xray-linux-${ARCH}.zip"
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
mv xray "xray-linux-${FNAME}" mv xray "xray-linux-${FNAME}"

View File

@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## Instalar una Versión Personalizada ## Instalar una Versión Personalizada
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.4.0`: Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.4.3`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.0 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.3
``` ```
## Certificado SSL ## Certificado SSL
@@ -220,11 +220,14 @@ location /sub {
- CentOS 8+ - CentOS 8+
- Fedora 36+ - Fedora 36+
- Arch Linux - Arch Linux
- Parch Linux
- Manjaro - Manjaro
- Armbian - Armbian
- AlmaLinux 9+ - AlmaLinux 8.0+
- Rockylinux 9+ - Rocky Linux 8+
- Oracle Linux 8+
- OpenSUSE Tubleweed - OpenSUSE Tubleweed
- Amazon Linux 2023
## Arquitecturas y Dispositivos Compatibles ## Arquitecturas y Dispositivos Compatibles

View File

@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## Install Custom Version ## Install Custom Version
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.4.0`: To install your desired version, add the version to the end of the installation command. e.g., ver `v2.4.3`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.0 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.3
``` ```
## SSL Certificate ## SSL Certificate
@@ -169,6 +169,8 @@ systemctl restart x-ui
docker compose up -d docker compose up -d
``` ```
Add ```--pull always``` flag to make docker automatically recreate container if a newer image is pulled. See https://docs.docker.com/reference/cli/docker/container/run/#pull for more info.
**OR** **OR**
```sh ```sh
@@ -248,10 +250,11 @@ location /sub {
- Parch Linux - Parch Linux
- Manjaro - Manjaro
- Armbian - Armbian
- AlmaLinux 9+ - AlmaLinux 8.0+
- Rocky Linux 9+ - Rocky Linux 8+
- Oracle Linux 8+ - Oracle Linux 8+
- OpenSUSE Tubleweed - OpenSUSE Tubleweed
- Amazon Linux 2023
## Supported Architectures and Devices ## Supported Architectures and Devices

View File

@@ -12,7 +12,7 @@
> **Отказ от ответственности:** Этот проект предназначен только для личного обучения и общения. Пожалуйста, не используйте его в незаконных целях и не применяйте в производственной среде. > **Отказ от ответственности:** Этот проект предназначен только для личного обучения и общения. Пожалуйста, не используйте его в незаконных целях и не применяйте в производственной среде.
**Если этот проект оказался полезным для вас, вы можете оценить его, постативив звёздочку** :star2: **Если этот проект оказался полезным для вас, вы можете оценить его, поставив звёздочку** :star2:
<p align="left"> <p align="left">
<a href="https://buymeacoffee.com/mhsanaei" target="_blank"> <a href="https://buymeacoffee.com/mhsanaei" target="_blank">
@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## Установка определённой версии ## Установка определённой версии
Чтобы установить нужную вам версию, добавьте номер версии в конец команды установки. Например, `v2.4.0`: Чтобы установить нужную вам версию, добавьте номер версии в конец команды установки. Например, `v2.4.3`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.0 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.3
``` ```
## SSL Сертификат ## SSL Сертификат
@@ -53,7 +53,7 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
- **Get SSL:** Получить SSL сертификаты. - **Get SSL:** Получить SSL сертификаты.
- **Revoke:** Отозвать существующие SSL сертификаты. - **Revoke:** Отозвать существующие SSL сертификаты.
- **Force Renew:** Принудительно превыпустить SSL сертификаты. - **Force Renew:** Принудительно перевыпустить SSL сертификаты.
### Certbot ### Certbot
@@ -76,7 +76,7 @@ certbot renew --dry-run
**Как получить глобальный API-ключ Cloudflare:** **Как получить глобальный API-ключ Cloudflare:**
1. Выполните команду `x-ui` в терминале, затем выберите `Cloudflare SSL Certificate`. 1. Выполните команду `x-ui` в терминале, затем выберите `Cloudflare SSL Certificate`.
2. Посетите ссылку: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens). 2. Перейдите по ссылке: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
3. Нажмите на "View Global API Key" (см. скриншот ниже): 3. Нажмите на "View Global API Key" (см. скриншот ниже):
![](media/APIKey1.PNG) ![](media/APIKey1.PNG)
4. Возможно, вам потребуется повторно пройти аутентификацию. После этого ключ API будет отображён (см. скриншот ниже): 4. Возможно, вам потребуется повторно пройти аутентификацию. После этого ключ API будет отображён (см. скриншот ниже):
@@ -168,6 +168,8 @@ systemctl restart x-ui
docker compose up -d docker compose up -d
``` ```
Добавьте параметр ```--pull always``` для автоматического обновления контейнера, когда публикуется новый образ. Подробности: https://docs.docker.com/reference/cli/docker/container/run/#pull
**ИЛИ** **ИЛИ**
```sh ```sh
@@ -247,10 +249,11 @@ location /sub {
- Parch Linux - Parch Linux
- Manjaro - Manjaro
- Armbian - Armbian
- AlmaLinux 9+ - AlmaLinux 8.0+
- Rocky Linux 9+ - Rocky Linux 8+
- Oracle Linux 8+ - Oracle Linux 8+
- OpenSUSE Tubleweed - OpenSUSE Tubleweed
- Amazon Linux 2023
## Поддерживаемые архитектуры и устройства ## Поддерживаемые архитектуры и устройства
@@ -285,6 +288,7 @@ location /sub {
- Индонезийский - Индонезийский
- Украинский - Украинский
- Турецкий - Турецкий
- Португальский (Бразилия)
## Возможности ## Возможности
@@ -329,7 +333,7 @@ location /sub {
- Выберите опцию `Reset Web Base Path`. - Выберите опцию `Reset Web Base Path`.
2. **Генерация или настройка пути:** 2. **Генерация или настройка пути:**
- Путь будет случайным образом сгенерирован, или вы можете ввести пользовательский путь. - Путь будет сгенерирован случайным образом, или вы можете ввести собственный путь.
3. **Просмотр текущих настроек:** 3. **Просмотр текущих настроек:**
- Чтобы просмотреть текущие настройки, используйте команду `x-ui settings` в терминале или опцию `View Current Settings` в `x-ui`. - Чтобы просмотреть текущие настройки, используйте команду `x-ui settings` в терминале или опцию `View Current Settings` в `x-ui`.
@@ -430,7 +434,7 @@ WARP встроен, и дополнительная установка не т
- Периодические отчеты - Периодические отчеты
- Уведомления о входе - Уведомления о входе
- Уведомления о пороге CPU - Уведомления о пороге загруженности процессора
- Уведомления о времени истечения и трафике заранее - Уведомления о времени истечения и трафике заранее
- Поддерживает меню отчетов клиента, если имя пользователя телеграм клиента добавлено в конфигурации пользователя - Поддерживает меню отчетов клиента, если имя пользователя телеграм клиента добавлено в конфигурации пользователя
- Поддержка отчета о трафике через Telegram, поиск по UUID (VMESS/VLESS) или паролю (TROJAN) - анонимно - Поддержка отчета о трафике через Telegram, поиск по UUID (VMESS/VLESS) или паролю (TROJAN) - анонимно
@@ -444,7 +448,7 @@ WARP встроен, и дополнительная установка не т
### Настройка телеграм-бота ### Настройка телеграм-бота
- Запустить [Botfather](https://t.me/BotFather) в вашем аккаунте Telegram: - Запустите [Botfather](https://t.me/BotFather) в вашем аккаунте Telegram:
![Botfather](./media/botfather.png) ![Botfather](./media/botfather.png)
- Создайте нового бота с помощью команды /newbot: у вас спросят 2 вопроса: отображаемое имя и имя пользователя для вашего бота. Обратите внимание, что имя пользователя должно заканчиваться на слово "bot". - Создайте нового бота с помощью команды /newbot: у вас спросят 2 вопроса: отображаемое имя и имя пользователя для вашего бота. Обратите внимание, что имя пользователя должно заканчиваться на слово "bot".
@@ -459,7 +463,7 @@ WARP встроен, и дополнительная установка не т
Введите токен вашего бота в поле ввода номер 3. Введите токен вашего бота в поле ввода номер 3.
Введите ID пользователя в поле ввода номер 4. Telegram-аккаунты с этим ID будут администраторами бота. (Вы можете ввести несколько ID, разделяя их запятой) Введите ID пользователя в поле ввода номер 4. Telegram-аккаунты с этим ID будут администраторами бота. (Вы можете ввести несколько ID, разделяя их запятой)
- Как получить ID пользователя Telegram? Используйте этого [бота](https://t.me/useridinfobot). Запустите бота, и он предоставит вам ваше ID пользователя Telegram. - Как получить ID пользователя Telegram? Используйте этот [бот](https://t.me/useridinfobot). Запустите бота, и он отобразит ваш ID пользователя Telegram.
![ID пользователя](./media/user-id.png) ![ID пользователя](./media/user-id.png)
</details> </details>
@@ -493,7 +497,7 @@ WARP встроен, и дополнительная установка не т
| `POST` | `"/resetAllTraffics"` | Сбросить трафик всех входящих соединений | `POST` | `"/resetAllTraffics"` | Сбросить трафик всех входящих соединений
| `POST` | `"/resetAllClientTraffics/:id"` | Сбросить трафик всех клиентов в входящем соединении | `POST` | `"/resetAllClientTraffics/:id"` | Сбросить трафик всех клиентов в входящем соединении
| `POST` | `"/delDepletedClients/:id"` | Удалить истекших клиентов в входящем соединении (-1: всех) | `POST` | `"/delDepletedClients/:id"` | Удалить истекших клиентов в входящем соединении (-1: всех)
| `POST` | `"/onlines"` | Получить пользователей, которые онлайн (список email'ов) | `POST` | `"/onlines"` | Получить пользователей, которые находятся онлайн (список email'ов)
\*- Поле `clientId` должно быть заполнено следующим образом: \*- Поле `clientId` должно быть заполнено следующим образом:

View File

@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## 安装指定版本 ## 安装指定版本
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.4.0`: 要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.4.3`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.0 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.4.3
``` ```
### SSL证书 ### SSL证书
@@ -243,11 +243,14 @@ location /sub {
- CentOS 8+ - CentOS 8+
- Fedora 36+ - Fedora 36+
- Arch Linux - Arch Linux
- Parch Linux
- Manjaro - Manjaro
- Armbian - Armbian
- AlmaLinux 9+ - AlmaLinux 8.0+
- Rockylinux 9+ - Rocky Linux 8+
- Oracle Linux 8+
- OpenSUSE Tubleweed - OpenSUSE Tubleweed
- Amazon Linux 2023
## 支持的架构和设备 ## 支持的架构和设备
<details> <details>

View File

@@ -1 +1 @@
2.4.0 2.4.3

View File

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

30
go.mod
View File

@@ -7,29 +7,30 @@ require (
github.com/gin-contrib/sessions v1.0.1 github.com/gin-contrib/sessions v1.0.1
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
github.com/goccy/go-json v0.10.3 github.com/goccy/go-json v0.10.3
github.com/mymmrac/telego v0.31.2 github.com/mymmrac/telego v0.31.3
github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml/v2 v2.2.3 github.com/pelletier/go-toml/v2 v2.2.3
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v4 v4.24.8 github.com/shirou/gopsutil/v4 v4.24.9
github.com/valyala/fasthttp v1.55.0 github.com/valyala/fasthttp v1.56.0
github.com/xtls/xray-core v1.8.24 github.com/xtls/xray-core v1.8.24
go.uber.org/atomic v1.11.0 go.uber.org/atomic v1.11.0
golang.org/x/text v0.18.0 golang.org/x/text v0.18.0
google.golang.org/grpc v1.66.0 google.golang.org/grpc v1.67.1
gorm.io/driver/sqlite v1.5.6 gorm.io/driver/sqlite v1.5.6
gorm.io/gorm v1.25.11 gorm.io/gorm v1.25.12
) )
require ( require (
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/bytedance/sonic v1.12.2 // indirect github.com/bytedance/sonic v1.12.3 // indirect
github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/cloudflare/circl v1.4.0 // indirect github.com/cloudflare/circl v1.4.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/ebitengine/purego v0.8.0 // indirect
github.com/fasthttp/router v1.5.2 // indirect github.com/fasthttp/router v1.5.2 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect github.com/francoispqt/gojay v1.2.13 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect
@@ -40,7 +41,7 @@ require (
github.com/go-playground/validator/v10 v10.22.1 // indirect github.com/go-playground/validator/v10 v10.22.1 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/btree v1.1.3 // indirect github.com/google/btree v1.1.3 // indirect
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 // indirect github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d // indirect
github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.4.0 // indirect github.com/gorilla/sessions v1.4.0 // indirect
@@ -49,10 +50,10 @@ require (
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/compress v1.17.10 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 // indirect github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.23 // indirect github.com/mattn/go-sqlite3 v1.14.23 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -64,12 +65,11 @@ require (
github.com/quic-go/quic-go v0.47.0 // indirect github.com/quic-go/quic-go v0.47.0 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect github.com/refraction-networking/utls v1.6.7 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/sagernet/sing v0.4.2 // indirect github.com/sagernet/sing v0.4.3 // indirect
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect github.com/tklauser/numcpus v0.8.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
@@ -79,19 +79,19 @@ require (
github.com/valyala/fastjson v1.6.4 // indirect github.com/valyala/fastjson v1.6.4 // indirect
github.com/vishvananda/netlink v1.3.0 // indirect github.com/vishvananda/netlink v1.3.0 // indirect
github.com/vishvananda/netns v0.0.4 // indirect github.com/vishvananda/netns v0.0.4 // indirect
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d // indirect github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/mock v0.4.0 // indirect go.uber.org/mock v0.4.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/arch v0.10.0 // indirect golang.org/x/arch v0.10.0 // indirect
golang.org/x/crypto v0.27.0 // indirect golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/mod v0.21.0 // indirect golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.29.0 // indirect golang.org/x/net v0.29.0 // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect golang.org/x/sys v0.25.0 // indirect
golang.org/x/time v0.6.0 // indirect golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect golang.org/x/tools v0.25.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect

62
go.sum
View File

@@ -18,8 +18,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg= github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU=
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
@@ -38,6 +38,8 @@ github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fp
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/fasthttp/router v1.5.2 h1:ckJCCdV7hWkkrMeId3WfEhz+4Gyyf6QPwxi/RHIMZ6I= github.com/fasthttp/router v1.5.2 h1:ckJCCdV7hWkkrMeId3WfEhz+4Gyyf6QPwxi/RHIMZ6I=
github.com/fasthttp/router v1.5.2/go.mod h1:C8EY53ozOwpONyevc/V7Gr8pqnEjwnkFFqPo1alAGs0= github.com/fasthttp/router v1.5.2/go.mod h1:C8EY53ozOwpONyevc/V7Gr8pqnEjwnkFFqPo1alAGs0=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -98,8 +100,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 h1:q5g0N9eal4bmJwXHC5z0QCKs8qhS35hFfq0BAYsIwZI= github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d h1:Jaz2JzpQaQXyET0AjLBXShrthbpqMkhGiEfkcQAiAUs=
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -125,8 +127,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -140,8 +142,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 h1:5RK988zAqB3/AN3opGfRpoQgAVqr6/A5+qRTi67VUZY= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0=
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -158,8 +160,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mymmrac/telego v0.31.2 h1:srvQOQtb5ZswmqIr03VuAkIF076bi25n7fyQ51Ifstw= github.com/mymmrac/telego v0.31.3 h1:yZlD+dm+1W6p3OmCG8K+MbS02Y6paUgwPnqfZN3RWQQ=
github.com/mymmrac/telego v0.31.2/go.mod h1:dyuyrOIagRstnm2ZNWuVilPdsslQyEgwYww9zkDqdJU= github.com/mymmrac/telego v0.31.3/go.mod h1:coOoqXVmjFnwBlzusjfEezbQ7RH9wQnDowJdMm+bnEo=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
@@ -196,11 +198,11 @@ github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sagernet/sing v0.4.2 h1:jzGNJdZVRI0xlAfFugsIQUPvyB9SuWvbJK7zQCXc4QM= github.com/sagernet/sing v0.4.3 h1:Ty/NAiNnVd6844k7ujlL5lkzydhcTH5Psc432jXA4Y8=
github.com/sagernet/sing v0.4.2/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls= github.com/sagernet/sing v0.4.3/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc= github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
@@ -208,12 +210,8 @@ github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEo
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil/v4 v4.24.8 h1:pVQjIenQkIhqO81mwTaXjTzOMT7d3TZkf43PlVFHENI= github.com/shirou/gopsutil/v4 v4.24.9 h1:KIV+/HaHD5ka5f570RZq+2SaeFsb/pq+fp2DGNWYoOI=
github.com/shirou/gopsutil/v4 v4.24.8/go.mod h1:wE0OrJtj4dG+hYkxqDH3QiBICdKSf04/npcvLLc/oRg= github.com/shirou/gopsutil/v4 v4.24.9/go.mod h1:3fkaHNeYsUFCGZ8+9vZVWtbyM1k2eRnlL+bWO8Bxa/Q=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
@@ -263,8 +261,8 @@ github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8= github.com/valyala/fasthttp v1.56.0 h1:bEZdJev/6LCBlpdORfrLu/WOZXXxvrUQSiyniuaoW8U=
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= github.com/valyala/fasthttp v1.56.0/go.mod h1:sReBt3XZVnudxuLOx4J/fMrJVorWRiWY2koQKgABiVI=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
@@ -273,8 +271,8 @@ github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQ
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg= github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 h1:g1Cj7d+my6k/HHxLAyxPwyX8i7FGRr6ulBDMkBzg2BM=
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE= github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463/go.mod h1:BjIOLmkEEtAgloAiVUcYj0Mt+YU00JARZw8AEU0IwAg=
github.com/xtls/xray-core v1.8.24 h1:Y2NumdlnJ9C9gvh1Ivs2+73ui5XQgB70wZXYCiI9DyY= github.com/xtls/xray-core v1.8.24 h1:Y2NumdlnJ9C9gvh1Ivs2+73ui5XQgB70wZXYCiI9DyY=
github.com/xtls/xray-core v1.8.24/go.mod h1:cWIOI6iBBOsB0HHU9PGhaiBhaMPfiktUjwA0IWolWJc= github.com/xtls/xray-core v1.8.24/go.mod h1:cWIOI6iBBOsB0HHU9PGhaiBhaMPfiktUjwA0IWolWJc=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
@@ -296,8 +294,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -350,8 +348,8 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
@@ -374,8 +372,8 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -392,8 +390,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE= gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE= gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE=
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk= gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=

View File

@@ -39,12 +39,12 @@ arch() {
echo "arch: $(arch)" echo "arch: $(arch)"
os_version="" os_version=""
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1) os_version=$(grep "^VERSION_ID" /etc/os-release | cut -d '=' -f2 | tr -d '"' | tr -d '.')
if [[ "${release}" == "arch" ]]; then if [[ "${release}" == "arch" ]]; then
echo "Your OS is Arch Linux" echo "Your OS is Arch Linux"
elif [[ "${release}" == "parch" ]]; then elif [[ "${release}" == "parch" ]]; then
echo "Your OS is Parch linux" echo "Your OS is Parch Linux"
elif [[ "${release}" == "manjaro" ]]; then elif [[ "${release}" == "manjaro" ]]; then
echo "Your OS is Manjaro" echo "Your OS is Manjaro"
elif [[ "${release}" == "armbian" ]]; then elif [[ "${release}" == "armbian" ]]; then
@@ -56,24 +56,28 @@ elif [[ "${release}" == "centos" ]]; then
echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1 echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "ubuntu" ]]; then elif [[ "${release}" == "ubuntu" ]]; then
if [[ ${os_version} -lt 20 ]]; then if [[ ${os_version} -lt 2004 ]]; then
echo -e "${red} Please use Ubuntu 20 or higher version!${plain}\n" && exit 1 echo -e "${red} Please use Ubuntu 20 or higher version!${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "fedora" ]]; then elif [[ "${release}" == "fedora" ]]; then
if [[ ${os_version} -lt 36 ]]; then if [[ ${os_version} -lt 36 ]]; then
echo -e "${red} Please use Fedora 36 or higher version!${plain}\n" && exit 1 echo -e "${red} Please use Fedora 36 or higher version!${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "amzn" ]]; then
if [[ ${os_version} != "2023" ]]; then
echo -e "${red} Please use Amazon Linux 2023!${plain}\n" && exit 1
fi
elif [[ "${release}" == "debian" ]]; then elif [[ "${release}" == "debian" ]]; then
if [[ ${os_version} -lt 11 ]]; then if [[ ${os_version} -lt 11 ]]; then
echo -e "${red} Please use Debian 11 or higher ${plain}\n" && exit 1 echo -e "${red} Please use Debian 11 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "almalinux" ]]; then elif [[ "${release}" == "almalinux" ]]; then
if [[ ${os_version} -lt 9 ]]; then if [[ ${os_version} -lt 80 ]]; then
echo -e "${red} Please use AlmaLinux 9 or higher ${plain}\n" && exit 1 echo -e "${red} Please use AlmaLinux 8.0 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "rocky" ]]; then elif [[ "${release}" == "rocky" ]]; then
if [[ ${os_version} -lt 9 ]]; then if [[ ${os_version} -lt 8 ]]; then
echo -e "${red} Please use Rocky Linux 9 or higher ${plain}\n" && exit 1 echo -e "${red} Please use Rocky Linux 8 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "oracle" ]]; then elif [[ "${release}" == "oracle" ]]; then
if [[ ${os_version} -lt 8 ]]; then if [[ ${os_version} -lt 8 ]]; then
@@ -90,12 +94,12 @@ else
echo "- Parch Linux" echo "- Parch Linux"
echo "- Manjaro" echo "- Manjaro"
echo "- Armbian" echo "- Armbian"
echo "- AlmaLinux 9+" echo "- AlmaLinux 8.0+"
echo "- Rocky Linux 9+" echo "- Rocky Linux 8+"
echo "- Oracle Linux 8+" echo "- Oracle Linux 8+"
echo "- OpenSUSE Tumbleweed" echo "- OpenSUSE Tumbleweed"
echo "- Amazon Linux 2023"
exit 1 exit 1
fi fi
install_base() { install_base() {
@@ -106,7 +110,7 @@ install_base() {
centos | almalinux | rocky | oracle) centos | almalinux | rocky | oracle)
yum -y update && yum install -y -q wget curl tar tzdata yum -y update && yum install -y -q wget curl tar tzdata
;; ;;
fedora) fedora | amzn)
dnf -y update && dnf install -y -q wget curl tar tzdata dnf -y update && dnf install -y -q wget curl tar tzdata
;; ;;
arch | manjaro | parch) arch | manjaro | parch)

View File

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

View File

@@ -92,9 +92,9 @@ func (s *Server) initRouter() (*gin.Engine, error) {
SubJsonFragment = "" SubJsonFragment = ""
} }
SubJsonNoise, err := s.settingService.GetSubJsonNoise() SubJsonNoises, err := s.settingService.GetSubJsonNoises()
if err != nil { if err != nil {
SubJsonNoise = "" SubJsonNoises = ""
} }
SubJsonMux, err := s.settingService.GetSubJsonMux() SubJsonMux, err := s.settingService.GetSubJsonMux()
@@ -111,7 +111,7 @@ func (s *Server) initRouter() (*gin.Engine, error) {
s.sub = NewSUBController( s.sub = NewSUBController(
g, LinksPath, JsonPath, Encrypt, ShowInfo, RemarkModel, SubUpdates, g, LinksPath, JsonPath, Encrypt, ShowInfo, RemarkModel, SubUpdates,
SubJsonFragment, SubJsonNoise, SubJsonMux, SubJsonRules) SubJsonFragment, SubJsonNoises, SubJsonMux, SubJsonRules)
return engine, nil return engine, nil
} }

View File

@@ -21,14 +21,14 @@ type SubJsonService struct {
configJson map[string]interface{} configJson map[string]interface{}
defaultOutbounds []json_util.RawMessage defaultOutbounds []json_util.RawMessage
fragment string fragment string
noise string noises string
mux string mux string
inboundService service.InboundService inboundService service.InboundService
SubService *SubService SubService *SubService
} }
func NewSubJsonService(fragment string, noise string, mux string, rules string, subService *SubService) *SubJsonService { func NewSubJsonService(fragment string, noises string, mux string, rules string, subService *SubService) *SubJsonService {
var configJson map[string]interface{} var configJson map[string]interface{}
var defaultOutbounds []json_util.RawMessage var defaultOutbounds []json_util.RawMessage
json.Unmarshal([]byte(defaultJson), &configJson) json.Unmarshal([]byte(defaultJson), &configJson)
@@ -53,15 +53,15 @@ func NewSubJsonService(fragment string, noise string, mux string, rules string,
defaultOutbounds = append(defaultOutbounds, json_util.RawMessage(fragment)) defaultOutbounds = append(defaultOutbounds, json_util.RawMessage(fragment))
} }
if noise != "" { if noises != "" {
defaultOutbounds = append(defaultOutbounds, json_util.RawMessage(noise)) defaultOutbounds = append(defaultOutbounds, json_util.RawMessage(noises))
} }
return &SubJsonService{ return &SubJsonService{
configJson: configJson, configJson: configJson,
defaultOutbounds: defaultOutbounds, defaultOutbounds: defaultOutbounds,
fragment: fragment, fragment: fragment,
noise: noise, noises: noises,
mux: mux, mux: mux,
SubService: subService, SubService: subService,
} }

View File

@@ -851,39 +851,44 @@ Outbound.Settings = class extends CommonClass {
Outbound.FreedomSettings = class extends CommonClass { Outbound.FreedomSettings = class extends CommonClass {
constructor( constructor(
domainStrategy = '', domainStrategy = '',
timeout = '',
redirect = '', redirect = '',
fragment = {}, fragment = {},
noise = {} noises = []
) { ) {
super(); super();
this.domainStrategy = domainStrategy; this.domainStrategy = domainStrategy;
this.timeout = timeout;
this.redirect = redirect; this.redirect = redirect;
this.fragment = fragment; this.fragment = fragment;
this.noise = noise; this.noises = noises;
}
addNoise() {
this.noises.push(new Outbound.FreedomSettings.Noise());
}
delNoise(index) {
this.noises.splice(index, 1);
} }
static fromJson(json = {}) { static fromJson(json = {}) {
return new Outbound.FreedomSettings( return new Outbound.FreedomSettings(
json.domainStrategy, json.domainStrategy,
json.timeout,
json.redirect, json.redirect,
json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : undefined, json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : undefined,
json.noise ? Outbound.FreedomSettings.Noise.fromJson(json.noise) : undefined, json.noises ? json.noises.map(noise => Outbound.FreedomSettings.Noise.fromJson(noise)) : [new Outbound.FreedomSettings.Noise()],
); );
} }
toJson() { toJson() {
return { return {
domainStrategy: ObjectUtil.isEmpty(this.domainStrategy) ? undefined : this.domainStrategy, domainStrategy: ObjectUtil.isEmpty(this.domainStrategy) ? undefined : this.domainStrategy,
timeout: this.timeout,
redirect: this.redirect, redirect: this.redirect,
fragment: Object.keys(this.fragment).length === 0 ? undefined : this.fragment, fragment: Object.keys(this.fragment).length === 0 ? undefined : this.fragment,
noise: Object.keys(this.noise).length === 0 ? undefined : this.noise, noises: Outbound.FreedomSettings.Noise.toJsonArray(this.noises),
}; };
} }
}; };
Outbound.FreedomSettings.Fragment = class extends CommonClass { Outbound.FreedomSettings.Fragment = class extends CommonClass {
constructor(packets = '1-3', length = '', interval = '') { constructor(packets = '1-3', length = '', interval = '') {
super(); super();
@@ -900,19 +905,38 @@ Outbound.FreedomSettings.Fragment = class extends CommonClass {
); );
} }
}; };
Outbound.FreedomSettings.Noise = class extends CommonClass { Outbound.FreedomSettings.Noise = class extends CommonClass {
constructor(packet = '', delay = '') { constructor(
type = 'rand',
packet = '10-20',
delay = '10-16'
) {
super(); super();
this.type = type;
this.packet = packet; this.packet = packet;
this.delay = delay; this.delay = delay;
} }
static fromJson(json = {}) { static fromJson(json = {}) {
return new Outbound.FreedomSettings.Noise( return new Outbound.FreedomSettings.Noise(
json.type,
json.packet, json.packet,
json.delay, json.delay,
); );
} }
toJson() {
return {
type: this.type,
packet: this.packet,
delay: this.delay,
};
}
static toJsonArray(noises) {
return noises.map(noise => noise.toJson());
}
}; };
Outbound.BlackholeSettings = class extends CommonClass { Outbound.BlackholeSettings = class extends CommonClass {
@@ -934,11 +958,19 @@ Outbound.BlackholeSettings = class extends CommonClass {
} }
}; };
Outbound.DNSSettings = 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(); super();
this.network = network; this.network = network;
this.address = address; this.address = address;
this.port = port; this.port = port;
this.nonIPQuery = nonIPQuery;
this.blockTypes = blockTypes;
} }
static fromJson(json = {}) { static fromJson(json = {}) {
@@ -946,6 +978,8 @@ Outbound.DNSSettings = class extends CommonClass {
json.network, json.network,
json.address, json.address,
json.port, json.port,
json.nonIPQuery,
json.blockTypes,
); );
} }
}; };

View File

@@ -7,7 +7,7 @@ class AllSetting {
this.webCertFile = ""; this.webCertFile = "";
this.webKeyFile = ""; this.webKeyFile = "";
this.webBasePath = "/"; this.webBasePath = "/";
this.sessionMaxAge = 0; this.sessionMaxAge = 60;
this.pageSize = 50; this.pageSize = 50;
this.expireDiff = 0; this.expireDiff = 0;
this.trafficDiff = 0; this.trafficDiff = 0;
@@ -38,7 +38,7 @@ class AllSetting {
this.subURI = ""; this.subURI = "";
this.subJsonURI = ""; this.subJsonURI = "";
this.subJsonFragment = ""; this.subJsonFragment = "";
this.subJsonNoise = ""; this.subJsonNoises = "";
this.subJsonMux = ""; this.subJsonMux = "";
this.subJsonRules = ""; this.subJsonRules = "";

View File

@@ -529,6 +529,12 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
scMinPostsIntervalMs = "10-50", scMinPostsIntervalMs = "10-50",
noSSEHeader = false, noSSEHeader = false,
xPaddingBytes = "100-1000", xPaddingBytes = "100-1000",
xmux = {
maxConcurrency: 0,
maxConnections: 0,
cMaxReuseTimes: 0,
cMaxLifetimeMs: 0
}
) { ) {
super(); super();
this.path = path; this.path = path;
@@ -539,6 +545,7 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
this.scMinPostsIntervalMs = scMinPostsIntervalMs; this.scMinPostsIntervalMs = scMinPostsIntervalMs;
this.noSSEHeader = noSSEHeader; this.noSSEHeader = noSSEHeader;
this.xPaddingBytes = xPaddingBytes; this.xPaddingBytes = xPaddingBytes;
this.xmux = xmux;
} }
addHeader(name, value) { addHeader(name, value) {
@@ -559,6 +566,7 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
json.scMinPostsIntervalMs, json.scMinPostsIntervalMs,
json.noSSEHeader, json.noSSEHeader,
json.xPaddingBytes, json.xPaddingBytes,
json.xmux,
); );
} }
@@ -572,6 +580,12 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
scMinPostsIntervalMs: this.scMinPostsIntervalMs, scMinPostsIntervalMs: this.scMinPostsIntervalMs,
noSSEHeader: this.noSSEHeader, noSSEHeader: this.noSSEHeader,
xPaddingBytes: this.xPaddingBytes, xPaddingBytes: this.xPaddingBytes,
xmux: {
maxConcurrency: this.xmux.maxConcurrency,
maxConnections: this.xmux.maxConnections,
cMaxReuseTimes: this.xmux.cMaxReuseTimes,
cMaxLifetimeMs: this.xmux.cMaxLifetimeMs
}
}; };
} }
} }
@@ -1197,6 +1211,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 { class Inbound extends XrayCommonClass {
constructor( constructor(
port = RandomUtil.randomIntRange(10000, 60000), port = RandomUtil.randomIntRange(10000, 60000),
@@ -1206,6 +1241,7 @@ class Inbound extends XrayCommonClass {
streamSettings = new StreamSettings(), streamSettings = new StreamSettings(),
tag = '', tag = '',
sniffing = new Sniffing(), sniffing = new Sniffing(),
allocate = new Allocate(),
clientStats = '', clientStats = '',
) { ) {
super(); super();
@@ -1216,6 +1252,7 @@ class Inbound extends XrayCommonClass {
this.stream = streamSettings; this.stream = streamSettings;
this.tag = tag; this.tag = tag;
this.sniffing = sniffing; this.sniffing = sniffing;
this.allocate = allocate;
this.clientStats = clientStats; this.clientStats = clientStats;
} }
getClientStats() { getClientStats() {
@@ -1406,6 +1443,7 @@ class Inbound extends XrayCommonClass {
this.stream = new StreamSettings(); this.stream = new StreamSettings();
this.tag = ''; this.tag = '';
this.sniffing = new Sniffing(); this.sniffing = new Sniffing();
this.allocate = new Allocate();
} }
genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) { genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) {
@@ -1885,6 +1923,7 @@ class Inbound extends XrayCommonClass {
StreamSettings.fromJson(json.streamSettings), StreamSettings.fromJson(json.streamSettings),
json.tag, json.tag,
Sniffing.fromJson(json.sniffing), Sniffing.fromJson(json.sniffing),
Allocate.fromJson(json.allocate),
json.clientStats json.clientStats
) )
} }
@@ -1902,6 +1941,7 @@ class Inbound extends XrayCommonClass {
streamSettings: streamSettings, streamSettings: streamSettings,
tag: this.tag, tag: this.tag,
sniffing: this.sniffing.toJson(), sniffing: this.sniffing.toJson(),
allocate: this.allocate.toJson(),
clientStats: this.clientStats clientStats: this.clientStats
}; };
} }
@@ -2473,15 +2513,13 @@ Inbound.DokodemoSettings = class extends Inbound.Settings {
address, address,
port, port,
network = 'tcp,udp', network = 'tcp,udp',
followRedirect = false, followRedirect = false
timeout = 30
) { ) {
super(protocol); super(protocol);
this.address = address; this.address = address;
this.port = port; this.port = port;
this.network = network; this.network = network;
this.followRedirect = followRedirect; this.followRedirect = followRedirect;
this.timeout = timeout;
} }
static fromJson(json = {}) { static fromJson(json = {}) {
@@ -2491,7 +2529,6 @@ Inbound.DokodemoSettings = class extends Inbound.Settings {
json.port, json.port,
json.network, json.network,
json.followRedirect, json.followRedirect,
json.timeout,
); );
} }
@@ -2501,7 +2538,6 @@ Inbound.DokodemoSettings = class extends Inbound.Settings {
port: this.port, port: this.port,
network: this.network, network: this.network,
followRedirect: this.followRedirect, followRedirect: this.followRedirect,
timeout: this.timeout,
}; };
} }
}; };
@@ -2561,9 +2597,14 @@ Inbound.SocksSettings.SocksAccount = class extends XrayCommonClass {
}; };
Inbound.HttpSettings = class extends Inbound.Settings { Inbound.HttpSettings = class extends Inbound.Settings {
constructor(protocol, accounts = [new Inbound.HttpSettings.HttpAccount()]) { constructor(
protocol,
accounts = [new Inbound.HttpSettings.HttpAccount()],
allowTransparent = false,
) {
super(protocol); super(protocol);
this.accounts = accounts; this.accounts = accounts;
this.allowTransparent = allowTransparent;
} }
addAccount(account) { addAccount(account) {
@@ -2578,12 +2619,14 @@ Inbound.HttpSettings = class extends Inbound.Settings {
return new Inbound.HttpSettings( return new Inbound.HttpSettings(
Protocols.HTTP, Protocols.HTTP,
json.accounts.map(account => Inbound.HttpSettings.HttpAccount.fromJson(account)), json.accounts.map(account => Inbound.HttpSettings.HttpAccount.fromJson(account)),
json.allowTransparent,
); );
} }
toJson() { toJson() {
return { return {
accounts: Inbound.HttpSettings.toJsonArray(this.accounts), accounts: Inbound.HttpSettings.toJsonArray(this.accounts),
allowTransparent: this.allowTransparent,
}; };
} }
}; };

View File

@@ -83,10 +83,6 @@ func (a *IndexController) login(c *gin.Context) {
logger.Warning("Unable to get session's max age from DB") logger.Warning("Unable to get session's max age from DB")
} }
if sessionMaxAge <= 0 {
sessionMaxAge = 60
}
err = session.SetMaxAge(c, sessionMaxAge*60) err = session.SetMaxAge(c, sessionMaxAge*60)
if err != nil { if err != nil {
logger.Warning("Unable to set session's max age") logger.Warning("Unable to set session's max age")

View File

@@ -42,12 +42,12 @@ func jsonMsgObj(c *gin.Context, msg string, obj interface{}, err error) {
if err == nil { if err == nil {
m.Success = true m.Success = true
if msg != "" { if msg != "" {
m.Msg = msg + I18nWeb(c, "success") m.Msg = msg + " " + I18nWeb(c, "success")
} }
} else { } else {
m.Success = false m.Success = false
m.Msg = msg + I18nWeb(c, "fail") + ": " + err.Error() m.Msg = msg + " " + I18nWeb(c, "fail") + ": " + err.Error()
logger.Warning(msg+I18nWeb(c, "fail")+": ", err) logger.Warning(msg+" "+I18nWeb(c, "fail")+": ", err)
} }
c.JSON(http.StatusOK, m) c.JSON(http.StatusOK, m)
} }

View File

@@ -52,7 +52,7 @@ type AllSetting struct {
SubJsonPath string `json:"subJsonPath" form:"subJsonPath"` SubJsonPath string `json:"subJsonPath" form:"subJsonPath"`
SubJsonURI string `json:"subJsonURI" form:"subJsonURI"` SubJsonURI string `json:"subJsonURI" form:"subJsonURI"`
SubJsonFragment string `json:"subJsonFragment" form:"subJsonFragment"` SubJsonFragment string `json:"subJsonFragment" form:"subJsonFragment"`
SubJsonNoise string `json:"subJsonNoise" form:"subJsonNoise"` SubJsonNoises string `json:"subJsonNoises" form:"subJsonNoises"`
SubJsonMux string `json:"subJsonMux" form:"subJsonMux"` SubJsonMux string `json:"subJsonMux" form:"subJsonMux"`
SubJsonRules string `json:"subJsonRules" form:"subJsonRules"` SubJsonRules string `json:"subJsonRules" form:"subJsonRules"`
Datepicker string `json:"datepicker" form:"datepicker"` Datepicker string `json:"datepicker" form:"datepicker"`

View File

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

View File

@@ -28,7 +28,7 @@
<a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2"> <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-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
</a-form-item> </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 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-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
</a-select> </a-select>

View File

@@ -1,5 +1,7 @@
{{define "dnsModal"}} {{define "dnsModal"}}
<a-modal id="dns-modal" v-model="dnsModal.visible" :title="dnsModal.title" @ok="dnsModal.ok" :closable="true" :mask-closable="false" :ok-text="dnsModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme"> <a-modal id="dns-modal" v-model="dnsModal.visible" :title="dnsModal.title" @ok="dnsModal.ok" :closable="true"
:mask-closable="false" :ok-text="dnsModal.okText" cancel-text='{{ i18n "close" }}'
:class="themeSwitcher.currentTheme">
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }"> <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
<a-form-item label='{{ i18n "pages.xray.outbound.address" }}'> <a-form-item label='{{ i18n "pages.xray.outbound.address" }}'>
<a-input v-model.trim="dnsModal.dnsServer.address"></a-input> <a-input v-model.trim="dnsModal.dnsServer.address"></a-input>
@@ -8,18 +10,29 @@
<a-button icon="plus" size="small" type="primary" @click="dnsModal.dnsServer.domains.push('')"></a-button> <a-button icon="plus" size="small" type="primary" @click="dnsModal.dnsServer.domains.push('')"></a-button>
<template v-for="(domain, index) in dnsModal.dnsServer.domains"> <template v-for="(domain, index) in dnsModal.dnsServer.domains">
<a-input v-model.trim="dnsModal.dnsServer.domains[index]"> <a-input v-model.trim="dnsModal.dnsServer.domains[index]">
<a-button icon="minus" size="small" slot="addonAfter" @click="dnsModal.dnsServer.domains.splice(index,1)"></a-button> <a-button icon="minus" size="small" slot="addonAfter"
@click="dnsModal.dnsServer.domains.splice(index,1)"></a-button>
</a-input> </a-input>
</template> </template>
</a-form-item> </a-form-item>
<a-form-item label='{{ i18n "pages.xray.dns.strategy" }}' v-if="isAdvanced"> <a-form-item label='{{ i18n "pages.xray.dns.strategy" }}' v-if="isAdvanced">
<a-select v-model="dnsModal.dnsServer.queryStrategy" style="width: 100%" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="dnsModal.dnsServer.queryStrategy" style="width: 100%"
:dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option :value="l" :label="l" v-for="l in ['UseIP', 'UseIPv4', 'UseIPv6']"> [[ l ]] </a-select-option> <a-select-option :value="l" :label="l" v-for="l in ['UseIP', 'UseIPv4', 'UseIPv6']"> [[ l ]] </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label='Skip Fallback' v-if="isAdvanced"> <a-form-item label='Skip Fallback' v-if="isAdvanced">
<a-switch v-model="dnsModal.dnsServer.skipFallback"></a-switch> <a-switch v-model="dnsModal.dnsServer.skipFallback"></a-switch>
</a-form-item> </a-form-item>
<a-form-item label='{{ i18n "pages.xray.dns.expectIPs"}}'>
<a-button icon="plus" size="small" type="primary" @click="dnsModal.dnsServer.expectIPs.push('')"></a-button>
<template v-for="(domain, index) in dnsModal.dnsServer.expectIPs">
<a-input v-model.trim="dnsModal.dnsServer.expectIPs[index]">
<a-button icon="minus" size="small" slot="addonAfter"
@click="dnsModal.dnsServer.expectIPs.splice(index,1)"></a-button>
</a-input>
</template>
</a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>
<script> <script>
@@ -32,20 +45,24 @@
dnsServer: { dnsServer: {
address: "localhost", address: "localhost",
domains: [], domains: [],
expectIPs: [],
queryStrategy: 'UseIP', queryStrategy: 'UseIP',
skipFallback: true, skipFallback: true,
}, },
ok() { ok() {
domains = dnsModal.dnsServer.domains.filter(d => d.length > 0); domains = dnsModal.dnsServer.domains.filter(d => d.length > 0);
expectIPs = dnsModal.dnsServer.expectIPs.filter(ip => ip.length > 0);
dnsModal.dnsServer.domains = domains; dnsModal.dnsServer.domains = domains;
newDnsServer = domains.length > 0 ? dnsModal.dnsServer : dnsModal.dnsServer.address; dnsModal.dnsServer.expectIPs = expectIPs;
newDnsServer = (domains.length > 0 || expectIPs.length > 0) ? dnsModal.dnsServer : dnsModal.dnsServer.address;
ObjectUtil.execute(dnsModal.confirm, newDnsServer); ObjectUtil.execute(dnsModal.confirm, newDnsServer);
}, },
show({ show({
title = '', title = '',
okText = '{{ i18n "confirm" }}', okText = '{{ i18n "confirm" }}',
dnsServer, dnsServer,
confirm = (dnsServer) => {}, confirm = (dnsServer) => { },
isEdit = false isEdit = false
}) { }) {
this.title = title; this.title = title;
@@ -59,6 +76,7 @@
this.dnsServer = { this.dnsServer = {
address: dnsServer ?? "", address: dnsServer ?? "",
domains: [], domains: [],
expectIPs: [],
queryStrategy: 'UseIP', queryStrategy: 'UseIP',
skipFallback: true, skipFallback: true,
} }
@@ -67,6 +85,7 @@
this.dnsServer = { this.dnsServer = {
address: "localhost", address: "localhost",
domains: [], domains: [],
expectIPs: [],
queryStrategy: 'UseIP', queryStrategy: 'UseIP',
skipFallback: true, skipFallback: true,
} }
@@ -85,8 +104,8 @@
}, },
computed: { computed: {
isAdvanced: { isAdvanced: {
get: function() { get: function () {
return dnsModal.dnsServer.domains.length > 0 return dnsModal.dnsServer.domains.length > 0;
} }
} }
} }

View File

@@ -0,0 +1,15 @@
{{define "form/allocate"}}
<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}}

View File

@@ -39,7 +39,7 @@
</template> </template>
<a-input v-model.trim="client.id"></a-input> <a-input v-model.trim="client.id"></a-input>
</a-form-item> </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 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-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
</a-select> </a-select>
@@ -104,7 +104,7 @@
</a-textarea> </a-textarea>
</a-form> </a-form>
</a-form-item> </a-form-item>
<a-form-item v-if="inbound.xtls" label='Flow'> <a-form-item v-if="inbound.stream.isXtls" label='Flow'>
<a-select v-model="client.flow" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="client.flow" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option> <a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option> <a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>

View File

@@ -115,7 +115,19 @@
</template> </template>
<!-- sniffing --> <!-- sniffing -->
<template> <a-collapse>
{{template "form/sniffing"}} <a-collapse-panel header='Sniffing'>
</template> {{template "form/sniffing"}}
</a-collapse-panel>
</a-collapse>
<!-- allocate -->
<!-- Temporarily disabled until we accepts range for port allocation
<a-collapse>
<a-collapse-panel header='Allocate'>
{{template "form/allocate"}}
</a-collapse-panel>
</a-collapse>
-->
{{end}} {{end}}

View File

@@ -22,9 +22,6 @@
<a-select-option v-for="s in OutboundDomainStrategies" :value="s">[[ s ]]</a-select-option> <a-select-option v-for="s in OutboundDomainStrategies" :value="s">[[ s ]]</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label='Timeout'>
<a-input-number v-model.number="outbound.settings.timeout" min="0" ></a-input-number>
</a-form-item>
<a-form-item label='Redirect'> <a-form-item label='Redirect'>
<a-input v-model="outbound.settings.redirect"></a-input> <a-input v-model="outbound.settings.redirect"></a-input>
</a-form-item> </a-form-item>
@@ -46,16 +43,39 @@
<a-input v-model.trim="outbound.settings.fragment.interval"></a-input> <a-input v-model.trim="outbound.settings.fragment.interval"></a-input>
</a-form-item> </a-form-item>
</template> </template>
<a-form-item label='Noise'>
<a-switch :checked="Object.keys(outbound.settings.noise).length >0" @change="checked => outbound.settings.noise = checked ? new Outbound.FreedomSettings.Noise() : {}"></a-switch> <!-- Switch for Noises -->
<a-form-item label='Noises'>
<a-switch :checked="outbound.settings.noises.length > 0"
@change="checked => outbound.settings.noises = checked ? [new Outbound.FreedomSettings.Noise()] : []">
</a-switch>
</a-form-item> </a-form-item>
<template v-if="Object.keys(outbound.settings.noise).length >0">
<a-form-item label='Packet'> <!-- Add Noise Button -->
<a-input v-model.trim="outbound.settings.noise.packet"></a-input> <template v-if="outbound.settings.noises.length > 0">
</a-form-item> <a-form-item label="Noises">
<a-form-item label='Delay'> <a-button icon="plus" type="primary" size="small" @click="outbound.settings.addNoise()"></a-button>
<a-input v-model.trim="outbound.settings.noise.delay"></a-input>
</a-form-item> </a-form-item>
<!-- Noise Configurations -->
<a-form v-for="(noise, index) in outbound.settings.noises" :key="index" :colon="false" :label-col="{ md: {span:8} }"
:wrapper-col="{ md: {span:14} }">
<a-divider style="margin:0;"> Noise [[ index + 1 ]]
<a-icon v-if="outbound.settings.noises.length > 1" type="delete" @click="() => outbound.settings.delNoise(index)"
style="color: rgb(255, 77, 79); cursor: pointer;"></a-icon>
</a-divider>
<a-form-item label='Type'>
<a-select v-model="noise.type" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="s in ['rand','base64','str']" :value="s">[[ s ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label='Packet'>
<a-input v-model.trim="noise.packet"></a-input>
</a-form-item>
<a-form-item label='Delay'>
<a-input v-model.trim="noise.delay"></a-input>
</a-form-item>
</a-form>
</template> </template>
</template> </template>
@@ -75,6 +95,14 @@
<a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option> <a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option>
</a-select> </a-select>
</a-form-item> </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> </template>
<!-- wireguard settings --> <!-- wireguard settings -->
@@ -179,11 +207,15 @@
<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>
</a-form-item> </a-form-item>
<a-form-item label='Security'>
<a-select v-model="outbound.settings.security" :dropdown-class-name="themeSwitcher.currentTheme"> <!-- vmess settings -->
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option> <template v-if="outbound.protocol === Protocols.VMess">
</a-select> <a-form-item label='Security'>
</a-form-item> <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 --> <!-- vless settings -->
<template v-if="outbound.canEnableTlsFlow()"> <template v-if="outbound.canEnableTlsFlow()">

View File

@@ -16,8 +16,5 @@
<a-form-item label='Follow Redirect'> <a-form-item label='Follow Redirect'>
<a-switch v-model="inbound.settings.followRedirect"></a-switch> <a-switch v-model="inbound.settings.followRedirect"></a-switch>
</a-form-item> </a-form-item>
<a-form-item label='Timeout'>
<a-input-number v-model.number="inbound.settings.timeout" :min="0"></a-input-number>
</a-form-item>
</a-form> </a-form>
{{end}} {{end}}

View File

@@ -19,5 +19,8 @@
</template> </template>
</a-input> </a-input>
</a-input-group> </a-input-group>
<a-form-item label="Allow Transparent">
<a-switch v-model="inbound.settings.allowTransparent" />
</a-form-item>
</a-form> </a-form>
{{end}} {{end}}

View File

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

View File

@@ -0,0 +1,56 @@
{{define "form/realitySettings"}}
<template>
<a-form-item label='Show'>
<a-switch v-model="inbound.stream.reality.show"></a-switch>
</a-form-item>
<a-form-item label='Xver'>
<a-input-number v-model.number="inbound.stream.reality.xver" :min="0"></a-input-number>
</a-form-item>
<a-form-item label='uTLS'>
<a-select v-model="inbound.stream.reality.settings.fingerprint" style="width: 50%"
:dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label='Dest'>
<a-input v-model.trim="inbound.stream.reality.dest"></a-input>
</a-form-item>
<a-form-item label='SNI'>
<a-input v-model.trim="inbound.stream.reality.serverNames"></a-input>
</a-form-item>
<a-form-item label='Max Time Diff (ms)'>
<a-input-number v-model.number="inbound.stream.reality.maxTimediff" :min="0"></a-input-number>
</a-form-item>
<!-- we also have this but i think it's not necessary
<a-form-item label='Min Client'>
<a-input v-model.trim="inbound.stream.reality.minClient"></a-input>
</a-form-item>
<a-form-item label='Max Client'>
<a-input v-model.trim="inbound.stream.reality.maxClient"></a-input>
</a-form-item>
-->
<a-form-item>
<template slot="label">
<a-tooltip>
<template slot="title">
<span>{{ i18n "reset" }}</span>
</template> Short IDs <a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortIds()"
type="sync"></a-icon>
</a-tooltip>
</template>
<a-input v-model.trim="inbound.stream.reality.shortIds"></a-input>
</a-form-item>
<a-form-item label='SpiderX'>
<a-input v-model.trim="inbound.stream.reality.settings.spiderX"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.privatekey" }}'>
<a-input v-model.trim="inbound.stream.reality.privateKey"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
<a-input v-model.trim="inbound.stream.reality.settings.publicKey"></a-input>
</a-form-item>
<a-form-item label=" ">
<a-button type="primary" icon="import" @click="getNewX25519Cert">Get New Cert</a-button>
</a-form-item>
</template>
{{end}}

View File

@@ -1,9 +1,8 @@
{{define "form/sniffing"}} {{define "form/sniffing"}}
<a-divider style="margin:5px 0 0;"></a-divider>
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }"> <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
<a-form-item> <a-form-item>
<span slot="label"> <span slot="label">
Sniffing {{ i18n "enabled" }}
<a-tooltip> <a-tooltip>
<template slot="title"> <template slot="title">
<span>{{ i18n "pages.inbounds.noRecommendKeepDefault" }}</span> <span>{{ i18n "pages.inbounds.noRecommendKeepDefault" }}</span>

View File

@@ -4,7 +4,7 @@
<a-form-item label='{{ i18n "transmission" }}'> <a-form-item label='{{ i18n "transmission" }}'>
<a-select v-model="inbound.stream.network" style="width: 75%" @change="streamNetworkChange" <a-select v-model="inbound.stream.network" style="width: 75%" @change="streamNetworkChange"
:dropdown-class-name="themeSwitcher.currentTheme"> :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="tcp">TCP</a-select-option> <a-select-option value="tcp">TCP (RAW)</a-select-option>
<a-select-option value="kcp">mKCP</a-select-option> <a-select-option value="kcp">mKCP</a-select-option>
<a-select-option value="ws">WebSocket</a-select-option> <a-select-option value="ws">WebSocket</a-select-option>
<a-select-option value="http">H2</a-select-option> <a-select-option value="http">H2</a-select-option>

View File

@@ -34,5 +34,17 @@
<a-form-item label="No SSE Header"> <a-form-item label="No SSE Header">
<a-switch v-model="inbound.stream.splithttp.noSSEHeader"></a-switch> <a-switch v-model="inbound.stream.splithttp.noSSEHeader"></a-switch>
</a-form-item> </a-form-item>
<a-form-item label="Max Concurrency">
<a-input-number v-model="inbound.stream.splithttp.xmux.maxConcurrency"></a-input-number>
</a-form-item>
<a-form-item label="Max Connections">
<a-input-number v-model="inbound.stream.splithttp.xmux.maxConnections"></a-input-number>
</a-form-item>
<a-form-item label="Max Reuse Times">
<a-input-number v-model="inbound.stream.splithttp.xmux.cMaxReuseTimes"></a-input-number>
</a-form-item>
<a-form-item label="Max Lifetime (ms)">
<a-input-number v-model="inbound.stream.splithttp.xmux.cMaxLifetimeMs"></a-input-number>
</a-form-item>
</a-form> </a-form>
{{end}} {{end}}

View File

@@ -34,16 +34,19 @@
</a-form-item> </a-form-item>
<a-form-item label="Min/Max Version"> <a-form-item label="Min/Max Version">
<a-input-group compact> <a-input-group compact>
<a-select v-model="inbound.stream.tls.minVersion" style="width: 50%" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="inbound.stream.tls.minVersion" style="width: 50%"
:dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in TLS_VERSION_OPTION" :value="key">[[ key ]]</a-select-option> <a-select-option v-for="key in TLS_VERSION_OPTION" :value="key">[[ key ]]</a-select-option>
</a-select> </a-select>
<a-select v-model="inbound.stream.tls.maxVersion" style="width: 50%" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="inbound.stream.tls.maxVersion" style="width: 50%"
:dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in TLS_VERSION_OPTION" :value="key">[[ key ]]</a-select-option> <a-select-option v-for="key in TLS_VERSION_OPTION" :value="key">[[ key ]]</a-select-option>
</a-select> </a-select>
</a-input-group> </a-input-group>
</a-form-item> </a-form-item>
<a-form-item label="uTLS"> <a-form-item label="uTLS">
<a-select v-model="inbound.stream.tls.settings.fingerprint" style="width: 50%" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="inbound.stream.tls.settings.fingerprint" style="width: 50%"
:dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value=''>None</a-select-option> <a-select-option value=''>None</a-select-option>
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option> <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
</a-select> </a-select>
@@ -71,8 +74,10 @@
<a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath" }}</a-radio-button> <a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath" }}</a-radio-button>
<a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent" }}</a-radio-button> <a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent" }}</a-radio-button>
</a-radio-group> </a-radio-group>
<a-button icon="plus" v-if="index === 0" type="primary" size="small" @click="inbound.stream.tls.addCert()" style="margin-left: 10px"></a-button> <a-button icon="plus" v-if="index === 0" type="primary" size="small" @click="inbound.stream.tls.addCert()"
<a-button icon="minus" v-if="inbound.stream.tls.certs.length>1" type="primary" size="small" @click="inbound.stream.tls.removeCert(index)" style="margin-left: 10px"></a-button> style="margin-left: 10px"></a-button>
<a-button icon="minus" v-if="inbound.stream.tls.certs.length>1" type="primary" size="small"
@click="inbound.stream.tls.removeCert(index)" style="margin-left: 10px"></a-button>
</a-form-item> </a-form-item>
<template v-if="cert.useFile"> <template v-if="cert.useFile">
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'> <a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
@@ -82,7 +87,8 @@
<a-input v-model.trim="cert.keyFile"></a-input> <a-input v-model.trim="cert.keyFile"></a-input>
</a-form-item> </a-form-item>
<a-form-item label=" "> <a-form-item label=" ">
<a-button type="primary" icon="import" @click="setDefaultCertData(index)">{{ i18n "pages.inbounds.setDefaultCert" }}</a-button> <a-button type="primary" icon="import" @click="setDefaultCertData(index)">
{{ i18n "pages.inbounds.setDefaultCert" }}</a-button>
</a-form-item> </a-form-item>
</template> </template>
<template v-else> <template v-else>
@@ -111,101 +117,13 @@
</template> </template>
<!-- xtls settings --> <!-- xtls settings -->
<template v-else-if="inbound.xtls"> <template v-else-if="inbound.stream.isXtls">
<a-form-item label="SNI" placeholder="Server Name Indication"> {{template "form/xtlsSettings"}}
<a-input v-model.trim="inbound.stream.xtls.sni"></a-input>
</a-form-item>
<a-form-item label="ALPN">
<a-select mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme" v-model="inbound.stream.xtls.alpn">
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Allow Insecure">
<a-switch v-model="inbound.stream.xtls.settings.allowInsecure"></a-switch>
</a-form-item>
<template v-for="cert,index in inbound.stream.xtls.certs">
<a-form-item label='{{ i18n "certificate" }}'>
<a-radio-group v-model="cert.useFile" button-style="solid">
<a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath" }}</a-radio-button>
<a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent" }}</a-radio-button>
</a-radio-group>
<a-button icon="plus" v-if="index === 0" type="primary" size="small" @click="inbound.stream.xtls.addCert()" style="margin-left: 10px"></a-button>
<a-button icon="minus" v-if="inbound.stream.xtls.certs.length>1" type="primary" size="small" @click="inbound.stream.xtls.removeCert(index)" style="margin-left: 10px"></a-button>
</a-form-item>
<template v-if="cert.useFile">
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
<a-input v-model.trim="cert.certFile"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.privatekey" }}'>
<a-input v-model.trim="cert.keyFile"></a-input>
</a-form-item>
<a-form-item label=" ">
<a-button type="primary" icon="import" @click="setDefaultCertXtls(index)">{{ i18n "pages.inbounds.setDefaultCert" }}</a-button>
</a-form-item>
</template>
<template v-else>
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
<a-input type="textarea" :rows="3" v-model="cert.cert"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.privatekey" }}'>
<a-input type="textarea" :rows="3" v-model="cert.key"></a-input>
</a-form-item>
</template>
<a-form-item label='OCSP stapling'>
<a-input-number v-model.number="cert.ocspStapling" :min="0"></a-input-number>
</a-form-item>
<a-form-item label="One Time Loading">
<a-switch v-model="cert.oneTimeLoading"></a-switch>
</a-form-item>
<a-form-item label='Usage Option'>
<a-select v-model="cert.usage" style="width: 50%" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in USAGE_OPTION" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
</template>
</template> </template>
<!-- reality settings --> <!-- reality settings -->
<template v-if="inbound.stream.isReality"> <template v-if="inbound.stream.isReality">
<a-form-item label='Show'> {{template "form/realitySettings"}}
<a-switch v-model="inbound.stream.reality.show"></a-switch>
</a-form-item>
<a-form-item label='Xver'>
<a-input-number v-model.number="inbound.stream.reality.xver" :min="0"></a-input-number>
</a-form-item>
<a-form-item label='uTLS'>
<a-select v-model="inbound.stream.reality.settings.fingerprint" style="width: 50%" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label='Dest'>
<a-input v-model.trim="inbound.stream.reality.dest"></a-input>
</a-form-item>
<a-form-item label='SNI'>
<a-input v-model.trim="inbound.stream.reality.serverNames"></a-input>
</a-form-item>
<a-form-item>
<template slot="label">
<a-tooltip>
<template slot="title">
<span>{{ i18n "reset" }}</span>
</template> Short IDs <a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortIds()" type="sync"></a-icon>
</a-tooltip>
</template>
<a-input v-model.trim="inbound.stream.reality.shortIds"></a-input>
</a-form-item>
<a-form-item label='SpiderX'>
<a-input v-model.trim="inbound.stream.reality.settings.spiderX"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.privatekey" }}'>
<a-input v-model.trim="inbound.stream.reality.privateKey"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
<a-input v-model.trim="inbound.stream.reality.settings.publicKey"></a-input>
</a-form-item>
<a-form-item label=" ">
<a-button type="primary" icon="import" @click="getNewX25519Cert">Get New Cert</a-button>
</a-form-item>
</template> </template>
</a-form> </a-form>
{{end}} {{end}}

View File

@@ -0,0 +1,58 @@
{{define "form/xtlsSettings"}}
<template>
<a-form-item label="SNI" placeholder="Server Name Indication">
<a-input v-model.trim="inbound.stream.xtls.sni"></a-input>
</a-form-item>
<a-form-item label="ALPN">
<a-select mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme" v-model="inbound.stream.xtls.alpn">
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Allow Insecure">
<a-switch v-model="inbound.stream.xtls.settings.allowInsecure"></a-switch>
</a-form-item>
<template v-for="cert,index in inbound.stream.xtls.certs">
<a-form-item label='{{ i18n "certificate" }}'>
<a-radio-group v-model="cert.useFile" button-style="solid">
<a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath" }}</a-radio-button>
<a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent" }}</a-radio-button>
</a-radio-group>
<a-button icon="plus" v-if="index === 0" type="primary" size="small" @click="inbound.stream.xtls.addCert()"
style="margin-left: 10px"></a-button>
<a-button icon="minus" v-if="inbound.stream.xtls.certs.length>1" type="primary" size="small"
@click="inbound.stream.xtls.removeCert(index)" style="margin-left: 10px"></a-button>
</a-form-item>
<template v-if="cert.useFile">
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
<a-input v-model.trim="cert.certFile"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.privatekey" }}'>
<a-input v-model.trim="cert.keyFile"></a-input>
</a-form-item>
<a-form-item label=" ">
<a-button type="primary" icon="import" @click="setDefaultCertXtls(index)">
{{ i18n "pages.inbounds.setDefaultCert" }}</a-button>
</a-form-item>
</template>
<template v-else>
<a-form-item label='{{ i18n "pages.inbounds.publicKey" }}'>
<a-input type="textarea" :rows="3" v-model="cert.cert"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.privatekey" }}'>
<a-input type="textarea" :rows="3" v-model="cert.key"></a-input>
</a-form-item>
</template>
<a-form-item label='OCSP stapling'>
<a-input-number v-model.number="cert.ocspStapling" :min="0"></a-input-number>
</a-form-item>
<a-form-item label="One Time Loading">
<a-switch v-model="cert.oneTimeLoading"></a-switch>
</a-form-item>
<a-form-item label='Usage Option'>
<a-select v-model="cert.usage" style="width: 50%" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in USAGE_OPTION" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
</template>
</template>
{{end}}

View File

@@ -139,6 +139,12 @@
<a-tag>[[ infoModal.clientSettings.id ]]</a-tag> <a-tag>[[ infoModal.clientSettings.id ]]</a-tag>
</td> </td>
</tr> </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()"> <tr v-if="infoModal.inbound.canEnableTlsFlow()">
<td>Flow</td> <td>Flow</td>
<td v-if="infoModal.clientSettings.flow"> <td v-if="infoModal.clientSettings.flow">

View File

@@ -733,7 +733,7 @@
this.inbounds.push(to_inbound); this.inbounds.push(to_inbound);
this.dbInbounds.push(dbInbound); this.dbInbounds.push(dbInbound);
if ([Protocols.VMESS, Protocols.VLESS, Protocols.TROJAN, Protocols.SHADOWSOCKS].includes(inbound.protocol)) { if ([Protocols.VMESS, Protocols.VLESS, Protocols.TROJAN, Protocols.SHADOWSOCKS].includes(inbound.protocol)) {
if (inbound.protocol === Protocols.SHADOWSOCKS && (!to_inbound.isSSMultiUser)) { if (dbInbound.isSS && (!to_inbound.isSSMultiUser)) {
continue; continue;
} }
this.clientCount[inbound.id] = this.getClientCounts(inbound, to_inbound); this.clientCount[inbound.id] = this.getClientCounts(inbound, to_inbound);
@@ -935,6 +935,7 @@
settings: Inbound.Settings.getSettings(baseInbound.protocol).toString(), settings: Inbound.Settings.getSettings(baseInbound.protocol).toString(),
streamSettings: baseInbound.stream.toString(), streamSettings: baseInbound.stream.toString(),
sniffing: baseInbound.sniffing.toString(), sniffing: baseInbound.sniffing.toString(),
allocate: baseInbound.allocate.toString(),
}; };
await this.submit('/panel/inbound/add', data, inModal); await this.submit('/panel/inbound/add', data, inModal);
}, },
@@ -980,6 +981,7 @@
}; };
if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString(); if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString();
data.sniffing = inbound.sniffing.toString(); data.sniffing = inbound.sniffing.toString();
data.allocate = inbound.allocate.toString();
await this.submit('/panel/inbound/add', data, inModal); await this.submit('/panel/inbound/add', data, inModal);
}, },
@@ -999,6 +1001,7 @@
}; };
if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString(); if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString();
data.sniffing = inbound.sniffing.toString(); data.sniffing = inbound.sniffing.toString();
data.allocate = inbound.allocate.toString();
await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal); await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal);
}, },

View File

@@ -138,7 +138,7 @@
<setting-list-item type="text" title='{{ i18n "pages.settings.publicKeyPath"}}' desc='{{ i18n "pages.settings.publicKeyPathDesc"}}' v-model="allSetting.webCertFile"></setting-list-item> <setting-list-item type="text" title='{{ i18n "pages.settings.publicKeyPath"}}' desc='{{ i18n "pages.settings.publicKeyPathDesc"}}' v-model="allSetting.webCertFile"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.privateKeyPath"}}' desc='{{ i18n "pages.settings.privateKeyPathDesc"}}' v-model="allSetting.webKeyFile"></setting-list-item> <setting-list-item type="text" title='{{ i18n "pages.settings.privateKeyPath"}}' desc='{{ i18n "pages.settings.privateKeyPathDesc"}}' v-model="allSetting.webKeyFile"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.panelUrlPath"}}' desc='{{ i18n "pages.settings.panelUrlPathDesc"}}' v-model="allSetting.webBasePath"></setting-list-item> <setting-list-item type="text" title='{{ i18n "pages.settings.panelUrlPath"}}' desc='{{ i18n "pages.settings.panelUrlPathDesc"}}' v-model="allSetting.webBasePath"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.sessionMaxAge" }}' desc='{{ i18n "pages.settings.sessionMaxAgeDesc" }}' v-model="allSetting.sessionMaxAge" :min="0"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.sessionMaxAge" }}' desc='{{ i18n "pages.settings.sessionMaxAgeDesc" }}' v-model="allSetting.sessionMaxAge" :min="60"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.pageSize" }}' desc='{{ i18n "pages.settings.pageSizeDesc" }}' v-model="allSetting.pageSize" :min="0" :step="5"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.pageSize" }}' desc='{{ i18n "pages.settings.pageSizeDesc" }}' v-model="allSetting.pageSize" :min="0" :step="5"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.expireTimeDiff" }}' desc='{{ i18n "pages.settings.expireTimeDiffDesc" }}' v-model="allSetting.expireDiff" :min="0"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.expireTimeDiff" }}' desc='{{ i18n "pages.settings.expireTimeDiffDesc" }}' v-model="allSetting.expireDiff" :min="0"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.trafficDiff" }}' desc='{{ i18n "pages.settings.trafficDiffDesc" }}' v-model="allSetting.trafficDiff" :min="0"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.trafficDiff" }}' desc='{{ i18n "pages.settings.trafficDiffDesc" }}' v-model="allSetting.trafficDiff" :min="0"></setting-list-item>
@@ -305,20 +305,38 @@
<a-list-item style="padding: 20px"> <a-list-item style="padding: 20px">
<a-row> <a-row>
<a-col :lg="24" :xl="12"> <a-col :lg="24" :xl="12">
<a-list-item-meta title='Noise'> <a-list-item-meta title='Noises'>
<template slot="description">{{ i18n "pages.settings.noiseDesc"}}</template> <template slot="description">{{ i18n "pages.settings.noisesDesc"}}</template>
</a-list-item-meta> </a-list-item-meta>
</a-col> </a-col>
<a-col :lg="24" :xl="12"> <a-col :lg="24" :xl="12">
<a-switch v-model="noise"></a-switch> <a-switch v-model="noises"></a-switch>
</a-col> </a-col>
</a-row> </a-row>
<a-collapse v-if="noise" style="margin-top: 14px;"> <a-collapse v-if="noises" style="margin-top: 14px;">
<a-collapse-panel header='{{ i18n "pages.settings.noiseSett"}}' v-if="noise"> <a-collapse-panel v-for="(noise, index) in noisesArray" :key="index" :header="`Noise ${index + 1}`">
<setting-list-item style="padding: 10px 20px" type="text" title='Packet (ms)' v-model="noisePacket" placeholder="rand:5-10"></setting-list-item> <a-list-item style="padding: 10px 20px">
<setting-list-item style="padding: 10px 20px" type="text" title='Delay (ms)' v-model="noiseDelay" placeholder="10-20"></setting-list-item> <a-row>
<a-col :lg="24" :xl="12">
<a-list-item-meta title='Type'></a-list-item-meta>
</a-col>
<a-col :lg="24" :xl="12">
<a-select :value="noise.type" style="width: 100%" :dropdown-class-name="themeSwitcher.currentTheme"
@change="(value) => updateNoiseType(index, value)">
<a-select-option :value="p" :label="p" v-for="p in ['rand', 'base64', 'str']" :key="p">
[[ p ]] </a-select-option>
</a-select>
</a-col>
</a-row>
</a-list-item>
<setting-list-item style="padding: 10px 20px" type="text" title='Packet' :value="noise.packet"
@input="(value) => updateNoisePacket(index, value)" placeholder="5-10"></setting-list-item>
<setting-list-item style="padding: 10px 20px" type="text" title='Delay (ms)' :value="noise.delay"
@input="(value) => updateNoiseDelay(index, value)" placeholder="10-20"></setting-list-item>
<a-button v-if="noisesArray.length > 1" type="danger" @click="removeNoise(index)">Remove</a-button>
</a-collapse-panel> </a-collapse-panel>
</a-collapse> </a-collapse>
<a-button v-if="noises" type="primary" @click="addNoise" style="margin-top: 10px">Add Noise</a-button>
</a-list-item> </a-list-item>
<a-list-item style="padding: 20px"> <a-list-item style="padding: 20px">
<a-row> <a-row>
@@ -362,9 +380,14 @@
</a-col> </a-col>
</a-row> </a-row>
<a-collapse v-if="enableDirect" style="margin-top: 14px;"> <a-collapse v-if="enableDirect" style="margin-top: 14px;">
<a-collapse-panel header='{{ i18n "pages.settings.directSett"}}'> <a-collapse-panel header='{{ i18n "pages.xray.directips"}}'>
<a-list-item style="padding: 10px 20px"> <a-list-item style="padding: 10px 20px">
<a-checkbox-group v-model="directCountries" name="Countries" :options="countryOptions"></a-checkbox-group> <a-checkbox-group v-model="geoIP" :options="geoIPOptions"></a-checkbox-group>
</a-list-item>
</a-collapse-panel>
<a-collapse-panel header='{{ i18n "pages.xray.directdomains"}}'>
<a-list-item style="padding: 10px 20px">
<a-checkbox-group v-model="geoSite" :options="geoSiteOptions"></a-checkbox-group>
</a-list-item> </a-list-item>
</a-collapse-panel> </a-collapse-panel>
</a-collapse> </a-collapse>
@@ -419,15 +442,14 @@
} }
} }
}, },
defaultNoise: { defaultNoises: {
tag: "noise", tag: "noises",
protocol: "freedom", protocol: "freedom",
settings: { settings: {
domainStrategy: "AsIs", domainStrategy: "AsIs",
noise: { noises: [
packet: "rand:5-10", { type: "rand", packet: "10-20", delay: "10-16" },
delay: "10-20", ],
}
}, },
}, },
defaultMux: { defaultMux: {
@@ -441,8 +463,7 @@
type: "field", type: "field",
outboundTag: "direct", outboundTag: "direct",
domain: [ domain: [
"geosite:category-ir", "geosite:category-ir"
"geosite:cn"
], ],
"enabled": true "enabled": true
}, },
@@ -451,17 +472,30 @@
outboundTag: "direct", outboundTag: "direct",
ip: [ ip: [
"geoip:private", "geoip:private",
"geoip:ir", "geoip:ir"
"geoip:cn"
], ],
enabled: true enabled: true
}, },
], ],
countryOptions: [ geoIPOptions: [
{ label: 'Private IP/Domain', value: 'private' }, { label: 'Private IP', value: 'private' },
{ label: '🇮🇷 Iran', value: 'ir' }, { label: '🇮🇷 Iran', value: 'ir' },
{ label: '🇨🇳 China', value: 'cn' }, { label: '🇨🇳 China', value: 'cn' },
{ label: '🇷🇺 Russia', value: 'ru' }, { label: '🇷🇺 Russia', value: 'ru' },
{ label: '🇻🇳 Vietnam', value: 'vn' },
{ label: '🇪🇸 Spain', value: 'es' },
{ label: '🇮🇩 Indonesia', value: 'id' },
{ label: '🇺🇦 Ukraine', value: 'ua' },
{ label: '🇹🇷 Türkiye', value: 'tr' },
{ label: '🇧🇷 Brazil', value: 'br' },
],
geoSiteOptions: [
{ label: '🇮🇷 Iran', value: 'ir' },
{ label: '🇨🇳 China', value: 'cn' },
{ label: '🇷🇺 Russia', value: 'ru' },
{ label: 'Apple', value: 'apple' },
{ label: 'Meta', value: 'meta' },
{ label: 'Google', value: 'google' },
], ],
get remarkModel() { get remarkModel() {
rm = this.allSetting.remarkModel; rm = this.allSetting.remarkModel;
@@ -591,6 +625,30 @@
this.user.loginSecret = ""; this.user.loginSecret = "";
} }
}, },
addNoise() {
const newNoise = { type: "rand", packet: "10-20", delay: "10-16" };
this.noisesArray = [...this.noisesArray, newNoise];
},
removeNoise(index) {
const newNoises = [...this.noisesArray];
newNoises.splice(index, 1);
this.noisesArray = newNoises;
},
updateNoiseType(index, value) {
const updatedNoises = [...this.noisesArray];
updatedNoises[index] = { ...updatedNoises[index], type: value };
this.noisesArray = updatedNoises;
},
updateNoisePacket(index, value) {
const updatedNoises = [...this.noisesArray];
updatedNoises[index] = { ...updatedNoises[index], packet: value };
this.noisesArray = updatedNoises;
},
updateNoiseDelay(index, value) {
const updatedNoises = [...this.noisesArray];
updatedNoises[index] = { ...updatedNoises[index], delay: value };
this.noisesArray = updatedNoises;
},
}, },
computed: { computed: {
fragment: { fragment: {
@@ -629,29 +687,27 @@
} }
} }
}, },
noise: { noises: {
get: function () { return this.allSetting?.subJsonNoise != ""; }, get() {
set: function (v) { return this.allSetting?.subJsonNoises != "";
this.allSetting.subJsonNoise = v ? JSON.stringify(this.defaultNoise) : ""; },
} set(v) {
}, if (v) {
noisePacket: { this.allSetting.subJsonNoises = JSON.stringify(this.defaultNoises);
get: function () { return this.noise ? JSON.parse(this.allSetting.subJsonNoise).settings.noise.packet : ""; }, } else {
set: function (v) { this.allSetting.subJsonNoises = "";
if (v != "") {
newNoise = JSON.parse(this.allSetting.subJsonNoise);
newNoise.settings.noise.packet = v;
this.allSetting.subJsonNoise = JSON.stringify(newNoise);
} }
} }
}, },
noiseDelay: { noisesArray: {
get: function () { return this.noise ? JSON.parse(this.allSetting.subJsonNoise).settings.noise.delay : ""; }, get() {
set: function (v) { return this.noises ? JSON.parse(this.allSetting.subJsonNoises).settings.noises : [];
if (v != "") { },
newNoise = JSON.parse(this.allSetting.subJsonNoise); set(value) {
newNoise.settings.noise.delay = v; if (this.noises) {
this.allSetting.subJsonNoise = JSON.stringify(newNoise); const newNoises = JSON.parse(this.allSetting.subJsonNoises);
newNoises.settings.noises = value;
this.allSetting.subJsonNoises = JSON.stringify(newNoises);
} }
} }
}, },
@@ -691,28 +747,49 @@
this.allSetting.subJsonRules = v ? JSON.stringify(this.defaultRules) : ""; this.allSetting.subJsonRules = v ? JSON.stringify(this.defaultRules) : "";
} }
}, },
directCountries: { geoIP: {
get: function () { get: function () {
if (!this.enableDirect) return []; if (!this.enableDirect) return [];
rules = JSON.parse(this.allSetting.subJsonRules); const rules = JSON.parse(this.allSetting.subJsonRules);
return Array.isArray(rules) ? rules[1].ip.map(d => d.replace("geoip:", "")) : []; return Array.isArray(rules) ? rules[1].ip.map(d => d.replace("geoip:", "")) : [];
}, },
set: function (v) { set: function (v) {
rules = JSON.parse(this.allSetting.subJsonRules); const rules = JSON.parse(this.allSetting.subJsonRules);
if (!Array.isArray(rules)) return; if (!Array.isArray(rules)) return;
rules[0].domain = [];
rules[1].ip = []; rules[1].ip = [];
v.forEach(d => {
rules[1].ip.push("geoip:" + d);
});
this.allSetting.subJsonRules = JSON.stringify(rules);
}
},
geoSite: {
get: function () {
if (!this.enableDirect) return [];
const rules = JSON.parse(this.allSetting.subJsonRules);
return Array.isArray(rules) ?
rules[0].domain.map(d => {
if (d.startsWith("geosite:category-")) {
return d.replace("geosite:category-", "");
}
return d.replace("geosite:", "");
})
: [];
},
set: function (v) {
const rules = JSON.parse(this.allSetting.subJsonRules);
if (!Array.isArray(rules)) return;
rules[0].domain = [];
v.forEach(d => { v.forEach(d => {
let category = ''; let category = '';
if (["cn", "private"].includes(d)) { if (["cn", "apple", "meta", "google"].includes(d)) {
category = ""; category = "";
} else if (d === 'ru') { } else if (["ru", "ir"].includes(d)) {
category = "category-gov-";
} else {
category = "category-"; category = "category-";
} }
rules[0].domain.push("geosite:" + category + d); rules[0].domain.push("geosite:" + category + d);
rules[1].ip.push("geoip:" + d);
}); });
this.allSetting.subJsonRules = JSON.stringify(rules); this.allSetting.subJsonRules = JSON.stringify(rules);
} }

View File

@@ -163,8 +163,8 @@
</a-col> </a-col>
<a-col :lg="24" :xl="12"> <a-col :lg="24" :xl="12">
<template> <template>
<a-select v-model="setLogLevel" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%"> <a-select v-model="logLevel" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%">
<a-select-option v-for="s in logLevel" :value="s">[[ s ]]</a-select-option> <a-select-option v-for="s in log.loglevel" :value="s">[[ s ]]</a-select-option>
</a-select> </a-select>
</template> </template>
</a-col> </a-col>
@@ -178,7 +178,8 @@
<a-col :lg="24" :xl="12"> <a-col :lg="24" :xl="12">
<template> <template>
<a-select v-model="accessLog" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%"> <a-select v-model="accessLog" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%">
<a-select-option v-for="s in access" :key="s" :value="s">[[ s ]]</a-select-option> <a-select-option value=''>Empty</a-select-option>
<a-select-option v-for="s in log.access" :value="s">[[ s ]]</a-select-option>
</a-select> </a-select>
</template> </template>
</a-col> </a-col>
@@ -192,11 +193,28 @@
<a-col :lg="24" :xl="12"> <a-col :lg="24" :xl="12">
<template> <template>
<a-select v-model="errorLog" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%"> <a-select v-model="errorLog" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%">
<a-select-option v-for="s in error" :key="s" :value="s">[[ s ]]</a-select-option> <a-select-option value=''>Empty</a-select-option>
<a-select-option v-for="s in log.error" :value="s">[[ s ]]</a-select-option>
</a-select> </a-select>
</template> </template>
</a-col> </a-col>
</a-row> </a-row>
<a-row style="padding: 10px 20px">
<a-col :lg="24" :xl="12">
<a-list-item-meta title='{{ i18n "pages.xray.maskAddress" }}'
description='{{ i18n "pages.xray.maskAddressDesc" }}'>
</a-list-item-meta>
</a-col>
<a-col :lg="24" :xl="12">
<template>
<a-select v-model="maskAddressLog" :dropdown-class-name="themeSwitcher.currentTheme" style="width: 100%">
<a-select-option value=''>Empty</a-select-option>
<a-select-option v-for="s in log.maskAddress" :value="s">[[ s ]]</a-select-option>
</a-select>
</template>
</a-col>
</a-row>
<setting-list-item type="switch" title='{{ i18n "pages.xray.dnsLog"}}' desc='{{ i18n "pages.xray.dnsLogDesc"}}' v-model="dnslog"></setting-list-item>
</a-list-item> </a-list-item>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel header='{{ i18n "pages.xray.blockConfigs"}}'> <a-collapse-panel header='{{ i18n "pages.xray.blockConfigs"}}'>
@@ -217,44 +235,78 @@
<setting-list-item type="switch" title='{{ i18n "pages.xray.Speedtest"}}' desc='{{ i18n "pages.xray.SpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item> <setting-list-item type="switch" title='{{ i18n "pages.xray.Speedtest"}}' desc='{{ i18n "pages.xray.SpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item>
</a-list-item> </a-list-item>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'> <a-collapse-panel header='{{ i18n "pages.xray.blockConnectionsConfigs"}}'>
<a-row :xs="24" :sm="24" :lg="12"> <a-row :xs="24" :sm="24" :lg="12">
<a-alert type="warning" style="text-align: center;"> <a-alert type="warning" style="text-align: center;">
<template slot="message"> <template slot="message">
<a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon> <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
{{ i18n "pages.xray.blockCountryConfigsDesc" }} {{ i18n "pages.xray.blockConnectionsConfigsDesc" }}
</template> </template>
</a-alert> </a-alert>
</a-row> </a-row>
<a-list-item> <a-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.IRIp"}}' desc='{{ i18n "pages.xray.IRIpDesc"}}' v-model="IRIpSettings"></setting-list-item> <a-collapse>
<setting-list-item type="switch" title='{{ i18n "pages.xray.IRDomain"}}' desc='{{ i18n "pages.xray.IRDomainDesc"}}' v-model="IRDomainSettings"></setting-list-item> <a-collapse-panel header='{{ i18n "pages.xray.blockips"}}'>
<setting-list-item type="switch" title='{{ i18n "pages.xray.ChinaIp"}}' desc='{{ i18n "pages.xray.ChinaIpDesc"}}' v-model="ChinaIpSettings"></setting-list-item> <setting-list-item type="switch" title='🇮🇷 Iran'
<setting-list-item type="switch" title='{{ i18n "pages.xray.ChinaDomain"}}' desc='{{ i18n "pages.xray.ChinaDomainDesc"}}' v-model="ChinaDomainSettings"></setting-list-item> v-model="IRIpSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.RussiaIp"}}' desc='{{ i18n "pages.xray.RussiaIpDesc"}}' v-model="RussiaIpSettings"></setting-list-item> <setting-list-item type="switch" title='🇨🇳 China'
<setting-list-item type="switch" title='{{ i18n "pages.xray.RussiaDomain"}}' desc='{{ i18n "pages.xray.RussiaDomainDesc"}}' v-model="RussiaDomainSettings"></setting-list-item> v-model="ChinaIpSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.VNIp"}}' desc='{{ i18n "pages.xray.VNIpDesc"}}' v-model="VNIpSettings"></setting-list-item> <setting-list-item type="switch" title='🇷🇺 Russia'
<setting-list-item type="switch" title='{{ i18n "pages.xray.VNDomain"}}' desc='{{ i18n "pages.xray.VNDomainDesc"}}' v-model="VNDomainSettings"></setting-list-item> v-model="RussiaIpSettings"></setting-list-item>
<setting-list-item type="switch" title='🇻🇳 Vietnam'
v-model="VNIpSettings"></setting-list-item>
</a-collapse-panel>
</a-collapse>
<br>
<a-collapse>
<a-collapse-panel header='{{ i18n "pages.xray.blockdomains"}}'>
<setting-list-item type="switch" title='🇮🇷 Iran'
v-model="IRDomainSettings"></setting-list-item>
<setting-list-item type="switch" title='🇨🇳 China'
v-model="ChinaDomainSettings"></setting-list-item>
<setting-list-item type="switch" title='🇷🇺 Russia'
v-model="RussiaDomainSettings"></setting-list-item>
<setting-list-item type="switch" title='🇻🇳 Vietnam'
v-model="VNDomainSettings"></setting-list-item>
</a-collapse-panel>
</a-collapse>
</a-list-item> </a-list-item>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel header='{{ i18n "pages.xray.directCountryConfigs"}}'> <a-collapse-panel header='{{ i18n "pages.xray.directConnectionsConfigs"}}'>
<a-row :xs="24" :sm="24" :lg="12"> <a-row :xs="24" :sm="24" :lg="12">
<a-alert type="warning" style="text-align: center;"> <a-alert type="warning" style="text-align: center;">
<template slot="message"> <template slot="message">
<a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon> <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
{{ i18n "pages.xray.directCountryConfigsDesc" }} {{ i18n "pages.xray.directConnectionsConfigsDesc" }}
</template> </template>
</a-alert> </a-alert>
</a-row> </a-row>
<a-list-item> <a-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectIRIp"}}' desc='{{ i18n "pages.xray.DirectIRIpDesc"}}' v-model="IRIpDirectSettings"></setting-list-item> <a-collapse>
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectIRDomain"}}' desc='{{ i18n "pages.xray.DirectIRDomainDesc"}}' v-model="IRDomainDirectSettings"></setting-list-item> <a-collapse-panel header='{{ i18n "pages.xray.directips"}}'>
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectChinaIp"}}' desc='{{ i18n "pages.xray.DirectChinaIpDesc"}}' v-model="ChinaIpDirectSettings"></setting-list-item> <setting-list-item type="switch" title='🇮🇷 Iran'
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectChinaDomain"}}' desc='{{ i18n "pages.xray.DirectChinaDomainDesc"}}' v-model="ChinaDomainDirectSettings"></setting-list-item> v-model="IRIpDirectSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectRussiaIp"}}' desc='{{ i18n "pages.xray.DirectRussiaIpDesc"}}' v-model="RussiaIpDirectSettings"></setting-list-item> <setting-list-item type="switch" title='🇨🇳 China'
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectRussiaDomain"}}' desc='{{ i18n "pages.xray.DirectRussiaDomainDesc"}}' v-model="RussiaDomainDirectSettings"></setting-list-item> v-model="ChinaIpDirectSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectVNIp"}}' desc='{{ i18n "pages.xray.DirectVNIpDesc"}}' v-model="VNIpDirectSettings"></setting-list-item> <setting-list-item type="switch" title='🇷🇺 Russia'
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectVNDomain"}}' desc='{{ i18n "pages.xray.DirectVNDomainDesc"}}' v-model="VNDomainDirectSettings"></setting-list-item> v-model="RussiaIpDirectSettings"></setting-list-item>
<setting-list-item type="switch" title='🇻🇳 Vietnam'
v-model="VNIpDirectSettings"></setting-list-item>
</a-collapse-panel>
</a-collapse>
<br>
<a-collapse>
<a-collapse-panel header='{{ i18n "pages.xray.directdomains"}}'>
<setting-list-item type="switch" title='🇮🇷 Iran'
v-model="IRDomainDirectSettings"></setting-list-item>
<setting-list-item type="switch" title='🇨🇳 China'
v-model="ChinaDomainDirectSettings"></setting-list-item>
<setting-list-item type="switch" title='🇷🇺 Russia'
v-model="RussiaDomainDirectSettings"></setting-list-item>
<setting-list-item type="switch" title='🇻🇳 Vietnam'
v-model="VNDomainDirectSettings"></setting-list-item>
</a-collapse-panel>
</a-collapse>
</a-list-item> </a-list-item>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel header='{{ i18n "pages.xray.ipv4Configs"}}'> <a-collapse-panel header='{{ i18n "pages.xray.ipv4Configs"}}'>
@@ -569,86 +621,90 @@
</a-radio-group> </a-radio-group>
<textarea style="position:absolute; left: -800px;" id="obsSetting"></textarea> <textarea style="position:absolute; left: -800px;" id="obsSetting"></textarea>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="tpl-dns" tab='DNS' style="padding-top: 20px;" force-render="true"> <a-tab-pane key="tpl-dns" tab='DNS' style="padding-top: 20px;" force-render="true">
<setting-list-item type="switch" title='{{ i18n "pages.xray.dns.enable" }}' desc='{{ i18n "pages.xray.dns.enableDesc" }}' v-model="enableDNS"></setting-list-item> <setting-list-item type="switch" title='{{ i18n "pages.xray.dns.enable" }}'
desc='{{ i18n "pages.xray.dns.enableDesc" }}' v-model="enableDNS"></setting-list-item>
<template v-if="enableDNS"> <template v-if="enableDNS">
<setting-list-item style="padding: 10px 20px" type="text" title='{{ i18n "pages.xray.dns.tag" }}' desc='{{ i18n "pages.xray.dns.tagDesc" }}' v-model="dnsTag"></setting-list-item> <setting-list-item style="padding: 10px 20px" type="text" title='{{ i18n "pages.xray.dns.tag" }}'
<a-list-item style="padding: 10px 20px"> desc='{{ i18n "pages.xray.dns.tagDesc" }}' v-model="dnsTag"></setting-list-item>
<a-row> <a-list-item style="padding: 10px 20px">
<a-col :lg="24" :xl="12"> <a-row>
<a-list-item-meta title='{{ i18n "pages.xray.dns.strategy" }}' description='{{ i18n "pages.xray.dns.strategyDesc" }}' /> <a-col :lg="24" :xl="12">
</a-col> <a-list-item-meta title='{{ i18n "pages.xray.dns.strategy" }}'
<a-col :lg="24" :xl="12"> description='{{ i18n "pages.xray.dns.strategyDesc" }}' />
<a-select </a-col>
v-model="dnsStrategy" <a-col :lg="24" :xl="12">
style="width: 100%" <a-select v-model="dnsStrategy" style="width: 100%"
:dropdown-class-name="themeSwitcher.currentTheme"> :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option :value="l" :label="l" v-for="l in ['UseIP', 'UseIPv4', 'UseIPv6']"> <a-select-option :value="l" :label="l" v-for="l in ['UseIP', 'UseIPv4', 'UseIPv6']">
[[ l ]] [[ l ]]
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-col> </a-col>
</a-row> </a-row>
</a-list-item> </a-list-item>
<a-divider>DNS</a-divider> <a-divider>DNS</a-divider>
<a-button type="primary" icon="plus" @click="addDNSServer()" style="margin-bottom: 10px;">{{ i18n "pages.xray.dns.add" }}</a-button> <a-button type="primary" icon="plus" @click="addDNSServer()" style="margin-bottom: 10px;">{{ i18n
<a-table :columns="dnsColumns" bordered v-if="dnsServers.length>0" "pages.xray.dns.add" }}</a-button>
:row-key="r => r.key" <a-table :columns="dnsColumns" bordered v-if="dnsServers.length>0" :row-key="r => r.key"
:data-source="dnsServers" :data-source="dnsServers" :scroll="isMobile ? {} : { x: 200 }" :pagination="false" :indent-size="0"
:scroll="isMobile ? {} : { x: 200 }" :style="isMobile ? 'padding: 5px 0' : 'margin-left: 1px;'">
:pagination="false" <template slot="action" slot-scope="text,dns,index">
:indent-size="0" [[ index+1 ]]
:style="isMobile ? 'padding: 5px 0' : 'margin-left: 1px;'"> <a-dropdown :trigger="['click']">
<template slot="action" slot-scope="text,dns,index"> <a-icon @click="e => e.preventDefault()" type="more"
[[ index+1 ]] style="font-size: 16px; text-decoration: bold;"></a-icon>
<a-dropdown :trigger="['click']"> <a-menu slot="overlay" :theme="themeSwitcher.currentTheme">
<a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon> <a-menu-item @click="editDNSServer(index)">
<a-menu slot="overlay" :theme="themeSwitcher.currentTheme"> <a-icon type="edit"></a-icon>
<a-menu-item @click="editDNSServer(index)"> {{ i18n "edit" }}
<a-icon type="edit"></a-icon> </a-menu-item>
{{ i18n "edit" }} <a-menu-item @click="deleteDNSServer(index)">
</a-menu-item> <span style="color: #FF4D4F">
<a-menu-item @click="deleteDNSServer(index)"> <a-icon type="delete"></a-icon> {{ i18n "delete"}}
<span style="color: #FF4D4F"> </span>
<a-icon type="delete"></a-icon> {{ i18n "delete"}} </a-menu-item>
</span> </a-menu>
</a-menu-item> </a-dropdown>
</a-menu> </template>
</a-dropdown> <template slot="address" slot-scope="dns,index">
</template> <span v-if="typeof dns == 'object'">[[ dns.address ]]</span>
<template slot="address" slot-scope="dns,index"> <span v-else>[[ dns ]]</span>
<span v-if="typeof dns == 'object'">[[ dns.address ]]</span> </template>
<span v-else>[[ dns ]]</span> <template slot="domain" slot-scope="dns,index">
</template> <span v-if="typeof dns == 'object'">[[ dns.domains.join(",") ]]</span>
<template slot="domain" slot-scope="dns,index"> </template>
<span v-if="typeof dns == 'object'">[[ dns.domains.join(",") ]]</span> <template slot="expectIPs" slot-scope="dns,index">
</template> <span v-if="typeof dns == 'object'">[[ dns.expectIPs.join(",") ]]</span>
</a-table> </template>
<a-divider>Fake DNS</a-divider> </a-table>
<a-button type="primary" icon="plus" @click="addFakedns()" style="margin-bottom: 10px;">{{ i18n "pages.xray.fakedns.add" }}</a-button> <a-divider>Fake DNS</a-divider>
<a-table :columns="fakednsColumns" bordered v-if="fakeDns && fakeDns.length>0" :row-key="r => r.key" <a-button type="primary" icon="plus" @click="addFakedns()" style="margin-bottom: 10px;">{{ i18n
:data-source="fakeDns" :scroll="isMobile ? {} : { x: 200 }" :pagination="false" :indent-size="0" "pages.xray.fakedns.add" }}</a-button>
:style="isMobile ? 'padding: 5px 0' : 'margin-left: 1px;'"> <a-table :columns="fakednsColumns" bordered v-if="fakeDns && fakeDns.length>0" :row-key="r => r.key"
<template slot="action" slot-scope="text,fakedns,index"> :data-source="fakeDns" :scroll="isMobile ? {} : { x: 200 }" :pagination="false" :indent-size="0"
[[ index+1 ]] :style="isMobile ? 'padding: 5px 0' : 'margin-left: 1px;'">
<a-dropdown :trigger="['click']"> <template slot="action" slot-scope="text,fakedns,index">
<a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon> [[ index+1 ]]
<a-menu slot="overlay" :theme="themeSwitcher.currentTheme"> <a-dropdown :trigger="['click']">
<a-menu-item @click="editFakedns(index)"> <a-icon @click="e => e.preventDefault()" type="more"
<a-icon type="edit"></a-icon> style="font-size: 16px; text-decoration: bold;"></a-icon>
{{ i18n "edit" }} <a-menu slot="overlay" :theme="themeSwitcher.currentTheme">
</a-menu-item> <a-menu-item @click="editFakedns(index)">
<a-menu-item @click="deleteFakedns(index)"> <a-icon type="edit"></a-icon>
<span style="color: #FF4D4F"> {{ i18n "edit" }}
<a-icon type="delete"></a-icon> {{ i18n "delete"}} </a-menu-item>
</span> <a-menu-item @click="deleteFakedns(index)">
</a-menu-item> <span style="color: #FF4D4F">
</a-menu> <a-icon type="delete"></a-icon> {{ i18n "delete"}}
</a-dropdown> </span>
</template> </a-menu-item>
</a-table> </a-menu>
</a-dropdown>
</template>
</a-table>
</template> </template>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="tpl-advanced" tab='{{ i18n "pages.xray.advancedTemplate"}}' style="padding-top: 20px;" force-render="true"> <a-tab-pane key="tpl-advanced" tab='{{ i18n "pages.xray.advancedTemplate"}}' style="padding-top: 20px;" force-render="true">
<a-list-item-meta title='{{ i18n "pages.xray.Template"}}' description='{{ i18n "pages.xray.TemplateDesc"}}'></a-list-item-meta> <a-list-item-meta title='{{ i18n "pages.xray.Template"}}' description='{{ i18n "pages.xray.TemplateDesc"}}'></a-list-item-meta>
<a-radio-group v-model="advSettings" @change="changeCode" button-style="solid" style="margin: 10px 0;" :size="isMobile ? 'small' : ''"> <a-radio-group v-model="advSettings" @change="changeCode" button-style="solid" style="margin: 10px 0;" :size="isMobile ? 'small' : ''">
@@ -730,6 +786,7 @@
{ title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } }, { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
{ title: '{{ i18n "pages.xray.outbound.address"}}', align: 'center', width: 50, scopedSlots: { customRender: 'address' } }, { title: '{{ i18n "pages.xray.outbound.address"}}', align: 'center', width: 50, scopedSlots: { customRender: 'address' } },
{ title: '{{ i18n "pages.xray.dns.domains"}}', align: 'center', width: 50, scopedSlots: { customRender: 'domain' } }, { title: '{{ i18n "pages.xray.dns.domains"}}', align: 'center', width: 50, scopedSlots: { customRender: 'domain' } },
{ title: '{{ i18n "pages.xray.dns.expectIPs"}}', align: 'center', width: 50, scopedSlots: { customRender: 'expectIPs' } },
]; ];
const fakednsColumns = [ const fakednsColumns = [
@@ -791,9 +848,13 @@
protocol: "freedom" protocol: "freedom"
}, },
routingDomainStrategies: ["AsIs", "IPIfNonMatch", "IPOnDemand"], routingDomainStrategies: ["AsIs", "IPIfNonMatch", "IPOnDemand"],
logLevel: ["none" , "debug" , "info" , "warning", "error"], log: {
access: [], loglevel: ["none", "debug", "info", "warning", "error"],
error: [], access: ["none", "./access.log"],
error: ["none", "./error.log"],
dnsLog: false,
maskAddress: ["quarter", "half", "full"],
},
settingsData: { settingsData: {
protocols: { protocols: {
bittorrent: ["bittorrent"], bittorrent: ["bittorrent"],
@@ -824,17 +885,19 @@
apple: ["geosite:apple"], apple: ["geosite:apple"],
reddit: ["geosite:reddit"], reddit: ["geosite:reddit"],
cn: [ cn: [
"geosite:cn", "regexp:.*\\.cn$",
"regexp:.*\\.cn$" "geosite:cn"
], ],
ru: [ ru: [
"geosite:category-gov-ru", "regexp:.*\\.ru$",
"regexp:.*\\.ru$" "geosite:category-ru" //https://github.com/v2fly/domain-list-community/blob/master/data/category-ru
], ],
ir: [ ir: [
"regexp:.*\\.ir$", "regexp:.*\\.ir$",
"regexp:.*\\.xn--mgba3a4f16a$", // .ایران "ext:geosite_IR.dat:ir",
"ext:geosite_IR.dat:ir" "geosite:category-ir", // https://github.com/v2fly/domain-list-community/blob/master/data/category-ir
"regexp:.*\\.xn--mgba3a4f16a$" // .ایران
], ],
vn: [ vn: [
"regexp:.*\\.vn$", "regexp:.*\\.vn$",
@@ -1519,27 +1582,11 @@
templateSettings: { templateSettings: {
get: function () { get: function () {
const parsedSettings = this.xraySetting ? JSON.parse(this.xraySetting) : null; const parsedSettings = this.xraySetting ? JSON.parse(this.xraySetting) : null;
let accessLogPath = "./access.log";
let errorLogPath = "./error.log";
if (parsedSettings && parsedSettings.log) {
if (parsedSettings.log.access && parsedSettings.log.access !== "none") {
accessLogPath = parsedSettings.log.access;
}
if (parsedSettings.log.error && parsedSettings.log.error !== "none") {
errorLogPath = parsedSettings.log.error;
}
}
this.access = ["none", accessLogPath];
this.error = ["none", errorLogPath];
return parsedSettings; return parsedSettings;
}, },
set: function (newValue) { set: function (newValue) {
if (newValue && newValue.log) { if (newValue) {
this.xraySetting = JSON.stringify(newValue, null, 2); this.xraySetting = JSON.stringify(newValue, null, 2);
this.access = ["none", newValue.log.access || "./access.log"];
this.error = ["none", newValue.log.error || "./error.log"];
} }
}, },
}, },
@@ -1688,7 +1735,7 @@
this.templateSettings = newTemplateSettings; this.templateSettings = newTemplateSettings;
} }
}, },
setLogLevel: { logLevel: {
get: function () { get: function () {
if (!this.templateSettings || !this.templateSettings.log || !this.templateSettings.log.loglevel) return "warning"; if (!this.templateSettings || !this.templateSettings.log || !this.templateSettings.log.loglevel) return "warning";
return this.templateSettings.log.loglevel; return this.templateSettings.log.loglevel;
@@ -1721,6 +1768,28 @@
this.templateSettings = newTemplateSettings; this.templateSettings = newTemplateSettings;
} }
}, },
dnslog: {
get: function () {
if (!this.templateSettings || !this.templateSettings.log || !this.templateSettings.log.dnsLog) return false;
return this.templateSettings.log.dnsLog;
},
set: function (newValue) {
newTemplateSettings = this.templateSettings;
newTemplateSettings.log.dnsLog = newValue;
this.templateSettings = newTemplateSettings;
}
},
maskAddressLog: {
get: function () {
if (!this.templateSettings || !this.templateSettings.log || !this.templateSettings.log.maskAddress) return "";
return this.templateSettings.log.maskAddress;
},
set: function (newValue) {
newTemplateSettings = this.templateSettings;
newTemplateSettings.log.maskAddress = newValue;
this.templateSettings = newTemplateSettings;
}
},
blockedIPs: { blockedIPs: {
get: function () { get: function () {
return this.templateRuleGetter({ outboundTag: "blocked", property: "ip" }); return this.templateRuleGetter({ outboundTag: "blocked", property: "ip" });

View File

@@ -36,17 +36,12 @@ func (j *CheckClientIpJob) Run() {
} }
shouldClearAccessLog := false shouldClearAccessLog := false
f2bInstalled := j.checkFail2BanInstalled() iplimitActive := j.hasLimitIp()
isAccessLogAvailable := j.checkAccessLogAvailable() f2bInstalled := j.checkFail2BanInstalled(iplimitActive)
isAccessLogAvailable := j.checkAccessLogAvailable(iplimitActive)
if j.hasLimitIp() { if iplimitActive && f2bInstalled && isAccessLogAvailable {
if f2bInstalled && isAccessLogAvailable { shouldClearAccessLog = j.processLogFile()
shouldClearAccessLog = j.processLogFile()
} else {
if !f2bInstalled {
logger.Warning("[iplimit] fail2ban is not installed. IP limiting may not work properly.")
}
}
} }
if shouldClearAccessLog || (isAccessLogAvailable && time.Now().Unix()-j.lastClear > 3600) { if shouldClearAccessLog || (isAccessLogAvailable && time.Now().Unix()-j.lastClear > 3600) {
@@ -123,7 +118,7 @@ func (j *CheckClientIpJob) processLogFile() bool {
line := scanner.Text() line := scanner.Text()
ipRegx, _ := regexp.Compile(`from \[?([0-9a-fA-F:.]+)\]?:\d+ accepted`) ipRegx, _ := regexp.Compile(`from \[?([0-9a-fA-F:.]+)\]?:\d+ accepted`)
emailRegx, _ := regexp.Compile(`email:.+`) emailRegx, _ := regexp.Compile(`email: (\S+)$`)
matches := ipRegx.FindStringSubmatch(line) matches := ipRegx.FindStringSubmatch(line)
if len(matches) > 1 { if len(matches) > 1 {
@@ -136,7 +131,7 @@ func (j *CheckClientIpJob) processLogFile() bool {
if matchesEmail == "" { if matchesEmail == "" {
continue continue
} }
matchesEmail = strings.TrimSpace(strings.Split(matchesEmail, "email: ")[1]) matchesEmail = strings.Split(matchesEmail, "email: ")[1]
if InboundClientIps[matchesEmail] != nil { if InboundClientIps[matchesEmail] != nil {
if j.contains(InboundClientIps[matchesEmail], ip) { if j.contains(InboundClientIps[matchesEmail], ip) {
@@ -167,26 +162,33 @@ func (j *CheckClientIpJob) processLogFile() bool {
return shouldCleanLog return shouldCleanLog
} }
func (j *CheckClientIpJob) checkFail2BanInstalled() bool { func (j *CheckClientIpJob) checkFail2BanInstalled(iplimitActive bool) bool {
cmd := "fail2ban-client" cmd := "fail2ban-client"
args := []string{"-h"} args := []string{"-h"}
err := exec.Command(cmd, args...).Run() err := exec.Command(cmd, args...).Run()
return err == nil
if iplimitActive && err != nil {
logger.Warning("[LimitIP] Fail2Ban is not installed, Please install Fail2Ban from the x-ui bash menu.")
return false
}
return true
} }
func (j *CheckClientIpJob) checkAccessLogAvailable() bool { func (j *CheckClientIpJob) checkAccessLogAvailable(iplimitActive bool) bool {
isAvailable := true
accessLogPath, err := xray.GetAccessLogPath() accessLogPath, err := xray.GetAccessLogPath()
if err != nil { if err != nil {
return false return false
} }
switch accessLogPath { if accessLogPath == "none" || accessLogPath == "" {
case "none", "": if iplimitActive {
isAvailable = false logger.Warning("[LimitIP] Access log path is not set, Please configure the access log path in Xray configs.")
}
return false
} }
return isAvailable return true
} }
func (j *CheckClientIpJob) checkError(e error) { func (j *CheckClientIpJob) checkError(e error) {

View File

@@ -2,8 +2,9 @@
"log": { "log": {
"access": "none", "access": "none",
"dnsLog": false, "dnsLog": false,
"error": "./error.log", "error": "",
"loglevel": "warning" "loglevel": "warning",
"maskAddress": ""
}, },
"api": { "api": {
"tag": "api", "tag": "api",

View File

@@ -331,6 +331,7 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
oldInbound.Settings = inbound.Settings oldInbound.Settings = inbound.Settings
oldInbound.StreamSettings = inbound.StreamSettings oldInbound.StreamSettings = inbound.StreamSettings
oldInbound.Sniffing = inbound.Sniffing oldInbound.Sniffing = inbound.Sniffing
oldInbound.Allocate = inbound.Allocate
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" { if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port) oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port)
} else { } else {
@@ -2031,9 +2032,9 @@ func validateEmail(email string) (bool, error) {
return false, errors.New("email contains uppercase letters, please convert to lowercase") return false, errors.New("email contains uppercase letters, please convert to lowercase")
} }
emailPattern := `^[a-z0-9._-]+$` emailPattern := `^[a-z0-9@._-]+$`
if !regexp.MustCompile(emailPattern).MatchString(email) { if !regexp.MustCompile(emailPattern).MatchString(email) {
return false, errors.New("email contains invalid characters, please use only lowercase letters, digits, dots, dashes, and underscores") return false, errors.New("email contains invalid characters, please use only lowercase letters, digits, and @._-")
} }
return true, nil return true, nil

View File

@@ -32,7 +32,7 @@ var defaultValueMap = map[string]string{
"webKeyFile": "", "webKeyFile": "",
"secret": random.Seq(32), "secret": random.Seq(32),
"webBasePath": "/", "webBasePath": "/",
"sessionMaxAge": "0", "sessionMaxAge": "60",
"pageSize": "50", "pageSize": "50",
"expireDiff": "0", "expireDiff": "0",
"trafficDiff": "0", "trafficDiff": "0",
@@ -62,7 +62,7 @@ var defaultValueMap = map[string]string{
"subJsonPath": "/json/", "subJsonPath": "/json/",
"subJsonURI": "", "subJsonURI": "",
"subJsonFragment": "", "subJsonFragment": "",
"subJsonNoise": "", "subJsonNoises": "",
"subJsonMux": "", "subJsonMux": "",
"subJsonRules": "", "subJsonRules": "",
"datepicker": "gregorian", "datepicker": "gregorian",
@@ -459,8 +459,8 @@ func (s *SettingService) GetSubJsonFragment() (string, error) {
return s.getString("subJsonFragment") return s.getString("subJsonFragment")
} }
func (s *SettingService) GetSubJsonNoise() (string, error) { func (s *SettingService) GetSubJsonNoises() (string, error) {
return s.getString("subJsonNoise") return s.getString("subJsonNoises")
} }
func (s *SettingService) GetSubJsonMux() (string, error) { func (s *SettingService) GetSubJsonMux() (string, error) {

View File

@@ -43,8 +43,8 @@
"domainName" = "Domain Name" "domainName" = "Domain Name"
"monitor" = "Listen IP" "monitor" = "Listen IP"
"certificate" = "Digital Certificate" "certificate" = "Digital Certificate"
"fail" = " Failed" "fail" = "Failed"
"success" = " Successfully" "success" = "Successfully"
"getVersion" = "Get Version" "getVersion" = "Get Version"
"install" = "Install" "install" = "Install"
"clients" = "Clients" "clients" = "Clients"
@@ -143,7 +143,7 @@
"destinationPort" = "Destination Port" "destinationPort" = "Destination Port"
"targetAddress" = "Target Address" "targetAddress" = "Target Address"
"monitorDesc" = "Leave blank to listen on all IPs" "monitorDesc" = "Leave blank to listen on all IPs"
"meansNoLimit" = " = Unlimited. (unit: GB)" "meansNoLimit" = "= Unlimited. (unit: GB)"
"totalFlow" = "Total Flow" "totalFlow" = "Total Flow"
"leaveBlankToNeverExpire" = "Leave blank to never expire" "leaveBlankToNeverExpire" = "Leave blank to never expire"
"noRecommendKeepDefault" = "It is recommended to keep the default" "noRecommendKeepDefault" = "It is recommended to keep the default"
@@ -309,14 +309,14 @@
"fragment" = "Fragmentation" "fragment" = "Fragmentation"
"fragmentDesc" = "Enable fragmentation for TLS hello packet." "fragmentDesc" = "Enable fragmentation for TLS hello packet."
"fragmentSett" = "Fragmentation Settings" "fragmentSett" = "Fragmentation Settings"
"noiseDesc" = "Enable Noise." "noisesDesc" = "Enable Noises."
"noiseSett" = "Noise Settings" "noisesSett" = "Noises Settings"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Transmit multiple independent data streams within an established data stream." "muxDesc" = "Transmit multiple independent data streams within an established data stream."
"muxSett" = "Mux Settings" "muxSett" = "Mux Settings"
"direct" = "Direct Connection" "direct" = "Direct Connection"
"directDesc" = "Directly establishes connections with domains or IP ranges of a specific country." "directDesc" = "Directly establishes connections with domains or IP ranges of a specific country."
"directSett" = "Direct Connection Options"
[pages.xray] [pages.xray]
"title" = "Xray Configs" "title" = "Xray Configs"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Logs may affect your server's efficiency. It is recommended to enable it wisely only in case of your needs" "logConfigsDesc" = "Logs may affect your server's efficiency. It is recommended to enable it wisely only in case of your needs"
"blockConfigs" = "Protection Shield" "blockConfigs" = "Protection Shield"
"blockConfigsDesc" = "These options will block traffic based on specific requested protocols and websites." "blockConfigsDesc" = "These options will block traffic based on specific requested protocols and websites."
"blockCountryConfigs" = "Block Country" "blockConnectionsConfigs" = "Block Connections"
"blockCountryConfigsDesc" = "These options will block traffic based on the specific requested country." "blockConnectionsConfigsDesc" = "These options will block traffic based on the specific requested country."
"directCountryConfigs" = "Direct Country" "directConnectionsConfigs" = "Direct Connections"
"directCountryConfigsDesc" = "A direct connection ensures that specific traffic is not routed through another server." "directConnectionsConfigsDesc" = "A direct connection ensures that specific traffic is not routed through another server."
"blockips" = "Block IPs"
"blockdomains" = "Block Domains"
"directips" = "Direct IPs"
"directdomains" = "Direct Domains"
"ipv4Configs" = "IPv4 Routing" "ipv4Configs" = "IPv4 Routing"
"ipv4ConfigsDesc" = "These options will route traffic based on a specific destination via IPv4." "ipv4ConfigsDesc" = "These options will route traffic based on a specific destination via IPv4."
"warpConfigs" = "WARP Routing" "warpConfigs" = "WARP Routing"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Blocks malware, phishing, and cryptominers websites." "SecurityDesc" = "Blocks malware, phishing, and cryptominers websites."
"Speedtest" = "Block Speedtest" "Speedtest" = "Block Speedtest"
"SpeedtestDesc" = "Blocks establishing connectins to speedtest websites." "SpeedtestDesc" = "Blocks establishing connectins to speedtest websites."
"IRIp" = "Block Connection to Iran IPs"
"IRIpDesc" = "Blocks establishing connections to Iran IP ranges."
"IRDomain" = "Block Connection to Iran Domains"
"IRDomainDesc" = "Blocks establishing connections to Iran domains."
"ChinaIp" = "Block Connection to China IPs"
"ChinaIpDesc" = "Blocks establishing connections to China IP ranges."
"ChinaDomain" = "Block Connection to China Domains"
"ChinaDomainDesc" = "Blocks establishing connections to China domains."
"RussiaIp" = "Block Connection to Russia IPs"
"RussiaIpDesc" = "Blocks establishing connections to Russia IP ranges."
"RussiaDomain" = "Block Connection to Russia Domains"
"RussiaDomainDesc" = "Blocks establishing connections to Russia domains."
"VNIp" = "Block Connection to Vietnam IPs"
"VNIpDesc" = "Blocks establishing connections to Vietnam IP ranges."
"VNDomain" = "Block Connection to Vietnam Domains"
"VNDomainDesc" = "Blocks establishing connections to Vietnam domains."
"DirectIRIp" = "Direct Connection to Iran IPs"
"DirectIRIpDesc" = "Directly establishes connections to Iran IP ranges."
"DirectIRDomain" = "Direct Connection to Iran Domains"
"DirectIRDomainDesc" = "Directly establishes connections to Iran domains."
"DirectChinaIp" = "Direct Connection to China IPs"
"DirectChinaIpDesc" = "Directly establishes connections to China IP ranges."
"DirectChinaDomain" = "Direct Connection to China Domains"
"DirectChinaDomainDesc" = "Directly establishes connections to China domains."
"DirectRussiaIp" = "Direct Connection to Russia IPs"
"DirectRussiaIpDesc" = "Directly establishes connections to Russia IP ranges."
"DirectRussiaDomain" = "Direct Connection to Russia Domains"
"DirectRussiaDomainDesc" = "Directly establishes connections to Russia domains."
"DirectVNIp" = "Direct Connection to Vietnam IPs"
"DirectVNIpDesc" = "Directly establishes connections to Vietnam IP ranges."
"DirectVNDomain" = "Direct Connection to Vietnam Domains"
"DirectVNDomainDesc" = "Directly establishes connections to Vietnam domains."
"GoogleIPv4" = "Google" "GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "Routes traffic to Google via IPv4." "GoogleIPv4Desc" = "Routes traffic to Google via IPv4."
"NetflixIPv4" = "Netflix" "NetflixIPv4" = "Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "The file path for the access log. The special value 'none' disabled access logs" "accessLogDesc" = "The file path for the access log. The special value 'none' disabled access logs"
"errorLog" = "Error Log" "errorLog" = "Error Log"
"errorLogDesc" = "The file path for the error log. The special value 'none' disabled error logs" "errorLogDesc" = "The file path for the error log. The special value 'none' disabled error logs"
"dnsLog" = "DNS Log"
"dnsLogDesc" = "Whether to enable DNS query logs"
"maskAddress" = "Mask Address"
"maskAddressDesc" = "IP address mask, when enabled, will automatically replace the IP address that appears in the log."
[pages.xray.rules] [pages.xray.rules]
"first" = "First" "first" = "First"
@@ -484,6 +460,7 @@
"add" = "Add Server" "add" = "Add Server"
"edit" = "Edit Server" "edit" = "Edit Server"
"domains" = "Domains" "domains" = "Domains"
"expectIPs" = "Expect IPs"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Add Fake DNS" "add" = "Add Fake DNS"

View File

@@ -143,7 +143,7 @@
"destinationPort" = "Puerto de Destino" "destinationPort" = "Puerto de Destino"
"targetAddress" = "Dirección de Destino" "targetAddress" = "Dirección de Destino"
"monitorDesc" = "Dejar en blanco por defecto" "monitorDesc" = "Dejar en blanco por defecto"
"meansNoLimit" = " = illimitata. (unidad: GB)" "meansNoLimit" = "= illimitata. (unidad: GB)"
"totalFlow" = "Flujo Total" "totalFlow" = "Flujo Total"
"leaveBlankToNeverExpire" = "Dejar en Blanco para Nunca Expirar" "leaveBlankToNeverExpire" = "Dejar en Blanco para Nunca Expirar"
"noRecommendKeepDefault" = "No hay requisitos especiales para mantener la configuración predeterminada" "noRecommendKeepDefault" = "No hay requisitos especiales para mantener la configuración predeterminada"
@@ -309,14 +309,14 @@
"fragment" = "Fragmentación" "fragment" = "Fragmentación"
"fragmentDesc" = "Habilitar la fragmentación para el paquete de saludo de TLS" "fragmentDesc" = "Habilitar la fragmentación para el paquete de saludo de TLS"
"fragmentSett" = "Configuración de Fragmentación" "fragmentSett" = "Configuración de Fragmentación"
"noiseDesc" = "Activar Noise." "noisesDesc" = "Activar Noises."
"noiseSett" = "Configuración de Noise" "noisesSett" = "Configuración de Noises"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Transmite múltiples flujos de datos independientes dentro de un flujo de datos establecido." "muxDesc" = "Transmite múltiples flujos de datos independientes dentro de un flujo de datos establecido."
"muxSett" = "Configuración Mux" "muxSett" = "Configuración Mux"
"direct" = "Conexión Directa" "direct" = "Conexión Directa"
"directDesc" = "Establece conexiones directas con dominios o rangos de IP de un país específico." "directDesc" = "Establece conexiones directas con dominios o rangos de IP de un país específico."
"directSett" = "Opciones de Conexión Directa"
[pages.xray] [pages.xray]
"title" = "Xray Configuración" "title" = "Xray Configuración"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Los registros pueden afectar la eficiencia de su servidor. Se recomienda habilitarlos sabiamente solo en caso de sus necesidades." "logConfigsDesc" = "Los registros pueden afectar la eficiencia de su servidor. Se recomienda habilitarlos sabiamente solo en caso de sus necesidades."
"blockConfigs" = "Configuraciones de Bloqueo" "blockConfigs" = "Configuraciones de Bloqueo"
"blockConfigsDesc" = "Estas opciones evitarán que los usuarios se conecten a protocolos y sitios web específicos." "blockConfigsDesc" = "Estas opciones evitarán que los usuarios se conecten a protocolos y sitios web específicos."
"blockCountryConfigs" = "Configuraciones de Bloqueo por País" "blockConnectionsConfigs" = "Bloquear Conexiones"
"blockCountryConfigsDesc" = "Estas opciones evitarán que los usuarios se conecten a dominios de países específicos." "blockConnectionsConfigsDesc" = "Estas opciones bloquearán el tráfico según el país solicitado específico."
"directCountryConfigs" = "Configuraciones de Conexión Directa por País" "directConnectionsConfigs" = "Conexiones Directas"
"directCountryConfigsDesc" = "Una conexión directa asegura que el tráfico específico no se enruta a través de otro servidor." "directConnectionsConfigsDesc" = "Una conexión directa asegura que el tráfico específico no sea enrutado a través de otro servidor."
"blockips" = "Bloquear IPs"
"blockdomains" = "Bloquear Dominios"
"directips" = "IPs Directas"
"directdomains" = "Dominios Directos"
"ipv4Configs" = "Configuraciones IPv4" "ipv4Configs" = "Configuraciones IPv4"
"ipv4ConfigsDesc" = "Estas opciones solo enrutarán a los dominios objetivo a través de IPv4." "ipv4ConfigsDesc" = "Estas opciones solo enrutarán a los dominios objetivo a través de IPv4."
"warpConfigs" = "Configuraciones de WARP" "warpConfigs" = "Configuraciones de WARP"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Cambiar la plantilla de configuración para la protección de seguridad." "SecurityDesc" = "Cambiar la plantilla de configuración para la protección de seguridad."
"Speedtest" = "Bloquear Sitios Web de Pruebas de Velocidad" "Speedtest" = "Bloquear Sitios Web de Pruebas de Velocidad"
"SpeedtestDesc" = "Cambia la plantilla de configuración para evitar la conexión a sitios web de pruebas de velocidad." "SpeedtestDesc" = "Cambia la plantilla de configuración para evitar la conexión a sitios web de pruebas de velocidad."
"IRIp" = "Desactivar Conexión a Rangos de IP de Irán"
"IRIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de Irán."
"IRDomain" = "Desactivar Conexión a Dominios de Irán"
"IRDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de Irán."
"ChinaIp" = "Desactivar Conexión a Rangos de IP de China"
"ChinaIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de China."
"ChinaDomain" = "Desactivar Conexión a Dominios de China"
"ChinaDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de China."
"RussiaIp" = "Desactivar Conexión a Rangos de IP de Rusia"
"RussiaIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de Rusia."
"RussiaDomain" = "Desactivar Conexión a Dominios de Rusia"
"RussiaDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de Rusia."
"VNIp" = "Deshabilitar la conexión a las IP de Vietnam"
"VNIpDesc" = "Cambie la plantilla de configuración para evitar conectarse a rangos de IP de Vietnam."
"VNDomain" = "Deshabilitar la conexión a dominios de Vietnam"
"VNDomainDesc" = "Cambie la plantilla de configuración para evitar conectarse a dominios de Vietnam."
"DirectIRIp" = "Conexión Directa a Rangos de IP de Irán"
"DirectIRIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de Irán."
"DirectIRDomain" = "Conexión Directa a Dominios de Irán"
"DirectIRDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de Irán."
"DirectChinaIp" = "Conexión Directa a Rangos de IP de China"
"DirectChinaIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de China."
"DirectChinaDomain" = "Conexión Directa a Dominios de China"
"DirectChinaDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de China."
"DirectRussiaIp" = "Conexión Directa a Rangos de IP de Rusia"
"DirectRussiaIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de Rusia."
"DirectRussiaDomain" = "Conexión Directa a Dominios de Rusia"
"DirectRussiaDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de Rusia."
"DirectVNIp" = "Conexión directa a IP de Vietnam"
"DirectVNIpDesc" = "Cambie la plantilla de configuración para la conexión directa a rangos de IP de Vietnam."
"DirectVNDomain" = "Conexión directa a dominios de Vietnam"
"DirectVNDomainDesc" = "Cambie la plantilla de configuración para la conexión directa a dominios de Vietnam."
"GoogleIPv4" = "Usar IPv4 para Google" "GoogleIPv4" = "Usar IPv4 para Google"
"GoogleIPv4Desc" = "Agregar enrutamiento para que Google se conecte con IPv4." "GoogleIPv4Desc" = "Agregar enrutamiento para que Google se conecte con IPv4."
"NetflixIPv4" = "Usar IPv4 para Netflix" "NetflixIPv4" = "Usar IPv4 para Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "La ruta del archivo para el registro de acceso. El valor especial 'ninguno' deshabilita los registros de acceso" "accessLogDesc" = "La ruta del archivo para el registro de acceso. El valor especial 'ninguno' deshabilita los registros de acceso"
"errorLog" = "Registro de Errores" "errorLog" = "Registro de Errores"
"errorLogDesc" = "La ruta del archivo para el registro de errores. El valor especial 'none' desactiva los registros de errores." "errorLogDesc" = "La ruta del archivo para el registro de errores. El valor especial 'none' desactiva los registros de errores."
"dnsLog" = "Registro DNS"
"dnsLogDesc" = "Si habilitar los registros de consulta DNS"
"maskAddress" = "Enmascarar Dirección"
"maskAddressDesc" = "Máscara de dirección IP, cuando se habilita, reemplazará automáticamente la dirección IP que aparece en el registro."
[pages.xray.rules] [pages.xray.rules]
"first" = "Primero" "first" = "Primero"
@@ -482,6 +458,7 @@
"add" = "Agregar Servidor" "add" = "Agregar Servidor"
"edit" = "Editar Servidor" "edit" = "Editar Servidor"
"domains" = "Dominios" "domains" = "Dominios"
"expectIPs" = "IPs esperadas"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Agregar DNS Falso" "add" = "Agregar DNS Falso"
@@ -591,7 +568,7 @@
"confirmResetTraffic" = "✅ ¿Confirmar Reinicio de Tráfico?" "confirmResetTraffic" = "✅ ¿Confirmar Reinicio de Tráfico?"
"confirmClearIps" = "✅ ¿Confirmar Limpiar IPs?" "confirmClearIps" = "✅ ¿Confirmar Limpiar IPs?"
"confirmRemoveTGUser" = "✅ ¿Confirmar Eliminar Usuario de Telegram?" "confirmRemoveTGUser" = "✅ ¿Confirmar Eliminar Usuario de Telegram?"
"confirmToggle" = " ✅ ¿Confirmar habilitar/deshabilitar usuario?" "confirmToggle" = "✅ ¿Confirmar habilitar/deshabilitar usuario?"
"dbBackup" = "Obtener Copia de Seguridad de BD" "dbBackup" = "Obtener Copia de Seguridad de BD"
"serverUsage" = "Uso del Servidor" "serverUsage" = "Uso del Servidor"
"getInbounds" = "Obtener Entradas" "getInbounds" = "Obtener Entradas"

View File

@@ -44,7 +44,7 @@
"monitor" = "آی‌پی اتصال" "monitor" = "آی‌پی اتصال"
"certificate" = "گواهی دیجیتال" "certificate" = "گواهی دیجیتال"
"fail" = "ناموفق" "fail" = "ناموفق"
"success" = " موفق" "success" = "موفق"
"getVersion" = "دریافت نسخه" "getVersion" = "دریافت نسخه"
"install" = "نصب" "install" = "نصب"
"clients" = "کاربران" "clients" = "کاربران"
@@ -109,7 +109,7 @@
"backup" = "پشتیبان‌گیری" "backup" = "پشتیبان‌گیری"
"backupTitle" = "پشتیبان‌گیری دیتابیس" "backupTitle" = "پشتیبان‌گیری دیتابیس"
"backupDescription" = "توصیه‌می‌شود قبل‌از واردکردن یک دیتابیس جدید، نسخه پشتیبان تهیه ‌کنید" "backupDescription" = "توصیه‌می‌شود قبل‌از واردکردن یک دیتابیس جدید، نسخه پشتیبان تهیه ‌کنید"
"exportDatabase" = " پشتیبان‌گیری" "exportDatabase" = "پشتیبان‌گیری"
"importDatabase" = "بازگرداندن" "importDatabase" = "بازگرداندن"
[pages.inbounds] [pages.inbounds]
@@ -285,7 +285,7 @@
"timeZoneDesc" = "وظایف برنامه ریزی شده بر اساس این منطقه‌زمانی اجرا می‌شود" "timeZoneDesc" = "وظایف برنامه ریزی شده بر اساس این منطقه‌زمانی اجرا می‌شود"
"subSettings" = "سابسکریپشن" "subSettings" = "سابسکریپشن"
"subEnable" = "فعال‌سازی سرویس سابسکریپشن" "subEnable" = "فعال‌سازی سرویس سابسکریپشن"
"subEnableDesc" = " سرویس سابسکریپشن‌ را فعال‌می‌کند" "subEnableDesc" = "سرویس سابسکریپشن‌ را فعال‌می‌کند"
"subListen" = "آدرس آی‌پی" "subListen" = "آدرس آی‌پی"
"subListenDesc" = "آدرس آی‌پی برای سرویس سابسکریپشن. برای گوش دادن به‌تمام آی‌پی‌ها خالی‌بگذارید" "subListenDesc" = "آدرس آی‌پی برای سرویس سابسکریپشن. برای گوش دادن به‌تمام آی‌پی‌ها خالی‌بگذارید"
"subPort" = "پورت" "subPort" = "پورت"
@@ -309,14 +309,14 @@
"fragment" = "فرگمنت" "fragment" = "فرگمنت"
"fragmentDesc" = "فعال کردن فرگمنت برای بسته‌ی نخست تی‌ال‌اس" "fragmentDesc" = "فعال کردن فرگمنت برای بسته‌ی نخست تی‌ال‌اس"
"fragmentSett" = "تنظیمات فرگمنت" "fragmentSett" = "تنظیمات فرگمنت"
"noiseDesc" = "فعال کردن Noise." "noisesDesc" = "فعال کردن Noises."
"noiseSett" = "تنظیمات Noise" "noisesSett" = "تنظیمات Noises"
"mux" = "ماکس" "mux" = "ماکس"
"muxDesc" = "چندین جریان داده مستقل را در یک جریان داده ثابت منتقل می کند" "muxDesc" = "چندین جریان داده مستقل را در یک جریان داده ثابت منتقل می کند"
"muxSett" = "تنظیمات ماکس" "muxSett" = "تنظیمات ماکس"
"direct" = "اتصال مستقیم" "direct" = "اتصال مستقیم"
"directDesc" = "به طور مستقیم با دامنه ها یا محدوده آی‌پی یک کشور خاص ارتباط برقرار می کند" "directDesc" = "به طور مستقیم با دامنه ها یا محدوده آی‌پی یک کشور خاص ارتباط برقرار می کند"
"directSett" = "گزینه های اتصال مستقیم"
[pages.xray] [pages.xray]
"title" = "پیکربندی ایکس‌ری" "title" = "پیکربندی ایکس‌ری"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "گزارش‌ها ممکن است بر کارایی سرور شما تأثیر بگذارد. توصیه می شود فقط در صورت نیاز آن را عاقلانه فعال کنید" "logConfigsDesc" = "گزارش‌ها ممکن است بر کارایی سرور شما تأثیر بگذارد. توصیه می شود فقط در صورت نیاز آن را عاقلانه فعال کنید"
"blockConfigs" = "سپر محافظ" "blockConfigs" = "سپر محافظ"
"blockConfigsDesc" = "این گزینه‌ها ترافیک را بر اساس پروتکل‌های درخواستی خاص، و وب سایت‌ها مسدود می‌کند" "blockConfigsDesc" = "این گزینه‌ها ترافیک را بر اساس پروتکل‌های درخواستی خاص، و وب سایت‌ها مسدود می‌کند"
"blockCountryConfigs" = "مسدودسازی کشور" "blockConnectionsConfigs" = "مسدود کردن اتصالات"
"blockCountryConfigsDesc" = "این گزینه‌ها ترافیک را بر اساس کشور درخواستی خاص مسدود می‌کند" "blockConnectionsConfigsDesc" = "این گزینه‌ها ترافیک را بر اساس کشور درخواست‌شده خاص مسدود می‌کنند."
"directCountryConfigs" = "اتصال مستقیم کشور" "directConnectionsConfigs" = "اتصالات مستقیم"
"directCountryConfigsDesc" = "اتصال مستقیم اطمینان حاصل می‌کند که ترافیک خاص از طریق یک سرور دیگر هدایت نمی‌شود." "directConnectionsConfigsDesc" = "یک اتصال مستقیم تضمین می‌کند که ترافیک خاص از طریق سرور دیگری مسیریابی نشود."
"blockips" = "مسدود کردن آی‌پی‌ها"
"blockdomains" = "مسدود کردن دامنه‌ها"
"directips" = "آی‌پی‌های مستقیم"
"directdomains" = "دامنه‌های مستقیم"
"ipv4Configs" = "IPv4 مسیریابی" "ipv4Configs" = "IPv4 مسیریابی"
"ipv4ConfigsDesc" = "این گزینه‌ها ترافیک‌ را از طریق آیپینسخه4 به مقصد هدایت می‌کند" "ipv4ConfigsDesc" = "این گزینه‌ها ترافیک‌ را از طریق آیپینسخه4 به مقصد هدایت می‌کند"
"warpConfigs" = "WARP مسیریابی" "warpConfigs" = "WARP مسیریابی"
@@ -356,38 +360,6 @@
"SecurityDesc" = "وب‌سایت‌های ناامن، بدافزار، فیشینگ، و کریپتوماینرها را مسدود می‌کند" "SecurityDesc" = "وب‌سایت‌های ناامن، بدافزار، فیشینگ، و کریپتوماینرها را مسدود می‌کند"
"Speedtest" = "مسدودسازی اسپیدتست" "Speedtest" = "مسدودسازی اسپیدتست"
"SpeedtestDesc" = "اتصال به وب‌سایت‌های تست سرعت را مسدود می‌کند" "SpeedtestDesc" = "اتصال به وب‌سایت‌های تست سرعت را مسدود می‌کند"
"IRIp" = "مسدودسازی اتصال به آی‌پی‌های ایران"
"IRIpDesc" = "اتصال به آی‌پی‌های کشور ایران را مسدود می‌کند"
"IRDomain" = "مسدودسازی اتصال به دامنه‌های‌ ایران"
"IRDomainDesc" = "اتصال به دامنه‌های کشور ایران را مسدود می‌کند"
"ChinaIp" = "مسدودسازی اتصال به آی‌‌پی‌های چین"
"ChinaIpDesc" = "اتصال به آی‌پی‌های کشور چین را مسدود می‌کند"
"ChinaDomain" = "مسدودسازی اتصال به دامنه‌های چین"
"ChinaDomainDesc" = "اتصال به دامنه‌های کشور چین را مسدود می‌کند"
"RussiaIp" = "مسدودسازی اتصال به آی‌پی‌های روسیه"
"RussiaIpDesc" = "اتصال به آی‌پی‌های کشور روسیه را مسدود می‌کند"
"RussiaDomain" = "مسدودسازی اتصال به دامنه‌های روسیه"
"RussiaDomainDesc" = "اتصال به دامنه‌های کشور روسیه را مسدود می‌کند"
"VNIp" = "مسدودسازی اتصال به آی‌پی‌های ویتنام"
"VNIpDesc" = "اتصال به آی‌پی‌های کشور ویتنام را مسدود می‌کند"
"VNDomain" = "مسدودسازی اتصال به دامنه های ویتنام"
"VNDomainDesc" = "اتصال به دامنه‌های کشور ویتنام را مسدود می‌کند"
"DirectIRIp" = "اتصال مستقیم آی‌پی‌های ایران"
"DirectIRIpDesc" = "اتصال مستقیم به آی‌پی‌های کشور ایران"
"DirectIRDomain" = "اتصال مستقیم دامنه‌های ایران"
"DirectIRDomainDesc" = "اتصال مستقیم به دامنه‌های کشور ایران"
"DirectChinaIp" = "اتصال مستقیم آی‌پی‌های چین"
"DirectChinaIpDesc" = "اتصال مستقیم به آی‌پی‌های کشور چین"
"DirectChinaDomain" = "اتصال مستقیم دامنه‌های چین"
"DirectChinaDomainDesc" = "اتصال مستقیم به دامنه‌های کشور چین"
"DirectRussiaIp" = "اتصال مستقیم آی‌پی‌های روسیه"
"DirectRussiaIpDesc" = "اتصال مستقیم به آی‌پی‌های کشور روسیه"
"DirectRussiaDomain" = "اتصال مستقیم دامنه‌های روسیه"
"DirectRussiaDomainDesc" = "اتصال مستقیم به دامنه‌های کشور روسیه"
"DirectVNIp" = "اتصال مستقیم آی‌پی‌های ویتنام"
"DirectVNIpDesc" = "اتصال مستقیم به آی‌پی‌های کشور ویتنام"
"DirectVNDomain" = "اتصال مستقیم دامنه‌های ویتنام"
"DirectVNDomainDesc" = "اتصال مستقیم به دامنه‌های کشور ویتنام"
"GoogleIPv4" = "گوگل" "GoogleIPv4" = "گوگل"
"GoogleIPv4Desc" = "ترافیک را از طریق آیپینسخه4 به گوگل هدایت می‌کند" "GoogleIPv4Desc" = "ترافیک را از طریق آیپینسخه4 به گوگل هدایت می‌کند"
"NetflixIPv4" = "نتفلیکس" "NetflixIPv4" = "نتفلیکس"
@@ -401,11 +373,11 @@
"MetaWARP" = "متا" "MetaWARP" = "متا"
"MetaWARPDesc" = "ترافیک را از طریق وارپ به متا (اینستاگرام، فیس بوک، واتساپ، تردز و...) هدایت می کند." "MetaWARPDesc" = "ترافیک را از طریق وارپ به متا (اینستاگرام، فیس بوک، واتساپ، تردز و...) هدایت می کند."
"AppleWARP" = "اپل" "AppleWARP" = "اپل"
"AppleWARPDesc" = " ترافیک را از طریق وارپ به اپل هدایت می‌کند" "AppleWARPDesc" = "ترافیک را از طریق وارپ به اپل هدایت می‌کند"
"RedditWARP" = "ردیت" "RedditWARP" = "ردیت"
"RedditWARPDesc" = " ترافیک را از طریق وارپ به ردیت هدایت می‌کند" "RedditWARPDesc" = "ترافیک را از طریق وارپ به ردیت هدایت می‌کند"
"SpotifyWARP" = "اسپاتیفای" "SpotifyWARP" = "اسپاتیفای"
"SpotifyWARPDesc" = " ترافیک را از طریق وارپ به اسپاتیفای هدایت می‌کند" "SpotifyWARPDesc" = "ترافیک را از طریق وارپ به اسپاتیفای هدایت می‌کند"
"IRWARP" = "دامنه‌های ایران" "IRWARP" = "دامنه‌های ایران"
"IRWARPDesc" = "ترافیک را از طریق وارپ به دامنه‌های کشور ایران هدایت می‌کند" "IRWARPDesc" = "ترافیک را از طریق وارپ به دامنه‌های کشور ایران هدایت می‌کند"
"Inbounds" = "ورودی‌ها" "Inbounds" = "ورودی‌ها"
@@ -422,6 +394,10 @@
"accessLogDesc" = "مسیر فایل برای گزارش دسترسی. مقدار ویژه «هیچ» گزارش‌های دسترسی را غیرفعال میکند." "accessLogDesc" = "مسیر فایل برای گزارش دسترسی. مقدار ویژه «هیچ» گزارش‌های دسترسی را غیرفعال میکند."
"errorLog" = "گزارش خطا" "errorLog" = "گزارش خطا"
"errorLogDesc" = "مسیر فایل برای ورود به سیستم خطا. مقدار ویژه «هیچ» گزارش های خطا را غیرفعال میکند" "errorLogDesc" = "مسیر فایل برای ورود به سیستم خطا. مقدار ویژه «هیچ» گزارش های خطا را غیرفعال میکند"
"dnsLog" = "گزارش DNS"
"dnsLogDesc" = "آیا ثبت‌های درخواست DNS را فعال کنید"
"maskAddress" = "پنهان کردن آدرس"
"maskAddressDesc" = "پوشش آدرس IP، هنگامی که فعال می‌شود، به طور خودکار آدرس IP که در لاگ ظاهر می‌شود را جایگزین می‌کند."
[pages.xray.rules] [pages.xray.rules]
"first" = "اولین" "first" = "اولین"
@@ -484,6 +460,7 @@
"add" = "افزودن سرور" "add" = "افزودن سرور"
"edit" = "ویرایش سرور" "edit" = "ویرایش سرور"
"domains" = "دامنه‌ها" "domains" = "دامنه‌ها"
"expectIPs" = "آی‌پی‌های مورد انتظار"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "افزودن دی‌ان‌اس جعلی" "add" = "افزودن دی‌ان‌اس جعلی"

View File

@@ -143,7 +143,7 @@
"destinationPort" = "Port Tujuan" "destinationPort" = "Port Tujuan"
"targetAddress" = "Alamat Target" "targetAddress" = "Alamat Target"
"monitorDesc" = "Biarkan kosong untuk mendengarkan semua IP" "monitorDesc" = "Biarkan kosong untuk mendengarkan semua IP"
"meansNoLimit" = " = Unlimited. (unit: GB)" "meansNoLimit" = "= Unlimited. (unit: GB)"
"totalFlow" = "Total Aliran" "totalFlow" = "Total Aliran"
"leaveBlankToNeverExpire" = "Biarkan kosong untuk tidak pernah kedaluwarsa" "leaveBlankToNeverExpire" = "Biarkan kosong untuk tidak pernah kedaluwarsa"
"noRecommendKeepDefault" = "Disarankan untuk tetap menggunakan pengaturan default" "noRecommendKeepDefault" = "Disarankan untuk tetap menggunakan pengaturan default"
@@ -309,14 +309,14 @@
"fragment" = "Fragmentasi" "fragment" = "Fragmentasi"
"fragmentDesc" = "Aktifkan fragmentasi untuk paket hello TLS" "fragmentDesc" = "Aktifkan fragmentasi untuk paket hello TLS"
"fragmentSett" = "Pengaturan Fragmentasi" "fragmentSett" = "Pengaturan Fragmentasi"
"noiseDesc" = "Aktifkan Noise." "noisesDesc" = "Aktifkan Noises."
"noiseSett" = "Pengaturan Noise" "noisesSett" = "Pengaturan Noises"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Mengirimkan beberapa aliran data independen dalam aliran data yang sudah ada." "muxDesc" = "Mengirimkan beberapa aliran data independen dalam aliran data yang sudah ada."
"muxSett" = "Pengaturan Mux" "muxSett" = "Pengaturan Mux"
"direct" = "Koneksi langsung" "direct" = "Koneksi langsung"
"directDesc" = "Secara langsung membuat koneksi dengan domain atau rentang IP negara tertentu." "directDesc" = "Secara langsung membuat koneksi dengan domain atau rentang IP negara tertentu."
"directSett" = "Opsi Koneksi Langsung"
[pages.xray] [pages.xray]
"title" = "Konfigurasi Xray" "title" = "Konfigurasi Xray"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Log dapat mempengaruhi efisiensi server Anda. Disarankan untuk mengaktifkannya dengan bijak hanya jika diperlukan" "logConfigsDesc" = "Log dapat mempengaruhi efisiensi server Anda. Disarankan untuk mengaktifkannya dengan bijak hanya jika diperlukan"
"blockConfigs" = "Pelindung" "blockConfigs" = "Pelindung"
"blockConfigsDesc" = "Opsi ini akan memblokir lalu lintas berdasarkan protokol dan situs web yang diminta." "blockConfigsDesc" = "Opsi ini akan memblokir lalu lintas berdasarkan protokol dan situs web yang diminta."
"blockCountryConfigs" = "Blokir Negara" "blockConnectionsConfigs" = "Blokir Koneksi"
"blockCountryConfigsDesc" = "Opsi ini akan memblokir lalu lintas berdasarkan negara yang diminta." "blockConnectionsConfigsDesc" = "Opsi ini akan memblokir lalu lintas berdasarkan negara yang diminta."
"directCountryConfigs" = "Langsung ke Negara" "directConnectionsConfigs" = "Koneksi Langsung"
"directCountryConfigsDesc" = "Koneksi langsung memastikan bahwa lalu lintas tertentu tidak diarahkan melalui server lain." "directConnectionsConfigsDesc" = "Koneksi langsung memastikan bahwa lalu lintas tertentu tidak dialihkan melalui server lain."
"blockips" = "Blokir IP"
"blockdomains" = "Blokir Domain"
"directips" = "IP Langsung"
"directdomains" = "Domain Langsung"
"ipv4Configs" = "Pengalihan IPv4" "ipv4Configs" = "Pengalihan IPv4"
"ipv4ConfigsDesc" = "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui IPv4." "ipv4ConfigsDesc" = "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui IPv4."
"warpConfigs" = "Pengalihan WARP" "warpConfigs" = "Pengalihan WARP"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Memblokir situs web malware, phishing, dan penambang kripto." "SecurityDesc" = "Memblokir situs web malware, phishing, dan penambang kripto."
"Speedtest" = "Blokir Speedtest" "Speedtest" = "Blokir Speedtest"
"SpeedtestDesc" = "Memblokir pembentukan koneksi ke situs web speedtest." "SpeedtestDesc" = "Memblokir pembentukan koneksi ke situs web speedtest."
"IRIp" = "Blokir Koneksi ke IP Iran"
"IRIpDesc" = "Memblokir pembentukan koneksi ke rentang IP Iran."
"IRDomain" = "Blokir Koneksi ke Domain Iran"
"IRDomainDesc" = "Memblokir pembentukan koneksi ke domain Iran."
"ChinaIp" = "Blokir Koneksi ke IP China"
"ChinaIpDesc" = "Memblokir pembentukan koneksi ke rentang IP China."
"ChinaDomain" = "Blokir Koneksi ke Domain China"
"ChinaDomainDesc" = "Memblokir pembentukan koneksi ke domain China."
"RussiaIp" = "Blokir Koneksi ke IP Rusia"
"RussiaIpDesc" = "Memblokir pembentukan koneksi ke rentang IP Rusia."
"RussiaDomain" = "Blokir Koneksi ke Domain Rusia"
"RussiaDomainDesc" = "Memblokir pembentukan koneksi ke domain Rusia."
"VNIp" = "Blokir Koneksi ke IP Vietnam"
"VNIpDesc" = "Memblokir pembentukan koneksi ke rentang IP Vietnam."
"VNDomain" = "Blokir Koneksi ke Domain Vietnam"
"VNDomainDesc" = "Memblokir pembentukan koneksi ke domain Vietnam."
"DirectIRIp" = "Koneksi Langsung ke IP Iran"
"DirectIRIpDesc" = "Membentuk koneksi langsung ke rentang IP Iran."
"DirectIRDomain" = "Koneksi Langsung ke Domain Iran"
"DirectIRDomainDesc" = "Membentuk koneksi langsung ke domain Iran."
"DirectChinaIp" = "Koneksi Langsung ke IP China"
"DirectChinaIpDesc" = "Membentuk koneksi langsung ke rentang IP China."
"DirectChinaDomain" = "Koneksi Langsung ke Domain China"
"DirectChinaDomainDesc" = "Membentuk koneksi langsung ke domain China."
"DirectRussiaIp" = "Koneksi Langsung ke IP Rusia"
"DirectRussiaIpDesc" = "Membentuk koneksi langsung ke rentang IP Rusia."
"DirectRussiaDomain" = "Koneksi Langsung ke Domain Rusia"
"DirectRussiaDomainDesc" = "Membentuk koneksi langsung ke domain Rusia."
"DirectVNIp" = "Koneksi Langsung ke IP Vietnam"
"DirectVNIpDesc" = "Membentuk koneksi langsung ke rentang IP Vietnam."
"DirectVNDomain" = "Koneksi Langsung ke Domain Vietnam"
"DirectVNDomainDesc" = "Membentuk koneksi langsung ke domain Vietnam."
"GoogleIPv4" = "Google" "GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "Rute lalu lintas ke Google melalui IPv4." "GoogleIPv4Desc" = "Rute lalu lintas ke Google melalui IPv4."
"NetflixIPv4" = "Netflix" "NetflixIPv4" = "Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "Jalur file untuk log akses. Nilai khusus 'tidak ada' menonaktifkan log akses" "accessLogDesc" = "Jalur file untuk log akses. Nilai khusus 'tidak ada' menonaktifkan log akses"
"errorLog" = "Catatan eror" "errorLog" = "Catatan eror"
"errorLogDesc" = "Jalur file untuk log kesalahan. Nilai khusus 'tidak ada' menonaktifkan log kesalahan" "errorLogDesc" = "Jalur file untuk log kesalahan. Nilai khusus 'tidak ada' menonaktifkan log kesalahan"
"dnsLog" = "Log DNS"
"dnsLogDesc" = "Apakah akan mengaktifkan log kueri DNS"
"maskAddress" = "Alamat Masker"
"maskAddressDesc" = "Masker alamat IP, ketika diaktifkan, akan secara otomatis mengganti alamat IP yang muncul di log."
[pages.xray.rules] [pages.xray.rules]
"first" = "Pertama" "first" = "Pertama"
@@ -484,6 +460,7 @@
"add" = "Tambahkan Server" "add" = "Tambahkan Server"
"edit" = "Sunting Server" "edit" = "Sunting Server"
"domains" = "Domains" "domains" = "Domains"
"expectIPs" = "IP yang Diharapkan"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Tambahkan DNS Palsu" "add" = "Tambahkan DNS Palsu"

View File

@@ -43,8 +43,8 @@
"domainName" = "Nome de Domínio" "domainName" = "Nome de Domínio"
"monitor" = "IP de Escuta" "monitor" = "IP de Escuta"
"certificate" = "Certificado Digital" "certificate" = "Certificado Digital"
"fail" = " Falhou" "fail" = "Falhou"
"success" = " Com Sucesso" "success" = "Com Sucesso"
"getVersion" = "Obter Versão" "getVersion" = "Obter Versão"
"install" = "Instalar" "install" = "Instalar"
"clients" = "Clientes" "clients" = "Clientes"
@@ -143,7 +143,7 @@
"destinationPort" = "Porta de Destino" "destinationPort" = "Porta de Destino"
"targetAddress" = "Endereço de Destino" "targetAddress" = "Endereço de Destino"
"monitorDesc" = "Deixe em branco para ouvir todos os IPs" "monitorDesc" = "Deixe em branco para ouvir todos os IPs"
"meansNoLimit" = " = Ilimitado. (unidade: GB)" "meansNoLimit" = "= Ilimitado. (unidade: GB)"
"totalFlow" = "Fluxo Total" "totalFlow" = "Fluxo Total"
"leaveBlankToNeverExpire" = "Deixe em branco para nunca expirar" "leaveBlankToNeverExpire" = "Deixe em branco para nunca expirar"
"noRecommendKeepDefault" = "Recomenda-se manter o padrão" "noRecommendKeepDefault" = "Recomenda-se manter o padrão"
@@ -309,14 +309,14 @@
"fragment" = "Fragmentação" "fragment" = "Fragmentação"
"fragmentDesc" = "Ativa a fragmentação para o pacote TLS hello." "fragmentDesc" = "Ativa a fragmentação para o pacote TLS hello."
"fragmentSett" = "Configurações de Fragmentação" "fragmentSett" = "Configurações de Fragmentação"
"noiseDesc" = "Ativar Noise." "noisesDesc" = "Ativar Noises."
"noiseSett" = "Configurações de Noise" "noisesSett" = "Configurações de Noises"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Transmitir múltiplos fluxos de dados independentes dentro de um fluxo de dados estabelecido." "muxDesc" = "Transmitir múltiplos fluxos de dados independentes dentro de um fluxo de dados estabelecido."
"muxSett" = "Configurações de Mux" "muxSett" = "Configurações de Mux"
"direct" = "Conexão Direta" "direct" = "Conexão Direta"
"directDesc" = "Estabelece conexões diretamente com domínios ou intervalos de IP de um país específico." "directDesc" = "Estabelece conexões diretamente com domínios ou intervalos de IP de um país específico."
"directSett" = "Opções de Conexão Direta"
[pages.xray] [pages.xray]
"title" = "Configurações Xray" "title" = "Configurações Xray"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Os logs podem afetar a eficiência do servidor. É recomendável habilitá-los com sabedoria apenas se necessário." "logConfigsDesc" = "Os logs podem afetar a eficiência do servidor. É recomendável habilitá-los com sabedoria apenas se necessário."
"blockConfigs" = "Escudo de Proteção" "blockConfigs" = "Escudo de Proteção"
"blockConfigsDesc" = "Essas opções bloqueiam tráfego com base em protocolos e sites específicos solicitados." "blockConfigsDesc" = "Essas opções bloqueiam tráfego com base em protocolos e sites específicos solicitados."
"blockCountryConfigs" = "Bloquear País" "blockConnectionsConfigs" = "Bloquear Conexões"
"blockCountryConfigsDesc" = "Essas opções bloqueiam tráfego com base no país solicitado." "blockConnectionsConfigsDesc" = "Essas opções bloquearão o tráfego com base no país solicitado."
"directCountryConfigs" = "País Direto" "directConnectionsConfigs" = "Conexões Diretas"
"directCountryConfigsDesc" = "Uma conexão direta garante que o tráfego específico não seja roteado por outro servidor." "directConnectionsConfigsDesc" = "Uma conexão direta garante que o tráfego específico não seja roteado por outro servidor."
"blockips" = "Bloquear IPs"
"blockdomains" = "Bloquear Domínios"
"directips" = "IPs Diretos"
"directdomains" = "Domínios Diretos"
"ipv4Configs" = "Roteamento IPv4" "ipv4Configs" = "Roteamento IPv4"
"ipv4ConfigsDesc" = "Essas opções roteam o tráfego para um destino específico via IPv4." "ipv4ConfigsDesc" = "Essas opções roteam o tráfego para um destino específico via IPv4."
"warpConfigs" = "Roteamento WARP" "warpConfigs" = "Roteamento WARP"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Bloqueia sites de malware, phishing e mineradores de criptomoedas." "SecurityDesc" = "Bloqueia sites de malware, phishing e mineradores de criptomoedas."
"Speedtest" = "Bloquear Speedtest" "Speedtest" = "Bloquear Speedtest"
"SpeedtestDesc" = "Bloqueia a conexão com sites de teste de velocidade." "SpeedtestDesc" = "Bloqueia a conexão com sites de teste de velocidade."
"IRIp" = "Bloquear Conexão para IPs do Irã"
"IRIpDesc" = "Bloqueia a conexão com faixas de IP do Irã."
"IRDomain" = "Bloquear Conexão para Domínios do Irã"
"IRDomainDesc" = "Bloqueia a conexão com domínios do Irã."
"ChinaIp" = "Bloquear Conexão para IPs da China"
"ChinaIpDesc" = "Bloqueia a conexão com faixas de IP da China."
"ChinaDomain" = "Bloquear Conexão para Domínios da China"
"ChinaDomainDesc" = "Bloqueia a conexão com domínios da China."
"RussiaIp" = "Bloquear Conexão para IPs da Rússia"
"RussiaIpDesc" = "Bloqueia a conexão com faixas de IP da Rússia."
"RussiaDomain" = "Bloquear Conexão para Domínios da Rússia"
"RussiaDomainDesc" = "Bloqueia a conexão com domínios da Rússia."
"VNIp" = "Bloquear Conexão para IPs do Vietnã"
"VNIpDesc" = "Bloqueia a conexão com faixas de IP do Vietnã."
"VNDomain" = "Bloquear Conexão para Domínios do Vietnã"
"VNDomainDesc" = "Bloqueia a conexão com domínios do Vietnã."
"DirectIRIp" = "Conexão Direta para IPs do Irã"
"DirectIRIpDesc" = "Estabelece conexão diretamente com faixas de IP do Irã."
"DirectIRDomain" = "Conexão Direta para Domínios do Irã"
"DirectIRDomainDesc" = "Estabelece conexão diretamente com domínios do Irã."
"DirectChinaIp" = "Conexão Direta para IPs da China"
"DirectChinaIpDesc" = "Estabelece conexão diretamente com faixas de IP da China."
"DirectChinaDomain" = "Conexão Direta para Domínios da China"
"DirectChinaDomainDesc" = "Estabelece conexão diretamente com domínios da China."
"DirectRussiaIp" = "Conexão Direta para IPs da Rússia"
"DirectRussiaIpDesc" = "Estabelece conexão diretamente com faixas de IP da Rússia."
"DirectRussiaDomain" = "Conexão Direta para Domínios da Rússia"
"DirectRussiaDomainDesc" = "Estabelece conexão diretamente com domínios da Rússia."
"DirectVNIp" = "Conexão Direta para IPs do Vietnã"
"DirectVNIpDesc" = "Estabelece conexão diretamente com faixas de IP do Vietnã."
"DirectVNDomain" = "Conexão Direta para Domínios do Vietnã"
"DirectVNDomainDesc" = "Estabelece conexão diretamente com domínios do Vietnã."
"GoogleIPv4" = "Google" "GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "Roteia tráfego para o Google via IPv4." "GoogleIPv4Desc" = "Roteia tráfego para o Google via IPv4."
"NetflixIPv4" = "Netflix" "NetflixIPv4" = "Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "O caminho do arquivo para o log de acesso. O valor especial 'none' desativa os logs de acesso." "accessLogDesc" = "O caminho do arquivo para o log de acesso. O valor especial 'none' desativa os logs de acesso."
"errorLog" = "Log de Erros" "errorLog" = "Log de Erros"
"errorLogDesc" = "O caminho do arquivo para o log de erros. O valor especial 'none' desativa os logs de erro." "errorLogDesc" = "O caminho do arquivo para o log de erros. O valor especial 'none' desativa os logs de erro."
"dnsLog" = "Log DNS"
"dnsLogDesc" = "Se ativar logs de consulta DNS"
"maskAddress" = "Mascarar Endereço"
"maskAddressDesc" = "Máscara de endereço IP, quando ativado, substitui automaticamente o endereço IP que aparece no log."
[pages.xray.rules] [pages.xray.rules]
"first" = "Primeiro" "first" = "Primeiro"
@@ -484,6 +460,7 @@
"add" = "Adicionar Servidor" "add" = "Adicionar Servidor"
"edit" = "Editar Servidor" "edit" = "Editar Servidor"
"domains" = "Domínios" "domains" = "Domínios"
"expectIPs" = "IPs Esperadas"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Adicionar Fake DNS" "add" = "Adicionar Fake DNS"

View File

@@ -143,7 +143,7 @@
"destinationPort" = "Порт назначения" "destinationPort" = "Порт назначения"
"targetAddress" = "Целевой адрес" "targetAddress" = "Целевой адрес"
"monitorDesc" = "Оставьте пустым по умолчанию" "monitorDesc" = "Оставьте пустым по умолчанию"
"meansNoLimit" = " = Без ограничений (значение: ГБ)" "meansNoLimit" = "= Без ограничений (значение: ГБ)"
"totalFlow" = "Общий расход" "totalFlow" = "Общий расход"
"leaveBlankToNeverExpire" = "Оставьте пустым, чтобы не истекало" "leaveBlankToNeverExpire" = "Оставьте пустым, чтобы не истекало"
"noRecommendKeepDefault" = "Нет требований для сохранения настроек по умолчанию" "noRecommendKeepDefault" = "Нет требований для сохранения настроек по умолчанию"
@@ -309,14 +309,14 @@
"fragment" = "Фрагментация" "fragment" = "Фрагментация"
"fragmentDesc" = "Включить фрагментацию для пакета приветствия TLS" "fragmentDesc" = "Включить фрагментацию для пакета приветствия TLS"
"fragmentSett" = "Настройки фрагментации" "fragmentSett" = "Настройки фрагментации"
"noiseDesc" = "Включить Noise." "noisesDesc" = "Включить Noises."
"noiseSett" = "Настройки Noise" "noisesSett" = "Настройки Noises"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Передача нескольких независимых потоков данных в рамках установленного потока данных." "muxDesc" = "Передача нескольких независимых потоков данных в рамках установленного потока данных."
"muxSett" = "Mux Настройки" "muxSett" = "Mux Настройки"
"direct" = "Прямая связь" "direct" = "Прямая связь"
"directDesc" = "Напрямую устанавливает соединения с доменами или диапазонами IP конкретной страны." "directDesc" = "Напрямую устанавливает соединения с доменами или диапазонами IP конкретной страны."
"directSett" = "Варианты прямого подключения"
[pages.xray] [pages.xray]
"title" = "Настройки Xray" "title" = "Настройки Xray"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Журналы могут повлиять на эффективность вашего сервера. Рекомендуется включать их с умом только в случае ваших нужд!" "logConfigsDesc" = "Журналы могут повлиять на эффективность вашего сервера. Рекомендуется включать их с умом только в случае ваших нужд!"
"blockConfigs" = "Блокировка конфигураций" "blockConfigs" = "Блокировка конфигураций"
"blockConfigsDesc" = "Эти параметры не позволят пользователям подключаться к определенным протоколам и веб-сайтам" "blockConfigsDesc" = "Эти параметры не позволят пользователям подключаться к определенным протоколам и веб-сайтам"
"blockCountryConfigs" = "Конфигурации блокировки страны" "blockConnectionsConfigs" = "Блокировать соединения"
"blockCountryConfigsDesc" = "Эти параметры не позволят пользователям подключаться к доменам определенной страны" "blockConnectionsConfigsDesc" = "Эти параметры будут блокировать трафик в зависимости от запрашиваемой страны."
"directCountryConfigs" = "Настройки прямого подключения для страны" "directConnectionsConfigs" = "Прямые соединения"
"directCountryConfigsDesc" = "Прямое подключение обеспечивает, что конкретный трафик не направляется через другой сервер." "directConnectionsConfigsDesc" = "Прямое соединение гарантирует, что определенный трафик не будет перенаправлен через другой сервер."
"blockips" = "Блокировать IP"
"blockdomains" = "Блокировать домены"
"directips" = "Прямые IP"
"directdomains" = "Прямые домены"
"ipv4Configs" = "Настройки IPv4" "ipv4Configs" = "Настройки IPv4"
"ipv4ConfigsDesc" = "Эти параметры позволят пользователям маршрутизироваться к целевым доменам только через IPv4" "ipv4ConfigsDesc" = "Эти параметры позволят пользователям маршрутизироваться к целевым доменам только через IPv4"
"warpConfigs" = "Настройки WARP" "warpConfigs" = "Настройки WARP"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Изменение шаблона конфигурации для защиты безопасности." "SecurityDesc" = "Изменение шаблона конфигурации для защиты безопасности."
"Speedtest" = "Блокировать сайты для проверки скорости" "Speedtest" = "Блокировать сайты для проверки скорости"
"SpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости" "SpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости"
"IRIp" = "Заблокировать подключения к диапазонам IP-адресов Ирана"
"IRIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонам IP-адресов Ирана"
"IRDomain" = "Заблокировать подключения к доменам Ирана"
"IRDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам Ирана"
"ChinaIp" = "Заблокировать подключения к диапазонам IP-адресов Китая"
"ChinaIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонам IP-адресов Китая"
"ChinaDomain" = "Заблокировать подключения к доменам Китая"
"ChinaDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам Китая"
"RussiaIp" = "Заблокировать подключения к диапазонам IP-адресов России"
"RussiaIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонами IP-адресов России"
"RussiaDomain" = "Заблокировать подключения к доменам России"
"RussiaDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам России"
"VNIp" = "Отключить подключение к IP-адресам Вьетнама"
"VNIpDesc" = "Измените шаблон конфигурации, чтобы избежать подключения к диапазонам IP-адресов Вьетнама"
"VNDomain" = "Отключить подключение к доменам Вьетнама"
"VNDomainDesc" = "Измените шаблон конфигурации, чтобы избежать подключения к доменам Вьетнама."
"DirectIRIp" = "Прямое подключения к диапазонам IP-адресов Ирана"
"DirectIRIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов Ирана"
"DirectIRDomain" = "Прямое подключение к доменам Ирана"
"DirectIRDomainDesc" = "Изменение шаблон конфигурации для прямого подключения к доменам Ирана"
"DirectChinaIp" = "Прямое подключение к диапазонам IP-адресов Китая"
"DirectChinaIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов Китая"
"DirectChinaDomain" = "Прямое подключение к доменам Китая"
"DirectChinaDomainDesc" = "Изменение шаблона конфигурации для прямого подключения к доменам Китая"
"DirectRussiaIp" = "Прямое подключение к диапазонам IP-адресов России"
"DirectRussiaIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов России"
"DirectRussiaDomain" = "Прямое подключение к доменам России"
"DirectRussiaDomainDesc" = "Изменение шаблона конфигурации для прямого подключения к доменам России"
"DirectVNIp" = "Прямое подключение к IP-адресам Вьетнама"
"DirectVNIpDesc" = "Измените шаблон конфигурации для прямого подключения к диапазонам IP-адресов Вьетнама"
"DirectVNDomain" = "Прямое подключение к доменам Вьетнама"
"DirectVNDomainDesc" = "Измените шаблон конфигурации для прямого подключения к доменам Вьетнама"
"GoogleIPv4" = "Использовать IPv4 для Google" "GoogleIPv4" = "Использовать IPv4 для Google"
"GoogleIPv4Desc" = "Добавить маршрутизацию для Google для подключения к IPv4" "GoogleIPv4Desc" = "Добавить маршрутизацию для Google для подключения к IPv4"
"NetflixIPv4" = "Использовать IPv4 для Netflix" "NetflixIPv4" = "Использовать IPv4 для Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "Путь к файлу журнала доступа. Специальное значение «none» отключило журналы доступа." "accessLogDesc" = "Путь к файлу журнала доступа. Специальное значение «none» отключило журналы доступа."
"errorLog" = "Журнал ошибок" "errorLog" = "Журнал ошибок"
"errorLogDesc" = "Путь к файлу журнала ошибок. Специальное значение «none» отключает журналы ошибок." "errorLogDesc" = "Путь к файлу журнала ошибок. Специальное значение «none» отключает журналы ошибок."
"dnsLog" = "DNS Журнал"
"dnsLogDesc" = "Включить логи запросов DNS"
"maskAddress" = "Маскировать Адрес"
"maskAddressDesc" = "Маска IP-адреса, при активации автоматически заменяет IP-адрес, который появляется в логе."
[pages.xray.rules] [pages.xray.rules]
"first" = "Первый" "first" = "Первый"
@@ -484,6 +460,7 @@
"add" = "Добавить сервер" "add" = "Добавить сервер"
"edit" = "Редактировать сервер" "edit" = "Редактировать сервер"
"domains" = "Домены" "domains" = "Домены"
"expectIPs" = "Ожидаемые IP"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Добавить поддельный DNS" "add" = "Добавить поддельный DNS"

View File

@@ -143,7 +143,7 @@
"destinationPort" = "Hedef Port" "destinationPort" = "Hedef Port"
"targetAddress" = "Hedef Adres" "targetAddress" = "Hedef Adres"
"monitorDesc" = "Tüm IP'leri dinlemek için boş bırakın" "monitorDesc" = "Tüm IP'leri dinlemek için boş bırakın"
"meansNoLimit" = " = Sınırsız. (birim: GB)" "meansNoLimit" = "= Sınırsız. (birim: GB)"
"totalFlow" = "Toplam Akış" "totalFlow" = "Toplam Akış"
"leaveBlankToNeverExpire" = "Hiçbir zaman sona ermemesi için boş bırakın" "leaveBlankToNeverExpire" = "Hiçbir zaman sona ermemesi için boş bırakın"
"noRecommendKeepDefault" = "Varsayılanı korumanız önerilir" "noRecommendKeepDefault" = "Varsayılanı korumanız önerilir"
@@ -309,14 +309,14 @@
"fragment" = "Parçalama" "fragment" = "Parçalama"
"fragmentDesc" = "TLS merhaba paketinin parçalanmasını etkinleştir." "fragmentDesc" = "TLS merhaba paketinin parçalanmasını etkinleştir."
"fragmentSett" = "Parçalama Ayarları" "fragmentSett" = "Parçalama Ayarları"
"noiseDesc" = "Noise'i Etkinleştir." "noisesDesc" = "Noises'i Etkinleştir."
"noiseSett" = "Noise Ayarları" "noisesSett" = "Noises Ayarları"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Kurulmuş bir veri akışında birden çok bağımsız veri akışını iletir." "muxDesc" = "Kurulmuş bir veri akışında birden çok bağımsız veri akışını iletir."
"muxSett" = "Mux Ayarları" "muxSett" = "Mux Ayarları"
"direct" = "Doğrudan Bağlantı" "direct" = "Doğrudan Bağlantı"
"directDesc" = "Belirli bir ülkenin alan adları veya IP aralıkları ile doğrudan bağlantı kurar." "directDesc" = "Belirli bir ülkenin alan adları veya IP aralıkları ile doğrudan bağlantı kurar."
"directSett" = "Doğrudan Bağlantı Seçenekleri"
[pages.xray] [pages.xray]
"title" = "Xray Yapılandırmaları" "title" = "Xray Yapılandırmaları"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Günlükler sunucunuzun verimliliğini etkileyebilir. Yalnızca ihtiyaç durumunda akıllıca etkinleştirmeniz önerilir" "logConfigsDesc" = "Günlükler sunucunuzun verimliliğini etkileyebilir. Yalnızca ihtiyaç durumunda akıllıca etkinleştirmeniz önerilir"
"blockConfigs" = "Koruma Kalkanı" "blockConfigs" = "Koruma Kalkanı"
"blockConfigsDesc" = "Bu seçenekler belirli istek protokolleri ve web siteleri temelinde trafiği engeller." "blockConfigsDesc" = "Bu seçenekler belirli istek protokolleri ve web siteleri temelinde trafiği engeller."
"blockCountryConfigs" = "Ülke Engelleme" "blockConnectionsConfigs" = "Bağlantıları Engelle"
"blockCountryConfigsDesc" = "Bu seçenekler belirli istek ülkesi temelinde trafiği engeller." "blockConnectionsConfigsDesc" = "Bu seçenekler belirli bir istenen ülkeye göre trafiği engelleyecektir."
"directCountryConfigs" = "Doğrudan Ülke" "directConnectionsConfigs" = "Doğrudan Bağlantılar"
"directCountryConfigsDesc" = "Doğrudan bağlantı, belirli trafiğin başka bir sunucu üzerinden yönlendirilmemesini sağlar." "directConnectionsConfigsDesc" = "Doğrudan bağlantı, belirli bir trafiğin başka bir sunucu üzerinden yönlendirilmediğini sağlar."
"blockips" = "IP'leri Engelle"
"blockdomains" = "Alan Adlarını Engelle"
"directips" = "Doğrudan IP'ler"
"directdomains" = "Doğrudan Alan Adları"
"ipv4Configs" = "IPv4 Yönlendirme" "ipv4Configs" = "IPv4 Yönlendirme"
"ipv4ConfigsDesc" = "Bu seçenekler belirli bir varış yerine IPv4 üzerinden trafiği yönlendirir." "ipv4ConfigsDesc" = "Bu seçenekler belirli bir varış yerine IPv4 üzerinden trafiği yönlendirir."
"warpConfigs" = "WARP Yönlendirme" "warpConfigs" = "WARP Yönlendirme"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Kötü amaçlı yazılım, kimlik avı ve kripto madencilik web sitelerini engeller." "SecurityDesc" = "Kötü amaçlı yazılım, kimlik avı ve kripto madencilik web sitelerini engeller."
"Speedtest" = "Speedtest Bağlantısını Engelle" "Speedtest" = "Speedtest Bağlantısını Engelle"
"SpeedtestDesc" = "Speedtest web sitelerine bağlantı kurmayı engeller." "SpeedtestDesc" = "Speedtest web sitelerine bağlantı kurmayı engeller."
"IRIp" = "İran IP'lerine Bağlantıyı Engelle"
"IRIpDesc" = "İran IP aralıklarına bağlantı kurmayı engeller."
"IRDomain" = "İran Alan Adlarına Bağlantıyı Engelle"
"IRDomainDesc" = "İran alan adlarına bağlantı kurmayı engeller."
"ChinaIp" = "Çin IP'lerine Bağlantıyı Engelle"
"ChinaIpDesc" = "Çin IP aralıklarına bağlantı kurmayı engeller."
"ChinaDomain" = "Çin Alan Adlarına Bağlantıyı Engelle"
"ChinaDomainDesc" = "Çin alan adlarına bağlantı kurmayı engeller."
"RussiaIp" = "Rusya IP'lerine Bağlantıyı Engelle"
"RussiaIpDesc" = "Rusya IP aralıklarına bağlantı kurmayı engeller."
"RussiaDomain" = "Rusya Alan Adlarına Bağlantıyı Engelle"
"RussiaDomainDesc" = "Rusya alan adlarına bağlantı kurmayı engeller."
"VNIp" = "Vietnam IP'lerine Bağlantıyı Engelle"
"VNIpDesc" = "Vietnam IP aralıklarına bağlantı kurmayı engeller."
"VNDomain" = "Vietnam Alan Adlarına Bağlantıyı Engelle"
"VNDomainDesc" = "Vietnam alan adlarına bağlantı kurmayı engeller."
"DirectIRIp" = "İran IP'lerine Doğrudan Bağlantı"
"DirectIRIpDesc" = "İran IP aralıklarına doğrudan bağlantı kurar."
"DirectIRDomain" = "İran Alan Adlarına Doğrudan Bağlantı"
"DirectIRDomainDesc" = "İran alan adlarına doğrudan bağlantı kurar."
"DirectChinaIp" = "Çin IP'lerine Doğrudan Bağlantı"
"DirectChinaIpDesc" = "Çin IP aralıklarına doğrudan bağlantı kurar."
"DirectChinaDomain" = "Çin Alan Adlarına Doğrudan Bağlantı"
"DirectChinaDomainDesc" = "Çin alan adlarına doğrudan bağlantı kurar."
"DirectRussiaIp" = "Rusya IP'lerine Doğrudan Bağlantı"
"DirectRussiaIpDesc" = "Rusya IP aralıklarına doğrudan bağlantı kurar."
"DirectRussiaDomain" = "Rusya Alan Adlarına Doğrudan Bağlantı"
"DirectRussiaDomainDesc" = "Rusya alan adlarına doğrudan bağlantı kurar."
"DirectVNIp" = "Vietnam IP'lerine Doğrudan Bağlantı"
"DirectVNIpDesc" = "Vietnam IP aralıklarına doğrudan bağlantı kurar."
"DirectVNDomain" = "Vietnam Alan Adlarına Doğrudan Bağlantı"
"DirectVNDomainDesc" = "Vietnam alan adlarına doğrudan bağlantı kurar."
"GoogleIPv4" = "Google" "GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "Google'a trafiği IPv4 üzerinden yönlendirir." "GoogleIPv4Desc" = "Google'a trafiği IPv4 üzerinden yönlendirir."
"NetflixIPv4" = "Netflix" "NetflixIPv4" = "Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "Erişim günlüğü için dosya yolu. 'none' özel değeri erişim günlüklerini devre dışı bırakır" "accessLogDesc" = "Erişim günlüğü için dosya yolu. 'none' özel değeri erişim günlüklerini devre dışı bırakır"
"errorLog" = "Hata Günlüğü" "errorLog" = "Hata Günlüğü"
"errorLogDesc" = "Hata günlüğü için dosya yolu. 'none' özel değeri hata günlüklerini devre dışı bırakır" "errorLogDesc" = "Hata günlüğü için dosya yolu. 'none' özel değeri hata günlüklerini devre dışı bırakır"
"dnsLog" = "DNS Günlüğü"
"dnsLogDesc" = "DNS sorgu günlüklerini etkinleştirin"
"maskAddress" = "Adres Maskesi"
"maskAddressDesc" = "IP adresi maskesi, etkinleştirildiğinde, günlükte görünen IP adresini otomatik olarak değiştirecektir."
[pages.xray.rules] [pages.xray.rules]
"first" = "İlk" "first" = "İlk"
@@ -484,6 +460,7 @@
"add" = "Sunucu Ekle" "add" = "Sunucu Ekle"
"edit" = "Sunucuyu Düzenle" "edit" = "Sunucuyu Düzenle"
"domains" = "Alan Adları" "domains" = "Alan Adları"
"expectIPs" = "Beklenen IP'ler"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Sahte DNS Ekle" "add" = "Sahte DNS Ekle"

View File

@@ -43,8 +43,8 @@
"domainName" = "Доменне ім`я" "domainName" = "Доменне ім`я"
"monitor" = "Слухати IP" "monitor" = "Слухати IP"
"certificate" = "Цифровий сертифікат" "certificate" = "Цифровий сертифікат"
"fail" = " Помилка" "fail" = "Помилка"
"success" = " Успішно" "success" = "Успішно"
"getVersion" = "Отримати версію" "getVersion" = "Отримати версію"
"install" = "Встановити" "install" = "Встановити"
"clients" = "Клієнти" "clients" = "Клієнти"
@@ -143,7 +143,7 @@
"destinationPort" = "Порт призначення" "destinationPort" = "Порт призначення"
"targetAddress" = "Цільова адреса" "targetAddress" = "Цільова адреса"
"monitorDesc" = "Залиште порожнім, щоб слухати всі IP-адреси" "monitorDesc" = "Залиште порожнім, щоб слухати всі IP-адреси"
"meansNoLimit" = " = Необмежено. (одиниця: ГБ)" "meansNoLimit" = "= Необмежено. (одиниця: ГБ)"
"totalFlow" = "Загальна витрата" "totalFlow" = "Загальна витрата"
"leaveBlankToNeverExpire" = "Залиште порожнім, щоб ніколи не закінчувався" "leaveBlankToNeverExpire" = "Залиште порожнім, щоб ніколи не закінчувався"
"noRecommendKeepDefault" = "Рекомендується зберегти значення за замовчуванням" "noRecommendKeepDefault" = "Рекомендується зберегти значення за замовчуванням"
@@ -309,14 +309,14 @@
"fragment" = "Фрагментація" "fragment" = "Фрагментація"
"fragmentDesc" = "Увімкнути фрагментацію для пакету привітання TLS" "fragmentDesc" = "Увімкнути фрагментацію для пакету привітання TLS"
"fragmentSett" = "Параметри фрагментації" "fragmentSett" = "Параметри фрагментації"
"noiseDesc" = "Увімкнути Noise." "noisesDesc" = "Увімкнути Noises."
"noiseSett" = "Налаштування Noise" "noisesSett" = "Налаштування Noises"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Передавати кілька незалежних потоків даних у межах встановленого потоку даних." "muxDesc" = "Передавати кілька незалежних потоків даних у межах встановленого потоку даних."
"muxSett" = "Налаштування Mux" "muxSett" = "Налаштування Mux"
"direct" = "Пряме підключення" "direct" = "Пряме підключення"
"directDesc" = "Безпосередньо встановлює з’єднання з доменами або діапазонами IP певної країни." "directDesc" = "Безпосередньо встановлює з’єднання з доменами або діапазонами IP певної країни."
"directSett" = "Параметри прямого підключення"
[pages.xray] [pages.xray]
"title" = "Xray конфігурації" "title" = "Xray конфігурації"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Журнали можуть вплинути на ефективність вашого сервера. Рекомендується вмикати його з розумом лише у випадку ваших потреб" "logConfigsDesc" = "Журнали можуть вплинути на ефективність вашого сервера. Рекомендується вмикати його з розумом лише у випадку ваших потреб"
"blockConfigs" = "Захисний екран" "blockConfigs" = "Захисний екран"
"blockConfigsDesc" = "Ці параметри блокуватимуть трафік на основі конкретних запитуваних протоколів і веб-сайтів." "blockConfigsDesc" = "Ці параметри блокуватимуть трафік на основі конкретних запитуваних протоколів і веб-сайтів."
"blockCountryConfigs" = "Заблокувати країну" "blockConnectionsConfigs" = "Блокувати з'єднання"
"blockCountryConfigsDesc" = "Ці параметри блокуватимуть трафік на основі конкретної запитуваної країни." "blockConnectionsConfigsDesc" = "Ці параметри блокуватимуть трафік на основі запитаних країн."
"directCountryConfigs" = "Пряма країна" "directConnectionsConfigs" = "Прямі з'єднання"
"directCountryConfigsDesc" = "Пряме підключення забезпечує, що конкретний трафік не маршрутизується через інший сервер." "directConnectionsConfigsDesc" = "Пряме з'єднання гарантує, що певний трафік не буде маршрутизовано через інший сервер."
"blockips" = "Блокувати IP"
"blockdomains" = "Блокувати домени"
"directips" = "Прямі IP"
"directdomains" = "Прямі домени"
"ipv4Configs" = "Маршрутизація IPv4" "ipv4Configs" = "Маршрутизація IPv4"
"ipv4ConfigsDesc" = "Ці параметри спрямовуватимуть трафік на основі певного призначення через IPv4." "ipv4ConfigsDesc" = "Ці параметри спрямовуватимуть трафік на основі певного призначення через IPv4."
"warpConfigs" = "WARP маршрутизація" "warpConfigs" = "WARP маршрутизація"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Блокує веб-сайти шкідливого програмного забезпечення, фішингу та майнерів." "SecurityDesc" = "Блокує веб-сайти шкідливого програмного забезпечення, фішингу та майнерів."
"Speedtest" = "Заблокувати Speedtest" "Speedtest" = "Заблокувати Speedtest"
"SpeedtestDesc" = "Блокує підключення до веб-сайтів для тестування швидкості." "SpeedtestDesc" = "Блокує підключення до веб-сайтів для тестування швидкості."
"IRIp" = "Блокувати підключення до IP-адрес Ірану"
"IRIpDesc" = "Блокує встановлення з'єднань з діапазонами IP Ірану."
"IRDomain" = "Блокувати підключення до доменів Ірану"
"IRDomainDesc" = "Блокує встановлення з'єднань з доменами Ірану."
"ChinaIp" = "Блокувати підключення до IP-адрес Китаю"
"ChinaIpDesc" = "Блокує встановлення з'єднань із діапазонами IP-адрес Китаю."
"ChinaDomain" = "Блокувати підключення до китайських доменів"
"ChinaDomainDesc" = "Блокує встановлення підключень до доменів Китаю."
"RussiaIp" = "Блокувати підключення до російських IP-адрес"
"RussiaIpDesc" = "Блокує встановлення з'єднань з діапазонами IP-адрес Росії."
"RussiaDomain" = "Блокувати підключення до російських доменів"
"RussiaDomainDesc" = "Блокує встановлення з'єднань з російськими доменами."
"VNIp" = "Блокувати підключення до IP-адрес В'єтнаму"
"VNIpDesc" = "Блокує встановлення з'єднань із діапазонами IP-адрес В'єтнаму."
"VNDomain" = "Блокувати підключення до доменів В'єтнаму"
"VNDomainDesc" = "Блокує встановлення з'єднань із доменами В'єтнаму."
"DirectIRIp" = "Пряме підключення до IP-адрес Ірану"
"DirectIRIpDesc" = "Безпосередньо встановлює з'єднання з діапазонами IP Ірану."
"DirectIRDomain" = "Пряме підключення до доменів Ірану"
"DirectIRDomainDesc" = "Безпосередньо встановлює підключення до доменів Ірану."
"DirectChinaIp" = "Пряме підключення до китайських IP-адрес"
"DirectChinaIpDesc" = "Безпосередньо встановлює підключення до IP-діапазонів Китаю."
"DirectChinaDomain" = "Пряме підключення до китайських доменів"
"DirectChinaDomainDesc" = "Безпосередньо встановлює підключення до доменів Китаю."
"DirectRussiaIp" = "Пряме підключення до IP-адрес Росії"
"DirectRussiaIpDesc" = "Безпосередньо встановлює з'єднання з діапазонами IP-адрес Росії."
"DirectRussiaDomain" = "Пряме підключення до російських доменів"
"DirectRussiaDomainDesc" = "Безпосередньо встановлює підключення до російських доменів."
"DirectVNIp" = "Пряме підключення до IP-адрес В'єтнаму"
"DirectVNIpDesc" = "Безпосередньо встановлює з'єднання з діапазонами IP-адрес В'єтнаму."
"DirectVNDomain" = "Пряме підключення до доменів В'єтнаму"
"DirectVNDomainDesc" = "Безпосередньо встановлює з'єднання з доменами В'єтнаму."
"GoogleIPv4" = "Google" "GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "Направляє трафік до Google через IPv4." "GoogleIPv4Desc" = "Направляє трафік до Google через IPv4."
"NetflixIPv4" = "Netflix" "NetflixIPv4" = "Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "Шлях до файлу журналу доступу. Спеціальне значення 'none' вимикає журнали доступу" "accessLogDesc" = "Шлях до файлу журналу доступу. Спеціальне значення 'none' вимикає журнали доступу"
"errorLog" = "Журнал помилок" "errorLog" = "Журнал помилок"
"errorLogDesc" = "Шлях до файлу журналу помилок. Спеціальне значення 'none' вимикає журнали помилок" "errorLogDesc" = "Шлях до файлу журналу помилок. Спеціальне значення 'none' вимикає журнали помилок"
"dnsLog" = "Журнал DNS"
"dnsLogDesc" = "Чи включити журнали запитів DNS"
"maskAddress" = "Маскувати Адресу"
"maskAddressDesc" = "Маска IP-адреси, при активації автоматично замінює IP-адресу, яка з'являється у журналі."
[pages.xray.rules] [pages.xray.rules]
"first" = "Перший" "first" = "Перший"
@@ -484,6 +460,7 @@
"add" = "Додати сервер" "add" = "Додати сервер"
"edit" = "Редагувати сервер" "edit" = "Редагувати сервер"
"domains" = "Домени" "domains" = "Домени"
"expectIPs" = "Очікувані IP"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Додати підроблений DNS" "add" = "Додати підроблений DNS"

View File

@@ -143,7 +143,7 @@
"destinationPort" = "Cổng đích" "destinationPort" = "Cổng đích"
"targetAddress" = "Địa chỉ mục tiêu" "targetAddress" = "Địa chỉ mục tiêu"
"monitorDesc" = "Mặc định để trống" "monitorDesc" = "Mặc định để trống"
"meansNoLimit" = " = Không giới hạn (đơn vị: GB)" "meansNoLimit" = "= Không giới hạn (đơn vị: GB)"
"totalFlow" = "Tổng lưu lượng" "totalFlow" = "Tổng lưu lượng"
"leaveBlankToNeverExpire" = "Để trống để không bao giờ hết hạn" "leaveBlankToNeverExpire" = "Để trống để không bao giờ hết hạn"
"noRecommendKeepDefault" = "Không yêu cầu đặc biệt để giữ nguyên cài đặt mặc định" "noRecommendKeepDefault" = "Không yêu cầu đặc biệt để giữ nguyên cài đặt mặc định"
@@ -309,14 +309,14 @@
"fragment" = "Sự phân mảnh" "fragment" = "Sự phân mảnh"
"fragmentDesc" = "Kích hoạt phân mảnh cho gói TLS hello" "fragmentDesc" = "Kích hoạt phân mảnh cho gói TLS hello"
"fragmentSett" = "Cài đặt phân mảnh" "fragmentSett" = "Cài đặt phân mảnh"
"noiseDesc" = "Bật Noise." "noisesDesc" = "Bật Noises."
"noiseSett" = "Cài đặt Noise" "noisesSett" = "Cài đặt Noises"
"mux" = "Mux" "mux" = "Mux"
"muxDesc" = "Truyền nhiều luồng dữ liệu độc lập trong luồng dữ liệu đã thiết lập." "muxDesc" = "Truyền nhiều luồng dữ liệu độc lập trong luồng dữ liệu đã thiết lập."
"muxSett" = "Mux Cài đặt" "muxSett" = "Mux Cài đặt"
"direct" = "Kết nối trực tiếp" "direct" = "Kết nối trực tiếp"
"directDesc" = "Trực tiếp thiết lập kết nối với tên miền hoặc dải IP của một quốc gia cụ thể." "directDesc" = "Trực tiếp thiết lập kết nối với tên miền hoặc dải IP của một quốc gia cụ thể."
"directSett" = "Tùy chọn kết nối trực tiếp"
[pages.xray] [pages.xray]
"title" = "Cài đặt Xray" "title" = "Cài đặt Xray"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "Nhật ký có thể ảnh hưởng đến hiệu suất máy chủ của bạn. Bạn chỉ nên kích hoạt nó một cách khôn ngoan trong trường hợp bạn cần" "logConfigsDesc" = "Nhật ký có thể ảnh hưởng đến hiệu suất máy chủ của bạn. Bạn chỉ nên kích hoạt nó một cách khôn ngoan trong trường hợp bạn cần"
"blockConfigs" = "Cấu hình Chặn" "blockConfigs" = "Cấu hình Chặn"
"blockConfigsDesc" = "Những tùy chọn này sẽ ngăn người dùng kết nối đến các giao thức và trang web cụ thể." "blockConfigsDesc" = "Những tùy chọn này sẽ ngăn người dùng kết nối đến các giao thức và trang web cụ thể."
"blockCountryConfigs" = "Cấu hình Chặn Quốc gia" "blockConnectionsConfigs" = "Chặn Kết Nối"
"blockCountryConfigsDesc" = "Những tùy chọn này sẽ ngăn người dùng kết nối đến các tên miền quốc gia cụ thể." "blockConnectionsConfigsDesc" = "Các tùy chọn này sẽ chặn lưu lượng truy cập dựa trên quốc gia được yêu cầu cụ thể."
"directCountryConfigs" = "Cấu hình Kết nối Trực tiếp Quốc gia" "directConnectionsConfigs" = "Kết Nối Trực Tiếp"
"directCountryConfigsDesc" = "Một kết nối trực tiếp đảm bảo rằng lưu lượng cụ thể không được định tuyến qua một máy chủ khác." "directConnectionsConfigsDesc" = "Kết nối trực tiếp đảm bảo rằng lưu lượng truy cập cụ thể không được định tuyến qua máy chủ khác."
"blockips" = "Chặn IP"
"blockdomains" = "Chặn Tên Miền"
"directips" = "IP Trực Tiếp"
"directdomains" = "Tên Miền Trực Tiếp"
"ipv4Configs" = "Cấu hình IPv4" "ipv4Configs" = "Cấu hình IPv4"
"ipv4ConfigsDesc" = "Những tùy chọn này sẽ chỉ định kết nối đến các tên miền mục tiêu qua IPv4." "ipv4ConfigsDesc" = "Những tùy chọn này sẽ chỉ định kết nối đến các tên miền mục tiêu qua IPv4."
"warpConfigs" = "Cấu hình WARP" "warpConfigs" = "Cấu hình WARP"
@@ -356,38 +360,6 @@
"SecurityDesc" = "Thay đổi mẫu cấu hình để bảo vệ Bảo mật." "SecurityDesc" = "Thay đổi mẫu cấu hình để bảo vệ Bảo mật."
"Speedtest" = "Chặn Trang web Speedtest" "Speedtest" = "Chặn Trang web Speedtest"
"SpeedtestDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các trang web Speedtest." "SpeedtestDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các trang web Speedtest."
"IRIp" = "Vô hiệu hóa kết nối đến dải IP của Iran"
"IRIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Iran."
"IRDomain" = "Vô hiệu hóa kết nối đến tên miền của Iran"
"IRDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Iran."
"ChinaIp" = "Vô hiệu hóa kết nối đến dải IP của Trung Quốc"
"ChinaIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Trung Quốc."
"ChinaDomain" = "Vô hiệu hóa kết nối đến tên miền của Trung Quốc"
"ChinaDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Trung Quốc."
"RussiaIp" = "Vô hiệu hóa kết nối đến dải IP của Nga"
"RussiaIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Nga."
"RussiaDomain" = "Vô hiệu hóa kết nối đến tên miền của Nga"
"RussiaDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Nga."
"VNIp" = "Vô hiệu hóa kết nối đến dải IP của Việt Nam"
"VNIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Việt Nam."
"VNDomain" = "Vô hiệu hóa kết nối đến tên miền của Việt Nam"
"VNDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Việt Nam."
"DirectIRIp" = "Kết nối trực tiếp đến dải IP của Iran"
"DirectIRIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Iran."
"DirectIRDomain" = "Kết nối trực tiếp đến tên miền của Iran"
"DirectIRDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Iran."
"DirectChinaIp" = "Kết nối trực tiếp đến dải IP của Trung Quốc"
"DirectChinaIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Trung Quốc."
"DirectChinaDomain" = "Kết nối trực tiếp đến tên miền của Trung Quốc"
"DirectChinaDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Trung Quốc."
"DirectRussiaIp" = "Kết nối trực tiếp đến dải IP của Nga"
"DirectRussiaIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Nga."
"DirectRussiaDomain" = "Kết nối trực tiếp đến tên miền của Nga"
"DirectRussiaDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Nga."
"DirectVNIp" = "Kết nối trực tiếp đến dải IP của Việt Nam"
"DirectVNIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Việt Nam"
"DirectVNDomain" = "Kết nối trực tiếp đến tên miền của Việt Nam"
"DirectVNDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Việt Nam."
"GoogleIPv4" = "Sử dụng IPv4 cho Google" "GoogleIPv4" = "Sử dụng IPv4 cho Google"
"GoogleIPv4Desc" = "Thêm định tuyến cho Google để kết nối qua IPv4." "GoogleIPv4Desc" = "Thêm định tuyến cho Google để kết nối qua IPv4."
"NetflixIPv4" = "Sử dụng IPv4 cho Netflix" "NetflixIPv4" = "Sử dụng IPv4 cho Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "Đường dẫn tệp cho nhật ký truy cập. Nhật ký truy cập bị vô hiệu hóa có giá trị đặc biệt 'không'" "accessLogDesc" = "Đường dẫn tệp cho nhật ký truy cập. Nhật ký truy cập bị vô hiệu hóa có giá trị đặc biệt 'không'"
"errorLog" = "Nhật ký lỗi" "errorLog" = "Nhật ký lỗi"
"errorLogDesc" = "Đường dẫn tệp cho nhật ký lỗi. Nhật ký lỗi bị vô hiệu hóa có giá trị đặc biệt 'không'" "errorLogDesc" = "Đường dẫn tệp cho nhật ký lỗi. Nhật ký lỗi bị vô hiệu hóa có giá trị đặc biệt 'không'"
"dnsLog" = "Nhật ký DNS"
"dnsLogDesc" = "Có bật nhật ký truy vấn DNS không"
"maskAddress" = "Ẩn Địa Chỉ"
"maskAddressDesc" = "Mặt nạ địa chỉ IP, khi được bật, sẽ tự động thay thế địa chỉ IP xuất hiện trong nhật ký."
[pages.xray.rules] [pages.xray.rules]
"first" = "Đầu tiên" "first" = "Đầu tiên"
@@ -484,6 +460,7 @@
"add" = "Thêm máy chủ" "add" = "Thêm máy chủ"
"edit" = "Chỉnh sửa máy chủ" "edit" = "Chỉnh sửa máy chủ"
"domains" = "Tên miền" "domains" = "Tên miền"
"expectIPs" = "Các IP Dự Kiến"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "Thêm DNS giả" "add" = "Thêm DNS giả"

View File

@@ -143,7 +143,7 @@
"destinationPort" = "目标端口" "destinationPort" = "目标端口"
"targetAddress" = "目标地址" "targetAddress" = "目标地址"
"monitorDesc" = "留空表示监听所有 IP" "monitorDesc" = "留空表示监听所有 IP"
"meansNoLimit" = " = 无限制单位GB)" "meansNoLimit" = "= 无限制单位GB)"
"totalFlow" = "总流量" "totalFlow" = "总流量"
"leaveBlankToNeverExpire" = "留空表示永不过期" "leaveBlankToNeverExpire" = "留空表示永不过期"
"noRecommendKeepDefault" = "建议保留默认值" "noRecommendKeepDefault" = "建议保留默认值"
@@ -309,14 +309,14 @@
"fragment" = "分片" "fragment" = "分片"
"fragmentDesc" = "启用 TLS hello 数据包分片" "fragmentDesc" = "启用 TLS hello 数据包分片"
"fragmentSett" = "设置" "fragmentSett" = "设置"
"noiseDesc" = "启用 Noise." "noisesDesc" = "启用 Noises."
"noiseSett" = "Noise 设置" "noisesSett" = "Noises 设置"
"mux" = "多路复用器" "mux" = "多路复用器"
"muxDesc" = "在已建立的数据流内传输多个独立的数据流" "muxDesc" = "在已建立的数据流内传输多个独立的数据流"
"muxSett" = "复用器设置" "muxSett" = "复用器设置"
"direct" = "直接连接" "direct" = "直接连接"
"directDesc" = "直接与特定国家的域或IP范围建立连接" "directDesc" = "直接与特定国家的域或IP范围建立连接"
"directSett" = "直接连接选项"
[pages.xray] [pages.xray]
"title" = "Xray 配置" "title" = "Xray 配置"
@@ -330,10 +330,14 @@
"logConfigsDesc" = "日志可能会影响服务器的性能,建议仅在需要时启用" "logConfigsDesc" = "日志可能会影响服务器的性能,建议仅在需要时启用"
"blockConfigs" = "防护屏蔽" "blockConfigs" = "防护屏蔽"
"blockConfigsDesc" = "这些选项将阻止用户连接到特定协议和网站" "blockConfigsDesc" = "这些选项将阻止用户连接到特定协议和网站"
"blockCountryConfigs" = "屏蔽国家/地区" "blockConnectionsConfigs" = "阻止连接"
"blockCountryConfigsDesc" = "这些选项将阻止用户连接到特定国家/地区" "blockConnectionsConfigsDesc" = "这些选项将根据特定的请求国家阻止流量。"
"directCountryConfigs" = "直连国家/地区" "directConnectionsConfigs" = "直接连接"
"directCountryConfigsDesc" = "直接连接确保特定流量不会通过其他服务器路由" "directConnectionsConfigsDesc" = "直接连接确保特定流量不会通过其他服务器路由"
"blockips" = "阻止IP"
"blockdomains" = "阻止域名"
"directips" = "直接IP"
"directdomains" = "直接域名"
"ipv4Configs" = "IPv4 路由" "ipv4Configs" = "IPv4 路由"
"ipv4ConfigsDesc" = "此选项将仅通过 IPv4 路由到目标域" "ipv4ConfigsDesc" = "此选项将仅通过 IPv4 路由到目标域"
"warpConfigs" = "WARP 路由" "warpConfigs" = "WARP 路由"
@@ -356,38 +360,6 @@
"SecurityDesc" = "屏蔽恶意软件、网络钓鱼和挖矿网站" "SecurityDesc" = "屏蔽恶意软件、网络钓鱼和挖矿网站"
"Speedtest" = "屏蔽测速网站" "Speedtest" = "屏蔽测速网站"
"SpeedtestDesc" = "阻止连接到测速网站" "SpeedtestDesc" = "阻止连接到测速网站"
"IRIp" = "屏蔽连接到伊朗 IP"
"IRIpDesc" = "阻止建立到伊朗 IP 范围的连接"
"IRDomain" = "屏蔽连接到伊朗域名"
"IRDomainDesc" = "阻止建立到伊朗域名的连接"
"ChinaIp" = "屏蔽连接到中国 IP"
"ChinaIpDesc" = "阻止建立到中国 IP 范围的连接"
"ChinaDomain" = "屏蔽连接到中国域名"
"ChinaDomainDesc" = "阻止建立到中国域名的连接"
"RussiaIp" = "屏蔽连接到俄罗斯 IP"
"RussiaIpDesc" = "阻止建立到俄罗斯 IP 范围的连接"
"RussiaDomain" = "屏蔽连接到俄罗斯域名"
"RussiaDomainDesc" = "阻止建立到俄罗斯域名的连接"
"VNIp" = "屏蔽连接到越南 IP"
"VNIpDesc" = "阻止建立到越南 IP 范围的连接"
"VNDomain" = "屏蔽连接到越南域名"
"VNDomainDesc" = "阻止建立到越南域名的连接"
"DirectIRIp" = "直连伊朗 IP"
"DirectIRIpDesc" = "直接建立到伊朗 IP 范围的连接"
"DirectIRDomain" = "直连伊朗域名"
"DirectIRDomainDesc" = "直接建立到伊朗域名的连接"
"DirectChinaIp" = "直连中国 IP"
"DirectChinaIpDesc" = "直接建立到中国 IP 范围的连接"
"DirectChinaDomain" = "直连中国域名"
"DirectChinaDomainDesc" = "直接建立到中国域名的连接"
"DirectRussiaIp" = "直连俄罗斯 IP"
"DirectRussiaIpDesc" = "直接建立到俄罗斯 IP 范围的连接"
"DirectRussiaDomain" = "直连俄罗斯域名"
"DirectRussiaDomainDesc" = "直接建立到俄罗斯域名的连接"
"DirectVNIp" = "直连越南 IP"
"DirectVNIpDesc" = "直接建立到越南 IP 范围的连接"
"DirectVNDomain" = "直连越南域名"
"DirectVNDomainDesc" = "直接建立到越南域名的连接"
"GoogleIPv4" = "Google" "GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "通过 IPv4 将流量路由到谷歌" "GoogleIPv4Desc" = "通过 IPv4 将流量路由到谷歌"
"NetflixIPv4" = "Netflix" "NetflixIPv4" = "Netflix"
@@ -422,6 +394,10 @@
"accessLogDesc" = "访问日志的文件路径。特殊值 'none' 禁用访问日志" "accessLogDesc" = "访问日志的文件路径。特殊值 'none' 禁用访问日志"
"errorLog" = "错误日志" "errorLog" = "错误日志"
"errorLogDesc" = "错误日志的文件路径。特殊值 'none' 禁用错误日志" "errorLogDesc" = "错误日志的文件路径。特殊值 'none' 禁用错误日志"
"dnsLog" = "DNS 日志"
"dnsLogDesc" = "是否启用 DNS 查询日志"
"maskAddress" = "隐藏地址"
"maskAddressDesc" = "IP 地址掩码,启用时会自动替换日志中出现的 IP 地址。"
[pages.xray.rules] [pages.xray.rules]
"first" = "置顶" "first" = "置顶"
@@ -484,6 +460,7 @@
"add" = "添加服务器" "add" = "添加服务器"
"edit" = "编辑服务器" "edit" = "编辑服务器"
"domains" = "域" "domains" = "域"
"expectIPs" = "预期 IP"
[pages.xray.fakedns] [pages.xray.fakedns]
"add" = "添加假 DNS" "add" = "添加假 DNS"
@@ -497,7 +474,7 @@
"loginSecurity" = "登录安全" "loginSecurity" = "登录安全"
"loginSecurityDesc" = "添加额外的身份验证以提高安全性" "loginSecurityDesc" = "添加额外的身份验证以提高安全性"
"secretToken" = "安全令牌" "secretToken" = "安全令牌"
"secretTokenDesc" = "请将此令牌存储在安全的地方。此令牌用于登录,丢失无法恢复。" "secretTokenDesc" = "请将此令牌存储在安全的地方。此令牌用于登录,丢失无法恢复。"
[pages.settings.toasts] [pages.settings.toasts]
"modifySettings" = "修改设置" "modifySettings" = "修改设置"

32
x-ui.sh
View File

@@ -36,12 +36,12 @@ fi
echo "The OS release is: $release" echo "The OS release is: $release"
os_version="" os_version=""
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1) os_version=$(grep "^VERSION_ID" /etc/os-release | cut -d '=' -f2 | tr -d '"' | tr -d '.')
if [[ "${release}" == "arch" ]]; then if [[ "${release}" == "arch" ]]; then
echo "Your OS is Arch Linux" echo "Your OS is Arch Linux"
elif [[ "${release}" == "parch" ]]; then elif [[ "${release}" == "parch" ]]; then
echo "Your OS is Parch linux" echo "Your OS is Parch Linux"
elif [[ "${release}" == "manjaro" ]]; then elif [[ "${release}" == "manjaro" ]]; then
echo "Your OS is Manjaro" echo "Your OS is Manjaro"
elif [[ "${release}" == "armbian" ]]; then elif [[ "${release}" == "armbian" ]]; then
@@ -53,24 +53,28 @@ elif [[ "${release}" == "centos" ]]; then
echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1 echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "ubuntu" ]]; then elif [[ "${release}" == "ubuntu" ]]; then
if [[ ${os_version} -lt 20 ]]; then if [[ ${os_version} -lt 2004 ]]; then
echo -e "${red} Please use Ubuntu 20 or higher version!${plain}\n" && exit 1 echo -e "${red} Please use Ubuntu 20 or higher version!${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "fedora" ]]; then elif [[ "${release}" == "fedora" ]]; then
if [[ ${os_version} -lt 36 ]]; then if [[ ${os_version} -lt 36 ]]; then
echo -e "${red} Please use Fedora 36 or higher version!${plain}\n" && exit 1 echo -e "${red} Please use Fedora 36 or higher version!${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "amzn" ]]; then
if [[ ${os_version} != "2023" ]]; then
echo -e "${red} Please use Amazon Linux 2023!${plain}\n" && exit 1
fi
elif [[ "${release}" == "debian" ]]; then elif [[ "${release}" == "debian" ]]; then
if [[ ${os_version} -lt 11 ]]; then if [[ ${os_version} -lt 11 ]]; then
echo -e "${red} Please use Debian 11 or higher ${plain}\n" && exit 1 echo -e "${red} Please use Debian 11 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "almalinux" ]]; then elif [[ "${release}" == "almalinux" ]]; then
if [[ ${os_version} -lt 9 ]]; then if [[ ${os_version} -lt 80 ]]; then
echo -e "${red} Please use AlmaLinux 9 or higher ${plain}\n" && exit 1 echo -e "${red} Please use AlmaLinux 8.0 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "rocky" ]]; then elif [[ "${release}" == "rocky" ]]; then
if [[ ${os_version} -lt 9 ]]; then if [[ ${os_version} -lt 8 ]]; then
echo -e "${red} Please use Rocky Linux 9 or higher ${plain}\n" && exit 1 echo -e "${red} Please use Rocky Linux 8 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "oracle" ]]; then elif [[ "${release}" == "oracle" ]]; then
if [[ ${os_version} -lt 8 ]]; then if [[ ${os_version} -lt 8 ]]; then
@@ -87,12 +91,12 @@ else
echo "- Parch Linux" echo "- Parch Linux"
echo "- Manjaro" echo "- Manjaro"
echo "- Armbian" echo "- Armbian"
echo "- AlmaLinux 9+" echo "- AlmaLinux 8.0+"
echo "- Rocky Linux 9+" echo "- Rocky Linux 8+"
echo "- Oracle Linux 8+" echo "- Oracle Linux 8+"
echo "- OpenSUSE Tumbleweed" echo "- OpenSUSE Tumbleweed"
echo "- Amazon Linux 2023"
exit 1 exit 1
fi fi
# Declare Variables # Declare Variables
@@ -474,7 +478,7 @@ enable_bbr() {
centos | almalinux | rocky | oracle) centos | almalinux | rocky | oracle)
yum -y update && yum -y install ca-certificates yum -y update && yum -y install ca-certificates
;; ;;
fedora) fedora | amzn)
dnf -y update && dnf -y install ca-certificates dnf -y update && dnf -y install ca-certificates
;; ;;
arch | manjaro | parch) arch | manjaro | parch)
@@ -814,7 +818,7 @@ ssl_cert_issue() {
centos | almalinux | rocky | oracle) centos | almalinux | rocky | oracle)
yum -y update && yum -y install socat yum -y update && yum -y install socat
;; ;;
fedora) fedora | amzn)
dnf -y update && dnf -y install socat dnf -y update && dnf -y install socat
;; ;;
arch | manjaro | parch) arch | manjaro | parch)
@@ -1165,7 +1169,7 @@ install_iplimit() {
yum update -y && yum install epel-release -y yum update -y && yum install epel-release -y
yum -y install fail2ban yum -y install fail2ban
;; ;;
fedora) fedora | amzn)
dnf -y update && dnf -y install fail2ban dnf -y update && dnf -y install fail2ban
;; ;;
arch | manjaro | parch) arch | manjaro | parch)
@@ -1246,7 +1250,7 @@ remove_iplimit() {
yum remove fail2ban -y yum remove fail2ban -y
yum autoremove -y yum autoremove -y
;; ;;
fedora) fedora | amzn)
dnf remove fail2ban -y dnf remove fail2ban -y
dnf autoremove -y dnf autoremove -y
;; ;;

View File

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