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
conditions:
- a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
- b) The work must carry prominent notices stating that it is
released under this License and any conditions added under
section 7. This requirement modifies the requirement in section 4
to "keep intact all notices".
- c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
- d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
- a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
- b) The work must carry prominent notices stating that it is
released under this License and any conditions added under
section 7. This requirement modifies the requirement in section 4
to "keep intact all notices".
- c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
- d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
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
ways:
- a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
- b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding
Source from a network server at no charge.
- c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
- d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
- e) Convey the object code using peer-to-peer transmission,
provided you inform other peers where the object code and
Corresponding Source of the work are being offered to the general
public at no charge under subsection 6d.
- a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
- b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding
Source from a network server at no charge.
- c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
- d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
- e) Convey the object code using peer-to-peer transmission,
provided you inform other peers where the object code and
Corresponding Source of the work are being offered to the general
public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
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
of that material) supplement the terms of this License with terms:
- a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
- b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
- c) Prohibiting misrepresentation of the origin of that material,
or requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
- d) Limiting the use for publicity purposes of names of licensors
or authors of the material; or
- e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
- f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions
of it) with contractual assumptions of liability to the recipient,
for any liability that these contractual assumptions directly
impose on those licensors and authors.
- a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
- b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
- c) Prohibiting misrepresentation of the origin of that material,
or requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
- d) Limiting the use for publicity purposes of names of licensors
or authors of the material; or
- e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
- f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions
of it) with contractual assumptions of liability to the recipient,
for any liability that these contractual assumptions directly
impose on those licensors and authors.
All other non-permissive additional terms are considered "further
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.server = GeyserServer(
java_ip="play.minearchy.com",
bedrock_ip="bedrock.minearchy.com",
java_ip = "play.minearchy.com",
bedrock_ip = "bedrock.minearchy.com",
)
super().__init__(
command_prefix=when_mentioned_or("="),
strip_after_prefix=True,
case_insensitive=True,
status=Game("on play.minearchy.com"),
owner_ids={512640455834337290, 160087716757897216},
allowed_mentions=AllowedMentions.none(),
max_messages=100,
intents=Intents(
guilds=True,
members=True,
messages=True,
message_content=True,
command_prefix = when_mentioned_or("="),
strip_after_prefix = True,
case_insensitive = True,
status = Game("on play.minearchy.com"),
owner_ids = { 512640455834337290, 160087716757897216 },
allowed_mentions = AllowedMentions.none(),
max_messages = 100,
intents = Intents(
guilds = True,
members = True,
messages = True,
message_content = True,
),
help_attrs=dict(
brief="Sends help.",
help="Sends all the commands of the bot, or help of a specific command or module.",
help_attrs = dict(
brief = "Sends help.",
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 with self, AIOHTTPSession() as self.session:
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.start(self.token, reconnect=True)
await self.start(self.token)
try:
asyncio.run(runner())

View file

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

View file

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

View file

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

View file

@ -20,8 +20,8 @@ if TYPE_CHECKING:
class Moderation(
Cog,
name="Moderation",
description="Moderation commands & utilities.",
name = "Moderation",
description = "Moderation commands & utilities.",
):
def __init__(self, bot: MinearchyBot) -> None:
self.bot = bot
@ -34,11 +34,11 @@ class Moderation(
self.sniped = DefaultDict(Deque)
@command(
aliases=("mute",),
brief="Times out a user.",
help="Times out a user."
aliases = ("mute",),
brief = "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:
if duration[-1] not in self.time_values or len(duration) < 2:
await ctx.reply("Invalid duration. Valid durations are: d, h, m, s.")
@ -55,20 +55,21 @@ class Moderation(
# This is so cursed but works.
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}.")
# noinspection GrazieInspection
@command(
brief="Sends the latest deleted messages.",
help=(
brief = "Sends the latest deleted messages.",
help = (
"Sends the last 5 deleted messages in a specified channel.\nIf the channel"
" isn't specified, it uses the current channel."
),
)
# 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:
if channel is None:
channel = ctx.channel
@ -83,12 +84,12 @@ class Moderation(
return
embed = Embed(
title=(
title = (
"Showing last 5 deleted messages for"
f" {'the current channel' if ctx.channel.id == channel.id else channel}"
),
description="The lower the number is, the more recent it got deleted.",
color=Color.random(),
description = "The lower the number is, the more recent it got deleted.",
color = Color.random(),
)
zwsp = "\uFEFF"
@ -97,8 +98,8 @@ class Moderation(
message, ts = log
embed.add_field(
name=str(i) + ("" if i else " (latest)"),
value=strip(
name = str(i) + ("" if i else " (latest)"),
value = strip(
f"""
Author: {message.author.mention} (ID: {message.author.id}, Plain: {escape_markdown(str(message.author))})
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()
async def on_message_delete(self, message: Message) -> None:

View file

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

View file

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

View file

@ -4,9 +4,9 @@ __all__ = ("override",)
from typing import Callable, TypeVar
T = TypeVar("T", bound=Callable)
T = TypeVar("T", bound = Callable)
def override(function: T) -> T:
"""Basically Java's @Override annotation. Makes stuff less ambiguous."""
"""Basically Javas @Override annotation. Makes stuff less ambiguous."""
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"
version = "1.0.0"
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]
python = "^3.10"
"discord.py" = { version = "*", extras = [ "speed" ] }
"discord.py" = { version = "*", extras = ["speed"] }
jishaku = "*"
mcstatus = "*"
uvloop = "*"