3X-UI_autoVPS: баннер Hacker 07, новое имя вместо 3X-UI KIT, терпимая шапка релиза; -дублирование подсказки SSH; робот без --apply

This commit is contained in:
2026-10-12 21:30:39 +03:00
parent c270b09891
commit 8d470f3eb1
16 changed files with 166 additions and 79 deletions
+4 -10
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# 3X-UI KIT (форк hacker07) — установка сервера одной командой из нашего канала.
# 3X-UI_autoVPS (форк hacker07) — установка сервера одной командой из нашего канала.
#
# Что делает (по шагам):
# 1) проверяет сервер и наличие curl, ssh-keygen, openssl;
@@ -47,7 +47,7 @@ GITEA="${KIT_FORK_BASE:-https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS}"
NS="3x-ui-kit-release"
SIG_ID="releases@3x-ui-kit"
# Публичный ключ форка. Меняется только вместе с ключом подписи (тогда обновляется и здесь, и в kit).
SIGNER_PUB='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKM0Sfn/UQeqjvUvY9wVgg7QtG1RR2pEUkqrUD5Yy6EF 3X-UI KIT fork releases (hacker07)'
SIGNER_PUB='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKM0Sfn/UQeqjvUvY9wVgg7QtG1RR2pEUkqrUD5Yy6EF 3X-UI_autoVPS fork releases (hacker07)'
G=$'\e[32m'; Y=$'\e[33m'; R=$'\e[31m'; B=$'\e[1m'; D=$'\e[2m'; N=$'\e[0m'
[[ -t 1 ]] || { G=; Y=; R=; B=; D=; N=; }
@@ -57,7 +57,7 @@ die() { printf '%s\n' "${R}✗${N} $*" >&2; exit 1; }
usage() {
cat <<'EOF'
3X-UI KIT (форк hacker07) — установка сервера одной командой из нашего канала.
3X-UI_autoVPS (форк hacker07) — установка сервера одной командой из нашего канала.
bash <(curl -fsSL <наш Gitea>/raw/branch/main/scripts/3x-ui-local.sh) [флаги…]
@@ -385,12 +385,6 @@ ask_ssh_port() { # пусто — оставить как есть; иначе
if [[ -n $ssh_port ]]; then
say "перевожу SSH на порт $ssh_port: новый добавляю, прежний пока остаётся рабочим"
kit local ssh "$ssh_port" || warn "порт не добавился — сделайте отдельно: kit local ssh $ssh_port"
cat <<EOF
${Y}Дальше обязательно (иначе можно потерять доступ к серверу):${N}
1) откройте ВТОРОЕ окно и проверьте вход: ssh -p $ssh_port root@<IP сервера>
2) вход работает — закройте прежние порты: kit local ssh --close-old $ssh_port
EOF
fi
# пароль root: в флагах его нет намеренно — значение в командной строке видно в списке процессов
@@ -410,7 +404,7 @@ fi
cat <<EOF
${G}${B}Готово.${N} Сервер поставлен из нашей сборки (3X-UI KIT $KIT_VERSION, канал: наш Gitea).
${G}${B}Готово.${N} Сервер поставлен из нашей сборки (3X-UI_autoVPS $KIT_VERSION, канал: наш Gitea).
подписка и ссылки: kit user link admin (или страница подписки из вывода установщика)
если что-то не так: kit check --deep, затем kit fix
+21 -21
View File
@@ -372,15 +372,15 @@ kit_banner() {
echo
printf '%s' "$G"
cat <<'ART'
_ _ _ _ _ _ _
(_) |_ ___ _ __ ___ | |_| | ___ _| |__ _ __(_) ___| | __
| | __/ __| '_ \ / _ \| __| |/ / | | | '_ \| '__| |/ __| |/ /
| | |_\__ \ | | | (_) | |_| <| |_| | |_) | | | | (__| <
|_|\__|___/_| |_|\___/ \__|_|\_\\__,_|_.__/|_| |_|\___|_|\_\
_ _ _ ___ _____
| | | | __ _ ___| | _____ _ __ / _ \___ |
| |_| |/ _` |/ __| |/ / _ \ '__| | | | | / /
| _ | (_| | (__| < __/ | | |_| |/ /
|_| |_|\__,_|\___|_|\_\___|_| \___//_/
ART
printf '%s' "$N"
echo
echo "${B}3X-UI KIT $KIT_VERSION${N} · it's not Kubrick. it's just a VPN."
echo "${B}3X-UI_autoVPS $KIT_VERSION${N} · сборка форка: панель 3X-UI и VPN-протоколы на одном порту"
echo "${D}на основе панели 3X-UI (MHSanaei/3x-ui) и ядра Xray · github.com/itsnotkubrick/3X-UI_KIT${N}"
}
@@ -761,7 +761,7 @@ main() {
[[ $SINGLE == yes ]] && links=$(sed "s/^\(tg:\/\/proxy?\)\(.*\)port=${INNER[mtproto]}/\1\2port=443/" <<<"$links")
umask 077
{
echo "3X-UI KIT (3X-UI $XUI_VERSION) – данные для входа (файл виден только root)"
echo "3X-UI_autoVPS (3X-UI $XUI_VERSION) – данные для входа (файл виден только root)"
echo
echo "Панель: $panel_url"
echo "Логин: $XUI_USERNAME"
@@ -1480,7 +1480,7 @@ setup_nginx() {
local panel_path=/${XUI_WEB_BASE_PATH#/}
panel_path=${panel_path%/}/
{
echo "# Сгенерировано 3x-ui.sh (3X-UI KIT) – перезаписывается при повторном запуске."
echo "# Сгенерировано 3x-ui.sh (3X-UI_autoVPS) – перезаписывается при повторном запуске."
echo "stream {"
echo " map \$ssl_preread_server_name \$kit_upstream {"
[[ -n $reality_sni ]] && echo " $reality_sni 127.0.0.1:${INNER[reality]};"
@@ -1500,7 +1500,7 @@ setup_nginx() {
echo "}"
} >/etc/nginx/kit-stream.conf
cat >/etc/nginx/conf.d/kit.conf <<NGX
# Сгенерировано 3x-ui.sh (3X-UI KIT) – перезаписывается при повторном запуске.
# Сгенерировано 3x-ui.sh (3X-UI_autoVPS) – перезаписывается при повторном запуске.
server {
listen 127.0.0.1:${INNER[web]} ssl http2 proxy_protocol;
server_name _;
@@ -1588,14 +1588,14 @@ setup_subscription() {
# Без subURI панель показывает ссылку на внутренний порт 2097, до которого снаружи не достучаться.
local uri="https://$HOST:$SUB_PORT$SUB_PATH"
[[ $SINGLE == yes ]] && uri="https://$HOST$SUB_PATH"
upd=$(jq -c --arg path "$SUB_PATH" --argjson ip "$SUB_INTERNAL" --arg title "3X-UI KIT" --arg uri "$uri" '
upd=$(jq -c --arg path "$SUB_PATH" --argjson ip "$SUB_INTERNAL" --arg title "3X-UI_autoVPS" --arg uri "$uri" '
.subEnable = true | .subPath = $path | .subTitle = $title | .subListen = "127.0.0.1" | .subPort = $ip
| .subURI = $uri
| .subCertFile = "" | .subKeyFile = ""
| .subClashEnable = true | .subClashAutoDetect = true | .subJsonEnable = true | .subJsonAutoDetect = true' <<<"$all")
else
SUB_PORT=$(jq -r '.subPort // 2096' <<<"$all")
upd=$(jq -c --arg path "$SUB_PATH" --arg title "3X-UI KIT" '
upd=$(jq -c --arg path "$SUB_PATH" --arg title "3X-UI_autoVPS" '
.subEnable = true | .subPath = $path | .subTitle = $title
| .subClashEnable = true | .subClashAutoDetect = true | .subJsonEnable = true | .subJsonAutoDetect = true' <<<"$all")
fi
@@ -1616,7 +1616,7 @@ setup_subscription() {
kit_sub_unit() { # путь-к-сертификату путь-к-ключу (пусто – за nginx)
cat <<UNIT
[Unit]
Description=kit-sub: подписка с учётом приложения (3X-UI KIT)
Description=kit-sub: подписка с учётом приложения (3X-UI_autoVPS)
After=network-online.target x-ui.service
Wants=network-online.target
@@ -1718,11 +1718,11 @@ safe_env() { # файл имя...
local f=$1 n re; shift
[[ -r $f ]] || die "В копии нет файла ${f##*/}."
[[ $(LC_ALL=C tr -d '\n -~' <"$f" | wc -c) -eq 0 ]] \
|| die "Это не резервная копия 3X-UI KIT или она повреждена (файл ${f##*/}). Ничего не менял."
|| die "Это не резервная копия 3X-UI_autoVPS или она повреждена (файл ${f##*/}). Ничего не менял."
LC_ALL=C grep -aqvE "^([A-Z][A-Z0-9_]*=([A-Za-z0-9._:/@%+,=_-]*|''))?$" "$f" \
&& die "Это не резервная копия 3X-UI KIT или она повреждена (файл ${f##*/}). Ничего не менял."
&& die "Это не резервная копия 3X-UI_autoVPS или она повреждена (файл ${f##*/}). Ничего не менял."
while IFS= read -r n; do
[[ " $* " == *" $n "* ]] || die "Это не резервная копия 3X-UI KIT или она повреждена (лишнее имя $n в ${f##*/}). Ничего не менял."
[[ " $* " == *" $n "* ]] || die "Это не резервная копия 3X-UI_autoVPS или она повреждена (лишнее имя $n в ${f##*/}). Ничего не менял."
case $n in
BACKUP_KIT_VERSION) re='^[0-9]{1,3}(\.[0-9]{1,3}){1,3}$' ;;
BACKUP_HOST | HOST) re='^[A-Za-z0-9.:-]{1,253}$' ;;
@@ -1740,10 +1740,10 @@ safe_env() { # файл имя...
SUB_PATH) re='^/[A-Za-z0-9_-]{1,64}/$' ;;
SINGLE) re='^(yes|no)?$' ;;
MTPROTO_INNER) re='^[0-9]{0,5}$' ;;
*) die "Это не резервная копия 3X-UI KIT или она повреждена (имя $n в ${f##*/}). Ничего не менял." ;;
*) die "Это не резервная копия 3X-UI_autoVPS или она повреждена (имя $n в ${f##*/}). Ничего не менял." ;;
esac
[[ $(env_get "$f" "$n") =~ $re ]] \
|| die "Это не резервная копия 3X-UI KIT или она повреждена (значение $n в ${f##*/}). Ничего не менял."
|| die "Это не резервная копия 3X-UI_autoVPS или она повреждена (значение $n в ${f##*/}). Ничего не менял."
done < <(LC_ALL=C grep -aoE '^[A-Z][A-Z0-9_]*' "$f")
return 0
}
@@ -1874,7 +1874,7 @@ restore_main() { # файл
tmp=$(mktemp -d)
# shellcheck disable=SC2064 # путь подставляем сразу: при выходе локальной переменной уже нет
trap "rm -rf -- '$tmp'" EXIT
python3 - "$file" "$tmp" <<'PY' || die "Это не резервная копия 3X-UI KIT или она повреждена. Ничего не менял."
python3 - "$file" "$tmp" <<'PY' || die "Это не резервная копия 3X-UI_autoVPS или она повреждена. Ничего не менял."
import os, sys, tarfile
allowed = ("etc/x-ui/x-ui.db", "etc/x-ui/install-result.env", "etc/kit/kit.env", "etc/kit-sub/config.json", "etc/kit-sub/rules.yaml",
"etc/nginx/kit-stream.conf", "etc/nginx/conf.d/kit.conf", "var/www/kit", "root/cert/self",
@@ -1935,7 +1935,7 @@ PY
safe_env "$tmp/kit-backup.env" BACKUP_KIT_VERSION BACKUP_HOST BACKUP_SSL BACKUP_DATE
safe_env "$tmp/etc/x-ui/install-result.env" XUI_USERNAME XUI_PASSWORD XUI_PANEL_PORT XUI_WEB_BASE_PATH XUI_ACCESS_URL XUI_API_TOKEN XUI_DB_TYPE
[[ $(env_get "$tmp/etc/x-ui/install-result.env" XUI_PANEL_PORT) =~ ^[0-9]{1,5}$ ]] \
|| die "Это не резервная копия 3X-UI KIT или она повреждена (порт панели). Ничего не менял."
|| die "Это не резервная копия 3X-UI_autoVPS или она повреждена (порт панели). Ничего не менял."
if [[ -f $tmp/etc/kit/kit.env ]]; then
safe_env "$tmp/etc/kit/kit.env" HOST LINK_HOST PANEL_ON SUB_BASE SUB_PATH SUB_INTERNAL SINGLE MTPROTO_INNER
fi
@@ -1947,10 +1947,10 @@ PY
BACKUP_SSL=$(env_get "$tmp/kit-backup.env" BACKUP_SSL)
BACKUP_DATE=$(env_get "$tmp/kit-backup.env" BACKUP_DATE)
BACKUP_KIT_VERSION=$(env_get "$tmp/kit-backup.env" BACKUP_KIT_VERSION)
[[ $BACKUP_HOST =~ ^[A-Za-z0-9.:-]+$ ]] || die "Это не резервная копия 3X-UI KIT или она повреждена (адрес сервера). Ничего не менял."
[[ $BACKUP_HOST =~ ^[A-Za-z0-9.:-]+$ ]] || die "Это не резервная копия 3X-UI_autoVPS или она повреждена (адрес сервера). Ничего не менял."
[[ $BACKUP_SSL =~ ^(ip|custom|none)$ ]] || die "В копии нет данных о сертификате."
[[ $BACKUP_SSL != custom || -f $tmp/root/cert/custom/fullchain.pem ]] \
|| die "Это не резервная копия 3X-UI KIT или она повреждена (нет своего сертификата). Ничего не менял."
|| die "Это не резервная копия 3X-UI_autoVPS или она повреждена (нет своего сертификата). Ничего не менял."
PANEL_SSL=$BACKUP_SSL
# Домен переезжает вместе с сервером (поменяйте A-запись), IP – нет.
if [[ $BACKUP_HOST =~ ^[0-9.]+$ ]]; then
+2 -2
View File
@@ -2,7 +2,7 @@
# Hysteria2 – https://github.com/itsnotkubrick/3X-UI_KIT
#
# Отдельный установщик Hysteria2 больше не поддерживается: Hysteria2 входит в основную
# установку 3X-UI KIT (scripts/3x-ui.sh). Файл оставлен, чтобы старая команда `hy2 update`
# установку 3X-UI_autoVPS (scripts/3x-ui.sh). Файл оставлен, чтобы старая команда `hy2 update`
# получила из подписанного релиза понятное сообщение. Ничего не ставит, не удаляет и не
# останавливает: сервер Hysteria2, установленный раньше, продолжает работать как был.
# Код выхода 1 при любом запуске (и при `__update_binary`) – старый `hy2 update` на нём
@@ -13,7 +13,7 @@ KIT_VERSION="1.2.7"
cat >&2 <<'MSG'
Отдельный установщик Hysteria2 больше не поддерживается.
Сервер Hysteria2 продолжает работать как раньше, но не обновляется этим скриптом.
Hysteria2 входит в основную установку 3X-UI KIT (один из 11 протоколов).
Hysteria2 входит в основную установку 3X-UI_autoVPS (один из 11 протоколов).
Если нужен только Hysteria2 без панели – официальный установщик:
bash <(curl -fsSL https://get.hy2.sh/)
MSG
+5 -5
View File
@@ -64,7 +64,7 @@ kl_need_root() { [[ ${EUID:-0} -eq 0 ]] || kl_die "нужен root"; }
kit_local_help() {
cat <<'EOF'
3X-UI KIT — дополнения форка (hacker07):
3X-UI_autoVPS — дополнения форка (hacker07):
Состояние
kit local эта справка
@@ -233,7 +233,7 @@ EOF
printf ' (dry-run) записал бы в %s: [Socket] + ListenStream=%s (старый порт остаётся)\n' "$KL_SOCKET_DROPIN" "$new"
else
install -d -m 755 "$(dirname "$KL_SOCKET_DROPIN")"
printf '# 3X-UI KIT (форк): дополнительный порт SSH, добавлен %s\n[Socket]\nListenStream=%s\n' "$(date +%F)" "$new" >"$KL_SOCKET_DROPIN"
printf '# 3X-UI_autoVPS (форк): дополнительный порт SSH, добавлен %s\n[Socket]\nListenStream=%s\n' "$(date +%F)" "$new" >"$KL_SOCKET_DROPIN"
kl_ok "добавлен $KL_SOCKET_DROPIN"
fi
kl_run systemctl daemon-reload
@@ -244,7 +244,7 @@ EOF
printf ' (dry-run) записал бы в %s: Port %s (старый порт остаётся)\n' "$KL_SSHD_DROPIN" "$new"
else
install -d -m 755 /etc/ssh/sshd_config.d
printf '# 3X-UI KIT (форк): дополнительный порт SSH, добавлен %s\nPort %s\n' "$(date +%F)" "$new" >"$KL_SSHD_DROPIN"
printf '# 3X-UI_autoVPS (форк): дополнительный порт SSH, добавлен %s\nPort %s\n' "$(date +%F)" "$new" >"$KL_SSHD_DROPIN"
kl_ok "добавлен $KL_SSHD_DROPIN"
fi
kl_run sshd -t || { kl_warn "sshd -t не принял конфиг — убираю наш файл, ничего не перезапускаю"; kl_dry || rm -f "$KL_SSHD_DROPIN"; return 1; }
@@ -414,7 +414,7 @@ APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
EOF
cat >/etc/apt/apt.conf.d/52-kit-local-upgrades <<'EOF'
// 3X-UI KIT (форк): только обновления безопасности, никакой самовольной перезагрузки.
// 3X-UI_autoVPS (форк): только обновления безопасности, никакой самовольной перезагрузки.
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
EOF
@@ -910,7 +910,7 @@ kit_local_cmd() {
# про неё не знает — сборку релиза остановит проверка tools/check-help.sh.
kit_help_all() {
cat <<EOF
${B:-}3X-UI KIT ${KIT_VERSION:-?} — все команды${N:-} (то же самое доступно в меню: kit без аргументов)
${B:-}3X-UI_autoVPS ${KIT_VERSION:-?} — все команды${N:-} (то же самое доступно в меню: kit без аргументов)
Состояние и версии
kit меню
+2 -2
View File
@@ -494,11 +494,11 @@ def routing_payload(kind, loaded):
else:
ips.append(v)
if kind == "happ":
data = {"Name": "3X-UI KIT", "GlobalProxy": "false", "DomainStrategy": "IPIfNonMatch", "ProxySites": sites,
data = {"Name": "3X-UI_autoVPS", "GlobalProxy": "false", "DomainStrategy": "IPIfNonMatch", "ProxySites": sites,
"ProxyIp": ips, "DirectIp": ["geoip:private"]}
else:
# localhost – системный DNS клиента для прямых сайтов (как в подписке Mihomo); список direct_dns его заменяет.
data = {"Name": "3X-UI KIT", "DomainStrategy": "IPIfNonMatch", "RouteOrder": "block-proxy-direct",
data = {"Name": "3X-UI_autoVPS", "DomainStrategy": "IPIfNonMatch", "RouteOrder": "block-proxy-direct",
"ProxySites": sites, "ProxyIp": ["1.1.1.1", "8.8.8.8"] + ips, "DirectSites": ["regexp:.*"],
"DirectIp": ["geoip:private", "0.0.0.0/0", "::/0"], "DomesticDNSDomain": direct_dns[0] if direct_dns else "localhost"}
text = json.dumps(data, ensure_ascii=False, separators=(",", ":"))
+15 -15
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# kit – управление сервером 3X-UI KIT: пользователи, обновление, резервная копия.
# kit – управление сервером 3X-UI_autoVPS: пользователи, обновление, резервная копия.
# https://github.com/itsnotkubrick/3X-UI_KIT
#
# kit user add имя [--gb 50] [--days 30] [--devices 3]
@@ -387,7 +387,7 @@ cmd_enforce() {
limit_timer_on() {
cat >/etc/systemd/system/kit-limit.service <<'UNIT'
[Unit]
Description=3X-UI KIT: общий лимит трафика пользователей (сумма по всем записям)
Description=3X-UI_autoVPS: общий лимит трафика пользователей (сумма по всем записям)
After=x-ui.service
[Service]
@@ -397,7 +397,7 @@ TimeoutStartSec=120
UNIT
cat >/etc/systemd/system/kit-limit.timer <<'UNIT'
[Unit]
Description=3X-UI KIT: проверка общего лимита трафика раз в 5 минут
Description=3X-UI_autoVPS: проверка общего лимита трафика раз в 5 минут
[Timer]
OnBootSec=2min
@@ -462,7 +462,7 @@ cmd_del() {
# Новый ключ приходит только в релизе, подписанном старым.
KIT_SIGNERS=(
# Ключ подписи форка (владелец: hacker07). Закрытая часть — только на рабочей станции.
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKM0Sfn/UQeqjvUvY9wVgg7QtG1RR2pEUkqrUD5Yy6EF 3X-UI KIT fork releases (hacker07)"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKM0Sfn/UQeqjvUvY9wVgg7QtG1RR2pEUkqrUD5Yy6EF 3X-UI_autoVPS fork releases (hacker07)"
)
KIT_SIG_NS="3x-ui-kit-release"
KIT_SIG_ID="releases@3x-ui-kit"
@@ -496,7 +496,7 @@ update_hint() {
}
cmd_version() {
echo "3X-UI KIT $KIT_VERSION"
echo "3X-UI_autoVPS $KIT_VERSION"
echo "${D}панель 3X-UI $(/usr/local/x-ui/x-ui -v 2>/dev/null | head -1 || echo '?'), ядро Xray $(xray_version)${N}"
if auto_enabled; then echo "${D}автообновление: включено (только подписанные релизы), журнал $KIT_UPDATE_LOG${N}"
else echo "${D}автообновление: выключено, включить: kit update --auto${N}"; fi
@@ -525,7 +525,7 @@ fetch_release() { # версия каталог
return 1
fi
# Версия записана внутри подписанного файла: старый подписанный релиз под видом нового не пройдёт.
grep -qx "# 3X-UI KIT $v" "$d/SHA256SUMS" || { warn "Подписанный релиз не той версии – ничего не ставлю."; return 1; }
grep -qxE "# (3X-UI KIT|3X-UI_autoVPS) $v" "$d/SHA256SUMS" || { warn "Подписанный релиз не той версии – ничего не ставлю."; return 1; }
for f in scripts/kit.sh scripts/kit-sub.py scripts/kit-local.sh; do
sum=$(awk -v f="$f" '$2 == f {print $1}' "$d/SHA256SUMS")
[[ $sum =~ ^[0-9a-f]{64}$ ]] || { warn "В подписанном списке нет $f."; return 1; }
@@ -540,7 +540,7 @@ fetch_release() { # версия каталог
kit_sub_unit() { # путь-к-сертификату путь-к-ключу (пусто – за nginx)
cat <<UNIT
[Unit]
Description=kit-sub: подписка с учётом приложения (3X-UI KIT)
Description=kit-sub: подписка с учётом приложения (3X-UI_autoVPS)
After=network-online.target x-ui.service
Wants=network-online.target
@@ -604,7 +604,7 @@ needs_migration() {
auto_on() {
cat >/etc/systemd/system/kit-update.service <<UNIT
[Unit]
Description=3X-UI KIT: автообновление kit и kit-sub (только подписанные релизы)
Description=3X-UI_autoVPS: автообновление kit и kit-sub (только подписанные релизы)
After=network-online.target
Wants=network-online.target
@@ -616,7 +616,7 @@ StandardError=append:$KIT_UPDATE_LOG
UNIT
cat >/etc/systemd/system/kit-update.timer <<'UNIT'
[Unit]
Description=3X-UI KIT: проверка обновлений раз в сутки
Description=3X-UI_autoVPS: проверка обновлений раз в сутки
[Timer]
OnCalendar=*-*-* 03:00:00
@@ -666,7 +666,7 @@ cmd_update() {
[[ $unattended == yes ]] || echo "${D}Переустановить файлы kit той же версии: kit update --force${N}"
return
fi
if [[ $latest == "$KIT_VERSION" ]]; then say "Применяю исправления версии $latest"; else say "3X-UI KIT $KIT_VERSION → $latest"; fi
if [[ $latest == "$KIT_VERSION" ]]; then say "Применяю исправления версии $latest"; else say "3X-UI_autoVPS $KIT_VERSION → $latest"; fi
tmp=$(mktemp -d)
# shellcheck disable=SC2064 # путь подставляем сразу: при выходе локальной переменной уже нет
trap "rm -rf -- '$tmp'" EXIT
@@ -728,7 +728,7 @@ cmd_update() {
# Новые пути подписки (Clash и JSON) подключает уже новая версия kit.
/usr/local/bin/kit __subextra >/dev/null 2>&1 || warn "Дополнительные пути подписки не подключились: kit update --force"
echo
echo "${G}✓ Готово: 3X-UI KIT $latest.${N} Пользователи, ссылки и подписки не менялись."
echo "${G}✓ Готово: 3X-UI_autoVPS $latest.${N} Пользователи, ссылки и подписки не менялись."
[[ $unattended == yes ]] && return
local news
news=$(changelog_of "$latest")
@@ -1914,10 +1914,10 @@ YAML
# Приложениям на Xray правила раздаёт сама панель (3X-UI 3.9+): заголовок Routing для Happ и правила JSON-подписки.
# Собираем их из того же rules.yaml. Чужой профиль, уже стоящий в панели, не трогаем.
split_panel_ours() { # наш профиль: JSON или ссылка happ://routing/onadd/<base64> с Name "3X-UI KIT"
split_panel_ours() { # наш профиль: JSON или ссылка happ://routing/onadd/<base64> с Name "3X-UI_autoVPS"
local v=$1
[[ $v == happ://routing/onadd/* ]] && v=$(printf '%s' "${v#happ://routing/onadd/}" | base64 -d 2>/dev/null || true)
grep -q '"Name":"3X-UI KIT"' <<<"$v"
grep -q '"Name":"3X-UI_autoVPS"' <<<"$v"
}
split_panel_sync() { # on|off
@@ -2551,7 +2551,7 @@ menu_main() {
local c
while :; do
echo
box "3X-UI KIT $KIT_VERSION – управление сервером" "1. Пользователи" "2. Протоколы, порты и маскировка" "3. Проверка сервера" "" \
box "3X-UI_autoVPS $KIT_VERSION – управление сервером" "1. Пользователи" "2. Протоколы, порты и маскировка" "3. Проверка сервера" "" \
"4. Обновить kit и подписку" "5. Обновить панель 3X-UI" "6. Автообновление: включить или выключить" "" \
"7. Резервная копия" "8. Версии" "" "9. Панель 3X-UI (меню x-ui)" "0. Выход"
echo
@@ -2577,7 +2577,7 @@ menu_main() {
usage() {
cat <<EOF
${B}3X-UI KIT $KIT_VERSION${N} – команды (то же самое есть в меню: просто ${B}kit${N})
${B}3X-UI_autoVPS $KIT_VERSION${N} – команды (то же самое есть в меню: просто ${B}kit${N})
kit меню
kit user … add, list, link, limit, on, off, del