1
Fork 0
mirror of https://github.com/RGBCube/minearchy-bot synced 2025-07-27 00:47:44 +00:00
This commit is contained in:
RGBCube 2023-01-15 16:24:57 +03:00
parent c1eb216eb5
commit 4e5c4507c8
11 changed files with 952 additions and 945 deletions

View file

@ -204,23 +204,23 @@ produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these terms of section 4, provided that you also meet all of these
conditions: conditions:
- a) The work must carry prominent notices stating that you modified - a) The work must carry prominent notices stating that you modified
it, and giving a relevant date. it, and giving a relevant date.
- b) The work must carry prominent notices stating that it is - b) The work must carry prominent notices stating that it is
released under this License and any conditions added under released under this License and any conditions added under
section 7. This requirement modifies the requirement in section 4 section 7. This requirement modifies the requirement in section 4
to "keep intact all notices". to "keep intact all notices".
- c) You must license the entire work, as a whole, under this - c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7 License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts, additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it. invalidate such permission if you have separately received it.
- d) If the work has interactive user interfaces, each must display - d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your interfaces that do not display Appropriate Legal Notices, your
work need not make them do so. work need not make them do so.
A compilation of a covered work with other separate and independent A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work, works, which are not by their nature extensions of the covered work,
@ -239,42 +239,42 @@ sections 4 and 5, provided that you also convey the machine-readable
Corresponding Source under the terms of this License, in one of these Corresponding Source under the terms of this License, in one of these
ways: ways:
- a) Convey the object code in, or embodied in, a physical product - a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the (including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium Corresponding Source fixed on a durable physical medium
customarily used for software interchange. customarily used for software interchange.
- b) Convey the object code in, or embodied in, a physical product - b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a (including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding conveying of source, or (2) access to copy the Corresponding
Source from a network server at no charge. Source from a network server at no charge.
- c) Convey individual copies of the object code with a copy of the - c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord only if you received the object code with such an offer, in accord
with subsection 6b. with subsection 6b.
- d) Convey the object code by offering access from a designated - d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party) may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements. available for as long as needed to satisfy these requirements.
- e) Convey the object code using peer-to-peer transmission, - e) Convey the object code using peer-to-peer transmission,
provided you inform other peers where the object code and provided you inform other peers where the object code and
Corresponding Source of the work are being offered to the general Corresponding Source of the work are being offered to the general
public at no charge under subsection 6d. public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be from the Corresponding Source as a System Library, need not be
@ -350,23 +350,23 @@ Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders add to a covered work, you may (if authorized by the copyright holders
of that material) supplement the terms of this License with terms: of that material) supplement the terms of this License with terms:
- a) Disclaiming warranty or limiting liability differently from the - a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or terms of sections 15 and 16 of this License; or
- b) Requiring preservation of specified reasonable legal notices or - b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or Notices displayed by works containing it; or
- c) Prohibiting misrepresentation of the origin of that material, - c) Prohibiting misrepresentation of the origin of that material,
or requiring that modified versions of such material be marked in or requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or reasonable ways as different from the original version; or
- d) Limiting the use for publicity purposes of names of licensors - d) Limiting the use for publicity purposes of names of licensors
or authors of the material; or or authors of the material; or
- e) Declining to grant rights under trademark law for use of some - e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or trade names, trademarks, or service marks; or
- f) Requiring indemnification of licensors and authors of that - f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions material by anyone who conveys the material (or modified versions
of it) with contractual assumptions of liability to the recipient, of it) with contractual assumptions of liability to the recipient,
for any liability that these contractual assumptions directly for any liability that these contractual assumptions directly
impose on those licensors and authors. impose on those licensors and authors.
All other non-permissive additional terms are considered "further All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you restrictions" within the meaning of section 10. If the Program as you

View file

