Откат изменений v3.1.4

This commit is contained in:
JonnyBro 2022-01-04 02:18:28 +05:00
parent a3aac66d25
commit 9bd1e3fd1f
7875 changed files with 718156 additions and 0 deletions

30
.gitignore vendored Normal file
View file

@ -0,0 +1,30 @@
# Bot Configuration
config.js
# Node modules
node_modules
package-lock.json
yarn.lock
# Fortnite Shop images
assets/img/fortnite/shop/**/*.png
!assets/img/fortnite/shop/**/example-shop.png
# DB
giveaways.json
# Mac OS files
.DS_Store
# PM2
report*.json
!languages/**/general/report.json
# IDE
.vscode
# commands.md
**/commands.md
# Clips
clips

1
README.md Normal file
View file

@ -0,0 +1 @@
# JaBa-new

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
assets/img/facepalm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

23
base/Command.js Normal file
View file

@ -0,0 +1,23 @@
const path = require("path");
module.exports = class Command {
constructor(client, {
name = null,
dirname = false,
enabled = true,
guildOnly = false,
aliases = new Array(),
botPermissions = new Array(),
memberPermissions = new Array(),
nsfw = false,
ownerOnly = false,
cooldown = 3000
})
{
const category = (dirname ? dirname.split(path.sep)[parseInt(dirname.split(path.sep).length - 1, 10)] : "Other");
this.client = client;
this.conf = { enabled, guildOnly, memberPermissions, botPermissions, nsfw, ownerOnly, cooldown};
this.help = { name, category, aliases };
}
};

69
base/Guild.js Normal file
View file

@ -0,0 +1,69 @@
const mongoose = require("mongoose"),
Schema = mongoose.Schema,
config = require("../config.js"),
languages = require("../languages/language-meta.json");
module.exports = mongoose.model("Guild", new Schema({
/* REQUIRED */
id: { type: String }, // Discord ID of the guild
/* MEMBERSDATA */
membersData: { type: Object, default: {} }, // Members data of the guild
members: [{ type: Schema.Types.ObjectId, ref: "Member" }],
/* CONFIGURATION */
language: { type: String, default: languages.find((l) => l.default).name }, // Language of the guild
prefix: { type: String, default: config.prefix }, // Default or custom prefix of the guild
plugins: { type: Object, default: { // Plugins data
// Welcome messages
welcome: {
enabled: false, // Whether the welcome messages are enabled
message: null, // The welcome message
channel: null, // The channel to send the welcome messages
withImage: null // Whether the welcome images are enabled
},
// Goodbye messages
goodbye: {
enabled: false, // Whether the goodbye messages are enabled
message: null, // The goodbye message
channel: null, // The channel to send the goodbye messages
withImage: null // Whether the goodbye images are enabled
},
// Autorole
autorole: {
enabled: false, // Whether the autorole is enabled
role: null // The role to add when a member join the server
},
// Auto moderation
automod: {
enabled: false, // Whether the auto moderation is enabled
ignored: [] // The channels in which the auto moderation is disabled
},
// Auto sanctions
warnsSanctions: {
kick: false, // The number of warns required to kick the user
ban: false // The number of warns required to ban the user
},
// Tickets
tickets: {
enabled: false, // Whether the tickets system is enabled
category: null // The category for the tickets system
},
suggestions: false, // the channel in which the suggestions will be sent
modlogs: false, // the channel in which the moderation logs (mute, kick, ban, etc...) will be sent
birthdays: false, // the channel in which birtdays announcements will be sent
reports: false, // the channel in which the reports will be sent
fortniteshop: false, // the channel in which the fortnite shop image will be sent at 2.05am
logs: false // the channel in which the logs (message deleted, etc...) will be sent
}},
slowmode: { type: Object, default: { // Servers slowmode
users: [],
channels: []
}},
casesCount: { type: Number, default: 0 },
ignoredChannels: { type: Array, default: [] }, // Channels ignored by the bot
customCommands: { type: Array, default: [] }, // Custom commands of the guild
commands: { type: Array, default: [] }, // Commands logs
autoDeleteModCommands: { type: Boolean, default: false }, // Whether to auto delete moderation commands
disabledCategories: { type: Array, default: [] } // Disabled categories
}));

339
base/JaBa.js Normal file
View file

