This commit is contained in:
JonnyBro 2021-12-16 23:42:58 +05:00
parent 3daa9c2bab
commit ae7986bfcd
34 changed files with 780 additions and 733 deletions

View file

@ -1,7 +1,7 @@
const { MessageEmbed, Util, Client, Collection } = require("discord.js"); const { MessageEmbed, Util, Client, Collection } = require("discord.js"),
const { GiveawaysManager } = require("discord-giveaways"); { GiveawaysManager } = require("discord-giveaways"),
const { Player } = require("discord-player"); { Player } = require("discord-player"),
const { Client: Joker } = require("blague.xyz"); { Client: Joker } = require("blague.xyz");
const util = require("util"), const util = require("util"),
AmeClient = require("amethyste-api"), AmeClient = require("amethyste-api"),
@ -44,15 +44,8 @@ class Atlanta extends Client {
this.databaseCache.usersReminds = new Collection(); // members with active reminds this.databaseCache.usersReminds = new Collection(); // members with active reminds
this.databaseCache.mutedUsers = new Collection(); // members who are currently muted this.databaseCache.mutedUsers = new Collection(); // members who are currently muted
if (this.config.apiKeys.amethyste) { if (this.config.apiKeys.amethyste) this.AmeAPI = new AmeClient(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" });
};
if (this.config.apiKeys.blagueXYZ) {
this.joker = new Joker(this.config.apiKeys.blagueXYZ, {
defaultLanguage: "en"
});
};
this.player = new Player(this, { this.player = new Player(this, {
ytdlDownloadOptions: { ytdlDownloadOptions: {
@ -68,16 +61,10 @@ class Atlanta extends Client {
this.player this.player
.on("trackStart", (message, track) => { .on("trackStart", (message, track) => {
message.success("music/play:NOW_PLAYING", { message.success("music/play:NOW_PLAYING", { songName: track.title });
songName: track.title
});
}) })
.on("playlistStart", (message, queue, playlist, track) => { .on("playlistStart", (message, queue, playlist, track) => {
message.channel.send(this.customEmojis.success+" | "+message.translate("music/play:PLAYING_PLAYLIST", { message.channel.send(`${this.customEmojis.success} ${message.translate("music/play:PLAYING_PLAYLIST", { playlistTitle: playlist.title, playlistEmoji: this.customEmojis.playlist, songName: track.title })}`);
playlistTitle: playlist.title,
playlistEmoji: this.customEmojis.playlist,
songName: track.title
}));
}) })
.on("searchResults", (message, query, tracks) => { .on("searchResults", (message, query, tracks) => {
if (tracks.length > 10) tracks = tracks.slice(0, 10); if (tracks.length > 10) tracks = tracks.slice(0, 10);
@ -93,10 +80,7 @@ class Atlanta extends Client {
return message.success("music/play:RESULTS_CANCEL"); return message.success("music/play:RESULTS_CANCEL");
}; };
message.error("misc:INVALID_NUMBER_RANGE", { message.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: tracks.length });
min: 1,
max: tracks.length
});
}) })
.on("searchCancel", (message) => { .on("searchCancel", (message) => {
message.error("misc:TIMES_UP"); message.error("misc:TIMES_UP");
@ -111,14 +95,10 @@ class Atlanta extends Client {
message.success("music/play:QUEUE_ENDED"); message.success("music/play:QUEUE_ENDED");
}) })
.on("playlistAdd", (message, queue, playlist) => { .on("playlistAdd", (message, queue, playlist) => {
message.success("music/play:ADDED_QUEUE_COUNT", { message.success("music/play:ADDED_QUEUE_COUNT", { songCount: playlist.items.length });
songCount: playlist.items.length
});
}) })
.on("trackAdd", (message, queue, track) => { .on("trackAdd", (message, queue, track) => {
message.success("music/play:ADDED_QUEUE", { message.success("music/play:ADDED_QUEUE", { songName: track.title });
songName: track.title
});
}) })
.on("channelEmpty", () => { .on("channelEmpty", () => {
// do nothing, leaveOnEmpty is not enabled // do nothing, leaveOnEmpty is not enabled
@ -155,7 +135,7 @@ class Atlanta extends Client {
default: { default: {
botsCanWin: false, botsCanWin: false,
// exemptPermissions: [ "MANAGE_MESSAGES", "ADMINISTRATOR" ], // exemptPermissions: [ "MANAGE_MESSAGES", "ADMINISTRATOR" ],
embedColor: "#FF0000", embedColor: this.config.embed.color,
reaction: "🎉" reaction: "🎉"
} }
}); });
@ -169,6 +149,7 @@ class Atlanta extends Client {
if (!locale) locale = this.defaultLanguage; if (!locale) locale = this.defaultLanguage;
const language = this.translations.get(locale); const language = this.translations.get(locale);
if (!language) throw "Invalid language set in data."; if (!language) throw "Invalid language set in data.";
return language(key, args); return language(key, args);
}; };
@ -176,6 +157,7 @@ class Atlanta extends Client {
if (!locale) locale = this.defaultLanguage; if (!locale) locale = this.defaultLanguage;
const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale)); const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale));
if (!format) format = languageData.defaultMomentFormat; if (!format) format = languageData.defaultMomentFormat;
return moment(new Date(date)) return moment(new Date(date))
.locale(languageData.moment) .locale(languageData.moment)
.format(format); .format(format);
@ -185,8 +167,8 @@ class Atlanta extends Client {
if (!type) time = "to"; if (!type) time = "to";
if (!locale) locale = this.defaultLanguage; if (!locale) locale = this.defaultLanguage;
const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale)); const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale));
const m = moment(time) const m = moment(time).locale(languageData.moment);
.locale(languageData.moment);
return (type === "to" ? m.toNow(noPrefix) : m.fromNow(noPrefix)); return (type === "to" ? m.toNow(noPrefix) : m.fromNow(noPrefix));
}; };
@ -196,13 +178,13 @@ class Atlanta extends Client {
const props = new (require(`.${commandPath}${path.sep}${commandName}`))(this); const props = new (require(`.${commandPath}${path.sep}${commandName}`))(this);
this.logger.log(`Loading Command: ${props.help.name}. 👌`, "log"); this.logger.log(`Loading Command: ${props.help.name}. 👌`, "log");
props.conf.location = commandPath; props.conf.location = commandPath;
if (props.init) { if (props.init) props.init(this);
props.init(this);
};
this.commands.set(props.help.name, props); this.commands.set(props.help.name, props);
props.help.aliases.forEach((alias) => { props.help.aliases.forEach((alias) => {
this.aliases.set(alias, props.help.name); this.aliases.set(alias, props.help.name);
}); });
return false; return false;
} catch (e) { } catch (e) {
return `Unable to load command ${commandName}: ${e}`; return `Unable to load command ${commandName}: ${e}`;
@ -212,34 +194,31 @@ class Atlanta extends Client {
// This function is used to unload a command (you need to load them again) // This function is used to unload a command (you need to load them again)
async unloadCommand (commandPath, commandName) { async unloadCommand (commandPath, commandName) {
let command; let command;
if (this.commands.has(commandName)) { if (this.commands.has(commandName)) command = this.commands.get(commandName);
command = this.commands.get(commandName); else if (this.aliases.has(commandName)) command = this.commands.get(this.aliases.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);
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`)]; delete require.cache[require.resolve(`.${commandPath}${path.sep}${commandName}.js`)];
return false; return false;
}; };
// This function is used to find a user data or create it // This function is used to find a user data or create it
async findOrCreateUser({ id: userID }, isLean) { async findOrCreateUser({ id: userID }, isLean) {
if (this.databaseCache.users.get(userID)) { if (this.databaseCache.users.get(userID)) return isLean ? this.databaseCache.users.get(userID).toJSON() : this.databaseCache.users.get(userID);
return isLean ? this.databaseCache.users.get(userID).toJSON() : this.databaseCache.users.get(userID); else {
} else {
let userData = (isLean ? await this.usersData.findOne({ id: userID }).lean() : await this.usersData.findOne({ id: userID })); let userData = (isLean ? await this.usersData.findOne({ id: userID }).lean() : await this.usersData.findOne({ id: userID }));
if (userData) { if (userData) {
if (!isLean) this.databaseCache.users.set(userID, userData); if (!isLean) this.databaseCache.users.set(userID, userData);
return userData; return userData;
} else { } else {
userData = new this.usersData({ id: userID }); userData = new this.usersData({ id: userID });
await userData.save(); await userData.save();
this.databaseCache.users.set(userID, userData); this.databaseCache.users.set(userID, userData);
return isLean ? userData.toJSON() : userData; return isLean ? userData.toJSON() : userData;
}; };
}; };
@ -247,12 +226,12 @@ class Atlanta extends Client {
// This function is used to find a member data or create it // This function is used to find a member data or create it
async findOrCreateMember({ id: memberID, guildID }, isLean) { async findOrCreateMember({ id: memberID, guildID }, isLean) {
if (this.databaseCache.members.get(`${memberID}${guildID}`)) { if (this.databaseCache.members.get(`${memberID}${guildID}`)) return isLean ? this.databaseCache.members.get(`${memberID}${guildID}`).toJSON() : this.databaseCache.members.get(`${memberID}${guildID}`);
return isLean ? this.databaseCache.members.get(`${memberID}${guildID}`).toJSON() : this.databaseCache.members.get(`${memberID}${guildID}`); else {
} else {
let memberData = (isLean ? await this.membersData.findOne({ guildID, id: memberID }).lean() : await this.membersData.findOne({ guildID, id: memberID })); let memberData = (isLean ? await this.membersData.findOne({ guildID, id: memberID }).lean() : await this.membersData.findOne({ guildID, id: memberID }));
if (memberData) { if (memberData) {
if (!isLean) this.databaseCache.members.set(`${memberID}${guildID}`, memberData); if (!isLean) this.databaseCache.members.set(`${memberID}${guildID}`, memberData);
return memberData; return memberData;
} else { } else {
memberData = new this.membersData({ id: memberID, guildID: guildID }); memberData = new this.membersData({ id: memberID, guildID: guildID });
@ -263,6 +242,7 @@ class Atlanta extends Client {
await guild.save(); await guild.save();
}; };
this.databaseCache.members.set(`${memberID}${guildID}`, memberData); this.databaseCache.members.set(`${memberID}${guildID}`, memberData);
return isLean ? memberData.toJSON() : memberData; return isLean ? memberData.toJSON() : memberData;
}; };
}; };
@ -270,17 +250,18 @@ class Atlanta extends Client {
// This function is used to find a guild data or create it // This function is used to find a guild data or create it
async findOrCreateGuild({ id: guildID }, isLean) { async findOrCreateGuild({ id: guildID }, isLean) {
if (this.databaseCache.guilds.get(guildID)) { if (this.databaseCache.guilds.get(guildID)) return isLean ? this.databaseCache.guilds.get(guildID).toJSON() : this.databaseCache.guilds.get(guildID);
return isLean ? this.databaseCache.guilds.get(guildID).toJSON() : this.databaseCache.guilds.get(guildID); else {
} else {
let guildData = (isLean ? await this.guildsData.findOne({ id: guildID }).populate("members").lean() : await this.guildsData.findOne({ id: guildID }).populate("members")); let guildData = (isLean ? await this.guildsData.findOne({ id: guildID }).populate("members").lean() : await this.guildsData.findOne({ id: guildID }).populate("members"));
if (guildData) { if (guildData) {
if (!isLean) this.databaseCache.guilds.set(guildID, guildData); if (!isLean) this.databaseCache.guilds.set(guildID, guildData);
return guildData; return guildData;
} else { } else {
guildData = new this.guildsData({ id: guildID }); guildData = new this.guildsData({ id: guildID });
await guildData.save(); await guildData.save();
this.databaseCache.guilds.set(guildID, guildData); this.databaseCache.guilds.set(guildID, guildData);
return isLean ? guildData.toJSON() : guildData; return isLean ? guildData.toJSON() : guildData;
}; };
}; };
@ -290,12 +271,14 @@ class Atlanta extends Client {
async resolveUser(search) { async resolveUser(search) {
let user = null; let user = null;
if (!search || typeof search !== "string") return; if (!search || typeof search !== "string") return;
// Try ID search // Try ID search
if (search.match(/^<@!?(\d+)>$/)) { if (search.match(/^<@!?(\d+)>$/)) {
const id = search.match(/^<@!?(\d+)>$/)[1]; const id = search.match(/^<@!?(\d+)>$/)[1];
user = this.users.fetch(id).catch(() => {}); user = this.users.fetch(id).catch(() => {});
if (user) return user; if (user) return user;
}; };
// Try username search // Try username search
if (search.match(/^!?(\w+)#(\d+)$/)) { if (search.match(/^!?(\w+)#(\d+)$/)) {
const username = search.match(/^!?(\w+)#(\d+)$/)[0]; const username = search.match(/^!?(\w+)#(\d+)$/)[0];
@ -304,18 +287,21 @@ class Atlanta extends Client {
if (user) return user; if (user) return user;
}; };
user = await this.users.fetch(search).catch(() => {}); user = await this.users.fetch(search).catch(() => {});
return user; return user;
}; };
async resolveMember(search, guild) { async resolveMember(search, guild) {
let member = null; let member = null;
if (!search || typeof search !== "string") return; if (!search || typeof search !== "string") return;
// Try ID search // Try ID search
if (search.match(/^<@!?(\d+)>$/)) { if (search.match(/^<@!?(\d+)>$/)) {
const id = search.match(/^<@!?(\d+)>$/)[1]; const id = search.match(/^<@!?(\d+)>$/)[1];
member = await guild.members.fetch(id).catch(() => {}); member = await guild.members.fetch(id).catch(() => {});
if (member) return member; if (member) return member;
}; };
// Try username search // Try username search
if (search.match(/^!?(\w+)#(\d+)$/)) { if (search.match(/^!?(\w+)#(\d+)$/)) {
guild = await guild.fetch(); guild = await guild.fetch();
@ -323,22 +309,26 @@ class Atlanta extends Client {
if (member) return member; if (member) return member;
}; };
member = await guild.members.fetch(search).catch(() => {}); member = await guild.members.fetch(search).catch(() => {});
return member; return member;
}; };
async resolveRole(search, guild) { async resolveRole(search, guild) {
let role = null; let role = null;
if (!search || typeof search !== "string") return; if (!search || typeof search !== "string") return;
// Try ID search // Try ID search
if (search.match(/^<@&!?(\d+)>$/)) { if (search.match(/^<@&!?(\d+)>$/)) {
const id = search.match(/^<@&!?(\d+)>$/)[1]; const id = search.match(/^<@&!?(\d+)>$/)[1];
role = guild.roles.cache.get(id); role = guild.roles.cache.get(id);
if (role) return role; if (role) return role;
}; };
// Try name search // Try name search
role = guild.roles.cache.find((r) => search === r.name); role = guild.roles.cache.find((r) => search === r.name);
if (role) return role; if (role) return role;
role = guild.roles.cache.get(search); role = guild.roles.cache.get(search);
return role; return role;
}; };
}; };

View file

@ -107,7 +107,7 @@ userSchema.method("getAchievements", async function() {
await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.invite.achieved ? "_colored" : ""}7.png`) await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.invite.achieved ? "_colored" : ""}7.png`)
]; ];
let dim = 0; let dim = 0;
for(let i = 0; i < images.length; i++) { for (let i = 0; i < images.length; i++) {
await ctx.drawImage(images[i], dim, 10, 350, 200); await ctx.drawImage(images[i], dim, 10, 350, 200);
dim += 200; dim += 200;
}; };

View file

@ -4,7 +4,6 @@ const config = require("../config"),
module.exports.load = async(client) => { module.exports.load = async(client) => {
/* Init express app */ /* Init express app */
const express = require("express"), const express = require("express"),
session = require("express-session"), session = require("express-session"),
path = require("path"), path = require("path"),
@ -56,7 +55,7 @@ module.exports.load = async(client) => {
.use("/", mainRouter) .use("/", mainRouter)
.use("/commands", commandsManagerRouter) .use("/commands", commandsManagerRouter)
.use("/updates", updatesManagerRouter) .use("/updates", updatesManagerRouter)
.use(CheckAuth, function(req, res){ .use(CheckAuth, function(req, res) {
res.status(404).render("404", { res.status(404).render("404", {
user: req.userInfos, user: req.userInfos,
translate: req.translate, translate: req.translate,

View file

@ -1,7 +1,6 @@
module.exports = async (req, res, next) => { module.exports = async (req, res, next) => {
if (req.session.user) { if (req.session.user) return next();
return next(); else {
} else {
const redirectURL = ((req.originalUrl.includes("login") || req.originalUrl === "/") ? "/selector" : req.originalUrl); const redirectURL = ((req.originalUrl.includes("login") || req.originalUrl === "/") ? "/selector" : req.originalUrl);
const state = Math.random().toString(36).substring(5); const state = Math.random().toString(36).substring(5);
req.client.states[state] = redirectURL; req.client.states[state] = redirectURL;

View file

@ -7,9 +7,8 @@ const fetch = require("node-fetch"),
// Gets login page // Gets login page
router.get("/login", async function(req, res) { router.get("/login", async function(req, res) {
if (!req.user || !req.user.id || !req.user.guilds) { if (!req.user || !req.user.id || !req.user.guilds) return res.redirect(`https://discordapp.com/api/oauth2/authorize?client_id=${req.client.user.id}&scope=identify%20guilds&response_type=code&redirect_uri=${encodeURIComponent(req.client.config.dashboard.baseURL+"/api/callback")}&state=${req.query.state || "no"}`);
return res.redirect(`https://discordapp.com/api/oauth2/authorize?client_id=${req.client.user.id}&scope=identify%20guilds&response_type=code&redirect_uri=${encodeURIComponent(req.client.config.dashboard.baseURL+"/api/callback")}&state=${req.query.state || "no"}`);
};
res.redirect("/selector"); res.redirect("/selector");
}); });
@ -19,9 +18,11 @@ router.get("/callback", async (req, res) => {
if (req.query.code) { if (req.query.code) {
const guildID = req.query.state.substr("invite".length, req.query.state.length); const guildID = req.query.state.substr("invite".length, req.query.state.length);
req.client.knownGuilds.push({ id: guildID, user: req.user.id }); req.client.knownGuilds.push({ id: guildID, user: req.user.id });
return res.redirect("/manage/"+guildID); return res.redirect("/manage/"+guildID);
}; };
}; };
const redirectURL = req.client.states[req.query.state] || "/selector"; const redirectURL = req.client.states[req.query.state] || "/selector";
const params = new URLSearchParams(); const params = new URLSearchParams();
params.set("grant_type", "authorization_code"); params.set("grant_type", "authorization_code");
@ -35,8 +36,10 @@ router.get("/callback", async (req, res) => {
"Content-Type": "application/x-www-form-urlencoded" "Content-Type": "application/x-www-form-urlencoded"
} }
}); });
// Fetch tokens (used to fetch user informations) // Fetch tokens (used to fetch user informations)
const tokens = await response.json(); const tokens = await response.json();
// If the code isn't valid // If the code isn't valid
if (tokens.error || !tokens.access_token) return res.redirect(`/api/login&state=${req.query.state}`); if (tokens.error || !tokens.access_token) return res.redirect(`/api/login&state=${req.query.state}`);
const userData = { const userData = {
@ -54,6 +57,7 @@ router.get("/callback", async (req, res) => {
if (json.retry_after) await req.client.wait(json.retry_after); if (json.retry_after) await req.client.wait(json.retry_after);
else userData.infos = json; else userData.infos = json;
}; };
/* User guilds */ /* User guilds */
if (!userData.guilds) { if (!userData.guilds) {
response = await fetch("https://discordapp.com/api/users/@me/guilds", { response = await fetch("https://discordapp.com/api/users/@me/guilds", {
@ -65,9 +69,11 @@ router.get("/callback", async (req, res) => {
else userData.guilds = json; else userData.guilds = json;
}; };
}; };
/* Change format (from "0": { data }, "1": { data }, etc... to [ { data }, { data } ]) */ /* Change format (from "0": { data }, "1": { data }, etc... to [ { data }, { data } ]) */
const guilds = []; const guilds = [];
for(const guildPos in userData.guilds) guilds.push(userData.guilds[guildPos]); for (const guildPos in userData.guilds) guilds.push(userData.guilds[guildPos]);
// Update session // Update session
req.session.user = { ... userData.infos, ... { guilds } }; req.session.user = { ... userData.infos, ... { guilds } };
const user = await req.client.users.fetch(req.session.user.id); const user = await req.client.users.fetch(req.session.user.id);

View file

@ -42,12 +42,9 @@ router.post("/:serverID", CheckAuth, async(req, res) => {
if (data.language) { if (data.language) {
const language = req.client.languages.find((language) => language.aliases[0].toLowerCase() === data.language.toLowerCase()); const language = req.client.languages.find((language) => language.aliases[0].toLowerCase() === data.language.toLowerCase());
if (language) { if (language) guildData.language = language.name;
guildData.language = language.name; if (data.prefix.length >= 1 && data.prefix.length < 2000) guildData.prefix = data.prefix;
};
if (data.prefix.length >= 1 && data.prefix.length < 2000) {
guildData.prefix = data.prefix;
};
await guildData.save(); await guildData.save();
}; };
@ -120,21 +117,15 @@ router.post("/:serverID", CheckAuth, async(req, res) => {
}; };
if (Object.prototype.hasOwnProperty.call(data, "suggestions")) { if (Object.prototype.hasOwnProperty.call(data, "suggestions")) {
if (data.suggestions === req.translate("common:NO_CHANNEL")) { if (data.suggestions === req.translate("common:NO_CHANNEL")) guildData.plugins.suggestions = false;
guildData.plugins.suggestions = false; else guildData.plugins.suggestions = guild.channels.cache.find((ch) => "#"+ch.name === data.suggestions).id;
} else {
guildData.plugins.suggestions = guild.channels.cache.find((ch) => "#"+ch.name === data.suggestions).id; if (data.modlogs === req.translate("common:NO_CHANNEL")) guildData.plugins.modlogs = false;
}; else guildData.plugins.modlogs = guild.channels.cache.find((ch) => "#"+ch.name === data.modlogs).id;
if (data.modlogs === req.translate("common:NO_CHANNEL")) {
guildData.plugins.modlogs = false; if (data.fortniteshop === req.translate("common:NO_CHANNEL")) guildData.plugins.fortniteshop = false;
} else { else guildData.plugins.fortniteshop = guild.channels.cache.find((ch) => "#"+ch.name === data.fortniteshop).id;
guildData.plugins.modlogs = guild.channels.cache.find((ch) => "#"+ch.name === data.modlogs).id;
};
if (data.fortniteshop === req.translate("common:NO_CHANNEL")) {
guildData.plugins.fortniteshop = false;
} else {
guildData.plugins.fortniteshop = guild.channels.cache.find((ch) => "#"+ch.name === data.fortniteshop).id;
};
guildData.markModified("plugins"); guildData.markModified("plugins");
}; };

View file

@ -25,14 +25,16 @@ router.get("/:serverID", CheckAuth, async(req, res) => {
level: sortArrayOfObjects("level", membersData) level: sortArrayOfObjects("level", membersData)
}; };
for(const cat in leaderboards){ for (const cat in leaderboards) {
const e = leaderboards[cat]; const e = leaderboards[cat];
if (e.length > 10) e.length = 10; if (e.length > 10) e.length = 10;
} };
const stats = { const stats = {
money: await utils.fetchUsers(leaderboards.money, req.client), money: await utils.fetchUsers(leaderboards.money, req.client),
level: await utils.fetchUsers(leaderboards.level, req.client) level: await utils.fetchUsers(leaderboards.level, req.client)
}; };
res.render("stats/guild", { res.render("stats/guild", {
stats, stats,
commands: getCommands(guildInfos.commands.filter((c) => c.date > Date.now()-604800000)), commands: getCommands(guildInfos.commands.filter((c) => c.date > Date.now()-604800000)),
@ -49,22 +51,17 @@ function getCommands(commands) {
const aDateCommand = {}; const aDateCommand = {};
commands.forEach((cmd) => { commands.forEach((cmd) => {
const tDate = formatDate(new Date(cmd.date)); const tDate = formatDate(new Date(cmd.date));
if (aDateCommand[tDate]) { if (aDateCommand[tDate]) aDateCommand[tDate]++;
aDateCommand[tDate]++; else aDateCommand[tDate] = 1;
} else {
aDateCommand[tDate] = 1;
};
}); });
return aDateCommand; return aDateCommand;
}; };
function getCommandsUsage(commands) { function getCommandsUsage(commands) {
const objectCount = commands.reduce((acc, curr) => { const objectCount = commands.reduce((acc, curr) => {
if (typeof acc[curr.command] == "undefined") { if (typeof acc[curr.command] == "undefined") acc[curr.command] = 1;
acc[curr.command] = 1; else acc[curr.command] += 1;
} else {
acc[curr.command] += 1;
}
return acc; return acc;
}, {}); }, {});
const percentages = getPercentagePerKey(objectCount); // [ { key: "help", percentage: 20 } ] const percentages = getPercentagePerKey(objectCount); // [ { key: "help", percentage: 20 } ]
@ -74,6 +71,7 @@ function getCommandsUsage(commands) {
p.color = colors[i]; p.color = colors[i];
i++; i++;
}); });
return percentages; return percentages;
}; };
@ -85,14 +83,14 @@ function getPercentagePerKey(myArray) {
const percentage = Math.round((val / sum) * 100); const percentage = Math.round((val / sum) * 100);
arrayWithPercentages.push({key, percentage}); arrayWithPercentages.push({key, percentage});
}; };
return arrayWithPercentages; return arrayWithPercentages;
}; };
function getSum(myArray) { function getSum(myArray) {
let sum = 0; let sum = 0;
for (const key in myArray) { for (const key in myArray) sum += myArray[key];
sum += myArray[key];
};
return sum; return sum;
}; };
@ -109,5 +107,6 @@ function formatDate(date) {
if (dd < 10) dd = `0${dd}` if (dd < 10) dd = `0${dd}`
if (mm < 10) mm = `0${mm}` if (mm < 10) mm = `0${mm}`
date = `${mm}/${dd}` date = `${mm}/${dd}`
return date; return date;
}; };

View file

@ -12,18 +12,18 @@ router.get("/", CheckAuth, async function(req, res) {
}); });
}); });
router.post("/", CheckAuth, async function(req, res){ router.post("/", CheckAuth, async function(req, res) {
const user = await req.client.findOrCreateUser({ id: req.user.id }); const user = await req.client.findOrCreateUser({ id: req.user.id });
const data = req.body; const data = req.body;
if (data.bio) { if (data.bio) user.bio = data.bio;
user.bio = data.bio;
};
if (data.birthdate) { if (data.birthdate) {
if (checkDate(data.birthdate)) { if (checkDate(data.birthdate)) {
user.birthdate = checkDate(data.birthdate); user.birthdate = checkDate(data.birthdate);
user.markModified("birthdate"); user.markModified("birthdate");
}; };
}; };
await user.save(); await user.save();
res.redirect(303, "/settings"); res.redirect(303, "/settings");
}); });
@ -33,19 +33,18 @@ module.exports = router;
/** /**
* @returns {Boolean} * @returns {Boolean}
*/ */
function checkDate(birthdate){ function checkDate(birthdate) {
const [day, month, year] = birthdate; const [day, month, year] = birthdate;
if (!day || !month || !year) return false; if (!day || !month || !year) return false;
const match = birthdate.match(/\d+/g); const match = birthdate.match(/\d+/g);
if (!match) return false; if (!match) return false;
const tday = + match[0], tmonth = + match[1] - 1; const tday = + match[0], tmonth = + match[1] - 1;
let tyear = + match[2]; let tyear = + match[2];
if (tyear < 100) { if (tyear < 100) tyear += tyear < 50 ? 2000 : 1900;
tyear += tyear < 50 ? 2000 : 1900;
};
const d = new Date(tyear, tmonth, tday); const d = new Date(tyear, tmonth, tday);
if (!(tday == d.getDate() && tmonth == d.getMonth() && tyear == d.getFullYear())) return false; if (!(tday == d.getDate() && tmonth == d.getMonth() && tyear == d.getFullYear())) return false;
if (d.getTime() > Date.now()) return false; if (d.getTime() > Date.now()) return false;
if (d.getTime() < (Date.now() - 2.523e+12)) return false; if (d.getTime() < (Date.now() - 2.523e+12)) return false;
return d; return d;
}; };

