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

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`)
];
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);
dim += 200;
};

View file

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

View file

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

View file

@ -7,9 +7,8 @@ const fetch = require("node-fetch"),
// Gets login page
router.get("/login", async function(req, res) {
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"}`);
};
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"}`);
res.redirect("/selector");
});
@ -19,9 +18,11 @@ router.get("/callback", async (req, res) => {
if (req.query.code) {
const guildID = req.query.state.substr("invite".length, req.query.state.length);
req.client.knownGuilds.push({ id: guildID, user: req.user.id });
return res.redirect("/manage/"+guildID);
};
};
const redirectURL = req.client.states[req.query.state] || "/selector";
const params = new URLSearchParams();
params.set("grant_type", "authorization_code");
@ -35,8 +36,10 @@ router.get("/callback", async (req, res) => {
"Content-Type": "application/x-www-form-urlencoded"
}
});
// Fetch tokens (used to fetch user informations)
const tokens = await response.json();
// If the code isn't valid
if (tokens.error || !tokens.access_token) return res.redirect(`/api/login&state=${req.query.state}`);
const userData = {
@ -54,6 +57,7 @@ router.get("/callback", async (req, res) => {
if (json.retry_after) await req.client.wait(json.retry_after);
else userData.infos = json;
};
/* User guilds */
if (!userData.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;
};
};
/* Change format (from "0": { data }, "1": { data }, etc... to [ { data }, { data } ]) */
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
req.session.user = { ... userData.infos, ... { guilds } };
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) {
const language = req.client.languages.find((language) => language.aliases[0].toLowerCase() === data.language.toLowerCase());
if (language) {
guildData.language = language.name;
};
if (data.prefix.length >= 1 && data.prefix.length < 2000) {
guildData.prefix = data.prefix;
};
if (language) guildData.language = language.name;
if (data.prefix.length >= 1 && data.prefix.length < 2000) guildData.prefix = data.prefix;
await guildData.save();
};
@ -120,21 +117,15 @@ router.post("/:serverID", CheckAuth, async(req, res) => {
};
if (Object.prototype.hasOwnProperty.call(data, "suggestions")) {
if (data.suggestions === req.translate("common:NO_CHANNEL")) {
guildData.plugins.suggestions = false;
} 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.fortniteshop === req.translate("common:NO_CHANNEL")) {
guildData.plugins.fortniteshop = false;
} else {
guildData.plugins.fortniteshop = guild.channels.cache.find((ch) => "#"+ch.name === data.fortniteshop).id;
};
if (data.suggestions === req.translate("common:NO_CHANNEL")) guildData.plugins.suggestions = false;
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.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");
};

View file