@ -0,0 +1,339 @@
const { MessageEmbed, Util, Client, Collection } = require("discord.js"),
{ GiveawaysManager } = require("discord-giveaways"),
{ SoundCloudPlugin } = require("@distube/soundcloud"),
{ SpotifyPlugin } = require("@distube/spotify"),
{ Client: Joker } = require("blague.xyz");
const util = require("util"),
AmeClient = require("amethyste-api"),
path = require("path"),
DisTube = require("distube"),
moment = require("moment");
moment.relativeTimeThreshold("s", 60);
moment.relativeTimeThreshold("ss", 5);
moment.relativeTimeThreshold("m", 60);
moment.relativeTimeThreshold("h", 60);
moment.relativeTimeThreshold("d", 24);
moment.relativeTimeThreshold("M", 12);
// Creates JaBa class
class JaBa extends Client {
constructor(options) {
super(options);
this.config = require("../config"); // Load the config file
this.customEmojis = require("../emojis"); // load the bot's emojis
this.languages = require("../languages/language-meta"); // Load the bot's languages
this.commands = new Collection(); // Creates new commands collection
this.aliases = new Collection(); // Creates new command aliases collection
this.logger = require("../helpers/logger"); // Load the logger file
this.wait = util.promisify(setTimeout); // client.wait(1000) - Wait 1 second
this.functions = require("../helpers/functions"); // Load the functions file
this.guildsData = require("../base/Guild"); // Guild mongoose model
this.usersData = require("../base/User"); // User mongoose model
this.membersData = require("../base/Member"); // Member mongoose model
this.logs = require("../base/Log"); // Log mongoose model
this.dashboard = require("../dashboard/app"); // Dashboard app
this.queues = new Collection(); // This collection will be used for the music
this.states = {}; // Used for the dashboard
this.knownGuilds = [];
this.databaseCache = {};
this.databaseCache.users = new Collection();
this.databaseCache.guilds = new Collection();
this.databaseCache.members = new Collection();
this.databaseCache.usersReminds = new Collection(); // members with active reminds
this.databaseCache.mutedUsers = new Collection(); // members who are currently muted
if (this.config.apiKeys.amethyste) this.AmeAPI = new AmeClient(this.config.apiKeys.amethyste);
if (this.config.apiKeys.blagueXYZ) this.joker = new Joker(this.config.apiKeys.blagueXYZ, {
defaultLanguage: "en"
});
this.player = new DisTube.default(this, {
searchSongs: 10,
searchCooldown: 30,
leaveOnEmpty: true,
emptyCooldown: 0,
leaveOnFinish: true,
leaveOnStop: true,
plugins: [new SoundCloudPlugin(), new SpotifyPlugin()],
});
this.player
.on("playSong", async (queue, song) => {
const m = await queue.textChannel.send(this.translate("music/play:NOW_PLAYING", { songName: song.name }))
if (!song.isLive) {
setTimeout(() => {
if (!m.deleted) m.delete();
}, song.duration * 1000);
} else {
setTimeout(() => {
if (!m.deleted) m.delete();
}, 600 * 1000);
}
})
.on("addSong", (queue, song) => queue.textChannel.send(this.translate("music/play:ADDED_QUEUE", { songName: song.name })))
.on("addList", (queue, playlist) => queue.textChannel.send(this.translate("music/play:ADDED_QUEUE_COUNT", { songCount: playlist.songs.length })))
.on("searchResult", (message, result) => {
let i = 0
const embed = new MessageEmbed()
.setDescription(Util.escapeSpoiler(result.map(song => `**${++i} -** ${song.name}`).join("\n")))
.setFooter(this.translate("music/play:RESULTS_FOOTER"))
.setColor(this.config.embed.color);
message.channel.send(embed);
})
.on("searchDone", () => {})
.on("searchCancel", message => message.error("misc:TIMES_UP"))
.on("searchInvalidAnswer", message => message.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: 10 }))
.on("searchNoResult", message => message.error("music/play:NO_RESULT"))
.on("error", (textChannel, e) => {
console.error(e);
textChannel.send(this.translate("music/play:ERR_OCCURRED", {
error: e
}));
})
.on("finish", queue => queue.textChannel.send(this.translate("music/play:QUEUE_ENDED")))
.on("empty", queue => queue.textChannel.send(this.translate("music/play:STOP_EMPTY")));
// .on("disconnect", queue => queue.textChannel.send(this.translate("music/play:STOP_DISCONNECTED")))
this.giveawaysManager = new GiveawaysManager(this, {
storage: "./giveaways.json",
updateCountdownEvery: 10000,
default: {
botsCanWin: false,
// exemptPermissions: [ "MANAGE_MESSAGES", "ADMINISTRATOR" ],
embedColor: this.config.embed.color,
reaction: "🎉"
}
});
};
get defaultLanguage() {
return this.languages.find(language => language.default).name;
};
translate(key, args, locale) {
if (!locale) locale = this.defaultLanguage;
const language = this.translations.get(locale);
if (!language) throw "Invalid language set in data.";
return language(key, args);
};
printDate(date, format, locale) {
if (!locale) locale = this.defaultLanguage;
const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale));
if (!format) format = languageData.defaultMomentFormat;
return moment(new Date(date))
.locale(languageData.moment)
.format(format);
};
convertTime(time, type, noPrefix, locale) {
if (!type) time = "to";
if (!locale) locale = this.defaultLanguage;
const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale));
const m = moment(time).locale(languageData.moment);
return (type === "to" ? m.toNow(noPrefix) : m.fromNow(noPrefix));
};
getNoun(number, one, two, five) {
let n = Math.abs(number);
n %= 100;
if (n >= 5 && n <= 20) return five;
n %= 10;
if (n === 1) return one;
if (n >= 2 && n <= 4) return two;
return five;
};
// This function is used to load a command and add it to the collection
loadCommand(commandPath, commandName) {
try {
const props = new(require(`.${commandPath}${path.sep}${commandName}`))(this);
this.logger.log(`Loading Command: ${props.help.name}. 👌`, "log");
props.conf.location = commandPath;
if (props.init) props.init(this);
this.commands.set(props.help.name, props);
props.help.aliases.forEach((alias) => {
this.aliases.set(alias, props.help.name);
});
return false;
} catch (e) {
return `Unable to load command ${commandName}: ${e}`;
};
};
// This function is used to unload a command (you need to load them again)
async unloadCommand(commandPath, commandName) {
let command;
if (this.commands.has(commandName)) command = this.commands.get(commandName);
else if (this.aliases.has(commandName)) command = this.commands.get(this.aliases.get(commandName));
if (!command) return `The command \`${commandName}\` doesn't seem to exist, nor is it an alias. Try again!`;
if (command.shutdown) await command.shutdown(this);
delete require.cache[require.resolve(`.${commandPath}${path.sep}${commandName}.js`)];
return false;
};
// This function is used to find a user data or create it
async findOrCreateUser({ id: userID }, isLean) {
if (this.databaseCache.users.get(userID)) return isLean ? this.databaseCache.users.get(userID).toJSON() : this.databaseCache.users.get(userID);
else {
let userData = (isLean ? await this.usersData.findOne({
id: userID
}).lean() : await this.usersData.findOne({
id: userID
}));
if (userData) {
if (!isLean) this.databaseCache.users.set(userID, userData);
return userData;
} else {
userData = new this.usersData({
id: userID
});
await userData.save();
this.databaseCache.users.set(userID, userData);
return isLean ? userData.toJSON() : userData;
};
};
};
// This function is used to find a member data or create it
async findOrCreateMember({ id: memberID, guildID }, isLean) {
if (this.databaseCache.members.get(`${memberID}${guildID}`)) return isLean ? this.databaseCache.members.get(`${memberID}${guildID}`).toJSON() : this.databaseCache.members.get(`${memberID}${guildID}`);
else {
let memberData = (isLean ? await this.membersData.findOne({
guildID,
id: memberID
}).lean() : await this.membersData.findOne({
guildID,
id: memberID
}));
if (memberData) {
if (!isLean) this.databaseCache.members.set(`${memberID}${guildID}`, memberData);
return memberData;
} else {
memberData = new this.membersData({
id: memberID,
guildID: guildID
});
await memberData.save();
const guild = await this.findOrCreateGuild({
id: guildID
});
if (guild) {
guild.members.push(memberData._id);
await guild.save();
};
this.databaseCache.members.set(`${memberID}${guildID}`, memberData);
return isLean ? memberData.toJSON() : memberData;
};
};
};
// This function is used to find a guild data or create it
async findOrCreateGuild({ id: guildID }, isLean) {
if (this.databaseCache.guilds.get(guildID)) return isLean ? this.databaseCache.guilds.get(guildID).toJSON() : this.databaseCache.guilds.get(guildID);
else {
let guildData = (isLean ? await this.guildsData.findOne({
id: guildID
}).populate("members").lean() : await this.guildsData.findOne({
id: guildID
}).populate("members"));
if (guildData) {
if (!isLean) this.databaseCache.guilds.set(guildID, guildData);
return guildData;
} else {
guildData = new this.guildsData({
id: guildID
});
await guildData.save();
this.databaseCache.guilds.set(guildID, guildData);
return isLean ? guildData.toJSON() : guildData;
};
};
};
// This function is used to resolve a user from a string
async resolveUser(search) {
let user = null;
if (!search || typeof search !== "string") return;
// Try ID search
if (search.match(/^<@!?(\d+)>$/)) {
const id = search.match(/^<@!?(\d+)>$/)[1];
user = this.users.fetch(id).catch(() => {});
if (user) return user;
};
// Try username search
if (search.match(/^!?(\w+)#(\d+)$/)) {
const username = search.match(/^!?(\w+)#(\d+)$/)[0];
const discriminator = search.match(/^!?(\w+)#(\d+)$/)[1];
user = this.users.find((u) => u.username === username && u.discriminator === discriminator);
if (user) return user;
};
user = await this.users.fetch(search).catch(() => {});
return user;
};
async resolveMember(search, guild) {
let member = null;
if (!search || typeof search !== "string") return;
// Try ID search
if (search.match(/^<@!?(\d+)>$/)) {
const id = search.match(/^<@!?(\d+)>$/)[1];
member = await guild.members.fetch(id).catch(() => {});
if (member) return member;
};
// Try username search
if (search.match(/^!?(\w+)#(\d+)$/)) {
guild = await guild.fetch();
member = guild.members.cache.find((m) => m.user.tag === search);
if (member) return member;
};
member = await guild.members.fetch(search).catch(() => {});
return member;
};
async resolveRole(search, guild) {
let role = null;
if (!search || typeof search !== "string") return;
// Try ID search
if (search.match(/^<@&!?(\d+)>$/)) {
const id = search.match(/^<@&!?(\d+)>$/)[1];
role = guild.roles.cache.get(id);
if (role) return role;
};
// Try name search
role = guild.roles.cache.find((r) => search === r.name);
if (role) return role;
role = guild.roles.cache.get(search);
return role;
};
};
module.exports = JaBa;

15
base/Log.js Normal file
View file

@ -0,0 +1,15 @@
const mongoose = require("mongoose");
module.exports = mongoose.model("Log", new mongoose.Schema({
commandName: { type: String, default: "unknown" },
date: { type: Number, default: Date.now() },
author: { type: Object, default: {
username: "Unknown",
discrminator: "0000",
id: null
}},
guild: { type: Object, default: {
name: "Unknown",
id: null
}}
}));

31
base/Member.js Normal file
View file

@ -0,0 +1,31 @@
const mongoose = require("mongoose");
module.exports = mongoose.model("Member", new mongoose.Schema({
/* REQUIRED */
id: { type: String }, // Discord ID of the user
guildID: { type: String }, // ID of the guild to which the member is connected
/* SERVER ECONOMY */
money: { type: Number, default: 0 }, // Money of the user
workStreak: { type: Number, default: 0 }, // work streak of the user
bankSold: { type: Number, default: 0 }, // Bank sold of the user
exp: { type: Number, default: 0 }, // Exp points of the user
level: { type: Number, default: 0 }, // Level of the user
/* STATS */
registeredAt: { type: Number, default: Date.now() }, // Registered date of the member
/* COOLDOWN */
cooldowns: { type: Object, default: {
work: 0,
rob: 0
}},
/* OTHER INFORMATIONS */
sanctions: { type: Array, default: [] }, // Array of the member sanctions (mute, ban, kick, etc...)
mute: { type: Object, default: { // The member mute infos
muted: false,
case: null,
endDate: null
}},
}));

117
base/User.js Normal file
View file

@ -0,0 +1,117 @@
const mongoose = require("mongoose"),
Canvas = require("canvas");
const genToken = () => {
let token = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwzy0123456789.-_";
for (let i = 0; i < 32; i++) {
token += characters.charAt(Math.floor(Math.random() * characters.length));
};
return token;
};
const userSchema = new mongoose.Schema({
/* REQUIRED */
id: { type: String }, // Discord ID of the user
/* ECONOMY (GLOBAL) */
rep: { type: Number, default: 0 }, // Reputation points of the user
bio: { type: String }, // Biography of the user
birthdate: { type: Number }, // Birthdate of the user (the timestamp)
lover: { type: String }, // The person with whom the user is in a relationship
/* STATS */
registeredAt: { type: Number, default: Date.now() }, // Registered date of the user
/* ACHIEVEMENTS */
achievements: { type: Object, default: {
married: {
achieved: false,
progress: {
now: 0,
total: 1
}
},
work: {
achieved: false,
progress: {
now: 0,
total: 10
}
},
firstCommand: {
achieved: false,
progress: {
now: 0,
total: 1
}
},
slots: {
achieved: false,
progress: {
now: 0,
total: 3
}
},
tip: {
achieved: false,
progress: {
now: 0,
total: 1
}
},
rep: {
achieved: false,
progress: {
now: 0,
total: 20
},
},
invite: {
achieved: false,
progress: {
now: 0,
total: 1
}
}
}},
/* COOLDOWN */
cooldowns: { type: Object, default: {
rep: 0
}},
/* OTHER INFORMATIONS */
afk: { type: String, default: null }, // Whether the member is AFK
reminds: { type: Array, default: [] }, // the reminds of the user
logged: { type: Boolean, default: false }, // if the user is logged to the dashboard
apiToken: { type: String, default: genToken() } // the api token of the user
});
userSchema.method("genApiToken", async function() {
this.apiToken = genToken();
await this.save();
return this.apiToken;
});
userSchema.method("getAchievements", async function() {
const canvas = Canvas.createCanvas(1800, 250),
ctx = canvas.getContext("2d");
const images = [
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.work.achieved ? "_colored" : ""}1.png`),
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.firstCommand.achieved ? "_colored" : ""}2.png`),
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.married.achieved ? "_colored" : ""}3.png`),
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.slots.achieved ? "_colored" : ""}4.png`),
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.tip.achieved ? "_colored" : ""}5.png`),
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.rep.achieved ? "_colored" : ""}6.png`),
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.invite.achieved ? "_colored" : ""}7.png`)
];
let dim = 0;
for (let i = 0; i < images.length; i++) {
await ctx.drawImage(images[i], dim, 10, 350, 200);
dim += 200;
};
return canvas.toBuffer();
});
module.exports = mongoose.model("User", userSchema);

View file

@ -0,0 +1,42 @@
const Command = require("../../base/Command.js");
class Addcommand extends Command {
constructor(client) {
super(client, {
name: "addcommand",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["addc"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
if (!args[0]) return message.error("administration/addcommand:MISSING_NAME");
const name = args[0].split("\n")[0];
if (this.client.commands.get(name) || this.client.aliases.get(name) || data.guild.customCommands.find((c) => c.name === name)) return message.error("administration/addcommand:COMMAND_ALREADY_EXISTS");
const answer = (args[0].split("\n")[1] || "") + args.slice(1).join(" ");
if (!answer) return message.error("administration/addcommand:MISSING_ANSWER");
data.guild.customCommands.push({
name: name.toLowerCase(),
answer: answer
});
data.guild.save();
message.success("administration/addcommand:SUCCESS", {
commandName: name,
prefix: data.guild.prefix
});
}
};
module.exports = Addcommand;

View file

@ -0,0 +1,34 @@
const Command = require("../../base/Command.js");
class Addemoji extends Command {
constructor(client) {
super(client, {
name: "addemoji",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["adde"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args) {
const URL = args[0];
if (!URL) return message.error("administration/addemoji:MISSING_URL");
const name = args[1] ? args[1].replace(/[^a-z0-9]/gi, "") : null;
if (!name) return message.error("administration/addemoji:MISSING_NAME");
if (name.length < 2 || name > 32) return message.error("administration/addemoji:INVALID_NAME");
message.guild.emojis
.create(URL, name)
.then(emoji => message.success("administration/addemoji:SUCCESS", { emojiName: `<:${emoji.name}:${emoji.id}>` }))
.catch(() => message.error("administration/addemoji:ERROR", { emojiName: name }));
}
};
module.exports = Addemoji;

View file

@ -0,0 +1,55 @@
const Command = require("../../base/Command.js");
class Automod extends Command {
constructor(client) {
super(client, {
name: "automod",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["autom"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const status = args[0];
if (!status || (status !== "on" && status !== "off")) return message.error("administration/automod:MISSING_STATUS");
if (status === "on") {
data.guild.plugins.automod = {
enabled: true,
ignored: []
};
data.guild.markModified("plugins.automod");
data.guild.save();
message.success("administration/automod:ENABLED", {
prefix: data.guild.prefix
});
} else if (status === "off") {
if (message.mentions.channels.filter((ch) => ch.type === "text" && ch.guild.id === message.guild.id).first()) {
const channel = message.mentions.channels.first();
data.guild.plugins.automod.ignored.push(channel);
data.guild.markModified("plugins.automod");
data.guild.save();
message.success("administration/automod:DISABLED_CHANNEL", {
channel: channel.toString()
});
} else {
data.guild.plugins.automod = {
enabled: false,
ignored: []
};
data.guild.markModified("plugins.automod");
data.guild.save();
message.success("administration/automod:DISABLED");
};
};
}
};
module.exports = Automod;

View file

@ -0,0 +1,60 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Autorole extends Command {
constructor(client) {
super(client, {
name: "autorole",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["autor"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const status = args[0];
if (status !== "on" && status !== "off") return message.error("administration/autorole:MISSING_STATUS");
if (status === "on") {
const role = await Resolvers.resolveRole({
message,
search: args.slice(1).join(" ")
});
if (!role) return message.error("administration/autorole:MISSING_ROLE");
data.guild.plugins.autorole = {
enabled: true,
role: role.id
};
data.guild.markModified("plugins.autorole");
await data.guild.save();
message.success("administration/autorole:SUCCESS_ENABLED", {
roleName: role.name
});
} else if (status === "off") {
if (!data.guild.plugins.autorole.enabled) return message.success("administration/autorole:ALREADY_DISABLED", {
prefix: data.guild.prefix
});
data.guild.plugins.autorole = {
enabled: false,
role: null
};
data.guild.markModified("plugins.autorole");
await data.guild.save();
message.success("administration/autorole:SUCCESS_DISABLED", {
prefix: data.guild.prefix
});
};
}
};
module.exports = Autorole;

View file

@ -0,0 +1,105 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js"),
backup = require("discord-backup"),
Sentry = require("@sentry/node");
class Backup extends Command {
constructor(client) {
super(client, {
name: "backup",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["ba"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "ADMINISTRATOR"],
nsfw: false,
ownerOnly: false,
cooldown: 10000
});
}
async run(message, args, data) {
const status = args[0];
if (!status) return message.error("administration/backup:MISSING_STATUS");
if (status === "create") {
const m = await message.sendT("misc:PLEASE_WAIT", null, {
prefixEmoji: "loading"
});
backup.create(message.guild).then((backup) => {
m.delete();
message.success("administration/backup:SUCCESS_PUBLIC");
message.author.send(message.translate("administration/backup:SUCCESS_PRIVATE", {
backupID: backup.id
})).catch(() => {
backup.remove(backup.id);
message.error("misc:CANNOT_DM");
});
}).catch((err) => {
Sentry.captureException(err);
return message.error("misc:ERR_OCCURRED");
});
} else if (status === "load") {
const backupID = args[1];
if (!backupID) return message.error("administration/backup:MISSING_BACKUP_ID");
backup.fetch(backupID).then(async () => {
message.sendT("administration/backup:CONFIRMATION");
await message.channel.awaitMessages(m => (m.author.id === message.author.id) && (m.content === "confirm"), {
max: 1,
time: 20000,
errors: ["time"]
}).catch(() => {
// if the author of the commands does not confirm the backup loading
return message.error("misc:TIMES_UP");
});
// When the author of the command has confirmed that he wants to load the backup on his server
message.author.send(message.translate("administration/backup:START_LOADING"));
// Load the backup
backup.load(backupID, message.guild).then(() => {
// When the backup is loaded, delete them from the server
backup.remove(backupID);
message.author.send(message.translate("administration/backup:LOAD_SUCCESS"));
}).catch((err) => {
Sentry.captureException(err);
// If an error occurenced
return message.error("misc:ERR_OCCURRED");
});
}).catch(() => {
// if the backup wasn't found
return message.error("administration/backup:NO_BACKUP_FOUND", {
backupID
});
});
} else if (status === "info") {
const backupID = args[1];
if (!backupID) return message.error("administration/backup:MISSING_BACKUP_ID");
backup.fetch(backupID).then(async (backupInfos) => {
const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("administration/backup:TITLE_INFO"))
// Display the backup ID
.addField(message.translate("administration/backup:TITLE_ID"), backupInfos.id, true)
// Displays the server from which this backup comes
.addField(message.translate("administration/backup:TITLE_SERVER_ID"), backupInfos.data.guildID, true)
// Display the size (in mb) of the backup
.addField(message.translate("administration/backup:TITLE_SIZE"), `${backupInfos.size}mb`, true)
// Display when the backup was created
.addField(message.translate("administration/backup:TITLE_CREATED_AT"), message.printDate(new Date(backupInfos.data.createdTimestamp)), true)
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer);
message.channel.send(embed);
}).catch(() => {
// if the backup wasn't found
return message.error("administration/backup:NO_BACKUP_FOUND", {
backupID
});
});
} else {
return message.error("administration/backup:MISSING_STATUS");
};
}
};
module.exports = Backup;

View file

@ -0,0 +1,92 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Configuration extends Command {
constructor(client) {
super(client, {
name: "configuration",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["conf", "config"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const guildData = data.guild;
const embed = new Discord.MessageEmbed()
.setAuthor(message.guild.name, message.guild.iconURL())
.setColor(this.client.config.embed.color)
.setFooter(this.client.config.embed.footer);
// Guild prefix
embed.addField(message.translate("administration/configuration:PREFIX_TITLE"), guildData.prefix);
// Ignored channels
embed.addField(message.translate("administration/configuration:IGNORED_CHANNELS_TITLE"), guildData.ignoredChannels.length > 0 ? guildData.ignoredChannels.map((ch) => `<#${ch}>`).join(", ") : message.translate("administration/configuration:NO_IGNORED_CHANNELS"));
// Autorole plugin
embed.addField(message.translate("administration/configuration:AUTOROLE_TITLE"), guildData.plugins.autorole.enabled ? message.translate("administration/configuration:AUTOROLE_CONTENT", {
roleName: `<@&${guildData.plugins.autorole.role}>`
}) : message.translate("administration/configuration:AUTOROLE_DISABLED"));
// Welcome plugin
embed.addField(message.translate("administration/configuration:WELCOME_TITLE"), guildData.plugins.welcome.enabled ? message.translate("administration/configuration:WELCOME_CONTENT", {
channel: `<#${guildData.plugins.welcome.channel}>`,
withImage: guildData.plugins.welcome.withImage ? message.translate("common:YES") : message.translate("common:NO")
}) : message.translate("administration/configuration:WELCOME_DISABLED"));
// Goodbye plugin
embed.addField(message.translate("administration/configuration:GOODBYE_TITLE"), guildData.plugins.goodbye.enabled ? message.translate("administration/configuration:GOODBYE_CONTENT", {
channel: `<#${guildData.plugins.goodbye.channel}>`,
withImage: guildData.plugins.goodbye.withImage ? message.translate("common:YES") : message.translate("common:NO")
}) : message.translate("administration/configuration:GOODBYE_DISABLED"));
// Special channels
embed.addField(message.translate("administration/configuration:SPECIAL_CHANNELS"),
message.translate("administration/configuration:SUGGESTIONS", {
channel: guildData.plugins.suggestions ? `<#${guildData.plugins.suggestions}>` : message.translate("common:NOT_DEFINED")
}) + "\n" +
message.translate("administration/configuration:REPORTS", {
channel: guildData.plugins.reports ? `<#${guildData.plugins.reports}>` : message.translate("common:NOT_DEFINED")
}) + "\n" +
message.translate("administration/configuration:MODLOGS", {
channel: guildData.plugins.modlogs ? `<#${guildData.plugins.modlogs}>` : message.translate("common:NOT_DEFINED")
}) + "\n" +
message.translate("administration/configuration:BIRTHDAYS", {
channel: guildData.plugins.birthdays ? `<#${guildData.plugins.birthdays}>` : message.translate("common:NOT_DEFINED")
}) + "\n" +
message.translate("administration/configuration:FORTNITESHOP", {
channel: guildData.plugins.fortniteshop ? `<#${guildData.plugins.fortniteshop}>` : message.translate("common:NOT_DEFINED")
})
);
// Auto sanctions
embed.addField(message.translate("administration/configuration:AUTO_SANCTIONS"), (guildData.plugins.warnsSanctions.kick ? message.translate("administration/configuration:KICK_CONTENT", {
count: guildData.plugins.warnsSanctions.kick
}) : message.translate("administration/configuration:KICK_NOT_DEFINED")) + "\n" + (guildData.plugins.warnsSanctions.ban ? message.translate("administration/configuration:BAN_CONTENT", {
count: guildData.plugins.warnsSanctions.ban
}) : message.translate("administration/configuration:BAN_NOT_DEFINED")));
// Automod plugin
embed.addField(message.translate("administration/configuration:AUTOMOD_TITLE"), guildData.plugins.automod.enabled ? message.translate("administration/configuration:AUTOMOD_CONTENT", {
channels: guildData.plugins.automod.ignored.map((ch) => `<#${ch}>`)
}) : message.translate("administration/configuration:AUTOMOD_DISABLED"));
// Auto-delete mod commands
embed.addField(message.translate("administration/configuration:AUTODELETEMOD"), guildData.autoDeleteModCommands ? message.translate("administration/configuration:AUTODELETEMOD_ENABLED") : message.translate("administration/configuration:AUTODELETEMOD_DISABLED"));
// Dashboard link
embed.addField(message.translate("administration/configuration:DASHBOARD_TITLE"), `[${message.translate("administration/configuration:DASHBOARD_CONTENT")}](${this.client.config.dashboard.baseURL})`);
message.channel.send(embed);
}
};
module.exports = Configuration;

