Merge pull request #10 from Vylpes/feature/comments

Code Comments
This commit is contained in:
Vylpes 2020-10-30 23:06:59 +00:00 committed by GitHub
commit 45cd269248
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 16 deletions

View file

@ -1,22 +1,32 @@
// Required Components
const { Client } = require('discord.js'); const { Client } = require('discord.js');
const { existsSync } = require('fs'); const { existsSync } = require('fs');
const events = require('./events'); const events = require('./events');
const util = require('./util'); const util = require('./util');
// Client Class
class client extends Client { class client extends Client {
constructor(config) { constructor(config) {
// Call Discord.JS Client
super(); super();
// Set the client's configuration, initialise events, initialise utilities
this.config = config; this.config = config;
this.events = new events(); this.events = new events();
this.util = new util(this); this.util = new util(this);
} }
// Method to start the bot
start() { start() {
// Events to handle commands
super.on("message", this.events.message); super.on("message", this.events.message);
super.on("ready", this.events.ready); super.on("ready", this.events.ready);
// Login to discord using Discord.JS
super.login(this._config.token); super.login(this._config.token);
// Load events
this.util.loadEvents(); this.util.loadEvents();
} }
@ -27,12 +37,16 @@ class client extends Client {
set config(config) { set config(config) {
// Validate the config // Validate the config
// Only allow config to be set once and only as a JSON object
if (this._config) throw "Config has already been set"; if (this._config) throw "Config has already been set";
if (typeof config != "object") throw "Config is not a JSON object"; if (typeof config != "object") throw "Config is not a JSON object";
// Make sure the token and prefix are strings
if (typeof config.token != "string") throw "Token is not a string"; if (typeof config.token != "string") throw "Token is not a string";
if (typeof config.prefix != "string") throw "Prefix is not a string"; if (typeof config.prefix != "string") throw "Prefix is not a string";
// Make sure commands and events are arrays, each item inside will be validated later
if (typeof config.commands != "object") throw "Commands is not a string"; if (typeof config.commands != "object") throw "Commands is not a string";
if (typeof config.events != "object") throw "Events is not a string"; if (typeof config.events != "object") throw "Events is not a string";

View file

@ -1,18 +1,27 @@
// Events Class
class event { class event {
// Emit when a message is sent
// Used to check for commands
message(message) { message(message) {
// Make sure command is sent within a guild and not by a bot, otherwise return and ignore
if (!message.guild) return; if (!message.guild) return;
if (message.author.bot) return; if (message.author.bot) return;
// Get the prefix from the config
let prefix = this.config.prefix; let prefix = this.config.prefix;
// If the message starts with the prefix, then treat it as a command
if (message.content.substring(0, prefix.length).toLowerCase() == prefix.toLowerCase()) { if (message.content.substring(0, prefix.length).toLowerCase() == prefix.toLowerCase()) {
// Get the arguments in the message, after the first space (after the command name)
let args = message.content.substring(prefix.length).split(" "); let args = message.content.substring(prefix.length).split(" ");
let name = args.shift(); let name = args.shift();
// Load the command from the util class
this.util.loadCommand(name, args, message); this.util.loadCommand(name, args, message);
} }
} }
// Emit when bot is logged in and ready to use
ready() { ready() {
console.log("Ready"); console.log("Ready");
} }

View file

@ -1,49 +1,68 @@
// Required Components
const { stat, readdirSync } = require('fs'); const { stat, readdirSync } = require('fs');
const { config } = require('process'); const { config } = require('process');
// Util Class
class util { class util {
constructor(client) { constructor(client) {
// Set the client
this._client = client; this._client = client;
} }
// Load a command and send the arguments with it
loadCommand(name, args, message) { loadCommand(name, args, message) {
// Loop through all folders set in config
// c = command folder index
for (let c = 0; c < this._client.config.commands.length; c++) { for (let c = 0; c < this._client.config.commands.length; c++) {
// Get the current folder to check
let folder = this._client.config.commands[c]; let folder = this._client.config.commands[c];
// See if the folder being checked has the command being sent
stat(`${process.cwd()}/${folder}/${name}.js`, err => { stat(`${process.cwd()}/${folder}/${name}.js`, err => {
// If no error, attempt to run the command
if (err == null) { if (err == null) {
// Require the command file, now that we know it exists and initialise it
let commandFile = require(`${process.cwd()}/${folder}/${name}.js`); let commandFile = require(`${process.cwd()}/${folder}/${name}.js`);
let command = new commandFile(); let command = new commandFile();
// Get the list of required configurations the command needs
let requiredConfigs = command.requiredConfigs; let requiredConfigs = command.requiredConfigs;
// Loop through all the required configs of the command
for (let i = 0; i < requiredConfigs.length; i++) { for (let i = 0; i < requiredConfigs.length; i++) {
if (!this._client.config[name]) throw `${commandFile.name} requires ${requiredConfigs[i]} in it's configuration`; // If the command doesn't have the configs in the config string, throw an error
if (!this._client.config[name][requiredConfigs[i]]) throw `${commandFile.name} requires ${requiredConfigs[i]} in it's configuration`; if (!this._client.config[name]) throw `${commandFile.name} requires ${requiredConfigs[i]} in it's configuration`;
} if (!this._client.config[name][requiredConfigs[i]]) throw `${commandFile.name} requires ${requiredConfigs[i]} in it's configuration`;
}
let requiredRoles = command.roles; // Get the roles required for this command to run
let requiredRoles = command.roles;
for (let i = 0; i < requiredRoles.length; i++) { // Loop through all roles required
if (!message.member.roles.cache.find(role => role.name == requiredRoles[i])) { for (let i = 0; i < requiredRoles.length; i++) {
message.reply(`You require the \`${requiredRoles[i]}\` role to run this command`); // If the user doesn't have a required role, don't run the command and let the user know
return; if (!message.member.roles.cache.find(role => role.name == requiredRoles[i])) {
} message.reply(`You require the \`${requiredRoles[i]}\` role to run this command`);
return;
} }
}
// Get the ids of the users that are only permitted to run this command
let users = command.users; let users = command.users;
// If the user isn't in the list, don't run the command
if (!users.includes(message.member.id)) { if (!users.includes(message.member.id)) {
message.reply(`You do not have permission to run this command`); message.reply(`You do not have permission to run this command`);
return; return;
} }
command[command.run]({ // Run the command and pass the command context with it
"command": name, command[command.run]({
"arguments": args, "command": name,
"client": this._client, "arguments": args,
"message": message, "client": this._client,
"config": config "message": message,
"config": config
}); });
} else if (err.code === 'ENOENT') { } else if (err.code === 'ENOENT') {
// FILE DOESN'T EXIST // FILE DOESN'T EXIST
@ -52,18 +71,28 @@ class util {
} }
} }
// Load the events
loadEvents() { loadEvents() {
// Loop through all the event folders
for (let e = 0; e < this._client.config.events.length; e++) { for (let e = 0; e < this._client.config.events.length; e++) {
// Get the current folder to check
let folder = this._client.config.events[e]; let folder = this._client.config.events[e];
// Get the files inside of this folder
let eventFiles = readdirSync(`${process.cwd()}/${folder}/`); let eventFiles = readdirSync(`${process.cwd()}/${folder}/`);
// Loop through all the files in the folder
for (let i = 0; i < eventFiles.length; i++) { for (let i = 0; i < eventFiles.length; i++) {
// Get the event name, by taking the command file and removing the ".js" from the end
let eventName = eventFiles[i].split('.')[0]; let eventName = eventFiles[i].split('.')[0];
// Get the file of the event
let file = require(`${process.cwd()}/${folder}/${eventName}.js`); let file = require(`${process.cwd()}/${folder}/${eventName}.js`);
// Initialise the event class
let event = new file; let event = new file;
// Set the client to emit to this event
this._client.on(eventName, event[event.run]); this._client.on(eventName, event[event.run]);
} }
} }