diff --git a/.gitignore b/.gitignore index d81631d1..2b86767f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,3 @@ Thumbs.db # Node node_modules - -# Dashboard DB -/json.sqlite diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index f1ab3994..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "dashboard/dashboard-core"] - path = dashboard/dashboard-core - url = https://git.jonnybro.ru/jonny_bro/dashboard-core - branch = main diff --git a/README.md b/README.md index 9a5387ff..87ce7928 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ JaBa offers: * Slash and Context commands. * Supports commands in DMs. * Localization support (any language; English, Russian and Ukrainian for now). -* Dashboard for changing various settings. * Basic messages monitoring (updating and deletion). ## Commands @@ -30,10 +29,6 @@ JaBa does many thing, here is **8 main categories**: * **General**: `afk`, `avatar`, `boosters`, `minecraft`, `remindme`, `shorturl`, `serverinfo`, `userinfo`, `whois` and **7** more! * **Bot's owner commands**: `eval`, `servers`, `reload` and **2** more! -## *Kinda* Cool Dashboard - -JaBa has it's own dashboard to change server's settings! - ## Get The Bot ### Ready To Use @@ -54,7 +49,6 @@ Use [this instruction](https://github.com/JonnyBro/JaBa/wiki/Self-Hosting) to le * [Full commands list](https://dash.jababot.ru/commands) * [Discord](https://discord.gg/Ptkj2n9nzZ) * [Github](https://github.com/JonnyBro/JaBa/) -* [Dashboard](https://dash.jababot.ru) ## Support @@ -64,7 +58,7 @@ If you want to contribute, feel free to fork this repo and making a pull request ## TODO * [ ] Refactor [tictactoe](./helpers/tictactoe.js). -* [ ] Finish and release *dashboard-core* submodule. +* [ ] Rewrite dashboard. ## License diff --git a/base/BaseEvent.js b/base/BaseEvent.js index bd69c478..2fa28085 100644 --- a/base/BaseEvent.js +++ b/base/BaseEvent.js @@ -11,4 +11,4 @@ class BaseEvent { } } -module.exports = BaseEvent; +export default BaseEvent; diff --git a/base/Client.js b/base/Client.js index d2b21f14..b8217352 100644 --- a/base/Client.js +++ b/base/Client.js @@ -1,32 +1,41 @@ -const { Client, Collection, SlashCommandBuilder, ContextMenuCommandBuilder, EmbedBuilder, PermissionsBitField, ChannelType } = require("discord.js"), - { GiveawaysManager } = require("discord-giveaways"), - { REST } = require("@discordjs/rest"), - { Player: DiscordPlayer } = require("discord-player"), - { SpotifyExtractor } = require("@discord-player/extractor"), - { YoutubeiExtractor } = require("discord-player-youtubei"), - { Routes } = require("discord-api-types/v10"); +import { Client, Collection, SlashCommandBuilder, ContextMenuCommandBuilder, EmbedBuilder, PermissionsBitField, ChannelType } from "discord.js"; +import { GiveawaysManager } from "discord-giveaways"; +import { REST } from "@discordjs/rest"; +import { Player } from "discord-player"; +import { SpotifyExtractor } from "@discord-player/extractor"; +import { YoutubeiExtractor } from "discord-player-youtubei"; +import { Routes } from "discord-api-types/v10"; +import { join, sep } from "path"; +import { promises as fs } from "fs"; +import { setTimeout } from "timers/promises"; +import mongoose from "mongoose"; -const BaseEvent = require("./BaseEvent.js"), - BaseCommand = require("./BaseCommand.js").default, - path = require("path"), - fs = require("fs").promises, - mongoose = require("mongoose"); +import config from "../config.js"; +import * as emojis from "../emojis.json"; +import langs from "../languages/language-meta.js"; +import logger from "../helpers/logger.js"; +import * as funcs from "../helpers/functions.js"; + +import BaseEvent from "./BaseEvent.js"; +import BaseCommand from "./BaseCommand.js"; +import guild from "./Guild.js"; +import user from "./User.js"; +import member from "./Member.js"; class JaBaClient extends Client { constructor(options) { super(options); - this.config = require("../config"); - this.customEmojis = require("../emojis"); - this.languages = require("../languages/language-meta"); + this.config = config; + this.customEmojis = emojis; + this.languages = langs; this.commands = new Collection(); - this.logger = require("../helpers/logger"); - this.wait = require("node:timers/promises").setTimeout; - this.functions = require("../helpers/functions"); - this.guildsData = require("../base/Guild"); - this.usersData = require("../base/User"); - this.membersData = require("../base/Member"); - this.dashboard = require("../dashboard/dashboard"); + this.logger = logger; + this.wait = setTimeout; + this.functions = funcs; + this.guildsData = guild.default; + this.usersData = user.default; + this.membersData = member.default; this.databaseCache = {}; this.databaseCache.users = new Collection(); @@ -43,7 +52,7 @@ class JaBaClient extends Client { * @returns {Promise} A Promise that resolves when the client is fully initialized. */ async init() { - this.player = new DiscordPlayer(this); + this.player = new Player(this); await this.player.extractors.register(YoutubeiExtractor, { authentication: this.config.youtubeCookie, @@ -74,13 +83,13 @@ class JaBaClient extends Client { }) ).id; - if (track.durationMS > 1) + if (track.durationMS > 1) { setTimeout(() => { const message = queue.metadata.channel.messages.cache.get(m); if (message && message.deletable) message.delete(); }, track.durationMS); - else + } else { setTimeout( () => { const message = queue.metadata.channel.messages.cache.get(m); @@ -89,6 +98,7 @@ class JaBaClient extends Client { }, 5 * 60 * 1000, ); + } }); this.player.events.on("emptyQueue", queue => queue.metadata.channel.send(this.translate("music/play:QUEUE_ENDED", null, queue.metadata.data.guild.language))); this.player.events.on("emptyChannel", queue => queue.metadata.channel.send(this.translate("music/play:STOP_EMPTY", null, queue.metadata.data.guild.language))); @@ -113,9 +123,7 @@ class JaBaClient extends Client { mongoose .connect(this.config.mongoDB) - .then(() => { - this.logger.log("Connected to the MongoDB database."); - }) + .then(this.logger.log("Connected to the MongoDB database.")) .catch(e => { this.logger.error(`Unable to connect to the MongoDB database.\nError: ${e.message}\n${e.stack}`); }); @@ -134,8 +142,8 @@ class JaBaClient extends Client { */ async loadCommands(dir) { const rest = new REST().setToken(this.config.token), - filePath = path.join(__dirname, dir), - folders = (await fs.readdir(filePath)).map(file => path.join(filePath, file)); + filePath = join(__dirname, dir), + folders = (await fs.readdir(filePath)).map(file => join(filePath, file)); const commands = []; for (const folder of folders) { @@ -144,7 +152,7 @@ class JaBaClient extends Client { for (const file of files) { if (!file.endsWith(".js")) continue; - const Command = require(path.join(folder, file)); + const Command = require(join(folder, file)); if (!(Command.prototype instanceof BaseCommand)) continue; @@ -165,8 +173,8 @@ class JaBaClient extends Client { await rest.put(route, { body: commands }); this.logger.log("Successfully registered application commands."); - } catch (err) { - this.logger.error("Error registering application commands:", err); + } catch (e) { + this.logger.error("Error registering application commands:", e); } } @@ -178,7 +186,7 @@ class JaBaClient extends Client { */ async loadCommand(dir, file) { try { - const Command = require(path.join(dir, `${file}.js`)); + const Command = require(join(dir, `${file}.js`)); if (!(Command.prototype instanceof BaseCommand)) { return this.logger.error(`Tried to load a non-command file: "${file}.js"`); @@ -190,8 +198,8 @@ class JaBaClient extends Client { if (typeof command.onLoad === "function") await command.onLoad(this); this.logger.log(`Successfully loaded "${file}" command file. (Command: ${command.command.name})`); - } catch (error) { - this.logger.error(`Error loading command "${file}":`, error); + } catch (e) { + this.logger.error(`Error loading command "${file}":`, e); } } @@ -202,7 +210,7 @@ class JaBaClient extends Client { * @returns {void} This method does not return a value. */ unloadCommand(dir, name) { - delete require.cache[require.resolve(`${dir}${path.sep}${name}.js`)]; + delete require.cache[require.resolve(`${dir}${sep}${name}.js`)]; return; } @@ -213,15 +221,15 @@ class JaBaClient extends Client { * @returns {Promise} This method does not return a value. */ async loadEvents(dir) { - const filePath = path.join(__dirname, dir); + const filePath = join(__dirname, dir); const files = await fs.readdir(filePath); for (const file of files) { - const fullPath = path.join(filePath, file); + const fullPath = join(filePath, file); const stat = await fs.lstat(fullPath); if (stat.isDirectory()) { - await this.loadEvents(path.join(dir, file)); + await this.loadEvents(join(dir, file)); continue; } @@ -244,8 +252,8 @@ class JaBaClient extends Client { event.once ? this.once(event.name, event.execute.bind(event, this)) : this.on(event.name, event.execute.bind(event, this)); this.logger.log(`Successfully loaded "${file}" event. (Event: ${event.name})`); - } catch (error) { - this.logger.error(`Error loading event "${file}":`, error); + } catch (e) { + this.logger.error(`Error loading event "${file}":`, e); } } } @@ -348,6 +356,7 @@ class JaBaClient extends Client { await memberData.save(); const guildData = await this.getGuildData(guildId); + if (guildData) { guildData.members.push(memberData._id); await guildData.save(); @@ -377,4 +386,4 @@ class JaBaClient extends Client { } } -module.exports = JaBaClient; +export default JaBaClient; diff --git a/base/Guild.js b/base/Guild.js index 634cfdd9..a2b3507b 100644 --- a/base/Guild.js +++ b/base/Guild.js @@ -1,55 +1,57 @@ -const mongoose = require("mongoose"), - Schema = mongoose.Schema, - languages = require("../languages/language-meta.json"); +import { model, Schema } from "mongoose"; +import { langs } from "../languages/language-meta.js"; -module.exports = mongoose.model("Guild", new Schema({ - id: { type: String }, +export default model( + "Guild", + new Schema({ + id: { type: String }, - membersData: { type: Object, default: {} }, - members: [{ type: Schema.Types.ObjectId, ref: "Member" }], + membersData: { type: Object, default: {} }, + members: [{ type: Schema.Types.ObjectId, ref: "Member" }], - language: { type: String, default: languages.find(l => l.default).name }, - plugins: { - type: Object, - default: { - welcome: { - enabled: false, - message: null, - channel: null, - withImage: null, + language: { type: String, default: langs.find(l => l.default).name }, + plugins: { + type: Object, + default: { + welcome: { + enabled: false, + message: null, + channel: null, + withImage: null, + }, + goodbye: { + enabled: false, + message: null, + channel: null, + withImage: null, + }, + autorole: { + enabled: false, + role: null, + }, + automod: { + enabled: false, + ignored: [], + }, + warnsSanctions: { + kick: null, + ban: null, + }, + monitoring: { + messageUpdate: null, + messageDelete: null, + }, + tickets: { + count: 0, + ticketLogs: null, + transcriptionLogs: null, + ticketsCategory: null, + }, + suggestions: null, + reports: null, + birthdays: null, + modlogs: null, }, - goodbye: { - enabled: false, - message: null, - channel: null, - withImage: null, - }, - autorole: { - enabled: false, - role: null, - }, - automod: { - enabled: false, - ignored: [], - }, - warnsSanctions: { - kick: null, - ban: null, - }, - monitoring: { - messageUpdate: null, - messageDelete: null, - }, - tickets: { - count: 0, - ticketLogs: null, - transcriptionLogs: null, - ticketsCategory: null, - }, - suggestions: null, - reports: null, - birthdays: null, - modlogs: null, }, - }, -})); + }), +); diff --git a/base/Member.js b/base/Member.js index d494f72c..59aeec04 100644 --- a/base/Member.js +++ b/base/Member.js @@ -1,33 +1,36 @@ -const mongoose = require("mongoose"); +import { model, Schema } from "mongoose"; -module.exports = mongoose.model("Member", new mongoose.Schema({ - id: { type: String }, - guildID: { type: String }, +export default model( + "Member", + new Schema({ + id: { type: String }, + guildID: { type: String }, - money: { type: Number, default: 0 }, - workStreak: { type: Number, default: 0 }, - bankSold: { type: Number, default: 0 }, - exp: { type: Number, default: 0 }, - level: { type: Number, default: 0 }, - transactions: { type: Array, default: [] }, + money: { type: Number, default: 0 }, + workStreak: { type: Number, default: 0 }, + bankSold: { type: Number, default: 0 }, + exp: { type: Number, default: 0 }, + level: { type: Number, default: 0 }, + transactions: { type: Array, default: [] }, - registeredAt: { type: Number, default: Date.now() }, + registeredAt: { type: Number, default: Date.now() }, - cooldowns: { - type: Object, - default: { - work: 0, - rob: 0, + cooldowns: { + type: Object, + default: { + work: 0, + rob: 0, + }, }, - }, - sanctions: { type: Array, default: [] }, - mute: { - type: Object, - default: { - muted: false, - case: null, - endDate: null, + sanctions: { type: Array, default: [] }, + mute: { + type: Object, + default: { + muted: false, + case: null, + endDate: null, + }, }, - }, -})); + }), +); diff --git a/base/User.js b/base/User.js index c455a4c4..e86ba80b 100644 --- a/base/User.js +++ b/base/User.js @@ -1,5 +1,5 @@ -const mongoose = require("mongoose"), - Canvas = require("@napi-rs/canvas"); +import { Schema, model } from "mongoose"; +import { createCanvas, loadImage } from "@napi-rs/canvas"; const genToken = () => { let token = ""; @@ -9,7 +9,7 @@ const genToken = () => { return token; }; -const userSchema = new mongoose.Schema({ +const userSchema = new Schema({ id: { type: String }, rep: { type: Number, default: 0 }, @@ -88,17 +88,17 @@ const userSchema = new mongoose.Schema({ }); userSchema.method("getAchievements", async function () { - const canvas = Canvas.createCanvas(1800, 250), + const canvas = createCanvas(1800, 250), ctx = canvas.getContext("2d"); const images = [ - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.work.achieved ? "_colored" : ""}1.png`), - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.firstCommand.achieved ? "_colored" : ""}2.png`), - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.married.achieved ? "_colored" : ""}3.png`), - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.slots.achieved ? "_colored" : ""}4.png`), - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.tip.achieved ? "_colored" : ""}5.png`), - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.rep.achieved ? "_colored" : ""}6.png`), - await Canvas.loadImage(`./assets/img/achievements/achievement${this.achievements.invite.achieved ? "_colored" : ""}7.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.work.achieved ? "_colored" : ""}1.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.firstCommand.achieved ? "_colored" : ""}2.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.married.achieved ? "_colored" : ""}3.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.slots.achieved ? "_colored" : ""}4.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.tip.achieved ? "_colored" : ""}5.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.rep.achieved ? "_colored" : ""}6.png`), + await loadImage(`./assets/img/achievements/achievement${this.achievements.invite.achieved ? "_colored" : ""}7.png`), ]; let dim = 0; @@ -107,7 +107,7 @@ userSchema.method("getAchievements", async function () { dim += 200; } - return (await canvas.encode("png")); + return await canvas.encode("png"); }); -module.exports = mongoose.model("User", userSchema); +export default model("User", userSchema); diff --git a/commands/Administration/config.js b/commands/Administration/config.js index c0aa1f57..d4f5f0df 100644 --- a/commands/Administration/config.js +++ b/commands/Administration/config.js @@ -103,7 +103,8 @@ class Config extends BaseCommand { ? interaction.translate("administration/config:WELCOME_CONTENT", { channel: `<#${guildData.plugins.welcome.channel}>`, withImage: guildData.plugins.welcome.withImage ? interaction.translate("common:YES") : interaction.translate("common:NO"), - }) : interaction.translate("common:DISABLED"), + }) + : interaction.translate("common:DISABLED"), inline: true, }, { @@ -112,7 +113,8 @@ class Config extends BaseCommand { ? interaction.translate("administration/config:GOODBYE_CONTENT", { channel: `<#${guildData.plugins.goodbye.channel}>`, withImage: guildData.plugins.goodbye.withImage ? interaction.translate("common:YES") : interaction.translate("common:NO"), - }) : interaction.translate("common:DISABLED"), + }) + : interaction.translate("common:DISABLED"), inline: true, }, { @@ -125,19 +127,22 @@ class Config extends BaseCommand { (guildData.plugins.warnsSanctions.kick ? interaction.translate("administration/config:KICK_CONTENT", { count: guildData.plugins.warnsSanctions.kick, - }) : interaction.translate("administration/config:KICK_NOT_DEFINED")) + + }) + : interaction.translate("administration/config:KICK_NOT_DEFINED")) + "\n" + (guildData.plugins.warnsSanctions.ban ? interaction.translate("administration/config:BAN_CONTENT", { count: guildData.plugins.warnsSanctions.ban, - }) : interaction.translate("administration/config:BAN_NOT_DEFINED")), + }) + : interaction.translate("administration/config:BAN_NOT_DEFINED")), }, { name: interaction.translate("administration/config:AUTOMOD_TITLE"), value: guildData.plugins.automod.enabled ? interaction.translate("administration/config:AUTOMOD_CONTENT", { channels: guildData.plugins.automod.ignored.map(ch => ` ${ch}`), - }) : interaction.translate("common:DISABLED"), + }) + : interaction.translate("common:DISABLED"), }, { name: interaction.translate("administration/config:MONITORING_CHANNELS"), @@ -156,10 +161,6 @@ class Config extends BaseCommand { `${interaction.translate("administration/config:TICKETLOGS")}: ${guildData.plugins?.tickets?.ticketLogs ? `<#${guildData.plugins?.tickets?.ticketLogs}>` : `*${interaction.translate("common:NOT_DEFINED")}*`}\n` + `${interaction.translate("administration/config:TRANSCRIPTIONLOGS")}: ${guildData.plugins?.tickets?.transcriptionLogs ? `<#${guildData.plugins?.tickets?.transcriptionLogs}>` : `*${interaction.translate("common:NOT_DEFINED")}*`}\n`, }, - { - name: interaction.translate("administration/config:DASHBOARD_TITLE"), - value: `[${interaction.translate("administration/config:DASHBOARD_CONTENT")}](${client.config.dashboard.domain})`, - }, ], }); @@ -215,13 +216,14 @@ async function changeSetting(interaction, setting, state, channel) { content: `${interaction.translate(`administration/config:${settingSplitted.length === 2 ? settingSplitted[1].toUpperCase() : setting.toUpperCase()}`)}: **${interaction.translate("common:ENABLED")}** (${channel.toString()})`, ephemeral: true, }); - } else + } else { return interaction.reply({ content: `${interaction.translate(`administration/config:${settingSplitted.length === 2 ? settingSplitted[1].toUpperCase() : setting.toUpperCase()}`)}: ${ data.plugins[setting] ? `**${interaction.translate("common:ENABLED")}** (<#${data.plugins[setting]}>)` : `**${interaction.translate("common:DISABLED")}**` }`, ephemeral: true, }); + } } } else { if (!state) { @@ -245,13 +247,14 @@ async function changeSetting(interaction, setting, state, channel) { content: `${interaction.translate(`administration/config:${setting.toUpperCase()}`)}: **${interaction.translate("common:ENABLED")}** (${channel.toString()})`, ephemeral: true, }); - } else + } else { return interaction.reply({ content: `${interaction.translate(`administration/config:${setting.toUpperCase()}`)}: ${ data.plugins[setting] ? `**${interaction.translate("common:ENABLED")}** (<#${data.plugins[setting]}>)` : `**${interaction.translate("common:DISABLED")}**` }`, ephemeral: true, }); + } } } } diff --git a/commands/General/stats.js b/commands/General/stats.js index 7cc62b61..2813fcb2 100644 --- a/commands/General/stats.js +++ b/commands/General/stats.js @@ -91,7 +91,6 @@ class Stats extends BaseCommand { { name: client.customEmojis.link + " " + interaction.translate("general/stats:LINKS_TITLE"), value: interaction.translate("misc:STATS_FOOTER", { - dashboardLink: client.config.dashboard.domain, supportLink: "https://discord.gg/Ptkj2n9nzZ", inviteLink: client.generateInvite({ scopes: ["bot", "applications.commands"], permissions: [PermissionsBitField.Flags.Administrator] }), owner: client.config.owner.id, diff --git a/config.sample.js b/config.sample.js index 6257bd15..4a008270 100644 --- a/config.sample.js +++ b/config.sample.js @@ -1,4 +1,4 @@ -export const config = { +export default { /* The token of your Discord Bot */ token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", /* UserID of your Discord Bot */ @@ -22,14 +22,14 @@ export const config = { invite: "https://discord.gg/discord", // Invite link to the support server }, /* Dashboard configuration */ - dashboard: { + /* dashboard: { enabled: false, // Whether the dashboard is enabled or not maintanceKey: "letmein", // Maintance key port: 80, // Dashboard port domain: "http://localhost", // The base URL of the dashboard without / at the end secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", // Your Bot's Client Secret logs: "123456789098765432", // The channel ID for logs - }, + }, */ /* Embeds defaults */ embed: { color: "#00FF00", // Color diff --git a/dashboard/dashboard-core b/dashboard/dashboard-core deleted file mode 160000 index 42cb4400..00000000 --- a/dashboard/dashboard-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 42cb44000f844f17b0d9e12e15a45ab60f3dcdb7 diff --git a/dashboard/dashboard.js b/dashboard/dashboard.js deleted file mode 100644 index 8279623d..00000000 --- a/dashboard/dashboard.js +++ /dev/null @@ -1,221 +0,0 @@ -const SoftUI = require("./dashboard-core/theme/dbd-soft-ui"), - DBD = require("./dashboard-core/index"), - settings = require("./settings"); - -const { PermissionsBitField } = require("discord.js"); - -const locales = { - "en-US": require("../languages/en-US/dashboard.json"), - "ru-RU": require("../languages/ru-RU/dashboard.json"), - "uk-UA": require("../languages/uk-UA/dashboard.json"), -}; - -/** - * - * @param {import("../base/Client")} client - */ -module.exports.load = async client => { - const commands = client.commands.map(v => { - return { - commandName: v.command.name, - commandDescription: client.translate(`${v.category.toLowerCase()}/${v.command.name}:DESCRIPTION`), - commandUsage: client.translate(`${v.category.toLowerCase()}/${v.command.name}:USAGE`), - commandAlias: "", - _category: v.category, - }; - }); - let categories = []; - - commands.forEach(c => { - if (!categories.includes(c._category)) categories.push(c._category); - }); - - categories = categories.map(c => { - return { - category: c, - categoryId: c.toLowerCase(), - subTitle: "", - hideAlias: true, - hideDescription: false, - hideSidebarItem: c === "Owner" || c === "IAT" ? true : false, - list: commands.filter(v => v._category === c), - }; - }); - - const Dashboard = new DBD.Dashboard({ - port: client.config.dashboard.port, - client: { - id: client.user.id, - secret: client.config.dashboard.secret, - }, - cookiesSecret: client.config.dashboard.secret, - domain: client.config.dashboard.domain, - redirectUri: `${client.config.dashboard.domain}/discord/callback`, - bot: client, - ownerIDs: [client.config.owner.id], - requiredPermissions: PermissionsBitField.Flags.ViewChannel, - invite: { - clientId: client.user.id, - scopes: ["bot", "applications.commands"], - permissions: "8", - redirectUri: `${client.config.dashboard.domain}`, - }, - supportServer: { - slash: "/support", - inviteUrl: client.config.support.invite, - }, - rateLimits: { - manage: { - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes) - message: "You are ratelimited!", // Message returned if user should be rate limited, could be also JSON/HTML - store: null, // - if null, new MemoryStore() - // supported stores: https://www.npmjs.com/package/express-rate-limit#store - }, - guildPage: { - windowMs: 15 * 60 * 1000, - max: 100, - message: "You are ratelimited!", - store: null, - }, - settingsUpdatePostAPI: { - windowMs: 15 * 60 * 1000, - max: 100, - message: "You are ratelimited!", - store: null, - }, - }, - useTheme404: true, - useThemeMaintenance: true, - useUnderMaintenance: false, - underMaintenanceAccessKey: client.config.dashboard.maintanceKey, - underMaintenanceAccessPage: "/get-access", - underMaintenance: { - title: "Under Maintenance", - contentTitle: "This page is under maintenance", - texts: [ - "
", - "We still want to change for the better for you.", - "Therefore, we are introducing technical updates so that we can allow you to enjoy the quality of our services.", - "
", - `Come back to us later or join our Discord Support Server`, - ], - }, - theme: SoftUI({ - customThemeOptions: { - // eslint-disable-next-line no-unused-vars - index: async ({ req, res, config }) => { - const user = req.session?.user; - const username = (user?.discriminator === "0" ? user?.username : user?.tag) || "Guest"; - - let users = 0; - client.guilds.cache.forEach(g => { - users += g.memberCount; - }); - - const cards = [ - { - title: "Current User", - icon: "single-02", - getValue: username, - }, - { - title: "Playing music in this much servers", - icon: "settings-gear-65", - getValue: client.player.nodes.cache.size, - }, - { - title: "Users Count", - icon: "favourite-28", - getValue: users, - }, - { - title: "Servers Count", - icon: "notification-70", - getValue: `${client.guilds.cache.size - 1} out of 2000`, - progressBar: { - enabled: true, - getProgress: Math.round(((client.guilds.cache.size - 1) / 2000) * 100), - }, - }, - ]; - - return { - values: [], - graph: {}, - cards, - }; - }, - }, - websiteName: `${client.user.username} Dashboard`, - colorScheme: "blue", - supporteMail: "", - icons: { - favicon: client.user.avatarURL(), - noGuildIcon: "https://pnggrid.com/wp-content/uploads/2021/05/Discord-Logo-Circle-1024x1024.png", - sidebar: { - darkUrl: client.user.avatarURL(), - lightUrl: client.user.avatarURL(), - hideName: false, - borderRadius: "1rem", - alignCenter: true, - }, - }, - index: { - card: { - category: "JaBa Bot", - title: "Simple bot made by Jonny_Bro", - description: "JaBa's dashboard", - image: "", - link: { - enabled: false, - url: "https://github.com/JonnyBro", - }, - }, - graph: { - enabled: false, - lineGraph: true, - title: "Memory Usage", - tag: "Memory (MB)", - max: 100, - }, - }, - notify: { - errors: { - settingsSave: "Failed to save setttings", - }, - success: { - settingsSave: "Successfully saved setttings.", - login: "Successfully logged in.", - logout: "Successfully logged out.", - }, - }, - preloader: { - image: "", - spinner: true, - text: "Page is loading", - }, - commands: categories, - locales: { - enUS: locales["en-US"], - ruRU: locales["ru-RU"], - ukUA: locales["uk-UA"], - }, - }), - customPages: [ - DBD.customPagesTypes.redirectToUrl("/github", () => { - return "https://github.com/JonnyBro/JaBa"; - }), - DBD.customPagesTypes.redirectToUrl("/updates", () => { - return "https://github.com/JonnyBro/JaBa/blob/main/dashboard/docs/updates.md"; - }), - ], - settings: settings(client), - }); - - await Dashboard.init().then(() => { - client.logger.ready(`Dashboard launched on port ${client.config.dashboard.port}`); - }).catch(err => { - client.logger.error(`Dashboard failed to initialize:\n${err}`); - }); -}; diff --git a/dashboard/settings.js b/dashboard/settings.js deleted file mode 100644 index 7110aba0..00000000 --- a/dashboard/settings.js +++ /dev/null @@ -1,459 +0,0 @@ -const SoftUI = require("./dashboard-core/theme/dbd-soft-ui"), - DBD = require("./dashboard-core/index"); - -const { PermissionsBitField, ChannelType } = require("discord.js"); - -module.exports = client => [ - { - categoryId: "main", - categoryName: "Main settings", - categoryDescription: "Setup your bot here!", - categoryPermissions: PermissionsBitField.Flags.ManageGuild, - categoryOptionsList: [ - { - optionId: "lang", - optionName: "Language", - optionDescription: "Change bot's language on the server", - optionType: DBD.formTypes.select({ - English: "en-US", - Russian: "ru-RU", - Ukrainian: "uk-UA", - }), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.language; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.language = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "welcome", - optionName: "Welcome Message", - optionDescription: "Setup welcome message on the server", - optionType: SoftUI.formTypes.multiRow([ - { - optionId: "welcome_enable", - optionName: "Enabled", - optionDescription: "Toggle welcome messages sending", - optionType: DBD.formTypes.switch(), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.welcome.enabled; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.welcome.enabled = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "welcome_image", - optionName: "Add Image", - optionDescription: "Toggle sending an image with welcome message", - optionType: DBD.formTypes.switch(), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.welcome.withImage; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.welcome.withImage = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "welcome_message", - optionName: "Message", - optionDescription: "Change welcome message (You can use {user}, {server} and {membercount} wildcards)", - optionType: DBD.formTypes.input("Welcome, {user}!", 2, 100, false, false), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.welcome.message; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.welcome.message = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - { - optionId: "welcome_channel", - optionName: "Channel", - optionDescription: "Select a channel for welcome messages", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.welcome.channel; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.welcome.channel = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - ]), - }, - { - optionId: "goodbye", - optionName: "Goodbye Message", - optionDescription: "Setup goodbye message on the server", - optionType: SoftUI.formTypes.multiRow([ - { - optionId: "goodbye_enable", - optionName: "Enabled", - optionDescription: "Toggle goodbye messages sending", - optionType: DBD.formTypes.switch(), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.goodbye.enabled; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.goodbye.enabled = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "goodbye_image", - optionName: "Add Image", - optionDescription: "Toggle sending an image with goodbye message", - optionType: DBD.formTypes.switch(), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.goodbye.withImage; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.goodbye.withImage = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "goodbye_message", - optionName: "Message", - optionDescription: "Change goodbye message (You can use {user}, {server} and {membercount} wildcards)", - optionType: DBD.formTypes.input("goodbye, {user}!", 2, 100, false, false), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.goodbye.message; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.goodbye.message = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - { - optionId: "goodbye_channel", - optionName: "Channel", - optionDescription: "Select a channel for goodbye messages", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.goodbye.channel; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.goodbye.channel = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - ]), - }, - { - optionId: "autorole", - optionName: "Auto Role", - optionDescription: "Setup auto role on the server", - optionType: SoftUI.formTypes.multiRow([ - { - optionId: "autorole_enable", - optionName: "Enabled", - optionDescription: "Toggle auto role granting for new members", - optionType: DBD.formTypes.switch(), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.autorole.enabled; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.autorole.enabled = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "autorole_role", - optionName: "Role", - optionDescription: "Select a role for auto role. Select \"-\" to disable", - optionType: DBD.formTypes.rolesSelect(false, false, true), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.autorole.role; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.autorole.role = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - ]), - }, - { - optionId: "automod", - optionName: "Auto Mod", - optionDescription: "Setup auto mod on the server", - optionType: SoftUI.formTypes.multiRow([ - { - optionId: "automod_enable", - optionName: "Enabled", - optionDescription: "Toggle auto mod. It will remove invite links from non-moderators", - optionType: DBD.formTypes.switch(), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.automod.enabled; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.automod.enabled = newData; - - await guildData.save(); - - return; - }, - }, - { - optionId: "automod_ignore", - optionName: "Ignore Channels", - optionDescription: "Select a channels for auto mod to ignore", - optionType: DBD.formTypes.channelsMultiSelect(false, false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.automod.ignored; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.automod.ignored = newData; - - await guildData.save(); - - return; - }, - }, - ]), - }, - { - optionId: "monitoring", - optionName: "Monitoring Channels", - optionDescription: "Setup monitoring channels on the server", - optionType: SoftUI.formTypes.multiRow([ - { - optionId: "monitoring_messageupdate", - optionName: "Message Update Channel", - optionDescription: "Select a channel for messages update logs to go to. Select \"-\" to disable", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins?.monitoring?.messageUpdate; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - if (guildData.plugins.monitoring === undefined) guildData.plugins.monitoring = {}; - - guildData.plugins.monitoring.messageUpdate = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - { - optionId: "monitoring_messagedelete", - optionName: "Message Deletion Channel", - optionDescription: "Select a channel for messages deletion logs to go to. Select \"-\" to disable", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins?.monitoring?.messageDelete; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - if (guildData.plugins.monitoring === undefined) guildData.plugins.monitoring = {}; - - guildData.plugins.monitoring.messageDelete = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - ]), - }, - { - optionId: "channels", - optionName: "Special Channels", - optionDescription: "Setup special channels on the server. Select \"-\" to disable", - optionType: SoftUI.formTypes.multiRow([ - { - optionId: "channels_suggestions", - optionName: "Suggestions Channel", - optionDescription: "Select a channel for suggestions to go to", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.suggestions; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.suggestions = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - { - optionId: "channels_reports", - optionName: "Reports Channel", - optionDescription: "Select a channel for reports to go to. Select \"-\" to disable", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.reports; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.reports = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - { - optionId: "channels_birthdays", - optionName: "Birthdays Channel", - optionDescription: "Select a channel for birthdays message to go to. Select \"-\" to disable", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.birthdays; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.birthdays = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - { - optionId: "channels_modlogs", - optionName: "Moderation Logs Channel", - optionDescription: "Select a channel for moderation logs to go to (warns). Select \"-\" to disable", - optionType: DBD.formTypes.channelsSelect(false, [ChannelType.GuildText]), - getActualSet: async ({ guild }) => { - const guildData = await client.getGuildData(guild.id); - - return guildData.plugins.modlogs; - }, - setNew: async ({ guild, newData }) => { - const guildData = await client.getGuildData(guild.id); - - guildData.plugins.modlogs = newData !== "" ? newData : null; - - await guildData.save(); - - return; - }, - }, - ]), - }, - ], - }, - { - categoryId: "test", - categoryName: "test settings", - categoryDescription: "ooga booga", - categoryPermissions: PermissionsBitField.Flags.ViewChannel, - categoryOptionsList: [ - { - optionType: DBD.formTypes.embedBuilder({ - username: "JaBa", - avatarURL: "https://cdn.discordapp.com/avatars/708637495054565426/af98d49ebc9bf28b40b45ed5a0a623b4.png?size=4096", - }), - }, - ], - }, -]; diff --git a/eslint.config.js b/eslint.config.js index d36eda08..eabf7207 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -18,7 +18,7 @@ export default [ rules: { "arrow-body-style": ["error", "as-needed"], camelcase: "error", - curly: "error", + curly: ["error", "multi-line"], eqeqeq: ["error", "always"], "no-console": "off", "no-var": "error", diff --git a/events/CommandHandler.js b/events/CommandHandler.js index 0337da0c..4923eec7 100644 --- a/events/CommandHandler.js +++ b/events/CommandHandler.js @@ -1,5 +1,5 @@ -const { InteractionType } = require("discord.js"); -const BaseEvent = require("../base/BaseEvent"); +import { InteractionType } from "discord.js"; +import BaseEvent from "../base/BaseEvent"; class CommandHandler extends BaseEvent { constructor() { @@ -33,12 +33,10 @@ class CommandHandler extends BaseEvent { if (interaction.type !== InteractionType.ApplicationCommand || !interaction.isCommand()) return; // IAT Guild Command Check - if (command?.dirname.includes("IAT") && interaction.guildId !== "1039187019957555252") - return interaction.reply({ content: "IAT only", ephemeral: true }); + if (command?.dirname.includes("IAT") && interaction.guildId !== "1039187019957555252") return interaction.reply({ content: "IAT only", ephemeral: true }); // Owner-only command check - if (command.ownerOnly && interaction.user.id !== client.config.owner.id) - return interaction.error("misc:OWNER_ONLY", null, { ephemeral: true }); + if (command.ownerOnly && interaction.user.id !== client.config.owner.id) return interaction.error("misc:OWNER_ONLY", null, { ephemeral: true }); // First command achievement check const { firstCommand } = interaction.data.user.achievements; @@ -68,4 +66,4 @@ class CommandHandler extends BaseEvent { } } -module.exports = CommandHandler; +export default CommandHandler; diff --git a/events/Guild/guildBanAdd.js b/events/Guild/guildBanAdd.js index be02d479..dd92d904 100644 --- a/events/Guild/guildBanAdd.js +++ b/events/Guild/guildBanAdd.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class guildBanAdd extends BaseEvent { constructor() { @@ -26,8 +26,10 @@ class guildBanAdd extends BaseEvent { await ban.user.send({ embeds: [embed], }); - } catch (e) { /**/ } + } catch { + /**/ + } } } -module.exports = guildBanAdd; +export default guildBanAdd; diff --git a/events/Guild/guildCreate.js b/events/Guild/guildCreate.js index ffa6a96f..0856149d 100644 --- a/events/Guild/guildCreate.js +++ b/events/Guild/guildCreate.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class GuildCreate extends BaseEvent { constructor() { @@ -62,12 +62,13 @@ class GuildCreate extends BaseEvent { const logChannel = client.channels.cache.get(client.config.support.logs); - if (logChannel) + if (logChannel) { await logChannel.send({ embeds: [embed], }); + } } } } -module.exports = GuildCreate; +export default GuildCreate; diff --git a/events/Guild/guildDelete.js b/events/Guild/guildDelete.js index 20b795cc..b87299c0 100644 --- a/events/Guild/guildDelete.js +++ b/events/Guild/guildDelete.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class GuildDelete extends BaseEvent { constructor() { @@ -25,13 +25,13 @@ class GuildDelete extends BaseEvent { const logChannel = client.channels.cache.get(client.config.support.logs); - if (logChannel) + if (logChannel) { await logChannel.send({ embeds: [embed], }); - else client.logger.warn(`Log channel not found for guild deletion: ${guild.name}`); + } else client.logger.warn(`Log channel not found for guild deletion: ${guild.name}`); } } } -module.exports = GuildDelete; +export default GuildDelete; diff --git a/events/Guild/guildMemberAdd.js b/events/Guild/guildMemberAdd.js index 0112ae64..8bad2c4c 100644 --- a/events/Guild/guildMemberAdd.js +++ b/events/Guild/guildMemberAdd.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class GuildMemberAdd extends BaseEvent { constructor() { @@ -46,4 +46,4 @@ class GuildMemberAdd extends BaseEvent { } } -module.exports = GuildMemberAdd; +export default GuildMemberAdd; diff --git a/events/Guild/guildMemberRemove.js b/events/Guild/guildMemberRemove.js index c3e1499a..9726d708 100644 --- a/events/Guild/guildMemberRemove.js +++ b/events/Guild/guildMemberRemove.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class GuildMemberRemove extends BaseEvent { constructor() { @@ -37,4 +37,4 @@ class GuildMemberRemove extends BaseEvent { } } -module.exports = GuildMemberRemove; +export default GuildMemberRemove; diff --git a/events/Guild/guildMemberUpdate.js b/events/Guild/guildMemberUpdate.js index 2c48d1a9..fd8d1e3b 100644 --- a/events/Guild/guildMemberUpdate.js +++ b/events/Guild/guildMemberUpdate.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class GuildMemberUpdate extends BaseEvent { constructor() { @@ -44,4 +44,4 @@ class GuildMemberUpdate extends BaseEvent { } } -module.exports = GuildMemberUpdate; +export default GuildMemberUpdate; diff --git a/events/MessageHandler.js b/events/MessageHandler.js index fd1abac8..6ef06e6a 100644 --- a/events/MessageHandler.js +++ b/events/MessageHandler.js @@ -1,5 +1,5 @@ -const { PermissionsBitField, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js"); -const BaseEvent = require("../base/BaseEvent"); +import { PermissionsBitField, ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; +import BaseEvent from "../base/BaseEvent"; const xpCooldown = {}; @@ -23,7 +23,7 @@ class MessageCreate extends BaseEvent { if (message.guild) { if (!message.member) await message.guild.members.fetch(message.author.id); - + data.guild = await client.getGuildData(message.guildId); data.member = await client.getMemberData(message.author.id, message.guildId); } @@ -69,8 +69,7 @@ class MessageCreate extends BaseEvent { if (msg.content) embed.addFields([{ name: message.translate("misc:QUOTE_CONTENT"), value: msg.content }]); if (msg.attachments.size > 0) { - if (msg.attachments.find(a => a.contentType.includes("image/"))) - embed.setImage(msg.attachments.find(a => a.contentType.includes("image/")).url); + if (msg.attachments.find(a => a.contentType.includes("image/"))) embed.setImage(msg.attachments.find(a => a.contentType.includes("image/")).url); embed.addFields([ { @@ -160,4 +159,4 @@ class MessageCreate extends BaseEvent { } } -module.exports = MessageCreate; +export default MessageCreate; diff --git a/events/Monitoring/messageDelete.js b/events/Monitoring/messageDelete.js index 5b760cd1..643bf78d 100644 --- a/events/Monitoring/messageDelete.js +++ b/events/Monitoring/messageDelete.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class messageDelete extends BaseEvent { constructor() { @@ -40,4 +40,4 @@ class messageDelete extends BaseEvent { } } -module.exports = messageDelete; +export default messageDelete; diff --git a/events/Monitoring/messageUpdate.js b/events/Monitoring/messageUpdate.js index 72bc91df..38fa9521 100644 --- a/events/Monitoring/messageUpdate.js +++ b/events/Monitoring/messageUpdate.js @@ -1,4 +1,4 @@ -const BaseEvent = require("../../base/BaseEvent"); +import BaseEvent from "../../base/BaseEvent"; class messageUpdate extends BaseEvent { constructor() { @@ -42,4 +42,4 @@ class messageUpdate extends BaseEvent { } } -module.exports = messageUpdate; +export default messageUpdate; diff --git a/events/Ready.js b/events/Ready.js index 41fd0645..af7fe3cb 100644 --- a/events/Ready.js +++ b/events/Ready.js @@ -1,5 +1,5 @@ -const { ActivityType } = require("discord.js"); -const BaseEvent = require("../base/BaseEvent"); +import { ActivityType } from "discord.js"; +import BaseEvent from "../base/BaseEvent"; class Ready extends BaseEvent { constructor() { @@ -28,8 +28,6 @@ class Ready extends BaseEvent { const checkReminds = require("../helpers/checkReminds"); checkReminds.init(client); - if (client.config.dashboard.enabled) await client.dashboard.load(client); - client.logger.ready(`Loaded a total of ${commands.length} command(s).`); client.logger.ready(`${client.user.getUsername()}, ready to serve ${users} members in ${servers} servers.`); console.timeEnd("botReady"); @@ -63,4 +61,4 @@ class Ready extends BaseEvent { } } -module.exports = Ready; +export default Ready; diff --git a/events/TicketsButton.js b/events/TicketsButton.js index dbbf7340..9aa95547 100644 --- a/events/TicketsButton.js +++ b/events/TicketsButton.js @@ -1,5 +1,5 @@ -const { ButtonBuilder, ActionRowBuilder, ButtonStyle, ChannelType, PermissionsBitField } = require("discord.js"); -const BaseEvent = require("../base/BaseEvent"); +import { ButtonBuilder, ActionRowBuilder, ButtonStyle, ChannelType, PermissionsBitField } from "discord.js"; +import BaseEvent from "../base/BaseEvent"; class CommandHandler extends BaseEvent { constructor() { @@ -60,9 +60,13 @@ class CommandHandler extends BaseEvent { }); await logChannel.send({ embeds: [logEmbed] }); - await interaction.success("tickets/createticketembed:TICKET_CREATED", { - channel: channel.toString(), - }, { ephemeral: true }); + await interaction.success( + "tickets/createticketembed:TICKET_CREATED", + { + channel: channel.toString(), + }, + { ephemeral: true }, + ); await channel.send(`<@${interaction.user.id}>`); @@ -75,14 +79,8 @@ class CommandHandler extends BaseEvent { description: interaction.translate("tickets/createticketembed:TICKET_CREATED_DESC"), }); - const closeButton = new ButtonBuilder() - .setCustomId("close_ticket") - .setLabel(interaction.translate("tickets/closeticket:CLOSE_TICKET")) - .setStyle(ButtonStyle.Danger); - const transcriptButton = new ButtonBuilder() - .setCustomId("transcript_ticket") - .setLabel(interaction.translate("tickets/closeticket:TRANSCRIPT_TICKET")) - .setStyle(ButtonStyle.Secondary); + const closeButton = new ButtonBuilder().setCustomId("close_ticket").setLabel(interaction.translate("tickets/closeticket:CLOSE_TICKET")).setStyle(ButtonStyle.Danger); + const transcriptButton = new ButtonBuilder().setCustomId("transcript_ticket").setLabel(interaction.translate("tickets/closeticket:TRANSCRIPT_TICKET")).setStyle(ButtonStyle.Secondary); const row = new ActionRowBuilder().addComponents(closeButton, transcriptButton); guildData.plugins.tickets.count++; @@ -135,14 +133,18 @@ class CommandHandler extends BaseEvent { }); transcript += "---- TICKET CLOSED ----\n"; - if (transcriptionLogs !== null) interaction.guild.channels.cache.get(transcriptionLogs).send({ content: interaction.translate("tickets/closeticket:TRANSCRIPT", { channel: `<#${interaction.channelId}>` }), files: [{ attachment: Buffer.from(transcript), name: `${interaction.channel.name}.txt` }] }); + if (transcriptionLogs !== null) { + interaction.guild.channels.cache + .get(transcriptionLogs) + .send({ content: interaction.translate("tickets/closeticket:TRANSCRIPT", { channel: `<#${interaction.channelId}>` }), files: [{ attachment: Buffer.from(transcript), name: `${interaction.channel.name}.txt` }] }); + } try { await interaction.user.send({ content: interaction.translate("tickets/closeticket:TRANSCRIPT", { channel: interaction.channel.name }), files: [{ attachment: Buffer.from(transcript), name: `${interaction.channel.name}.txt` }], }); - } catch (e) { + } catch { interaction.followUp({ content: interaction.translate("misc:CANT_DM"), ephemeral: true }); } } @@ -181,7 +183,7 @@ class CommandHandler extends BaseEvent { content: interaction.translate("tickets/closeticket:TRANSCRIPT", { channel: `<#${interaction.channelId}>` }), files: [{ attachment: Buffer.from(transcript), name: `${interaction.channel.name}.txt` }], }); - } catch (error) { + } catch { interaction.followUp({ content: interaction.translate("misc:CANT_DM"), ephemeral: true }); } } else return; @@ -189,4 +191,4 @@ class CommandHandler extends BaseEvent { } } -module.exports = CommandHandler; +export default CommandHandler; diff --git a/helpers/birthdays.js b/helpers/birthdays.js index 2a8a57d3..7334e6fb 100644 --- a/helpers/birthdays.js +++ b/helpers/birthdays.js @@ -1,4 +1,4 @@ -const { CronJob } = require("cron"); +import { CronJob } from "cron"; /** * @@ -61,5 +61,9 @@ async function checkBirthdays(client) { } } -module.exports.init = async client => new CronJob("0 5 * * *", checkBirthdays(client), null, true, "Europe/Moscow"); -module.exports.run = async client => await checkBirthdays(client); +export async function init(client) { + new CronJob("0 5 * * *", checkBirthdays(client), null, true, "Europe/Moscow"); +} +export async function run(client) { + await checkBirthdays(client); +} diff --git a/helpers/checkReminds.js b/helpers/checkReminds.js index 7f0c123b..7c271c9c 100644 --- a/helpers/checkReminds.js +++ b/helpers/checkReminds.js @@ -56,5 +56,11 @@ async function checkReminds(client) { }); } -module.exports.init = async client => setInterval(async () => await checkReminds(client), 1000); -module.exports.run = async client => await checkReminds(client); +export async function init(client) { + setInterval(async () => { + await checkReminds(client); + }, 1000); +} +export async function run(client) { + await checkReminds(client); +} diff --git a/helpers/cleanup.js b/helpers/cleanup.js index 159bd4e1..59cce4e0 100644 --- a/helpers/cleanup.js +++ b/helpers/cleanup.js @@ -1,5 +1,4 @@ // Thanks Stackoverflow <3 - function setDaysTimeout(callback, days) { // 86400 seconds in a day const msInDay = 86400 * 1000; @@ -19,7 +18,7 @@ function setDaysTimeout(callback, days) { * * @param {import("../base/Client")} client */ -module.exports.init = async function (client) { +export async function init(client) { setDaysTimeout(async () => { const timestamp = Date.now() + 29 * 24 * 60 * 60 * 1000; // 29 days const members = client.membersData.find({ transactions: { $gt: [] } }); @@ -66,4 +65,4 @@ module.exports.init = async function (client) { } }); }, 30); -}; +} diff --git a/helpers/extenders.js b/helpers/extenders.js index 54856c47..33cc2c01 100644 --- a/helpers/extenders.js +++ b/helpers/extenders.js @@ -1,4 +1,4 @@ -const { Message, BaseInteraction, User, GuildMember } = require("discord.js"); +import { Message, BaseInteraction, User, GuildMember } from "discord.js"; /** * diff --git a/helpers/functions.js b/helpers/functions.js index 923885cc..9cd8623b 100644 --- a/helpers/functions.js +++ b/helpers/functions.js @@ -1,147 +1,137 @@ -const moment = require("moment"); +import moment from "moment"; -module.exports = { - /** - * 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} callback - The async callback function to execute for each item in the collection. - * @returns {Promise} A promise that resolves when all items in the collection have been processed. - */ - async asyncForEach(collection, callback) { - const allPromises = collection.map(async key => { - await callback(key); - }); +/** + * 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} callback - The async callback function to execute for each item in the collection. + * @returns {Promise} A promise that resolves when all items in the collection have been processed. + */ +export async function asyncForEach(collection, callback) { + const allPromises = collection.map(async key => { + await callback(key); + }); - return await Promise.all(allPromises); - }, + return await Promise.all(allPromises); +} - /** - * 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) { - const x = a[key]; - const y = b[key]; - return x < y ? 1 : x > y ? -1 : 0; - }); - }, +/** + * 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. + */ +export function sortByKey(array, key) { + return array.sort(function (a, b) { + const x = a[key]; + const y = b[key]; + return x < y ? 1 : x > y ? -1 : 0; + }); +} - /** - * 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 = []; +/** + * Shuffles the elements of the provided array in-place. + * + * @param {any[]} pArray - The array to shuffle. + * @returns {any[]} The shuffled array. + */ +export function shuffle(pArray) { + const array = []; - pArray.forEach(element => array.push(element)); + pArray.forEach(element => array.push(element)); - let currentIndex = array.length, - temporaryValue, - randomIndex; + let currentIndex = array.length, + temporaryValue, + randomIndex; - while (currentIndex !== 0) { - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex -= 1; + while (currentIndex !== 0) { + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } - temporaryValue = array[currentIndex]; - array[currentIndex] = array[randomIndex]; - array[randomIndex] = temporaryValue; - } + return array; +} - return array; - }, +/** + * Generates a random integer between the specified minimum and maximum values (inclusive). + * + * @param {number} [min=0] - The minimum value (inclusive). + * @param {number} [max=100] - The maximum value (inclusive). + * @returns {number} A random integer between min and max. + */ +export function randomNum(min = 0, max = 100) { + min = Math.floor(min); + max = Math.floor(max); - /** - * Generates a random integer between the specified minimum and maximum values (inclusive). - * - * @param {number} [min=0] - The minimum value (inclusive). - * @param {number} [max=100] - The maximum value (inclusive). - * @returns {number} A random integer between min and max. - */ - randomNum(min = 0, max = 100) { - min = Math.floor(min); - max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1) + min); +} +/** + * 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. + */ +export function printDate(client, date, format = null, locale = client.defaultLanguage.name) { + const languageData = client.languages.find(language => language.name === locale); + if (format === "" || format === null) format = languageData.defaultMomentFormat; + return moment(new Date(date)).locale(languageData.moment).format(format); +} +/** + * 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. + */ +export function convertTime(client, time, type = false, prefix = true, locale = client.defaultLanguage.name) { + const languageData = client.languages.find(language => language.name === locale); + const m = moment(time).locale(languageData.moment); + return type ? m.toNow(!prefix) : m.fromNow(!prefix); +} - return Math.floor(Math.random() * (max - min + 1) + min); - }, +/** + * 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. + */ +export function getNoun(number, one, two, five) { + let n = Math.abs(number); + n %= 100; + if (n >= 5 && n <= 20) return five; + n %= 10; + if (n === 1) return one; + if (n >= 2 && n <= 4) return two; + return five; +} - /** - * 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); - if (format === "" || format === null) format = languageData.defaultMomentFormat; - - return moment(new Date(date)).locale(languageData.moment).format(format); - }, - - /** - * 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); - const m = moment(time).locale(languageData.moment); - - return type ? m.toNow(!prefix) : m.fromNow(!prefix); - }, - - /** - * 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); - n %= 100; - if (n >= 5 && n <= 20) return five; - n %= 10; - - if (n === 1) return one; - if (n >= 2 && n <= 4) return two; - - return five; - }, - - /** - * Function to apply text on a canvas with dynamic font size based on the width constraint. - * - * @param {import("@napi-rs/canvas").Canvas} canvas - The canvas object where the text will be applied. - * @param {string} text - The string of text that needs to be applied on the canvas. - * @param {number} defaultFontSize - The initial font size for the text. It is expected to decrease with each iteration. - * @param {number} width - The maximum width that the text can occupy before it has to shrink down. - * @param {string} font - The name of the font used for drawing the text on the canvas. - * - * @return {string} - The final calculated font size in a format 'px '. - */ - applyText(canvas, text, defaultFontSize, width, font) { - const ctx = canvas.getContext("2d"); - do ctx.font = `${(defaultFontSize -= 1)}px ${font}`; - while (ctx.measureText(text).width > width); - - return ctx.font; - }, -}; +/** + * Function to apply text on a canvas with dynamic font size based on the width constraint. + * + * @param {import("@napi-rs/canvas").Canvas} canvas - The canvas object where the text will be applied. + * @param {string} text - The string of text that needs to be applied on the canvas. + * @param {number} defaultFontSize - The initial font size for the text. It is expected to decrease with each iteration. + * @param {number} width - The maximum width that the text can occupy before it has to shrink down. + * @param {string} font - The name of the font used for drawing the text on the canvas. + * + * @return {string} - The final calculated font size in a format 'px '. + */ +export function applyText(canvas, text, defaultFontSize, width, font) { + const ctx = canvas.getContext("2d"); + do ctx.font = `${(defaultFontSize -= 1)}px ${font}`; + while (ctx.measureText(text).width > width); + return ctx.font; +} diff --git a/helpers/languages.js b/helpers/languages.js index 78ff2445..742c648e 100644 --- a/helpers/languages.js +++ b/helpers/languages.js @@ -1,19 +1,19 @@ -const i18next = require("i18next"), - Backend = require("i18next-fs-backend"), - path = require("path"), - fs = require("fs").promises; +import { use, init, getFixedT } from "i18next"; +import Backend from "i18next-fs-backend"; +import { join, resolve } from "path"; +import { promises as fs } from "fs"; async function walkDirectory(dir, namespaces = [], folderName = "") { const files = await fs.readdir(dir); const languages = []; for (const file of files) { - const stat = await fs.stat(path.join(dir, file)); + const stat = await fs.stat(join(dir, file)); if (stat.isDirectory()) { const isLanguage = file.includes("-"); if (isLanguage) languages.push(file); - const folder = await walkDirectory(path.join(dir, file), namespaces, isLanguage ? "" : `${file}/`); + const folder = await walkDirectory(join(dir, file), namespaces, isLanguage ? "" : `${file}/`); namespaces = folder.namespaces; } else { @@ -27,16 +27,16 @@ async function walkDirectory(dir, namespaces = [], folderName = "") { }; } -module.exports = async () => { +export default async () => { const options = { - loadPath: path.resolve(__dirname, "../languages/{{lng}}/{{ns}}.json"), + loadPath: resolve(__dirname, "../languages/{{lng}}/{{ns}}.json"), }; - const { namespaces, languages } = await walkDirectory(path.resolve(__dirname, "../languages/")); + const { namespaces, languages } = await walkDirectory(resolve(__dirname, "../languages/")); - i18next.use(Backend); + use(Backend); - await i18next.init({ + await init({ backend: options, debug: false, fallbackLng: "en-US", @@ -47,5 +47,5 @@ module.exports = async () => { preload: languages, }); - return new Map(languages.map(item => [item, i18next.getFixedT(item)])); + return new Map(languages.map(item => [item, getFixedT(item)])); }; diff --git a/helpers/logger.js b/helpers/logger.js index 86f02925..4c912908 100644 --- a/helpers/logger.js +++ b/helpers/logger.js @@ -1,4 +1,4 @@ -const { bgBlue, black, green } = require("chalk"); +import { bgBlue, black, green } from "chalk"; function dateTimePad(value, digits) { let number = value; @@ -25,28 +25,28 @@ function format(tDate) { ); } -module.exports = class Logger { - static log(content) { +export default { + log(content) { return console.log(`[${format(new Date(Date.now()))}]: ${bgBlue("LOG")} ${content}`); - } + }, - static warn(content) { + warn(content) { return console.log(`[${format(new Date(Date.now()))}]: ${black.bgYellow("WARN")} ${content}`); - } + }, - static error(content) { + error(content) { return console.log(`[${format(new Date(Date.now()))}]: ${black.bgRed("ERROR")} ${content}`); - } + }, - static debug(content) { + debug(content) { return console.log(`[${format(new Date(Date.now()))}]: ${green("DEBUG")} ${content}`); - } + }, - static cmd(content) { + cmd(content) { return console.log(`[${format(new Date(Date.now()))}]: ${black.bgWhite("CMD")} ${content}`); - } + }, - static ready(content) { + ready(content) { return console.log(`[${format(new Date(Date.now()))}]: ${black.bgGreen("READY")} ${content}`); - } + }, }; diff --git a/helpers/tictactoe.js b/helpers/tictactoe.js index a7c44a33..c3d238b9 100644 --- a/helpers/tictactoe.js +++ b/helpers/tictactoe.js @@ -1,7 +1,7 @@ // Thanks to simply-djs for this =) // TODO: Refactor this please... -const { ButtonBuilder, ActionRowBuilder, ButtonStyle, ComponentType } = require("discord.js"); +import { ButtonBuilder, ActionRowBuilder, ButtonStyle, ComponentType } from "discord.js"; /** * @param {import("discord.js").ChatInputCommandInteraction} interaction @@ -15,7 +15,7 @@ const { ButtonBuilder, ActionRowBuilder, ButtonStyle, ComponentType } = require( * @param {string} options.idleEmoji Emoji for "nothing" * @returns {Promise} */ -async function tictactoe(interaction, options = {}) { +export async function tictactoe(interaction, options = {}) { // eslint-disable-next-line no-async-promise-executor return new Promise(async resolve => { try { @@ -25,41 +25,47 @@ async function tictactoe(interaction, options = {}) { if (interaction.commandId) { opponent = interaction.options.getUser(options.userSlash || "user"); - if (!opponent) + if (!opponent) { return interaction.reply({ content: interaction.translate("fun/tictactoe:NO_USER"), ephemeral: true, }); + } - if (opponent.bot) + if (opponent.bot) { return interaction.reply({ content: interaction.translate("fun/tictactoe:BOT_USER"), ephemeral: true, }); + } - if (opponent.id == (interaction.user ? interaction.user : interaction.author).id) + if (opponent.id === (interaction.user ? interaction.user : interaction.author).id) { return interaction.reply({ content: interaction.translate("misc:CANT_YOURSELF"), ephemeral: true, }); + } } else if (!interaction.commandId) { opponent = interaction.mentions.members.first()?.user; - if (!opponent) + if (!opponent) { return interaction.reply({ content: interaction.translate("fun/tictactoe:NO_USER"), }); + } - if (opponent.bot) + if (opponent.bot) { return interaction.reply({ content: interaction.translate("fun/tictactoe:BOT_USER"), ephemeral: true, }); + } - if (opponent.id === interaction.member.id) + if (opponent.id === interaction.member.id) { return interaction.reply({ content: interaction.translate("misc:CANT_YOURSELF"), }); + } } const footer = options.embedFooter || client.config.embed.footer, @@ -97,25 +103,26 @@ async function tictactoe(interaction, options = {}) { }); collector.on("collect", async button => { - if (button.user.id !== opponent.id) + if (button.user.id !== opponent.id) { return button.reply({ content: interaction.translate("fun/tictactoe:REQUEST_SEND", { opponent: opponent.id, }), ephemeral: true, }); + } - if (button.customId == "declinettt") { + if (button.customId === "declinettt") { button.deferUpdate(); return collector.stop("decline"); - } else if (button.customId == "acceptttt") { + } else if (button.customId === "acceptttt") { button.deferUpdate(); collector.stop(); const fighters = [(interaction.user ? interaction.user : interaction.author).id, opponent.id].sort(() => (Math.random() > 0.5 ? 1 : -1)); - const x_emoji = options.xEmoji || "❌"; - const o_emoji = options.oEmoji || "⭕"; + const xEmoji = options.xEmoji || "❌"; + const oEmoji = options.oEmoji || "⭕"; const dashmoji = options.idleEmoji || "➖"; @@ -175,32 +182,32 @@ async function tictactoe(interaction, options = {}) { }); let msg; - if (interaction.commandId) + if (interaction.commandId) { msg = await interaction.editReply({ embeds: [ epm.setDescription( interaction.translate("fun/tictactoe:WAITING", { user: Args.userid, - emoji: client.emojis.cache.get(o_emoji) || "⭕", + emoji: client.emojis.cache.get(oEmoji) || "⭕", }), ), ], }); - else if (!interaction.commandId) + } else if (!interaction.commandId) { msg = await button.message.edit({ embeds: [ epm.setDescription( interaction.translate("fun/tictactoe:WAITING", { user: Args.userid, - emoji: client.emojis.cache.get(o_emoji) || "⭕", + emoji: client.emojis.cache.get(oEmoji) || "⭕", }), ), ], }); + } await ttt(msg); - // eslint-disable-next-line no-inner-declarations async function ttt(m) { Args.userid = fighters[Args.user]; const won = { @@ -222,214 +229,212 @@ async function tictactoe(interaction, options = {}) { const c = new ActionRowBuilder().addComponents([c1, c2, c3]); const buttons = [a, b, c]; - if (Args.a1.emoji == o_emoji && Args.b1.emoji == o_emoji && Args.c1.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.a1.emoji === oEmoji && Args.b1.emoji === oEmoji && Args.c1.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.a2.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.c2.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.a2.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.c2.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.a3.emoji == o_emoji && Args.b3.emoji == o_emoji && Args.c3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.a3.emoji === oEmoji && Args.b3.emoji === oEmoji && Args.c3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.a1.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.c3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.a1.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.c3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.a3.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.c1.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.a3.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.c1.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.a1.emoji == o_emoji && Args.a2.emoji == o_emoji && Args.a3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.a1.emoji === oEmoji && Args.a2.emoji === oEmoji && Args.a3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.b1.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.b3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.b1.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.b3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (Args.c1.emoji == o_emoji && Args.c2.emoji == o_emoji && Args.c3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Args.c1.emoji === oEmoji && Args.c2.emoji === oEmoji && Args.c3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (won["<:O_:863314110560993340>"] != false) - if (Args.user == 0) { + if (won["<:O_:863314110560993340>"] !== false) { + if (Args.user === 0) { const won = await client.users.fetch(fighters[1]).catch(console.error); resolve(won); - if (options.resultBtn === true) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - components: buttons, + if (options.resultBtn === true) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + components: buttons, - embeds: [ - epm.setDescription( - interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - ), - ], - }); - else if (!options.resultBtn || options.resultBtn === false) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), + embeds: [ + epm.setDescription( + interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + ), + ], + }); + } else if (!options.resultBtn || options.resultBtn === false) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), - embeds: [ - epm.setDescription( - `${interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - })}\n\`\`\`\n${Args.a1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.b1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.c1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), - ), - ], - components: [], - }); - } else if (Args.user == 1) { + embeds: [ + epm.setDescription( + `${interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + })}\n\`\`\`\n${Args.a1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.b1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.c1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), + ), + ], + components: [], + }); + } + } else if (Args.user === 1) { const won = await client.users.fetch(fighters[0]).catch(console.error); resolve(won); - if (options.resultBtn === true) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - components: buttons, - embeds: [ - epm.setDescription( - interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - ), - ], - }); - else if (!options.resultBtn || options.resultBtn === false) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), + if (options.resultBtn === true) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + components: buttons, + embeds: [ + epm.setDescription( + interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + ), + ], + }); + } else if (!options.resultBtn || options.resultBtn === false) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), - embeds: [ - epm.setDescription( - `${interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - })}\n\`\`\`\n${Args.a1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.b1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.c1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), - ), - ], - components: [], - }); + embeds: [ + epm.setDescription( + `${interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + })}\n\`\`\`\n${Args.a1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.b1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.c1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), + ), + ], + components: [], + }); + } } + } - if (Args.a1.emoji == x_emoji && Args.b1.emoji == x_emoji && Args.c1.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.a2.emoji == x_emoji && Args.b2.emoji == x_emoji && Args.c2.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.a3.emoji == x_emoji && Args.b3.emoji == x_emoji && Args.c3.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.a1.emoji == x_emoji && Args.b2.emoji == x_emoji && Args.c3.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.a3.emoji == x_emoji && Args.b2.emoji == x_emoji && Args.c1.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.a1.emoji == x_emoji && Args.a2.emoji == x_emoji && Args.a3.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.b1.emoji == x_emoji && Args.b2.emoji == x_emoji && Args.b3.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (Args.c1.emoji == x_emoji && Args.c2.emoji == x_emoji && Args.c3.emoji == x_emoji) won["<:X_:863314044781723668>"] = true; - if (won["<:X_:863314044781723668>"] != false) - if (Args.user == 0) { + if (Args.a1.emoji === xEmoji && Args.b1.emoji === xEmoji && Args.c1.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.a2.emoji === xEmoji && Args.b2.emoji === xEmoji && Args.c2.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.a3.emoji === xEmoji && Args.b3.emoji === xEmoji && Args.c3.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.a1.emoji === xEmoji && Args.b2.emoji === xEmoji && Args.c3.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.a3.emoji === xEmoji && Args.b2.emoji === xEmoji && Args.c1.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.a1.emoji === xEmoji && Args.a2.emoji === xEmoji && Args.a3.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.b1.emoji === xEmoji && Args.b2.emoji === xEmoji && Args.b3.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (Args.c1.emoji === xEmoji && Args.c2.emoji === xEmoji && Args.c3.emoji === xEmoji) won["<:X_:863314044781723668>"] = true; + if (won["<:X_:863314044781723668>"] !== false) { + if (Args.user === 0) { const won = await client.users.fetch(fighters[1]).catch(console.error); resolve(won); - if (options.resultBtn === true) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - components: buttons, - embeds: [ - epm.setDescription( - interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - ), - ], - }); - else if (!options.resultBtn || options.resultBtn === false) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - embeds: [ - epm.setDescription( - `${interaction.translate("fun/tictactoe:WON", { - winner: fighters[1], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - })}\n\`\`\`\n${Args.a1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.b1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.c1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), - ), - ], - components: [], - }); - } else if (Args.user == 1) { + if (options.resultBtn === true) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + components: buttons, + embeds: [ + epm.setDescription( + interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + ), + ], + }); + } else if (!options.resultBtn || options.resultBtn === false) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + embeds: [ + epm.setDescription( + `${interaction.translate("fun/tictactoe:WON", { + winner: fighters[1], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + })}\n\`\`\`\n${Args.a1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.b1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.c1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), + ), + ], + components: [], + }); + } + } else if (Args.user === 1) { const won = await client.users.fetch(fighters[0]).catch(console.error); resolve(won); - if (options.resultBtn === true) - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - components: buttons, - embeds: [ - epm.setDescription( - interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - ), - ], - }); - else - return m - .edit({ - content: interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - }), - embeds: [ - epm.setDescription( - `${interaction.translate("fun/tictactoe:WON", { - winner: fighters[0], - emoji: client.emojis.cache.get(o_emoji) || "⭕", - })}\n\`\`\`\n${Args.a1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.b1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n${Args.c1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c2.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c3.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), - ), - ], - components: [], - }); + if (options.resultBtn === true) { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + components: buttons, + embeds: [ + epm.setDescription( + interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + ), + ], + }); + } else { + return m.edit({ + content: interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + }), + embeds: [ + epm.setDescription( + `${interaction.translate("fun/tictactoe:WON", { + winner: fighters[0], + emoji: client.emojis.cache.get(oEmoji) || "⭕", + })}\n\`\`\`\n${Args.a1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.b1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n${Args.c1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c2.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c3.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), + ), + ], + components: [], + }); + } } + } m.edit({ content: `<@${Args.userid}>`, @@ -437,7 +442,7 @@ async function tictactoe(interaction, options = {}) { epm.setDescription( interaction.translate("fun/tictactoe:WAITING", { user: Args.userid, - emoji: Args.user == 0 ? `${client.emojis.cache.get(o_emoji) || "⭕"}` : `${client.emojis.cache.get(x_emoji) || "❌"}`, + emoji: Args.user === 0 ? `${client.emojis.cache.get(oEmoji) || "⭕"}` : `${client.emojis.cache.get(xEmoji) || "❌"}`, }), ), ], @@ -458,18 +463,18 @@ async function tictactoe(interaction, options = {}) { ttt(m); } else { - if (Args.user == 0) { + if (Args.user === 0) { Args.user = 1; Args[b.customId] = { style: ButtonStyle.Success, - emoji: o_emoji, + emoji: oEmoji, disabled: true, }; } else { Args.user = 0; Args[b.customId] = { style: ButtonStyle.Danger, - emoji: x_emoji, + emoji: xEmoji, disabled: true, }; } @@ -487,49 +492,49 @@ async function tictactoe(interaction, options = {}) { .filter(key => predicate(obj[key])) .reduce((res, key) => ((res[key] = obj[key]), res), {}); const Brgs = objectFilter( - map(Args, (_, fruit) => fruit.emoji == dashmoji), - num => num == true, + map(Args, (_, fruit) => fruit.emoji === dashmoji), + num => num === true, ); - if (Object.keys(Brgs).length == 0) { - if (Args.a1.emoji == o_emoji && Args.b1.emoji == o_emoji && Args.c1.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.a2.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.c2.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.a3.emoji == o_emoji && Args.b3.emoji == o_emoji && Args.c3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.a1.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.c3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.a3.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.c1.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.a1.emoji == o_emoji && Args.a2.emoji == o_emoji && Args.a3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.b1.emoji == o_emoji && Args.b2.emoji == o_emoji && Args.b3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; - if (Args.c1.emoji == o_emoji && Args.c2.emoji == o_emoji && Args.c3.emoji == o_emoji) won["<:O_:863314110560993340>"] = true; + if (Object.keys(Brgs).length === 0) { + if (Args.a1.emoji === oEmoji && Args.b1.emoji === oEmoji && Args.c1.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.a2.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.c2.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.a3.emoji === oEmoji && Args.b3.emoji === oEmoji && Args.c3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.a1.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.c3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.a3.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.c1.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.a1.emoji === oEmoji && Args.a2.emoji === oEmoji && Args.a3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.b1.emoji === oEmoji && Args.b2.emoji === oEmoji && Args.b3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; + if (Args.c1.emoji === oEmoji && Args.c2.emoji === oEmoji && Args.c3.emoji === oEmoji) won["<:O_:863314110560993340>"] = true; - if (won["<:O_:863314110560993340>"] == true) return ttt(m); - else if (won["<:X_:863314044781723668>"] == true) return; + if (won["<:O_:863314110560993340>"] === true) return ttt(m); + else if (won["<:X_:863314044781723668>"] === true) return; else { ttt(m); - if (options.resultBtn === true) - return m - .edit({ - content: interaction.translate("fun/tictactoe:TIE"), - embeds: [epm.setDescription(interaction.translate("fun/tictactoe:TIE_DESC"))], - }); - else + if (options.resultBtn === true) { + return m.edit({ + content: interaction.translate("fun/tictactoe:TIE"), + embeds: [epm.setDescription(interaction.translate("fun/tictactoe:TIE_DESC"))], + }); + } else { return m .edit({ content: interaction.translate("fun/tictactoe:TIE"), embeds: [ epm.setDescription( - `${interaction.translate("fun/tictactoe:TIE_DESC")}!\n\`\`\`\n${Args.a1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.a2.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")} | ${Args.a3.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")}\n${Args.b1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.b2.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")} | ${Args.b3.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")}\n${Args.c1.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")} | ${Args.c2.emoji - .replace(o_emoji, "⭕") - .replace(x_emoji, "❌")} | ${Args.c3.emoji.replace(o_emoji, "⭕").replace(x_emoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), + `${interaction.translate("fun/tictactoe:TIE_DESC")}!\n\`\`\`\n${Args.a1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.a2.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")} | ${Args.a3.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")}\n${Args.b1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.b2.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")} | ${Args.b3.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")}\n${Args.c1.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")} | ${Args.c2.emoji + .replace(oEmoji, "⭕") + .replace(xEmoji, "❌")} | ${Args.c3.emoji.replace(oEmoji, "⭕").replace(xEmoji, "❌")}\n\`\`\``.replaceAll(dashmoji, "➖"), ), ], components: [], }) .catch(() => {}); + } } } @@ -537,20 +542,21 @@ async function tictactoe(interaction, options = {}) { } }); collector.on("end", (collected, reason) => { - if (collected.size === 0 && reason == "time") + if (collected.size === 0 && reason === "time") { m.edit({ content: interaction.translate("fun/tictactoe:NO_ANSWER", { user: Args.userid, }), components: [], }); + } }); } } }); collector.on("end", (_, reason) => { - if (reason == "time") { + if (reason === "time") { const embed = client.embed({ author: { name: user.getUsername(), @@ -570,7 +576,7 @@ async function tictactoe(interaction, options = {}) { components: [], }); } - if (reason == "decline") { + if (reason === "decline") { const embed = client.embed({ author: { name: user.getUsername(), @@ -594,6 +600,4 @@ async function tictactoe(interaction, options = {}) { console.log("TicTacToe errored:", e); } }); -} - -module.exports = tictactoe; +}; diff --git a/index.js b/index.js index 93a36e3d..49a3c579 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,10 @@ import "./helpers/extenders.js"; import { GatewayIntentBits } from "discord.js"; -import Client from "./base/Client.js"; +import JaBaClient from "./base/Client.js"; +import languages from "./helpers/languages.js"; -const client = new Client({ +const client = new JaBaClient({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, @@ -27,7 +28,7 @@ const client = new Client({ (async () => { console.time("botReady"); - client.translations = await require("./helpers/languages")(); + client.translations = await languages(); await client.loadEvents("../events"); await client.loadCommands("../commands"); diff --git a/languages/en-US/administration/config.json b/languages/en-US/administration/config.json index ec9ec653..29fc99cf 100644 --- a/languages/en-US/administration/config.json +++ b/languages/en-US/administration/config.json @@ -23,8 +23,6 @@ "AUTO_SANCTIONS": "Automatic Sanctions", "BAN_CONTENT": "Ban: After **{{count}}** warnings", "BAN_NOT_DEFINED": "Ban: Not set", - "DASHBOARD_TITLE": "Modify Settings", - "DASHBOARD_CONTENT": "Click here to go to the dashboard", "GOODBYE_TITLE": "Farewell", "GOODBYE_CONTENT": "Channel: {{channel}}\nCard: {{withImage}}", "KICK_CONTENT": "Kick: After **{{count}}** warnings", diff --git a/languages/en-US/dashboard.json b/languages/en-US/dashboard.json deleted file mode 100644 index 315050aa..00000000 --- a/languages/en-US/dashboard.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "name": "English", - "index": { - "feeds": [ "Current User", "Playing music in this much servers", "Users Count", "Servers Count" ], - "card": { - "category": "JaBa Bot", - "title": "Simple bot made by Jonny_Bro", - "description": "Upper Text", - "image": "", - "footer": "Bottom Text" - }, - "feedsTitle": "Feeds", - "graphTitle": "Graphs" - }, - "manage": { - "settings": { - "memberCount": "Members", - "info": { - "info": "Info", - "server": "Server Information" - } - } - }, - "privacyPolicy": { - "title": "Privacy Policy", - "description": "Privacy Policy and Terms of Service", - "pp": "Complete Privacy Policy" - }, - "partials": { - "sidebar": { - "dash": "Dashboard", - "manage": "Manage Guilds", - "commands": "Commands", - "pp": "Privacy Policy", - "admin": "Admin", - "account": "Account Pages", - "login": "Sign In", - "logout": "Sign Out" - }, - "navbar": { - "home": "Home", - "pages": { - "manage": "Manage Guilds", - "settings": "Manage Guilds", - "commands": "Commands", - "pp": "Privacy Policy", - "admin": "Admin Panel", - "error": "Error", - "credits": "Credits", - "debug": "Debug", - "leaderboard": "Leaderboard", - "profile": "Profile", - "maintenance": "Under Maintenance" - } - }, - "title": { - "pages": { - "manage": "Manage Guilds", - "settings": "Manage Guilds", - "commands": "Commands", - "pp": "Privacy Policy", - "admin": "Admin Panel", - "error": "Error", - "credits": "Credits", - "debug": "Debug", - "leaderboard": "Leaderboard", - "profile": "Profile", - "maintenance": "Under Maintenance" - } - }, - "notify": { - "errors": { - "settingsSave": "Failed to save setttings" - }, - "success": { - "settingsSave": "Successfully saved setttings.", - "login": "Successfully logged in.", - "logout": "Successfully logged out." - } - }, - "preloader": { - "text": "Page is loading..." - }, - "premium": { - "title": "Want more from JaBa?", - "description": "Check out premium features below!", - "buttonText": "Become Premium" - }, - "settings": { - "title": "Site Configuration", - "description": "Configurable Viewing Options", - "theme": { - "title": "Site Theme", - "description": "Make the site more appealing for your eyes!" - }, - "language": { - "title": "Site Language", - "description": "Select your preffered language!" - } - } - } -} \ No newline at end of file diff --git a/languages/en-US/misc.json b/languages/en-US/misc.json index ed6d5cd7..baa94e62 100644 --- a/languages/en-US/misc.json +++ b/languages/en-US/misc.json @@ -15,7 +15,7 @@ "OPTION_NAN_ALL": "Please specify an integer greater than 0 or `all`.", "OWNER_ONLY": "Only the bot owner can use this command.", "SELECT_CANCELED": "Selection canceled.", - "STATS_FOOTER": "● [Dashboard]({{dashboardLink}})\n● [Support Server]({{supportLink}})\n● [Invite JaBa to Your Server]({{inviteLink}})", + "STATS_FOOTER": "● [Support Server]({{supportLink}})\n● [Invite JaBa to Your Server]({{inviteLink}})", "TIMED_OUT": "Time out.", "JUMP_TO_PAGE": "Specify the page you want to jump to (maximum **{{length}}**):", "QUOTE_TITLE": "Message from {{user}}", diff --git a/languages/language-meta.js b/languages/language-meta.js new file mode 100644 index 00000000..cc409b36 --- /dev/null +++ b/languages/language-meta.js @@ -0,0 +1,23 @@ +export default [ + { + name: "en-US", + nativeName: "English", + moment: "en", + defaultMomentFormat: "HH:mm:ss, MMMM Do YYYY", + default: true, + }, + { + name: "ru-RU", + nativeName: "Русский", + moment: "ru", + defaultMomentFormat: "HH:mm:ss, Do MMMM YYYY", + default: false, + }, + { + name: "uk-UA", + nativeName: "Українська", + moment: "uk", + defaultMomentFormat: "HH:mm:ss, Do MMMM YYYY", + default: false, + }, +]; diff --git a/languages/language-meta.json b/languages/language-meta.json deleted file mode 100644 index ae102d46..00000000 --- a/languages/language-meta.json +++ /dev/null @@ -1,23 +0,0 @@ -[ - { - "name": "en-US", - "nativeName": "English", - "moment": "en", - "defaultMomentFormat": "HH:mm:ss, MMMM Do YYYY", - "default": true - }, - { - "name": "ru-RU", - "nativeName": "Русский", - "moment": "ru", - "defaultMomentFormat": "HH:mm:ss, Do MMMM YYYY", - "default": false - }, - { - "name": "uk-UA", - "nativeName": "Українська", - "moment": "uk", - "defaultMomentFormat": "HH:mm:ss, Do MMMM YYYY", - "default": false - } -] \ No newline at end of file diff --git a/languages/ru-RU/administration/config.json b/languages/ru-RU/administration/config.json index 277325d3..eb229e73 100644 --- a/languages/ru-RU/administration/config.json +++ b/languages/ru-RU/administration/config.json @@ -23,8 +23,6 @@ "AUTO_SANCTIONS": "Автоматические наказания", "BAN_CONTENT": "Бан: После **{{count}}** предупреждений", "BAN_NOT_DEFINED": "Бан: Не назначено", - "DASHBOARD_TITLE": "Изменить настройки", - "DASHBOARD_CONTENT": "Нажмите сюда, чтобы перейти в панель управления", "GOODBYE_TITLE": "Прощание", "GOODBYE_CONTENT": "Канал: {{channel}}\nКарточка: {{withImage}}", "KICK_CONTENT": "Кик: После **{{count}}** предупреждений", diff --git a/languages/ru-RU/dashboard.json b/languages/ru-RU/dashboard.json deleted file mode 100644 index c60a4107..00000000 --- a/languages/ru-RU/dashboard.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "name": "Русский", - "index": { - "feeds": [ "Текущий пользователь", "Играю музыку в стольких серверах", "Кол-во пользователей", "Кол-во серверов" ], - "card": { - "category": "JaBa Bot", - "title": "Простой бот, созданный Jonny_Bro", - "description": "Верхний текст", - "image": "", - "footer": "Нижний текст" - }, - "feedsTitle": "Новости", - "graphTitle": "Графики" - }, - "manage": { - "settings": { - "memberCount": "Участники", - "info": { - "info": "Информация", - "server": "Информация о сервере" - } - } - }, - "privacyPolicy": { - "title": "Политика конф.", - "description": "Политика конфиденциальности и Условия использования", - "pp": "Полная политика конфиденциальности" - }, - "partials": { - "sidebar": { - "dash": "Панель управления", - "manage": "Сервера", - "commands": "Команды", - "pp": "Политика конф.", - "admin": "Админ панель", - "account": "Аккаунт", - "login": "Войти", - "logout": "Выйти" - }, - "navbar": { - "home": "Главная", - "pages": { - "manage": "Настройки серверов", - "settings": "Настройки", - "commands": "Команды", - "pp": "Политика конфиденциальности", - "admin": "Админ панель", - "error": "Ошибка", - "credits": "Разработчики панели", - "debug": "Отладка", - "leaderboard": "Таблица лидеров", - "profile": "Профиль", - "maintenance": "Техобслуживание" - } - }, - "title": { - "pages": { - "manage": "Настройки серверов", - "settings": "Настройки", - "commands": "Команды", - "pp": "Политика конфиденциальности", - "admin": "Админ панель", - "error": "Ошибка", - "credits": "Разработчики панели", - "debug": "Отладка", - "leaderboard": "Таблица лидеров", - "profile": "Профиль", - "maintenance": "Техобслуживание" - } - }, - "notify": { - "errors": { - "settingsSave": "Произошла ошибка при сохранении настроек." - }, - "success": { - "settingsSave": "Настройки успешно сохранены.", - "login": "Вход успешно выполнен.", - "logout": "Выход успешно выполнен." - } - }, - "preloader": { - "text": "Загрузка..." - }, - "premium": { - "title": "Хотите большего JaBa?", - "description": "Проверьте Премиум функции!", - "buttonText": "Стать Премиум" - }, - "settings": { - "title": "Настройки сайта", - "description": "Настройте параметры панели управления", - "theme": { - "title": "Тема", - "description": "У нас есть тёмная и светлая!" - }, - "language": { - "title": "Язык", - "description": "Выберите предпочитаемый язык!" - } - } - } -} \ No newline at end of file diff --git a/languages/ru-RU/misc.json b/languages/ru-RU/misc.json index 307c3184..693cbda8 100644 --- a/languages/ru-RU/misc.json +++ b/languages/ru-RU/misc.json @@ -15,7 +15,7 @@ "OPTION_NAN_ALL": "Укажите целое число больше 0 или `all`", "OWNER_ONLY": "Данную команду может использовать только владелец бота", "SELECT_CANCELED": "Выбор отменён", - "STATS_FOOTER": "● [Панель управления]({{dashboardLink}})\n● [Сервер поддержки]({{supportLink}})\n● [Пригласить JaBa на свой сервер]({{inviteLink}})", + "STATS_FOOTER": "● [Сервер поддержки]({{supportLink}})\n● [Пригласить JaBa на свой сервер]({{inviteLink}})", "TIMED_OUT": "Время вышло", "JUMP_TO_PAGE": "Укажите страницу к которой хотите перейти (максимум **{{length}}**):", "QUOTE_TITLE": "Сообщение от {{user}}", diff --git a/languages/uk-UA/administration/config.json b/languages/uk-UA/administration/config.json index 23667af3..63c4c186 100644 --- a/languages/uk-UA/administration/config.json +++ b/languages/uk-UA/administration/config.json @@ -23,8 +23,6 @@ "AUTO_SANCTIONS": "Автоматичні покарання", "BAN_CONTENT": "Бан: Після **{{count}}** попереджень", "BAN_NOT_DEFINED": "Бан: Не призначено", - "DASHBOARD_TITLE": "Змінити налаштування", - "DASHBOARD_CONTENT": "Натисніть сюди, щоб перейти до панелі керування", "GOODBYE_TITLE": "Прощання", "GOODBYE_CONTENT": "Канал: {{channel}}\nКартка: {{withImage}}", "KICK_CONTENT": "Кік: Після **{{count}}** попереджень", diff --git a/languages/uk-UA/dashboard.json b/languages/uk-UA/dashboard.json deleted file mode 100644 index 6141e871..00000000 --- a/languages/uk-UA/dashboard.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "name": "Українська", - "index": { - "feeds": [ "Поточний Користувач", "Играю музыку в стольких серверах", "Кількість користувачів", "Кількість серверів" ], - "card": { - "category": "JaBa Бот", - "title": "Простий бот, створений Jonny_Bro", - "description": "Верхній Текст", - "image": "", - "footer": "Нижній Текст" - }, - "feedsTitle": "Канали", - "graphTitle": "Графіки" - }, - "manage": { - "settings": { - "memberCount": "Учасники", - "info": { - "info": "Інформація", - "server": "Інформація про Сервер" - } - } - }, - "privacyPolicy": { - "title": "Політика Конфіденційності", - "description": "Політика Конфіденційності та Умови Сервісу", - "pp": "Повна Політика Конфіденційності" - }, - "partials": { - "sidebar": { - "dash": "Панель Керування", - "manage": "Налаштування серверів", - "commands": "Команди", - "pp": "Політика Конфіденційності", - "admin": "Адмін", - "account": "Сторінки Аккаунта", - "login": "Увійти", - "logout": "Вийти" - }, - "navbar": { - "home": "Головна", - "pages": { - "manage": "Налаштування серверів", - "settings": "Керувати", - "commands": "Команди", - "pp": "Політика Конфіденційності", - "admin": "Панель Адміністратора", - "error": "Помилка", - "credits": "Автори", - "debug": "Налагодження", - "leaderboard": "Таблиця Лідерів", - "profile": "Профіль", - "maintenance": "Технічне Обслуговування" - } - }, - "title": { - "pages": { - "manage": "Керувати Гілдіями", - "settings": "Керувати", - "commands": "Команди", - "pp": "Політика Конфіденційності", - "admin": "Панель Адміністратора", - "error": "Помилка", - "credits": "Автори", - "debug": "Налагодження", - "leaderboard": "Таблиця Лідерів", - "profile": "Профіль", - "maintenance": "Технічне Обслуговування" - } - }, - "notify": { - "errors": { - "settingsSave": "Сталася помилка при збереженні налаштувань." - }, - "success": { - "settingsSave": "Налаштування успішно збережені.", - "login": "Успішний вхід.", - "logout": "Успішний вихід." - } - }, - "preloader": { - "text": "Завантаження..." - }, - "premium": { - "title": "Бажаєте більше від JaBa?", - "description": "Ознайомтесь з преміум-функціями нижче!", - "buttonText": "Стати Преміум" - }, - "settings": { - "title": "Налаштування Сайту", - "description": "Налаштовувані параметри перегляду", - "theme": { - "title": "Тема", - "description": "Зробіть сайт більш привабливим для своїх очей!" - }, - "language": { - "title": "Мова", - "description": "Виберіть бажану мову!" - } - } - } -} \ No newline at end of file diff --git a/languages/uk-UA/misc.json b/languages/uk-UA/misc.json index d5ffcdc1..383b642b 100644 --- a/languages/uk-UA/misc.json +++ b/languages/uk-UA/misc.json @@ -15,7 +15,7 @@ "OPTION_NAN_ALL": "Вкажіть ціле число більше 0 або `all`", "OWNER_ONLY": "Цю команду може використовувати тільки власник бота", "SELECT_CANCELED": "Вибір скасовано", - "STATS_FOOTER": "● [Панель керування]({{dashboardLink}})\n● [Сервер підтримки]({{supportLink}})\n● [Запросити JaBa на свій сервер]({{inviteLink}})", + "STATS_FOOTER": "● [Сервер підтримки]({{supportLink}})\n● [Запросити JaBa на свій сервер]({{inviteLink}})", "TIMED_OUT": "Час вийшов", "JUMP_TO_PAGE": "Вкажіть сторінку, до якої хочете перейти (максимум **{{length}}**):", "QUOTE_TITLE": "Повідомлення від {{user}}",