├── .gitignore ├── Procfile ├── config.json ├── cache ├── welcome-cache.js └── polls-cache.js ├── gifs ├── polls.gif ├── modlogs.gif ├── thanks.gif ├── welcome.gif ├── role-claim.gif └── suggestions.gif ├── pictures ├── emojis │ ├── c++.png │ ├── java.png │ ├── python.png │ ├── website.png │ └── javascript.png └── screenshots │ ├── help-command.png │ └── sample-command.png ├── notes.txt ├── utils ├── temp-message.js ├── getUser.js ├── updateCoins.js ├── addUser.js ├── updateVault.js ├── updateUser.js └── updateXP.js ├── database ├── schemas │ ├── prefix-schema.js │ ├── polls-schema.js │ ├── modlogs-schema.js │ ├── suggestions-schema.js │ ├── thanks-channel-schema.js │ ├── welcome-schema.js │ ├── plunder-schema.js │ ├── roleclaim-schema.js │ ├── daily-rewards-schema.js │ ├── hourly-rewards-schema.js │ ├── weekly-rewards-schema.js │ ├── verification-channels-schema.js │ ├── thanks-schema.js │ └── profile-schema.js ├── mongo.js └── redis.js ├── commands ├── commands │ ├── management │ │ ├── rem-tc.js │ │ ├── create-vc.js │ │ ├── create-tc.js │ │ ├── set-prefix.js │ │ ├── rem-polls.js │ │ ├── rem-welcome.js │ │ ├── rem-roleclaim.js │ │ ├── set-polls.js │ │ ├── set-suggestions-channel.js │ │ ├── set-welcome.js │ │ ├── set-thanks-leaderboard.js │ │ ├── set-roleclaim.js │ │ └── set-verification.js │ ├── misc │ │ ├── clear.js │ │ ├── ping.js │ │ ├── add.js │ │ ├── echo.js │ │ ├── server-info.js │ │ ├── nickname.js │ │ ├── invites.js │ │ ├── botinfo.js │ │ ├── thanks.js │ │ └── help.js │ ├── moderation │ │ ├── ban.js │ │ ├── kick.js │ │ ├── slow.js │ │ ├── give-role.js │ │ ├── remove-role.js │ │ ├── rem-modlogs.js │ │ ├── set-modlogs.js │ │ ├── suggestion.js │ │ ├── roleAssign.js │ │ └── mute.js │ └── fun │ │ ├── shop.js │ │ ├── balance.js │ │ ├── inventory.js │ │ ├── greater-give.js │ │ ├── withdraw.js │ │ ├── gamble.js │ │ ├── deposit.js │ │ ├── profile.js │ │ ├── give.js │ │ ├── hourly.js │ │ ├── daily.js │ │ ├── weekly.js │ │ ├── sell.js │ │ ├── explore.js │ │ ├── buy.js │ │ ├── fish.js │ │ ├── plunder.js │ │ └── hunt.js ├── load-commands.js └── command-base.js ├── replies ├── items.js ├── shop.js ├── fish.js ├── gold.js ├── nothing.js └── hunt.js ├── cmds ├── misc │ └── add.js ├── moderation │ └── kick.js └── economy │ ├── balance.js │ ├── deposit.js │ └── daily.js ├── features ├── features │ ├── memeber-count │ │ └── member-count.js │ ├── welcome │ │ └── welcome.js │ ├── mod-logs │ │ └── mod-logs.js │ ├── advanced-polls │ │ └── advanced-polls.js │ ├── suggestions │ │ └── suggestions.js │ ├── verification-channel │ │ └── verification-channel.js │ ├── thanks │ │ └── thanks-lb.js │ └── role-claim │ │ └── role-claim.js └── load-features.js ├── LICENSE ├── package.json ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: node index.js -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "prefix": "hit" 3 | } 4 | -------------------------------------------------------------------------------- /cache/welcome-cache.js: -------------------------------------------------------------------------------- 1 | const cache = {}; 2 | module.exports = cache; 3 | -------------------------------------------------------------------------------- /cache/polls-cache.js: -------------------------------------------------------------------------------- 1 | let cache = []; 2 | module.exports.cache = cache; 3 | -------------------------------------------------------------------------------- /gifs/polls.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/gifs/polls.gif -------------------------------------------------------------------------------- /gifs/modlogs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/gifs/modlogs.gif -------------------------------------------------------------------------------- /gifs/thanks.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/gifs/thanks.gif -------------------------------------------------------------------------------- /gifs/welcome.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/gifs/welcome.gif -------------------------------------------------------------------------------- /gifs/role-claim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/gifs/role-claim.gif -------------------------------------------------------------------------------- /gifs/suggestions.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/gifs/suggestions.gif -------------------------------------------------------------------------------- /pictures/emojis/c++.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/emojis/c++.png -------------------------------------------------------------------------------- /pictures/emojis/java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/emojis/java.png -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | [] - verification command wokring? 2 | [] - rem verification ? 3 | [] - setTC, remTC, setVC, remVC wokrin? 4 | -------------------------------------------------------------------------------- /pictures/emojis/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/emojis/python.png -------------------------------------------------------------------------------- /pictures/emojis/website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/emojis/website.png -------------------------------------------------------------------------------- /pictures/emojis/javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/emojis/javascript.png -------------------------------------------------------------------------------- /pictures/screenshots/help-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/screenshots/help-command.png -------------------------------------------------------------------------------- /pictures/screenshots/sample-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrishinvv/discord-bot-GenuineGenie/HEAD/pictures/screenshots/sample-command.png -------------------------------------------------------------------------------- /utils/temp-message.js: -------------------------------------------------------------------------------- 1 | module.exports = (channel, text, duration = -1) => { 2 | channel.send(text).then((message) => { 3 | if (duration == -1) { 4 | return; 5 | } 6 | setTimeout(() => { 7 | message.delete(); 8 | }, 1000 * duration); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /database/schemas/prefix-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const prefixSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | prefix: reqString, 11 | }); 12 | 13 | module.exports = mongoose.model('prefix', prefixSchema); 14 | -------------------------------------------------------------------------------- /database/schemas/polls-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const pollsSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | }); 12 | 13 | module.exports = mongoose.model('polls-channels', pollsSchema); 14 | -------------------------------------------------------------------------------- /commands/commands/management/rem-tc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['remTC', 'rem-tc', 'del-tc'], 3 | description: 'deletes a text channel the command is run in', 4 | permissionError: '', 5 | callback: (message, arguments, text) => { 6 | message.channel.delete(); 7 | }, 8 | requiredRoles: 'Moderator', 9 | }; 10 | -------------------------------------------------------------------------------- /database/schemas/modlogs-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const modlogsSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | }); 12 | 13 | module.exports = mongoose.model('modlogs-schema', modlogsSchema); 14 | -------------------------------------------------------------------------------- /replies/items.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | description: 'How could you just find an old bow :bow_and_arrow: lying on the ground. talk about luck.', 4 | bow: true, 5 | }, 6 | { 7 | description: 'Alas you find a rabbit dragging a fishing pole :fishing_pole_and_fish:', 8 | fishing_rod: true, 9 | }, 10 | ]; 11 | -------------------------------------------------------------------------------- /database/schemas/suggestions-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const suggestionsSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | }); 12 | 13 | module.exports = mongoose.model('suggestions-schema', suggestionsSchema); 14 | -------------------------------------------------------------------------------- /database/schemas/thanks-channel-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const thanksSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | }); 12 | 13 | module.exports = mongoose.model('thanks-channel-schema', thanksSchema); 14 | -------------------------------------------------------------------------------- /database/schemas/welcome-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const welcomeSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | text: reqString, 12 | }); 13 | 14 | module.exports = mongoose.model('welcome-channels', welcomeSchema); 15 | -------------------------------------------------------------------------------- /database/schemas/plunder-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const plunderSchema = mongoose.Schema( 9 | { 10 | userId: reqString, 11 | }, 12 | { 13 | timestamps: true, 14 | } 15 | ); 16 | 17 | module.exports = mongoose.model('plunder-schema', plunderSchema); 18 | -------------------------------------------------------------------------------- /database/schemas/roleclaim-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const roleclaimSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | emojiRoles: reqString, 12 | }); 13 | 14 | module.exports = mongoose.model('roleclaim-channels', roleclaimSchema); 15 | -------------------------------------------------------------------------------- /database/schemas/daily-rewards-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const dailyRewardsSchema = mongoose.Schema( 9 | { 10 | userId: reqString, 11 | }, 12 | { 13 | timestamps: true, 14 | } 15 | ); 16 | 17 | module.exports = mongoose.model('daily-rewards', dailyRewardsSchema); 18 | -------------------------------------------------------------------------------- /database/schemas/hourly-rewards-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const hourlyRewardsSchema = mongoose.Schema( 9 | { 10 | userId: reqString, 11 | }, 12 | { 13 | timestamps: true, 14 | } 15 | ); 16 | 17 | module.exports = mongoose.model('hourly-rewards', hourlyRewardsSchema); 18 | -------------------------------------------------------------------------------- /database/schemas/weekly-rewards-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const weeklyRewardsSchema = mongoose.Schema( 9 | { 10 | userId: reqString, 11 | }, 12 | { 13 | timestamps: true, 14 | } 15 | ); 16 | 17 | module.exports = mongoose.model('weekly-rewards', weeklyRewardsSchema); 18 | -------------------------------------------------------------------------------- /replies/shop.js: -------------------------------------------------------------------------------- 1 | module.exports.items = [ 2 | ['⚔️', 'shamshir daggers', 'increases **ATK** stats by `2`', 3000], 3 | ['🛡️', 'goliath armor', 'increases **DEF** stats by `2`', 3000], 4 | ['🔵', 'trusted role', 'gets the `trusted` server role', 100000], 5 | ['🏹', 'hunting bow', 'allows you to use `hunt` command', 30000], 6 | ['🎣', 'fishing pole', 'allows you to use `fish` command', 30000], 7 | ]; 8 | -------------------------------------------------------------------------------- /utils/getUser.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const profileSchema = require('@schemas/profile-schema'); 3 | const addUser = require('./addUser'); 4 | 5 | module.exports = async (name, userId) => { 6 | //console.log(`getting user ${name}`); 7 | return ( 8 | (await profileSchema.findOne({ 9 | userId, 10 | })) || (await addUser(name, userId)) 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /database/schemas/verification-channels-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const verificationChannelsSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | channelId: reqString, 11 | roleId: reqString, 12 | }); 13 | 14 | module.exports = mongoose.model('verification-channels-schema', verificationChannelsSchema); 15 | -------------------------------------------------------------------------------- /database/mongo.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | //const { mongoURL } = require('@root/config.json'); 3 | const mongoURL = process.env.mongoURL; 4 | 5 | module.exports = async () => { 6 | await mongoose.connect(encodeURI(mongoURL), { 7 | keepAlive: true, 8 | useNewUrlParser: true, 9 | useUnifiedTopology: true, 10 | useFindAndModify: false, 11 | }); 12 | return mongoose; 13 | }; 14 | -------------------------------------------------------------------------------- /utils/updateCoins.js: -------------------------------------------------------------------------------- 1 | const profileSchema = require('@schemas/profile-schema'); 2 | 3 | module.exports = async (userId, delta) => { 4 | return await profileSchema 5 | .findOneAndUpdate( 6 | { 7 | userId, 8 | }, 9 | { 10 | $inc: { 11 | coins: delta, 12 | }, 13 | } 14 | ) 15 | .exec(); 16 | }; 17 | -------------------------------------------------------------------------------- /commands/commands/misc/clear.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['cc', 'clear'], 3 | description: 'bulk deletes set of recent messages from channel', 4 | minArgs: 0, 5 | maxArgs: 0, 6 | callback: (message, arguments, text) => { 7 | message.channel.messages.fetch().then((results) => { 8 | message.channel.bulkDelete(results); 9 | }); 10 | }, 11 | requiredRoles: ['Moderator'], 12 | }; 13 | -------------------------------------------------------------------------------- /database/schemas/thanks-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const thanksSchema = mongoose.Schema({ 9 | guildId: reqString, 10 | userId: reqString, 11 | received: { 12 | type: Number, 13 | default: 0, 14 | }, 15 | lastGave: Date, 16 | }); 17 | 18 | module.exports = mongoose.model('thanks', thanksSchema); 19 | -------------------------------------------------------------------------------- /commands/commands/misc/ping.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['ping'], 3 | description: 'replies with pong', 4 | minArgs: 0, 5 | maxArgs: 0, 6 | callback: (message, arguments, text, client) => { 7 | message.reply(`Calculating ping...`).then((res) => { 8 | const ping = res.createdTimestamp - message.createdTimestamp; 9 | res.edit(`Pong!\nBOT Latency: **${ping}**\nAPI Latency: **${client.ws.ping}**`); 10 | }); 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /commands/commands/misc/add.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['add', 'addition'], 3 | expectedArgs: ' ', 4 | description: 'adds two numbers', 5 | permissionError: '', 6 | minArgs: 2, 7 | maxArgs: 2, 8 | cooldown: 5, 9 | repeats: 3, 10 | callback: (message, arguments, text, client) => { 11 | message.reply(`The sum is ${Number(arguments[0]) + Number(arguments[1])}`); 12 | }, 13 | permissions: [], 14 | requiredRoles: [], 15 | }; 16 | -------------------------------------------------------------------------------- /utils/addUser.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const profileSchema = require('@schemas/profile-schema'); 3 | 4 | module.exports = async (name, userId) => { 5 | return await new profileSchema({ 6 | name, 7 | userId, 8 | coins: 500, 9 | vault_coins: 500, 10 | vault_size: 500, 11 | items: JSON.stringify({}), 12 | huntedCount: 0, 13 | fishedCount: 0, 14 | inventoryCount: 0, 15 | commands_issued: 0, 16 | }).save(); 17 | }; 18 | -------------------------------------------------------------------------------- /cmds/misc/add.js: -------------------------------------------------------------------------------- 1 | const Commando = require('discord.js-commando'); 2 | 3 | module.exports = class AddCommand extends ( 4 | Commando.Command 5 | ) { 6 | constructor(client) { 7 | super(client, { 8 | name: 'add', 9 | group: 'misc', 10 | memberName: 'add', 11 | description: 'Adds numbers together', 12 | argsType: 'multiple', 13 | }); 14 | } 15 | 16 | async run(message, args) { 17 | let sum = 0; 18 | for (const val of args) { 19 | sum += +val; 20 | } 21 | message.reply(`The sum is **${sum}**`); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /commands/commands/management/create-vc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['createVC', 'create-vc'], 3 | expectedArgs: '', 4 | description: 'creates a voice channel', 5 | minArgs: 1, 6 | maxArgs: null, 7 | callback: (message, arguments, text) => { 8 | message.guild.channels 9 | .create(text, { 10 | type: 'voice', 11 | }) 12 | .then((channel) => { 13 | console.log(`${message.author.id} created a new voice channel: '${text}'`); 14 | // channel.setUserLimit(10); 15 | }); 16 | }, 17 | requiredRoles: 'Moderator', 18 | }; 19 | -------------------------------------------------------------------------------- /features/features/memeber-count/member-count.js: -------------------------------------------------------------------------------- 1 | module.exports = (client) => { 2 | const channelId = '786900703804129290'; // member Count channel 3 | 4 | const updateMemmbers = (guild) => { 5 | const channel = guild.channels.cache.get(channelId); 6 | if (!channel) return; 7 | channel.setName(`Members: ${guild.memberCount.toLocaleString()}`); 8 | }; 9 | 10 | client.on('guildMemberAdd', (member) => updateMemmbers(member.guild)); 11 | client.on('guildMemberRemove', (member) => updateMemmbers(member.guild)); 12 | 13 | const guild = client.guilds.cache.get('776778928639311882'); 14 | updateMemmbers(guild); 15 | }; 16 | -------------------------------------------------------------------------------- /commands/commands/management/create-tc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['createTC', 'create-tc'], 3 | expectedArgs: '', 4 | description: 'creates a text channel', 5 | minArgs: 1, 6 | maxArgs: null, 7 | callback: (message, arguments, text) => { 8 | message.guild.channels 9 | .create(text, { 10 | type: 'text', 11 | }) 12 | .then((channel) => { 13 | console.log(`${message.author.id} created a new text channel: '${text}'`); 14 | 15 | // Add a channel to a particular category 16 | // channel.setParent('') 17 | }); 18 | }, 19 | requiredRoles: 'Moderator', 20 | }; 21 | -------------------------------------------------------------------------------- /commands/commands/misc/echo.js: -------------------------------------------------------------------------------- 1 | const dissapearingMessage = require('@utils/temp-message'); 2 | module.exports = { 3 | commands: ['echo'], 4 | expectedArgs: '(o) ', 5 | description: 'echoes amessage for a set duration. forever by default', 6 | callback: (message, arguments, text) => { 7 | const { channel } = message; 8 | if (isNaN(arguments[0])) { 9 | dissapearingMessage(channel, text); 10 | return; 11 | } 12 | const duration = +arguments[0]; 13 | arguments.shift(); 14 | text = arguments.join(' '); 15 | dissapearingMessage(channel, text, duration); 16 | }, 17 | permissions: [], 18 | requiredRoles: [], 19 | }; 20 | -------------------------------------------------------------------------------- /features/load-features.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | 4 | module.exports = (client) => { 5 | // Registering all the commands 6 | const readFeatures = (dir) => { 7 | const files = fs.readdirSync(path.join(__dirname, dir)); 8 | for (const file of files) { 9 | const stat = fs.lstatSync(path.join(__dirname, dir, file)); 10 | if (stat.isDirectory()) { 11 | readFeatures(path.join(dir, file)); 12 | } else if (file !== 'load-features.js') { 13 | const feature = require(path.join(__dirname, dir, file)); 14 | console.log(`Enabling Feature "${file}"`); 15 | feature(client); 16 | } 17 | } 18 | }; 19 | readFeatures('./'); 20 | }; 21 | -------------------------------------------------------------------------------- /commands/commands/moderation/ban.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['ban'], 3 | description: 'bans the user from the server', 4 | expectedArgs: "", 5 | minArgs: 1, 6 | maxArgs: 1, 7 | callback: (message, arguments, text) => { 8 | const { member, mentions } = message; 9 | const target = mentions.users.first(); 10 | const tag = `<@${target.id}>`; 11 | //console.log(target); 12 | if (target) { 13 | const targetMember = message.guild.members.cache.get(target.id); 14 | targetMember.ban(); 15 | message.channel.send(`${tag} has been banned`); 16 | } else { 17 | message.relpy(`${tag} does not exist`); 18 | } 19 | }, 20 | permissions: ['ADMINISTRATOR', 'BAN_MEMBERS'], 21 | }; 22 | -------------------------------------------------------------------------------- /commands/commands/fun/shop.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const getUser = require('@utils/getUser'); 3 | const { items } = require('@root/replies/shop'); 4 | 5 | module.exports = { 6 | commands: ['shop'], 7 | description: 'displays the in-game shop from which users can buy items', 8 | permissionError: '', 9 | callback: async (message, arguments, text, client) => { 10 | let desc = ``; 11 | for (const [emoji, name, info, cost] of items) { 12 | desc += `${emoji} \`${name}\` - **${cost.toLocaleString()}** 🪙\n${info}\n\n`; 13 | } 14 | const embed = new MessageEmbed().setAuthor(`Shop items`).setDescription(desc).setColor('RANDOM'); 15 | message.channel.send(embed); 16 | }, 17 | permissions: [], 18 | requiredRoles: [], 19 | }; 20 | -------------------------------------------------------------------------------- /commands/commands/moderation/kick.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['kick'], 3 | description: 'kicks the user from the server', 4 | expectedArgs: "", 5 | minArgs: 1, 6 | maxArgs: 1, 7 | callback: (message, arguments, text) => { 8 | const { member, mentions } = message; 9 | const target = mentions.users.first(); 10 | const tag = `<@${target.id}>`; 11 | //console.log(target); 12 | if (target) { 13 | const targetMember = message.guild.members.cache.get(target.id); 14 | targetMember.kick(); 15 | message.channel.send(`${tag} has been kicked`); 16 | } else { 17 | message.relpy(`${tag} does not exist`); 18 | } 19 | }, 20 | permissions: ['ADMINISTRATOR', 'KICK_MEMBERS'], //kick? 21 | }; 22 | -------------------------------------------------------------------------------- /utils/updateVault.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const profileSchema = require('@schemas/profile-schema'); 3 | 4 | module.exports = async (userId, delta) => { 5 | return await mongo().then(async (mongoose) => { 6 | try { 7 | let result = await profileSchema 8 | .findOneAndUpdate( 9 | { 10 | userId, 11 | }, 12 | { 13 | $inc: { 14 | vault_coins: +delta, 15 | coins: -delta, 16 | }, 17 | } 18 | ) 19 | .exec(); 20 | return result; 21 | } finally { 22 | //mongoose.connection.close(); 23 | } 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /commands/commands/misc/server-info.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | 3 | module.exports = { 4 | commands: ['server-info'], 5 | description: 'displays server info', 6 | minArgs: 0, 7 | maxArgs: 0, 8 | callback: (message, arguments, text) => { 9 | const { guild } = message; 10 | 11 | const { name, region, memberCount, owner } = guild; 12 | const icon = guild.iconURL(); 13 | 14 | const embed = new Discord.MessageEmbed().setTitle(`Sever info for "${name}"`).setThumbnail(icon).addFields( 15 | { 16 | name: 'Region', 17 | value: region, 18 | }, 19 | { 20 | name: 'Member Count', 21 | value: memberCount, 22 | }, 23 | { 24 | name: 'Owner', 25 | value: owner.user.tag, 26 | } 27 | ); 28 | 29 | message.channel.send(embed); 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /commands/commands/moderation/slow.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['slow'], 3 | expectedArgs: ' -or- "off"', 4 | description: 'you will be able to send a message once every x secs, when this mode is enabled', 5 | minArgs: 1, 6 | maxArgs: 1, 7 | callback: (message, arguments, text) => { 8 | const { channel } = message; 9 | let duration = arguments[0].toLowerCase(); 10 | if (duration === 'off') { 11 | message.reply(`you have turned off \`slow mode\` for this channel`); 12 | duration = 0; 13 | } 14 | 15 | if (isNaN(duration)) { 16 | message.reply('Please enter a valid duration or the word "off"'); 17 | return; 18 | } 19 | 20 | channel.setRateLimitPerUser(duration); 21 | if (duration !== 0) { 22 | message.reply(`the \`slow mode\` has been set for this channel at **${duration}**s`); 23 | } 24 | }, 25 | 26 | requiredRoles: 'Moderator', 27 | }; 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 V Vrishin Vigneshwar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /commands/commands/management/set-prefix.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const prefixSchema = require('@schemas/prefix-schema'); 3 | const { loadPrefixes, updatePrefix } = require('../../command-base'); 4 | module.exports = { 5 | commands: ['setPrefix', 'set-prefix', 'set-pre', 'prefix', 'pre'], 6 | minArgs: 1, 7 | maxArgs: 1, 8 | expectedArgs: '', 9 | callback: async (message, arguments, text, client) => { 10 | const guildId = message.guild.id; 11 | const prefix = arguments[0]; 12 | 13 | await prefixSchema 14 | .findOneAndUpdate( 15 | { 16 | guildId, 17 | }, 18 | { 19 | guildId, 20 | prefix, 21 | }, 22 | { 23 | upsert: true, 24 | } 25 | ) 26 | .exec(); 27 | 28 | loadPrefixes(client, guildId); 29 | updatePrefix(guildId, prefix); 30 | message.reply(`you have set the new command to prefix \`${prefix}\``); 31 | }, 32 | permissions: ['ADMINISTRATOR'], 33 | }; 34 | -------------------------------------------------------------------------------- /cmds/moderation/kick.js: -------------------------------------------------------------------------------- 1 | const Commando = require('discord.js-commando'); 2 | 3 | module.exports = class kickCommand extends ( 4 | Commando.Command 5 | ) { 6 | constructor(client) { 7 | super(client, { 8 | name: 'kick', 9 | group: 'moderation', 10 | memberName: 'kick', 11 | description: 'Kicks a member from the discord server', 12 | clientPermissions: ['KICK_MEMBERS'], // perimsiion for the bot 13 | userPermissions: ['KICK_MEMBERS'], // perimsiion for the user argsType: 'multiple', 14 | }); 15 | } 16 | 17 | async run(message) { 18 | const target = message.mentions.users.first(); 19 | if (!target) { 20 | message.reply('Please specify a correct username'); 21 | return; 22 | } 23 | 24 | const { guild } = message; 25 | const member = guild.members.cache.get(target.id); 26 | if (member.kickable) { 27 | member.kick(); 28 | message.reply('that user has been kicked'); 29 | } else { 30 | message.reply('hat user cannot be kicked'); 31 | } 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /database/schemas/profile-schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const reqString = { 4 | type: String, 5 | required: true, 6 | }; 7 | 8 | const reqNumber = { 9 | type: Number, 10 | required: true, 11 | }; 12 | 13 | const reqBoolean = { 14 | type: Boolean, 15 | required: true, 16 | }; 17 | 18 | const profileSchema = mongoose.Schema({ 19 | name: reqString, 20 | userId: reqString, 21 | coins: reqNumber, 22 | vault_coins: reqNumber, 23 | vault_size: reqNumber, 24 | items: reqString, 25 | huntedCount: reqNumber, 26 | fishedCount: reqNumber, 27 | inventoryCount: reqNumber, 28 | commands_issued: { 29 | type: Number, 30 | default: 0, 31 | }, 32 | xp: { 33 | type: Number, 34 | default: 0, 35 | }, 36 | level: { 37 | type: Number, 38 | default: 1, 39 | }, 40 | hp: { 41 | type: Number, 42 | default: 100, 43 | }, 44 | atk: { 45 | type: Number, 46 | default: 30, 47 | }, 48 | def: { 49 | type: Number, 50 | default: 30, 51 | }, 52 | }); 53 | 54 | module.exports = mongoose.model('profiles', profileSchema); 55 | -------------------------------------------------------------------------------- /commands/commands/fun/balance.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const getUser = require('@utils/getUser'); 3 | 4 | module.exports = { 5 | commands: ['balance', 'bal'], 6 | description: "shows yours'/user's richness value, your hot coins and your vault coins", 7 | expectedArgs: "(opt)", 8 | permissionError: '', 9 | maxArgs: 1, 10 | callback: async (message, arguments, text) => { 11 | const target = message.mentions.users.first() || message.author; 12 | const targetId = target.id; 13 | const name = target.username; 14 | const result = await getUser(name, targetId); 15 | let desc = `coins:\t **${result.coins.toLocaleString()}**`; 16 | desc += `\nvault:\t **${result.vault_coins.toLocaleString()}/${result.vault_size.toLocaleString()}**`; 17 | desc += `\nTotal: **${(result.coins + result.vault_coins).toLocaleString()}**`; 18 | const embed = new Discord.MessageEmbed().setTitle(`${name}'s richness`).setDescription(desc); 19 | //message.channel.send(`<@${targetId}> has **${coins}** coins`); 20 | message.channel.send(embed); 21 | }, 22 | permissions: [], 23 | requiredRoles: [], 24 | }; 25 | -------------------------------------------------------------------------------- /commands/commands/fun/inventory.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const getUser = require('@utils/getUser'); 3 | 4 | module.exports = { 5 | commands: ['inventory', 'inv'], 6 | description: "shows yours'/user's inventory", 7 | expectedArgs: "(opt)", 8 | permissionError: '', 9 | callback: async (message, arguments, text, client) => { 10 | const target = message.mentions.users.first() || message.author; 11 | const targetId = target.id; 12 | const name = target.username; 13 | const member = message.guild.members.cache.get(targetId); 14 | 15 | const result = await getUser(name, targetId); 16 | let desc = ``; 17 | const items = JSON.parse(result.items); 18 | 19 | for (const [key, value] of Object.entries(items)) { 20 | desc += `${value.emoji} **x ${value.count}** - \`${key}\`\n`; 21 | } 22 | 23 | const embed = new MessageEmbed() 24 | .setAuthor(`${name}'s Inventory`, target.displayAvatarURL()) 25 | .setDescription(desc) 26 | .setColor('RANDOM'); 27 | 28 | message.channel.send(embed); 29 | }, 30 | permissions: [], 31 | requiredRoles: [], 32 | }; 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-bot-GenuienGenie", 3 | "version": "1.0.0", 4 | "description": "A bot that can do everything?", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/vrishinvv/discord-bot-GenuienGenie.git" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/vrishinvv/discord-bot-GenuienGenie/issues" 18 | }, 19 | "homepage": "https://github.com/vrishinvv/discord-bot-GenuienGenie#readme", 20 | "dependencies": { 21 | "commando-provider-mongo": "^1.3.0", 22 | "discord.js": "^12.5.1", 23 | "discord.js-commando": "git+https://github.com/discordjs/Commando.git", 24 | "module-alias": "^2.2.2", 25 | "mongoose": "^5.11.7", 26 | "redis": "^3.0.2" 27 | }, 28 | "_moduleAliases": { 29 | "@root": ".", 30 | "@schemas": "./database/schemas", 31 | "@utils": "./utils", 32 | "@features": "./features/features", 33 | "@commands": "./commands/commands" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /replies/fish.js: -------------------------------------------------------------------------------- 1 | 50; 2 | module.exports.none = [ 3 | ['💧', '"A" for effort'], 4 | ['💧', 'not even a dime'], 5 | ['💧', 'maybe next time. maybe'], 6 | ['💧', 'you can fish out all the water with these skills'], 7 | ['💧', 'wow, you found a DROP'], 8 | ['💧', 'you could have waited for it to rain for this'], 9 | ['💧', 'lol how did you catch a water drop'], 10 | ['💧', 'i think this is the oceans tears seeing your fishing skills'], 11 | ]; 12 | 13 | 35; 14 | module.exports.common = [ 15 | ['🐟', 'fresh-water fish'], 16 | ['🐠', 'tropical fish'], 17 | ['🐚', 'am-i-a-fish shell'], 18 | ['🦐', 'shrimp'], 19 | ]; 20 | 21 | 13; 22 | module.exports.rare = [ 23 | ['🐬', 'ring dolphin'], 24 | ['🐡', 'gulab-jamun fish'], 25 | ['🦈', 'shark'], 26 | ['🐙', 'inktopus'], 27 | ['🍤', 'evolved shrimp'], 28 | ['🦀', 'the crab'], 29 | ['🦑', 'squid'], 30 | ]; 31 | 32 | 1.9; 33 | module.exports.superRare = [ 34 | ['🐋', 'blue whale'], 35 | ['🐬', 'adolphin butler'], 36 | ['🦈', 'arctic white shark'], 37 | ['🦞', 'leviathan'], 38 | ]; 39 | 40 | 0.1; 41 | module.exports.legendary = [ 42 | ['🐳', 'world Whale'], 43 | ['🦈', 'megaladon'], 44 | ['🐙', 'kraken'], 45 | ]; 46 | -------------------------------------------------------------------------------- /database/redis.js: -------------------------------------------------------------------------------- 1 | const redis = require('redis'); 2 | //const { redisURL } = require('@root/config.json'); 3 | const redisURL = process.env.redisURL; 4 | // 8rAhMhZyLOsbe1oWVrC45Zikzkt76BJY 5 | // redis-18143.c232.us-east-1-2.ec2.cloud.redislabs.com:18143 6 | 7 | module.exports = async () => { 8 | return await new Promise((resolve, reject) => { 9 | const client = redis.createClient({ 10 | url: redisURL, 11 | }); 12 | 13 | client.on('error', (err) => { 14 | console.error('Radis error: ', err); 15 | client.quit(); 16 | reject(err); 17 | }); 18 | 19 | client.on('ready', () => { 20 | resolve(client); 21 | }); 22 | }); 23 | }; 24 | 25 | module.exports.expire = (callback) => { 26 | const expired = () => { 27 | const sub = redis.createClient({ url: redisURL }); 28 | sub.subscribe('__keyevent@0__:expired', () => { 29 | sub.on('message', (channel, message) => { 30 | callback(message); 31 | }); 32 | }); 33 | }; 34 | 35 | const pub = redis.createClient({ url: redisURL }); 36 | pub.send_command('config', ['set', 'notify-keyspace-events', 'Ex'], expired()); 37 | }; 38 | 39 | // later convert code to mongoDB 40 | -------------------------------------------------------------------------------- /commands/commands/moderation/give-role.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['give-role'], 3 | expectedArgs: " ", 4 | description: 'gives role to user', 5 | minArgs: 2, 6 | maxArgs: 2, 7 | callback: (message, arguments, text) => { 8 | const targetUser = message.mentions.users.first(); 9 | if (!targetUser) { 10 | message.reply('Please specify a proper user @'); 11 | return; 12 | } 13 | 14 | // Remove the User's @, we dont need it any longert 15 | arguments.shift(); 16 | 17 | // Ensure that the role exists 18 | const roleName = arguments.join(' '); 19 | const { guild } = message; 20 | const role = guild.roles.cache.find((role) => { 21 | return role.name === roleName; 22 | }); 23 | if (!role) { 24 | message.reply(`There is no role "${roleName}"`); 25 | } 26 | 27 | // Member object has more information than the User object 28 | const member = guild.members.cache.get(targetUser.id); 29 | 30 | // Give the role 31 | member.roles.add(role); 32 | 33 | message.channel.send(`<@${targetUser.id}> now has the role ${roleName}`); 34 | }, 35 | 36 | requiredRoles: 'Moderator', 37 | }; 38 | -------------------------------------------------------------------------------- /replies/gold.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | description: 'You stumble upon a rock and fall into a hole. WHAT? You found XXX :coin: in a hole??', 4 | }, 5 | { 6 | description: 'You look at your reflection in a river. The river spouts out XXX :coin: out of pity...', 7 | }, 8 | { 9 | description: 'Ting! Something fell on your head! XXX :coin:!!! did the sky just open up to you?', 10 | }, 11 | { 12 | description: 'Something glitters in the sewer. You reach inside and pull out XXX :coin:', 13 | }, 14 | { 15 | description: 'After a 5 mins nap you find that someone mistook you for a beggar and left behind XXX :coin:', 16 | }, 17 | { 18 | description: 19 | 'The tavern that you enter sells high quality wine. You get too drunk and dance which earns you XXX :coin:', 20 | }, 21 | { 22 | description: 'A bloke approaches you and hands over XXX :coin:', 23 | }, 24 | { 25 | description: 26 | 'You overhear a secret conversation that you are not suppposed to hear. They bribe you a XXX :coin: to remain silent. You shamelessly agree', 27 | }, 28 | { 29 | description: 'You find XXX :coin: lying on the ground. You obviously pick it', 30 | }, 31 | { 32 | description: 'A rich aristocrat boy throws XXX :coin: at your face. Kids these days...', 33 | }, 34 | ]; 35 | -------------------------------------------------------------------------------- /commands/commands/fun/greater-give.js: -------------------------------------------------------------------------------- 1 | const getUser = require('@utils/getUser'); 2 | const updateCoins = require('@utils/updateCoins'); 3 | 4 | module.exports = { 5 | commands: ['greater-give'], 6 | description: 'admin/role specific - donates said amount to someone else', 7 | expectedArgs: " ", 8 | permissionError: '', 9 | minArgs: 2, 10 | maxArgs: 2, 11 | /* cooldown: 5, 12 | repeats: 3, */ 13 | callback: async (message, arguments, text) => { 14 | const target = message.mentions.users.first(); 15 | if (!target) { 16 | message.reply('No such user exists'); 17 | return; 18 | } 19 | 20 | arguments.shift(); 21 | 22 | const targetName = target.username; 23 | const targetId = target.id; 24 | const dummy = await getUser(targetName, targetId); 25 | 26 | const delta = +arguments[0]; 27 | if (isNaN(delta)) { 28 | message.reply('please provide a valid amount of coins to give'); 29 | return; 30 | } 31 | 32 | if (delta < 0) { 33 | message.reply('-.- what is negative cash?'); 34 | return; 35 | } 36 | await updateCoins(targetId, +delta); 37 | message.channel.send(`<@${targetId}>, the god's favour you! you were instantly given **${delta}** :coin:.`); 38 | }, 39 | permissions: ['ADMINISTRATOR'], 40 | requiredRoles: [], 41 | }; 42 | -------------------------------------------------------------------------------- /commands/commands/moderation/remove-role.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | commands: ['remove-role'], 3 | expectedArgs: " ", 4 | description: 'remove role of user', 5 | minArgs: 2, 6 | maxArgs: 2, 7 | callback: (message, arguments, text) => { 8 | const targetUser = message.mentions.users.first(); 9 | if (!targetUser) { 10 | message.reply('Please specify a proper user @'); 11 | return; 12 | } 13 | 14 | // Remove the User's @, we dont need it any longert 15 | arguments.shift(); 16 | 17 | // Ensure that the role exists 18 | const roleName = arguments.join(' '); 19 | const { guild } = message; 20 | const role = guild.roles.cache.find((role) => { 21 | return role.name === roleName; 22 | }); 23 | if (!role) { 24 | message.reply(`There is no role "${roleName}"`); 25 | } 26 | 27 | // Member object has more information than the User object 28 | const member = guild.members.cache.get(targetUser.id); 29 | 30 | if (member.roles.cache.get(role.id)) { 31 | member.roles.remove(role); 32 | message.channel.send(`${targetUser} no longer has the role ${roleName} `); 33 | } else { 34 | message.channel.send(`${targetUser} does not have the role ${roleName} `); 35 | } 36 | }, 37 | 38 | requiredRoles: 'Moderator', 39 | }; 40 | -------------------------------------------------------------------------------- /utils/updateUser.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const profileSchema = require('@schemas/profile-schema'); 3 | 4 | module.exports = async (userId, diff) => { 5 | return await mongo().then(async (mongoose) => { 6 | try { 7 | //console.log(`updating user with:::::::: `, diff); 8 | let result = await profileSchema 9 | .findOneAndUpdate( 10 | { 11 | userId, 12 | }, 13 | { 14 | $set: { 15 | name: diff.name, 16 | userId: diff.userId, 17 | coins: diff.coins, 18 | vault_coins: diff.vault_coins, 19 | vault_size: diff.vault_size, 20 | hunting_bow: diff.hunting_bow, 21 | fishing_rod: diff.fishing_rod, 22 | commands_issued: diff.commands_issued, 23 | xp: diff.xp, 24 | level: diff.level, 25 | }, 26 | }, 27 | { 28 | new: true, 29 | } 30 | ) 31 | .exec(); 32 | return result; 33 | } finally { 34 | //mongoose.connection.close(); 35 | } 36 | }); 37 | }; 38 | -------------------------------------------------------------------------------- /commands/commands/management/rem-polls.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const pollsSchema = require('@schemas/polls-schema'); 3 | const { delFromCache } = require('@features/advanced-polls/advanced-polls'); 4 | 5 | module.exports = { 6 | commands: ['remPolls', 'rem-polls'], 7 | description: 'removes the current channel from being a `polls channel`', 8 | callback: async (message, arguments, text, client) => { 9 | const { member, channel, guild, content } = message; 10 | 11 | const result = await mongo().then(async (mongoose) => { 12 | try { 13 | return await pollsSchema 14 | .findOneAndDelete( 15 | { 16 | guildId: guild.id, 17 | channelId: channel.id, 18 | }, 19 | { 20 | new: false, 21 | } 22 | ) 23 | .exec(); 24 | } finally { 25 | //mongoose.connection.close(); 26 | } 27 | }); 28 | 29 | if (!result) { 30 | message.reply('this channel was not a `polls channel`, but ok xD'); 31 | return; 32 | } 33 | 34 | delFromCache(guild.id); 35 | 36 | message.reply('this channel is no longer a `polls channel`! '); 37 | }, 38 | permissions: ['ADMINISTRATOR'], 39 | requiredRoles: [], 40 | }; 41 | -------------------------------------------------------------------------------- /commands/commands/management/rem-welcome.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const welcomeSchema = require('@schemas/welcome-schema'); 3 | const { delFromCache } = require('@features/welcome/welcome'); 4 | //let cache = require('@root/cache/welcome-cache.js'); 5 | 6 | module.exports = { 7 | commands: ['remWelcome', 'rem-welcome'], 8 | description: 'removes the current channel from being a `welcome channel`', 9 | callback: async (message, arguments, text, client) => { 10 | const { member, channel, guild, content } = message; 11 | 12 | const result = await mongo().then(async (mongoose) => { 13 | try { 14 | return await welcomeSchema 15 | .findOneAndDelete( 16 | { 17 | guildId: guild.id, 18 | channelId: channel.id, 19 | }, 20 | { 21 | new: false, 22 | } 23 | ) 24 | .exec(); 25 | } finally { 26 | //mongoose.connection.close(); 27 | } 28 | }); 29 | 30 | if (!result) { 31 | message.reply('this channel was not a `welcome channel`, but ok xD'); 32 | return; 33 | } 34 | 35 | delFromCache(guild.id); 36 | message.reply('this channel is no longer a `welcome channel`! '); 37 | }, 38 | permissions: ['ADMINISTRATOR'], 39 | }; 40 | -------------------------------------------------------------------------------- /commands/commands/fun/withdraw.js: -------------------------------------------------------------------------------- 1 | const updateVault = require('@utils/updateVault'); 2 | const getUser = require('@utils/getUser'); 3 | 4 | module.exports = { 5 | commands: ['with', 'wit', 'withdraw'], 6 | description: 'withdraws coins into from vault', 7 | expectedArgs: ' -or- ', 8 | minArgs: 1, 9 | maxArgs: 1, 10 | //cooldown: 3, 11 | //repeats: 7, 12 | callback: async (message, arguments, text) => { 13 | const name = message.author.username; 14 | const userId = message.author.id; 15 | 16 | const result = await getUser(name, userId); 17 | 18 | if (result.vault_coins === 0) { 19 | message.reply('Your vault is empty !'); 20 | return; 21 | } 22 | 23 | if (arguments[0] === 'max') { 24 | let delta = result.vault_coins; 25 | await updateVault(userId, -delta); 26 | message.reply(`Transferred **${delta}** :coin: to your coin pouch.`); 27 | } else if (!isNaN(Number(arguments[0]))) { 28 | let delta = Number(arguments[0]); 29 | if (delta < 0) { 30 | message.reply('-.- what is negative cash?'); 31 | } else if (delta > result.vault_coins) { 32 | message.reply('You dont have that much to withdraw!'); 33 | } else { 34 | await updateVault(userId, -delta); 35 | message.reply(`Transferred **${delta}** :coin: to your coin pouch.`); 36 | } 37 | } 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /commands/commands/moderation/rem-modlogs.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const modlogsSchema = require('@schemas/modlogs-schema'); 3 | const { delFromCache } = require('@features/mod-logs/mod-logs'); 4 | 5 | //let { cache } = require('@root/cache/modlogs-cache.js'); 6 | 7 | module.exports = { 8 | commands: ['remModLogs', 'rem-modlogs', 'rem-mod-logs'], 9 | description: 'removes the current channel from being a `modlogs channel`', 10 | callback: async (message, arguments, text, client) => { 11 | const { member, channel, guild, content } = message; 12 | 13 | const result = await mongo().then(async (mongoose) => { 14 | try { 15 | return await modlogsSchema 16 | .findOneAndDelete( 17 | { 18 | guildId: guild.id, 19 | channelId: channel.id, 20 | }, 21 | { 22 | new: false, 23 | } 24 | ) 25 | .exec(); 26 | } finally { 27 | //mongoose.connection.close(); 28 | } 29 | }); 30 | 31 | if (!result) { 32 | message.reply('this channel was not a `modlogs channel`, but ok xD'); 33 | return; 34 | } 35 | 36 | delFromCache(guild.id); 37 | 38 | message.reply('this channel is no longer a `modlogs channel`! '); 39 | }, 40 | permissions: ['ADMINISTRATOR'], 41 | }; 42 | -------------------------------------------------------------------------------- /commands/commands/moderation/set-modlogs.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const modlogsSchema = require('@schemas/modlogs-schema'); 3 | const { addToCache } = require('@features/mod-logs/mod-logs'); 4 | //let { cache } = require('@root/cache/modlogs-cache.js'); 5 | 6 | module.exports = { 7 | commands: ['setModLogs', 'set-modlogs', 'set-mod-logs'], 8 | description: 9 | 'sets a channel to be a `modlogs channel`. It is advised to use this command on a channel which is privy to the eyes of only the moderators', 10 | callback: async (message, arguments, text, client) => { 11 | const { member, channel, guild, content } = message; 12 | 13 | await mongo().then(async (mongoose) => { 14 | try { 15 | await modlogsSchema 16 | .findOneAndUpdate( 17 | { 18 | guildId: guild.id, 19 | }, 20 | { 21 | guildId: guild.id, 22 | channelId: channel.id, 23 | }, 24 | { 25 | upsert: true, 26 | } 27 | ) 28 | .exec(); 29 | } finally { 30 | //mongoose.connection.close(); 31 | } 32 | }); 33 | 34 | addToCache(guild.id, channel.id); 35 | message.reply('you have set this channel to a `modlogs channel`!'); 36 | }, 37 | permissions: ['ADMINISTRATOR'], 38 | }; 39 | -------------------------------------------------------------------------------- /commands/commands/management/rem-roleclaim.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const roleclaimSchema = require('@schemas/roleclaim-schema'); 3 | const { delFromCache } = require('@features/role-claim/role-claim'); 4 | 5 | //let { cache } = require('@root/cache/roleclaim-cache.js'); 6 | 7 | module.exports = { 8 | commands: ['remRoleClaim', 'rem-roleClaim', 'rem-role-claim'], 9 | description: 'removes the current channel from being a `role claim channel`', 10 | callback: async (message, arguments, text, client) => { 11 | const { member, channel, guild, content } = message; 12 | 13 | const result = await mongo().then(async (mongoose) => { 14 | try { 15 | return await roleclaimSchema 16 | .findOneAndDelete( 17 | { 18 | guildId: guild.id, 19 | channelId: channel.id, 20 | }, 21 | { 22 | new: false, 23 | } 24 | ) 25 | .exec(); 26 | } finally { 27 | //mongoose.connection.close(); 28 | } 29 | }); 30 | 31 | if (!result) { 32 | message.reply('this channel was not a `role claim channel`, but ok xD'); 33 | return; 34 | } 35 | 36 | delFromCache(guild.id); 37 | 38 | message.reply('this channel is no longer a `roleclaim channel`! '); 39 | }, 40 | permissions: ['ADMINISTRATOR'], 41 | }; 42 | -------------------------------------------------------------------------------- /commands/commands/misc/nickname.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const { version } = require('@root/package.json'); 3 | 4 | module.exports = { 5 | commands: ['nickname', 'nick'], 6 | expectedArgs: " ", 7 | description: 'change your nickanme', 8 | minArgs: 1, 9 | maxArgs: 2, 10 | callback: async (message, arguments, text, client) => { 11 | const author = message.author; 12 | const target = message.mentions.users.first() || message.author; 13 | //console.log(target); 14 | if (!target) { 15 | message.reply("Please provide a valid user's @"); 16 | return; 17 | } 18 | 19 | if (message.mentions.users.size !== 0) arguments.shift(); 20 | 21 | const member = message.guild.members.cache.get(target.id); 22 | const auth_member = message.guild.members.cache.get(author.id); 23 | if (author.username !== target.username) { 24 | if (!auth_member.hasPermission('ADMINISTRATOR')) { 25 | message.reply('you can only change your nickname'); 26 | return; 27 | } 28 | } 29 | const nickname = arguments.join(' '); 30 | 31 | let exit = 0; 32 | await member.setNickname(nickname).catch((err) => { 33 | message.reply('woah the bot cannot mess with this user it seems!'); 34 | exit = 1; 35 | }); 36 | if (exit) return; 37 | message.reply('you have changed the nickname!'); 38 | }, 39 | permissions: [], 40 | requiredRoles: [], 41 | }; 42 | -------------------------------------------------------------------------------- /cmds/economy/balance.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const Commando = require('discord.js-commando'); 3 | const getUser = require('@utils/getUser'); 4 | // Array of member IDs who have claimed their daily rewards in the last 24hrs 5 | // Resets every 10 mins 6 | let claimedCache = []; 7 | 8 | const clearCache = () => { 9 | claimedCache = []; 10 | setTimeout(clearCache, 20 * 60 * 1000); 11 | }; 12 | 13 | clearCache(); 14 | 15 | module.exports = class kickCommand extends ( 16 | Commando.Command 17 | ) { 18 | constructor(client) { 19 | super(client, { 20 | name: 'bal', 21 | aliases: ['balance'], 22 | group: 'economy', 23 | memberName: 'bal', 24 | description: 'Displays the balance of a user', 25 | format: "", 26 | throttling: { 27 | usages: 3, 28 | duration: 10, 29 | }, 30 | argsType: 'multiple', 31 | }); 32 | } 33 | 34 | async run(message) { 35 | const target = message.mentions.users.first() || message.author; 36 | const targetId = target.id; 37 | const name = target.username; 38 | const result = await getUser(name, targetId); 39 | let desc = `coins:\t **${result.coins}**`; 40 | desc += `\nvault:\t **${result.vault_coins}/${result.vault_size}**`; 41 | const embed = new Discord.MessageEmbed().setTitle(`${name}'s richness`).setDescription(desc); 42 | //message.channel.send(`<@${targetId}> has **${coins}** coins`); 43 | message.channel.send(embed); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /commands/commands/management/set-polls.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const pollsSchema = require('@schemas/polls-schema'); 3 | const { addToCache } = require('@features/advanced-polls/advanced-polls'); 4 | 5 | //let { cache } = require('@root/cache/polls-cache.js'); 6 | 7 | module.exports = { 8 | commands: ['setPolls', 'set-polls'], 9 | expectedArgs: '<#channel_name>(opt)', 10 | description: 'sets a channel to a `polls channel. A server can have only one polls channel.`', 11 | maxArgs: 1, 12 | callback: async (message, arguments, text, client) => { 13 | const { member, guild, content } = message; 14 | 15 | const channel = message.mentions.channels.first() || message.channel; 16 | 17 | await mongo().then(async (mongoose) => { 18 | try { 19 | await pollsSchema 20 | .findOneAndUpdate( 21 | { 22 | guildId: guild.id, 23 | }, 24 | { 25 | guildId: guild.id, 26 | channelId: channel.id, 27 | }, 28 | { 29 | upsert: true, 30 | } 31 | ) 32 | .exec(); 33 | } finally { 34 | //mongoose.connection.close(); 35 | } 36 | }); 37 | 38 | addToCache(guild.id, channel.id); 39 | 40 | message.reply('you have set this channel to a `polls channel`!'); 41 | }, 42 | permissions: ['ADMINISTRATOR'], 43 | }; 44 | -------------------------------------------------------------------------------- /features/features/welcome/welcome.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const welcomeSchema = require('@schemas/welcome-schema'); 3 | 4 | let welcomeCache = {}; 5 | // guildID : [channelId, text] 6 | const onJoin = async (member) => { 7 | const { guild } = member; 8 | 9 | // fetch from db 10 | if (!welcomeCache[guild.id]) return; 11 | 12 | let [channelId, text] = welcomeCache[guild.id]; 13 | if (!channelId) { 14 | return; 15 | } 16 | 17 | const channel = guild.channels.cache.get(channelId); 18 | text = text.replace(/<@>/g, `<@${member.user.id}>`); 19 | channel.send(text); 20 | }; 21 | 22 | const delFromCache = (guildId, channelId, text) => { 23 | delete welcomeCache[guildId]; 24 | }; 25 | 26 | const addToCache = (guildId, channelId, text) => { 27 | welcomeCache[guildId] = [channelId, text]; 28 | }; 29 | 30 | const loadCache = async () => { 31 | const results = await mongo().then((mongoose) => { 32 | try { 33 | return welcomeSchema.find({}); 34 | } finally { 35 | } 36 | }); 37 | 38 | for (const { guildId, channelId, text } of results) { 39 | welcomeCache[guildId] = [channelId, text]; 40 | } 41 | console.log('finsihed loading welcome CACHE'); 42 | }; 43 | 44 | module.exports = async (client) => { 45 | await loadCache(); 46 | // set up event listner for channel 47 | client.on('guildMemberAdd', (member) => { 48 | onJoin(member); 49 | }); 50 | }; 51 | 52 | module.exports.addToCache = addToCache; 53 | module.exports.delFromCache = delFromCache; 54 | module.exports.cache = () => { 55 | return welcomeCache; 56 | }; 57 | -------------------------------------------------------------------------------- /features/features/mod-logs/mod-logs.js: -------------------------------------------------------------------------------- 1 | const roles = ['Moderator']; 2 | 3 | const mongo = require('@root/database/mongo'); 4 | const modlogsSchema = require('@schemas/modlogs-schema'); 5 | 6 | let modlogsCache = {}; 7 | // guildID : channelId 8 | 9 | const delFromCache = (guildId, channelId) => { 10 | delete modlogsCache[guildId]; 11 | }; 12 | 13 | const addToCache = (guildId, channelId) => { 14 | modlogsCache[guildId] = channelId; 15 | }; 16 | 17 | const loadCache = async () => { 18 | const results = await mongo().then((mongoose) => { 19 | try { 20 | return modlogsSchema.find({}); 21 | } finally { 22 | } 23 | }); 24 | 25 | for (const { guildId, channelId } of results) { 26 | modlogsCache[guildId] = channelId; 27 | } 28 | console.log('finsihed loading modlogs CACHE'); 29 | }; 30 | 31 | module.exports = async (client) => { 32 | loadCache(); 33 | client.on('message', (message) => { 34 | const { content, member, guild } = message; 35 | if (member.user.bot) return; 36 | 37 | const hasRole = member.roles.cache.find((role) => { 38 | return roles.includes(role.name); 39 | }); 40 | 41 | const channelId = modlogsCache[guild.id]; 42 | if (hasRole && channelId) { 43 | const channel = guild.channels.cache.get(channelId); 44 | channel.send(`\`<${member.user.tag}>\` in <#${message.channel.id}> sent,\`\`\`\n${content}\`\`\`\n`); 45 | } 46 | }); 47 | }; 48 | 49 | module.exports.addToCache = addToCache; 50 | module.exports.delFromCache = delFromCache; 51 | module.exports.cache = () => { 52 | return modlogsCache; 53 | }; 54 | -------------------------------------------------------------------------------- /commands/commands/fun/gamble.js: -------------------------------------------------------------------------------- 1 | const updateCoins = require('@utils/updateCoins'); 2 | const getUser = require('@utils/getUser'); 3 | 4 | module.exports = { 5 | commands: ['gamble'], 6 | description: '50% chance of winning or losing the cash you bet', 7 | expectedArgs: '', 8 | minArgs: 1, 9 | maxArgs: 1, 10 | cooldown: 10, 11 | repeats: 1, 12 | callback: async (message, arguments, text) => { 13 | const name = message.author.username; 14 | const userId = message.author.id; 15 | 16 | const result = await getUser(name, userId); 17 | 18 | if (result.coins < Number(arguments[0])) { 19 | message.reply('Hello, please gamble with what you have xD'); 20 | } else if (+arguments[0] < 400) { 21 | message.reply('Need atleast **400** :coin: to gamble'); 22 | } else { 23 | const delta = +arguments[0]; 24 | if (isNaN(delta)) { 25 | message.reply('please provide a valid amount of coins to give'); 26 | return; 27 | } 28 | const flip = Math.random() * 2; 29 | if (flip >= 1) { 30 | const new_coins = Math.floor(Number(arguments[0]) * (Math.random() * 1.5 + 1)); 31 | await updateCoins(userId, new_coins); 32 | message.reply(`you WON! you got **${new_coins}** :coin:`); 33 | } else { 34 | const new_coins = Math.floor(Number(arguments[0]) * (Math.random() * 1)) + 75; 35 | await updateCoins(userId, -new_coins); 36 | message.reply(`you LOST! there goes a **${new_coins}** :coin:`); 37 | } 38 | } 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /commands/commands/misc/invites.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | 3 | module.exports = { 4 | commands: ['invites'], 5 | description: 'checks invites leaderboard', 6 | callback: async (message, arguments, text) => { 7 | const { guild } = message; 8 | const inviteCounter = {}; 9 | await guild.fetchInvites().then((invites) => { 10 | invites.forEach((invite) => { 11 | const { uses, inviter } = invite; 12 | const { username, discriminator } = inviter; 13 | 14 | const name = `${username}#${discriminator}`; 15 | 16 | inviteCounter[name] = (inviteCounter[name] || 0) + uses; 17 | }); 18 | }); 19 | 20 | const sortedInvites = Object.keys(inviteCounter).sort((a, b) => { 21 | return inviteCounter[b] - inviteCounter[a]; 22 | }); 23 | 24 | sortedInvites.length = Math.min(sortedInvites.length, 10); 25 | 26 | //console.log(sortedInvites); 27 | let i = 1; 28 | let replyText = ``; 29 | for (const invite of sortedInvites) { 30 | const count = inviteCounter[invite]; 31 | //console.log(invite, count); 32 | replyText += `\n(${i}). **${invite}** has invited **${count}** member(s)!`; 33 | i += 1; 34 | } 35 | 36 | const icon = guild.iconURL(); 37 | const embed = new Discord.MessageEmbed() 38 | .setTitle(`Top ${sortedInvites.length} Invitees: `) 39 | .setThumbnail(icon) 40 | .setDescription(replyText); 41 | 42 | message.channel.send(embed); 43 | 44 | //message.channel.send(replyText); 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /commands/load-commands.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | 4 | let temp = {}; 5 | const fields = []; 6 | 7 | module.exports = (client) => { 8 | const baseFile = 'command-base.js'; 9 | 10 | const commandBase = require(`./${baseFile}`); 11 | 12 | const commands = []; 13 | 14 | // Registering all the commands 15 | const readCommands = (dir) => { 16 | const files = fs.readdirSync(path.join(__dirname, dir)); 17 | for (const file of files) { 18 | const stat = fs.lstatSync(path.join(__dirname, dir, file)); 19 | if (stat.isDirectory()) { 20 | if (file !== 'commands') { 21 | // reseting our temp 22 | temp = {}; 23 | temp.name = file; 24 | temp.value = ''; 25 | } 26 | readCommands(path.join(dir, file)); 27 | } else if (file !== baseFile && file !== 'load-commands.js') { 28 | const options = require(path.join(__dirname, dir, file)); 29 | commands.push(options); 30 | const comm = options.commands; 31 | if (typeof comm === 'string') comm = [comm]; 32 | temp.value += `\`${comm[0]}\`, `; 33 | if (client) { 34 | commandBase(client, options); 35 | } 36 | } 37 | } 38 | fields.push(temp); 39 | // reseting our temp 40 | temp = {}; 41 | }; 42 | readCommands('./'); 43 | fields.length = 4; // cos i have 4 directories in my commmadns folder 44 | //console.log(fields); 45 | return commands; 46 | }; 47 | 48 | module.exports.fields = fields; 49 | -------------------------------------------------------------------------------- /replies/nothing.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | description: `You walk aimlessly...`, 4 | }, 5 | { 6 | description: `You think to yourself the reason for existence`, 7 | }, 8 | { 9 | description: `A thought comes into your head. "Is this game real?". Oops.`, 10 | }, 11 | { 12 | description: `A sign post reads, "Oh you are still exploring?"`, 13 | }, 14 | { 15 | description: `When relaxing in the beach, a fish says "hi" to you! you wave back xD`, 16 | }, 17 | { 18 | description: `A donkey is chassing you!!!! RUN!`, 19 | }, 20 | { 21 | description: `Have you ever seen a musquito as big as a tree? no? Neither have I.`, 22 | }, 23 | { 24 | description: `The sun set gives you an eere feeling. Wierd.`, 25 | }, 26 | { 27 | description: `You walk into a tavern. Everyone is looking at you. What did you do?...`, 28 | }, 29 | { 30 | description: `A giant man walks up to you and vomits. you miss being enveloped in a rain of vomit by a whisker`, 31 | }, 32 | { 33 | description: `You hear wierd noises coming from the woods. You wonders if you should go check it out`, 34 | }, 35 | { 36 | description: `A wandering monk looks at you asks, "sup bro?". You dont know what to say.`, 37 | }, 38 | { 39 | description: `Its raining cats and dogs. Quick get some shelter or you'll catch a cold`, 40 | }, 41 | { 42 | description: `Lately theres been a rumour about an assasin in town, better be safe than sorry`, 43 | }, 44 | { 45 | description: `Lately theres been a rumour about an assasin in town, better be safe than sorry`, 46 | }, 47 | ]; 48 | -------------------------------------------------------------------------------- /commands/commands/fun/deposit.js: -------------------------------------------------------------------------------- 1 | const updateVault = require('@utils/updateVault'); 2 | const getUser = require('@utils/getUser'); 3 | 4 | module.exports = { 5 | commands: ['dep', 'deposit'], 6 | expectedArgs: ' -or- ', 7 | description: 'deposits coins into your vault', 8 | minArgs: 1, 9 | maxArgs: 1, 10 | //cooldown: 3, 11 | //repeats: 7, 12 | callback: async (message, arguments, text) => { 13 | const name = message.author.username; 14 | const userId = message.author.id; 15 | 16 | const result = await getUser(name, userId); 17 | 18 | const available_space_in_vault = result.vault_size - result.vault_coins; 19 | if (available_space_in_vault === 0) { 20 | message.reply('Your vault is already full!'); 21 | return; 22 | } 23 | if (arguments[0] === 'max') { 24 | const toDeposit = Math.min(available_space_in_vault, result.coins); 25 | await updateVault(userId, toDeposit); 26 | message.reply(`Transferred **${toDeposit}** :coin: to vault.`); 27 | } else { 28 | let delta = +arguments[0]; 29 | if (delta < 0) { 30 | message.reply('-.- what is negative cash?'); 31 | } else if (delta > result.coins) { 32 | message.reply('You dont have that much to deposit!'); 33 | } else if (delta > available_space_in_vault) { 34 | message.reply('Your vault will break if you deposit more than it can hold!'); 35 | } else { 36 | await updateVault(userId, delta); 37 | message.reply(`Transferred **${delta}** :coin: to vault.`); 38 | } 39 | } 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /commands/commands/management/set-suggestions-channel.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const suggestionsSchema = require('@schemas/suggestions-schema'); 3 | const { fetchSuggestionsChannels } = require('@features/suggestions/suggestions'); 4 | 5 | module.exports = { 6 | commands: ['set-suggestions', 'setSuggestions'], 7 | expectedArgs: '<#channel_name>(opt)', 8 | description: 'set the current channel into a suggestions channel. A server can have only one sugestions channel.', 9 | maxArgs: 1, 10 | permissionError: '', 11 | callback: async (message, arguments, text, client) => { 12 | //console.log('im in'); 13 | const channel = message.mentions.channels.first() || message.channel; 14 | const { 15 | guild: { id: guildId }, 16 | } = message; 17 | 18 | const { id: channelId } = channel; 19 | 20 | await mongo().then(async (mongoose) => { 21 | try { 22 | await suggestionsSchema 23 | .findOneAndUpdate( 24 | { 25 | guildId, 26 | }, 27 | { 28 | guildId, 29 | channelId, 30 | }, 31 | { 32 | new: true, 33 | upsert: true, 34 | } 35 | ) 36 | .exec(); 37 | 38 | message.reply(`you have set ${channel} as the \`suggestions channel\`!`); 39 | 40 | fetchSuggestionsChannels(guildId); 41 | } finally { 42 | } 43 | }); 44 | }, 45 | permissions: ['ADMINISTRATOR'], 46 | }; 47 | -------------------------------------------------------------------------------- /commands/commands/management/set-welcome.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const welcomeSchema = require('@schemas/welcome-schema'); 3 | const { addToCache } = require('@features/welcome/welcome.js'); 4 | 5 | module.exports = { 6 | commands: ['setWelcome', 'set-welcome'], 7 | expectedArgs: ' ', 8 | description: 'sets a channel to a `welcome channel. A server can have only one welcome channel.`', 9 | maxArgs: null, 10 | callback: async (message, arguments, text, client) => { 11 | const { member, guild, content } = message; 12 | const channel = message.mentions.channels.first() || message.channel; 13 | 14 | if (message.mentions.channels.first()) { 15 | arguments.length = arguments.length - 1; 16 | } 17 | //console.log(arguments); 18 | text = arguments.join(' '); 19 | //console.log(arguments); 20 | //console.log(channel.id); 21 | if (text === '') { 22 | //console.log(message.mentions.channel.first().id, message.channel.id); 23 | message.reply('Cannot set welcome message to empty string'); 24 | return; 25 | } 26 | 27 | await welcomeSchema 28 | .findOneAndUpdate( 29 | { 30 | guildId: guild.id, 31 | }, 32 | { 33 | guildId: guild.id, 34 | channelId: channel.id, 35 | text, 36 | }, 37 | { 38 | upsert: true, 39 | } 40 | ) 41 | .exec(); 42 | 43 | addToCache(guild.id, channel.id, text); 44 | message.reply(`you have set <#${channel.id}> to a \`welcome channel\`!`); 45 | }, 46 | permissions: ['ADMINISTRATOR'], 47 | }; 48 | -------------------------------------------------------------------------------- /commands/commands/management/set-thanks-leaderboard.js: -------------------------------------------------------------------------------- 1 | const thanksChannelSchema = require('@schemas/thanks-channel-schema'); 2 | const { updateLeaderBoard } = require('@features/thanks/thanks-lb'); 3 | module.exports = { 4 | commands: ['setThanks', 'set-thanks', 'set-thenks', 'set-thanksLeaderBoard'], 5 | expectedArgs: '<#channel_name>(opt)', 6 | description: 7 | 'set a channel as a `thanks leaderbaord` channel. Make sure the server is empty befoer running this command. A server can have only one thanks leaderboard channel.', 8 | maxArgs: 1, 9 | callback: async (message, arguments, text, client) => { 10 | const { guild } = message; 11 | 12 | const guildId = guild.id; 13 | const channel = message.mentions.channels.first() || message.channel; 14 | const channelId = channel.id; 15 | 16 | const collected = await channel.messages.fetch(); 17 | if (collected.size > 1) { 18 | await message.reply('channel must be empty when you run this command').then((message) => { 19 | message.delete({ timeout: 5 * 1000 }); 20 | }); 21 | message.delete(); 22 | return; 23 | } 24 | await thanksChannelSchema.findOneAndUpdate( 25 | { 26 | guildId, 27 | }, 28 | { 29 | guildId, 30 | channelId, 31 | }, 32 | { 33 | upsert: true, 34 | } 35 | ); 36 | 37 | await message.delete(); 38 | /* await message.reply('you have set this channel to a `thanks leaderboard channel`!').then((message) => { 39 | message.delete({ 40 | timeout: 1000 * 5, 41 | }); 42 | }); */ 43 | updateLeaderBoard(client, guild, channel); 44 | }, 45 | permissions: ['ADMINISTRATOR'], 46 | requiredRoles: [], 47 | }; 48 | -------------------------------------------------------------------------------- /commands/commands/misc/botinfo.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const { version } = require('@root/package.json'); 3 | 4 | module.exports = { 5 | commands: ['botInfo', 'bot-info'], 6 | description: "display's bot information", 7 | callback: async (message, arguments, text, client) => { 8 | const getPrefix = require('@root/commands/command-base').getPrefix; 9 | const prefix = getPrefix(client, message.guild.id); 10 | let totalMembers = 0; 11 | for (const guild of client.guilds.cache) { 12 | totalMembers += (await guild[1].members.fetch()).size; 13 | } 14 | const embed = new MessageEmbed() 15 | .setAuthor(`${client.user.username} Bot`, client.user.displayAvatarURL()) 16 | .addFields( 17 | { 18 | name: "Bot's tag", 19 | value: `\`${client.user.tag}\``, 20 | inline: true, 21 | }, 22 | { 23 | name: 'Version', 24 | value: `*${version}*`, 25 | inline: true, 26 | }, 27 | { 28 | name: "Server's comamnd prefix", 29 | value: prefix, 30 | }, 31 | { 32 | name: 'Time since last restart', 33 | value: `${process.uptime().toFixed(2)}s`, 34 | }, 35 | { 36 | name: 'Server count', 37 | value: client.guilds.cache.size, 38 | }, 39 | { 40 | name: 'Total Members', 41 | value: totalMembers, 42 | } 43 | ) 44 | .setColor('RANDOM'); 45 | message.channel.send(embed); 46 | }, 47 | permissions: [], 48 | requiredRoles: [], 49 | }; 50 | -------------------------------------------------------------------------------- /commands/commands/management/set-roleclaim.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const roleclaimSchema = require('@schemas/roleclaim-schema'); 3 | const { addToCache, displaySampleMessage } = require('@features/role-claim/role-claim'); 4 | 5 | //let { cache } = require('@root/cache/roleclaim-cache.js'); 6 | 7 | module.exports = { 8 | commands: ['setRoleClaim', 'set-roleclaim', 'set-role-claim'], 9 | expectedArgs: '<#channel_name>(opt)', 10 | description: 11 | 'sets a channel to a `role claim channel`. Remember to assign roles to emojis before/after using this command for your purposes. A server can have only one role claim channel.', 12 | maxArgs: 1, 13 | callback: async (message, arguments, text, client) => { 14 | const { member, guild, content } = message; 15 | const channel = message.mentions.channels.first() || message.channel; 16 | let query = {}; 17 | const result = await roleclaimSchema.findOne({ guildId }); 18 | if (result) { 19 | query = JSON.parse(result.emojiRoles); 20 | } 21 | 22 | await roleclaimSchema 23 | .findOneAndUpdate( 24 | { 25 | guildId: guild.id, 26 | }, 27 | { 28 | guildId: guild.id, 29 | channelId: channel.id, 30 | emojiRoles: JSON.stringify(query), 31 | }, 32 | { 33 | upsert: true, 34 | } 35 | ) 36 | .exec(); 37 | 38 | addToCache(guild.id, channel.id); 39 | 40 | message.reply('you have set this channel to a `role claim channel`!').then(async (message) => { 41 | message.delete({ timeout: 1000 * 5 }); 42 | }); 43 | message.delete(); 44 | 45 | displaySampleMessage(channel, client); 46 | }, 47 | permissions: ['ADMINISTRATOR'], 48 | }; 49 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('module-alias/register'); 2 | 3 | const Discord = require('discord.js'); 4 | const client = new Discord.Client(); 5 | 6 | const config = require('@root/config.json'); 7 | const loadCommands = require('@root/commands/load-commands'); 8 | const loadFeatures = require('@root/features/load-features'); 9 | const { loadPrefixes } = require('./commands/command-base'); 10 | const mongo = require('@root/database/mongo'); 11 | 12 | /* 13 | const { MongoClient } = require('mongodb'); 14 | const MongoDBProvider = require('commando-provider-mongo'); 15 | const Commando = require('discord.js-commando'); 16 | const client = new Commando.CommandoClient({ 17 | owner: '384318671037661184', 18 | commandPrefix: '!', 19 | }); */ 20 | client.setMaxListeners(100); 21 | 22 | /* client.setProvider( 23 | MongoClient.connect(config.mongoURL) 24 | .then((client) => { 25 | return new MongoDBProvider(client, 'lesgo'); 26 | }) 27 | .catch((err) => { 28 | console.log(err); 29 | }) 30 | ); 31 | */ 32 | try { 33 | console.log('Starting up Discord Client...'); 34 | client.on('ready', async () => { 35 | console.log('Estabished connection with Discord...'); 36 | console.log(`Logged in as ${client.user.tag}!\n`); 37 | 38 | await mongo(); 39 | /* client.registry 40 | .registerGroups([ 41 | ['moderation', 'moderation commands'], 42 | ['misc', 'misc commands'], 43 | ['economy', 'money and economy system commands'], 44 | ]) 45 | .registerDefaults() 46 | .registerCommandsIn(path.join(__dirname, 'cmds')); */ 47 | 48 | // load Prefixes 49 | loadPrefixes(client); 50 | 51 | // Load commands 52 | loadCommands(client); 53 | 54 | // Load features 55 | loadFeatures(client); 56 | }); 57 | //client.login(config.token); 58 | client.login(process.env.token); 59 | } catch { 60 | console.log(err, '\n'); 61 | } 62 | -------------------------------------------------------------------------------- /utils/updateXP.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const profileSchema = require('@schemas/profile-schema'); 3 | const updateUser = require('./updateUser'); 4 | const addUser = require('./addUser'); 5 | const { commands } = require('@commands/misc/invites'); 6 | 7 | module.exports = async (userId, delta, message) => { 8 | if (userId === '786230987964809257') { 9 | return; 10 | } 11 | 12 | return await mongo().then(async (mongoose) => { 13 | try { 14 | let result = await profileSchema 15 | .findOneAndUpdate( 16 | { 17 | userId, 18 | }, 19 | { 20 | $inc: { 21 | xp: delta, 22 | commands_issued: 1, 23 | }, 24 | }, 25 | { 26 | new: true, 27 | } 28 | ) 29 | .exec(); 30 | 31 | if (!result) { 32 | await addUser(message.author.username, userId); 33 | return; 34 | } 35 | 36 | let { xp, level, vault_size, commands_issued } = result; 37 | const needed = level * 200 + commands_issued * 10; 38 | if (xp >= needed) { 39 | level = level + 1; 40 | xp -= needed; 41 | vault_size += level * (43 + commands_issued); 42 | result.xp = xp; 43 | result.level = level; 44 | result.vault_size = vault_size; 45 | //console.log(result); 46 | await updateUser(userId, result); 47 | message 48 | .reply(`:confetti_ball: You are now Level **${level}**! Use bot-commands to gain more XP!`) 49 | .then((message) => { 50 | setTimeout(() => { 51 | message.delete(); 52 | }, 120 * 1000); 53 | }); 54 | } 55 | 56 | return result; 57 | } finally { 58 | //mongoose.connection.close(); 59 | } 60 | }); 61 | }; 62 | -------------------------------------------------------------------------------- /cmds/economy/deposit.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const Commando = require('discord.js-commando'); 3 | const getUser = require('@utils/getUser'); 4 | const updateVault = require('@utils/updateVault'); 5 | // Array of member IDs who have claimed their daily rewards in the last 24hrs 6 | // Resets every 10 mins 7 | let claimedCache = []; 8 | 9 | const clearCache = () => { 10 | claimedCache = []; 11 | setTimeout(clearCache, 20 * 60 * 1000); 12 | }; 13 | 14 | clearCache(); 15 | 16 | module.exports = class kickCommand extends ( 17 | Commando.Command 18 | ) { 19 | constructor(client) { 20 | super(client, { 21 | name: 'dep', 22 | aliases: ['deposit'], 23 | group: 'economy', 24 | memberName: 'dep', 25 | description: 'deposits coins into your vault', 26 | format: ' -or- ', 27 | throttling: { 28 | usages: 3, 29 | duration: 10, 30 | }, 31 | argsType: 'multiple', 32 | }); 33 | } 34 | 35 | async run(message, args) { 36 | const name = message.author.username; 37 | const userId = message.author.id; 38 | 39 | const result = await getUser(name, userId); 40 | 41 | const available = result.vault_size - result.vault_coins; 42 | if (available === 0) { 43 | message.reply('Your vault is already full!'); 44 | return; 45 | } 46 | if (args[0] === 'max') { 47 | await updateVault(userId, available); 48 | message.reply(`Transferred **${available}** :coin: to vault.`); 49 | } else { 50 | let delta = +args[0]; 51 | if (delta < 0) { 52 | message.reply('-.- what is negative cash?'); 53 | } else if (delta > result.coins) { 54 | message.reply('You dont have that much to deposit!'); 55 | } else if (delta > available) { 56 | message.reply('Your vault will break if you deposit more than it can hold!'); 57 | } else { 58 | await updateVault(userId, delta); 59 | message.reply(`Transferred **${delta}** :coin: to vault.`); 60 | } 61 | } 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /commands/commands/fun/profile.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const getUser = require('@utils/getUser'); 3 | 4 | module.exports = { 5 | commands: ['profile'], 6 | description: "shows yours'/user's GGprofile", 7 | expectedArgs: "(opt)", 8 | permissionError: '', 9 | callback: async (message, arguments, text, client) => { 10 | const target = message.mentions.users.first() || message.author; 11 | const targetId = target.id; 12 | const name = target.username; 13 | const member = message.guild.members.cache.get(targetId); 14 | 15 | const result = await getUser(name, targetId); 16 | let desc = `Coins:\t **${result.coins.toLocaleString()}**`; 17 | desc += `\nVault:\t **${result.vault_coins.toLocaleString()}/${result.vault_size.toLocaleString()}**`; 18 | desc += `\nTotal: **${(result.coins + result.vault_coins).toLocaleString()}**`; 19 | desc += `\nInventory:\t *${result.inventoryCount.toLocaleString()}*`; 20 | 21 | //TODO:: complete this bit 22 | let itemReply = ''; 23 | 24 | const embed = new MessageEmbed() 25 | .setAuthor(`${name} profile`, target.displayAvatarURL()) 26 | .addFields( 27 | { 28 | name: 'General', 29 | value: `Level: **${result.level.toLocaleString()}**\nXP: \`${result.xp.toLocaleString()}/${ 30 | result.level.toLocaleString() * 200 + result.commands_issued.toLocaleString() * 10 31 | }\`\nATK: **${result.atk.toLocaleString()}** DEF:**${result.def.toLocaleString()}**\nCommands Issued: *${result.commands_issued.toLocaleString()}*`, 32 | }, 33 | { 34 | name: 'Richness', 35 | value: desc, 36 | }, 37 | { 38 | name: 'Misc', 39 | value: `Nickname: \`${member.nickname || 'None'}\`\nJoined Server: *${new Date( 40 | member.joinedTimestamp 41 | ).toLocaleDateString()}*\nRole Count: **${member.roles.cache.size}**`, 42 | } 43 | ) 44 | .setColor('RANDOM'); 45 | 46 | message.channel.send(embed); 47 | }, 48 | permissions: [], 49 | requiredRoles: [], 50 | }; 51 | -------------------------------------------------------------------------------- /commands/commands/moderation/suggestion.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const suggestionsSchema = require('@schemas/suggestions-schema'); 3 | const { statusMessages, suggestionsCache } = require('@features/suggestions/suggestions'); 4 | const { MessageEmbed } = require('discord.js'); 5 | 6 | module.exports = { 7 | commands: ['suggestion'], 8 | expectedArgs: ' (opt)', 9 | description: 'updates the status of a suggestion', 10 | minArgs: 2, 11 | maxArgs: null, 12 | permissionError: '', 13 | callback: async (message, arguments, text, client) => { 14 | const { guild } = message; 15 | 16 | const messageId = arguments.shift(); 17 | const status = arguments.shift().toUpperCase(); 18 | const reason = arguments.join(' '); 19 | 20 | message.delete(); 21 | 22 | const newStatus = statusMessages[status]; 23 | 24 | if (!newStatus) { 25 | message.reply(`Unknown status "${status}", please use ${Object.keys(statusMessages)}`); 26 | return; 27 | } 28 | 29 | const channelId = suggestionsCache()[guild.id]; 30 | if (!channelId) { 31 | message.reply(`An error ocuured! please report this!`); 32 | return; 33 | } 34 | 35 | const channel = guild.channels.cache.get(channelId); 36 | if (!channel) { 37 | message.reply(`that suggestion channel no longer exists`); 38 | return; 39 | } 40 | 41 | const targetMessage = await channel.messages.fetch(messageId, false, true); 42 | if (!targetMessage) { 43 | message.reply(`that message no longer exists`); 44 | return; 45 | } 46 | 47 | const oldEmbed = targetMessage.embeds[0]; 48 | const newEmbed = new MessageEmbed() 49 | .setAuthor(oldEmbed.author.name, oldEmbed.author.iconURL) 50 | .setDescription(oldEmbed.description) 51 | .setColor(newStatus.color) 52 | .setFooter('Want to suggest something? Simply type it in this channel') 53 | .addFields({ 54 | name: 'Status', 55 | value: `${newStatus.text}${reason ? ` Reason: ${reason}` : ''}`, 56 | }); 57 | 58 | targetMessage.edit(newEmbed); 59 | }, 60 | requiredRoles: ['Moderator'], 61 | }; 62 | -------------------------------------------------------------------------------- /cmds/economy/daily.js: -------------------------------------------------------------------------------- 1 | const Commando = require('discord.js-commando'); 2 | const mongo = require('@root/database/mongo'); 3 | const dailyRewardsSchema = require('@schemas/daily-rewards-schema'); 4 | 5 | // Array of member IDs who have claimed their daily rewards in the last 24hrs 6 | // Resets every 20 mins 7 | let claimedCache = []; 8 | 9 | const clearCache = () => { 10 | claimedCache = []; 11 | setTimeout(clearCache, 20 * 60 * 1000); 12 | }; 13 | 14 | clearCache(); 15 | 16 | module.exports = class kickCommand extends ( 17 | Commando.Command 18 | ) { 19 | constructor(client) { 20 | super(client, { 21 | name: 'daily', 22 | group: 'economy', 23 | memberName: 'daily', 24 | description: 'Get a daily reward', 25 | }); 26 | } 27 | 28 | async run(message) { 29 | const { guild, member } = message; 30 | const { id } = member; 31 | 32 | if (claimedCache.includes(id)) { 33 | //console.log('returning from cache'); 34 | message.reply(`you have already claimed your daily rewards!`); 35 | return; 36 | } 37 | 38 | //console.log('Fetching from Mongo'); 39 | 40 | const obj = { 41 | userId: id, 42 | }; 43 | 44 | await mongo().then(async (mongoose) => { 45 | try { 46 | const results = await dailyRewardsSchema.findOne(obj); 47 | if (results) { 48 | const then = new Date(results.updatedAt).getTime(); 49 | const now = new Date().getTime(); 50 | 51 | const diffTime = Math.abs(now - then); 52 | const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24)); 53 | 54 | if (diffDays <= 1) { 55 | claimedCache.push(id); 56 | message.reply(`you have already claimed your daily rewards!`); 57 | return; 58 | } 59 | } 60 | 61 | await dailyRewardsSchema.findOneAndUpdate(obj, obj, { new: true, upsert: true }); 62 | 63 | claimedCache.push(id); 64 | 65 | //TODO: Give the rewards 66 | message.reply(`you have claimed your daily!`); 67 | } finally { 68 | } 69 | }); 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /features/features/advanced-polls/advanced-polls.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const pollsSchema = require('@schemas/polls-schema'); 3 | 4 | let pollsCache = {}; 5 | // guildId: channelId 6 | 7 | const onMessage = async (message) => { 8 | if (message.member.user.bot) return; 9 | const { guild, content, channel } = message; 10 | message.reactions.removeAll(); 11 | 12 | const curchannelId = pollsCache[guild.id]; 13 | 14 | if (curchannelId !== channel.id) { 15 | return; 16 | } 17 | 18 | const eachLine = content.split('\n'); 19 | 20 | for (const line of eachLine) { 21 | if (line.includes('=')) { 22 | const split = line.split('='); 23 | let emoji = split[0].trim(); 24 | emoji = emoji.replace(/^[a-zA-Z0-9\(\)\,\.\[\]\: ]*/, ''); 25 | 26 | try { 27 | message.react(emoji).catch((err) => { 28 | console.log(err); 29 | }); 30 | } catch { 31 | message.reply("you probably forgot that ' = ' has to have an emoji on the left!").then((message) => { 32 | setTimeout(() => { 33 | message.delete(); 34 | }, 10 * 1000); 35 | return; 36 | }); 37 | } 38 | } 39 | } 40 | }; 41 | 42 | const addToCache = (guildId, channelId) => { 43 | pollsCache[guildId] = channelId; 44 | }; 45 | 46 | const delFromCache = (guildId, channelId) => { 47 | delete pollsCache[guildId]; 48 | }; 49 | 50 | const loadCache = async () => { 51 | const results = await mongo().then((mongoose) => { 52 | try { 53 | return pollsSchema.find({}); 54 | } finally { 55 | } 56 | }); 57 | 58 | for (const { guildId, channelId } of results) { 59 | pollsCache[guildId] = channelId; 60 | } 61 | console.log('finsihed loading polls CACHE'); 62 | }; 63 | 64 | module.exports = (client) => { 65 | loadCache(); 66 | client.on('message', (message) => { 67 | onMessage(message); 68 | }); 69 | client.on('messageUpdate', (oldMessage, newMessage) => { 70 | onMessage(newMessage); 71 | }); 72 | }; 73 | 74 | module.exports.addToCache = addToCache; 75 | module.exports.delFromCache = delFromCache; 76 | 77 | module.exports.cache = () => { 78 | return pollsCache; 79 | }; 80 | -------------------------------------------------------------------------------- /features/features/suggestions/suggestions.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | 3 | const suggestionsSchema = require('@schemas/suggestions-schema'); 4 | const { MessageEmbed } = require('discord.js'); 5 | 6 | let suggestionsCache = {}; 7 | 8 | const statusMessages = { 9 | WAITING: { 10 | text: '📊 Waiting for community feedback, please vote!', 11 | color: 0xffea00, 12 | }, 13 | ACCEPTED: { 14 | text: '✅ Accepted Idea! Expect this soon.', 15 | color: 0x34eb5b, 16 | }, 17 | DENIED: { 18 | text: '❌ Thank you for the idea. But we are not able to pursue with this currently!', 19 | color: 0xc20808, 20 | }, 21 | }; 22 | 23 | const fetchSuggestionsChannels = async (guildId) => { 24 | let query = {}; 25 | 26 | if (guildId) { 27 | query.guildId = guildId; 28 | } 29 | 30 | const results = await mongo().then((mongoose) => { 31 | try { 32 | return suggestionsSchema.find(query); 33 | } finally { 34 | } 35 | }); 36 | 37 | for (const { guildId, channelId } of results) { 38 | suggestionsCache[guildId] = channelId; 39 | } 40 | console.log('finsihed loading suggestions CACHE'); 41 | }; 42 | 43 | module.exports = (client) => { 44 | fetchSuggestionsChannels(); 45 | 46 | client.on('message', (message) => { 47 | const { guild, channel, content, member } = message; 48 | const cachedChannelId = suggestionsCache[guild.id]; 49 | if (cachedChannelId && cachedChannelId === channel.id && !member.user.bot) { 50 | const status = statusMessages.WAITING; 51 | 52 | const embed = new MessageEmbed() 53 | .setColor(status.color) 54 | .setDescription(content) 55 | .setAuthor(member.displayName, member.user.displayAvatarURL()) 56 | .addFields({ name: 'Status', value: status.text }) 57 | .setFooter('Want to suggest something? Simply type it in this channel'); 58 | 59 | channel.send(embed).then((message) => { 60 | message.react('👍').then(() => { 61 | message.react('👎'); 62 | }); 63 | }); 64 | 65 | message.delete(); 66 | } 67 | }); 68 | }; 69 | 70 | module.exports.fetchSuggestionsChannels = fetchSuggestionsChannels; 71 | module.exports.statusMessages = statusMessages; 72 | module.exports.suggestionsCache = () => { 73 | return suggestionsCache; 74 | }; 75 | -------------------------------------------------------------------------------- /commands/commands/fun/give.js: -------------------------------------------------------------------------------- 1 | const getUser = require('@utils/getUser'); 2 | const updateCoins = require('@utils/updateCoins'); 3 | 4 | module.exports = { 5 | commands: ['give'], 6 | description: 'donates said amount to someone else', 7 | expectedArgs: " ", 8 | permissionError: '', 9 | minArgs: 2, 10 | maxArgs: 2, 11 | /* cooldown: 5, 12 | repeats: 3, */ 13 | callback: async (message, arguments, text) => { 14 | const target = message.mentions.users.first(); 15 | if (!target) { 16 | message.reply('No such user exists'); 17 | return; 18 | } 19 | 20 | if (target.id === message.author.id) { 21 | message.reply('Funny you thought that will work xD'); 22 | return; 23 | } 24 | 25 | arguments.shift(); 26 | const delta = +arguments[0]; 27 | if (isNaN(delta)) { 28 | message.reply('please provide a valid amount of coins to give'); 29 | return; 30 | } 31 | 32 | const userName = message.author.username; 33 | const userId = message.author.id; 34 | 35 | const targetName = target.username; 36 | const targetId = target.id; 37 | 38 | const result = await getUser(userName, userId); 39 | const dummy = await getUser(targetName, targetId); 40 | 41 | const available = result.coins; 42 | if (available === 0) { 43 | message.reply('you dont have coins in the first place. Think about donating later'); 44 | return; 45 | } 46 | 47 | console.log(target); 48 | if (arguments[0] === 'max') { 49 | await updateCoins(userId, -available); 50 | await updateCoins(targetId, +available); 51 | message.channel.send(`<@${userId}>, What a samaritan! you gave **${available}** :coin: to <@${targetId}>.`); 52 | } else { 53 | let delta = +arguments[0]; 54 | if (delta < 0) { 55 | message.reply('-.- what is negative cash?'); 56 | } else if (delta > result.coins) { 57 | message.reply('You dont have that much to throw around!'); 58 | } else { 59 | await updateCoins(userId, -delta); 60 | await updateCoins(targetId, +delta); 61 | message.channel.send(`<@${userId}>, What a samaritan! you gave **${delta}** :coin: to <@${targetId}>.`); 62 | } 63 | } 64 | }, 65 | permissions: [], 66 | requiredRoles: [], 67 | }; 68 | -------------------------------------------------------------------------------- /commands/commands/fun/hourly.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const hourlyRewardsSchema = require('@schemas/hourly-rewards-schema'); 3 | const updateCoins = require('@utils/updateCoins'); 4 | const updateXP = require('@utils/updateXP'); 5 | 6 | // Array of member IDs who have claimed their hourly rewards in the last 24hrs 7 | // Resets every 20 mins 8 | let claimedCache = []; 9 | const clearCache = () => { 10 | claimedCache = []; 11 | setTimeout(clearCache, 20 * 1000 * 60); 12 | }; 13 | clearCache(); 14 | 15 | module.exports = { 16 | commands: ['hourly'], 17 | description: 'get some fantastic hourly rewards', 18 | expectedArgs: "", 19 | /* cooldown: 5, 20 | repeats: 3, */ 21 | callback: async (message, arguments, text) => { 22 | const { guild, member } = message; 23 | const { id } = member; 24 | 25 | if (claimedCache.includes(id)) { 26 | //console.log('returning from cache'); 27 | message.reply(`you have already claimed your **hourly** rewards!`); 28 | return; 29 | } 30 | 31 | //console.log('Fetching from Mongo'); 32 | 33 | const obj = { 34 | userId: id, 35 | }; 36 | 37 | await mongo().then(async (mongoose) => { 38 | try { 39 | const results = await hourlyRewardsSchema.findOne(obj); 40 | if (results) { 41 | const then = new Date(results.updatedAt).getTime(); 42 | const now = new Date().getTime(); 43 | 44 | const diffTime = Math.abs(now - then); 45 | const diffHours = diffTime / (1000 * 60 * 60); 46 | 47 | if (diffHours <= 1) { 48 | claimedCache.push(id); 49 | message.reply(`you have already claimed your **hourly** rewards!`); 50 | return; 51 | } 52 | } 53 | 54 | await hourlyRewardsSchema.findOneAndUpdate(obj, obj, { new: true, upsert: true }); 55 | 56 | claimedCache.push(id); 57 | 58 | const coins = Math.floor(Math.random() * 75) + 100; 59 | await updateCoins(message.author.id, coins); 60 | 61 | const XP = Math.floor(Math.random() * 5) + 10; 62 | await updateXP(message.author.id, XP, message); 63 | 64 | message.reply(`nice! **${coins}** coins and \`${XP}\`XP were granted to you`); 65 | } finally { 66 | } 67 | }); 68 | }, 69 | permissions: [], 70 | requiredRoles: [], 71 | }; 72 | -------------------------------------------------------------------------------- /commands/commands/fun/daily.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const dailyRewardsSchema = require('@schemas/daily-rewards-schema'); 3 | const updateCoins = require('@utils/updateCoins'); 4 | const updateXP = require('@utils/updateXP'); 5 | 6 | // Array of member IDs who have claimed their daily rewards in the last 24hrs 7 | // Resets every 20 mins 8 | let claimedCache = []; 9 | const clearCache = () => { 10 | claimedCache = []; 11 | setTimeout(clearCache, 20 * 60 * 1000); 12 | }; 13 | clearCache(); 14 | 15 | module.exports = { 16 | commands: ['daily'], 17 | description: 'get some fantastic daily rewards, coins, xp and what not?', 18 | expectedArgs: "", 19 | /* cooldown: 5, 20 | repeats: 3, */ 21 | callback: async (message, arguments, text) => { 22 | const { guild, member } = message; 23 | const { id } = member; 24 | 25 | if (claimedCache.includes(id)) { 26 | //console.log('returning from cache'); 27 | message.reply(`you have already claimed your **daily** rewards!`); 28 | return; 29 | } 30 | 31 | //console.log('Fetching from Mongo'); 32 | 33 | const obj = { 34 | userId: id, 35 | }; 36 | 37 | await mongo().then(async (mongoose) => { 38 | try { 39 | const results = await dailyRewardsSchema.findOne(obj); 40 | if (results) { 41 | const then = new Date(results.updatedAt).getTime(); 42 | const now = new Date().getTime(); 43 | 44 | const diffTime = Math.abs(now - then); 45 | const diffDays = diffTime / (1000 * 60 * 60 * 24); 46 | 47 | if (diffDays <= 1) { 48 | claimedCache.push(id); 49 | message.reply(`you have already claimed your **daily** rewards!`); 50 | return; 51 | } 52 | } 53 | 54 | await dailyRewardsSchema.findOneAndUpdate(obj, obj, { new: true, upsert: true }); 55 | 56 | claimedCache.push(id); 57 | 58 | const coins = Math.floor(Math.random() * 500) + 500; 59 | await updateCoins(message.author.id, coins); 60 | 61 | const XP = Math.floor(Math.random() * 20) + 25; 62 | await updateXP(message.author.id, XP, message); 63 | 64 | message.reply(`> WOAH! you just got **${coins}** coins and \`${XP}\`XP`); 65 | } finally { 66 | } 67 | }); 68 | }, 69 | permissions: [], 70 | requiredRoles: [], 71 | }; 72 | -------------------------------------------------------------------------------- /commands/commands/misc/thanks.js: -------------------------------------------------------------------------------- 1 | const thanksSchema = require('@schemas/thanks-schema'); 2 | const thanksChannelSchema = require('@schemas/thanks-channel-schema'); 3 | 4 | module.exports = { 5 | commands: ['thanks', 'thx', 'thenks', 'thank'], 6 | expectedArgs: "", 7 | description: 'thank a user for helping you', 8 | permissionError: '', 9 | minArgs: 1, 10 | maxArgs: 1, 11 | callback: async (message, arguments, text, client) => { 12 | const target = message.mentions.users.first(); 13 | if (!target) { 14 | message.reply('Please specify someone to thank'); 15 | return; 16 | } 17 | 18 | const { guild } = message; 19 | const targetId = target.id; 20 | const guildId = guild.id; 21 | const authorId = message.author.id; 22 | const now = new Date(); 23 | 24 | if (targetId === authorId) { 25 | message.reply('You cannot thank yourself :)'); 26 | return; 27 | } 28 | 29 | const authorData = await thanksSchema.findOne({ 30 | userId: authorId, 31 | guildId, 32 | }); 33 | 34 | if (authorData && authorData.lastGave) { 35 | const then = new Date(authorData.lastGave); 36 | const diff = now.getTime() - then.getTime(); 37 | 38 | const diffHours = Math.round(diff / (1000 * 60 * 60)); 39 | const hours = 1; 40 | if (diffHours < hours) { 41 | message.reply(`you have already thanked someone within the last \`${hours}hr(s)\``); 42 | return; 43 | } 44 | } 45 | 46 | // Update the "lastGave" property 47 | await thanksSchema.findOneAndUpdate( 48 | { 49 | userId: authorId, 50 | guildId, 51 | }, 52 | { userId: authorId, guildId, lastGave: now }, 53 | { upsert: true } 54 | ); 55 | 56 | // Increase how many thanks the target user had 57 | const result = await thanksSchema.findOneAndUpdate( 58 | { 59 | userId: targetId, 60 | guildId, 61 | }, 62 | { userId: targetId, guildId, $inc: { received: 1 } }, 63 | { upsert: true, new: true } 64 | ); 65 | const amount = result.received; 66 | const { channelId: channelId2 } = await thanksChannelSchema.findOne({ guildId }); 67 | message.channel.send( 68 | `<@${authorId}>, You have thanked <@${targetId}>, they now have \`${amount}\` thanks. Check out <#${channelId2}>` 69 | ); 70 | }, 71 | permissions: [], 72 | requiredRoles: [], 73 | }; 74 | -------------------------------------------------------------------------------- /commands/commands/fun/weekly.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const weeklyRewardsSchema = require('@schemas/weekly-rewards-schema'); 3 | const updateCoins = require('@utils/updateCoins'); 4 | const updateXP = require('@utils/updateXP'); 5 | 6 | // Array of member IDs who have claimed their weekly rewards in the last 24hrs 7 | // Resets every 20 mins 8 | let claimedCache = []; 9 | const clearCache = () => { 10 | claimedCache = []; 11 | setTimeout(clearCache, 20 * 1000 * 60); 12 | }; 13 | clearCache(); 14 | 15 | module.exports = { 16 | commands: ['weekly'], 17 | description: 'get some fantastic weekly rewards', 18 | expectedArgs: "", 19 | /* cooldown: 5, 20 | repeats: 3, */ 21 | callback: async (message, arguments, text) => { 22 | const { guild, member } = message; 23 | const { id } = member; 24 | 25 | if (claimedCache.includes(id)) { 26 | //console.log('returning from cache'); 27 | message.reply(`you have already claimed your **weekly** rewards!`); 28 | return; 29 | } 30 | 31 | //console.log('Fetching from Mongo'); 32 | 33 | const obj = { 34 | userId: id, 35 | }; 36 | 37 | await mongo().then(async (mongoose) => { 38 | try { 39 | const results = await weeklyRewardsSchema.findOne(obj); 40 | if (results) { 41 | const then = new Date(results.updatedAt).getTime(); 42 | const now = new Date().getTime(); 43 | 44 | const diffTime = Math.abs(now - then); 45 | const diffWeekly = diffTime / (1000 * 60 * 60 * 24 * 7); 46 | 47 | if (diffWeekly <= 1) { 48 | claimedCache.push(id); 49 | message.reply(`you have already claimed your **weekly** rewards!`); 50 | return; 51 | } 52 | } 53 | 54 | await weeklyRewardsSchema.findOneAndUpdate(obj, obj, { new: true, upsert: true }); 55 | 56 | claimedCache.push(id); 57 | 58 | const coins = Math.floor(Math.random() * 1000) + 2000; 59 | await updateCoins(message.author.id, coins); 60 | 61 | const XP = Math.floor(Math.random() * 70) + 70; 62 | await updateXP(message.author.id, XP, message); 63 | 64 | message.reply( 65 | `AMAZE! a blessing? a miracle? **${coins}** coins and \`${XP}\`XP got instantly trasnferred to you` 66 | ); 67 | } finally { 68 | } 69 | }); 70 | }, 71 | permissions: [], 72 | requiredRoles: [], 73 | }; 74 | -------------------------------------------------------------------------------- /commands/commands/moderation/roleAssign.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const roleclaimSchema = require('@schemas/roleclaim-schema'); 3 | const { roleclaimCache } = require('@features/role-claim/role-claim'); 4 | const { delFromCache } = require('@features/role-claim/role-claim'); 5 | const { addToCache } = require('@features/role-claim/role-claim'); 6 | 7 | //let { cache } = require('@root/cache/role claim-cache.js'); 8 | 9 | module.exports = { 10 | commands: ['roleAssign', 'role-assign'], 11 | expectedArgs: ' /"del"', 12 | description: 'assigns a Role name to an emoji - needed for creating a role claim channel', 13 | callback: async (message, arguments, text, client) => { 14 | const customEmoji = (emojiName) => { 15 | emojiName = emojiName.split(':')[1]; 16 | return guild.emojis.cache.find((emoji) => emoji.name === emojiName); 17 | }; 18 | 19 | const { member, channel, guild, content } = message; 20 | const guildId = guild.id; 21 | const channelId = roleclaimCache()[guildId][0]; 22 | 23 | // checks if role claim channel has been set for this guild 24 | if (!channelId) { 25 | message.reply('you need to set up a `role claim channel` before using this command'); 26 | return; 27 | } 28 | 29 | let emoji = arguments[0]; 30 | const orig = emoji; 31 | 32 | if (customEmoji(emoji)) emoji = customEmoji(emoji).name; 33 | 34 | arguments.shift(); 35 | const roleName = arguments.join(' '); 36 | 37 | if (roleName === 'del') { 38 | const result = await roleclaimSchema.findOne({ guildId }); 39 | 40 | let assigns = JSON.parse(result.emojiRoles); 41 | 42 | delete assigns[emoji]; 43 | await roleclaimSchema.findOneAndUpdate( 44 | { guildId }, 45 | { guildId, channelId, emojiRoles: JSON.stringify(assigns) }, 46 | {} 47 | ); 48 | addToCache(guildId, channelId, assigns); 49 | 50 | message.reply('yup we have deleted that emoji'); 51 | //console.log(roleclaimCache()); 52 | return; 53 | } 54 | // check if such a role exists 55 | const role = guild.roles.cache.find((role) => { 56 | return role.name === roleName; 57 | }); 58 | if (!role) { 59 | message.reply(`There is no role "${roleName}"`); 60 | return; 61 | } 62 | 63 | //console.log(); 64 | 65 | const result = await roleclaimSchema.findOne({ guildId }); 66 | 67 | let assigns = JSON.parse(result.emojiRoles); 68 | 69 | assigns[emoji] = roleName; 70 | // console.log(assigns, guildId, channelId); 71 | await roleclaimSchema.findOneAndUpdate( 72 | { guildId }, 73 | { guildId, channelId, emojiRoles: JSON.stringify(assigns) }, 74 | {} 75 | ); 76 | addToCache(guildId, channelId, assigns); 77 | 78 | message.reply(`you have assigned ${orig} for \`${roleName}\``); 79 | }, 80 | 81 | requiredRoles: 'Moderator', 82 | }; 83 | -------------------------------------------------------------------------------- /commands/commands/fun/sell.js: -------------------------------------------------------------------------------- 1 | const getUser = require('@utils/getUser'); 2 | const updateCoins = require('@utils/updateCoins'); 3 | const profileSchema = require('@schemas/profile-schema'); 4 | module.exports = { 5 | commands: ['sell'], 6 | description: 'sell an item in the market', 7 | expectedArgs: ``, 8 | permissionError: '', 9 | minArgs: 1, 10 | /* cooldown: 5, 11 | repeats: 3, */ 12 | callback: async (message, arguments, text, client) => { 13 | const userName = message.author.username; 14 | const userId = message.author.id; 15 | let result = await getUser(userName, userId); 16 | 17 | let inventory = JSON.parse(result.items); 18 | 19 | let item = arguments.join(' '); 20 | if (typeof item !== 'string') { 21 | message.reply('please enter a valid name'); 22 | return; 23 | } 24 | 25 | item.toLowerCase(); 26 | 27 | if (!inventory[item]) { 28 | message.reply('you do not own this item!'); 29 | return; 30 | } 31 | 32 | message.reply('how many?'); 33 | const filter = (m) => m.author.id === message.author.id; 34 | let collected = await message.channel.awaitMessages(filter, { 35 | max: 1, 36 | time: 5000, 37 | error: ['you are so slow, the merchants went away'], 38 | }); 39 | 40 | if (collected.size === 0) { 41 | message.reply('since you took too long, the merchants went away'); 42 | return; 43 | } 44 | 45 | let quantity = collected.first().content; 46 | if (quantity === 'max') { 47 | quantity = inventory[item].count; 48 | } 49 | quantity = +quantity; 50 | if (isNaN(quantity) || quantity < 0) { 51 | message.reply('please provide a valid amount to sell'); 52 | return; 53 | } 54 | if (quantity > inventory[item].count) { 55 | message.reply('you dont have that many to sell'); 56 | return; 57 | } 58 | 59 | const status = inventory[item].status; 60 | const cash = { 61 | LEGENDARY: 500000, 62 | EPIC: 50000, 63 | 'SUPER RARE': 10000, 64 | RARE: 2000, 65 | COMMON: 300, 66 | }; 67 | 68 | if (!cash[status]) { 69 | message.reply('this item cannot be sold at the moment'); 70 | return; 71 | } 72 | 73 | const total = quantity * cash[status]; 74 | message.reply( 75 | `you have earned **${total.toLocaleString()}** coins by selling \n**x${quantity.toLocaleString()}** ${ 76 | inventory[item].emoji 77 | }\`${item}\` - [**${status}**] ` 78 | ); 79 | 80 | inventory[item].count -= quantity; 81 | if (inventory[item].count === 0) { 82 | delete inventory[item]; 83 | } 84 | result.items = JSON.stringify(inventory); 85 | result.inventoryCount -= quantity; 86 | result.coins += quantity * cash[status]; 87 | await profileSchema.findOneAndUpdate({ userId }, result); 88 | }, 89 | permissions: [], 90 | requiredRoles: [], 91 | }; 92 | -------------------------------------------------------------------------------- /commands/commands/fun/explore.js: -------------------------------------------------------------------------------- 1 | const gold = require('@root/replies/gold.js'); 2 | const nothing = require('@root/replies/nothing.js'); 3 | const items = require('@root/replies/items.js'); 4 | const updateCoins = require('@utils/updateCoins'); 5 | const updateVault = require('@utils/updateVault'); 6 | const getUser = require('@utils/getUser'); 7 | const updatetUser = require('@utils/updateUser'); 8 | 9 | module.exports = { 10 | commands: ['explore', 'exp'], 11 | description: 'explores the wilderness ', 12 | minArgs: 0, 13 | maxArgs: 0, 14 | cooldown: 12, 15 | repeats: 2, 16 | callback: async (message, arguments, text) => { 17 | const { memeber, content, guild } = message; 18 | const name = message.author.username; 19 | const userId = message.author.id; 20 | let search_chance = Math.floor(Math.random() * 1000); 21 | /* 22 | 1% chance of item 23 | 17% chance of gold 24 | 82% chance of nothing 25 | */ 26 | let break_item = Math.floor(Math.random() * 10000); 27 | /* 28 | 5% chance of item break 29 | */ 30 | 31 | // Make's sure the user exist's 32 | let result = await getUser(name, userId); 33 | let inventory = JSON.parse(result.items); 34 | 35 | if (0 <= search_chance && search_chance < 10) { 36 | const rnd = Math.floor(Math.random() * items.length); 37 | const res = items[rnd]; 38 | const { hunting_bow, fishing_rod } = res; 39 | if (hunting_bow) { 40 | if (!inventory['hunting bow']) { 41 | inventory['hunting bow'] = { 42 | emoji: '🏹', 43 | count: 1, 44 | }; 45 | } else { 46 | inventory['hunting bow'].count++; 47 | } 48 | } else if (fishing_rod) { 49 | if (!inventory['fishing pole']) { 50 | inventory['fishing pole'] = { 51 | emoji: '🎣', 52 | count: 1, 53 | }; 54 | } else { 55 | inventory['fishing pole'].count++; 56 | } 57 | } 58 | 59 | result.items = JSON.stringify(inventory); 60 | await updatetUser(userId, result); 61 | message.reply(res.description); 62 | } else if (0 <= search_chance - 10 && search_chance - 10 < 170) { 63 | const rnd = Math.floor(Math.random() * gold.length); 64 | const res = gold[rnd]; 65 | const rnd_coins = Math.floor(Math.random() * 900) + 100; 66 | res.description = res.description.replace('XXX', '**' + String(rnd_coins) + '**'); 67 | 68 | await updateCoins(userId, rnd_coins); 69 | message.reply(res.description); 70 | } else { 71 | const rnd = Math.floor(Math.random() * nothing.length); 72 | const res = nothing[rnd]; 73 | 74 | message.reply(res.description); 75 | } 76 | 77 | if (0 <= break_item && break_item < 600) { 78 | if (inventory['hunting bow']) { 79 | inventory['hunting bow'].count--; 80 | result.items = JSON.stringify(inventory); 81 | await updatetUser(userId, result); 82 | message.reply('Your bow :bow_and_arrow: just snapped into two. What did you two?'); 83 | } 84 | } 85 | }, 86 | }; 87 | -------------------------------------------------------------------------------- /replies/hunt.js: -------------------------------------------------------------------------------- 1 | module.exports.common = [ 2 | ['🐶', "tamer's dog"], 3 | ['🐒', 'jungle monkey'], 4 | ['🐱', 'why-would-you-fight-me cat'], 5 | ['🐈', 'small cat '], 6 | ['🦌', 'minding-my-own-business deer'], 7 | ['🐮', 'simple cow'], 8 | ['🐷', 'backyard pig'], 9 | ['🐖', 'money bank pig'], 10 | ['🐗', 'small boar'], 11 | ['🐑', "Mary's lamb"], 12 | ['🐐', 'goat'], 13 | ['🦙', 'llama'], 14 | ['🦒', 'taller giraffe'], 15 | ['🐭', 'house rat'], 16 | ['🐁', 'small mouse'], 17 | ['🐀', 'pesty rat'], 18 | ['🐹', 'friendly hamster'], 19 | ['🐰', 'rabbit'], 20 | ['🐿️', 'chipmunk'], 21 | ['🦇', 'bat'], 22 | ['🐨', 'cool koala'], 23 | ['🐔', 'chicken'], 24 | ['🐤', 'no-way-you-are-fighting-me chick'], 25 | ['🕊️', 'dove'], 26 | ['🦆', 'yikes duck'], 27 | ['🦢', 'swan'], 28 | ['🦉', 'owl'], 29 | ['🐸', 'swamp frog'], 30 | ['🦎', 'house lizzard'], 31 | ]; 32 | 33 | module.exports.rare = [ 34 | ['🐵', 'magical satori'], 35 | ['🐕', 'egyptian hound'], 36 | ['🦮', 'suspicious chamarosh'], 37 | ['🐴', 'stray horse'], 38 | ['🦌', 'angry deer'], 39 | ['🐂', 'wild oxen'], 40 | ['🐄', 'giant cow'], 41 | ['🐗', 'wild boar'], 42 | ['🐏', 'wild sheep'], 43 | ['🐐', 'faun'], 44 | ['🐫', 'double hump camel'], 45 | ['🐘', 'noraml elephant'], 46 | ['🦔', 'hedgehog'], 47 | ['🐼', 'zoo panda'], 48 | ['🦥', 'sloth'], 49 | ['🦦', 'harry otter'], 50 | ['🦨', 'sublime skunk'], 51 | ['🦘', 'kangaroo'], 52 | ['🦡', 'badger'], 53 | ['🐧', 'penguin'], 54 | ['🕊️', 'peace masters dove'], 55 | ['🦜', 'tarag parrot'], 56 | ['🐸', 'goblin'], 57 | ['🐢', 'apprentice turtle'], 58 | ['🦎', 'geccko'], 59 | ['🐍', 'snake'], 60 | ]; 61 | 62 | module.exports.superRare = [ 63 | ['🦧', 'Shojo spirit'], 64 | ['🐕‍🦺', 'blood-thirsty wild dog'], 65 | ['🐩', 'snow feline'], 66 | ['🦝', 'dark tanuki'], 67 | ['🐯', 'jungle tiger'], 68 | ['🐆', 'articulan leapord'], 69 | ['🦌', 'Keresh stag'], 70 | ['🐃', 'silver buffalo'], 71 | ['🐏', 'mountain shamshir'], 72 | ['🐐', 'satyr'], 73 | ['🐪', 'sun-kissed camel'], 74 | ['🐘', 'angry elephant'], 75 | ['🦏', 'rhino'], 76 | ['🐰', 'alice-in-wonderland rabbit'], 77 | ['🦇', 'chipacabra'], 78 | ['🐻', 'bear'], 79 | ['🦃', 'persian turkey'], 80 | ['🐓', 'midnight rooster'], 81 | ['🦅', 'sky eagle'], 82 | ['🦉', 'strix'], 83 | ['🐊', 'amazonian crocodile'], 84 | ['🐍', 'deadly viper'], 85 | ]; 86 | 87 | module.exports.epic = [ 88 | ['🦍', 'ancient primate'], 89 | ['🐺', 'werewolf fenerir'], 90 | ['🦁', 'vermillion lion'], 91 | ['🐅', 'slumber tiger'], 92 | ['🐘', 'behemoth mammoth'], 93 | ['🦛', 'crimson hippo'], 94 | ['🐇', 're-zero rabbit'], 95 | ['🐼', 'shaolin panda'], 96 | ['🐦', 'elven harbringer'], 97 | ['🐧', 'empoleon'], 98 | ['🦅', 'hippogriff'], 99 | ['🦩', 'blood pink flame-ingo'], 100 | ['🦚', 'abysall peacock'], 101 | ['🐍', 'anaconda'], 102 | ['🐲', 'valley point drake'], 103 | ['🦕', 'sauropod'], 104 | ]; 105 | 106 | module.exports.legendary = [ 107 | ['🦊', 'Nine-tailed fox'], 108 | ['🦄', 'celestial unicorn'], 109 | ['🦓', 'Mythical Arion'], 110 | ['🦇', 'camazotz bat god'], 111 | ['🦅', "empire's griffon"], 112 | ['🐊', 'aztec cipactli'], 113 | ['🐢', 'wisdom-god turtlox'], 114 | ['🐉', 'chineese dragon'], 115 | ['🦖', 't-rex'], 116 | ]; 117 | -------------------------------------------------------------------------------- /commands/commands/management/set-verification.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const verificationChannelsSchema = require('@schemas/verification-channels-schema'); 3 | const { fetch } = require('@features/verification-channel/verification-channel'); 4 | //let { cache } = require('@root/cache/verification-channels-cache.js'); 5 | 6 | module.exports = { 7 | commands: ['setVerification', 'set-verification', 'set-ver'], 8 | description: 9 | 'set a channel to a `verification channel`. This will set the previous message in the channel as the message to vefiy with. Please specifiy a role which is lower than the bots role in the server. A server can have only one verification channel.', 10 | expectedArgs: ' <#channel_name>(opt)', 11 | permissionError: '', 12 | minArgs: 2, 13 | maxArgs: 3, 14 | callback: async (message, arguments, text, client) => { 15 | const seconds = 3; 16 | const { member, guild, content } = message; 17 | const channel = message.mentions.channels.first() || message.channel; 18 | 19 | if (message.mentions.channels.first()) { 20 | arguments.length = arguments.length - 1; 21 | text = arguments.join(' '); 22 | } 23 | 24 | let emoji = arguments[0]; 25 | const roleName = arguments[1]; 26 | const role = guild.roles.cache.find((role) => role.name === roleName); 27 | if (!role) { 28 | message.reply('That role does not exist').then((message) => { 29 | setTimeout(() => { 30 | // deletes the bots response message 31 | message.delete(); 32 | }, seconds * 1000); 33 | }); 34 | 35 | // delete the message the user sent 36 | message.delete().catch((err) => { 37 | console.log('cannot delete server owners message', err); 38 | }); // but if server owner sent this, then it becomes forbidden 39 | return; 40 | } 41 | 42 | const roleId = role.id; 43 | 44 | //Custom emojis have this syntax { EmojiName: emojiCode } 45 | if (emoji.includes(':')) { 46 | const split = emoji.split(':'); 47 | const emojiName = split[1]; 48 | emoji = guild.emojis.cache.find((emoji) => { 49 | return emoji.name === emojiName; 50 | }); 51 | } 52 | 53 | // deleting user's message, which is a command 54 | message.delete().then(() => { 55 | channel.messages.fetch({ limit: 1 }).then(async (results) => { 56 | const firstMessage = results.first(); 57 | if (!firstMessage) { 58 | channel.send('There is no message to react to').then((message) => { 59 | // deletes the bots response message 60 | 61 | message.delete({ timeout: seconds * 1000 }); 62 | }); 63 | } 64 | 65 | // react to latest message with emoji 66 | firstMessage.react(emoji); 67 | 68 | // update to mongo db 69 | await mongo().then(async (mongoose) => { 70 | try { 71 | await verificationChannelsSchema 72 | .findOneAndUpdate( 73 | { guildId: guild.id }, 74 | { guildId: guild.id, channelId: channel.id, roleId }, 75 | { upsert: true } 76 | ) 77 | .exec(); 78 | } finally { 79 | } 80 | }); 81 | 82 | await fetch(client); 83 | }); 84 | }); 85 | }, 86 | permissions: ['ADMINISTRATOR'], 87 | }; 88 | -------------------------------------------------------------------------------- /features/features/verification-channel/verification-channel.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const verificationChannelsSchema = require('@schemas/verification-channels-schema'); 3 | 4 | // { 'channelId' : 'roleId' } 5 | let verificationCache = {}; 6 | 7 | const fetchData = async (client) => { 8 | //console.log('FETCHING DATA - verifcation channel - cache populate'); 9 | 10 | await mongo().then(async (mongoose) => { 11 | try { 12 | const results = await verificationChannelsSchema.find({}); 13 | 14 | for (const result of results) { 15 | const { guildId, channelId, roleId } = result; 16 | const guild = client ? client.guilds.cache.get(guildId) : undefined; 17 | if (guild) { 18 | const channel = guild.channels.cache.get(channelId); 19 | if (channel) { 20 | verificationCache[channelId] = roleId; 21 | //console.log(channel); 22 | // this will read all messsages and trigger appropriate liserners 23 | // this is to accomdate the time when the bot is offline and stuff 24 | channel.messages.fetch().then((message) => { 25 | //console.log(message); 26 | for (const [author, m] of message) { 27 | const { guild } = m; 28 | const reactionsCache = m.reactions.cache; 29 | for (const [dummy, value] of reactionsCache) { 30 | value.users.fetch().then((res) => { 31 | for (const [id, val] of res) { 32 | const member = guild.members.cache.get(id); 33 | if (!member) continue; 34 | member.roles.add(roleId); 35 | } 36 | }); 37 | } 38 | } 39 | }); 40 | } 41 | } 42 | } 43 | console.log('finsihed loading prefix CACHE'); 44 | } finally { 45 | } 46 | }); 47 | }; 48 | 49 | const populateCache = async (client) => { 50 | verificationCache = {}; 51 | 52 | await fetchData(client); 53 | //console.log('athellam fetch panni mudichachu rasa'); 54 | 55 | setTimeout(populateCache, 1000 * 60 * 10); 56 | }; 57 | 58 | module.exports = (client) => { 59 | populateCache(client); 60 | 61 | client.on('messageReactionAdd', (reaction, user) => { 62 | const channelId = reaction.message.channel.id; 63 | const roleId = verificationCache[channelId]; 64 | 65 | //console.log('im printing this: ', roleId, user); 66 | if (roleId) { 67 | const { guild } = reaction.message; 68 | //console.log(user); 69 | //guild member has more p roperties than user object. though the ids are same 70 | const member = guild.members.cache.get(user.id); 71 | member.roles.add(roleId); 72 | } 73 | }); 74 | 75 | client.on('messageReactionRemove', (reaction, user) => { 76 | const channelId = reaction.message.channel.id; 77 | const roleId = verificationCache[channelId]; 78 | 79 | //console.log('im printing this: ', roleId, user); 80 | if (roleId) { 81 | const { guild } = reaction.message; 82 | 83 | //guild member has more properties than user object. though the ids are same 84 | const member = guild.members.cache.get(user.id); 85 | member.roles.remove(roleId); 86 | } 87 | }); 88 | }; 89 | 90 | module.exports.fetch = fetchData; 91 | -------------------------------------------------------------------------------- /features/features/thanks/thanks-lb.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const thanksSchema = require('@schemas/thanks-schema'); 3 | const thanksChannelSchema = require('@schemas/thanks-channel-schema'); 4 | 5 | const fetchTopMembers = async (guildId, guild, channel) => { 6 | const role = guild.roles.cache.find((role) => role.name === 'Helping Herald'); 7 | if (!role) { 8 | channel.send("please create a role 'Helping Herald' first").then((message) => { 9 | message.delete({ timeout: 1000 * 20 }); 10 | }); 11 | return; 12 | } 13 | 14 | let text = 'Gratitude is a virtue! Appreciation is another 🥺\n*Here is recognition for our **TOP** helpers:*\n'; 15 | text += `**Top 3** users will recieve the <@&${role.id}> role\n\n`; 16 | const results = await thanksSchema 17 | .find({ 18 | guildId, 19 | }) 20 | .sort({ 21 | received: -1, 22 | }) 23 | .limit(30); 24 | 25 | //console.log(guild.roles.cache); 26 | for (let counter = 0; counter < results.length; counter++) { 27 | const { userId, received = 0 } = results[counter]; 28 | const member = guild.members.cache.get(userId); 29 | if (!member) continue; 30 | text += `#${counter + 1} <@${userId}> with \`${received}\` thanks\n`; 31 | if (role) { 32 | if (counter < 3) { 33 | member.roles.add(role); 34 | } else { 35 | member.roles.remove(role); 36 | } 37 | } 38 | } 39 | 40 | text += `\nThis is updated every \`30\`mins...\nWe will try and reset the thanks count every month :)`; 41 | return text; 42 | }; 43 | 44 | const updateLeaderBoard = async (client) => { 45 | const results = await thanksChannelSchema.find({}); 46 | 47 | for (const result of results) { 48 | const { channelId, guildId } = result; 49 | const guild = client.guilds.cache.get(guildId); 50 | if (guild) { 51 | const channel = guild.channels.cache.get(channelId); 52 | if (channel) { 53 | const messages = await channel.messages.fetch(); 54 | const firstMessage = messages.first(); 55 | 56 | const text = await fetchTopMembers(guildId, guild, channel); 57 | 58 | if (firstMessage) { 59 | firstMessage.edit(text); 60 | } else { 61 | channel.send(text); 62 | } 63 | } 64 | } 65 | } 66 | 67 | setTimeout(() => { 68 | updateLeaderBoard; 69 | }, 30 * 60 * 1000); 70 | }; 71 | 72 | module.exports = async (client) => { 73 | updateLeaderBoard(client); 74 | client.on('message', async (message) => { 75 | const { content, member, guild } = message; 76 | const getPrefix = require('@root/commands/command-base').getPrefix; 77 | const prefix = getPrefix(client, guild.id); 78 | if (content.toLowerCase().startsWith(prefix) || member.user.bot) return; 79 | 80 | const authorData = await thanksSchema.findOne({ 81 | userId: message.author.id, 82 | guildId: message.guild.id, 83 | }); 84 | 85 | const now = new Date(); 86 | if (authorData && authorData.lastGave) { 87 | const then = new Date(authorData.lastGave); 88 | const diff = now.getTime() - then.getTime(); 89 | 90 | const diffHours = Math.round(diff / (1000 * 60 * 60)); 91 | const hours = 1; 92 | if (diffHours < hours) { 93 | //message.reply(`you have already thanked someone within the last \`${hours}hr(s)\``); 94 | return; 95 | } 96 | } 97 | 98 | const res = content.match(/th[a|e]*nks/g); 99 | if (res) { 100 | message.channel.send(`**TIP** Want to thank someone? Use \`${prefix} thank \``).then((message) => { 101 | setTimeout(() => { 102 | message.delete(); 103 | }, 5 * 1000); 104 | }); 105 | } 106 | }); 107 | }; 108 | 109 | module.exports.updateLeaderBoard = updateLeaderBoard; 110 | -------------------------------------------------------------------------------- /commands/commands/fun/buy.js: -------------------------------------------------------------------------------- 1 | const getUser = require('@utils/getUser'); 2 | const updateCoins = require('@utils/updateCoins'); 3 | const profileSchema = require('@schemas/profile-schema'); 4 | const { items } = require('@root/replies/shop'); 5 | 6 | module.exports = { 7 | commands: ['buy'], 8 | description: 'buys an item from the shop', 9 | expectedArgs: ``, 10 | permissionError: '', 11 | minArgs: 1, 12 | /* cooldown: 5, 13 | repeats: 3, */ 14 | callback: async (message, arguments, text, client) => { 15 | const userName = message.author.username; 16 | const userId = message.author.id; 17 | let result = await getUser(userName, userId); 18 | 19 | let inventory = JSON.parse(result.items); 20 | 21 | const temp = []; 22 | for (const [emoji, name, info, cost] of items) { 23 | temp[name.toLowerCase()] = [cost, emoji]; 24 | } 25 | 26 | let item = arguments.join(' '); 27 | if (typeof item !== 'string') { 28 | message.reply('please enter a valid name'); 29 | return; 30 | } 31 | item.toLowerCase(); 32 | 33 | if (!temp[item]) { 34 | message.reply('there is no such item to buy!'); 35 | return; 36 | } 37 | 38 | message.reply('how many?'); 39 | const filter = (m) => m.author.id === message.author.id; 40 | let collected = await message.channel.awaitMessages(filter, { 41 | max: 1, 42 | time: 5000, 43 | error: ['you are so slow, the merchants went away'], 44 | }); 45 | 46 | if (collected.size === 0) { 47 | message.reply('since you took too long, the merchants went away'); 48 | return; 49 | } 50 | 51 | let quantity = +collected.first().content; 52 | 53 | if (isNaN(quantity) || quantity < 0) { 54 | message.reply('please provide a valid amount to buy'); 55 | return; 56 | } 57 | 58 | if (quantity * temp[item][0] > result.coins) { 59 | message.reply('you dont have that much coins to buy'); 60 | return; 61 | } 62 | 63 | let exit = 0; 64 | const handleItem = (item) => { 65 | switch (item) { 66 | case 'shamshir daggers': 67 | result.atk += 2 * quantity; 68 | break; 69 | 70 | case 'goliath armor': 71 | result.def += 2 * quantity; 72 | break; 73 | 74 | case 'trusted role': 75 | const role = message.guild.roles.cache.find((role) => role.name === 'Trusted'); 76 | if (!role) { 77 | message.reply('sorry it seems like your server owner hasnt made this a role'); 78 | exit = 1; 79 | } else { 80 | const member = message.guild.members.cache.get(message.author.id); 81 | member.roles.add(role); 82 | message.reply('you now have the `Trusted` role'); 83 | } 84 | break; 85 | 86 | case 'hunting bow': 87 | message.reply('you can now use the `hunt` command'); 88 | break; 89 | 90 | case 'fishing pole': 91 | message.reply('you can now use the `fish` command'); 92 | break; 93 | default: 94 | break; 95 | } 96 | }; 97 | 98 | if (exit) return; 99 | 100 | result.coins -= quantity * temp[item][0]; 101 | result.inventoryCount += quantity; 102 | if (!inventory[item]) { 103 | inventory[item] = { 104 | emoji: temp[item][1], 105 | count: quantity, 106 | }; 107 | } else { 108 | inventory[item].count += quantity; 109 | } 110 | handleItem(item); 111 | result.items = JSON.stringify(inventory); 112 | await profileSchema.findOneAndUpdate({ userId }, result); 113 | 114 | const total = quantity * temp[item][0]; 115 | message.reply( 116 | `you have bought \n**x${quantity.toLocaleString()}** ${ 117 | temp[item][1] 118 | }\`${item}\` for **${total.toLocaleString()}** coins` 119 | ); 120 | }, 121 | permissions: [], 122 | requiredRoles: [], 123 | }; 124 | -------------------------------------------------------------------------------- /commands/commands/moderation/mute.js: -------------------------------------------------------------------------------- 1 | const redis = require('@root/database/redis'); 2 | 3 | module.exports = { 4 | commands: ['mute'], 5 | description: 'mutes the user for the given time', 6 | expectedArgs: " ", 7 | minArgs: 3, 8 | maxArgs: 3, 9 | callback: async (message, arguments, text, client) => { 10 | const redisKeyPrefix = 'muted-'; 11 | 12 | const getRole = (guild) => { 13 | return guild.roles.cache.find((role) => role.name === 'Silence'); 14 | }; 15 | 16 | redis.expire((message) => { 17 | if (message.startsWith(redisKeyPrefix)) { 18 | const [d1, memberId, guildId] = message.split('-'); 19 | const guild = client.guilds.cache.get(guildId); 20 | const member = guild.members.cache.get(memberId); 21 | 22 | const role = getRole(guild); 23 | if (role) { 24 | member.roles.remove(role); 25 | console.log('Unmuted' + member.id); 26 | } else { 27 | console.log('Could not find the role'); 28 | } 29 | console.log('expired', guild.name); 30 | } 31 | }); 32 | 33 | // gives the 'Silence' role to a member 34 | const giveRole = (member) => { 35 | const role = getRole(member.guild); 36 | if (role) { 37 | member.roles.add(role); 38 | console.log('Muted' + member.id); 39 | } else { 40 | console.log('Could not find the role'); 41 | } 42 | }; 43 | 44 | // what we do on member join 45 | const onJoin = async (member) => { 46 | const { guild } = member; 47 | const redisClient = await redis(); 48 | try { 49 | redisClient.get(`${redisKeyPrefix}${target.id}-${guild.id}`, (err, res) => { 50 | if (err) { 51 | console.log('redis GET error: ', err); 52 | } else if (res) { 53 | giveRole(member); 54 | } else { 55 | console.log('User is not muted'); 56 | } 57 | }); 58 | } finally { 59 | //redisClient.quit(); 60 | } 61 | }; 62 | 63 | // listens to people joinnig the server - to catch people trying to get rid of the mute role 64 | client.on('guildMemberAdd', (member) => { 65 | onJoin(member); 66 | }); 67 | 68 | const { mentions, channel, guild, content } = message; 69 | const target = mentions.users.first(); 70 | const tag = `<@${target.id}>`; 71 | console.log(target); 72 | 73 | arguments.shift(); 74 | duration = arguments[0]; 75 | durationType = arguments[1]; 76 | console.log(arguments); 77 | 78 | if (target) { 79 | if (isNaN(duration)) { 80 | channel.send('Please provide a valid number for the duration ' + this.expectedArgs); 81 | } else { 82 | const durations = { 83 | s: 1, 84 | m: 60, 85 | h: 60 * 60, 86 | d: 24 * 60 * 60, 87 | life: -1, 88 | }; 89 | 90 | if (!durations[durationType]) { 91 | channel.send('Please provide a valid duration type ' + this.expectedArgs); 92 | } else { 93 | const targetMember = guild.members.cache.get(target.id); 94 | giveRole(targetMember); 95 | 96 | const seconds = duration * durations[durationType]; 97 | const redisClient = await redis(); 98 | try { 99 | const redisKey = `${redisKeyPrefix}${target.id}-${guild.id}`; 100 | if (seconds > 0) { 101 | redisClient.set(redisKey, 'true', 'EX', seconds); 102 | } else { 103 | redisClient.set(redisKey, 'true'); 104 | } 105 | } finally { 106 | //redis.client.quit() 107 | } 108 | } 109 | /* const targetMember = message.guild.members.cache.get(target.id); 110 | targetMember.kick(); 111 | message.channel.send(`${tag} has been kicked`); */ 112 | } 113 | } else { 114 | message.relpy(`${tag} does not exist`); 115 | } 116 | }, 117 | requiredRoles: 'Moderator', 118 | }; 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # discord-bot-GenuineGenie 2 | 3 | A bot that can do everything? Yes you read that right, this is an advanced community server _setup/management/moderation/handling_ discord-bot with about **50+ commands** and **10+ features**!! 4 | 5 | Invite the bot by clicking on this URL right now, and see it in action yourself, [click here](https://discord.com/api/oauth2/authorize?client_id=786230987964809257&permissions=8&scope=bot) 6 | 7 | --- 8 | 9 | # Features 10 | 11 | - ## Welcome 12 | 13 | - set up any channel as a welcome channel with your own custom message. 14 | - When anyone joins, the bot will auto greet with your custom text 15 | - _the inbuilt tool that discord provides doesnt let you @ the user that joins_ 16 | ![](./gifs/welcome.gif) 17 | 18 | - ## Thank's Leaderboard 19 | 20 | - set up any channel with the thank's leaderboard 21 | - The top 30 people who have been thanked will be displyed in this channel, refreshing every 30 mins 22 | - _This is a fun way to motivate your server members to help out others, incase you are building a server that would require this use case_ 23 | ![](./gifs/thanks.gif) 24 | 25 | - ## Polls 26 | 27 | - set up any channel to auto-poll any message sent 28 | - When someone sends a message ` = `, the bot will audo add those emojis to the message sent. So people can now easily voice their opinions by simply reacting to the message. 29 | - _Do you have a server which requires a lot of community opinion? Or do you want to ask a simple question like when you want to hold your next meeting? Just use the polls channel_ 30 | ![](./gifs/polls.gif) 31 | 32 | - ## Role-Claim 33 | 34 | - Set up any channel as the role-claim channel 35 | - Once you finish up assigning roles to emojis, you can create a role claim channel with the syntax ` = `, and leave the bot to take care of the rest 36 | - emojis that represent roles are automatically added 37 | - and then comes the Magical part!! When people react, they **GET THE ROLE**! 38 | - This is a **premium** feature in many well known bots, offered for free in GG 39 | - _handy tool to nail your first impression, especially if you are building a community server_ 40 | ![](./gifs/role-claim.gif) 41 | 42 | - ## Suggestions Channel 43 | 44 | - Set up any channel as the role-claim channel 45 | - Once set up, any message you send here will be auto styled into an aesthetic template awaiting community feedback 46 | - Moderators can then accept or deny a suggestion with basic commands 47 | - _Extremely handy to get and process communtiy suggestions and giving feedback to each. If everything was just a boring text channel, would'nt it be broing?_ 48 | ![](./gifs/suggestions.gif) 49 | 50 | - ## Mod-logs 51 | 52 | - Set up any channel to log everything that a person with the role 'Moderator' would say 53 | - Effective tool to moderate anything and everything that a 'Moderator' says in your server 54 | - _If you are building a big community with many unknown temporary mods, this is the right feature for you_ 55 | ![](./gifs/modlogs.gif) 56 | 57 | - ## Per server Prefix 58 | 59 | - run a simple ` prefix ` and set a prefix of your choice for youur server 60 | - _Often used by guild masters to stop 2 or more bots from having the same command prefix_ 61 | 62 | - ## Member Count (coming soon...) 63 | 64 | - Set up any channel to display the number of people in your server 65 | - you can see the member count channel in any of the above gifs 66 | - _Want to show off the enormous amount of people in your server or just you know display useful information, then this is your goto feature_ 67 | 68 | # Commands 69 | 70 | There are over **50 commands** that is offered by the bot. The differnt commands can be seen in the pic below. 71 | ![](./pictures/screenshots/help-command.png) 72 | 73 | - #### As it is shown, the commadns are widely divided into _4 categories_, namely, 74 | 75 | - **fun** - comers with levelling and economy systems (**MUST CHECK OUT**) 76 | - **management** - commands that implement features and much more 77 | - **misc** - random ad hoc commands for curious minds 78 | - **moderation** - moderators rule over these commands 79 | 80 | - You can type `hit help ` anytime to get a detailed description of any command like below, 81 | ![](./pictures/screenshots/sample-command.png)! 82 | 83 | ## **NOTE** 84 | 85 | The **fun commands** are _very vast_ and includes some amazing **premium** features like `daily`, `battles`, `levelling`, `shop`, `buy`, `sell` and much more. These commmands will surely increase your _server activity by 3 folds_ if used properly. [_**MUST CHECK OUT FEATURE**_] 86 | -------------------------------------------------------------------------------- /commands/commands/fun/fish.js: -------------------------------------------------------------------------------- 1 | const { none, common, rare, superRare, legendary } = require('@root/replies/fish'); 2 | const { MessageEmbed } = require('discord.js'); 3 | const getUser = require('@utils/getUser'); 4 | const profileSchema = require('@schemas/profile-schema'); 5 | 6 | module.exports = { 7 | commands: ['fish'], 8 | description: 'fishes a random monster', 9 | cooldown: 100, 10 | repeats: 1, 11 | callback: async (message, arguments, text, client) => { 12 | const userName = message.author.username; 13 | const userId = message.author.id; 14 | 15 | const fish = async (usr, opp, status) => { 16 | const filter = (m) => m.author.id === message.author.id; 17 | 18 | message.reply('type `pull` asap, hurryyyy!'); 19 | 20 | // await for messages 21 | let result = await message.channel.awaitMessages(filter, { 22 | max: 1, 23 | time: 4000, 24 | error: ['since you took too long, you found nothing'], 25 | }); 26 | 27 | if (result.size === 0) { 28 | message.reply('since you took too long, you found nothing'); 29 | return; 30 | } 31 | 32 | // fetch and validate user reply 33 | result = result.first().content; 34 | if (typeof result !== 'string') { 35 | message.reply('you didnt enter a valid move, you found nothing'); 36 | return; 37 | } 38 | result = result.toLowerCase(); 39 | 40 | if (result !== 'pull') { 41 | message.reply('you didnt enter a valid move, you found nothing'); 42 | return; 43 | } 44 | 45 | if (status !== 'NONE') { 46 | const res = await getUser(userName, userId); 47 | let items = JSON.parse(res.items); 48 | if (!items[opp.name]) { 49 | items[opp.name] = { 50 | emoji: opp.emoji, 51 | count: 1, 52 | status, 53 | }; 54 | } else { 55 | items[opp.name].count++; 56 | } 57 | res.items = JSON.stringify(items); 58 | res.fishedCount++; 59 | res.inventoryCount++; 60 | 61 | await profileSchema.findOneAndUpdate({ userId }, res); 62 | message.reply( 63 | `you caught something in your fishing pole!\n${opp.emoji} \`${opp.name}\` [ **${status}** ], has been added to your inventory!` 64 | ); 65 | } else { 66 | message.reply(`${opp.emoji}. \`${opp.name}\`!`); 67 | } 68 | }; 69 | 70 | const user = await getUser(userName, userId); 71 | const inventory = JSON.parse(user.items); 72 | if (!inventory['fishing pole']) { 73 | message.reply( 74 | 'you need a 🎣 `fishing pole` to use the `fish` command.\n**TIP** you can buy it in the shop' 75 | ); 76 | return; 77 | } 78 | 79 | const usr = { 80 | name: user.name, 81 | hp: user.hp, 82 | atk: user.atk, 83 | def: user.def, 84 | }; 85 | 86 | const roll = Math.floor(Math.random() * 100); 87 | // legendary (4000 - 200- 330) 88 | if (roll < 0.1) { 89 | const index = Math.floor(Math.random() * legendary.length); 90 | const [emoji, name] = legendary[index]; 91 | opp = { emoji, name }; 92 | fish(usr, opp, 'LEGENDARY'); 93 | } // epic (1000- 80 - 200) 94 | else if (roll < 2) { 95 | const index = Math.floor(Math.random() * superRare.length); 96 | const [emoji, name] = superRare[index]; 97 | opp = { emoji, name }; 98 | fish(usr, opp, 'EPIC'); 99 | } //super rare (450 - 50 - 100) 100 | else if (roll < 15) { 101 | const index = Math.floor(Math.random() * rare.length); 102 | const [emoji, name] = rare[index]; 103 | opp = { emoji, name }; 104 | fish(usr, opp, 'RARE'); 105 | } //rare (200 - 35- 50) 106 | else if (roll < 50) { 107 | const index = Math.floor(Math.random() * common.length); 108 | const [emoji, name] = common[index]; 109 | opp = { emoji, name }; 110 | fish(usr, opp, 'COMMON'); 111 | } // common (120 - 20 - 20) 112 | else { 113 | const index = Math.floor(Math.random() * none.length); 114 | const [emoji, name] = none[index]; 115 | opp = { emoji, name }; 116 | fish(usr, opp, 'NONE'); 117 | } 118 | }, 119 | }; 120 | -------------------------------------------------------------------------------- /commands/commands/fun/plunder.js: -------------------------------------------------------------------------------- 1 | const getUser = require('@utils/getUser'); 2 | const updateCoins = require('@utils/updateCoins'); 3 | const plunderSchema = require('@schemas/plunder-schema'); 4 | const { MessageEmbed } = require('discord.js'); 5 | 6 | module.exports = { 7 | commands: ['plunder', 'rob', 'steal'], 8 | description: "robs a % from someone's coins", 9 | expectedArgs: "", 10 | permissionError: '', 11 | minArgs: 1, 12 | maxArgs: 1, 13 | cooldown: 60, 14 | repeats: 1, 15 | callback: async (message, arguments, text) => { 16 | const target = message.mentions.users.first(); 17 | if (!target) { 18 | message.reply('No such user exists'); 19 | return; 20 | } 21 | 22 | if (target.id === message.author.id) { 23 | message.reply('Funny you thought that will work xD'); 24 | return; 25 | } 26 | 27 | const userName = message.author.username; 28 | const userId = message.author.id; 29 | 30 | const targetName = target.username; 31 | const targetId = target.id; 32 | 33 | const resultUser = await getUser(userName, userId); 34 | const resultTarget = await getUser(targetName, targetId); 35 | if (resultUser.coins < 400) { 36 | message.reply(`you need atleast *400* coins in your coin pouch, before you can plunder somoene else`); 37 | return 1; 38 | } 39 | 40 | const results = await plunderSchema.findOne({ userId: targetId }); 41 | //console.log(results); 42 | if (results) { 43 | const then = new Date(results.updatedAt).getTime(); 44 | const now = new Date().getTime(); 45 | 46 | const diffTime = Math.abs(now - then); 47 | const diffMinutes = diffTime / (1000 * 60); 48 | //console.log(diffMinutes); 49 | if (diffMinutes <= 2) { 50 | message.reply(`this user was robbed within the last 2 mins! please give them some time to cry`); 51 | return 1; 52 | } 53 | } 54 | 55 | const roll = Math.floor(Math.random() * 100); 56 | if (roll < 5) { 57 | const delta = resultTarget.coins; 58 | message.channel.send( 59 | `<@${userId}>, 🤑 You evil little twig. You emptied <@${targetId}>'s wallet.\nyou plundered **${delta}** coins.` 60 | ); 61 | await updateCoins(userId, delta); 62 | await updateCoins(targetId, -delta); 63 | await plunderSchema.findOneAndUpdate( 64 | { userId: targetId }, 65 | { userId: targetId }, 66 | { new: true, upsert: true } 67 | ); 68 | } else if (roll < 10) { 69 | const delta = Math.floor((Math.random() * resultTarget.coins * 75) / 100); 70 | message.channel.send( 71 | `<@${userId}>, 💰 You almost stole everything from <@${targetId}>'s wallet. What a theif!\nyou plundered **${delta}** coins.` 72 | ); 73 | await updateCoins(userId, delta); 74 | await updateCoins(targetId, -delta); 75 | await plunderSchema.findOneAndUpdate( 76 | { userId: targetId }, 77 | { userId: targetId }, 78 | { new: true, upsert: true } 79 | ); 80 | } else if (roll < 20) { 81 | const delta = Math.floor((Math.random() * resultTarget.coins * 33) / 100); 82 | message.channel.send( 83 | `<@${userId}>, 💵 you plundered **${delta}** coins from <@${targetId}>'s wallet. oof. ` 84 | ); 85 | await updateCoins(userId, delta); 86 | await updateCoins(targetId, -delta); 87 | await plunderSchema.findOneAndUpdate( 88 | { userId: targetId }, 89 | { userId: targetId }, 90 | { new: true, upsert: true } 91 | ); 92 | } else if (roll < 40) { 93 | const delta = Math.floor((Math.random() * resultTarget.coins * 20) / 100); 94 | message.channel.send(`<@${userId}>, you plundered **${delta}** coins from your target. not bad. `); 95 | await updateCoins(userId, delta); 96 | await updateCoins(targetId, -delta); 97 | await plunderSchema.findOneAndUpdate( 98 | { userId: targetId }, 99 | { userId: targetId }, 100 | { new: true, upsert: true } 101 | ); 102 | } else if (roll < 60) { 103 | const delta = 250; 104 | message.reply('😂 you got caught!\nyou payed the person you tried to rob **250** coins'); 105 | await updateCoins(userId, -250); 106 | await updateCoins(targetId, 250); 107 | } else { 108 | message.reply('lol. you are bad at even plundering! try again later or something xD'); 109 | } 110 | }, 111 | permissions: [], 112 | requiredRoles: [], 113 | }; 114 | -------------------------------------------------------------------------------- /commands/commands/misc/help.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const loadCommands = require('@root/commands/load-commands'); 3 | 4 | module.exports = { 5 | commands: ['help'], 6 | expectedArgs: '[o]', 7 | description: 'describes differnt commands', 8 | callback: (message, arguments, text, client) => { 9 | let reply = 'I am the **GenuinGenie**-bot. I can pretty much do anything: \n\n'; 10 | const commands = loadCommands(); 11 | 12 | const getPrefix = require('@root/commands/command-base').getPrefix; 13 | const prefix = getPrefix(client, message.guild.id); 14 | 15 | let ok = 0; 16 | if (arguments.length === 0) { 17 | /* for (const command of commands) { 18 | let permissions = command.permission; 19 | if (permissions) { 20 | let hasPermission = true; 21 | if (typeof permissions === 'string') { 22 | permissions = [permissions]; 23 | } 24 | 25 | for (const permission of permissions) { 26 | if (!message.author.hasPermission(permission)) { 27 | hasPermission = false; 28 | break; 29 | } 30 | } 31 | 32 | if (!hasPermission) { 33 | continue; 34 | } 35 | } 36 | 37 | // Format the text 38 | const mainCommand = typeof command.commands === 'string' ? command.commands : command.commands[0]; 39 | const args = command.expectedArgs ? ` ${command.expectedArgs}` : ``; 40 | const { description } = command; 41 | 42 | reply += `**${prefix} ${mainCommand}${args}** = ${description}\n`; 43 | } 44 | message.channel.send(reply); */ 45 | const { guild } = message; 46 | 47 | const getPrefix = require('@root/commands/command-base').getPrefix; 48 | const prefix = getPrefix(client, guild.id); 49 | const fields = require('@root/commands/load-commands.js').fields; 50 | 51 | let footer = `\n\n\`${prefix} help \` - to know more about a command\n`; 52 | footer += `NOTE: Some commands require special *roles* and/or *permissions* to run`; 53 | const embed = new Discord.MessageEmbed() 54 | //.setDescription('modules and commands of the GG-bot') 55 | //.setTitle(`_Genuine Genie_ #HELP`) 56 | .addFields(...fields) 57 | .setFooter(footer) 58 | .setColor('RANDOM'); 59 | 60 | message.channel.send(embed); 61 | ok = 1; 62 | } else { 63 | const query = arguments[0].toLowerCase(); 64 | //console.log(query); 65 | for (const command of commands) { 66 | let cc = command.commands; 67 | if (typeof cc === 'string') cc = [cc]; 68 | for (let i = 0; i < cc.length; i++) { 69 | cc[i] = cc[i].toLowerCase(); 70 | } 71 | 72 | if (cc.includes(query)) { 73 | let aliases = ''; 74 | for (const name of cc) { 75 | aliases += `\`${name}\`, `; 76 | } 77 | 78 | const { expectedArgs } = command; 79 | const mainCommand = typeof command.commands === 'string' ? command.commands : command.commands[0]; 80 | const args = expectedArgs ? ` ${expectedArgs}` : ``; 81 | const format = `*${prefix} ${mainCommand}${args}*`; 82 | 83 | const fields = []; 84 | fields.push({ 85 | name: 'aliases', 86 | value: aliases, 87 | }); 88 | fields.push({ 89 | name: 'description', 90 | value: command.description, 91 | }); 92 | fields.push({ 93 | name: 'format', 94 | value: format, 95 | }); 96 | 97 | if (command.requiredRoles ? command.requiredRoles.length : undefined) { 98 | let rol = command.requiredRoles; 99 | if (typeof rol === 'string') rol = [rol]; 100 | fields.push({ 101 | name: 'Required Roles', 102 | value: rol.join(', '), 103 | }); 104 | } 105 | 106 | if (command.permissions ? command.permissions.length : undefined) { 107 | let per = command.permissions; 108 | if (typeof per === 'string') per = [per]; 109 | fields.push({ 110 | name: 'Required Permissions', 111 | value: per.join(', '), 112 | }); 113 | } 114 | 115 | ok = 1; 116 | const embed = new Discord.MessageEmbed().addFields(fields).setColor('RANDOM'); 117 | 118 | message.channel.send(embed); 119 | } 120 | } 121 | } 122 | 123 | if (!ok) { 124 | message.reply('No such command\n**TIP** `help` command for the full list of commands'); 125 | } 126 | }, 127 | }; 128 | -------------------------------------------------------------------------------- /features/features/role-claim/role-claim.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const roleclaimSchema = require('@schemas/roleclaim-schema'); 3 | 4 | let roleclaimCache = {}; 5 | // guildId: [channelid, assigns] 6 | 7 | const addToCache = (guildId, channelId, emojiRoles) => { 8 | roleclaimCache[guildId] = [channelId, emojiRoles]; 9 | }; 10 | 11 | const delFromCache = (guildId, channelId) => { 12 | delete roleclaimCache[guildId]; 13 | }; 14 | 15 | const loadCache = async () => { 16 | const results = await mongo().then(async (mongoose) => { 17 | try { 18 | return await roleclaimSchema.find({}); 19 | } finally { 20 | } 21 | }); 22 | 23 | for (const { guildId, channelId, emojiRoles } of results) { 24 | roleclaimCache[guildId] = [channelId, JSON.parse(emojiRoles)]; 25 | } 26 | console.log('finsihed loading role claim CACHE'); 27 | }; 28 | 29 | const onMessage = async (message, old) => { 30 | const customEmoji = (emojiName) => { 31 | emojiName = emojiName.split(':')[1]; 32 | return guild.emojis.cache.find((emoji) => emoji.name === emojiName); 33 | }; 34 | 35 | if (message.member.user.bot) return; 36 | const { guild, content, channel } = message; 37 | //message.reactions.removeAll(); 38 | 39 | if (!roleclaimCache[guild.id]) return; 40 | const [channelId, emojiRoles] = roleclaimCache[guild.id]; 41 | 42 | if (channelId !== channel.id) { 43 | return; 44 | } 45 | if (!emojiRoles) return; 46 | 47 | //console.log(emojiRoles); 48 | const eachLine = content.split('\n'); 49 | for (const line of eachLine) { 50 | if (line.includes('=')) { 51 | const split = line.split('='); 52 | let emoji = split[0].trim(); 53 | const orig = emoji; 54 | emoji = emoji.replace(/^[a-zA-Z0-9\(\)\,\.\[\] ]*/, ''); 55 | //console.log('inside', emoji); 56 | if (customEmoji(emoji)) emoji = customEmoji(emoji).name; 57 | 58 | if (!emojiRoles[emoji]) { 59 | message 60 | .reply(`${emoji} is not registered\n**TIP** use commmand \`roleassign\` to register role`) 61 | .then((message) => { 62 | message.delete({ 63 | timeout: 7 * 1000, 64 | }); 65 | }); 66 | continue; 67 | } 68 | 69 | try { 70 | message.react(orig).catch((err) => { 71 | console.log(err); 72 | }); 73 | } catch { 74 | message.reply('Incorrect Syntax!\n` = ` is strictly binding').then((message) => { 75 | message.delete({ 76 | timeout: 10 * 1000, 77 | }); 78 | return; 79 | }); 80 | } 81 | } 82 | } 83 | }; 84 | 85 | const displaySampleMessage = (channel, client) => { 86 | const getEmoji = (emojiName) => client.emojis.cache.find((emoji) => emoji.name === emojiName); 87 | const emojis = { 88 | '🅰️': '', 89 | '🅱️': '', 90 | '🅾️': '', 91 | '🆎': '', 92 | }; 93 | 94 | let emojiText = 'Choose reaction(s) to claim a role!\n\n'; 95 | for (const key in emojis) { 96 | const emoji = getEmoji(key); 97 | const role = ``; 98 | emojiText += `${key} = ${role}\n`; 99 | } 100 | 101 | emojiText += 102 | '\nThis is a sample message to help you set up your `role claim channel`.\n*you can copy-paste this template if you want!*\n\n**This Message will auto delete in `60`s**'; 103 | //setting the init_message in a 'particular' role-claim Channel 104 | channel.send(emojiText).then((message) => { 105 | setTimeout(() => { 106 | message.delete(); 107 | }, 60 * 1000); 108 | }); 109 | }; 110 | 111 | const handleReacion = (reaction, user, add) => { 112 | // Just ignore the bot 113 | if (user.id === '786230987964809257') { 114 | return; 115 | } 116 | 117 | if (!roleclaimCache[reaction.message.guild.id]) return; 118 | const [channelId, emojiRoles] = roleclaimCache[reaction.message.guild.id]; 119 | 120 | if (channelId !== reaction.message.channel.id) { 121 | return; 122 | } 123 | 124 | //console.log(reaction._emoji); 125 | const emoji = reaction._emoji.name; 126 | const { guild } = reaction.message; 127 | 128 | const roleName = emojiRoles[emoji]; 129 | if (!roleName) { 130 | return; 131 | } 132 | 133 | const role = guild.roles.cache.find((role) => { 134 | return role.name === roleName; 135 | }); 136 | if (!role) { 137 | reaction.message.reply(`There is no role \`${roleName}\``); 138 | return; 139 | } 140 | 141 | // Member object has more information than the User object 142 | const member = guild.members.cache.get(user.id); 143 | 144 | // Give/remove the role 145 | if (add) { 146 | member.roles.add(role); 147 | } else { 148 | member.roles.remove(role); 149 | } 150 | }; 151 | 152 | module.exports = async (client) => { 153 | await loadCache(); 154 | for (const [guildId, [channelId, emojiRoles]] of Object.entries(roleclaimCache)) { 155 | // returns an actual emoji object, and emojiName = actual name of the emoji 156 | const guild = client.guilds.cache.get(guildId); 157 | const channel = guild.channels.cache.get(channelId); 158 | await channel.messages.fetch(); 159 | } 160 | 161 | // We need to add a couple of event listeners now 162 | client.on('messageReactionAdd', (reaction, user) => { 163 | handleReacion(reaction, user, true); 164 | }); 165 | 166 | client.on('messageReactionRemove', (reaction, user) => { 167 | handleReacion(reaction, user, false); 168 | }); 169 | 170 | client.on('messageUpdate', (oldMessage, newMessage) => { 171 | onMessage(newMessage, oldMessage); 172 | }); 173 | 174 | client.on('message', (message) => { 175 | onMessage(message); 176 | }); 177 | }; 178 | 179 | module.exports.addToCache = addToCache; 180 | module.exports.delFromCache = delFromCache; 181 | module.exports.roleclaimCache = () => { 182 | return roleclaimCache; 183 | }; 184 | 185 | module.exports.displaySampleMessage = displaySampleMessage; 186 | -------------------------------------------------------------------------------- /commands/command-base.js: -------------------------------------------------------------------------------- 1 | const mongo = require('@root/database/mongo'); 2 | const prefixSchema = require('@schemas/prefix-schema'); 3 | const { prefix: globalPrefix } = require('@root/config.json'); 4 | const updateXP = require('@utils/updateXP'); 5 | let givePrefix = globalPrefix; 6 | const guildPrefixes = {}; //guildId: prefix 7 | const validatePermissions = (permissions) => { 8 | const validPermissions = [ 9 | 'CREATE_INSTANT_INVITE', 10 | 'KICK_MEMBERS', 11 | 'BAN_MEMBERS', 12 | 'ADMINISTRATOR', 13 | 'MANAGE_CHANNELS', 14 | 'MANAGE_GUILD', 15 | 'ADD_REACTIONS', 16 | 'VIEW_AUDIT_LOG', 17 | 'PRIORITY_SPEAKER', 18 | 'STREAM', 19 | 'VIEW_CHANNEL', 20 | 'SEND_MESSAGES', 21 | 'SEND_TTS_MESSAGES', 22 | 'MANAGE_MESSAGES', 23 | 'EMBED_LINKS', 24 | 'ATTACH_FILES', 25 | 'READ_MESSAGE_HISTORY', 26 | 'MENTION_EVERYONE', 27 | 'USE_EXTERNAL_EMOJIS', 28 | 'VIEW_GUILD_INSIGHTS', 29 | 'CONNECT', 30 | 'SPEAK', 31 | 'MUTE_MEMBERS', 32 | 'DEAFEN_MEMBERS', 33 | 'MOVE_MEMBERS', 34 | 'USE_VAD', 35 | 'CHANGE_NICKNAME', 36 | 'MANAGE_NICKNAMES', 37 | 'MANAGE_ROLES', 38 | 'MANAGE_WEBHOOKS', 39 | 'MANAGE_EMOJIS', 40 | ]; 41 | 42 | for (const permission of permissions) { 43 | if (!validPermissions.includes(permission)) { 44 | throw new Error(`unknown permsission node "${permission}"`); 45 | } 46 | } 47 | }; 48 | 49 | const getTimespan = (date_now, date_future) => { 50 | // get total seconds between the times 51 | var delta = Math.abs(date_future - date_now) / 1000; 52 | 53 | // calculate (and subtract) whole days 54 | var days = Math.floor(delta / 86400); 55 | delta -= days * 86400; 56 | 57 | // calculate (and subtract) whole hours 58 | var hours = Math.floor(delta / 3600) % 24; 59 | delta -= hours * 3600; 60 | 61 | // calculate (and subtract) whole minutes 62 | var minutes = Math.floor(delta / 60) % 60; 63 | delta -= minutes * 60; 64 | 65 | // what's left is seconds 66 | return delta; 67 | }; 68 | 69 | let recently = new Map(); //guild-userId-command-time 70 | 71 | module.exports = (client, commandOptions) => { 72 | let { 73 | commands, 74 | expectedArgs = '', 75 | permissionError = 'You do not have permission to run this command.', 76 | minArgs = 0, 77 | maxArgs = null, 78 | cooldown = -1, 79 | repeats = 1, 80 | permissions = [], 81 | requiredRoles = [], 82 | callback, 83 | } = commandOptions; 84 | 85 | console.log(`Registering command "${commands[0]}"`); 86 | // Ensure the command and aliases are in an array 87 | if (typeof commands === 'string') { 88 | commands = [commands]; 89 | } 90 | 91 | // Ensure the permissions are in an array and are all valid 92 | if (permissions.length) { 93 | if (typeof permissions === 'string') { 94 | permissions = [permissions]; 95 | } 96 | validatePermissions(permissions); 97 | } 98 | 99 | client.on('message', async (message) => { 100 | let { member, content, guild } = message; 101 | const prefix = guildPrefixes[guild.id] || globalPrefix; 102 | givePrefix = prefix; 103 | const currentDate = new Date(); 104 | // Setting bot's status 105 | client.user.setPresence({ 106 | activity: { 107 | name: `"${prefix} help" - for help`, 108 | }, 109 | }); 110 | 111 | for (const alias of commands) { 112 | if ( 113 | content.toLowerCase().startsWith(`${prefix} ${alias.toLowerCase()} `) || 114 | content.toLowerCase() === `${prefix} ${alias.toLowerCase()}` || 115 | content.toLowerCase().startsWith(`${prefix}${alias.toLowerCase()} `) || 116 | content.toLowerCase() === `${prefix}${alias.toLowerCase()}` 117 | ) { 118 | // A command has to be run 119 | 120 | // Ensure the user has the required permissions 121 | for (const permission of permissions) { 122 | if (!member.hasPermission(permission)) { 123 | message.reply(`You must have the "${permission}" to use this command.`); 124 | return; 125 | //message.reply(permissionError); 126 | } 127 | } 128 | 129 | if (typeof requiredRoles === 'string') requiredRoles = [requiredRoles]; 130 | 131 | // Enusre the user has the required roles 132 | for (const requiredRole of requiredRoles) { 133 | const role = guild.roles.cache.find((role) => role.name === requiredRole); 134 | 135 | if (!role || !member.roles.cache.has(role.id)) { 136 | message.reply(`You must have the "${requiredRole}" role to use this command.`); 137 | return; 138 | } 139 | } 140 | 141 | // Ensure that the user has not run the command very frequently 142 | let cooldownString = `${guild.id}-${member.id}-${commands}`; 143 | if (cooldown > 0 && recently.has(cooldownString)) { 144 | const parsedArray = recently.get(cooldownString).split(' '); 145 | const [currentrepeats, oldTime] = parsedArray; 146 | 147 | if (currentrepeats <= 0) { 148 | const timeElapsed = getTimespan(currentDate.getTime(), Number(oldTime)); 149 | const waitingTime = cooldown - timeElapsed; 150 | 151 | message.reply(`You can use this command in \`${+waitingTime.toFixed(2)} secs\`. Please wait!`); 152 | return; 153 | } 154 | } 155 | 156 | if ( 157 | content.toLowerCase().startsWith(`${prefix}${alias.toLowerCase()} `) || 158 | content.toLowerCase() === `${prefix}${alias.toLowerCase()}` 159 | ) { 160 | const temp = content.toLowerCase().split(prefix.toLowerCase()); 161 | content = prefix.toLowerCase() + ' ' + temp[1]; 162 | console.log(temp); 163 | console.log(content); 164 | } 165 | 166 | // Split on any number of spaces 167 | const arguments = content.split(/[ ]+/); 168 | // Remove the command which is the first index 169 | arguments.shift(); 170 | arguments.shift(); 171 | 172 | // Ensure we have the correct number of arguments 173 | if (arguments.length < minArgs || (maxArgs !== null && arguments.length > maxArgs)) { 174 | message.reply(`Incorrect syntax! use:\n *${prefix} ${alias} ${expectedArgs}*`); 175 | return; 176 | } 177 | 178 | // Handle the custom command code 179 | const retVal = await callback(message, arguments, arguments.join(' '), client); 180 | 181 | // commands issued ++ 182 | await updateXP(message.author.id, Math.floor(Math.random() * 50) + 50, message); 183 | 184 | // Handle Cooldowns 185 | if (cooldown > 0 && retVal !== 1) { 186 | if (recently.has(cooldownString)) { 187 | const parsedArray = recently.get(cooldownString).split(' '); 188 | const [currentrepeats, ...others] = parsedArray; 189 | recently.set(cooldownString, `${currentrepeats - 1} ${currentDate.getTime()}`); 190 | 191 | if (currentrepeats <= 1) { 192 | setTimeout(() => { 193 | recently.delete(cooldownString); 194 | }, 1000 * cooldown); 195 | } 196 | } else { 197 | if (repeats === 1) { 198 | recently.set(cooldownString, `${repeats - 1} ${currentDate.getTime()}`); 199 | setTimeout(() => { 200 | recently.delete(cooldownString); 201 | }, 1000 * cooldown); 202 | } else { 203 | recently.set(cooldownString, `${repeats - 1} ${currentDate.getTime()}`); 204 | } 205 | } 206 | } 207 | 208 | return; 209 | } 210 | } 211 | }); 212 | }; 213 | 214 | const loadPrefixes = async (client, guildId) => { 215 | for (const guild of client.guilds.cache) { 216 | //console.log(guild) 217 | const result = await prefixSchema.findOne({ guildId: guild[1].id }); 218 | guildPrefixes[guild[1].id] = result ? result.prefix : globalPrefix; 219 | } 220 | 221 | console.log('finsihed loading prefix CACHE'); 222 | 223 | if (guildId) { 224 | // Setting bot's status 225 | client.user.setPresence({ 226 | activity: { 227 | name: `"${guildPrefixes[guildId]} help" - for help`, 228 | }, 229 | }); 230 | } 231 | }; 232 | 233 | module.exports.loadPrefixes = loadPrefixes; 234 | module.exports.getPrefix = (client, guildId) => { 235 | //oadPrefixes(client, guildId); 236 | if (guildPrefixes[guildId]) return guildPrefixes[guildId]; 237 | else { 238 | loadPrefixes(); 239 | return guildPrefixes[guildId]; 240 | } 241 | }; 242 | 243 | module.exports.updatePrefix = (guildId, newPrefix) => { 244 | guildPrefixes[guildId] = newPrefix; 245 | }; 246 | -------------------------------------------------------------------------------- /commands/commands/fun/hunt.js: -------------------------------------------------------------------------------- 1 | const { common, rare, superRare, epic, legendary } = require('@root/replies/hunt'); 2 | const { MessageEmbed } = require('discord.js'); 3 | const getUser = require('@utils/getUser'); 4 | const profileSchema = require('@schemas/profile-schema'); 5 | module.exports = { 6 | commands: ['hunt'], 7 | description: 'hunts a random monster', 8 | cooldown: 120, 9 | repeats: 1, 10 | callback: async (message, arguments, text, client) => { 11 | const userName = message.author.username; 12 | const userId = message.author.id; 13 | 14 | const fight = async (usr, opp, status) => { 15 | message.reply( 16 | `${opp.emoji} \`${opp.name}\` [ **${status}** ] - (*${opp.hp}/${opp.atk}/${opp.def}*),\nhas jumped right next to you!` 17 | ); 18 | const filter = (m) => m.author.id === message.author.id; 19 | 20 | const displayStats = (usr, opp) => { 21 | const embed = new MessageEmbed().setDescription( 22 | `Your *HP* = **${usr.hp.toFixed(2)}**\n${opp.emoji}'s *HP*: **${opp.hp.toFixed(2)}**` 23 | ); 24 | return embed; 25 | }; 26 | 27 | const attack = (A, B) => { 28 | let dat, dis; 29 | if (A.emoji) (dat = `${A.emoji} ${A.name}`), (dis = `you`); 30 | else (dis = `${B.emoji} ${B.name}`), (dat = `you`); 31 | 32 | const damage_dealt = A.atk - B.def / 1000 * A.atk + Math.random() * 5 - Math.random() * 2; 33 | B.hp -= damage_dealt; 34 | message.reply(`\`${dat}\` attacked \`${dis}\` and dealt **${damage_dealt.toFixed(2)}** true damage`); 35 | }; 36 | 37 | const defend = (A, B) => { 38 | let dat; 39 | if (A.emoji) dat = `${A.emoji} ${A.name}`; 40 | else dat = `you`; 41 | 42 | A.def += 40; 43 | message.reply(`\`${dat}\` defended and permenantly rose thier DEF by **40**`); 44 | }; 45 | 46 | const heal = (A, B) => { 47 | let dat; 48 | if (A.emoji) dat = `${A.emoji} ${A.name}`; 49 | else dat = `you`; 50 | 51 | const heal = Math.random() * (A.hp / 50) + 10; 52 | A.hp += heal; 53 | message.reply(`\`${dat}\` and recovered **${heal.toFixed(2)}** HP`); 54 | }; 55 | 56 | const action = (usr, opp, move, counter) => { 57 | if (move === 'attack') { 58 | attack(usr, opp); 59 | } else if (move === 'defend') { 60 | defend(usr, opp); 61 | } else if (move === 'heal') { 62 | heal(usr, opp); 63 | } else { 64 | return -1; 65 | } 66 | }; 67 | 68 | const isEndGame = async (usr, opp) => { 69 | //console.log('in here', usr.hp, opp.hp); 70 | if (opp.hp <= 0) { 71 | message.reply( 72 | `you **WON** the battle!\n${opp.emoji} \`${opp.name}\` [ **${status}** ], has been added to your inventory!` 73 | ); 74 | let res = await getUser(userName, userId); 75 | 76 | let items = JSON.parse(res.items); 77 | if (!items[opp.name]) { 78 | items[opp.name] = { 79 | emoji: opp.emoji, 80 | count: 1, 81 | status, 82 | }; 83 | } else { 84 | items[opp.name].count++; 85 | } 86 | 87 | res.items = JSON.stringify(items); 88 | res.huntedCount++; 89 | res.inventoryCount++; 90 | 91 | await profileSchema.findOneAndUpdate({ userId }, res); 92 | return 1; 93 | } 94 | 95 | if (usr.hp <= 0) { 96 | message.reply(`you **LOST** the battle!`); 97 | return 1; 98 | } 99 | 100 | return 0; 101 | }; 102 | 103 | let turn = 0; 104 | let counter = 0; 105 | // 0 - usr, 1 - opp 106 | 107 | while ((await isEndGame(usr, opp)) === 0) { 108 | if (turn === 0) { 109 | // Display prompt for battle 110 | if (counter === 0) { 111 | message.channel.send('what would you like to do?\n `attack`, `defend`, `heal`, `run`'); 112 | } else { 113 | message.channel.send('what would you like to do?\n `attack`, `defend`, `heal`'); 114 | } 115 | 116 | // await for messages 117 | let result = await message.channel.awaitMessages(filter, { 118 | max: 1, 119 | time: 20000, 120 | error: ['since you took too long, the monster ran away'], 121 | }); 122 | 123 | if (result.size === 0) { 124 | message.reply('since you took too long, the monster ran away'); 125 | break; 126 | } 127 | 128 | // fetch and validate user reply 129 | result = result.first().content; 130 | if (typeof result !== 'string') { 131 | message.reply('you didnt enter a valid move, the monster ran away'); 132 | return; 133 | } 134 | result = result.toLowerCase(); 135 | 136 | if (result === 'run' && counter === 0) { 137 | message.reply("the monster growls! I guess it says 'wise choice human' in monster lang"); 138 | return; 139 | } 140 | 141 | // handle cases 142 | const val = action(usr, opp, result, counter); 143 | if (val === -1) { 144 | message.reply('there is no such move, say again xD'); 145 | continue; 146 | } 147 | } else { 148 | const roll = Math.random() * 3; 149 | if (roll < 2) { 150 | action(opp, usr, 'attack'); 151 | } else if (roll < 2.5) { 152 | action(opp, usr, 'defend'); 153 | } else { 154 | action(opp, usr, 'heal'); 155 | } 156 | } 157 | 158 | message.reply(displayStats(usr, opp)); 159 | 160 | turn = 1 - turn; 161 | counter++; 162 | } 163 | }; 164 | 165 | const setAttribute = (base) => { 166 | const mul = Math.floor(Math.random() * 2) === 0 ? -1 : +1; 167 | const add = 168 | mul === -1 ? Math.floor(-1 * Math.random() * (base / 60)) : Math.floor(Math.random() * (base / 10)); 169 | const attr = base + add; 170 | 171 | return attr; 172 | }; 173 | 174 | const user = await getUser(userName, userId); 175 | const inventory = JSON.parse(user.items); 176 | if (!inventory['hunting bow']) { 177 | message.reply('you need a 🏹 `hunting bow` to use the `hunt` command.\n**TIP** you can buy it in the shop'); 178 | return; 179 | } 180 | 181 | const usr = { 182 | name: user.name, 183 | hp: user.hp, 184 | atk: user.atk, 185 | def: user.def, 186 | }; 187 | 188 | const roll = Math.floor(Math.random() * 100); 189 | // legendary (4000 - 200- 330) 190 | if (roll < 2) { 191 | const index = Math.floor(Math.random() * legendary.length); 192 | const [emoji, name] = legendary[index]; 193 | const hp = setAttribute(4000); 194 | const atk = setAttribute(250); 195 | const def = setAttribute(300); 196 | 197 | const opp = { 198 | emoji, 199 | name, 200 | hp, 201 | atk, 202 | def, 203 | }; 204 | fight(usr, opp, 'LEGENDARY'); 205 | } // epic (1000- 80 - 200) 206 | else if (roll < 10) { 207 | const index = Math.floor(Math.random() * epic.length); 208 | const [emoji, name] = epic[index]; 209 | const hp = setAttribute(1000); 210 | const atk = setAttribute(100); 211 | const def = setAttribute(200); 212 | const opp = { 213 | emoji, 214 | name, 215 | hp, 216 | atk, 217 | def, 218 | }; 219 | fight(usr, opp, 'EPIC'); 220 | } //super rare (450 - 50 - 100) 221 | else if (roll < 25) { 222 | const index = Math.floor(Math.random() * superRare.length); 223 | const [emoji, name] = superRare[index]; 224 | const hp = setAttribute(450); 225 | const atk = setAttribute(60); 226 | const def = setAttribute(100); 227 | 228 | const opp = { 229 | emoji, 230 | name, 231 | hp, 232 | atk, 233 | def, 234 | }; 235 | fight(usr, opp, 'SUPER RARE'); 236 | } //rare (200 - 35- 50) 237 | else if (roll < 50) { 238 | const index = Math.floor(Math.random() * rare.length); 239 | const [emoji, name] = rare[index]; 240 | const hp = setAttribute(200); 241 | const atk = setAttribute(40); 242 | const def = setAttribute(50); 243 | const opp = { 244 | emoji, 245 | name, 246 | hp, 247 | atk, 248 | def, 249 | }; 250 | fight(usr, opp, 'RARE'); 251 | } // common (120 - 20 - 20) 252 | else { 253 | const index = Math.floor(Math.random() * common.length); 254 | const [emoji, name] = common[index]; 255 | const hp = setAttribute(120); 256 | const atk = setAttribute(20); 257 | const def = setAttribute(20); 258 | 259 | const opp = { 260 | emoji, 261 | name, 262 | hp, 263 | atk, 264 | def, 265 | }; 266 | fight(usr, opp, 'COMMON'); 267 | } 268 | }, 269 | }; 270 | --------------------------------------------------------------------------------