View file

@ -6,9 +6,10 @@ const Discord = require("discord.js");
* @param {object} client The discord client instance * @param {object} client The discord client instance
* @param {array} guilds The user guilds * @param {array} guilds The user guilds
*/ */
async function fetchGuild(guildID, client, guilds){ async function fetchGuild(guildID, client, guilds) {
const guild = client.guilds.cache.get(guildID); const guild = client.guilds.cache.get(guildID);
const conf = await client.findOrCreateGuild({id:guild.id}); const conf = await client.findOrCreateGuild({ id:guild.id });
return { ...guild, ...conf.toJSON(), ...guilds.find((g) => g.id === guild.id) }; return { ...guild, ...conf.toJSON(), ...guilds.find((g) => g.id === guild.id) };
}; };
@ -19,27 +20,25 @@ async function fetchGuild(guildID, client, guilds){
* @param {string} query The optional query for guilds * @param {string} query The optional query for guilds
* @returns {object} The user informations * @returns {object} The user informations
*/ */
async function fetchUser(userData, client, query){ async function fetchUser(userData, client, query) {
if (userData.guilds) { if (userData.guilds) {
userData.guilds.forEach((guild) => { userData.guilds.forEach((guild) => {
if (!client.guilds.cache.get(guild.id)) return; if (!client.guilds.cache.get(guild.id)) return;
const perms = new Discord.Permissions(guild.permissions); const perms = new Discord.Permissions(guild.permissions);
if (perms.has("MANAGE_GUILD")) { if (perms.has("MANAGE_GUILD")) guild.admin = true;
guild.admin = true;
};
guild.settingsUrl = (client.guilds.cache.get(guild.id) ? `/manage/${guild.id}/` : `https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&scope=bot&permissions=8&guild_id=${guild.id}`); guild.settingsUrl = (client.guilds.cache.get(guild.id) ? `/manage/${guild.id}/` : `https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&scope=bot&permissions=8&guild_id=${guild.id}`);
guild.statsUrl = (client.guilds.cache.get(guild.id) ? `/stats/${guild.id}/` : `https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&scope=bot&permissions=8&guild_id=${guild.id}`); guild.statsUrl = (client.guilds.cache.get(guild.id) ? `/stats/${guild.id}/` : `https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&scope=bot&permissions=8&guild_id=${guild.id}`);
guild.iconURL = (guild.icon ? `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=128` : "https://discordemoji.com/assets/emoji/discordcry.png"); guild.iconURL = (guild.icon ? `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=128` : "https://discordemoji.com/assets/emoji/discordcry.png");
guild.displayed = (query ? guild.name.toLowerCase().includes(query.toLowerCase()) : true); guild.displayed = (query ? guild.name.toLowerCase().includes(query.toLowerCase()) : true);
}); });
userData.displayedGuilds = userData.guilds.filter((g) => g.displayed && g.admin); userData.displayedGuilds = userData.guilds.filter((g) => g.displayed && g.admin);
if (userData.displayedGuilds.length < 1) { if (userData.displayedGuilds.length < 1) delete userData.displayedGuilds;
delete userData.displayedGuilds;
};
}; };
const user = await client.users.fetch(userData.id); const user = await client.users.fetch(userData.id);
const userDb = await client.findOrCreateUser({ id: user.id }, true); const userDb = await client.findOrCreateUser({ id: user.id }, true);
const userInfos = { ...user.toJSON(), ...userDb, ...userData, ...user.presence }; const userInfos = { ...user.toJSON(), ...userDb, ...userData, ...user.presence };
return userInfos; return userInfos;
}; };

View file

@ -1,17 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('includes/head') %> <%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar --> <body class="hold-transition skin-red sidebar-mini">
<%- include('includes/header') %> <div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- The sidebar includes the menu --> <!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %> <%- include('includes/sidebar') %>
<!-- Content Wrapper. Contains page content --> <!-- Content Wrapper. Contains page content -->
<div class="content-wrapper"> <div class="content-wrapper">
<!-- Content Header (Page header) --> <!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
@ -34,7 +34,8 @@
<form class="search-form" action="/selector"> <form class="search-form" action="/selector">
<div class="input-group"> <div class="input-group">
<input type="text" name="q" class="form-control" placeholder="<%= translate("dashboard:SEARCH") %>"> <input type="text" name="q" class="form-control"
placeholder="<%= translate("dashboard:SEARCH") %>">
<div class="input-group-btn"> <div class="input-group-btn">
<button type="submit" class="btn btn-warning btn-flat"><i class="fa fa-search"></i> <button type="submit" class="btn btn-warning btn-flat"><i class="fa fa-search"></i>
@ -56,4 +57,5 @@
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
</body> </body>
</html> </html>

View file

@ -1,16 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('includes/head') %> <%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- The sidebar includes the menu --> <body class="hold-transition skin-red sidebar-mini">
<%- include('includes/sidebar') %> <div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- Content Wrapper. Contains page content --> <!-- The sidebar includes the menu -->
<div class="content-wrapper"> <%- include('includes/sidebar') %>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) --> <!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
@ -33,7 +34,8 @@
<form class="search-form" action="/selector"> <form class="search-form" action="/selector">
<div class="input-group"> <div class="input-group">
<input type="text" name="q" class="form-control" placeholder="<%= translate("dashboard:SEARCH") %>"> <input type="text" name="q" class="form-control"
placeholder="<%= translate("dashboard:SEARCH") %>">
<div class="input-group-btn"> <div class="input-group-btn">
<button type="submit" class="btn btn-danger btn-flat"><i class="fa fa-search"></i> <button type="submit" class="btn btn-danger btn-flat"><i class="fa fa-search"></i>
@ -55,4 +57,5 @@
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
</body> </body>
</html> </html>