@ -31,27 +31,27 @@ class MinearchyBot(CommandsBot):
self.webhook_url = webhook_url self.webhook_url = webhook_url
self.server = GeyserServer( self.server = GeyserServer(
java_ip="play.minearchy.com", java_ip = "play.minearchy.com",
bedrock_ip="bedrock.minearchy.com", bedrock_ip = "bedrock.minearchy.com",
) )
super().__init__( super().__init__(
command_prefix=when_mentioned_or("="), command_prefix = when_mentioned_or("="),
strip_after_prefix=True, strip_after_prefix = True,
case_insensitive=True, case_insensitive = True,
status=Game("on play.minearchy.com"), status = Game("on play.minearchy.com"),
owner_ids={512640455834337290, 160087716757897216}, owner_ids = { 512640455834337290, 160087716757897216 },
allowed_mentions=AllowedMentions.none(), allowed_mentions = AllowedMentions.none(),
max_messages=100, max_messages = 100,
intents=Intents( intents = Intents(
guilds=True, guilds = True,
members=True, members = True,
messages=True, messages = True,
message_content=True, message_content = True,
), ),
help_attrs=dict( help_attrs = dict(
brief="Sends help.", brief = "Sends help.",
help="Sends all the commands of the bot, or help of a specific command or module.", help = "Sends all the commands of the bot, or help of a specific command or module.",
), ),
) )
@ -90,10 +90,10 @@ class MinearchyBot(CommandsBot):
async def runner() -> None: async def runner() -> None:
async with self, AIOHTTPSession() as self.session: async with self, AIOHTTPSession() as self.session:
self.log_webhook = Webhook.from_url( self.log_webhook = Webhook.from_url(
self.webhook_url, session=self.session, bot_token=self.token self.webhook_url, session = self.session, bot_token = self.token
) )
await self.load_extensions() await self.load_extensions()
await self.start(self.token, reconnect=True) await self.start(self.token)
try: try:
asyncio.run(runner()) asyncio.run(runner())

View file

@ -14,7 +14,7 @@ def main() -> None:
config = json.loads( config = json.loads(
( (
Path(__file__).parent / "config.json" Path(__file__).parent / "config.json"
).read_text() ).read_text()
) )
@ -22,8 +22,8 @@ def main() -> None:
env[f"JISHAKU_NO_UNDERSCORE"] = "True" env[f"JISHAKU_NO_UNDERSCORE"] = "True"
bot = MinearchyBot( bot = MinearchyBot(
token=config["BOT_TOKEN"], token = config["BOT_TOKEN"],
webhook_url=config["WEBHOOK_URL"] webhook_url = config["WEBHOOK_URL"]
) )
bot.run() bot.run()

View file

