From a82c054ce303e0d32b133c30e5a86ced428266b7 Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Sat, 4 Apr 2020 17:59:22 +1100 Subject: [PATCH] Mongo works, added new events --- commands/level.js | 2 +- configTemplate.js | 9 ++- events/disconnect.js | 3 + events/error.js | 3 + events/guildCreate.js | 24 ++++++++ events/message.js | 33 +++++++++-- events/reconnecting.js | 3 + index.js | 85 ++++++++++++++++++++-------- models/guild.js | 29 ++++++++++ modules/dbfix.js => models/member.js | 0 models/user.js | 0 modules/commands.js | 28 --------- modules/events.js | 21 ------- modules/mongoose.js | 33 ----------- util/dbfix.js | 1 + {modules => util}/functions.js | 50 +++++++++++++++- util/mongoose.js | 36 ++++++++++++ {modules => util}/music.js | 0 {modules => util}/webhooks.js | 0 19 files changed, 246 insertions(+), 114 deletions(-) create mode 100644 events/disconnect.js create mode 100644 events/error.js create mode 100644 events/guildCreate.js create mode 100644 events/reconnecting.js create mode 100644 models/guild.js rename modules/dbfix.js => models/member.js (100%) create mode 100644 models/user.js delete mode 100644 modules/commands.js delete mode 100644 modules/events.js delete mode 100644 modules/mongoose.js create mode 100644 util/dbfix.js rename {modules => util}/functions.js (78%) create mode 100644 util/mongoose.js rename {modules => util}/music.js (100%) rename {modules => util}/webhooks.js (100%) diff --git a/commands/level.js b/commands/level.js index ec9ad8f..1c53a7f 100644 --- a/commands/level.js +++ b/commands/level.js @@ -2,7 +2,7 @@ exports.conf = { enabled: true, guildOnly: false, aliases: ['plevel', 'permlevel'], - permLevel: 'User', + permLevel: 'Administrator', requiredPerms: [], cooldown: 2000 } diff --git a/configTemplate.js b/configTemplate.js index 09bef32..e8b940d 100644 --- a/configTemplate.js +++ b/configTemplate.js @@ -23,8 +23,13 @@ const config = { // URL of MongoDB database mongoDB: 'mongodb://localhost:27017/woomy', - // Default prefix - prefix: '~', + // Default settings for guilds + defaultGuildSettings: { + prefix: '~', + systemNotice: true, + modRole: 'Moderator', + adminRole: 'Administrator' + }, // Emojis used by Woomy emojis: { diff --git a/events/disconnect.js b/events/disconnect.js new file mode 100644 index 0000000..0e44cc0 --- /dev/null +++ b/events/disconnect.js @@ -0,0 +1,3 @@ +module.exports = (client) => { + client.logger.warn('Lost connection to Discord.') +} diff --git a/events/error.js b/events/error.js new file mode 100644 index 0000000..f1e3615 --- /dev/null +++ b/events/error.js @@ -0,0 +1,3 @@ +module.exports = async (client, error) => { + client.logger.error(JSON.stringify(error.stack)) +} diff --git a/events/guildCreate.js b/events/guildCreate.js new file mode 100644 index 0000000..40cce63 --- /dev/null +++ b/events/guildCreate.js @@ -0,0 +1,24 @@ +const Discord = require('discord.js') +module.exports = async (client, guild) => { + client.logger.info('Guild joined.') + + // Create DB entry for newly joined guild + try { + const newGuild = { + guildID: guild.id, + guildName: guild.name + } + await client.createGuild(newGuild) + } catch (err) { + client.logger.error('Failed to create DB entry for newly joined guild: ' + err) + } + + if (client.devmode === false) { + const channel = client.channels.cache.get(client.config.support.serverLogs) + // check if has perms, channel exists + const embed = new Discord.MessageEmbed() + embed.setColor('#F38159') + embed.setDescription(`Joined a new server with \`${guild.members.cache.size}\` members! I'm now in \`${client.guilds.cache.size}\` servers.`) + channel.send(embed) + } +} diff --git a/events/message.js b/events/message.js index cc3a44e..01693fb 100644 --- a/events/message.js +++ b/events/message.js @@ -1,7 +1,23 @@ module.exports = async (client, message) => { if (message.author.bot) return - var prefix = '!' + try { + await client.getGuild(message.guild) + } catch (err) { + try { + const newGuild = { + guildID: message.guild.id, + guildName: message.guild.name + } + await client.createGuild(newGuild) + } catch (err) { + client.logger.error('Failed to create DB entry for existing guild: ' + err) + } + } + + const settings = await client.getGuild(message.guild) + + let prefix = settings.prefix const myMention = `<@&${client.user.id}>` const myMention2 = `<@!${client.user.id}>` @@ -33,12 +49,21 @@ module.exports = async (client, message) => { // Dev perm level is separate so dev's don't get owner perms where they shouldn't have them if (cmd.conf.permLevel === 'Developer') { if (!client.config.devs.includes(message.author.id)) { - return message.channel.send('You don\'t have permission to run this command!') + if (settings.systemNotice === true) { + return message.channel.send('You don\'t have permission to run this command!') + } else { + return + } } } + console.log(settings.systemNotice) if (level < client.levelCache[cmd.conf.permLevel]) { - return message.channel.send('You don\'t have permission to run this command!') + if (settings.systemNotice === true) { + return message.channel.send('You don\'t have permission to run this command!') + } else { + return + } } // Cooldown @@ -65,5 +90,5 @@ module.exports = async (client, message) => { } client.logger.log(`Command ran: ${cmd.help.name}`) - cmd.run(client, message, args, level) + cmd.run(client, message, args, level, settings) } diff --git a/events/reconnecting.js b/events/reconnecting.js new file mode 100644 index 0000000..7178034 --- /dev/null +++ b/events/reconnecting.js @@ -0,0 +1,3 @@ +module.exports = (client) => { + client.logger.info('Reconnecting to Discord...') +} diff --git a/index.js b/index.js index 3827160..1340dda 100644 --- a/index.js +++ b/index.js @@ -44,29 +44,68 @@ client.cooldown = new Discord.Collection() client.aliases = new Discord.Collection() client.config = require('./config') -client.mongoose = require('./modules/mongoose') -require('./modules/functions')(client) -require('./modules/music')(client) -require('./modules/commands')(client) -require('./modules/events')(client) +client.db = require('./util/mongoose') +require('./util/functions')(client) +require('./util/music')(client) -for (let i = 0; i < client.config.permLevels.length; i++) { - const thisLevel = client.config.permLevels[i] - client.levelCache[thisLevel.name] = thisLevel.level +// Initialization function +const init = async () => { + // Command handler + fs.readdir('./commands', (err, files) => { + if (err) { + client.logger.fatal('Failed to get files in commands directory: ' + err) + process.exit() + } + client.logger.info(`Loading ${files.length} commands.`) + files.forEach(file => { + if (!file.endsWith('.js')) { + return + } + const response = client.loadCommand(file) + if (response) { + client.logger.error(response) + } + }) + }) + + // Event handler + fs.readdir('./events', (err, files) => { + if (err) { + client.logger.fatal('Failed to get files in events directory: ' + err) + process.exit() + } + client.logger.info(`Loading ${files.length} events.`) + files.forEach(file => { + if (!file.endsWith('.js')) { + return + } + const event = require(`./events/${file}`) + client.on(file.substr(0, file.length - 3), event.bind(null, client)) + }) + }) + + // Cache client permissions + for (let i = 0; i < client.config.permLevels.length; i++) { + const thisLevel = client.config.permLevels[i] + client.levelCache[thisLevel.name] = thisLevel.level + } + + if (isDocker() === true) { + client.devmode = true + client.logger.warn('Running in development mode.') + } else { + client.devmode = false + } + + // Initialise DB + await client.db.init(client) + + // Login to Discord + if (client.devmode !== true) { + client.login(client.config.token) + } else { + client.login(client.config.token_dev) + } } -if (isDocker() === true) { - client.devmode = true - client.logger.warn('Running in development mode.') -} else { - client.devmode = false -} - -console.log(client.mongoose) -client.mongoose.init() - -if (client.devmode !== true) { - client.login(client.config.token) -} else { - client.login(client.config.token_dev) -} +init() diff --git a/models/guild.js b/models/guild.js new file mode 100644 index 0000000..d565018 --- /dev/null +++ b/models/guild.js @@ -0,0 +1,29 @@ +const mongoose = require('mongoose') +const Schema = mongoose.Schema +const { defaultGuildSettings: defaults } = require('../config') + +module.exports = mongoose.model('Guild', new Schema({ + _id: mongoose.Schema.Types.ObjectId, + guildID: String, + guildName: String, + + prefix: { + type: String, + default: defaults.prefix + }, + + systemNotice: { + type: Boolean, + default: defaults.systemNotice + }, + + modRole: { + type: String, + default: defaults.modRole + }, + + adminRole: { + type: String, + default: defaults.modRole + } +})) diff --git a/modules/dbfix.js b/models/member.js similarity index 100% rename from modules/dbfix.js rename to models/member.js diff --git a/models/user.js b/models/user.js new file mode 100644 index 0000000..e69de29 diff --git a/modules/commands.js b/modules/commands.js deleted file mode 100644 index 2646a7d..0000000 --- a/modules/commands.js +++ /dev/null @@ -1,28 +0,0 @@ -const fs = require('fs') -module.exports = client => { - fs.readdir('./commands', (err, files) => { - if (err) { - client.logger.fatal('Failed to get files in commands directory: ' + err) - process.exit() - } - client.logger.info(`Loading ${files.length} commands.`) - files.forEach(file => { - if (!file.endsWith('.js')) { - return - } - try { - const props = require(`../commands/${file}`) - if (props.init) { - props.init(client) - } - client.commands.set(props.help.name, props) - client.cooldown.set(props.help.name, new Map()) - props.conf.aliases.forEach(alias => { - client.aliases.set(alias, props.help.name) - }) - } catch (err) { - client.logger.error(`Failed to load ${file}: ${err}`) - } - }) - }) -} diff --git a/modules/events.js b/modules/events.js deleted file mode 100644 index dbb7229..0000000 --- a/modules/events.js +++ /dev/null @@ -1,21 +0,0 @@ -const fs = require('fs') -module.exports = client => { - fs.readdir('./events', (err, files) => { - if (err) { - client.logger.fatal('Failed to get files in events directory: ' + err) - process.exit() - } - client.logger.info(`Loading ${files.length} events.`) - files.forEach(file => { - if (!file.endsWith('.js')) { - return - } - try { - const event = require(`../events/${file}`) - client.on(file.substr(0, file.length - 3), event.bind(null, client)) - } catch (err) { - client.logger.error(`Failed to load ${file}: ${err}`) - } - }) - }) -} diff --git a/modules/mongoose.js b/modules/mongoose.js deleted file mode 100644 index 3dd45d5..0000000 --- a/modules/mongoose.js +++ /dev/null @@ -1,33 +0,0 @@ -const mongoose = require('mongoose') - -// doesnt work - -module.exports = { - init: () => { - const dbOps = { - useNewUrlParser: true, - autoIndex: false, - reconnectTries: Number.MAX_VALUE, - reconnectInterval: 500, - poolSize: 5, - connectTimeoutMS: 10000, - family: 4 - } - - mongoose.connect(client.config.mongoDB, dbOps) - mongoose.set('useFindAndModify', false) - mongoose.Promise = global.Promise - - mongoose.connection.on('connected', () => { - client.logger.info('Database connection established.') - }) - - mongoose.connection.on('err', err => { - client.logger.error(`Database connection error:\n ${err.stack}`) - }) - - mongoose.connection.on('disconnected', () => { - client.logger.info('Disconected from database.') - }) - } -} diff --git a/util/dbfix.js b/util/dbfix.js new file mode 100644 index 0000000..b03aec6 --- /dev/null +++ b/util/dbfix.js @@ -0,0 +1 @@ +// will fix invalid db entries (invalid ids and stuff) diff --git a/modules/functions.js b/util/functions.js similarity index 78% rename from modules/functions.js rename to util/functions.js index a0725fc..d5922b4 100644 --- a/modules/functions.js +++ b/util/functions.js @@ -1,3 +1,6 @@ +const mongoose = require('mongoose') +const Guild = require('../models/guild') + module.exports = client => { // Permission level function client.permlevel = message => { @@ -16,6 +19,49 @@ module.exports = client => { return permlvl } + // Get settings + client.getGuild = async (guild) => { + const data = await Guild.findOne({ guildID: guild.id }) + if (data) { + return data + } else { + throw new Error('No entry for this guild was found in the database!') + } + } + + // Update settings + client.updateGuild = async (guild, settings) => { + const data = await client.getGuild(guild) + for (const key in settings) { + // eslint-disable-next-line no-prototype-builtins + if (settings.hasOwnProperty(key)) { + if (data[key] !== settings[key]) { + data[key] = settings[key] + } else { + return + } + } + client.logger.debug(`Updated settings for ${data.guildName}: ${Object.keys(settings)}`) + } + } + + // Create new entry for new guild + client.createGuild = async (settings) => { + const merged = Object.assign({ _id: mongoose.Types.ObjectId() }, settings) + const newGuild = await new Guild(merged) + return newGuild.save().then(g => { + client.logger.debug(`Created settings for guild ${g.guildName}`) + }) + } + + // Delete guild data + client.deleteGuild = async (guild) => { + const data = await client.getGuild(guild) + if (data) { + data.deleteOne({ guildID: guild.id }) + } + } + // Loads commands client.loadCommand = (commandName) => { try { @@ -99,9 +145,9 @@ module.exports = client => { } } - // FIND RANDOM INT BETWEEN TWO INTEGERS + // Returns a random number between min and max client.intBetween = function (min, max) { - return Math.round((Math.random() * (max - min)) + min) + return Math.floor((Math.random() * (max - min)) + min) } // Get random array object diff --git a/util/mongoose.js b/util/mongoose.js new file mode 100644 index 0000000..af45541 --- /dev/null +++ b/util/mongoose.js @@ -0,0 +1,36 @@ +const mongoose = require('mongoose') + +module.exports = { + init: (client) => { + const options = { + useNewUrlParser: true, + useUnifiedTopology: true, + autoIndex: false, + family: 4 + } + + try { + mongoose.connect(client.config.mongoDB, options) + mongoose.set('useFindAndModify', false) + mongoose.Promise = global.Promise + } catch (err) { + client.logger.fatal(`Could not connect to the database:\n ${err.stack}`) + } + + mongoose.connection.on('connected', () => { + client.logger.info('Connected to the database.') + }) + + mongoose.connection.on('err', err => { + client.logger.error(`Database connection error:\n ${err.stack}`) + }) + + mongoose.connection.on('disconnected', () => { + client.logger.info('Disconected from the database.') + }) + + mongoose.connection.on('reconnected', () => { + client.logger.info('Reconnected to the database.') + }) + } +} diff --git a/modules/music.js b/util/music.js similarity index 100% rename from modules/music.js rename to util/music.js diff --git a/modules/webhooks.js b/util/webhooks.js similarity index 100% rename from modules/webhooks.js rename to util/webhooks.js