master
Kit Kasune 3 years ago
parent 558669b968
commit e1c7093d80
  1. 54
      commands/leveling/leaderboard.js
  2. 2
      commands/leveling/stats.js
  3. 119
      commands/utility/apply.js
  4. 4
      events/message.js
  5. 14
      util/lxp/cacheloop.js
  6. 6
      util/lxp/gainxp.js

@ -0,0 +1,54 @@
const Discord = require('discord.js');
const Monners = require('../../models/monners');
const XP = require('../../models/localxp');
module.exports = {
name: "leaderboard",
aliases: ['lb', 'rank'],
meta: {
category: 'Leveling',
description: "Find your place in the server's ranks and see the top-ranking members in the server.",
syntax: '`leaderboard`',
extra: null,
guildOnly: true
},
help: "Find your place in the server's ranks and see the top-ranking members in the server.",
async execute(message, msg, args, cmd, prefix, mention, client) {
let cfmh = '<a:CF_moonheart:868653516913246208>';
let gxp = await XP.findOne({gid: message.guild.id});
let xp = gxp.xp;
let lvlp = Object.keys(xp).sort((a, b) => {return xp[a][1] - xp[b][1];}).reverse();
let lvl = lvlp.slice(0, Object.keys(xp).length >= 5 ? 5 : Object.keys(xp).length);
let lvls = ``;
let i; for (i=0; i<lvl.length; i++) {lvls += `${i+1}. <@${lvl[i]}> -> **Level ${xp[lvl[i]][1]}**\n`;}
lvls += `\n${cfmh} *You are ranked #${lvlp.indexOf(message.author.id) + 1} at Level ${xp[lvlp[i]][1]}.*`;
/*let tmon = {};
for (let u of Object.keys(xp)) {let um = await Monners.findOne({uid: u}); if (um) {tmon[u] = um.currency;}};
let tmp = Object.keys(tmon).sort((a, b) => {return tmon[a] - tmon[b];}).reverse();
let tm = tmp.slice(0, Object.keys(tmon).length >= 5 ? 5 : Object.keys(tmon).length);
let tms = ``;
let i2; for (i2=0; i2<tm.length; i2++) {tms += `${i2+1}. <@${tm[i2]}> -> **${tmon[tm[i2]]}** <a:CF_mooners:868652679717589012>\n`;}
tms += `\n${cfmh} *You are ranked #${lvlp.indexOf(message.author.id) + 1} at ${tmon[tmp[i2]]} Mooners.*`;*/
return message.channel.send(new Discord.MessageEmbed()
.setTitle("Server Leaderboard")
.setThumbnail(message.guild.iconURL({size: 2048, dynamic: true}))
.addField("Level", lvls)
//.addField("Mooners", tms)
.setColor('328ba8')
.setFooter("Luno | Stats may be up to 2 minutes out of sync")
.setTimestamp()
);
/*u = Object.keys(tm.messages.members).sort((a, b) => {return tm.messages.members[a] - tm.messages.members[b];}).reverse().slice(0, Object.keys(tm.messages.members).length >= 5 ? 5 : Object.keys(tm.messages.members).length);
us = ``;
let i2; for (i2=0; i2<u.length; i2++) {us += `${i2+1}. <@${u[i2]}> -> **${tm.messages.members[u[i2]]} Messages**\n`;}*/
//if (args[0] && ['mooners', 'currency', 'balance', 'bal'].includes(args[0].toLowerCase())) {}
//else {}
}
};

