From dacfba7f62febb5599881ceba2e71a22dd468af1 Mon Sep 17 00:00:00 2001 From: anten-ka Date: Fri, 20 Mar 2026 17:19:47 +0300 Subject: [PATCH] v2.1: MODE=both support - 3X-UI and AmneziaWG simultaneously, dual bot handlers, 4 bugs fixed Made-with: Cursor --- warp.sh | 245 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 149 insertions(+), 96 deletions(-) diff --git a/warp.sh b/warp.sh index de0524d..4ac751c 100644 --- a/warp.sh +++ b/warp.sh @@ -88,9 +88,12 @@ save_config_val() { # MODE DETECTION # ═══════════════════════════════════════════════════════════════ +has_3xui_mode() { [[ "$MODE" == "3xui" || "$MODE" == "both" ]]; } +has_awg_mode() { [[ "$MODE" == "amnezia" || "$MODE" == "both" ]]; } + detect_mode() { source "$WARP_CONF" 2>/dev/null - if [ -n "${MODE:-}" ] && [[ "$MODE" == "3xui" || "$MODE" == "amnezia" ]]; then + if [ -n "${MODE:-}" ] && [[ "$MODE" == "3xui" || "$MODE" == "amnezia" || "$MODE" == "both" ]]; then return 0 fi @@ -106,16 +109,7 @@ detect_mode() { [ "$has_3xui" -eq 0 ] && command -v x-ui &>/dev/null && has_3xui=1 if [ "$has_amnezia" -eq 1 ] && [ "$has_3xui" -eq 1 ]; then - echo -e "\n${CYAN}Обнаружены оба режима:${NC}" - echo -e " ${GREEN}1)${NC} 3X-UI (SOCKS5-прокси)" - echo -e " ${GREEN}2)${NC} AmneziaWG (Docker WireGuard)" - while true; do - read -p "Выберите режим (1/2): " choice - case "$choice" in - 1) MODE="3xui"; break ;; - 2) MODE="amnezia"; break ;; - esac - done + MODE="both" elif [ "$has_amnezia" -eq 1 ]; then MODE="amnezia" elif [ "$has_3xui" -eq 1 ]; then @@ -124,11 +118,13 @@ detect_mode() { echo -e "\n${YELLOW}Не обнаружено ни 3X-UI, ни AmneziaWG Docker.${NC}" echo -e " ${GREEN}1)${NC} 3X-UI (SOCKS5-прокси для Xray)" echo -e " ${GREEN}2)${NC} AmneziaWG (Docker WireGuard)" + echo -e " ${GREEN}3)${NC} Оба режима" while true; do - read -p "Выберите режим (1/2): " choice + read -p "Выберите режим (1/2/3): " choice case "$choice" in 1) MODE="3xui"; break ;; 2) MODE="amnezia"; break ;; + 3) MODE="both"; break ;; esac done fi @@ -1096,11 +1092,24 @@ awg_remove_from_start_sh() { # ═══════════════════════════════════════════════════════════════ get_warp_status() { - if [ "$MODE" = "3xui" ]; then get_warp_status_3xui; else get_warp_status_awg; fi + if [ "$MODE" = "both" ]; then + local s3 sa + s3=$(get_warp_status_3xui); sa=$(get_warp_status_awg) + echo "3X-UI: ${s3} | AWG: ${sa}" + elif [ "$MODE" = "3xui" ]; then + get_warp_status_3xui + else + get_warp_status_awg + fi } get_warp_ip() { - if [ "$MODE" = "3xui" ]; then + if [ "$MODE" = "both" ]; then + local ip3 ipa + ip3=$(get_warp_ip_3xui) + awg_detect_warp_exit_ip; ipa="${AWG_WARP_EXIT_IP:-N/A}" + echo "3X-UI: ${ip3} | AWG: ${ipa}" + elif [ "$MODE" = "3xui" ]; then get_warp_ip_3xui else awg_detect_warp_exit_ip; echo "${AWG_WARP_EXIT_IP:-N/A}" @@ -1108,7 +1117,13 @@ get_warp_ip() { } is_warp_running() { - if [ "$MODE" = "3xui" ]; then is_warp_running_3xui; else is_warp_running_awg; fi + if [ "$MODE" = "both" ]; then + is_warp_running_3xui 2>/dev/null || is_warp_running_awg 2>/dev/null + elif [ "$MODE" = "3xui" ]; then + is_warp_running_3xui + else + is_warp_running_awg + fi } # ═══════════════════════════════════════════════════════════════ @@ -1180,7 +1195,25 @@ kbd_main_awg() { JSON } -kbd_main() { if [ "$MODE" = "3xui" ]; then kbd_main_3xui; else kbd_main_awg; fi; } +kbd_main_both() { + cat <<'JSON' +[ + [{"text":"📊 Статус","callback_data":"st"},{"text":"🌐 IP","callback_data":"ip"}], + [{"text":"▶️ Запустить","callback_data":"on"},{"text":"⏹ Остановить","callback_data":"off"}], + [{"text":"🔑 Перевыпуск","callback_data":"rk"}], + [{"text":"📋 JSON 3X-UI","callback_data":"js"},{"text":"👥 Клиенты AWG","callback_data":"cl"}], + [{"text":"🔄 Контейнер","callback_data":"rc"}], + [{"text":"💻 Система","callback_data":"sys"}], + [{"text":"🏢 Хостинг","callback_data":"promo"}] +] +JSON +} + +kbd_main() { + if [ "$MODE" = "both" ]; then kbd_main_both + elif [ "$MODE" = "3xui" ]; then kbd_main_3xui + else kbd_main_awg; fi +} kbd_back() { echo '[[{"text":"⬅️ Меню","callback_data":"m"}]]'; } kbd_rekey_confirm() { echo '[[{"text":"✅ Да","callback_data":"rk_y"}],[{"text":"⬅️ Отмена","callback_data":"m"}]]'; } @@ -1192,9 +1225,11 @@ bot_main_menu() { local ws wip="" extra="" ws=$(get_warp_status) is_warp_running && wip=" | WARP IP: $(get_warp_ip)" - [ "$MODE" = "amnezia" ] && extra="\nКонтейнер: ${CONTAINER:-N/A}" - [ "$MODE" = "3xui" ] && extra="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}" - local mode_label="3X-UI"; [ "$MODE" = "amnezia" ] && mode_label="AmneziaWG" + if has_3xui_mode; then extra+="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}"; fi + if has_awg_mode; then extra+="\nКонтейнер: ${CONTAINER:-N/A}"; fi + local mode_label="3X-UI" + [ "$MODE" = "amnezia" ] && mode_label="AmneziaWG" + [ "$MODE" = "both" ] && mode_label="3X-UI + AWG" local text="WARP Manager v${WARP_VERSION} (${mode_label})\nСервер: ${MY_IP:-N/A}\nСтатус: ${ws}${wip}${extra}\n\nВыберите:" local kbd; kbd=$(kbd_main) if [ -n "$msg_id" ]; then @@ -1217,12 +1252,13 @@ bot_handle_callback() { local ws wip="" extra="" ws=$(get_warp_status) is_warp_running && wip="\nWARP IP: $(get_warp_ip)" - if [ "$MODE" = "3xui" ]; then - extra="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}" + if has_3xui_mode; then + extra+="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}" local raw; raw=$(warp-cli --accept-tos status 2>/dev/null | head -3) - extra+="\n\n
${raw}
" - else - extra="\nКонтейнер: ${CONTAINER}\nПодсеть: ${AWG_SUBNET:-N/A}" + [ -n "$raw" ] && extra+="\n\n
${raw}
" + fi + if has_awg_mode; then + extra+="\nКонтейнер: ${CONTAINER:-N/A}\nПодсеть: ${AWG_SUBNET:-N/A}" awg_load_clients extra+="\nКлиентов в WARP: ${#AWG_SELECTED_IPS[@]}" fi @@ -1231,49 +1267,48 @@ bot_handle_callback() { ip) local wip="N/A"; is_warp_running && wip=$(get_warp_ip) local t="🌐 IP адреса\n\nРеальный: ${MY_IP:-N/A}\nWARP: ${wip}" - [ "$MODE" = "3xui" ] && t+="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}" + if has_3xui_mode; then t+="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}"; fi tg_edit "$chat_id" "$msg_id" "$t" "$(kbd_back)" ;; on) - if [ "$MODE" = "3xui" ]; then - is_warp_installed_3xui || { tg_edit "$chat_id" "$msg_id" "❌ Не установлен." "$(kbd_back)"; return; } - is_warp_running_3xui && { tg_edit "$chat_id" "$msg_id" "✅ Уже подключён." "$(kbd_back)"; return; } - tg_edit "$chat_id" "$msg_id" "⏳ Подключение..." "" + tg_edit "$chat_id" "$msg_id" "⏳ Запуск..." "" + local result="" + if has_3xui_mode && is_warp_installed_3xui; then warp-cli --accept-tos connect > /dev/null 2>&1; sleep 3 if is_warp_running_3xui; then - local w; w=$(get_warp_ip_3xui) - tg_edit "$chat_id" "$msg_id" "✅ Подключён\nWARP IP: ${w}" "$(kbd_back)"; log_action "BOT 3XUI ON" - else - tg_edit "$chat_id" "$msg_id" "❌ Ошибка." "$(kbd_back)" - fi - else - is_warp_installed_awg || { tg_edit "$chat_id" "$msg_id" "❌ Не установлен." "$(kbd_back)"; return; } - is_warp_running_awg && { tg_edit "$chat_id" "$msg_id" "✅ Уже работает." "$(kbd_back)"; return; } - tg_edit "$chat_id" "$msg_id" "⏳ Запуск..." "" + result+="✅ 3X-UI: $(get_warp_ip_3xui)\n"; log_action "BOT 3XUI ON" + else result+="❌ 3X-UI: ошибка\n"; fi + fi + if has_awg_mode && is_warp_installed_awg; then awg_warp_up 2>/dev/null if is_warp_running_awg; then awg_detect_warp_exit_ip - tg_edit "$chat_id" "$msg_id" "✅ WARP запущен\nWARP IP: ${AWG_WARP_EXIT_IP:-?}" "$(kbd_back)"; log_action "BOT AWG ON" - else tg_edit "$chat_id" "$msg_id" "❌ Ошибка." "$(kbd_back)"; fi - fi ;; + result+="✅ AWG: ${AWG_WARP_EXIT_IP:-?}\n"; log_action "BOT AWG ON" + else result+="❌ AWG: ошибка\n"; fi + fi + [ -z "$result" ] && result="❌ WARP не установлен." + tg_edit "$chat_id" "$msg_id" "Запуск WARP\n\n${result}" "$(kbd_back)" ;; off) - if [ "$MODE" = "3xui" ]; then - is_warp_running_3xui || { tg_edit "$chat_id" "$msg_id" "ℹ️ Уже отключён." "$(kbd_back)"; return; } + local result="" + if has_3xui_mode && is_warp_running_3xui 2>/dev/null; then warp-cli --accept-tos disconnect > /dev/null 2>&1 - tg_edit "$chat_id" "$msg_id" "⏹ WARP отключён." "$(kbd_back)"; log_action "BOT 3XUI OFF" - else - is_warp_running_awg || { tg_edit "$chat_id" "$msg_id" "ℹ️ Уже остановлен." "$(kbd_back)"; return; } + result+="⏹ 3X-UI отключён\n"; log_action "BOT 3XUI OFF" + fi + if has_awg_mode && is_warp_running_awg 2>/dev/null; then docker exec "$CONTAINER" sh -c "wg-quick down '$AWG_WARP_CONF' 2>/dev/null || true" - tg_edit "$chat_id" "$msg_id" "⏹ WARP остановлен." "$(kbd_back)"; log_action "BOT AWG OFF" - fi ;; + result+="⏹ AWG остановлен\n"; log_action "BOT AWG OFF" + fi + [ -z "$result" ] && result="ℹ️ Уже отключён." + tg_edit "$chat_id" "$msg_id" "Остановка WARP\n\n${result}" "$(kbd_back)" ;; rk) tg_edit "$chat_id" "$msg_id" "🔑 Перевыпуск ключа\n\nПродолжить?" "$(kbd_rekey_confirm)" ;; rk_y) tg_edit "$chat_id" "$msg_id" "⏳ Перевыпуск..." "" - if [ "$MODE" = "3xui" ]; then + local result="" + if has_3xui_mode; then warp-cli --accept-tos disconnect > /dev/null 2>&1 warp-cli --accept-tos registration delete > /dev/null 2>&1 warp-cli --accept-tos registration new > /dev/null 2>&1 @@ -1282,27 +1317,28 @@ bot_handle_callback() { warp-cli --accept-tos connect > /dev/null 2>&1; sleep 3 if is_warp_running_3xui; then local w; w=$(get_warp_ip_3xui) - tg_edit "$chat_id" "$msg_id" "✅ Ключ перевыпущен\nWARP IP: ${w}" "$(kbd_back)"; log_action "BOT 3XUI REKEY: ${w}" - else tg_edit "$chat_id" "$msg_id" "⚠️ Перевыпущен, подключение не подтверждено." "$(kbd_back)"; fi - else + result+="✅ 3X-UI: ${w}\n"; log_action "BOT 3XUI REKEY: ${w}" + else result+="⚠️ 3X-UI: не подтверждено\n"; fi + fi + if has_awg_mode; then docker exec "$CONTAINER" sh -c "wg-quick down '$AWG_WARP_CONF' 2>/dev/null || true" rm -f "$WGCF_ACCOUNT" (cd /root && yes | ./wgcf register 2>/dev/null && yes | ./wgcf generate 2>/dev/null) if [ -f "$WGCF_PROFILE" ]; then local ep; ep=$(awg_resolve_endpoint 2>/dev/null) if [ -n "$ep" ]; then - docker cp "$WGCF_PROFILE" "${CONTAINER}:${AWG_WARP_DIR}/wgcf-profile.conf" 2>/dev/null awg_build_warp_conf "$ep" awg_warp_up 2>/dev/null awg_load_clients; awg_apply_rules; awg_patch_start_sh awg_detect_warp_exit_ip - tg_edit "$chat_id" "$msg_id" "✅ Ключ перевыпущен\nWARP IP: ${AWG_WARP_EXIT_IP:-?}" "$(kbd_back)"; log_action "BOT AWG REKEY" - else tg_edit "$chat_id" "$msg_id" "❌ Ошибка endpoint." "$(kbd_back)"; fi - else tg_edit "$chat_id" "$msg_id" "❌ Ошибка генерации профиля." "$(kbd_back)"; fi - fi ;; + result+="✅ AWG: ${AWG_WARP_EXIT_IP:-?}\n"; log_action "BOT AWG REKEY" + else result+="❌ AWG: ошибка endpoint\n"; fi + else result+="❌ AWG: ошибка профиля\n"; fi + fi + tg_edit "$chat_id" "$msg_id" "🔑 Перевыпуск ключа\n\n${result}" "$(kbd_back)" ;; js) - if [ "$MODE" = "3xui" ]; then + if has_3xui_mode; then local t="📋 Конфигурация для 3X-UI\n\nOutbound:\n
{\n  \"tag\": \"warp\",\n  \"protocol\": \"socks\",\n  \"settings\": {\n    \"servers\": [{\"address\": \"127.0.0.1\", \"port\": ${SOCKS_PORT}}]\n  }\n}
\n\nRouting:\n
{\"outboundTag\": \"warp\", \"domain\": [\"geosite:openai\",\"geosite:netflix\"]}
" tg_edit "$chat_id" "$msg_id" "$t" "$(kbd_back)" else @@ -1373,7 +1409,7 @@ bot_handle_callback() { bot_handle_callback "$chat_id" "$msg_id" "" "cl" ;; rc) - if [ "$MODE" != "amnezia" ]; then + if ! has_awg_mode; then tg_edit "$chat_id" "$msg_id" "ℹ️ Только для AmneziaWG." "$(kbd_back)"; return fi tg_edit "$chat_id" "$msg_id" "🔄 Перезапуск контейнера..." "" @@ -1389,8 +1425,8 @@ bot_handle_callback() { local ws; ws=$(get_warp_status) s+="\nWARP: ${ws}" s+="\nРежим: ${MODE}" - [ "$MODE" = "3xui" ] && s+="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}" - [ "$MODE" = "amnezia" ] && s+="\nКонтейнер: ${CONTAINER:-N/A}" + if has_3xui_mode; then s+="\nSOCKS5: 127.0.0.1:${SOCKS_PORT}"; fi + if has_awg_mode; then s+="\nКонтейнер: ${CONTAINER:-N/A}"; fi tg_edit "$chat_id" "$msg_id" "$s" "$(kbd_back)" ;; promo) @@ -1406,7 +1442,7 @@ bot_daemon() { source "$WARP_CONF" [ -z "$BOT_TOKEN" ] && { log_action "BOT ERROR: no token"; exit 1; } get_my_ip - [ "$MODE" = "amnezia" ] && [ -n "$CONTAINER" ] && awg_load_container_data 2>/dev/null + if has_awg_mode && [ -n "$CONTAINER" ]; then awg_load_container_data 2>/dev/null; fi local offset=0 while true; do local response @@ -1540,15 +1576,17 @@ show_info() { echo -e "${MAGENTA}║ 📚 WARP Manager v${WARP_VERSION} ║${NC}" echo -e "${MAGENTA}╚══════════════════════════════════════════════════════════════╝${NC}" echo "" - if [ "$MODE" = "3xui" ]; then - echo -e "${CYAN}═══ РЕЖИМ: 3X-UI ═══${NC}\n" + if has_3xui_mode; then + echo -e "${CYAN}═══ 3X-UI ═══${NC}\n" echo -e "${WHITE} Клиент → 3X-UI (Xray) → SOCKS5 (WARP) → Cloudflare → Интернет${NC}\n" echo -e "${GREEN} 1.${NC} cloudflare-warp установлен нативно" echo -e "${GREEN} 2.${NC} SOCKS5-прокси на 127.0.0.1:${SOCKS_PORT}" echo -e "${GREEN} 3.${NC} В 3X-UI: outbound SOCKS → warp" echo -e "${GREEN} 4.${NC} Маршрутизация по доменам в Xray" - else - echo -e "${CYAN}═══ РЕЖИМ: AmneziaWG ═══${NC}\n" + echo "" + fi + if has_awg_mode; then + echo -e "${CYAN}═══ AmneziaWG ═══${NC}\n" echo -e "${WHITE} Клиент → AmneziaWG Docker → warp WG → Cloudflare → Интернет${NC}\n" echo -e "${GREEN} 1.${NC} wgcf генерирует WireGuard-профиль WARP" echo -e "${GREEN} 2.${NC} WG-интерфейс warp внутри Docker-контейнера" @@ -1575,7 +1613,8 @@ full_uninstall() { read -p "$(echo -e "${RED}Удалить полностью? (y/n): ${NC}")" c1 [[ "$c1" != "y" ]] && return - if [ "$MODE" = "3xui" ]; then uninstall_3xui; else uninstall_awg; fi + if has_3xui_mode; then uninstall_3xui; fi + if has_awg_mode; then uninstall_awg; fi rm -rf "$WARP_DIR" "$WARP_LOG" echo -e " ${GREEN}✓${NC} Конфигурация и логи" @@ -1584,7 +1623,7 @@ full_uninstall() { echo -e "\n${GREEN}══════════════════════════════════════════════════════════════${NC}" echo -e "${GREEN} WARP Manager полностью удалён.${NC}" - [ "$MODE" = "3xui" ] && echo -e "${WHITE} Уберите outbound \"warp\" из 3X-UI!${NC}" + has_3xui_mode && echo -e "${WHITE} Уберите outbound \"warp\" из 3X-UI!${NC}" echo -e "${GREEN}══════════════════════════════════════════════════════════════${NC}" log_action "UNINSTALL: full removal ($MODE)" read -p "Enter..." @@ -1600,8 +1639,10 @@ show_menu() { clear local st sc st=$(get_warp_status) - sc="$RED"; [[ "$st" == "Подключён" ]] && sc="$GREEN"; [[ "$st" == "Отключён" ]] && sc="$YELLOW" - local mode_label="3X-UI"; [ "$MODE" = "amnezia" ] && mode_label="AmneziaWG" + sc="$RED"; [[ "$st" == *"Подключён"* ]] && sc="$GREEN"; [[ "$st" == *"Отключён"* && "$st" != *"Подключён"* ]] && sc="$YELLOW" + local mode_label="3X-UI" + [ "$MODE" = "amnezia" ] && mode_label="AmneziaWG" + [ "$MODE" = "both" ] && mode_label="3X-UI + AmneziaWG" echo -e "${MAGENTA}╔══════════════════════════════════════════════════════╗" echo -e "║ anten-ka · WARP Manager v${WARP_VERSION} ║" @@ -1609,10 +1650,10 @@ show_menu() { echo -e "╚══════════════════════════════════════════════════════╝${NC}" echo -e " ${WHITE}IP сервера:${NC} ${GREEN}${MY_IP}${NC} ${WHITE}Режим:${NC} ${CYAN}${mode_label}${NC}" echo -e " ${WHITE}WARP:${NC} ${sc}${st}${NC}" - if [ "$MODE" = "3xui" ] && is_warp_running; then + if has_3xui_mode && is_warp_running_3xui 2>/dev/null; then echo -e " ${WHITE}SOCKS5:${NC} ${CYAN}127.0.0.1:${SOCKS_PORT}${NC}" fi - if [ "$MODE" = "amnezia" ] && [ -n "${CONTAINER:-}" ]; then + if has_awg_mode && [ -n "${CONTAINER:-}" ]; then echo -e " ${WHITE}Контейнер:${NC} ${CYAN}${CONTAINER}${NC}" fi @@ -1623,38 +1664,44 @@ show_menu() { echo -e " 4) 📊 Статус" echo -e " 5) 🔑 ${YELLOW}Перевыпуск ключа${NC}" - if [ "$MODE" = "3xui" ]; then + if has_3xui_mode; then echo -e "\n${CYAN}── 3X-UI ──────────────────────────────────────────────${NC}" echo -e " 6) 📋 ${CYAN}Настройки SOCKS5 / JSON / Инструкция${NC}" fi - if [ "$MODE" = "amnezia" ]; then + if has_awg_mode; then echo -e "\n${CYAN}── AmneziaWG ──────────────────────────────────────────${NC}" - echo -e " 6) 👥 ${GREEN}Управление клиентами WARP${NC}" + echo -e " 7) 👥 ${GREEN}Управление клиентами WARP${NC}" fi echo -e "\n${CYAN}── Telegram-бот ───────────────────────────────────────${NC}" - echo -e " 7) 🤖 ${CYAN}Настройка и управление ботом${NC}" + echo -e " 8) 🤖 ${CYAN}Настройка и управление ботом${NC}" echo -e "\n${CYAN}── Прочее ─────────────────────────────────────────────${NC}" - echo -e " 8) ${YELLOW}PROMO${NC}" - echo -e " 9) ${MAGENTA}📚 Инструкция${NC}" - echo -e " 10) ${RED}⚠ Полное удаление${NC}" + echo -e " 9) ${YELLOW}PROMO${NC}" + echo -e " 10) ${MAGENTA}📚 Инструкция${NC}" + echo -e " 11) ${RED}⚠ Полное удаление${NC}" echo -e " 0) Выход" echo -e "${CYAN}──────────────────────────────────────────────────────${NC}" read -p " Выбор: " ch case $ch in - 1) if [ "$MODE" = "3xui" ]; then install_warp_3xui; else install_warp_awg; fi ;; - 2) if [ "$MODE" = "3xui" ]; then start_warp_3xui; else start_warp_awg; fi ;; - 3) if [ "$MODE" = "3xui" ]; then stop_warp_3xui; else stop_warp_awg; fi ;; - 4) if [ "$MODE" = "3xui" ]; then show_status_3xui; else show_status_awg; fi ;; - 5) if [ "$MODE" = "3xui" ]; then rekey_warp_3xui; else rekey_warp_awg; fi ;; - 6) if [ "$MODE" = "3xui" ]; then show_3xui_menu; else awg_toggle_clients_ssh; fi ;; - 7) bot_menu ;; - 8) show_promo ;; - 9) show_info ;; - 10) full_uninstall ;; + 1) if has_3xui_mode; then install_warp_3xui; fi + if has_awg_mode; then install_warp_awg; fi ;; + 2) if has_3xui_mode; then start_warp_3xui; fi + if has_awg_mode; then start_warp_awg; fi ;; + 3) if has_3xui_mode; then stop_warp_3xui; fi + if has_awg_mode; then stop_warp_awg; fi ;; + 4) if has_3xui_mode; then show_status_3xui; fi + if has_awg_mode; then show_status_awg; fi ;; + 5) if has_3xui_mode; then rekey_warp_3xui; fi + if has_awg_mode; then rekey_warp_awg; fi ;; + 6) has_3xui_mode && show_3xui_menu ;; + 7) has_awg_mode && awg_toggle_clients_ssh ;; + 8) bot_menu ;; + 9) show_promo ;; + 10) show_info ;; + 11) full_uninstall ;; 0) exit 0 ;; esac done @@ -1665,7 +1712,7 @@ show_menu() { # ═══════════════════════════════════════════════════════════════ run_startup() { - local total=7 s=0 + local total=6 s=0 clear; echo "" echo -e "${MAGENTA}╔══════════════════════════════════════════════════════════════╗${NC}" @@ -1702,11 +1749,15 @@ run_startup() { ((s++)) printf " ${CYAN}[%d/%d]${NC} ${YELLOW}⏳${NC} Определение режима..." "$s" "$total" detect_mode - local mode_label="3X-UI"; [ "$MODE" = "amnezia" ] && mode_label="AmneziaWG" + local mode_label="3X-UI" + [ "$MODE" = "amnezia" ] && mode_label="AmneziaWG" + [ "$MODE" = "both" ] && mode_label="3X-UI + AmneziaWG" + has_awg_mode && ((total++)) + has_3xui_mode && ((total++)) printf "\r ${CYAN}[%d/%d]${NC} ${GREEN}✓${NC} Режим: %-25s \n" "$s" "$total" "$mode_label" - ((s++)) - if [ "$MODE" = "amnezia" ]; then + if has_awg_mode; then + ((s++)) printf " ${CYAN}[%d/%d]${NC} ${YELLOW}⏳${NC} Docker контейнер..." "$s" "$total" if awg_pick_container 2>/dev/null; then awg_load_container_data 2>/dev/null @@ -1714,10 +1765,12 @@ run_startup() { else printf "\r ${CYAN}[%d/%d]${NC} ${YELLOW}⚠${NC} Контейнер не найден \n" "$s" "$total" fi - else - printf " ${CYAN}[%d/%d]${NC} ${YELLOW}⏳${NC} Проверка WARP..." "$s" "$total" + fi + if has_3xui_mode; then + ((s++)) + printf " ${CYAN}[%d/%d]${NC} ${YELLOW}⏳${NC} Проверка WARP (3X-UI)..." "$s" "$total" local ws; ws=$(get_warp_status_3xui) - printf "\r ${CYAN}[%d/%d]${NC} ${GREEN}✓${NC} WARP: %-25s \n" "$s" "$total" "$ws" + printf "\r ${CYAN}[%d/%d]${NC} ${GREEN}✓${NC} 3X-UI WARP: %-20s \n" "$s" "$total" "$ws" fi echo ""