rename helpers utils

This commit is contained in:
Emily 2020-04-18 17:30:59 +10:00
parent 9b58684c16
commit 2958652eff
4 changed files with 0 additions and 0 deletions

286
utils/_functions.js Normal file
View file

@ -0,0 +1,286 @@
const { MessageEmbed } = require('discord.js')
const mongoose = require('mongoose')
const Guild = require('../models/guild')
const User = require('../models/user')
module.exports = client => {
// Permission level function
client.permlevel = (message, settings) => {
let permlvl = 0
const permOrder = client.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, settings)) {
permlvl = currentLevel.level
break
}
}
return permlvl
}
// Get guild settings
client.findOrCreateGuild = async (guild) => {
const data = await Guild.findOne({ guildID: guild.id })
if (data) {
return data
} else {
const merged = Object.assign({ _id: mongoose.Types.ObjectId() }, { guildID: guild.id })
const newGuild = await new Guild(merged)
return newGuild.save()
}
}
// Update guild settings
client.updateGuild = async (guild, settings) => {
let data = await client.findOrCreateGuild(guild)
if (typeof data !== 'object') data = {}
for (const key in settings) {
if (data[key] !== settings[key]) {
data[key] = settings[key]
} else return
}
return data.updateOne(settings)
}
// Delete guild settings
client.deleteGuild = async (guild) => {
const data = await client.findOrCreateGuild(guild)
if (data) {
data.deleteOne({ guildID: guild.id })
}
}
// Get user settings
client.findOrCreateUser = async (user) => {
const data = await User.findOne({ userID: user.id })
if (data) {
return data
} else {
const merged = Object.assign({ _id: mongoose.Types.ObjectId() }, { userID: user.id })
const newUser = await new User(merged)
return newUser.save()
}
}
// Update user settings
client.updateUser = async (user, settings) => {
let data = await client.findOrCreateUser(user)
if (typeof data !== 'object') data = {}
for (const key in settings) {
if (data[key] !== settings[key]) {
data[key] = settings[key]
} else return
}
return data.updateOne(settings)
}
// Delete user settings
client.deleteUser = async (user) => {
const data = await client.findOrCreateUser(user)
if (data) {
data.deleteOne({ userID: user.id })
}
}
// Loads commands
client.loadCommand = (commandName) => {
try {
const props = require(`../commands/${commandName}`)
if (props.init) {
props.init(client)
}
client.commands.set(props.help.name, props)
// So commands can each have their own cooldown time
client.cooldown.set(props.help.name, new Map())
props.conf.aliases.forEach(alias => {
client.aliases.set(alias, props.help.name)
})
return false
} catch (e) {
return `Failed to load ${commandName}: ${e}`
}
}
// Command unloader
client.unloadCommand = async (commandName) => {
let command
if (client.commands.has(commandName)) {
command = client.commands.get(commandName)
} else if (client.aliases.has(commandName)) {
command = client.commands.get(client.aliases.get(commandName))
}
if (!command) return `The command \`${commandName}\` doesn't seem to exist, nor is it an alias. Try again!`
if (command.shutdown) {
await command.shutdown(client)
}
const mod = require.cache[require.resolve(`../commands/${command.help.name}`)]
delete require.cache[require.resolve(`../commands/${command.help.name}.js`)]
for (let i = 0; i < mod.parent.children.length; i++) {
if (mod.parent.children[i] === mod) {
mod.parent.children.splice(i, 1)
break
}
}
return false
}
// Creates an embed for when commands are used incorrectly
client.userError = (msg, cmd, err) => {
const embed = new MessageEmbed()
embed.setColor('#EF5350')
embed.setTitle(cmd.help.name + ':' + cmd.help.category.toLowerCase())
embed.setDescription(err)
embed.addField('**Usage**', cmd.help.usage)
embed.addField('**Parameters**', cmd.help.parameters)
embed.setFooter(`Run 'help ${cmd.help.name}' for more information.`)
msg.channel.send(embed).then(msg => {
msg.delete({ timeout: 60000 })
})
}
// Clean up input to remove @everyone, token, etc
client.clean = async (client, text) => {
if (text && text.constructor.name === 'Promise') {
text = await text
}
if (typeof text !== 'string') {
text = require('util').inspect(text, { depth: 1 })
}
text = text
.replace(/`/g, '`' + String.fromCharCode(8203))
.replace(/@/g, '@' + String.fromCharCode(8203))
.replace(client.token, 'mfa.VkO_2G4Qv3T--NO--lWetW_tjND--TOKEN--QFTm6YGtzq9PH--4U--tG0')
return text
}
// Single line await messages
client.awaitReply = async (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
}
}
// Embed colour function
client.embedColour = function (guild) {
if (!guild || guild.member(client.user).displayHexColor === '#000000') {
return ['#ff9d68', '#ff97cb', '#d789ff', '#74FFFF'].random()
} else {
return guild.member(client.user).displayHexColor
}
}
// Capitalises the first letter of every word in a string
// eslint-disable-next-line no-extend-native
Object.defineProperty(String.prototype, 'toProperCase', {
value: function () {
return this.replace(/([^\W_]+[^\s-]*) */g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())
}
})
// Returns a random int between min and max
client.intBetween = function (min, max) {
return Math.floor((Math.random() * (max - min)) + min)
}
// Get random array object
// eslint-disable-next-line no-extend-native
Object.defineProperty(Array.prototype, 'random', {
value: function () {
return this[Math.floor(Math.random() * this.length)]
}
})
// `await client.wait(1000);` to 'pause' for 1 second.
client.wait = require('util').promisify(setTimeout)
// Find guild members
client.findMembers = function (guild, search) {
if (!search || typeof search !== 'string') return
const members = []
let member
// Try ID search
if (!isNaN(search) === true) {
members.push(guild.members.cache.get(search))
if (members[0]) {
return members[0]
}
}
// Try username search
try {
member = guild.members.cache.find(m => m.displayName.toLowerCase() === search)
if (!member) {
guild.members.cache.find(m => m.user.tag.toLowerCase() === search)
}
} catch (err) {}
if (member) {
members.push(member)
}
guild.members.cache.forEach(m => {
if (m.displayName.toLowerCase().startsWith(search) || m.user.tag.toLowerCase().startsWith(search)) {
members.push(m)
}
})
return members
}
// USER OBJECT FROM MENTION
client.getUserFromMention = mention => {
if (!mention) return
if (mention.startsWith('<@') && mention.endsWith('>')) {
mention = mention.slice(2, -1)
if (mention.startsWith('!')) {
mention = mention.slice(1)
}
return client.users.cache.get(mention)
}
}
client.findRole = function (guild, search) {
var role = guild.roles.cache.find(r => r.name.toLowerCase() === search.toLowerCase())
if (!role) {
role = guild.roles.cache.get(search.toLowerCase())
}
if (!role) {
return
}
return role
}
// Both of these functions catch errors and log them (maybe we could use sentry?)
process.on('uncaughtException', (err) => {
const errorMsg = err.stack.replace(new RegExp(`${__dirname}/`, 'g'), './')
client.logger.fatal(`Uncaught Exception: ${errorMsg}`)
process.exit(1)
})
process.on('unhandledRejection', err => {
client.logger.error(`Unhandled rejection: ${err.stack}`)
})
}

