init
This commit is contained in:
commit
ddd5972f72
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/node_modules
|
||||||
|
/.babelrc
|
||||||
|
/yarn.lock
|
||||||
|
/botconfig.json
|
||||||
38
botconfig.sample.json
Normal file
38
botconfig.sample.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"token": "",
|
||||||
|
"api": "https://chat.f95.io/api",
|
||||||
|
"mongoDB": "mongodb://127.0.0.1:27017/zonies",
|
||||||
|
"defaultGuildId": "01HAT8SAMPMRD554Z9942EEHJ7",
|
||||||
|
"owners": ["01HATCHHMPTJBHH534H6VFYKK3"],
|
||||||
|
"prefix": "!",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"mod": "01HB2G8GJHJS1ZA8XSQ6PECG12",
|
||||||
|
"staff": "01HATA3EAVF0H5T9QSD89Z4C9K",
|
||||||
|
"jrmod": "01HB2H2JFY9PWDW7GXRC1SBY4C",
|
||||||
|
"uploader": "01HF78H660P67QXEZPZ9MD1HBZ",
|
||||||
|
"jruploader": "01HF78RZDE32E5CXKS4P85PY54"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"rule7": {
|
||||||
|
"apiKey": ""
|
||||||
|
},
|
||||||
|
"emojis": {
|
||||||
|
"one": "1️⃣",
|
||||||
|
"two": "2️⃣",
|
||||||
|
"three": "3️⃣",
|
||||||
|
"four": "4️⃣",
|
||||||
|
"five": "5️⃣",
|
||||||
|
"six": "6️⃣",
|
||||||
|
"seven": "7️⃣",
|
||||||
|
"eight": "8️⃣",
|
||||||
|
"nine": "9️⃣",
|
||||||
|
"ten": "🔟",
|
||||||
|
"confetti": "🎊",
|
||||||
|
"stop": "🛑",
|
||||||
|
"check": "✅",
|
||||||
|
"cross": "❌"
|
||||||
|
},
|
||||||
|
"tenor_api_key": ""
|
||||||
|
}
|
||||||
26
commands/avatar.js
Normal file
26
commands/avatar.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "avatar",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: ['av']
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
if (message.mentions?.length <= 0) return message.reply('Must mention a user!');
|
||||||
|
const targetName = (message.mentions?.length >= 1 ? message.mentions[0]?.username : message.author.username)
|
||||||
|
const member = await (client.servers.get(message.server.id) || await client.servers.fetch(message.server.id))?.fetchMember(message.mentionIds[0]);
|
||||||
|
const target = message.mentions?.length >= 1 ? member.user.avatar.createFileURL({ max_side: 4096 }, true) ? member.user.avatar.createFileURL({ max_side: 4096 }, true) : message.mentions[0]?.defaultAvatarURL : member.user.avatar.createFileURL({ size: 4096 }, true) ? member.user.avatar.createFileURL({ size: 4096 }, true) : member.user.avatar.createFileURL({ size: 4096 }, true) ? message.author.avatarURL({ size: 4096 }, true) : message.author.avatarURL({ size: 4096 }, true) ? message.author.avatarURL({ size: 4096 }, true) : message.member.user.defaultAvatarURL
|
||||||
|
const embed = { description: "Avatar for [" + targetName + "](" + target + ")", colour: "#00FFFF", iconURL: target }
|
||||||
|
|
||||||
|
await message.channel.sendMessage({ content: "[ ](" + target + ")", embeds: [embed] }).catch(err => {
|
||||||
|
console.log(`${Date(Date.now().toString()).slice(0, 25)}`);
|
||||||
|
console.log("User: " + message.author.username + ` [${message.authorId}] ` + " | Command: avatar | Args: " + (args?.join(" ") || "NONE"))
|
||||||
|
console.log(err.message);
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
90
commands/command.js
Normal file
90
commands/command.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
const CommandsDB = require('../models/commands');
|
||||||
|
const { random } = require('../functions/randomStr');
|
||||||
|
const moment = require('moment');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "command",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 0,
|
||||||
|
available: true,
|
||||||
|
permissions: ['ManageServer'],
|
||||||
|
aliases: ['cmd']
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* HELP
|
||||||
|
*************************************************/
|
||||||
|
if (args[0] === 'help') {
|
||||||
|
let embed = new Embed()
|
||||||
|
.setDescription(`### Custom Commands\n**add**: \`add [name] [content]\`\nEx: \`add soul Fucks his cousin|Is swedish\` or \`add zemax Is the punching bag for uploaders\`\nIf you want to add multiple options to a command use a pipe \`|\`\n\n**delete**: \`delete [name/id]\`\n\n**edit**: \`edit [name/id]\`\n\n**show**: \`show [name/id]\`\n\n`)
|
||||||
|
.setColor(`#A52F05`);
|
||||||
|
return message.reply({ embeds: [embed] }, false);
|
||||||
|
/*************************************************
|
||||||
|
* ADD
|
||||||
|
*************************************************/
|
||||||
|
} else if (args[0] === 'add') {
|
||||||
|
let name = args[1];
|
||||||
|
let content = args[2];
|
||||||
|
const cmd = new CommandsDB();
|
||||||
|
let check = await CommandsDB.findOne({ name: name }).select("name").lean();
|
||||||
|
if (check) return message.reply('Command already exists with that name!');
|
||||||
|
|
||||||
|
if (content.includes('|')) {
|
||||||
|
cmd.id = random(5);
|
||||||
|
cmd.name = name;
|
||||||
|
cmd.content = JSON.stringify(content.split('|'));
|
||||||
|
cmd.createdBy = message.member.user.username;
|
||||||
|
cmd.save();
|
||||||
|
return message.reply('Command saved!');
|
||||||
|
}
|
||||||
|
cmd.id = random(5);
|
||||||
|
cmd.name = name;
|
||||||
|
cmd.content = args.slice(2).join(' ');
|
||||||
|
cmd.createdBy = message.member.user.username;
|
||||||
|
cmd.save();
|
||||||
|
return message.reply('Command saved!');
|
||||||
|
/*************************************************
|
||||||
|
* FIND
|
||||||
|
*************************************************/
|
||||||
|
} else if (args[0] === 'find') {
|
||||||
|
let check = await (CommandsDB.findOne({ name: args[1] }).select("id name").lean() || CommandsDB.findOne({ id: args[1] }).select("id name").lean());
|
||||||
|
if (!check) return message.reply('Command doesn\'t exists with that name or ID!');
|
||||||
|
CommandsDB.findOne({ name: args[1] }).then((data) => {
|
||||||
|
let embed = new Embed()
|
||||||
|
.setDescription(`### Custom Commands: ${data.name}\n**ID**: ${data.id}\n**Content**: ${data.content}\n**Created by**: ${data.createdBy}\n**Created at**: ${moment.unix(data.created_at).format('YYYY/MMM/DD HH:MM:ss')} (UTC)`)
|
||||||
|
.setColor(`#A52F05`);
|
||||||
|
return message.reply({ embeds: [embed] }, false);
|
||||||
|
});
|
||||||
|
/*************************************************
|
||||||
|
* DELETE
|
||||||
|
*************************************************/
|
||||||
|
} else if (args[0] === 'delete') {
|
||||||
|
let check = await (CommandsDB.findOne({ name: args[1] }).select("id name").lean() || CommandsDB.findOne({ id: args[1] }).select("id name").lean());
|
||||||
|
console.log(check)
|
||||||
|
if (!check) return message.reply('Command doesn\'t exists with that name or id!');
|
||||||
|
CommandsDB.deleteMany({ id: check.id }).exec();
|
||||||
|
return message.reply('Command Removed!');
|
||||||
|
/*************************************************
|
||||||
|
* SHOW
|
||||||
|
*************************************************/
|
||||||
|
} else if (args[0] === 'show') {
|
||||||
|
// let cmds = await CommandsDB.find({}).select('name').lean();
|
||||||
|
// console.log(cmds.toString().join(','))
|
||||||
|
let data = CommandsDB.find({}).select('name').then((data) => {
|
||||||
|
let names = [];
|
||||||
|
data.forEach((item) => { names.push(item.name) });
|
||||||
|
message.reply('DM Sent with all available custom commands.');
|
||||||
|
message.member.user.openDM().then((dm) => { dm.sendMessage(names.join(', ')) });
|
||||||
|
});
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* NO ARGS
|
||||||
|
*************************************************/
|
||||||
|
} else {
|
||||||
|
return message.reply(`First argument must be add, delete, edit, show, find or help. You put ${args[0]}`, false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
40
commands/gaydar.js
Normal file
40
commands/gaydar.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
// const { } = require('revolt.js')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "gaydar",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: ['gd']
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
function randomInteger(min, max) {
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
const member = await (client.servers.get(message.server.id) || await client.servers.fetch(message.server.id))?.fetchMember(message.mentionIds[0]).then((user) => {
|
||||||
|
return console.log();
|
||||||
|
});
|
||||||
|
// const target = member.user.username;
|
||||||
|
// return console.log(member)
|
||||||
|
// let amount = randomInteger(1, 100);
|
||||||
|
|
||||||
|
// const embed = {
|
||||||
|
// description: `#### ${target} is ${amount}% gay.`,
|
||||||
|
// colour: "#ff8080",
|
||||||
|
// image: 'https://overlord.lordainz.xyz/f/gaydar.jpg'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await message.channel.sendMessage({ content: "", embeds: [embed] }).catch(err => {
|
||||||
|
// console.log(`${Date(Date.now().toString()).slice(0, 25)}`);
|
||||||
|
// console.log("User: " + message.author.username + ` [${message.authorId}] ` + " | Command: gardar | Args: " + (args?.join(" ") || "NONE"))
|
||||||
|
// console.log(err.message);
|
||||||
|
// return;
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
};
|
||||||
29
commands/gif.js
Normal file
29
commands/gif.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
const fetch = require('node-fetch-commonjs')
|
||||||
|
const config = require('../config')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "gif",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: ['tenor', 'giphy', 'gify']
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
if (!args[0]) return message.reply('Usage: !gif SEARCHTERM | Aliases: gif, tneor, giphy, gify');
|
||||||
|
async function get_gif_url(query) {
|
||||||
|
// Fetches the gif url
|
||||||
|
const gif_response = await fetch(`https://tenor.googleapis.com/v2/search?q=${query}&key=${config.tenor_api_key}&limit=1&media_filter=gif`);
|
||||||
|
// Converts it to json
|
||||||
|
const gif_data = await gif_response.json();
|
||||||
|
// Returns the url
|
||||||
|
return gif_data.results[0].media_formats.gif.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = await get_gif_url(args.join(' '));
|
||||||
|
|
||||||
|
return message.reply(url);
|
||||||
|
},
|
||||||
|
};
|
||||||
30
commands/help.js
Normal file
30
commands/help.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "help",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: ['h']
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
const embed = {
|
||||||
|
description: `**!avatar**: \`!avatar @USER\`\n**Aliases**: \`!av\`\n
|
||||||
|
**!command**: \`!command add NAME CONTENT\`\n**Aliases**: \`!cmd\`\n
|
||||||
|
**!gif**: \`!gif TERM\`\n**Aliases**: \`!gify, !tenor, !giphy\`\n
|
||||||
|
**!polls**: \`!polls TIME | How are you? | Good | Bad\`\n**Aliases**: \`!poll\`\n
|
||||||
|
**!urban**: \`!urban TERM\`\n**Aliases**: \`!ub\`\n\n
|
||||||
|
**Tip**: You can run each command without an argument and it will return how to use it.`, colour: "#00FFFF", title: "Commands Help"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await message.channel.sendMessage({ content: "", embeds: [embed] }).catch(err => {
|
||||||
|
console.log(`${Date(Date.now().toString()).slice(0, 25)}`);
|
||||||
|
console.log("User: " + message.author.username + ` [${message.authorId}] ` + " | Command: help | Args: " + (args?.join(" ") || "NONE"))
|
||||||
|
console.log(err.message);
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
26
commands/info.js
Normal file
26
commands/info.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
const Giveaway = require("../models/giveaways");
|
||||||
|
const SavedPolls = require("../models/savedPolls");
|
||||||
|
const { dependencies } = require("../package.json");
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "info",
|
||||||
|
usage: false,
|
||||||
|
cooldown: 10000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: ["stats"]
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
const unixstamp = client.functions.get("fetchTime")(Math.floor(process.uptime() * 1000), client, db.language)
|
||||||
|
let beforeCall = Date.now();
|
||||||
|
const polls = await SavedPolls.find();
|
||||||
|
let dbPing = Date.now() - beforeCall;
|
||||||
|
|
||||||
|
const embed = new Embed()
|
||||||
|
.setDescription(`### ${client.translate.get(db.language, 'Commands.info.start')}\n${client.translate.get(db.language, 'Commands.info.servers')}: ${client.servers.size().toLocaleString()}\n${client.translate.get(db.language, 'Commands.info.giveaways')}: ${(await Giveaway.find()).length.toLocaleString()}\n${client.translate.get(db.language, 'Commands.info.polls')}: ${polls.length.toLocaleString()}\n${client.translate.get(db.language, 'Commands.info.uptime')}: ${unixstamp}\n\n${client.translate.get(db.language, 'Commands.info.ping')}: ${client.events.ping()}ms\n${client.translate.get(db.language, 'Commands.info.database')}: ${dbPing}ms\n${client.translate.get(db.language, 'Commands.info.library')}: Revolt.js | ${dependencies["revolt.js"]}`)
|
||||||
|
.setColor(`#A52F05`);
|
||||||
|
|
||||||
|
message.reply({ embeds: [embed] }, false)
|
||||||
|
},
|
||||||
|
};
|
||||||
55
commands/polls.js
Normal file
55
commands/polls.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
const Embed = require(`../functions/embed`)
|
||||||
|
const Polls = require(`../functions/poll`)
|
||||||
|
const dhms = require(`../functions/dhms`);
|
||||||
|
const PollDB = require("../models/polls");
|
||||||
|
const SavedPolls = require(`../models/savedPolls`)
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: `polls`,
|
||||||
|
usage: true,
|
||||||
|
cooldown: 10000,
|
||||||
|
available: true,
|
||||||
|
permissions: ['ManageServer'],
|
||||||
|
aliases: ["poll"]
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
// const check = await PollDB.find({ owner: message.authorId })
|
||||||
|
// if (check.length === 5) return message.reply({ embeds: [new Embed().setDescription(client.translate.get(db.language, "Commands.polls.tooMany")).setColor(`#FF0000`)] }, false);
|
||||||
|
const options = args.join(` `).split(`|`).map(x => x.trim()).filter(x => x);
|
||||||
|
if (!options[0]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validTime")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
const time = dhms(options[0]);
|
||||||
|
if (!time) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validTime")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (time === 0) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validTime")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (time < 30000) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.longerThan")} \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (time > 2592000000) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.shorterThan")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (!options[1]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validQuestion")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (!options[2]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validOption")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (!options[3]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validOption2")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (options.length >= 13) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.maxOptions")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
|
||||||
|
const names = [options[2], options[3], options[4] ? options[4] : null, options[5] ? options[5] : null, options[6] ? options[6] : null, options[7] ? options[7] : null, options[8] ? options[8] : null, options[9] ? options[9] : null, options[10] ? options[10] : null, options[11] ? options[11] : null];
|
||||||
|
const reactions = [client.config.emojis.one, client.config.emojis.two, options[4] ? client.config.emojis.three : null, options[5] ? client.config.emojis.four : null, options[6] ? client.config.emojis.five : null, options[7] ? client.config.emojis.six : null, options[8] ? client.config.emojis.seven : null, options[9] ? client.config.emojis.eight : null, options[10] ? client.config.emojis.nine : null, options[11] ? client.config.emojis.ten : null, client.config.emojis.stop];
|
||||||
|
|
||||||
|
const poll = new Polls({ time, client, name: { name: client.translate.get(db.language, "Commands.polls.polls"), description: options[1] }, options: { name: names.filter(a => a) }, owner: message.authorId, lang: db.language })
|
||||||
|
await poll.update();
|
||||||
|
|
||||||
|
let tooMuch = [];
|
||||||
|
if (options[1].length > 75) tooMuch.push(`**${client.translate.get(db.language, "Commands.polls.title")}**: ${options[1]}`)
|
||||||
|
names.filter(e => e).forEach((e, i) => {
|
||||||
|
i++
|
||||||
|
if (e.length > 70) {
|
||||||
|
tooMuch.push(`**${i}.** ${e}`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
message.channel.sendMessage({ embeds: [new Embed().setDescription(tooMuch.length > 0 ? tooMuch.map(e => e).join("\n") : null).setMedia(await client.Uploader.upload(poll.canvas.toBuffer(), `Poll.png`)).setColor(`#A52F05`)], interactions: [reactions.filter(e => e)] }).then((msg) => {
|
||||||
|
poll.start(msg, poll);
|
||||||
|
});
|
||||||
|
|
||||||
|
await (new SavedPolls({
|
||||||
|
owner: message.authorId,
|
||||||
|
desc: options[1],
|
||||||
|
options: { name: names }
|
||||||
|
}).save());
|
||||||
|
},
|
||||||
|
};
|
||||||
22
commands/prefix.js
Normal file
22
commands/prefix.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "prefix",
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
usage: true,
|
||||||
|
permissions: ["ManageServer"],
|
||||||
|
aliases: []
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
const embed = new Embed()
|
||||||
|
.setDescription(`${client.translate.get(db.language, "Commands.prefix.prefix")}: \`${db.prefix}\`\n\n${client.translate.get(db.language, "Commands.prefix.change")} \`${db.prefix}prefix <${client.translate.get(db.language, "Commands.prefix.new")}>\``)
|
||||||
|
if (!args[0]) return message.reply({ embeds: [embed] }, false);
|
||||||
|
if (args[0] === db.prefix) return message.reply({ embeds: [embed] }, false);
|
||||||
|
if (args[0].length > 8) return message.reply(client.translate.get(db.language, "Commands.prefix.tooMany"), false);
|
||||||
|
|
||||||
|
await client.database.updateGuild(message.server.id, { prefix: args[0] });
|
||||||
|
return message.reply(`${client.translate.get(db.language, "Commands.prefix.success")} \`${args[0]}\``, false);
|
||||||
|
},
|
||||||
|
};
|
||||||
170
commands/register.js
Normal file
170
commands/register.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
const axios = require(`axios`);
|
||||||
|
const botConfig = require('../botconfig.json');
|
||||||
|
const { generateUniqueId } = require('../functions/randomStr');
|
||||||
|
const https = require('https');
|
||||||
|
const Invites = require('../models/registerInvite');
|
||||||
|
const Embed = require('../functions/embed');
|
||||||
|
|
||||||
|
// Create axios instance outside of module.exports
|
||||||
|
const makeRequest = axios.create({
|
||||||
|
baseURL: `https://rule7.zonies.xyz/api/v1`,
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${botConfig.rule7.apiKey}`
|
||||||
|
},
|
||||||
|
httpsAgent: new https.Agent({
|
||||||
|
rejectUnauthorized: false
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: `register`,
|
||||||
|
usage: true,
|
||||||
|
cooldown: 10000,
|
||||||
|
available: true,
|
||||||
|
permissions: [''],
|
||||||
|
roles: ['staff', 'uploader', 'jrmod', 'mod'],
|
||||||
|
aliases: ["reg"],
|
||||||
|
dm: true
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
try {
|
||||||
|
// If not in DM, check for permissions and roles
|
||||||
|
if (message.channel.type !== 'DirectMessage') {
|
||||||
|
// Check if user has any of the required roles
|
||||||
|
const hasRequiredRole = message.member.roles.some(role =>
|
||||||
|
module.exports.config.roles.includes(role.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasRequiredRole && !client.config.owners.includes(message.authorId)) {
|
||||||
|
return message.reply({
|
||||||
|
embeds: [
|
||||||
|
new Embed()
|
||||||
|
.setColor("#FF0000")
|
||||||
|
.setDescription(`You don't have the required roles to use this command.`)
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the command is used in a DM
|
||||||
|
if (message.channel.type !== 'DirectMessage') {
|
||||||
|
const inviteCode = generateUniqueId();
|
||||||
|
|
||||||
|
const staffRoles = {
|
||||||
|
is_staff: 0,
|
||||||
|
is_mod: 0,
|
||||||
|
is_jrmod: 0,
|
||||||
|
is_uploader: 0,
|
||||||
|
is_jruploader: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let memberRoles = message.member.roles;
|
||||||
|
|
||||||
|
// Set staff role values based on member's roles
|
||||||
|
if (memberRoles.includes(client.botConfig.roles[0].staff)) staffRoles.is_staff = 1;
|
||||||
|
if (memberRoles.includes(client.botConfig.roles[0].mod)) staffRoles.is_mod = 1;
|
||||||
|
if (memberRoles.includes(client.botConfig.roles[0].jrmod)) staffRoles.is_jrmod = 1;
|
||||||
|
if (memberRoles.includes(client.botConfig.roles[0].uploader)) staffRoles.is_uploader = 1;
|
||||||
|
if (memberRoles.includes(client.botConfig.roles[0].jruploader)) staffRoles.is_jruploader = 1;
|
||||||
|
|
||||||
|
const registerInvite = new Invites({
|
||||||
|
userId: message.author.id,
|
||||||
|
invite: inviteCode,
|
||||||
|
staffRoles,
|
||||||
|
createdAt: Date.now()
|
||||||
|
});
|
||||||
|
|
||||||
|
await registerInvite.save();
|
||||||
|
|
||||||
|
return message.reply({
|
||||||
|
content: `Run this command in a DM to the bot and use this invite code: \`${inviteCode}\`\n
|
||||||
|
**Usage:** \`!register ${inviteCode} <username> <email> <f95zone profile url>\`\n
|
||||||
|
**Note: This invite code will expire in 10 minutes.**`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const [invite, username, email, profileUrl] = args;
|
||||||
|
|
||||||
|
if (!invite || !username || !email || !profileUrl) {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG3] Please provide a invite code, username, email, and f95zone profile url. \n\n**Usage:** \`${client.prefix}register <invite> <username> <email> <f95zone profile url>\``
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// DM flow - Use client.database instead of direct model
|
||||||
|
const registerInvite = await Invites.findOne({ invite: invite });
|
||||||
|
|
||||||
|
if (!registerInvite) {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG1] You don't have an invite code. Please run the command outside of DMs.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registerInvite.createdAt + 10 * 60 * 1000 < Date.now()) {
|
||||||
|
await registerInvite.deleteOne({ invite: invite });
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG2] Your invite code has expired. Please run the command outside of DMs.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invite !== registerInvite.invite) {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG4] Invalid invite code. Please run the command outside of DMs.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let f95zoneId = profileUrl.split('/')[4];
|
||||||
|
f95zoneId = f95zoneId.split('.')[1];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data } = await makeRequest.post(`/bot/register`, {
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
f95_id: f95zoneId,
|
||||||
|
is_staff: registerInvite.staffRoles.is_staff,
|
||||||
|
is_mod: registerInvite.staffRoles.is_mod,
|
||||||
|
is_jrmod: registerInvite.staffRoles.is_jrmod,
|
||||||
|
is_uploader: registerInvite.staffRoles.is_uploader,
|
||||||
|
is_jruploader: registerInvite.staffRoles.is_jruploader
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.status === 'success') {
|
||||||
|
await registerInvite.deleteOne({ invite: invite });
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG5] You have been registered. Please check your email for verification.`
|
||||||
|
});
|
||||||
|
} else if (data.status === 'invalid_email') {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG5.1] An error occurred during registration. ${data.msg}`
|
||||||
|
});
|
||||||
|
} else if (data.status === 'username_exists') {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG5.2] An error occurred during registration. ${data.msg}`
|
||||||
|
});
|
||||||
|
} else if (data.status === 'invalid_f95_id') {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG5.3] An error occurred during registration. ${data.msg}`
|
||||||
|
});
|
||||||
|
} else if (data.status === 'email_exists') {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG5.4] An error occurred during registration. ${data.msg}`
|
||||||
|
});
|
||||||
|
} else if (data.status === 'error') {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG5.5] An error occurred during registration. ${data.msg}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (apiError) {
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG6] An error occurred during registration. Please try again later.\n\`${apiError}\``
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Registration Error:', error);
|
||||||
|
return message.reply({
|
||||||
|
content: `[REG7] An unexpected error occurred. Please try again later.\n\`${error}\``
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
31
commands/reload.js
Normal file
31
commands/reload.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
const Reload = require("../functions/reload")
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "reload",
|
||||||
|
cooldown: 0,
|
||||||
|
available: "Owner",
|
||||||
|
permissions: [],
|
||||||
|
aliases: ["r"]
|
||||||
|
},
|
||||||
|
run: async (client, message, args) => {
|
||||||
|
if (!client.config.owners.includes(message.authorId)) return;
|
||||||
|
if (!args[0]) return message.reply("Provide either a category or a command to reload.", false)
|
||||||
|
if (args[0] === "category") {
|
||||||
|
let error = [];
|
||||||
|
let success = [];
|
||||||
|
|
||||||
|
if (!args[1]) return message.reply("Provide a category's name to reload it.", false)
|
||||||
|
|
||||||
|
client.commands.filter(c => c.config.category === args[1]).map(cc => {
|
||||||
|
Reload(client, cc.config.category, cc.config.name, args[2])
|
||||||
|
|
||||||
|
let check = client.reloadCommand(args[1], cc.config.name)
|
||||||
|
if (check.includes("Error")) return error.push(check)
|
||||||
|
else if (check.includes("Reloaded command:")) return success.push("1")
|
||||||
|
})
|
||||||
|
|
||||||
|
return message.reply(`\`\`\`css\nSuccessful Commands: ${success.length}\nErrored Commands: ${error.length} ${error.length > 0 ? "\n" + error.map(c => c).join("\n") : " "}`, false)
|
||||||
|
}
|
||||||
|
message.reply(Reload(client, args[0], args[1], args[2]), false)
|
||||||
|
}
|
||||||
|
}
|
||||||
55
commands/rule7.js
Normal file
55
commands/rule7.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
const Embed = require(`../functions/embed`)
|
||||||
|
const Polls = require(`../functions/poll`)
|
||||||
|
const dhms = require(`../functions/dhms`);
|
||||||
|
const PollDB = require("../models/rule7");
|
||||||
|
const SavedPolls = require(`../models/savedPolls`)
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: `rule7`,
|
||||||
|
usage: true,
|
||||||
|
cooldown: 10000,
|
||||||
|
available: true,
|
||||||
|
permissions: ['ManageServer'],
|
||||||
|
aliases: ["r7"]
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
// const check = await PollDB.find({ owner: message.authorId })
|
||||||
|
// if (check.length === 5) return message.reply({ embeds: [new Embed().setDescription(client.translate.get(db.language, "Commands.polls.tooMany")).setColor(`#FF0000`)] }, false);
|
||||||
|
const options = args.join(` `).split(`|`).map(x => x.trim()).filter(x => x);
|
||||||
|
if (!options[0]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validTime")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
const time = dhms(options[0]);
|
||||||
|
if (!time) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validTime")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (time === 0) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validTime")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (time < 30000) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.longerThan")} \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (time > 2592000000) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.shorterThan")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (!options[1]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validQuestion")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (!options[2]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validOption")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (!options[3]) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.validOption2")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
if (options.length >= 13) return message.reply({ embeds: [new Embed().setDescription(`${client.translate.get(db.language, "Commands.polls.maxOptions")}: \`${client.config.prefix}polls 5m | ${client.translate.get(db.language, "Commands.polls.example")}\``).setColor(`#FF0000`)] }, false);
|
||||||
|
|
||||||
|
const names = [options[2], options[3], options[4] ? options[4] : null, options[5] ? options[5] : null, options[6] ? options[6] : null, options[7] ? options[7] : null, options[8] ? options[8] : null, options[9] ? options[9] : null, options[10] ? options[10] : null, options[11] ? options[11] : null];
|
||||||
|
const reactions = [client.config.emojis.one, client.config.emojis.two, options[4] ? client.config.emojis.three : null, options[5] ? client.config.emojis.four : null, options[6] ? client.config.emojis.five : null, options[7] ? client.config.emojis.six : null, options[8] ? client.config.emojis.seven : null, options[9] ? client.config.emojis.eight : null, options[10] ? client.config.emojis.nine : null, options[11] ? client.config.emojis.ten : null, client.config.emojis.stop];
|
||||||
|
|
||||||
|
const poll = new Polls({ time, client, name: { name: client.translate.get(db.language, "Commands.polls.polls"), description: options[1] }, options: { name: names.filter(a => a) }, owner: message.authorId, lang: db.language })
|
||||||
|
await poll.update();
|
||||||
|
|
||||||
|
let tooMuch = [];
|
||||||
|
if (options[1].length > 75) tooMuch.push(`**${client.translate.get(db.language, "Commands.polls.title")}**: ${options[1]}`)
|
||||||
|
names.filter(e => e).forEach((e, i) => {
|
||||||
|
i++
|
||||||
|
if (e.length > 70) {
|
||||||
|
tooMuch.push(`**${i}.** ${e}`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
message.channel.sendMessage({ embeds: [new Embed().setDescription(tooMuch.length > 0 ? tooMuch.map(e => e).join("\n") : null).setMedia(await client.Uploader.upload(poll.canvas.toBuffer(), `Poll.png`)).setColor(`#A52F05`)], interactions: [reactions.filter(e => e)] }).then((msg) => {
|
||||||
|
poll.start(msg, poll);
|
||||||
|
});
|
||||||
|
|
||||||
|
await (new SavedPolls({
|
||||||
|
owner: message.authorId,
|
||||||
|
desc: options[1],
|
||||||
|
options: { name: names }
|
||||||
|
}).save());
|
||||||
|
},
|
||||||
|
};
|
||||||
19
commands/template.txt
Normal file
19
commands/template.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: []
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
|
||||||
|
new Paginator([], { timeout: 5 * 2e4, user: message.authorId, client: client })
|
||||||
|
.add([embed, embed2])
|
||||||
|
.start(message.channel);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
36
commands/urban.js
Normal file
36
commands/urban.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config: {
|
||||||
|
name: "urban",
|
||||||
|
usage: true,
|
||||||
|
cooldown: 5000,
|
||||||
|
available: true,
|
||||||
|
permissions: [],
|
||||||
|
aliases: ['ub']
|
||||||
|
},
|
||||||
|
run: async (client, message, args, db) => {
|
||||||
|
let query = args.join(' ');
|
||||||
|
const url = ('https://api.urbandictionary.com/v0/define?term=' + query)
|
||||||
|
const response = await axios.get(url);
|
||||||
|
const data = response.data;
|
||||||
|
const def = data.list[0];
|
||||||
|
var length = data.list.length
|
||||||
|
if (parseInt(length) < 1) {
|
||||||
|
message.reply("No results")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = {
|
||||||
|
description: `### Definition for ${query}\n\n${def.definition}\n\n**Example**:\n\`\`\`${def.example}\`\`\` \n\n:thumbsup: ${def.thumbs_up} :thumbsdown: ${def.thumbs_down}\n\n**Link**: [${query}](${def.permalink})`,
|
||||||
|
colour: "#00FFFF"
|
||||||
|
}
|
||||||
|
await message.channel.sendMessage({ content: "", embeds: [embed] }).catch(err => {
|
||||||
|
console.log(`${Date(Date.now().toString()).slice(0, 25)}`);
|
||||||
|
console.log("User: " + message.author.username + ` [${message.authorId}] ` + " | Command: urban | Args: " + (args?.join(" ") || "NONE"))
|
||||||
|
console.log(err.message);
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
23
config.js
Normal file
23
config.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
const config = {
|
||||||
|
"owners": ["01HATCHHMPTJBHH534H6VFYKK3"],
|
||||||
|
"prefix": "!",
|
||||||
|
"emojis": {
|
||||||
|
"one": "1️⃣",
|
||||||
|
"two": "2️⃣",
|
||||||
|
"three": "3️⃣",
|
||||||
|
"four": "4️⃣",
|
||||||
|
"five": "5️⃣",
|
||||||
|
"six": "6️⃣",
|
||||||
|
"seven": "7️⃣",
|
||||||
|
"eight": "8️⃣",
|
||||||
|
"nine": "9️⃣",
|
||||||
|
"ten": "🔟",
|
||||||
|
"confetti": "🎊",
|
||||||
|
"stop": "🛑",
|
||||||
|
"check": "✅",
|
||||||
|
"cross": "❌",
|
||||||
|
},
|
||||||
|
"tenor_api_key": "AIzaSyCBUnqtNWMPn3f7F4Iu09KewGS8BfwUkDE",
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
7
ecosystem.config.js
Normal file
7
ecosystem.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
apps : [{
|
||||||
|
name : "Zonies",
|
||||||
|
script : "./index.js",
|
||||||
|
node_args: "--experimental-specifier-resolution=node"
|
||||||
|
}]
|
||||||
|
}
|
||||||
145
events/messageCreate.js
Normal file
145
events/messageCreate.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
const Collector = require("../functions/messageCollector");
|
||||||
|
const EditCollector = require("../functions/messageEdit");
|
||||||
|
const CommandDB = require('../models/commands');
|
||||||
|
const { isJson } = require('../functions/randomStr');
|
||||||
|
const logger = require('../functions/logger');
|
||||||
|
const audit = require('../functions/audit');
|
||||||
|
|
||||||
|
module.exports = async (client, message) => {
|
||||||
|
// Early return checks
|
||||||
|
if (!message || !message.content || message.author.bot) return;
|
||||||
|
|
||||||
|
const isDM = message.channel.type === "DirectMessage";
|
||||||
|
|
||||||
|
// Get guild settings (if not DM)
|
||||||
|
const db = isDM ? { prefix: client.botConfig.prefix, language: 'en' } : await client.database.getGuild(message.server.id, true);
|
||||||
|
|
||||||
|
// Check if message starts with prefix
|
||||||
|
if (!message.content.startsWith(db.prefix)) {
|
||||||
|
// Handle bot mention
|
||||||
|
if (message.content && (new RegExp(`^(<@!?${client.user.id}>)`)).test(message.content)) {
|
||||||
|
const mention = new Embed()
|
||||||
|
.setColor("#A52F05")
|
||||||
|
.setTitle(client.user.username)
|
||||||
|
.setDescription(`${client.translate.get(db.language, "Events.messageCreate.prefix")} \`${db.prefix}\`\n${client.translate.get(db.language, "Events.messageCreate.prefix2")} \`${db.prefix}help\``)
|
||||||
|
|
||||||
|
return message.reply({
|
||||||
|
embeds: [mention]
|
||||||
|
}, false).catch(() => { return });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let args = message.content.slice(db.prefix.length).trim().split(/ +/g);
|
||||||
|
let cmd = args.shift().toLowerCase();
|
||||||
|
|
||||||
|
// Handle collectors
|
||||||
|
if (client.messageCollector.has(message.authorId) && client.messageCollector.get(message.authorId).channelId === message.channelId && !client.messageCollector.get(message.authorId).messageId) return await Collector(client, message, db);
|
||||||
|
if (client.messageEdit.has(message.authorId) && client.messageEdit.get(message.authorId).channelId === message.channelId && !client.messageEdit.get(message.authorId).messageId) return await EditCollector(client, message, db);
|
||||||
|
|
||||||
|
// Handle custom commands
|
||||||
|
let check = await CommandDB.findOne({ name: cmd }).select("name").lean();
|
||||||
|
if (check) {
|
||||||
|
CommandDB.findOne({ name: cmd }).then((data) => {
|
||||||
|
if (isJson(data.content)) {
|
||||||
|
let items = JSON.parse(data.content);
|
||||||
|
let item = items[Math.floor(Math.random() * items.length)];
|
||||||
|
return message.reply(item);
|
||||||
|
}
|
||||||
|
return message.reply(data.content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command handling
|
||||||
|
let commandfile = client.commands.get(cmd) || client.commands.get(client.aliases.get(cmd));
|
||||||
|
if (commandfile) {
|
||||||
|
// DM Check - if command doesn't allow DMs and we're in a DM, return
|
||||||
|
if (isDM && !commandfile.config.dm) {
|
||||||
|
return message.reply({
|
||||||
|
embeds: [new Embed()
|
||||||
|
.setColor("#FF0000")
|
||||||
|
.setDescription(client.translate.get(db.language, "Events.messageCreate.noDM"))]
|
||||||
|
}, false).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission checks for non-DM messages
|
||||||
|
if (!isDM) {
|
||||||
|
// Check bot permissions first
|
||||||
|
const canSendMessage = message.channel.havePermission("SendMessage");
|
||||||
|
const canReact = message.channel.havePermission("React");
|
||||||
|
|
||||||
|
if (!canSendMessage) {
|
||||||
|
return message.member.user.openDM().then((dm) => {
|
||||||
|
dm.sendMessage(`${client.translate.get(db.language, "Events.messageCreate.unable")} <#${message.channelId}>. ${client.translate.get(db.language, "Events.messageCreate.contact")}.`)
|
||||||
|
}).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canReact) {
|
||||||
|
return message.reply(`${client.translate.get(db.language, "Events.messageCreate.noPerms")}. ${client.translate.get(db.language, "Events.messageCreate.contact")}.`, false).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user has required roles
|
||||||
|
const hasRequiredRole = commandfile.config.roles && message.member.roles && client.botConfig.roles && client.botConfig.roles.length > 0 ?
|
||||||
|
message.member.roles.some(role => {
|
||||||
|
const whitelistedRoles = Object.values(client.botConfig.roles[0] || {});
|
||||||
|
return whitelistedRoles.includes(role);
|
||||||
|
}) : false;
|
||||||
|
|
||||||
|
// Command availability check (skip for DMs)
|
||||||
|
if (!commandfile.config.available && !hasRequiredRole && !client.botConfig.owners.includes(message.authorId)) {
|
||||||
|
return message.reply({
|
||||||
|
embeds: [new Embed()
|
||||||
|
.setColor("#FF0000")
|
||||||
|
.setDescription(client.translate.get(db.language, "Events.messageCreate.unavail"))]
|
||||||
|
}, false).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission and role checks (skip for DMs)
|
||||||
|
const needsPermissionCheck = commandfile.config.permissions && commandfile.config.permissions.length > 0;
|
||||||
|
const needsRoleCheck = commandfile.config.roles && commandfile.config.roles.length > 0;
|
||||||
|
|
||||||
|
if (needsPermissionCheck || needsRoleCheck) {
|
||||||
|
let hasPermission = true;
|
||||||
|
|
||||||
|
if (needsPermissionCheck) {
|
||||||
|
try {
|
||||||
|
hasPermission = message.member.hasPermission(commandfile.config.permissions[0]);
|
||||||
|
} catch (err) {
|
||||||
|
hasPermission = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPermission && !hasRequiredRole && !client.botConfig.owners.includes(message.authorId)) {
|
||||||
|
return message.reply({
|
||||||
|
embeds: [new Embed()
|
||||||
|
.setColor("#FF0000")
|
||||||
|
.setDescription(`${client.translate.get(db.language, "Events.messageCreate.perms")}.\n${needsPermissionCheck ? `${client.translate.get(db.language, "Events.messageCreate.perms2")}: [${commandfile.config.permissions[0]}]` : ''}`)]
|
||||||
|
}, false).catch(() => { return });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cooldown handling
|
||||||
|
const used = client.used.get(`${message.authorId}-${cmd.toLowerCase()}`);
|
||||||
|
if (used) {
|
||||||
|
if (client.timeout.get(`${message.authorId}-${cmd.toLowerCase()}`)) return;
|
||||||
|
|
||||||
|
client.timeout.set(`${message.authorId}-${cmd.toLowerCase()}`, used);
|
||||||
|
setTimeout(() => client.timeout.delete(`${message.authorId}-${cmd.toLowerCase()}`), used);
|
||||||
|
|
||||||
|
const uremaining = client.functions.get("fetchTime")(used, client, db.language)
|
||||||
|
const embed = new Embed()
|
||||||
|
.setColor("#A52F05")
|
||||||
|
.setDescription(`<@${message.authorId}>, ${client.translate.get(db.language, "Events.messageCreate.wait")} \`${uremaining}\` ${client.translate.get(db.language, "Events.messageCreate.wait2")} \`${cmd.toLowerCase()}\` ${client.translate.get(db.language, "Events.messageCreate.wait3")}.`)
|
||||||
|
|
||||||
|
return message.reply({ embeds: [embed] }, false).catch(() => { return })
|
||||||
|
} else {
|
||||||
|
let cooldown = commandfile.config.cooldown;
|
||||||
|
client.used.set(`${message.authorId}-${cmd.toLowerCase()}`, cooldown);
|
||||||
|
setTimeout(() => client.used.delete(`${message.authorId}-${cmd.toLowerCase()}`), cooldown);
|
||||||
|
|
||||||
|
return commandfile.run(client, message, args, db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
events/messageDelete.js
Normal file
25
events/messageDelete.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const PollDB = require("../models/polls");
|
||||||
|
const Giveaways = require("../models/giveaways");
|
||||||
|
const GuildDB = require("../models/guilds");
|
||||||
|
module.exports = async (client, msg) => {
|
||||||
|
const paginateCheck = client.paginate.get(msg.authorId);
|
||||||
|
const pollCheck = client.polls.get(msg.id);
|
||||||
|
if (paginateCheck) {
|
||||||
|
client.paginate.delete(msg.authorId);
|
||||||
|
} else if (pollCheck) {
|
||||||
|
client.polls.delete(msg.id);
|
||||||
|
await PollDB.findOneAndDelete({ messageId: msg.id });
|
||||||
|
} else {
|
||||||
|
const db = await Giveaways.findOne({ messageId: msg.id });
|
||||||
|
if (db) {
|
||||||
|
await db.updateOne({ ended: true, endDate: Date.now() })
|
||||||
|
await db.save();
|
||||||
|
} else {
|
||||||
|
const db2 = await GuildDB.findOne({ "roles": { $elemMatch: { msgId: msg.id } } });
|
||||||
|
if (db2) {
|
||||||
|
db2.roles = db2.roles.filter(e => e.msgId !== msg.id);
|
||||||
|
await db2.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
220
events/messageReactionAdd.js
Normal file
220
events/messageReactionAdd.js
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
const PollDB = require("../models/polls");
|
||||||
|
const Giveaways = require("../models/giveaways");
|
||||||
|
const emojis = [{ name: "1️⃣", id: 0 }, { name: "2️⃣", id: 1 }, { name: "3️⃣", id: 2 }, { name: "4️⃣", id: 3 }, { name: "5️⃣", id: 4 }, { name: "6️⃣", id: 5 }, { name: "7️⃣", id: 6 }, { name: "8️⃣", id: 7 }, { name: "9️⃣", id: 8 }, { name: "🔟", id: 9 }, { name: "🛑", id: "stop" }]
|
||||||
|
const colors = /^([A-Z0-9]+)/;
|
||||||
|
|
||||||
|
module.exports = async (client, message, userId, emojiId) => {
|
||||||
|
const paginateCheck = client.paginate.get(userId);
|
||||||
|
const pollCheck = client.polls.get(message.id);
|
||||||
|
const collector = client.messageCollector.get(userId);
|
||||||
|
const editCollector = client.messageEdit.get(userId);
|
||||||
|
|
||||||
|
if (collector && collector.messageId === message.id || collector?.oldMessageId && collector?.oldMessageId === message.id && collector.channelId === message.channelId) {
|
||||||
|
if (emojiId === client.config.emojis.check) {
|
||||||
|
if (collector.roles.length === 0) {
|
||||||
|
const db = await client.database.getGuild(message.server.id);
|
||||||
|
message.delete().catch(() => { });
|
||||||
|
client.messages.get(collector?.oldMessageId)?.delete().catch(() => { })
|
||||||
|
const reactions = [...collector.rolesDone.map(e => e.emoji)];
|
||||||
|
message.channel.sendMessage(collector.type === "content" ? { content: `${message.content}\n\n##### ${client.translate.get(db.language, "Events.messageReactionAdd.cooldown")}`, interactions: [reactions] } : { embeds: [new Embed().setColor("#A52F05").setDescription(`${client.messages.get(message.id).embeds[0].description}\n\n##### ${client.translate.get(db.language, "Events.messageReactionAdd.cooldown")}`)], interactions: [reactions] }).then(async (msg) => {
|
||||||
|
db.roles.push({ msgId: msg.id, chanId: msg.channelId, roles: [...collector.rolesDone] });
|
||||||
|
await client.database.updateGuild(msg.server.id, { roles: db.roles });
|
||||||
|
});
|
||||||
|
|
||||||
|
clearTimeout(client.messageCollector.get(userId).timeout);
|
||||||
|
return client.messageCollector.delete(userId);
|
||||||
|
} else return;
|
||||||
|
} else if (emojiId === client.config.emojis.cross) {
|
||||||
|
const db = await client.database.getGuild(message.server.id);
|
||||||
|
client.messageCollector.delete(userId);
|
||||||
|
return message.reply({ embeds: [new Embed().setColor("#A52F05").setDescription(client.translate.get(db.language, "Events.messageReactionAdd.deleteCollector"))] },);
|
||||||
|
} else {
|
||||||
|
if (collector.roles.length === 0) return;
|
||||||
|
let emote;
|
||||||
|
if (colors.test(emojiId)) emote = `:${emojiId}:`;
|
||||||
|
else if (!colors.test(emojiId)) emote = emojiId
|
||||||
|
collector.rolesDone.push({ emoji: emojiId, role: collector.roles[0][0], name: collector.roles[0][1].name, color: collector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : collector.roles[0][1].colour });
|
||||||
|
message.edit(collector.type === "content" ? { content: message.content.replace(`{role:${collector.regex[0]}}`, `${emote} $\\text{\\textcolor{${collector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : collector.roles[0][1].colour}}{${collector.roles[0][1].name}}}$`) } : { embeds: [new Embed().setColor("#A52F05").setDescription(client.messages.get(message.id).embeds[0].description.replace(`{role:${collector.regex[0]}}`, `:${emojiId}: $\\text{\\textcolor{${collector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : collector.roles[0][1].colour}}{${collector.roles[0][1].name}}}$`))] })
|
||||||
|
collector.roles.shift();
|
||||||
|
return collector.regex.shift();
|
||||||
|
}
|
||||||
|
} else if (editCollector && editCollector.messageId === message.id || editCollector?.botMessage && editCollector?.botMessage === message.id && editCollector.channelId === message.channelId) {
|
||||||
|
if (emojiId === client.config.emojis.check) {
|
||||||
|
if (editCollector.roles.length === 0) {
|
||||||
|
const db = await client.database.getGuild(message.server.id);
|
||||||
|
message.delete().catch(() => { });
|
||||||
|
client.messages.get(editCollector?.oldMessageId)?.delete().catch(() => { })
|
||||||
|
client.messages.get(editCollector?.botMessage)?.delete().catch(() => { })
|
||||||
|
const reactions = [...editCollector.rolesDone.map(e => e.emoji)];
|
||||||
|
message.channel.sendMessage(editCollector.type === "content" ? { content: `${message.content}\n\n##### ${client.translate.get(db.language, "Events.messageReactionAdd.cooldown")}`, interactions: [reactions] } : { embeds: [new Embed().setColor("#A52F05").setDescription(`${client.messages.get(message.id).embeds[0].description}\n\n##### ${client.translate.get(db.language, "Events.messageReactionAdd.cooldown")}`)], interactions: [reactions] }).then(async (msg) => {
|
||||||
|
db.roles.push({ msgId: msg.id, chanId: msg.channelId, roles: [...editCollector.rolesDone] });
|
||||||
|
await client.database.updateGuild(msg.server.id, { roles: db.roles.filter(e => e.msgId !== editCollector.oldMessageId) });
|
||||||
|
});
|
||||||
|
|
||||||
|
clearTimeout(client.messageEdit.get(userId).timeout);
|
||||||
|
return client.messageEdit.delete(userId);
|
||||||
|
} else return;
|
||||||
|
} else if (emojiId === client.config.emojis.cross) {
|
||||||
|
const db = await client.database.getGuild(message.server.id);
|
||||||
|
client.messageEdit.delete(userId);
|
||||||
|
return message.reply({ embeds: [new Embed().setColor("#A52F05").setDescription(client.translate.get(db.language, "Events.messageReactionAdd.deleteCollector"))] },);
|
||||||
|
} else {
|
||||||
|
if (editCollector.roles.length === 0) return;
|
||||||
|
let emote;
|
||||||
|
if (colors.test(emojiId)) emote = `:${emojiId}:`;
|
||||||
|
else if (!colors.test(emojiId)) emote = emojiId
|
||||||
|
editCollector.rolesDone.push({ emoji: emojiId, role: editCollector.roles[0][0], name: editCollector.roles[0][1].name, color: editCollector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : editCollector.roles[0][1].colour });
|
||||||
|
message.edit(editCollector.type === "content" ? { content: message.content.replace(`{role:${editCollector.regex[0]}}`, `${emote} $\\text{\\textcolor{${editCollector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : editCollector.roles[0][1].colour}}{${editCollector.roles[0][1].name}}}$`) } : { embeds: [new Embed().setColor("#A52F05").setDescription(client.messages.get(message.id).embeds[0].description.replace(`{role:${editCollector.regex[0]}}`, `:${emojiId}: $\\text{\\textcolor{${editCollector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : editCollector.roles[0][1].colour}}{${editCollector.roles[0][1].name}}}$`))] })
|
||||||
|
editCollector.roles.shift();
|
||||||
|
return editCollector.regex.shift();
|
||||||
|
}
|
||||||
|
} else if (paginateCheck && paginateCheck.message == message.id) {
|
||||||
|
let pages = paginateCheck.pages;
|
||||||
|
let page = paginateCheck.page;
|
||||||
|
switch (emojiId) {
|
||||||
|
case "⏪":
|
||||||
|
if (page !== 0) {
|
||||||
|
message.edit({
|
||||||
|
embeds: [pages[0]]
|
||||||
|
}).catch(() => { });
|
||||||
|
return paginateCheck.page = 0
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "⬅️":
|
||||||
|
if (pages[page - 1]) {
|
||||||
|
message.edit({
|
||||||
|
embeds: [pages[--page]]
|
||||||
|
}).catch(() => { });
|
||||||
|
return paginateCheck.page = paginateCheck.page - 1
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "➡️":
|
||||||
|
if (pages[page + 1]) {
|
||||||
|
message.edit({
|
||||||
|
embeds: [pages[++page]]
|
||||||
|
}).catch(() => { });
|
||||||
|
return paginateCheck.page = paginateCheck.page + 1
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "⏩":
|
||||||
|
if (page !== pages.length) {
|
||||||
|
message.edit({
|
||||||
|
embeds: [pages[pages.length - 1]]
|
||||||
|
}).catch(() => { });
|
||||||
|
return paginateCheck.page = pages.length - 1
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pollCheck) {
|
||||||
|
let tooMuch = [];
|
||||||
|
if (pollCheck.poll.options.description.length > 80) tooMuch.push(`**${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.title")}**: ${pollCheck.poll.options.description}`)
|
||||||
|
pollCheck.poll.voteOptions.name.filter(e => e).forEach((e, i) => {
|
||||||
|
i++
|
||||||
|
if (e.length > 70) {
|
||||||
|
tooMuch.push(`**${i}.** ${e}`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let convert = emojis.findIndex(e => e.name === emojiId);
|
||||||
|
if (convert === 10 && pollCheck.owner === userId) {
|
||||||
|
await PollDB.findOneAndDelete({ messageId: message.id });
|
||||||
|
await pollCheck.poll.update();
|
||||||
|
message.edit({ content: `${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.owner")} (<@${pollCheck.owner}>) ${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.end")}:`, embeds: [new Embed().setDescription(tooMuch.length > 0 ? tooMuch.map(e => e).join("\n") : null).setMedia(await client.Uploader.upload(pollCheck.poll.canvas.toBuffer(), `Poll.png`)).setColor("#F24646")] }).catch(() => { });
|
||||||
|
return client.polls.delete(message.id);
|
||||||
|
} else if (convert === 0 && convert !== 10 || convert !== -1 && convert !== 10) {
|
||||||
|
if (client.reactions.get(userId)) return client.users.get(userId)?.openDM().then(dm => dm.sendMessage(client.translate.get(pollCheck.lang, "Events.messageReactionAdd.tooFast"))).catch(() => { });
|
||||||
|
if (pollCheck.users.includes(userId)) return;
|
||||||
|
pollCheck.users.push(userId);
|
||||||
|
const user = (client.users.get(userId)) || await client.users.fetch(userId);
|
||||||
|
// console.log(user.avatar.id ? user.avatar.createFileURL() : 'https://chat.f95.io/api/users/01HATCWS7XZ7KEHW64AV20SMKR/default_avatar')
|
||||||
|
await pollCheck.poll.addVote(convert, userId, 'https://chat.f95.io/api/users/01HATCWS7XZ7KEHW64AV20SMKR/default_avatar', message.id);
|
||||||
|
message.edit({ embeds: [new Embed().setDescription(tooMuch.length > 0 ? tooMuch.map(e => e).join("\n") : null).setMedia(await client.Uploader.upload(pollCheck.poll.canvas.toBuffer(), `Poll.png`)).setColor("#A52F05")] }).catch(() => { });
|
||||||
|
client.reactions.set(userId, Date.now() + 3000)
|
||||||
|
return setTimeout(() => client.reactions.delete(userId), 3000)
|
||||||
|
} else return;
|
||||||
|
} else {
|
||||||
|
const db = await Giveaways.findOne({ messageId: message.id });
|
||||||
|
if (db) {
|
||||||
|
if (emojiId === client.config.emojis.confetti && db && !db.ended) {
|
||||||
|
if (client.reactions.get(userId)) return;
|
||||||
|
if (db.users.find(u => u.userID === userId)) return;
|
||||||
|
db.users.push({ userID: userId });
|
||||||
|
db.picking.push({ userID: userId });
|
||||||
|
db.save();
|
||||||
|
|
||||||
|
client.reactions.set(userId, Date.now() + 3000)
|
||||||
|
setTimeout(() => client.reactions.delete(userId), 3000)
|
||||||
|
|
||||||
|
client.users.get(userId)?.openDM().then(dm => dm.sendMessage(`${client.translate.get(db.lang, "Events.messageReactionAdd.joined")} [${db.prize}](https://chat.f95.io/server/${db.serverId}/channel/${db.channelId}/${db.messageId})!\n${client.translate.get(db.lang, "Events.messageReactionAdd.joined2")} **${db.users.length}** ${client.translate.get(db.lang, "Events.messageReactionAdd.joined3")}`)).catch(() => { });
|
||||||
|
} else if (emojiId === client.config.emojis.stop && db && db.owner === userId && !db.ended) {
|
||||||
|
let endDate = Date.now();
|
||||||
|
|
||||||
|
if (db.users.length === 0) {
|
||||||
|
const noUsers = new Embed()
|
||||||
|
.setColor("#A52F05")
|
||||||
|
.setTitle(client.translate.get(db.lang, "Events.messageReactionAdd.giveaway"))
|
||||||
|
.setDescription(`${client.translate.get(db.lang, "Events.messageReactionAdd.owner")} (<@${userId}>) ${client.translate.get(db.lang, "Events.messageReactionAdd.early")}\n${client.translate.get(db.lang, "Events.messageReactionAdd.endNone")}!\n\n${client.translate.get(db.lang, "Events.messageReactionAdd.ended")}: <t:${Math.floor((endDate) / 1000)}:R>\n${client.translate.get(db.lang, "Events.messageReactionAdd.prize")}: ${db.prize}\n${client.translate.get(db.lang, "Events.messageReactionAdd.winnersNone")}${db.requirement ? `\n${client.translate.get(db.lang, "Events.messageReactionAdd.reqs")}: ${db.requirement}` : ``}`)
|
||||||
|
|
||||||
|
await db.updateOne({ ended: true, endDate: endDate })
|
||||||
|
await db.save();
|
||||||
|
return await client.api.patch(`/channels/${db.channelId}/messages/${db.messageId}`, { "embeds": [noUsers] });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < db.winners; i++) {
|
||||||
|
let winner = db.picking[Math.floor(Math.random() * db.picking.length)];
|
||||||
|
if (winner) {
|
||||||
|
const filtered = db.picking.filter(object => object.userID != winner.userID)
|
||||||
|
db.picking = filtered;
|
||||||
|
db.pickedWinners.push({ id: winner.userID })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.updateOne({ ended: true, endDate: endDate })
|
||||||
|
await db.save();
|
||||||
|
|
||||||
|
const noUsers = new Embed()
|
||||||
|
.setColor("#A52F05")
|
||||||
|
.setTitle(client.translate.get(db.lang, "Events.messageReactionAdd.giveaway"))
|
||||||
|
.setDescription(`${client.translate.get(db.lang, "Events.messageReactionAdd.owner")} (<@${userId}>) ${client.translate.get(db.lang, "Events.messageReactionAdd.early")}\n${client.translate.get(db.lang, "Events.messageReactionAdd.partici")}: ${db.users.length}\n\n${client.translate.get(db.lang, "Events.messageReactionAdd.ended")}: <t:${Math.floor((endDate) / 1000)}:R>\n${client.translate.get(db.lang, "Events.messageReactionAdd.prize")}: ${db.prize}\n${client.translate.get(db.lang, "Events.messageReactionAdd.winners")}: ${db.pickedWinners.length > 0 ? db.pickedWinners.map(w => `<@${w.id}>`).join(", ") : client.translate.get(db.lang, "Events.messageReactionAdd.none")}${db.requirement ? `\n${client.translate.get(db.lang, "Events.messageReactionAdd.reqs")}: ${db.requirement}` : ``}`)
|
||||||
|
|
||||||
|
message.edit({ embeds: [noUsers] }).catch(() => { });
|
||||||
|
await client.api.post(`/channels/${db.channelId}/messages`, { "content": `${client.translate.get(db.lang, "Events.messageReactionAdd.congrats")} ${db.pickedWinners.map(w => `<@${w.id}>`).join(", ")}! ${client.translate.get(db.lang, "Events.messageReactionAdd.youWon")} **[${db.prize}](https://chat.f95.io/server/${db.serverId}/channel/${db.channelId}/${db.messageId})**!` }).catch(() => { });
|
||||||
|
client.reactions.set(userId, Date.now() + 3000)
|
||||||
|
setTimeout(() => client.reactions.delete(userId), 3000)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const db2 = await client.database.getGuild(message.server.id, true)
|
||||||
|
if (db2 && db2.roles.find(e => e.msgId === message.id) && db2.roles.find(e => e.roles.find(e => e.emoji === emojiId))) {
|
||||||
|
if (client.reactions.get(userId)) return;
|
||||||
|
|
||||||
|
const roles = [];
|
||||||
|
db2.roles.find(e => e.msgId === message.id).roles.map(e => roles.push(e));
|
||||||
|
const role = roles.find(e => e.emoji === emojiId);
|
||||||
|
const member = await (client.servers.get(message.server.id) || await client.servers.fetch(message.server.id))?.fetchMember(userId);
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
let error = false;
|
||||||
|
let dataRoles = [];
|
||||||
|
if (member.roles) member.roles.map(e => dataRoles.push(e));
|
||||||
|
if (dataRoles.includes(role.role)) return;
|
||||||
|
|
||||||
|
client.reactions.set(userId, Date.now() + 3000);
|
||||||
|
setTimeout(() => client.reactions.delete(userId), 3000);
|
||||||
|
|
||||||
|
dataRoles.push(role.role);
|
||||||
|
await member.edit({ roles: dataRoles }).catch(() => { error = true })
|
||||||
|
|
||||||
|
if (error && db2.dm) {
|
||||||
|
member?.user?.openDM().then((dm) => { dm.sendMessage(`${client.translate.get(db2.language, "Events.messageReactionAdd.noPerms").replace("{role}", `**${role.name}**`)}!`) }).catch(() => { });
|
||||||
|
} else if (db2.dm) {
|
||||||
|
member?.user?.openDM().then((dm) => { dm.sendMessage(`${client.translate.get(db2.language, "Events.messageReactionAdd.success").replace("{role}", `**${role.name}**`)}!`) }).catch(() => { });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
100
events/messageReactionRemove.js
Normal file
100
events/messageReactionRemove.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
const Giveaways = require("../models/giveaways");
|
||||||
|
const emojis = [{ name: "1️⃣", id: 0 }, { name: "2️⃣", id: 1 }, { name: "3️⃣", id: 2 }, { name: "4️⃣", id: 3 }, { name: "5️⃣", id: 4 }, { name: "6️⃣", id: 5 }, { name: "7️⃣", id: 6 }, { name: "8️⃣", id: 7 }, { name: "9️⃣", id: 8 }, { name: "🔟", id: 9 }, { name: "🛑", id: "stop" }]
|
||||||
|
const colors = /^([A-Z0-9]+)/;
|
||||||
|
|
||||||
|
module.exports = async (client, message, userId, emojiId) => {
|
||||||
|
const pollCheck = client.polls.get(message.id);
|
||||||
|
const collector = client.messageCollector.get(userId);
|
||||||
|
const editCollector = client.messageEdit.get(userId);
|
||||||
|
|
||||||
|
if (collector && collector.messageId === message.id && collector.channelId === message.channelId) {
|
||||||
|
const emoji = collector.rolesDone.find(e => e.emoji === emojiId);
|
||||||
|
if (emoji) {
|
||||||
|
collector.rolesDone = collector.rolesDone.filter(object => object.emoji != emojiId);
|
||||||
|
collector.roles.push([emoji.role, { name: emoji.name, colour: emoji.color }]);
|
||||||
|
collector.regex.push(emoji.name);
|
||||||
|
|
||||||
|
if (colors.test(emojiId)) emote = `:${emojiId}:`;
|
||||||
|
else if (!colors.test(emojiId)) emote = emojiId
|
||||||
|
return message.edit(collector.type === "content" ? { content: message.content.replace(`${emote} $\\text{\\textcolor{${emoji.color}}{${emoji.name}}}$`, `{role:${emoji.name}}`) } : { embeds: [new Embed().setColor("#A52F05").setDescription(client.messages.get(message.id).embeds[0].description.replace(`{role:${editCollector.regex[0]}}`, `:${emojiId}: $\\text{\\textcolor{${editCollector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : editCollector.roles[0][1].colour}}{${editCollector.roles[0][1].name}}}$`))] }).catch(() => { });
|
||||||
|
}
|
||||||
|
} else if (editCollector && editCollector.messageId === message.id && editCollector.channelId === message.channelId) {
|
||||||
|
const emoji = editCollector.rolesDone.find(e => e.emoji === emojiId);
|
||||||
|
if (emoji) {
|
||||||
|
editCollector.rolesDone = editCollector.rolesDone.filter(object => object.emoji != emojiId);
|
||||||
|
editCollector.roles.push([emoji.role, { name: emoji.name, colour: emoji.color }]);
|
||||||
|
editCollector.regex.push(emoji.name);
|
||||||
|
|
||||||
|
if (colors.test(emojiId)) emote = `:${emojiId}:`;
|
||||||
|
else if (!colors.test(emojiId)) emote = emojiId
|
||||||
|
return message.edit(editCollector.type === "content" ? { content: message.content.replace(`${emote} $\\text{\\textcolor{${emoji.color}}{${emoji.name}}}$`, `{role:${emoji.name}}`) } : { embeds: [new Embed().setColor("#A52F05").setDescription(client.messages.get(message.id).embeds[0].description.replace(`{role:${editCollector.regex[0]}}`, `:${emojiId}: $\\text{\\textcolor{${editCollector.roles[0][1].colour?.includes("linear-gradient") ? '#000000' : editCollector.roles[0][1].colour}}{${editCollector.roles[0][1].name}}}$`))] }).catch(() => { });
|
||||||
|
}
|
||||||
|
} else if (pollCheck) {
|
||||||
|
if (client.reactions.get(userId)) return client.users.get(userId)?.openDM().then(dm => dm.sendMessage(client.translate.get(pollCheck.language, "Events.messageReactionRemove.tooFast"))).catch(() => { });
|
||||||
|
let convert = emojis.findIndex(e => e.name === emojiId);
|
||||||
|
if (convert === 0 && convert !== 10 || convert !== -1 && convert !== 10) {
|
||||||
|
if (!pollCheck.users.includes(userId)) return;
|
||||||
|
|
||||||
|
let tooMuch = [];
|
||||||
|
if (pollCheck.poll.options.description.length > 80) tooMuch.push(`**${client.translate.get(pollCheck.language, "Events.messageReactionRemove.title")}**: ${pollCheck.poll.options.description}`)
|
||||||
|
pollCheck.poll.voteOptions.name.filter(e => e).forEach((e, i) => {
|
||||||
|
i++
|
||||||
|
if (e.length > 70) {
|
||||||
|
tooMuch.push(`**${i}.** ${e}`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pollCheck.users = pollCheck.users.filter(object => object != userId);
|
||||||
|
const user = (client.users.get(userId)) || await client.users.fetch(userId);
|
||||||
|
await pollCheck.poll.removeVote(convert, userId, 'https://chat.f95.io/api/users/01HATCWS7XZ7KEHW64AV20SMKR/default_avatar', message.id);
|
||||||
|
message.edit({ embeds: [new Embed().setDescription(tooMuch.length > 0 ? tooMuch.map(e => e).join("\n") : null).setMedia(await client.Uploader.upload(pollCheck.poll.canvas.toBuffer(), `Poll.png`)).setColor("#A52F05")] }).catch(() => { });
|
||||||
|
client.reactions.set(userId, Date.now() + 3000)
|
||||||
|
return setTimeout(() => client.reactions.delete(userId), 3000)
|
||||||
|
} else return;
|
||||||
|
} else {
|
||||||
|
if (client.reactions.get(userId)) return;
|
||||||
|
const db = await Giveaways.findOne({ messageId: message.id });
|
||||||
|
if (db && !db.ended) {
|
||||||
|
if (emojiId === client.config.emojis.confetti) {
|
||||||
|
if (!db.users.find(u => u.userID === userId)) return;
|
||||||
|
const filtered = db.users.filter(object => object.userID != userId)
|
||||||
|
db.users = filtered;
|
||||||
|
const filtered2 = db.picking.filter(object => object.userID != userId)
|
||||||
|
db.picking = filtered2;
|
||||||
|
db.save();
|
||||||
|
|
||||||
|
client.reactions.set(userId, Date.now() + 3000)
|
||||||
|
setTimeout(() => client.reactions.delete(userId), 3000)
|
||||||
|
|
||||||
|
client.users.get(userId)?.openDM().then(dm => dm.sendMessage(`${client.translate.get(pollCheck.language, "Events.messageReactionRemove.left")} [${db.prize}](https://chat.f95.io/server/${db.serverId}/channel/${db.channelId}/${db.messageId})!\n${client.translate.get(pollCheck.language, "Events.messageReactionRemove.left2")} **${db.users.length}** ${client.translate.get(pollCheck.language, "Events.messageReactionRemove.left")}!`)).catch(() => { });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const db2 = await client.database.getGuild(message.server.id, true)
|
||||||
|
if (db2 && db2.roles.find(e => e.msgId === message.id) && db2.roles.find(e => e.roles.find(e => e.emoji === emojiId))) {
|
||||||
|
const roles = [];
|
||||||
|
db2.roles.find(e => e.msgId === message.id).roles.map(e => roles.push(e));
|
||||||
|
const role = roles.find(e => e.emoji === emojiId);
|
||||||
|
const member = await (client.servers.get(message.server.id) || await client.servers.fetch(message.server.id))?.fetchMember(userId);
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
let error = false;
|
||||||
|
let dataRoles = [];
|
||||||
|
if (member.roles) member.roles.map(e => dataRoles.push(e));
|
||||||
|
if (!dataRoles.includes(role.role)) return;
|
||||||
|
|
||||||
|
client.reactions.set(userId, Date.now() + 3000);
|
||||||
|
setTimeout(() => client.reactions.delete(userId), 3000);
|
||||||
|
|
||||||
|
dataRoles = dataRoles.filter(object => object != role.role);
|
||||||
|
await member.edit({ roles: dataRoles }).catch(() => { error = true })
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
if (db2.dm) member?.user?.openDM().then((dm) => { dm.sendMessage(`${client.translate.get(db2.language, "Events.messageReactionRemove.noPerms").replace("{role}", `**${role.name}**`)}!`) }).catch(() => { });
|
||||||
|
} else {
|
||||||
|
if (db2.dm) member?.user?.openDM().then((dm) => { dm.sendMessage(`${client.translate.get(db2.language, "Events.messageReactionRemove.success").replace("{role}", `**${role.name}**`)}!`) }).catch(() => { });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
events/serverCreate.js
Normal file
12
events/serverCreate.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
module.exports = async (client, server) => {
|
||||||
|
//console.log("join", server)
|
||||||
|
// await client.database.getGuild(server.id, true)
|
||||||
|
|
||||||
|
// const embed = new Embed()
|
||||||
|
// .setColor("#A52F05")
|
||||||
|
// .setTitle(server.name || "Unknown")
|
||||||
|
// .setDescription(`**Owner**: ${server.ownerId}\n**Discoverable**: ${server.discoverable ? "true" : "false"}\n**Created**: <t:${Math.floor((server.createdAt) / 1000)}:R>\n**ID**: ${server.id}`)
|
||||||
|
|
||||||
|
// await client.api.post(`/channels/01H1KQ4GVP96MEHA95YT2F0NT4/messages`, { embeds: [embed] }).catch(() => { })
|
||||||
|
}
|
||||||
13
events/serverDelete.js
Normal file
13
events/serverDelete.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const Embed = require("../functions/embed")
|
||||||
|
module.exports = async (client, server) => {
|
||||||
|
//console.log("delete",server)
|
||||||
|
// await client.database.deleteGuild(server.id)
|
||||||
|
|
||||||
|
// const embed = new Embed()
|
||||||
|
// .setColor("#FF0000")
|
||||||
|
// .setTitle(server.name || "Unknown")
|
||||||
|
// .setIcon(server.icon ? `https://autumn.revolt.chat/icons/${server.icon._id}/${server.icon.filename}` : null)
|
||||||
|
// .setDescription(`**Owner**: ${server.ownerId}\n**Discoverable**: ${server.discoverable ? "true" : "false"}\n**Created**: <t:${Math.floor((server.createdAt) / 1000)}:R>\n**ID**: ${server.id}`)
|
||||||
|
|
||||||
|
// await client.api.post(`/channels/01H1KQ4GVP96MEHA95YT2F0NT4/messages`, { embeds: [embed] })
|
||||||
|
}
|
||||||
17
events/serverMemberUpdate.js
Normal file
17
events/serverMemberUpdate.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
let type;
|
||||||
|
module.exports = async (client, member, memberOld) => {
|
||||||
|
// Work in progress
|
||||||
|
if (member.roles > memberOld.roles && member.id.user === client.user.id) type = "add"
|
||||||
|
else if (member.roles < memberOld.roles) type = "remove"
|
||||||
|
else return;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "add":
|
||||||
|
let channel = await client.channels.fetch()
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "remove":
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
functions/audit.js
Normal file
12
functions/audit.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const db = require("../models/logging");
|
||||||
|
|
||||||
|
async function audit(type, message, cmd) {
|
||||||
|
const audit = new db();
|
||||||
|
audit.ranBy = message.member.user.username;
|
||||||
|
audit.name = cmd;
|
||||||
|
audit.type = type;
|
||||||
|
audit.channel = message.channel.name;
|
||||||
|
audit.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = audit;
|
||||||
24
functions/checkPolls.js
Normal file
24
functions/checkPolls.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
const db = require("../models/polls");
|
||||||
|
const Polls = require("./poll");
|
||||||
|
async function checkPolls(client) {
|
||||||
|
let polls = await db.find();
|
||||||
|
if (!polls || polls.length === 0) return;
|
||||||
|
let i = 0;
|
||||||
|
for (let poll of polls) {
|
||||||
|
i++
|
||||||
|
setTimeout(async () => {
|
||||||
|
const time = poll.now - (Date.now() - poll.time), users = poll.users, avatars = poll.avatars, votes = poll.votes, desc = poll.desc, name = poll.name, names = poll.options, owner = poll.owner, lang = poll.lang;
|
||||||
|
const newPoll = new Polls({ time, client, name: { name: name, description: desc }, options: names, votes: votes, users: users, avatars: avatars, owner: owner, lang: lang })
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.channels.get(poll.channelId).fetchMessage(poll.messageId).catch(() => { return });
|
||||||
|
const msg = await client.messages.get(poll.messageId);
|
||||||
|
if (msg) newPoll.start(msg, newPoll);
|
||||||
|
} catch (e) { }
|
||||||
|
|
||||||
|
poll.deleteOne({ messageId: poll.messageId });
|
||||||
|
}, i * 700);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = checkPolls;
|
||||||
24
functions/checkRoles.js
Normal file
24
functions/checkRoles.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
const db = require("../models/guilds");
|
||||||
|
async function checkRoles(client) {
|
||||||
|
let rr = await db.find({ $expr: { $gt: [{ $size: "$roles" }, 0] } });
|
||||||
|
if (!rr || rr.length === 0) return;
|
||||||
|
let i = 0;
|
||||||
|
let ii = 0;
|
||||||
|
for (let r of rr) {
|
||||||
|
i++
|
||||||
|
setTimeout(async () => {
|
||||||
|
r.roles.map((role) => {
|
||||||
|
ii++
|
||||||
|
setTimeout(async () => {
|
||||||
|
if (!client.channels.get(role.chanId) && role.roles.length === 0) {
|
||||||
|
return await client.database.updateGuild(r.id, { roles: r.roles.filter(e => e.msgId !== role.msgId) });
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.channels.get(role.chanId)?.fetchMessage(role.msgId).catch(() => { });
|
||||||
|
}, ii * 700);
|
||||||
|
});
|
||||||
|
}, i * 600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = checkRoles;
|
||||||
26
functions/colorCodes.js
Normal file
26
functions/colorCodes.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
function colors(altColorChar, textToTranslate) {
|
||||||
|
const colorMap = {
|
||||||
|
[`${altColorChar}0`]: '\x1b[30m', // Black
|
||||||
|
[`${altColorChar}1`]: '\x1b[34m', // Dark Blue
|
||||||
|
[`${altColorChar}2`]: '\x1b[32m', // Dark Green
|
||||||
|
[`${altColorChar}3`]: '\x1b[36m', // Dark Aqua
|
||||||
|
[`${altColorChar}4`]: '\x1b[31m', // Dark Red
|
||||||
|
[`${altColorChar}5`]: '\x1b[35m', // Dark Purple
|
||||||
|
[`${altColorChar}6`]: '\x1b[33m', // Gold
|
||||||
|
[`${altColorChar}7`]: '\x1b[37m', // Gray
|
||||||
|
[`${altColorChar}8`]: '\x1b[90m', // Dark Gray
|
||||||
|
[`${altColorChar}9`]: '\x1b[94m', // Blue
|
||||||
|
[`${altColorChar}a`]: '\x1b[92m', // Green
|
||||||
|
[`${altColorChar}b`]: '\x1b[96m', // Aqua
|
||||||
|
[`${altColorChar}c`]: '\x1b[91m', // Red
|
||||||
|
[`${altColorChar}d`]: '\x1b[95m', // Light Purple
|
||||||
|
[`${altColorChar}e`]: '\x1b[93m', // Yellow
|
||||||
|
[`${altColorChar}f`]: '\x1b[97m', // White
|
||||||
|
[`${altColorChar}r`]: '\x1b[0m', // Reset
|
||||||
|
};
|
||||||
|
|
||||||
|
const regex = new RegExp(`${altColorChar}([0-9a-fr])`, 'g');
|
||||||
|
return textToTranslate.replace(regex, (match, code) => colorMap[`${altColorChar}${code}`] || '');
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = colors;
|
||||||
11
functions/dhms.js
Normal file
11
functions/dhms.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
function dhms(str, sec = false) {
|
||||||
|
const x = sec ? 1 : 1000;
|
||||||
|
if (typeof str !== 'string') return 0;
|
||||||
|
const fixed = str.replace(/\s/g, '');
|
||||||
|
const tail = +fixed.match(/-?\d+$/g) || 0;
|
||||||
|
const parts = (fixed.match(/-?\d+[^-0-9]+/g) || [])
|
||||||
|
.map(v => +v.replace(/[^-0-9]+/g, '') * ({ s: x, m: 60 * x, h: 3600 * x, d: 86400 * x }[v.replace(/[-0-9]+/g, '')] || 0));
|
||||||
|
return [tail, ...parts].reduce((a, b) => a + b, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = dhms;
|
||||||
69
functions/embed.js
Normal file
69
functions/embed.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
class Embed {
|
||||||
|
url = null;
|
||||||
|
title = null;
|
||||||
|
description = null;
|
||||||
|
image = null;
|
||||||
|
icon_url = null;
|
||||||
|
color = null;
|
||||||
|
thumbnail = null;
|
||||||
|
media = null;
|
||||||
|
|
||||||
|
constructor(data) {
|
||||||
|
Object.assign(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle(title) {
|
||||||
|
this.title = title
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setMedia(media) {
|
||||||
|
this.media = media
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setIcon(iconURL) {
|
||||||
|
this.icon_url = iconURL
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setColor(color) {
|
||||||
|
this.color = color
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setImage(image) {
|
||||||
|
this.image = image
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setThumbnail(thumbnail) {
|
||||||
|
this.thumbnail = thumbnail
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setDescription(description) {
|
||||||
|
this.description = description
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setURL(url) {
|
||||||
|
this.url = url
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
return {
|
||||||
|
title: this.title,
|
||||||
|
description: this.description,
|
||||||
|
url: this.url,
|
||||||
|
icon_url: this.icon_url,
|
||||||
|
image: this.image,
|
||||||
|
thumbnail: this.thumbnail,
|
||||||
|
colour: this.color,
|
||||||
|
media: this.media
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Embed;
|
||||||
16
functions/fetchTime.js
Normal file
16
functions/fetchTime.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
function fetchTime(ms, client, lang) {
|
||||||
|
var totalSeconds = (ms / 1000);
|
||||||
|
let years = Math.floor(totalSeconds / 31536000);
|
||||||
|
totalSeconds %= 31536000;
|
||||||
|
let days = Math.floor(totalSeconds / 86400);
|
||||||
|
totalSeconds %= 86400;
|
||||||
|
let hours = Math.floor(totalSeconds / 3600);
|
||||||
|
totalSeconds %= 3600;
|
||||||
|
let minutes = Math.floor(totalSeconds / 60);
|
||||||
|
let seconds = totalSeconds % 60;
|
||||||
|
seconds = Math.floor(seconds);
|
||||||
|
|
||||||
|
return `${years ? `${years} ${client.translate.get(lang, "Functions.fetchTime.years")},` : ""} ${days ? `${days} ${client.translate.get(lang, "Functions.fetchTime.days")},` : ""} ${hours ? `${hours} ${client.translate.get(lang, "Functions.fetchTime.hours")},` : ""} ${minutes ? `${minutes} ${client.translate.get(lang, "Functions.fetchTime.minutes")},` : ""} ${seconds} ${client.translate.get(lang, "Functions.fetchTime.seconds")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = fetchTime;
|
||||||
85
functions/logger.js
Normal file
85
functions/logger.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* base code taken from https://github.com/Mirasaki/logger
|
||||||
|
*/
|
||||||
|
|
||||||
|
const chalk = require('chalk'),
|
||||||
|
moment = require('moment');
|
||||||
|
|
||||||
|
const tagList = {
|
||||||
|
SYSLOG: chalk.greenBright('[SYSLOG]'),
|
||||||
|
SYSERR: chalk.redBright('[SYSERR]'),
|
||||||
|
SUCCESS: chalk.greenBright('[SUCCESS]'),
|
||||||
|
INFO: chalk.blueBright('[INFO]'),
|
||||||
|
DEBUG: chalk.magentaBright('[DEBUG]'),
|
||||||
|
DATA: chalk.yellowBright('[DATA]'),
|
||||||
|
COMMAND: chalk.whiteBright('[CMD]'),
|
||||||
|
EVENT: chalk.cyanBright('[EVENT]'),
|
||||||
|
ERROR: chalk.redBright('[EVENT]'),
|
||||||
|
WARN: chalk.yellowBright('[WARN]')
|
||||||
|
};
|
||||||
|
|
||||||
|
const longestTagLength = Math.max(...Object.values(tagList).map(t => t.length));
|
||||||
|
const getTag = (tag) => `${tagList[tag]}${''.repeat(longestTagLength - tagList[tag].length)}`;
|
||||||
|
const timestamp = () => `${chalk.whiteBright.bold(`[${moment.utc().format('YYYY-MM-DD HH:mm:ss')}]`)}`;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
syslog: (type, str) => console.info(`${timestamp()} ${type ? `${getTag('SYSLOG')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('SYSLOG')}:`} ${str}`),
|
||||||
|
syserr: (type, str) => console.error(`${timestamp()} ${type ? `${getTag('SYSERR')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('SYSERR')} :`} ${str}`),
|
||||||
|
success: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('SUCCESS')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('SUCCESS')}:`} ${str}`),
|
||||||
|
info: (type, str) => console.info(`${timestamp()} ${type ? `${getTag('INFO')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('INFO')}:`} ${str}`),
|
||||||
|
debug: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('DEBUG')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('DEBUG')}:`} ${str}`),
|
||||||
|
data: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('DATA')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('DATA')}:`} ${str}`),
|
||||||
|
command: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('COMMAND')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('COMMAND')}:`} ${str}`),
|
||||||
|
event: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('EVENT')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('EVENT')}:`} ${str}`),
|
||||||
|
error: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('ERROR')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('ERROR')}:`} ${str}`),
|
||||||
|
warn: (type, str) => console.log(`${timestamp()} ${type ? `${getTag('WARN')} ${chalk.whiteBright.bgBlue.bold(`[${type}]`)}:` : `${getTag('WARN')}:`} ${str}`),
|
||||||
|
|
||||||
|
startLog: (identifier) => console.log(`${timestamp()} ${getTag('DEBUG')} ${chalk.greenBright('[START]')} ${identifier}`),
|
||||||
|
endLog: (identifier) => console.log(`${timestamp()} ${getTag('DEBUG')} ${chalk.redBright('[ END ]')} ${identifier}`),
|
||||||
|
|
||||||
|
timestamp,
|
||||||
|
getExecutionTime: (hrtime) => {
|
||||||
|
const timeSinceHrMs = (
|
||||||
|
process.hrtime(hrtime)[0] * 1000
|
||||||
|
+ hrtime[1] / 1000000
|
||||||
|
).toFixed(2);
|
||||||
|
return `${chalk.yellowBright(
|
||||||
|
(timeSinceHrMs / 1000).toFixed(2))
|
||||||
|
} seconds (${chalk.yellowBright(timeSinceHrMs)} ms)`;
|
||||||
|
},
|
||||||
|
|
||||||
|
printErr: (err) => {
|
||||||
|
if (!(err instanceof Error)) {
|
||||||
|
console.error(err)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(
|
||||||
|
!err.stack
|
||||||
|
? chalk.red(err)
|
||||||
|
: err.stack
|
||||||
|
.split('\n')
|
||||||
|
.map((msg, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
return chalk.red(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isFailedFunctionCall = index === 1;
|
||||||
|
const traceStartIndex = msg.indexOf('(');
|
||||||
|
const traceEndIndex = msg.lastIndexOf(')');
|
||||||
|
const hasTrace = traceStartIndex !== -1;
|
||||||
|
const functionCall = msg.slice(
|
||||||
|
msg.indexOf('at') + 3,
|
||||||
|
hasTrace ? traceStartIndex - 1 : msg.length
|
||||||
|
);
|
||||||
|
const trace = msg.slice(traceStartIndex, traceEndIndex + 1);
|
||||||
|
|
||||||
|
return ` ${chalk.grey('at')} ${isFailedFunctionCall
|
||||||
|
? `${chalk.redBright(functionCall)} ${chalk.red.underline(trace)}`
|
||||||
|
: `${chalk.greenBright(functionCall)} ${chalk.grey(trace)}`
|
||||||
|
}`;
|
||||||
|
})
|
||||||
|
.join('\n')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
26
functions/members.js
Normal file
26
functions/members.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
async function Members(client, server) {
|
||||||
|
if (typeof client !== 'object') return {
|
||||||
|
error: true,
|
||||||
|
msg: 'First argument isn\'t available or a valid client!'
|
||||||
|
};
|
||||||
|
if (typeof server !== 'string') return {
|
||||||
|
error: true,
|
||||||
|
msg: 'Second argument isn\'t available or a valid serverID string!'
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const member = await client.api.get(`/servers/${server}/members`)
|
||||||
|
return {
|
||||||
|
error: false,
|
||||||
|
users: member.users,
|
||||||
|
members: member.members
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
error: true,
|
||||||
|
msg: "Unknown Server"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Members;
|
||||||
72
functions/messageCollector.js
Normal file
72
functions/messageCollector.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
async function Collector(client, message, db) {
|
||||||
|
const regex = /{role:(.*?)}/;
|
||||||
|
const regexAll = /{role:(.*?)}/g;
|
||||||
|
const collector = client.messageCollector.get(message.authorId);
|
||||||
|
if (!message.content.match(regexAll) || message.content.match(regexAll)?.length === 0) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.noRoles")}: \`{role:Red}\``)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
const roles = message.content.match(regexAll).map((r) => r?.match(regex)[1]);
|
||||||
|
if (roles.length > 20) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(client.translate.get(db.language, "Events.messageCreate.maxRoles"))] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
collector.regex = roles
|
||||||
|
const roleIds = []
|
||||||
|
let newRoles = roles.map((r) => {
|
||||||
|
return [...message.server.roles].map((r) => r).find((role) => r.toLowerCase() === role[1]?.name?.toLowerCase());
|
||||||
|
})
|
||||||
|
newRoles.map((r) => roleIds.push(r));
|
||||||
|
|
||||||
|
if (roleIds.map((r) => !r).includes(true)) {
|
||||||
|
let unknown = [];
|
||||||
|
roleIds.map((r, i) => {
|
||||||
|
i++
|
||||||
|
if (!r) {
|
||||||
|
unknown.push(roles[i - 1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.unknown")}\n${unknown.map(e => `\`{role:${e}}\``).join(", ")}`)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
let duplicate = [];
|
||||||
|
roleIds.map((r, i) => {
|
||||||
|
i++
|
||||||
|
if (roleIds.filter(e => e[0] === r[0]).length > 1) duplicate.push(roleIds[i - 1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (duplicate.length > 0) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.duplicate")}\n${duplicate.map(e => `\`{role:${e[1].name}}\``)}`)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
let positions = [];
|
||||||
|
const botRole = message.channel.server.member.orderedRoles.reverse()[0]
|
||||||
|
if (!botRole) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(client.translate.get(db.language, "Events.messageCreate.noBotRole"))] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
roleIds.map((r, i) => {
|
||||||
|
i++
|
||||||
|
if (r[1].rank <= botRole.rank) positions.push(roleIds[i - 1])
|
||||||
|
});
|
||||||
|
|
||||||
|
if (positions.length > 0) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.positions")}\n${positions.map(e => `\`{role:${e[1].name}}\``)}`)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
message.delete().catch(() => { });
|
||||||
|
collector.roles = roleIds;
|
||||||
|
const react = [client.config.emojis.check];
|
||||||
|
return message.channel.sendMessage(collector.type === "content" ? { content: message.content, interactions: [react] } : { embeds: [new Embed().setDescription(message.content).setColor("#A52F05")], interactions: [react] }).then((msg) => {
|
||||||
|
collector.messageId = msg.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Collector;
|
||||||
72
functions/messageEdit.js
Normal file
72
functions/messageEdit.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
const Embed = require("../functions/embed");
|
||||||
|
async function Collector(client, message, db) {
|
||||||
|
const regex = /{role:(.*?)}/;
|
||||||
|
const regexAll = /{role:(.*?)}/g;
|
||||||
|
const collector = client.messageEdit.get(message.authorId);
|
||||||
|
if (!message.content.match(regexAll) || message.content.match(regexAll)?.length === 0) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.noRoles")}: \`{role:Red}\``)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
const roles = message.content.match(regexAll).map((r) => r?.match(regex)[1]);
|
||||||
|
if (roles.length > 20) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(client.translate.get(db.language, "Events.messageCreate.maxRoles"))] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
collector.regex = roles
|
||||||
|
const roleIds = []
|
||||||
|
let newRoles = roles.map((r) => {
|
||||||
|
return [...message.server.roles].map((r) => r).find((role) => r.toLowerCase() === role[1]?.name?.toLowerCase());
|
||||||
|
})
|
||||||
|
newRoles.map((r) => roleIds.push(r));
|
||||||
|
|
||||||
|
if (roleIds.map((r) => !r).includes(true)) {
|
||||||
|
let unknown = [];
|
||||||
|
roleIds.map((r, i) => {
|
||||||
|
i++
|
||||||
|
if (!r) {
|
||||||
|
unknown.push(roles[i - 1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.unknown")}\n${unknown.map(e => `\`{role:${e}}\``).join(", ")}`)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
let duplicate = [];
|
||||||
|
roleIds.map((r, i) => {
|
||||||
|
i++
|
||||||
|
if (roleIds.filter(e => e[0] === r[0]).length > 1) duplicate.push(roleIds[i - 1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (duplicate.length > 0) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.duplicate")}\n${duplicate.map(e => `\`{role:${e[1].name}}\``)}`)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
let positions = [];
|
||||||
|
const botRole = message.channel.server.member.orderedRoles.reverse()[0]
|
||||||
|
if (!botRole) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(client.translate.get(db.language, "Events.messageCreate.noBotRole"))] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
roleIds.map((r, i) => {
|
||||||
|
i++
|
||||||
|
if (r[1].rank <= botRole.rank) positions.push(roleIds[i - 1])
|
||||||
|
});
|
||||||
|
|
||||||
|
if (positions.length > 0) {
|
||||||
|
message.reply({ embeds: [new Embed().setColor("#FF0000").setDescription(`${client.translate.get(db.language, "Events.messageCreate.positions")}\n${positions.map(e => `\`{role:${e[1].name}}\``)}`)] }, false).catch(() => { return });
|
||||||
|
return message.react(client.config.emojis.cross).catch(() => { return });
|
||||||
|
}
|
||||||
|
|
||||||
|
message.delete().catch(() => { });
|
||||||
|
collector.roles = roleIds;
|
||||||
|
const react = [client.config.emojis.check];
|
||||||
|
return message.channel.sendMessage(collector.type === "content" ? { content: message.content, interactions: [react] } : { embeds: [new Embed().setDescription(message.content).setColor("#A52F05")], interactions: [react] }).then((msg) => {
|
||||||
|
collector.messageId = msg.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Collector;
|
||||||
29
functions/pagination.js
Normal file
29
functions/pagination.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
class Paginator {
|
||||||
|
constructor({ user, client, timeout }) {
|
||||||
|
this.pages = [];
|
||||||
|
this.client = client;
|
||||||
|
this.user = user;
|
||||||
|
this.page = 0;
|
||||||
|
this.timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(page) {
|
||||||
|
if (page.length) {
|
||||||
|
page.forEach((x) => { this.pages.push(x) });
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.pages.push(page);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
async start(channel) {
|
||||||
|
if (!this.pages.length) return;
|
||||||
|
const reactions = ["⏪", "⬅️", "➡️", "⏩"];
|
||||||
|
this.pages.forEach((e, i=0) => { e.description = `${e.description}\n\nPage ${i+1} / ${this.pages.length}` })
|
||||||
|
const message1 = await channel.sendMessage({ embeds: [this.pages[0]], interactions: { reactions } });
|
||||||
|
this.client.paginate.set(this.user, { pages: this.pages, page: this.page, message: message1.id });
|
||||||
|
setTimeout(() => { if (this.client.paginate.get(this.user)) this.client.paginate.delete(this.user) }, this.timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Paginator;
|
||||||
250
functions/poll.js
Normal file
250
functions/poll.js
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
const PollDB = require("../models/polls");
|
||||||
|
const Embed = require("./embed");
|
||||||
|
const Canvas = require('canvas');
|
||||||
|
const format = `${(new Date().getMonth() + 1) < 10 ? `0${new Date().getMonth() + 1}` : new Date().getMonth() + 1}/${new Date().getDate()}/${new Date().getFullYear()} ${new Date().getHours()}:${(new Date().getMinutes() < 10 ? '0' : '') + new Date().getMinutes()}`;
|
||||||
|
class Polls {
|
||||||
|
constructor({ time, client, name, options, users, avatars, votes, owner, lang }) {
|
||||||
|
this.client = client;
|
||||||
|
this.time = time;
|
||||||
|
if (votes) this.votes = votes;
|
||||||
|
else this.votes = options.name.length === 2 ? [0, 0] : options.name.length === 3 ? [0, 0, 0] : options.name.length === 4 ? [0, 0, 0, 0] : options.name.length === 5 ? [0, 0, 0, 0, 0] : options.name.length === 6 ? [0, 0, 0, 0, 0, 0] : options.name.length === 7 ? [0, 0, 0, 0, 0, 0, 0] : options.name.length === 8 ? [0, 0, 0, 0, 0, 0, 0, 0] : options.name.length === 9 ? [0, 0, 0, 0, 0, 0, 0, 0, 0] : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
this.users = users || [];
|
||||||
|
this.avatars = avatars || [];
|
||||||
|
this.options = { name: name.name, description: name.description };
|
||||||
|
this.voteOptions = options;
|
||||||
|
this.owner = owner;
|
||||||
|
this.lang = lang;
|
||||||
|
this.size = { canvas: options.name.length === 2 ? 200 : options.name.length === 3 ? 250 : options.name.length === 4 ? 300 : options.name.length === 5 ? 350 : options.name.length === 6 ? 400 : options.name.length === 7 ? 450 : options.name.length === 8 ? 500 : options.name.length === 9 ? 550 : 600, bar: options.name.length === 2 ? 150 : options.name.length === 3 ? 200 : options.name.length === 4 ? 250 : options.name.length === 5 ? 300 : options.name.length === 6 ? 350 : options.name.length === 7 ? 400 : options.name.length === 8 ? 450 : options.name.length === 9 ? 500 : 550 };
|
||||||
|
}
|
||||||
|
|
||||||
|
async start(message, poll) {
|
||||||
|
this.client.polls.set(message.id, { poll, messageId: message.id, users: this.users, owner: this.owner, lang: this.lang })
|
||||||
|
setTimeout(async () => {
|
||||||
|
if (!this.client.polls.get(message.id)) return;
|
||||||
|
await this.update();
|
||||||
|
message.edit({ embeds: [new Embed().setMedia(await this.client.Uploader.upload(poll.canvas.toBuffer(), `Poll.png`)).setColor(`#F24646`)], content: this.client.translate.get(this.lang, "Functions.poll.end") }).catch(() => { })
|
||||||
|
this.client.polls.delete(message.id);
|
||||||
|
await PollDB.findOneAndDelete({ messageId: message.id });
|
||||||
|
}, this.time);
|
||||||
|
|
||||||
|
if (this.time < 0) return;
|
||||||
|
await (new PollDB({
|
||||||
|
owner: this.owner,
|
||||||
|
channelId: message.channelId,
|
||||||
|
messageId: message.id,
|
||||||
|
avatars: this.avatars,
|
||||||
|
users: this.users,
|
||||||
|
votes: this.votes,
|
||||||
|
name: this.options.name,
|
||||||
|
desc: this.options.description,
|
||||||
|
options: this.voteOptions,
|
||||||
|
time: this.time,
|
||||||
|
lang: this.lang,
|
||||||
|
now: Date.now(),
|
||||||
|
}).save());
|
||||||
|
}
|
||||||
|
|
||||||
|
textHeight(text, ctx, m) {
|
||||||
|
let metrics = m || ctx.measureText(text);
|
||||||
|
return metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
|
||||||
|
}
|
||||||
|
|
||||||
|
roundRect(ctx, x, y, width, height, radius, fill, stroke) { // Credit to https://stackoverflow.com/users/227299/juan-mendes
|
||||||
|
if (typeof stroke === 'undefined') {
|
||||||
|
stroke = true;
|
||||||
|
}
|
||||||
|
if (typeof radius === 'undefined') {
|
||||||
|
radius = 5;
|
||||||
|
}
|
||||||
|
if (typeof radius === 'number') {
|
||||||
|
radius = { tl: radius, tr: radius, br: radius, bl: radius };
|
||||||
|
} else {
|
||||||
|
var defaultRadius = { tl: 0, tr: 0, br: 0, bl: 0 };
|
||||||
|
for (var side in defaultRadius) {
|
||||||
|
radius[side] = radius[side] || defaultRadius[side];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x + radius.tl, y);
|
||||||
|
ctx.lineTo(x + width - radius.tr, y);
|
||||||
|
ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
|
||||||
|
ctx.lineTo(x + width, y + height - radius.br);
|
||||||
|
ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
|
||||||
|
ctx.lineTo(x + radius.bl, y + height);
|
||||||
|
ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
|
||||||
|
ctx.lineTo(x, y + radius.tl);
|
||||||
|
ctx.quadraticCurveTo(x, y, x + radius.tl, y);
|
||||||
|
ctx.closePath();
|
||||||
|
if (fill) {
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
if (stroke) {
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async update() {
|
||||||
|
let roundRect = this.roundRect;
|
||||||
|
let textHeight = this.textHeight;
|
||||||
|
|
||||||
|
var width = 600, height = this.size.canvas, padding = 10;
|
||||||
|
const canvas = Canvas.createCanvas(width, height);
|
||||||
|
this.canvas = canvas;
|
||||||
|
const ctx = this.canvas.getContext('2d');
|
||||||
|
this.ctx = ctx;
|
||||||
|
|
||||||
|
let name = this.options.name?.length > 70 ? this.options?.name.slice(0, 67) + "..." : this.options.name;
|
||||||
|
var nameHeight = textHeight(name, ctx);
|
||||||
|
|
||||||
|
let description = this.options.description.length > 80 ? this.options.description.slice(0, 77) + "..." : this.options.description;
|
||||||
|
var descHeight = textHeight(description, ctx);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#23272A";
|
||||||
|
roundRect(ctx, 0, 0, width, height, 5, true, false); // background
|
||||||
|
|
||||||
|
ctx.fillStyle = "#4E535A";
|
||||||
|
ctx.font = `normal 12px Sans-Serif`;
|
||||||
|
ctx.fillText(name, padding, padding + 2 + nameHeight / 2); // name
|
||||||
|
|
||||||
|
ctx.fillStyle = "#FFFFFF";
|
||||||
|
ctx.font = `normal 17px Sans-Serif`;
|
||||||
|
ctx.fillText(description, padding, padding + 15 + nameHeight + descHeight / 2); // description
|
||||||
|
|
||||||
|
var headerHeight = padding + descHeight + nameHeight + 15;
|
||||||
|
var dataWidth = width - padding * 2;
|
||||||
|
var barHeight = 40;
|
||||||
|
var votes = this.votes;
|
||||||
|
var names = this.voteOptions.name;
|
||||||
|
|
||||||
|
this.drawVoteBars(ctx, dataWidth - 20, barHeight, votes, { pad: padding, hHeight: headerHeight }, names);
|
||||||
|
await this.drawFooter(ctx, padding, padding + headerHeight + barHeight * 2 + 20, width, height, padding, this.avatars);
|
||||||
|
}
|
||||||
|
|
||||||
|
async addVote(option, user, avatar, id) {
|
||||||
|
if (this.avatars.length === 6) this.avatars.shift();
|
||||||
|
this.avatars.push(avatar);
|
||||||
|
this.votes[option]++;
|
||||||
|
await PollDB.findOneAndUpdate({ messageId: id }, { $push: { users: user, avatars: avatar }, $inc: { [`votes.${option}`]: 1 } });
|
||||||
|
await this.update();
|
||||||
|
return this.canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeVote(option, user, avatar, id) {
|
||||||
|
this.avatars.splice(this.avatars.indexOf(avatar), 1);
|
||||||
|
this.votes[option]--;
|
||||||
|
await PollDB.findOneAndUpdate({ messageId: id }, { $pull: { users: user, avatars: avatar }, $inc: { [`votes.${option}`]: -1 } });
|
||||||
|
await this.update();
|
||||||
|
return this.canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawVoteBars(ctx, width, height, votes, vars, names, vote) {
|
||||||
|
let roundRect = this.roundRect;
|
||||||
|
let textHeight = this.textHeight;
|
||||||
|
let padding = vars.pad;
|
||||||
|
let headerHeight = vars.hHeight;
|
||||||
|
let sum = votes.reduce((prev, curr) => prev + curr);
|
||||||
|
let percentages = votes.map((v) => Math.floor(v / (sum / 100) * 10) / 10);
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(padding, padding + headerHeight);
|
||||||
|
|
||||||
|
var barPadding = 5;
|
||||||
|
percentages.forEach((percentage, i) => {
|
||||||
|
if (!percentage) percentage = 0;
|
||||||
|
let paddingLeft = (vote != undefined) ? 30 : 0;
|
||||||
|
|
||||||
|
ctx.fillStyle = "#2C2F33";
|
||||||
|
let y = (height + 10) * i;
|
||||||
|
roundRect(ctx, 20, y, width, height, 5, true, false); // full bar
|
||||||
|
|
||||||
|
if (vote == i || percentage) { ctx.fillStyle = "#A52F05"; }
|
||||||
|
else { ctx.fillStyle = "#24282B"; } // percentage display
|
||||||
|
roundRect(ctx, 20, y, width * (votes[i] / (sum / 100) / 100), height, 5, true, false);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#4E535A";
|
||||||
|
let h = textHeight(i + 1, ctx);
|
||||||
|
ctx.fillText(i + 1, 0, y + height / 2 + h / 2);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#FFFFFF"; // Option names
|
||||||
|
h = textHeight(names[i], ctx);
|
||||||
|
ctx.fillText(names[i].length > 65 ? names[i].slice(0, 62) + "..." : names[i], 30 + paddingLeft, y + 13 + h);
|
||||||
|
|
||||||
|
if (vote != undefined) {
|
||||||
|
ctx.strokeStyle = "#FFFFFF"; // selection circle
|
||||||
|
ctx.fillStyle = "#717cf4";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(35, y + 10 + h * 0.75, 6, 0, 2 * Math.PI);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.stroke();
|
||||||
|
if (vote == i) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(35, y + 10 + h * 0.75, 3, 0, 2 * Math.PI);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.fillStyle = "#2C2F33"; // percentage and vote count background
|
||||||
|
let metrics = ctx.measureText(percentage + "% (" + votes[i] + ")");
|
||||||
|
let w = metrics.width;
|
||||||
|
h = textHeight(percentage + "% (" + votes[i] + ")", ctx, metrics);
|
||||||
|
y = y + (height - h - barPadding * 2) + barPadding * 2.6;
|
||||||
|
if (vote == i || vote == undefined) roundRect(ctx, width - barPadding - w - 3, y - h - 4, w + 5, h + 12, 5, true, false);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#A52F05"; // percentage and vote count
|
||||||
|
ctx.fillText(percentage + "% (" + votes[i] + ")", width - barPadding - w, y);
|
||||||
|
});
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
async drawFooter(ctx, x, y, width, height, padding, users) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(10, this.size.bar);
|
||||||
|
|
||||||
|
var rad = 18;
|
||||||
|
ctx.fillStyle = "#4E535A";
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeStyle = "#4E535A";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0 - padding, 0);
|
||||||
|
ctx.lineTo(width, 0);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
let votes = (this.votes.reduce((p, c) => p + c) == 1) ? `${this.votes.reduce((p, c) => p + c)} vote` : `${this.votes.reduce((p, c) => p + c)} votes`;
|
||||||
|
let metrics = ctx.measureText(votes);
|
||||||
|
let h = this.textHeight(votes, ctx, metrics);
|
||||||
|
ctx.fillText(votes, 5, rad + h);
|
||||||
|
|
||||||
|
// Avatars
|
||||||
|
var pos = rad * users.length + 10 + metrics.width;
|
||||||
|
var yPos = 6;
|
||||||
|
users.reverse();
|
||||||
|
for (let i = 0; i < users.length; i++) {
|
||||||
|
ctx.beginPath();
|
||||||
|
let user = users[i];
|
||||||
|
|
||||||
|
const a = Canvas.createCanvas(rad * 2, rad * 2);
|
||||||
|
const context = a.getContext("2d");
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.arc(rad, rad, rad, 0, Math.PI * 2, true);
|
||||||
|
context.closePath();
|
||||||
|
context.clip();
|
||||||
|
|
||||||
|
const avatar = await Canvas.loadImage(user);
|
||||||
|
context.drawImage(avatar, 0, 0, rad * 2, rad * 2);
|
||||||
|
ctx.drawImage(a, pos, yPos);
|
||||||
|
|
||||||
|
ctx.closePath();
|
||||||
|
pos -= rad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Date
|
||||||
|
let date = format;
|
||||||
|
metrics = ctx.measureText(date);
|
||||||
|
h = this.textHeight(date, ctx, metrics);
|
||||||
|
ctx.fillText(date, width - 15 - metrics.width, rad + h);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Polls;
|
||||||
60
functions/randomStr.js
Normal file
60
functions/randomStr.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
const crypt = require("crypto");
|
||||||
|
// const FlakeId = require('flakeid');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Generates a unique ID
|
||||||
|
* @returns {string} 12-character base64 ID
|
||||||
|
*/
|
||||||
|
generateUniqueId: () => crypt.randomBytes(9)
|
||||||
|
.toString('base64')
|
||||||
|
.replace(/[/+]/g, c => c === '/' ? '_' : '-')
|
||||||
|
.slice(0, 12),
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number} len How long to set character length
|
||||||
|
* @returns alphanumeric string
|
||||||
|
*/
|
||||||
|
random: function random(len) {
|
||||||
|
len = len || 64;
|
||||||
|
return crypt.randomBytes(len).toString("hex");
|
||||||
|
},
|
||||||
|
|
||||||
|
// snowflake: function snowflake() {
|
||||||
|
|
||||||
|
// const flake = new FlakeId({
|
||||||
|
// mid: 64,
|
||||||
|
// timeOffset: 1431669781,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return flake.gen();
|
||||||
|
// },
|
||||||
|
|
||||||
|
shortid: function shortid() {
|
||||||
|
let str = Buffer.from(crypt.randomUUID()).toString('base64');
|
||||||
|
let n = 12;
|
||||||
|
|
||||||
|
return (str.length > n) ? str.substr(0, n - 1) : str
|
||||||
|
},
|
||||||
|
|
||||||
|
truncate: function truncate(str, n) {
|
||||||
|
return (str.length > n) ? str.substr(0, n - 1) : str;
|
||||||
|
},
|
||||||
|
|
||||||
|
randomNum: function (len1) {
|
||||||
|
const len2 = len1 || 17;
|
||||||
|
const { customAlphabet } = require('nanoid')
|
||||||
|
const nanoid = customAlphabet('1234567890', len2)
|
||||||
|
return nanoid();
|
||||||
|
},
|
||||||
|
|
||||||
|
isJson: function (str) {
|
||||||
|
try {
|
||||||
|
JSON.parse(str);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
49
functions/reload.js
Normal file
49
functions/reload.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
function Reload(client, category, name) {
|
||||||
|
if (category === "events") {
|
||||||
|
if (!name) return 'Provide an event name to reload!'
|
||||||
|
try {
|
||||||
|
const evtName = name;
|
||||||
|
delete require.cache[require.resolve(`../events/${name}.js`)];
|
||||||
|
const pull = require(`../events/${name}`);
|
||||||
|
|
||||||
|
client.off(evtName, typeof client._events[evtName] == 'function' ? client._events[evtName] : client._events[evtName][0])
|
||||||
|
client.event.delete(evtName)
|
||||||
|
|
||||||
|
client.on(evtName, pull.bind(null, client))
|
||||||
|
client.event.set(evtName, pull.bind(null, client))
|
||||||
|
} catch (e) {
|
||||||
|
return `Couldn't reload: **${category}/${name}**\n**Error**: ${e.message}`
|
||||||
|
}
|
||||||
|
return `Reloaded event: **${name}**.js`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category === "functions") {
|
||||||
|
if (!name) return 'Provide a function name to reload!'
|
||||||
|
try {
|
||||||
|
const evtName = name;
|
||||||
|
delete require.cache[require.resolve(`../functions/${name}.js`)];
|
||||||
|
const pull = require(`../functions/${name}`);
|
||||||
|
|
||||||
|
client.functions.delete(evtName)
|
||||||
|
client.functions.set(evtName, pull)
|
||||||
|
} catch (e) {
|
||||||
|
return `Couldn't reload: **functions/${name}**\n**Error**: ${e.message}`
|
||||||
|
}
|
||||||
|
return `Reloaded function: **${name}**.js`
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!category) return 'Provide a command name to reload!'
|
||||||
|
delete require.cache[require.resolve(`../commands/${category}.js`)];
|
||||||
|
const pull = require(`../commands/${category}.js`);
|
||||||
|
if (client.commands.get(category).config.aliases) client.commands.get(category).config.aliases.forEach(a => client.aliases.delete(a));
|
||||||
|
client.commands.delete(category);
|
||||||
|
client.commands.set(category, pull);
|
||||||
|
if (client.commands.get(category).config.aliases) client.commands.get(category).config.aliases.forEach(a => client.aliases.set(a, category));
|
||||||
|
return `Reloaded command: **commands/${category}**.js`
|
||||||
|
} catch (e) {
|
||||||
|
return `Couldn't reload: **commands/${category}**\n**Error**: ${e.message}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Reload;
|
||||||
12
handlers/command.js
Normal file
12
handlers/command.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const { readdirSync } = require("fs")
|
||||||
|
const color = require("../functions/colorCodes")
|
||||||
|
module.exports = (client) => {
|
||||||
|
const commands = readdirSync(`./commands/`).filter(d => d.endsWith('.js'));
|
||||||
|
for (let file of commands) {
|
||||||
|
let pull = require(`../commands/${file}`);
|
||||||
|
client.commands.set(pull.config.name, pull);
|
||||||
|
if (pull.config.aliases) pull.config.aliases.forEach(a => client.aliases.set(a, pull.config.name));
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(color("%", `%b[Command_Handler]%7 :: Loaded %e${client.commands.size} %7commands`));
|
||||||
|
}
|
||||||
103
handlers/database.js
Normal file
103
handlers/database.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
const { connect } = require("mongoose").set('strictQuery', true);
|
||||||
|
const color = require("../functions/colorCodes")
|
||||||
|
|
||||||
|
module.exports = class DatabaseHandler {
|
||||||
|
constructor(connectionString) {
|
||||||
|
this.cache = new Map();
|
||||||
|
this.guildModel = require('../models/guilds');
|
||||||
|
this.connectionString = connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheSweeper(client) {
|
||||||
|
setInterval(() => {
|
||||||
|
const guilds = this.cache.values();
|
||||||
|
for (const g of guilds) {
|
||||||
|
if (!client?.servers?.has(g?.id)) {
|
||||||
|
this.cache.delete(g?.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 60 * 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
guildSweeper(client) {
|
||||||
|
setInterval(async () => {
|
||||||
|
const guilds = await this.getAll();
|
||||||
|
let i = 0;
|
||||||
|
for (const g of guilds) {
|
||||||
|
setTimeout(async () => {
|
||||||
|
i++;
|
||||||
|
if (!client?.servers?.has(g?.id)) {
|
||||||
|
this.cache.delete(g?.id)
|
||||||
|
this.deleteGuild(g?.id);
|
||||||
|
}
|
||||||
|
}, i * 600)
|
||||||
|
}
|
||||||
|
}, 180 * 180 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async connectToDatabase() {
|
||||||
|
await connect(this.connectionString, {
|
||||||
|
useNewUrlParser: true,
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log(color("%", `%4[Mongoose]%7 :: ${err}`));
|
||||||
|
}).then(() => console.log(
|
||||||
|
color("%", "%6[Mongoose]%7 :: Connected to MongoDB"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchGuild(guildId, createIfNotFound = false) {
|
||||||
|
const fetched = await this.guildModel.findOne({ id: guildId });
|
||||||
|
|
||||||
|
if (fetched) return fetched;
|
||||||
|
if (!fetched && createIfNotFound) {
|
||||||
|
await this.guildModel.create({
|
||||||
|
id: guildId,
|
||||||
|
language: 'en_EN',
|
||||||
|
botJoined: Date.now() / 1000 | 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.guildModel.findOne({ id: guildId });
|
||||||
|
} return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGuild(guildId, createIfNotFound = true, force = false) {
|
||||||
|
if (force) return this.fetchGuild(guildId, createIfNotFound);
|
||||||
|
|
||||||
|
if (this.cache.has(guildId)) {
|
||||||
|
return this.cache.get(guildId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetched = await this.fetchGuild(guildId, createIfNotFound);
|
||||||
|
if (fetched) {
|
||||||
|
this.cache.set(guildId, fetched?.toObject() ?? fetched);
|
||||||
|
|
||||||
|
return this.cache.get(guildId);
|
||||||
|
} return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteGuild(guildId, onlyCache = false) {
|
||||||
|
if (this.cache.has(guildId)) this.cache.delete(guildId);
|
||||||
|
|
||||||
|
return !onlyCache ? this.guildModel.deleteMany({ id: guildId }) : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateGuild(guildId, data = {}, createIfNotFound = false) {
|
||||||
|
let oldData = await this.getGuild(guildId, createIfNotFound);
|
||||||
|
|
||||||
|
if (oldData) {
|
||||||
|
if (oldData?._doc) oldData = oldData?._doc;
|
||||||
|
|
||||||
|
data = { ...oldData, ...data };
|
||||||
|
|
||||||
|
this.cache.set(guildId, data);
|
||||||
|
|
||||||
|
return this.guildModel.updateOne({
|
||||||
|
id: guildId,
|
||||||
|
}, data);
|
||||||
|
} return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAll() {
|
||||||
|
return this.guildModel.find();
|
||||||
|
}
|
||||||
|
};
|
||||||
12
handlers/event.js
Normal file
12
handlers/event.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const { readdirSync } = require("fs")
|
||||||
|
const color = require("../functions/colorCodes")
|
||||||
|
module.exports = (client) => {
|
||||||
|
const events = readdirSync(`./events/`).filter(d => d.endsWith('.js'));
|
||||||
|
for (let file of events) {
|
||||||
|
let evt = require(`../events/${file}`);
|
||||||
|
client.event.set(file.split(".")[0], evt.bind(null, client));
|
||||||
|
client.on(file.split('.')[0], evt.bind(null, client));
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(color("%", `%b[Event_Handler]%7 :: Loaded %e${client.event.size} %7events`));
|
||||||
|
};
|
||||||
11
handlers/function.js
Normal file
11
handlers/function.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const { readdirSync } = require("fs")
|
||||||
|
const logger = require("../functions/logger")
|
||||||
|
module.exports = (client) => {
|
||||||
|
const functions = readdirSync(`./functions`).filter(d => d.endsWith('.js'));
|
||||||
|
for (let file of functions) {
|
||||||
|
let evt = require(`../functions/${file}`);
|
||||||
|
client.functions.set(file.split(".")[0], evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
logger.event('Function_Handler', `Loaded ${client.functions.size} functions`);
|
||||||
|
};
|
||||||
98
handlers/translation.js
Normal file
98
handlers/translation.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
const color = require("../functions/colorCodes")
|
||||||
|
class TranslationHandler {
|
||||||
|
constructor(languages) {
|
||||||
|
|
||||||
|
this.availableLanguages = languages ?? [
|
||||||
|
'en_EN',
|
||||||
|
// 'es_ES',
|
||||||
|
//'ar_AR',
|
||||||
|
// 'pt_BR',
|
||||||
|
//'sk_SK',
|
||||||
|
];
|
||||||
|
|
||||||
|
this.translations = {};
|
||||||
|
|
||||||
|
for (const l of this.availableLanguages) {
|
||||||
|
const data = require(`../languages/${l}.json`);
|
||||||
|
this.initLanguage(l, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(color("%", `%b[Translation_Handler]%7 :: Loaded %e${this.availableLanguages.length} %7languages`));
|
||||||
|
}
|
||||||
|
|
||||||
|
initLanguage(key, language) {
|
||||||
|
this.translations[key] = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRegex(value) {
|
||||||
|
return /^[a-z]{2}_[A-Z]{2}$/.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLanguage(language) {
|
||||||
|
if (!this.checkRegex(language)) return this.translations['en_EN'];
|
||||||
|
return this.translations[language];
|
||||||
|
}
|
||||||
|
|
||||||
|
addLanguage(language) {
|
||||||
|
if (!this.checkRegex(language)) {
|
||||||
|
throw new Error('Invalid language format. Example: en_EN');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.availableLanguages.push(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
this.translations = {};
|
||||||
|
for (const l of this.availableLanguages) {
|
||||||
|
try {
|
||||||
|
const d = require(`../languages/${l}.json`);
|
||||||
|
|
||||||
|
if (!d) continue;
|
||||||
|
|
||||||
|
this.initLanguage(l, d);
|
||||||
|
return "Success"
|
||||||
|
} catch (e) {
|
||||||
|
return e.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(language, path, data = {}) {
|
||||||
|
if (!language) language = 'en_EN';
|
||||||
|
const l = this.getLanguage(language);
|
||||||
|
const p = path.split('.');
|
||||||
|
let c = null;
|
||||||
|
|
||||||
|
if (p.length > 0) {
|
||||||
|
for (const i of p) {
|
||||||
|
try {
|
||||||
|
if (!c) {
|
||||||
|
if (!l.hasOwnProperty(i)) break;
|
||||||
|
c = l[i];
|
||||||
|
} else {
|
||||||
|
if (!c.hasOwnProperty(i)) break;
|
||||||
|
c = c[i];
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return `Unknown translation: ${language} | ${path}`;;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c) return `Unknown translation: ${language} | ${path}`;;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
try {
|
||||||
|
return c.replace(/{(\w+)}/g, (match, key) => data[key] ?? match);
|
||||||
|
} catch (e) {
|
||||||
|
return `Unknown translation: ${language} | ${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = TranslationHandler;
|
||||||
58
index.js
Normal file
58
index.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
const { Client } = require("revolt.js");
|
||||||
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
const { token, mongoDB, api } = require("./botconfig.json");
|
||||||
|
const logger = require('./functions/logger');
|
||||||
|
const checkPolls = require('./functions/checkPolls')
|
||||||
|
|
||||||
|
const color = require("./functions/colorCodes");
|
||||||
|
|
||||||
|
const client = new Client({ baseURL: api });
|
||||||
|
const Uploader = require("revolt-uploader");
|
||||||
|
const fetch = require("wumpfetch");
|
||||||
|
const TranslationHandler = require('./handlers/translation');
|
||||||
|
const DatabaseHandler = require('./handlers/database');
|
||||||
|
|
||||||
|
client.Uploader = new Uploader(client);
|
||||||
|
client.config = require("./config");
|
||||||
|
client.translate = new TranslationHandler();
|
||||||
|
client.logger = require('./functions/logger');
|
||||||
|
client.botConfig = require("./botconfig.json");
|
||||||
|
|
||||||
|
client.database = new DatabaseHandler(mongoDB);
|
||||||
|
client.database.connectToDatabase();
|
||||||
|
client.database.cacheSweeper(client);
|
||||||
|
client.database.guildSweeper(client);
|
||||||
|
|
||||||
|
["reactions", "paginate", "timeout", "polls", "used", "messageCollector", "messageEdit"].forEach(x => client[x] = new Map());
|
||||||
|
["aliases", "commands", "event", "functions"].forEach(x => client[x] = new Collection());
|
||||||
|
["command", "event", "function"].forEach(x => require(`./handlers/${x}`)(client));
|
||||||
|
|
||||||
|
client.once("ready", async () => {
|
||||||
|
logger.success('Bot Ready', `${client.user.username} is ready`);
|
||||||
|
|
||||||
|
//client.database.connectToDatabase();
|
||||||
|
//client.database.cacheSweeper(client);
|
||||||
|
//client.database.guildSweeper(client);
|
||||||
|
|
||||||
|
await checkPolls(client);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
process.on("unhandledRejection", (reason, p) => {
|
||||||
|
console.log(color("%", "%4[Error_Handling] :: Unhandled Rejection/Catch%c"));
|
||||||
|
console.log(reason);
|
||||||
|
console.log(p)
|
||||||
|
});
|
||||||
|
process.on("uncaughtException", (err, origin) => {
|
||||||
|
console.log(color("%", "%4[Error_Handling] :: Uncaught Exception/Catch%c"));
|
||||||
|
console.log(err);
|
||||||
|
console.log(origin)
|
||||||
|
});
|
||||||
|
process.on("uncaughtExceptionMonitor", (err, origin) => {
|
||||||
|
console.log(color("%", "%4[Error_Handling] :: Uncaught Exception/Catch (MONITOR)%c"));
|
||||||
|
console.log(err);
|
||||||
|
console.log(origin)
|
||||||
|
});
|
||||||
|
|
||||||
|
client.loginBot(token);
|
||||||
257
languages/en_EN.json
Normal file
257
languages/en_EN.json
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
{
|
||||||
|
"Events": {
|
||||||
|
"messageCreate": {
|
||||||
|
"wait": "wait",
|
||||||
|
"wait2": "before using",
|
||||||
|
"wait3": "again",
|
||||||
|
"unable": "Unable to send messages in",
|
||||||
|
"contact": "please contact a server administrator to get this settled",
|
||||||
|
"noPerms": "Need permission to react as all of my features use reactions",
|
||||||
|
"unavail": "This command is currently unavailable",
|
||||||
|
"perms": "You don't have the required permissions to use this command",
|
||||||
|
"perms2": "Permission needed",
|
||||||
|
"prefix": "My prefix is",
|
||||||
|
"prefix2": "To get started, type",
|
||||||
|
"noRoles": "There are no roles in your message, provide some by following this example",
|
||||||
|
"noReact": "I don't have permission to add reactions so this may not work correctly.",
|
||||||
|
"maxRoles": "You can only have a maximum of 20 roles in your message.",
|
||||||
|
"unknown": "There are unknown roles in your message, please remove them and try again.",
|
||||||
|
"duplicate": "There are duplicate roles in your message, please remove them and try again",
|
||||||
|
"positions": "There are roles with higher ranks (position) than my highest role in your message, please remove them and try again"
|
||||||
|
},
|
||||||
|
"messageReactionAdd": {
|
||||||
|
"title": "title",
|
||||||
|
"owner": "Owner",
|
||||||
|
"end": "ended the poll early. These are the final results",
|
||||||
|
"tooFast": "You are reacting too fast! Please wait a few seconds before reacting again.",
|
||||||
|
"joined": "You joined giveaway",
|
||||||
|
"joined2": "There's currently",
|
||||||
|
"joined3": "user(s) in this giveaway!",
|
||||||
|
"early": "ended the giveaway early",
|
||||||
|
"endNone": "No one entered into the giveaway, so there are no winners",
|
||||||
|
"ended": "Ended",
|
||||||
|
"prize": "Prize",
|
||||||
|
"winnersNone": "Winner(s): None",
|
||||||
|
"none": "None",
|
||||||
|
"reqs": "Requirement",
|
||||||
|
"giveaway": "Giveaway",
|
||||||
|
"partici": "Participants",
|
||||||
|
"winners": "Winner(s)",
|
||||||
|
"congrats": "Congratulations",
|
||||||
|
"youWon": "You won the giveaway for",
|
||||||
|
"cooldown": "Reaction cooldown is 3 seconds",
|
||||||
|
"success": "Successfully added role {role}",
|
||||||
|
"noPerms": "I do not have permission to give role {role}",
|
||||||
|
"role": "role",
|
||||||
|
"deleteCollector": "Successfully stopped reaction collector!"
|
||||||
|
},
|
||||||
|
"messageReactionRemove": {
|
||||||
|
"title": "Title",
|
||||||
|
"tooFast": "You are reacting too fast! Please wait a few seconds before reacting again.",
|
||||||
|
"left": "You left giveaway",
|
||||||
|
"left2": "There are now",
|
||||||
|
"left3": "user(s) in this giveaway",
|
||||||
|
"success": "Successfully removed role {role}",
|
||||||
|
"noPerms": "I do not have permission to remove role {role}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Commands": {
|
||||||
|
"roles": {
|
||||||
|
"description": "Setup a reaction role message for your server",
|
||||||
|
"usage": "help",
|
||||||
|
"already": "You already have an active message collector going on! Finish that first before starting a new one.",
|
||||||
|
"pick": "Provide what you would like the type of message to be sent. Options: `embed`, `content`",
|
||||||
|
"ended": "The message collector has ended after 25 minutes.",
|
||||||
|
"success": "Successfully sent message collector to",
|
||||||
|
"react": "Send a message you would like to be as your reaction role message. After that is done, react with emojis in order of the roles you want to be added to the message.",
|
||||||
|
"react2": "Once you're done, react with ✅ to complete it.\nTo cancel this reaction collector, react with ❌ to stop it!",
|
||||||
|
"noPerms": "I require the `AssignRoles` permission to add roles to users.",
|
||||||
|
"max": "You can only have a maximum of 12 reaction role messages in your server.",
|
||||||
|
"noRoles": "There are no reaction role messages setup currently. To add some, type",
|
||||||
|
"jump": "Jump",
|
||||||
|
"roles": "Roles",
|
||||||
|
"delete": "Provide an ID for the reaction role message to delete it",
|
||||||
|
"edit": "Provide an ID for the reaction role message to edit it",
|
||||||
|
"notFound": "I could not find a reaction role message with that ID.",
|
||||||
|
"deleted": "Successfully deleted that reaction role message.",
|
||||||
|
"view": "Viewing Reaction Role Messages",
|
||||||
|
"dms": "Successfully toggled DM messages",
|
||||||
|
"on": "On",
|
||||||
|
"off": "Off",
|
||||||
|
"create": "Creating",
|
||||||
|
"createExample": "create [Channel Mention] [Type: content | embed]",
|
||||||
|
"editing": "Editing",
|
||||||
|
"viewing": "Viewing",
|
||||||
|
"deleting": "Deleting",
|
||||||
|
"msgId": "Message",
|
||||||
|
"explain": "Explanation",
|
||||||
|
"explain2": "When you create a reaction message (`f!roles create`), you will need to provide it with roles (format: `{role:Blue}`) and I will copy your message. React to my message to automatically update the roles and once you are finished, react with ✅ to complete it.",
|
||||||
|
"dm": "Direct Messages"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"description": "Help command",
|
||||||
|
"usage": "[Command (Optional)]",
|
||||||
|
"embeds": {
|
||||||
|
"first": {
|
||||||
|
"cmdName": "Command",
|
||||||
|
"cmdDesc": "Description",
|
||||||
|
"cmdAvail": "Availability",
|
||||||
|
"cmdAvail2": "Available",
|
||||||
|
"cmdAvail3": "Unavailable",
|
||||||
|
"cmdCool": "Cooldown",
|
||||||
|
"cmdCool2": "seconds",
|
||||||
|
"cmdPerms": "Permissions",
|
||||||
|
"cmdPerms2": "None",
|
||||||
|
"cmdAlias": "Aliases",
|
||||||
|
"cmdUsage": "Usage"
|
||||||
|
},
|
||||||
|
"second": {
|
||||||
|
"start": "Available Commands",
|
||||||
|
"middle": "Unavailable Commands",
|
||||||
|
"end": "To get more information about a command, type",
|
||||||
|
"end2": "command"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"description": "Stats on the bot",
|
||||||
|
"start": "Random Information",
|
||||||
|
"servers": "Servers",
|
||||||
|
"giveaways": "Giveaways",
|
||||||
|
"polls": "Polls",
|
||||||
|
"uptime": "Uptime",
|
||||||
|
"ping": "Ping",
|
||||||
|
"database": "Database",
|
||||||
|
"library": "Library",
|
||||||
|
"links": "Links",
|
||||||
|
"links2": "Invite",
|
||||||
|
"links3": "Support"
|
||||||
|
},
|
||||||
|
"giveaway": {
|
||||||
|
"description": "Creates a giveaway. Reactions have 3 second cooldown.",
|
||||||
|
"usage": "[Time, E.g. 20m] | [Winners] | [Prize] | [Requirement (Optional)] [Channel (Optional), E.g. channel:#giveaways]",
|
||||||
|
"tooMany": "This server has 15 giveaways currently running. Wait until one finishes before making anymore!",
|
||||||
|
"validChannel": "Please provide a valid channel mention or channel ID.\nExample",
|
||||||
|
"validChannel2": "Note: If you are using a channel ID, provide it after the requirement text",
|
||||||
|
"validTime": "Please provide a valid time.\nExample",
|
||||||
|
"validWinners": "Please provide the amount of winners. Maximum: 5\nExample",
|
||||||
|
"validPrize": "Please provide the prize.\nExample",
|
||||||
|
"ormore": "Giveaways can only be 5 minutes or above in time!\nExample",
|
||||||
|
"orless": "Please provide a time shorter than 365 days.\nExample",
|
||||||
|
"format": "You failed to follow the giveaway format.\nExample",
|
||||||
|
"formatWinners": "You failed to properly specific how many winners there are\nExample",
|
||||||
|
"maxwins": "When making a giveaway, you can only have a maximum of 5 winners.\nExample",
|
||||||
|
"giveaway": "Giveaway",
|
||||||
|
"react": "React with",
|
||||||
|
"react2": "to enter!",
|
||||||
|
"hosted": "Hosted by",
|
||||||
|
"time": "Time",
|
||||||
|
"prize": "Prize",
|
||||||
|
"winners": "Winners",
|
||||||
|
"reqs": "Requirement",
|
||||||
|
"noperms": "I do not have permission to send messages in",
|
||||||
|
"noperms2": "I do not have permission to view",
|
||||||
|
"noperms3": "I do not have permission to add reactions in",
|
||||||
|
"success": "Successfully sent giveaway to"
|
||||||
|
},
|
||||||
|
"polls": {
|
||||||
|
"description": "Creates a poll. Reactions have 3 second cooldown.",
|
||||||
|
"usage": "[Time, E.g. 10m] | [Question] | [Option 1] | [Option 2] | [Options 3-10 (Optional)]",
|
||||||
|
"tooMany": "You already have 5 polls running. Wait for one to end before creating anymore.",
|
||||||
|
"validTime": "Please provide a valid time.\nExample",
|
||||||
|
"longerThan": "Please provide a time longer than 30 seconds.\nExample",
|
||||||
|
"shorterThan": "Please provide a time shorter than 30 days.\nExample",
|
||||||
|
"validQuestion": "Please provide a question.\nExample",
|
||||||
|
"validOption": "Please provide the first option for the question. Maximum of 10 options.\nExample",
|
||||||
|
"validOption2": "Please provide the second option for the question. Maximum of 10 options.\nExample",
|
||||||
|
"maxOptions": "Please provide a maximum of 10 options.\nExample",
|
||||||
|
"polls": "Polls",
|
||||||
|
"title": "Title",
|
||||||
|
"example": "How are you? | Good | Bad"
|
||||||
|
},
|
||||||
|
"reroll": {
|
||||||
|
"description": "Reroll winners from giveaways. Winner number is based on the order of the winners in the embed.",
|
||||||
|
"usage": "[Message ID] [Winner Number, E.g. 1, 2, all | Default: all]",
|
||||||
|
"validID": "Please provide a valid message ID.",
|
||||||
|
"notValid": "I could not find a giveaway message with that ID.",
|
||||||
|
"winners": "Please provide a winner number (E.g. 1, 2, 3) or use `all` to reroll all winners!",
|
||||||
|
"notEnded": "This giveaway hasn't ended yet!",
|
||||||
|
"notHosted": "You can't reroll this giveaway because you didn't host it!",
|
||||||
|
"noUsers": "There are no users in this giveaway to reroll!",
|
||||||
|
"noPicks": "There are no more users that can be picked for rerolling!",
|
||||||
|
"onlyWinners": "There are only",
|
||||||
|
"onlyWinners2": "winner(s) to pick from!\nExample",
|
||||||
|
"winnerNum": "Winner Number",
|
||||||
|
"giveaway": "Giveaway",
|
||||||
|
"owner": "Owner",
|
||||||
|
"rerolled": "rerolled",
|
||||||
|
"winners1": "all winners!",
|
||||||
|
"winners2": "winner position",
|
||||||
|
"partici": "Participants",
|
||||||
|
"ended": "Ended",
|
||||||
|
"prize": "Prize",
|
||||||
|
"winner": "Winner(s)",
|
||||||
|
"reqs": "Requirement",
|
||||||
|
"reroll": "The giveaway was rerolled! New winner(s)",
|
||||||
|
"reroll2": "won the giveaway for",
|
||||||
|
"error": "Unable to send message for new winners",
|
||||||
|
"error2": "Unable to edit embed"
|
||||||
|
},
|
||||||
|
"prefix": {
|
||||||
|
"success": "Prefix successfully changed to",
|
||||||
|
"tooMany": "Prefix cannot be longer than 8 characters.",
|
||||||
|
"prefix": "Prefix",
|
||||||
|
"change": "To change the prefix, use",
|
||||||
|
"new": "new prefix",
|
||||||
|
"description": "Changes default prefix to your own",
|
||||||
|
"usage": "<text>"
|
||||||
|
},
|
||||||
|
"credits": {
|
||||||
|
"thankyou": "As developer of Functious, I wanted to thank everyone who contributed toward the bot.",
|
||||||
|
"thankyou2": "The bot wouldn't be where it is without all of you, thank you!",
|
||||||
|
"translators": "Translators",
|
||||||
|
"title": "Credits",
|
||||||
|
"description": "Credits for everyone who helped"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"description": "Changes the language of the bot",
|
||||||
|
"usage": "<language>",
|
||||||
|
"example": "Example",
|
||||||
|
"current": "Current",
|
||||||
|
"change": "You can change your server's language by picking an available language.",
|
||||||
|
"avail": "Available",
|
||||||
|
"notAvailable": "Chosen language is not supported! ",
|
||||||
|
"success": "Successfully changed the language to"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Functions": {
|
||||||
|
"fetchTime": {
|
||||||
|
"years": "year(s)",
|
||||||
|
"days": "day(s)",
|
||||||
|
"hours": "hour(s)",
|
||||||
|
"minutes": "minute(s)",
|
||||||
|
"seconds": "second(s)"
|
||||||
|
},
|
||||||
|
"giveawaysEnd": {
|
||||||
|
"giveaway": "Giveaway",
|
||||||
|
"noUsers": "No one entered into the giveaway so I couldn't pick a winner",
|
||||||
|
"ended": "Ended",
|
||||||
|
"prize": "Prize",
|
||||||
|
"winnersNone": "Winner(s): None",
|
||||||
|
"winners": "Winner(s)",
|
||||||
|
"reqs": "Requirement",
|
||||||
|
"noOne": "No one entered into giveaway",
|
||||||
|
"warn": "[Channel Edit] Unable to edit message",
|
||||||
|
"warn1": "in channel",
|
||||||
|
"warn2": "[Channel Post] Unable to post to channel",
|
||||||
|
"givEnd": "Giveaway Ended",
|
||||||
|
"partici": "Participants",
|
||||||
|
"congrats": "Congratulations",
|
||||||
|
"youWon": "You won the giveaway for"
|
||||||
|
},
|
||||||
|
"poll": {
|
||||||
|
"end": "This poll has ended and these are the results"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"links4": "Vote"
|
||||||
|
}
|
||||||
13
models/commands.js
Normal file
13
models/commands.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
const moment = require('moment');
|
||||||
|
const timestamp = moment().valueOf() / 1000;
|
||||||
|
|
||||||
|
const commands = new Schema({
|
||||||
|
id: { type: String },
|
||||||
|
name: { type: String },
|
||||||
|
content: { type: String },
|
||||||
|
createdBy: { type: String },
|
||||||
|
created_at: { type: String, default: timestamp }
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("commands", commands);
|
||||||
21
models/giveaways.js
Normal file
21
models/giveaways.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const giveaways = new Schema({
|
||||||
|
owner: { type: String, required: true },
|
||||||
|
serverId: { type: String, required: true },
|
||||||
|
channelId: { type: String, required: true },
|
||||||
|
messageId: { type: String, required: true },
|
||||||
|
users: [{ type: Object }],
|
||||||
|
time: { type: String, required: true },
|
||||||
|
now: { type: String, required: true },
|
||||||
|
prize: { type: String, required: true },
|
||||||
|
winners: { type: Number, required: true },
|
||||||
|
pickedWinners: [{ type: Object }],
|
||||||
|
picking: [{ type: Object }],
|
||||||
|
ended: { type: Boolean, default: false },
|
||||||
|
lang: { type: String, required: true, default: "en_EN" },
|
||||||
|
requirement: { type: String },
|
||||||
|
endDate: { type: String }
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("giveaways", giveaways);
|
||||||
12
models/guilds.js
Normal file
12
models/guilds.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const guilds = new Schema({
|
||||||
|
id: { type: String },
|
||||||
|
prefix: { type: String, default: "f!" },
|
||||||
|
language: { type: String, default: "en_EN" },
|
||||||
|
joined: { type: String, default: Date.now() / 1000 | 0 },
|
||||||
|
dm: { type: Boolean, default: true },
|
||||||
|
roles: { type: Array, default: [] },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("guilds", guilds);
|
||||||
12
models/logging.js
Normal file
12
models/logging.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const logging = new Schema({
|
||||||
|
id: { type: String },
|
||||||
|
type: { type: String },
|
||||||
|
ranBy: { type: String },
|
||||||
|
name: { type: String },
|
||||||
|
channel: { type: String },
|
||||||
|
created_at: { type: String, default: Date.now() / 1000 }
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("logging", logging);
|
||||||
17
models/polls.js
Normal file
17
models/polls.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const polls = new Schema({
|
||||||
|
owner: { type: String },
|
||||||
|
serverId: { type: String },
|
||||||
|
channelId: { type: String },
|
||||||
|
messageId: { type: String },
|
||||||
|
avatars: { type: Object },
|
||||||
|
votes: { type: Object },
|
||||||
|
users: { type: Object },
|
||||||
|
time: { type: Number },
|
||||||
|
now: { type: Number },
|
||||||
|
desc: { type: String },
|
||||||
|
options: { type: Object },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("polls", polls);
|
||||||
10
models/registerInvite.js
Normal file
10
models/registerInvite.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const registerInvite = new Schema({
|
||||||
|
userId: { type: String },
|
||||||
|
invite: { type: String },
|
||||||
|
staffRoles: { type: Object },
|
||||||
|
createdAt: { type: Number },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("registerInvite", registerInvite);
|
||||||
19
models/rule7.js
Normal file
19
models/rule7.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const rule7 = new Schema({
|
||||||
|
owner: { type: String },
|
||||||
|
serverId: { type: String },
|
||||||
|
channelId: { type: String },
|
||||||
|
messageId: { type: String },
|
||||||
|
avatars: { type: Object },
|
||||||
|
votes: { type: Object },
|
||||||
|
users: { type: Object },
|
||||||
|
time: { type: Number },
|
||||||
|
now: { type: Number },
|
||||||
|
desc: { type: String },
|
||||||
|
options: { type: Object },
|
||||||
|
threadId: { type: String },
|
||||||
|
reportId: { type: String },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("rule7", rule7);
|
||||||
9
models/savedPolls.js
Normal file
9
models/savedPolls.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const { Schema, model } = require("mongoose");
|
||||||
|
|
||||||
|
const savedPolls = new Schema({
|
||||||
|
owner: { type: String },
|
||||||
|
desc: { type: String },
|
||||||
|
options: { type: Object },
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = model("savedPolls", savedPolls);
|
||||||
1715
package-lock.json
generated
Normal file
1715
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
package.json
Normal file
29
package.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node index.js"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@discordjs/collection": "^1.5.1",
|
||||||
|
"axios": "^1.9.0",
|
||||||
|
"canvas": "^2.11.2",
|
||||||
|
"chalk": "^4.1.2",
|
||||||
|
"date-fns": "^4.1.0",
|
||||||
|
"fs": "^0.0.1-security",
|
||||||
|
"moment": "^2.29.4",
|
||||||
|
"mongoose": "^7.2.0",
|
||||||
|
"nanoid": "3.3.4",
|
||||||
|
"node-fetch-commonjs": "^3.3.2",
|
||||||
|
"revolt-uploader": "^1.1.1",
|
||||||
|
"revolt.js": "npm:revolt.js-update@^7.0.0-beta.9",
|
||||||
|
"screen": "^0.2.10",
|
||||||
|
"wumpfetch": "^0.3.1"
|
||||||
|
},
|
||||||
|
"information": {
|
||||||
|
"Developer": "Ryahn",
|
||||||
|
"Discord": "ainzooalgown",
|
||||||
|
"Revolt": "Ryahn#1337",
|
||||||
|
"GitHub": "https://github.com/Ryahn/zonies"
|
||||||
|
}
|
||||||
|
}
|
||||||
27
test.js
Normal file
27
test.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// const { token, mongoDB, api } = require("./botconfig.json");
|
||||||
|
// const DatabaseHandler = require('./handlers/database');
|
||||||
|
// const util = require('util');
|
||||||
|
// const { isJson } = require('./functions/randomStr')
|
||||||
|
|
||||||
|
// const database = new DatabaseHandler(mongoDB);
|
||||||
|
// database.connectToDatabase();
|
||||||
|
|
||||||
|
// const CommandDB = require('./models/commands');
|
||||||
|
|
||||||
|
// let data = CommandDB.find({}).select('name').then((data) => {
|
||||||
|
// let names = [];
|
||||||
|
// data.forEach((item) => { names.push(item.name) })
|
||||||
|
// console.log(names.join(', '))
|
||||||
|
// })
|
||||||
|
(async () => {
|
||||||
|
|
||||||
|
const axios = require("axios");
|
||||||
|
const query = 'yeet'
|
||||||
|
const url = ('https://api.urbandictionary.com/v0/define?term=' + query)
|
||||||
|
const response = await axios.get(url);
|
||||||
|
const data = response.data;
|
||||||
|
const def = data.list[0];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
Loading…
x
Reference in New Issue
Block a user