From 48bee2dd88e747c3b5884b266a48748aa6b8c240 Mon Sep 17 00:00:00 2001 From: WhatDidYouExpect <89535984+WhatDidYouExpect@users.noreply.github.com> Date: Mon, 7 Jul 2025 23:41:23 +0200 Subject: [PATCH] did i not push this --- assets/cogs/fireboard.py | 1923 ++++++++++++++++++++++++++++++++++++++ assets/locales/en.json | 1 + assets/locales/it.json | 1 + bot.py | 2 +- modules/globalvars.py | 2 +- 5 files changed, 1927 insertions(+), 2 deletions(-) create mode 100644 assets/cogs/fireboard.py diff --git a/assets/cogs/fireboard.py b/assets/cogs/fireboard.py new file mode 100644 index 0000000..8d199b0 --- /dev/null +++ b/assets/cogs/fireboard.py @@ -0,0 +1,1923 @@ +import asyncio +import random + +import asqlite +import discord +import discord.ext +import discord.ext.commands +from discord import Color, app_commands +from discord.ext import commands +from discord.ui import View + + +class Fireboard(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.locked_messages = [] + self.disabled = False + + # Check if the bot has the fireboard_pool attribute + if not hasattr(bot, 'fireboard_pool') or bot.fireboard_pool is None: + print("Warning: Bot does not have fireboard_pool initialized. Fireboard functionality will be disabled.") + self.disabled = True + return + + self.fireboard_pool: asqlite.Pool = bot.fireboard_pool + self.bot.loop.create_task(self.setup()) + + # SQL Setup + async def setup(self): + async with self.fireboard_pool.acquire() as sql: + if ( + await sql.fetchone( + "SELECT name FROM sqlite_master WHERE type='table' AND name='fireMessages';" + ) + is None + ): + # Fire Messages - messages that are active on the fireboard + await sql.execute( + "CREATE TABLE fireMessages (serverID int, msgID int, boardMsgID int, reactionAmount int)" + ) + + if ( + await sql.fetchone( + "SELECT name FROM sqlite_master WHERE type='table' AND name='fireSettings';" + ) + is None + ): + # Fire Settings - server properties for fireboard + await sql.execute( + "CREATE TABLE fireSettings (serverID int, reactionAmount int, emoji text, channelID int, ignoreBots int)" + ) + + if ( + await sql.fetchone( + "SELECT name FROM sqlite_master WHERE type='table' AND name='fireChannelBlacklist';" + ) + is None + ): + # Fire Channel Blacklist - blacklisted channels + await sql.execute( + "CREATE TABLE fireChannelBlacklist (serverID int, channelID int)" + ) + + if ( + await sql.fetchone( + "SELECT name FROM sqlite_master WHERE type='table' AND name='fireRoleBlacklist';" + ) + is None + ): + # Fire Role Blacklist - blacklisted roles + await sql.execute( + "CREATE TABLE fireRoleBlacklist (serverID int, roleID int)" + ) + + await sql.commit() + + await self.refresh_fire_lists() + + # List refresh function + async def refresh_fire_lists(self): + async with self.fireboard_pool.acquire() as sql: + self.fire_messages = await sql.fetchall("SELECT * FROM fireMessages") + self.fire_settings = await sql.fetchall("SELECT * FROM fireSettings") + self.fire_channel_blacklist = await sql.fetchall( + "SELECT * FROM fireChannelBlacklist" + ) + self.fire_role_blacklist = await sql.fetchall( + "SELECT * FROM fireRoleBlacklist" + ) + + # Listen for reactions + @commands.Cog.listener() + async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): + self.bot: discord.ext.commands.Bot + + # Stop if this is a DM + if payload.guild_id is None: + return + + queued = False + + # Lock system + if payload.message_id in self.locked_messages: + queued = True + + while payload.message_id in self.locked_messages: + await asyncio.sleep(0.5) + + self.locked_messages.append(payload.message_id) + + try: + fetched = False + + # Find server config + for server in self.fire_settings: + if server[0] == payload.guild_id: + react_minimum = server[1] + emoji = server[2] + channel_id = server[3] + ignore_bots = True if int(server[4]) == 1 else False + + fetched = True + + # Stop if server has no config (fireboard isn't enabled) + if not fetched: + return + + # Stop if message is by Titanium + if payload.message_author_id == self.bot.user.id: + return + + # Stop if emoji doesn't match + if str(payload.emoji) != emoji: + return + + # --- Edit board message if it already exists --- + if payload.message_id in [message[1] for message in self.fire_messages]: + message = [ + message + for message in self.fire_messages + if message[1] == payload.message_id + ][0] + + # Only fetch updated reaction count if I have queued or reaction amount is undefined + if queued or message[3] is None: + # Fetch message and channel + try: + msg_channel = await self.bot.fetch_channel(payload.channel_id) + message = await msg_channel.fetch_message(payload.message_id) + except discord.errors.NotFound: + return + + # Stop if not enough reactions + for reaction in message.reactions: + if str(reaction.emoji) == emoji: + react_count = reaction.count + break + + if react_count < react_minimum: + return + else: + react_count = None + + async with self.fireboard_pool.acquire() as sql: + # Set updated react count + if react_count is not None: + await sql.execute( + "UPDATE fireMessages SET reactionAmount = ? WHERE msgID = ?", + ( + react_count, + payload.message_id, + ), + ) + await self.refresh_fire_lists() + else: + await sql.execute( + "UPDATE fireMessages SET reactionAmount = reactionAmount + 1 WHERE msgID = ?", + (payload.message_id,), + ) + await self.refresh_fire_lists() + + # Get message from message list + message = [ + message + for message in self.fire_messages + if message[1] == payload.message_id + ][0] + + # Get board message + board_channel = await self.bot.fetch_channel(channel_id) + board_message = await board_channel.fetch_message(message[2]) + + await board_message.edit( + content=f"**{message[3]} {emoji}** | <@{payload.message_author_id}> | <#{payload.channel_id}>", + embeds=board_message.embeds, + ) + + return + + # Stop if message is in a blacklisted channel + if payload.channel_id in [ + channel[1] for channel in self.fire_channel_blacklist + ]: + return + + # Stop if message is by a blacklisted role + guild = await self.bot.fetch_guild(payload.guild_id) + member = await guild.fetch_member(payload.user_id) + + if any( + role[1] in [role.id for role in member.roles] + for role in self.fire_role_blacklist + ): + return + + # Fetch message and channel + try: + msg_channel = await self.bot.fetch_channel(payload.channel_id) + message = await msg_channel.fetch_message(payload.message_id) + except discord.errors.NotFound: + return + + # Stop if message is by a bot + if ignore_bots and message.author.bot: + return + + # Check if this is a thread + if isinstance(msg_channel, discord.Thread): + # Check if parent channel is NSFW + if msg_channel.parent.nsfw: + return + else: + # Stop if message is in an NSFW channel + if message.channel.nsfw: + return + + # Stop if not enough reactions + for reaction in message.reactions: + if str(reaction.emoji) == emoji: + react_count = reaction.count + break + + if react_count < react_minimum: + return + + # --- Send message to fireboard --- + + # Create embed + embed = discord.Embed(description=message.content, color=Color.random()) + embed.set_author( + name=message.author.name, icon_url=message.author.display_avatar.url + ) + embed.timestamp = message.created_at + + # Jump to message button + view = View() + view.add_item( + discord.ui.Button( + label="Jump to Message", + url=message.jump_url, + style=discord.ButtonStyle.url, + ) + ) + + embed_list = [embed] + + # Add reply embed + if message.reference: + try: + reply_message = await msg_channel.fetch_message( + message.reference.message_id + ) + + reply_embed = discord.Embed( + title="Replying To", + description=reply_message.content, + color=Color.random(), + ) + reply_embed.set_author( + name=reply_message.author.name, + icon_url=reply_message.author.display_avatar.url, + ) + reply_embed.timestamp = reply_message.created_at + + embed_list.insert(0, reply_embed) + except discord.errors.NotFound: + pass + + # Send message + board_channel = await self.bot.fetch_channel(channel_id) + board_message = await board_channel.send( + content=f"**{react_count} {emoji}** | {message.author.mention} | <#{payload.channel_id}>", + embeds=embed_list, + view=view, + files=[ + await attachment.to_file() for attachment in message.attachments + ], + ) + + async with self.fireboard_pool.acquire() as sql: + # Insert message to DB + await sql.execute( + "INSERT INTO fireMessages (serverID, msgID, boardMsgID, reactionAmount) VALUES (?, ?, ?, ?)", + ( + payload.guild_id, + payload.message_id, + board_message.id, + react_count, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + except Exception as e: + raise e + finally: + self.locked_messages.remove(payload.message_id) + + # Listen for reaction removal + @commands.Cog.listener() + async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent): + self.bot: discord.ext.commands.Bot + + queued = False + + # Stop if this is a DM + if payload.guild_id is None: + return + + # Lock system + if payload.message_id in self.locked_messages: + queued = True + + while payload.message_id in self.locked_messages: + await asyncio.sleep(0.5) + + self.locked_messages.append(payload.message_id) + + try: + fetched = False + + # Find server config + for server in self.fire_settings: + if server[0] == payload.guild_id: + react_minimum = server[1] + emoji = server[2] + channel_id = server[3] + ignore_bots = True if int(server[4]) == 1 else False + + fetched = True + + # Stop if server has no config (fireboard isn't enabled) + if not fetched: + return + + # Stop if message is by Titanium + if payload.message_author_id == self.bot.user.id: + return + + # Stop if emoji doesn't match + if str(payload.emoji) != emoji: + return + + # --- Edit board message if it already exists --- + if payload.message_id in [message[1] for message in self.fire_messages]: + prev_react_count = [ + message + for message in self.fire_messages + if message[1] == payload.message_id + ][0][3] + + # Only fetch updated reaction count if I have queued + if queued or prev_react_count is None: + # Fetch message and channel + try: + msg_channel = await self.bot.fetch_channel(payload.channel_id) + message = await msg_channel.fetch_message(payload.message_id) + except discord.errors.NotFound: + return + + # Stop if not enough reactions + for reaction in message.reactions: + if str(reaction.emoji) == emoji: + react_count = reaction.count + break + + if react_count < react_minimum: + return + else: + react_count = None + + async with self.fireboard_pool.acquire() as sql: + # Set updated react count + if react_count is not None: + await sql.execute( + "UPDATE fireMessages SET reactionAmount = ? WHERE msgID = ?", + ( + react_count, + payload.message_id, + ), + ) + await self.refresh_fire_lists() + else: + await sql.execute( + "UPDATE fireMessages SET reactionAmount = reactionAmount - 1 WHERE msgID = ?", + (payload.message_id,), + ) + await self.refresh_fire_lists() + + # Get message from message list + message = [ + message + for message in self.fire_messages + if message[1] == payload.message_id + ][0] + + # Get board message + board_channel = await self.bot.fetch_channel(channel_id) + board_message = await board_channel.fetch_message(message[2]) + + # Remove message if not enough reactions + if message[3] < react_minimum: + await board_message.delete() + + async with self.fireboard_pool.acquire() as sql: + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (payload.message_id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + + # Workaround for lack of message author ID + content = board_message.content + content = content.replace( + f"{prev_react_count} {emoji}", f"{message[3]} {emoji}" + ) + + await board_message.edit(content=content) + + return + + # Stop if message is in a blacklisted channel + if payload.channel_id in [ + channel[1] for channel in self.fire_channel_blacklist + ]: + return + + # Stop if message is by a blacklisted role + guild = await self.bot.fetch_guild(payload.guild_id) + member = await guild.fetch_member(payload.user_id) + + if any( + role[1] in [role.id for role in member.roles] + for role in self.fire_role_blacklist + ): + return + + # Fetch message and channel + try: + msg_channel = await self.bot.fetch_channel(payload.channel_id) + message = await msg_channel.fetch_message(payload.message_id) + except discord.errors.NotFound: + return + + # Stop if message is by a bot + if ignore_bots and message.author.bot: + return + + # Check if this is a thread + if isinstance(msg_channel, discord.Thread): + # Check if parent channel is NSFW + if msg_channel.parent.nsfw: + return + else: + # Stop if message is in an NSFW channel + if message.channel.nsfw: + return + + # Get reaction count + react_count = 0 + + for reaction in message.reactions: + if str(reaction.emoji) == emoji: + react_count = reaction.count + break + + # Stop if not enough reactions + if react_count < react_minimum: + return + + # --- Send message to fireboard --- + + # Create embed + embed = discord.Embed(description=message.content, color=Color.random()) + embed.set_author( + name=message.author.name, icon_url=message.author.display_avatar.url + ) + embed.timestamp = message.created_at + + # Jump to message button + view = View() + view.add_item( + discord.ui.Button( + label="Jump to Message", + url=message.jump_url, + style=discord.ButtonStyle.url, + ) + ) + + embed_list = [embed] + + # Add reply embed + if message.reference: + try: + reply_message = await msg_channel.fetch_message( + message.reference.message_id + ) + + reply_embed = discord.Embed( + title="Replying To", + description=reply_message.content, + color=Color.random(), + ) + reply_embed.set_author( + name=reply_message.author.name, + icon_url=reply_message.author.display_avatar.url, + ) + reply_embed.timestamp = reply_message.created_at + + embed_list.insert(0, reply_embed) + except discord.errors.NotFound: + pass + + # Send message + board_channel = await self.bot.fetch_channel(channel_id) + board_message = await board_channel.send( + content=f"**{react_count} {emoji}** | {message.author.mention} | <#{payload.channel_id}>", + embeds=embed_list, + view=view, + files=[ + await attachment.to_file() for attachment in message.attachments + ], + ) + + async with self.fireboard_pool.acquire() as sql: + # Insert message to DB + await sql.execute( + "INSERT INTO fireMessages (serverID, msgID, boardMsgID, reactionAmount) VALUES (?, ?, ?, ?)", + ( + payload.guild_id, + payload.message_id, + board_message.id, + react_count, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + except Exception as e: + raise e + finally: + self.locked_messages.remove(payload.message_id) + + # Listen for message reaction clear + @commands.Cog.listener() + async def on_raw_reaction_clear(self, payload: discord.RawReactionClearEvent): + self.bot: discord.ext.commands.Bot + + # Stop if this is a DM + if payload.guild_id is None: + return + + # Lock system + if payload.message_id in self.locked_messages: + while payload.message_id in self.locked_messages: + await asyncio.sleep(0.5) + + self.locked_messages.append(payload.message_id) + + try: + # Only trigger if message is already in the fireboard DB + if payload.message_id in [message[1] for message in self.fire_messages]: + # Find server config + for server in self.fire_settings: + if server[0] == payload.guild_id: + channel_id = server[3] + + # Get guild + try: + guild: discord.Guild = await self.bot.fetch_guild(payload.guild_id) + except discord.errors.NotFound: + return + + # Get message channel + channel: discord.abc.GuildChannel = await guild.fetch_channel( + payload.channel_id + ) + + # Get our message + message: discord.Message = await channel.fetch_message( + payload.message_id + ) + + # See if board message is already present + for fire_message in self.fire_messages: + if fire_message[1] == message.id: + async with self.fireboard_pool.acquire() as sql: + try: + # Delete message + try: + channel: discord.TextChannel = ( + await guild.fetch_channel(channel_id) + ) + except discord.errors.NotFound: + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", + (payload.guild_id,), + ) + await sql.commit() + self.locked_messages.remove(payload.message_id) + + return + + board_message = await channel.fetch_message( + fire_message[2] + ) + await board_message.delete() + + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (message.id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + except discord.errors.NotFound: + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (message.id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + else: + return + except Exception as e: + raise e + finally: + self.locked_messages.remove(payload.message_id) + + # Listen for specific emoji being cleared + @commands.Cog.listener() + async def on_raw_reaction_clear_emoji( + self, payload: discord.RawReactionClearEmojiEvent + ): + self.bot: discord.ext.commands.Bot + + # Stop if this is a DM + if payload.guild_id is None: + return + + # Lock system + if payload.message_id in self.locked_messages: + while payload.message_id in self.locked_messages: + await asyncio.sleep(0.5) + + self.locked_messages.append(payload.message_id) + + try: + # Only trigger if message is already in the fireboard DB + if payload.message_id in [message[1] for message in self.fire_messages]: + for server in self.fire_settings: + if server[0] == payload.guild_id: + emoji = server[2] + channel_id = server[3] + + # Only trigger if cleared emoji is our emoji + if str(payload.emoji) == emoji: + # Fetch server + try: + guild: discord.Guild = await self.bot.fetch_guild( + payload.guild_id + ) + except discord.errors.NotFound: + return + + # Get message channel + channel: discord.abc.GuildChannel = await guild.fetch_channel( + payload.channel_id + ) + + # See if board message is already present + for fire_message in self.fire_messages: + if fire_message[1] == payload.message_id: + async with self.fireboard_pool.acquire() as sql: + try: + # Fetch fireboard channel + try: + channel: discord.TextChannel = ( + await guild.fetch_channel(channel_id) + ) + except discord.errors.NotFound: + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", + (payload.guild_id,), + ) + await sql.commit() + + return + + # Delete message + board_message = await channel.fetch_message( + fire_message[2] + ) + await board_message.delete() + + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (payload.message_id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + except discord.errors.NotFound: + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (payload.message_id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + else: + return + except Exception as e: + raise e + finally: + self.locked_messages.remove(payload.message_id) + + # Listen for message being deleted + @commands.Cog.listener() + async def on_raw_message_delete(self, payload: discord.RawMessageDeleteEvent): + self.bot: discord.ext.commands.Bot + + # Stop if this is a DM + if payload.guild_id is None: + return + + # Lock system + if payload.message_id in self.locked_messages: + while payload.message_id in self.locked_messages: + await asyncio.sleep(0.5) + + self.locked_messages.append(payload.message_id) + + try: + # Only trigger if message is already in the fireboard DB + if payload.message_id in [message[1] for message in self.fire_messages]: + # Fetch server config + for server in self.fire_settings: + if server[0] == payload.guild_id: + channel_id = server[3] + + # Fetch server + try: + guild: discord.Guild = await self.bot.fetch_guild(payload.guild_id) + except discord.errors.NotFound: + return + + # Get message channel + channel: discord.abc.GuildChannel = await guild.fetch_channel( + payload.channel_id + ) + + # See if board message is already present + for fire_message in self.fire_messages: + if fire_message[1] == payload.message_id: + async with self.fireboard_pool.acquire() as sql: + try: + # Fetch fireboard channel + try: + channel: discord.TextChannel = ( + await guild.fetch_channel(channel_id) + ) + except discord.errors.NotFound: + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", + (payload.guild_id,), + ) + await sql.commit() + + return + + # Delete message + board_message = await channel.fetch_message( + fire_message[2] + ) + await board_message.delete() + + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (payload.message_id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + except discord.errors.NotFound: + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (payload.message_id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + else: + return + except Exception as e: + raise e + finally: + self.locked_messages.remove(payload.message_id) + + # Listen for message being edited + @commands.Cog.listener() + async def on_raw_message_edit(self, payload: discord.RawMessageUpdateEvent): + self.bot: discord.ext.commands.Bot + + # Stop if this is a DM + if payload.guild_id is None: + return + + # Lock system + if payload.message_id in self.locked_messages: + while payload.message_id in self.locked_messages: + await asyncio.sleep(0.5) + + self.locked_messages.append(payload.message_id) + + try: + # Only trigger if message is already in the fireboard DB + if payload.message_id in [message[1] for message in self.fire_messages]: + # Fetch server config + for server in self.fire_settings: + if server[0] == payload.guild_id: + channel_id = server[3] + + # Fetch server + try: + guild: discord.Guild = await self.bot.fetch_guild(payload.guild_id) + except discord.errors.NotFound: + return + + # Get message channel + channel: discord.abc.GuildChannel = await guild.fetch_channel( + payload.channel_id + ) + + # Get our message + message: discord.Message = await channel.fetch_message( + payload.message_id + ) + + embed = discord.Embed(description=message.content, color=Color.random()) + embed.set_author( + name=message.author.name, icon_url=message.author.display_avatar.url + ) + embed.timestamp = message.created_at + + # Jump to message button + view = View() + view.add_item( + discord.ui.Button( + label="Jump to Message", + url=message.jump_url, + style=discord.ButtonStyle.url, + ) + ) + + embed_list = [embed] + + # Add reply embed + if message.reference: + try: + reply_message = await channel.fetch_message( + message.reference.message_id + ) + + reply_embed = discord.Embed( + title="Replying To", + description=reply_message.content, + color=Color.random(), + ) + reply_embed.set_author( + name=reply_message.author.name, + icon_url=reply_message.author.display_avatar.url, + ) + reply_embed.timestamp = reply_message.created_at + + embed_list.insert(0, reply_embed) + except discord.errors.NotFound: + pass + + try: + channel: discord.TextChannel = await guild.fetch_channel(channel_id) + except discord.errors.NotFound: + async with self.fireboard_pool.acquire() as sql: + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", + (payload.guild_id,), + ) + await sql.commit() + + return + + # Find previous fireboard message + try: + for fire_message in self.fire_messages: + if ( + fire_message[0] == payload.guild_id + and fire_message[1] == payload.message_id + ): + # Edit with updated embed - reaction amount stays the same + board_message = await channel.fetch_message(fire_message[2]) + + await board_message.edit( + embeds=embed_list, attachments=message.attachments + ) + except discord.errors.NotFound: # Message not found + async with self.fireboard_pool.acquire() as sql: + # Delete message from DB + await sql.execute( + "DELETE FROM fireMessages WHERE msgID = ?", + (payload.message_id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + else: + return + except Exception as e: + raise e + finally: + self.locked_messages.remove(payload.message_id) + + # Listen for fireboard channel delete + @commands.Cog.listener() + async def on_guild_channel_delete(self, channel: discord.abc.GuildChannel): + # Only trigger if server has fireboard enabled + if channel.guild.id in [guild[0] for guild in self.fire_settings]: + for server in self.fire_settings: + if server[0] == channel.guild.id: + if server[3] == channel.id: + async with self.fireboard_pool.acquire() as sql: + # Delete fireboard config + await sql.execute( + "DELETE FROM fireMessages WHERE serverID = ?", + (channel.guild.id,), + ) + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", + (channel.guild.id,), + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + else: + return + + # Listen for server being left / deleted + @commands.Cog.listener() + async def on_guild_remove(self, guild: discord.Guild): + # Only trigger if server has fireboard enabled + if guild.id in [guild[0] for guild in self.fire_settings]: + for server in self.fire_settings: + if server[0] == guild.id: + async with self.fireboard_pool.acquire() as sql: + # Delete fireboard config + await sql.execute( + "DELETE FROM fireMessages WHERE serverID = ?", (guild.id,) + ) + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", (guild.id,) + ) + await sql.commit() + + await self.refresh_fire_lists() + + return + else: + return + + # Command group setup + context = discord.app_commands.AppCommandContext( + guild=True, dm_channel=False, private_channel=False + ) + installs = discord.app_commands.AppInstallationType(guild=True, user=False) + fireGroup = app_commands.Group( + name="fireboard", + description="Fireboard related commands.", + allowed_contexts=context, + allowed_installs=installs, + ) + + # Random fireboard message command + @fireGroup.command( + name="random", description="Get a random message from the fireboard." + ) + @app_commands.describe( + ephemeral="Optional: whether to send the command output as a dismissible message only visible to you. Defaults to false." + ) + async def random_fireboard( + self, interaction: discord.Interaction, ephemeral: bool = False + ): + await interaction.response.defer(ephemeral=ephemeral) + + channel_id = None + + # Find server config + for server in self.fire_settings: + if server[0] == interaction.guild_id: + channel_id = server[3] + + if channel_id is None: + embed = discord.Embed( + title="Error", + description="Fireboard is not enabled in this server.", + color=Color.red(), + ) + await interaction.followup.send(embed=embed, ephemeral=ephemeral) + + return + + # Fetch channel + try: + channel = await interaction.guild.fetch_channel(channel_id) + except discord.errors.NotFound: + embed = discord.Embed( + title="Error", + description="Can't find the fireboard channel. Please contact a server admin.", + color=Color.red(), + ) + await interaction.followup.send(embed=embed, ephemeral=ephemeral) + + return + + # Fetch messages + async with self.fireboard_pool.acquire() as sql: + messages = await sql.fetchall( + "SELECT * FROM fireMessages WHERE serverID = ?", (interaction.guild_id,) + ) + + if not messages: + embed = discord.Embed( + title="Error", + description="No messages found in the fireboard.", + color=Color.red(), + ) + await interaction.followup.send(embed=embed, ephemeral=ephemeral) + + return + else: + while messages != []: + message = random.choice(messages) + + try: + board_message = await channel.fetch_message(message[2]) + + view = View().from_message(board_message) + files = [ + await attachment.to_file() + for attachment in board_message.attachments + ] + + await interaction.followup.send( + content=board_message.content, + embeds=board_message.embeds, + view=view, + ephemeral=ephemeral, + files=files, + allowed_mentions=discord.AllowedMentions.none(), + ) + + return + except discord.errors.NotFound: + messages.remove(message) + + embed = discord.Embed( + title="Error", + description="No messages found in the fireboard.", + color=Color.red(), + ) + await interaction.followup.send(embed=embed, ephemeral=ephemeral) + + # Command group setup + context = discord.app_commands.AppCommandContext( + guild=True, dm_channel=False, private_channel=False + ) + installs = discord.app_commands.AppInstallationType(guild=True, user=False) + perms = discord.Permissions(manage_guild=True) + fireSetupGroup = app_commands.Group( + name="fireboard-setup", + description="Control the fireboard.", + allowed_contexts=context, + allowed_installs=installs, + default_permissions=perms, + ) + + # Fireboard enable command + @fireSetupGroup.command( + name="enable", description="Enable the fireboard in the current channel." + ) + async def enable_fireboard(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild.id in [guild[0] for guild in self.fire_settings]: + embed = discord.Embed( + title="Fireboard is already enabled.", color=Color.green() + ) + await interaction.followup.send(embed=embed, ephemeral=True) + else: + # Default settings + react_minimum = 3 + emoji = "๐Ÿ”ฅ" + channel_id = interaction.channel_id + ignore_bots = True + + embed = discord.Embed( + title="Fireboard", + description="This channel has been configured as the server fireboard.", + color=Color.random(), + ) + embed.set_footer(text="Feel free to delete this message!") + + try: + channel = await interaction.guild.fetch_channel(channel_id) + await channel.send(embed=embed) + except discord.errors.Forbidden or discord.errors.NotFound: + embed = discord.Embed( + title="Error", + description="Looks like I can't send messages in this channel. Check permissions and try again.", + color=Color.random(), + ) + await interaction.followup.send(embed=embed, ephemeral=True) + + return + + async with self.fireboard_pool.acquire() as sql: + # Insert to DB, refresh lists + await sql.execute( + "INSERT INTO fireSettings (serverID, reactionAmount, emoji, channelID, ignoreBots) VALUES (?, ?, ?, ?, ?)", + ( + interaction.guild_id, + react_minimum, + emoji, + channel_id, + ignore_bots, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + + embed = discord.Embed( + title="Enabled", + description="Fireboard has been enabled in the current channel.", + color=Color.green(), + ) + embed.add_field( + name="Info", + value=f"**Reaction Requirement:** `{react_minimum} reactions`\n**Fireboard Channel:** <#{channel_id}>\n**Emoji:** {emoji}\n**Ignore Bots:** `{ignore_bots}`", + ) + + await interaction.followup.send(embed=embed, ephemeral=True) + + class ConfirmDisableView(View): + def __init__(self): + super().__init__(timeout=60) + + async def disable_fireboard( + self, interaction: discord.Interaction, pool: asqlite.Pool + ): + async with pool.acquire() as sql: + try: + await sql.execute( + "DELETE FROM fireMessages WHERE serverID = ?", + (interaction.guild_id,), + ) + await sql.execute( + "DELETE FROM fireSettings WHERE serverID = ?", + (interaction.guild_id,), + ) + await sql.execute( + "DELETE FROM fireChannelBlacklist WHERE serverID = ?", + (interaction.guild_id,), + ) + await sql.execute( + "DELETE FROM fireRoleBlacklist WHERE serverID = ?", + (interaction.guild_id,), + ) + await sql.commit() + return True + except Exception: + return False + + @discord.ui.button(label="Disable", style=discord.ButtonStyle.red) + async def confirm( + self, interaction: discord.Interaction, button: discord.ui.Button + ): + await interaction.response.defer(ephemeral=True) + + success = await self.disable_fireboard(interaction, self.pool) + + if success: + embed = discord.Embed( + title="Done!", + description="Fireboard was disabled.", + color=Color.green(), + ) + await self.cog.refresh_fire_lists() # pylint: disable=no-member + else: + embed = discord.Embed( + title="Error", + description="Failed to disable fireboard.", + color=Color.red(), + ) + + await interaction.edit_original_response(embed=embed, view=None) + self.stop() + + async def on_timeout(self): + for item in self.children: + item.disabled = True + + embed = discord.Embed( + title="Timeout", + description="You didn't press the button in time.", + color=Color.red(), + ) + await self.message.edit(embed=embed, view=self) + + # Fireboard disable command + @fireSetupGroup.command(name="disable", description="Disable the server fireboard.") + async def disable_fireboard(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + + if interaction.guild_id in [guild[0] for guild in self.fire_settings]: + view = self.ConfirmDisableView() + view.pool = self.fireboard_pool + view.cog = self + + embed = discord.Embed( + title="Are you sure?", + description="All data about this server's fireboard will be deleted. This cannot be undone!", + color=Color.orange(), + ) + + message = await interaction.followup.send( + embed=embed, view=view, ephemeral=True, wait=True + ) + view.message = message + else: + await interaction.followup.send( + "Fireboard is not enabled in this server!", ephemeral=True + ) + + # Fireboard server info command + @fireSetupGroup.command( + name="info", description="View fireboard config for this server." + ) + async def fireboard_info(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild.id in [guild[0] for guild in self.fire_settings]: + # Fetch server settings + for server in self.fire_settings: + if server[0] == interaction.guild_id: + react_minimum = server[1] + emoji = server[2] + channel_id = server[3] + ignore_bots = True if int(server[4]) == 1 else False + + embed = discord.Embed( + title="Server Fireboard Settings", + description=f"**Reaction Requirement:** `{react_minimum} reactions`\n**Fireboard Channel:** <#{channel_id}>\n**Emoji:** {emoji}\n**Ignore Bots:** `{ignore_bots}`", + color=Color.random(), + ) + + await interaction.followup.send(embed=embed, ephemeral=True) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + # Fireboard set emoji command + @fireSetupGroup.command(name="emoji", description="Set a custom fireboard emoji.") + async def fireboard_emoji(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=False) + + # Check fireboard status + if interaction.guild.id in [guild[0] for guild in self.fire_settings]: + embed = discord.Embed( + title="Waiting for Reaction", + description="๐Ÿ”„ React with this message with your target emoji to set the fireboard emoji.", + color=Color.orange(), + ) + + msg = await interaction.followup.send(embed=embed, ephemeral=False) + + def check(reaction, user): + return user == interaction.user and reaction.message.id == msg.id + + # Wait for a reaction + try: + reaction, user = await self.bot.wait_for( + "reaction_add", timeout=60.0, check=check + ) + + reaction: discord.Reaction = reaction + + async with self.fireboard_pool.acquire() as sql: + # Change emoji in DB, refresh lists + await sql.execute( + "UPDATE fireSettings SET emoji = ? WHERE serverID = ?", + ( + str(reaction.emoji), + interaction.guild_id, + ), + ) + await sql.commit() + + embed = discord.Embed( + title="Emoji Set", + description=f"Set emoji to **{str(reaction.emoji)}.**", + color=Color.green(), + ) + + await self.refresh_fire_lists() + await interaction.edit_original_response(embed=embed) + except asyncio.TimeoutError: # Timed out + embed = discord.Embed( + title="Timed Out", + description="You didn't react in time.", + color=Color.red(), + ) + + await interaction.edit_original_response(embed=embed) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=False) + + # Fireboard set channel command + @fireSetupGroup.command( + name="channel", + description="Set the channel for fireboard messages to be sent in.", + ) + async def fireboard_channel( + self, interaction: discord.Interaction, channel: discord.TextChannel + ): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild.id in [guild[0] for guild in self.fire_settings]: + embed = discord.Embed( + title="Fireboard", + description="This channel has been configured as the server fireboard.", + color=Color.random(), + ) + embed.set_footer(text="Feel free to delete this message!") + + try: + await channel.send(embed=embed) + except discord.errors.NotFound: + embed = discord.Embed( + title="Error", + description="Looks like I can't find that channel. Check permissions and try again.", + color=Color.random(), + ) + await interaction.followup.send(embed=embed, ephemeral=True) + + return + except discord.errors.Forbidden as e: + embed = discord.Embed( + title="Error", + description="Looks like I can't send messages in that channel. Check permissions and try again.", + color=Color.red(), + ) + await interaction.followup.send(embed=embed, ephemeral=True) + + return + + async with self.fireboard_pool.acquire() as sql: + # Update channel in DB, refresh lists + await sql.execute( + "UPDATE fireSettings SET channelID = ? WHERE serverID = ?", + ( + channel.id, + interaction.guild_id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + + embed = discord.Embed( + title="Channel Set", + description=f"Fireboard channel has been set to **{channel.mention}.**", + color=Color.green(), + ) + await interaction.followup.send(embed=embed, ephemeral=True) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + # Fireboard set requirement command + @fireSetupGroup.command( + name="requirement", + description="Set required reaction amount for message to be posted on the fireboard.", + ) + async def fireboard_requirement( + self, interaction: discord.Interaction, amount: int + ): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild.id in [guild[0] for guild in self.fire_settings]: + embed = discord.Embed( + title="Set", + description=f"Reaction requirement has been set to **{amount} reactions.**", + color=Color.green(), + ) + + async with self.fireboard_pool.acquire() as sql: + # Update reaction requirement in DB, refresh lists + await sql.execute( + "UPDATE fireSettings SET reactionAmount = ? WHERE serverID = ?", + ( + amount, + interaction.guild_id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + await interaction.followup.send(embed=embed, ephemeral=True) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + # Fireboard ignore bots command + @fireSetupGroup.command( + name="ignore-bots", + description="Whether bot messages are ignored in the fireboard. Defaults to true.", + ) + async def fireboard_ignore_bots( + self, interaction: discord.Interaction, value: bool + ): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild.id in [guild[0] for guild in self.fire_settings]: + embed = discord.Embed( + title="Set", + description=f"Bot messages will **{'be ignored.' if value else 'not be ignored.'}**", + color=Color.green(), + ) + + async with self.fireboard_pool.acquire() as sql: + # Update setting in DB, refresh lists + await sql.execute( + "UPDATE fireSettings SET ignoreBots = ? WHERE serverID = ?", + ( + value, + interaction.guild_id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + await interaction.followup.send(embed=embed, ephemeral=True) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + # Fireboard role blacklist + @fireSetupGroup.command( + name="channel-blacklist", + description="Toggle the blacklist for a channel. NSFW channels are always blacklisted.", + ) + async def fireboard_channel_blacklist( + self, interaction: discord.Interaction, channel: discord.abc.GuildChannel + ): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild_id in [guild[0] for guild in self.fire_settings]: + async with self.fireboard_pool.acquire() as sql: + if channel.id in [ + channelEntry[1] for channelEntry in self.fire_channel_blacklist + ]: + await sql.execute( + "DELETE FROM fireChannelBlacklist WHERE serverID = ? AND channelID = ?", + ( + interaction.guild_id, + channel.id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + + embed = discord.Embed( + title="Set", + description=f"Removed {channel.mention} from the channel blacklist.", + ) + await interaction.followup.send(embed=embed, ephemeral=True) + else: + await sql.execute( + "INSERT INTO fireChannelBlacklist (serverID, channelID) VALUES (?, ?)", + ( + interaction.guild_id, + channel.id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + + embed = discord.Embed( + title="Set", + description=f"Added {channel.mention} to the channel blacklist.", + ) + await interaction.followup.send(embed=embed, ephemeral=True) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + # Fireboard role blacklist + @fireSetupGroup.command( + name="role-blacklist", description="Toggle the blacklist for a role." + ) + async def fireboard_role_blacklist( + self, interaction: discord.Interaction, role: discord.Role + ): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild_id in [guild[0] for guild in self.fire_settings]: + async with self.fireboard_pool.acquire() as sql: + if role.id in [roleEntry[1] for roleEntry in self.fire_role_blacklist]: + await sql.execute( + "DELETE FROM fireRoleBlacklist WHERE serverID = ? AND roleID = ?", + ( + interaction.guild_id, + role.id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + + embed = discord.Embed( + title="Set", + description=f"Removed {role.mention} from the role blacklist.", + ) + await interaction.followup.send(embed=embed, ephemeral=True) + else: + await sql.execute( + "INSERT INTO fireRoleBlacklist (serverID, roleID) VALUES (?, ?)", + ( + interaction.guild_id, + role.id, + ), + ) + await sql.commit() + + await self.refresh_fire_lists() + + embed = discord.Embed( + title="Set", + description=f"Added {role.mention} to the role blacklist.", + ) + await interaction.followup.send(embed=embed, ephemeral=True) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + # Fireboard role blacklist + @fireSetupGroup.command( + name="blacklists", description="View this server's role and channel blacklists." + ) + async def fireboard_blacklists(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + + # Check fireboard status + if interaction.guild_id in [guild[0] for guild in self.fire_settings]: + + class BlacklistViewer(View): + def __init__(self): + super().__init__(timeout=240) + + self.fire_channel_blacklist: list + self.fire_role_blacklist: list + self.interaction: discord.Interaction + + async def on_timeout(self) -> None: + for item in self.children: + item.disabled = True + + await self.interaction.edit_original_response(view=self) + + @discord.ui.button( + label="Role Blacklist", + style=discord.ButtonStyle.gray, + row=0, + custom_id="role", + disabled=True, + ) + async def role( + self, interaction: discord.Interaction, button: discord.ui.Button + ): + await interaction.response.defer(ephemeral=True) + + for item in self.children: + if item.custom_id == "channel": + item.disabled = False + else: + item.disabled = True + + my_roles = [] + + for role in self.fire_role_blacklist: + if role[0] == interaction.guild_id: + my_roles.append(f"<@&{role[1]}>") + + if my_roles != []: + embed = discord.Embed( + title="Role Blacklist", + description="\n".join(my_roles), + color=Color.random(), + ) + await interaction.edit_original_response(embed=embed, view=self) + else: + embed = discord.Embed( + title="Role Blacklist", + description="No roles have been blacklisted.", + color=Color.random(), + ) + await interaction.edit_original_response(embed=embed, view=self) + + @discord.ui.button( + label="Channel Blacklist", + style=discord.ButtonStyle.gray, + row=0, + custom_id="channel", + ) + async def channel( + self, interaction: discord.Interaction, button: discord.ui.Button + ): + await interaction.response.defer(ephemeral=True) + + for item in self.children: + if item.custom_id == "role": + item.disabled = False + else: + item.disabled = True + + my_channels = [] + + for channel in self.fire_channel_blacklist: + if channel[0] == interaction.guild_id: + my_channels.append(f"<#{channel[1]}>") + + if my_channels != []: + embed = discord.Embed( + title="Channel Blacklist", + description="\n".join(my_channels), + color=Color.random(), + ) + await interaction.edit_original_response(embed=embed, view=self) + else: + embed = discord.Embed( + title="Channel Blacklist", + description="No channels have been blacklisted.", + color=Color.random(), + ) + await interaction.edit_original_response(embed=embed, view=self) + + view_instance = BlacklistViewer() + view_instance.fire_channel_blacklist = self.fire_channel_blacklist + view_instance.fire_role_blacklist = self.fire_role_blacklist + view_instance.interaction = interaction + + my_roles = [] + + for role in self.fire_role_blacklist: + if role[0] == interaction.guild_id: + my_roles.append(f"<@&{role[1]}>") + + if my_roles != []: + embed = discord.Embed( + title="Role Blacklist", + description="\n".join(my_roles), + color=Color.random(), + ) + await interaction.followup.send( + embed=embed, view=view_instance, ephemeral=True + ) + else: + embed = discord.Embed( + title="Role Blacklist", + description="No roles have been blacklisted.", + color=Color.random(), + ) + await interaction.followup.send( + embed=embed, view=view_instance, ephemeral=True + ) + else: + embed = discord.Embed(title="Fireboard is not enabled.", color=Color.red()) + + await interaction.followup.send(embed=embed, ephemeral=True) + + +async def setup(bot):import asyncio +import random +import json +import os + +import discord +from discord import Color, app_commands +from discord.ext import commands +from discord.ui import View + +FIREBOARD_PATH = "assets/cogs/files/fireboard.json" + +def load_data(): + if not os.path.exists(FIREBOARD_PATH): + return {} + with open(FIREBOARD_PATH, "r") as f: + return json.load(f) + +def save_data(data): + os.makedirs(os.path.dirname(FIREBOARD_PATH), exist_ok=True) + with open(FIREBOARD_PATH, "w") as f: + json.dump(data, f, indent=2) + +class Fireboard(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.data = load_data() + self.locked_messages = [] + + def save(self): + save_data(self.data) + + def get_guild(self, guild_id): + return self.data.setdefault(str(guild_id), { + "settings": None, + "messages": [], + "role_blacklist": [], + "channel_blacklist": [] + }) + + @commands.Cog.listener() + async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): + if payload.guild_id is None: + return + guild_data = self.get_guild(payload.guild_id) + settings = guild_data["settings"] + if not settings: + return + react_minimum = settings["reactionAmount"] + emoji = settings["emoji"] + channel_id = settings["channelID"] + ignore_bots = settings["ignoreBots"] + + if str(payload.emoji) != emoji: + return + if payload.channel_id in guild_data["channel_blacklist"]: + return + if payload.message_id in self.locked_messages: + return + self.locked_messages.append(payload.message_id) + try: + channel = await self.bot.fetch_channel(payload.channel_id) + message = await channel.fetch_message(payload.message_id) + if ignore_bots and message.author.bot: + return + if hasattr(message.channel, "nsfw") and message.channel.nsfw: + return + react_count = 0 + for reaction in message.reactions: + if str(reaction.emoji) == emoji: + react_count = reaction.count + break + if react_count < react_minimum: + return + # Already on fireboard? + for m in guild_data["messages"]: + if m["msgID"] == payload.message_id: + return + # Send to fireboard + board_channel = await self.bot.fetch_channel(channel_id) + embed = discord.Embed(description=message.content, color=Color.random()) + embed.set_author(name=message.author.name, icon_url=message.author.display_avatar.url) + embed.timestamp = message.created_at + view = View() + view.add_item(discord.ui.Button(label="Jump to Message", url=message.jump_url, style=discord.ButtonStyle.url)) + files = [await a.to_file() for a in message.attachments] + board_message = await board_channel.send( + content=f"**{react_count} {emoji}** | {message.author.mention} | <#{payload.channel_id}>", + embed=embed, view=view, files=files + ) + guild_data["messages"].append({ + "msgID": payload.message_id, + "boardMsgID": board_message.id, + "reactionAmount": react_count + }) + self.save() + finally: + if payload.message_id in self.locked_messages: + self.locked_messages.remove(payload.message_id) + + @commands.Cog.listener() + async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent): + if payload.guild_id is None: + return + guild_data = self.get_guild(payload.guild_id) + settings = guild_data["settings"] + if not settings: + return + emoji = settings["emoji"] + channel_id = settings["channelID"] + if str(payload.emoji) != emoji: + return + for m in guild_data["messages"]: + if m["msgID"] == payload.message_id: + channel = await self.bot.fetch_channel(channel_id) + try: + board_message = await channel.fetch_message(m["boardMsgID"]) + await board_message.delete() + except Exception: + pass + guild_data["messages"].remove(m) + self.save() + break + + @app_commands.command(name="fireboard_enable", description="Enable the fireboard in this channel.") + async def fireboard_enable(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + guild_data = self.get_guild(interaction.guild_id) + if guild_data["settings"]: + await interaction.followup.send("Fireboard is already enabled.", ephemeral=True) + return + guild_data["settings"] = { + "reactionAmount": 3, + "emoji": "๐Ÿ”ฅ", + "channelID": interaction.channel_id, + "ignoreBots": True + } + self.save() + await interaction.followup.send("Fireboard enabled in this channel.", ephemeral=True) + + @app_commands.command(name="fireboard_disable", description="Disable the fireboard.") + async def fireboard_disable(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + guild_data = self.get_guild(interaction.guild_id) + guild_data["settings"] = None + guild_data["messages"] = [] + self.save() + await interaction.followup.send("Fireboard disabled.", ephemeral=True) + + @app_commands.command(name="fireboard_info", description="Show fireboard settings.") + async def fireboard_info(self, interaction: discord.Interaction): + await interaction.response.defer(ephemeral=True) + guild_data = self.get_guild(interaction.guild_id) + settings = guild_data["settings"] + if not settings: + await interaction.followup.send("Fireboard is not enabled.", ephemeral=True) + return + embed = discord.Embed( + title="Fireboard Settings", + description=f"**Reaction Requirement:** `{settings['reactionAmount']}`\n" + f"**Fireboard Channel:** <#{settings['channelID']}>\n" + f"**Emoji:** {settings['emoji']}\n" + f"**Ignore Bots:** `{settings['ignoreBots']}`", + color=Color.random() + ) + await interaction.followup.send(embed=embed, ephemeral=True) + +async def setup(bot): + await bot.add_cog(Fireboard(bot)) \ No newline at end of file diff --git a/assets/locales/en.json b/assets/locales/en.json index cca8867..238e172 100644 --- a/assets/locales/en.json +++ b/assets/locales/en.json @@ -1,4 +1,5 @@ { + "psutil_not_installed": "Memory check skipped.", "not_cloned": "Goober is not cloned! Please clone it from GitHub.", "checks_disabled": "Checks are disabled!", "unhandled_exception": "An unhandled exception occurred. Please report this issue on GitHub.", diff --git a/assets/locales/it.json b/assets/locales/it.json index ebf28aa..54d1071 100644 --- a/assets/locales/it.json +++ b/assets/locales/it.json @@ -1,4 +1,5 @@ { + "psutil_not_installed": "Controllo memoria saltato.", "not_cloned": "Goober non รจ stato clonato! Clonalo da GitHub.", "checks_disabled": "I controlli sono disabilitati!", "unhandled_exception": "Si รจ verificata un'eccezione non gestita. Segnala questo problema su GitHub, per favore.", diff --git a/bot.py b/bot.py index 7c2050c..015f9f3 100644 --- a/bot.py +++ b/bot.py @@ -473,7 +473,7 @@ async def stats(ctx: commands.Context) -> None: embed: discord.Embed = discord.Embed(title=f"{(_('command_stats_embed_title'))}", description=f"{(_('command_stats_embed_desc'))}", color=Colour(0x000000)) embed.add_field(name=f"{(_('command_stats_embed_field1name'))}", value=f"{(_('command_stats_embed_field1value')).format(file_size=file_size, line_count=line_count)}", inline=False) embed.add_field(name=f"{(_('command_stats_embed_field2name'))}", value=f"{(_('command_stats_embed_field2value')).format(local_version=local_version, latest_version=latest_version)}", inline=False) - embed.add_field(name=f"{(_('command_stats_embed_field3name'))}", value=f"{(_('command_stats_embed_field3value')).format(NAME=NAME, PREFIX=PREFIX, ownerid=ownerid, cooldown_time=cooldown_time, PING_LINE=PING_LINE, showmemenabled=showmemenabled, USERTRAIN_ENABLED=USERTRAIN_ENABLED, song=song, splashtext=splashtext)}", inline=False) + embed.add_field(name=f"{(_('command_stats_embed_field3name'))}", value=f"{(_('command_stats_embed_field3value')).format(NAME=NAME, PREFIX=PREFIX, ownerid=ownerid, PING_LINE=PING_LINE, showmemenabled=showmemenabled, USERTRAIN_ENABLED=USERTRAIN_ENABLED, song=song, splashtext=splashtext)}", inline=False) await send_message(ctx, embed=embed) diff --git a/modules/globalvars.py b/modules/globalvars.py index 7dd1c8a..998267b 100644 --- a/modules/globalvars.py +++ b/modules/globalvars.py @@ -37,7 +37,7 @@ arch = platform.machine() slash_commands_enabled = True # 100% broken, its a newer enough version so its probably enabled by default.... fix this at somepoint or hard code it in goober central code launched = False latest_version = "0.0.0" -local_version = "2.0.2" +local_version = "2.1.2" os.environ['gooberlocal_version'] = local_version REACT = os.getenv("REACT") beta = False # this makes goober think its a beta version, so it will not update to the latest stable version or run any version checks