From 11cda8e7296ae5339edbbc9c923a555f4dcb7f23 Mon Sep 17 00:00:00 2001
From: Denis Vasilev <89912505+vasiljevdenis@users.noreply.github.com>
Date: Mon, 22 Dec 2025 00:58:48 +0300
Subject: [PATCH 01/17] fix panel url
---
install.sh | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/install.sh b/install.sh
index 01a67c2..0116fc1 100644
--- a/install.sh
+++ b/install.sh
@@ -45,9 +45,36 @@ echo ""
# ВВОД ДАННЫХ
#################################
-read -rp "URL панели 3x-ui (с портом и путем): " UI_URL
-UI_URL="${UI_URL%/}"
-validate_url "$UI_URL" || die "Некорректный URL 3x-ui"
+# Функция для получения URL панели из 3x-ui
+get_xui_url() {
+ # Пытаемся выполнить x-ui settings и вытащить строку Access URL
+ local output
+ output=$(x-ui settings 2>/dev/null | grep "Access URL:" | head -1)
+
+ if [[ -n "$output" ]]; then
+ # Обрезаем всё до последнего пробела и берём URL
+ echo "$output" | awk -F': ' '{print $2}' | sed 's/ *$//'
+ return 0
+ else
+ return 1
+ fi
+}
+
+echo "Определяем URL панели 3x-ui..."
+
+UI_URL=$(get_xui_url)
+
+if [[ -n "$UI_URL" ]]; then
+ UI_URL="${UI_URL%/}" # убираем trailing slash, если есть
+ echo "URL панели 3x-ui: $UI_URL"
+else
+ echo "Не удалось автоматически получить URL"
+ read -rp "Введите URL панели 3x-ui вручную (полная ссылка): " UI_URL
+ UI_URL="${UI_URL%/}"
+fi
+
+# Проверка корректности URL
+validate_url "$UI_URL" || die "Некорректный URL панели 3x-ui: $UI_URL"
read -rp "Логин 3x-ui: " UI_LOGIN
read -rsp "Пароль 3x-ui: " UI_PASSWORD
From 428d43a63dcd4e04d38ab1d3b9ae145199a840eb Mon Sep 17 00:00:00 2001
From: Denis Vasilev <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 11:14:40 +0300
Subject: [PATCH 02/17] readme, fix inbound link, auto url
---
README.md | 170 +++-
README_EN.md | 12 +-
app/assets/flags.json | 1307 ++++++++++++++++++++++++++++++
app/builders/buildInboundLink.js | 12 +-
app/index.js | 2 +-
forwarding_install.sh | 2 +-
install.sh | 25 +-
update.sh | 2 +-
8 files changed, 1483 insertions(+), 49 deletions(-)
create mode 100644 app/assets/flags.json
diff --git a/README.md b/README.md
index 6d6f0d0..f703091 100644
--- a/README.md
+++ b/README.md
@@ -1,63 +1,167 @@
-[English](https://github.com/denpiligrim/3dp-manager/blob/main/README_EN.md)
+[English](/README_EN.md) | [中文](/README_CN.md) | [فارسی](/README_IR.md) | [Türkmençe](/README_TK.md)
+
+

+
+ [](https://www.gnu.org/licenses/gpl-3.0) [](https://t.me/denpiligrim_web) [](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
-> [!WARNING]
-> **Это бета-версия!**
->
-> Программа находится в активной разработке. Возможны баги, нестабильность и изменения API.
-> Используйте с осторожностью.
+Утилита для автогенерации инбаундов к панели [3x-ui](https://github.com/MHSanaei/3x-ui), формирования единой подписки и настройки перенаправления трафика с промежуточного сервера на основной.
-3DP-MANAGER — утилита, которая позволяет регулярно генерировать входящие подключения для панели 3X-UI на основе списка разрешённых доменов (whitelist). Белый список общий, но вы также можете добавить свой собственный список, назвав его `my_whitelist.txt` и поместив его в папку `/opt/3dp-manager/app` на вашем сервере.
-Обсуждения доступны в Телеграм канале: [@denpiligrim_web](https://t.me/denpiligrim_web/719)
+**Поддержать проект**
-### Установка
-```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
-```
+- Реквизиты / донаты:
+ - Карта МИР: `2204320436318077`
+ - Карта MasterCard: `5395452209474530`
+ - PayPal: `vasiljevdenisx@gmail.com`
+ - USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
+ - USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
+ - Bitcoin: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
+ - TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
+ - Bybit ID: `165292278`
-### Обновление
-```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
-```
+## Описание
-### Удаление
-```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
-```
+Главная цель утилиты — сделать так, чтобы ваш трафик не выглядел одинаковым. Бот генерирует по заданному интервалу 10 подключений с разными параметрами:
+
+- протоколы: `vless`, `vmess`, `shadowsocks`, `trojan`;
+- порты: `443`, `8443` (фиксированные) и случайные из диапазона `10000-60000`;
+- транспорт: `tcp`, `websocket`, `grpc`, `xhttp`;
+- SNI берутся из белого списка доменов (whitelist); можно использовать свой список.
+
+Все подключения объединяются в одну подписку со статичным URL. Бот работает с панелью `3x-ui` и не вмешивается в её работу напрямую, используя открытое API панели.
+
+Вторичная цель — стабильность подключения: клиент получает 10 вариантов поключений и может выбрать любое из них.
+
+Дополнительно: бот можно использовать в каскадной схеме. Сервис перенаправления автоматически настроит переадресацию подписки и трафика к основному серверу.
+
+Рекомендации:
+
+- Используйте HTTPS для подписки (домен + SSL сертификат).
+- Интервал генерации задавайте ≥ 10 минут; для стабильности рекомендуется — раз в сутки (1440 минут).
+- В клиенте установите автообновление чаще (например, каждый час), чтобы была синхронизация с сервером.
+
+## Возможности
+
+- Генерация 10 разнообразных подключений
+- Формирование единой подписки со статичным URL
+- Поддержка кастомного `whitelist` доменов
+- Автоматическая настройка перенаправления трафика (опционально)
+
+## Требования
+
+- Ubuntu 20.04 (и выше)
+- Панель `3x-ui`
+- Домен + SSL сертификат (опционально)
---
-Сервис подписок и перенаправления входящего трафика работает совместно с **3DP-MANAGER** и позволяет перенаправлять весь входящий трафик с промежуточного сервера на основной сервер. Перенаправляются те же порты: `443`, `8443` и диапазон `10000-60000`. Сервис также создаёт ссылку на подписку, автоматически заменяя IP-адрес или домен в конфигурациях. Перенаправления настраиваются добавлением правил iptables в конфигурационный файл ufw, что обеспечивает стабильную работу в сочетании с файрволом. Рекомендуется устанавливать сервис на чистый сервер без ранее настроенных правил.
+## Установка
+
+Установите проект на сервер командой:
-### Установка перенаправления
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
```
-### Удаление перенаправления
+Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы.
+
+## Обновление
+
+Обновление до последней версии:
+
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
```
+Краткое описание: подтягивает последние изменения и перезапускает контейнеры.
+
+## Удаление
+
+Полное удаление сервиса:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+```
+
+Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки.
+
---
-### Показать URL подписки
+## Установка сервиса перенаправления (forwarding)
+
+Сервис перенаправления позволяет проксировать входящие порты с промежуточного сервера на основной.
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+```
+
+Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки.
+
+## Удаление перенаправления
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+```
+
+Краткое описание: удаляет правила и отключает сервис перенаправления.
+
+---
+
+## Показать URL подписки
+
+Команда для вывода текущего URL подписки из среды контейнера:
+
```bash
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
----
+Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на оснвном, так и на промежуточном сервере.
+
+## Сбор доменов из мульти-подписок
+
+Утилита извлекает домены из подписок и формирует `whitelist` для генератора.
-### Утилита для сбора доменов из мульти-подписок
-Позволяет собирать домены из подписок с несколькими конфигурациями. В интернете встречается много подобных списков конфигураций, использующих белый SNI. Инструмент позволяет извлечь домены и подготовить готовый список для дальнейшего использования в генераторе входящих подключений.
-Вставьте ссылку на подписку в скрипт и запустите команду в окружении `Node.js`.
```bash
node get_domains.js
```
-### Использовать свой белый список
-Файл должен иметь структуру аналогичную `whitelist.txt`. Переименуйте имя файла на `my_whitelist.txt`. Загрузите файл в папку `/opt/3dp-manager/app` на сервере и выполните команду:
+Краткое описание: добавьте ссылку на мульти-подписку в скрипт и запустите команду — на выходе получите список доменов. Неободим `Node.js` для работы скрипта.
+
+## Использование собственного белого списка
+
+1. Подготовьте файл в формате `whitelist.txt`.
+2. Переименуйте на `my_whitelist.txt` и скопируйте в папку `/opt/3dp-manager/app`.
+
```bash
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
-```
\ No newline at end of file
+```
+
+Краткое описание: добавляет ваш файл доменов в контейнер приложения.
+
+---
+
+## Замечания и текущие ограничения
+
+- Общий список доменов работает не у всех провайдеров, поэтому рекомендуется составить и использовать свой whitelist.
+
+---
+
+## Внести вклад
+
+Буду рад любому вкладу в разработку проекта! Простой процесс для контрибьюторов:
+
+1. Форкните репозиторий на GitHub.
+2. Создайте ветку с осмысленным именем, например `feature/add-README` или `fix/whitelist-load`.
+3. Внесите изменения и добавьте короткое описание в коммите.
+4. Запустите локально базовые проверки (если есть).
+5. Отправьте ветку в ваш форк и создайте Pull Request в основной репозиторий.
+
+Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты.
+
+---
+
+## Обсуждение
+
+- Телеграм: [@denpiligrim_web](https://t.me/denpiligrim_web)
+- Раздел Issues в данном репозитории
\ No newline at end of file
diff --git a/README_EN.md b/README_EN.md
index 50dd28e..eadb1f4 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,4 +1,4 @@
-[Русский](https://github.com/denpiligrim/3dp-manager/blob/main/README.md)
+[Русский](https://github.com/denpiligrim/3dp-manager/blob/dp-fix/README.md)
# 3DP-MANAGER
@@ -13,17 +13,17 @@ Discussions are available on the Telegram channel: [@denpiligrim_web](https://t.
### Install
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
```
### Update
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
```
### Delete
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
```
---
@@ -31,12 +31,12 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
The subscription and inbound redirection service works in conjunction with **3DP-MANAGER** and allows you to redirect all inbound traffic from the intermediate server to the main server. The same ports are redirected, namely `443`, `8443`, and the range `10000-60000`. The service also creates a link to the subscription, automatically replacing the IP address or domain in the configurations. Redirects are configured by adding iptables rules to the ufw configuration file, which ensures stable operation in conjunction with the firewall. It is recommended to install the service on a clean server without any previously installed rules.
### Install forwarding
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
```
### Delete forwarding
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
```
---
diff --git a/app/assets/flags.json b/app/assets/flags.json
new file mode 100644
index 0000000..4c0a92a
--- /dev/null
+++ b/app/assets/flags.json
@@ -0,0 +1,1307 @@
+[
+ {
+ "name": "Ascension Island",
+ "code": "AC",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%A8"
+ },
+ {
+ "name": "Andorra",
+ "code": "AD",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%A9"
+ },
+ {
+ "name": "United Arab Emirates",
+ "code": "AE",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%AA"
+ },
+ {
+ "name": "Afghanistan",
+ "code": "AF",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%AB"
+ },
+ {
+ "name": "Antigua & Barbuda",
+ "code": "AG",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%AC"
+ },
+ {
+ "name": "Anguilla",
+ "code": "AI",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%AE"
+ },
+ {
+ "name": "Albania",
+ "code": "AL",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B1"
+ },
+ {
+ "name": "Armenia",
+ "code": "AM",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B2"
+ },
+ {
+ "name": "Angola",
+ "code": "AO",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B4"
+ },
+ {
+ "name": "Antarctica",
+ "code": "AQ",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B6"
+ },
+ {
+ "name": "Argentina",
+ "code": "AR",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B7"
+ },
+ {
+ "name": "American Samoa",
+ "code": "AS",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B8"
+ },
+ {
+ "name": "Austria",
+ "code": "AT",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%B9"
+ },
+ {
+ "name": "Australia",
+ "code": "AU",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%BA"
+ },
+ {
+ "name": "Aruba",
+ "code": "AW",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%BC"
+ },
+ {
+ "name": "Åland Islands",
+ "code": "AX",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%BD"
+ },
+ {
+ "name": "Azerbaijan",
+ "code": "AZ",
+ "emoji": "%F0%9F%87%A6%F0%9F%87%BF"
+ },
+ {
+ "name": "Bosnia & Herzegovina",
+ "code": "BA",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%A6"
+ },
+ {
+ "name": "Barbados",
+ "code": "BB",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%A7"
+ },
+ {
+ "name": "Bangladesh",
+ "code": "BD",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%A9"
+ },
+ {
+ "name": "Belgium",
+ "code": "BE",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%AA"
+ },
+ {
+ "name": "Burkina Faso",
+ "code": "BF",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%AB"
+ },
+ {
+ "name": "Bulgaria",
+ "code": "BG",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%AC"
+ },
+ {
+ "name": "Bahrain",
+ "code": "BH",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%AD"
+ },
+ {
+ "name": "Burundi",
+ "code": "BI",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%AE"
+ },
+ {
+ "name": "Benin",
+ "code": "BJ",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%AF"
+ },
+ {
+ "name": "St. Barthélemy",
+ "code": "BL",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B1"
+ },
+ {
+ "name": "Bermuda",
+ "code": "BM",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B2"
+ },
+ {
+ "name": "Brunei",
+ "code": "BN",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B3"
+ },
+ {
+ "name": "Bolivia",
+ "code": "BO",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B4"
+ },
+ {
+ "name": "Caribbean Netherlands",
+ "code": "BQ",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B6"
+ },
+ {
+ "name": "Brazil",
+ "code": "BR",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B7"
+ },
+ {
+ "name": "Bahamas",
+ "code": "BS",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B8"
+ },
+ {
+ "name": "Bhutan",
+ "code": "BT",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%B9"
+ },
+ {
+ "name": "Bouvet Island",
+ "code": "BV",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%BB"
+ },
+ {
+ "name": "Botswana",
+ "code": "BW",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%BC"
+ },
+ {
+ "name": "Belarus",
+ "code": "BY",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%BE"
+ },
+ {
+ "name": "Belize",
+ "code": "BZ",
+ "emoji": "%F0%9F%87%A7%F0%9F%87%BF"
+ },
+ {
+ "name": "Canada",
+ "code": "CA",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%A6"
+ },
+ {
+ "name": "Cocos (Keeling) Islands",
+ "code": "CC",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%A8"
+ },
+ {
+ "name": "Congo - Kinshasa",
+ "code": "CD",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%A9"
+ },
+ {
+ "name": "Central African Republic",
+ "code": "CF",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%AB"
+ },
+ {
+ "name": "Congo - Brazzaville",
+ "code": "CG",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%AC"
+ },
+ {
+ "name": "Switzerland",
+ "code": "CH",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%AD"
+ },
+ {
+ "name": "Côte d’Ivoire",
+ "code": "CI",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%AE"
+ },
+ {
+ "name": "Cook Islands",
+ "code": "CK",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B0"
+ },
+ {
+ "name": "Chile",
+ "code": "CL",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B1"
+ },
+ {
+ "name": "Cameroon",
+ "code": "CM",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B2"
+ },
+ {
+ "name": "China",
+ "code": "CN",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B3"
+ },
+ {
+ "name": "Colombia",
+ "code": "CO",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B4"
+ },
+ {
+ "name": "Clipperton Island",
+ "code": "CP",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B5"
+ },
+ {
+ "name": "Costa Rica",
+ "code": "CR",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%B7"
+ },
+ {
+ "name": "Cuba",
+ "code": "CU",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%BA"
+ },
+ {
+ "name": "Cape Verde",
+ "code": "CV",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%BB"
+ },
+ {
+ "name": "Curaçao",
+ "code": "CW",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%BC"
+ },
+ {
+ "name": "Christmas Island",
+ "code": "CX",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%BD"
+ },
+ {
+ "name": "Cyprus",
+ "code": "CY",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%BE"
+ },
+ {
+ "name": "Czechia",
+ "code": "CZ",
+ "emoji": "%F0%9F%87%A8%F0%9F%87%BF"
+ },
+ {
+ "name": "Germany",
+ "code": "DE",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%AA"
+ },
+ {
+ "name": "Diego Garcia",
+ "code": "DG",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%AC"
+ },
+ {
+ "name": "Djibouti",
+ "code": "DJ",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%AF"
+ },
+ {
+ "name": "Denmark",
+ "code": "DK",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%B0"
+ },
+ {
+ "name": "Dominica",
+ "code": "DM",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%B2"
+ },
+ {
+ "name": "Dominican Republic",
+ "code": "DO",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%B4"
+ },
+ {
+ "name": "Algeria",
+ "code": "DZ",
+ "emoji": "%F0%9F%87%A9%F0%9F%87%BF"
+ },
+ {
+ "name": "Ceuta & Melilla",
+ "code": "EA",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%A6"
+ },
+ {
+ "name": "Ecuador",
+ "code": "EC",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%A8"
+ },
+ {
+ "name": "Estonia",
+ "code": "EE",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%AA"
+ },
+ {
+ "name": "Egypt",
+ "code": "EG",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%AC"
+ },
+ {
+ "name": "Western Sahara",
+ "code": "EH",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%AD"
+ },
+ {
+ "name": "Eritrea",
+ "code": "ER",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%B7"
+ },
+ {
+ "name": "Spain",
+ "code": "ES",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%B8"
+ },
+ {
+ "name": "Ethiopia",
+ "code": "ET",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%B9"
+ },
+ {
+ "name": "European Union",
+ "code": "EU",
+ "emoji": "%F0%9F%87%AA%F0%9F%87%BA"
+ },
+ {
+ "name": "Finland",
+ "code": "FI",
+ "emoji": "%F0%9F%87%AB%F0%9F%87%AE"
+ },
+ {
+ "name": "Fiji",
+ "code": "FJ",
+ "emoji": "%F0%9F%87%AB%F0%9F%87%AF"
+ },
+ {
+ "name": "Falkland Islands",
+ "code": "FK",
+ "emoji": "%F0%9F%87%AB%F0%9F%87%B0"
+ },
+ {
+ "name": "Micronesia",
+ "code": "FM",
+ "emoji": "%F0%9F%87%AB%F0%9F%87%B2"
+ },
+ {
+ "name": "Faroe Islands",
+ "code": "FO",
+ "emoji": "%F0%9F%87%AB%F0%9F%87%B4"
+ },
+ {
+ "name": "France",
+ "code": "FR",
+ "emoji": "%F0%9F%87%AB%F0%9F%87%B7"
+ },
+ {
+ "name": "Gabon",
+ "code": "GA",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%A6"
+ },
+ {
+ "name": "United Kingdom",
+ "code": "GB",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%A7"
+ },
+ {
+ "name": "Grenada",
+ "code": "GD",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%A9"
+ },
+ {
+ "name": "Georgia",
+ "code": "GE",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%AA"
+ },
+ {
+ "name": "French Guiana",
+ "code": "GF",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%AB"
+ },
+ {
+ "name": "Guernsey",
+ "code": "GG",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%AC"
+ },
+ {
+ "name": "Ghana",
+ "code": "GH",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%AD"
+ },
+ {
+ "name": "Gibraltar",
+ "code": "GI",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%AE"
+ },
+ {
+ "name": "Greenland",
+ "code": "GL",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B1"
+ },
+ {
+ "name": "Gambia",
+ "code": "GM",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B2"
+ },
+ {
+ "name": "Guinea",
+ "code": "GN",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B3"
+ },
+ {
+ "name": "Guadeloupe",
+ "code": "GP",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B5"
+ },
+ {
+ "name": "Equatorial Guinea",
+ "code": "GQ",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B6"
+ },
+ {
+ "name": "Greece",
+ "code": "GR",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B7"
+ },
+ {
+ "name": "South Georgia & South Sandwich Islands",
+ "code": "GS",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B8"
+ },
+ {
+ "name": "Guatemala",
+ "code": "GT",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%B9"
+ },
+ {
+ "name": "Guam",
+ "code": "GU",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%BA"
+ },
+ {
+ "name": "Guinea-Bissau",
+ "code": "GW",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%BC"
+ },
+ {
+ "name": "Guyana",
+ "code": "GY",
+ "emoji": "%F0%9F%87%AC%F0%9F%87%BE"
+ },
+ {
+ "name": "Hong Kong SAR China",
+ "code": "HK",
+ "emoji": "%F0%9F%87%AD%F0%9F%87%B0"
+ },
+ {
+ "name": "Heard & McDonald Islands",
+ "code": "HM",
+ "emoji": "%F0%9F%87%AD%F0%9F%87%B2"
+ },
+ {
+ "name": "Honduras",
+ "code": "HN",
+ "emoji": "%F0%9F%87%AD%F0%9F%87%B3"
+ },
+ {
+ "name": "Croatia",
+ "code": "HR",
+ "emoji": "%F0%9F%87%AD%F0%9F%87%B7"
+ },
+ {
+ "name": "Haiti",
+ "code": "HT",
+ "emoji": "%F0%9F%87%AD%F0%9F%87%B9"
+ },
+ {
+ "name": "Hungary",
+ "code": "HU",
+ "emoji": "%F0%9F%87%AD%F0%9F%87%BA"
+ },
+ {
+ "name": "Canary Islands",
+ "code": "IC",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%A8"
+ },
+ {
+ "name": "Indonesia",
+ "code": "ID",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%A9"
+ },
+ {
+ "name": "Ireland",
+ "code": "IE",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%AA"
+ },
+ {
+ "name": "Israel",
+ "code": "IL",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B1"
+ },
+ {
+ "name": "Isle of Man",
+ "code": "IM",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B2"
+ },
+ {
+ "name": "India",
+ "code": "IN",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B3"
+ },
+ {
+ "name": "British Indian Ocean Territory",
+ "code": "IO",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B4"
+ },
+ {
+ "name": "Iraq",
+ "code": "IQ",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B6"
+ },
+ {
+ "name": "Iran",
+ "code": "IR",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B7"
+ },
+ {
+ "name": "Iceland",
+ "code": "IS",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B8"
+ },
+ {
+ "name": "Italy",
+ "code": "IT",
+ "emoji": "%F0%9F%87%AE%F0%9F%87%B9"
+ },
+ {
+ "name": "Jersey",
+ "code": "JE",
+ "emoji": "%F0%9F%87%AF%F0%9F%87%AA"
+ },
+ {
+ "name": "Jamaica",
+ "code": "JM",
+ "emoji": "%F0%9F%87%AF%F0%9F%87%B2"
+ },
+ {
+ "name": "Jordan",
+ "code": "JO",
+ "emoji": "%F0%9F%87%AF%F0%9F%87%B4"
+ },
+ {
+ "name": "Japan",
+ "code": "JP",
+ "emoji": "%F0%9F%87%AF%F0%9F%87%B5"
+ },
+ {
+ "name": "Kenya",
+ "code": "KE",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%AA"
+ },
+ {
+ "name": "Kyrgyzstan",
+ "code": "KG",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%AC"
+ },
+ {
+ "name": "Cambodia",
+ "code": "KH",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%AD"
+ },
+ {
+ "name": "Kiribati",
+ "code": "KI",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%AE"
+ },
+ {
+ "name": "Comoros",
+ "code": "KM",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%B2"
+ },
+ {
+ "name": "St. Kitts & Nevis",
+ "code": "KN",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%B3"
+ },
+ {
+ "name": "North Korea",
+ "code": "KP",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%B5"
+ },
+ {
+ "name": "South Korea",
+ "code": "KR",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%B7"
+ },
+ {
+ "name": "Kuwait",
+ "code": "KW",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%BC"
+ },
+ {
+ "name": "Cayman Islands",
+ "code": "KY",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%BE"
+ },
+ {
+ "name": "Kazakhstan",
+ "code": "KZ",
+ "emoji": "%F0%9F%87%B0%F0%9F%87%BF"
+ },
+ {
+ "name": "Laos",
+ "code": "LA",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%A6"
+ },
+ {
+ "name": "Lebanon",
+ "code": "LB",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%A7"
+ },
+ {
+ "name": "St. Lucia",
+ "code": "LC",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%A8"
+ },
+ {
+ "name": "Liechtenstein",
+ "code": "LI",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%AE"
+ },
+ {
+ "name": "Sri Lanka",
+ "code": "LK",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%B0"
+ },
+ {
+ "name": "Liberia",
+ "code": "LR",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%B7"
+ },
+ {
+ "name": "Lesotho",
+ "code": "LS",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%B8"
+ },
+ {
+ "name": "Lithuania",
+ "code": "LT",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%B9"
+ },
+ {
+ "name": "Luxembourg",
+ "code": "LU",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%BA"
+ },
+ {
+ "name": "Latvia",
+ "code": "LV",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%BB"
+ },
+ {
+ "name": "Libya",
+ "code": "LY",
+ "emoji": "%F0%9F%87%B1%F0%9F%87%BE"
+ },
+ {
+ "name": "Morocco",
+ "code": "MA",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%A6"
+ },
+ {
+ "name": "Monaco",
+ "code": "MC",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%A8"
+ },
+ {
+ "name": "Moldova",
+ "code": "MD",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%A9"
+ },
+ {
+ "name": "Montenegro",
+ "code": "ME",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%AA"
+ },
+ {
+ "name": "St. Martin",
+ "code": "MF",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%AB"
+ },
+ {
+ "name": "Madagascar",
+ "code": "MG",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%AC"
+ },
+ {
+ "name": "Marshall Islands",
+ "code": "MH",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%AD"
+ },
+ {
+ "name": "North Macedonia",
+ "code": "MK",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B0"
+ },
+ {
+ "name": "Mali",
+ "code": "ML",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B1"
+ },
+ {
+ "name": "Myanmar (Burma)",
+ "code": "MM",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B2"
+ },
+ {
+ "name": "Mongolia",
+ "code": "MN",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B3"
+ },
+ {
+ "name": "Macao SAR China",
+ "code": "MO",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B4"
+ },
+ {
+ "name": "Northern Mariana Islands",
+ "code": "MP",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B5"
+ },
+ {
+ "name": "Martinique",
+ "code": "MQ",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B6"
+ },
+ {
+ "name": "Mauritania",
+ "code": "MR",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B7"
+ },
+ {
+ "name": "Montserrat",
+ "code": "MS",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B8"
+ },
+ {
+ "name": "Malta",
+ "code": "MT",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%B9"
+ },
+ {
+ "name": "Mauritius",
+ "code": "MU",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%BA"
+ },
+ {
+ "name": "Maldives",
+ "code": "MV",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%BB"
+ },
+ {
+ "name": "Malawi",
+ "code": "MW",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%BC"
+ },
+ {
+ "name": "Mexico",
+ "code": "MX",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%BD"
+ },
+ {
+ "name": "Malaysia",
+ "code": "MY",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%BE"
+ },
+ {
+ "name": "Mozambique",
+ "code": "MZ",
+ "emoji": "%F0%9F%87%B2%F0%9F%87%BF"
+ },
+ {
+ "name": "Namibia",
+ "code": "NA",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%A6"
+ },
+ {
+ "name": "New Caledonia",
+ "code": "NC",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%A8"
+ },
+ {
+ "name": "Niger",
+ "code": "NE",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%AA"
+ },
+ {
+ "name": "Norfolk Island",
+ "code": "NF",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%AB"
+ },
+ {
+ "name": "Nigeria",
+ "code": "NG",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%AC"
+ },
+ {
+ "name": "Nicaragua",
+ "code": "NI",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%AE"
+ },
+ {
+ "name": "Netherlands",
+ "code": "NL",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%B1"
+ },
+ {
+ "name": "Norway",
+ "code": "NO",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%B4"
+ },
+ {
+ "name": "Nepal",
+ "code": "NP",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%B5"
+ },
+ {
+ "name": "Nauru",
+ "code": "NR",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%B7"
+ },
+ {
+ "name": "Niue",
+ "code": "NU",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%BA"
+ },
+ {
+ "name": "New Zealand",
+ "code": "NZ",
+ "emoji": "%F0%9F%87%B3%F0%9F%87%BF"
+ },
+ {
+ "name": "Oman",
+ "code": "OM",
+ "emoji": "%F0%9F%87%B4%F0%9F%87%B2"
+ },
+ {
+ "name": "Panama",
+ "code": "PA",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%A6"
+ },
+ {
+ "name": "Peru",
+ "code": "PE",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%AA"
+ },
+ {
+ "name": "French Polynesia",
+ "code": "PF",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%AB"
+ },
+ {
+ "name": "Papua New Guinea",
+ "code": "PG",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%AC"
+ },
+ {
+ "name": "Philippines",
+ "code": "PH",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%AD"
+ },
+ {
+ "name": "Pakistan",
+ "code": "PK",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B0"
+ },
+ {
+ "name": "Poland",
+ "code": "PL",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B1"
+ },
+ {
+ "name": "St. Pierre & Miquelon",
+ "code": "PM",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B2"
+ },
+ {
+ "name": "Pitcairn Islands",
+ "code": "PN",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B3"
+ },
+ {
+ "name": "Puerto Rico",
+ "code": "PR",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B7"
+ },
+ {
+ "name": "Palestinian Territories",
+ "code": "PS",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B8"
+ },
+ {
+ "name": "Portugal",
+ "code": "PT",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%B9"
+ },
+ {
+ "name": "Palau",
+ "code": "PW",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%BC"
+ },
+ {
+ "name": "Paraguay",
+ "code": "PY",
+ "emoji": "%F0%9F%87%B5%F0%9F%87%BE"
+ },
+ {
+ "name": "Qatar",
+ "code": "QA",
+ "emoji": "%F0%9F%87%B6%F0%9F%87%A6"
+ },
+ {
+ "name": "Réunion",
+ "code": "RE",
+ "emoji": "%F0%9F%87%B7%F0%9F%87%AA"
+ },
+ {
+ "name": "Romania",
+ "code": "RO",
+ "emoji": "%F0%9F%87%B7%F0%9F%87%B4"
+ },
+ {
+ "name": "Serbia",
+ "code": "RS",
+ "emoji": "%F0%9F%87%B7%F0%9F%87%B8"
+ },
+ {
+ "name": "Russia",
+ "code": "RU",
+ "emoji": "%F0%9F%87%B7%F0%9F%87%BA"
+ },
+ {
+ "name": "Rwanda",
+ "code": "RW",
+ "emoji": "%F0%9F%87%B7%F0%9F%87%BC"
+ },
+ {
+ "name": "Saudi Arabia",
+ "code": "SA",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%A6"
+ },
+ {
+ "name": "Solomon Islands",
+ "code": "SB",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%A7"
+ },
+ {
+ "name": "Seychelles",
+ "code": "SC",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%A8"
+ },
+ {
+ "name": "Sudan",
+ "code": "SD",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%A9"
+ },
+ {
+ "name": "Sweden",
+ "code": "SE",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%AA"
+ },
+ {
+ "name": "Singapore",
+ "code": "SG",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%AC"
+ },
+ {
+ "name": "St. Helena",
+ "code": "SH",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%AD"
+ },
+ {
+ "name": "Slovenia",
+ "code": "SI",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%AE"
+ },
+ {
+ "name": "Svalbard & Jan Mayen",
+ "code": "SJ",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%AF"
+ },
+ {
+ "name": "Slovakia",
+ "code": "SK",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B0"
+ },
+ {
+ "name": "Sierra Leone",
+ "code": "SL",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B1"
+ },
+ {
+ "name": "San Marino",
+ "code": "SM",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B2"
+ },
+ {
+ "name": "Senegal",
+ "code": "SN",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B3"
+ },
+ {
+ "name": "Somalia",
+ "code": "SO",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B4"
+ },
+ {
+ "name": "Suriname",
+ "code": "SR",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B7"
+ },
+ {
+ "name": "South Sudan",
+ "code": "SS",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B8"
+ },
+ {
+ "name": "São Tomé & Príncipe",
+ "code": "ST",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%B9"
+ },
+ {
+ "name": "El Salvador",
+ "code": "SV",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%BB"
+ },
+ {
+ "name": "Sint Maarten",
+ "code": "SX",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%BD"
+ },
+ {
+ "name": "Syria",
+ "code": "SY",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%BE"
+ },
+ {
+ "name": "Eswatini",
+ "code": "SZ",
+ "emoji": "%F0%9F%87%B8%F0%9F%87%BF"
+ },
+ {
+ "name": "Tristan da Cunha",
+ "code": "TA",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%A6"
+ },
+ {
+ "name": "Turks & Caicos Islands",
+ "code": "TC",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%A8"
+ },
+ {
+ "name": "Chad",
+ "code": "TD",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%A9"
+ },
+ {
+ "name": "French Southern Territories",
+ "code": "TF",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%AB"
+ },
+ {
+ "name": "Togo",
+ "code": "TG",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%AC"
+ },
+ {
+ "name": "Thailand",
+ "code": "TH",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%AD"
+ },
+ {
+ "name": "Tajikistan",
+ "code": "TJ",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%AF"
+ },
+ {
+ "name": "Tokelau",
+ "code": "TK",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B0"
+ },
+ {
+ "name": "Timor-Leste",
+ "code": "TL",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B1"
+ },
+ {
+ "name": "Turkmenistan",
+ "code": "TM",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B2"
+ },
+ {
+ "name": "Tunisia",
+ "code": "TN",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B3"
+ },
+ {
+ "name": "Tonga",
+ "code": "TO",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B4"
+ },
+ {
+ "name": "Turkey",
+ "code": "TR",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B7"
+ },
+ {
+ "name": "Trinidad & Tobago",
+ "code": "TT",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%B9"
+ },
+ {
+ "name": "Tuvalu",
+ "code": "TV",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%BB"
+ },
+ {
+ "name": "Taiwan",
+ "code": "TW",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%BC"
+ },
+ {
+ "name": "Tanzania",
+ "code": "TZ",
+ "emoji": "%F0%9F%87%B9%F0%9F%87%BF"
+ },
+ {
+ "name": "Ukraine",
+ "code": "UA",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%A6"
+ },
+ {
+ "name": "Uganda",
+ "code": "UG",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%AC"
+ },
+ {
+ "name": "U.S. Outlying Islands",
+ "code": "UM",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%B2"
+ },
+ {
+ "name": "United Nations",
+ "code": "UN",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%B3"
+ },
+ {
+ "name": "United States",
+ "code": "US",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%B8"
+ },
+ {
+ "name": "Uruguay",
+ "code": "UY",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%BE"
+ },
+ {
+ "name": "Uzbekistan",
+ "code": "UZ",
+ "emoji": "%F0%9F%87%BA%F0%9F%87%BF"
+ },
+ {
+ "name": "Vatican City",
+ "code": "VA",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%A6"
+ },
+ {
+ "name": "St. Vincent & Grenadines",
+ "code": "VC",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%A8"
+ },
+ {
+ "name": "Venezuela",
+ "code": "VE",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%AA"
+ },
+ {
+ "name": "British Virgin Islands",
+ "code": "VG",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%AC"
+ },
+ {
+ "name": "U.S. Virgin Islands",
+ "code": "VI",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%AE"
+ },
+ {
+ "name": "Vietnam",
+ "code": "VN",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%B3"
+ },
+ {
+ "name": "Vanuatu",
+ "code": "VU",
+ "emoji": "%F0%9F%87%BB%F0%9F%87%BA"
+ },
+ {
+ "name": "Wallis & Futuna",
+ "code": "WF",
+ "emoji": "%F0%9F%87%BC%F0%9F%87%AB"
+ },
+ {
+ "name": "Samoa",
+ "code": "WS",
+ "emoji": "%F0%9F%87%BC%F0%9F%87%B8"
+ },
+ {
+ "name": "Kosovo",
+ "code": "XK",
+ "emoji": "%F0%9F%87%BD%F0%9F%87%B0"
+ },
+ {
+ "name": "Yemen",
+ "code": "YE",
+ "emoji": "%F0%9F%87%BE%F0%9F%87%AA"
+ },
+ {
+ "name": "Mayotte",
+ "code": "YT",
+ "emoji": "%F0%9F%87%BE%F0%9F%87%B9"
+ },
+ {
+ "name": "South Africa",
+ "code": "ZA",
+ "emoji": "%F0%9F%87%BF%F0%9F%87%A6"
+ },
+ {
+ "name": "Zambia",
+ "code": "ZM",
+ "emoji": "%F0%9F%87%BF%F0%9F%87%B2"
+ },
+ {
+ "name": "Zimbabwe",
+ "code": "ZW",
+ "emoji": "%F0%9F%87%BF%F0%9F%87%BC"
+ },
+ {
+ "name": "England",
+ "code": "ENGLAND",
+ "emoji": "%F0%9F%8F%B4%F3%A0%81%A7%F3%A0%81%A2%F3%A0%81%A5%F3%A0%81%AE%F3%A0%81%A7%F3%A0%81%BF"
+ },
+ {
+ "name": "Scotland",
+ "code": "SCOTLAND",
+ "emoji": "%F0%9F%8F%B4%F3%A0%81%A7%F3%A0%81%A2%F3%A0%81%B3%F3%A0%81%A3%F3%A0%81%B4%F3%A0%81%BF"
+ },
+ {
+ "name": "Wales",
+ "code": "WALES",
+ "emoji": "%F0%9F%8F%B4%F3%A0%81%A7%F3%A0%81%A2%F3%A0%81%B7%F3%A0%81%AC%F3%A0%81%B3%F3%A0%81%BF"
+ }
+]
\ No newline at end of file
diff --git a/app/builders/buildInboundLink.js b/app/builders/buildInboundLink.js
index ad5d620..fa9967e 100644
--- a/app/builders/buildInboundLink.js
+++ b/app/builders/buildInboundLink.js
@@ -1,3 +1,5 @@
+const flag = process.env.COUNTRY_FLAG ?? '%F0%9F%92%AF';
+
export function buildInboundLink(inbound, domain, idOrPass) {
let link = "";
@@ -48,7 +50,7 @@ function buildVlessLink(inbound, domain, uuid) {
params.set("fp", r.settings.fingerprint || "random");
params.set("sni", r.serverNames?.[0] || "");
params.set("sid", r.shortIds?.[0] || "");
- params.set("spx", '%2F');
+ params.set("spx", '/');
// TCP Reality flow
if (network === "tcp") {
@@ -88,7 +90,7 @@ function buildVlessLink(inbound, domain, uuid) {
return (
`vless://${uuid}@${domain}:${inbound.port}` +
`?${params.toString()}` +
- `#${encodeURIComponent(inbound.remark)}`
+ `#${flag}%20${encodeURIComponent(inbound.remark)}`
);
}
@@ -105,7 +107,7 @@ function buildVmessLink(inbound, domain, uuid) {
net: stream.network || "tcp",
path: "/",
port: inbound.port,
- ps: inbound.remark,
+ ps: flag + ' ' + inbound.remark,
scy: "",
sni: "",
tls: stream.security || "none",
@@ -134,7 +136,7 @@ function buildSsLink(inbound, domain) {
.from(userInfo, "utf8")
.toString("base64");
- return `ss://${base64}@${domain}:${inbound.port}?type=tcp#${inbound.remark}`;
+ return `ss://${base64}@${domain}:${inbound.port}?type=tcp#${flag}%20${inbound.remark}`;
}
function buildTrojanLink(inbound, domain, password) {
@@ -155,6 +157,6 @@ function buildTrojanLink(inbound, domain, password) {
`&sni=${sni}` +
`&sid=${sid}` +
`&spx=${spx}` +
- `#${inbound.remark}-${password}`
+ `#${flag}%20${inbound.remark}-${password}`
);
}
\ No newline at end of file
diff --git a/app/index.js b/app/index.js
index 9e15455..fece88d 100644
--- a/app/index.js
+++ b/app/index.js
@@ -23,7 +23,7 @@ api.interceptors.request.use(config => {
});
const WHITELIST_FILE = "/app/whitelist.txt";
-const WHITELIST_REPO_URL = "https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/whitelist.txt";
+const WHITELIST_REPO_URL = "https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/whitelist.txt";
// Вспомогательные функции
async function updateWhitelist() {
diff --git a/forwarding_install.sh b/forwarding_install.sh
index be6dd2b..af077e7 100644
--- a/forwarding_install.sh
+++ b/forwarding_install.sh
@@ -115,7 +115,7 @@ cd "$BASE_DIR"
#################################
# DOWNLOAD FILES
#################################
-REPO="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
+REPO="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
NGINX_PORT=$ORIGIN_PORT
SUB_URL="$ORIGIN_PROTO://$LOCAL_HOST:$NGINX_PORT$SUB_PATH"
diff --git a/install.sh b/install.sh
index 0116fc1..4200947 100644
--- a/install.sh
+++ b/install.sh
@@ -135,12 +135,32 @@ log "Используется директория проекта: $PROJECT_DIR"
mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"
+#################################
+# Получаем флаг
+#################################
+REPO_BASE="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
+COUNTRY_FLAG=""
+
+# Получаем countryCode
+IP_JSON=$(curl -s --fail http://ip-api.com/json/ || true)
+[ -z "$IP_JSON" ] && exit 0
+
+COUNTRY_CODE=$(echo "$IP_JSON" | jq -r '.countryCode // empty' 2>/dev/null)
+[ -z "$COUNTRY_CODE" ] && exit 0
+
+# URL флагов
+FLAGS_JSON_URL="$REPO_BASE/app/assets/flags.json"
+
+FLAGS_JSON=$(curl -s "$FLAGS_JSON_URL" || true)
+[ -z "$FLAGS_JSON" ] && exit 0
+
+# Ищем emoji
+COUNTRY_FLAG=$(echo "$FLAGS_JSON" | jq -r --arg code "$COUNTRY_CODE" '.[] | select(.code == $code) | .emoji // empty' 2>/dev/null | head -n1)
+
#################################
# Белый лист
#################################
-REPO_BASE="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
-
curl -fsSL "$REPO_BASE/whitelist.txt" -o whitelist.txt
log "whitelist.txt скопирован"
@@ -207,6 +227,7 @@ SUB_TOKEN=$SUB_TOKEN
UI_URL=$UI_URL
UI_LOGIN=$UI_LOGIN
UI_PASSWORD=$UI_PASSWORD
+COUNTRY_FLAG=$COUNTRY_FLAG
NGINX_PORT=$NGINX_PORT
UI_HOST=$UI_HOST
UI_PROTO=$UI_PROTO
diff --git a/update.sh b/update.sh
index 865c835..a7658d0 100644
--- a/update.sh
+++ b/update.sh
@@ -23,7 +23,7 @@ need_root() {
#################################
PROJECT_DIR="/opt/3dp-manager"
-REPO_RAW="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
+REPO_RAW="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
#################################
# START
From afb68a6e9b02de6f2ca347f09473c916ea31ef0a Mon Sep 17 00:00:00 2001
From: Denis Vasilev <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 11:44:44 +0300
Subject: [PATCH 03/17] all languages
---
README_CN.md | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++
README_EN.md | 149 ++++++++++++++++++++++++++++++++++++++-------
README_IR.md | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++
README_TK.md | 155 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 616 insertions(+), 22 deletions(-)
create mode 100644 README_CN.md
create mode 100644 README_IR.md
create mode 100644 README_TK.md
diff --git a/README_CN.md b/README_CN.md
new file mode 100644
index 0000000..5740aad
--- /dev/null
+++ b/README_CN.md
@@ -0,0 +1,167 @@
+[Русский](/README.md) | [English](/README_EN.md) | [فارسی](/README_IR.md) | [Türkmençe](/README_TK.md)
+
+
+
+ [](https://www.gnu.org/licenses/gpl-3.0) [](https://t.me/denpiligrim_web) [](https://www.youtube.com/@denpiligrim)
+
+# 3DP-MANAGER
+
+这是一个用于为 `3x-ui` 面板自动生成入站连接、生成统一订阅并将流量从中继服务器转发到主服务器的实用工具。
+
+**支持项目**
+
+- 捐助/支付信息:
+ - MIR 卡: `2204320436318077`
+ - MasterCard: `5395452209474530`
+ - PayPal: `vasiljevdenisx@gmail.com`
+ - USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
+ - USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
+ - 比特币: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
+ - TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
+ - Bybit ID: `165292278`
+
+## 描述
+
+该工具的主要目标是使您的流量看起来不那么统一。机器人会在设定间隔生成 10 个具有不同参数的连接:
+
+- 协议:`vless`、`vmess`、`shadowsocks`、`trojan`
+- 端口:`443`、`8443`(固定)以及 `10000-60000` 范围内的随机端口
+- 传输:`tcp`、`websocket`、`grpc`、`xhttp`
+- SNI 从域名白名单(`whitelist`)中获取;也可以使用自定义列表
+
+所有连接会合并为具有静态 URL 的单一订阅。该机器人通过 `3x-ui` 面板的公共 API 工作,不会直接修改面板内部。
+
+次要目标是提高连接稳定性:客户端会收到 10 个可选连接,用户可以选择任意一个。
+
+此外,机器人可用于级联部署。转发服务会自动配置将订阅和流量重定向到主服务器。
+
+建议:
+
+- 订阅请使用 HTTPS(域名 + SSL 证书)。
+- 生成间隔设置为 ≥ 10 分钟;为稳定性建议每天一次(1440 分钟)。
+- 在客户端设置更频繁的自动更新(例如每小时),以便与服务器同步。
+
+## 功能
+
+- 生成 10 个多样化连接
+- 形成具有静态 URL 的统一订阅
+- 支持自定义 `whitelist` 域名
+- 可选的自动流量转发配置
+
+## 要求
+
+- Ubuntu 20.04 或更高
+- `3x-ui` 面板
+- 域名 + SSL 证书(可选)
+
+---
+
+## 安装
+
+在服务器上运行以下命令安装项目:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+```
+
+简要说明:运行安装脚本并部署容器和服务。
+
+## 更新
+
+更新到最新版本:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+```
+
+简要说明:拉取最新更改并重启容器。
+
+## 删除
+
+彻底删除服务:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+```
+
+简要说明:删除容器和配置文件,恢复到安装前状态。
+
+---
+
+## 安装转发服务(forwarding)
+
+转发服务允许将中继服务器的入站端口代理到主服务器。
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+```
+
+简要说明:添加转发规则并创建用于更新订阅的服务。
+
+## 删除转发
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+```
+
+简要说明:删除规则并禁用转发服务。
+
+---
+
+## 显示订阅 URL
+
+在容器环境中打印当前订阅 URL 的命令:
+
+```bash
+cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
+```
+
+简要说明:打印可在客户端使用的静态订阅 URL,适用于主服务器和中继服务器。
+
+## 从多订阅收集域名
+
+该工具可从订阅中提取域名并为生成器构建 `whitelist`。
+
+```bash
+node get_domains.js
+```
+
+简要说明:在脚本中添加多订阅链接并运行命令 — 输出为域名列表。运行脚本需要 `Node.js`。
+
+## 使用自定义白名单
+
+1. 准备一个与 `whitelist.txt` 相同格式的文件。
+2. 将其重命名为 `my_whitelist.txt` 并复制到 `/opt/3dp-manager/app`。
+
+```bash
+cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
+```
+
+简要说明:将您的域名文件添加到应用容器中。
+
+---
+
+## 注意与当前限制
+
+- 共享的域名列表可能并非对所有提供商都有效;建议准备并使用自定义 `whitelist`。
+
+---
+
+## 贡献
+
+欢迎贡献!简单的贡献流程:
+
+1. 在 GitHub 上 fork 仓库。
+2. 创建有意义的分支名,例如 `feature/add-README` 或 `fix/whitelist-load`。
+3. 提交更改并添加简短的提交信息。
+4. 在本地运行检查(如有)。
+5. 推送分支到您的 fork 并创建 Pull Request。
+
+建议:在 PR 中说明更改和测试步骤;较大更改请拆成小提交。
+
+---
+
+## 讨论
+
+- Telegram: [@denpiligrim_web](https://t.me/denpiligrim_web)
+- Issues
\ No newline at end of file
diff --git a/README_EN.md b/README_EN.md
index eadb1f4..e37473a 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,62 +1,167 @@
-[Русский](https://github.com/denpiligrim/3dp-manager/blob/dp-fix/README.md)
+[Русский](/README.md) | [中文](/README_CN.md) | [فارسی](/README_IR.md) | [Türkmençe](/README_TK.md)
+
+
+
+ [](https://www.gnu.org/licenses/gpl-3.0) [](https://t.me/denpiligrim_web) [](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
-> [!WARNING]
-> **This is a beta version!**
->
-> The program is currently under active development. Bugs, instability, and API changes are possible.
-> Use with caution.
+A utility for auto-generating inbound connections for the [3x-ui](https://github.com/MHSanaei/3x-ui) panel, creating a single subscription URL, and configuring traffic forwarding from an intermediate server to the main server.
-3DP-MANAGER is a utility that allows you to regularly generate inbound connections for the 3X-UI panel based on a whitelist of domains. The whitelist is shared, but you can also add your own list by naming it `my_whitelist.txt` and adding it to the `/opt/3dp-manager/app` folder on your server.
-Discussions are available on the Telegram channel: [@denpiligrim_web](https://t.me/denpiligrim_web/719)
+**Support the project**
+
+- Donation / payment details:
+ - MIR card: `2204320436318077`
+ - MasterCard: `5395452209474530`
+ - PayPal: `vasiljevdenisx@gmail.com`
+ - USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
+ - USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
+ - Bitcoin: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
+ - TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
+ - Bybit ID: `165292278`
+
+## Description
+
+The main goal of the utility is to make your traffic appear non-uniform. The bot generates 10 connection entries at a configured interval with varying parameters:
+
+- Protocols: `vless`, `vmess`, `shadowsocks`, `trojan`;
+- Ports: `443`, `8443` (fixed) and random ports from the range `10000-60000`;
+- Transport: `tcp`, `websocket`, `grpc`, `xhttp`;
+- SNI values are taken from a whitelist of domains (`whitelist`); you can use your own list.
+
+All generated connections are combined into a single subscription with a static URL. The bot works with the `3x-ui` panel using its public API and does not directly modify the panel internals.
+
+The secondary goal is connection stability: the client receives 10 alternate connection options and can choose any of them.
+
+Additionally, the bot can be used in a cascading setup. The forwarding service will automatically configure the subscription and traffic redirection to the main server.
+
+Recommendations:
+
+- Use HTTPS for the subscription (domain + SSL certificate).
+- Set the generation interval to ≥ 10 minutes; for stability, once per day (1440 minutes) is recommended.
+- Configure the client to check for updates more frequently (for example, hourly) to stay synchronized with the server.
+
+## Features
+
+- Generates 10 diverse connection entries
+- Creates a single subscription with a static URL
+- Supports custom `whitelist` domains
+- Optional automatic configuration of traffic forwarding
+
+## Requirements
+
+- Ubuntu 20.04 or newer
+- `3x-ui` panel
+- Domain + SSL certificate (optional)
+
+---
+
+## Installation
+
+Install the project on your server with:
-### Install
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
```
-### Update
+Short description: runs the installer script and deploys containers and services.
+
+## Update
+
+Update to the latest version:
+
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
```
-### Delete
+Short description: pulls the latest changes and restarts containers.
+
+## Removal
+
+Remove the service completely:
+
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
```
+Short description: removes containers and configuration files, restoring the system to the pre-install state.
+
---
-The subscription and inbound redirection service works in conjunction with **3DP-MANAGER** and allows you to redirect all inbound traffic from the intermediate server to the main server. The same ports are redirected, namely `443`, `8443`, and the range `10000-60000`. The service also creates a link to the subscription, automatically replacing the IP address or domain in the configurations. Redirects are configured by adding iptables rules to the ufw configuration file, which ensures stable operation in conjunction with the firewall. It is recommended to install the service on a clean server without any previously installed rules.
-### Install forwarding
+## Install forwarding service
+
+The forwarding service allows proxying incoming ports from the intermediate server to the main server.
+
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
```
-### Delete forwarding
+Short description: adds forwarding rules and creates a service to update the subscription.
+
+## Remove forwarding
+
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
```
+Short description: removes rules and disables the forwarding service.
+
---
-### Show sub URL
+## Show subscription URL
+
+Command to print the current subscription URL from the container environment:
+
```bash
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
----
+Short description: prints the static subscription URL that can be used in clients. Works on both main and intermediate servers.
+
+## Collect domains from multi-subscriptions
+
+The utility extracts domains from subscriptions and builds a `whitelist` for the generator.
-### Utility for collecting domains from multi-subscriptions
-Allows you to collect domains from subscriptions with multiple configurations. There are many similar configuration lists circulating on the internet that use white SNI. The tool allows you to extract domains and prepare a ready-made list for further use in the inbound generator.
-Insert a subscription link into the script and run the command in the `Node.js` environment.
```bash
node get_domains.js
```
-### Use your whitelist
-The file should have a structure similar to `whitelist.txt`. Rename the file to `my_whitelist.txt`. Upload the file to the `/opt/3dp-manager/app` folder on the server and run the command:
+Short description: add a multi-subscription link to the script and run the command — the output will be a list of domains. `Node.js` is required to run the script.
+
+## Use your own whitelist
+
+1. Prepare a file in the format of `whitelist.txt`.
+2. Rename it to `my_whitelist.txt` and copy it into `/opt/3dp-manager/app`.
+
```bash
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
-```
\ No newline at end of file
+```
+
+Short description: adds your domain file into the application container.
+
+---
+
+## Notes and current limitations
+
+- The shared domain list may not work with all providers; it is recommended to prepare and use your own `whitelist`.
+
+---
+
+## Contributing
+
+Contributions are welcome! Simple contributor workflow:
+
+1. Fork the repository on GitHub.
+2. Create a branch with a meaningful name, e.g. `feature/add-README` or `fix/whitelist-load`.
+3. Make changes and add a short commit message.
+4. Run local checks if available.
+5. Push the branch to your fork and create a Pull Request to the main repository.
+
+Tips: describe changes and testing steps in the PR. For large changes, split into smaller commits.
+
+---
+
+## Discussion
+
+- Telegram: [@denpiligrim_web](https://t.me/denpiligrim_web)
+- Issues
\ No newline at end of file
diff --git a/README_IR.md b/README_IR.md
new file mode 100644
index 0000000..22dd4ef
--- /dev/null
+++ b/README_IR.md
@@ -0,0 +1,167 @@
+[Русский](/README.md) | [English](/README_EN.md) | [中文](/README_CN.md) | [Türkmençe](/README_TK.md)
+
+
+
+ [](https://www.gnu.org/licenses/gpl-3.0) [](https://t.me/denpiligrim_web) [](https://www.youtube.com/@denpiligrim)
+
+# 3DP-MANAGER
+
+ابزاری برای تولید خودکار اتصالهای inbound برای پنل `3x-ui`، ساخت یک اشتراک یکپارچه و هدایت ترافیک از سرور واسط به سرور اصلی.
+
+**حمایت از پروژه**
+
+- اطلاعات پرداخت/اهدا:
+ - کارت MIR: `2204320436318077`
+ - کارت MasterCard: `5395452209474530`
+ - PayPal: `vasiljevdenisx@gmail.com`
+ - USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
+ - USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
+ - بیتکوین: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
+ - TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
+ - Bybit ID: `165292278`
+
+## توضیحات
+
+هدف اصلی این ابزار این است که ترافیک شما یکسان به نظر نرسد. ربات در فواصل زمانی مشخص 10 اتصال با پارامترهای مختلف تولید میکند:
+
+- پروتکلها: `vless`, `vmess`, `shadowsocks`, `trojan`
+- پورتها: `443`, `8443` (ثابت) و پورتهای تصادفی در بازه `10000-60000`
+- لایه انتقال: `tcp`, `websocket`, `grpc`, `xhttp`
+- SNI از لیست سفید دامنهها گرفته میشود (`whitelist`); میتوانید از لیست خود استفاده کنید.
+
+تمام اتصالات در یک اشتراک با URL ثابت تجمیع میشوند. ربات با پنل `3x-ui` از طریق API باز کار میکند و بهطور مستقیم در عملکرد داخلی پنل دخالت نمیکند.
+
+هدف ثانویه افزایش پایداری اتصال است: مشتری 10 گزینه اتصال دریافت میکند و میتواند هر کدام را انتخاب کند.
+
+علاوه بر این، ربات میتواند در طرحهای آبشاری استفاده شود. سرویس فورواردینگ بهطور خودکار بازنشانی اشتراک و ترافیک به سرور اصلی را تنظیم میکند.
+
+توصیهها:
+
+- برای اشتراک از HTTPS استفاده کنید (دامنه + گواهی SSL).
+- فاصله تولید را ≥ 10 دقیقه در نظر بگیرید؛ برای پایداری توصیه میشود یکبار در روز (1440 دقیقه) تنظیم شود.
+- در کلاینت بهروزرسانی خودکار را بیشتر تنظیم کنید (مثلاً هر ساعت) تا همگامسازی با سرور انجام شود.
+
+## قابلیتها
+
+- تولید 10 اتصال متنوع
+- تشکیل یک اشتراک یکپارچه با URL ثابت
+- پشتیبانی از دامنههای `whitelist` سفارشی
+- پیکربندی خودکار فورواردینگ ترافیک (اختیاری)
+
+## نیازمندیها
+
+- Ubuntu 20.04 یا بالاتر
+- پنل `3x-ui`
+- دامنه + گواهی SSL (اختیاری)
+
+---
+
+## نصب
+
+برای نصب پروژه در سرور، دستور زیر را اجرا کنید:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+```
+
+توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویسها را راهاندازی میکند.
+
+## بهروزرسانی
+
+برای بهروزرسانی به آخرین نسخه:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+```
+
+توضیح کوتاه: تغییرات جدید را میکشد و کانتینرها را ریاستارت میکند.
+
+## حذف
+
+برای حذف کامل سرویس:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+```
+
+توضیح کوتاه: کانتینرها و فایلهای پیکربندی را حذف میکند و سیستم را به وضعیت پیش از نصب برمیگرداند.
+
+---
+
+## نصب سرویس فورواردینگ (forwarding)
+
+سرویس فورواردینگ امکان پراکسی کردن پورتهای ورودی از سرور واسط به سرور اصلی را فراهم میکند.
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+```
+
+توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای بهروزرسانی اشتراک ایجاد میکند.
+
+## حذف فورواردینگ
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+```
+
+توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال میکند.
+
+---
+
+## نمایش URL اشتراک
+
+دستور برای نمایش URL اشتراک فعلی در محیط کانتینر:
+
+```bash
+cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
+```
+
+توضیح کوتاه: URL ثابت اشتراک را نمایش میدهد که میتوان در کلاینتها استفاده کرد. هم در سرور اصلی و هم در سرور واسط کار میکند.
+
+## جمعآوری دامنهها از چندین اشتراک
+
+ابزار دامنهها را از اشتراکهای دارای چندین پیکربندی استخراج کرده و `whitelist` تولید میکند.
+
+```bash
+node get_domains.js
+```
+
+توضیح کوتاه: لینک چندین اشتراک را در اسکریپت قرار داده و فرمان را اجرا کنید — خروجی فهرست دامنهها خواهد بود. نیازمند `Node.js` است.
+
+## استفاده از whitelist شخصی
+
+1. فایلی با ساختار مشابه `whitelist.txt` آماده کنید.
+2. آن را به `my_whitelist.txt` تغییر نام دهید و در پوشه `/opt/3dp-manager/app` کپی کنید.
+
+```bash
+cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
+```
+
+توضیح کوتاه: فایل دامنه شما را به کانتینر برنامه اضافه میکند.
+
+---
+
+## نکات و محدودیتهای فعلی
+
+- لیست عمومی دامنهها برای همه ارائهدهندگان کار نمیکند؛ پیشنهاد میشود `whitelist` خود را تهیه و استفاده کنید.
+
+---
+
+## مشارکت
+
+از هرگونه مشارکت در توسعه پروژه خوشحال میشوم! روند ساده برای مشارکتکنندگان:
+
+1. مخزن را در GitHub fork کنید.
+2. شاخهای با نام معنادار ایجاد کنید مانند `feature/add-README` یا `fix/whitelist-load`.
+3. تغییرات را اعمال کرده و یک پیام کوتاه در کامیت اضافه کنید.
+4. در صورت وجود، بررسیهای محلی را اجرا کنید.
+5. شاخه را به fork خود پوش کرده و Pull Request ایجاد کنید.
+
+نکات: تغییرات را در PR شرح دهید و مراحل تست را بنویسید. در صورت تغییرات بزرگ، آنها را به کامیتهای کوچک تقسیم کنید.
+
+---
+
+## بحث
+
+- تلگرام: [@denpiligrim_web](https://t.me/denpiligrim_web)
+- Issues
\ No newline at end of file
diff --git a/README_TK.md b/README_TK.md
new file mode 100644
index 0000000..656e48e
--- /dev/null
+++ b/README_TK.md
@@ -0,0 +1,155 @@
+[Русский](/README.md) | [English](/README_EN.md) | [中文](/README_CN.md) | [فارسی](/README_IR.md)
+
+
+
+ [](https://www.gnu.org/licenses/gpl-3.0) [](https://t.me/denpiligrim_web) [](https://www.youtube.com/@denpiligrim)
+
+# 3DP-MANAGER
+
+Bu gural `3x-ui` paneli üçin awtomatiki ýagdaýda inbound baglanyşlaryny döredýär, birleşdirilen abunany (subscription) döretmäge we aragatnaşyk serwerinden esasy servere trafigiň ugradylyşyny sazlamaga kömek edýär.
+
+**Taslamany goldaň**
+
+- Töleg / goşant maglumatlary:
+ - MIR kart: `2204320436318077`
+ - MasterCard: `5395452209474530`
+ - PayPal: `vasiljevdenisx@gmail.com`
+ - USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
+ - USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
+ - Bitcoin: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
+ - TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
+ - Bybit ID: `165292278`
+
+## Düşündiriş
+
+Esasy maksady trafigiňizi birmeňzeş bolmaz ýaly etmekdir. Bot bellenen aralykda dürli parametrler bilen 10 sany baglanyşygy döredýär:
+
+- Protokollar: `vless`, `vmess`, `shadowsocks`, `trojan`;
+- Portlar: `443`, `8443` (hemişelik) we `10000-60000` aralygyndan tötänleýin portlar;
+- Transport: `tcp`, `websocket`, `grpc`, `xhttp`;
+- SNI `whitelist` domen sanawyndan alynýar; öz sanawyňyzy hem ulanyp bilersiňiz.
+
+Ähli döredilen baglanyşyklary biri-birine birleşdirip, statik URL bilen bir abuna döredilýär. Bot `3x-ui` paneliniň açyk API-sini ulanýar we paneliň içki konfigurasiýasyna gönüden-göni aralaşmaýar.
+
+Ikinji maksady baglanyşygyň durnuklylygyny ýokarlandyrmakdyr: müşderi 10 dürli baglanyşyk opsiýasyny alýar we islese haýsyny islese saýlap bilýär.
+
+Göçürme (forwarding) hyzmaty bilen birleşdirilende, bot abonnament we trafik diňe esasy servere ugradylyşyny awtomatiki sazlar.
+
+Maslahatchylyklar:
+
+- Abuna üçin HTTPS ulanyň (domain + SSL şahadatnamasy).
+- Dörediş aralygyny ≥ 10 minut goýuň; durnuklylyk üçin her gün bir gezek (1440 minut) maslahat berilýär.
+- Müşderide awtomatiki täzelenmäni ýygylaşdyryň (meselem, her sagat) — serwera sazlaşyklylyk üçin.
+
+## Imkançylyklar
+
+- 10 dürli baglanyşygy öndürýär
+- Statik URL bilen bir abuna döredýär
+- Öz `whitelist` domenleriňizi goldaýar
+- Trafigiň awtomatik forwarding sazlamalary (islege bagly)
+
+## Talaplar
+
+- Ubuntu 20.04 ýa-da täze
+- `3x-ui` paneli
+- Domain + SSL şahadatnamasy (islege bagly)
+
+---
+
+## Gurnama
+
+Taslamany serwera gurnamak üçin şu komandany ýerine ýetiriň:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+```
+
+Gysgaça: gurnama skripti işledilýär we konteýnerler we hyzmatlar döredilýär.
+
+## Täzelik
+
+Soňky wersiýa çenli täzeläň:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+```
+
+Gysgaça: iň soňky üýtgeşmeleri çekýär we konteýnerleri gaýtadan işledýär.
+
+## Pozmak
+
+Hyzmaty doly pozmak üçin:
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+```
+
+Gysgaça: konteýnerleri we konfigurasiýa faýllaryny pozup, systemany gurnamadan öňki ýagdaýyna getirer.
+
+---
+
+## Forwarding hyzmatyny gurnamak
+
+Forwarding hyzmaty aragatnaşyk serwerinden esasy servere gelýän portlary proxy arkaly geçirýär.
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+```
+
+## Forwarding-i pozmak
+
+```bash
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+```
+
+---
+
+## Abuna URL-ni görkezmek
+
+Konteýner gurşawynda häzirki abuna URL-ni görkezýän komanda:
+
+```bash
+cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
+```
+
+## Multi-abunalardan domenleri toplamak
+
+Gural birden köp konfigurasiýa içeren abunalardan domenleri çykaryp `whitelist` düzýär.
+
+```bash
+node get_domains.js
+```
+
+## Öz `whitelist`-iňizi ulanmak
+
+1. `whitelist.txt` bilen meňzeş struktura eýe faýl taýýarlaň.
+2. Ony `my_whitelist.txt` diýip atlandyryp `/opt/3dp-manager/app` içine göçüriň.
+
+```bash
+cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
+```
+
+---
+
+## Bellikler we çäklendirmeler
+
+- Umumy domen sanawy ähli üpjün edijilerde işlemeýär; öz `whitelist`-iňizi düzmegiňizi maslahat berýäris.
+
+---
+
+## Goşanty
+
+Proýekte goşant bermäge hoş geldiňiz! Goşant prosesi ýönekeý:
+
+1. GitHub-da repo-ny fork ediň.
+2. Meni manly at bilen şahamça (branch) dörediň, meselem `feature/add-README` ýa-da `fix/whitelist-load`.
+3. Üýtgeşmeleri giriziň we gysga commit ýazmagy unutmaň.
+4. Lokal barlaglary işlediň (bardy bolsa).
+5. Şahamçany fork-a iteriň we Pull Request dörediň.
+
+---
+
+## Çeperdeşlik
+
+- Telegram: [@denpiligrim_web](https://t.me/denpiligrim_web)
+- Issues
\ No newline at end of file
From 7e58644573c688aa70de9952319e916aa3a72eac Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 12:34:20 +0300
Subject: [PATCH 04/17] code styling
---
app/.env.example | 1 +
app/builders/buildVlessWs.js | 2 -
app/index.js | 8 ++--
delete.sh | 8 +---
forwarding_delete.sh | 17 ++++----
forwarding_install.sh | 39 ++++--------------
install.sh | 79 +++++++++++++++---------------------
update.sh | 11 +----
8 files changed, 57 insertions(+), 108 deletions(-)
diff --git a/app/.env.example b/app/.env.example
index caf9611..3d17eb8 100644
--- a/app/.env.example
+++ b/app/.env.example
@@ -2,6 +2,7 @@ SUB_TOKEN=$SUB_TOKEN
UI_URL=$UI_URL
UI_LOGIN=$UI_LOGIN
UI_PASSWORD=$UI_PASSWORD
+COUNTRY_FLAG=$COUNTRY_FLAG
NGINX_PORT=$NGINX_PORT
UI_HOST=$UI_HOST
UI_PROTO=$UI_PROTO
diff --git a/app/builders/buildVlessWs.js b/app/builders/buildVlessWs.js
index 2886130..4178cd6 100644
--- a/app/builders/buildVlessWs.js
+++ b/app/builders/buildVlessWs.js
@@ -1,5 +1,3 @@
-import crypto from "crypto";
-
export function buildVlessWs({ port, uuid, domain }) {
return {
enable: true,
diff --git a/app/index.js b/app/index.js
index fece88d..50e8af0 100644
--- a/app/index.js
+++ b/app/index.js
@@ -25,7 +25,7 @@ api.interceptors.request.use(config => {
const WHITELIST_FILE = "/app/whitelist.txt";
const WHITELIST_REPO_URL = "https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/whitelist.txt";
-// Вспомогательные функции
+// Helper functions
async function updateWhitelist() {
try {
const res = await axios.get(WHITELIST_REPO_URL, { timeout: 10000 });
@@ -138,7 +138,7 @@ async function addInbound(config) {
}
}
-// Основная ротация inbound'ов
+// Main rotation of inbound entries
async function rotate() {
await login();
@@ -169,7 +169,7 @@ async function rotate() {
usedPorts.add(inbound.port);
const idOrPass = inbound.settings ? JSON.parse(inbound.settings).clients?.[0]?.id || JSON.parse(inbound.settings).clients?.[0]?.password : "";
- // Формируем ссылку в зависимости от протокола
+ // Build the link depending on the protocol
const link = buildInboundLink(inbound, UI_HOST, idOrPass);
if (link) subs.push(link);
await addInbound(inbound);
@@ -179,7 +179,7 @@ async function rotate() {
console.log("✔ 10 inbound created, подписка обновлена");
}
-// Первый запуск
+// Initial run
rotate();
let interval = parseInt(process.env.ROTATE_INTERVAL) || 30;
diff --git a/delete.sh b/delete.sh
index 14ab825..1bc7e2c 100644
--- a/delete.sh
+++ b/delete.sh
@@ -9,7 +9,6 @@ trap 'echo -e "\033[1;31m[ERROR]\033[0m Ошибка в строке $LINENO"; e
#################################
# HELPERS
#################################
-
log() { echo -e "\033[1;32m[INFO]\033[0m $1"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
@@ -21,7 +20,6 @@ need_root() {
#################################
# START
#################################
-
need_root
PROJECT_DIR="/opt/3dp-manager"
@@ -38,7 +36,6 @@ cd "$PROJECT_DIR"
#################################
# DOCKER COMPOSE DOWN
#################################
-
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
if [[ -f docker-compose.yml ]]; then
log "Останавливаем контейнеры 3dp-manager"
@@ -51,9 +48,8 @@ else
fi
#################################
-# CLEAN IMAGES (ТОЛЬКО НАШИ)
+# CLEAN IMAGES
#################################
-
log "Удаляем образы 3dp-manager (если есть)"
docker images --format '{{.Repository}} {{.ID}}' \
@@ -64,12 +60,10 @@ docker images --format '{{.Repository}} {{.ID}}' \
#################################
# REMOVE DIRECTORY
#################################
-
log "Удаляем $PROJECT_DIR"
rm -rf "$PROJECT_DIR"
#################################
# DONE
#################################
-
log "✔ 3dp-manager полностью удалён"
\ No newline at end of file
diff --git a/forwarding_delete.sh b/forwarding_delete.sh
index 9c6fb42..e310a25 100644
--- a/forwarding_delete.sh
+++ b/forwarding_delete.sh
@@ -42,14 +42,11 @@ rm -rf "$BASE_DIR"
#################################
# UFW NAT CLEAN
#################################
-echo "--- 1. Удаление оптимизаций ядра ---"
+echo "--- Удаление перенаправления ---"
rm -f /etc/sysctl.d/99-relay-optimization.conf
-# Применяем стандартные настройки (отключаем BBR и forward, если они не были включены до этого)
sysctl net.ipv4.ip_forward=0
-sysctl net.core.default_qdisc=pfifo_fast
-sysctl net.ipv4.tcp_congestion_control=cubic
-echo "--- 2. Восстановление правил UFW из бэкапа ---"
+echo "--- Восстановление правил UFW из бэкапа ---"
if [ -f /etc/ufw/before.rules.bak ]; then
mv /etc/ufw/before.rules.bak /etc/ufw/before.rules
echo "Файл before.rules восстановлен из бэкапа."
@@ -57,17 +54,19 @@ else
echo "ВНИМАНИЕ: Бэкап before.rules.bak не найден. Правила NAT придется удалять вручную."
fi
-echo "--- 3. Удаление разрешающих правил портов ---"
+echo "--- Удаление разрешающих правил портов ---"
ufw delete allow 443/tcp
+ufw delete allow 443/udp
ufw delete allow 8443/tcp
+ufw delete allow 8443/udp
ufw delete allow "$NGINX_PORT"/tcp
ufw delete allow 10000:60000/tcp
ufw delete allow 10000:60000/udp
-echo "--- 4. Возврат политики FORWARD по умолчанию (DROP) ---"
+echo "--- Возврат политики FORWARD по умолчанию (DROP) ---"
sed -i 's/DEFAULT_FORWARD_POLICY="ACCEPT"/DEFAULT_FORWARD_POLICY="DROP"/' /etc/default/ufw
-echo "--- 5. Перезапуск фаервола ---"
+echo "--- Перезапуск фаервола ---"
ufw reload
#################################
@@ -77,4 +76,4 @@ ufw reload
echo "Docker контейнеры удалены"
echo "UFW NAT очищен"
echo "ip_forward отключён"
-log "Откат завершён. Для применения изменений перезагрузите систему!"
\ No newline at end of file
+log "Откат завершён. Для окончательного применения изменений перезагрузите систему!"
\ No newline at end of file
diff --git a/forwarding_install.sh b/forwarding_install.sh
index af077e7..39a7781 100644
--- a/forwarding_install.sh
+++ b/forwarding_install.sh
@@ -15,7 +15,9 @@ die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
[[ $EUID -eq 0 ]] || die "Запускать нужно от root"
-# --- ASCII-баннер ---
+#################################
+# ASCII-баннер
+#################################
echo "==================================================="
echo " ____ ____ _ ___ _ "
echo " / __ \___ ____ / __ \(_) (_)___ ______(_)___ ___ "
@@ -27,7 +29,6 @@ echo ""
echo " 3DP-MANAGER SUBSCRIPTION FORWARDER "
echo "==================================================="
echo ""
-# --------------------
#################################
# INPUT
@@ -51,22 +52,16 @@ SUB_PATH="/$(echo "$ORIGIN_SUB_URL" | cut -d/ -f4-)"
#################################
# Определяем ORIGIN_IP
#################################
-
if [[ "$ORIGIN_HOST" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
- # Это уже IP-адрес
ORIGIN_IP="$ORIGIN_HOST"
log "Используем прямой IP из URL: $ORIGIN_IP"
else
- # Это домен — разрешаем в IP
log "Разрешаем домен $ORIGIN_HOST в IP..."
- # Пробуем getent ahosts (IPv4 приоритет)
ORIGIN_IP=$(getent ahosts "$ORIGIN_HOST" | awk '/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1; exit}')
- # Если не вышло — fallback на hosts
[[ -z "$ORIGIN_IP" ]] && ORIGIN_IP=$(getent hosts "$ORIGIN_HOST" | awk '{print $1; exit}')
- # Последний шанс — dig (если установлен)
if [[ -z "$ORIGIN_IP" ]] && command -v dig >/dev/null; then
ORIGIN_IP=$(dig +short "$ORIGIN_HOST" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n1)
fi
@@ -76,7 +71,6 @@ else
log "Домен $ORIGIN_HOST разрешён в IP: $ORIGIN_IP"
fi
-# Финальная проверка
[[ -n "$ORIGIN_IP" && -n "$ORIGIN_PORT" && -n "$SUB_PATH" ]] || die "Ошибка парсинга URL подписки"
#################################
@@ -194,7 +188,6 @@ EOF
#################################
# NGINX & DOCKER COMPOSE
#################################
-
if $USE_HTTPS; then
cat > nginx.conf </dev/null 2>&1; then
log "docker compose v2 доступен"
else
log "Устанавливаем docker-compose-v2"
- # решаем конфликт с docker-compose-plugin
apt install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages \
docker-compose-v2 || warn "docker-compose-v2 не установлен, возможно уже есть плагин"
fi
@@ -313,27 +304,20 @@ docker compose up -d --build
#################################
LOCAL_IP=$(hostname -I | awk '{print $1}')
-# Проверка и установка UFW, если не установлен
if ! command -v ufw >/dev/null 2>&1; then
echo "UFW не установлен. Устанавливаю..."
apt update -qq && apt install -y ufw
fi
-# Проверка статуса UFW (независимо от локали, на английском)
if LC_ALL=C ufw status 2>/dev/null | grep -q "Status: active"; then
echo "UFW уже активен."
else
echo "ВНИМАНИЕ: UFW выключен или не настроен. Включаю..."
- # Разрешаем SSH (или другой порт, если используете не 22)
- # OpenSSH — стандартный профиль, обычно порт 22
ufw allow OpenSSH >/dev/null 2>&1 || true
- # Если SSH на другом порту, добавьте: ufw allow 2222/tcp
- # Включаем UFW без подтверждения
ufw --force enable >/dev/null 2>&1
- # Проверяем, успешно ли включён
if LC_ALL=C ufw status 2>/dev/null | grep -q "Status: active"; then
echo "UFW успешно включён."
else
@@ -342,7 +326,7 @@ else
fi
fi
-echo "--- 1. Оптимизация сетевого стека ядра ---"
+echo "--- Оптимизация сетевого стека ядра ---"
cat < /etc/sysctl.d/99-relay-optimization.conf
net.ipv4.ip_forward = 1
net.core.default_qdisc = fq
@@ -361,10 +345,9 @@ net.ipv4.tcp_tw_reuse=1
EOF
sysctl --system
-echo "--- 2. Настройка правил перенаправления (before.rules) ---"
+echo "--- Настройка правил перенаправления (before.rules) ---"
cp /etc/ufw/before.rules /etc/ufw/before.rules.bak
-# Создаем временный файл с вашими правилами
cat < /tmp/ufw_nat_rules
*nat
:PREROUTING ACCEPT [0:0]
@@ -400,28 +383,24 @@ COMMIT
EOF
-# Удаляем старые блоки *nat и *mangle из оригинала, если они там были (от прошлых запусков)
-# И создаем чистую копию без них
sed -i '/\*nat/,/COMMIT/d' /etc/ufw/before.rules
sed -i '/\*mangle/,/COMMIT/d' /etc/ufw/before.rules
-# Склеиваем: Сначала NAT/Mangle, потом остаток оригинального before.rules
cat /tmp/ufw_nat_rules /etc/ufw/before.rules > /etc/ufw/before.rules.new
mv /etc/ufw/before.rules.new /etc/ufw/before.rules
-echo "--- 3. Открытие портов в самом фаерволе ---"
-# Разрешаем входящий трафик на эти порты
+echo "--- Открытие портов в самом фаерволе ---"
ufw allow 443/tcp
+ufw allow 443/udp
ufw allow 8443/tcp
+ufw allow 8443/udp
ufw allow "$NGINX_PORT"/tcp
ufw allow 10000:60000/tcp
ufw allow 10000:60000/udp
-# Разрешаем FORWARD (пересылку)
-# Это критически важный шаг для корректной работы DNAT в UFW
sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
-echo "--- 4. Перезапуск ---"
+echo "--- Перезапуск ---"
ufw reload
echo "Готово! Система оптимизирована, порты открыты, трафик перенаправлен."
diff --git a/install.sh b/install.sh
index 4200947..e06442e 100644
--- a/install.sh
+++ b/install.sh
@@ -2,14 +2,13 @@
set -euo pipefail
#################################
-# TRAP ДЛЯ ОТЛАДКИ
+# DEBUG TRAP
#################################
trap 'echo -e "\033[1;31m[ERROR]\033[0m Ошибка в строке $LINENO"; exit 1' ERR
#################################
-# ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
+# HELPER FUNCTIONS
#################################
-
log() { echo -e "\033[1;32m[INFO]\033[0m $1"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
@@ -22,12 +21,13 @@ validate_url() {
}
#################################
-# ПРОВЕРКИ
+# CHECKS
#################################
-
need_root
-# --- ASCII-баннер ---
+#################################
+# ASCII-баннер
+#################################
echo "==================================================="
echo " ____ ____ _ ___ _ "
echo " / __ \___ ____ / __ \(_) (_)___ ______(_)___ ___ "
@@ -39,21 +39,19 @@ echo ""
echo " 3DP-MANAGER FOR 3X-UI "
echo "==================================================="
echo ""
-# --------------------
#################################
-# ВВОД ДАННЫХ
+# INPUT / USER DATA
#################################
-
-# Функция для получения URL панели из 3x-ui
+# Function to get panel URL from 3x-ui
get_xui_url() {
- # Пытаемся выполнить x-ui settings и вытащить строку Access URL
+ # Try to run `x-ui settings` and extract the Access URL line
local output
output=$(x-ui settings 2>/dev/null | grep "Access URL:" | head -1)
if [[ -n "$output" ]]; then
- # Обрезаем всё до последнего пробела и берём URL
- echo "$output" | awk -F': ' '{print $2}' | sed 's/ *$//'
+ # Trim everything before the URL and take it
+ echo "$output" | awk -F': ' '{print $2}' | sed 's/ *$//'
return 0
else
return 1
@@ -65,15 +63,15 @@ echo "Определяем URL панели 3x-ui..."
UI_URL=$(get_xui_url)
if [[ -n "$UI_URL" ]]; then
- UI_URL="${UI_URL%/}" # убираем trailing slash, если есть
- echo "URL панели 3x-ui: $UI_URL"
+ UI_URL="${UI_URL%/}" # remove trailing slash if present
+ echo "URL панели 3x-ui: $UI_URL"
else
echo "Не удалось автоматически получить URL"
read -rp "Введите URL панели 3x-ui вручную (полная ссылка): " UI_URL
UI_URL="${UI_URL%/}"
fi
-# Проверка корректности URL
+# Validate URL correctness
validate_url "$UI_URL" || die "Некорректный URL панели 3x-ui: $UI_URL"
read -rp "Логин 3x-ui: " UI_LOGIN
@@ -81,7 +79,7 @@ read -rsp "Пароль 3x-ui: " UI_PASSWORD
echo
[[ -z "$UI_LOGIN" || -z "$UI_PASSWORD" ]] && die "Логин/пароль обязательны"
-# Проверка логина
+# Check login
LOGIN_RESPONSE=$(curl -s -X POST "$UI_URL/login" -H "Content-Type: application/json" -d "{\"username\":\"$UI_LOGIN\",\"password\":\"$UI_PASSWORD\"}")
# Проверка успешного логина по ключевому полю "success" или наличию куки
@@ -92,9 +90,9 @@ fi
echo "✔ Успешный логин в 3x-ui"
-# Разбор UI_URL
-UI_HOST=$(echo "$UI_URL" | awk -F[/:] '{print $4}') # домен или IP
-UI_PROTO=$(echo "$UI_URL" | awk -F: '{print $1}') # http или https
+# Parse UI_URL
+UI_HOST=$(echo "$UI_URL" | awk -F[/:] '{print $4}') # domain or IP
+UI_PROTO=$(echo "$UI_URL" | awk -F: '{print $1}') # http or https
if [[ "$UI_PROTO" == "https" ]]; then
log "HTTPS панель обнаружена, проверяем SSL сертификаты"
@@ -117,11 +115,11 @@ if [[ "$UI_PROTO" == "https" ]]; then
fi
-# Ввод интервала ротации
+# Input rotation interval
read -rp "Интервал генерации инбаундов в минутах (от 10, по умолчанию 30): " ROTATE_INTERVAL
ROTATE_INTERVAL="${ROTATE_INTERVAL:-30}" # по умолчанию 30
-# Проверка, что это число и ≥10
+# Check that it's a number and ≥10
if ! [[ "$ROTATE_INTERVAL" =~ ^[0-9]+$ ]] || [ "$ROTATE_INTERVAL" -lt 10 ]; then
echo "Неверное значение. Используется значение по умолчанию 30 минут."
ROTATE_INTERVAL=30
@@ -136,19 +134,19 @@ mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"
#################################
-# Получаем флаг
+# Get country flag
#################################
REPO_BASE="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
COUNTRY_FLAG=""
-# Получаем countryCode
+# Get countryCode
IP_JSON=$(curl -s --fail http://ip-api.com/json/ || true)
[ -z "$IP_JSON" ] && exit 0
COUNTRY_CODE=$(echo "$IP_JSON" | jq -r '.countryCode // empty' 2>/dev/null)
[ -z "$COUNTRY_CODE" ] && exit 0
-# URL флагов
+# Flags JSON URL
FLAGS_JSON_URL="$REPO_BASE/app/assets/flags.json"
FLAGS_JSON=$(curl -s "$FLAGS_JSON_URL" || true)
@@ -158,23 +156,20 @@ FLAGS_JSON=$(curl -s "$FLAGS_JSON_URL" || true)
COUNTRY_FLAG=$(echo "$FLAGS_JSON" | jq -r --arg code "$COUNTRY_CODE" '.[] | select(.code == $code) | .emoji // empty' 2>/dev/null | head -n1)
#################################
-# Белый лист
+# Whitelist
#################################
-
curl -fsSL "$REPO_BASE/whitelist.txt" -o whitelist.txt
log "whitelist.txt скопирован"
#################################
-# ГЕНЕРАЦИЯ ТОКЕНА
+# TOKEN GENERATION
#################################
-
SUB_TOKEN="$(openssl rand -hex 24)"
log "Сгенерирован токен подписки"
#################################
# DOCKER
#################################
-
log "Проверка Docker"
if command -v docker >/dev/null 2>&1; then
@@ -187,7 +182,7 @@ else
systemctl restart docker
fi
-# Проверка docker compose v2
+# Check docker compose v2
if docker compose version >/dev/null 2>&1; then
log "docker compose v2 доступен"
else
@@ -198,15 +193,14 @@ else
fi
#################################
-# СТРУКТУРА
+# STRUCTURE
#################################
-
mkdir -p app app/builders subscriptions
-# Генерация случайного свободного порта для подписки/Nginx
+# Generate a random free port for subscription/Nginx
get_random_port() {
while :; do
- PORT=$((RANDOM % 50000 + 10000)) # диапазон 10000-60000
+ PORT=$((RANDOM % 50000 + 10000)) # range 10000-60000
if ! ss -ltn | awk '{print $4}' | grep -q ":$PORT\$"; then
echo "$PORT"
return
@@ -215,13 +209,12 @@ get_random_port() {
}
NGINX_PORT=$(get_random_port)
-# Генерация URL подписки
+# Generate subscription URL
SUB_URL="$UI_PROTO://$UI_HOST:$NGINX_PORT/bus/$SUB_TOKEN"
#################################
# ENV
#################################
-
cat > .env < docker-compose.yml </dev/null || die "Backend не запущен"
docker compose ps | grep nginx >/dev/null || die "Nginx не запущен"
#################################
-# РЕЗУЛЬТАТ
+# RESULT
#################################
-
log "✔ Установка завершена"
echo
echo "URL подписки:"
diff --git a/update.sh b/update.sh
index a7658d0..164b984 100644
--- a/update.sh
+++ b/update.sh
@@ -9,7 +9,6 @@ trap 'echo -e "\033[1;31m[ERROR]\033[0m Ошибка в строке $LINENO"; e
#################################
# HELPERS
#################################
-
log() { echo -e "\033[1;32m[INFO]\033[0m $1"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
@@ -21,14 +20,12 @@ need_root() {
#################################
# CONFIG
#################################
-
PROJECT_DIR="/opt/3dp-manager"
REPO_RAW="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
#################################
# START
#################################
-
need_root
log "Обновление 3dp-manager"
@@ -40,14 +37,12 @@ cd "$PROJECT_DIR"
#################################
# CHECK DOCKER
#################################
-
command -v docker >/dev/null 2>&1 || die "Docker не установлен"
docker compose version >/dev/null 2>&1 || die "docker compose v2 недоступен"
#################################
# DOWNLOAD FILES
#################################
-
log "Загружаем обновлённые файлы из репозитория"
mkdir -p app
@@ -70,21 +65,18 @@ log "Файлы обновлены"
#################################
# REBUILD BACKEND
#################################
-
log "Пересобираем backend"
docker compose build node
#################################
# RESTART CONTAINERS
#################################
-
log "Перезапускаем контейнеры"
docker compose up -d
#################################
# HEALTH CHECK
#################################
-
sleep 2
docker compose ps | grep node >/dev/null || die "Backend не запущен"
@@ -93,5 +85,4 @@ docker compose ps | grep nginx >/dev/null || die "Nginx не запущен"
#################################
# DONE
#################################
-
-log "3dp-manager успешно обновлён ✅"
+log "3dp-manager успешно обновлён ✅"
\ No newline at end of file
From 421c2e42ca4b730a247333f86fd4952f58973029 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 14:45:02 +0300
Subject: [PATCH 05/17] nginx headers
---
forwarding_install.sh | 6 ++++++
install.sh | 4 ++++
2 files changed, 10 insertions(+)
diff --git a/forwarding_install.sh b/forwarding_install.sh
index 39a7781..c9c1e4c 100644
--- a/forwarding_install.sh
+++ b/forwarding_install.sh
@@ -206,6 +206,9 @@ http {
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+
+ add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
+ add_header Access-Control-Allow-Origin *;
}
}
}
@@ -246,6 +249,9 @@ http {
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+
+ add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
+ add_header Access-Control-Allow-Origin *;
}
}
}
diff --git a/install.sh b/install.sh
index e06442e..da98754 100644
--- a/install.sh
+++ b/install.sh
@@ -293,6 +293,8 @@ http {
location = /bus/$SUB_TOKEN {
alias /subscriptions/list.txt;
default_type text/plain;
+ add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
+ add_header Access-Control-Allow-Origin *;
}
location / {
@@ -334,6 +336,8 @@ http {
location = /bus/$SUB_TOKEN {
alias /subscriptions/list.txt;
default_type text/plain;
+ add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
+ add_header Access-Control-Allow-Origin *;
}
location / {
From e3c54ce10d4958912fba41c4ebf4d7f4df78a3e7 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 15:00:49 +0300
Subject: [PATCH 06/17] fix url
---
install.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/install.sh b/install.sh
index da98754..f350f15 100644
--- a/install.sh
+++ b/install.sh
@@ -63,7 +63,9 @@ echo "Определяем URL панели 3x-ui..."
UI_URL=$(get_xui_url)
if [[ -n "$UI_URL" ]]; then
- UI_URL="${UI_URL%/}" # remove trailing slash if present
+ while [[ "$UI_URL" == */ ]]; do # remove trailing slash if present
+ UI_URL="${UI_URL%/}"
+ done
echo "URL панели 3x-ui: $UI_URL"
else
echo "Не удалось автоматически получить URL"
From 06395d81fb236bde0bf0e4cab5e2cf83659cdbb7 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 15:05:24 +0300
Subject: [PATCH 07/17] fix ui url
---
install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install.sh b/install.sh
index f350f15..5d9622a 100644
--- a/install.sh
+++ b/install.sh
@@ -50,8 +50,8 @@ get_xui_url() {
output=$(x-ui settings 2>/dev/null | grep "Access URL:" | head -1)
if [[ -n "$output" ]]; then
- # Trim everything before the URL and take it
- echo "$output" | awk -F': ' '{print $2}' | sed 's/ *$//'
+ # Trim everything before the URL and remove trailing whitespace/CR and trailing slashes
+ echo "$output" | awk -F': ' '{print $2}' | sed -e 's/[[:space:]]*$//' -e 's:/*$::'
return 0
else
return 1
From 44b107422d95647f1f0a9edec7b8960cb0764c93 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 15:10:49 +0300
Subject: [PATCH 08/17] url
---
install.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/install.sh b/install.sh
index 5d9622a..d12338f 100644
--- a/install.sh
+++ b/install.sh
@@ -63,9 +63,9 @@ echo "Определяем URL панели 3x-ui..."
UI_URL=$(get_xui_url)
if [[ -n "$UI_URL" ]]; then
- while [[ "$UI_URL" == */ ]]; do # remove trailing slash if present
- UI_URL="${UI_URL%/}"
- done
+ # Remove carriage returns and trailing whitespace, then strip trailing slashes
+ UI_URL="${UI_URL//$'\r'/}"
+ UI_URL="$(echo -n "$UI_URL" | sed -e 's/[[:space:]]*$//' -e 's:/*$::')"
echo "URL панели 3x-ui: $UI_URL"
else
echo "Не удалось автоматически получить URL"
From 2608937f9b88eda4d29ec7f671dba474d1484b2f Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 15:17:41 +0300
Subject: [PATCH 09/17] URL
---
install.sh | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/install.sh b/install.sh
index d12338f..94a335a 100644
--- a/install.sh
+++ b/install.sh
@@ -50,8 +50,8 @@ get_xui_url() {
output=$(x-ui settings 2>/dev/null | grep "Access URL:" | head -1)
if [[ -n "$output" ]]; then
- # Trim everything before the URL and remove trailing whitespace/CR and trailing slashes
- echo "$output" | awk -F': ' '{print $2}' | sed -e 's/[[:space:]]*$//' -e 's:/*$::'
+ # Extract the URL only (stop at space or closing parenthesis), then trim whitespace/CR and trailing slashes
+ echo "$output" | grep -oE 'https?://[^[:space:]\)\]\}]*' | head -n1 | sed -e 's/[[:space:]]*$//' -e 's:/*$::'
return 0
else
return 1
@@ -64,8 +64,6 @@ UI_URL=$(get_xui_url)
if [[ -n "$UI_URL" ]]; then
# Remove carriage returns and trailing whitespace, then strip trailing slashes
- UI_URL="${UI_URL//$'\r'/}"
- UI_URL="$(echo -n "$UI_URL" | sed -e 's/[[:space:]]*$//' -e 's:/*$::')"
echo "URL панели 3x-ui: $UI_URL"
else
echo "Не удалось автоматически получить URL"
From 045246a6f24ec33edb8a6914558ed96e6c27384b Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 15:49:40 +0300
Subject: [PATCH 10/17] fix: getting url
---
install.sh | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/install.sh b/install.sh
index 94a335a..d6fbd0e 100644
--- a/install.sh
+++ b/install.sh
@@ -45,32 +45,24 @@ echo ""
#################################
# Function to get panel URL from 3x-ui
get_xui_url() {
- # Try to run `x-ui settings` and extract the Access URL line
- local output
- output=$(x-ui settings 2>/dev/null | grep "Access URL:" | head -1)
+ local output=$(x-ui settings 2>/dev/null)
- if [[ -n "$output" ]]; then
- # Extract the URL only (stop at space or closing parenthesis), then trim whitespace/CR and trailing slashes
- echo "$output" | grep -oE 'https?://[^[:space:]\)\]\}]*' | head -n1 | sed -e 's/[[:space:]]*$//' -e 's:/*$::'
- return 0
- else
- return 1
- fi
+ echo "$output" | grep -oE 'https?://[^ ]+' | head -n1
}
echo "Определяем URL панели 3x-ui..."
UI_URL=$(get_xui_url)
-if [[ -n "$UI_URL" ]]; then
- # Remove carriage returns and trailing whitespace, then strip trailing slashes
- echo "URL панели 3x-ui: $UI_URL"
-else
+if [[ -z "$UI_URL" ]]; then
echo "Не удалось автоматически получить URL"
- read -rp "Введите URL панели 3x-ui вручную (полная ссылка): " UI_URL
- UI_URL="${UI_URL%/}"
+ read -rp "Введите URL панели 3x-ui вручную: " UI_URL
fi
+UI_URL=$(echo "$UI_URL" | sed -E 's/[[:space:]]*$//; s|/*$||')
+
+echo "URL панели 3x-ui: $UI_URL"
+
# Validate URL correctness
validate_url "$UI_URL" || die "Некорректный URL панели 3x-ui: $UI_URL"
From 9cd41884cd19cbae5fc08fb8e8518352212cbb64 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 15:58:09 +0300
Subject: [PATCH 11/17] fix url
---
install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install.sh b/install.sh
index d6fbd0e..2504411 100644
--- a/install.sh
+++ b/install.sh
@@ -47,7 +47,7 @@ echo ""
get_xui_url() {
local output=$(x-ui settings 2>/dev/null)
- echo "$output" | grep -oE 'https?://[^ ]+' | head -n1
+ echo "$output" | sed 's/\x1b\[[0-9;]*m//g' | grep "Access URL:" | grep -oE 'https?://[^[:space:]]+' | head -n1
}
echo "Определяем URL панели 3x-ui..."
From 8413d52c695d8d81a044481540ccdfda75e31bcd Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Tue, 23 Dec 2025 23:25:28 +0300
Subject: [PATCH 12/17] delete inbounds
---
README.md | 1 +
app/builders/buildInboundLink.js | 4 ++--
app/builders/buildVmessTcp.js | 3 ++-
app/index.js | 36 ++++++++++++++++++++++++++++----
4 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index f703091..933fb5e 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@
- Реквизиты / донаты:
- Карта МИР: `2204320436318077`
- Карта MasterCard: `5395452209474530`
+ - ЮМоney: `4100116897060652`
- PayPal: `vasiljevdenisx@gmail.com`
- USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
- USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
diff --git a/app/builders/buildInboundLink.js b/app/builders/buildInboundLink.js
index fa9967e..b3f26b0 100644
--- a/app/builders/buildInboundLink.js
+++ b/app/builders/buildInboundLink.js
@@ -107,7 +107,7 @@ function buildVmessLink(inbound, domain, uuid) {
net: stream.network || "tcp",
path: "/",
port: inbound.port,
- ps: flag + ' ' + inbound.remark,
+ ps: decodeURIComponent(flag) + ' ' + inbound.remark,
scy: "",
sni: "",
tls: stream.security || "none",
@@ -157,6 +157,6 @@ function buildTrojanLink(inbound, domain, password) {
`&sni=${sni}` +
`&sid=${sid}` +
`&spx=${spx}` +
- `#${flag}%20${inbound.remark}-${password}`
+ `#${flag}%20${inbound.remark}`
);
}
\ No newline at end of file
diff --git a/app/builders/buildVmessTcp.js b/app/builders/buildVmessTcp.js
index 0b71e8d..c138586 100644
--- a/app/builders/buildVmessTcp.js
+++ b/app/builders/buildVmessTcp.js
@@ -14,7 +14,8 @@ export function buildVmessTcp({ port, uuid }) {
totalGB: 0,
expiryTime: 0,
tgId: "",
- subId: "",
+ subId: "0",
+ alterId: "0",
reset: 0
}],
}),
diff --git a/app/index.js b/app/index.js
index 50e8af0..e1435a2 100644
--- a/app/index.js
+++ b/app/index.js
@@ -13,6 +13,7 @@ import { buildInboundLink } from "./builders/buildInboundLink.js";
const { UI_URL, UI_LOGIN, UI_PASSWORD, UI_HOST } = process.env;
const SUB_FILE = "/subscriptions/list.txt";
+const LAST_INBOUNDS = '/subscriptions/latestInbounds.json';
const cookieJar = {};
const api = axios.create({ baseURL: UI_URL, timeout: 15000, withCredentials: true });
@@ -124,6 +125,26 @@ async function getInbounds() {
} catch (e) { console.error("Get inbounds failed:", e.message); return []; }
}
+async function deleteInbounds() {
+ try {
+ const data = fs.readFileSync(LAST_INBOUNDS, 'utf-8');
+ const oldIds = JSON.parse(data);
+
+ if (Array.isArray(oldIds) && oldIds.length > 0) {
+ console.log(`Удаляем старые инбаунды: ${oldIds.length} шт.`);
+ for (const id of oldIds) {
+ try {
+ await deleteInbound(id);
+ } catch (err) {
+ console.error(`Ошибка при удалении инбаунда ${id}:`, err.message);
+ }
+ }
+ }
+ } catch (error) {
+ console.log("Старых ID не найдено, пропускаем удаление.");
+ }
+}
+
async function deleteInbound(id) {
try { await api.post(`/panel/api/inbounds/del/${id}`); } catch { }
}
@@ -131,7 +152,7 @@ async function deleteInbound(id) {
async function addInbound(config) {
try {
const res = await api.post("/panel/api/inbounds/add", config);
- return res.data?.id || null;
+ return res.data?.obj?.id || null;
} catch (e) {
console.error("Add inbound failed:", e.message);
return null;
@@ -147,8 +168,7 @@ async function rotate() {
const usedPorts = new Set();
const subs = [];
- const existing = await getInbounds();
- for (const i of existing) await deleteInbound(i.id);
+ await deleteInbounds();
const builders = [
async (d) => buildVlessRealityTcp({ port: await isPortFree(8443) ? 8443 : await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
@@ -163,6 +183,8 @@ async function rotate() {
async (d) => buildTrojanRealityTcp({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
];
+ const inboundIds = [];
+
for (const b of builders) {
const domain = pickDomain(whitelist);
const inbound = await b(domain);
@@ -172,7 +194,13 @@ async function rotate() {
// Build the link depending on the protocol
const link = buildInboundLink(inbound, UI_HOST, idOrPass);
if (link) subs.push(link);
- await addInbound(inbound);
+ const id = await addInbound(inbound);
+ inboundIds.push(id);
+ }
+
+ if (inboundIds.length > 0) {
+ fs.writeFileSync(LAST_INBOUNDS, JSON.stringify(inboundIds, null, 2));
+ console.log(`Новые ID (${inboundIds.length} шт.) сохранены в ${LAST_INBOUNDS}`);
}
fs.writeFileSync(SUB_FILE, subs.join("\n") + "\n", "utf8");
From a4e5808b044d15e1b1330b1f5cb36f1358a0c0c7 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Thu, 25 Dec 2025 14:52:44 +0300
Subject: [PATCH 13/17] my_whitelist
---
get_domains.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/get_domains.js b/get_domains.js
index 7f64e84..9fd5e8e 100644
--- a/get_domains.js
+++ b/get_domains.js
@@ -48,7 +48,7 @@ async function processSubscription() {
const result = Array.from(domains).sort(); // Сортируем для удобства
if (result.length > 0) {
- fs.writeFileSync('domains.txt', result.join('\n'), 'utf8');
+ fs.writeFileSync('my_whitelist.txt', result.join('\n'), 'utf8');
console.log(`Успешно! Сохранено уникальных доменов: ${result.length}`);
} else {
console.log('Валидные домены не найдены.');
From 13e64b4e866e472d87f9ae6269ba6e8192a05233 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Thu, 25 Dec 2025 15:44:53 +0300
Subject: [PATCH 14/17] fix readme
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 933fb5e..6477b93 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
-Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на оснвном, так и на промежуточном сервере.
+Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на основном, так и на промежуточном сервере.
## Сбор доменов из мульти-подписок
@@ -138,7 +138,7 @@ node get_domains.js
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
-Краткое описание: добавляет ваш файл доменов в контейнер приложения.
+Краткое описание: добавляет ваш файл доменов в контейнер приложения. Чтобы сразу же сгенерировать инбаунды с новыи списком, выполните `docker exec -it node sh` и затем `node index.js`.
---
From 3cb0e4e77e2f47fc854f41f67cc317f161e8a12d Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Thu, 25 Dec 2025 22:11:57 +0300
Subject: [PATCH 15/17] fix
---
delete.sh | 12 ++++++++++++
forwarding_delete.sh | 12 ++++++++++++
forwarding_install.sh | 2 ++
install.sh | 2 ++
4 files changed, 28 insertions(+)
diff --git a/delete.sh b/delete.sh
index 1bc7e2c..c3212b3 100644
--- a/delete.sh
+++ b/delete.sh
@@ -17,6 +17,18 @@ need_root() {
[[ $EUID -eq 0 ]] || die "Запускать только от root"
}
+read -r -p "Вы уверены, что хотите удалить? (y/N): " answer
+
+case "$answer" in
+ y|Y)
+ echo "Начинаю удаление..."
+ ;;
+ *)
+ echo "Удаление отменено"
+ exit 1
+ ;;
+esac
+
#################################
# START
#################################
diff --git a/forwarding_delete.sh b/forwarding_delete.sh
index e310a25..1854467 100644
--- a/forwarding_delete.sh
+++ b/forwarding_delete.sh
@@ -14,6 +14,18 @@ warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
[[ $EUID -eq 0 ]] || { echo "Запускать нужно от root"; exit 1; }
+read -r -p "Вы уверены, что хотите удалить? (y/N): " answer
+
+case "$answer" in
+ y|Y)
+ echo "Начинаю удаление..."
+ ;;
+ *)
+ echo "Удаление отменено"
+ exit 1
+ ;;
+esac
+
#################################
# PATHS
#################################
diff --git a/forwarding_install.sh b/forwarding_install.sh
index c9c1e4c..65b4762 100644
--- a/forwarding_install.sh
+++ b/forwarding_install.sh
@@ -225,6 +225,7 @@ services:
nginx:
image: nginx:alpine
+ restart: unless-stopped
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
@@ -268,6 +269,7 @@ services:
nginx:
image: nginx:alpine
+ restart: unless-stopped
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
diff --git a/install.sh b/install.sh
index 2504411..240fdcc 100644
--- a/install.sh
+++ b/install.sh
@@ -261,6 +261,7 @@ services:
nginx:
image: nginx:alpine
+ restart: unless-stopped
depends_on: [node]
ports:
- "$NGINX_PORT:$NGINX_PORT"
@@ -309,6 +310,7 @@ services:
nginx:
image: nginx:alpine
+ restart: unless-stopped
depends_on: [node]
ports:
- "$NGINX_PORT:$NGINX_PORT"
From 84e7db078528d507e46afc7177913862885dc41a Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Thu, 25 Dec 2025 22:22:57 +0300
Subject: [PATCH 16/17] fix proto
---
forwarding_install.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/forwarding_install.sh b/forwarding_install.sh
index 65b4762..916831e 100644
--- a/forwarding_install.sh
+++ b/forwarding_install.sh
@@ -111,7 +111,12 @@ cd "$BASE_DIR"
#################################
REPO="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
NGINX_PORT=$ORIGIN_PORT
-SUB_URL="$ORIGIN_PROTO://$LOCAL_HOST:$NGINX_PORT$SUB_PATH"
+if [[ "$USE_HTTPS" == "true" ]]; then
+ NGINX_PROTO="https"
+else
+ NGINX_PROTO="http"
+fi
+SUB_URL="$NGINX_PROTO://$LOCAL_HOST:$NGINX_PORT$SUB_PATH"
#################################
# ENV
From dbc38bb14231281bd676a7bfc1bfc10ebd1e4236 Mon Sep 17 00:00:00 2001
From: Den Piligrim <89912505+vasiljevdenis@users.noreply.github.com>
Date: Thu, 25 Dec 2025 22:47:22 +0300
Subject: [PATCH 17/17] preparation for release
---
README.md | 10 +++++-----
README_CN.md | 10 +++++-----
README_EN.md | 10 +++++-----
README_IR.md | 10 +++++-----
README_TK.md | 10 +++++-----
app/docker-compose.example.yml | 1 +
app/index.js | 2 +-
app/nginx.example.conf | 2 ++
forwarding_install.sh | 2 +-
install.sh | 2 +-
update.sh | 2 +-
11 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
index 6477b93..4e7cd6b 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@
Установите проект на сервер командой:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы.
@@ -72,7 +72,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Обновление до последней версии:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
Краткое описание: подтягивает последние изменения и перезапускает контейнеры.
@@ -82,7 +82,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Полное удаление сервиса:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки.
@@ -94,7 +94,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Сервис перенаправления позволяет проксировать входящие порты с промежуточного сервера на основной.
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки.
@@ -102,7 +102,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
## Удаление перенаправления
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
Краткое описание: удаляет правила и отключает сервис перенаправления.
diff --git a/README_CN.md b/README_CN.md
index 5740aad..e4d0b75 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -61,7 +61,7 @@
在服务器上运行以下命令安装项目:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
简要说明:运行安装脚本并部署容器和服务。
@@ -71,7 +71,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
更新到最新版本:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
简要说明:拉取最新更改并重启容器。
@@ -81,7 +81,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
彻底删除服务:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
简要说明:删除容器和配置文件,恢复到安装前状态。
@@ -93,7 +93,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
转发服务允许将中继服务器的入站端口代理到主服务器。
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
简要说明:添加转发规则并创建用于更新订阅的服务。
@@ -101,7 +101,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
## 删除转发
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
简要说明:删除规则并禁用转发服务。
diff --git a/README_EN.md b/README_EN.md
index e37473a..42919be 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -61,7 +61,7 @@ Recommendations:
Install the project on your server with:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
Short description: runs the installer script and deploys containers and services.
@@ -71,7 +71,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Update to the latest version:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
Short description: pulls the latest changes and restarts containers.
@@ -81,7 +81,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Remove the service completely:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
Short description: removes containers and configuration files, restoring the system to the pre-install state.
@@ -93,7 +93,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
The forwarding service allows proxying incoming ports from the intermediate server to the main server.
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
Short description: adds forwarding rules and creates a service to update the subscription.
@@ -101,7 +101,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
## Remove forwarding
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
Short description: removes rules and disables the forwarding service.
diff --git a/README_IR.md b/README_IR.md
index 22dd4ef..f65de74 100644
--- a/README_IR.md
+++ b/README_IR.md
@@ -61,7 +61,7 @@
برای نصب پروژه در سرور، دستور زیر را اجرا کنید:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویسها را راهاندازی میکند.
@@ -71,7 +71,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
برای بهروزرسانی به آخرین نسخه:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
توضیح کوتاه: تغییرات جدید را میکشد و کانتینرها را ریاستارت میکند.
@@ -81,7 +81,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
برای حذف کامل سرویس:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
توضیح کوتاه: کانتینرها و فایلهای پیکربندی را حذف میکند و سیستم را به وضعیت پیش از نصب برمیگرداند.
@@ -93,7 +93,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
سرویس فورواردینگ امکان پراکسی کردن پورتهای ورودی از سرور واسط به سرور اصلی را فراهم میکند.
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای بهروزرسانی اشتراک ایجاد میکند.
@@ -101,7 +101,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
## حذف فورواردینگ
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال میکند.
diff --git a/README_TK.md b/README_TK.md
index 656e48e..7b5617e 100644
--- a/README_TK.md
+++ b/README_TK.md
@@ -61,7 +61,7 @@ Maslahatchylyklar:
Taslamany serwera gurnamak üçin şu komandany ýerine ýetiriň:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
Gysgaça: gurnama skripti işledilýär we konteýnerler we hyzmatlar döredilýär.
@@ -71,7 +71,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Soňky wersiýa çenli täzeläň:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/update.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
Gysgaça: iň soňky üýtgeşmeleri çekýär we konteýnerleri gaýtadan işledýär.
@@ -81,7 +81,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Hyzmaty doly pozmak üçin:
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
Gysgaça: konteýnerleri we konfigurasiýa faýllaryny pozup, systemany gurnamadan öňki ýagdaýyna getirer.
@@ -93,13 +93,13 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-f
Forwarding hyzmaty aragatnaşyk serwerinden esasy servere gelýän portlary proxy arkaly geçirýär.
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_install.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
## Forwarding-i pozmak
```bash
-bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/forwarding_delete.sh)
+bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
---
diff --git a/app/docker-compose.example.yml b/app/docker-compose.example.yml
index f33bc59..89f7014 100644
--- a/app/docker-compose.example.yml
+++ b/app/docker-compose.example.yml
@@ -9,6 +9,7 @@ services:
nginx:
image: nginx:alpine
+ restart: unless-stopped
depends_on: [node]
ports:
- "80:80"
diff --git a/app/index.js b/app/index.js
index e1435a2..56afa2e 100644
--- a/app/index.js
+++ b/app/index.js
@@ -24,7 +24,7 @@ api.interceptors.request.use(config => {
});
const WHITELIST_FILE = "/app/whitelist.txt";
-const WHITELIST_REPO_URL = "https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix/whitelist.txt";
+const WHITELIST_REPO_URL = "https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/whitelist.txt";
// Helper functions
async function updateWhitelist() {
diff --git a/app/nginx.example.conf b/app/nginx.example.conf
index fcdc8a1..fd75cc9 100644
--- a/app/nginx.example.conf
+++ b/app/nginx.example.conf
@@ -7,6 +7,8 @@ http {
location = /bus/$SUB_TOKEN {
alias /subscriptions/list.txt;
default_type text/plain;
+ add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
+ add_header Access-Control-Allow-Origin *;
}
location / {
diff --git a/forwarding_install.sh b/forwarding_install.sh
index 916831e..debc6fd 100644
--- a/forwarding_install.sh
+++ b/forwarding_install.sh
@@ -109,7 +109,7 @@ cd "$BASE_DIR"
#################################
# DOWNLOAD FILES
#################################
-REPO="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
+REPO="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
NGINX_PORT=$ORIGIN_PORT
if [[ "$USE_HTTPS" == "true" ]]; then
NGINX_PROTO="https"
diff --git a/install.sh b/install.sh
index 240fdcc..686b977 100644
--- a/install.sh
+++ b/install.sh
@@ -128,7 +128,7 @@ cd "$PROJECT_DIR"
#################################
# Get country flag
#################################
-REPO_BASE="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
+REPO_BASE="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
COUNTRY_FLAG=""
# Get countryCode
diff --git a/update.sh b/update.sh
index 164b984..e44211e 100644
--- a/update.sh
+++ b/update.sh
@@ -21,7 +21,7 @@ need_root() {
# CONFIG
#################################
PROJECT_DIR="/opt/3dp-manager"
-REPO_RAW="https://raw.githubusercontent.com/denpiligrim/3dp-manager/dp-fix"
+REPO_RAW="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
#################################
# START