@ -14,16 +14,16 @@ if TYPE_CHECKING:
class MinecraftServer( class MinecraftServer(
Cog, Cog,
name="Minecraft Server", name = "Minecraft Server",
description="Utilities for the Minecraft server.", description = "Utilities for the Minecraft server.",
): ):
def __init__(self, bot: MinearchyBot) -> None: def __init__(self, bot: MinearchyBot) -> None:
self.bot = bot self.bot = bot
@commands.group( @commands.group(
invoke_without_command=True, invoke_without_command = True,
brief="Sends the server IP.", brief = "Sends the server IP.",
help="Sends the server IP.", help = "Sends the server IP.",
) )
async def ip(self, ctx: Context) -> None: async def ip(self, ctx: Context) -> None:
await ctx.reply( await ctx.reply(
@ -32,8 +32,8 @@ class MinecraftServer(
) )
@ip.command( @ip.command(
brief="Sends the Java edition IP.", brief = "Sends the Java edition IP.",
help="Sends the Java edition IP." help = "Sends the Java edition IP."
) )
async def java(self, ctx: Context) -> None: async def java(self, ctx: Context) -> None:
await ctx.reply( await ctx.reply(
@ -42,8 +42,8 @@ class MinecraftServer(
) )
@ip.command( @ip.command(
brief="Sends the Bedrock edition IP.", brief = "Sends the Bedrock edition IP.",
help="Sends the Bedrock edition IP.", help = "Sends the Bedrock edition IP.",
) )
async def bedrock(self, ctx: Context) -> None: async def bedrock(self, ctx: Context) -> None:
await ctx.reply( await ctx.reply(
@ -53,8 +53,8 @@ class MinecraftServer(
) )
@command( @command(
brief="Shows information about the Minecraft server.", brief = "Shows information about the Minecraft server.",
help="Shows the total player count, the Minecraft server IP and the server latency.", help = "Shows the total player count, the Minecraft server IP and the server latency.",
) )
async def status(self, ctx: Context) -> None: async def status(self, ctx: Context) -> None:
status = await self.bot.server.status() status = await self.bot.server.status()
@ -68,97 +68,97 @@ class MinecraftServer(
await ctx.reply(message) await ctx.reply(message)
@command( @command(
brief="Sends the link to the wiki.", brief = "Sends the link to the wiki.",
help="Sends the link to the wiki." help = "Sends the link to the wiki."
) )
async def wiki(self, ctx: Context) -> None: async def wiki(self, ctx: Context) -> None:
view = View() view = View()
view.add_item( view.add_item(
Button( Button(
label="Go to the wiki!", label = "Go to the wiki!",
url="https://landsofminearchy.com/wiki", url = "https://landsofminearchy.com/wiki",
) )
) )
await ctx.reply(view=view) await ctx.reply(view = view)
@command( @command(
brief="Sends the link to the store.", brief = "Sends the link to the store.",
help="Sends the link to the store.", help = "Sends the link to the store.",
) )
async def store(self, ctx: Context) -> None: async def store(self, ctx: Context) -> None:
view = View() view = View()
view.add_item( view.add_item(
Button( Button(
label="Go to the store!", label = "Go to the store!",
url="https://landsofminearchy.com/store", url = "https://landsofminearchy.com/store",
) )
) )
await ctx.reply(view=view) await ctx.reply(view = view)
@command( @command(
aliases=("forums",), aliases = ("forums",),
brief="Sends the link to the forum.", brief = "Sends the link to the forum.",
help="Sends the link to the forum.", help = "Sends the link to the forum.",
) )
async def forum(self, ctx: Context) -> None: async def forum(self, ctx: Context) -> None:
view = View() view = View()
view.add_item( view.add_item(
Button( Button(
label="Go to the forum!", label = "Go to the forum!",
url="https://landsofminearchy.com/forum", url = "https://landsofminearchy.com/forum",
) )
) )
await ctx.reply(view=view) await ctx.reply(view = view)
@command( @command(
aliases=("map",), aliases = ("map",),
brief="Sends the link to the dynmap.", brief = "Sends the link to the dynmap.",
help="Sends the link to the dynmap.", help = "Sends the link to the dynmap.",
) )
async def dynmap(self, ctx: Context) -> None: async def dynmap(self, ctx: Context) -> None:
view = View() view = View()
view.add_item( view.add_item(
Button( Button(
label="Go to the dynmap!", label = "Go to the dynmap!",
url="https://landsofminearchy.com/dynmap", url = "https://landsofminearchy.com/dynmap",
) )
) )
await ctx.reply( await ctx.reply(
content="The dynmap is an interactive, live map of our Minecraft server.", view=view content = "The dynmap is an interactive, live map of our Minecraft server.", view = view
) )
@command( @command(
brief="Sends the links you can use to vote for the Minecraft server.", brief = "Sends the links you can use to vote for the Minecraft server.",
help="Sends the links you can use to vote for the Minecraft server.", help = "Sends the links you can use to vote for the Minecraft server.",
) )
async def vote(self, ctx: Context) -> None: async def vote(self, ctx: Context) -> None:
view = View() view = View()
view.add_item( view.add_item(
Button( Button(
label="Vote for the Minecraft server!", label = "Vote for the Minecraft server!",
url="https://landsofminearchy.com/vote", url = "https://landsofminearchy.com/vote",
) )
) )
await ctx.reply(view=view) await ctx.reply(view = view)
@command( @command(
name="staff-application", name = "staff-application",
aliases=( aliases = (
"apply", "apply",
"staff-applications", "staff-applications",
), ),
brief="Sends the link to the staff application.", brief = "Sends the link to the staff application.",
help="Sends the link to the staff application.", help = "Sends the link to the staff application.",
) )
async def staff_application(self, ctx: Context) -> None: async def staff_application(self, ctx: Context) -> None:
view = View() view = View()
view.add_item( view.add_item(
Button( Button(
label="Apply for staff!", label = "Apply for staff!",
url="https://docs.google.com/forms/d/1I7Rh_e-ZTXm5L51XoKZsOAk7NAJcHomUUCuOlQcARvY/viewform", url = "https://docs.google.com/forms/d/1I7Rh_e-ZTXm5L51XoKZsOAk7NAJcHomUUCuOlQcARvY/viewform",
) )
) )
await ctx.reply(view=view) await ctx.reply(view = view)
async def setup(bot: MinearchyBot) -> None: async def setup(bot: MinearchyBot) -> None:

View file

@ -19,8 +19,8 @@ if TYPE_CHECKING:
class Miscellaneous( class Miscellaneous(
Cog, Cog,
name="Miscellaneous", name = "Miscellaneous",
description="Miscellaneous commands.", description = "Miscellaneous commands.",
): ):
def __init__(self, bot: MinearchyBot) -> None: def __init__(self, bot: MinearchyBot) -> None:
self.bot = bot self.bot = bot
@ -32,16 +32,16 @@ class Miscellaneous(
self.bot.help_command.hidden = True self.bot.help_command.hidden = True
@command( @command(
brief="Sends the GitHub repository link for the bot.", brief = "Sends the GitHub repository link for the bot.",
help="Sends the GitHub repository link for the bot.", help = "Sends the GitHub repository link for the bot.",
) )
async def github(self, ctx: Context) -> None: async def github(self, ctx: Context) -> None:
# Not a button since I want the embed. # Not a button since I want the embed.
await ctx.reply("https://github.com/RGBCube/minearchy-bot") await ctx.reply("https://github.com/RGBCube/minearchy-bot")
@command( @command(
brief="Sends info about the bot.", brief = "Sends info about the bot.",
help="Sends info about the bot." help = "Sends info about the bot."
) )
async def info(self, ctx: Context) -> None: async def info(self, ctx: Context) -> None:
await ctx.reply( await ctx.reply(
@ -49,14 +49,14 @@ class Miscellaneous(
f""" f"""
__**Bot Info**__ __**Bot Info**__
**Python Version:** v{python_version()} **Python Version:** v{python_version()}
**Uptime:** `{TimeDelta(seconds=int(get_time() - self.bot.ready_timestamp))}` **Uptime:** `{TimeDelta(seconds = int(get_time() - self.bot.ready_timestamp))}`
""" """
) )
) )
@command( @command(
brief="Sets you as AFK.", brief = "Sets you as AFK.",
help="Sets you as AFK.", help = "Sets you as AFK.",
) )
async def afk(self, ctx: Context) -> None: async def afk(self, ctx: Context) -> None:
# No error because it will un-afk the caller. # No error because it will un-afk the caller.
@ -70,7 +70,7 @@ class Miscellaneous(
) )
return return
await ctx.author.edit(nick=f"[AFK] {ctx.author.display_name}"[:32]) await ctx.author.edit(nick = f"[AFK] {ctx.author.display_name}"[:32])
await ctx.reply("Set your status to AFK. You can now touch grass freely 🌲.") await ctx.reply("Set your status to AFK. You can now touch grass freely 🌲.")
@Cog.listener() @Cog.listener()
@ -78,8 +78,10 @@ class Miscellaneous(
if not message.author.display_name.upper().startswith("[AFK]"): if not message.author.display_name.upper().startswith("[AFK]"):
return return
await message.author.edit(nick=message.author.display_name[5:]) await message.author.edit(nick = message.author.display_name[5:])
await message.channel.send(f"Welcome back {message.author.mention}! I've unset your AFK status.") await message.channel.send(
f"Welcome back {message.author.mention}! I've unset your AFK status."
)
async def setup(bot: MinearchyBot) -> None: async def setup(bot: MinearchyBot) -> None:

View file

@ -20,8 +20,8 @@ if TYPE_CHECKING:
class Moderation( class Moderation(
Cog, Cog,
name="Moderation", name = "Moderation",
description="Moderation commands & utilities.", description = "Moderation commands & utilities.",
): ):
def __init__(self, bot: MinearchyBot) -> None: def __init__(self, bot: MinearchyBot) -> None:
self.bot = bot self.bot = bot
@ -34,11 +34,11 @@ class Moderation(
self.sniped = DefaultDict(Deque) self.sniped = DefaultDict(Deque)
@command( @command(
aliases=("mute",), aliases = ("mute",),
brief="Times out a user.", brief = "Times out a user.",
help="Times out a user." help = "Times out a user."
) )
@commands.has_permissions(manage_messages=True) @commands.has_permissions(manage_messages = True)
async def timeout(self, ctx: Context, member: Member, duration: str = "1d") -> None: async def timeout(self, ctx: Context, member: Member, duration: str = "1d") -> None:
if duration[-1] not in self.time_values or len(duration) < 2: if duration[-1] not in self.time_values or len(duration) < 2:
await ctx.reply("Invalid duration. Valid durations are: d, h, m, s.") await ctx.reply("Invalid duration. Valid durations are: d, h, m, s.")
@ -55,20 +55,21 @@ class Moderation(
# This is so cursed but works. # This is so cursed but works.
await member.timeout( await member.timeout(
TimeDelta(**{clean_time_name: time}), reason=f"Timed out by moderator {ctx.author}" TimeDelta(**{ clean_time_name: time }), reason = f"Timed out by moderator {ctx.author}"
) )
await ctx.reply(f"Timed out {member.mention} for {time} {clean_time_name}.") await ctx.reply(f"Timed out {member.mention} for {time} {clean_time_name}.")
# noinspection GrazieInspection
@command( @command(
brief="Sends the latest deleted messages.", brief = "Sends the latest deleted messages.",
help=( help = (
"Sends the last 5 deleted messages in a specified channel.\nIf the channel" "Sends the last 5 deleted messages in a specified channel.\nIf the channel"
" isn't specified, it uses the current channel." " isn't specified, it uses the current channel."
), ),
) )
# Needs to be able to delete messages to run the command. # Needs to be able to delete messages to run the command.
@commands.has_permissions(manage_messages=True) @commands.has_permissions(manage_messages = True)
async def snipe(self, ctx: Context, channel: TextChannel | None = None) -> None: async def snipe(self, ctx: Context, channel: TextChannel | None = None) -> None:
if channel is None: if channel is None:
channel = ctx.channel channel = ctx.channel
@ -83,12 +84,12 @@ class Moderation(
return return
embed = Embed( embed = Embed(
title=( title = (
"Showing last 5 deleted messages for" "Showing last 5 deleted messages for"
f" {'the current channel' if ctx.channel.id == channel.id else channel}" f" {'the current channel' if ctx.channel.id == channel.id else channel}"
), ),
description="The lower the number is, the more recent it got deleted.", description = "The lower the number is, the more recent it got deleted.",
color=Color.random(), color = Color.random(),
) )
zwsp = "\uFEFF" zwsp = "\uFEFF"
@ -97,8 +98,8 @@ class Moderation(
message, ts = log message, ts = log
embed.add_field( embed.add_field(
name=str(i) + ("" if i else " (latest)"), name = str(i) + ("" if i else " (latest)"),
value=strip( value = strip(
f""" f"""
Author: {message.author.mention} (ID: {message.author.id}, Plain: {escape_markdown(str(message.author))}) Author: {message.author.mention} (ID: {message.author.id}, Plain: {escape_markdown(str(message.author))})
Deleted at: <t:{ts}:F> (Relative: <t:{ts}:R>) Deleted at: <t:{ts}:F> (Relative: <t:{ts}:R>)
@ -108,10 +109,10 @@ class Moderation(
``` ```
""" """
), ),
inline=False, inline = False,
) )
await ctx.reply(embed=embed) await ctx.reply(embed = embed)
@Cog.listener() @Cog.listener()
async def on_message_delete(self, message: Message) -> None: async def on_message_delete(self, message: Message) -> None:

View file

@ -24,33 +24,33 @@ if TYPE_CHECKING:
class Utils( class Utils(
Cog, Cog,
name="Utilities", name = "Utilities",
description="Various utilities.", description = "Various utilities.",
): ):
def __init__(self, bot: MinearchyBot) -> None: def __init__(self, bot: MinearchyBot) -> None:
self.bot = bot self.bot = bot
@command( @command(
brief="Sends the total members in the server.", brief = "Sends the total members in the server.",
help="Sends the total members in the server.", help = "Sends the total members in the server.",
) )
async def members(self, ctx: Context) -> None: async def members(self, ctx: Context) -> None:
await ctx.reply(f"There are `{ctx.guild.member_count}` users in this server.") await ctx.reply(f"There are `{ctx.guild.member_count}` users in this server.")
@command( @command(
brief="Sends the bots ping.", brief = "Sends the bots ping.",
help="Sends the bots ping." help = "Sends the bots ping."
) )
async def ping(self, ctx: Context) -> None: async def ping(self, ctx: Context) -> None:
ts = get_monotonic() ts = get_monotonic()
message = await ctx.reply("Pong!") message = await ctx.reply("Pong!")
ts = get_monotonic() - ts ts = get_monotonic() - ts
await message.edit(content=f"Pong! `{int(ts * 1000)}ms`") await message.edit(content = f"Pong! `{int(ts * 1000)}ms`")
# Fuck this thing I'm never touching it again. # Fuck this thing I'm never touching it again.
@command( @command(
name="channel-perm-tree", name = "channel-perm-tree",
hidden=True hidden = True
) )
async def channel_perm_tree(self, ctx: Context) -> None: async def channel_perm_tree(self, ctx: Context) -> None:
string = [] string = []
@ -88,18 +88,20 @@ class Utils(
deny.append(perm) deny.append(perm)
if allow or deny: if allow or deny:
perms.append(f" {typ} `{name}`: {thing.id if name != '@everyone' else ''}") perms.append(
f" {typ} `{name}`: {thing.id if name != '@everyone' else ''}"
)
perms.append(" permissions:") perms.append(" permissions:")
for a in allow: for a in allow:
perms.append(f" {a}: ✅") perms.append(f" {a}: ✅")
for d in deny: for d in deny:
perms.append(f" {d}: ❌") perms.append(f" {d}: ❌")
if perms: if perms:
string.append(" permissions:") string.append(" permissions:")
string.extend(perms) string.extend(perms)
# Category perms end. # Category perms end.
# Channel perms start. # Channel perms start.
@ -200,7 +202,9 @@ class Utils(
deny.append(perm) deny.append(perm)
if allow or deny: if allow or deny:
string.append(f" {typ} `{name}`: {thing.id if name != '@everyone' else ''}") string.append(
f" {typ} `{name}`: {thing.id if name != '@everyone' else ''}"
)
string.append(" permissions:") string.append(" permissions:")
for a in allow: for a in allow:
@ -215,9 +219,9 @@ class Utils(
# Root perms end. # Root perms end.
await ctx.reply( await ctx.reply(
file=File( file = File(
BytesIO("\n".join(string).encode()), BytesIO("\n".join(string).encode()),
filename="channel-perm-tree.txt" filename = "channel-perm-tree.txt"
) )
) )

View file

@ -1,4 +1,4 @@
{ {
"BOT_TOKEN": "", "BOT_TOKEN": "",
"WEBHOOK_URL": "" "WEBHOOK_URL": ""
} }

View file

@ -4,9 +4,9 @@ __all__ = ("override",)
from typing import Callable, TypeVar from typing import Callable, TypeVar
T = TypeVar("T", bound=Callable) T = TypeVar("T", bound = Callable)
def override(function: T) -> T: def override(function: T) -> T:
"""Basically Java's @Override annotation. Makes stuff less ambiguous.""" """Basically Javas @Override annotation. Makes stuff less ambiguous."""
return function return function

1516
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,11 +2,11 @@
name = "minearchy-bot" name = "minearchy-bot"
version = "1.0.0" version = "1.0.0"
description = "A simple Discord bot for the Lands of Minearchy Discord server." description = "A simple Discord bot for the Lands of Minearchy Discord server."
authors = [ "RGBCube", "The Lands of Minearchy team" ] authors = ["RGBCube", "The Lands of Minearchy team"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.10" python = "^3.10"
"discord.py" = { version = "*", extras = [ "speed" ] } "discord.py" = { version = "*", extras = ["speed"] }
jishaku = "*" jishaku = "*"
mcstatus = "*" mcstatus = "*"
uvloop = "*" uvloop = "*"