Compare commits
6
Commits
v1.2.1.6
...
c4f7c4f710
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4f7c4f710 | ||
|
|
19eb77be68 | ||
|
|
333b8edc9a | ||
|
|
13dfb44f3f | ||
|
|
3a8518651c | ||
|
|
915dd35f42 |
@@ -1,3 +1,34 @@
|
|||||||
|
## v1.2.1.9: kit fix снова выполняется при установке
|
||||||
|
|
||||||
|
* В 1.2.1.8 я понял просьбу слишком широко и **выключил сам `kit fix`** — вместе с ним пропала и
|
||||||
|
синхронизация времени. Возвращено: `kit fix` при установке выполняется как раньше (время, службы, права),
|
||||||
|
ключ `--no-time` его пропускает.
|
||||||
|
* Убрана только та строка, о которой шла речь: описание команды «kit fix – безопасные исправления
|
||||||
|
(службы, права, автообновление, сертификат, время)» больше не печатается — результат («Чинить нечего»
|
||||||
|
или список найденного) остаётся.
|
||||||
|
* Наша строка шага сокращена: «kit fix: безопасные починки (время, службы, права)».
|
||||||
|
|
||||||
|
## v1.2.1.8: подсказка меню исправлена, установка стала тише
|
||||||
|
|
||||||
|
* **«Выбор [0-10]» при 11 пунктах** — подсказка главного меню отстала, когда мы добавили пункт «Доступ к
|
||||||
|
панели, ссылки и заглушка». Теперь «Выбор [0-11]». Чтобы это не повторилось, добавлен тест
|
||||||
|
`tools/check-menus.py`: он сверяет подсказку каждого меню с числом пунктов и запускается в релизном
|
||||||
|
гейте — если мы снова добавим пункт и забудем подсказку, выпуск остановится.
|
||||||
|
* **`kit fix` больше не выполняется при установке** (в выводе это выглядело как «Чинить нечего: всё в
|
||||||
|
порядке»). Нужен — запускается из меню или ключом `--time`.
|
||||||
|
* **Вывод про автообновления безопасности сокращён до одной строки** («автообновления безопасности
|
||||||
|
включены…»): три строки про ядро и перезагрузку убраны из установки.
|
||||||
|
|
||||||
|
## v1.2.1.7: исправлена установка (моя регрессия в 1.2.1.6)
|
||||||
|
|
||||||
|
* В 1.2.1.6 я переписал загрузку файлов релиза и оставил проверку SHA256 установщика **раньше**
|
||||||
|
скачивания — установка обрывалась на первой же строке: `sha256sum: .../scripts/3x-ui.sh: No such file
|
||||||
|
or directory`. Теперь сначала скачиваются все файлы релиза (каждый сверяется с подписанным списком),
|
||||||
|
и только потом проверяется установщик.
|
||||||
|
* Проверено не на глаз: воспроизвёл ошибку у себя тем же путём (`--verify-only`) — красное, затем после
|
||||||
|
правки зелёное. Этот прогон добавлен в процедуру выпуска: перед подписью я запускаю установщик в режиме
|
||||||
|
`--verify-only` и убеждаюсь, что путь «скачать и проверить релиз» проходит целиком.
|
||||||
|
|
||||||
## v1.2.1.6: доступы к панели в конце установки и рабочая заглушка
|
## v1.2.1.6: доступы к панели в конце установки и рабочая заглушка
|
||||||
|
|
||||||
* **Исправлено: доступы к панели не выводились.** Автор пишет строки в `/root/3x-ui.txt` без ведущих
|
* **Исправлено: доступы к панели не выводились.** Автор пишет строки в `/root/3x-ui.txt` без ведущих
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ bash tools/fork-sync.sh # подтянуть автора, перен
|
|||||||
|
|
||||||
bash tools/release.sh ~/.ssh/3x-ui-kit-fork/release_key # SHA256SUMS + подпись нашим ключом
|
bash tools/release.sh ~/.ssh/3x-ui-kit-fork/release_key # SHA256SUMS + подпись нашим ключом
|
||||||
|
|
||||||
|
**Перед подписью — обязательный прогон.** `bash scripts/3x-ui-local.sh --verify-only` проверяет ровно тот
|
||||||
|
путь установки, которым пойдут серверы: скачивание всех файлов релиза и сверка каждого с подписанным
|
||||||
|
списком. На Windows запускать с `TMPDIR=C:/…` (нативные утилиты не понимают MSYS-пути).
|
||||||
|
|
||||||
**Нумерация версий.** Основа — версия автора, наша надстройка добавляется через точку с единицы:
|
**Нумерация версий.** Основа — версия автора, наша надстройка добавляется через точку с единицы:
|
||||||
у автора 1.2.1 → наша сборка 1.2.1.1; вышла его 1.2.2 → наша 1.2.2.1. Так на сервере всегда видно,
|
у автора 1.2.1 → наша сборка 1.2.1.1; вышла его 1.2.2 → наша 1.2.2.1. Так на сервере всегда видно,
|
||||||
на чьей базе собрана сборка.
|
на чьей базе собрана сборка.
|
||||||
|
|||||||
+8
-8
@@ -1,9 +1,9 @@
|
|||||||
# 3X-UI KIT 1.2.1.6
|
# 3X-UI KIT 1.2.1.8
|
||||||
# 3X-UI_autoVPS 1.2.1.6
|
# 3X-UI_autoVPS 1.2.1.8
|
||||||
f30fc23d1c667d6fc90742fdf12377ca84d9e119fc394d86822bf1daaf462795 scripts/3x-ui.sh
|
9776e75232d9e65614130cd350e5d7f0dd97ffaa5640729479cc1ced927869c8 scripts/3x-ui.sh
|
||||||
4ef4c3f830196704648c15dd546e20195ce15e2d4ee6ca66e363aac47811c4ab scripts/hysteria2.sh
|
81ae4f2c3d512f352e64596149174a9141f8a29e2fbd44f0e16db5387f8d31f0 scripts/hysteria2.sh
|
||||||
b85e6ca11eef15eed8d45fba9e7b4a7eddf6141de4aeceaac1fe7f51d4c9fa78 scripts/kit.sh
|
17d118d5aa7ba22d4541e7d4874d31b5fb1950b3b7cc09b2fc97885eb537ec8e scripts/kit.sh
|
||||||
f214671464e1c2e174e5af9df42c95567a9b4a9141f31a39f7df2e971e89d240 scripts/kit-sub.py
|
f214671464e1c2e174e5af9df42c95567a9b4a9141f31a39f7df2e971e89d240 scripts/kit-sub.py
|
||||||
75cc7bc4e048c43989f66ca3b9e9addff8d7a434e651daba6db894e18109b45b scripts/kit-local.sh
|
5d07c87452057e1c73e0f3af008074f94f5be6175817b2d6f94a93f69b0533b7 scripts/kit-local.sh
|
||||||
ba87dfba9abc3417092a2c2ec8da1b0332397e9952ead213e9367692f2849459 scripts/3x-ui-local.sh
|
483355bf1c0e9b75f15cf783a730ea59f5fc17038b9e212c952f792bcc57d0d8 scripts/3x-ui-local.sh
|
||||||
3acd832d329f916790a07153fcc6b7cbdbeb6958131e60751094c059e4fb0f76 VERSION
|
a9762073937784114e8467c57045aa83784f14ab0c0e62906ec5c4c164baf4ef VERSION
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
-----BEGIN SSH SIGNATURE-----
|
-----BEGIN SSH SIGNATURE-----
|
||||||
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgozRJ+f9RB6qO9S9j3BWCDtC0bV
|
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgozRJ+f9RB6qO9S9j3BWCDtC0bV
|
||||||
FHakRSSqtQPljLoQUAAAARM3gtdWkta2l0LXJlbGVhc2UAAAAAAAAABnNoYTUxMgAAAFMA
|
FHakRSSqtQPljLoQUAAAARM3gtdWkta2l0LXJlbGVhc2UAAAAAAAAABnNoYTUxMgAAAFMA
|
||||||
AAALc3NoLWVkMjU1MTkAAABADBMIIRfAe53BhNokGqyMTekQwEmlBZ8HdhkKUXjRPv0ofv
|
AAALc3NoLWVkMjU1MTkAAABAKCus5+Q0q6U/kWCLOJxk/TURjxPuy+TLbudsY80iVGf4sR
|
||||||
u4/0GW5p5d2QnwShb7+zS/Dr+LekQ2SMQEBvVbAA==
|
+Nohbd9U5s7OlYRoHWVN60bRDhesIqsYfxzWirDA==
|
||||||
-----END SSH SIGNATURE-----
|
-----END SSH SIGNATURE-----
|
||||||
|
|||||||
+10
-11
@@ -32,7 +32,6 @@
|
|||||||
# --no-harden не трогать ping и автообновления
|
# --no-harden не трогать ping и автообновления
|
||||||
# --ssh-port N добавить порт SSH N (прежний порт продолжает работать)
|
# --ssh-port N добавить порт SSH N (прежний порт продолжает работать)
|
||||||
# --yes ни о чём не спрашивать (ping закрою, автообновления включу, порт и пароль — нет)
|
# --yes ни о чём не спрашивать (ping закрою, автообновления включу, порт и пароль — нет)
|
||||||
# --no-time не запускать kit fix
|
|
||||||
# --no-check не запускать в конце kit check
|
# --no-check не запускать в конце kit check
|
||||||
# --clean убрать прошлую установку и поставить заново (SSH не трогает)
|
# --clean убрать прошлую установку и поставить заново (SSH не трогает)
|
||||||
# --auto-sni не предлагать выбор сайта маскировки (иначе покажем меню по скану подсети)
|
# --auto-sni не предлагать выбор сайта маскировки (иначе покажем меню по скану подсети)
|
||||||
@@ -44,7 +43,7 @@
|
|||||||
|
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
KIT_VERSION="1.2.1.6" # версия сборки форка; должна совпадать с VERSION релиза
|
KIT_VERSION="1.2.1.9" # версия сборки форка; должна совпадать с VERSION релиза
|
||||||
GITEA="${KIT_FORK_BASE:-https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS}"
|
GITEA="${KIT_FORK_BASE:-https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS}"
|
||||||
NS="3x-ui-kit-release"
|
NS="3x-ui-kit-release"
|
||||||
SIG_ID="releases@3x-ui-kit"
|
SIG_ID="releases@3x-ui-kit"
|
||||||
@@ -83,7 +82,7 @@ usage() {
|
|||||||
--no-sub не показывать в конце подписку, доступ к панели и QR-код
|
--no-sub не показывать в конце подписку, доступ к панели и QR-код
|
||||||
--clean снести прошлую установку и поставить заново (если прошлый запуск оборвался)
|
--clean снести прошлую установку и поставить заново (если прошлый запуск оборвался)
|
||||||
--auto-sni не предлагать выбор сайта маскировки (автоподбор автора)
|
--auto-sni не предлагать выбор сайта маскировки (автоподбор автора)
|
||||||
--no-time не запускать kit fix (время и безопасные починки)
|
--no-time не запускать kit fix при установке (время, службы, права)
|
||||||
--no-check не запускать в конце kit check
|
--no-check не запускать в конце kit check
|
||||||
--verify-only только проверить релиз (подпись и SHA256) и выйти
|
--verify-only только проверить релиз (подпись и SHA256) и выйти
|
||||||
--dry-run показать план и ничего не делать
|
--dry-run показать план и ничего не делать
|
||||||
@@ -162,7 +161,7 @@ if [[ $dry == yes ]]; then
|
|||||||
random) pre "заглушка: случайный ИТ-сайт из нашего набора (10 штук)" ;;
|
random) pre "заглушка: случайный ИТ-сайт из нашего набора (10 штук)" ;;
|
||||||
*) pre "заглушка: сайт №$site из нашего набора (список: kit local site --list)" ;;
|
*) pre "заглушка: сайт №$site из нашего набора (список: kit local site --list)" ;;
|
||||||
esac
|
esac
|
||||||
[[ $fix_time == yes ]] && pre "после: kit fix (время, безопасные починки)"
|
[[ $fix_time == yes ]] && pre "после: kit fix (время, службы, права) — тихо, без описания команды"
|
||||||
[[ $do_check == yes ]] && pre "проверка: kit check + kit local hardening"
|
[[ $do_check == yes ]] && pre "проверка: kit check + kit local hardening"
|
||||||
[[ $show_sub == yes ]] && pre "в самом конце: доступ к панели 3X-UI, подписка, QR-код и ссылки (--no-sub — не надо)"
|
[[ $show_sub == yes ]] && pre "в самом конце: доступ к панели 3X-UI, подписка, QR-код и ссылки (--no-sub — не надо)"
|
||||||
echo
|
echo
|
||||||
@@ -188,19 +187,19 @@ ssh-keygen -Y verify -f "$tmp/allowed_signers" -I "$SIG_ID" -n "$NS" -s "$tmp/SH
|
|||||||
|| die "подпись релиза v$KIT_VERSION не сошлась с ключом форка — это не наш релиз, ничего не запускаю"
|
|| die "подпись релиза v$KIT_VERSION не сошлась с ключом форка — это не наш релиз, ничего не запускаю"
|
||||||
sum=$(awk '{f = $2; sub(/^\*/, "", f)} f == "scripts/3x-ui.sh" {print $1}' "$tmp/SHA256SUMS")
|
sum=$(awk '{f = $2; sub(/^\*/, "", f)} f == "scripts/3x-ui.sh" {print $1}' "$tmp/SHA256SUMS")
|
||||||
[[ $(printf '%s' "$sum" | wc -c) -eq 64 ]] || die "в SHA256SUMS нет установщика — релиз собран неверно"
|
[[ $(printf '%s' "$sum" | wc -c) -eq 64 ]] || die "в SHA256SUMS нет установщика — релиз собран неверно"
|
||||||
got=$(sha256sum "$tmp/scripts/3x-ui.sh" | awk '{print $1}')
|
# Качаем ВСЕ файлы релиза и сверяем каждый с подписанным списком. Так у нас есть и scripts/3x-ui.sh
|
||||||
[[ $got == "$sum" ]] || die "SHA256 установщика не совпал с подписанным — не запускаю"
|
# (установщик), и scripts/kit-local.sh (наша страница-заглушка), и всё остальное. Раньше брали только
|
||||||
# Качаем все остальные файлы релиза и сверяем каждый с подписанным списком. Раньше брали только
|
# установщик: заглушка не готовилась («kl_site_html: command not found»), а проверка целостности была неполной.
|
||||||
# установщик, поэтому kit-local.sh (в нём наша страница-заглушка) отсутствовал, и подготовка
|
|
||||||
# заглушки до установщика падала с «kl_site_html: command not found».
|
|
||||||
while read -r sum2 name2; do
|
while read -r sum2 name2; do
|
||||||
case $sum2 in \#* | "") continue ;; esac
|
case $sum2 in \#* | "") continue ;; esac
|
||||||
[[ $name2 == scripts/3x-ui.sh ]] && continue
|
case $name2 in SHA256SUMS | SHA256SUMS.sig) continue ;; esac
|
||||||
mkdir -p "$tmp/$(dirname "$name2")"
|
mkdir -p "$tmp/$(dirname "$name2")"
|
||||||
curl -fsSL --retry 3 -m 60 -o "$tmp/$name2" "$raw/$name2" || die "не скачался $name2 из $raw (Gitea доступна с сервера?)"
|
curl -fsSL --retry 3 -m 60 -o "$tmp/$name2" "$raw/$name2" || die "не скачался $name2 из $raw (Gitea доступна с сервера?)"
|
||||||
got2=$(sha256sum "$tmp/$name2" | awk '{print $1}')
|
got2=$(sha256sum "$tmp/$name2" | awk '{print $1}')
|
||||||
[[ $got2 == "$sum2" ]] || die "SHA256 не совпал у $name2 — не запускаю"
|
[[ $got2 == "$sum2" ]] || die "SHA256 не совпал у $name2 — не запускаю"
|
||||||
done <"$tmp/SHA256SUMS"
|
done <"$tmp/SHA256SUMS"
|
||||||
|
got=$(sha256sum "$tmp/scripts/3x-ui.sh" | awk '{print $1}')
|
||||||
|
[[ $got == "$sum" ]] || die "SHA256 установщика не совпал с подписанным — не запускаю"
|
||||||
bash -n "$tmp/scripts/3x-ui.sh" || die "установщик не проходит проверку синтаксиса"
|
bash -n "$tmp/scripts/3x-ui.sh" || die "установщик не проходит проверку синтаксиса"
|
||||||
[[ -r $tmp/scripts/kit-local.sh ]] || die "в релизе нет scripts/kit-local.sh — сборка неполная"
|
[[ -r $tmp/scripts/kit-local.sh ]] || die "в релизе нет scripts/kit-local.sh — сборка неполная"
|
||||||
printf ' ✓ подпись сошлась, SHA256 установщика совпал\n'
|
printf ' ✓ подпись сошлась, SHA256 установщика совпал\n'
|
||||||
@@ -512,7 +511,7 @@ case ${stub_staged:-no} in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ $fix_time == yes ]]; then
|
if [[ $fix_time == yes ]]; then
|
||||||
say "kit fix: синхронизация времени и безопасные починки (авторская команда, ничего необратимого)"
|
say "kit fix: безопасные починки (время, службы, права)"
|
||||||
kit fix || warn "kit fix завершился с замечаниями — посмотрите вывод"
|
kit fix || warn "kit fix завершился с замечаниями — посмотрите вывод"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ wait_apt_idle() {
|
|||||||
XUI_VERSION="v3.9.0"
|
XUI_VERSION="v3.9.0"
|
||||||
# SHA256 установщика 3X-UI этой версии: тег могут передвинуть, а хеш – нет (проверено 2026-09-30).
|
# SHA256 установщика 3X-UI этой версии: тег могут передвинуть, а хеш – нет (проверено 2026-09-30).
|
||||||
XUI_INSTALL_SHA256="18616fe26c8f6c92db6daa2dcd7cd53c5143ee69ecfd26d8ea6dc9b2c78607a6"
|
XUI_INSTALL_SHA256="18616fe26c8f6c92db6daa2dcd7cd53c5143ee69ecfd26d8ea6dc9b2c78607a6"
|
||||||
KIT_VERSION="1.2.1.6"
|
KIT_VERSION="1.2.1.9"
|
||||||
# kit и kit-sub берём из того же релиза, что и этот скрипт, а не из меняющейся ветки main.
|
# kit и kit-sub берём из того же релиза, что и этот скрипт, а не из меняющейся ветки main.
|
||||||
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$KIT_VERSION"
|
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$KIT_VERSION"
|
||||||
# Ядро Xray для панели. С 26.7.x клиенты на Mihomo и sing-box (Hiddify, FlClash,
|
# Ядро Xray для панели. С 26.7.x клиенты на Mihomo и sing-box (Hiddify, FlClash,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# Код выхода 1 при любом запуске (и при `__update_binary`) – старый `hy2 update` на нём
|
# Код выхода 1 при любом запуске (и при `__update_binary`) – старый `hy2 update` на нём
|
||||||
# останавливается и не заменяет команду hy2.
|
# останавливается и не заменяет команду hy2.
|
||||||
|
|
||||||
KIT_VERSION="1.2.1.6"
|
KIT_VERSION="1.2.1.9"
|
||||||
|
|
||||||
cat >&2 <<'MSG'
|
cat >&2 <<'MSG'
|
||||||
Отдельный установщик Hysteria2 больше не поддерживается.
|
Отдельный установщик Hysteria2 больше не поддерживается.
|
||||||
|
|||||||
@@ -423,9 +423,8 @@ Unattended-Upgrade::Automatic-Reboot "false";
|
|||||||
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||||
EOF
|
EOF
|
||||||
systemctl enable --now unattended-upgrades >/dev/null 2>&1 || kl_warn "служба не включилась — проверьте: systemctl status unattended-upgrades"
|
systemctl enable --now unattended-upgrades >/dev/null 2>&1 || kl_warn "служба не включилась — проверьте: systemctl status unattended-upgrades"
|
||||||
kl_ok "включено: обновления безопасности ставятся сами"
|
# Одна строка: подробности нужны редко, а в выводе установки они превращались в шум.
|
||||||
kl_ok "панель и ядро это не затрагивает — они ставятся не из apt, а из своих релизов"
|
kl_ok "автообновления безопасности включены (панель и ядро это не затрагивает, сервер сам не перезагружается)"
|
||||||
kl_warn "обновление ядра применится только после перезагрузки, сам сервер не перезагружается"
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -12,7 +12,7 @@
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
export LC_ALL=C.UTF-8 # ширина колонок по символам, а не байтам
|
export LC_ALL=C.UTF-8 # ширина колонок по символам, а не байтам
|
||||||
|
|
||||||
KIT_VERSION="1.2.1.6"
|
KIT_VERSION="1.2.1.9"
|
||||||
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main"
|
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main"
|
||||||
# Файлы новой версии берём из её тега, а не из меняющейся ветки main.
|
# Файлы новой версии берём из её тега, а не из меняющейся ветки main.
|
||||||
kit_ref_raw() { echo "https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$1"; }
|
kit_ref_raw() { echo "https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$1"; }
|
||||||
@@ -1342,8 +1342,8 @@ fix_plan() {
|
|||||||
cmd_fix() {
|
cmd_fix() {
|
||||||
local dry=no c pass plan
|
local dry=no c pass plan
|
||||||
case ${1:-} in --dry-run) dry=yes ;; "") ;; *) die "kit fix [--dry-run]" ;; esac
|
case ${1:-} in --dry-run) dry=yes ;; "") ;; *) die "kit fix [--dry-run]" ;; esac
|
||||||
echo "${B}kit fix${N} – безопасные исправления (службы, права, автообновление, сертификат, время)"
|
# Наш шов: строку-описание команды не печатаем — при установке это лишний шум,
|
||||||
echo
|
# а смысл виден по результату (подробности — в kit help).
|
||||||
CHECK_QUIET=yes; run_checks; CHECK_QUIET=no
|
CHECK_QUIET=yes; run_checks; CHECK_QUIET=no
|
||||||
if ((${#CHECK_FIX[@]} == 0)); then
|
if ((${#CHECK_FIX[@]} == 0)); then
|
||||||
if ((CHECK_BAD == 0)); then echo "${G}Чинить нечего: всё в порядке.${N}"; return 0; fi
|
if ((CHECK_BAD == 0)); then echo "${G}Чинить нечего: всё в порядке.${N}"; return 0; fi
|
||||||
@@ -3199,7 +3199,7 @@ menu_main() {
|
|||||||
menu_status
|
menu_status
|
||||||
update_hint
|
update_hint
|
||||||
echo
|
echo
|
||||||
ask_num "Выбор [0-10]: "; c=$REPLY
|
ask_num "Выбор [0-11]: "; c=$REPLY
|
||||||
case $c in
|
case $c in
|
||||||
1) menu_users ;;
|
1) menu_users ;;
|
||||||
2) menu_net ;;
|
2) menu_net ;;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Проверка: подсказка «Выбор [0-N]» в каждом меню kit должна совпадать с числом пунктов.
|
||||||
|
|
||||||
|
Пункты считаются по строкам box (с учётом переносов через «\\»). Смысл проверки: мы добавляем в меню
|
||||||
|
свои пункты — однажды подсказка осталась «0-10» при 11 пунктах, и человек не мог выбрать последний.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
path = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else "scripts/kit.sh")
|
||||||
|
text = path.read_text(encoding="utf-8").replace("\\\n", "")
|
||||||
|
lines = text.splitlines()
|
||||||
|
bad = 0
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
m = re.search(r'\bbox\s+"([^"]+)"(.*)$', line)
|
||||||
|
if not m:
|
||||||
|
continue
|
||||||
|
items = re.findall(r'"(\d+)\.\s', m.group(2))
|
||||||
|
maxn = max((int(x) for x in items), default=0)
|
||||||
|
prompt = None
|
||||||
|
for j in range(i + 1, min(i + 120, len(lines))):
|
||||||
|
pm = re.search(r'ask_num\s+"Выбор \[0-(\d+)\]', lines[j])
|
||||||
|
if pm:
|
||||||
|
prompt = int(pm.group(1))
|
||||||
|
break
|
||||||
|
if prompt != maxn:
|
||||||
|
print(f"! меню «{m.group(1)}»: пунктов {maxn}, а подсказка «Выбор [0-{prompt}]»", file=sys.stderr)
|
||||||
|
bad += 1
|
||||||
|
print(f"меню проверены: {len(lines) and sum(1 for l in lines if 'box \"' in l)} · рассинхронов: {bad}")
|
||||||
|
sys.exit(1 if bad else 0)
|
||||||
@@ -191,6 +191,13 @@ def main():
|
|||||||
' echo "${G}✓ Готово: 3X-UI_autoVPS $latest.${N} Пользователи, ссылки и подписки не менялись."\n',
|
' echo "${G}✓ Готово: 3X-UI_autoVPS $latest.${N} Пользователи, ссылки и подписки не менялись."\n',
|
||||||
'авто-шов: replace, строк 1',
|
'авто-шов: replace, строк 1',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
'scripts/kit.sh',
|
||||||
|
' echo "${B}kit fix${N} – безопасные исправления (службы, права, автообновление, сертификат, время)"\n echo\n',
|
||||||
|
False,
|
||||||
|
' # Наш шов: строку-описание команды не печатаем — при установке это лишний шум,\n # а смысл виден по результату (подробности — в kit help).\n',
|
||||||
|
'авто-шов: replace, строк 2',
|
||||||
|
),
|
||||||
(
|
(
|
||||||
'scripts/kit.sh',
|
'scripts/kit.sh',
|
||||||
'split_panel_ours() { # наш профиль: JSON или ссылка happ://routing/onadd/<base64> с Name "3X-UI KIT"\n',
|
'split_panel_ours() { # наш профиль: JSON или ссылка happ://routing/onadd/<base64> с Name "3X-UI KIT"\n',
|
||||||
@@ -219,6 +226,13 @@ def main():
|
|||||||
' "7. Резервная копия" "8. Версии" "" "9. Доступ к панели, ссылки и заглушка" "10. Панель x-ui" "11. Удалить KIT с сервера" "0. Выход"\n',
|
' "7. Резервная копия" "8. Версии" "" "9. Доступ к панели, ссылки и заглушка" "10. Панель x-ui" "11. Удалить KIT с сервера" "0. Выход"\n',
|
||||||
'авто-шов: replace, строк 1',
|
'авто-шов: replace, строк 1',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
'scripts/kit.sh',
|
||||||
|
' ask_num "Выбор [0-10]: "; c=$REPLY\n',
|
||||||
|
False,
|
||||||
|
' ask_num "Выбор [0-11]: "; c=$REPLY\n',
|
||||||
|
'авто-шов: replace, строк 1',
|
||||||
|
),
|
||||||
(
|
(
|
||||||
'scripts/kit.sh',
|
'scripts/kit.sh',
|
||||||
' 9) command -v x-ui >/dev/null && x-ui || echo "Меню x-ui не найдено." ;;\n 10) run_action cmd_uninstall; pause ;;\n',
|
' 9) command -v x-ui >/dev/null && x-ui || echo "Меню x-ui не найдено." ;;\n 10) run_action cmd_uninstall; pause ;;\n',
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ for fn in ask_yes ask_ssh_port ssh_ports_now ask_protocols proto_parse proto_men
|
|||||||
[[ -z $c || $c -gt $d ]] || die "scripts/3x-ui-local.sh: $fn вызывается (строка $c) раньше, чем определена ($d)"
|
[[ -z $c || $c -gt $d ]] || die "scripts/3x-ui-local.sh: $fn вызывается (строка $c) раньше, чем определена ($d)"
|
||||||
done
|
done
|
||||||
ok "Все наши функции определены раньше своих вызовов"
|
ok "Все наши функции определены раньше своих вызовов"
|
||||||
|
# python3 есть не везде (на Windows обычно только python) — берём тот, что есть.
|
||||||
|
py=$(command -v python3 || command -v python || true)
|
||||||
|
[[ -n $py ]] || die "нет python — им проверяются меню (tools/check-menus.py)"
|
||||||
|
"$py" tools/check-menus.py >/dev/null || die "подсказка «Выбор [0-N]» не совпадает с числом пунктов меню (tools/check-menus.py)"
|
||||||
|
ok "Подсказки меню совпадают с числом пунктов"
|
||||||
|
|
||||||
[[ -z $(git status --porcelain -- "${FILES[@]}" CHANGELOG.md FORK-CHANGELOG.md) ]] || die "Есть незакоммиченные изменения в файлах релиза – сначала коммит."
|
[[ -z $(git status --porcelain -- "${FILES[@]}" CHANGELOG.md FORK-CHANGELOG.md) ]] || die "Есть незакоммиченные изменения в файлах релиза – сначала коммит."
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user