#!/usr/bin/env python3.12 # pylint: disable=bare-except, broad-exception-caught import io import random import asyncio import traceback from typing import Optional import discord import requests from discord.ext import bridge, commands import util class Owner(commands.Cog): """Owner Cog for Havoc""" def __init__(self, bot) -> None: self.bot: discord.Bot = bot self.former_roles_store: dict = {} self._temperature: int = random.randrange(20, 30) @bridge.bridge_command(guild_ids=[1145182936002482196]) async def temperature(self, ctx, temp: Optional[int|str] = None) -> None: """ Set Temperature Args: ctx (Any): Discord context temperature (Optional[int|str]): New temperature Returns: None """ if not temp: return await ctx.respond(f"The current temperature is: {self._temperature} °C") if not self.bot.is_owner(ctx.author): return await ctx.respond("I am afraid I can't let you do that.") try: _temperature: int = int(temp) except: return await ctx.respond("Invalid input") if _temperature < -15: return await ctx.respond("Too cold! (-15°C minimum)") elif _temperature > 35: return await ctx.respond("Too hot! (35°C maximum)") self._temperature: int = _temperature return await ctx.respond(f"As per your request, I have adjusted the temperature to {_temperature} °C.") @bridge.bridge_command() @commands.is_owner() async def reload(self, ctx) -> None: """ Reload Cogs Args: ctx (Any): Discord context Returns: None """ self.bot.load_exts(False) await ctx.respond("Reloaded!", ephemeral=True) @bridge.bridge_command() @commands.is_owner() async def say(self, ctx, *, parameters: str) -> None: """ Make me say something in a channel Args: ctx (Any): Discord context parameters (str): Channel Message Returns: None """ parameters: list[str] = parameters.split(" ") if not len(parameters) > 1: return await ctx.respond("**Error**: Incorrect command usage; required: ", ephemeral=True) channel: str = parameters[0] channel_mentions: list[str] = discord.utils.raw_channel_mentions(channel) if channel_mentions: channel: str = str(channel_mentions[0]) msg: str = " ".join(parameters[1:]) sent = await util.discord_helpers.send_message(self.bot, channel=channel, message=msg) if not sent: return await ctx.respond("**Failed.**", ephemeral=True) return await ctx.respond("**Done.**", ephemeral=True) @bridge.bridge_command() @commands.is_owner() async def chgstatus(self, ctx, *, status: Optional[str] = None) -> None: """ Change bots status Args: ctx (Any): Discord context status (Optional[str]): The new status to set Returns: None """ if not status: return await ctx.respond("ERR: No status provided to change to!", ephemeral=True) await self.bot.change_presence(status=discord.Status.online, activity=discord.CustomActivity(name=status.strip())) await ctx.respond("Done!", ephemeral=True) @commands.message_command(name="Remove Messages Starting Here") @commands.is_owner() async def purge(self, ctx, message: discord.Message) -> None: """ Purge Messages Args: ctx (Any): Discord context message (discord.Message): Discord message Returns: None """ try: await ctx.channel.purge(after=message, bulk=True, limit=900000, reason=f"Purge initiated by {ctx.author.display_name}") await message.delete(reason=f"Purge initiated by {ctx.author.display_name}") await ctx.respond("**Done!**") # Wait 3 seconds, then delete interaction await asyncio.sleep(3) interaction = await ctx.interaction.original_response() await interaction.delete() except Exception as e: traceback.print_exc() return await ctx.respond(f"**ERR: {str(e)}**") @commands.message_command(name="Move to Memes") @commands.is_owner() async def movememe(self, ctx, message: discord.Message) -> None: """ Move to Memes Args: ctx (Any): Discord context message (discord.Message): Discord message Returns: None """ try: memes_channel: discord.TextChannel = ctx.guild.get_channel(1147229098544988261) message_content: str = message.content message_author: str = message.author.display_name message_channel: str = message.channel.name _file: Optional[discord.File] = None if message.attachments: for item in message.attachments: if item.url and len(item.url) >= 20: image: io.BytesIO = io.BytesIO(requests.get(item.url, stream=True, timeout=20).raw.read()) ext: str = item.url.split(".")[-1]\ .split("?")[0].split("&")[0] _file: discord.File = discord.File(image, filename=f'img.{ext}') await memes_channel.send(f"*Performing bureaucratic duties (this didn't belong in #{message_channel})...*\n**{message_author}:** {message_content}", file=_file) await message.delete() await ctx.respond("OK!", ephemeral=True) except: traceback.print_exc() return await ctx.respond("Failed! :(", ephemeral=True) @commands.message_command(name="Move to Drugs") @commands.is_owner() async def movedrugs(self, ctx, message: discord.Message) -> None: """ Move to Drugs Args: ctx (Any): Discord context message (discord.Message): Discord message Returns: None """ try: drugs_channel: discord.TextChannel = ctx.guild.get_channel(1172247451047034910) message_content: str = message.content message_author: str = message.author.display_name message_channel: str = message.channel.name _file: Optional[discord.File] = None if message.attachments: for item in message.attachments: if item.url and len(item.url) >= 20: image: io.BytesIO = io.BytesIO(requests.get(item.url, stream=True, timeout=20).raw.read()) ext: str = item.url.split(".")[-1]\ .split("?")[0].split("&")[0] _file: discord.File = discord.File(image, filename=f'img.{ext}') await drugs_channel.send(f"*Performing bureaucratic duties (this didn't belong in #{message_channel})...\ *\n**{message_author}:** {message_content}", file=_file) await message.delete() await ctx.respond("OK!", ephemeral=True) except: traceback.print_exc() return await ctx.respond("Failed! :(", ephemeral=True) @commands.message_command(name="Move to fun-house") @commands.is_owner() async def movefunhouse(self, ctx, message: discord.Message) -> None: """ Move to fun-house Args: ctx (Any): Discord context message (discord.Message): Discord message Returns: None """ try: funhouse_channel: discord.TextChannel = ctx.guild.get_channel(1213160512364478607) message_content: str = message.content message_author: str = message.author.display_name message_channel: str = message.channel.name _file: Optional[discord.File] = None if message.attachments: for item in message.attachments: if item.url and len(item.url) >= 20: image: io.BytesIO = io.BytesIO(requests.get(item.url, stream=True, timeout=20).raw.read()) ext: str = item.url.split(".")[-1]\ .split("?")[0].split("&")[0] _file: discord.File = discord.File(image, filename=f'img.{ext}') await funhouse_channel.send(f"*Performing bureaucratic duties (this didn't belong in #{message_channel})\ ...*\n**{message_author}:** {message_content}") await message.delete() await ctx.respond("OK!", ephemeral=True) except: traceback.print_exc() return await ctx.respond("Failed! :(", ephemeral=True) @commands.user_command(name="Einsperren!", guild_ids=[145182936002482196]) @commands.is_owner() async def einsperren(self, ctx, member: discord.Member) -> None: """ Einsperren! Args: ctx (Any): Discord context member (discord.Member): Discord member Returns: None """ try: if not ctx.guild.id == 1145182936002482196: return # Not home server! audit_reason: str = f"Einsperren von {ctx.user.display_name}" member: discord.Member = ctx.guild.get_member(member.id) member_display: str = member.display_name einsperren_role: discord.Role = ctx.guild.get_role(1235415059300093973) if ctx.guild.id != 1145182936002482196\ else ctx.guild.get_role(1235406301614309386) member_roles: list[discord.Role] = [role for role in member.roles if not role.name == "@everyone"] member_role_names: list[str] = [str(role.name).lower() for role in member_roles] opers_chan: discord.TextChannel = ctx.guild.get_channel(1181416083287187546) if not "einsperren" in member_role_names: try: if member.id in self.former_roles_store: self.former_roles_store.pop(member.id) self.former_roles_store[member.id] = member.roles except: pass # Safe to ignore try: await member.edit(roles=[einsperren_role], reason=audit_reason) await ctx.respond(f"Gesendet {member_display} an einsperren.", ephemeral=True) await opers_chan.send(f"@everyone: {ctx.user.display_name} gesendet {member_display} an einsperren.") except: traceback.print_exc() return await ctx.respond("GOTTVERDAMMT!!", ephemeral=True) self.former_roles_store[member.id] = member.roles if not member.id in self.former_roles_store: await member.edit(roles=[]) # No roles else: former_roles: list[discord.Role] = self.former_roles_store.get(member.id) await member.edit(roles=former_roles, reason=f"De-{audit_reason}") await ctx.respond(f"{member_display} wurde von der Einsperre befreit.", ephemeral=True) await opers_chan.send(f"{member_display} wurde von {ctx.user.display_name} aus der Einsperre befreit.") except Exception as e: traceback.print_exc() return await ctx.respond(f"ERR: {str(e)}", ephemeral=True) def setup(bot) -> None: """Run on Cog Load""" bot.add_cog(Owner(bot))