first commit
This commit is contained in:
27
modules/Logger.js
Normal file
27
modules/Logger.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Logger class for easy and aesthetically pleasing console logging
|
||||
*/
|
||||
const { cyan, red, magenta, gray, yellow, white, green } = require("colorette");
|
||||
const { Timestamp } = require("@sapphire/time-utilities");
|
||||
|
||||
exports.log = (content, type = "log") => {
|
||||
const timestamp = `[${cyan(new Timestamp("YYYY-MM-DD HH:mm:ss"))}]:`;
|
||||
|
||||
switch (type) {
|
||||
case "log": return console.log(`${timestamp} ${gray(type.toUpperCase())} ${content} `);
|
||||
case "warn": return console.log(`${timestamp} ${yellow(type.toUpperCase())} ${content} `);
|
||||
case "error": return console.log(`${timestamp} ${red(type.toUpperCase())} ${content} `);
|
||||
case "debug": return console.log(`${timestamp} ${magenta(type.toUpperCase())} ${content} `);
|
||||
case "cmd": return console.log(`${timestamp} ${white(type.toUpperCase())} ${content}`);
|
||||
case "ready": return console.log(`${timestamp} ${green(type.toUpperCase())} ${content}`);
|
||||
default: throw new TypeError("Logger type must be either warn, debug, log, ready, cmd or error.");
|
||||
}
|
||||
};
|
||||
|
||||
exports.error = (...args) => this.log(...args, "error");
|
||||
|
||||
exports.warn = (...args) => this.log(...args, "warn");
|
||||
|
||||
exports.debug = (...args) => this.log(...args, "debug");
|
||||
|
||||
exports.cmd = (...args) => this.log(...args, "cmd");
|
99
modules/functions.js
Normal file
99
modules/functions.js
Normal file
@ -0,0 +1,99 @@
|
||||
const logger = require("./Logger.js");
|
||||
const config = require("../config.js");
|
||||
const { settings } = require("./settings.js");
|
||||
// Let's start by getting some useful functions that we'll use throughout
|
||||
// the bot, like logs and elevation features.
|
||||
|
||||
/*
|
||||
PERMISSION LEVEL FUNCTION
|
||||
|
||||
This is a very basic permission system for commands which uses "levels"
|
||||
"spaces" are intentionally left black so you can add them if you want.
|
||||
NEVER GIVE ANYONE BUT OWNER THE LEVEL 10! By default this can run any
|
||||
command including the VERY DANGEROUS `eval` and `exec` commands!
|
||||
|
||||
*/
|
||||
function permlevel(message) {
|
||||
let permlvl = 0;
|
||||
|
||||
const permOrder = config.permLevels.slice(0).sort((p, c) => p.level < c.level ? 1 : -1);
|
||||
|
||||
while (permOrder.length) {
|
||||
const currentLevel = permOrder.shift();
|
||||
if (message.guild && currentLevel.guildOnly) continue;
|
||||
if (currentLevel.check(message)) {
|
||||
permlvl = currentLevel.level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return permlvl;
|
||||
}
|
||||
|
||||
/*
|
||||
GUILD SETTINGS FUNCTION
|
||||
|
||||
This function merges the default settings (from config.defaultSettings) with any
|
||||
guild override you might have for particular guild. If no overrides are present,
|
||||
the default settings are used.
|
||||
|
||||
*/
|
||||
|
||||
// getSettings merges the client defaults with the guild settings. guild settings in
|
||||
// enmap should only have *unique* overrides that are different from defaults.
|
||||
function getSettings(guild) {
|
||||
settings.ensure("default", config.defaultSettings);
|
||||
if (!guild) return settings.get("default");
|
||||
const guildConf = settings.get(guild.id) || {};
|
||||
// This "..." thing is the "Spread Operator". It's awesome!
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
|
||||
return ({...settings.get("default"), ...guildConf});
|
||||
}
|
||||
|
||||
/*
|
||||
SINGLE-LINE AWAIT MESSAGE
|
||||
|
||||
A simple way to grab a single reply, from the user that initiated
|
||||
the command. Useful to get "precisions" on certain things...
|
||||
|
||||
USAGE
|
||||
|
||||
const response = await awaitReply(msg, "Favourite Color?");
|
||||
msg.reply(`Oh, I really love ${response} too!`);
|
||||
|
||||
*/
|
||||
async function awaitReply(msg, question, limit = 60000) {
|
||||
const filter = m => m.author.id === msg.author.id;
|
||||
await msg.channel.send(question);
|
||||
try {
|
||||
const collected = await msg.channel.awaitMessages({ filter, max: 1, time: limit, errors: ["time"] });
|
||||
return collected.first().content;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* MISCELLANEOUS NON-CRITICAL FUNCTIONS */
|
||||
|
||||
// toProperCase(String) returns a proper-cased string such as:
|
||||
// toProperCase("Mary had a little lamb") returns "Mary Had A Little Lamb"
|
||||
function toProperCase(string) {
|
||||
return string.replace(/([^\W_]+[^\s-]*) */g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
|
||||
}
|
||||
|
||||
// These 2 process methods will catch exceptions and give *more details* about the error and stack trace.
|
||||
process.on("uncaughtException", (err) => {
|
||||
const errorMsg = err.stack.replace(new RegExp(`${__dirname}/`, "g"), "./");
|
||||
logger.error(`Uncaught Exception: ${errorMsg}`);
|
||||
console.error(err);
|
||||
// Always best practice to let the code crash on uncaught exceptions.
|
||||
// Because you should be catching them anyway.
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on("unhandledRejection", err => {
|
||||
logger.error(`Unhandled rejection: ${err}`);
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
module.exports = { getSettings, permlevel, awaitReply, toProperCase };
|
9
modules/settings.js
Normal file
9
modules/settings.js
Normal file
@ -0,0 +1,9 @@
|
||||
const Enmap = require("enmap");
|
||||
// Now we integrate the use of Evie's awesome Enmap module, which
|
||||
// essentially saves a collection to disk. This is great for per-server configs,
|
||||
// and makes things extremely easy for this purpose.
|
||||
module.exports = {
|
||||
settings: new Enmap({
|
||||
name: "settings",
|
||||
}),
|
||||
};
|
Reference in New Issue
Block a user