From bba0e3ebdbd4fea60365626a389f4bc92feb3254 Mon Sep 17 00:00:00 2001 From: Vlad Date: Thu, 3 Oct 2024 06:20:38 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=8E?= =?UTF-8?q?=D1=89=D0=B8=D0=B9=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/keys.py | 87 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/handlers/keys.py b/handlers/keys.py index 0d399640..727bde1c 100644 --- a/handlers/keys.py +++ b/handlers/keys.py @@ -3,10 +3,10 @@ from datetime import datetime, timedelta import asyncpg from aiogram import Router, types -from auth import login_with_credentials +from auth import login_with_credentials, link from bot import bot -from client import delete_client, extend_client_key -from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL +from client import delete_client, extend_client_key, add_client +from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SERVERS from database import get_balance, update_balance router = Router() @@ -97,8 +97,9 @@ async def process_callback_view_key(callback_query: types.CallbackQuery): renew_button = types.InlineKeyboardButton(text='⏳ Продлить ключ', callback_data=f'renew_key|{client_id}') instructions_button = types.InlineKeyboardButton(text='📘 Инструкции', callback_data='instructions') delete_button = types.InlineKeyboardButton(text='❌ Удалить ключ', callback_data=f'delete_key|{client_id}') + change_location_button = types.InlineKeyboardButton(text='🌍 Сменить локацию', callback_data=f'change_location|{client_id}') back_button = types.InlineKeyboardButton(text='🔙 Назад в профиль', callback_data='view_profile') - keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[renew_button], [instructions_button], [delete_button], [back_button]]) + keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[renew_button], [instructions_button], [delete_button], [change_location_button], [back_button]]) await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard, parse_mode="HTML") else: @@ -277,4 +278,80 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery): await callback_query.answer() async def handle_error(tg_id, callback_query, message): - await bot.edit_message_text(message, chat_id=tg_id, message_id=callback_query.message.message_id) \ No newline at end of file + await bot.edit_message_text(message, chat_id=tg_id, message_id=callback_query.message.message_id) + +@router.callback_query(lambda c: c.data.startswith('change_location|')) +async def process_callback_change_location(callback_query: types.CallbackQuery): + tg_id = callback_query.from_user.id + client_id = callback_query.data.split('|')[1] # Используем разделитель вертикальная черта + + # Запрос выбора сервера + server_buttons = [ + [types.InlineKeyboardButton(text=server['name'], callback_data=f'select_server&{server_id}&{client_id}')] + for server_id, server in SERVERS.items() + ] + keyboard = types.InlineKeyboardMarkup(inline_keyboard=server_buttons) + + response_message = "Выберите новый сервер для вашего ключа:" + await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard, parse_mode="HTML") + await callback_query.answer() + +@router.callback_query(lambda c: c.data.startswith('select_server&')) +async def process_callback_select_server(callback_query: types.CallbackQuery): + tg_id = callback_query.from_user.id + server_id, client_id = callback_query.data.split('&')[1], callback_query.data.split('&')[2] + + try: + conn = await asyncpg.connect(DATABASE_URL) + try: + # Извлекаем email и expiry_time из базы данных + record = await conn.fetchrow('SELECT email, expiry_time, server_id FROM keys WHERE client_id = $1', client_id) + + if record: + email = record['email'] + expiry_time = record['expiry_time'] + current_server_id = record['server_id'] + + # Создаем сессию для нового сервера + session = login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD) + + # Рассчитываем новое время окончания ключа + new_expiry_time = int(datetime.utcnow().timestamp() * 1000) + (expiry_time - datetime.utcnow().timestamp() * 1000) + + # Создаем нового клиента на новом сервере + new_client_data = add_client(session, server_id, client_id, email, tg_id, limit_ip=1, total_gb=0, expiry_time=new_expiry_time, enable=True, flow="xtls-rprx-vision") + + if new_client_data: + # Генерируем новый ключ + new_key = link(session, server_id, client_id, email) + + # Обновляем запись в базе данных, только ключ и сервер + await conn.execute('UPDATE keys SET server_id = $1, key = $2 WHERE client_id = $3', + server_id, new_key, client_id) + + # Удаляем клиента с текущего сервера + session = login_with_credentials(current_server_id, ADMIN_USERNAME, ADMIN_PASSWORD) + success_delete = delete_client(session, current_server_id, client_id) + if success_delete: + response_message = ("Ключ успешно перемещен на новый сервер.\n\n" + "**Не забудьте удалить старый ключ из вашего приложения и установить новый.**") + else: + response_message = "Ошибка при удалении ключа с текущего сервера." + else: + response_message = "Ошибка при создании клиента на новом сервере." + + else: + response_message = "Ключ не найден или уже удален." + + back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_keys') + keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[back_button]]) + + await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard) + + finally: + await conn.close() + + except Exception as e: + await bot.edit_message_text(f"Ошибка при смене локации: {e}", chat_id=tg_id, message_id=callback_query.message.message_id) + + await callback_query.answer()