aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/__main__.py14
-rw-r--r--bot/cogs/bot.py21
-rw-r--r--bot/cogs/eval.py12
-rw-r--r--bot/cogs/events.py11
-rw-r--r--bot/cogs/security.py2
-rw-r--r--bot/cogs/verification.py54
-rw-r--r--bot/constants.py11
-rw-r--r--bot/decorators.py27
-rw-r--r--requirements.txt2
9 files changed, 137 insertions, 17 deletions
diff --git a/bot/__main__.py b/bot/__main__.py
index 2dc0ccc1f..9f9c82077 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -5,8 +5,14 @@ from discord import Game
from discord.ext.commands import AutoShardedBot, when_mentioned_or
bot = AutoShardedBot(
- command_prefix=when_mentioned_or(">>> ", ">> ", ">>>", ">>"), # Order matters
- game=Game(name=">>> help")
+ command_prefix=when_mentioned_or(
+ ">>> self.", ">> self.", "> self.", "self.",
+ ">>> bot.", ">> bot.", "> bot.", "bot.",
+ ">>> ", ">> ", "> ",
+ ">>>", ">>", ">"
+ ), # Order matters (and so do commas)
+ game=Game(name="Help: bot.help()"),
+ help_attrs={"aliases": ["help()"]}
)
# Internal/debug
@@ -14,10 +20,12 @@ bot.load_extension("bot.cogs.logging")
bot.load_extension("bot.cogs.security")
bot.load_extension("bot.cogs.events")
+
# Owner-only
bot.load_extension("bot.cogs.eval")
-# Commands
+# Commands, etc
bot.load_extension("bot.cogs.bot")
+bot.load_extension("bot.cogs.verification")
bot.run(os.environ.get("BOT_TOKEN"))
diff --git a/bot/cogs/bot.py b/bot/cogs/bot.py
index 6ab844725..e8530a8d0 100644
--- a/bot/cogs/bot.py
+++ b/bot/cogs/bot.py
@@ -1,9 +1,12 @@
# coding=utf-8
from discord import Embed
-from discord.ext.commands import AutoShardedBot, Context, group
+from discord.ext.commands import AutoShardedBot, Context, command, group
from dulwich.repo import Repo
+from bot.constants import VERIFIED_ROLE
+from bot.decorators import with_role
+
__author__ = "Gareth Coles"
@@ -16,6 +19,7 @@ class Bot:
self.bot = bot
@group(invoke_without_command=True, name="bot")
+ @with_role(VERIFIED_ROLE)
async def bot_group(self, ctx: Context):
"""
Bot informational commands
@@ -23,14 +27,15 @@ class Bot:
await ctx.invoke(self.bot.get_command("help"), "bot")
- @bot_group.command(aliases=["about"])
+ @bot_group.command(aliases=["about"], hidden=True)
+ @with_role(VERIFIED_ROLE)
async def info(self, ctx: Context):
"""
- Get information about the current bot
+ Get information about the bot
"""
embed = Embed(
- description="A utility bot designed just for the Python server! Try `>>> help` for more info.",
+ description="A utility bot designed just for the Python server! Try `bot.help()` for more info.",
url="https://github.com/discord-python/bot"
)
@@ -48,6 +53,14 @@ class Bot:
await ctx.send(embed=embed)
+ @command(name="bot.info()", aliases=["bot.info", "bot.about", "bot.about()"])
+ def info_wrapper(self, ctx: Context):
+ """
+ Get information about the bot
+ """
+
+ return self.info(ctx)
+
def setup(bot):
bot.add_cog(Bot(bot))
diff --git a/bot/cogs/eval.py b/bot/cogs/eval.py
index ceca8ab77..cf4b69eca 100644
--- a/bot/cogs/eval.py
+++ b/bot/cogs/eval.py
@@ -2,14 +2,16 @@
from io import StringIO
-from discord.ext.commands import AutoShardedBot, Context, command, is_owner
+from discord.ext.commands import AutoShardedBot, Context, command
+from bot.constants import OWNER_ROLE
+from bot.decorators import with_role
from bot.interpreter import Interpreter
-__author__ = "Gareth Coles"
+__author__ = "Careth Goles"
-class Eval:
+class EvalCog: # Named this way because a flake8 plugin isn't case-sensitive
"""
Bot owner only: Evaluate Python code
"""
@@ -19,7 +21,7 @@ class Eval:
self.interpreter = Interpreter(bot)
@command()
- @is_owner()
+ @with_role(OWNER_ROLE)
async def eval(self, ctx: Context, *, string: str):
"""
Bot owner only: Evaluate Python code
@@ -75,5 +77,5 @@ class Eval:
def setup(bot):
- bot.add_cog(Eval(bot))
+ bot.add_cog(EvalCog(bot))
print("Cog loaded: Eval")
diff --git a/bot/cogs/events.py b/bot/cogs/events.py
index 1c4d52623..a64859d77 100644
--- a/bot/cogs/events.py
+++ b/bot/cogs/events.py
@@ -18,12 +18,17 @@ class Events:
async def on_command_error(self, ctx: Context, e: CommandError):
command = ctx.command
- parent = command.parent
+ parent = None
- if parent:
+ if command is not None:
+ parent = command.parent
+
+ if parent and command:
help_command = (self.bot.get_command("help"), parent.name, command.name)
- else:
+ elif command:
help_command = (self.bot.get_command("help"), command.name)
+ else:
+ help_command = (self.bot.get_command("help"),)
if isinstance(e, BadArgument):
await ctx.send(f"Bad argument: {e}\n")
diff --git a/bot/cogs/security.py b/bot/cogs/security.py
index 91029f2cd..6827af690 100644
--- a/bot/cogs/security.py
+++ b/bot/cogs/security.py
@@ -11,7 +11,7 @@ class Security:
def __init__(self, bot: AutoShardedBot):
self.bot = bot
- self.bot.check(self.check_not_bot)
+ self.bot.check(self.check_not_bot) # Global commands check - no bots can run any commands at all
def check_not_bot(self, ctx: Context):
return not ctx.author.bot
diff --git a/bot/cogs/verification.py b/bot/cogs/verification.py
new file mode 100644
index 000000000..d4fbe5d78
--- /dev/null
+++ b/bot/cogs/verification.py
@@ -0,0 +1,54 @@
+# coding=utf-8
+from discord import Message, Object
+from discord.ext.commands import AutoShardedBot, Context, command
+
+from bot.constants import VERIFICATION_CHANNEL, VERIFIED_ROLE
+from bot.decorators import in_channel, without_role
+
+__author__ = "Careth Goles"
+
+
+class Verification:
+ """
+ User verification
+ """
+
+ def __init__(self, bot: AutoShardedBot):
+ self.bot = bot
+
+ async def on_message(self, message: Message):
+ if message.author.bot:
+ return # They're a bot, ignore
+
+ ctx = await self.bot.get_context(message) # type: Context
+
+ if ctx.command is not None and ctx.command.name == "accept":
+ return # They didn't use a command, or they used a command that isn't the accept command
+
+ if ctx.channel.id == VERIFICATION_CHANNEL: # We're in the verification channel
+ for role in ctx.author.roles:
+ if role.id == VERIFIED_ROLE:
+ return # They're already verified
+
+ await ctx.send(
+ f"{ctx.author.mention} Please type `self.accept()` to verify that you accept our rules, "
+ f"and gain access to the rest of the server.",
+ delete_after=10
+ )
+ await ctx.message.delete()
+
+ @command(name="accept", hidden=True, aliases=["verify", "verified", "accepted", "accept()"])
+ @without_role(VERIFIED_ROLE)
+ @in_channel(VERIFICATION_CHANNEL)
+ async def accept(self, ctx: Context):
+ """
+ Accept our rules and gain access to the rest of the server
+ """
+
+ await ctx.author.add_roles(Object(VERIFIED_ROLE), reason="Accepted the rules")
+ await ctx.message.delete()
+
+
+def setup(bot):
+ bot.add_cog(Verification(bot))
+ print("Cog loaded: Verification")
diff --git a/bot/constants.py b/bot/constants.py
new file mode 100644
index 000000000..af1830e07
--- /dev/null
+++ b/bot/constants.py
@@ -0,0 +1,11 @@
+# coding=utf-8
+
+__author__ = "Gareth Coles"
+
+
+VERIFICATION_CHANNEL = 352442727016693763
+
+ADMIN_ROLE = 267628507062992896
+MODERATOR_ROLE = 267629731250176001
+VERIFIED_ROLE = 352427296948486144
+OWNER_ROLE = 267627879762755584
diff --git a/bot/decorators.py b/bot/decorators.py
new file mode 100644
index 000000000..833094210
--- /dev/null
+++ b/bot/decorators.py
@@ -0,0 +1,27 @@
+# coding=utf-8
+from discord.ext import commands
+from discord.ext.commands import Context
+
+__author__ = "Careth Goles"
+
+
+def with_role(*role_ids: int):
+ async def predicate(ctx: Context):
+ for role in ctx.author.roles:
+ if role.id in role_ids:
+ return True
+ return False
+ return commands.check(predicate)
+
+
+def without_role(*role_ids: int):
+ async def predicate(ctx: Context):
+ author_roles = [role.id for role in ctx.author.roles]
+ return all(role not in author_roles for role in role_ids)
+ return commands.check(predicate)
+
+
+def in_channel(channel_id):
+ async def predicate(ctx: Context):
+ return ctx.channel.id == channel_id
+ return commands.check(predicate)
diff --git a/requirements.txt b/requirements.txt
index b1cabf9b0..58eeb7bd5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
-https://github.com/Rapptz/discord.py/archive/rewrite.zip
+https://github.com/Rapptz/discord.py/archive/rewrite.zip#egg=discord.py[voice]
dulwich \ No newline at end of file