mirror of
https://github.com/JonnyBro/JaBa.git
synced 2024-11-24 06:04:57 +05:00
v4.5.0
This commit is contained in:
parent
07658d64d2
commit
b1d1c5a0ab
12 changed files with 230 additions and 78 deletions
|
@ -81,7 +81,11 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Logins into the account and connects to the database
|
||||
* Initializes the client by logging in with the provided token and connecting to the MongoDB database.
|
||||
*
|
||||
* This method is called during the client's startup process to set up the necessary connections and resources.
|
||||
*
|
||||
* @returns {Promise<void>} A Promise that resolves when the client is fully initialized.
|
||||
*/
|
||||
async init() {
|
||||
this.login(this.config.token);
|
||||
|
@ -100,8 +104,14 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads all commands from directory
|
||||
* @param {String} dir Directory where commands are located
|
||||
* Loads all the commands from the specified directory and registers them with the Discord API.
|
||||
*
|
||||
* This method is responsible for dynamically loading all the command files from the specified directory,
|
||||
* creating instances of the corresponding command classes, and registering the commands with the Discord API.
|
||||
* It also handles any additional setup or initialization required by the loaded commands.
|
||||
*
|
||||
* @param {string} dir - The directory path where the command files are located.
|
||||
* @returns {Promise<void>} A Promise that resolves when all the commands have been loaded and registered.
|
||||
*/
|
||||
async loadCommands(dir) {
|
||||
const rest = new REST().setToken(this.config.token),
|
||||
|
@ -147,17 +157,19 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* @returns {String} Bot's default language
|
||||
* Returns the default language from the list of available languages.
|
||||
* @returns {Language} The default language.
|
||||
*/
|
||||
get defaultLanguage() {
|
||||
return this.languages.find(language => language.default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates from a key to language
|
||||
* @param {String} key Key
|
||||
* @param {Array} args Arguments for translation
|
||||
* @param {String} locale Language
|
||||
* Translates a key using the specified locale, or the default language if no locale is provided.
|
||||
* @param {string} key The translation key to look up.
|
||||
* @param {any[]} args Any arguments to pass to the translation function.
|
||||
* @param {string} [locale=this.defaultLanguage.name] The locale to use for the translation. Defaults to the default language.
|
||||
* @returns {string} The translated string.
|
||||
*/
|
||||
translate(key, args, locale = this.defaultLanguage.name) {
|
||||
const lang = this.translations.get(locale);
|
||||
|
@ -166,9 +178,19 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns an embed created from given data
|
||||
* @param {Object} data Data for embed
|
||||
* @returns {import("discord.js").Embed}
|
||||
* Generates an EmbedBuilder instance with the provided data.
|
||||
* @param {Object} data - The data to use for the embed.
|
||||
* @param {string} [data.title] - The title of the embed.
|
||||
* @param {string} [data.description] - The description of the embed.
|
||||
* @param {string} [data.thumbnail] - The URL of the thumbnail image for the embed.
|
||||
* @param {Object[]} [data.fields] - An array of field objects for the embed.
|
||||
* @param {string} [data.image] - The URL of the image for the embed.
|
||||
* @param {string} [data.url] - The URL to be used as the embed's hyperlink.
|
||||
* @param {number} [data.color] - The color of the embed's border. If not provided, the default color from the client's configuration will be used.
|
||||
* @param {string} [data.footer] - The text to be displayed as the embed's footer. If not provided, the default footer from the client's configuration will be used.
|
||||
* @param {Date} [data.timestamp] - The timestamp to be displayed in the embed's footer. If not provided, the current timestamp will be used.
|
||||
* @param {string|Object} [data.author] - The author information for the embed. Can be a string (name) or an object with `name` and/or `iconURL` properties.
|
||||
* @returns {EmbedBuilder} The generated EmbedBuilder instance.
|
||||
*/
|
||||
embed(data) {
|
||||
const embed = new EmbedBuilder()
|
||||
|
@ -193,16 +215,16 @@ class JaBaClient extends Client {
|
|||
|
||||
if (!data.author || data.author === null) embed.setAuthor(null);
|
||||
else if (typeof data.author === "string") embed.setAuthor({ name: data.author, iconURL: this.user.avatarURL() });
|
||||
else if (typeof data.author === "object" && (data.author.iconURL !== null || data.author.iconURL !== undefined)) embed.setAuthor({ name: data.author.name, iconURL: this.user.avatarURL() });
|
||||
else if (typeof data.author === "object" && (data.author.iconURL !== null || data.author.iconURL !== undefined)) embed.setAuthor({ name: data.author.name, iconURL: data.author.iconURL });
|
||||
else embed.setAuthor(data.author);
|
||||
|
||||
return embed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invite link for guild
|
||||
* @param {String} guildId Guild ID
|
||||
* @returns {String} Invite link
|
||||
* Creates an invite for the specified guild.
|
||||
* @param {string} guildId - The ID of the guild to create the invite for.
|
||||
* @returns {Promise<string>} The URL of the created invite, or an error message if no suitable channel was found or the bot lacks the necessary permissions.
|
||||
*/
|
||||
async createInvite(guildId) {
|
||||
const guild = this.guilds.cache.get(guildId),
|
||||
|
@ -213,9 +235,10 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads a single command from directory
|
||||
* @param {String} dir Directory where command is located
|
||||
* @param {String} file Filename of the command
|
||||
* Loads a command from the specified directory and file.
|
||||
* @param {string} dir - The directory containing the command file.
|
||||
* @param {string} file - The name of the command file (without the .js extension).
|
||||
* @returns {Promise<string>} A log message indicating the successful loading of the command.
|
||||
*/
|
||||
async loadCommand(dir, file) {
|
||||
const Command = require(path.join(dir, `${file}.js`));
|
||||
|
@ -230,10 +253,10 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes a command from cache
|
||||
* @param {String} dir Directory where command is located
|
||||
* @param {String} name Command name
|
||||
* @returns
|
||||
* Unloads a command from the specified directory and file.
|
||||
* @param {string} dir - The directory containing the command file.
|
||||
* @param {string} name - The name of the command file (without the .js extension).
|
||||
* @returns {void} This method does not return a value.
|
||||
*/
|
||||
async unloadCommand(dir, name) {
|
||||
delete require.cache[require.resolve(`${dir}${path.sep}${name}.js`)];
|
||||
|
@ -242,8 +265,9 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads all events from directory recursively
|
||||
* @param {String} dir Directory where events are located
|
||||
* Loads all event files from the specified directory and its subdirectories.
|
||||
* @param {string} dir - The directory containing the event files.
|
||||
* @returns {void} This method does not return a value.
|
||||
*/
|
||||
async loadEvents(dir) {
|
||||
const filePath = path.join(__dirname, dir);
|
||||
|
@ -270,9 +294,9 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Finds or creates a user in the database
|
||||
* @param {String} userID User ID
|
||||
* @returns {Promise<import("./User")>} Mongoose model
|
||||
* Finds or creates a user in the database based on the provided user ID.
|
||||
* @param {string} userID - The ID of the user to find or create.
|
||||
* @returns {Promise<Object>} The user data object, either retrieved from the database or newly created.
|
||||
*/
|
||||
async findOrCreateUser(userID) {
|
||||
let userData = await this.usersData.findOne({ id: userID });
|
||||
|
@ -293,9 +317,11 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Finds or creates a guild's member in the database
|
||||
* @param {Array} { id: Member ID, Guild ID }
|
||||
* @returns {Promise<import("./Member")>} Mongoose model
|
||||
* Finds or creates a member in the database based on the provided member ID and guild ID.
|
||||
* @param {Object} options - The options for finding or creating the member.
|
||||
* @param {string} options.id - The ID of the member to find or create.
|
||||
* @param {string} options.guildId - The ID of the guild the member belongs to.
|
||||
* @returns {Promise<Object>} The member data object, either retrieved from the database or newly created.
|
||||
*/
|
||||
async findOrCreateMember({ id: memberID, guildId }) {
|
||||
let memberData = await this.membersData.findOne({ guildID: guildId, id: memberID });
|
||||
|
@ -324,9 +350,9 @@ class JaBaClient extends Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Finds or creates guild in DB
|
||||
* @param {String} guildId Guild ID
|
||||
* @returns {Promise<import("./Guild")>} Mongoose model
|
||||
* Finds or creates a guild in the database based on the provided guild ID.
|
||||
* @param {string} guildId - The ID of the guild to find or create.
|
||||
* @returns {Promise<Object>} The guild data object, either retrieved from the database or newly created.
|
||||
*/
|
||||
async findOrCreateGuild(guildId) {
|
||||
let guildData = await this.guildsData.findOne({ id: guildId }).populate("members");
|
||||
|
|
|
@ -91,11 +91,11 @@ class Poll extends BaseCommand {
|
|||
author: interaction.translate("moderation/poll:TITLE"),
|
||||
fields: [
|
||||
{
|
||||
name: "\u200b",
|
||||
name: "\u200B",
|
||||
value: question,
|
||||
},
|
||||
{
|
||||
name: "\u200b",
|
||||
name: "\u200B",
|
||||
value: interaction.translate("moderation/poll:REACT", {
|
||||
success: cool.toString(),
|
||||
error: notcool.toString(),
|
||||
|
|
|
@ -278,7 +278,7 @@ async function updateEmbed(interaction, queue) {
|
|||
value: progressBar,
|
||||
},
|
||||
{
|
||||
name: "\u200b",
|
||||
name: "\u200B",
|
||||
value: `${interaction.translate("music/nowplaying:REPEAT")}: \`${translated[mode]}\``,
|
||||
},
|
||||
],
|
||||
|
|
90
commands/beatrun.ru/courses.js
Normal file
90
commands/beatrun.ru/courses.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
const { SlashCommandBuilder } = require("discord.js");
|
||||
const BaseCommand = require("../../base/BaseCommand"),
|
||||
fetch = require("node-fetch");
|
||||
|
||||
class Courses extends BaseCommand {
|
||||
/**
|
||||
*
|
||||
* @param {import("../base/Client")} client
|
||||
*/
|
||||
constructor(client) {
|
||||
super({
|
||||
command: new SlashCommandBuilder()
|
||||
.setName("courses")
|
||||
.setDescription(client.translate("beatrun.ru/courses:DESCRIPTION"))
|
||||
.setDescriptionLocalizations({
|
||||
uk: client.translate("beatrun.ru/courses:DESCRIPTION", null, "uk-UA"),
|
||||
ru: client.translate("beatrun.ru/courses:DESCRIPTION", null, "ru-RU"),
|
||||
})
|
||||
.setDMPermission(false)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName("code")
|
||||
.setDescription(client.translate("common:CODE"))
|
||||
.setDescriptionLocalizations({
|
||||
uk: client.translate("common:CODE", null, "uk-UA"),
|
||||
ru: client.translate("common:CODE", null, "ru-RU"),
|
||||
})
|
||||
.setRequired(true),
|
||||
),
|
||||
dirname: __dirname,
|
||||
ownerOnly: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../../base/Client")} client
|
||||
* @param {import("discord.js").ChatInputCommandInteraction} interaction
|
||||
* @param {Object} data
|
||||
*/
|
||||
async execute(client, interaction) {
|
||||
await interaction.deferReply();
|
||||
|
||||
const code = interaction.options.getString("code");
|
||||
|
||||
const response = await fetch(`https://courses.beatrun.ru/api/stats/${code}`).then(res => res.json());
|
||||
|
||||
if (response.res === 401) return interaction.error("beatrun.ru/courses:NOT_FOUND", null, { ephemeral: true, edit: true });
|
||||
|
||||
const embed = client.embed({
|
||||
title: code,
|
||||
description: `[${interaction.translate("beatrun.ru/courses:DOWNLOAD")}](https://courses.beatrun.ru/${response.course.path})`,
|
||||
thumbnail: response.course.mapimg,
|
||||
url: `https://courses.beatrun.ru/?search=${code}`,
|
||||
fields: [
|
||||
{
|
||||
name: interaction.translate("beatrun.ru/courses:MAP"),
|
||||
value: `[${response.course.map}](https://steamcommunity.com/sharedfiles/filedetails/?id=${response.course.mapid})`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: interaction.translate("beatrun.ru/courses:UPLOADER"),
|
||||
value: `[${response.course.uploader.name}](https://steamcommunity.com/profiles/${response.course.uploader.userid})`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "\u200B",
|
||||
value: "\u200B",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: interaction.translate("beatrun.ru/courses:DATE"),
|
||||
value: `<t:${Math.floor(response.course.time / 1000)}:D>`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: interaction.translate("beatrun.ru/courses:PLAYS"),
|
||||
value: `${response.course.plays || 0}`,
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
interaction.editReply({
|
||||
embeds: [embed],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Courses;
|
|
@ -1,18 +1,12 @@
|
|||
const moment = require("moment");
|
||||
|
||||
moment.relativeTimeThreshold("ss", 5);
|
||||
moment.relativeTimeThreshold("s", 60);
|
||||
moment.relativeTimeThreshold("m", 60);
|
||||
moment.relativeTimeThreshold("h", 60);
|
||||
moment.relativeTimeThreshold("d", 24);
|
||||
moment.relativeTimeThreshold("M", 12);
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Calls a Callback for Each Element in Collection Asynchronously
|
||||
* @param {Array} collection Collection
|
||||
* @param {Function} callback Function to Perform on Collection
|
||||
* @returns {Promise}
|
||||
* Asynchronously iterates over a collection and executes a callback function for each item.
|
||||
*
|
||||
* @param {any[]} collection - The collection to iterate over.
|
||||
* @param {(item: any) => Promise<void>} callback - The async callback function to execute for each item in the collection.
|
||||
* @returns {Promise<void>} A promise that resolves when all items in the collection have been processed.
|
||||
*/
|
||||
async asyncForEach(collection, callback) {
|
||||
const allPromises = collection.map(async key => {
|
||||
|
@ -23,10 +17,11 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Sorts an Array by Key
|
||||
* @param {Array} array Array to Sort
|
||||
* @param {Number} key Key
|
||||
* @returns {Array} Sorted Array
|
||||
* Sorts an array by the specified key in ascending order.
|
||||
*
|
||||
* @param {any[]} array - The array to sort.
|
||||
* @param {string} key - The key to sort the array by.
|
||||
* @returns {any[]} The sorted array.
|
||||
*/
|
||||
sortByKey(array, key) {
|
||||
return array.sort(function (a, b) {
|
||||
|
@ -37,9 +32,10 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Shuffles the Array
|
||||
* @param {Array} pArray Array to Shuffle
|
||||
* @returns {Array} Shuffled Array
|
||||
* Shuffles the elements of the provided array in-place.
|
||||
*
|
||||
* @param {any[]} pArray - The array to shuffle.
|
||||
* @returns {any[]} The shuffled array.
|
||||
*/
|
||||
shuffle(pArray) {
|
||||
const array = [];
|
||||
|
@ -63,10 +59,11 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Returns a Random Number Between min (inclusive) And max (inclusive)
|
||||
* @param {Number} min Min value (inclusive)
|
||||
* @param {Number} max Max value (inclusive)
|
||||
* @returns {Number} Integer
|
||||
* Generates a random integer between the specified minimum and maximum values (inclusive).
|
||||
*
|
||||
* @param {number} min - The minimum value (inclusive).
|
||||
* @param {number} max - The maximum value (inclusive).
|
||||
* @returns {number} A random integer between min and max.
|
||||
*/
|
||||
randomNum(min, max) {
|
||||
min = Math.ceil(min);
|
||||
|
@ -76,12 +73,13 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Beautifies the given Date
|
||||
* @param {import("../base/Client")} client Discord Client
|
||||
* @param {Date} date Date
|
||||
* @param {String | null} format Format for Moment
|
||||
* @param {String} locale Language
|
||||
* @returns {String} Beautified Date
|
||||
* Formats a date for the specified client and locale.
|
||||
*
|
||||
* @param {Object} client - The client object containing language data.
|
||||
* @param {string} date - The date to format.
|
||||
* @param {string} [format=null] - The date format to use. If not provided, the default format for the client's language will be used.
|
||||
* @param {string} [locale=client.defaultLanguage.name] - The locale to use for formatting the date.
|
||||
* @returns {string} The formatted date.
|
||||
*/
|
||||
printDate(client, date, format = null, locale = client.defaultLanguage.name) {
|
||||
const languageData = client.languages.find(language => language.name === locale);
|
||||
|
@ -91,13 +89,14 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Converts the Given Time
|
||||
* @param {import("../base/Client")} client Discord Client
|
||||
* @param {String} time Time
|
||||
* @param {Boolean} type Type (To now = true or from now = false)
|
||||
* @param {Boolean} prefix Include Prefix
|
||||
* @param {String} locale Language
|
||||
* @returns {String} Time
|
||||
* Formats a time value relative to the current time.
|
||||
*
|
||||
* @param {Object} client - The client object containing language data.
|
||||
* @param {string|number|Date} time - The time value to format.
|
||||
* @param {boolean} [type=false] - If true, formats the time as "X time ago", otherwise formats it as "in X time".
|
||||
* @param {boolean} [prefix=true] - If true, includes a prefix like "in" or "ago" in the formatted time.
|
||||
* @param {string} [locale=client.defaultLanguage.name] - The locale to use for formatting the time.
|
||||
* @returns {string} The formatted time value.
|
||||
*/
|
||||
convertTime(client, time, type = false, prefix = true, locale = client.defaultLanguage.name) {
|
||||
const languageData = client.languages.find(language => language.name === locale);
|
||||
|
@ -107,12 +106,13 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Get a Noun for Number
|
||||
* @param {Number} number Number
|
||||
* @param {String} one String for one
|
||||
* @param {String} two String for two
|
||||
* @param {String} five String for five
|
||||
* @returns
|
||||
* Generates the appropriate noun form based on the given number and noun forms.
|
||||
*
|
||||
* @param {number} number - The number to use for determining the noun form.
|
||||
* @param {string} one - The noun form for the singular case.
|
||||
* @param {string} two - The noun form for the dual case.
|
||||
* @param {string} five - The noun form for the plural case.
|
||||
* @returns {string} The appropriate noun form based on the given number.
|
||||
*/
|
||||
getNoun(number, one, two, five) {
|
||||
let n = Math.abs(number);
|
||||
|
|
11
languages/en-US/beatrun.ru/courses.json
Normal file
11
languages/en-US/beatrun.ru/courses.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"DESCRIPTION": "Get course info",
|
||||
"USAGE": "",
|
||||
"EXAMPLES": "courses code:ABCD-XZYX-1234",
|
||||
"NOT_FOUND": "Course not found",
|
||||
"MAP": "Map",
|
||||
"UPLOADER": "Uploaded by",
|
||||
"DATE": "Upload date",
|
||||
"PLAYS": "Plays",
|
||||
"DOWNLOAD": "Download"
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
"CANCEL": "Cancel",
|
||||
"CHANNEL": "Channel",
|
||||
"CHANNELS": "Channels",
|
||||
"CODE": "Code",
|
||||
"COLOR": "Color",
|
||||
"CONTENT": "Content",
|
||||
"COMMAND": "Command",
|
||||
|
|
11
languages/ru-RU/beatrun.ru/courses.json
Normal file
11
languages/ru-RU/beatrun.ru/courses.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"DESCRIPTION": "Получить информацию о курсе",
|
||||
"USAGE": "",
|
||||
"EXAMPLES": "courses code:ABCD-XZYX-1234",
|
||||
"NOT_FOUND": "Курс не найден",
|
||||
"MAP": "Карта",
|
||||
"UPLOADER": "Загрузил",
|
||||
"DATE": "Дата загрузки",
|
||||
"PLAYS": "Сыграно",
|
||||
"DOWNLOAD": "Скачать"
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
"CANCEL": "Отменить",
|
||||
"CHANNEL": "Канал",
|
||||
"CHANNELS": "Каналы",
|
||||
"CODE": "Код",
|
||||
"COLOR": "Цвет",
|
||||
"CONTENT": "Содержимое",
|
||||
"COMMAND": "Команда",
|
||||
|
|
11
languages/uk-UA/beatrun.ru/courses.json
Normal file
11
languages/uk-UA/beatrun.ru/courses.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"DESCRIPTION": "Отримати інформацію про курс",
|
||||
"USAGE": "",
|
||||
"EXAMPLES": "courses code:ABCD-XZYX-1234",
|
||||
"NOT_FOUND": "Курс не знайдено",
|
||||
"MAP": "Карта",
|
||||
"UPLOADER": "Завантажив",
|
||||
"DATE": "Дата завантаження",
|
||||
"PLAYS": "Зіграно",
|
||||
"DOWNLOAD": "Завантажити"
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
"CANCEL": "Скасувати",
|
||||
"CHANNEL": "Канал",
|
||||
"CHANNELS": "Канали",
|
||||
"CODE": "Код",
|
||||
"COLOR": "Колір",
|
||||
"CONTENT": "Вміст",
|
||||
"COMMAND": "Команда",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jaba",
|
||||
"version": "4.4.4",
|
||||
"version": "4.5.0",
|
||||
"description": "My Discord Bot",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
Loading…
Reference in a new issue