v2.1: MODE=both support - 3X-UI and AmneziaWG simultaneously, dual bot handlers, 4 bugs fixed

Made-with: Cursor
This commit is contained in:
anten-ka
2026-03-20 17:19:47 +03:00
parent 4ad1ac497e
commit dacfba7f62

245
warp.sh
View File

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