# ============================================ # PRODUCTION BOT WITH API - bot_with_api.py # Clean command processing, no excess logs # ============================================ import asyncio import threading import aiohttp # ADDED for keep-alive from api import app, command_queue import sys # ============================================ # COMMAND PROCESSOR - Clean & Efficient # ============================================ async def process_api_commands(): """Process commands from API queue - production version""" while True: try: if not command_queue.empty(): command = command_queue.get_nowait() if command['type'] == 'join': await handle_join(command) elif command['type'] == 'emote': await handle_emote(command) await asyncio.sleep(0.1) except Exception as e: print(f"[API ERROR] {e}") await asyncio.sleep(1) # ============================================ # JOIN HANDLER # ============================================ async def handle_join(command): """Handle join team command""" teamcode = command['teamcode'] try: from main import online_writer, key, iv from xC4 import GenJoinSquadsPacket if not online_writer: print(f"[JOIN] Failed - Bot not connected") return if not key or not iv: print(f"[JOIN] Failed - No encryption keys") return packet = await GenJoinSquadsPacket(teamcode, key, iv) online_writer.write(packet) await online_writer.drain() print(f"[JOIN] ✓ Team: {teamcode}") except Exception as e: print(f"[JOIN] ✗ Error: {e}") # ============================================ # EMOTE HANDLER - Only works if in team # ============================================ async def handle_emote(command): """Handle emote command - checks team status first""" uids = command['uids'] emote_code = command['emote_code'] try: from main import online_writer, key, iv, region, team_collection_active, team_members_data from xC4 import Emote_k # Check if bot is in team if not team_collection_active or len(team_members_data) == 0: print(f"[EMOTE] ✗ Bot not in team - Skipped") return if not online_writer or not key or not iv or not region: print(f"[EMOTE] ✗ Bot not ready") return success = 0 failed = 0 for uid in uids: try: packet = await Emote_k( int(uid), int(emote_code), key, iv, region ) online_writer.write(packet) await online_writer.drain() success += 1 await asyncio.sleep(0.3) # Rate limit except Exception as e: failed += 1 if success > 0: print(f"[EMOTE] ✓ Sent: {success}/{len(uids)} | Code: {emote_code}") if failed > 0: print(f"[EMOTE] ✗ Failed: {failed}") except Exception as e: print(f"[EMOTE] ✗ Error: {e}") # ============================================ # KEEP-ALIVE FOR HUGGING FACE # ============================================ async def keep_alive(): """Ping status endpoint every 30 minutes to keep Hugging Face space awake.""" # Wait a bit for Flask to start await asyncio.sleep(30) url = "https://matrixcoder-emote-api.hf.space/status" while True: try: async with aiohttp.ClientSession() as session: async with session.get(url) as resp: if resp.status == 200: print("[KEEPALIVE] ✓ Ping successful") else: print(f"[KEEPALIVE] ✗ Ping failed (status {resp.status})") except Exception as e: print(f"[KEEPALIVE] ✗ Error: {e}") await asyncio.sleep(1800) # 30 minutes # ============================================ # FLASK SERVER THREAD # ============================================ def run_flask(): """Run Flask in separate thread""" app.run(host='0.0.0.0', port=7860, debug=False, use_reloader=False) # ============================================ # MAIN RUNNER # ============================================ async def run_bot_with_api(): """Main function - runs bot + API together + keep-alive""" # Start Flask API flask_thread = threading.Thread(target=run_flask, daemon=True) flask_thread.start() print("[API] Started on http://0.0.0.0:7860") # Start command processor api_processor = asyncio.create_task(process_api_commands()) # Start keep-alive task keep_alive_task = asyncio.create_task(keep_alive()) # Start main bot try: from main import StarTinG print("[BOT] Starting...") bot_task = asyncio.create_task(StarTinG()) await asyncio.gather(api_processor, keep_alive_task, bot_task) except ImportError as e: print(f"[ERROR] Could not import bot: {e}") print("[API] Running in API-only mode...") await asyncio.gather(api_processor, keep_alive_task) # ============================================ # ENTRY POINT # ============================================ if __name__ == '__main__': print(""" ╔══════════════════════════════════════════════╗ ║ FF Emote Bot - Production Mode ║ ║ (Keep-alive active - pings every 30m) ║ ╚══════════════════════════════════════════════╝ Starting services... """) try: asyncio.run(run_bot_with_api()) except KeyboardInterrupt: print("\n[SHUTDOWN] Stopping...") sys.exit(0)