View file

@ -1,34 +1,36 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('includes/head') %> <%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar --> <body class="hold-transition skin-red sidebar-mini">
<%- include('includes/header') %> <div class="wrapper">
<!-- The sidebar includes the menu --> <!-- The header is the topbar -->
<%- include('includes/sidebar') %> <%- include('includes/header') %>
<!-- Content Wrapper. Contains page content --> <!-- The sidebar includes the menu -->
<div class="content-wrapper"> <%- include('includes/sidebar') %>
<!-- Content Header (Page header) --> <!-- Content Wrapper. Contains page content -->
<section class="content-header"> <div class="content-wrapper">
<h1> Команды <small> Dashboard v1.0 </small> </h1>
<ol class="breadcrumb">
<li class="active"><a href="/commands"><i class="fa fa-home"></i> Команды </a></li>
</ol>
</section>
<section class="content"> <!-- Content Header (Page header) -->
<%- md("commands.md") %> <section class="content-header">
</section> <h1> Команды <small> Dashboard v1.0 </small> </h1>
</div> <ol class="breadcrumb">
<li class="active"><a href="/commands"><i class="fa fa-home"></i> Команды </a></li>
</ol>
</section>
<!-- Footer includes credits and version --> <section class="content">
<%- include('includes/footer') %> <%- md("commands.md") %>
</section>
</div> </div>
<!-- ./wrapper -->
</body> <!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html> </html>

View file

@ -15,3 +15,5 @@
* Добавлено **множество** новых команд. * Добавлено **множество** новых команд.
* Возвращены старые категории *NSFW* и *Discord Together* (Теперь он называется *Games*) * Возвращены старые категории *NSFW* и *Discord Together* (Теперь он называется *Games*)
* Список всех команд и их описания вы можете найти [тут](/commands) (список обновляется автоматически). * Список всех команд и их описания вы можете найти [тут](/commands) (список обновляется автоматически).
> Украинский язык ещё не закончен, ожидайте его ближе к Новому Году.

View file

