raxmatjon2013's picture
Create app.py
afe8f6e verified
Raw
History Blame Contribute Delete
14 kB
import logging
import json
import os
import asyncio
from datetime import datetime
import pytz
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.client.session.aiohttp import AiohttpSession
import aiohttp
from fastapi import FastAPI, Request
from contextlib import asynccontextmanager
import uvicorn
TOKEN = "8471671662:AAGOgJx0mb-z4CIGGmJY0J_C4SCL9l1mUoA"
ADMIN_ID = 7253593181
# Sizning to'g'ri va aniq server manzilingiz
SPACE_WEBHOOK_URL = "https://raxmatjon2013-minicraft-server-bot.hf.space/webhook"
RADMIN_IP = "26.99.233.131"
RADMIN_NETWORK_NAME = "raxmatjonMC"
RADMIN_NETWORK_PASS = "123456789"
bot = None
dp = Dispatcher()
logging.basicConfig(level=logging.INFO)
class ServerState(StatesGroup):
waiting_for_port = State()
in_chat = State()
waiting_for_broadcast = State()
USERS_FILE = "registered_users.json"
LANG_FILE = "user_languages.json"
def load_data(filename, default_type=list):
if os.path.exists(filename):
with open(filename, "r") as f:
try: return json.load(f)
except: return default_type()
return default_type()
def save_data(filename, data):
with open(filename, "w") as f:
json.dump(data, f)
registered_users = set(load_data(USERS_FILE, list))
user_languages = load_data(LANG_FILE, dict)
server_status = {"uz": "🔴 O'CHIQ", "ru": "🔴 ВЫКЛЮЧЕН", "en": "🔴 OFFLINE"}
is_server_on = False
current_port = None
active_chats = {}
user_by_admin = {}
def is_work_time():
tz = pytz.timezone('Asia/Tashkent')
now = datetime.now(tz)
return 11 <= now.hour < 20
TEXTS = {
"welcome": {"uz": "🎮 **Minecraft Server Botiga Xush Kelibsiz!** 🎮", "ru": "🎮 **Добро пожаловать!** 🎮", "en": "🎮 **Welcome!** 🎮"},
"btn_add_port": {"uz": "➕ Port kiritish", "ru": "➕ Ввести порт", "en": "➕ Enter Port"},
"btn_status": {"uz": "📊 Server holati", "ru": "📊 Status", "en": "📊 Status"},
"btn_how_to": {"uz": "❓ Qanday ulanadi?", "ru": "❓ Инструкция", "en": "❓ Guide"},
"btn_rules": {"uz": "📜 Server qoidalari", "ru": "📜 Правила", "en": "📜 Rules"},
"btn_players": {"uz": "👥 O'yinchilar", "ru": "👥 Игроки", "en": "👥 Players"},
"btn_support": {"uz": "📞 Yordam xizmati", "ru": "📞 Поддержка", "en": "📞 Support"},
"btn_downloads": {"uz": "💾 Yuklamalar", "ru": "💾 Скачать", "en": "💾 Downloads"},
"btn_faq": {"uz": "💡 Savol-Javoblar", "ru": "💡 FAQ", "en": "💡 FAQ"},
"btn_back": {"uz": "⬅️ Orqaga", "ru": "⬅️ Назад", "en": "⬅️ Back"},
"btn_end_chat": {"uz": "🛑 Suhbatni tugatish", "ru": "🛑 Завершить чат", "en": "🛑 End Chat"},
"ask_port": {"uz": f"🌐 **Radmin IP:** `{RADMIN_IP}`\n\n📥 PORT kiriting:", "ru": "📥 Введите ПОРТ:", "en": "📥 Enter PORT:"},
"error_port": {"uz": "❌ Xato format!", "ru": "❌ Неверный формат!", "en": "❌ Invalid format!"},
"success": {"uz": f"📢 **🔔 Server ishga tushdi! 🔔**\n\n🔗 Adres:\n`{RADMIN_IP}:{{port}}`", "ru": f"📢 **🔔 Сервер запущен! 🔔**", "en": f"📢 **🔔 Server is live! 🔔**"},
"guide_text": {"uz": f"🎮 **Ulanish:**\n👤 Name: `{RADMIN_NETWORK_NAME}`\n🔑 Pass: `{RADMIN_NETWORK_PASS}`", "ru": "🎮 Инструкция...", "en": "🎮 Guide..."},
"rules_text": {"uz": "📜 **Qoidalar:**\n1. Griefing taqiqlanadi.", "ru": "📜 Правила...", "en": "📜 Rules..."},
"players_text": {"uz": "👥 **O'yinchilar:**\n• 👑 `raxmatjonMC`", "ru": "👥 Игроки...", "en": "👥 Players..."},
"downloads_text": {"uz": "💾 **Yuklamalar:**\n• [Radmin VPN](https://www.radmin-vpn.com/)", "ru": "💾 Скачать...", "en": "💾 Downloads..."},
"faq_text": {"uz": "💡 **FAQ:** Versiyalar bir xil bo'lsin.", "ru": "💡 FAQ...", "en": "💡 FAQ..."},
"support_connecting": {"uz": "⏳ Bog'lanyapsiz... Yozing.", "ru": "⏳ Связываю...", "en": "⏳ Connecting..."},
"support_closed": {"uz": "💤 Ish vaqti soat 11:00 dan 20:00 gacha.", "ru": "💤 Поддержка сейчас недоступна.", "en": "💤 Support is closed."},
"chat_ended": {"uz": "🛑 Suhbat yakunlandi. Baholang:", "ru": "🛑 Чат завершен.", "en": "🛑 Chat ended."}
}
def lang_keyboard():
builder = InlineKeyboardBuilder()
builder.row(types.InlineKeyboardButton(text="🇺🇿 O'zbekcha", callback_data="lang_uz"),
types.InlineKeyboardButton(text="🇷🇺 Русский", callback_data="lang_ru"),
types.InlineKeyboardButton(text="🇺🇸 English", callback_data="lang_en"))
return builder.as_markup()
def main_menu_keyboard(lang):
builder = InlineKeyboardBuilder()
builder.row(types.InlineKeyboardButton(text=TEXTS["btn_add_port"][lang], callback_data="add_map"),
types.InlineKeyboardButton(text=TEXTS["btn_status"][lang], callback_data="server_status"))
builder.row(types.InlineKeyboardButton(text=TEXTS["btn_how_to"][lang], callback_data="how_to_get_port"),
types.InlineKeyboardButton(text=TEXTS["btn_rules"][lang], callback_data="server_rules"))
builder.row(types.InlineKeyboardButton(text=TEXTS["btn_players"][lang], callback_data="server_players"),
types.InlineKeyboardButton(text=TEXTS["btn_downloads"][lang], callback_data="server_downloads"))
builder.row(types.InlineKeyboardButton(text=TEXTS["btn_faq"][lang], callback_data="server_faq"),
types.InlineKeyboardButton(text=TEXTS["btn_support"][lang], callback_data="connect_support"))
return builder.as_markup()
def rating_keyboard():
builder = InlineKeyboardBuilder()
for i in range(1, 11): builder.add(types.InlineKeyboardButton(text=str(i), callback_data=f"rate_{i}"))
builder.adjust(5)
return builder.as_markup()
def end_chat_keyboard(lang):
builder = InlineKeyboardBuilder()
builder.row(types.InlineKeyboardButton(text=TEXTS["btn_end_chat"][lang], callback_data="user_end_chat"))
return builder.as_markup()
def back_keyboard(lang):
builder = InlineKeyboardBuilder()
builder.row(types.InlineKeyboardButton(text=TEXTS["btn_back"][lang], callback_data="back_to_menu"))
return builder.as_markup()
@dp.message(Command("admin"))
async def admin_panel(message: types.Message):
if message.from_user.id == ADMIN_ID:
builder = InlineKeyboardBuilder()
builder.row(types.InlineKeyboardButton(text="📢 E'lon yuborish", callback_data="admin_broadcast"))
await message.answer(f"🛠 **Admin Panel**\nJami: {len(registered_users)}", reply_markup=builder.as_markup())
@dp.callback_query(F.data == "admin_broadcast")
async def start_broadcast(callback: types.CallbackQuery, state: FSMContext):
await callback.message.answer("📝 E'lon matnini kiriting:")
await state.set_state(ServerState.waiting_for_broadcast)
await callback.answer()
@dp.message(ServerState.waiting_for_broadcast)
async def do_broadcast(message: types.Message, state: FSMContext):
text = message.text
await state.clear()
count = 0
for u_id in registered_users:
try:
await bot.send_message(u_id, f"📢 **E'lon!**\n\n{text}")
count += 1
except: pass
await message.answer(f"✅ Yetkazildi: {count}")
@dp.message(Command("start"))
async def start_cmd(message: types.Message):
if message.from_user.id not in registered_users:
registered_users.add(message.from_user.id)
save_data(USERS_FILE, list(registered_users))
await message.answer("🌐 Tilni tanlang / Choose language:", reply_markup=lang_keyboard())
@dp.callback_query(F.data.startswith("lang_"))
async def set_language(callback: types.CallbackQuery):
lang = callback.data.split("_")[1]
user_languages[str(callback.from_user.id)] = lang
save_data(LANG_FILE, user_languages)
await callback.message.edit_text(TEXTS["welcome"][lang], parse_mode="Markdown", reply_markup=main_menu_keyboard(lang))
await callback.answer()
@dp.callback_query(F.data == "add_map")
async def add_map_callback(callback: types.CallbackQuery, state: FSMContext):
lang = user_languages.get(str(callback.from_user.id), "uz")
await callback.message.edit_text(TEXTS["ask_port"][lang], parse_mode="Markdown", reply_markup=back_keyboard(lang))
await state.set_state(ServerState.waiting_for_port)
@dp.callback_query(F.data in ["how_to_get_port", "server_rules", "server_players", "server_downloads", "server_faq"])
async def sections_callback(callback: types.CallbackQuery):
lang = user_languages.get(str(callback.from_user.id), "uz")
mapped_keys = {"how_to_get_port": "guide_text", "server_rules": "rules_text", "server_players": "players_text", "server_downloads": "downloads_text", "server_faq": "faq_text"}
await callback.message.edit_text(TEXTS[mapped_keys[callback.data]][lang], parse_mode="Markdown", reply_markup=back_keyboard(lang))
@dp.callback_query(F.data == "back_to_menu")
async def back_to_menu(callback: types.CallbackQuery, state: FSMContext):
await state.clear()
lang = user_languages.get(str(callback.from_user.id), "uz")
await callback.message.edit_text(TEXTS["welcome"][lang], parse_mode="Markdown", reply_markup=main_menu_keyboard(lang))
@dp.message(ServerState.waiting_for_port)
async def process_port(message: types.Message, state: FSMContext):
global is_server_on, current_port
lang = user_languages.get(str(message.from_user.id), "uz")
if not message.text.isdigit():
await message.answer(TEXTS["error_port"][lang])
return
current_port = message.text.strip()
is_server_on = True
await state.clear()
await message.answer(TEXTS["success"][lang].format(port=current_port), parse_mode="Markdown", reply_markup=main_menu_keyboard(lang))
@dp.callback_query(F.data == "server_status")
async def check_status(callback: types.CallbackQuery):
lang = user_languages.get(str(callback.from_user.id), "uz")
text = f"📊 Status: {server_status[lang]}" if not is_server_on else f"📊 Status: 🟢 YONIQ\n🔗 Adres: `{RADMIN_IP}:{current_port}`"
await callback.message.edit_text(text, parse_mode="Markdown", reply_markup=main_menu_keyboard(lang))
@dp.callback_query(F.data == "connect_support")
async def connect_support(callback: types.CallbackQuery, state: FSMContext):
lang = user_languages.get(str(callback.from_user.id), "uz")
if not is_work_time():
await callback.message.edit_text(TEXTS["support_closed"][lang], parse_mode="Markdown", reply_markup=back_keyboard(lang))
await callback.answer()
return
user_id = callback.from_user.id
await callback.message.edit_text(TEXTS["support_connecting"][lang], reply_markup=end_chat_keyboard(lang))
await state.set_state(ServerState.in_chat)
await bot.send_message(ADMIN_ID, f"🔔 **Murojaat!**\n👤 {callback.from_user.full_name}\nID: `{user_id}`")
user_by_admin[ADMIN_ID] = user_id
active_chats[user_id] = ADMIN_ID
await callback.answer()
@dp.callback_query(F.data == "user_end_chat")
async def user_end_chat(callback: types.CallbackQuery, state: FSMContext):
lang = user_languages.get(str(callback.from_user.id), "uz")
user_id = callback.from_user.id
await state.clear()
await callback.message.edit_text(TEXTS["chat_ended"][lang], reply_markup=rating_keyboard())
if user_id in active_chats:
await bot.send_message(ADMIN_ID, "🛑 Suhbat yakunlandi.")
active_chats.pop(user_id, None)
user_by_admin.pop(ADMIN_ID, None)
@dp.message(ServerState.in_chat, F.text)
async def forward_to_admin(message: types.Message):
await bot.send_message(ADMIN_ID, f"💬 **[O'yinchi {message.from_user.first_name}]:** {message.text}")
@dp.message(F.chat.id == ADMIN_ID, F.text)
async def forward_to_user(message: types.Message):
user_id = user_by_admin.get(ADMIN_ID)
if user_id:
await bot.send_message(user_id, f"👨‍💼 **[Admin]:** {message.text}")
@dp.callback_query(F.data.startswith("rate_"))
async def process_rating(callback: types.CallbackQuery):
score = callback.data.split("_")[1]
lang = user_languages.get(str(callback.from_user.id), "uz")
await callback.message.edit_text(f"⭐️ Rahmat! Bahongiz: {score}\n\n" + TEXTS["welcome"][lang], parse_mode="Markdown", reply_markup=main_menu_keyboard(lang))
await bot.send_message(ADMIN_ID, f"📊 **Baho:** {score}/10")
await callback.answer()
# Serverni o'chib qolishdan asraydigan fondagi vazifa
async def keep_alive():
await asyncio.sleep(15)
async with aiohttp.ClientSession() as session:
while True:
try:
async with session.get("https://raxmatjon2013-minicraft-server-bot.hf.space/") as resp:
logging.info(f"Uyg'otish muvaffaqiyatli: {resp.status}")
except: pass
await asyncio.sleep(180) # Har 3 daqiqada serverni turtib turadi
@asynccontextmanager
async def lifespan(app: FastAPI):
global bot
connector = aiohttp.TCPConnector(ssl=False)
session = AiohttpSession()
session._session = aiohttp.ClientSession(connector=connector)
bot = Bot(token=TOKEN, session=session)
asyncio.create_task(keep_alive())
yield
await bot.session.close()
app = FastAPI(lifespan=lifespan)
@app.post("/webhook")
async def webhook_endpoint(request: Request):
update = types.Update(**await request.json())
await dp.feed_update(bot=bot, update=update)
return {"status": "ok"}
@app.get("/")
async def root():
return {"status": "running", "message": "Minecraft Webhook Server Active"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)