3
utils/botlists.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = client => {
}

36
utils/mongoose.js Normal file
View file

@ -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.')
})
}
}

198
utils/music.js Normal file
View file

@ -0,0 +1,198 @@
const ytdl = require('ytdl-core-discord')
const fetch = require('node-fetch')
const { MessageEmbed } = require('discord.js')
module.exports = client => {
client.music = { guilds: {} }
// MUSIC - TIMESTAMP
client.createTimestamp = function (duration) {
var hrs = ~~(duration / 60 / 60)
var min = ~~(duration / 60) % 60
var sec = ~~(duration - min * 60)
if (String(hrs).length < 2) {
hrs = '0' + String(hrs) + ':'
}
if (String(min).length < 2) {
min = '0' + String(min)
}
if (String(sec).length < 2) {
sec = '0' + String(sec)
}
if (hrs === '00:') {
hrs = ''
}
var time = hrs + min + ':' + sec
return time
}
client.music.getGuild = function (id) {
let guild = client.music.guilds[id]
if (!guild) {
guild = {}
guild.dispatcher = null
guild.playing = false
guild.queue = []
client.music.guilds[id] = guild
}
return guild
}
client.music.getLinkFromID = function (id) {
return 'https://www.youtube.com/watch?v=' + id
}
client.music.getVideoByQuery = async query => {
let resp
try {
const id = await ytdl.getURLVideoID(query)
resp = await fetch('https://invidio.us/api/v1/videos/' + id)
console.log(resp)
} catch (err) {
resp = await fetch('https://invidio.us/api/v1/search?q=' + encodeURIComponent(query))
}
const parsed = await resp.json()
if (parsed) {
const videos = parsed
if (videos) {
return videos
} else {
return false
}
} else {
return false
}
}
client.music.play = async function (message, query, ignoreQueue) {
const guild = client.music.getGuild(message.guild.id)
if (!message.member.voice.channel && !guild.voiceChannel) {
return message.reply('you are not in a voice channel!')
}
const vc = message.member.voice.channel
let video
let videos
if (!ignoreQueue) {
videos = await client.music.getVideoByQuery(query)
if (!videos[1]) {
if (!videos[0]) {
video = videos
} else {
video = videos[0]
}
}
}
if (videos || ignoreQueue) {
if (!ignoreQueue) {
// Fix the bot if somehow broken
// music "playing", nothing in queue
if ((guild.playing || guild.dispatcher) && guild.queue.length === 0) {
guild.playing = false
guild.dispatcher = null
// music not playing, something is in queue
} else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) {
guild.queue = []
}
if (!video) {
let output = ''
let i = 0
for (i = 0; i < 5; i++) {
if (!videos[i]) break
output += `\`${i + 1}:\` **[${videos[i].title}](https://www.youtube.com/watch?v=${videos[i].videoId})** \`[${client.createTimestamp(videos[i].lengthSeconds)}]\`\n`
}
const embed = new MessageEmbed()
embed.setTitle('Please reply with a number `1-' + i + '` to select which song you want to add to the queue.')
embed.setColor(client.embedColour(message.guild))
embed.setDescription(output)
const selection = await client.awaitReply(message, embed)
console.log(selection)
switch (selection) {
}
}
if (!video && videos[0]) {
video = videos[0]
} else if (!video) {
video = videos
}
console.log(video)
// Add video to queue
guild.queue.push({ video: video, requestedBy: message.member.id })
}
// Figure out if the bot should add it to queue or play it right now
if (guild.playing) {
message.reply('added **' + video.title + '** to the queue')
} else {
guild.playing = true
guild.voiceChannel = vc
const connection = await vc.join()
const v = guild.queue[0]
guild.dispatcher = connection.play(await ytdl(client.music.getLinkFromID(v.video.videoId), { highWaterMark: 1024 * 1024 * 32 }), { type: 'opus' })
guild.dispatcher.setVolume(0.25)
message.channel.send('Playing **' + v.video.title + '**')
// play next in queue on end
guild.dispatcher.once('finish', () => {
guild.queue.shift()
guild.playing = false
if (guild.queue.length > 0) {
client.music.play(message, null, true)
} else {
guild.dispatcher = null
connection.disconnect()
}
})
}
} else {
return message.reply('failed to find the video!')
}
}
client.music.setVolume = function (guild, target) {
const g = client.music.getGuild(guild.id)
if (g.dispatcher) {
g.dispatcher.setVolume(target)
}
}
client.music.skip = function (guild, reason) {
const g = client.music.getGuild(guild.id)
if (g.dispatcher) {
g.dispatcher.end(reason)
}
}
}