@ -25,11 +25,11 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<!-- Menu Footer--> <!-- Menu Footer-->
<li class="user-footer" style="min-width: auto !important;"> <li class="user-footer" style="min-width: auto !important;">
<div> <div>
<a href="/logout" class="btn btn-default btn-flat btn-block">Выйти</a> <a href="/logout" class="btn btn-default btn-flat btn-block">Выйти</a>
</div> </div>
</li> </li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -4,13 +4,15 @@
<section class="sidebar"> <section class="sidebar">
<!-- Sidebar user panel --> <!-- Sidebar user panel -->
<div class="user-panel"> <div class="user-panel">
<div class="pull-left image"> <div class="pull-left image">
<img src="<%= user.displayAvatarURL %>" class="img-circle" alt="User Image"> <img src="<%= user.displayAvatarURL %>" class="img-circle" alt="User Image">
</div> </div>
<div class="pull-left info"> <div class="pull-left info">
<p><%= user.username %></p> <p><%= user.username %></p>
<a href="#"><i class="fa fa-circle text-<%= user.status === 'dnd' ? 'danger' : user.status === 'idle' ? 'warning' : user.status === 'online' ? 'success' : ''%>"></i> <%= translate("common:STATUS_"+user.status.toUpperCase()) %></a> <a href="#"><i
</div> class="fa fa-circle text-<%= user.status === 'dnd' ? 'danger' : user.status === 'idle' ? 'warning' : user.status === 'online' ? 'success' : ''%>"></i>
<%= translate("common:STATUS_"+user.status.toUpperCase()) %></a>
</div>
</div> </div>
<!-- search form --> <!-- search form -->
<!-- <!--
@ -30,31 +32,34 @@
<ul class="sidebar-menu" data-widget="tree"> <ul class="sidebar-menu" data-widget="tree">
<li class="header"><%= translate("dashboard:SERVERS_MANAGEMENT").toUpperCase() %></li> <li class="header"><%= translate("dashboard:SERVERS_MANAGEMENT").toUpperCase() %></li>
<li class="treeview menu-open"> <li class="treeview menu-open">
<li><a href="/selector"><i class="fa fa-home"></i> <span><%= translate("dashboard:SELECTOR") %></span></a></li> <li><a href="/selector"><i class="fa fa-home"></i> <span><%= translate("dashboard:SELECTOR") %></span></a>
</li>
</li> </li>
<li class="treeview"> <li class="treeview">
<a href="/manage/"> <a href="/manage/">
<i class="fa fa-server"></i> <i class="fa fa-server"></i>
<span><%= translate("dashboard:SERVERS_LIST") %></span> <span><%= translate("dashboard:SERVERS_LIST") %></span>
<span class="pull-right-container"> <span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i> <i class="fa fa-angle-left pull-right"></i>
</span> </span>
</a> </a>
<% if(user.displayedGuilds){ %> <% if(user.displayedGuilds) { %>
<ul class="treeview-menu"> <ul class="treeview-menu">
<% user.displayedGuilds.forEach((guild) => { %> <% user.displayedGuilds.forEach((guild) => { %>
<li><a href="<%= guild.settingsUrl %>"><i class="fa fa-circle-o text-<%= guild.owner ? 'blue' : 'grey' %>"></i> <%= guild.name %></a></li> <li><a href="<%= guild.settingsUrl %>"><i
<% }); %> class="fa fa-circle-o text-<%= guild.owner ? 'blue' : 'grey' %>"></i>
</ul> <%= guild.name %></a></li>
<% }); %>
</ul>
<% } %> <% } %>
</li> </li>
</ul> </ul>
<ul class="sidebar-menu" data-widget="tree"> <ul class="sidebar-menu" data-widget="tree">
<li class="header"><%= translate("common:PROFILE").toUpperCase() %></li> <li class="header"><%= translate("common:PROFILE").toUpperCase() %></li>
<li class="treeview menu-open"> <li class="treeview menu-open">
<li><a href="/commands"><i class="fa fa-wrench"></i> <span>Команды</span></a></li> <li><a href="/commands"><i class="fa fa-wrench"></i> <span>Команды</span></a></li>
<li><a href="/updates"><i class="fa fa-wrench"></i> <span>Обновления</span></a></li> <li><a href="/updates"><i class="fa fa-wrench"></i> <span>Обновления</span></a></li>
<li><a href="/settings"><i class="fa fa-gear"></i> <span><%= translate("common:SETTINGS") %></span></a></li> <li><a href="/settings"><i class="fa fa-gear"></i> <span><%= translate("common:SETTINGS") %></span></a></li>
</li> </li>
</ul> </ul>
</section> </section>
@ -62,11 +67,12 @@
</aside> </aside>
<script> <script>
$(document).ready(function() { $(document).ready(function () {
// get current URL path and assign 'active' class // get current URL path and assign 'active' class
let pathname = window.location.pathname; let pathname = window.location.pathname;
$(`.sidebar-menu > li > a[href="${pathname}"]`).parent().addClass("active"); $(`.sidebar-menu > li > a[href="${pathname}"]`).parent().addClass("active");
$(`.sidebar-menu > li > ul > li > a[href="${window.location.pathname}"]`).parent().addClass("active"); $(`.sidebar-menu > li > ul > li > a[href="${window.location.pathname}"]`).parent().addClass("active");
$(`.sidebar-menu > li > a[href="/${window.location.pathname.split("/")[1]}/"]`).parent().addClass("active"); $(`.sidebar-menu > li > a[href="/${window.location.pathname.split("/")[1]}/"]`).parent().addClass(
"active");
}); });
</script> </script>

View file

