Add initial code

This commit is contained in:
James H
2021-11-29 23:13:52 +00:00
parent cffc46bd45
commit 0f3416c11b
8 changed files with 200 additions and 0 deletions

4
config.json Normal file
View File

@@ -0,0 +1,4 @@
{
"command_prefix": "$",
"token": ""
}

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
discord.py[voice]==1.7.3
PyNaCl==1.4.0

20
src/commands/command.py Normal file
View File

@@ -0,0 +1,20 @@
import discord
class Command():
def __init__(self):
# Useful boilerplate
# You should overwrite these values!
self.name = "command" # Lower case and no spaces please :)
self.display_name = "Command"
self.description = "command description"
self.triggers = ["command"]
self.hidden = False
# {} will be .formatted to be the command prefix
self.usage = "{}command"
async def run(self, bot: discord.Client, config: dict, message: discord.message, content: str):
# Implement this!
pass

36
src/commands/help.py Normal file
View File

@@ -0,0 +1,36 @@
import discord
from commands.command import Command
class Help(Command):
def __init__(self):
self.name = "help"
self.display_name = "Help"
self.description = "Show a summary of the available bot commands"
self.triggers = ["help", "h"]
self.usage = "{0}help"
async def run(self, bot: discord.Client, config: dict, message: discord.Message, content: str):
commands = []
output = "MemeMan 3 : Electric Boogaloo 2\n\t The finest meme connoisseur\n"
output = f"{output}\nCommands:"
if config.get("loaded_commands") == None:
output = f"{output}\nNo commands to show!"
else:
for command in config.get("loaded_commands").values():
command_output = f"\t{command.display_name} : {command.description}\n"
usage = command.usage.format(config.get("command_prefix"))
triggers_str = f"${', $'.join(command.triggers)}"
command_output = f"{command_output}\t\tTriggers: {triggers_str}\n"
command_output = f"{command_output}\t\tUsage: {usage}\n"
output = f"{output}\n{command_output}"
output = f"```{output}\n\nMemeMan is open source! Find him at https://gitlab.hodgyj.com/james/mememan```"
await message.reply(output)

16
src/core/bot.py Normal file
View File

@@ -0,0 +1,16 @@
import discord
from core.commands import load_commands
from core.messages import handle_message
class Bot(discord.Client):
def load_config(self: discord.Client, config: dict):
self.config = config
load_commands(self.config)
async def on_ready(self: discord.Client):
print("It's showtime!")
print(f"Logged in as {self.user}")
async def on_message(self: discord.Client, message: discord.Message):
await handle_message(self, self.config, message)

69
src/core/commands.py Normal file
View File

@@ -0,0 +1,69 @@
import discord
# Import commands
from commands.help import Help
def split_message(message: str, config: dict) -> list:
prefix = config.get("command_prefix")
if prefix == None:
return []
if message[0] != prefix:
return []
return message.split(prefix, 1)
def load_commands(config: dict):
print("Loading commands")
commands = [
Help
]
loaded_commands = {}
for command in commands:
loaded = command()
if loaded_commands.get(loaded.name) == None:
loaded_commands[loaded.name] = loaded
print(f"\tLoaded command '{loaded.name}'")
else:
print(f"\tA command with name '{loaded.name}' already exists - skipping")
continue
config["loaded_commands"] = loaded_commands
async def dispatch_command(bot: discord.Client, config: dict, message: discord.Message):
split_content = split_message(message.content.lower(), config)
if len(split_content) < 2:
print(split_content)
# no prefix
return
command_name = split_content[1].split(" ", 1)[0]
message_content = ""
if len(split_content) > 2:
message_content = split_content[2]
print(f"Dispatching command '{command_name}'")
if config.get("loaded_commands") == None:
print("No loaded commands!")
return
found = False
for command in config.get("loaded_commands").values():
print(command.triggers)
if command_name in command.triggers:
print(f"Matched trigger in {command.name}")
found = True
await command.run(bot, config, message, message_content)
break
if not found:
print(f"Could not find command with trigger {command_name}")
await message.reply(f"`{command_name}` is not a command!")

18
src/core/messages.py Normal file
View File

@@ -0,0 +1,18 @@
import discord
from core.commands import dispatch_command
async def handle_message(bot: discord.Client, config: dict, message: discord.Message):
"""
Handle messages received from Discord
"""
if message.author == bot.user:
# Ignore messages from the bot!
return
# Ping!
if message.content == "ping":
await message.reply("pong!")
if message.content[0] == config.get("command_prefix"):
await dispatch_command(bot, config, message)

35
src/main.py Normal file
View File

@@ -0,0 +1,35 @@
import json
from core.bot import Bot
def main():
try:
with open("config.json", "rt") as config_file:
config = json.load(config_file)
except OSError as e:
print(f"Could not open config.json! Error: {e.strerror}")
return
except Exception as e:
print(f"Error loading config. Error: {e}")
return
# Load token from token file if not in JSON config
if config["token"] == "":
try:
with open("token.txt", "rt") as token_file:
config["token"] = token_file.readline()
except OSError as e:
print(f"Could not open token.txt! Error: {e.strerror}")
return
try:
bot = Bot()
bot.load_config(config)
bot.run(config["token"])
except Exception as e:
print(f"Exception running bot! Error: {e}")
return
if __name__ == "__main__":
main()