@ -28,7 +28,7 @@ module.exports = {
if (!txp.xp[u.id]) {return message.channel.send(`${u.id === message.author.id ? "You" : "That user"} doesn't have any leveling info available!`);} if (!txp.xp[u.id]) {return message.channel.send(`${u.id === message.author.id ? "You" : "That user"} doesn't have any leveling info available!`);}
xp = {xp: txp.xp[u.id][0], level: txp.xp[u.id][1]}; xp = {xp: txp.xp[u.id][0], level: txp.xp[u.id][1]};
} else {xp = client.misc.cache.lxp.xp[message.guild.id][u.id];} } else {xp = client.misc.cache.lxp.xp[message.guild.id][u.id];}
let tmoon = await Monners.findOne({uid: u.id}); let tmoon = client.misc.cache.monners[u.id] ? {currency: client.misc.cache.monners[u.id]} : await Monners.findOne({uid: u.id});
return message.channel.send(new Discord.MessageEmbed() return message.channel.send(new Discord.MessageEmbed()
.setTitle(`${u.displayName}${u.displayName.toLowerCase().endsWith('s') ? "'" : "'s"} Stats`) .setTitle(`${u.displayName}${u.displayName.toLowerCase().endsWith('s') ? "'" : "'s"} Stats`)
.setDescription("Local leveling stats") .setDescription("Local leveling stats")

@ -0,0 +1,119 @@
const Discord = require('discord.js');
const moment = require('moment');
require('moment-precise-range-plugin');
const ModApp = require('../../models/modapp');
const ask = require('../../util/ask');
module.exports = {
name: "apply",
meta: {
category: 'Utility',
description: "Apply for a moderation position here!",
syntax: '`apply`',
extra: null
},
help: "Apply for a moderation position here!",
async execute(message, msg, args, cmd, prefix, mention, client) {
let ma = await ModApp.findOne({gid: client.misc.neptune}) || new ModApp({gid: client.misc.neptune});
if (!ma.enabled && !message.author.id === '330547934951112705') {return message.channel.send("Moderation applications are not currently open at this time! We'll announce when we're looking for mods, so keep your eyes peeled!");}
if (ma.apps[message.author.id]) {return message.channel.send("Looks like you already have an application made! If you need it to be removed for some reason, contact WubzyGD.");};
function clearDM() {client.misc.activeDMs.delete(message.author.id);}
if (client.misc.activeDMs.has(message.author.id)) {return message.reply("I'm already asking you questions in DM! Finish that command before using this one.");}
client.misc.activeDMs.set(message.author.id, 'modapp');
if (message.guild) {message.channel.send("Check your DMs!");}
let mesg = await message.author.send("I'll be asking you a few questions here about yourself. You can simply ignore the messages for a few minutes to cancel the process. If at any point I tell you that you did something wrong (usually that your answer was too long), you'll need to restart your application.").catch(() => {message.reply("Please open your DMs so I can ask you some questions!");});
let dmch = mesg.channel;
let conf = await ask(mesg, "The whole of the moderation team (but nobody else) at Crescent's Family will be able to see this application's responses. Joke responses will be rejected and may result in consequences. Responses with little or no effort or grammatical quality will be rejected. Are you clear about these things?", 60000, true); if (!conf) {return clearDM();}
if (['n', 'no'].includes(conf.trim().toLowerCase())) {clearDM(); return dmch.send("Oh, alrighty. Thanks for trying to apply... I guess?");}
if (!['yes', 'ye', 'y', 'sure'].includes(conf.trim().toLowerCase())) {clearDM(); return dmch.send("Please specify yes or no you weeb!");}
let name = await ask(mesg, "**:crescent_moon:┋ Q1 •** What is your name (optional) and Discord username (with tag)?", 120000, true); if (!name) {return clearDM();}
if (name.length > 50) {clearDM(); return dmch.send("Are you sure your name's that long? :sweat_smile: Make sure you're only stating your name and username.");}
let agep = await ask(mesg, "**:crescent_moon:┋ Q2 •** How old are you and what are your preferred pronouns?", 90000, true); if (!agep) {return clearDM();}
if (agep.length > 150) {clearDM(); return dmch.send(":sweat_smile: let's keep your answer a little shorter than that, please.");}
let hobbies = await ask(mesg, "**:crescent_moon:┋ Q3 •** Do you have any special hobbies? (Optional, if you choose not to, put '**N/A**') (Please be brief)", 180000, true); if (!hobbies) {return clearDM();}
if (hobbies.length > 750) {clearDM(); return dmch.send("Heya! Please send just a quick list of your hobbies!");}
let tz = await ask(mesg, "**:crescent_moon:┋ Q4 •** What is your time zone? (EX: CST, EST) ", 60000, true); if (!tz) {return clearDM();}
if (tz.length > 150) {clearDM(); return dmch.send("That's way too long to be a timezone...");}
let experience = await ask(mesg, "**:crescent_moon:┋ Q5 •** Do you have any Moderation experience? If so, what kind of community/communities did you moderate, what position(s) did you have? If you have loads of experience, please specify your most notable and lengthy positions.", 240000, true); if (!experience) {return clearDM();}
if (experience.length > 1000) {clearDM(); return dmch.send("Heya! That looks like a lot of experiece, but we want to avoid bloat-y applications, so please try again and be more brief in your response.");}
let contrib = await ask(mesg, "**:crescent_moon:┋ Q6 •** If you were to be accepted into our team, what special contributions can you bring to the server and team? How would the community benefit from your role?", 240000, true); if (!contrib) {return clearDM();}
if (contrib.length > 1024) {clearDM(); return dmch.send("I love that you're enthusiastic, but I'm gonna forget all of that. Can you try getting to the point just a *liiitle* more quickly?");}
let time = await ask(mesg, "**:crescent_moon:┋ Q7 •** What days are you active on Discord, and how much time do you typically spend in the server? (Use mostly numbers and quick answers, like \"I'm active whenever I'm not at school/work, and I usually spend 3 or 4 hours a day in the server.\" Yes, you can use that if it applies to you)", 120000, true); if (!time) {return clearDM();}
if (time.length > 500) {clearDM(); return dmch.send("Oi! I said be brief!");}
let warn = await ask(mesg, "**:crescent_moon:┋ Q8 •** What do you consider to be a **warnable offense**? *(aka giving someone a warning through a bot or verbal)*", 120000, true); if (!warn) {return clearDM();}
if (warn.length > 750) {clearDM(); return dmch.send("Just like... a couple examples is fine...");}
let mute = await ask(mesg, "**:crescent_moon:┋ Q9 •** What do you consider to be a **mute-able offense**? *(aka preventing someone from being able to speak for a given duration of time)*", 120000, true); if (!mute) {return clearDM();}
if (mute.length > 750) {clearDM(); return dmch.send("Just like... a couple examples is fine...");}
let ban = await ask(mesg, "**:crescent_moon:┋ Q10 •** What do you consider to be a **bannable offense**? *(aka permanently removing someone from the server)*", 120000, true); if (!ban) {return clearDM();}
if (ban.length > 750) {clearDM(); return dmch.send("Just like... a couple examples is fine...");}
let traits = await ask(mesg, "**:crescent_moon:┋ Q11 •** What are some of your **strengths** and **weaknesses**? You don't have to spoil your deepest darkest secret, and if you're not comfortable with sharing, then say **N/A**, but this makes selecting you more difficult as we won't know you as well.", 240000, true); if (!traits) {return clearDM();}
if (traits.length > 1000) {clearDM(); return dmch.send("The Discord police won't let me let you have a response longer than that, sadly. Can you try shortening it a little? Thanks.");}
let notes = await ask(mesg, "**:crescent_moon:┋ Q12 •** Anything else you'd like to briefly add? (**N/A** if not)", 240000, true); if (!notes) {return clearDM();}
if (notes.length > 1000) {clearDM(); return dmch.send("C'mon now, I said *briefly*.");}
let fconf = await ask(mesg, "Is this your card? Or... ehm... are you sure that the answers you have submitted are what you want to use, as they cannot be changed?", 120000, true); if (!fconf) {return clearDM();}
if (['n', 'no'].includes(fconf.trim().toLowerCase())) {clearDM(); return dmch.send("Oh, alrighty. I won't send your application.");}
if (!['yes', 'ye', 'y', 'sure'].includes(fconf.trim().toLowerCase())) {clearDM(); return dmch.send("Please specify yes or no you weeb!");}
clearDM();
try {
let mch = await client.fetchWebhook("869739554897285150", "o1igg02aB_rFNPbucnIe-ntN0gTsKYnC47NWYNQoFP536EliAQtqLuAFK6NQy1Wzr1_a");
mch.send("<@&814668063366184960>", {
username: "Luno | Moderation Applications",
avatarURL: client.user.avatarURL({size: 2048}),
embeds: [
new Discord.MessageEmbed()
.setAuthor(message.author.tag, message.author.avatarURL())
.setTitle("New Moderator Application")
.setDescription(`User ID: **${message.author.id}**\nThey've been in the server for **${moment.preciseDiff(moment(client.guilds.cache.get(client.misc.neptune).members.cache.get(message.author.id).joinedAt), moment())}**\n\nThis is the personal section of the application.`)
.addField("Name", name, true)
.addField("Age/Pronouns", agep, true)
.addField("Hobbies", hobbies)
//.addField("Server Time", sage)
.addField("Timezone", tz)
.addField("Activity/Dedication", time)
.addField("Experience", experience)
.addField("Contribution", contrib)
.addField("Strengths/Weaknesses", traits)
.addField("Other Notes", notes)
.setColor('dc134c')
.setFooter("Luno | Part 1 of 2")
.setTimestamp(),
new Discord.MessageEmbed()
.setAuthor(message.author.tag, message.author.avatarURL())
.setDescription(`This is the moderation section of the application.`)
.addField("Warnable Offense(s)", warn)
.addField("Mute-able Offense(s)", mute)
.addField("Bannable Offense(s)", ban)
.setColor('dc134c')
.setFooter("Luno | Part 2 of 2")
.setTimestamp()
]
}).then(async whm => {
await whm.react('👍');
await whm.react('👎');
ma.apps[message.author.id] = "Submitted";
ma.markModified(`apps.${message.author.id}`);
await ma.save();
return dmch.send("Your application has been submitted. Please be patient as we review the applications. Do not harrass any member of staff about the results of the apps or their progress. **You will be muted or banned.**");
}).catch((e) => {dmch.send("For some reason, your application was not submitted. Please contact WubzyGD#8766 **as soon as possible** to resolve this issue."); console.log(e);})
} catch (e) {console.log(e); return dmch.send("For some reason, your application was not submitted. Please contact WubzyGD#8766 **as soon as possible** to resolve this issue.");}
}
};

@ -64,8 +64,12 @@ module.exports = async (client, message) => {
} }
if (!client.misc.cache.monners[message.author.id]) { if (!client.misc.cache.monners[message.author.id]) {
//console.log("\nMESSAGE/CACHE || User not cached: " + message.member.displayName);
let tmonners = await Monners.findOne({uid: message.author.id}) || new Monners({uid: message.author.id}); let tmonners = await Monners.findOne({uid: message.author.id}) || new Monners({uid: message.author.id});
//console.log(`MESSAGE/CACHE || Caching. User ${tmonners.currency ? chalk.greenBright('has') : chalk.redBright("doesn't have")} currency field.`)
//if (tmonners.currency) {console.log(`MESSAGE/CACHE || Found ${tmonners.currency} monners`);}
client.misc.cache.monners[message.author.id] = tmonners.currency; client.misc.cache.monners[message.author.id] = tmonners.currency;
//console.log(`MESSAGE/CACHE || Cached ${client.misc.cache.monners[message.author.id]} monners`);
} }
if (new Date().getTime() - client.misc.cache.lxp.xp[message.guild.id][message.author.id].lastXP > 60000) { if (new Date().getTime() - client.misc.cache.lxp.xp[message.guild.id][message.author.id].lastXP > 60000) {

@ -1,16 +1,28 @@
const LXP = require('../../models/localxp'); const LXP = require('../../models/localxp');
const Monners = require('../../models/monners'); const Monners = require('../../models/monners');
const chalk = require('chalk');
module.exports = async (client) => { module.exports = async (client) => {
let cd = new Date().getTime(); let cd = new Date().getTime();
//console.log(chalk.blueBright("\nSYNC/STRT || Beginning new Database sync loop"));
await Object.keys(client.misc.cache.lxp.xp).forEach(gxp => { await Object.keys(client.misc.cache.lxp.xp).forEach(gxp => {
LXP.findOne({gid: gxp}).then(xp => { LXP.findOne({gid: gxp}).then(xp => {
if (!xp) {return;} if (!xp) {return;}
Object.keys(client.misc.cache.lxp.xp[gxp]).forEach(user => { Object.keys(client.misc.cache.lxp.xp[gxp]).forEach(user => {
Monners.findOne({uid: user}).then(m => { Monners.findOne({uid: user}).then(m => {
if (!m) {m = new Monners({uid: user});} if (!Object.keys(client.misc.cache.monners).includes(user)) {/*console.log(chalk.yellow(`\nSYNC/VAL || User ${client.guilds.cache.get(client.misc.neptune).members.cache.get(user).displayName} in XP cache but not Monners cache. Aborting.`));*/ return;}
//console.log(`\nSYNC/PRE || Syncing monners for ${client.guilds.cache.get(client.misc.neptune).members.cache.get(user).displayName}. Doc ${m ? `exists and ${m.currency ? chalk.greenBright('has') : chalk.redBright("doesn't have")} currency field` : chalk.magenta("doesn't exist")}.`);
if (!m) {
//console.log(`SYNC/PRE || Didn't find doc. Making new.`);
m = new Monners({uid: user});
}
//console.log(`SYNC/PRE || User ${m.currency ? chalk.greenBright('has') : chalk.redBright("doesn't have")} currency field.`);
//let pre = m.currency ? true : false;
m.currency = client.misc.cache.monners[user]; m.currency = client.misc.cache.monners[user];
m.save(); m.save();
//let post = m.currency ? true : false;
//console.log(`SYNC/POST || User ${m.currency ? chalk.greenBright('has') : chalk.redBright("doesn't have")} currency field.`);
//if (pre && !post) {console.log(chalk.red(`SYNC/POST || Had currency field but it vanished.`));}
}); });
xp.xp[user] = [client.misc.cache.lxp.xp[gxp][user].xp, client.misc.cache.lxp.xp[gxp][user].level]; xp.xp[user] = [client.misc.cache.lxp.xp[gxp][user].xp, client.misc.cache.lxp.xp[gxp][user].level];
xp.markModified(`xp.${user}`); xp.markModified(`xp.${user}`);

@ -4,7 +4,10 @@ const LR = require('../../models/levelroles');
module.exports = async (client, member, channel) => { module.exports = async (client, member, channel) => {
client.misc.cache.lxp.xp[channel.guild.id][member].lastXP = new Date().getTime(); client.misc.cache.lxp.xp[channel.guild.id][member].lastXP = new Date().getTime();
client.misc.cache.lxp.xp[channel.guild.id][member].xp += 10; client.misc.cache.lxp.xp[channel.guild.id][member].xp += 10;
//console.log(`\nGAIN/PSV || Giving ${(Math.floor(client.misc.cache.lxp.xp[channel.guild.id][member].level / 35) + 1)} monners to ${client.guilds.cache.get(client.misc.neptune).members.cache.get(member).displayName} who is level ${client.misc.cache.lxp.xp[channel.guild.id][member].level}.`);
//console.log(`GAIN/PSV || Currently has ${client.misc.cache.monners[member]}`);
client.misc.cache.monners[member] += (Math.floor(client.misc.cache.lxp.xp[channel.guild.id][member].level / 35) + 1); client.misc.cache.monners[member] += (Math.floor(client.misc.cache.lxp.xp[channel.guild.id][member].level / 35) + 1);
//console.log(`GAIN/PSV || Now has ${client.misc.cache.monners[member]}`);
let x = client.misc.cache.lxp.xp[channel.guild.id][member].level; let x = client.misc.cache.lxp.xp[channel.guild.id][member].level;
let max = Math.ceil(100 + (((x / 2.85) ** 2.2) * 2.5)); let max = Math.ceil(100 + (((x / 2.85) ** 2.2) * 2.5));
@ -14,12 +17,15 @@ module.exports = async (client, member, channel) => {
client.misc.cache.lxp.xp[channel.guild.id][member].level += 1; client.misc.cache.lxp.xp[channel.guild.id][member].level += 1;
LXP.findOne({gid: channel.guild.id}).then(async xp => { LXP.findOne({gid: channel.guild.id}).then(async xp => {
if (!xp || !xp.msg) {return;} if (!xp || !xp.msg) {return;}
try { try {
let ch = xp.lvch.length ? channel.guild.channels.cache.get(xp.lvch) : channel; let ch = xp.lvch.length ? channel.guild.channels.cache.get(xp.lvch) : channel;
if (ch.partial) {await ch.fetch().catch(() => {});} if (ch.partial) {await ch.fetch().catch(() => {});}
//console.log(`\nGAIN/BONUS || Level ${x + 1} user ${client.guilds.cache.get(client.misc.neptune).members.cache.get(member).displayName} getting ${((Math.floor((x + 1) / 10) + 1) * 5)} bonus`);
let cur = ((Math.floor((x + 1) / 10) + 1) * 5); let cur = ((Math.floor((x + 1) / 10) + 1) * 5);
client.misc.cache.monners[member] += cur; client.misc.cache.monners[member] += cur;
//console.log(`GAIN/BONUS || Now has ${client.misc.cache.monners[member]}`);
if (ch && ch.permissionsFor(ch.guild.me.id).has('SEND_MESSAGES')) {ch.send(`<a:CF_moonheart:868653516913246208> <@${member}> has reached **Level ${x + 1}**, and gained **${cur}** bonus Mooners<a:CF_mooners:868652679717589012>!`).catch((e) => {/*console.error(e)*/});} if (ch && ch.permissionsFor(ch.guild.me.id).has('SEND_MESSAGES')) {ch.send(`<a:CF_moonheart:868653516913246208> <@${member}> has reached **Level ${x + 1}**, and gained **${cur}** bonus Mooners<a:CF_mooners:868652679717589012>!`).catch((e) => {/*console.error(e)*/});}
if (client.misc.cache.lxp.hasLevelRoles.includes(channel.guild.id)) { if (client.misc.cache.lxp.hasLevelRoles.includes(channel.guild.id)) {
LR.findOne({gid: channel.guild.id}).then(async lr => { LR.findOne({gid: channel.guild.id}).then(async lr => {

Loading…
Cancel
Save