async def handle_broadcast(self, packet: ClassyDict) -> None: if packet.type == "eval": try: result = eval(packet.code, self.eval_env) success = True except Exception as e: result = format_exception(e) success = False await self.ipc.send({ "type": "broadcast-response", "id": packet.id, "result": result, "success": success }) elif packet.type == "exec": try: result = await execute_code(packet.code, self.eval_env) success = True except Exception as e: result = format_exception(e) success = False await self.ipc.send({ "type": "broadcast-response", "id": packet.id, "result": result, "success": success })
async def heal_users_loop(self): try: while True: await asyncio.sleep(32) await self.db.execute( "UPDATE users SET health = health + 1 WHERE health < 20") except Exception as e: self.logger.error(format_exception(e))
async def on_error(self, event, *args, **kwargs): # logs errors in events, such as on_message self.bot.error_count += 1 exception = sys.exc_info()[1] traceback = format_exception(exception) event_call_repr = f"{event}({', '.join(list(map(repr, args)) + [f'{k}={repr(v)}' for k, v in kwargs.items()])})" self.logger.error( f"An exception occurred in this call:\n{event_call_repr}\n\n{traceback}" ) await self.after_ready.wait() await self.bot.error_channel.send( f"```py\n{event_call_repr[:100]}``````py\n{traceback[:1880]}```")
async def update_stats(self): await self.bot.wait_until_ready() while True: try: res = await self.ipc.broadcast({"type": "eval", "code": "len(bot.guilds)"}) await self.bot.aiohttp.post( f"https://top.gg/api/bots/{self.bot.user.id}/stats", headers={"Authorization": self.k.topgg_api}, json={"server_count": str(sum([r.result for r in res.responses]))}, ) except Exception as e: self.bot.logger.error(format_exception(e)) await asyncio.sleep(3600)
def run_cluster(shard_count: int, shard_ids: list, max_db_pool_size: int) -> None: # add cython support, with numpy header files pyximport.install(language_level=3, setup_args={"include_dirs": numpy.get_include()}) # for some reason, asyncio tries to use the event loop from the main process asyncio.set_event_loop(asyncio.new_event_loop()) cluster = VillagerBotCluster(shard_count, shard_ids, max_db_pool_size) try: cluster.run() except KeyboardInterrupt: pass except Exception as e: cluster.logger.error(format_exception(e))
async def commands_dump_loop(self): try: while True: await asyncio.sleep(60) if self.commands: async with self.commands_lock: commands_dump = list(self.commands.items()) user_ids = [(user_id, ) for user_id in list(self.commands.keys())] self.commands.clear() await self.db.executemany( 'INSERT INTO users (user_id) VALUES ($1) ON CONFLICT ("user_id") DO NOTHING', user_ids) # ensure users are in the database first await self.db.executemany( 'INSERT INTO leaderboards (user_id, commands) VALUES ($1, $2) ON CONFLICT ("user_id") DO UPDATE SET "commands" = leaderboards.commands + $2 WHERE leaderboards.user_id = $1', commands_dump, ) except Exception as e: self.logger.error(format_exception(e))
from urllib.parse import quote as urlquote from discord.ext import commands import classyjson as cj import asyncio import discord import random import typing from util.code import format_exception from util.misc import strip_command try: from util import tiler_rgba except ImportError as e: print(format_exception(e)) tiler = None ALPHABET_LOWER = "abcdefghijklmnopqrstuvwxyz" INSULTS = {"i am stupid", "i am dumb", "i am very stupid", "i am very dumb", "i stupid", "i'm stupid", "i'm dumb"} class Fun(commands.Cog): def __init__(self, bot): self.bot = bot self.d = bot.d self.k = bot.k self.aiohttp = bot.aiohttp self.db = bot.get_cog("Database")
async def handle_packet(self, stream: Stream, packet: ClassyDict): if packet.type == "shard-ready": self.online_shards.add(packet.shard_id) if len(self.online_shards) == len(self.shard_ids): self.logger.info( f"\u001b[36;1mALL SHARDS\u001b[0m [0-{len(self.online_shards)-1}] \u001b[36;1mREADY\u001b[0m" ) elif packet.type == "shard-disconnect": self.online_shards.discard(packet.shard_id) elif packet.type == "eval": try: result = eval(packet.code, self.eval_env) success = True except Exception as e: result = format_exception(e) success = False await stream.write_packet({ "type": "eval-response", "id": packet.id, "result": result, "success": success }) elif packet.type == "exec": try: result = await execute_code(packet.code, self.eval_env) success = True except Exception as e: result = format_exception(e) success = False await stream.write_packet({ "type": "exec-response", "id": packet.id, "result": result, "success": success }) elif packet.type == "broadcast-request": # broadcasts the packet to every connection including the broadcaster, and waits for responses broadcast_id = f"b{self.current_id}" self.current_id += 1 broadcast_packet = {**packet.packet, "id": broadcast_id} broadcast_coros = [ s.write_packet(broadcast_packet) for s in self.server.connections ] broadcast = self.broadcasts[broadcast_id] = { "ready": asyncio.Event(), "responses": [], "expects": len(broadcast_coros), } await asyncio.wait(broadcast_coros) await broadcast["ready"].wait() await stream.write_packet({ "type": "broadcast-response", "id": packet.id, "responses": broadcast["responses"] }) elif packet.type == "broadcast-response": broadcast = self.broadcasts[packet.id] broadcast["responses"].append(packet) if len(broadcast["responses"]) == broadcast["expects"]: broadcast["ready"].set() elif packet.type == "cooldown": cooldown_info = self.cooldowns.check(packet.command, packet.user_id) await stream.write_packet({ "type": "cooldown-info", "id": packet.id, **cooldown_info }) elif packet.type == "cooldown-add": self.cooldowns.add_cooldown(packet.command, packet.user_id) elif packet.type == "cooldown-reset": self.cooldowns.clear_cooldown(packet.command, packet.user_id) elif packet.type == "dm-message-request": entry = self.dm_messages[packet.user_id] = { "event": asyncio.Event(), "content": None } await entry["event"].wait() self.dm_messages.pop(packet.user_id, None) await stream.write_packet({ "type": "dm-message", "id": packet.id, "content": entry["content"] }) elif packet.type == "dm-message": entry = self.dm_messages.get(packet.user_id) if entry is None: return entry["content"] = packet.content entry["event"].set() elif packet.type == "mine-command": # actually used for fishing too self.v.mine_commands[packet.user_id] += packet.addition await stream.write_packet({ "type": "mine-command-response", "id": packet.id, "current": self.v.mine_commands[packet.user_id] }) elif packet.type == "concurrency-check": can_run = self.concurrency.check(packet.command, packet.user_id) await stream.write_packet({ "type": "concurrency-check-response", "id": packet.id, "can_run": can_run }) elif packet.type == "concurrency-acquire": self.concurrency.acquire(packet.command, packet.user_id) elif packet.type == "concurrency-release": self.concurrency.release(packet.command, packet.user_id) elif packet.type == "command-ran": async with self.commands_lock: self.commands[packet.user_id] += 1