transferring everything over here
This commit is contained in:
parent
6253bfaceb
commit
ae936e67f6
7 changed files with 667 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
galaxy/slashtag arguments.txt
|
5
galaxy/__init__.py
Normal file
5
galaxy/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from .galaxy import Galaxy
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Galaxy(bot))
|
134
galaxy/galaxy.py
Normal file
134
galaxy/galaxy.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
from redbot.core import commands, checks
|
||||
import discord
|
||||
|
||||
class Galaxy(commands.Cog):
|
||||
"""Custom cog intended for use on the Galaxy discord server."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
async def faq(self, ctx):
|
||||
"""Posts answers to frequently asked questions."""
|
||||
|
||||
@commands.guild_only()
|
||||
@faq.command(name="test")
|
||||
@checks.admin()
|
||||
async def faq_test(self, ctx, member: discord.Member = None):
|
||||
"""Testing FAQ"""
|
||||
embed=discord.Embed(title="Test Embed", color=await self.bot.get_embed_color(None), description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer in faucibus odio, at mollis metus.")
|
||||
embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url_as(format="png", size=512))
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@commands.guild_only()
|
||||
@faq.command(name="dps")
|
||||
async def faq_dps(self, ctx, member: discord.Member = None):
|
||||
"""DPS Calculations/Inaccuracy"""
|
||||
embed=discord.Embed(title="DPS Calculations", color=await self.bot.get_embed_color(None), description="The ``/info`` command (and by extention ``/shipinfo`` from Odin) misreports DPS, due to it calculating DPS disregarding the turret's type (kinetic, laser), causing it to assume the target ship is both hulled and has shield simultaneously. It also ignores turret overrides, custom reloads, and custom damage values. If you'd like to check ship stats accurately, you can either use the ``/ship`` command in this channel or you can use the [Galaxy Info Website](https://galaxy.wingysam.xyz/ships). Alternatively, to check turret stats, you can use the [Galaxy Info Turrets Page](https://galaxy.wingysam.xyz/turrets).")
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@faq.command(name="links")
|
||||
async def faq_links(self, ctx, member: discord.Member = None):
|
||||
"""Posts important links, primarily invite links."""
|
||||
embed=discord.Embed(title="Important Links", color=await self.bot.get_embed_color(None))
|
||||
embed.add_field(name="Galaxy", value="[Galaxy Discord](https://discord.com/invite/robloxgalaxy)\n[Galaxy Support](https://discord.com/invite/ShWshkhYhZ)")
|
||||
embed.add_field(name="Galaxypedia", value="[Galaxypedia Website](https://robloxgalaxy.wiki/wiki/Main_Page)\n[Galaxypedia Discord](https://discord.robloxgalaxy.wiki/)")
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@commands.guild_only()
|
||||
@faq.command(name="ropro")
|
||||
async def faq_ropro(self, ctx, member: discord.Member = None):
|
||||
"""Posts a link to RoPro"""
|
||||
embed=discord.Embed(title="RoPro", url="https://ropro.io", color=await self.bot.get_embed_color(None), description="""[RoPro](https://ropro.io) is a browser extension that tracks ROBLOX playtime, enhances your profile, and provides other useful utilities. **Please keep in mind that RoPro only tracks playtime from AFTER you install the extension.**""")
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@commands.guild_only()
|
||||
@faq.command(name="polaris_ranks")
|
||||
async def faq_polaris_ranks(self, ctx, member: discord.Member = None):
|
||||
"""Lists required levels for certain roles."""
|
||||
embed=discord.Embed(title="Polaris Ranks", color=await self.bot.get_embed_color(None))
|
||||
embed.add_field(name="Picture Perms", value="Level 7", inline=False)
|
||||
embed.add_field(name="Suggestions", value="Level 9", inline=False)
|
||||
embed.add_field(name="DJ", value="Level 11", inline=False)
|
||||
embed.add_field(name="Reaction Perms", value="Level 30", inline=False)
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@commands.guild_only()
|
||||
@faq.command(name="polaris_switch")
|
||||
@checks.admin()
|
||||
async def faq_polaris_switch(self, ctx, member: discord.Member = None):
|
||||
"""Posts an embed on the switch to the Polaris bot."""
|
||||
embed=discord.Embed(title="Polaris FAQ", color=await self.bot.get_embed_color(None), description="As you probably know, we've decided to switch to the Polaris bot for leveling/xp, as opposed to Tatsu.\nThere are many reasons for this, which will be explained below.")
|
||||
embed.add_field(name="Problems with Tatsu", value="1: Tatsu does not provide nearly as much configuration potential as Polaris does. An example of this is Polaris' customizable Level Curve.\n\n2: Tatsu does not have channel/role modifiers.\n\n3: Tatsu does not have actual levels, instead it has unconfigurable \"Global XP\", which gives \"Global Levels\". You cannot do anything with Global XP aside from blacklisting channels where people can gain it, like a bot-commands channel or something like that.\n\n4: Tatsu's leaderboard sucks, and only shows the top 10 on the web version.\n\n5: Tatsu has no XP management commands.\n\n6: Tatsu has TONS of bloat/useless commands, making the bot harder to configure.", inline=False)
|
||||
embed.add_field(name="Polaris' Features", value="1: Polaris allows you to customize the level curve of your server, and provides presets to make the transition easier.\n\n2: Polaris has XP management commands.\n\n3: Polaris has way more configuration in terms of Reward Roles.\n\n4: Polaris allows you to customize the level-up message shown whenever people achieve the next level.\n\n5: Polaris has both role and channel modifiers.\n\n6: Polaris' leaderboard is excellent, showing the top 1,000 ranked users on the same webpage, and allowing you to see your own stats, progress towards your next reward role, and all 350 levels and your progress towards them.\n\n7: Polaris is **just** a leveling bot. You don't have to deal with any of the bloat of multi-purpose bots like Tatsu or MEE6, you only get what you actually need.", inline=False)
|
||||
embed.add_field(name="Conclusion",value="With all of that said, you're probably wondering why we're putting so much effort into transferring peoples' data to the new bot.\n\nWell, Tatsu has been going since 2020, and I don't particularly favor the idea of clearing everyone's XP, especially when people have built up reward roles from Tatsu already, like Picture Perms, Suggestions access, and DJ.\n\nWith all this in mind, I hope this isn't too much of an inconvenience for you all, as I tried to make the process as seamless as possible without having to update all 10,000 people in the server.", inline=False)
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@commands.guild_only()
|
||||
@faq.command(name="npc_intervals")
|
||||
async def faq_npc_intervals(self, ctx, member: discord.Member = None):
|
||||
"""Posts an embed containing NPC spawn intervals."""
|
||||
embed=discord.Embed(title="NPC Spawn Intervals", color=await self.bot.get_embed_color(None), description="*Disclaimer: Spawn times may be different if EventID is active!*")
|
||||
embed.add_field(name="Every 6.7 Minutes", value="[Dragoon](https://robloxgalaxy.wiki/wiki/Dragoon) *(80% Chance)*")
|
||||
embed.add_field(name="Every 8.4 Minutes", value="[Swarmer](https://robloxgalaxy.wiki/wiki/Swarmer) *(33% Chance)*")
|
||||
embed.add_field(name="Every 10 Minutes", value="[Jormungand](https://robloxgalaxy.wiki/wiki/Jormungand) *(75% Chance)*")
|
||||
embed.add_field(name="Every 12.5 Minutes", value="[Bruiser](https://robloxgalaxy.wiki/wiki/Bruiser) *(50% Chance)*")
|
||||
embed.add_field(name="Every 16.7 Minutes", value="[Outrider](https://robloxgalaxy.wiki/wiki/Outrider) *(50% Chance)*")
|
||||
embed.add_field(name="Every 28.5 Minutes", value="[Punisher](https://robloxgalaxy.wiki/wiki/Punisher)")
|
||||
embed.add_field(name="Every 60 Minutes", value="[X-0](https://robloxgalaxy.wiki/wiki/X-0) *(45% Chance)*\n[Decimator](https://robloxgalaxy.wiki/wiki/Decimator)")
|
||||
embed.add_field(name="Every 70 Minutes", value="[Galleon](https://robloxgalaxy.wiki/wiki/Galleon)")
|
||||
embed.add_field(name="Every 120 Minutes", value="[Kodiak](https://robloxgalaxy.wiki/wiki/Kodiak)")
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
@faq.command(name="linked_role")
|
||||
@commands.guild_only()
|
||||
async def faq_linked_role(self, ctx, member: discord.Member = None):
|
||||
"""Posts an embed containing FAQ about Linked Role. (WIP)"""
|
||||
embed=discord.Embed(title="WIP")
|
||||
if member:
|
||||
await ctx.send(embed=embed, content=member.mention)
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.message.delete()
|
||||
|
||||
|
||||
@faq_test.error
|
||||
@faq_linked_role.error
|
||||
@faq_npc_intervals.error
|
||||
@faq_links.error
|
||||
@faq_dps.error
|
||||
@faq_ropro.error
|
||||
@faq_polaris_ranks.error
|
||||
@faq_polaris_switch.error
|
||||
async def faq_handler(self, ctx, error):
|
||||
"""Error Handler for FAQ."""
|
||||
if isinstance(error, commands.CommandInvokeError):
|
||||
return
|
8
galaxy/info.json
Normal file
8
galaxy/info.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"author" : ["SeaswimmerTheFsh"],
|
||||
"install_msg" : "Galaxy installed!",
|
||||
"name" : "Galaxy",
|
||||
"short" : "Custom cog intended for use on the Galaxy discord server.",
|
||||
"description" : "Custom cog intended for use on the Galaxy discord server.",
|
||||
"end_user_data_statement" : "This cog does not store any End User Data."
|
||||
}
|
5
suggestions/__init__.py
Normal file
5
suggestions/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from .suggestions import Suggestions
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Suggestions(bot))
|
9
suggestions/info.json
Normal file
9
suggestions/info.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"author" : ["Galaxy Development Team"],
|
||||
"install_msg" : "Thank you for installing Suggestions!\nYou can find the source code of this cog here: https://github.com/SeaswimmerTheFsh/GalaxyCogs.\nYou can find the original source code from SauriCogs here: <https://github.com/elijabesu/SauriCogs>.",
|
||||
"name" : "Suggestions",
|
||||
"short" : "Simple suggestions system.",
|
||||
"description" : "Per guild suggestions system.",
|
||||
"tags" : ["suggestions, suggestion, voting"],
|
||||
"end_user_data_statement": "This cog stores user names, discriminators, and IDs upon sending a suggestion. This data is used solely to display and contact the user about any change to their suggestion."
|
||||
}
|
505
suggestions/suggestions.py
Normal file
505
suggestions/suggestions.py
Normal file
|
@ -0,0 +1,505 @@
|
|||
import discord
|
||||
import datetime
|
||||
import typing
|
||||
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.utils.chat_formatting import humanize_list
|
||||
|
||||
from redbot.core.bot import Red
|
||||
|
||||
|
||||
class Suggestions(commands.Cog):
|
||||
"""
|
||||
Per guild, as well as global, suggestion box voting system.
|
||||
"""
|
||||
|
||||
__version__ = "1.7.1"
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(
|
||||
self, identifier=2115656421364, force_registration=True
|
||||
)
|
||||
self.config.register_guild(
|
||||
same=False,
|
||||
suggest_id=None,
|
||||
approve_id=None,
|
||||
denied_id=None,
|
||||
next_id=1,
|
||||
up_emoji=1071095785455886436,
|
||||
down_emoji=1071096039119007804,
|
||||
delete_suggest=True,
|
||||
delete_suggestion=True,
|
||||
anonymous=False,
|
||||
)
|
||||
self.config.init_custom("SUGGESTION", 2) # server_id, suggestion_id
|
||||
self.config.register_custom(
|
||||
"SUGGESTION",
|
||||
author=[], # id, name, discriminator
|
||||
guild_id=0,
|
||||
msg_id=0,
|
||||
finished=False,
|
||||
approved=False,
|
||||
denied=False,
|
||||
reason=False,
|
||||
stext=None,
|
||||
rtext=None,
|
||||
)
|
||||
|
||||
async def red_delete_data_for_user(self, *, requester, user_id):
|
||||
# per guild suggestions
|
||||
for guild in self.bot.guilds:
|
||||
for suggestion_id in range(1, await self.config.guild(guild).next_id()):
|
||||
author_info = await self.config.custom(
|
||||
"SUGGESTION", guild.id, suggestion_id
|
||||
).author()
|
||||
if user_id in author_info:
|
||||
await self.config.custom(
|
||||
"SUGGESTION", guild.id, suggestion_id
|
||||
).author.clear()
|
||||
|
||||
def format_help_for_context(self, ctx: commands.Context) -> str:
|
||||
context = super().format_help_for_context(ctx)
|
||||
return f"{context}\n\nVersion: {self.__version__}"
|
||||
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.bot_has_permissions(add_reactions=True)
|
||||
async def suggest(self, ctx: commands.Context, *, suggestion: str):
|
||||
"""Suggest something."""
|
||||
suggest_id = await self.config.guild(ctx.guild).suggest_id()
|
||||
if not suggest_id:
|
||||
if not await self.config.toggle():
|
||||
return await ctx.send("Uh oh, suggestions aren't enabled.")
|
||||
if ctx.guild.id in await self.config.ignore():
|
||||
return await ctx.send("Uh oh, suggestions aren't enabled.")
|
||||
else:
|
||||
channel = ctx.guild.get_channel(suggest_id)
|
||||
if not channel:
|
||||
return await ctx.send(
|
||||
"Uh oh, looks like the Admins haven't added the required channel."
|
||||
)
|
||||
embed = discord.Embed(color=await ctx.embed_colour(), description=suggestion)
|
||||
footer = [f"Suggested by {ctx.author.name}#{ctx.author.discriminator}",
|
||||
ctx.author.avatar_url]
|
||||
author = [f"{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})", ctx.author.avatar_url]
|
||||
embed.set_footer(
|
||||
text=footer[0],
|
||||
icon_url=footer[1]
|
||||
)
|
||||
embed.set_author(
|
||||
name=author[0],
|
||||
icon_url=author[1]
|
||||
)
|
||||
if ctx.message.attachments:
|
||||
embed.set_image(url=ctx.message.attachments[0].url)
|
||||
|
||||
s_id = await self.config.guild(ctx.guild).next_id()
|
||||
await self.config.guild(ctx.guild).next_id.set(s_id + 1)
|
||||
server = ctx.guild.id
|
||||
content = f"Suggestion #{s_id}"
|
||||
embed.title = content
|
||||
msg = await channel.send(embed=embed)
|
||||
|
||||
up_emoji, down_emoji = await self._get_emojis(ctx)
|
||||
await msg.add_reaction(up_emoji)
|
||||
await msg.add_reaction(down_emoji)
|
||||
|
||||
async with self.config.custom("SUGGESTION", server, s_id).author() as author:
|
||||
author.append(ctx.author.id)
|
||||
author.append(ctx.author.name)
|
||||
author.append(ctx.author.discriminator)
|
||||
await self.config.custom("SUGGESTION", server, s_id).guild_id.set(ctx.guild.id)
|
||||
await self.config.custom("SUGGESTION", server, s_id).stext.set(suggestion)
|
||||
await self.config.custom("SUGGESTION", server, s_id).msg_id.set(msg.id)
|
||||
|
||||
if await self.config.guild(ctx.guild).delete_suggest():
|
||||
try:
|
||||
await ctx.message.delete()
|
||||
except discord.errors.NotFound:
|
||||
pass
|
||||
else:
|
||||
await ctx.tick()
|
||||
|
||||
@checks.admin()
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.bot_has_permissions(manage_messages=True)
|
||||
async def approve(
|
||||
self,
|
||||
ctx: commands.Context,
|
||||
suggestion_id: int,
|
||||
*,
|
||||
reason: typing.Optional[str],
|
||||
):
|
||||
"""Approve a suggestion."""
|
||||
await self._finish_suggestion(ctx, suggestion_id, True, reason, ctx.author)
|
||||
|
||||
@checks.admin()
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.bot_has_permissions(manage_messages=True)
|
||||
async def deny(
|
||||
self,
|
||||
ctx: commands.Context,
|
||||
suggestion_id: int,
|
||||
*,
|
||||
reason: typing.Optional[str],
|
||||
):
|
||||
"""Deny a suggestion. Reason is optional."""
|
||||
await self._finish_suggestion(ctx, suggestion_id, False, reason, ctx.author)
|
||||
|
||||
@checks.admin()
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.bot_has_permissions(manage_messages=True)
|
||||
async def addreason(
|
||||
self,
|
||||
ctx: commands.Context,
|
||||
suggestion_id: int,
|
||||
*,
|
||||
reason: str,
|
||||
):
|
||||
server = ctx.guild.id
|
||||
author = ctx.author
|
||||
approved_channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).approve_id()
|
||||
)
|
||||
reject_channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).denied_id()
|
||||
)
|
||||
|
||||
msg_id = await self.config.custom("SUGGESTION", server, suggestion_id).msg_id()
|
||||
try:
|
||||
old_msg = await approved_channel.fetch_message(msg_id)
|
||||
approve = True
|
||||
except discord.NotFound:
|
||||
try:
|
||||
old_msg = await reject_channel.fetch_message(msg_id)
|
||||
approve = False
|
||||
except discord.NotFound:
|
||||
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||
if not old_msg:
|
||||
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||
embed = old_msg.embeds[0]
|
||||
content = old_msg.content
|
||||
approved = "Approved" if approve else "Denied"
|
||||
embed.title = f"Suggestion {approved} (#{suggestion_id})"
|
||||
footer = [f"{approved} by {author.name}#{author.discriminator} ({author.id}",
|
||||
author.avatar_url_as(format="png", size=512)]
|
||||
embed.set_footer(
|
||||
text=footer[0],
|
||||
icon_url=footer[1]
|
||||
)
|
||||
if reason:
|
||||
embed.add_field(name="Reason", value=reason, inline=False)
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).reason.set(
|
||||
True
|
||||
)
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).rtext.set(
|
||||
reason
|
||||
)
|
||||
|
||||
await old_msg.edit(content=content, embed=embed)
|
||||
await ctx.tick()
|
||||
|
||||
@checks.admin()
|
||||
@checks.bot_has_permissions(
|
||||
manage_channels=True, add_reactions=True, manage_messages=True
|
||||
)
|
||||
@commands.group(autohelp=True, aliases=["suggestion"])
|
||||
@commands.guild_only()
|
||||
async def suggestset(self, ctx: commands.Context):
|
||||
"""Various Suggestion settings."""
|
||||
|
||||
@suggestset.command(name="channel")
|
||||
async def suggestset_channel(
|
||||
self, ctx: commands.Context, channel: typing.Optional[discord.TextChannel]
|
||||
):
|
||||
"""Set the channel for suggestions.
|
||||
|
||||
If the channel is not provided, suggestions will be disabled."""
|
||||
if channel:
|
||||
await self.config.guild(ctx.guild).suggest_id.set(channel.id)
|
||||
else:
|
||||
await self.config.guild(ctx.guild).suggest_id.clear()
|
||||
await ctx.tick()
|
||||
|
||||
@suggestset.command(name="approved")
|
||||
async def suggestset_approved(
|
||||
self, ctx: commands.Context, channel: typing.Optional[discord.TextChannel]
|
||||
):
|
||||
"""Set the channel for approved suggestions.
|
||||
|
||||
If the channel is not provided, approved suggestions will not be reposted."""
|
||||
old_channel = ctx.guild.get_channel(await self.config.guild(ctx.guild).approve_id())
|
||||
if channel:
|
||||
await self.config.guild(ctx.guild).approve_id.set(channel.id)
|
||||
if ctx.guild.get_channel(await self.config.guild(ctx.guild).approve_id()) == \
|
||||
ctx.guild.get_channel(await self.config.guild(ctx.guild).denied_id()):
|
||||
await ctx.send("Cannot make approved and denied the same channel!hjo8")
|
||||
try:
|
||||
await self.config.guild(ctx.guild).approve_id.set(old_channel.id)
|
||||
except AttributeError:
|
||||
await self.config.guild(ctx.guild).approve_id.clear()
|
||||
return
|
||||
else:
|
||||
await self.config.guild(ctx.guild).approve_id.clear()
|
||||
await ctx.tick()
|
||||
|
||||
@suggestset.command(name="denied")
|
||||
async def suggestset_denied(
|
||||
self, ctx: commands.Context, channel: typing.Optional[discord.TextChannel]
|
||||
):
|
||||
"""Set the channel for denied suggestions.
|
||||
|
||||
If the channel is not provided, denied suggestions will not be reposted."""
|
||||
old_channel = ctx.guild.get_channel(await self.config.guild(ctx.guild).denied_id())
|
||||
if channel:
|
||||
await self.config.guild(ctx.guild).denied_id.set(channel.id)
|
||||
if ctx.guild.get_channel(await self.config.guild(ctx.guild).approve_id()) == \
|
||||
ctx.guild.get_channel(await self.config.guild(ctx.guild).denied_id()):
|
||||
await ctx.send("Cannot make approved and denied the same channel!")
|
||||
try:
|
||||
await self.config.guild(ctx.guild).denied_id.set(old_channel.id)
|
||||
except AttributeError:
|
||||
await self.config.guild(ctx.guild).denied_id.clear()
|
||||
return
|
||||
else:
|
||||
await self.config.guild(ctx.guild).denied_id.clear()
|
||||
await ctx.tick()
|
||||
|
||||
@suggestset.command(name="same")
|
||||
async def suggestset_same(self, ctx: commands.Context, same: bool):
|
||||
"""Set whether to use the same channel for new and finished suggestions."""
|
||||
await ctx.send(
|
||||
"Suggestions won't be reposted anywhere, only their title will change accordingly."
|
||||
if same
|
||||
else "Suggestions will go to their appropriate channels upon approving/denying."
|
||||
)
|
||||
await self.config.guild(ctx.guild).same.set(same)
|
||||
|
||||
@suggestset.command(name="upemoji")
|
||||
async def suggestset_upemoji(
|
||||
self, ctx: commands.Context, up_emoji: typing.Optional[discord.Emoji]
|
||||
):
|
||||
"""Set a custom upvote emoji instead of <:upvote:1071095785455886436>."""
|
||||
if not up_emoji:
|
||||
await self.config.guild(ctx.guild).up_emoji.clear()
|
||||
else:
|
||||
try:
|
||||
await ctx.message.add_reaction(up_emoji)
|
||||
except discord.HTTPException:
|
||||
return await ctx.send("Uh oh, I cannot use that emoji.")
|
||||
await self.config.guild(ctx.guild).up_emoji.set(up_emoji.id)
|
||||
await ctx.tick()
|
||||
|
||||
@suggestset.command(name="downemoji")
|
||||
async def suggestset_downemoji(
|
||||
self, ctx: commands.Context, down_emoji: typing.Optional[discord.Emoji]
|
||||
):
|
||||
"""Set a custom downvote emoji instead of <:downvote:1071096039119007804>."""
|
||||
if not down_emoji:
|
||||
await self.config.guild(ctx.guild).down_emoji.clear()
|
||||
else:
|
||||
try:
|
||||
await ctx.message.add_reaction(down_emoji)
|
||||
except discord.HTTPException:
|
||||
return await ctx.send("Uh oh, I cannot use that emoji.")
|
||||
await self.config.guild(ctx.guild).down_emoji.set(down_emoji.id)
|
||||
await ctx.tick()
|
||||
|
||||
@suggestset.command(name="autodelete")
|
||||
async def suggestset_autodelete(
|
||||
self, ctx: commands.Context, on_off: typing.Optional[bool]
|
||||
):
|
||||
"""Toggle whether after `[p]suggest`, the bot deletes the command message."""
|
||||
target_state = on_off or not (
|
||||
await self.config.guild(ctx.guild).delete_suggest()
|
||||
)
|
||||
|
||||
await self.config.guild(ctx.guild).delete_suggest.set(target_state)
|
||||
await ctx.send(
|
||||
"Auto deletion is now enabled."
|
||||
if target_state
|
||||
else "Auto deletion is now disabled."
|
||||
)
|
||||
|
||||
@suggestset.command(name="delete")
|
||||
async def suggestset_delete(
|
||||
self, ctx: commands.Context, on_off: typing.Optional[bool]
|
||||
):
|
||||
"""Toggle whether suggestions in the original suggestion channel get deleted after being approved/denied.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped."""
|
||||
target_state = on_off or not (
|
||||
await self.config.guild(ctx.guild).delete_suggestion()
|
||||
)
|
||||
|
||||
await self.config.guild(ctx.guild).delete_suggestion.set(target_state)
|
||||
await ctx.send(
|
||||
"Suggestions will be deleted upon approving/denying from the original suggestion channel."
|
||||
if target_state
|
||||
else "Suggestions will stay in the original channel after approving/denying."
|
||||
)
|
||||
|
||||
@suggestset.command(name="settings")
|
||||
async def suggestset_settings(self, ctx: commands.Context):
|
||||
"""See current settings."""
|
||||
data = await self.config.guild(ctx.guild).all()
|
||||
suggest_channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).suggest_id()
|
||||
)
|
||||
suggest_channel = "None" if not suggest_channel else suggest_channel.mention
|
||||
approve_channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).approve_id()
|
||||
)
|
||||
approve_channel = "None" if not approve_channel else approve_channel.mention
|
||||
reject_channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).denied_id()
|
||||
)
|
||||
reject_channel = "None" if not reject_channel else reject_channel.mention
|
||||
up_emoji, down_emoji = await self._get_emojis(ctx)
|
||||
|
||||
embed = discord.Embed(
|
||||
colour=await ctx.embed_colour()
|
||||
)
|
||||
embed.set_author(name=ctx.guild.name, icon_url=ctx.guild.icon_url)
|
||||
embed.title = "**__Suggestion settings (guild):__**"
|
||||
|
||||
embed.set_footer(text="*required to function properly")
|
||||
embed.add_field(name="Same channel*:", value=str(data["same"]), inline=False)
|
||||
embed.add_field(name="Suggest channel*:", value=suggest_channel)
|
||||
embed.add_field(name="Approved channel:", value=approve_channel)
|
||||
embed.add_field(name="Denied channel:", value=reject_channel)
|
||||
embed.add_field(name="Up emoji:", value=up_emoji)
|
||||
embed.add_field(name="Down emoji:", value=down_emoji)
|
||||
embed.add_field(
|
||||
name=f"Delete `{ctx.clean_prefix}suggest` upon use:",
|
||||
value=data["delete_suggest"],
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(
|
||||
name="Delete suggestion upon approving/denying:",
|
||||
value=data["delete_suggestion"],
|
||||
inline=False,
|
||||
)
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_reaction_add(self, reaction, user):
|
||||
message = reaction.message
|
||||
if user.id == self.bot.user.id:
|
||||
return
|
||||
if not message.guild:
|
||||
return
|
||||
# server suggestions
|
||||
if message.channel.id == await self.config.guild(message.guild).suggest_id():
|
||||
for message_reaction in message.reactions:
|
||||
if (
|
||||
message_reaction.emoji != reaction.emoji
|
||||
and user in await message_reaction.users().flatten()
|
||||
):
|
||||
await message_reaction.remove(user)
|
||||
|
||||
async def _get_results(self, ctx, message):
|
||||
up_emoji, down_emoji = await self._get_emojis(ctx)
|
||||
up_count = 0
|
||||
down_count = 0
|
||||
|
||||
for reaction in message.reactions:
|
||||
if reaction.emoji == up_emoji:
|
||||
up_count = reaction.count - 1 # minus the bot
|
||||
if reaction.emoji == down_emoji:
|
||||
down_count = reaction.count - 1 # minus the bot
|
||||
|
||||
return f"{up_count}x {up_emoji}\n{down_count}x {down_emoji}"
|
||||
|
||||
async def _get_emojis(self, ctx):
|
||||
up_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).up_emoji())
|
||||
if not up_emoji:
|
||||
up_emoji = "✅"
|
||||
down_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).down_emoji())
|
||||
if not down_emoji:
|
||||
down_emoji = "âŽ"
|
||||
return up_emoji, down_emoji
|
||||
|
||||
async def _finish_suggestion(self, ctx, suggestion_id, approve, reason, author):
|
||||
server = ctx.guild.id
|
||||
old_channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).suggest_id()
|
||||
)
|
||||
if approve:
|
||||
channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).approve_id()
|
||||
)
|
||||
else:
|
||||
channel = ctx.guild.get_channel(
|
||||
await self.config.guild(ctx.guild).denied_id()
|
||||
)
|
||||
msg_id = await self.config.custom("SUGGESTION", server, suggestion_id).msg_id()
|
||||
if (
|
||||
msg_id != 0
|
||||
and await self.config.custom("SUGGESTION", server, suggestion_id).finished()
|
||||
):
|
||||
return await ctx.send("This suggestion has been finished already.")
|
||||
try:
|
||||
old_msg = await old_channel.fetch_message(msg_id)
|
||||
except discord.NotFound:
|
||||
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||
if not old_msg:
|
||||
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||
embed = old_msg.embeds[0]
|
||||
content = old_msg.content
|
||||
|
||||
approved = "Approved" if approve else "Denied"
|
||||
|
||||
embed.title = f"Suggestion {approved} (#{suggestion_id})"
|
||||
footer = [f"{approved} by {author.name}#{author.discriminator} ({author.id}",
|
||||
author.avatar_url_as(format="png", size=512)]
|
||||
embed.set_footer(
|
||||
text=footer[0],
|
||||
icon_url=footer[1]
|
||||
)
|
||||
embed.add_field(
|
||||
name="Results", value=await self._get_results(ctx, old_msg), inline=False
|
||||
)
|
||||
if reason:
|
||||
embed.add_field(name="Reason", value=reason, inline=False)
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).reason.set(
|
||||
True
|
||||
)
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).rtext.set(
|
||||
reason
|
||||
)
|
||||
|
||||
if channel:
|
||||
if not await self.config.guild(ctx.guild).same():
|
||||
if await self.config.guild(ctx.guild).delete_suggestion():
|
||||
await old_msg.delete()
|
||||
nmsg = await channel.send(content=content, embed=embed)
|
||||
await self.config.custom(
|
||||
"SUGGESTION", server, suggestion_id
|
||||
).msg_id.set(nmsg.id)
|
||||
else:
|
||||
await old_msg.edit(content=content, embed=embed)
|
||||
else:
|
||||
if not await self.config.guild(ctx.guild).same():
|
||||
if await self.config.guild(ctx.guild).delete_suggestion():
|
||||
await old_msg.delete()
|
||||
await self.config.custom(
|
||||
"SUGGESTION", server, suggestion_id
|
||||
).msg_id.set(1)
|
||||
else:
|
||||
await old_msg.edit(content=content, embed=embed)
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).finished.set(True)
|
||||
if approve:
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).approved.set(
|
||||
True
|
||||
)
|
||||
else:
|
||||
await self.config.custom("SUGGESTION", server, suggestion_id).denied.set(
|
||||
True
|
||||
)
|
||||
await ctx.tick()
|
Loading…
Reference in a new issue