import asyncio,signal from pathlib import Path import discord,dotenv from discord.ext import commands from discord.http import Route from core import threads from core.hook import Hook from core.loader import load_all from core.presence import presence from core.whitelist import Whitelist dotenv.load_dotenv() env=dotenv.find_dotenv() token=dotenv.get_key(env,"TOKEN");log=dotenv.get_key(env,"LOG") bot=commands.Bot(command_prefix=";",self_bot=True,help_command=None) def banned(e): return isinstance(e,discord.LoginFailure) or (isinstance(e,discord.ConnectionClosed) and e.code==4004) or (isinstance(e,discord.HTTPException) and e.status in(401,403)) async def guard(): await bot.wait_until_ready() if bot.user.id not in bot.wl: await bot.wl.mutate(bot.user.id,True);bot.hook.put(f"owner {bot.user.id} added to whitelist") bot.hook.put(f"started as {bot.user} ({bot.user.id}), {len(bot.guilds)} guilds, whitelist {len(bot.wl.ids)}") while True: await asyncio.sleep(60) try:await bot.http.request(Route("GET","/users/@me")) except Exception as e: if banned(e):return f"account banned, disabled or token revoked: {e!r}" async def main(): hook=Hook(log);await hook.start();bot.hook=hook;bot.wl=Whitelist(Path(__file__).resolve().parent/"whitelist.json",hook);await bot.wl.start() stop=asyncio.Event();loop=asyncio.get_running_loop() for s in(signal.SIGINT,signal.SIGTERM):loop.add_signal_handler(s,stop.set) await load_all(bot) run=asyncio.create_task(bot.start(token));g=asyncio.create_task(guard());w=asyncio.create_task(stop.wait());p=asyncio.create_task(presence(bot)) done,_=await asyncio.wait({run,g,w},return_when=asyncio.FIRST_COMPLETED) if run in done: e=run.exception() if not run.cancelled() else None r=f"account banned or invalid token: {e!r}" if banned(e) else f"unexpected stop: {e!r}" elif g in done:r=f"guard stopped: {g.exception()!r}" if g.exception() else g.result() else:r="stopped by signal" hook.put(r) for t in(g,w,p,bot.wl.task):t.cancel() await bot.close();await hook.close();threads.shutdown() if __name__=="__main__":asyncio.run(main())