first commit

This commit is contained in:
Raven Scott
2022-01-24 19:05:30 +00:00
commit 390fff9c42
31 changed files with 10171 additions and 0 deletions

27
modules/Logger.js Normal file
View 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
View 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
View 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",
}),
};