@ -1,312 +1,345 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('../includes/head') %> <%- include('../includes/head') %>
<body class="hold-transition skin-red sidebar-mini"> <body class="hold-transition skin-red sidebar-mini">
<div class="wrapper"> <div class="wrapper">
<!-- The header is the topbar --> <!-- The header is the topbar -->
<%- include('../includes/header') %> <%- include('../includes/header') %>
<!-- The sidebar includes the menu --> <!-- The sidebar includes the menu -->
<%- include('../includes/sidebar') %> <%- include('../includes/sidebar') %>
<!-- Content Wrapper. Contains page content --> <!-- Content Wrapper. Contains page content -->
<div class="content-wrapper"> <div class="content-wrapper">
<!-- Content Header (Page header) --> <!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
<h1> <%= translate("common:CONFIGURATION") %> <small> Dashboard v1.0 </small> </h1> <h1> <%= translate("common:CONFIGURATION") %> <small> Dashboard v1.0 </small> </h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><a href="/"><i class="fa fa-home"></i> <%= translate("dashboard:SELECTOR") %></a></li> <li><a href="/"><i class="fa fa-home"></i> <%= translate("dashboard:SELECTOR") %></a></li>
<li class="active"><%= guild.name %></li> <li class="active"><%= guild.name %></li>
</ol> </ol>
</section> </section>
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="box box-widget widget-user"> <div class="box box-widget widget-user">
<div class="widget-user-header bg-aqua-active"> <div class="widget-user-header bg-aqua-active">
<h3 class="widget-user-username"><%= guild.name %></h3> <h3 class="widget-user-username"><%= guild.name %></h3>
</div>
<div class="widget-user-image">
<img class="img-circle" src="<%= guild.iconURL %>" alt="Server icon">
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-12 border-right">
<div class="description-block">
<h5 class="description-header"><%= guild.memberCount %></h5>
<span class="description-text"><%= translate("common:MEMBERS") %></span>
</div>
<!-- /.description-block -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</div>
<!-- /.box-footer -->
</div> </div>
<!-- BASIC CONFIGURATION --> <div class="widget-user-image">
<div class="box box-warning"> <img class="img-circle" src="<%= guild.iconURL %>" alt="Server icon">
<div class="box-header with-border"> </div>
<h3 class="box-title"><%= translate("dashboard:BASIC_CONF") %></h3> <div class="box-footer">
</div> <div class="row">
<form role="form" action="/manage/<%= guild.id %>/" method="POST"> <div class="col-sm-12 border-right">
<!-- /.box-header --> <div class="description-block">
<div class="box-body"> <h5 class="description-header"><%= guild.memberCount %></h5>
<!-- text input --> <span class="description-text"><%= translate("common:MEMBERS") %></span>
<div class="form-group">
<label><%= translate("common:PREFIX") %></label>
<input type="text" name="prefix" class="form-control" placeholder="<%= guild.prefix %>">
</div> </div>
<!-- select --> <!-- /.description-block -->
<div class="form-group"> </div>
<label><%= translate("common:LANGUAGE") %></label> <!-- /.col -->
<select class="form-control" name="language"> </div>
<% bot.languages.forEach((language) => { %> <!-- /.row -->
<% if(guild.language === language.name){ %> </div>
<option selected="selected"><%= language.aliases[0] %></option> <!-- /.box-footer -->
<% } else { %> </div>
<option><%= language.aliases[0] %></options> <!-- BASIC CONFIGURATION -->
<% } %> <div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:BASIC_CONF") %></h3>
</div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- text input -->
<div class="form-group">
<label><%= translate("common:PREFIX") %></label>
<input type="text" name="prefix" class="form-control"
placeholder="<%= guild.prefix %>">
</div>
<!-- select -->
<div class="form-group">
<label><%= translate("common:LANGUAGE") %></label>
<select class="form-control" name="language">
<% bot.languages.forEach((language) => { %>
<% if(guild.language === language.name) { %>
<option selected="selected"><%= language.aliases[0] %></option>
<% } else { %>
<option><%= language.aliases[0] %></options>
<% } %>
<% }) %> <% }) %>
</select> </select>
</div>
</div> </div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-primary"><%= translate("common:UPDATE") %></button>
</div>
</form>
</div>
<!-- /.box -->
<!-- SPECIAL CHANNELS -->
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:CHANNELS_CONF") %></h3>
</div> </div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST"> <!-- /.box-body -->
<!-- /.box-header --> <div class="box-footer">
<div class="box-body"> <button type="submit"
<!-- select --> class="btn btn-primary"><%= translate("common:UPDATE") %></button>
<div class="form-group"> </div>
<label><%= translate("common:SUGGESTIONS") %></label> </form>
<select class="form-control" name="suggestions">
<% if(guild.plugins.suggestions && bot.channels.cache.has(guild.plugins.suggestions)){ %>
<option selected="selected">#<%= bot.channels.cache.get(guild.plugins.suggestions).name %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text" && ch.id !== guild.plugins.suggestions).forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<option><%= translate("common:NO_CHANNEL") %></option>
<% } else { %>
<option selected="selected"><%= translate("common:NO_CHANNEL") %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<div class="form-group">
<label><%= translate("common:MODLOGS") %></label>
<select class="form-control" name="modlogs">
<% if(guild.plugins.modlogs && bot.channels.cache.has(guild.plugins.modlogs)){ %>
<option selected="selected">#<%= bot.channels.cache.get(guild.plugins.modlogs).name %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text" && ch.id !== guild.plugins.modlogs).forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<option><%= translate("common:NO_CHANNEL") %></option>
<% } else { %>
<option selected="selected"><%= translate("common:NO_CHANNEL")%></option>
<% guild.channels.cache.filter((ch) => ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<div class="form-group">
<label><%= translate("common:FORTNITESHOP") %></label>
<select class="form-control" name="fortniteshop">
<% if(guild.plugins.fortniteshop && bot.channels.cache.has(guild.plugins.fortniteshop)){ %>
<option selected="selected">#<%= bot.channels.cache.get(guild.plugins.fortniteshop).name %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text" && ch.id !== guild.plugins.fortniteshop).forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<option><%= translate("common:NO_CHANNEL") %></option>
<% } else { %>
<option selected="selected"><%= translate("common:NO_CHANNEL")%></option>
<% guild.channels.cache.filter((ch) => ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-primary"><%= translate("common:UPDATE") %></button>
</div>
</form>
</div>
<!-- /.box -->
</div> </div>
<div class="col-md-6"> <!-- /.box -->
<!-- WELCOME CONFIGURATION --> <!-- SPECIAL CHANNELS -->
<div class="box box-success"> <div class="box box-warning">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:WELCOME_CONF") %></h3> <h3 class="box-title"><%= translate("dashboard:CHANNELS_CONF") %></h3>
</div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- text input -->
<div class="form-group">
<label><%= translate("common:MESSAGE") %></label>
<textarea rows="3" name="message" class="form-control" required><%= (guild.plugins.welcome.message || translate("administration/welcome:DEFAULT_MESSAGE")) %></textarea>
</div>
<!-- select -->
<div class="form-group">
<label><%= translate("common:CHANNEL") %></label>
<select class="form-control" name="channel">
<% if(guild.plugins.welcome.enabled && bot.channels.cache.has(guild.plugins.welcome.channel)){ %>
<option selected="selected">#<%= bot.channels.cache.get(guild.plugins.welcome.channel).name %></option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.plugins.welcome.channel && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); } else { %>
<option selected="selected">#<%= guild.channels.cache.filter((ch) => ch.type === "text").first().name %></option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.channels.cache.first().id && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<!-- select -->
<div class="form-group">
<div class="checkbox">
<label>
<% if(guild.plugins.welcome.withImage || !guild.plugins.welcome.enabled) { %>
<input type="checkbox" name="withImage" checked><%= translate("dashboard:WELCOME_IMG") %>
<% } else { %>
<input type="checkbox" name="withImage"><%= translate("dashboard:WELCOME_IMG") %>
<% } %>
</label>
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<% if(guild.plugins.welcome.enabled){ %>
<button type="submit" name="welcomeDisable" class="btn btn-danger"><%= translate("dashboard:DISABLE_MESSAGES") %></button>
<button type="submit" name="welcomeUpdate" class="btn btn-primary pull-right"><%= translate("common:UPDATE") %></button>
<% } else { %>
<button type="submit" name="welcomeEnable" class="btn btn-success"><%= translate("dashboard:ENABLE_MESSAGES") %></button>
<% } %>
</div>
</form>
</div> </div>
<!-- GOODBYE CONFIGURATION --> <form role="form" action="/manage/<%= guild.id %>/" method="POST">
<div class="box box-danger"> <!-- /.box-header -->
<div class="box-header with-border"> <div class="box-body">
<h3 class="box-title"><%= translate("dashboard:GOODBYE_CONF") %></h3> <!-- select -->
<div class="form-group">
<label><%= translate("common:SUGGESTIONS") %></label>
<select class="form-control" name="suggestions">
<% if(guild.plugins.suggestions && bot.channels.cache.has(guild.plugins.suggestions)) { %>
<option selected="selected">
#<%= bot.channels.cache.get(guild.plugins.suggestions).name %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text" && ch.id !== guild.plugins.suggestions).forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<option><%= translate("common:NO_CHANNEL") %></option>
<% } else { %>
<option selected="selected"><%= translate("common:NO_CHANNEL") %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<div class="form-group">
<label><%= translate("common:MODLOGS") %></label>
<select class="form-control" name="modlogs">
<% if(guild.plugins.modlogs && bot.channels.cache.has(guild.plugins.modlogs)) { %>
<option selected="selected">
#<%= bot.channels.cache.get(guild.plugins.modlogs).name %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text" && ch.id !== guild.plugins.modlogs).forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<option><%= translate("common:NO_CHANNEL") %></option>
<% } else { %>
<option selected="selected"><%= translate("common:NO_CHANNEL")%></option>
<% guild.channels.cache.filter((ch) => ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<div class="form-group">
<label><%= translate("common:FORTNITESHOP") %></label>
<select class="form-control" name="fortniteshop">
<% if(guild.plugins.fortniteshop && bot.channels.cache.has(guild.plugins.fortniteshop)) { %>
<option selected="selected">
#<%= bot.channels.cache.get(guild.plugins.fortniteshop).name %></option>
<% guild.channels.cache.filter((ch) => ch.type === "text" && ch.id !== guild.plugins.fortniteshop).forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<option><%= translate("common:NO_CHANNEL") %></option>
<% } else { %>
<option selected="selected"><%= translate("common:NO_CHANNEL")%></option>
<% guild.channels.cache.filter((ch) => ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
</div> </div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST"> <!-- /.box-body -->
<!-- /.box-header --> <div class="box-footer">
<div class="box-body"> <button type="submit"
<!-- text input --> class="btn btn-primary"><%= translate("common:UPDATE") %></button>
<div class="form-group">
<label><%= translate("common:MESSAGE") %></label>
<textarea rows="3" name="message" class="form-control" required><%= (guild.plugins.goodbye.message || translate("administration/goodbye:DEFAULT_MESSAGE")) %></textarea>
</div>
<!-- select -->
<div class="form-group">
<label><%= translate("common:CHANNEL") %></label>
<select class="form-control" name="channel">
<% if(guild.plugins.goodbye.enabled && bot.channels.cache.has(guild.plugins.goodbye.channel)){ %>
<option selected="selected">#<%= bot.channels.cache.get(guild.plugins.goodbye.channel).name %></option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.plugins.goodbye.channel && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); } else { %>
<option selected="selected">#<%= guild.channels.cache.filter((ch) => ch.type === "text").first().name %></option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.channels.cache.first().id && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<!-- select -->
<div class="form-group">
<div class="checkbox">
<label>
<% if(guild.plugins.goodbye.withImage || !guild.plugins.goodbye.enabled) { %>
<input type="checkbox" name="withImage" checked><%= translate("dashboard:GOODBYE_IMG") %>
<% } else { %>
<input type="checkbox" name="withImage"><%= translate("dashboard:GOODBYE_IMG") %>
<% } %>
</label>
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<% if(guild.plugins.goodbye.enabled){ %>
<button type="submit" name="goodbyeDisable" class="btn btn-danger"><%= translate("dashboard:DISABLE_MESSAGES") %></button>
<button type="submit" name="goodbyeUpdate" class="btn btn-primary pull-right"><%= translate("common:UPDATE") %></button>
<% } else { %>
<button type="submit" name="goodbyeEnable" class="btn btn-success"><%= translate("dashboard:ENABLE_MESSAGES") %></button>
<% } %>
</div>
</form>
</div>
<!-- AUTOROLE CONFIGURATION -->
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:AUTOROLE_CONF") %></h3>
</div> </div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST"> </form>
<!-- /.box-header -->
<div class="box-body">
<!-- select -->
<div class="form-group">
<label><%= translate("common:ROLE") %></label>
<select class="form-control" name="role">
<% if(guild.plugins.autorole.enabled && guild.roles.cache.has(guild.plugins.autorole.role)){ %>
<option selected="selected">@<%= guild.roles.cache.get(guild.plugins.autorole.role).name %></option>
<% guild.roles.cache.filter((r) => r.id !== guild.plugins.autorole.role && r.name !== "@everyone").forEach((r) => { %>
<option>@<%= r.name %></option>
<% }); } else { %>
<option selected="selected">@<%= guild.roles.cache.filter((r) => r.name !== "@everyone").first().name %></option>
<% guild.roles.cache.filter((r) => r.id !== guild.roles.cache.filter((r) => r.name !== "@everyone").first().id && r.name !== "@everyone").forEach((r) => { %>
<option>@<%= r.name %></option>
<% }); %>
<% } %>
</select>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<% if(guild.plugins.autorole.enabled){ %>
<button type="submit" name="autoroleDisable" class="btn btn-danger"><%= translate("dashboard:DISABLE_AUTOROLE") %></button>
<button type="submit" name="autoroleUpdate" class="btn btn-primary pull-right"><%= translate("common:UPDATE") %></button>
<% } else { %>
<button type="submit" name="autoroleEnable" class="btn btn-success"><%= translate("dashboard:ENABLE_AUTOROLE") %></button>
<% } %>
</div>
</form>
</div>
<!-- /.box -->
</div> </div>
<!-- /.box -->
</div>
<div class="col-md-6">
<!-- WELCOME CONFIGURATION -->
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:WELCOME_CONF") %></h3>
</div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- text input -->
<div class="form-group">
<label><%= translate("common:MESSAGE") %></label>
<textarea rows="3" name="message" class="form-control"
required><%= (guild.plugins.welcome.message || translate("administration/welcome:DEFAULT_MESSAGE")) %></textarea>
</div>
<!-- select -->
<div class="form-group">
<label><%= translate("common:CHANNEL") %></label>
<select class="form-control" name="channel">
<% if(guild.plugins.welcome.enabled && bot.channels.cache.has(guild.plugins.welcome.channel)) { %>
<option selected="selected">
#<%= bot.channels.cache.get(guild.plugins.welcome.channel).name %>
</option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.plugins.welcome.channel && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); } else { %>
<option selected="selected">
#<%= guild.channels.cache.filter((ch) => ch.type === "text").first().name %>
</option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.channels.cache.first().id && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<!-- select -->
<div class="form-group">
<div class="checkbox">
<label>
<% if(guild.plugins.welcome.withImage || !guild.plugins.welcome.enabled) { %>
<input type="checkbox" name="withImage"
checked><%= translate("dashboard:WELCOME_IMG") %>
<% } else { %>
<input type="checkbox"
name="withImage"><%= translate("dashboard:WELCOME_IMG") %>
<% } %>
</label>
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<% if(guild.plugins.welcome.enabled) { %>
<button type="submit" name="welcomeDisable"
class="btn btn-danger"><%= translate("dashboard:DISABLE_MESSAGES") %></button>
<button type="submit" name="welcomeUpdate"
class="btn btn-primary pull-right"><%= translate("common:UPDATE") %></button>
<% } else { %>
<button type="submit" name="welcomeEnable"
class="btn btn-success"><%= translate("dashboard:ENABLE_MESSAGES") %></button>
<% } %>
</div>
</form>
</div>
<!-- GOODBYE CONFIGURATION -->
<div class="box box-danger">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:GOODBYE_CONF") %></h3>
</div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- text input -->
<div class="form-group">
<label><%= translate("common:MESSAGE") %></label>
<textarea rows="3" name="message" class="form-control"
required><%= (guild.plugins.goodbye.message || translate("administration/goodbye:DEFAULT_MESSAGE")) %></textarea>
</div>
<!-- select -->
<div class="form-group">
<label><%= translate("common:CHANNEL") %></label>
<select class="form-control" name="channel">
<% if(guild.plugins.goodbye.enabled && bot.channels.cache.has(guild.plugins.goodbye.channel)) { %>
<option selected="selected">
#<%= bot.channels.cache.get(guild.plugins.goodbye.channel).name %>
</option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.plugins.goodbye.channel && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); } else { %>
<option selected="selected">
#<%= guild.channels.cache.filter((ch) => ch.type === "text").first().name %>
</option>
<% guild.channels.cache.filter((ch) => ch.id !== guild.channels.cache.first().id && ch.type === "text").forEach((ch) => { %>
<option>#<%= ch.name %></option>
<% }); %>
<% } %>
</select>
</div>
<!-- select -->
<div class="form-group">
<div class="checkbox">
<label>
<% if(guild.plugins.goodbye.withImage || !guild.plugins.goodbye.enabled) { %>
<input type="checkbox" name="withImage"
checked><%= translate("dashboard:GOODBYE_IMG") %>
<% } else { %>
<input type="checkbox"
name="withImage"><%= translate("dashboard:GOODBYE_IMG") %>
<% } %>
</label>
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<% if(guild.plugins.goodbye.enabled) { %>
<button type="submit" name="goodbyeDisable"
class="btn btn-danger"><%= translate("dashboard:DISABLE_MESSAGES") %></button>
<button type="submit" name="goodbyeUpdate"
class="btn btn-primary pull-right"><%= translate("common:UPDATE") %></button>
<% } else { %>
<button type="submit" name="goodbyeEnable"
class="btn btn-success"><%= translate("dashboard:ENABLE_MESSAGES") %></button>
<% } %>
</div>
</form>
</div>
<!-- AUTOROLE CONFIGURATION -->
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:AUTOROLE_CONF") %></h3>
</div>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- select -->
<div class="form-group">
<label><%= translate("common:ROLE") %></label>
<select class="form-control" name="role">
<% if(guild.plugins.autorole.enabled && guild.roles.cache.has(guild.plugins.autorole.role)) { %>
<option selected="selected">
@<%= guild.roles.cache.get(guild.plugins.autorole.role).name %></option>
<% guild.roles.cache.filter((r) => r.id !== guild.plugins.autorole.role && r.name !== "@everyone").forEach((r) => { %>
<option>@<%= r.name %></option>
<% }); } else { %>
<option selected="selected">
@<%= guild.roles.cache.filter((r) => r.name !== "@everyone").first().name %>
</option>
<% guild.roles.cache.filter((r) => r.id !== guild.roles.cache.filter((r) => r.name !== "@everyone").first().id && r.name !== "@everyone").forEach((r) => { %>
<option>@<%= r.name %></option>
<% }); %>
<% } %>
</select>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<% if(guild.plugins.autorole.enabled) { %>
<button type="submit" name="autoroleDisable"
class="btn btn-danger"><%= translate("dashboard:DISABLE_AUTOROLE") %></button>
<button type="submit" name="autoroleUpdate"
class="btn btn-primary pull-right"><%= translate("common:UPDATE") %></button>
<% } else { %>
<button type="submit" name="autoroleEnable"
class="btn btn-success"><%= translate("dashboard:ENABLE_AUTOROLE") %></button>
<% } %>
</div>
</form>
</div>
<!-- /.box -->
</div>
<div> <div>
</section> </section>
<!-- Footer includes credits and version --> <!-- Footer includes credits and version -->
</div>
<!-- /.content-wrapper -->
<%- include('../includes/footer') %>
</div> </div>
<!-- ./wrapper --> <!-- /.content-wrapper -->
</body>
<%- include('../includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html> </html>

View file

@ -1,76 +1,82 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('includes/head') %> <%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- The sidebar includes the menu --> <body class="hold-transition skin-red sidebar-mini">
<%- include('includes/sidebar') %> <div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- Content Wrapper. Contains page content --> <!-- The sidebar includes the menu -->
<div class="content-wrapper"> <%- include('includes/sidebar') %>
<!-- Content Header (Page header) -->
<section class="content-header">
<h1> <%= translate("dashboard:SELECTOR") %> <small> Dashboard v1.0 </small> </h1>
<ol class="breadcrumb">
<li class="active"><a href="/"><i class="fa fa-home"></i> <%= translate("dashboard:SELECTOR") %></a></li>
</ol>
</section>
<section class="content"> <!-- Content Wrapper. Contains page content -->
<div class="row"> <div class="content-wrapper">
<% if(user.displayedGuilds){ user.displayedGuilds.forEach(function(guild) { %> <!-- Content Header (Page header) -->
<!-- Displays 4 servers by line --> <section class="content-header">
<div class="col-md-3"> <h1> <%= translate("dashboard:SELECTOR") %> <small> Dashboard v1.0 </small> </h1>
<div class="box box-solid"> <ol class="breadcrumb">
<div class="box-header text-center"> <li class="active"><a href="/"><i class="fa fa-home"></i> <%= translate("dashboard:SELECTOR") %></a>
<i class="fas fa-crown"></i> </li>
<h3 class="box-title server-name"><%= guild.name %></h3> </ol>
</div> </section>
<!-- /.box-header -->
<div class="box-body"> <section class="content">
<div class="text-center"> <div class="row">
<img src="<%= guild.iconURL %>" style="border-radius:100%" width="100" height="100" class="img-fluid"> <% if(user.displayedGuilds) { user.displayedGuilds.forEach(function(guild) { %>
</div> <!-- Displays 4 servers by line -->
</div> <div class="col-md-3">
<!-- /.box-body --> <div class="box box-solid">
<div class="box-footer"> <div class="box-header text-center">
<a href="<%= guild.settingsUrl %>"><button class="btn btn-block btn-success"><%= translate("dashboard:MANAGE") %></button></a> <i class="fas fa-crown"></i>
</div> <h3 class="box-title server-name"><%= guild.name %></h3>
<!-- /.box-footer -->
</div> </div>
<!-- /.box --> <!-- /.box-header -->
</div> <div class="box-body">
<!-- /.col --> <div class="text-center">
<% }); } else { %> <img src="<%= guild.iconURL %>" style="border-radius:100%" width="100" height="100"
<div class="col-md-12"> class="img-fluid">
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:NO_SERVER") %></h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
</div>
<!-- /.box-tools -->
</div> </div>
<!-- /.box-header -->
<div class="box-body">
<%= translate("dashboard:NO_SERVER_CONTENT") %>
</div>
<!-- /.box-body -->
</div> </div>
<!-- /.box --> <!-- /.box-body -->
<div class="box-footer">
<a href="<%= guild.settingsUrl %>"><button
class="btn btn-block btn-success"><%= translate("dashboard:MANAGE") %></button></a>
</div>
<!-- /.box-footer -->
</div> </div>
<% } %> <!-- /.box -->
</div> </div>
</section> <!-- /.col -->
<% }); } else { %>
<div class="col-md-12">
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:NO_SERVER") %></h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i
class="fa fa-minus"></i>
</button>
</div>
<!-- /.box-tools -->
</div>
<!-- /.box-header -->
<div class="box-body">
<%= translate("dashboard:NO_SERVER_CONTENT") %>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<% } %>
</div> </div>
</section>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div> </div>
<!-- ./wrapper -->
</body> <!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html> </html>

View file

@ -1,97 +1,102 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('includes/head') %> <%- include('includes/head') %>
<!-- bootstrap datepicker --> <!-- bootstrap datepicker -->
<link rel="stylesheet" href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css">
<body class="hold-transition skin-red sidebar-mini"> <body class="hold-transition skin-red sidebar-mini">
<div class="wrapper"> <div class="wrapper">
<!-- The header is the topbar --> <!-- The header is the topbar -->
<%- include('includes/header') %> <%- include('includes/header') %>
<!-- The sidebar includes the menu --> <!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %> <%- include('includes/sidebar') %>
<!-- Content Wrapper. Contains page content --> <!-- Content Wrapper. Contains page content -->
<div class="content-wrapper"> <div class="content-wrapper">
<!-- Content Header (Page header) --> <!-- Content Header (Page header) -->
<section class="content-header"> <section class="content-header">
<h1> <%= translate("UTILS").SETTINGS %> <small> Dashboard v1.0 </small> </h1> <h1> <%= translate("UTILS").SETTINGS %> <small> Dashboard v1.0 </small> </h1>
</section> </section>
<!-- Main content --> <!-- Main content -->
<section class="content"> <section class="content">
<!-- Info boxes --> <!-- Info boxes -->
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<!-- general form elements --> <!-- general form elements -->
<div class="box box-primary"> <div class="box box-primary">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"><%= translate("economy/profile:YOUR_PROFILE") %></h3> <h3 class="box-title"><%= translate("economy/profile:YOUR_PROFILE") %></h3>
</div> </div>
<!-- /.box-header --> <!-- /.box-header -->
<!-- form start --> <!-- form start -->
<form role="form" action="/settings" method="POST"> <form role="form" action="/settings" method="POST">
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label><%= translate("economy/profile:BIO") %></label> <label><%= translate("economy/profile:BIO") %></label>
<input name="bio" class="form-control" placeholder="<%= user.bio || translate("economy/profile:NO_BIO") %>"> <input name="bio" class="form-control"
</div> placeholder="<%= user.bio || translate("economy/profile:NO_BIO") %>">
<div class="form-group">
<label><%= translate("economy/profile:BIRTHDATE") %></label>
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" name="birthdate" class="form-control pull-right" id="datepicker" placeholder="<%= printDate(new Date(user.birthdate)) %>">
</div>
<!-- /.input group -->
</div>
<!-- /.form group -->
</div> </div>
<div class="form-group">
<label><%= translate("economy/profile:BIRTHDATE") %></label>
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" name="birthdate" class="form-control pull-right"
id="datepicker"
placeholder="<%= printDate(new Date(user.birthdate)) %>">
</div>
<!-- /.input group -->
</div>
<!-- /.form group -->
</div> </div>
</div> </div>
<!-- /.box-body --> </div>
<div class="box-footer"> <!-- /.box-body -->
<button type="submit" class="btn btn-primary"><%= translate("common:UPDATE") %></button> <div class="box-footer">
</div> <button type="submit"
</form> class="btn btn-primary"><%= translate("common:UPDATE") %></button>
</div> </div>
<!-- /.box --> </form>
</div> </div>
<!-- ./col --> <!-- /.box -->
</div> </div>
<!-- /.row --> <!-- ./col -->
</section> </div>
<!-- /.content --> <!-- /.row -->
</div> </section>
<!-- /.content-wrapper --> <!-- /.content -->
<%- include('includes/footer') %>
</div> </div>
<!-- ./wrapper --> <!-- /.content-wrapper -->
<!-- bootstrap datepicker --> <%- include('includes/footer') %>
<script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script> </div>
<!-- ChartJS --> <!-- ./wrapper -->
<script src="/bower_components/chart.js/Chart.js"></script> <!-- bootstrap datepicker -->
<script> <script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
$(function(){ <!-- ChartJS -->
$("#datepicker").datepicker({ <script src="/bower_components/chart.js/Chart.js"></script>
language: "ru", <script>
title: "Выбор даты", $(function () {
format: 'dd/mm/yyyy', $("#datepicker").datepicker({
clearBtn: true, language: "ru",
autoclose: true, title: "Выбор даты",
zIndexOffset: 5 format: 'dd/mm/yyyy',
}); clearBtn: true,
autoclose: true,
zIndexOffset: 5
}); });
</script> });
</body> </script>
</body>
</html> </html>

View file

@ -1,34 +1,36 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<%- include('includes/head') %> <%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar --> <body class="hold-transition skin-red sidebar-mini">
<%- include('includes/header') %> <div class="wrapper">
<!-- The sidebar includes the menu --> <!-- The header is the topbar -->
<%- include('includes/sidebar') %> <%- include('includes/header') %>
<!-- Content Wrapper. Contains page content --> <!-- The sidebar includes the menu -->
<div class="content-wrapper"> <%- include('includes/sidebar') %>
<!-- Content Header (Page header) --> <!-- Content Wrapper. Contains page content -->
<section class="content-header"> <div class="content-wrapper">
<h1> Обновления <small> Dashboard v1.0 </small> </h1>
<ol class="breadcrumb">
<li class="active"><a href="/updates"><i class="fa fa-home"></i> Обновления </a></li>
</ol>
</section>
<section class="content"> <!-- Content Header (Page header) -->
<%- md("updates.md") %> <section class="content-header">
</section> <h1> Обновления <small> Dashboard v1.0 </small> </h1>
</div> <ol class="breadcrumb">
<li class="active"><a href="/updates"><i class="fa fa-home"></i> Обновления </a></li>
</ol>
</section>
<!-- Footer includes credits and version --> <section class="content">
<%- include('includes/footer') %> <%- md("updates.md") %>
</section>
</div> </div>
<!-- ./wrapper -->
</body> <!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html> </html>

View file

@ -19,12 +19,7 @@ module.exports = class {
if (!userData.achievements.invite.achieved) { if (!userData.achievements.invite.achieved) {
userData.achievements.invite.progress.now += 1; userData.achievements.invite.progress.now += 1;
userData.achievements.invite.achieved = true; userData.achievements.invite.achieved = true;
messageOptions.files = [ messageOptions.files = [{ name: "unlocked.png", attachment: "./assets/img/achievements/achievement_unlocked7.png" }];
{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked7.png"
}
];
userData.markModified("achievements.invite"); userData.markModified("achievements.invite");
await userData.save(); await userData.save();
}; };

View file

@ -38,9 +38,7 @@ module.exports = class {
}; };
// Check if the autorole is enabled // Check if the autorole is enabled
if (guildData.plugins.autorole.enabled) { if (guildData.plugins.autorole.enabled) member.roles.add(guildData.plugins.autorole.role).catch(() => {});
member.roles.add(guildData.plugins.autorole.role).catch(() => {});
};
// Check if welcome message is enabled // Check if welcome message is enabled
if (guildData.plugins.welcome.enabled) { if (guildData.plugins.welcome.enabled) {

View file

@ -12,7 +12,8 @@ module.exports = class {
userData.achievements.tip.achieved = true; userData.achievements.tip.achieved = true;
userData.markModified("achievements.tip"); userData.markModified("achievements.tip");
await userData.save(); await userData.save();
newMember.send({ files: [ { name: "unlocked.png", attachment: "./assets/img/achievements/achievement_unlocked5.png"} ] });
newMember.send({ files: [{ name: "unlocked.png", attachment: "./assets/img/achievements/achievement_unlocked5.png"} ]});
}; };
} }
}; };

View file

@ -9,7 +9,7 @@ module.exports = class {
async run (message) { async run (message) {
const data = {}; const data = {};
// If the messagr author is a bot // If the message author is a bot
if (message.author.bot) return; if (message.author.bot) return;
// If the member on a guild is invisible or not cached, fetch them. // If the member on a guild is invisible or not cached, fetch them.
@ -26,14 +26,11 @@ module.exports = class {
// Check if the bot was mentionned // Check if the bot was mentionned
if (message.content.match(new RegExp(`^<@!?${client.user.id}>( |)$`))) { if (message.content.match(new RegExp(`^<@!?${client.user.id}>( |)$`))) {
if (message.guild) { if (message.guild) return message.sendT("misc:HELLO_SERVER", { username: message.author.username, prefix: data.guild.prefix });
return message.sendT("misc:HELLO_SERVER", { username: message.author.username, prefix: data.guild.prefix }); else return message.sendT("misc:HELLO_DM", { username: message.author.username });
} else {
return message.sendT("misc:HELLO_DM", { username: message.author.username });
};
}; };
if (message.includes === "@someone" && message.guild) return client.commands.get("someone").run(message, null, data); if (message.content.includes("@someone") && message.guild) return client.commands.get("someone").run(message, null, data);
if (message.guild) { if (message.guild) {
// Gets the data of the member // Gets the data of the member
@ -55,6 +52,7 @@ module.exports = class {
if (uSlowmode.time > Date.now()) { if (uSlowmode.time > Date.now()) {
message.delete(); message.delete();
const delay = message.convertTime(uSlowmode.time, "to", true); const delay = message.convertTime(uSlowmode.time, "to", true);
return message.author.send(message.translate("administration/slowmode:PLEASE_WAIT", { time: delay, channel: message.channel.toString() })); return message.author.send(message.translate("administration/slowmode:PLEASE_WAIT", { time: delay, channel: message.channel.toString() }));
} else { } else {
uSlowmode.time = channelSlowmode.time + Date.now(); uSlowmode.time = channelSlowmode.time + Date.now();
@ -89,9 +87,7 @@ module.exports = class {
message.mentions.users.forEach(async (u) => { message.mentions.users.forEach(async (u) => {
const userData = await client.findOrCreateUser({ id: u.id }); const userData = await client.findOrCreateUser({ id: u.id });
if (userData.afk) { if (userData.afk) message.error("general/setafk:IS_AFK", { user: u.tag, reason: userData.afk });
message.error("general/setafk:IS_AFK", { user: u.tag, reason: userData.afk });
};
}); });
}; };
@ -112,21 +108,23 @@ module.exports = class {
if (message.guild && data.guild.ignoredChannels.includes(message.channel.id) && !message.member.hasPermission("MANAGE_MESSAGES")) { if (message.guild && data.guild.ignoredChannels.includes(message.channel.id) && !message.member.hasPermission("MANAGE_MESSAGES")) {
message.delete(); message.delete();
message.author.send(message.translate("misc:RESTRICTED_CHANNEL", { channel: message.channel.toString() })); message.author.send(message.translate("misc:RESTRICTED_CHANNEL", { channel: message.channel.toString() }));
return; return;
}; };
if (customCommandAnswer) return message.channel.send(customCommandAnswer); if (customCommandAnswer) return message.channel.send(customCommandAnswer);
if (cmd.conf.guildOnly && !message.guild) return message.error("misc:GUILD_ONLY"); if (cmd.conf.guildOnly && !message.guild) return message.error("misc:GUILD_ONLY");
if (message.guild) { if (message.guild) {
let neededPermissions = []; let neededPermissions = [];
if (!cmd.conf.botPermissions.includes("EMBED_LINKS")) cmd.conf.botPermissions.push("EMBED_LINKS"); if (!cmd.conf.botPermissions.includes("EMBED_LINKS")) cmd.conf.botPermissions.push("EMBED_LINKS");
cmd.conf.botPermissions.forEach((perm) => { cmd.conf.botPermissions.forEach((perm) => {
if (!message.channel.permissionsFor(message.guild.me).has(perm)) { if (!message.channel.permissionsFor(message.guild.me).has(perm)) {
neededPermissions.push(perm); neededPermissions.push(perm);
}; };
}); });
if (neededPermissions.length > 0) return message.error("misc:MISSING_BOT_PERMS", { list: neededPermissions.map((p) => `\`${p}\``).join(", ") }); if (neededPermissions.length > 0) return message.error("misc:MISSING_BOT_PERMS", { list: neededPermissions.map((p) => `\`${p}\``).join(", ") });
neededPermissions = []; neededPermissions = [];
@ -135,13 +133,13 @@ module.exports = class {
neededPermissions.push(perm); neededPermissions.push(perm);
}; };
}); });
if (neededPermissions.length > 0) return message.error("misc:MISSING_MEMBER_PERMS", { list: neededPermissions.map((p) => `\`${p}\``).join(", ") }); if (neededPermissions.length > 0) return message.error("misc:MISSING_MEMBER_PERMS", { list: neededPermissions.map((p) => `\`${p}\``).join(", ") });
if (!message.channel.permissionsFor(message.member).has("MENTION_EVERYONE") && (message.content.includes("@everyone") || message.content.includes("@here"))) return message.error("misc:EVERYONE_MENTION"); if (!message.channel.permissionsFor(message.member).has("MENTION_EVERYONE") && (message.content.includes("@everyone") || message.content.includes("@here"))) return message.error("misc:EVERYONE_MENTION");
if (!message.channel.nsfw && cmd.conf.nsfw) return message.error("misc:NSFW_COMMAND"); if (!message.channel.nsfw && cmd.conf.nsfw) return message.error("misc:NSFW_COMMAND");
}; };
if (!cmd.conf.enabled) return message.error("misc:COMMAND_DISABLED"); if (!cmd.conf.enabled) return message.error("misc:COMMAND_DISABLED");
if (cmd.conf.ownerOnly && message.author.id !== client.config.owner.id) return message.error("misc:OWNER_ONLY"); if (cmd.conf.ownerOnly && message.author.id !== client.config.owner.id) return message.error("misc:OWNER_ONLY");
let uCooldown = cmdCooldown[message.author.id]; let uCooldown = cmdCooldown[message.author.id];
@ -149,6 +147,7 @@ module.exports = class {
cmdCooldown[message.author.id] = {}; cmdCooldown[message.author.id] = {};
uCooldown = cmdCooldown[message.author.id]; uCooldown = cmdCooldown[message.author.id];
}; };
const time = uCooldown[cmd.help.name] || 0; const time = uCooldown[cmd.help.name] || 0;
if (time && (time > Date.now())) return message.error("misc:COOLDOWNED", { seconds: Math.ceil((time-Date.now())/1000) }); if (time && (time > Date.now())) return message.error("misc:COOLDOWNED", { seconds: Math.ceil((time-Date.now())/1000) });
cmdCooldown[message.author.id][cmd.help.name] = Date.now() + cmd.conf.cooldown; cmdCooldown[message.author.id][cmd.help.name] = Date.now() + cmd.conf.cooldown;
@ -167,12 +166,10 @@ module.exports = class {
data.userData.achievements.firstCommand.achieved = true; data.userData.achievements.firstCommand.achieved = true;
data.userData.markModified("achievements.firstCommand"); data.userData.markModified("achievements.firstCommand");
await data.userData.save(); await data.userData.save();
await message.channel.send({ files: [ await message.channel.send({ files: [{
{ name: "unlocked.png",
name: "unlocked.png", attachment: "./assets/img/achievements/achievement_unlocked2.png"
attachment: "./assets/img/achievements/achievement_unlocked2.png" }]});
}
]});
}; };
try { try {

View file

@ -8,34 +8,34 @@ module.exports = class {
async run () { async run () {
const client = this.client; const client = this.client;
// Logs some informations using the logger file // Logs some informations using logger
client.logger.log(`Loading a total of ${client.commands.size} command(s).`, "log"); client.logger.log(`Loading a total of ${client.commands.size} command(s).`, "log");
client.logger.log(`${client.user.tag}, ready to serve ${client.users.cache.size} users in ${client.guilds.cache.filter(guild => guild.id != "568120814776614924" && guild.id != "892727526911258654").size} servers.`, "ready"); client.logger.log(`${client.user.tag}, ready to serve ${client.users.cache.size} users in ${client.guilds.cache.filter(guild => guild.id != "568120814776614924" && guild.id != "892727526911258654").size} servers.`, "ready");
/* Discord Together */ // Discord Together
const discordtogether = require("../helpers/discordTogether"); const discordtogether = require("../helpers/discordTogether");
discordtogether.init(client); discordtogether.init(client);
/* DiscordBots.org STATS */ // DiscordBots.org STATS
const discordbotsorg = require("../helpers/discordbots.org"); const discordbotsorg = require("../helpers/discordbots.org");
discordbotsorg.init(client); discordbotsorg.init(client);
/* UNMUTE USERS */ // UNMUTE USERS
const checkUnmutes = require("../helpers/checkUnmutes"); const checkUnmutes = require("../helpers/checkUnmutes");
checkUnmutes.init(client); checkUnmutes.init(client);
/* SEND REMINDS */ // SEND REMINDS
const checkReminds = require("../helpers/checkReminds"); const checkReminds = require("../helpers/checkReminds");
checkReminds.init(client); checkReminds.init(client);
/* DAILY SHOP FORTNITE */ // DAILY SHOP FORTNITE
const fortniteShop = require("../helpers/fortniteShop"); const fortniteShop = require("../helpers/fortniteShop");
fortniteShop.init(client); fortniteShop.init(client);
// Start the dashboard // Start the dashboard
if (client.config.dashboard.enabled) client.dashboard.load(client); if (client.config.dashboard.enabled) client.dashboard.load(client);
// Update the game every 20s // Update status every 20s
const status = [ const status = [
{ name: `{servers} сервер(а/ов)`, type: "WATCHING" }, { name: `{servers} сервер(а/ов)`, type: "WATCHING" },
{ name: "help", type: "WATCHING" } { name: "help", type: "WATCHING" }
@ -43,8 +43,9 @@ module.exports = class {
const version = require("../package.json").version; const version = require("../package.json").version;
let i = 0; let i = 0;
setInterval(function() { setInterval(function() {
const toDisplay = status[parseInt(i, 10)].name.replace("{servers}", client.guilds.cache.filter(guild => guild.id != "568120814776614924" && guild.id != "892727526911258654").size) + " | v" + version; const random = status[parseInt(i, 10)];
client.user.setActivity(toDisplay, { type: status[parseInt(i, 10)].type }); const toDisplay = random.name.replace("{servers}", client.guilds.cache.filter(guild => guild.id != "568120814776614924" && guild.id != "892727526911258654").size) + " | v" + version;
client.user.setActivity(toDisplay, { type: random.type });
if (status[parseInt(i + 1, 10)]) i++; if (status[parseInt(i + 1, 10)]) i++;
else i = 0; else i = 0;
}, 20000); // Every 20 seconds }, 20000); // Every 20 seconds

View file

@ -17,11 +17,8 @@ module.exports = {
categories.sort(function(a, b) { categories.sort(function(a, b) {
const aCmdsLength = commands.filter((cmd) => cmd.help.category === a).array().length; const aCmdsLength = commands.filter((cmd) => cmd.help.category === a).array().length;
const bCmdsLength = commands.filter((cmd) => cmd.help.category === b).array().length; const bCmdsLength = commands.filter((cmd) => cmd.help.category === b).array().length;
if (aCmdsLength > bCmdsLength) { if (aCmdsLength > bCmdsLength) return -1;
return -1; else return 1;
} else {
return 1;
};
}).forEach((cat) => { }).forEach((cat) => {
const arrCat = [ const arrCat = [
[ "Название", "Описание", "Использование", "Откат" ] [ "Название", "Описание", "Использование", "Откат" ]
@ -29,11 +26,8 @@ module.exports = {
const cmds = commands.filter((cmd) => cmd.help.category === cat).array(); const cmds = commands.filter((cmd) => cmd.help.category === cat).array();
text += `### ${cat} (${cmds.length} команд(а/ы))\n\n`; text += `### ${cat} (${cmds.length} команд(а/ы))\n\n`;
cmds.sort(function(a, b) { cmds.sort(function(a, b) {
if (a.help.name < b.help.name) { if (a.help.name < b.help.name) return -1;
return -1; else return 1;
} else {
return 1;
};
}).forEach((cmd) => { }).forEach((cmd) => {
arrCat.push([ arrCat.push([
`**${cmd.help.name}** ${cmd.help.aliases.length ? `**(${cmd.help.aliases.join(", ")})**` : ""}`, `**${cmd.help.name}** ${cmd.help.aliases.length ? `**(${cmd.help.aliases.join(", ")})**` : ""}`,
@ -45,14 +39,20 @@ module.exports = {
text += `${table(arrCat)}\n\n`; text += `${table(arrCat)}\n\n`;
}); });
if (!fs.existsSync("./dashboard/views/docs")) fs.mkdirSync("./dashboard/views/docs"); if (!fs.existsSync("./dashboard/views/docs")) {
if (fs.existsSync("./dashboard/views/docs")) { fs.mkdirSync("./dashboard/views/docs");
fs.writeFileSync("./dashboard/views/docs/commands.md", text);
client.logger.log("Dashboard docs updated!");
} else if (fs.existsSync("./dashboard/views/docs")) {
fs.writeFileSync("./dashboard/views/docs/commands.md", text); fs.writeFileSync("./dashboard/views/docs/commands.md", text);
client.logger.log("Dashboard docs updated!"); client.logger.log("Dashboard docs updated!");
}; };
if (!fs.existsSync("./docs")) fs.mkdirSync("./docs"); if (!fs.existsSync("./docs")) {
if (fs.existsSync("./docs")) { fs.mkdirSync("./docs");
fs.writeFileSync("./docs/commands.md", text);
client.logger.log("Docs updated!");
} else if (fs.existsSync("./docs")) {
fs.writeFileSync("./docs/commands.md", text); fs.writeFileSync("./docs/commands.md", text);
client.logger.log("Docs updated!"); client.logger.log("Docs updated!");
}; };

View file

@ -34,9 +34,7 @@ module.exports = {
}); });
user.reminds = user.reminds.filter((r) => r.sendAt >= dateNow); user.reminds = user.reminds.filter((r) => r.sendAt >= dateNow);
user.save(); user.save();
if (user.reminds.length === 0) { if (user.reminds.length === 0) client.databaseCache.usersReminds.delete(user.id);
client.databaseCache.usersReminds.delete(user.id);
};
}; };
}; };
}); });

View file

@ -24,6 +24,7 @@ module.exports = {
}; };
memberData.save(); memberData.save();
client.logger.log("[unmute] "+memberData.id+" cannot be found."); client.logger.log("[unmute] "+memberData.id+" cannot be found.");
return null; return null;
}); });
const guildData = await client.findOrCreateGuild({ id: guild.id }); const guildData = await client.findOrCreateGuild({ id: guild.id });
@ -44,9 +45,8 @@ module.exports = {
.setColor("#f44271") .setColor("#f44271")
.setFooter(guild.client.config.embed.footer); .setFooter(guild.client.config.embed.footer);
const channel = guild.channels.cache.get(guildData.plugins.modlogs); const channel = guild.channels.cache.get(guildData.plugins.modlogs);
if (channel) { if (channel) channel.send(embed);
channel.send(embed);
};
memberData.mute = { memberData.mute = {
muted: false, muted: false,
endDate: null, endDate: null,

View file

@ -22,12 +22,8 @@ module.exports = {
user: dUser.tag user: dUser.tag
})).catch(() => {}); })).catch(() => {});
const logsChannel = client.channels.cache.get(client.config.votes.channel); const logsChannel = client.channels.cache.get(client.config.votes.channel);
if (logsChannel) {
logsChannel.send(client.translate("misc:VOTE_LOGS", { if (logsChannel) logsChannel.send(client.translate("misc:VOTE_LOGS", { userid: dUser.id, usertag: dUser.tag }));
userid: dUser.id,
usertag: dUser.tag
}));
};
}); });
}; };
} }

View file

@ -4,26 +4,28 @@ const config = require("../config");
Guild.prototype.translate = function(key, args) { Guild.prototype.translate = function(key, args) {
const language = this.client.translations.get(this.data.language); const language = this.client.translations.get(this.data.language);
if (!language) throw "Message: Invalid language set in data."; if (!language) throw "Message: Invalid language set in data.";
return language(key, args); return language(key, args);
}; };
Message.prototype.translate = function(key, args) { Message.prototype.translate = function(key, args) {
const language = this.client.translations.get( const language = this.client.translations.get(this.guild ? this.guild.data.language : "ru-RU");
this.guild ? this.guild.data.language : "ru-RU"
);
if (!language) throw "Message: Invalid language set in data."; if (!language) throw "Message: Invalid language set in data.";
return language(key, args); return language(key, args);
}; };
// Wrapper for sendT with error emoji // Wrapper for sendT with error emoji
Message.prototype.error = function(key, args, options = {}) { Message.prototype.error = function(key, args, options = {}) {
options.prefixEmoji = "error"; options.prefixEmoji = "error";
return this.sendT(key, args, options); return this.sendT(key, args, options);
}; };
// Wrapper for sendT with success emoji // Wrapper for sendT with success emoji
Message.prototype.success = function(key, args, options = {}) { Message.prototype.success = function(key, args, options = {}) {
options.prefixEmoji = "success"; options.prefixEmoji = "success";
return this.sendT(key, args, options); return this.sendT(key, args, options);
}; };
@ -31,11 +33,9 @@ Message.prototype.success = function(key, args, options = {}) {
Message.prototype.sendT = function(key, args, options = {}) { Message.prototype.sendT = function(key, args, options = {}) {
let string = this.translate(key, args); let string = this.translate(key, args);
if (options.prefixEmoji) string = `${this.client.customEmojis[options.prefixEmoji]} | ${string}`; if (options.prefixEmoji) string = `${this.client.customEmojis[options.prefixEmoji]} | ${string}`;
if (options.edit) {
return this.edit(string); if (options.edit) return this.edit(string);
} else { else return this.channel.send(string);
return this.channel.send(string);
};
}; };
// Format a date // Format a date
@ -50,15 +50,18 @@ Message.prototype.convertTime = function(time, type, noPrefix) {
MessageEmbed.prototype.errorColor = function() { MessageEmbed.prototype.errorColor = function() {
this.setColor("#FF0000"); this.setColor("#FF0000");
return this; return this;
}; };
MessageEmbed.prototype.successColor = function() { MessageEmbed.prototype.successColor = function() {
this.setColor("#32CD32"); this.setColor("#32CD32");
return this; return this;
}; };
MessageEmbed.prototype.defaultColor = function() { MessageEmbed.prototype.defaultColor = function() {
this.setColor(config.color); this.setColor(config.color);
return this; return this;
}; };

View file

@ -5,6 +5,7 @@ const Canvas = require("discord-canvas"),
async function init(client) { async function init(client) {
new CronJob("0 3 12 * * *", async function() { new CronJob("0 3 12 * * *", async function() {
if (!client.config.apiKeys.fortniteFNBR || client.config.apiKeys.fortniteFNBR === "") return; if (!client.config.apiKeys.fortniteFNBR || client.config.apiKeys.fortniteFNBR === "") return;
client.guilds.cache.forEach(async (guild) => { client.guilds.cache.forEach(async (guild) => {
const guildData = await client.findOrCreateGuild({ id: guild.id }); const guildData = await client.findOrCreateGuild({ id: guild.id });
if (guildData.plugins.fortniteshop) { if (guildData.plugins.fortniteshop) {

View file

@ -1,6 +1,6 @@
const languages = require("../languages/language-meta.json").map((l) => l.moment).filter((l) => l !== "en"); const languages = require("../languages/language-meta.json").map((l) => l.moment).filter((l) => l !== "en");
languages.forEach((l) => { languages.forEach((lang) => {
require(`moment/locale/${l}.js`); require(`moment/locale/${lang}.js`);
}); });
module.exports = { module.exports = {
@ -21,19 +21,21 @@ module.exports = {
prefixes.forEach((p) => { prefixes.forEach((p) => {
if (message.content.startsWith(p) || message.content.toLowerCase().startsWith(p)) prefix = p; if (message.content.startsWith(p) || message.content.toLowerCase().startsWith(p)) prefix = p;
}); });
return prefix; return prefix;
} else { } else {
return true; return true;
}; };
}, },
// This function return a valid link to the support server // This function return a actual link to the support server
async supportLink(client) { async supportLink(client) {
const guild = client.guilds.cache.get(client.config.support.id); const guild = client.guilds.cache.get(client.config.support.id);
const member = guild.me; const member = guild.me;
const channel = guild.channels.cache.find((ch) => ch.permissionsFor(member.id).has("CREATE_INSTANT_INVITE") && ch.type === "text" || ch.type === "voice"); const channel = guild.channels.cache.find((ch) => ch.permissionsFor(member.id).has("CREATE_INSTANT_INVITE") && ch.type === "text" || ch.type === "voice");
if (channel) { if (channel) {
const invite = await channel.createInvite({ maxAge: 0 }).catch(() => {}); const invite = await channel.createInvite({ maxAge: 0 }).catch(() => {});
return invite ? invite.url : null; return invite ? invite.url : null;
} else { } else {
return ""; return "";
@ -54,6 +56,7 @@ module.exports = {
const array = []; const array = [];
pArray.forEach(element => array.push(element)); pArray.forEach(element => array.push(element));
let currentIndex = array.length, temporaryValue, randomIndex; let currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle... // While there remain elements to shuffle...
while (0 !== currentIndex) { while (0 !== currentIndex) {
// Pick a remaining element... // Pick a remaining element...
@ -64,6 +67,7 @@ module.exports = {
array[currentIndex] = array[randomIndex]; array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue; array[randomIndex] = temporaryValue;
} }
return array; return array;
}, },

View file

@ -13,11 +13,7 @@ async function walkDirectory(dir, namespaces = [], folderName = "") {
const isLanguage = file.includes("-"); const isLanguage = file.includes("-");
if (isLanguage) languages.push(file); if (isLanguage) languages.push(file);
const folder = await walkDirectory( const folder = await walkDirectory(path.join(dir, file), namespaces, isLanguage ? "" : `${file}/`);
path.join(dir, file),
namespaces,
isLanguage ? "" : `${file}/`
);
namespaces = folder.namespaces; namespaces = folder.namespaces;
} else { } else {
@ -34,9 +30,7 @@ module.exports = async () => {
loadPath: path.resolve(__dirname, "../languages/{{lng}}/{{ns}}.json") loadPath: path.resolve(__dirname, "../languages/{{lng}}/{{ns}}.json")
}; };
const { namespaces, languages } = await walkDirectory( const { namespaces, languages } = await walkDirectory(path.resolve(__dirname, "../languages/"));
path.resolve(__dirname, "../languages/")
);
i18next.use(Backend); i18next.use(Backend);

View file

@ -5,9 +5,8 @@ const { bgBlue, black, green } = require("chalk");
function dateTimePad(value, digits) { function dateTimePad(value, digits) {
let number = value; let number = value;
while (number.toString().length < digits) { while (number.toString().length < digits) number = "0" + number;
number = "0" + number;
};
return number; return number;
}; };
@ -29,21 +28,27 @@ module.exports = class Logger {
case "log": { case "log": {
return console.log(`${date} ${bgBlue(type.toUpperCase())} ${content} `); return console.log(`${date} ${bgBlue(type.toUpperCase())} ${content} `);
}; };
case "warn": { case "warn": {
return console.log(`${date} ${black.bgYellow(type.toUpperCase())} ${content} `); return console.log(`${date} ${black.bgYellow(type.toUpperCase())} ${content} `);
}; };
case "error": { case "error": {
return console.log(`${date} ${black.bgRed(type.toUpperCase())} ${content} `); return console.log(`${date} ${black.bgRed(type.toUpperCase())} ${content} `);
}; };
case "debug": { case "debug": {
return console.log(`${date} ${green(type.toUpperCase())} ${content} `); return console.log(`${date} ${green(type.toUpperCase())} ${content} `);
}; };
case "cmd": { case "cmd": {
return console.log(`${date} ${black.bgWhite(type.toUpperCase())} ${content}`); return console.log(`${date} ${black.bgWhite(type.toUpperCase())} ${content}`);
}; };
case "ready": { case "ready": {
return console.log(`${date} ${black.bgGreen(type.toUpperCase())} ${content}`); return console.log(`${date} ${black.bgGreen(type.toUpperCase())} ${content}`);
}; };
default: throw new TypeError("Logger type must be either warn, debug, log, ready, cmd or error."); default: throw new TypeError("Logger type must be either warn, debug, log, ready, cmd or error.");
}; };
} }

View file

@ -1,53 +1,61 @@
const resolveChannel = async ({ message, search, channelType }) => { const resolveChannel = async ({ message, search, channelType }) => {
const contentToCheck = search || message.content; const contentToCheck = search || message.content;
if (!contentToCheck || typeof contentToCheck !== "string") return; if (!contentToCheck || typeof contentToCheck !== "string") return;
// Try by parsing the search // Try by parsing the search
if (contentToCheck.match(/^<#([0-9]{18})>/)) { if (contentToCheck.match(/^<#([0-9]{18})>/)) {
const [, channelID] = contentToCheck.match(/^<#([0-9]{18})>/); const [, channelID] = contentToCheck.match(/^<#([0-9]{18})>/);
const channelFound = message.guild.channels.cache.get(channelID); const channelFound = message.guild.channels.cache.get(channelID);
if (channelFound && channelType && channelFound.type === channelType) return channelFound; if (channelFound && channelType && channelFound.type === channelType) return channelFound;
}; };
// Try with ID // Try with ID
if (message.guild.channels.cache.has(search)) { if (message.guild.channels.cache.has(search)) {
const channelFound = message.guild.channels.cache.get(search); const channelFound = message.guild.channels.cache.get(search);
if (channelFound && channelType && channelFound.type === channelType) return channelFound; if (channelFound && channelType && channelFound.type === channelType) return channelFound;
}; };
// Try with name with # // Try with name with #
if (message.guild.channels.cache.some(channel => `#${channel.name}` === search || channel.name === search)) { if (message.guild.channels.cache.some(channel => `#${channel.name}` === search || channel.name === search)) {
const channelFound = message.guild.channels.cache.find(channel => `#${channel.name}` === search || channel.name === search); const channelFound = message.guild.channels.cache.find(channel => `#${channel.name}` === search || channel.name === search);
if (channelFound && channelType && channelFound.type === channelType) return channelFound; if (channelFound && channelType && channelFound.type === channelType) return channelFound;
}; };
return; return;
}; };
const resolveMember = async ({ message, search, useMessageContent = true }) => { const resolveMember = async ({ message, search, useMessageContent = true }) => {
const contentToCheck = search || (useMessageContent ? message.content : null); const contentToCheck = search || (useMessageContent ? message.content : null);
if (!contentToCheck || typeof contentToCheck !== "string") return; if (!contentToCheck || typeof contentToCheck !== "string") return;
// Try by parsing the search // Try by parsing the search
if (contentToCheck.match(/^<@!?(\d+)>$/)) { if (contentToCheck.match(/^<@!?(\d+)>$/)) {
const [, userID] = contentToCheck.match(/^<@!?(\d+)>$/); const [, userID] = contentToCheck.match(/^<@!?(\d+)>$/);
const memberFound = await message.guild.members.fetch(userID).catch(() => {}); const memberFound = await message.guild.members.fetch(userID).catch(() => {});
if (memberFound) return memberFound; if (memberFound) return memberFound;
}; };
// Try with ID // Try with ID
if (await message.guild.members.fetch(search).catch(() => {})) { if (await message.guild.members.fetch(search).catch(() => {})) {
const memberFound = await message.guild.members.fetch(search); const memberFound = await message.guild.members.fetch(search);
if (memberFound) return memberFound; if (memberFound) return memberFound;
}; };
// Try with name with @ // Try with name with @
await message.guild.members.fetch({ await message.guild.members.fetch({ query: search });
query: search
});
if (message.guild.members.cache.some(member => member.user.tag === search || member.user.username === search)) { if (message.guild.members.cache.some(member => member.user.tag === search || member.user.username === search)) {
const memberFound = message.guild.members.cache.find(member => member.user.tag === search || member.user.username === search); const memberFound = message.guild.members.cache.find(member => member.user.tag === search || member.user.username === search);
if (memberFound) return memberFound; if (memberFound) return memberFound;
}; };
return; return;
}; };
const resolveRole = async ({ message, search }) => { const resolveRole = async ({ message, search }) => {
const contentToCheck = search || message.content; const contentToCheck = search || message.content;
if (!contentToCheck || typeof contentToCheck !== "string") return; if (!contentToCheck || typeof contentToCheck !== "string") return;
// Try by parsing the search // Try by parsing the search
if (contentToCheck.match(/^<@&([0-9]{18})>/)) { if (contentToCheck.match(/^<@&([0-9]{18})>/)) {
const [, roleID] = contentToCheck.match(/^<@&([0-9]{18})>/); const [, roleID] = contentToCheck.match(/^<@&([0-9]{18})>/);
@ -55,16 +63,19 @@ const resolveRole = async ({ message, search }) => {
if (roleFound) if (roleFound)
return roleFound; return roleFound;
}; };
// Try with ID // Try with ID
if (message.guild.roles.cache.has(search)) { if (message.guild.roles.cache.has(search)) {
const roleFound = message.guild.roles.cache.get(search); const roleFound = message.guild.roles.cache.get(search);
if (roleFound) return roleFound; if (roleFound) return roleFound;
}; };
// Try with name with @ // Try with name with @
if (message.guild.roles.cache.some(role => `@${role.name}` === search || role.name === search)) { if (message.guild.roles.cache.some(role => `@${role.name}` === search || role.name === search)) {
const roleFound = message.guild.roles.cache.find(role => `@${role.name}` === search || role.name === search); const roleFound = message.guild.roles.cache.find(role => `@${role.name}` === search || role.name === search);
if (roleFound) return roleFound; if (roleFound) return roleFound;
}; };
return; return;
}; };