Много фиксов и удалений старого, лишнего или не используемого

This commit is contained in:
JonnyBro 2022-07-26 17:20:10 +05:00
parent b812a4401e
commit 73a2834109
40 changed files with 259 additions and 372 deletions

View file

@ -1,4 +1,6 @@
/* eslint-disable no-unused-vars */
const path = require("path");
class BaseCommand {
constructor(options, client) {
/**
@ -17,6 +19,14 @@ class BaseCommand {
* @type {Boolean}
*/
this.ownerOnly = options.ownerOnly || false;
/**
* @type {Object}
*/
this.dirname = options.dirname || false;
/**
* @type {String}
*/
this.category = (this.dirname ? this.dirname.split(path.sep)[parseInt(this.dirname.split(path.sep).length - 1, 10)] : "Other");
}
}

View file

@ -124,8 +124,6 @@ class JaBa extends Client {
* @returns
*/
async loadCommands(dir, guild_id) {
if (!this.translations) this.translations = await require("../helpers/languages")();
const filePath = path.join(__dirname, dir);
const files = await fs.readdir(filePath);
const rest = new REST({ version: "9" }).setToken(this.config.token);
@ -215,11 +213,8 @@ class JaBa extends Client {
this.logger.log(`Unable to connect to the Mongodb database. Error: ${err}`, "error");
});
// const languages = require("../helpers/languages");
// this.translations = await languages();
// const autoUpdateDocs = require("../helpers/autoUpdateDocs");
// autoUpdateDocs.update(this);
const autoUpdateDocs = require("../helpers/autoUpdateDocs");
autoUpdateDocs.update(this);
}
get defaultLanguage() {
@ -251,12 +246,12 @@ class JaBa extends Client {
}
convertTime(time, type, noPrefix, locale) {
if (!type) time = "to";
if (!type) type = false;
if (!locale) locale = this.defaultLanguage;
const languageData = this.languages.find((language) => language.name === locale || language.aliases.includes(locale));
const m = moment(time).locale(languageData.moment);
return (type === "to" ? m.toNow(noPrefix) : m.fromNow(noPrefix));
return (type ? m.toNow(noPrefix) : m.fromNow(noPrefix));
}
getNoun(number, one, two, five) {

View file

@ -1,9 +1,9 @@
const BaseCommand = require("../base/BaseCommand");
const BaseCommand = require("../../base/BaseCommand");
class Mention extends BaseCommand {
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
*/
constructor() {
super({
@ -12,19 +12,20 @@ class Mention extends BaseCommand {
type: 2 // Type 2 is USER COMMAND.
},
aliases: ["m"], // Application command aliases.
dirname: __dirname,
guildOnly: true // Determines whether your command is only guild.
});
}
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ContextMenuInteraction} interaction
*/
async execute(client, interaction) {

View file

@ -1,10 +1,10 @@
const { SlashCommandBuilder } = require("@discordjs/builders");
const BaseCommand = require("../base/BaseCommand");
const BaseCommand = require("../../base/BaseCommand");
class Ping extends BaseCommand {
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
*/
constructor() {
super({
@ -12,19 +12,20 @@ class Ping extends BaseCommand {
.setName("ping")
.setDescription("Ping command."), // This option is included in type 1. You can configure this option directly with the SlashCommandBuilder feature.
aliases: ["p"], // Application command aliases.
dirname: __dirname,
guildOnly: true // Determines whether your command is only guild.
});
}
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").CommandInteraction} interaction
*/
async execute(client, interaction) {

View file

@ -1,9 +1,9 @@
const BaseCommand = require("../base/BaseCommand");
const BaseCommand = require("../../base/BaseCommand");
class Repeat extends BaseCommand {
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
*/
constructor() {
super({
@ -12,19 +12,20 @@ class Repeat extends BaseCommand {
type: 3 // Type 3 is MESSAGE COMMAND.
},
aliases: ["r"], // Application command aliases.
dirname: __dirname,
guildOnly: true // Determines whether your command is only guild.
});
}
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../base/JaBa")} client
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ContextMenuInteraction} interaction
*/
async execute(client, interaction) {

View file

@ -17,6 +17,7 @@ class Eval extends BaseCommand {
.setDescription(client.translate("owner/eval:USAGE"))
.setRequired(true)),
aliases: ["e"],
dirname: __dirname,
guildOnly: true,
ownerOnly: true
});

View file

@ -4,8 +4,8 @@ module.exports = {
/* ID of Bot's user */
user: "XXXXXXXXXXX",
/* For the support server */
production: true, // Set to true for production
support: {
enabled: false, // Set to false for production
id: "XXXXXXXXXXX", // The ID of the support server
logs: "XXXXXXXXXXX", // And the ID of the logs channel of your server (new servers for example)
},

View file

@ -2,7 +2,7 @@ const config = require("../config"),
utils = require("./utils"),
CheckAuth = require("./auth/CheckAuth");
module.exports.load = async(client) => {
module.exports.init = async(client) => {
/* Init express app */
const express = require("express"),
session = require("express-session"),

View file

@ -8,7 +8,6 @@
"link": "<:atlanta_link:598176933855100976>",
"voice": "<:atlanta_voice:598176518891372560>",
"add": "<:atlanta_add:598176235700355083>",
"vote": "<:atlanta_vote:598175768274665492>",
"help": "<:atlanta_help:598175335078559771>",
"warn": "<:atlanta_warn:598179558927106058>",
"error": "<:atlanta_error:736144198318686278>",

View file

@ -24,8 +24,8 @@ class CommandHandler extends BaseEvent {
});
data.userData = userData;
if (command.guildOnly && !interaction.inGuild()) return interaction.reply({ content: client.translate("misc:GUILD_ONLY"), ephemeral: true});
if (command.ownerOnly && interaction.user.id !== client.config.owner.id) return interaction.reply({ content: client.translate("misc:OWNER_ONLY"), ephemeral: true });
if (command.guildOnly && !interaction.inGuild()) return interaction.replyT("misc:GUILD_ONLY", { ephemeral: true });
if (command.ownerOnly && interaction.user.id !== client.config.owner.id) return interaction.replyT("misc:OWNER_ONLY", { ephemeral: true });
if (interaction.inGuild()) {
const guildData = await client.findOrCreateGuild({

View file

@ -1,5 +1,5 @@
const { MessageEmbed } = require("discord.js"),
BaseEvent = require("../base/BaseEvent");
BaseEvent = require("../../base/BaseEvent");
class GuildCreate extends BaseEvent {
constructor() {

View file

@ -1,5 +1,5 @@
const { MessageEmbed } = require("discord.js"),
BaseEvent = require("../base/BaseEvent");
BaseEvent = require("../../base/BaseEvent");
class GuildDelete extends BaseEvent {
constructor() {

View file

@ -1,5 +1,5 @@
const Canvas = require("canvas"),
BaseEvent = require("../base/BaseEvent"),
BaseEvent = require("../../base/BaseEvent"),
{ MessageAttachment } = require("discord.js"),
{ resolve } = require("path");

View file

@ -1,5 +1,5 @@
const Canvas = require("canvas"),
BaseEvent = require("../base/BaseEvent"),
BaseEvent = require("../../base/BaseEvent"),
{ MessageAttachment } = require("discord.js"),
{ resolve } = require("path");

View file

@ -1,4 +1,4 @@
const BaseEvent = require("../base/BaseEvent");
const BaseEvent = require("../../base/BaseEvent");
class GuildMemberUpdate extends BaseEvent {
constructor() {

View file

@ -34,7 +34,7 @@ class MessageCreate extends BaseEvent {
message.guild.data = data.guild = guild;
}
if (message.content.match(new RegExp(`^<@!?${client.user.id}>( |)$`))) return message.sendT("misc:HELLO_SERVER", { username: message.author.username });
if (message.content.match(new RegExp(`^<@!?${client.user.id}>( |)$`))) return message.replyT("misc:HELLO_SERVER", { username: message.author.username });
if (message.guild) {
const memberData = await client.findOrCreateMember({
@ -68,7 +68,7 @@ class MessageCreate extends BaseEvent {
if (afkReason) {
data.userData.afk = null;
await data.userData.save();
message.sendT("general/setafk:DELETED", {
message.replyT("general/setafk:DELETED", {
username: message.author.username
});
}

View file

@ -19,7 +19,7 @@ class Ready extends BaseEvent {
let tServers = client.guilds.cache.size - 1;
// Logs some informations using logger
client.logger.log(`Loaded a total of ${commands.length} command(s).`, "log");
client.logger.log(`Loaded a total of ${commands.length} command(s).`, "ready");
client.logger.log(`${client.user.tag}, ready to serve ${tUsers} users in ${tServers} servers.`, "ready");
client.logger.log(`Invite Link: ${client.generateInvite({ scopes: ["bot", "applications.commands"] , permissions: [Permissions.FLAGS.ADMINISTRATOR] })}`, "ready");
@ -44,7 +44,7 @@ class Ready extends BaseEvent {
clearTransactions.init(client);
// Start the dashboard
if (client.config.dashboard.enabled) client.dashboard.load(client);
if (client.config.dashboard.enabled) client.dashboard.init(client);
// Update status
const version = require("../package.json").version;

View file

@ -1,48 +1,40 @@
/* THIS UPDATES THE DOCS */
module.exports = {
/**
* Update the doc
* @param {object} client The Discord Client instance
*/
update(client) {
const table = require("markdown-table"),
fs = require("fs"),
commands = client.commands,
categories = [];
commands.forEach((cmd) => {
if (!categories.includes(cmd.help.category)) categories.push(cmd.help.category);
module.exports.update = function (client) {
const table = require("markdown-table"),
fs = require("fs"),
commands = client.commands,
categories = [],
length = [...new Map(commands.map(v => [v.constructor.name, v])).values()].length;
commands.forEach((cmd) => {
if (!categories.includes(cmd.category)) categories.push(cmd.category);
});
let text = `# JaBa имеет **${length} ${client.getNoun(length, "команда", "команды", "команд")}** в **${categories.length} ${client.getNoun(categories.length, "категории", "категориях", "категориях")}**! \n\n#### Содержимое таблицы \n**Название**: Название команды \n**Описание**: Описание команды \n**Использование**: Использование команды ( [] - обязательно, () - необязательно ) \n**Разрешено использование**: Где можно использовать команду \n\n`;
// categories.sort(function(a, b) {
// const aCmdsSize = commands.filter((cmd) => cmd.category === a).size;
// const bCmdsSize = commands.filter((cmd) => cmd.category === b).size;
// if (aCmdsSize > bCmdsSize) return -1;
// else return 1;
// })
categories.sort().forEach((cat) => {
const categoriesArray = [
["Название", "Описание", "Использование", "Разрешено использование"]
];
const cmds = commands.filter((cmd) => cmd.category === cat),
length = [...new Map(cmds.map(v => [v.constructor.name, v])).values()].length;
text += `### ${cat} (${length} ${client.getNoun(length, "команда", "команды", "команд")})\n\n`;
cmds.sort(function (a, b) {
if (a.command.name < b.command.name) return -1;
else return 1;
}).forEach((cmd) => {
categoriesArray.push([
`**${cmd.command.name}** ${cmd.aliases.length ? `**(${cmd.aliases.join(", ")})**` : ""}`,
client.translate(`${cmd.category.toLowerCase()}/${cmd.command.name}:DESCRIPTION`),
`${cmd.command.name} ${client.translate(`${cmd.category.toLowerCase()}/${cmd.command.name}:USAGE`)}`,
cmd.guildOnly ? "Только на сервере" : "На сервере и в ЛС бота"
]);
});
let text = `# JaBa имеет свыше **${Math.floor(commands.size / 10)}0 команд** в **${categories.length} категориях**! \n\n#### Содержимое таблицы \n**Название**: Название команды \n**Описание**: Описание команды \n**Использование**: Использование команды ( [] - обязательно, () - необязательно ) \n**Разрешено использование**: Где можно использовать команду \n**Откат**: Время, через которое команду можно будет использовать повторно\n\n`;
// categories.sort(function(a, b) {
// const aCmdsSize = commands.filter((cmd) => cmd.help.category === a).size;
// const bCmdsSize = commands.filter((cmd) => cmd.help.category === b).size;
// if (aCmdsSize > bCmdsSize) return -1;
// else return 1;
// })
categories.sort().forEach((cat) => {
const arrCat = [
["Название", "Описание", "Использование", "Разрешено использование", "Откат"]
];
const cmds = commands.filter((cmd) => cmd.help.category === cat);
text += `### ${cat} (${cmds.size} ${client.getNoun(cmds.size, "команда", "команды", "команд")})\n\n`;
cmds.sort(function (a, b) {
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(", ")})**` : ""}`,
client.translate(`${cmd.help.category.toLowerCase()}/${cmd.help.name}:DESCRIPTION`),
client.translate(`${cmd.help.category.toLowerCase()}/${cmd.help.name}:USAGE`),
cmd.conf.guildOnly ? "Только на сервере" : "На сервере и в ЛС бота",
`${Math.ceil(cmd.conf.cooldown / 1000)} ${client.getNoun(Math.ceil(cmd.conf.cooldown / 1000), "секунда", "секунды", "секунд")}`
]);
});
text += `${table(arrCat)}\n\n`;
});
if (!fs.existsSync("./dashboard/public/docs")) fs.mkdirSync("./dashboard/public/docs");
fs.writeFileSync("./dashboard/public/docs/commands.md", text);
client.logger.log("Dashboard docs updated!");
}
text += `${table(categoriesArray)}\n\n`;
});
if (!fs.existsSync("./dashboard/public/docs")) fs.mkdirSync("./dashboard/public/docs");
fs.writeFileSync("./dashboard/public/docs/commands.md", text);
client.logger.log("Dashboard docs updated!");
};

View file

@ -1,7 +1,7 @@
const CronJob = require("cron").CronJob,
Discord = require("discord.js");
async function init(client) {
module.exports.init = async function (client) {
new CronJob("0 5 * * *", async function () {
client.guilds.cache.forEach(async (guild) => {
const date = new Date(),
@ -55,8 +55,4 @@ async function init(client) {
}
});
}, null, true, "Europe/Moscow");
}
module.exports = {
init
};

View file

@ -1,51 +1,44 @@
const Discord = require("discord.js");
/* THIS CHECK IF THERE IS A REMIND MUST BE SENT */
module.exports = {
/**
* Starts checking...
* @param {object} client The Discord Client instance
*/
init(client) {
client.usersData
.find({ reminds: { $gt: [] } })
.then((users) => {
for (const user of users) {
if (!client.users.cache.has(user.id)) client.users.fetch(user.id);
client.databaseCache.usersReminds.set(user.id, user);
}
});
setInterval(async function () {
const dateNow = Date.now();
client.databaseCache.usersReminds.forEach(async (user) => {
const dUser = client.users.cache.get(user.id);
if (dUser) {
const reminds = user.reminds;
const mustSent = reminds.filter((r) => r.sendAt < dateNow);
if (mustSent.length > 0) {
mustSent.forEach((r) => {
const embed = new Discord.MessageEmbed()
.setAuthor({
name: client.translate("general/remindme:TITLE")
})
.addField(client.translate("common:CREATION"), client.translate("general/remindme:CREATED", {
time: client.convertTime(r.createdAt, "from")
}))
.addField(client.translate("common:MESSAGE"), r.message)
.setColor(client.config.embed.color)
.setFooter({
text: client.config.embed.footer
});
dUser.send({
embeds: [embed]
module.exports.init = function (client) {
client.usersData
.find({ reminds: { $gt: [] } })
.then((users) => {
for (const user of users) {
if (!client.users.cache.has(user.id)) client.users.fetch(user.id);
client.databaseCache.usersReminds.set(user.id, user);
}
});
setInterval(async function () {
const dateNow = Date.now();
client.databaseCache.usersReminds.forEach(async (user) => {
const dUser = client.users.cache.get(user.id);
if (dUser) {
const reminds = user.reminds;
const mustSent = reminds.filter((r) => r.sendAt < dateNow);
if (mustSent.length > 0) {
mustSent.forEach((r) => {
const embed = new Discord.MessageEmbed()
.setAuthor({
name: client.translate("general/remindme:TITLE")
})
.addField(client.translate("common:CREATION"), client.translate("general/remindme:CREATED", {
time: client.convertTime(r.createdAt, "from")
}))
.addField(client.translate("common:MESSAGE"), r.message)
.setColor(client.config.embed.color)
.setFooter({
text: client.config.embed.footer
});
dUser.send({
embeds: [embed]
});
user.reminds = user.reminds.filter((r) => r.sendAt >= dateNow);
user.save();
if (user.reminds.length === 0) client.databaseCache.usersReminds.delete(user.id);
}
});
user.reminds = user.reminds.filter((r) => r.sendAt >= dateNow);
user.save();
if (user.reminds.length === 0) client.databaseCache.usersReminds.delete(user.id);
}
});
}, 1000);
}
}
});
}, 1000);
};

View file

@ -1,67 +1,59 @@
const Discord = require("discord.js");
module.exports = {
/**
* Check if there is a user to unmute
* @param {object} client The Discord Client instance
*/
async init(client) {
client.membersData
.find({ "mute.muted": true })
.then((members) => {
members.forEach((member) => {
client.databaseCache.mutedUsers.set(`${member.id}${member.guildID}`, member);
});
});
setInterval(async () => {
client.databaseCache.mutedUsers.filter((m) => m.mute.endDate <= Date.now()).forEach(async (memberData) => {
const guild = client.guilds.cache.get(memberData.guildID);
if (!guild) return;
const member = guild.members.cache.get(memberData.id) || await guild.members.fetch(memberData.id).catch(() => {
memberData.mute = {
muted: false,
endDate: null,
case: null
};
memberData.save();
client.logger.log("[unmute] " + memberData.id + " cannot be found.");
return null;
});
const guildData = await client.findOrCreateGuild({
id: guild.id
});
guild.data = guildData;
if (member) {
guild.channels.cache.forEach((channel) => {
const permOverwrites = channel.permissionOverwrites.cache.get(member.id);
if (permOverwrites) permOverwrites.delete();
});
}
const user = member ? member.user : await client.users.fetch(memberData.id);
const embed = new Discord.MessageEmbed()
.setDescription(guild.translate("moderation/unmute:SUCCESS_CASE", {
user: user.toString(),
usertag: user.tag,
count: memberData.mute.case
}))
.setColor("#f44271")
.setFooter({
text: guild.client.config.embed.footer
});
const channel = guild.channels.cache.get(guildData.plugins.modlogs);
if (channel) channel.send({
embeds: [embed]
});
module.exports.init = async function (client) {
client.membersData
.find({ "mute.muted": true })
.then((members) => {
members.forEach((member) => client.databaseCache.mutedUsers.set(`${member.id}${member.guildID}`, member));
});
setInterval(async () => {
client.databaseCache.mutedUsers.filter((m) => m.mute.endDate <= Date.now()).forEach(async (memberData) => {
const guild = client.guilds.cache.get(memberData.guildID);
if (!guild) return;
const member = guild.members.cache.get(memberData.id) || await guild.members.fetch(memberData.id).catch(() => {
memberData.mute = {
muted: false,
endDate: null,
case: null
};
client.databaseCache.mutedUsers.delete(`${memberData.id}${memberData.guildID}`);
await memberData.save();
memberData.save();
client.logger.log("[unmute] " + memberData.id + " cannot be found.");
return null;
});
}, 1000);
}
const guildData = await client.findOrCreateGuild({
id: guild.id
});
if (member) {
guild.channels.cache.forEach((channel) => {
const permOverwrites = channel.permissionOverwrites.cache.get(member.id);
if (permOverwrites) permOverwrites.delete();
});
}
const user = member ? member.user : await client.users.fetch(memberData.id);
const embed = new Discord.MessageEmbed()
.setDescription(guild.translate("moderation/unmute:SUCCESS_CASE", {
user: user.toString(),
usertag: user.tag,
count: memberData.mute.case
}))
.setColor("#F44271")
.setFooter({
text: guild.client.config.embed.footer
});
const channel = guild.channels.cache.get(guildData.plugins.modlogs);
if (channel) channel.send({ embeds: [embed] });
memberData.mute = {
muted: false,
endDate: null,
case: null
};
client.databaseCache.mutedUsers.delete(`${memberData.id}${memberData.guildID}`);
await memberData.save();
});
}, 1000);
};

View file

@ -1,19 +1,18 @@
module.exports = {
async init(client) {
setInterval(async () => {
const timestamp = Date.now() + 30 * 24 * 60 * 60 * 1000; // day hour min sec msec / 1 month
const members = client.membersData.find({ transactions: { $gt: [] } });
module.exports.init = async function (client) {
setInterval(async () => {
// Date.now() + days * hours * mins * secs * msecs / 1 month
const timestamp = Date.now() + 30 * 24 * 60 * 60 * 1000;
const members = client.membersData.find({ transactions: { $gt: [] } });
for (const member of members) {
const transactions = member.transactions;
for await (const transaction of transactions) {
if (transaction.date < timestamp) {
const index = transactions.indexOf(transaction);
transactions.splice(index, 1);
await member.save();
}
for (const member of members) {
const transactions = member.transactions;
for await (const transaction of transactions) {
if (transaction.date < timestamp) {
const index = transactions.indexOf(transaction);
transactions.splice(index, 1);
await member.save();
}
}
}, 24 * 60 * 60 * 1000); // every 24 hours
},
}
}, 7 * 24 * 60 * 60 * 1000); // every 7 days
};

View file

@ -1,6 +1,4 @@
module.exports = {
init(client) {
const { DiscordTogether } = require("discord-together");
client.discordTogether = new DiscordTogether(client);
}
module.exports.init = function (client) {
const { DiscordTogether } = require("discord-together");
client.discordTogether = new DiscordTogether(client);
};

View file

@ -1,11 +1,4 @@
const { Guild, Message } = require("discord.js");
Guild.prototype.translate = function (key, args) {
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);
};
const { Message, Interaction } = require("discord.js");
Message.prototype.translate = function (key, args) {
const language = this.client.translations.get(this.guild ? this.guild.data.language : "ru-RU");
@ -14,39 +7,49 @@ Message.prototype.translate = function (key, args) {
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);
};
// Translate and send the message
Message.prototype.sendT = function (key, args, options = {}) {
let string = this.translate(key, args);
Message.prototype.replyT = function (key, args, options = {}) {
let string = this.translate(key, args, this.guild ? this.guild.data.language : "ru-RU");
if (options.prefixEmoji) string = `${this.client.customEmojis[options.prefixEmoji]} | ${string}`;
if (options.edit) return this.edit(string);
else return this.reply({ content: string });
};
// Format a date
Message.prototype.printDate = function (date, format) {
return this.client.printDate(date, format, this.guild.data.language);
Message.prototype.error = function (key, args, options = {}) {
options.prefixEmoji = "error";
return this.replyT(key, args, options);
};
// Convert time
Message.prototype.convertTime = function (time, type, noPrefix) {
return this.client.convertTime(time, type, noPrefix, (this.guild && this.guild.data) ? this.guild.data.language : null);
Message.prototype.success = function (key, args, options = {}) {
options.prefixEmoji = "success";
return this.replyT(key, args, options);
};
Message.prototype.getNoun = function (number, one, two, five) {
return this.client.getNoun(number, one, two, five);
Interaction.prototype.translate = function (key, args) {
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);
};
Interaction.prototype.replyT = function (key, args, options = {}) {
let string = this.translate(key, args, this.guild ? this.guild.data.language : "ru-RU");
if (options.prefixEmoji) string = `${this.client.customEmojis[options.prefixEmoji]} | ${string}`;
if (options.edit) return this.editReply(string);
else return this.reply({ content: string, ephemeral: options.ephemeral || false, fetchReply: options.fetchReply || false });
};
Interaction.prototype.error = function (key, args, options = {}) {
options.prefixEmoji = "error";
return this.replyT(key, args, options);
};
Interaction.prototype.success = function (key, args, options = {}) {
options.prefixEmoji = "success";
return this.replyT(key, args, options);
};

View file

@ -1,31 +1,10 @@
const { Permissions } = require("discord.js");
const languages = require("../languages/language-meta.json").map((l) => l.moment).filter((l) => l !== "en");
languages.forEach((lang) => {
const { Permissions } = require("discord.js"),
langs = require("../languages/language-meta.json").map((l) => l.moment).filter((l) => l !== "en");
langs.forEach((lang) => {
require(`moment/locale/${lang}.js`);
});
module.exports = {
getPrefix(message, data) {
if (message.channel.type !== "DM") {
const prefixes = [
`<@!${message.client.user.id}> `,
`<@${message.client.user.id}> `,
`<@!${message.client.user.id}>`,
`<@${message.client.user.id}>`,
message.client.user.username.toLowerCase(),
data.guild.prefix
];
let prefix = null;
prefixes.forEach((p) => {
if (message.content.startsWith(p) || message.content.toLowerCase().startsWith(p)) prefix = p;
});
return prefix;
} else return true;
},
async createInvite(client, guildId) {
const guild = client.guilds.cache.get(guildId);
const member = guild.me;
@ -70,49 +49,5 @@ module.exports = {
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min + 1);
},
convertTime(guild, time) {
const absoluteSeconds = Math.floor((time / 1000) % 60);
const absoluteMinutes = Math.floor((time / (1000 * 60)) % 60);
const absoluteHours = Math.floor((time / (1000 * 60 * 60)) % 24);
const absoluteDays = Math.floor(time / (1000 * 60 * 60 * 24));
const d = absoluteDays ?
absoluteDays === 1 ?
guild.translate("time:ONE_DAY") :
guild.translate("time:DAYS", {
amount: absoluteDays
}) :
null;
const h = absoluteHours ?
absoluteHours === 1 ?
guild.translate("time:ONE_HOUR") :
guild.translate("time:HOURS", {
amount: absoluteHours
}) :
null;
const m = absoluteMinutes ?
absoluteMinutes === 1 ?
guild.translate("time:ONE_MINUTE") :
guild.translate("time:MINUTES", {
amount: absoluteMinutes
}) :
null;
const s = absoluteSeconds ?
absoluteSeconds === 1 ?
guild.translate("time:ONE_SECOND") :
guild.translate("time:SECONDS", {
amount: absoluteSeconds
}) :
null;
const absoluteTime = [];
if (d) absoluteTime.push(d);
if (h) absoluteTime.push(h);
if (m) absoluteTime.push(m);
if (s) absoluteTime.push(s);
return absoluteTime.join(", ");
}
};

View file

@ -11,9 +11,9 @@ function dateTimePad(value, digits) {
}
function format(tDate) {
return (tDate.getFullYear() + "-" +
return (tDate.getDate() + "-" +
dateTimePad((tDate.getMonth() + 1), 2) + "-" +
dateTimePad(tDate.getDate(), 2) + " " +
dateTimePad(tDate.getFullYear(), 2) + " " +
dateTimePad(tDate.getHours(), 2) + ":" +
dateTimePad(tDate.getMinutes(), 2) + ":" +
dateTimePad(tDate.getSeconds(), 2) + "." +

View file

@ -1,10 +1,10 @@
// Thanks to simply-djs for this =)
const Discord = require("discord.js");
const { MessageEmbed, MessageButton, MessageActionRow } = require("discord.js");
/**
* @param message Discord Message
* @param options Array of Options
* @param {require("discord.js").Message} message
* @param {Array} options
*/
/**
slash => Boolean
@ -23,7 +23,6 @@ const Discord = require("discord.js");
idleEmoji => (Emoji ID) String
*/
async function tictactoe(message, options = []) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve) => {
@ -73,7 +72,7 @@ async function tictactoe(message, options = []) {
const foot = options.embedFoot ? { text: options.embedFoot } : { text: "Удачи =)" };
const acceptEmbed = new Discord.MessageEmbed()
const acceptEmbed = new MessageEmbed()
.setTitle(message.translate("economy/tictactoe:REQUEST_WAIT", {
user: opponent.tag
}))
@ -85,17 +84,17 @@ async function tictactoe(message, options = []) {
.setFooter(foot)
.setTimestamp();
const accept = new Discord.MessageButton()
const accept = new MessageButton()
.setLabel(message.translate("economy/tictactoe:ACCEPT"))
.setStyle("SUCCESS")
.setCustomId("acceptttt");
const decline = new Discord.MessageButton()
const decline = new MessageButton()
.setLabel(message.translate("economy/tictactoe:DECLINE"))
.setStyle("DANGER")
.setCustomId("declinettt");
const accep = new Discord.MessageActionRow().addComponents([
const accep = new MessageActionRow().addComponents([
accept,
decline
]);
@ -199,7 +198,7 @@ async function tictactoe(message, options = []) {
};
const { MessageActionRow, MessageButton } = require("discord.js");
const epm = new Discord.MessageEmbed()
const epm = new MessageEmbed()
.setTitle(message.translate("economy/tictactoe:DESCRIPTION"))
.setColor(options.embedColor || "#075FFF")
.setFooter(foot)
@ -845,7 +844,7 @@ async function tictactoe(message, options = []) {
collector.on("end", (collected, reason) => {
if (reason == "time") {
const embed = new Discord.MessageEmbed()
const embed = new MessageEmbed()
.setTitle(message.translate("economy/tictactoe:NO_ANSWER_TITLE"))
.setAuthor({
name: (message.user ? message.user : message.author).tag,
@ -864,7 +863,7 @@ async function tictactoe(message, options = []) {
});
}
if (reason == "decline") {
const embed = new Discord.MessageEmbed()
const embed = new MessageEmbed()
.setTitle(message.translate("economy/tictactoe:CANCELED"))
.setAuthor({
name: (message.user ? message.user : message.author).tag,

View file

@ -9,8 +9,10 @@ const client = new JaBa({
});
(async () => {
client.translations = await require("./helpers/languages")();
await client.loadEvents("../events");
await client.loadCommands("../commands", client.config.support.enabled ? client.config.support.id : "");
await client.loadCommands("../commands", client.config.support.production ? "" : client.config.support.id);
await client.init();
})();

View file

@ -6,6 +6,5 @@
"CLICK": "[**Click**]({{link}})",
"TIP": "Send `invite copy` to be able to copy the invite link!",
"ADD": "Invite JaBa",
"VOTE": "Vote for JaBa",
"SUPPORT": "Support developer"
}

View file

@ -4,6 +4,5 @@
"EXAMPLES": "suggest New channel #offtopic please",
"MISSING_CHANNEL": "No suggestion channel defined!",
"MISSING_CONTENT": "Please enter a suggestion!",
"TITLE": "Suggestion - {{user}}",
"SUCCESS": "Your suggestion is being voted in {{channel}}!"
"TITLE": "Suggestion - {{user}}"
}

View file

@ -6,6 +6,5 @@
"NO_GAME": "Not playing",
"NO_ROLE": "No role",
"NO_NICKNAME": "No nickname",
"MORE_ROLES": "and {{count}} others roles",
"BOT_STATS": "**{{votes}}** votes ([top.gg](https://top.gg))\n**{{servers}}** servers\n**{{shards}}** shards\nUsing **{{lib}}**"
"MORE_ROLES": "and {{count}} others roles"
}

View file

@ -14,8 +14,6 @@
"NO_PERMS": "You must have an administration rights to perform this action!",
"NO_REASON_PROVIDED": "No reason provided",
"NO_USER_FOUND_ID": "No user on Discord has the ID `{{id}}`!",
"VOTE_DM": "⬆️ Hello {{user}}, thanks for voting!\nHere's your reward: 40 credits (on the support server)!",
"VOTE_LOGS": "⬆️ **{{usertag}}** (`{{userid}}`) voted for **JaBa** and won **40** credits, thank you!\n<https://discordbots.org/bot/557445719892688897/vote>",
"HELLO_SERVER": "Hello **{{username}}**, my prefix on this server is ``. Use `help` to get the list of the commands!",
"HELLO_DM": "Hello, as you are currently in direct message you don't need to add a prefix before command name.",
"GUILD_ONLY": "This command is only available on a server!",

View file

@ -2,6 +2,5 @@
"DESCRIPTION": "Stop the music",
"USAGE": "stop",
"EXAMPLES": "stop",
"VOTE_CONTENT": "React with 👍 to stop the music! {{requiredCount}} more votes are required.",
"SUCCESS": "Music stopped!"
}

View file

@ -6,6 +6,5 @@
"CLICK": "[**Тык**]({{link}})",
"TIP": "Отправьте `invite copy`, чтобы получить ссылку для копирования!",
"ADD": "Пригласить JaBa",
"VOTE": "Проголосовать за JaBa",
"SUPPORT": "Поддержать разработчика"
}

View file

@ -7,6 +7,5 @@
"NO_ROLE": "Нет роли",
"ROLE": "Высшая роль",
"NO_NICKNAME": "Нет никнейма",
"MORE_ROLES": "и ещё {{count}} роль(и/ей)",
"BOT_STATS": "**{{votes}}** голосов ([top.gg](https://top.gg))\n**{{servers}}** серверов\n**{{shards}}** шардов\nИспользует **{{lib}}**"
"MORE_ROLES": "и ещё {{count}} роль(и/ей)"
}

View file

@ -15,8 +15,6 @@
"NO_PERMS": "Недостаточно прав для выполнения данного действия!",
"NO_REASON_PROVIDED": "Причина не указана",
"NO_USER_FOUND_ID": "Пользователя с ID `{{id}}` не существует!",
"VOTE_DM": "⬆️ Привет, {{user}}, спасибо за голос!\nТвоя награда - 50 кредитов (на сервере поддержки)!",
"VOTE_LOGS": "⬆️ **{{usertag}}** (`{{userid}}`) проголосовал за **JaBa** и получил **50** кредитов, спасибо!\n<https://discordbots.org/bot/000000000000/vote>",
"HELLO_SERVER": "Привет, **{{username}}**! Все мои команды доступны через **/** Используйте `/help`, чтобы получить список команд!",
"GUILD_ONLY": "Данную команду можно использовать только на сервере!",
"MISSING_BOT_PERMS": "Мне необходимы следующие права для выполнения данной команды: {{list}}",

View file

@ -6,6 +6,5 @@
"CLICK": "[**Тик**]({{link}})",
"TIP": "Відправте `invite copy`, щоб отримати посилання для копіювання!",
"ADD": "Запросити JaBa",
"VOTE": "Проголосувати за JaBa",
"SUPPORT": "Підтримати розробника"
}

View file

@ -7,6 +7,5 @@
"NO_ROLE": "Немає ролі",
"ROLE": "Вища роль",
"NO_NICKNAME": "Немає нікнейму",
"MORE_ROLES": "і ще {{count}} роль(і/ей)",
"BOT_STATS": "**{{votes}}** голосів ([top.gg](https://top.gg))\n**{{servers}}** серверів\n**{{shards }}** шардів\nВикористовує **{{lib}}**"
"MORE_ROLES": "і ще {{count}} роль(і/ей)"
}

View file

@ -15,8 +15,6 @@
"NO_PERMS": "Недостатньо прав для виконання цієї дії!",
"NO_REASON_PROVIDED": "Причина не вказана",
"NO_USER_FOUND_ID": "Користувача з ID `{{id}}` не існує!",
"VOTE_DM": "⬆️ Привіт, {{user}}, дякую за голос!\nТвоя нагорода - 50 кредитів (на сервері підтримки)!",
"VOTE_LOGS": "⬆️ **{{usertag}}** (`{{userid}}`) проголосував за **JaBa** і отримав **50** кредитів, дякую!\n<https://discordbots .org/bot/000000000000/vote>",
"HELLO_SERVER": "Привіт, **{{username}}**, мій префікс на даному сервері - ``. Використовуйте `help`, щоб отримати список команд!",
"HELLO_DM": "Привіт, тому що ви пишете в ОП, вам не потрібно використовувати префікс.",
"GUILD_ONLY": "Цю команду можна використовувати лише на сервері!",

View file

@ -1,11 +1,11 @@
/* eslint-disable no-async-promise-executor */
const config = require("../config");
const fetch = require("node-fetch");
const chalk = require("chalk");
const success = (message) => console.log(` ${chalk.green("✓")} ${message}`);
const error = (message, howToFix) => console.log(` ${chalk.red("✗")} ${message}${howToFix ? ` : ${howToFix}` : ""}`);
const ignore = (message) => console.log(` ${chalk.yellow("~")} ${message}`);
const { Intents } = require("discord.js"),
config = require("../config"),
fetch = require("node-fetch"),
chalk = require("chalk"),
success = (message) => console.log(` ${chalk.green("✓")} ${message}`),
error = (message, howToFix) => console.log(` ${chalk.red("✗")} ${message}${howToFix ? ` : ${howToFix}` : ""}`),
ignore = (message) => console.log(` ${chalk.yellow("~")} ${message}`);
const checks = [
() => {
@ -23,7 +23,7 @@ const checks = [
console.log("\n\nDiscord Bot");
return new Promise((res) => {
const Discord = require("discord.js");
const client = new Discord.Client();
const client = new Discord.Client({ intents: Object.keys(Intents.FLAGS) });
let readyResolve;
new Promise((resolve) => readyResolve = resolve);
client.login(config.token).then(async () => {
@ -55,7 +55,7 @@ const checks = [
success("Connection to Mongo database success");
res();
}).catch(() => {
error("Should be able to connect to Mongo database", "please verify if the MongoDB server is started");
error("Not able to connect to Mongo database", "please verify if the MongoDB server is started");
res();
});
});
@ -64,7 +64,7 @@ const checks = [
console.log("\n\nAPI keys");
return new Promise(async (resolve) => {
if (!config.apiKeys.amethyste) {
ignore("Amethyste API is not configured, key should not be checked.");
ignore("Amethyste API is not configured, skipping check.");
} else {
const res = await fetch("https://v1.api.amethyste.moe/generate/blurple", {
method: "POST",
@ -74,13 +74,13 @@ const checks = [
});
const result = await res.json();
if (result.status === 401) {
error("Should be a valid Amethyste API key", "get your key here: https://api.amethyste.moe/");
error("Not valid Amethyste API key", "get your key here: https://api.amethyste.moe/");
} else {
success("Valid Amethyste API key");
}
}
if (!config.apiKeys.blagueXYZ) {
ignore("blague.xyz API is not configured, key should not be checked.");
ignore("blague.xyz API is not configured, skipping check.");
} else {
const res = await fetch("https://blague.xyz/api/joke/random", {
headers: {
@ -89,27 +89,11 @@ const checks = [
});
const result = await res.json();
if (result.status === 401) {
error("Should be a valid blague.xyz key", "get your key here: https://blague.xyz/");
error("Not valid blague.xyz key", "get your key here: https://blague.xyz/");
} else {
success("Valid blague.xyz key");
}
}
if (!config.apiKeys.dbl) {
ignore("DBL API is not configured, key should not be checked.");
} else {
const res = await fetch("https://top.gg/api/bots/check?userId=test", {
method: "POST",
headers: {
Authorization: config.apiKeys.dbl
}
});
const result = await res.json();
if (result.error && result.error === "Unauthorized") {
error("Should be a valid DBL key", "get your key here: https://top.gg/ OR delete the key from the config if you don't have a key");
} else {
success("Valid DBL key");
}
}
resolve();
});
},
@ -117,7 +101,7 @@ const checks = [
console.log("\n\nDashboard");
return new Promise(async (resolve) => {
if (!config.dashboard.enabled) {
ignore("Dashboard is not enabled, config shouldn't be checked.");
ignore("Dashboard is not enabled, skipping check.");
} else {
const checkPortTaken = (port) => {
return new Promise((resolve) => {
@ -138,7 +122,7 @@ const checks = [
};
const isPortTaken = await checkPortTaken(config.dashboard.port);
if (isPortTaken) {
error("Dashboard port should be available", "you have probably another process using this port");
error("Dashboard port not available", "you have probably another process using this port");
} else {
success("Dashboard port is available");
}