Откат изменений v3.1.4
30
.gitignore
vendored
Normal 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
|
@ -0,0 +1 @@
|
|||
# JaBa-new
|
BIN
assets/fonts/Burbank-Big-Condensed-Bold-Font.otf
Normal file
BIN
assets/fonts/KeepCalm-Medium.ttf
Normal file
BIN
assets/fonts/LuckiestGuy-Regular.ttf
Normal file
BIN
assets/fonts/RubikMonoOne-Regular.ttf
Normal file
BIN
assets/fonts/RussoOne-Regular.ttf
Normal file
BIN
assets/fonts/SketchMatch.ttf
Normal file
BIN
assets/fonts/theboldfont.ttf
Normal file
BIN
assets/img/achievements/achievement1.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/img/achievements/achievement2.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/img/achievements/achievement3.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/img/achievements/achievement4.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/img/achievements/achievement5.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/img/achievements/achievement6.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/img/achievements/achievement7.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/img/achievements/achievement_colored1.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/img/achievements/achievement_colored2.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
assets/img/achievements/achievement_colored3.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
assets/img/achievements/achievement_colored4.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/img/achievements/achievement_colored5.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
assets/img/achievements/achievement_colored6.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/img/achievements/achievement_colored7.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
assets/img/achievements/achievement_unlocked1.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
assets/img/achievements/achievement_unlocked2.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
assets/img/achievements/achievement_unlocked3.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
assets/img/achievements/achievement_unlocked4.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
assets/img/achievements/achievement_unlocked5.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
assets/img/achievements/achievement_unlocked6.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
assets/img/achievements/achievement_unlocked7.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
assets/img/facepalm.png
Normal file
After Width: | Height: | Size: 210 KiB |
BIN
assets/img/fortnite/shop/english/example-shop.png
Normal file
After Width: | Height: | Size: 921 KiB |
BIN
assets/img/fortnite/stats/background.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
assets/img/fortnite/stats/crown.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/img/fortnite/stats/pc.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/img/fortnite/stats/psn.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/img/fortnite/stats/xbl.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/img/greetings_background.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
1
assets/json/words/en-US.json
Normal file
1
assets/json/words/ru-RU.json
Normal file
23
base/Command.js
Normal 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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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);
|
42
commands/Administration/addcommand.js
Normal 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;
|
34
commands/Administration/addemoji.js
Normal 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;
|
55
commands/Administration/automod.js
Normal 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;
|
60
commands/Administration/autorole.js
Normal 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;
|
105
commands/Administration/backup.js
Normal 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;
|
92
commands/Administration/configuration.js
Normal 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;
|
33
commands/Administration/delcommand.js
Normal 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;
|
35
commands/Administration/deletemod.js
Normal 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;
|
109
commands/Administration/goodbye.js
Normal 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;
|
41
commands/Administration/ignore.js
Normal 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;
|
57
commands/Administration/set.js
Normal 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;
|
45
commands/Administration/setbirthdays.js
Normal 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;
|
74
commands/Administration/setfortniteshop.js
Normal 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;
|
33
commands/Administration/setlang.js
Normal 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;
|
45
commands/Administration/setmodlogs.js
Normal 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;
|
33
commands/Administration/setprefix.js
Normal 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;
|
45
commands/Administration/setreports.js
Normal 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;
|
45
commands/Administration/setsuggests.js
Normal 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;
|
54
commands/Administration/slowmode.js
Normal 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;
|
110
commands/Administration/welcome.js
Normal 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;
|
66
commands/Economy/achievements.js
Normal 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;
|
49
commands/Economy/birthdate.js
Normal 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;
|
45
commands/Economy/deposit.js
Normal 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;
|
39
commands/Economy/divorce.js
Normal 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;
|
91
commands/Economy/leaderboard.js
Normal 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
|
@ -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
|
@ -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
|
@ -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;
|
88
commands/Economy/profile.js
Normal 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
|
@ -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
|
@ -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;
|
30
commands/Economy/setbio.js
Normal 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
|
@ -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;
|
45
commands/Economy/withdraw.js
Normal 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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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;
|
188
commands/General/activity.js
Normal 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;
|
77
commands/General/fortnite.js
Normal 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;
|
61
commands/General/fortniteshop.js
Normal 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;
|
45
commands/General/github.js
Normal 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;
|
50
commands/General/hastebin.js
Normal 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
|
@ -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;
|
66
commands/General/invitations.js
Normal 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;
|
42
commands/General/invite.js
Normal 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;
|