@ -25,14 +25,16 @@ router.get("/:serverID", CheckAuth, async(req, res) => {
level: sortArrayOfObjects("level", membersData)
};
for(const cat in leaderboards){
for (const cat in leaderboards) {
const e = leaderboards[cat];
if (e.length > 10) e.length = 10;
}
};
const stats = {
money: await utils.fetchUsers(leaderboards.money, req.client),
level: await utils.fetchUsers(leaderboards.level, req.client)
};
res.render("stats/guild", {
stats,
commands: getCommands(guildInfos.commands.filter((c) => c.date > Date.now()-604800000)),
@ -49,22 +51,17 @@ function getCommands(commands) {
const aDateCommand = {};
commands.forEach((cmd) => {
const tDate = formatDate(new Date(cmd.date));
if (aDateCommand[tDate]) {
aDateCommand[tDate]++;
} else {
aDateCommand[tDate] = 1;
};
if (aDateCommand[tDate]) aDateCommand[tDate]++;
else aDateCommand[tDate] = 1;
});
return aDateCommand;
};
function getCommandsUsage(commands) {
const objectCount = commands.reduce((acc, curr) => {
if (typeof acc[curr.command] == "undefined") {
acc[curr.command] = 1;
} else {
acc[curr.command] += 1;
}
if (typeof acc[curr.command] == "undefined") acc[curr.command] = 1;
else acc[curr.command] += 1;
return acc;
}, {});
const percentages = getPercentagePerKey(objectCount); // [ { key: "help", percentage: 20 } ]
@ -74,6 +71,7 @@ function getCommandsUsage(commands) {
p.color = colors[i];
i++;
});
return percentages;
};
@ -85,14 +83,14 @@ function getPercentagePerKey(myArray) {
const percentage = Math.round((val / sum) * 100);
arrayWithPercentages.push({key, percentage});
};
return arrayWithPercentages;
};
function getSum(myArray) {
let sum = 0;
for (const key in myArray) {
sum += myArray[key];
};
for (const key in myArray) sum += myArray[key];
return sum;
};
@ -109,5 +107,6 @@ function formatDate(date) {
if (dd < 10) dd = `0${dd}`
if (mm < 10) mm = `0${mm}`
date = `${mm}/${dd}`
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 data = req.body;
if (data.bio) {
user.bio = data.bio;
};
if (data.bio) user.bio = data.bio;
if (data.birthdate) {
if (checkDate(data.birthdate)) {
user.birthdate = checkDate(data.birthdate);
user.markModified("birthdate");
};
};
await user.save();
res.redirect(303, "/settings");
});
@ -33,19 +33,18 @@ module.exports = router;
/**
* @returns {Boolean}
*/
function checkDate(birthdate){
function checkDate(birthdate) {
const [day, month, year] = birthdate;
if (!day || !month || !year) return false;
const match = birthdate.match(/\d+/g);
if (!match) return false;
const tday = + match[0], tmonth = + match[1] - 1;
let tyear = + match[2];
if (tyear < 100) {
tyear += tyear < 50 ? 2000 : 1900;
};
if (tyear < 100) tyear += tyear < 50 ? 2000 : 1900;
const d = new Date(tyear, tmonth, tday);
if (!(tday == d.getDate() && tmonth == d.getMonth() && tyear == d.getFullYear())) return false;
if (d.getTime() > Date.now()) return false;
if (d.getTime() < (Date.now() - 2.523e+12)) return false;
return d;
};

View file

@ -6,9 +6,10 @@ const Discord = require("discord.js");
* @param {object} client The discord client instance
* @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 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) };
};
@ -19,27 +20,25 @@ async function fetchGuild(guildID, client, guilds){
* @param {string} query The optional query for guilds
* @returns {object} The user informations
*/
async function fetchUser(userData, client, query){
async function fetchUser(userData, client, query) {
if (userData.guilds) {
userData.guilds.forEach((guild) => {
if (!client.guilds.cache.get(guild.id)) return;
const perms = new Discord.Permissions(guild.permissions);
if (perms.has("MANAGE_GUILD")) {
guild.admin = true;
};
if (perms.has("MANAGE_GUILD")) 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.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.displayed = (query ? guild.name.toLowerCase().includes(query.toLowerCase()) : true);
});
userData.displayedGuilds = userData.guilds.filter((g) => g.displayed && g.admin);
if (userData.displayedGuilds.length < 1) {
delete userData.displayedGuilds;
};
if (userData.displayedGuilds.length < 1) delete userData.displayedGuilds;
};
const user = await client.users.fetch(userData.id);
const userDb = await client.findOrCreateUser({ id: user.id }, true);
const userInfos = { ...user.toJSON(), ...userDb, ...userData, ...user.presence };
return userInfos;
};

View file

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

View file

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

View file

@ -1,34 +1,36 @@
<!DOCTYPE html>
<html>
<%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<%- include('includes/head') %>
<!-- The header is the topbar -->
<%- include('includes/header') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %>
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %>
<!-- Content Header (Page header) -->
<section class="content-header">
<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>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<section class="content">
<%- md("commands.md") %>
</section>
</div>
<!-- Content Header (Page header) -->
<section class="content-header">
<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>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
<section class="content">
<%- md("commands.md") %>
</section>
</div>
<!-- ./wrapper -->
</body>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html>

View file

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

View file

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

View file

@ -4,13 +4,15 @@
<section class="sidebar">
<!-- Sidebar user panel -->
<div class="user-panel">
<div class="pull-left image">
<img src="<%= user.displayAvatarURL %>" class="img-circle" alt="User Image">
</div>
<div class="pull-left info">
<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>
</div>
<div class="pull-left image">
<img src="<%= user.displayAvatarURL %>" class="img-circle" alt="User Image">
</div>
<div class="pull-left info">
<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>
</div>
</div>
<!-- search form -->
<!--
@ -30,31 +32,34 @@
<ul class="sidebar-menu" data-widget="tree">
<li class="header"><%= translate("dashboard:SERVERS_MANAGEMENT").toUpperCase() %></li>
<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 class="treeview">
<a href="/manage/">
<i class="fa fa-server"></i>
<span><%= translate("dashboard:SERVERS_LIST") %></span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
<i class="fa fa-server"></i>
<span><%= translate("dashboard:SERVERS_LIST") %></span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<% if(user.displayedGuilds){ %>
<ul class="treeview-menu">
<% 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>
<% }); %>
</ul>
<% if(user.displayedGuilds) { %>
<ul class="treeview-menu">
<% 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>
<% }); %>
</ul>
<% } %>
</li>
</ul>
<ul class="sidebar-menu" data-widget="tree">
<li class="header"><%= translate("common:PROFILE").toUpperCase() %></li>
<li class="treeview menu-open">
<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="/settings"><i class="fa fa-gear"></i> <span><%= translate("common:SETTINGS") %></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="/settings"><i class="fa fa-gear"></i> <span><%= translate("common:SETTINGS") %></span></a></li>
</li>
</ul>
</section>
@ -62,11 +67,12 @@
</aside>
<script>
$(document).ready(function() {
$(document).ready(function () {
// get current URL path and assign 'active' class
let pathname = window.location.pathname;
$(`.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 > a[href="/${window.location.pathname.split("/")[1]}/"]`).parent().addClass("active");
$(`.sidebar-menu > li > a[href="/${window.location.pathname.split("/")[1]}/"]`).parent().addClass(
"active");
});
</script>

View file

@ -1,312 +1,345 @@
<!DOCTYPE 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 -->
<%- include('../includes/header') %>
<!-- The header is the topbar -->
<%- include('../includes/header') %>
<!-- The sidebar includes the menu -->
<%- include('../includes/sidebar') %>
<!-- The sidebar includes the menu -->
<%- include('../includes/sidebar') %>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1> <%= translate("common:CONFIGURATION") %> <small> Dashboard v1.0 </small> </h1>
<ol class="breadcrumb">
<li><a href="/"><i class="fa fa-home"></i> <%= translate("dashboard:SELECTOR") %></a></li>
<li class="active"><%= guild.name %></li>
</ol>
</section>
<!-- Content Header (Page header) -->
<section class="content-header">
<h1> <%= translate("common:CONFIGURATION") %> <small> Dashboard v1.0 </small> </h1>
<ol class="breadcrumb">
<li><a href="/"><i class="fa fa-home"></i> <%= translate("dashboard:SELECTOR") %></a></li>
<li class="active"><%= guild.name %></li>
</ol>
</section>
<section class="content">
<div class="row">
<div class="col-md-6">
<div class="box box-widget widget-user">
<div class="widget-user-header bg-aqua-active">
<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 -->
<section class="content">
<div class="row">
<div class="col-md-6">
<div class="box box-widget widget-user">
<div class="widget-user-header bg-aqua-active">
<h3 class="widget-user-username"><%= guild.name %></h3>
</div>
<!-- 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 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>
<!-- 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>
<% } %>
<!-- /.description-block -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</div>
<!-- /.box-footer -->
</div>
<!-- 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>
</div>
</select>
</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>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- 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>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-primary"><%= translate("common:UPDATE") %></button>
</div>
</form>
</div>
<!-- /.box -->
<!-- /.box-body -->
<div class="box-footer">
<button type="submit"
class="btn btn-primary"><%= translate("common:UPDATE") %></button>
</div>
</form>
</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>
<!-- /.box -->
<!-- SPECIAL CHANNELS -->
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:CHANNELS_CONF") %></h3>
</div>
<!-- GOODBYE CONFIGURATION -->
<div class="box box-danger">
<div class="box-header with-border">
<h3 class="box-title"><%= translate("dashboard:GOODBYE_CONF") %></h3>
<form role="form" action="/manage/<%= guild.id %>/" method="POST">
<!-- /.box-header -->
<div class="box-body">
<!-- 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>
<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>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit"
class="btn btn-primary"><%= translate("common:UPDATE") %></button>
</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 -->
</form>
</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>
</section>
</section>
<!-- Footer includes credits and version -->
</div>
<!-- /.content-wrapper -->
<%- include('../includes/footer') %>
<!-- Footer includes credits and version -->
</div>
<!-- ./wrapper -->
</body>
<!-- /.content-wrapper -->
<%- include('../includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html>

View file

@ -1,76 +1,82 @@
<!DOCTYPE html>
<html>
<%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<%- include('includes/head') %>
<!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- 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>
<!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %>
<section class="content">
<div class="row">
<% if(user.displayedGuilds){ user.displayedGuilds.forEach(function(guild) { %>
<!-- Displays 4 servers by line -->
<div class="col-md-3">
<div class="box box-solid">
<div class="box-header text-center">
<i class="fas fa-crown"></i>
<h3 class="box-title server-name"><%= guild.name %></h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="text-center">
<img src="<%= guild.iconURL %>" style="border-radius:100%" width="100" height="100" class="img-fluid">
</div>
</div>
<!-- /.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 -->
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- 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">
<div class="row">
<% if(user.displayedGuilds) { user.displayedGuilds.forEach(function(guild) { %>
<!-- Displays 4 servers by line -->
<div class="col-md-3">
<div class="box box-solid">
<div class="box-header text-center">
<i class="fas fa-crown"></i>
<h3 class="box-title server-name"><%= guild.name %></h3>
</div>
<!-- /.box -->
</div>
<!-- /.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 -->
<!-- /.box-header -->
<div class="box-body">
<div class="text-center">
<img src="<%= guild.iconURL %>" style="border-radius:100%" width="100" height="100"
class="img-fluid">
</div>
<!-- /.box-header -->
<div class="box-body">
<%= translate("dashboard:NO_SERVER_CONTENT") %>
</div>
<!-- /.box-body -->
</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>
<% } %>
<!-- /.box -->
</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>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</section>
</div>
<!-- ./wrapper -->
</body>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html>

View file

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

View file

@ -1,34 +1,36 @@
<!DOCTYPE html>
<html>
<%- include('includes/head') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<%- include('includes/head') %>
<!-- The header is the topbar -->
<%- include('includes/header') %>
<body class="hold-transition skin-red sidebar-mini">
<div class="wrapper">
<!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %>
<!-- The header is the topbar -->
<%- include('includes/header') %>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- The sidebar includes the menu -->
<%- include('includes/sidebar') %>
<!-- Content Header (Page header) -->
<section class="content-header">
<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>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<section class="content">
<%- md("updates.md") %>
</section>
</div>
<!-- Content Header (Page header) -->
<section class="content-header">
<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>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
<section class="content">
<%- md("updates.md") %>
</section>
</div>
<!-- ./wrapper -->
</body>
<!-- Footer includes credits and version -->
<%- include('includes/footer') %>
</div>
<!-- ./wrapper -->
</body>
</html>

View file

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

View file

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

View file

@ -12,7 +12,8 @@ module.exports = class {
userData.achievements.tip.achieved = true;
userData.markModified("achievements.tip");
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) {
const data = {};
// If the messagr author is a bot
// If the message author is a bot
if (message.author.bot) return;
// 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
if (message.content.match(new RegExp(`^<@!?${client.user.id}>( |)$`))) {
if (message.guild) {
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 });
};
if (message.guild) 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 });
};
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) {
// Gets the data of the member
@ -55,6 +52,7 @@ module.exports = class {
if (uSlowmode.time > Date.now()) {
message.delete();
const delay = message.convertTime(uSlowmode.time, "to", true);
return message.author.send(message.translate("administration/slowmode:PLEASE_WAIT", { time: delay, channel: message.channel.toString() }));
} else {
uSlowmode.time = channelSlowmode.time + Date.now();
@ -89,9 +87,7 @@ module.exports = class {
message.mentions.users.forEach(async (u) => {
const userData = await client.findOrCreateUser({ id: u.id });
if (userData.afk) {
message.error("general/setafk:IS_AFK", { user: u.tag, reason: userData.afk });
};
if (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")) {
message.delete();
message.author.send(message.translate("misc:RESTRICTED_CHANNEL", { channel: message.channel.toString() }));
return;
};
if (customCommandAnswer) return message.channel.send(customCommandAnswer);
if (cmd.conf.guildOnly && !message.guild) return message.error("misc:GUILD_ONLY");
if (message.guild) {
let neededPermissions = [];
if (!cmd.conf.botPermissions.includes("EMBED_LINKS")) cmd.conf.botPermissions.push("EMBED_LINKS");
cmd.conf.botPermissions.forEach((perm) => {
if (!message.channel.permissionsFor(message.guild.me).has(perm)) {
neededPermissions.push(perm);
};
});
if (neededPermissions.length > 0) return message.error("misc:MISSING_BOT_PERMS", { list: neededPermissions.map((p) => `\`${p}\``).join(", ") });
neededPermissions = [];
@ -135,13 +133,13 @@ module.exports = class {
neededPermissions.push(perm);
};
});
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.nsfw && cmd.conf.nsfw) return message.error("misc:NSFW_COMMAND");
};
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");
let uCooldown = cmdCooldown[message.author.id];
@ -149,6 +147,7 @@ module.exports = class {
cmdCooldown[message.author.id] = {};
uCooldown = cmdCooldown[message.author.id];
};
const time = uCooldown[cmd.help.name] || 0;
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;
@ -167,12 +166,10 @@ module.exports = class {
data.userData.achievements.firstCommand.achieved = true;
data.userData.markModified("achievements.firstCommand");
await data.userData.save();
await message.channel.send({ files: [
{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked2.png"
}
]});
await message.channel.send({ files: [{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked2.png"
}]});
};
try {

View file

@ -8,34 +8,34 @@ module.exports = class {
async run () {
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(`${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");
discordtogether.init(client);
/* DiscordBots.org STATS */
// DiscordBots.org STATS
const discordbotsorg = require("../helpers/discordbots.org");
discordbotsorg.init(client);
/* UNMUTE USERS */
// UNMUTE USERS
const checkUnmutes = require("../helpers/checkUnmutes");
checkUnmutes.init(client);
/* SEND REMINDS */
// SEND REMINDS
const checkReminds = require("../helpers/checkReminds");
checkReminds.init(client);
/* DAILY SHOP FORTNITE */
// DAILY SHOP FORTNITE
const fortniteShop = require("../helpers/fortniteShop");
fortniteShop.init(client);
// Start the dashboard
if (client.config.dashboard.enabled) client.dashboard.load(client);
// Update the game every 20s
// Update status every 20s
const status = [
{ name: `{servers} сервер(а/ов)`, type: "WATCHING" },
{ name: "help", type: "WATCHING" }
@ -43,8 +43,9 @@ module.exports = class {
const version = require("../package.json").version;
let i = 0;
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;
client.user.setActivity(toDisplay, { type: status[parseInt(i, 10)].type });
const random = status[parseInt(i, 10)];
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++;
else i = 0;
}, 20000); // Every 20 seconds

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,6 +5,7 @@ const Canvas = require("discord-canvas"),
async function init(client) {
new CronJob("0 3 12 * * *", async function() {
if (!client.config.apiKeys.fortniteFNBR || client.config.apiKeys.fortniteFNBR === "") return;
client.guilds.cache.forEach(async (guild) => {
const guildData = await client.findOrCreateGuild({ id: guild.id });
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");
languages.forEach((l) => {
require(`moment/locale/${l}.js`);
languages.forEach((lang) => {
require(`moment/locale/${lang}.js`);
});
module.exports = {
@ -21,19 +21,21 @@ module.exports = {
prefixes.forEach((p) => {
if (message.content.startsWith(p) || message.content.toLowerCase().startsWith(p)) prefix = p;
});
return prefix;
} else {
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) {
const guild = client.guilds.cache.get(client.config.support.id);
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");
if (channel) {
const invite = await channel.createInvite({ maxAge: 0 }).catch(() => {});
return invite ? invite.url : null;
} else {
return "";
@ -54,6 +56,7 @@ module.exports = {
const array = [];
pArray.forEach(element => array.push(element));
let currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
@ -64,6 +67,7 @@ module.exports = {
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
},

View file

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

View file

@ -5,9 +5,8 @@ const { bgBlue, black, green } = require("chalk");
function dateTimePad(value, digits) {
let number = value;
while (number.toString().length < digits) {
number = "0" + number;
};
while (number.toString().length < digits) number = "0" + number;
return number;
};
@ -29,21 +28,27 @@ module.exports = class Logger {
case "log": {
return console.log(`${date} ${bgBlue(type.toUpperCase())} ${content} `);
};
case "warn": {
return console.log(`${date} ${black.bgYellow(type.toUpperCase())} ${content} `);
};
case "error": {
return console.log(`${date} ${black.bgRed(type.toUpperCase())} ${content} `);
};
case "debug": {
return console.log(`${date} ${green(type.toUpperCase())} ${content} `);
};
case "cmd": {
return console.log(`${date} ${black.bgWhite(type.toUpperCase())} ${content}`);
};
case "ready": {
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.");
};
}

View file

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