View file

@ -0,0 +1,33 @@
const Command = require("../../base/Command.js");
class Delcommand extends Command {
constructor(client) {
super(client, {
name: "delcommand",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["delc"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const name = args[0];
if (!name) return message.error("administration/delcommand:MISSING_NAME");
if (!data.guild.customCommands.find((c) => c.name === name)) return message.error("administration/delcommand:UNKNOWN_COMMAND", { commandName: name });
data.guild.customCommands = data.guild.customCommands.filter((c) => c.name !== name);
data.guild.save();
message.success("administration/delcommand:SUCCESS", {
commandName: name
});
}
};
module.exports = Delcommand;

View file

@ -0,0 +1,35 @@
const Command = require("../../base/Command.js");
class Deletemod extends Command {
constructor(client) {
super(client, {
name: "deletemod",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["delm"],
memberPermissions: ["MANAGE_MESSAGES"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const status = args[0];
if (!status || status !== "on" && status !== "off") return message.error("administration/deletemod:MISSING_STATUS");
if (status === "on") {
data.guild.autoDeleteModCommands = true;
data.guild.save();
message.success("administration/deletemod:ENABLED");
} else {
data.guild.autoDeleteModCommands = false;
data.guild.save();
message.success("administration/deletemod:DISABLED");
};
}
};
module.exports = Deletemod;

View file

@ -0,0 +1,109 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Goodbye extends Command {
constructor(client) {
super(client, {
name: "goodbye",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["gb"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
if (args[0] === "test" && data.guild.plugins.goodbye.enabled) {
this.client.emit("guildMemberRemove", message.member);
return message.success("administration/goodbye:TEST_SUCCESS");
};
if ((!args[0] || !["edit", "off"].includes(args[0])) && data.guild.plugins.goodbye.enabled) return message.error("administration/goodbye:MISSING_STATUS");
if (args[0] === "off") {
data.guild.plugins.goodbye = {
enabled: false,
message: null,
channelID: null,
withImage: null
};
data.guild.markModified("plugins.goodbye");
data.guild.save();
return message.error("administration/goodbye:DISABLED", {
prefix: data.guild.prefix
});
} else {
const goodbye = {
enabled: true,
channel: null,
message: null,
withImage: null,
};
message.sendT("administration/goodbye:FORM_1", {
author: message.author.toString()
});
const collector = message.channel.createMessageCollector(m => m.author.id === message.author.id, {
time: 120000 // 2 minutes
});
collector.on("collect", async msg => {
// If the message is filled, it means the user sent yes or no for the image
if (goodbye.message) {
if (msg.content.toLowerCase() === message.translate("common:YES").toLowerCase()) {
goodbye.withImage = true;
} else if (msg.content.toLowerCase() === message.translate("common:NO").toLowerCase()) {
goodbye.withImage = false;
} else {
return message.error("misc:INVALID_YES_NO");
};
data.guild.plugins.goodbye = goodbye;
data.guild.markModified("plugins.goodbye");
await data.guild.save();
message.sendT("administration/goodbye:FORM_SUCCESS", {
prefix: data.guild.prefix,
channel: `<#${goodbye.channel}>`
});
return collector.stop();
};
// If the channel is filled and the message is not, it means the user sent the message
if (goodbye.channel && !goodbye.message) {
if (msg.content.length < 1800) {
goodbye.message = msg.content;
return message.sendT("administration/goodbye:FORM_3");
};
return message.error("administration/goodbye:MAX_CHARACT");
};
// If the channel is not filled, it means the user sent it
if (!goodbye.channel) {
const channel = await Resolvers.resolveChannel({
message: msg,
channelType: "text"
});
if (!channel) return message.error("misc:INVALID_CHANNEL");
goodbye.channel = channel.id;
message.sendT("administration/goodbye:FORM_2", {
channel: channel.toString(),
author: msg.author.tag,
memberCount: msg.guild.memberCount
});
};
});
collector.on("end", (_, reason) => {
if (reason === "time") return message.error("misc:TIMES_UP");
});
};
}
};
module.exports = Goodbye;

View file

@ -0,0 +1,41 @@
const Command = require("../../base/Command.js");
class Ignore extends Command {
constructor(client) {
super(client, {
name: "ignore",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["ig"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const channel = message.mentions.channels.filter((ch) => ch.type === "text" && ch.guild.id === message.guild.id).first();
if (!channel) return message.error("misc:INVALID_CHANNEL");
const ignored = data.guild.ignoredChannels.includes(channel.id);
if (ignored) {
data.guild.ignoredChannels = data.guild.ignoredChannels.filter((ch) => ch !== channel.id);
data.guild.save();
return message.success("administration/ignore:ALLOWED", {
channel: channel.toString()
});
} else if (!ignored) {
data.guild.ignoredChannels.push(channel.id);
data.guild.save();
return message.success("administration/ignore:IGNORED", {
channel: channel.toString()
});
};
}
};
module.exports = Ignore;

View file

@ -0,0 +1,57 @@
const Command = require("../../base/Command.js");
class Set extends Command {
constructor(client) {
super(client, {
name: "set",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: [],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const status = args[0];
if (!status || !["level", "xp", "credits", "bank"].includes(status)) return message.error("administration/set:NO_STATUS");
const member = await this.client.resolveMember(args[1], message.guild);
if (!member) return message.error("administration/set:INVALID_MEMBER");
if (member.user.bot) return message.error("administration/set:BOT_USER");
const number = args[2];
if (!number || isNaN(number) || parseInt(number, 10) < 0) return message.error("administration/set:INVALID_AMOUNT");
const amount = Math.ceil(parseInt(number, 10));
const memberData = await this.client.findOrCreateMember({
id: member.id,
guildID: message.guild.id
});
if (status === "level") {
memberData.level = parseInt(amount, 10);
memberData.save();
} else if (status === "xp") {
memberData.exp = parseInt(amount, 10);
memberData.save();
} else if (status === "credits") {
memberData.money = parseInt(amount, 10);
memberData.save();
} else if (status === "bank") {
memberData.bankSold = parseInt(amount, 10);
memberData.save();
}
message.success("administration/set:SUCCESS_" + status.toUpperCase(), {
username: member.user.tag,
amount
});
}
};
module.exports = Set;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Setbirthdays extends Command {
constructor(client) {
super(client, {
name: "setbirthdays",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setb"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const areBirthdaysEnabled = Boolean(data.guild.plugins.birthdays);
const sentChannel = await Resolvers.resolveChannel({
message,
search: args.join(" "),
channelType: "text"
});
if (!sentChannel && areBirthdaysEnabled) {
data.guild.plugins.birthdays = null;
data.guild.markModified("plugins.birthdays");
await data.guild.save();
return message.success("administration/setbirthdays:DISABLED");
} else {
const channel = sentChannel || message.channel;
data.guild.plugins.birthdays = channel.id;
data.guild.markModified("plugins.birthdays");
await data.guild.save();
return message.success("administration/setbirthdays:ENABLED", {
channel: channel.toString()
});
};
}
};
module.exports = Setbirthdays;

View file

@ -0,0 +1,74 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js"),
Canvas = require("discord-canvas");
class Setfortniteshop extends Command {
constructor(client) {
super(client, {
name: "setfortniteshop",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setfnshop"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
if (!data.config.apiKeys.fortniteFNBR || data.config.apiKeys.fortniteFNBR.length === "") return message.error("misc:COMMAND_DISABLED");
if (data.guild.plugins.fortniteshop && !message.mentions.channels.first() || message.mentions.channels.first() && data.guild.plugins.fortniteshop === message.mentions.channels.first().id) {
data.guild.plugins.fortniteshop = false;
data.guild.markModified("plugins.fortniteshop");
data.guild.save();
return message.success("administration/setfortniteshop:DISABLED");
};
const channel = message.mentions.channels.first() || message.channel;
data.guild.plugins.fortniteshop = channel.id;
data.guild.markModified("plugins.fortniteshop");
data.guild.save();
message.success("administration/setfortniteshop:ENABLED", {
channel: channel.toString()
});
const momentName = this.client.languages.find((language) => language.name === data.guild.language || language.aliases.includes(data.guild.language)).moment;
const shop = new Canvas.FortniteShop();
const image = await shop
.setToken(data.config.apiKeys.fortniteFNBR)
.setText("header", message.translate("general/fortniteshop:HEADER"))
.setText("daily", message.translate("general/fortniteshop:DAILY"))
.setText("featured", message.translate("general/fortniteshop:FEATURED"))
.setText("date", message.translate("general/fortniteshop:DATE", {
skipInterpolation: true
}).replace("{{date}}", "{date}"))
.setText("footer", message.translate("general/fortniteshop:FOOTER"))
.lang(momentName)
.toAttachment();
const attachment = new Discord.MessageAttachment(image, "shop.png");
const embed = new Discord.MessageEmbed()
.setAuthor(this.client.translate("general/fortniteshop:DATE", {
date: this.client.printDate(new Date(Date.now()), null, message.guild.data.language)
}, message.guild.data.language), this.client.user.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}))
.attachFiles(attachment)
.setImage("attachment://shop.png")
.setColor(this.client.config.embed.color)
.setFooter(this.client.config.embed.footer);
const msg = await channel.send(embed);
await msg.react("😍");
await msg.react("😐");
await msg.react("😭");
}
};
module.exports = Setfortniteshop;

View file

@ -0,0 +1,33 @@
const Command = require("../../base/Command.js");
class Setlang extends Command {
constructor(client) {
super(client, {
name: "setlang",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setl"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const language = this.client.languages.find((l) => l.name === args[0] || l.aliases.includes(args[0]));
if (!args[0] || !language) return message.error("administration/setlang:MISSING_LANG", { list: this.client.languages.map((l) => `\`${l.name}\``).join(", ") });
data.guild.language = language.name;
await data.guild.save();
return message.sendT("administration/setlang:SUCCESS", {
lang: language.nativeName
});
}
};
module.exports = Setlang;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Setmodlogs extends Command {
constructor(client) {
super(client, {
name: "setmodlogs",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setm"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const areModLogsEnabled = Boolean(data.guild.plugins.modlogs);
const sentChannel = await Resolvers.resolveChannel({
message,
search: args.join(" "),
channelType: "text"
});
if (!sentChannel && areModLogsEnabled) {
data.guild.plugins.modlogs = null;
data.guild.markModified("plugins.modlogs");
await data.guild.save();
return message.success("administration/setmodlogs:DISABLED");
} else {
const channel = sentChannel || message.channel;
data.guild.plugins.modlogs = channel.id;
data.guild.markModified("plugins.modlogs");
await data.guild.save();
return message.success("administration/setmodlogs:ENABLED", {
channel: channel.toString()
});
};
}
};
module.exports = Setmodlogs;

View file

@ -0,0 +1,33 @@
const Command = require("../../base/Command.js");
class Setprefix extends Command {
constructor(client) {
super(client, {
name: "setprefix",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setp"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const prefix = args[0];
if (!prefix) return message.error("administration/setprefix:MISSING_PREFIX");
if (prefix.length > 5) return message.error("administration/setprefix:TOO_LONG");
data.guild.prefix = prefix;
data.guild.save();
return message.success("administration/setprefix:SUCCESS", {
prefix
});
}
};
module.exports = Setprefix;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Setreports extends Command {
constructor(client) {
super(client, {
name: "setreports",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setr"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const areReportsEnabled = Boolean(data.guild.plugins.reports);
const sentChannel = await Resolvers.resolveChannel({
message,
search: args.join(" "),
channelType: "text"
});
if (!sentChannel && areReportsEnabled) {
data.guild.plugins.reports = null;
data.guild.markModified("plugins.reports");
await data.guild.save();
return message.success("administration/setreports:DISABLED");
} else {
const channel = sentChannel || message.channel;
data.guild.plugins.reports = channel.id;
data.guild.markModified("plugins.reports");
await data.guild.save();
return message.success("administration/setreports:ENABLED", {
channel: channel.toString()
});
};
}
};
module.exports = Setreports;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Setsuggests extends Command {
constructor(client) {
super(client, {
name: "setsuggests",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["setsu"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const areSuggestsEnabled = Boolean(data.guild.plugins.suggestions);
const sentChannel = await Resolvers.resolveChannel({
message,
search: args.join(" "),
channelType: "text"
});
if (!sentChannel && areSuggestsEnabled) {
data.guild.plugins.suggestions = null;
data.guild.markModified("plugins.suggestions");
await data.guild.save();
return message.success("administration/setsuggests:DISABLED");
} else {
const channel = sentChannel || message.channel;
data.guild.plugins.suggestions = channel.id;
data.guild.markModified("plugins.suggestions");
await data.guild.save();
return message.success("administration/setsuggests:ENABLED", {
channel: channel.toString()
});
};
}
};
module.exports = Setsuggests;

View file

@ -0,0 +1,54 @@
const Command = require("../../base/Command.js"),
ms = require("ms");
class Slowmode extends Command {
constructor(client) {
super(client, {
name: "slowmode",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["sl"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const channel = message.mentions.channels.filter((ch) => ch.type === "text" && ch.guild.id === message.guild.id).first();
if (!channel) return message.error("misc:INVALID_CHANNEL");
const time = args[1];
if (!time) {
if (!data.guild.slowmode.channels.find((ch) => ch.id === channel.id)) return message.error("misc:INVALID_TIME");
data.guild.slowmode.channels = data.guild.slowmode.channels.filter((ch) => ch.id !== channel.id);
data.guild.markModified("slowmode.channels");
data.guild.save();
message.success("administration/slowmode:DISABLED", {
prefix: data.guild.prefix,
channel: `#${channel.name}`
});
} else {
if (isNaN(ms(time))) return message.error("misc:INVALID_TIME");
if (data.guild.slowmode.channels.find((ch) => ch.id === channel.id)) data.guild.slowmode.channels = data.guild.slowmode.channels.filter((ch) => ch.id !== channel.id);
data.guild.slowmode.channels.push({
id: channel.id,
time: ms(time)
});
data.guild.markModified("slowmode.channels");
data.guild.save();
message.success("administration/slowmode:ENABLED", {
prefix: data.guild.prefix,
channel: `#${channel.name}`,
time: this.client.functions.convertTime(message.guild, ms(time))
});
};
}
};
module.exports = Slowmode;

View file

@ -0,0 +1,110 @@
const Command = require("../../base/Command.js"),
Resolvers = require("../../helpers/resolvers");
class Welcome extends Command {
constructor(client) {
super(client, {
name: "welcome",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["welc"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
if (args[0] === "test" && data.guild.plugins.welcome.enabled) {
this.client.emit("guildMemberAdd", message.member);
return message.success("administration/welcome:TEST_SUCCESS");
};
if ((!args[0] || !["edit", "off"].includes(args[0])) && data.guild.plugins.welcome.enabled) return message.error("administration/welcome:MISSING_STATUS");
if (args[0] === "off") {
data.guild.plugins.welcome = {
enabled: false,
message: null,
channelID: null,
withImage: null
};
data.guild.markModified("plugins.welcome");
data.guild.save();
return message.error("administration/welcome:DISABLED", {
prefix: data.guild.prefix
});
} else {
const welcome = {
enabled: true,
channel: null,
message: null,
withImage: null,
};
message.sendT("administration/welcome:FORM_1", {
author: message.author.toString()
});
const collector = message.channel.createMessageCollector(m => m.author.id === message.author.id, {
time: 120000 // 2 minutes
});
collector.on("collect", async msg => {
// If the message is filled, it means the user sent yes or no for the image
if (welcome.message) {
if (msg.content.toLowerCase() === message.translate("common:YES").toLowerCase()) {
welcome.withImage = true;
} else if (msg.content.toLowerCase() === message.translate("common:NO").toLowerCase()) {
welcome.withImage = false;
} else {
return message.error("misc:INVALID_YES_NO");
};
data.guild.plugins.welcome = welcome;
data.guild.markModified("plugins.welcome");
await data.guild.save();
message.sendT("administration/welcome:FORM_SUCCESS", {
prefix: data.guild.prefix,
channel: `<#${welcome.channel}>`
});
return collector.stop();
};
// If the channel is filled and the message is not, it means the user sent the message
if (welcome.channel && !welcome.message) {
if (msg.content.length < 1800) {
welcome.message = msg.content;
return message.sendT("administration/welcome:FORM_3");
};
return message.error("administration/goodbye:MAX_CHARACT");
};
// If the channel is not filled, it means the user sent it
if (!welcome.channel) {
const channel = await Resolvers.resolveChannel({
message: msg,
channelType: "text"
});
if (!channel) return message.error("misc:INVALID_CHANNEL");
welcome.channel = channel.id;
message.sendT("administration/welcome:FORM_2", {
guildName: message.guild.name,
author: msg.author.tag,
memberCount: msg.guild.memberCount
});
};
});
collector.on("end", (_, reason) => {
if (reason === "time") {
return message.error("misc:TIMES_UP");
};
});
};
}
};
module.exports = Welcome;

View file

@ -0,0 +1,66 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Achievements extends Command {
constructor(client) {
super(client, {
name: "achievements",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["ac"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("economy/achievements:TITLE"))
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer);
embed.addField(message.translate("economy/achievements:SEND_CMD"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.firstCommand.progress.now,
total: data.userData.achievements.firstCommand.progress.total,
percent: Math.round(100 * (data.userData.achievements.firstCommand.progress.now / data.userData.achievements.firstCommand.progress.total))
}));
embed.addField(message.translate("economy/achievements:CLAIM_SALARY"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.work.progress.now,
total: data.userData.achievements.work.progress.total,
percent: Math.round(100 * (data.userData.achievements.work.progress.now / data.userData.achievements.work.progress.total))
}));
embed.addField(message.translate("economy/achievements:MARRY"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.married.progress.now,
total: data.userData.achievements.married.progress.total,
percent: Math.round(100 * (data.userData.achievements.married.progress.now / data.userData.achievements.married.progress.total))
}));
embed.addField(message.translate("economy/achievements:SLOTS"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.slots.progress.now,
total: data.userData.achievements.slots.progress.total,
percent: Math.round(100 * (data.userData.achievements.slots.progress.now / data.userData.achievements.slots.progress.total))
}));
embed.addField(message.translate("economy/achievements:TIP"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.tip.progress.now,
total: data.userData.achievements.tip.progress.total,
percent: Math.round(100 * (data.userData.achievements.tip.progress.now / data.userData.achievements.tip.progress.total))
}));
embed.addField(message.translate("economy/achievements:REP"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.rep.progress.now,
total: data.userData.achievements.rep.progress.total,
percent: Math.round(100 * (data.userData.achievements.rep.progress.now / data.userData.achievements.rep.progress.total))
}));
embed.addField(message.translate("economy/achievements:INVITE"), message.translate("economy/achievements:PROGRESS", {
now: data.userData.achievements.invite.progress.now,
total: data.userData.achievements.invite.progress.total,
percent: Math.round(100 * (data.userData.achievements.invite.progress.now / data.userData.achievements.invite.progress.total))
}));
message.channel.send(embed);
}
};
module.exports = Achievements;

View file

@ -0,0 +1,49 @@
const Command = require("../../base/Command.js");
class Birthdate extends Command {
constructor(client) {
super(client, {
name: "birthdate",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["bd"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const date = args[0];
if (!date) return message.error("economy/birthdate:MISSING_DATE");
const tArgs = date.split("/");
const [day, month, year] = tArgs;
if (!day || !month || !year) return message.error("economy/birthdate:INVALID_DATE");
// Gets the string of the date
const match = date.match(/\d+/g);
if (!match) return message.error("economy/birthdate:INVALID_DATE");
const tday = +match[0],
tmonth = +match[1] - 1;
let tyear = +match[2];
if (tyear < 100) tyear += tyear < 50 ? 2000 : 1900;
const d = new Date(tyear, tmonth, tday);
if (!(tday == d.getDate() && tmonth == d.getMonth() && tyear == d.getFullYear())) return message.error("economy/birthdate:INVALID_DATE");
if (d.getTime() > Date.now()) return message.error("economy/birthdate:DATE_TOO_HIGH");
if (d.getTime() < (Date.now() - 2.523e+12)) return message.error("economy/birthdate:DATE_TOO_LOW");
data.userData.birthdate = d;
data.userData.save();
message.success("economy/birthdate:SUCCESS", {
date: message.printDate(d)
});
}
};
module.exports = Birthdate;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js");
class Deposit extends Command {
constructor(client) {
super(client, {
name: "deposit",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["bank", "dep"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
let amount = args[0];
if (!(parseInt(data.memberData.money, 10) > 0)) return message.error("economy/deposit:NO_CREDIT");
if (args[0] === "all") {
amount = parseInt(data.memberData.money, 10);
} else {
if (isNaN(amount) || parseInt(amount, 10) < 1) return message.error("economy/deposit:MISSING_AMOUNT");
amount = parseInt(amount, 10);
};
if (data.memberData.money < amount) return message.error("economy/deposit:NOT_ENOUGH_CREDIT", {
money: `**${amount}** ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
data.memberData.money = data.memberData.money - amount;
data.memberData.bankSold = data.memberData.bankSold + amount;
data.memberData.save();
message.success("economy/deposit:SUCCESS", {
money: `**${amount}** ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
}
};
module.exports = Deposit;

View file

@ -0,0 +1,39 @@
const Command = require("../../base/Command.js");
class Divorce extends Command {
constructor(client) {
super(client, {
name: "divorce",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["di"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (!data.userData.lover) return message.error("economy/divorce:NOT_MARRIED");
const user = this.client.users.cache.get(data.userData.lover) || await this.client.users.fetch(data.userData.lover);
data.userData.lover = null;
data.userData.save();
const oldLover = await this.client.findOrCreateUser({
id: user.id
});
oldLover.lover = null;
oldLover.save();
message.success("economy/divorce:DIVORCED", {
username: user.username
});
}
};
module.exports = Divorce;

View file

@ -0,0 +1,91 @@
const Command = require("../../base/Command.js"),
AsciiTable = require("ascii-table");
class Leaderboard extends Command {
constructor(client) {
super(client, {
name: "leaderboard",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["lb"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args) {
const isOnlyOnMobile = (message.author.presence.clientStatus ? JSON.stringify(Object.keys(message.author.presence.clientStatus)) === JSON.stringify(["mobile"]) : false);
const type = args[0];
if (!type || (type !== "credits" && type !== "level" && type !== "rep")) return message.error("economy/leaderboard:MISSING_TYPE");
if (type === "credits") {
const members = await this.client.membersData.find({
guildID: message.guild.id
}).lean(),
membersLeaderboard = members.map((m) => {
return {
id: m.id,
value: m.money + m.bankSold
};
}).sort((a, b) => b.value - a.value);
const table = new AsciiTable("Таблица лидеров");
table.setHeading("#", message.translate("common:USER"), message.translate("common:CREDITS"));
if (membersLeaderboard.length > 20) membersLeaderboard.length = 20;
const newTable = await fetchUsers(membersLeaderboard, table, this.client);
message.channel.send(`\`\`\`\n${newTable.toString()}\`\`\``);
} else if (type === "level") {
const members = await this.client.membersData.find({
guildID: message.guild.id
}).lean(),
membersLeaderboard = members.map((m) => {
return {
id: m.id,
value: m.level
};
}).sort((a, b) => b.value - a.value);
const table = new AsciiTable("Таблица лидеров");
table.setHeading("#", message.translate("common:USER"), message.translate("common:LEVEL"));
if (membersLeaderboard.length > 20) membersLeaderboard.length = 20;
const newTable = await fetchUsers(membersLeaderboard, table, this.client);
message.channel.send(`\`\`\`\n${newTable.toString()}\`\`\``);
} else if (type === "rep") {
const users = await this.client.usersData.find().lean(),
usersLeaderboard = users.map((u) => {
return {
id: u.id,
value: u.rep
};
}).sort((a, b) => b.value - a.value);
const table = new AsciiTable("Таблица лидеров");
table.setHeading("#", message.translate("common:USER"), message.translate("common:POINTS"));
if (usersLeaderboard.length > 20) usersLeaderboard.length = 20;
const newTable = await fetchUsers(usersLeaderboard, table, this.client);
message.channel.send(`\`\`\`\n${newTable.toString()}\`\`\``);
};
if (isOnlyOnMobile) message.sendT("economy/leaderboard:MOBILE");
}
};
module.exports = Leaderboard;
async function fetchUsers(array, table, client) {
return new Promise((resolve) => {
let index = 1;
array.forEach((element) => {
client.users.fetch(element.id).then((user) => {
const regEx = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
let username = user.username.replace(regEx, "");
if (username.length > 20) username = username.substr(0, 20);
table.addRow(index++, username, element.value);
});
});
resolve(table);
});
};

145
commands/Economy/marry.js Normal file
View file

@ -0,0 +1,145 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
const pendings = {};
class Marry extends Command {
constructor(client) {
super(client, {
name: "marry",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: [],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
// if the message author is already wedded
if (data.userData.lover) return message.error("economy/marry:ALREADY_MARRIED", {
prefix: data.guild.prefix
});
// Gets the first mentionned member
const member = await this.client.resolveMember(args[0], message.guild);
if (!member) return message.error("economy/marry:INVALID_MEMBER");
const userData = await this.client.findOrCreateUser({
id: member.id
});
// if the member is already wedded
if (userData.lover) return message.error("economy/marry:ALREADY_MARRIED_USER", {
username: member.user.tag
});
if (member.user.bot) return message.error("economy/marry:BOT_USER");
if (member.id === message.author.id) return message.error("economy/marry:YOURSELF");
for (const requester in pendings) {
const receiver = pendings[requester];
// If the member already sent a request to someone
if (requester === message.author.id) {
const user = this.client.users.cache.get(receiver) || await this.client.users.fetch(receiver);
return message.error("economy/marry:REQUEST_AUTHOR_TO_AMEMBER", {
username: user.tag
});
} else if (receiver === message.author.id) { // If there is a pending request for this member
const user = this.client.users.cache.get(requester) || await this.client.users.fetch(requester);
return message.error("economy/marry:REQUEST_AMEMBER_TO_AUTHOR", {
username: user.tag
});
} else if (requester === member.id) { // If the asked member has sent pending request
const user = this.client.users.cache.get(receiver) || await this.client.users.fetch(receiver);
return message.error("economy/marry:REQUEST_AMEMBER_TO_MEMBER", {
firstUsername: member.user.tag,
secondUsername: user.tag
});
} else if (receiver === member.id) { // If there is a pending request for the asked member
const user = this.client.users.cache.get(requester) || await this.client.users.fetch(requester);
return message.error("economy/marry:REQUEST_MEMBER_TO_AMEMBER", {
firstUsername: member.user.tag,
secondUsername: user.tag
});
};
};
// Update pending requests
pendings[message.author.id] = member.id;
message.sendT("economy/marry:REQUEST", {
from: message.author.toString(),
to: member.user.toString()
});
const collector = new Discord.MessageCollector(message.channel, (m) => m.author.id === member.id, {
time: 120000
});
collector.on("collect", (msg) => {
if (msg.content.toLowerCase() === message.translate("common:YES").toLowerCase()) {
return collector.stop(true);
} else if (msg.content.toLowerCase() === message.translate("common:NO").toLowerCase()) {
return collector.stop(false);
} else {
return message.error("misc:INVALID_YES_NO");
};
});
collector.on("end", async (_collected, reason) => {
// Delete pending request
delete pendings[message.author.id];
if (reason === "time") {
return message.error("misc:TIMES_UP", {
username: member.user.toString()
});
};
if (reason) {
data.userData.lover = member.id;
await data.userData.save();
userData.lover = message.author.id;
await userData.save();
const messageOptions = {
content: `${member.toString()} :heart: ${message.author.toString()}`,
files: [{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked3.png"
}]
};
let sent = false;
if (!userData.achievements.married.achieved) {
message.channel.send(messageOptions);
sent = true;
userData.achievements.married.achieved = true;
userData.achievements.married.progress.now = 1;
userData.markModified("achievements.married");
userData.save();
};
if (!data.userData.achievements.married.achieved) {
if (!sent) message.channel.send(messageOptions);
data.userData.achievements.married.achieved = true;
data.userData.achievements.married.progress.now = 1;
data.userData.markModified("achievements.married");
data.userData.save();
};
return message.success("economy/marry:SUCCESS", {
creator: message.author.toString(),
partner: member.user.toString()
});
} else {
return message.success("economy/marry:DENIED", {
creator: message.author.toString(),
partner: member.user.toString()
});
};
});
}
};
module.exports = Marry;

66
commands/Economy/money.js Normal file
View file

@ -0,0 +1,66 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
const asyncForEach = async (array, callback) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
};
};
class Credits extends Command {
constructor(client) {
super(client, {
name: "money",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["credits", "balance", "mon"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
let member = await this.client.resolveMember(args[0], message.guild);
if (!member) member = message.member;
const user = member.user;
if (user.bot) return message.error("misc:BOT_USER");
const memberData = (message.author === user) ? data.memberData : await this.client.findOrCreateMember({
id: user.id,
guildID: message.guild.id
});
const commonsGuilds = this.client.guilds.cache.filter((g) => g.members.cache.get(user.id));
let globalMoney = 0;
await asyncForEach(commonsGuilds.array(), async (guild) => {
const memberData = await this.client.findOrCreateMember({
id: user.id,
guildID: guild.id
});
globalMoney += memberData.money;
globalMoney += memberData.bankSold;
});
const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("economy/money:TITLE", {
username: member.user.username
}), member.user.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}))
.addField(message.translate("economy/profile:CASH"), `**${memberData.money}** ${message.getNoun(memberData.money, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
.addField(message.translate("economy/profile:BANK"), `**${memberData.bankSold}** ${message.getNoun(memberData.bankSold, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
.addField(message.translate("economy/profile:GLOBAL"), `**${globalMoney}** ${message.getNoun(globalMoney, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
.setColor(this.client.config.embed.color)
.setFooter(this.client.config.embed.footer);
message.channel.send(embed);
}
};
module.exports = Credits;

51
commands/Economy/pay.js Normal file
View file

@ -0,0 +1,51 @@
const Command = require("../../base/Command.js");
class Pay extends Command {
constructor(client) {
super(client, {
name: "pay",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: [],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const member = await this.client.resolveMember(args[0], message.guild);
if (!member) return message.error("economy/pay:INVALID_MEMBER");
if (member.user.bot) return message.error("economy/pay:BOT_USER");
if (member.id === message.author.id) return message.error("economy/pay:YOURSELF");
const sentAmount = args[1];
if (!sentAmount || isNaN(sentAmount) || parseInt(sentAmount, 10) <= 0) return message.error("economy/pay:INVALID_AMOUNT", { username: member.user.tag });
const amount = Math.ceil(parseInt(sentAmount, 10));
if (amount > data.memberData.money) return message.error("economy/pay:ENOUGH_MONEY", {
amount: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:CREDITS:1"), message.translate("misc:NOUNS:CREDITS:2"), message.translate("misc:NOUNS:CREDITS:5"))}`
});
const memberData = await this.client.findOrCreateMember({
id: member.id,
guildID: message.guild.id
});
data.memberData.money = data.memberData.money - parseInt(amount, 10);
data.memberData.save();
memberData.money = memberData.money + parseInt(amount, 10);
memberData.save();
message.success("economy/pay:SUCCESS", {
amount: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
username: member.user.tag
});
}
};
module.exports = Pay;

View file

@ -0,0 +1,88 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
const asyncForEach = async (array, callback) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
};
};
class Profile extends Command {
constructor(client) {
super(client, {
name: "profile",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["prof"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const client = this.client;
const arg = args[0] || message.author
let member = await client.resolveMember(arg, message.guild);
if (!member) member = message.member;
if (member.user.bot) return message.error("economy/profile:BOT_USER");
const memberData = (member.id === message.author.id ? data.memberData : await client.findOrCreateMember({
id: member.id,
guildID: message.guild.id
}));
const userData = (member.id === message.author.id ? data.userData : await client.findOrCreateUser({
id: member.id
}));
if (userData.lover && !this.client.users.cache.get(userData.lover)) await this.client.users.fetch(userData.lover, true);
const commonsGuilds = client.guilds.cache.filter((g) => g.members.cache.get(member.id));
let globalMoney = 0;
await asyncForEach(commonsGuilds.array(), async (guild) => {
const memberData = await client.findOrCreateMember({
id: member.id,
guildID: guild.id
});
globalMoney += memberData.money;
globalMoney += memberData.bankSold;
});
const profileEmbed = new Discord.MessageEmbed()
.setAuthor(message.translate("economy/profile:TITLE", {
username: member.user.tag
}), member.user.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}))
.attachFiles([{
attachment: await userData.getAchievements(),
name: "achievements.png"
}])
.setImage("attachment://achievements.png")
.addField(message.translate("economy/profile:BIO"), userData.bio ? userData.bio : message.translate("economy/profile:NO_BIO"))
.addField(message.translate("economy/profile:CASH"), `**${memberData.money}** ${message.getNoun(memberData.money, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
.addField(message.translate("economy/profile:BANK"), `**${memberData.bankSold}** ${message.getNoun(memberData.bankSold, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
.addField(message.translate("economy/profile:GLOBAL"), `**${globalMoney}** ${message.getNoun(globalMoney, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
.addField(message.translate("economy/profile:REPUTATION"), `**${userData.rep}** ${message.getNoun(userData.rep, message.translate("misc:NOUNS:POINTS:1"), message.translate("misc:NOUNS:POINTS:2"), message.translate("misc:NOUNS:POINTS:5"))}`, true)
.addField(message.translate("economy/profile:LEVEL"), `**${memberData.level}**`, true)
.addField(message.translate("economy/profile:EXP"), `**${memberData.exp}/${5 * (memberData.level * memberData.level) + 80 * memberData.level + 100}** xp`, true)
.addField(message.translate("economy/profile:REGISTERED"), message.printDate(new Date(memberData.registeredAt)), true)
.addField(message.translate("economy/profile:BIRTHDATE"), (!userData.birthdate ? message.translate("economy/profile:NO_BIRTHDATE") : message.printDate(new Date(userData.birthdate))), true)
.addField(message.translate("economy/profile:LOVER"), (!userData.lover ? message.translate("economy/profile:NO_LOVER") : this.client.users.cache.get(userData.lover).tag), true)
.addField(message.translate("economy/profile:ACHIEVEMENTS"), message.translate("economy/profile:ACHIEVEMENTS_CONTENT", {
prefix: data.guild.prefix
}))
.setColor(data.config.embed.color) // Sets the color of the embed
.setFooter(data.config.embed.footer) // Sets the footer of the embed
.setTimestamp();
message.channel.send(profileEmbed); // Send the embed in the current channel
}
};
module.exports = Profile;

70
commands/Economy/rep.js Normal file
View file

@ -0,0 +1,70 @@
const Command = require("../../base/Command.js");
class Rep extends Command {
constructor(client) {
super(client, {
name: "rep",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["reputation"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
// if the member is already in the cooldown db
const isInCooldown = (data.userData.cooldowns || {
rep: 0
}).rep;
if (isInCooldown) {
/*if the timestamp recorded in the database indicating
when the member will be able to execute the order again
is greater than the current date, display an error message */
if (isInCooldown > Date.now()) return message.error("economy/rep:COOLDOWN", {
time: message.convertTime(isInCooldown, "to", true)
});
};
const user = await this.client.resolveUser(args[0]);
if (!user) return message.error("economy/rep:INVALID_USER");
if (user.bot) return message.error("economy/rep:BOT_USER");
if (user.id === message.author.id) return message.error("economy/rep:YOURSELF");
// Records in the database the time when the member will be able to execute the command again (in 12 hours)
const toWait = Date.now() + 21600000;
data.userData.cooldowns = {};
data.userData.cooldowns.rep = toWait;
data.userData.markModified("cooldowns");
data.userData.save();
const userData = await this.client.findOrCreateUser({
id: user.id
});
userData.rep++;
if (!userData.achievements.rep.achieved) {
userData.achievements.rep.progress.now = (userData.rep > userData.achievements.rep.progress.total ? userData.achievements.rep.progress.total : userData.rep);
if (userData.achievements.rep.progress.now >= userData.achievements.rep.progress.total) {
userData.achievements.rep.achieved = true;
message.channel.send({
files: [{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked6.png"
}]
});
};
userData.markModified("achievements.rep");
};
await userData.save();
message.success("economy/rep:SUCCESS", {
username: user.username
});
}
};
module.exports = Rep;

85
commands/Economy/rob.js Normal file
View file

@ -0,0 +1,85 @@
const Command = require("../../base/Command.js");
class Rob extends Command {
constructor(client) {
super(client, {
name: "rob",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["steal"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const member = await this.client.resolveMember(args[0], message.guild);
if (!member) return message.error("economy/rob:MISSING_MEMBER");
if (member.id === message.author.id) return message.error("economy/rob:YOURSELF");
const memberData = await this.client.findOrCreateMember({
id: member.id,
guildID: message.guild.id
});
const isInCooldown = memberData.cooldowns.rob || 0;
if (isInCooldown) {
if (isInCooldown > Date.now()) return message.error("economy/rob:COOLDOWN", {
username: member.user.tag
});
};
let amountToRob = args[1];
if (!amountToRob || isNaN(amountToRob) || parseInt(amountToRob, 10) <= 0) return message.error("economy/rob:MISSING_AMOUNT", {
username: member.user.username
});
amountToRob = Math.floor(parseInt(amountToRob, 10));
if (amountToRob > memberData.money) return message.error("economy/rob:NOT_ENOUGH_MEMBER", {
username: member.user.username
});
const potentiallyLose = Math.floor(amountToRob * 1.5);
if (potentiallyLose > data.memberData.money) return message.error("economy/rob:NOT_ENOUGH_AUTHOR", {
moneyMin: `${potentiallyLose} ${message.getNoun(potentiallyLose, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
moneyCurrent: `${data.memberData.money} ${message.getNoun(data.memberData.money, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
const itsAWon = Math.floor(this.client.functions.randomNum(0, 100) < 25);
if (itsAWon) {
const toWait = Date.now() + 6 * (60 * 60000);
memberData.cooldowns.rob = toWait;
memberData.markModified("cooldowns");
await memberData.save();
const randomNum = Math.floor(this.client.functions.randomNum(1, 3));
message.sendT("economy/rob:ROB_WON_" + randomNum, {
money: `${amountToRob} ${message.getNoun(amountToRob, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
username: member.user.username
});
data.memberData.money += amountToRob;
memberData.money -= amountToRob, 10;
memberData.save();
data.memberData.save();
} else {
const won = Math.floor(0.9 * amountToRob);
const randomNum = Math.floor(this.client.functions.randomNum(1, 3));
message.sendT("economy/rob:ROB_LOSE_" + randomNum, {
fine: `${potentiallyLose} ${message.getNoun(potentiallyLose, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
offset: `${won} ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
username: member.user.username
});
data.memberData.money -= potentiallyLose;
memberData.money += won;
memberData.save();
data.memberData.save();
};
}
};
module.exports = Rob;

View file

@ -0,0 +1,30 @@
const Command = require("../../base/Command.js");
class Setbio extends Command {
constructor(client) {
super(client, {
name: "setbio",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["biography", "setdesc", "sb"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const newBio = args.join(" ");
if (!newBio) return message.error("economy/setbio:MISSING");
if (newBio.length > 100) return message.error("economy/setbio:MAX_CHARACT");
data.userData.bio = newBio;
message.success("economy/setbio:SUCCESS");
await data.userData.save();
}
};
module.exports = Setbio;

171
commands/Economy/slots.js Normal file
View file

@ -0,0 +1,171 @@
const Command = require("../../base/Command.js");
class Slots extends Command {
constructor(client) {
super(client, {
name: "slots",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["casino", "slot"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const fruits = ["🍎", "🍐", "🍌", "🍇", "🍉", "🍒", "🍓"];
let i1 = 0, j1 = 0, k1 = 0,
i2 = 1, j2 = 1, k2 = 1,
i3 = 2, j3 = 2, k3 = 2;
// Gets three random fruits array
const colonnes = [
this.client.functions.shuffle(fruits),
this.client.functions.shuffle(fruits),
this.client.functions.shuffle(fruits)
];
// Gets the amount provided
let amount = args[0];
if (!amount || isNaN(amount) || amount < 1) amount = 50;
if (amount > data.memberData.money) return message.error("economy/slots:NOT_ENOUGH", {
money: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
amount = Math.round(amount);
function getCredits(number, isJackpot) {
if (!isJackpot) number = number * 1.5;
else if (isJackpot) number = number * 4;
return Math.round(number);
};
const tmsg = await message.sendT("misc:PLEASE_WAIT", null, {
prefixEmoji: "loading"
});
editMsg();
const interval = setInterval(editMsg, 1000);
setTimeout(() => {
clearInterval(interval);
end(tmsg);
}, 4000);
async function end() {
let msg = "[ :slot_machine: | **СЛОТЫ** ]\n------------------\n";
i1 = (i1 < fruits.length - 1) ? i1 + 1 : 0;
i2 = (i2 < fruits.length - 1) ? i2 + 1 : 0;
i3 = (i3 < fruits.length - 1) ? i3 + 1 : 0;
j1 = (j1 < fruits.length - 1) ? j1 + 1 : 0;
j2 = (j2 < fruits.length - 1) ? j2 + 1 : 0;
j3 = (j3 < fruits.length - 1) ? j3 + 1 : 0;
k1 = (k1 < fruits.length - 1) ? k1 + 1 : 0;
k2 = (k2 < fruits.length - 1) ? k2 + 1 : 0;
k3 = (k3 < fruits.length - 1) ? k3 + 1 : 0;
msg += colonnes[0][i1] + " : " + colonnes[1][j1] + " : " + colonnes[2][k1] + "\n";
msg += colonnes[0][i2] + " : " + colonnes[1][j2] + " : " + colonnes[2][k2] + " **<**\n";
msg += colonnes[0][i3] + " : " + colonnes[1][j3] + " : " + colonnes[2][k3] + "\n------------------\n";
if ((colonnes[0][i2] == colonnes[1][j2]) && (colonnes[1][j2] == colonnes[2][k2])) {
msg += "| : : : **" + (message.translate("common:VICTORY").toUpperCase()) + "** : : : |";
tmsg.edit(msg);
const credits = getCredits(amount, true);
message.channel.send("**!! ДЖЕКПОТ !!**\n" + message.translate("economy/slots:VICTORY", {
money: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
won: `${credits} ${message.getNoun(credits, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
username: message.author.username
}));
const toAdd = credits - amount;
data.memberData.money = data.memberData.money + toAdd;
if (!data.userData.achievements.slots.achieved) {
data.userData.achievements.slots.progress.now += 1;
if (data.userData.achievements.slots.progress.now === data.userData.achievements.slots.progress.total) {
data.userData.achievements.slots.achieved = true;
message.channel.send({
files: [{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked4.png"
}]
});
};
data.userData.markModified("achievements.slots");
await data.userData.save();
};
await data.memberData.save();
return;
};
if (colonnes[0][i2] == colonnes[1][j2] || colonnes[1][j2] == colonnes[2][k2] || colonnes[0][i2] == colonnes[2][k2]) {
msg += "| : : : **" + (message.translate("common:VICTORY").toUpperCase()) + "** : : : |";
tmsg.edit(msg);
const credits = getCredits(amount, false);
message.channel.send(message.translate("economy/slots:VICTORY", {
money: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
won: `${credits} ${message.getNoun(credits, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
username: message.author.username
}));
const toAdd = credits - amount;
data.memberData.money = data.memberData.money + toAdd;
if (!data.userData.achievements.slots.achieved) {
data.userData.achievements.slots.progress.now += 1;
if (data.userData.achievements.slots.progress.now === data.userData.achievements.slots.progress.total) {
data.userData.achievements.slots.achieved = true;
message.channel.send({
files: [{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked4.png"
}]
});
};
data.userData.markModified("achievements.slots");
await data.userData.save();
};
await data.memberData.save();
return;
};
msg += "| : : : **" + (message.translate("common:DEFEAT").toUpperCase()) + "** : : : |";
message.channel.send(message.translate("economy/slots:DEFEAT", {
money: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`,
username: message.author.username
}));
data.memberData.money = data.memberData.money - amount;
if (!data.userData.achievements.slots.achieved) {
data.userData.achievements.slots.progress.now = 0;
data.userData.markModified("achievements.slots");
await data.userData.save();
};
await data.memberData.save();
return;
};
function editMsg() {
let msg = "[ :slot_machine: | **СЛОТЫ** ]\n------------------\n";
i1 = (i1 < fruits.length - 1) ? i1 + 1 : 0;
i2 = (i2 < fruits.length - 1) ? i2 + 1 : 0;
i3 = (i3 < fruits.length - 1) ? i3 + 1 : 0;
j1 = (j1 < fruits.length - 1) ? j1 + 1 : 0;
j2 = (j2 < fruits.length - 1) ? j2 + 1 : 0;
j3 = (j3 < fruits.length - 1) ? j3 + 1 : 0;
k1 = (k1 < fruits.length - 1) ? k1 + 1 : 0;
k2 = (k2 < fruits.length - 1) ? k2 + 1 : 0;
k3 = (k3 < fruits.length - 1) ? k3 + 1 : 0;
msg += colonnes[0][i1] + " : " + colonnes[1][j1] + " : " + colonnes[2][k1] + "\n";
msg += colonnes[0][i2] + " : " + colonnes[1][j2] + " : " + colonnes[2][k2] + " **<**\n";
msg += colonnes[0][i3] + " : " + colonnes[1][j3] + " : " + colonnes[2][k3] + "\n";
tmsg.edit(msg);
};
}
};
module.exports = Slots;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js");
class Withdraw extends Command {
constructor(client) {
super(client, {
name: "withdraw",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["wd"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
let amount = args[0];
if (!(parseInt(data.memberData.bankSold, 10) > 0)) return message.error("economy/withdraw:NO_CREDIT");
if (args[0] === "all") {
amount = parseInt(data.memberData.bankSold, 10);
} else {
if (isNaN(amount) || parseInt(amount, 10) < 1) return message.error("economy/withdraw:MISSING_AMOUNT");
amount = parseInt(amount, 10);
};
if (data.memberData.bankSold < amount) return message.error("economy/withdraw:NOT_ENOUGH", {
money: `**${amount}** ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
data.memberData.money = data.memberData.money + amount;
data.memberData.bankSold = data.memberData.bankSold - amount;
data.memberData.save();
message.success("economy/withdraw:SUCCESS", {
money: `**${amount}** ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
}
};
module.exports = Withdraw;

103
commands/Economy/work.js Normal file
View file

@ -0,0 +1,103 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Work extends Command {
constructor(client) {
super(client, {
name: "work",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["salary", "daily"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
// if the member is already in the cooldown db
const isInCooldown = data.memberData.cooldowns.work;
if (isInCooldown) {
/*if the timestamp recorded in the database indicating
when the member will be able to execute the order again
is greater than the current date, display an error message */
if (isInCooldown > Date.now()) return message.error("economy/work:COOLDOWN", {
time: message.convertTime(isInCooldown, "to", true)
});
};
if (Date.now() > data.memberData.cooldowns.work + (24 * 3600000)) data.memberData.workStreak = 0;
// Records in the database the time when the member will be able to execute the command again (in 12 hours)
const toWait = Date.now() + 43200000;
data.memberData.cooldowns.work = toWait;
data.memberData.markModified("cooldowns");
data.memberData.workStreak = (data.memberData.workStreak || 0) + 1;
await data.memberData.save();
const embed = new Discord.MessageEmbed()
.setFooter(message.translate("economy/work:AWARD"), message.author.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}))
.setColor(data.config.embed.color);
const award = [
this.client.customEmojis.letters.a,
this.client.customEmojis.letters.w,
this.client.customEmojis.letters.a,
this.client.customEmojis.letters.r,
this.client.customEmojis.letters.d
];
let won = 200;
if (data.memberData.workStreak >= 5) {
won += 200;
embed.addField(message.translate("economy/work:SALARY"), message.translate("economy/work:SALARY_CONTENT", {
won: `${won} ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
}))
.addField(message.translate("economy/work:STREAK"), message.translate("economy/work:STREAK_CONTENT"));
data.memberData.workStreak = 0;
} else {
for (let i = 0; i < award.length; i++) {
if (data.memberData.workStreak > i) {
const letter = Discord.Util.parseEmoji(award[i]).name.split("_")[1];
award[i] = `:regional_indicator_${letter.toLowerCase()}:`;
};
};
embed.addField(message.translate("economy/work:SALARY"), message.translate("economy/work:SALARY_CONTENT", {
won: `${won} ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
}))
.addField(message.translate("economy/work:STREAK"), award.join(""));
};
data.memberData.money = data.memberData.money + won;
data.memberData.save();
const messageOptions = {
embed
};
if (!data.userData.achievements.work.achieved) {
data.userData.achievements.work.progress.now += 1;
if (data.userData.achievements.work.progress.now === data.userData.achievements.work.progress.total) {
messageOptions.files = [{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked1.png"
}];
data.userData.achievements.work.achieved = true;
};
data.userData.markModified("achievements.work");
data.userData.save();
};
// Send the embed in the current channel
message.channel.send(messageOptions);
}
};
module.exports = Work;

29
commands/Fun/8ball.js Normal file
View file

@ -0,0 +1,29 @@
const Command = require("../../base/Command.js");
class Eightball extends Command {
constructor(client) {
super(client, {
name: "8ball",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["8b"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args) {
if (!args[0] || !message.content.endsWith("?")) return message.error("fun/8ball:ERR_QUESTION");
const answerN = this.client.functions.randomNum(1, 19);
const answer = message.translate(`fun/8ball:RESPONSE_${answerN + 1}`);
message.channel.send(answer);
}
};
module.exports = Eightball;

32
commands/Fun/ascii.js Normal file
View file

@ -0,0 +1,32 @@
const Command = require("../../base/Command.js"),
figlet = require("figlet"),
util = require("util"),
figletAsync = util.promisify(figlet);
class Ascii extends Command {
constructor(client) {
super(client, {
name: "ascii",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: [],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args) {
const text = args.join(" ");
if (!text || text.length > 20) return message.error("fun/ascii:TEXT_MISSING");
const rendered = await figletAsync(text);
message.channel.send("```" + rendered + "```");
}
};
module.exports = Ascii;

37
commands/Fun/choice.js Normal file
View file

@ -0,0 +1,37 @@
const Command = require("../../base/Command.js");
class Choice extends Command {
constructor(client) {
super(client, {
name: "choice",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["random"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args) {
// Gets the answers by spliting on "/"
const answers = args.join(" ").split("/");
if (answers.length < 2) return message.error("fun/choice:MISSING");
if (answers.some(answer => !answer)) return message.error("fun/choice:EMPTY");
const m = await message.sendT("fun/choice:PROGRESS", null, false, false, "loading");
setTimeout(() => {
m.success("fun/choice:DONE", null, {
edit: true
});
const result = answers[parseInt(Math.floor(Math.random() * answers.length))];
message.channel.send("```" + result + "```");
}, 1500);
}
};
module.exports = Choice;

143
commands/Fun/findwords.js Normal file
View file

@ -0,0 +1,143 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
const currentGames = {};
class FindWords extends Command {
constructor(client) {
super(client, {
name: "findwords",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["findw"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (currentGames[message.guild.id]) return message.error("fun/number:GAME_RUNNING");
// Reads words file
let lang = null;
if (message.guild.data.language === "uk-UA") return lang = "ru-RU";
else lang = message.guild.data.language;
const wordList = require(`../../assets/json/words/${lang}.json`);
// Init some utils variables
const participants = [],
winners = [],
words = [],
nbGames = 4;
// Store the date wich the game has started
const createdAt = Date.now(); // 20929038303
for (let i = 0; i < nbGames; i++) {
const result = Math.floor((Math.random() * wordList.length));
words.push(wordList[result].substring(0, 3).toLowerCase());
};
let i = 0; // Inits i variable to count games
currentGames[message.guild.id] = true; // Update current game variable
generateGame.call(this, words[i]); // Generate a new round
function generateGame(word) {
word = word.toLowerCase();
// Launch timer
const delay = (i === 0) ? 10000 : 0;
if (i === 0) message.sendT("fun/findwords:GAME_STARTING");
setTimeout(() => {
// Send announcment message
message.sendT("fun/findwords:FIND_WORD", {
word: word.toUpperCase()
}, false, false, "warn");
// init a collector to receive the answers
const collector = new Discord.MessageCollector(message.channel, (m) => !m.author.bot, {
time: 20000
});
collector.on("collect", (msg) => {
if (this.client.functions.getPrefix(msg, data)) return;
if (!participants.includes(msg.author.id)) participants.push(msg.author.id);
if (msg.content.toLowerCase().indexOf(word) >= 0 && wordList.map((word) => word.toLowerCase()).indexOf(msg.content.toLowerCase()) >= 0) {
collector.stop(msg.author.id); // Stop the collector
} else msg.error("fun/findwords:INVALID_WORD", { member: msg.author.toString() });
});
collector.on("end", async (collected, reason) => {
if (reason === "time") {
message.error("fun/findwords:NO_WINNER");
} else {
message.success("fun/findwords:WORD_FOUND", {
winner: `<@${reason}>`
});
winners.push(reason);
}
if (i < nbGames - 1) {
i++;
generateGame.call(this, words[i]);
} else {
currentGames[message.guild.id] = false;
if (winners.length < 1) return message.error("fun/findwords:NO_WINNER_ALL");
const winnerID = await getWinner(winners);
const time = message.convertTime(createdAt, "from", true);
const user = await this.client.users.fetch(winnerID);
message.sendT("fun/findwords:GAME_STATS", {
winner: user.username,
duration: time,
participantCount: participants.length,
participants: participants.map((p) => `<@${p}>`).join(", ")
});
if (participants.length > 1 && data.guild.disabledCategories && !data.guild.disabledCategories.includes("Economy")) {
const won = 150 * (participants.length * 0.5);
message.sendT("fun/findwords:CREDITS", {
winner: user.username,
credits: `**${won}** ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
const userdata = await this.client.findOrCreateMember({
id: user.id,
guildID: message.guild.id
});
userdata.money = userdata.money + won;
userdata.save();
};
};
});
}, delay);
};
async function getWinner(array) {
return new Promise(function (resolve) {
const counts = {};
let compare = 0,
mostFrequent;
for (let i = 0, len = array.length; i < len; i++) {
const winner = array[i];
if (!counts[winner]) counts[winner] = 1;
else counts[winner] = counts[winner] + 1;
if (counts[winner] > compare) {
compare = counts[winner];
mostFrequent = array[i];
};
};
resolve(mostFrequent);
});
};
}
};
module.exports = FindWords;

25
commands/Fun/flip.js Normal file
View file

@ -0,0 +1,25 @@
const Command = require("../../base/Command.js");
class Flip extends Command {
constructor(client) {
super(client, {
name: "flip",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["dice", "coin"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message) {
const isHeads = Math.random() > 0.5;
isHeads ? message.sendT("fun/flip:HEADS") : message.sendT("fun/flip:TAILS");
}
};
module.exports = Flip;

35
commands/Fun/fml.js Normal file
View file

@ -0,0 +1,35 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Fml extends Command {
constructor(client) {
super(client, {
name: "fml",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: [],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (!this.client.config.apiKeys.blagueXYZ) return message.error("misc:COMMAND_DISABLED");
// const fml = await this.client.joker.randomVDM(null, data.guild.language.substr(0, 2));
const fml = await this.client.joker.randomVDM(null, "en");
const embed = new Discord.MessageEmbed()
.setDescription(fml.content)
.setFooter(message.translate("fun/fml:FOOTER"))
.setColor(this.client.config.embed.color);
message.channel.send(embed);
}
};
module.exports = Fml;

35
commands/Fun/joke.js Normal file
View file

@ -0,0 +1,35 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Joke extends Command {
constructor(client) {
super(client, {
name: "joke",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: [],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (!this.client.config.apiKeys.blagueXYZ) return message.error("misc:COMMAND_DISABLED");
// const joke = await this.client.joker.randomJoke(data.guild.language.substr(0, 2));
const joke = await this.client.joker.randomJoke("en");
const embed = new Discord.MessageEmbed()
.setDescription(joke.toDiscordSpoils())
.setFooter(message.translate("fun/joke:FOOTER"))
.setColor(this.client.config.embed.color);
message.channel.send(embed);
}
};
module.exports = Joke;

28
commands/Fun/lmg.js Normal file
View file

@ -0,0 +1,28 @@
const Command = require("../../base/Command.js");
class Lmg extends Command {
constructor(client) {
super(client, {
name: "lmg",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["lmgtfy"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args) {
const question = args.join(" ");
if (!question) return message.error("fun/lmg:MISSING");
const encodedQuestion = question.replace(/[' '_]/g, "+");
await message.channel.send(`https://google.gik-team.com/?q=${encodedQuestion}`);
message.delete().catch(() => {});
}
};
module.exports = Lmg;

53
commands/Fun/lovecalc.js Normal file
View file

@ -0,0 +1,53 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js"),
md5 = require("md5");
class Lovecalc extends Command {
constructor(client) {
super(client, {
name: "lovecalc",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["lc"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message) {
const firstMember = message.mentions.members.filter(m => m.id !== message.author.id).first();
if (!firstMember) return message.error("fun/lovecalc:MISSING");
const secondMember = message.mentions.members
.filter(m => m.id !== firstMember.id)
.filter(m => m.id !== message.author.id)
.first() || message.member;
if (!secondMember) return message.error("fun/lovecalc:MISSING");
const members = [firstMember, secondMember].sort((a, b) => parseInt(a.id, 10) - parseInt(b.id, 10));
const hash = md5(`${members[0].id}${members[1].user.username}${members[0].user.username}${members[1].id}`);
const string = hash
.split("")
.filter(e => !isNaN(e))
.join("");
const percent = parseInt(string.substr(0, 2), 10);
const embed = new Discord.MessageEmbed()
.setAuthor(`❤️ ${message.translate("fun/lovecalc:DESCRIPTION")}`)
.setDescription(message.translate("fun/lovecalc:CONTENT", {
percent,
firstUsername: firstMember.user.username,
secondUsername: secondMember.user.username
}))
.setColor(this.client.config.embed.color)
.setFooter(this.client.config.embed.footer);
message.channel.send(embed);
}
};
module.exports = Lovecalc;

93
commands/Fun/number.js Normal file
View file

@ -0,0 +1,93 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
const currentGames = {};
class Number extends Command {
constructor(client) {
super(client, {
name: "number",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["num"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (currentGames[message.guild.id]) return message.error("fun/number:GAME_RUNNING");
const participants = [],
number = Math.floor(this.client.functions.randomNum(100, 10000));
await message.sendT("fun/number:GAME_START");
// Store the date wich the game has started
const gameCreatedAt = Date.now();
const collector = new Discord.MessageCollector(message.channel, m => !m.author.bot, {
time: 480000 // 8 minutes
});
currentGames[message.guild.id] = true;
collector.on("collect", async msg => {
if (this.client.functions.getPrefix(msg, data)) return;
if (!participants.includes(msg.author.id)) participants.push(msg.author.id);
if (isNaN(msg.content)) return;
const parsedNumber = parseInt(msg.content, 10);
if (parsedNumber === number) {
const time = this.client.functions.convertTime(message.guild, Date.now() - gameCreatedAt);
message.sendT("fun/number:GAME_STATS", {
winner: msg.author.toString(),
number,
time,
participantCount: participants.length,
participants: participants.map(p => `<@${p}>`).join(", ")
});
if (participants.length > 1 && data.guild.disabledCategories && !data.guild.disabledCategories.includes("Economy")) {
const won = 100 * (participants.length * 0.5);
message.sendT("fun/number:WON", {
winner: msg.author.username,
credits: `**${won}** ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
});
const userdata = await this.client.findOrCreateMember({
id: msg.author.id,
guildID: message.guild.id
});
userdata.money = userdata.money + won;
userdata.save();
collector.stop(msg.author.username);
};
};
if (parseInt(msg.content) < number) message.error("fun/number:BIG", {
user: msg.author.toString(),
number: parsedNumber
});
if (parseInt(msg.content) > number) message.error("fun/number:SMALL", {
user: msg.author.toString(),
number: parsedNumber
});
});
collector.on("end", (_collected, reason) => {
delete currentGames[message.guild.id];
if (reason === "time") {
return message.error("fun/number:DEFEAT", {
number
});
};
});
}
};
module.exports = Number;

42
commands/Fun/tictactoe.js Normal file
View file

@ -0,0 +1,42 @@
const Command = require("../../base/Command.js"),
TTT = require("discord-tictactoe");
class TicTacToe extends Command {
constructor(client) {
super(client, {
name: "tictactoe",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["ttt"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args) {
const game = new TTT({ language: "ru" })
game.handleMessage(message);
game.on("win", async (data) => {
if (data.winner.id === "AI") return;
message.sendT("fun/number:WON", {
winner: data.winner.displayName
});
const userdata = await this.client.findOrCreateMember({
id: data.winner.id,
guildID: message.guild.id
});
userdata.money = userdata.money + 100;
userdata.save();
});
}
};
module.exports = TicTacToe;

View file

@ -0,0 +1,188 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Activity extends Command {
constructor(client) {
super(client, {
name: "activity",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["act"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
const perms = voice.permissionsFor(this.client.user);
if (!perms.has("CONNECT") || !perms.has("SPEAK")) return message.error("music/play:VOICE_CHANNEL_CONNECT");
const activities = ["awkword", "betrayal", "checkers", "chess", "doodlecrew", "fishing", "lettertile", "poker", "spellcast", "wordsnack", "puttparty", "youtube"];
const activity = args[0];
switch (activity) {
case "awkword":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "awkword").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Awkword")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Awkword", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "betrayal":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "betrayal").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Betrayal.io")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Betrayal.io", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "checkers":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "checkers").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Checkers In The Park")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Checkers In The Park", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "chess":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "chess").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Chess In The Park")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Chess In The Park", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "doodlecrew":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "doodlecrew").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Doodle Crew")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Doodle Crew", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "fishing":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "fishing").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Fishington.io")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Fishington.io", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "lettertile":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "lettertile").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Letter Tile")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Letter Tile", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "poker":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "poker").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Poker Night")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Poker Night", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "spellcast":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "spellcast").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Spell Cast")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Spell Cast", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "wordsnack":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "wordsnack").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Words Snack")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Words Snack", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "puttparty":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "puttparty").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Puttparty")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Puttparty", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
case "youtube":
this.client.discordTogether.createTogetherCode(message.member.voice.channelID, "youtube").then(async invite => {
const embed = new Discord.MessageEmbed()
.setTitle("Youtube Together")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Youtube Together", channel: voice.name })}](${invite.code})**`)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
return message.channel.send(embed);
});
break;
default:
const embed = new Discord.MessageEmbed()
.setTitle(message.translate("general/activity:TITLE"))
.setDescription(activities.join("\n"))
.setColor(data.config.embed.color)
.setFooter(message.translate("general/activity:FOOTER"))
.setTimestamp()
message.channel.send(embed);
break;
};
}
};
module.exports = Activity;

View file

@ -0,0 +1,77 @@
const Command = require("../../base/Command.js"),
Canvas = require("discord-canvas"),
Discord = require("discord.js");
class Fortnite extends Command {
constructor(client) {
super(client, {
name: "fortnite",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["fn"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (!data.config.apiKeys.fortniteTRN || data.config.apiKeys.fortniteTRN.length === "") return message.success("misc:COMMAND_DISABLED");
const stats = new Canvas.FortniteStats();
const platform = args[0].toLowerCase();
if (!platform || (platform !== "pc" && platform !== "xbl" && platform !== "psn")) return message.error("general/fortnite:MISSING_PLATFORM");
const user = args.slice(1).join(" ");
if (!user) return message.error("general/fortnite:MISSING_USERNAME");
const m = await message.sendT("misc:PLEASE_WAIT", null, {
prefixEmoji: "loading"
});
const statsImage = await stats
.setToken(data.config.apiKeys.fortniteTRN)
.setUser(user)
.setPlatform(platform)
.setText("averageKills", message.translate("general/fortnite:AVERAGE_KILLS"))
.setText("averageKill", message.translate("general/fortnite:AVERAGE_KILL"))
.setText("wPercent", message.translate("general/fortnite:W_PERCENT"))
.setText("winPercent", message.translate("general/fortnite:WIN_PERCENT"))
.setText("kD", message.translate("general/fortnite:KD"))
.setText("wins", message.translate("general/fortnite:WINS"))
.setText("win", message.translate("general/fortnite:WIN"))
.setText("kills", message.translate("general/fortnite:KILLS"))
.setText("kill", message.translate("general/fortnite:KILL"))
.setText("matches", message.translate("general/fortnite:MATCHES"))
.setText("match", message.translate("general/fortnite:MATCH"))
.setText("footer", message.translate("general/fortnite:FOOTER"))
.toAttachment();
if (!statsImage) {
m.delete();
return message.error("general/fortnite:NOT_FOUND", {
platform,
search: user
});
};
// Send embed
const attachment = new Discord.MessageAttachment(statsImage.toBuffer(), "fortnite-stats-image.png"),
embed = new Discord.MessageEmbed()
.setDescription(message.translate("general/fortnite:TITLE", {
username: `[${stats.data.username}](${stats.data.url.replace(new RegExp(" ", "g"), "%20")})`
}))
.attachFiles(attachment)
.setImage("attachment://fortnite-stats-image.png")
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer);
message.channel.send(embed);
m.delete();
}
};
module.exports = Fortnite;

View file

@ -0,0 +1,61 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js"),
Canvas = require("discord-canvas");
class Fortniteshop extends Command {
constructor(client) {
super(client, {
name: "fortniteshop",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["fns"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
if (!data.config.apiKeys.fortniteFNBR || data.config.apiKeys.fortniteFNBR.length === "") return message.error("misc:COMMAND_DISABLED");
const m = await message.sendT("misc:PLEASE_WAIT", null, {
prefixEmoji: "loading"
});
const momentName = this.client.languages.find((language) => language.name === data.guild.language || language.aliases.includes(data.guild.language)).moment;
const shop = new Canvas.FortniteShop();
const image = await shop
.setToken(data.config.apiKeys.fortniteFNBR)
.setText("header", message.translate("general/fortniteshop:HEADER"))
.setText("daily", message.translate("general/fortniteshop:DAILY"))
.setText("featured", message.translate("general/fortniteshop:FEATURED"))
.setText("date", message.translate("general/fortniteshop:DATE", {
skipInterpolation: true
}).replace("{{date}}", "{date}"))
.setText("footer", message.translate("general/fortniteshop:FOOTER"))
.lang(momentName)
.toAttachment();
const attachment = new Discord.MessageAttachment(image, "shop.png");
const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("general/fortniteshop:HEADER", {
date: message.printDate(new Date(Date.now()))
}), this.client.user.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}))
.attachFiles(attachment)
.setImage("attachment://shop.png")
.setColor(this.client.config.embed.color)
.setFooter(this.client.config.embed.footer);
await message.channel.send(embed);
await m.delete();
return;
}
};
module.exports = Fortniteshop;

View file

@ -0,0 +1,45 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js"),
fetch = require("node-fetch");
class Github extends Command {
constructor(client) {
super(client, {
name: "github",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["git"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const res = await fetch("https://api.github.com/repos/JonnyBro/jaba-v2");
const json = await res.json();
const embed = new Discord.MessageEmbed()
.setAuthor(this.client.user.tag, this.client.user.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}))
.setDescription(`[${message.translate("general/github:CLICK_HERE")}](${json.html_url})`)
.addField("Название", json.name, true)
.addField("Звёзды", json.stargazers_count, true)
.addField("Форки", json.forks_count, true)
.addField(message.translate("general/github:LANGUAGE"), json.language, true)
.addField(message.translate("general/github:OWNER"), `[${json.owner.login}](${json.owner.html_url})`)
.setImage(json.owner.avatar_url)
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer);
message.channel.send(embed);
}
};
module.exports = Github;

View file

@ -0,0 +1,50 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js"),
fetch = require("node-fetch");
class Hastebin extends Command {
constructor(client) {
super(client, {
name: "hastebin",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["hb"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const content = args.join(" ");
if (!content) return message.error("general/hastebin:MISSING_TEXT");
try {
const res = await fetch("https://hastebin.com/documents", {
method: "POST",
body: content,
headers: {
"Content-Type": "text/plain"
}
});
const json = await res.json();
if (!json.key) return message.error("misc:ERR_OCCURRED");
const url = `https://hastebin.com/${json.key}.js`;
const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("general/hastebin:SUCCESS"))
.setDescription(url)
.setColor(data.config.embed.color);
message.channel.send(embed);
} catch (e) {
message.error("misc:ERR_OCCURRED");
};
}
};
module.exports = Hastebin;

101
commands/General/help.js Normal file
View file

@ -0,0 +1,101 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Help extends Command {
constructor(client) {
super(client, {
name: "help",
dirname: __dirname,
enabled: true,
guildOnly: false,
aliases: ["h", "commands"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
if (args[0]) {
const isCustom = (message.guild && data.guild.customCommands ? data.guild.customCommands.find((c) => c.name === args[0]) : false);
const cmd = this.client.commands.get(args[0]) || this.client.commands.get(this.client.aliases.get(args[0]));
if (!cmd && isCustom) {
return message.error("general/help:CUSTOM", {
cmd: args[0]
});
} else if (!cmd) {
return message.error("general/help:NOT_FOUND", {
search: args[0]
});
};
const description = message.translate(`${cmd.help.category.toLowerCase()}/${cmd.help.name}:DESCRIPTION`);
const usage = message.translate(`${cmd.help.category.toLowerCase()}/${cmd.help.name}:USAGE`, {
prefix: message.guild ? data.guild.prefix : ""
});
const examples = message.translate(`${cmd.help.category.toLowerCase()}/${cmd.help.name}:EXAMPLES`, {
prefix: message.guild ? data.guild.prefix : ""
});
const groupEmbed = new Discord.MessageEmbed()
.setAuthor(message.translate("general/help:CMD_TITLE", {
cmd: cmd.help.name
}))
.addField(message.translate("general/help:FIELD_DESCRIPTION"), description)
.addField(message.translate("general/help:FIELD_USAGE"), usage)
.addField(message.translate("general/help:FIELD_EXAMPLES"), examples)
.addField(message.translate("general/help:FIELD_ALIASES"), cmd.help.aliases.length > 0 ? cmd.help.aliases.map(a => "`" + a + "`").join("\n") : message.translate("general/help:NO_ALIAS"))
.addField(message.translate("general/help:FIELD_PERMISSIONS"), cmd.conf.memberPermissions.length > 0 ? cmd.conf.memberPermissions.map((p) => `\`${p}\``).join("\n") : message.translate("general/help:NO_REQUIRED_PERMISSION"))
.setColor(this.client.config.embed.color)
.setFooter(this.client.config.embed.footer);
return message.channel.send(groupEmbed);
};
const categories = [];
const commands = this.client.commands;
commands.forEach((command) => {
if (!categories.includes(command.help.category)) {
if (command.help.category === "Owner" && message.author.id !== this.client.config.owner.id) return;
categories.push(command.help.category);
};
});
const emojis = this.client.customEmojis;
const embed = new Discord.MessageEmbed()
.setDescription(message.translate("general/help:INFO", {
prefix: message.guild ? data.guild.prefix : ""
}))
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer);
categories.sort().forEach((cat) => {
const tCommands = commands.filter((cmd) => cmd.help.category === cat);
embed.addField(`${emojis.categories[cat.toLowerCase()]} ${cat} - (${tCommands.size})`, `${tCommands.map((cmd) => `${cmd.help.name}`).join(", ")}`);
});
if (message.guild) {
if (data.guild.customCommands.length > 0) embed.addField(`${emojis.categories.custom} ${message.guild.name} | ${message.translate("general/help:CUSTOM_COMMANDS")} - (${data.guild.customCommands.length})`, data.guild.customCommands.map((cmd) => `\`${cmd.name}\``).join(", "));
};
embed.addField("\u200B", message.translate("misc:STATS_FOOTER", {
dashboardLink: "https://jaba.pp.ua/",
docsLink: "https://jaba.pp.ua/docs/",
donateLink: "https://qiwi.com/n/JONNYBRO/",
owner: this.client.config.owner.id
}));
embed.setAuthor(message.translate("general/help:TITLE", {
name: this.client.user.username
}), this.client.user.displayAvatarURL({
size: 512,
dynamic: true,
format: "png"
}));
return message.channel.send(embed);
}
};
module.exports = Help;

View file

@ -0,0 +1,66 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Invitations extends Command {
constructor(client) {
super(client, {
name: "invitations",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["invs"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "MANAGE_GUILD"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
let member = await this.client.resolveMember(args[0], message.guild);
if (!member) member = message.member;
const invites = await message.guild.fetchInvites().catch(() => {});
if (!invites) return message.error("misc:ERR_OCCURRED");
const memberInvites = invites.filter((i) => i.inviter && i.inviter.id === member.user.id);
if (memberInvites.size <= 0) {
if (member === message.member) {
return message.error("general/invitations:NOBODY_AUTHOR");
} else {
return message.error("general/invitations:NOBODY_MEMBER", {
member: member.user.tag
});
};
};
const content = memberInvites.map((i) => {
return message.translate("general/invitations:CODE", {
uses: i.uses,
code: i.code,
channel: i.channel.toString()
});
}).join("\n");
let index = 0;
memberInvites.forEach((invite) => index += invite.uses);
const embed = new Discord.MessageEmbed()
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer)
.setAuthor(message.translate("general/invitations:TRACKER"))
.setDescription(message.translate("general/invitations:TITLE", {
member: member.user.tag,
guild: message.guild.name
}))
.addField(message.translate("general/invitations:FIELD_INVITED"), message.translate("general/invitations:FIELD_MEMBERS", {
total: index
}))
.addField(message.translate("general/invitations:FIELD_CODES"), content);
message.channel.send(embed);
}
};
module.exports = Invitations;

View file

@ -0,0 +1,42 @@
const Command = require("../../base/Command.js"),
Discord = require("discord.js");
class Invite extends Command {
constructor(client) {
super(client, {
name: "invite",
dirname: __dirname,
enabled: false,
guildOnly: false,
aliases: ["i", "add", "vote"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const inviteLink = `https://discordapp.com/oauth2/authorize?client_id=${this.client.user.id}&scope=bot&permissions=8`;
const voteURL = `https://discordbots.org/bot/${this.client.user.id}/vote`;
const supportURL = await this.client.functions.supportLink(this.client);
if (args[0] && args[0] === "copy") return message.channel.send(inviteLink);
const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("general/invite:LINKS"))
.setDescription(message.translate("general/invite:TIP", {
prefix: data.guild.prefix || ""
}))
.addField(message.translate("general/invite:ADD"), inviteLink)
.addField(message.translate("general/invite:VOTE"), voteURL)
.addField(message.translate("general/invite:SUPPORT"), supportURL)
.setColor(data.config.embed.color)
.setFooter(data.config.embed.footer);
message.channel.send(embed);
}
};
module.exports = Invite;

Some files were not shown because too many files have changed in this diff Show more