Compare commits

...

52 commits

Author SHA1 Message Date
b11cf4ce11
clean up 2024-11-20 12:11:29 +05:00
e5c6659de5
fix birthdays 2024-11-20 12:01:41 +05:00
5a7088671f
update nsfw api domain 2024-11-20 11:51:50 +05:00
f77913c007
remove useless reactions 2024-11-18 19:35:33 +05:00
358253a4e3
? 2024-11-18 19:32:48 +05:00
19ed241e76
fix error in tictactoe 2024-11-18 19:31:24 +05:00
4aa0cfe9fa
refactor some helpers 2024-11-18 19:19:24 +05:00
f65f09463c
update deps where we can 2024-11-17 13:58:35 +05:00
f9cc19531e
update dependencies 2024-11-17 13:34:50 +05:00
786aa9112b
make reminds always ephemeral 2024-11-10 17:28:24 +05:00
f7057160a0
make old dates backwards compatible 2024-11-05 18:02:08 +05:00
d34c5cee09
update deps, add ids to servers command 2024-11-04 22:28:48 +05:00
3524051548
update deps 2024-10-08 18:54:45 +05:00
Jonny_Bro (Nikita)
4b89b8f447
quote return 2024-10-04 12:22:35 +05:00
Jonny_Bro (Nikita)
80c93c95e0
fix quote deletion, move some functions 2024-10-04 12:13:41 +05:00
6967581788
fix message quotes 2024-10-03 21:15:41 +05:00
f26012561b
dont need to do that, they are already ints 2024-10-03 11:17:36 +05:00
672b7b2001
Refactor some functions 2024-10-03 11:07:02 +05:00
2469183919
fallback image for join/leave logs 2024-09-20 22:48:40 +05:00
96009bad69
remove Music category from User Installs 2024-09-20 20:15:44 +05:00
77ec27dc1d
4.6.6 - Fixed User Installs 2024-09-19 23:58:06 +05:00
d97c4bf4f2
v4.6.5 2024-09-14 19:52:56 +05:00
b4dd085ea7
custom statuses 2024-08-25 15:13:18 +05:00
Jonny_Bro (Nikita)
e2bd32cb3a
Update emojis.json
add roles empji
2024-08-23 12:03:01 +05:00
58c103d9ba
fix emojis 2024-08-21 19:44:04 +05:00
Jonny_Bro (Nikita)
1aa2c7bd22
update info 2024-08-21 12:03:33 +05:00
Jonny_Bro (Nikita)
3898cbcf2d
Update info.js 2024-08-21 11:59:02 +05:00
6c48716ba7
v4.6.4 2024-08-18 13:12:49 +05:00
Jonny_Bro (Nikita)
f6a6716f58
Update MessageHandler.js 2024-08-15 20:33:54 +05:00
dd0e893aff
remove donation link 2024-08-15 18:10:51 +05:00
097a41ba65
remove emoji from quote button 2024-08-15 17:39:59 +05:00
8050abbabc
add pagination to delete buttons in reminds 2024-08-14 18:52:46 +05:00
05f49331e0
Update NSFW domain 2024-08-14 14:03:45 +05:00
5dceb1abd4
v4.6.3 2024-08-13 18:52:55 +05:00
Jonny_Bro (Nikita)
9af053061d
Update stats.json's (#18)
* Update stats.json

ugly

* Update stats.json

ugly 2

* Update stats.json

ugly 3
2024-08-13 12:21:50 +05:00
Jonny_Bro (Nikita)
ffb7ee97d0
change stats translation a bit 2024-08-13 12:18:25 +05:00
Jonny_Bro (Nikita)
b26af17908
fix stats 2024-08-13 12:12:39 +05:00
8b005b4d06
remove hidden channel from counter 2024-08-10 21:52:23 +05:00
c22dd92a35
add test function to reminds 2024-08-10 21:49:18 +05:00
34b219e278
fix old link in courses command 2024-08-04 22:35:58 +05:00
8d2557fac8
fix url shorturl and music (please) 2024-08-01 23:23:23 +05:00
8963681b30
move to in-app emojis 2024-07-31 21:06:43 +05:00
a7af97b756
update deps 2024-07-27 18:32:34 +05:00
9a8c912b3f
update packages 2024-07-21 21:58:02 +05:00
f9f2a42d03
update packages 2024-07-18 17:08:53 +05:00
18451ebb11
disable clearwanrs on yourself 2024-07-18 00:07:24 +05:00
7774a1df6b
remove unused variable 2024-07-17 21:03:54 +05:00
66c4af9ac5
revert that 2024-07-17 21:03:08 +05:00
e4ac2624ae
oj 2024-07-17 20:32:45 +05:00
b2070ba6cb
add deleted by 2024-07-17 20:30:01 +05:00
54cfde2a05
temp fix for music (only youtube works!) 2024-07-14 17:23:28 +05:00
a3e906a8f8
update submodule 2024-07-13 15:40:36 +05:00
180 changed files with 2590 additions and 3268 deletions

View file

@ -64,6 +64,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.
## License

View file

@ -1,7 +1,9 @@
const { Client, Collection, SlashCommandBuilder, ContextMenuCommandBuilder, EmbedBuilder, PermissionsBitField, ChannelType } = require("discord.js"),
{ GiveawaysManager } = require("discord-giveaways"),
{ REST } = require("@discordjs/rest"),
{ Player } = require("discord-player"),
{ Player: DiscordPlayer } = require("discord-player"),
{ SpotifyExtractor } = require("@discord-player/extractor"),
{ YoutubeiExtractor } = require("discord-player-youtubei"),
{ Routes } = require("discord-api-types/v10");
const BaseEvent = require("./BaseEvent.js"),
@ -31,23 +33,32 @@ class JaBaClient extends Client {
this.databaseCache.guilds = new Collection();
this.databaseCache.members = new Collection();
this.databaseCache.usersReminds = new Collection();
}
this.player = new Player(this, {
ytdlOptions: {
requestOptions: {
headers: {
cookie: this.config.youtubeCookie,
},
},
/**
* Initializes the client by logging in with the provided token and connecting to the MongoDB database.
*
* This method is called during the client's startup process to set up the necessary connections and resources.
*
* @returns {Promise<void>} A Promise that resolves when the client is fully initialized.
*/
async init() {
this.player = new DiscordPlayer(this);
await this.player.extractors.register(YoutubeiExtractor, {
authentication: this.config.youtubeCookie,
streamOptions: {
useClient: "YTMUSIC_ANDROID",
},
});
this.player.extractors.loadDefault(null, {
SpotifyExtractor: {
clientId: this.config.spotify.clientId,
clientSecret: this.config.spotify.clientSecret,
},
await this.player.extractors.register(SpotifyExtractor, {
clientId: this.config.spotify.clientId,
clientSecret: this.config.spotify.clientSecret,
});
await this.player.extractors.loadDefault(ext => !["YouTubeExtractor", "SpotifyExtractor"].includes(ext));
this.player.events.on("playerStart", async (queue, track) => {
const m = (
await queue.metadata.channel.send({
@ -88,37 +99,24 @@ class JaBaClient extends Client {
reaction: "🎉",
},
});
}
/**
* Initializes the client by logging in with the provided token and connecting to the MongoDB database.
*
* This method is called during the client's startup process to set up the necessary connections and resources.
*
* @returns {Promise<void>} A Promise that resolves when the client is fully initialized.
*/
async init() {
this.login(this.config.token);
mongoose
.connect(this.config.mongoDB)
.then(() => {
this.logger.log("Connected to the Mongodb database.");
this.logger.log("Connected to the MongoDB database.");
})
.catch(err => {
this.logger.error(`Unable to connect to the Mongodb database.\nError: ${err}`);
.catch(e => {
this.logger.error(`Unable to connect to the MongoDB database.\nError: ${e.message}\n${e.stack}`);
});
// const autoUpdateDocs = require("../helpers/autoUpdateDocs");
// autoUpdateDocs.update(this);
this.login(this.config.token);
}
/**
* Loads all the commands from the specified directory and registers them with the Discord API.
*
* This method is responsible for dynamically loading all the command files from the specified directory,
* creating instances of the corresponding command classes, and registering the commands with the Discord API.
* It also handles any additional setup or initialization required by the loaded commands.
* This method dynamically loads all command files from the specified directory,
* creates instances of the corresponding command classes, and registers them with the Discord API.
*
* @param {string} dir - The directory path where the command files are located.
* @returns {Promise<void>} A Promise that resolves when all the commands have been loaded and registered.
@ -126,43 +124,119 @@ 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)).filter(async path => (await fs.lstat(path)).isDirectory());
folders = (await fs.readdir(filePath)).map(file => path.join(filePath, file));
const commands = [];
for (let index = 0; index < folders.length; index++) {
const folder = folders[index];
if (folder.endsWith("!DISABLED")) continue;
for (const folder of folders) {
const files = await fs.readdir(folder);
for (let index = 0; index < files.length; index++) {
const file = files[index];
for (const file of files) {
if (!file.endsWith(".js")) continue;
if (file.endsWith(".js")) {
const Command = require(path.join(folder, file));
const Command = require(path.join(folder, file));
if (Command.prototype instanceof BaseCommand) {
const command = new Command(this);
this.commands.set(command.command.name, command);
if (!(Command.prototype instanceof BaseCommand)) continue;
if (command.onLoad && typeof command.onLoad === "function") await command.onLoad(this);
const command = new Command(this);
this.commands.set(command.command.name, command);
commands.push(command.command instanceof SlashCommandBuilder || command.command instanceof ContextMenuCommandBuilder ? command.command.toJSON() : command.command);
if (typeof command.onLoad === "function") await command.onLoad(this);
this.logger.log(`Successfully loaded "${file}" command file. (Command: ${command.command.name})`);
}
}
commands.push(command.command instanceof SlashCommandBuilder || command.command instanceof ContextMenuCommandBuilder ? command.command.toJSON() : command.command);
this.logger.log(`Successfully loaded "${file}" command. (Command: ${command.command.name})`);
}
}
try {
if (this.config.production) await rest.put(Routes.applicationCommands(this.config.userId), { body: commands });
else await rest.put(Routes.applicationGuildCommands(this.config.userId, this.config.support.id), { body: commands });
const route = this.config.production ? Routes.applicationCommands(this.config.userId) : Routes.applicationGuildCommands(this.config.userId, this.config.support.id);
await rest.put(route, { body: commands });
this.logger.log("Successfully registered application commands.");
} catch (err) {
console.log(err);
this.logger.error("Error registering application commands:", err);
}
}
/**
* Loads a command from the specified directory and file.
* @param {string} dir - The directory containing the command file.
* @param {string} file - The name of the command file (without the .js extension).
* @returns {Promise<void>} This method does not return a value.
*/
async loadCommand(dir, file) {
try {
const Command = require(path.join(dir, `${file}.js`));
if (!(Command.prototype instanceof BaseCommand)) {
return this.logger.error(`Tried to load a non-command file: "${file}.js"`);
}
const command = new Command(this);
this.commands.set(command.command.name, command);
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);
}
}
/**
* Unloads a command from the specified directory and file.
* @param {string} dir - The directory containing the command file.
* @param {string} name - The name of the command file (without the .js extension).
* @returns {void} This method does not return a value.
*/
unloadCommand(dir, name) {
delete require.cache[require.resolve(`${dir}${path.sep}${name}.js`)];
return;
}
/**
* Loads all event files from the specified directory and its subdirectories.
* @param {string} dir - The directory containing the event files.
* @returns {Promise<void>} This method does not return a value.
*/
async loadEvents(dir) {
const filePath = path.join(__dirname, dir);
const files = await fs.readdir(filePath);
for (const file of files) {
const fullPath = path.join(filePath, file);
const stat = await fs.lstat(fullPath);
if (stat.isDirectory()) {
await this.loadEvents(path.join(dir, file));
continue;
}
if (file.endsWith(".js")) {
try {
const Event = require(fullPath);
if (!(Event.prototype instanceof BaseEvent)) {
this.logger.error(`"${file}" is not a valid event file.`);
continue;
}
const event = new Event();
if (!event.name || !event.name.length) {
this.logger.error(`Cannot load "${file}" event: Event name is missing!`);
continue;
}
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);
}
}
}
}
@ -196,37 +270,24 @@ class JaBaClient extends Client {
* @param {Object[]} [data.fields] - An array of field objects for the embed.
* @param {string} [data.image] - The URL of the image for the embed.
* @param {string} [data.url] - The URL to be used as the embed's hyperlink.
* @param {string} [data.color] - The HEX color of the embed's border. If not provided, the default color from the client's configuration will be used.
* @param {string} [data.footer] - The text to be displayed as the embed's footer. If not provided, the default footer from the client's configuration will be used.
* @param {Date} [data.timestamp] - The timestamp to be displayed in the embed's footer. If not provided, the current timestamp will be used.
* @param {string|Object} [data.author] - The author information for the embed. Can be a string (name) or an object with `name` and/or `iconURL` properties.
* @param {string} [data.color] - The HEX color of the embed's border.
* @param {string|Object} [data.footer] - The text to be displayed as the embed's footer.
* @param {Date} [data.timestamp] - The timestamp to be displayed in the embed.
* @param {string|Object} [data.author] - The author information for the embed.
* @returns {EmbedBuilder} The generated EmbedBuilder instance.
*/
embed(data) {
const embed = new EmbedBuilder()
.setTitle(data.title || null)
.setDescription(data.description || null)
.setThumbnail(data.thumbnail || null)
.addFields(data.fields || [])
.setImage(data.image || null)
.setURL(data.url || null);
if (data.color) embed.setColor(data.color);
else if (data.color === null) embed.setColor(null);
else embed.setColor(this.config.embed.color);
if (data.footer) embed.setFooter(data.footer);
else if (data.footer === null) embed.setFooter(null);
else embed.setFooter(this.config.embed.footer);
if (data.timestamp) embed.setTimestamp(data.timestamp);
else if (data.timestamp === null) embed.setTimestamp(null);
else embed.setTimestamp();
if (!data.author || data.author === null) embed.setAuthor(null);
else if (typeof data.author === "string") embed.setAuthor({ name: data.author, iconURL: this.user.avatarURL() });
else if (typeof data.author === "object" && (data.author.iconURL !== null || data.author.iconURL !== undefined)) embed.setAuthor({ name: data.author.name, iconURL: data.author.iconURL });
else embed.setAuthor(data.author);
.setTitle(data.title ?? null)
.setDescription(data.description ?? null)
.setThumbnail(data.thumbnail ?? null)
.addFields(data.fields ?? [])
.setImage(data.image ?? null)
.setURL(data.url ?? null)
.setColor(data.color ?? this.config.embed.color)
.setFooter(typeof data.footer === "object" ? data.footer : data.footer ? { text: data.footer } : this.config.embed.footer)
.setTimestamp(data.timestamp ?? null)
.setAuthor(typeof data.author === "string" ? { name: data.author, iconURL: this.user.avatarURL() } : data.author ?? null);
return embed;
}
@ -244,86 +305,22 @@ class JaBaClient extends Client {
if (channel) return (await channel.createInvite()).url || "No channels found or missing permissions";
}
/**
* Loads a command from the specified directory and file.
* @param {string} dir - The directory containing the command file.
* @param {string} file - The name of the command file (without the .js extension).
* @returns {Promise<string>} A log message indicating the successful loading of the command.
*/
async loadCommand(dir, file) {
const Command = require(path.join(dir, `${file}.js`));
if (!(Command.prototype instanceof BaseCommand)) return this.logger.error("Tried to load a non-command file!");
const command = new Command(this);
this.commands.set(command.command.name, command);
if (command.onLoad && typeof command.onLoad === "function") await command.onLoad(this);
return this.logger.log(`Successfully loaded "${file}" command file. (Command: ${command.command.name})`);
}
/**
* Unloads a command from the specified directory and file.
* @param {string} dir - The directory containing the command file.
* @param {string} name - The name of the command file (without the .js extension).
* @returns {void} This method does not return a value.
*/
async unloadCommand(dir, name) {
delete require.cache[require.resolve(`${dir}${path.sep}${name}.js`)];
return;
}
/**
* Loads all event files from the specified directory and its subdirectories.
* @param {string} dir - The directory containing the event files.
* @returns {void} This method does not return a value.
*/
async loadEvents(dir) {
const filePath = path.join(__dirname, dir);
const files = await fs.readdir(filePath);
for (let index = 0; index < files.length; index++) {
const file = files[index];
const stat = await fs.lstat(path.join(filePath, file));
if (stat.isDirectory()) this.loadEvents(path.join(dir, file));
if (file.endsWith(".js")) {
const Event = require(path.join(filePath, file));
if (Event.prototype instanceof BaseEvent) {
const event = new Event();
if (!event.name || !event.name.length) return console.error(`Cannot load "${file}" event file: Event name is not set!`);
if (event.once) this.once(event.name, event.execute.bind(event, this));
else this.on(event.name, event.execute.bind(event, this));
this.logger.log(`Successfully loaded "${file}" event file. (Event: ${event.name})`);
}
}
}
}
/**
* Returns a User data from the database.
* @param {string} userID - The ID of the user to find or create.
* @returns {Promise<import("./User")>} The user data object, either retrieved from the database or newly created.
*/
*/
async getUserData(userID) {
let userData = await this.usersData.findOne({ id: userID });
if (userData) {
this.databaseCache.users.set(userID, userData);
return userData;
} else {
if (!userData) {
userData = new this.usersData({ id: userID });
await userData.save();
this.databaseCache.users.set(userID, userData);
return userData;
}
this.databaseCache.users.set(userID, userData);
return userData;
}
/**
@ -335,27 +332,19 @@ class JaBaClient extends Client {
async getMemberData(memberId, guildId) {
let memberData = await this.membersData.findOne({ guildID: guildId, id: memberId });
if (memberData) {
this.databaseCache.members.set(`${memberId}${guildId}`, memberData);
return memberData;
} else {
if (!memberData) {
memberData = new this.membersData({ id: memberId, guildID: guildId });
await memberData.save();
const guildData = await this.getGuildData(guildId);
if (guildData) {
guildData.members.push(memberData._id);
await guildData.save();
}
this.databaseCache.members.set(`${memberId}/${guildId}`, memberData);
return memberData;
}
this.databaseCache.members.set(`${memberId}/${guildId}`, memberData);
return memberData;
}
/**
@ -366,19 +355,14 @@ class JaBaClient extends Client {
async getGuildData(guildId) {
let guildData = await this.guildsData.findOne({ id: guildId }).populate("members");
if (guildData) {
this.databaseCache.guilds.set(guildId, guildData);
return guildData;
} else {
if (!guildData) {
guildData = new this.guildsData({ id: guildId });
await guildData.save();
this.databaseCache.guilds.set(guildId, guildData);
return guildData;
}
this.databaseCache.guilds.set(guildId, guildData);
return guildData;
}
}

View file

@ -1,73 +0,0 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Ban extends BaseCommand {
/**
*
* @param {import("../../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("ban")
.setDescription(client.translate("moderation/ban:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("moderation/ban:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/ban:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setDefaultMemberPermissions(PermissionsBitField.Flags.BanMembers)
.addUserOption(option =>
option
.setName("user")
.setDescription(client.translate("common:USER"))
.setDescriptionLocalizations({
uk: client.translate("common:USER", null, "uk-UA"),
ru: client.translate("common:USER", null, "ru-RU"),
})
.setRequired(true),
)
.addStringOption(option =>
option
.setName("reason")
.setDescription(client.translate("common:REASON"))
.setDescriptionLocalizations({
uk: client.translate("common:REASON", null, "uk-UA"),
ru: client.translate("common:REASON", null, "ru-RU"),
})
.setRequired(true),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
const member = interaction.options.getMember("user"),
reason = interaction.options.getString("reason"),
memberPosition = member.roles.highest.position,
moderationPosition = interaction.member.roles.highest.position;
if (member.user.bot) return interaction.error("misc:BOT_USER", null, { ephemeral: true, edit: true });
if (member.id === interaction.member.id) return interaction.error("moderation/ban:YOURSELF", null, { ephemeral: true, edit: true });
if (interaction.guild.ownerId !== interaction.member.id && !(moderationPosition > memberPosition) && member.bannable) return interaction.error("moderation/ban:SUPERIOR", null, { ephemeral: true, edit: true });
await member.ban({
reason,
});
interaction.success("moderation/ban:SUCCESS", {
user: member.user.toString(),
reason,
}, { edit: true });
}
}
module.exports = Ban;

View file

@ -1,49 +0,0 @@
const { SlashCommandBuilder } = require("discord.js"),
Mee6Api = require("../../helpers/mee6-api");
const BaseCommand = require("../../base/BaseCommand");
class ImportMee6 extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("importmee6")
.setDescription(client.translate("economy/importmee6:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("economy/importmee6:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/importmee6:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
const level = (await Mee6Api.getUserXp(interaction.guildId, interaction.member)).level;
interaction.data.member.level = level;
interaction.data.member.exp = 0;
await interaction.data.member.save();
interaction.editReply({
content: interaction.translate("owner/debug:SUCCESS_LEVEL", {
user: interaction.member.toString(),
amount: level,
}),
});
}
}
module.exports = ImportMee6;

View file

@ -1,73 +0,0 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Kick extends BaseCommand {
/**
*
* @param {import("../../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("kick")
.setDescription(client.translate("moderation/kick:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("moderation/kick:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/kick:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setDefaultMemberPermissions(PermissionsBitField.Flags.KickMembers)
.addUserOption(option =>
option
.setName("user")
.setDescription(client.translate("common:USER"))
.setDescriptionLocalizations({
uk: client.translate("common:USER", null, "uk-UA"),
ru: client.translate("common:USER", null, "ru-RU"),
})
.setRequired(true),
)
.addStringOption(option =>
option
.setName("reason")
.setDescription(client.translate("common:REASON"))
.setDescriptionLocalizations({
uk: client.translate("common:REASON", null, "uk-UA"),
ru: client.translate("common:REASON", null, "ru-RU"),
})
.setRequired(true),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
const member = interaction.options.getMember("user"),
reason = interaction.options.getString("reason"),
memberPosition = member.roles.highest.position,
moderationPosition = interaction.member.roles.highest.position;
if (member.user.bot) return interaction.error("misc:BOT_USER", null, { ephemeral: true, edit: true });
if (member.id === interaction.member.id) return interaction.error("moderation/kick:YOURSELF", null, { ephemeral: true, edit: true });
if (interaction.guild.ownerId !== interaction.member.id && !(moderationPosition > memberPosition) && member.kickable) return interaction.error("moderation/kick:SUPERIOR", null, { ephemeral: true, edit: true });
await member.kick({
reason,
});
interaction.success("moderation/kick:SUCCESS", {
user: member.user.toString(),
reason,
}, { edit: true });
}
}
module.exports = Kick;

View file

@ -1,79 +0,0 @@
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
class Memes extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("memes")
.setDescription(client.translate("fun/memes:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("fun/memes:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/memes:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
*/
async onLoad(client) {
client.on("interactionCreate", async interaction => {
if (!interaction.isStringSelectMenu()) return;
if (interaction.customId === "memes_select") {
interaction.deferUpdate();
interaction.guild.data = await client.getGuildData(interaction.guildId);
const tag = interaction.values[0];
const res = await fetch(`https://meme-api.com/gimme/${tag}`).then(response => response.json());
const embed = client.embed({
title: res.title,
description: `${interaction.translate("fun/memes:SUBREDDIT")}: **${res.subreddit}**\n${interaction.translate("common:AUTHOR")}: **${res.author}**\n${interaction.translate("fun/memes:UPS")}: **${res.ups}**`,
image: res.url,
});
await interaction.editReply({
embeds: [embed],
});
}
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
const tags = ["funny", "memes", "dankmemes", "me_irl", "wholesomememes"].map(tag =>
JSON.parse(
JSON.stringify({
label: tag,
value: tag,
}),
),
);
const row = new ActionRowBuilder().addComponents(new StringSelectMenuBuilder().setCustomId("memes_select").setPlaceholder(interaction.translate("common:NOTHING_SELECTED")).addOptions(tags));
await interaction.editReply({
components: [row],
});
}
}
module.exports = Memes;

View file

@ -1,63 +0,0 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Staff extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("staff")
.setDescription(client.translate("general/staff:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("general/staff:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/staff:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.guild.members.fetch();
const administrators = interaction.guild.members.cache.filter(m => m.permissions.has(PermissionsBitField.Flags.Administrator) && !m.user.bot);
const moderators = interaction.guild.members.cache.filter(m => !administrators.has(m.id) && m.permissions.has(PermissionsBitField.Flags.ManageMessages) && !m.user.bot);
const embed = client.embed({
author: {
name: interaction.translate("general/staff:TITLE", {
guild: interaction.guild.name,
}),
iconURL: interaction.guild.iconURL(),
},
fields: [
{
name: interaction.translate("general/staff:ADMINS"),
value:
administrators.size > 0
? administrators.map(a => `${a.presence ? client.customEmojis.status[a.presence.status] : client.customEmojis.status.offline} | <@${a.user.id}>`).join("\n")
: interaction.translate("general/staff:NO_ADMINS"),
},
{
name: interaction.translate("general/staff:MODS"),
value: moderators.size > 0 ? moderators.map(m => `${m.presence ? client.customEmojis.status[m.presence.status] : client.customEmojis.status.offline} | <@${m.user.id}>`).join("\n") : interaction.translate("general/staff:NO_MODS"),
},
],
});
interaction.reply({
embeds: [embed],
});
}
}
module.exports = Staff;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Addemoji extends BaseCommand {
@ -15,7 +15,8 @@ class Addemoji extends BaseCommand {
uk: client.translate("administration/addemoji:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/addemoji:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addStringOption(option =>
option
@ -58,7 +59,7 @@ class Addemoji extends BaseCommand {
})
.then(emoji =>
interaction.success("administration/stealemoji:SUCCESS", {
emoji: emoji.name,
emoji: emoji.toString(),
}, { ephemeral: true }),
)
.catch(e => {

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField, ChannelType } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, ChannelType, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Automod extends BaseCommand {
@ -15,7 +15,8 @@ class Automod extends BaseCommand {
uk: client.translate("administration/automod:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/automod:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addSubcommand(subcommand =>
subcommand

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Autorole extends BaseCommand {
@ -15,7 +15,8 @@ class Autorole extends BaseCommand {
uk: client.translate("administration/autorole:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/autorole:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addBooleanOption(option =>
option

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField, ChannelType } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, ChannelType, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Config extends BaseCommand {
@ -15,7 +15,8 @@ class Config extends BaseCommand {
uk: client.translate("administration/config:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/config:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addSubcommand(subcommand =>
subcommand

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Goodbye extends BaseCommand {
@ -15,7 +15,8 @@ class Goodbye extends BaseCommand {
uk: client.translate("administration/goodbye:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/goodbye:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addSubcommand(subcommand =>
subcommand
@ -26,42 +27,43 @@ class Goodbye extends BaseCommand {
ru: client.translate("administration/goodbye:TEST", null, "ru-RU"),
}),
)
.addSubcommand(subcommand =>
subcommand
.setName("config")
.setDescription(client.translate("administration/goodbye:CONFIG"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:CONFIG", null, "uk-UA"),
ru: client.translate("administration/goodbye:CONFIG", null, "ru-RU"),
})
.addBooleanOption(option =>
option
.setName("state")
.setDescription(client.translate("common:STATE"))
.setDescriptionLocalizations({
uk: client.translate("common:STATE", null, "uk-UA"),
ru: client.translate("common:STATE", null, "ru-RU"),
})
.setRequired(true),
)
.addChannelOption(option =>
option
.setName("channel")
.setDescription(client.translate("common:CHANNEL"))
.setDescriptionLocalizations({
uk: client.translate("common:CHANNEL", null, "uk-UA"),
ru: client.translate("common:CHANNEL", null, "ru-RU"),
}),
)
.addStringOption(option =>
option
.setName("message")
.setDescription(client.translate("administration/goodbye:MESSAGE"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:MESSAGE", null, "uk-UA"),
ru: client.translate("administration/goodbye:MESSAGE", null, "ru-RU"),
}),
),
.addSubcommand(
subcommand =>
subcommand
.setName("config")
.setDescription(client.translate("administration/goodbye:CONFIG"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:CONFIG", null, "uk-UA"),
ru: client.translate("administration/goodbye:CONFIG", null, "ru-RU"),
})
.addBooleanOption(option =>
option
.setName("state")
.setDescription(client.translate("common:STATE"))
.setDescriptionLocalizations({
uk: client.translate("common:STATE", null, "uk-UA"),
ru: client.translate("common:STATE", null, "ru-RU"),
})
.setRequired(true),
)
.addChannelOption(option =>
option
.setName("channel")
.setDescription(client.translate("common:CHANNEL"))
.setDescriptionLocalizations({
uk: client.translate("common:CHANNEL", null, "uk-UA"),
ru: client.translate("common:CHANNEL", null, "ru-RU"),
}),
)
.addStringOption(option =>
option
.setName("message")
.setDescription(client.translate("administration/goodbye:MESSAGE"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:MESSAGE", null, "uk-UA"),
ru: client.translate("administration/goodbye:MESSAGE", null, "ru-RU"),
}),
),
// .addBooleanOption(option =>
// option
// .setName("image")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField, ActionRowBuilder, StringSelectMenuBuilder } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, ActionRowBuilder, StringSelectMenuBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Selectroles extends BaseCommand {
@ -15,7 +15,8 @@ class Selectroles extends BaseCommand {
uk: client.translate("administration/selectroles:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/selectroles:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addSubcommand(subcommand =>
subcommand

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Set extends BaseCommand {
@ -15,7 +15,8 @@ class Set extends BaseCommand {
uk: client.translate("administration/set:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/set:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addStringOption(option =>
option

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Setlang extends BaseCommand {
@ -15,7 +15,8 @@ class Setlang extends BaseCommand {
uk: client.translate("administration/setlang:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/setlang:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addStringOption(option =>
option

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, parseEmoji, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, parseEmoji, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Stealemoji extends BaseCommand {
@ -15,7 +15,8 @@ class Stealemoji extends BaseCommand {
uk: client.translate("administration/stealemoji:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/stealemoji:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addStringOption(option =>
option
@ -47,7 +48,7 @@ class Stealemoji extends BaseCommand {
})
.then(emoji =>
interaction.success("administration/stealemoji:SUCCESS", {
emoji: emoji.name,
emoji: emoji.toString(),
}, { ephemeral: true }),
)
.catch(e => {

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Welcome extends BaseCommand {
@ -15,7 +15,8 @@ class Welcome extends BaseCommand {
uk: client.translate("administration/welcome:DESCRIPTION", null, "uk-UA"),
ru: client.translate("administration/welcome:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild)
.addSubcommand(subcommand =>
subcommand
@ -26,42 +27,43 @@ class Welcome extends BaseCommand {
ru: client.translate("administration/goodbye:TEST", null, "ru-RU"),
}),
)
.addSubcommand(subcommand =>
subcommand
.setName("config")
.setDescription(client.translate("administration/goodbye:CONFIG"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:CONFIG", null, "uk-UA"),
ru: client.translate("administration/goodbye:CONFIG", null, "ru-RU"),
})
.addBooleanOption(option =>
option
.setName("state")
.setDescription(client.translate("common:STATE"))
.setDescriptionLocalizations({
uk: client.translate("common:STATE", null, "uk-UA"),
ru: client.translate("common:STATE", null, "ru-RU"),
})
.setRequired(true),
)
.addChannelOption(option =>
option
.setName("channel")
.setDescription(client.translate("common:CHANNEL"))
.setDescriptionLocalizations({
uk: client.translate("common:CHANNEL", null, "uk-UA"),
ru: client.translate("common:CHANNEL", null, "ru-RU"),
}),
)
.addStringOption(option =>
option
.setName("message")
.setDescription(client.translate("administration/goodbye:MESSAGE"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:MESSAGE", null, "uk-UA"),
ru: client.translate("administration/goodbye:MESSAGE", null, "ru-RU"),
}),
),
.addSubcommand(
subcommand =>
subcommand
.setName("config")
.setDescription(client.translate("administration/goodbye:CONFIG"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:CONFIG", null, "uk-UA"),
ru: client.translate("administration/goodbye:CONFIG", null, "ru-RU"),
})
.addBooleanOption(option =>
option
.setName("state")
.setDescription(client.translate("common:STATE"))
.setDescriptionLocalizations({
uk: client.translate("common:STATE", null, "uk-UA"),
ru: client.translate("common:STATE", null, "ru-RU"),
})
.setRequired(true),
)
.addChannelOption(option =>
option
.setName("channel")
.setDescription(client.translate("common:CHANNEL"))
.setDescriptionLocalizations({
uk: client.translate("common:CHANNEL", null, "uk-UA"),
ru: client.translate("common:CHANNEL", null, "ru-RU"),
}),
)
.addStringOption(option =>
option
.setName("message")
.setDescription(client.translate("administration/goodbye:MESSAGE"))
.setDescriptionLocalizations({
uk: client.translate("administration/goodbye:MESSAGE", null, "uk-UA"),
ru: client.translate("administration/goodbye:MESSAGE", null, "ru-RU"),
}),
),
// .addBooleanOption(option =>
// option
// .setName("image")

100
commands/Beatrun/courses.js Normal file
View file

@ -0,0 +1,100 @@
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
class Courses extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("courses")
.setDescription(client.translate("beatrun/courses:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("beatrun/courses:DESCRIPTION", null, "uk-UA"),
ru: client.translate("beatrun/courses:DESCRIPTION", null, "ru-RU"),
})
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.Guild, InteractionContextType.BotDM, InteractionContextType.PrivateChannel])
.addStringOption(option =>
option
.setName("code")
.setDescription(client.translate("common:CODE"))
.setDescriptionLocalizations({
uk: client.translate("common:CODE", null, "uk-UA"),
ru: client.translate("common:CODE", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Object} data
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const code = interaction.options.getString("code");
const response = await fetch(`https://courses.jonnybro.ru/api/info/${code}`).then(res => res.json()),
{ data } = response;
if (response.res === 401) return interaction.error("beatrun/courses:NOT_FOUND", null, { ephemeral: true, edit: true });
const embed = client.embed({
title: data.name,
description: `[${interaction.translate("beatrun/courses:DOWNLOAD")}](https://courses.jonnybro.ru/${data.path})`,
thumbnail: data.mapimg,
url: `https://courses.jonnybro.ru/?search=${code}`,
fields: [
{
name: interaction.translate("beatrun/courses:MAP"),
value: `[${data.map}](https://steamcommunity.com/sharedfiles/filedetails/?id=${data.mapid})`,
inline: true,
},
{
name: interaction.translate("beatrun/courses:UPLOADER"),
value: `[${data.uploader.name || data.uploader.userid}](https://steamcommunity.com/profiles/${data.uploader.userid})`,
inline: true,
},
{
name: "\u200B",
value: "\u200B",
inline: true,
},
{
name: interaction.translate("beatrun/courses:DATE"),
value: `<t:${Math.floor(data.time / 1000)}:D>`,
inline: true,
},
{
name: interaction.translate("beatrun/courses:PLAYS"),
value: `${data.plays || 0}`,
inline: true,
},
],
});
interaction.editReply({
embeds: [embed],
});
}
}
module.exports = Courses;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Achievements extends BaseCommand {
@ -15,7 +15,8 @@ class Achievements extends BaseCommand {
uk: client.translate("economy/achievements:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/achievements:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Bank extends BaseCommand {
@ -15,7 +15,8 @@ class Bank extends BaseCommand {
uk: client.translate("economy/bank:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/bank:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("option")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Birthdate extends BaseCommand {
@ -15,7 +15,8 @@ class Birthdate extends BaseCommand {
uk: client.translate("economy/birthdate:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/birthdate:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.Guild, InteractionContextType.PrivateChannel])
.addIntegerOption(option =>
option
.setName("day")
@ -23,8 +24,7 @@ class Birthdate extends BaseCommand {
.setDescriptionLocalizations({
uk: client.translate("economy/birthdate:DAY", null, "uk-UA"),
ru: client.translate("economy/birthdate:DAY", null, "ru-RU"),
})
.setRequired(true),
}),
)
.addIntegerOption(option =>
option
@ -34,20 +34,19 @@ class Birthdate extends BaseCommand {
uk: client.translate("economy/birthdate:MONTH", null, "uk-UA"),
ru: client.translate("economy/birthdate:MONTH", null, "ru-RU"),
})
.setRequired(true)
.setChoices(
{ name: client.translate("economy/birthdate:JANUARY"), value: 1 },
{ name: client.translate("economy/birthdate:FEBRUARY"), value: 2 },
{ name: client.translate("economy/birthdate:MARCH"), value: 3 },
{ name: client.translate("economy/birthdate:APRIL"), value: 4 },
{ name: client.translate("economy/birthdate:MAY"), value: 5 },
{ name: client.translate("economy/birthdate:JUNE"), value: 6 },
{ name: client.translate("economy/birthdate:JULY"), value: 7 },
{ name: client.translate("economy/birthdate:AUGUST"), value: 8 },
{ name: client.translate("economy/birthdate:SEPTEMBER"), value: 9 },
{ name: client.translate("economy/birthdate:OCTOBER"), value: 10 },
{ name: client.translate("economy/birthdate:NOVEMBER"), value: 11 },
{ name: client.translate("economy/birthdate:DECEMBER"), value: 12 },
{ name: client.translate("misc:MONTHS:JANUARY"), value: 1 },
{ name: client.translate("misc:MONTHS:FEBRUARY"), value: 2 },
{ name: client.translate("misc:MONTHS:MARCH"), value: 3 },
{ name: client.translate("misc:MONTHS:APRIL"), value: 4 },
{ name: client.translate("misc:MONTHS:MAY"), value: 5 },
{ name: client.translate("misc:MONTHS:JUNE"), value: 6 },
{ name: client.translate("misc:MONTHS:JULY"), value: 7 },
{ name: client.translate("misc:MONTHS:AUGUST"), value: 8 },
{ name: client.translate("misc:MONTHS:SEPTEMBER"), value: 9 },
{ name: client.translate("misc:MONTHS:OCTOBER"), value: 10 },
{ name: client.translate("misc:MONTHS:NOVEMBER"), value: 11 },
{ name: client.translate("misc:MONTHS:DECEMBER"), value: 12 },
),
)
.addIntegerOption(option =>
@ -57,8 +56,25 @@ class Birthdate extends BaseCommand {
.setDescriptionLocalizations({
uk: client.translate("economy/birthdate:YEAR", null, "uk-UA"),
ru: client.translate("economy/birthdate:YEAR", null, "ru-RU"),
})
.setRequired(true),
}),
)
.addBooleanOption(option =>
option
.setName("clear")
.setDescription(client.translate("economy/birthdate:CLEAR"))
.setDescriptionLocalizations({
uk: client.translate("economy/birthdate:CLEAR", null, "uk-UA"),
ru: client.translate("economy/birthdate:CLEAR", null, "ru-RU"),
}),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -71,8 +87,20 @@ class Birthdate extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
const userData = interaction.data.user,
day = interaction.options.getInteger("day"),
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const userData = interaction.data.user;
if (interaction.options.getBoolean("clear")) {
userData.birthdate = null;
await userData.save();
return interaction.success("economy/birthdate:SUCCESS", {
date: "none",
}, { edit: true });
}
const day = interaction.options.getInteger("day"),
month = interaction.options.getInteger("month"),
year = interaction.options.getInteger("year"),
date = new Date(year, month - 1, day);
@ -81,9 +109,9 @@ class Birthdate extends BaseCommand {
const d = Math.floor(date.getTime() / 1000);
if (!(day == date.getDate() && month - 1 == date.getMonth() && year == date.getFullYear())) return interaction.error("economy/birthdate:INVALID_DATE");
if (date.getTime() > Date.now()) return interaction.error("economy/birthdate:DATE_TOO_HIGH");
if (date.getTime() < Date.now() - 2.523e12) return interaction.error("economy/birthdate:DATE_TOO_LOW");
if (!(day == date.getDate() && month - 1 == date.getMonth() && year == date.getFullYear())) return interaction.error("economy/birthdate:INVALID_DATE", null, { edit: true });
if (date.getTime() > Date.now()) return interaction.error("economy/birthdate:DATE_TOO_HIGH", null, { edit: true });
if (date.getTime() < Date.now() - 2.523e12) return interaction.error("economy/birthdate:DATE_TOO_LOW", null, { edit: true });
userData.birthdate = d;
@ -91,7 +119,7 @@ class Birthdate extends BaseCommand {
interaction.success("economy/birthdate:SUCCESS", {
date: `<t:${d}:D>`,
});
}, { edit: true });
}
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Divorce extends BaseCommand {
@ -15,7 +15,8 @@ class Divorce extends BaseCommand {
uk: client.translate("economy/divorce:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/divorce:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Leaderboard extends BaseCommand {
@ -15,7 +15,8 @@ class Leaderboard extends BaseCommand {
uk: client.translate("economy/leaderboard:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/leaderboard:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("type")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
pendings = {};
@ -16,7 +16,8 @@ class Marry extends BaseCommand {
uk: client.translate("economy/marry:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/marry:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -44,7 +45,7 @@ class Marry extends BaseCommand {
const member = interaction.options.getMember("user");
if (member.user.bot) return interaction.error("economy/marry:BOT_USER");
if (member.id === interaction.member.id) return interaction.error("economy/marry:YOURSELF");
if (member.id === interaction.member.id) return interaction.error("misc:CANT_YOURSELF");
const otherUserData = await client.getUserData(member.id);
if (otherUserData.lover) return interaction.error("economy/marry:ALREADY_MARRIED_USER", { user: member.toString() });

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Money extends BaseCommand {
@ -15,7 +15,8 @@ class Money extends BaseCommand {
uk: client.translate("economy/money:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/money:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -39,10 +40,9 @@ class Money extends BaseCommand {
await interaction.deferReply();
const member = interaction.options.getMember("user") || interaction.member;
if (member.user.bot) return interaction.error("economy/money:BOT_USER");
if (member.user.bot) return interaction.error("economy/money:BOT_USER", null, { edit: true });
const memberData = member.id === interaction.user.id ? interaction.data.member : await client.getMemberData(member.id, interaction.guildId);
const guilds = client.guilds.cache.filter(g => g.members.cache.find(m => m.id === member.id));
let globalMoney = 0;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Pay extends BaseCommand {
@ -15,7 +15,8 @@ class Pay extends BaseCommand {
uk: client.translate("economy/pay:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/pay:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -50,7 +51,7 @@ class Pay extends BaseCommand {
const memberData = interaction.data.member,
otherMember = interaction.options.getMember("user");
if (otherMember.user.bot) return interaction.error("economy/pay:BOT_USER");
if (otherMember.id === interaction.member.id) return interaction.error("economy/pay:YOURSELF");
if (otherMember.id === interaction.member.id) return interaction.error("misc:CANT_YOURSELF");
const amount = interaction.options.getInteger("amount");
if (amount <= 0) return interaction.error("misc:MORE_THAN_ZERO");

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Profile extends BaseCommand {
@ -15,7 +15,8 @@ class Profile extends BaseCommand {
uk: client.translate("economy/profile:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/profile:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Rep extends BaseCommand {
@ -15,7 +15,8 @@ class Rep extends BaseCommand {
uk: client.translate("economy/rep:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/rep:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -49,7 +50,7 @@ class Rep extends BaseCommand {
const user = interaction.options.getUser("user");
if (user.bot) return interaction.error("economy/rep:BOT_USER");
if (user.id === interaction.user.id) return interaction.error("economy/rep:YOURSELF");
if (user.id === interaction.user.id) return interaction.error("misc:CANT_YOURSELF");
const toWait = Math.floor((Date.now() + 12 * 60 * 60 * 1000) / 1000); // 12 hours
if (!userData.cooldowns) userData.cooldowns = {};

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Rob extends BaseCommand {
@ -15,7 +15,8 @@ class Rob extends BaseCommand {
uk: client.translate("economy/rob:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/rob:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -50,7 +51,7 @@ class Rob extends BaseCommand {
const memberData = interaction.data.member,
otherMember = interaction.options.getMember("user");
if (otherMember.user.bot) return interaction.error("economy/pay:BOT_USER");
if (otherMember.id === interaction.member.id) return interaction.error("economy/rob:YOURSELF");
if (otherMember.id === interaction.member.id) return interaction.error("misc:CANT_YOURSELF");
const amount = interaction.options.getInteger("amount");
if (amount <= 0) return interaction.error("misc:MORE_THAN_ZERO");

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType, escapeEscape, escapeCodeBlock, escapeInlineCode } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Setbio extends BaseCommand {
@ -15,7 +15,8 @@ class Setbio extends BaseCommand {
uk: client.translate("economy/setbio:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/setbio:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("text")
@ -25,6 +26,15 @@ class Setbio extends BaseCommand {
ru: client.translate("economy/profile:BIO", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -37,15 +47,17 @@ class Setbio extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const userData = interaction.data.user,
newBio = interaction.options.getString("text");
if (newBio.length > 150) return interaction.error("economy/setbio:MAX_CHARACTERS");
if (newBio.length > 150) return interaction.error("misc:MAX_150_CHARS", null, { edit: true });
userData.bio = newBio;
userData.bio = escapeEscape(escapeCodeBlock(escapeInlineCode(newBio))).replace("@", "@\u200b");
await userData.save();
interaction.success("economy/setbio:SUCCESS");
interaction.success("economy/setbio:SUCCESS", null, { edit: true });
}
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Slots extends BaseCommand {
@ -15,7 +15,8 @@ class Slots extends BaseCommand {
uk: client.translate("economy/slots:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/slots:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addIntegerOption(option =>
option
.setName("amount")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Transactions extends BaseCommand {
@ -15,7 +15,8 @@ class Transactions extends BaseCommand {
uk: client.translate("economy/transactions:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/transactions:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addBooleanOption(option =>
option
.setName("clear")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, parseEmoji } = require("discord.js");
const { SlashCommandBuilder, parseEmoji, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Work extends BaseCommand {
@ -15,7 +15,8 @@ class Work extends BaseCommand {
uk: client.translate("economy/work:DESCRIPTION", null, "uk-UA"),
ru: client.translate("economy/work:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Eightball extends BaseCommand {
@ -15,7 +15,8 @@ class Eightball extends BaseCommand {
uk: client.translate("fun/8ball:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/8ball:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("question")
@ -25,6 +26,15 @@ class Eightball extends BaseCommand {
ru: client.translate("fun/8ball:QUESTION", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -37,7 +47,7 @@ class Eightball extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const question = interaction.options.getString("question");
const embed = client.embed({

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
@ -16,7 +16,17 @@ class Cat extends BaseCommand {
uk: client.translate("fun/cat:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/cat:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
@ -28,7 +38,7 @@ class Cat extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const res = await fetch("https://api.thecatapi.com/v1/images/search").then(r => r.json());
const cat = res[0].url;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
@ -16,7 +16,17 @@ class Dog extends BaseCommand {
uk: client.translate("fun/dog:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/dog:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
@ -28,7 +38,7 @@ class Dog extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const res = await fetch("https://dog.ceo/api/breeds/image/random").then(r => r.json());
const dog = res.message;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
@ -16,7 +16,8 @@ class LMGTFY extends BaseCommand {
uk: client.translate("fun/lmgtfy:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/lmgtfy:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("query")
@ -36,6 +37,15 @@ class LMGTFY extends BaseCommand {
ru: client.translate("fun/lmgtfy:SHORT", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -48,24 +58,24 @@ class LMGTFY extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const query = interaction.options.getString("query").replace(/[' '_]/g, "+"),
short = interaction.options.getBoolean("short"),
url = `https://letmegooglethat.com/?q=${encodeURIComponent(query)}`;
if (short) {
const res = await fetch("https://plsgo.ru/rest/v3/short-urls", {
const res = await fetch("https://i.jonnybro.ru/api/shorten", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Api-Key": client.config.apiKeys.shlink,
"Content-Type": "application/json",
Authorization: client.config.apiKeys.zipline,
},
body: new URLSearchParams({ longUrl: url }),
body: JSON.stringify({ url: url }),
}).then(res => res.json());
interaction.editReply({
content: `<${res.shortUrl}>`,
content: `<${res.url}>`,
});
} else {
interaction.editReply({

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
md5 = require("md5");
@ -16,7 +16,8 @@ class Lovecalc extends BaseCommand {
uk: client.translate("fun/lovecalc:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/lovecalc:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("first_member")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, MessageCollector, ButtonBuilder, ActionRowBuilder, ButtonStyle, ThreadAutoArchiveDuration } = require("discord.js");
const { SlashCommandBuilder, MessageCollector, ButtonBuilder, ActionRowBuilder, ButtonStyle, ThreadAutoArchiveDuration, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
currentGames = {};
@ -16,7 +16,8 @@ class Number extends BaseCommand {
uk: client.translate("fun/number:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/number:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
tictactoe = require("../../helpers/tictactoe");
@ -16,7 +16,8 @@ class TicTacToe extends BaseCommand {
uk: client.translate("fun/tictactoe:DESCRIPTION", null, "uk-UA"),
ru: client.translate("fun/tictactoe:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.Guild, InteractionContextType.PrivateChannel])
.addUserOption(option =>
option
.setName("user")
@ -38,26 +39,23 @@ class TicTacToe extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
tictactoe(interaction, {
const winner = await tictactoe(interaction, {
resultBtn: true,
embedColor: client.config.embed.color,
embedFoot: client.config.embed.footer,
}).then(async winner => {
const memberData = await client.getMemberData(winner.id, interaction.guildId);
memberData.money += 100;
const info = {
user: interaction.translate("economy/transactions:TTT"),
amount: 100,
date: Date.now(),
type: "got",
};
memberData.transactions.push(info);
await memberData.save();
});
const memberData = await client.getMemberData(winner.id, interaction.guildId);
memberData.money += 100;
const info = {
user: interaction.translate("economy/transactions:TTT"),
amount: 100,
date: Date.now(),
type: "got",
};
memberData.transactions.push(info);
await memberData.save();
}
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType, escapeEscape, escapeCodeBlock, escapeInlineCode } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Afk extends BaseCommand {
@ -15,7 +15,8 @@ class Afk extends BaseCommand {
uk: client.translate("general/afk:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/afk:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("message")
@ -25,6 +26,15 @@ class Afk extends BaseCommand {
ru: client.translate("common:MESSAGE", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -37,17 +47,19 @@ class Afk extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const userData = interaction.data.user,
reason = interaction.options.getString("message");
message = interaction.options.getString("message");
userData.afk = reason;
if (message.length > 150) return interaction.error("misc:MAX_150_CHARS", null, { edit: true });
userData.afk = escapeEscape(escapeCodeBlock(escapeInlineCode(message))).replace("@", "@\u200b");
await userData.save();
interaction.success("general/afk:SUCCESS", {
reason,
message,
}, { edit: true });
}
}

View file

@ -1,4 +1,4 @@
const { ContextMenuCommandBuilder, ApplicationCommandType } = require("discord.js");
const { ContextMenuCommandBuilder, ApplicationCommandType, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class AvatarContext extends BaseCommand {
@ -11,7 +11,8 @@ class AvatarContext extends BaseCommand {
command: new ContextMenuCommandBuilder()
.setName("Get Avatar")
.setType(ApplicationCommandType.User)
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Avatar extends BaseCommand {
@ -15,7 +15,8 @@ class Avatar extends BaseCommand {
uk: client.translate("general/avatar:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/avatar:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -33,6 +34,15 @@ class Avatar extends BaseCommand {
uk: client.translate("general/avatar:SERVER", null, "uk-UA"),
ru: client.translate("general/avatar:SERVER", null, "ru-RU"),
}),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -45,11 +55,13 @@ class Avatar extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
const member = interaction.options.getMember("user") || interaction.member;
const avatarURL = interaction.options.getBoolean("server") ? member.displayAvatarURL({ size: 2048 }) : member.user.displayAvatarURL({ size: 2048 });
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const user = interaction.options.getUser("user") || interaction.user;
const avatarURL = interaction.options.getBoolean("server") ? user.displayAvatarURL({ size: 2048 }) : user.avatarURL({ size: 2048 });
const embed = client.embed({ image: avatarURL });
interaction.reply({
interaction.editReply({
embeds: [embed],
});
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Boosters extends BaseCommand {
@ -15,7 +15,8 @@ class Boosters extends BaseCommand {
uk: client.translate("general/boosters:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/boosters:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, parseEmoji } = require("discord.js");
const { SlashCommandBuilder, parseEmoji, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Emoji extends BaseCommand {
@ -15,7 +15,8 @@ class Emoji extends BaseCommand {
uk: client.translate("general/emoji:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/emoji:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("emoji")
@ -25,6 +26,15 @@ class Emoji extends BaseCommand {
ru: client.translate("common:EMOJI", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -37,9 +47,10 @@ class Emoji extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const rawEmoji = interaction.options.getString("emoji");
const parsedEmoji = parseEmoji(rawEmoji);
const embed = client.embed({
author: {
name: interaction.translate("general/emoji:TITLE", {
@ -66,7 +77,7 @@ class Emoji extends BaseCommand {
],
});
interaction.reply({
interaction.editReply({
embeds: [embed],
});
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Help extends BaseCommand {
@ -15,7 +15,8 @@ class Help extends BaseCommand {
uk: client.translate("general/help:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/help:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("command")
@ -25,6 +26,15 @@ class Help extends BaseCommand {
ru: client.translate("common:COMMAND", null, "ru-RU"),
})
.setAutocomplete(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -80,7 +90,7 @@ class Help extends BaseCommand {
* @param {Object} data
*/
async execute(client, interaction) {
await interaction.deferReply();
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const commands = [...new Map(client.commands.map(v => [v.constructor.name, v])).values()];
const categories = [... new Set(commands.map(c => c.category))];

236
commands/General/info.js Normal file
View file

@ -0,0 +1,236 @@
const { SlashCommandBuilder, ChannelType, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Info extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("info")
.setDescription(client.translate("general/info:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("general/info:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/info:DESCRIPTION", null, "ru-RU"),
})
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addSubcommand(subcommand =>
subcommand
.setName("user")
.setDescription(client.translate("general/info:USER"))
.setDescriptionLocalizations({
uk: client.translate("general/info:USER", null, "uk-UA"),
ru: client.translate("general/info:USER", null, "ru-RU"),
})
.addUserOption(option =>
option
.setName("user")
.setDescription(client.translate("common:USER"))
.setDescriptionLocalizations({
uk: client.translate("common:USER", null, "uk-UA"),
ru: client.translate("common:USER", null, "ru-RU"),
}),
),
)
.addSubcommand(subcommand =>
subcommand
.setName("server")
.setDescription(client.translate("general/info:SERVER"))
.setDescriptionLocalizations({
uk: client.translate("general/info:SERVER", null, "uk-UA"),
ru: client.translate("general/info:SERVER", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
const command = interaction.options.getSubcommand();
if (command === "user") {
const member = interaction.options.getMember("user") || interaction.member;
const embed = getUserInfo(client, interaction, member);
return interaction.editReply({
embeds: [embed],
});
} else {
const embed = await getServerInfo(client, interaction);
return interaction.editReply({
embeds: [embed],
});
}
}
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @returns {Promise<import("discord.js").Embed>} Embed containing information about the guild
*/
async function getServerInfo(client, interaction) {
const { guild } = interaction;
await guild.members.fetch();
const owner = await guild.fetchOwner();
const embed = client.embed({
author: guild.name,
thumbnail: guild.iconURL(),
fields: [
{
name: client.customEmojis.title + interaction.translate("common:NAME"),
value: guild.name,
inline: true,
},
{
name: client.customEmojis.calendar + interaction.translate("common:CREATION"),
value: `<t:${Math.floor(guild.createdTimestamp / 1000)}:D>`,
inline: true,
},
{
name: client.customEmojis.users + interaction.translate("common:MEMBERS"),
value:
`${guild.members.cache.filter(m => !m.user.bot).size} ${client.functions.getNoun(
guild.members.cache.filter(m => !m.user.bot).size,
interaction.translate("misc:NOUNS:MEMBERS:1"),
interaction.translate("misc:NOUNS:MEMBERS:2"),
interaction.translate("misc:NOUNS:MEMBERS:5"),
)}` +
"\n" +
`${guild.members.cache.filter(m => m.user.bot).size} ${client.functions.getNoun(
guild.members.cache.filter(m => m.user.bot).size,
interaction.translate("misc:NOUNS:BOTS:1"),
interaction.translate("misc:NOUNS:BOTS:2"),
interaction.translate("misc:NOUNS:BOTS:5"),
)}`,
inline: true,
},
{
name: client.customEmojis.afk + interaction.translate("general/info:AFK_CHANNEL"),
value: guild.afkChannel?.toString() || interaction.translate("common:MISSING"),
inline: true,
},
{
name: client.customEmojis.id + interaction.translate("common:SERVER_ID"),
value: guild.id,
inline: true,
},
{
name: client.customEmojis.crown + interaction.translate("common:OWNER"),
value: owner.toString(),
inline: true,
},
{
name: client.customEmojis.boost + interaction.translate("general/info:BOOSTS"),
value: guild.premiumSubscriptionCount?.toString() || "0",
inline: true,
},
{
name: client.customEmojis.channels + interaction.translate("common:CHANNELS"),
value:
`${guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size} ${client.functions.getNoun(
guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size,
interaction.translate("misc:NOUNS:TEXT:1"),
interaction.translate("misc:NOUNS:TEXT:2"),
interaction.translate("misc:NOUNS:TEXT:5"),
)}` +
"\n" +
`${guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size} ${client.functions.getNoun(
guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size,
interaction.translate("misc:NOUNS:VOICE:1"),
interaction.translate("misc:NOUNS:VOICE:2"),
interaction.translate("misc:NOUNS:VOICE:5"),
)}` +
"\n" +
`${guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size} ${client.functions.getNoun(
guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size,
interaction.translate("misc:NOUNS:CATEGORY:1"),
interaction.translate("misc:NOUNS:CATEGORY:2"),
interaction.translate("misc:NOUNS:CATEGORY:5"),
)}`,
inline: true,
},
],
});
return embed;
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {import("discord.js").Member} member
* @returns {import("discord.js").Embed} Embed containing information about the user
*/
function getUserInfo(client, interaction, member) {
const embed = client.embed({
author: {
name: `${member.user.getUsername()} (${member.id})`,
iconURL: member.displayAvatarURL(),
},
thumbnail: member.displayAvatarURL(),
fields: [
{
name: ":man: " + interaction.translate("common:USERNAME"),
value: member.user.getUsername(),
inline: true,
},
{
name: client.customEmojis.pencil + " " + interaction.translate("common:NICKNAME"),
value: member.nickname || interaction.translate("general/info:NO_NICKNAME"),
inline: true,
},
{
name: client.customEmojis.bot + " " + interaction.translate("common:ROBOT"),
value: member.user.bot ? interaction.translate("common:YES") : interaction.translate("common:NO"),
inline: true,
},
{
name: client.customEmojis.calendar + " " + interaction.translate("common:CREATION"),
value: `<t:${Math.floor(member.user.createdTimestamp / 1000)}:D>`,
inline: true,
},
{
name: client.customEmojis.calendar2 + " " + interaction.translate("common:JOINED"),
value: `<t:${Math.floor(member.joinedTimestamp / 1000)}:D>`,
inline: true,
},
{
name: client.customEmojis.color + " " + interaction.translate("common:COLOR"),
value: member.displayHexColor,
inline: true,
},
{
name: client.customEmojis.roles + " " + interaction.translate("common:ROLES"),
value:
member.roles.size > 10
? member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", ") + " " +
interaction.translate("general/info:MORE_ROLES", {
count: member.roles.cache.size - 10,
})
: member.roles.cache.size < 1 ? interaction.translate("general/info:NO_ROLE") : member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", "),
inline: true,
},
],
});
return embed;
}
module.exports = Info;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
gamedig = require("gamedig");
@ -16,7 +16,8 @@ class Minecraft extends BaseCommand {
uk: client.translate("general/minecraft:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/minecraft:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("ip")
@ -26,6 +27,15 @@ class Minecraft extends BaseCommand {
ru: client.translate("common:IP", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -38,7 +48,7 @@ class Minecraft extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const ip = interaction.options.getString("ip");
const options = {
@ -55,7 +65,7 @@ class Minecraft extends BaseCommand {
let res = await gamedig.query(options).catch(() => {});
if (!res) {
options.type = "minecraftpe";
options.type = "mbe";
res = await gamedig.query(options).catch(() => {});
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Ping extends BaseCommand {
@ -15,7 +15,17 @@ class Ping extends BaseCommand {
uk: client.translate("general/ping:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/ping:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
@ -27,6 +37,8 @@ class Ping extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const embed = client.embed({
author: {
name: interaction.translate("general/ping:PONG"),
@ -36,7 +48,7 @@ class Ping extends BaseCommand {
}),
});
interaction.reply({
interaction.editReply({
embeds: [embed],
});
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
ms = require("ms");
@ -16,7 +16,8 @@ class Remindme extends BaseCommand {
uk: client.translate("general/remindme:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/remindme:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("time")
@ -50,6 +51,12 @@ class Remindme extends BaseCommand {
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
const conditions = ["s", "m", "h", "d", "w", "y"],
time = interaction.options.getString("time"),
message = interaction.options.getString("message");
if (!conditions.some(s => time.includes(s))) return interaction.error("general/remindme:TIME", null, { edit: true });
const userData = interaction.data.user;
if (!userData.reminds) userData.reminds = [];
@ -57,9 +64,9 @@ class Remindme extends BaseCommand {
const dateNow = Date.now();
const reminder = {
message: interaction.options.getString("message"),
message: message,
createdAt: Math.floor(dateNow / 1000),
sendAt: Math.floor((dateNow + ms(interaction.options.getString("time"))) / 1000),
sendAt: Math.floor((dateNow + ms(time)) / 1000),
};
userData.reminds.push(reminder);

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Reminds extends BaseCommand {
@ -15,7 +15,8 @@ class Reminds extends BaseCommand {
uk: client.translate("general/reminds:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/reminds:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});
@ -28,88 +29,129 @@ class Reminds extends BaseCommand {
async onLoad(client) {
client.on("interactionCreate", async interaction => {
if (!interaction.isButton()) return;
if (!interaction.customId.startsWith("reminds_")) return;
if (interaction.customId.startsWith("reminds_")) {
interaction.data = [];
interaction.data.guild = await client.getGuildData(interaction.guildId);
interaction.data.user = await client.getUserData(interaction.user.id);
interaction.data = [];
interaction.data.guild = await client.getGuildData(interaction.guildId);
interaction.data.user = await client.getUserData(interaction.user.id);
const reminds = interaction.data.user.reminds,
embeds = generateRemindsEmbeds(interaction, reminds);
const reminds = interaction.data.user.reminds,
embeds = generateRemindsEmbeds(interaction, reminds);
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId("reminds_prev_page").setStyle(ButtonStyle.Primary).setEmoji("⬅️"),
new ButtonBuilder().setCustomId("reminds_next_page").setStyle(ButtonStyle.Primary).setEmoji("➡️"),
new ButtonBuilder().setCustomId("reminds_jump_page").setStyle(ButtonStyle.Secondary).setEmoji("↗️"),
new ButtonBuilder().setCustomId("reminds_stop").setStyle(ButtonStyle.Danger).setEmoji("❌"),
);
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId("reminds_prev_page").setStyle(ButtonStyle.Primary).setEmoji("⬅️"),
new ButtonBuilder().setCustomId("reminds_next_page").setStyle(ButtonStyle.Primary).setEmoji("➡️"),
new ButtonBuilder().setCustomId("reminds_jump_page").setStyle(ButtonStyle.Secondary).setEmoji("↗️"),
new ButtonBuilder().setCustomId("reminds_stop").setStyle(ButtonStyle.Danger).setEmoji("❌"),
);
let currentPage = Number(interaction.message.content.match(/\d+/g)[0]) - 1 ?? 0;
let currentPage = Number(interaction.message.content.match(/\d+/g)[0]) - 1 ?? 0;
if (interaction.customId === "reminds_prev_page") {
await interaction.deferUpdate();
if (interaction.customId === "reminds_prev_page") {
await interaction.deferUpdate();
if (currentPage !== 0) {
--currentPage;
interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row],
});
}
} else if (interaction.customId === "reminds_next_page") {
await interaction.deferUpdate();
if (currentPage !== 0) {
--currentPage;
if (currentPage < embeds.length - 1) {
currentPage++;
interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row],
});
}
} else if (interaction.customId === "reminds_jump_page") {
await interaction.deferUpdate();
const row2 = new ActionRowBuilder().addComponents(embeds[currentPage].data._buttons);
const msg = await interaction.followUp({
content: interaction.translate("misc:JUMP_TO_PAGE", {
length: embeds.length,
}),
fetchReply: true,
});
const filter = res => {
return res.author.id === interaction.user.id && !isNaN(res.content);
};
interaction.channel.awaitMessages({ filter, max: 1, time: 10 * 1000 }).then(collected => {
if (embeds[collected.first().content - 1]) {
currentPage = collected.first().content - 1;
interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row],
});
if (collected.first().deletable) collected.first().delete();
if (msg.deletable) msg.delete();
} else {
if (collected.first().deletable) collected.first().delete();
if (msg.deletable) msg.delete();
return;
}
});
} else if (interaction.customId === "reminds_stop") {
await interaction.deferUpdate();
row.components.forEach(component => {
component.setDisabled(true);
});
return interaction.editReply({
components: [row],
interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row, row2],
});
}
} else if (interaction.customId === "reminds_next_page") {
await interaction.deferUpdate();
if (currentPage < embeds.length - 1) {
currentPage++;
const row2 = new ActionRowBuilder().addComponents(embeds[currentPage].data._buttons);
interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row, row2],
});
}
} else if (interaction.customId === "reminds_jump_page") {
await interaction.deferUpdate();
const msg = await interaction.followUp({
content: interaction.translate("misc:JUMP_TO_PAGE", {
length: embeds.length,
}),
fetchReply: true,
ephemeral: true,
});
const filter = res => {
return res.author.id === interaction.user.id && !isNaN(res.content);
};
interaction.channel.awaitMessages({ filter, max: 1, time: 10 * 1000 }).then(collected => {
if (embeds[collected.first().content - 1]) {
currentPage = collected.first().content - 1;
const row2 = new ActionRowBuilder().addComponents(embeds[currentPage].data._buttons);
interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row, row2],
});
if (collected.first().deletable) collected.first().delete();
if (msg.deletable) msg.delete();
} else {
if (collected.first().deletable) collected.first().delete();
if (msg.deletable) msg.delete();
return;
}
});
} else if (interaction.customId === "reminds_stop") {
await interaction.deferUpdate();
row.components.forEach(component => {
component.setDisabled(true);
});
return interaction.editReply({
components: [row],
});
} else if (interaction.customId.startsWith("reminds_delete_")) {
await interaction.deferUpdate();
const id = parseInt(interaction.customId.split("_")[2]);
const remindToDelete = reminds[id - 1];
interaction.data.user.reminds = reminds.filter(r => r.sendAt !== remindToDelete.sendAt);
await interaction.data.user.save();
const embeds = generateRemindsEmbeds(interaction, interaction.data.user.reminds);
if (embeds.length === 0) return interaction.editReply({
content: interaction.translate("general/reminds:NO_REMINDS"),
embeds: [],
components: [],
});
embeds.length <= 5 ? currentPage = 0 : currentPage;
const row2 = new ActionRowBuilder().addComponents(embeds[currentPage].data._buttons);
await interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **${currentPage + 1}**/**${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row, row2],
});
return interaction.followUp({
content: `${client.customEmojis.success} | ${interaction.translate("general/reminds:DELETED", { pos: id })}`,
ephemeral: true,
});
}
});
}
@ -134,10 +176,12 @@ class Reminds extends BaseCommand {
new ButtonBuilder().setCustomId("reminds_stop").setStyle(ButtonStyle.Danger).setEmoji("❌"),
);
const buttonsRow = new ActionRowBuilder().addComponents(embeds[0].data._buttons);
await interaction.editReply({
content: `${interaction.translate("common:PAGE")}: **1**/**${embeds.length}**`,
embeds: [embeds[0]],
components: [row],
components: [row, buttonsRow],
ephemeral: true,
});
}
@ -168,9 +212,21 @@ function generateRemindsEmbeds(interaction, reminds) {
description: info,
});
embed.data._buttons = [];
for (const key in current) {
embed.data._buttons.push(
new ButtonBuilder()
.setCustomId(`reminds_delete_${parseInt(key) + i + 1}`)
.setLabel(interaction.translate("general/reminds:DELETE", { pos: parseInt(key) + i + 1 }))
.setStyle(ButtonStyle.Danger),
);
}
embeds.push(embed);
}
return embeds;
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, parseEmoji } = require("discord.js");
const { SlashCommandBuilder, parseEmoji, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Report extends BaseCommand {
@ -15,7 +15,8 @@ class Report extends BaseCommand {
uk: client.translate("general/report:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/report:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addUserOption(option =>
option
.setName("user")
@ -86,14 +87,14 @@ class Report extends BaseCommand {
],
});
const success = parseEmoji(client.customEmojis.cool).id;
const error = parseEmoji(client.customEmojis.notcool).id;
const cool = parseEmoji(client.customEmojis.cool).id;
const notcool = parseEmoji(client.customEmojis.notcool).id;
repChannel.send({
embeds: [embed],
}).then(async m => {
await m.react(success);
await m.react(error);
await m.react(cool);
await m.react(notcool);
});
interaction.success("general/report:SUCCESS", {

View file

@ -1,121 +0,0 @@
const { SlashCommandBuilder, ChannelType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Serverinfo extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("serverinfo")
.setDescription(client.translate("general/serverinfo:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("general/serverinfo:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/serverinfo:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
const { guild } = interaction;
await guild.members.fetch();
const owner = await guild.fetchOwner();
const embed = client.embed({
author: guild.name,
thumbnail: guild.iconURL(),
fields: [
{
name: client.customEmojis.title + interaction.translate("common:NAME"),
value: guild.name,
inline: true,
},
{
name: client.customEmojis.calendar + interaction.translate("common:CREATION"),
value: `<t:${guild.createdTimestamp}:D>`,
inline: true,
},
{
name: client.customEmojis.users + interaction.translate("common:MEMBERS"),
value:
`${guild.members.cache.filter(m => !m.user.bot).size} ${client.functions.getNoun(
guild.members.cache.filter(m => !m.user.bot).size,
interaction.translate("misc:NOUNS:MEMBERS:1"),
interaction.translate("misc:NOUNS:MEMBERS:2"),
interaction.translate("misc:NOUNS:MEMBERS:5"),
)}` +
"\n" +
`${guild.members.cache.filter(m => m.user.bot).size} ${client.functions.getNoun(
guild.members.cache.filter(m => m.user.bot).size,
interaction.translate("misc:NOUNS:BOTS:1"),
interaction.translate("misc:NOUNS:BOTS:2"),
interaction.translate("misc:NOUNS:BOTS:5"),
)}`,
inline: true,
},
{
name: client.customEmojis.afk + interaction.translate("general/serverinfo:AFK_CHANNEL"),
value: guild.afkChannel?.toString() || interaction.translate("common:MISSING"),
inline: true,
},
{
name: client.customEmojis.id + interaction.translate("common:SERVER_ID"),
value: guild.id,
inline: true,
},
{
name: client.customEmojis.crown + interaction.translate("common:OWNER"),
value: owner.toString(),
inline: true,
},
{
name: client.customEmojis.boost + interaction.translate("general/serverinfo:BOOSTS"),
value: guild.premiumSubscriptionCount?.toString() || "0",
inline: true,
},
{
name: client.customEmojis.channels + interaction.translate("common:CHANNELS"),
value:
`${guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size} ${client.functions.getNoun(
guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size,
interaction.translate("misc:NOUNS:TEXT:1"),
interaction.translate("misc:NOUNS:TEXT:2"),
interaction.translate("misc:NOUNS:TEXT:5"),
)}` +
"\n" +
`${guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size} ${client.functions.getNoun(
guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size,
interaction.translate("misc:NOUNS:VOICE:1"),
interaction.translate("misc:NOUNS:VOICE:2"),
interaction.translate("misc:NOUNS:VOICE:5"),
)}` +
"\n" +
`${guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size} ${client.functions.getNoun(
guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size,
interaction.translate("misc:NOUNS:CATEGORY:1"),
interaction.translate("misc:NOUNS:CATEGORY:2"),
interaction.translate("misc:NOUNS:CATEGORY:5"),
)}`,
inline: true,
},
],
});
interaction.reply({
embeds: [embed],
});
}
}
module.exports = Serverinfo;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
@ -16,7 +16,8 @@ class Shorturl extends BaseCommand {
uk: client.translate("general/shorturl:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/shorturl:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("url")
@ -26,6 +27,15 @@ class Shorturl extends BaseCommand {
ru: client.translate("common:URL", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -38,20 +48,22 @@ class Shorturl extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const url = interaction.options.getString("url");
const res = await fetch("https://plsgo.ru/rest/v3/short-urls", {
const res = await fetch("https://i.jonnybro.ru/api/shorten", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Api-Key": client.config.apiKeys.shlink,
"Content-Type": "application/json",
Authorization: client.config.apiKeys.zipline,
},
body: new URLSearchParams({ longUrl: url }),
body: JSON.stringify({ url: url }),
}).then(res => res.json());
console.log(res);
interaction.editReply({
content: `<${res.shortUrl}>`,
content: `<${res.url}>`,
});
}
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField, version: djsVersion } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, version: discordJsVersion, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Stats extends BaseCommand {
@ -15,7 +15,17 @@ class Stats extends BaseCommand {
uk: client.translate("general/stats:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/stats:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
@ -27,13 +37,13 @@ class Stats extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
const hiddenGuildMembersCount = client.guilds.cache.get("568120814776614924").memberCount;
const servers = client.guilds.cache.size - 1;
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const servers = client.guilds.cache.size;
let users = 0;
client.guilds.cache.forEach(g => {
users += g.memberCount;
});
users = users - hiddenGuildMembersCount;
const embed = client.embed({
author: interaction.translate("common:STATS"),
@ -49,7 +59,7 @@ class Stats extends BaseCommand {
},
{
name: client.customEmojis.version + " " + interaction.translate("general/stats:VERSIONS_TITLE"),
value: `\`Discord.js: v${djsVersion}\`\n\`Nodejs: v${process.versions.node}\``,
value: `\`Discord.js: v${discordJsVersion}\`\n\`Nodejs: v${process.versions.node}\``,
inline: true,
},
{
@ -84,14 +94,13 @@ class Stats extends BaseCommand {
dashboardLink: client.config.dashboard.domain,
supportLink: "https://discord.gg/Ptkj2n9nzZ",
inviteLink: client.generateInvite({ scopes: ["bot", "applications.commands"], permissions: [PermissionsBitField.Flags.Administrator] }),
donateLink: "https://www.donationalerts.com/r/jonny_bro",
owner: client.config.owner.id,
}),
},
],
});
interaction.reply({
interaction.editReply({
embeds: [embed],
});
}

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, parseEmoji } = require("discord.js");
const { SlashCommandBuilder, parseEmoji, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Suggest extends BaseCommand {
@ -15,7 +15,8 @@ class Suggest extends BaseCommand {
uk: client.translate("general/suggest:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/suggest:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("message")

View file

@ -1,99 +0,0 @@
const { SlashCommandBuilder } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Userinfo extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("userinfo")
.setDescription(client.translate("general/userinfo:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("general/userinfo:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/userinfo:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.addUserOption(option =>
option
.setName("user")
.setDescription(client.translate("common:USER"))
.setDescriptionLocalizations({
uk: client.translate("common:USER", null, "uk-UA"),
ru: client.translate("common:USER", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Object} data
*/
async execute(client, interaction) {
const member = interaction.options.getMember("user") || interaction.member;
const embed = client.embed({
author: {
name: `${member.user.getUsername()} (${member.id})`,
iconURL: member.displayAvatarURL(),
},
thumbnail: member.displayAvatarURL(),
fields: [
{
name: ":man: " + interaction.translate("common:USERNAME"),
value: member.user.getUsername(),
inline: true,
},
{
name: client.customEmojis.pencil + " " + interaction.translate("common:NICKNAME"),
value: member.nickname || interaction.translate("general/userinfo:NO_NICKNAME"),
inline: true,
},
{
name: client.customEmojis.bot + " " + interaction.translate("common:ROBOT"),
value: member.user.bot ? interaction.translate("common:YES") : interaction.translate("common:NO"),
inline: true,
},
{
name: client.customEmojis.calendar + " " + interaction.translate("common:CREATION"),
value: `<t:${member.user.createdTimestamp}:D>`,
inline: true,
},
{
name: client.customEmojis.calendar2 + " " + interaction.translate("common:JOINED"),
value: `<t:${member.joinedTimestamp}:D>`,
inline: true,
},
{
name: client.customEmojis.color + " " + interaction.translate("common:COLOR"),
value: member.displayHexColor,
inline: true,
},
{
name: client.customEmojis.roles + " " + interaction.translate("common:ROLES"),
value:
member.roles.size > 10
? member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", ") + " " +
interaction.translate("general/userinfo:MORE_ROLES", {
count: member.roles.cache.size - 10,
})
: member.roles.cache.size < 1 ? interaction.translate("general/userinfo:NO_ROLE") : member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", "),
inline: true,
},
],
});
interaction.reply({
embeds: [embed],
});
}
}
module.exports = Userinfo;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
@ -16,7 +16,8 @@ class Whois extends BaseCommand {
uk: client.translate("general/whois:DESCRIPTION", null, "uk-UA"),
ru: client.translate("general/whois:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("ip")
@ -26,6 +27,15 @@ class Whois extends BaseCommand {
ru: client.translate("common:IP", null, "ru-RU"),
})
.setRequired(true),
)
.addBooleanOption(option =>
option
.setName("ephemeral")
.setDescription(client.translate("misc:EPHEMERAL_RESPONSE"))
.setDescriptionLocalizations({
uk: client.translate("misc:EPHEMERAL_RESPONSE", null, "uk-UA"),
ru: client.translate("misc:EPHEMERAL_RESPONSE", null, "ru-RU"),
}),
),
dirname: __dirname,
ownerOnly: false,
@ -38,12 +48,12 @@ class Whois extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply();
await interaction.deferReply({ ephemeral: interaction.options.getBoolean("ephemeral") || false });
const ip = interaction.options.getString("ip"),
whois = await fetch(`http://ip-api.com/json/${ip}?fields=status,message,continent,continentCode,country,countryCode,region,regionName,city,zip,timezone,currency,isp,org,as,mobile,proxy,hosting,query`).then(response => response.json());
if (whois.status === "fail") return interaction.editReply({ content: interaction.translate("general/whois:ERROR", { ip }) });
if (whois.status === "fail") return interaction.error("general/whois:ERROR", { ip }, { edit: true });
const embed = client.embed({
title: interaction.translate("general/whois:INFO_ABOUT", {

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch"),
moment = require("moment");
@ -17,7 +17,8 @@ class Checkjar extends BaseCommand {
uk: client.translate("iat/checkjar:DESCRIPTION", null, "uk-UA"),
ru: client.translate("iat/checkjar:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Clear extends BaseCommand {
@ -15,7 +15,8 @@ class Clear extends BaseCommand {
uk: client.translate("moderation/clear:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/clear:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addStringOption(option =>
option
@ -117,7 +118,7 @@ class Clear extends BaseCommand {
}
});
} else {
if (isNaN(option) || parseInt(option) < 1) return interaction.error("misc:OPTION_NAN_ALL", null, { ephemeral: true });
if (isNaN(option) || parseInt(option) < 1) return interaction.error("misc:OPTION_NAN_ALL", null, { edit: true });
let messages = await interaction.channel.messages.fetch({ limit: option });

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Clearwarns extends BaseCommand {
@ -15,7 +15,8 @@ class Clearwarns extends BaseCommand {
uk: client.translate("moderation/clearwarns:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/clearwarns:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addUserOption(option =>
option
@ -39,6 +40,7 @@ class Clearwarns extends BaseCommand {
*/
async execute(client, interaction) {
const member = interaction.options.getMember("user");
if (member.user.id === interaction.user.id) return interaction.error("misc:CANT_YOURSELF");
const memberData = await client.getMemberData(member.id, interaction.guildId);

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
ms = require("ms");
@ -16,7 +16,8 @@ class Giveaway extends BaseCommand {
uk: client.translate("moderation/giveaway:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/giveaway:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addSubcommand(subcommand =>
subcommand

View file

@ -1,119 +0,0 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionsBitField } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Poll extends BaseCommand {
/**
*
* @param {import("../../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("poll")
.setDescription(client.translate("moderation/poll:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("moderation/poll:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/poll:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addStringOption(option =>
option
.setName("question")
.setDescription(client.translate("moderation/poll:QUESTION"))
.setDescriptionLocalizations({
uk: client.translate("moderation/poll:QUESTION", null, "uk-UA"),
ru: client.translate("moderation/poll:QUESTION", null, "ru-RU"),
})
.setRequired(true),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
const question = interaction.options.getString("question");
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId("poll_everyone").setLabel("@everyone").setStyle(ButtonStyle.Primary),
new ButtonBuilder().setCustomId("poll_here").setLabel("@here").setStyle(ButtonStyle.Primary),
new ButtonBuilder().setCustomId("poll_nothing").setLabel(interaction.translate("moderation/poll:NOTHING")).setStyle(ButtonStyle.Primary),
new ButtonBuilder().setCustomId("poll_cancel").setLabel(interaction.translate("common:CANCEL")).setStyle(ButtonStyle.Danger),
);
await interaction.reply({
content: interaction.translate("moderation/poll:SELECT_MENTION"),
ephemeral: true,
components: [row],
});
let mention = null;
const filter = i => i.user.id === interaction.user.id;
const collector = interaction.channel.createMessageComponentCollector({ filter, idle: 15 * 1000 });
collector.on("collect", async i => {
if (i.isButton()) {
if (i.customId === "poll_everyone") {
mention = "||@everyone||";
i.update({
content: interaction.translate("moderation/poll:POLL_SENDED"),
components: [],
});
} else if (i.customId === "poll_here") {
mention = "||@here||";
i.update({
content: interaction.translate("moderation/poll:POLL_SENDED"),
components: [],
});
} else if (i.customId === "poll_nothing") {
mention = null;
i.update({
content: interaction.translate("moderation/poll:POLL_SENDED"),
components: [],
});
} else if (i.customId === "poll_cancel") {
return i.update({
content: interaction.translate("misc:SELECT_CANCELED"),
components: [],
});
}
const cool = client.emojis.cache.find(e => e.name === client.customEmojis.cool.split(":")[1]);
const notcool = client.emojis.cache.find(e => e.name === client.customEmojis.notcool.split(":")[1]);
const embed = client.embed({
author: interaction.translate("moderation/poll:TITLE"),
fields: [
{
name: "\u200B",
value: question,
},
{
name: "\u200B",
value: interaction.translate("moderation/poll:REACT", {
success: cool.toString(),
error: notcool.toString(),
}),
},
],
});
return interaction.channel.send({
content: mention,
embeds: [embed],
}).then(async m => {
await m.react(cool);
await m.react(notcool);
});
}
});
}
}
module.exports = Poll;

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Unban extends BaseCommand {
@ -15,7 +15,8 @@ class Unban extends BaseCommand {
uk: client.translate("moderation/unban:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/unban:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addStringOption(option =>
option

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Ban extends BaseCommand {
@ -15,7 +15,8 @@ class Ban extends BaseCommand {
uk: client.translate("moderation/untimeout:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/untimeout:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)
.addUserOption(option =>
option
@ -44,7 +45,7 @@ class Ban extends BaseCommand {
timedout = member.isCommunicationDisabled();
if (member.user.bot) return interaction.error("misc:BOT_USER", null, { ephemeral: true, edit: true });
if (member.id === interaction.member.id) return interaction.error("moderation/untimeout:YOURSELF", null, { ephemeral: true, edit: true });
if (member.id === interaction.member.id) return interaction.error("misc:CANT_YOURSELF", null, { ephemeral: true, edit: true });
if (!timedout) return interaction.error("moderation/untimeout:NOT_TIMEDOUT", null, { ephemeral: true, edit: true });
await member.timeout(null);

View file

@ -1,4 +1,4 @@
const { ContextMenuCommandBuilder, ModalBuilder, ActionRowBuilder, TextInputBuilder, ApplicationCommandType, PermissionsBitField, TextInputStyle } = require("discord.js");
const { ContextMenuCommandBuilder, ModalBuilder, ActionRowBuilder, TextInputBuilder, ApplicationCommandType, PermissionsBitField, TextInputStyle, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class WarnContext extends BaseCommand {
@ -11,7 +11,8 @@ class WarnContext extends BaseCommand {
command: new ContextMenuCommandBuilder()
.setName("Give Warn")
.setType(ApplicationCommandType.User)
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages),
dirname: __dirname,
ownerOnly: false,
@ -29,7 +30,7 @@ class WarnContext extends BaseCommand {
moderationPosition = interaction.member.roles.highest.position;
if (member.user.bot) return interaction.error("misc:BOT_USER", null, { ephemeral: true });
if (member.id === interaction.member.id) return interaction.error("moderation/warn:YOURSELF", null, { ephemeral: true });
if (member.id === interaction.member.id) return interaction.error("misc:CANT_YOURSELF", null, { ephemeral: true });
if (interaction.guild.ownerId !== interaction.member.id && !(moderationPosition > memberPosition)) return interaction.error("moderation/warn:SUPERIOR", null, { ephemeral: true });
const memberData = await client.getMemberData(member.id, interaction.guildId);
@ -66,11 +67,6 @@ class WarnContext extends BaseCommand {
if (submitted) {
const reason = submitted.fields.getTextInputValue("warn_reason");
// const sanctions = memberData.sanctions.filter(s => s.type === "warn").length;
// const banCount = data.guildData.plugins.warnsSanctions.ban;
// const kickCount = data.guildData.plugins.warnsSanctions.kick;
const caseInfo = {
moderator: interaction.member.id,
date: Date.now(),
@ -97,67 +93,6 @@ class WarnContext extends BaseCommand {
],
});
/*
if (banCount) {
if (sanctions >= banCount) {
member.send({
content: interaction.translate("moderation/ban:BANNED_DM", {
user: member.user,
moderator: interaction.user.getUsername(),
server: interaction.guild.name,
reason,
}),
});
caseInfo.type = "ban";
embed
.setAuthor({
name: interaction.translate("moderation/warn:BAN"),
})
.setColor(client.config.embed.color);
interaction.guild.members.ban(member).catch(() => {});
interaction.followUp({
content: interaction.translate("moderation/setwarns:AUTO_BAN", {
user: member.user.getUsername(),
count: `${banCount} ${client.functions.getNoun(banCount, interaction.translate("misc:NOUNS:WARNS:1"), interaction.translate("misc:NOUNS:WARNS:2"), interaction.translate("misc:NOUNS:WARNS:5"))}`,
}),
});
}
}
if (kickCount) {
if (sanctions >= kickCount) {
member.send({
content: interaction.translate("moderation/kick:KICKED_DM", {
user: member.user,
moderator: interaction.user.getUsername(),
server: interaction.guild.name,
reason,
}),
});
caseInfo.type = "kick";
embed
.setAuthor({
name: interaction.translate("moderation/warn:KICK"),
})
.setColor(client.config.embed.color);
member.kick().catch(() => {});
interaction.followUp({
content: interaction.translate("moderation/setwarns:AUTO_KICK", {
user: member.user.getUsername(),
count: `${kickCount} ${client.functions.getNoun(kickCount, interaction.translate("misc:NOUNS:WARNS:1"), interaction.translate("misc:NOUNS:WARNS:2"), interaction.translate("misc:NOUNS:WARNS:5"))}`,
}),
});
}
} */
try {
await member.send({
content: interaction.translate("moderation/warn:WARNED_DM", {

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Warns extends BaseCommand {
@ -15,7 +15,8 @@ class Warns extends BaseCommand {
uk: client.translate("moderation/warns:DESCRIPTION", null, "uk-UA"),
ru: client.translate("moderation/warns:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addUserOption(option =>
option

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Back extends BaseCommand {
@ -15,7 +15,8 @@ class Back extends BaseCommand {
uk: client.translate("music/back:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/back:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js"),
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js"),
{ QueryType } = require("discord-player");
const BaseCommand = require("../../base/BaseCommand"),
fs = require("fs");
@ -17,7 +17,8 @@ class Clips extends BaseCommand {
uk: client.translate("music/clips:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/clips:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("query")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js"),
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js"),
{ QueueRepeatMode } = require("discord-player");
const BaseCommand = require("../../base/BaseCommand");
@ -16,7 +16,8 @@ class Loop extends BaseCommand {
uk: client.translate("music/loop:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/loop:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("option")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } = require("discord.js"),
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js"),
{ QueueRepeatMode } = require("discord-player");
const BaseCommand = require("../../base/BaseCommand");
@ -16,7 +16,8 @@ class Nowplaying extends BaseCommand {
uk: client.translate("music/nowplaying:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/nowplaying:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { ContextMenuCommandBuilder, ApplicationCommandType, PermissionsBitField } = require("discord.js");
const { ContextMenuCommandBuilder, ApplicationCommandType, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class PlayContext extends BaseCommand {
@ -11,7 +11,8 @@ class PlayContext extends BaseCommand {
command: new ContextMenuCommandBuilder()
.setName("Add to Queue")
.setType(ApplicationCommandType.Message)
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});
@ -40,8 +41,6 @@ class PlayContext extends BaseCommand {
});
if (!searchResult.hasTracks()) {
console.log(searchResult);
return interaction.error("music/play:NO_RESULT", { query }, { edit: true });
} else {
await client.player.play(voice, searchResult, {

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js"),
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js"),
{ QueryType } = require("discord-player");
const BaseCommand = require("../../base/BaseCommand");
@ -16,7 +16,8 @@ class Play extends BaseCommand {
uk: client.translate("music/play:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/play:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("query")
@ -49,14 +50,11 @@ class Play extends BaseCommand {
if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return interaction.error("music/play:VOICE_CHANNEL_CONNECT", null, { edit: true });
const searchResult = await client.player.search(query, {
requestedBy: interaction.user,
requestedBy: interaction.member,
});
if (!searchResult.hasTracks()) {
console.log(searchResult);
return interaction.error("music/play:NO_RESULT", { query }, { edit: true });
} else {
if (!searchResult.hasTracks()) return interaction.error("music/play:NO_RESULT", { query }, { edit: true, ephemeral: true });
else {
await client.player.play(voice, searchResult, {
nodeOptions: {
metadata: interaction,
@ -85,7 +83,8 @@ class Play extends BaseCommand {
*/
async autocompleteRun(client, interaction) {
const query = interaction.options.getString("query");
if (query === "" || query === null) return;
if (query === "" || query === null) return interaction.respond([ { name: "No Query Provided", value: "" } ]);
if (query.startsWith("http")) return interaction.respond([ { name: "Current Link", value: query } ]);
const youtubeResults = await client.player.search(query, { searchEngine: QueryType.YOUTUBE });
const spotifyResults = await client.player.search(query, { searchEngine: QueryType.SPOTIFY_SEARCH });

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, ButtonBuilder, ButtonStyle, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Queue extends BaseCommand {
@ -15,7 +15,8 @@ class Queue extends BaseCommand {
uk: client.translate("music/queue:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/queue:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Seek extends BaseCommand {
@ -15,6 +15,8 @@ class Seek extends BaseCommand {
uk: client.translate("music/seek:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/seek:DESCRIPTION", null, "ru-RU"),
})
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addIntegerOption(option =>
option
.setName("time")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Shuffle extends BaseCommand {
@ -15,7 +15,8 @@ class Shuffle extends BaseCommand {
uk: client.translate("music/shuffle:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/shuffle:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Skip extends BaseCommand {
@ -15,7 +15,8 @@ class Skip extends BaseCommand {
uk: client.translate("music/skip:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/skip:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addIntegerOption(option =>
option
.setName("position")
@ -23,8 +24,7 @@ class Skip extends BaseCommand {
.setDescriptionLocalizations({
uk: client.translate("music/skip:POSITION", null, "uk-UA"),
ru: client.translate("music/skip:POSITION", null, "ru-RU"),
})
.setRequired(false),
}),
),
dirname: __dirname,
ownerOnly: false,

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Stop extends BaseCommand {
@ -15,7 +15,8 @@ class Stop extends BaseCommand {
uk: client.translate("music/stop:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/stop:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Volume extends BaseCommand {
@ -15,7 +15,8 @@ class Volume extends BaseCommand {
uk: client.translate("music/volume:DESCRIPTION", null, "uk-UA"),
ru: client.translate("music/volume:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addIntegerOption(option =>
option
.setName("int")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder, AttachmentBuilder } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, StringSelectMenuBuilder, AttachmentBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
@ -16,7 +16,8 @@ class NSFW extends BaseCommand {
uk: client.translate("nsfw/nsfw:DESCRIPTION", null, "uk-UA"),
ru: client.translate("nsfw/nsfw:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: false,
});
@ -38,7 +39,7 @@ class NSFW extends BaseCommand {
const tag = interaction?.values[0],
splitted = tag.split("_"),
res = await fetch(`https://nsfw-api.jababot.ru/media/${splitted[0].charAt(0).toLowerCase()}/${splitted[1].toLowerCase()}`).then(async r => await r.buffer()),
res = await fetch(`https://nsfw-api.jonnybro.ru/media/${splitted[0].charAt(0).toLowerCase()}/${splitted[1].toLowerCase()}`).then(async r => await r.buffer()),
image = new AttachmentBuilder(res, { name: "image.jpeg" });
const embed = client.embed({

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Debug extends BaseCommand {
@ -15,7 +15,8 @@ class Debug extends BaseCommand {
uk: client.translate("owner/debug:DESCRIPTION", null, "uk-UA"),
ru: client.translate("owner/debug:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addSubcommand(subcommand =>
subcommand
.setName("set")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Eval extends BaseCommand {
@ -15,7 +15,8 @@ class Eval extends BaseCommand {
uk: client.translate("owner/eval:DESCRIPTION", null, "uk-UA"),
ru: client.translate("owner/eval:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("code")

View file

@ -1,7 +1,6 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
i18next = require("i18next");
// autoUpdateDocs = require("../../helpers/autoUpdateDocs");
class Reload extends BaseCommand {
/**
@ -17,7 +16,8 @@ class Reload extends BaseCommand {
uk: client.translate("owner/reload:DESCRIPTION", null, "uk-UA"),
ru: client.translate("owner/reload:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("command")
@ -40,19 +40,21 @@ class Reload extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
const command = interaction.options.getString("command"),
cmd = client.commands.get(command);
if (!cmd) return interaction.error("owner/reload:NOT_FOUND", { command }, { ephemeral: true });
await client.unloadCommand(`../commands/${cmd.category}`, cmd.command.name);
client.unloadCommand(`../commands/${cmd.category}`, cmd.command.name);
await client.loadCommand(`../commands/${cmd.category}`, cmd.command.name);
i18next.reloadResources(["ru-RU", "uk-UA", "en-US"]);
// autoUpdateDocs.update(client);
interaction.success("owner/reload:SUCCESS", {
command: cmd.command.name,
}, { ephemeral: true });
}, { edit: true });
}
/**

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder } = require("discord.js");
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Say extends BaseCommand {
@ -15,7 +15,8 @@ class Say extends BaseCommand {
uk: client.translate("owner/say:DESCRIPTION", null, "uk-UA"),
ru: client.translate("owner/say:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.addStringOption(option =>
option
.setName("message")

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Servers extends BaseCommand {
@ -15,7 +15,8 @@ class Servers extends BaseCommand {
uk: client.translate("owner/servers:DESCRIPTION", null, "uk-UA"),
ru: client.translate("owner/servers:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(true),
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall])
.setContexts([InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild]),
dirname: __dirname,
ownerOnly: true,
});
@ -30,7 +31,7 @@ class Servers extends BaseCommand {
await interaction.deferReply({ ephemeral: true });
let currentPage = 0;
const embeds = generateServersEmbeds(interaction, client.guilds.cache);
const embeds = generateGuildsEmbeds(interaction, client.guilds.cache);
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId("servers_prev_page").setStyle(ButtonStyle.Primary).setEmoji("⬅️"),
@ -93,15 +94,15 @@ class Servers extends BaseCommand {
/**
*
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} servers
* @param {Array[import("discord.js").Guild]} guilds
* @returns
*/
function generateServersEmbeds(interaction, servers) {
function generateGuildsEmbeds(interaction, guilds) {
const embeds = [];
let k = 10;
for (let i = 0; i < servers.size; i += 10) {
const current = servers
for (let i = 0; i < guilds.size; i += 10) {
const current = guilds
.sort((a, b) => b.memberCount - a.memberCount)
.map(g => g)
.slice(i, k);
@ -110,9 +111,9 @@ function generateServersEmbeds(interaction, servers) {
const info = current
.map(
server =>
`${++j}. ${server.name} | ${server.memberCount} ${interaction.client.functions.getNoun(
server.memberCount,
guild =>
`${++j}. ${guild.name} (${guild.id}) | ${guild.memberCount} ${interaction.client.functions.getNoun(
guild.memberCount,
interaction.translate("misc:NOUNS:MEMBERS:1"),
interaction.translate("misc:NOUNS:MEMBERS:2"),
interaction.translate("misc:NOUNS:MEMBERS:5"),

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class AddUser extends BaseCommand {
@ -15,7 +15,8 @@ class AddUser extends BaseCommand {
uk: client.translate("tickets/adduser:DESCRIPTION", null, "uk-UA"),
ru: client.translate("tickets/adduser:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addUserOption(option =>
option

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, ButtonBuilder, ButtonStyle, ActionRowBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class CloseTicket extends BaseCommand {
@ -15,7 +15,8 @@ class CloseTicket extends BaseCommand {
uk: client.translate("tickets/closeticket:DESCRIPTION", null, "uk-UA"),
ru: client.translate("tickets/closeticket:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages),
dirname: __dirname,
ownerOnly: false,

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField, ButtonBuilder, ButtonStyle, ActionRowBuilder, ChannelType } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, ButtonBuilder, ButtonStyle, ActionRowBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class CreateTicketEmbed extends BaseCommand {
@ -15,193 +15,14 @@ class CreateTicketEmbed extends BaseCommand {
uk: client.translate("tickets/createticketembed:DESCRIPTION", null, "uk-UA"),
ru: client.translate("tickets/createticketembed:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageGuild),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
*/
async onLoad(client) {
client.on("interactionCreate", async interaction => {
if (!interaction.isButton()) return;
interaction.data = [];
interaction.data.guild = await client.getGuildData(interaction.guildId);
const button = interaction.component;
if (button.customId === "support_ticket") {
const guildData = interaction.data.guild,
ticketsCategory = guildData.plugins.tickets.ticketsCategory,
ticketLogs = guildData.plugins.tickets.ticketLogs;
if (interaction.guild.channels.cache.get(ticketsCategory).children.cache.size >= 50) {
const sorted = interaction.guild.channels.cache.get(ticketsCategory).children.cache.sort((ch1, ch2) => ch1.createdTimestamp - ch2.createdTimestamp);
await sorted.first().delete();
}
if (guildData.plugins.tickets.count === undefined) guildData.plugins.tickets.count = 0;
guildData.plugins.tickets.count++;
const channel = await interaction.guild.channels.create({
name: `${interaction.user.username}-support-${guildData.plugins.tickets.count}`,
topic: interaction.user.id,
type: ChannelType.GuildText,
parent: ticketsCategory,
permissionOverwrites: [
{
id: interaction.user.id,
allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
},
{
id: interaction.guild.roles.everyone,
deny: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
},
],
});
const logChannel = interaction.guild.channels.cache.get(ticketLogs);
const logEmbed = client.embed({
title: interaction.translate("tickets/createticketembed:TICKET_CREATED_TITLE"),
description: `${interaction.user.toString()} (${channel.toString()})`,
});
await logChannel.send({ embeds: [logEmbed] });
await interaction.success("tickets/createticketembed:TICKET_CREATED", {
channel: channel.toString(),
}, { ephemeral: true });
await channel.send(`<@${interaction.user.id}>`);
const embed = client.embed({
author: {
name: interaction.user.getUsername(),
iconURL: interaction.user.displayAvatarURL(),
},
title: "Support Ticket",
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 row = new ActionRowBuilder().addComponents(closeButton, transcriptButton);
await guildData.save();
await channel.send({ embeds: [embed], components: [row] });
} else if (button.customId === "close_ticket") {
const embed = client.embed({
title: interaction.translate("tickets/closeticket:CLOSING_TITLE"),
description: interaction.translate("tickets/closeticket:CLOSING_DESC"),
fields: [
{
name: interaction.translate("common:TICKET"),
value: interaction.channel.name,
},
{
name: interaction.translate("tickets/closeticket:CLOSING_BY"),
value: interaction.user.getUsername(),
},
],
});
const button = new ButtonBuilder().setCustomId("cancel_closing").setLabel(interaction.translate("common:CANCEL")).setStyle(ButtonStyle.Danger);
const row = new ActionRowBuilder().addComponents(button);
await interaction.reply({
embeds: [embed],
components: [row],
});
const filter = i => i.customId === "cancel_closing";
const collector = interaction.channel.createMessageComponentCollector({ filter, time: 5000 });
collector.on("collect", async i => {
await i.update({ content: interaction.translate("tickets/closeticket:CLOSING_CANCELED"), components: [] });
collector.stop("canceled");
});
collector.on("end", async (_, reason) => {
if (reason !== "canceled") {
const reversedMessages = (await interaction.channel.messages.fetch()).filter(m => !m.author.bot),
messages = Array.from(reversedMessages.values()).reverse(),
transcriptionLogs = interaction.data.guild.plugins.tickets.transcriptionLogs,
ticketLogs = interaction.data.guild.plugins.tickets.ticketLogs;
if (messages.length > 1) {
let transcript = "---- TICKET CREATED ----\n";
messages.forEach(message => {
transcript += `[${client.functions.printDate(client, message.createdTimestamp, null, interaction.getLocale())}] ${message.author.getUsername()}: ${message.content}\n`;
});
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` }] });
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) {
interaction.followUp({ content: interaction.translate("misc:CANT_DM"), ephemeral: true });
}
}
const logChannel = interaction.guild.channels.cache.get(ticketLogs);
const logEmbed = client.embed({
title: interaction.translate("tickets/createticketembed:TICKET_CLOSED_TITLE"),
description: `${interaction.user.toString()} (${interaction.channel.toString()})`,
});
logChannel.send({ embeds: [logEmbed] });
interaction.channel.send("Closed!");
const member = interaction.guild.members.cache.find(u => u.user.id === interaction.channel.topic);
await interaction.channel.permissionOverwrites.edit(member, { ViewChannel: false, SendMessages: null });
await interaction.channel.setName(`${interaction.channel.name}-closed`);
}
});
} else if (button.customId === "transcript_ticket") {
await interaction.deferUpdate();
const reversedMessages = (await interaction.channel.messages.fetch()).filter(m => !m.author.bot);
const messages = Array.from(reversedMessages.values()).reverse();
if (messages.length > 1) {
let transcript = "---- TICKET CREATED ----\n";
messages.forEach(message => {
transcript += `[${client.functions.printDate(client, message.createdTimestamp, null, interaction.getLocale())}] ${message.author.getUsername()}: ${message.content}\n`;
});
transcript += "---- TICKET CLOSED ----\n";
try {
await interaction.user.send({
content: interaction.translate("tickets/closeticket:TRANSCRIPT", { channel: `<#${interaction.channelId}>` }),
files: [{ attachment: Buffer.from(transcript), name: `${interaction.channel.name}.txt` }],
});
} catch (error) {
interaction.followUp({ content: interaction.translate("misc:CANT_DM"), ephemeral: true });
}
} else return;
}
});
}
/**
*
* @param {import("../../base/Client")} client

View file

@ -1,4 +1,4 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js");
const { SlashCommandBuilder, PermissionsBitField, InteractionContextType, ApplicationIntegrationType } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class RemoveUser extends BaseCommand {
@ -15,7 +15,8 @@ class RemoveUser extends BaseCommand {
uk: client.translate("tickets/removeuser:DESCRIPTION", null, "uk-UA"),
ru: client.translate("tickets/removeuser:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.setIntegrationTypes([ApplicationIntegrationType.GuildInstall])
.setContexts([InteractionContextType.Guild])
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
.addUserOption(option =>
option

View file

@ -1,91 +0,0 @@
const { SlashCommandBuilder } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch");
class Courses extends BaseCommand {
/**
*
* @param {import("../base/Client")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("courses")
.setDescription(client.translate("beatrun.ru/courses:DESCRIPTION"))
.setDescriptionLocalizations({
uk: client.translate("beatrun.ru/courses:DESCRIPTION", null, "uk-UA"),
ru: client.translate("beatrun.ru/courses:DESCRIPTION", null, "ru-RU"),
})
.setDMPermission(false)
.addStringOption(option =>
option
.setName("code")
.setDescription(client.translate("common:CODE"))
.setDescriptionLocalizations({
uk: client.translate("common:CODE", null, "uk-UA"),
ru: client.translate("common:CODE", null, "ru-RU"),
})
.setRequired(true),
),
dirname: __dirname,
ownerOnly: false,
});
}
/**
*
* @param {import("../../base/Client")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Object} data
*/
async execute(client, interaction) {
await interaction.deferReply();
const code = interaction.options.getString("code");
const response = await fetch(`https://courses.jonnybro.ru/api/info/${code}`).then(res => res.json());
const course = response.data;
if (response.res === 401) return interaction.error("beatrun.ru/courses:NOT_FOUND", null, { ephemeral: true, edit: true });
const embed = client.embed({
title: code,
description: `[${interaction.translate("beatrun.ru/courses:DOWNLOAD")}](https://courses.jonnybro.ru/${course.path})`,
thumbnail: course.mapimg,
url: `https://courses.beatrun.ru/?search=${code}`,
fields: [
{
name: interaction.translate("beatrun.ru/courses:MAP"),
value: `[${course.map}](https://steamcommunity.com/sharedfiles/filedetails/?id=${course.mapid})`,
inline: true,
},
{
name: interaction.translate("beatrun.ru/courses:UPLOADER"),
value: `[${course.uploader.name || course.uploader.userid}](https://steamcommunity.com/profiles/${course.uploader.userid})`,
inline: true,
},
{
name: "\u200B",
value: "\u200B",
inline: true,
},
{
name: interaction.translate("beatrun.ru/courses:DATE"),
value: `<t:${Math.floor(course.time / 1000)}:D>`,
inline: true,
},
{
name: interaction.translate("beatrun.ru/courses:PLAYS"),
value: `${course.plays || 0}`,
inline: true,
},
],
});
interaction.editReply({
embeds: [embed],
});
}
}
module.exports = Courses;

View file

@ -13,6 +13,8 @@ module.exports = {
clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
clientSecret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
},
/* YouTube Cookie */
youtubeCookie: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
/* Support server */
support: {
id: "123456789098765432", // The ID of the support server
@ -41,6 +43,6 @@ module.exports = {
},
/* Add your own API keys here */
apiKeys: {
shlink: "12345678-1234-1234-1234-123456789098", /* Shlink.io REST API key */
shlink: "12345678-1234-1234-1234-123456789098" /* Shlink.io REST API key */,
},
};

@ -1 +1 @@
Subproject commit d63e6e4301abfdba6ba031adfd6115c4a639cb88
Subproject commit 42cb44000f844f17b0d9e12e15a45ab60f3dcdb7

View file

@ -108,12 +108,10 @@ module.exports.load = async client => {
const user = req.session?.user;
const username = (user?.discriminator === "0" ? user?.username : user?.tag) || "Guest";
const hiddenGuildMembersCount = client.guilds.cache.get("568120814776614924").memberCount;
let users = 0;
client.guilds.cache.forEach(g => {
users += g.memberCount;
});
users = users - hiddenGuildMembersCount;
const cards = [
{

View file

@ -1,72 +1,36 @@
{
"To get access to these emojis,": "add your bot on https://discord.gg/5wrBEwE4bc",
"stats": "<:atlanta_stats:598179382657286152>",
"ram": "<:atlanta_ram:598178809031688192>",
"version": "<:atlanta_version:598178475525931014>",
"online": "<:atlanta_online:598178166443474969>",
"link": "<:atlanta_link:598176933855100976>",
"voice": "<:atlanta_voice:598176518891372560>",
"add": "<:atlanta_add:598176235700355083>",
"help": "<:atlanta_help:598175335078559771>",
"warn": "<:atlanta_warn:598179558927106058>",
"error": "<:atlanta_error:736144198318686278>",
"success": "<:atlanta_success:736144092123234354>",
"loading": "<a:atlanta_loading:743090350490648727>",
"score": "<:atlanta_score:598175051216584744>",
"games": "<:atlanta_games:598174813860921344>",
"kills": "<:atlanta_kills:598174305599094784>",
"crown": "<:atlanta_crown:598174064183607317>",
"discriminator": "<:atlanta_discriminator:598173725497622539>",
"bot": "<:atlanta_bot:598173448543666187>",
"avatar": "<:atlanta_avatar:598173071567880192>",
"calendar": "<:atlanta_calendar:598172497912922123>",
"calendar2": "<:atlanta_calendar2:598172680889434132>",
"up": "<:atlanta_up:598171826052530196>",
"pencil": "<:atlanta_pencil:598171459960963083>",
"roles": "<:atlanta_roles:598171057345658910>",
"color": "<:atlanta_color:598170806413033472>",
"minecraft": "<:atlanta_minecraft:598170502963396620>",
"users": "<:atlanta_users:598170041510264843>",
"title": "<:atlanta_title:598169749935095818>",
"singer": "<:atlanta_singer:598169322266820630>",
"time": "<:atlanta_time:598169056125911040>",
"search": "<:atlanta_search:598168686162870283>",
"desc": "<:atlanta_desc:598168292993138689>",
"playlist": "<:atlanta_playlist:598167786195517440>",
"channels": "<:atlanta_channels:598166880271859712>",
"afk": "<:atlanta_afk:598164293598314496>",
"id": "<:atlanta_id:598162717232332811>",
"ip": "<:atlanta_ip:598161921329594368>",
"folder": "<:atlanta_folder:601019084468912129>",
"desc2": "<:atlanta_desc2:601019203721625640>",
"patreon": "<:atlanta_patreon:602163441083351051>",
"server": "<:atlanta_server:610825960853471242>",
"boost": "<:atlanta_boost:629316191797641248>",
"cool": "<:cool:957690472573325383>",
"notcool": "<:notcool:957690532203724862>",
"status": {
"dnd": "<:atlanta_dnd:616613445252546570>",
"idle": "<:atlanta_idle:616613445290164224>",
"online": "<:atlanta_online:616613445424513028>",
"offline": "<:atlanta_offline:616613445487558696>"
},
"afk": "<:afk:1275714552440295499>",
"boost": "<:boost:1268237342100033591>",
"bot": "<:bot:1268237356066934865>",
"calendar": "<:calendar:1268237366401831015>",
"calendar2": "<:calendar2:1268237375352340500>",
"channels": "<:channels:1268237403131219969>",
"color": "<:color:1275714517954723880>",
"cool": "<:cool:1268237412979445780>",
"crown": "<:crown:1268237425910485084>",
"error": "<:error:1268237435331149985>",
"roles": "<:roles:1276435229862658141>",
"id": "<:id:1275714562053771294>",
"link": "<:link:1268237497758908567>",
"notcool": "<:notcool:1268237504352489513>",
"pencil": "<:pencil:1268237511814025266>",
"ram": "<:ram:1268237517979779244>",
"stats": "<:stats:1268237534471917599>",
"success": "<:success:1268237569510867067>",
"title": "<:title:1275714991529398333>",
"users": "<:users:1268237577958461592>",
"version": "<:version:1268237586439213140>",
"voice": "<:voice:1268237596392292352>",
"letters": {
"a": "<:atlanta_a:616628945059840000>",
"w": "<:atlanta_w:616628945269424158>",
"r": "<:atlanta_r:616628944732422212>",
"d": "<:atlanta_d:616628944942268456>"
"a": "<:letter_a:1268237457019764836>",
"d": "<:letter_d:1268237464229904424>",
"r": "<:letter_r:1268237470722560021>",
"w": "<:letter_w:1268237479190728715>"
},
"categories": {
"administration": "<:atlanta_administration_category:789030159419310101>",
"economy": "<:atlanta_economy_category:789030493793288212>",
"fun": "<:atlanta_fun_category:789030226607996958>",
"general": "<:atlanta_general_category:789030444167200808>",
"images": "<:atlanta_images_category:789030084861362257>",
"moderation": "<:atlanta_moderation_category:789030389741781033>",
"music": "<:atlanta_music_category:789030283637948417>",
"nsfw": ":smirk:",
"owner": "<:atlanta_owner_category:789030328261410836>",
"custom": "<:atlanta_custom_category:789029974379462686>"
"status": {
"dnd": "<:status_dnd:1268237541379805314>",
"idle": "<:status_idle:1268237548308926516>",
"offline": "<:status_offline:1268237556084903997>",
"online": "<:status_online:1268237561793609852>"
}
}

View file

@ -10,16 +10,17 @@ class CommandHandler extends BaseEvent {
}
/**
*
* Handles command interaction events.
* @param {import("../base/Client")} client
* @param {import("discord.js").CommandInteraction} interaction
*/
async execute(client, interaction) {
if (interaction.isButton() && interaction.customId === "quote_delete" && interaction.message.deletable) return interaction.message.delete();
const command = client.commands.get(interaction.commandName);
if (!command) return;
const data = [];
data.user = await client.getUserData(interaction.user.id);
const data = { user: await client.getUserData(interaction.user.id) };
if (interaction.inGuild()) {
data.guild = await client.getGuildData(interaction.guildId);
@ -28,46 +29,40 @@ class CommandHandler extends BaseEvent {
interaction.data = data;
if (interaction.isButton() && interaction.customId === "quote_delete" && interaction.message.deletable) return interaction.message.delete();
if (interaction.isAutocomplete()) return await command.autocompleteRun(client, interaction);
if (interaction.type !== InteractionType.ApplicationCommand || !interaction.isCommand()) return;
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 });
if (command.ownerOnly && interaction.user.id !== client.config.owner.id) return interaction.error("misc:OWNER_ONLY", null, { 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 (!interaction.data.user.achievements.firstCommand.achieved) {
const args = {
content: interaction.user.toString(),
files: [
{
name: "achievement_unlocked2.png",
attachment: "./assets/img/achievements/achievement_unlocked2.png",
},
],
};
interaction.data.user.achievements.firstCommand.progress.now = 1;
interaction.data.user.achievements.firstCommand.achieved = true;
// First command achievement check
const { firstCommand } = interaction.data.user.achievements;
if (!firstCommand.achieved) {
firstCommand.progress.now = 1;
firstCommand.achieved = true;
await interaction.data.user.save();
const message = {
content: interaction.user.toString(),
files: [{ name: "achievement_unlocked2.png", attachment: "./assets/img/achievements/achievement_unlocked2.png" }],
};
try {
interaction.user.send(args);
} catch (e) { /**/ }
await interaction.user.send(message);
} catch (e) {
client.logger.warn("Failed to send achievement message to user:", e);
}
}
client.logger.cmd(
`[${interaction.guild ? interaction.guild.name : "DM"}]: [${interaction.user.getUsername()}] => /${command.command.name}${
interaction.options.data.length > 0
? `, args: [${interaction.options.data
.map(arg => {
return `${arg.name}: ${arg.value}`;
})
.join(", ")}]`
: ""
}`,
);
// Command logging
const args = interaction.options.data.map(arg => `${arg.name}: ${arg.value}`).join(", ");
client.logger.cmd(`[${interaction.guild ? interaction.guild.name : "DM/Private Channel"}]: [${interaction.user.tag}] => /${command.command.name}${args ? `, args: [${args}]` : ""}`);
return command.execute(client, interaction);
}

View file

@ -23,7 +23,7 @@ class guildBanAdd extends BaseEvent {
});
try {
ban.user.send({
await ban.user.send({
embeds: [embed],
});
} catch (e) { /**/ }

View file

@ -23,23 +23,25 @@ class GuildCreate extends BaseEvent {
await userData.save();
}
const thanks = client.embed({
const embed = client.embed({
author: "Thanks for inviting me to your server!",
description: "Use </help:1029832476077596773> in your server to get list of all commands!.",
description: "Use </help:1029832476077596773> in your server to get a list of all commands!",
});
try {
const owner = await guild.fetchOwner();
owner.send({
await owner.send({
files: [
{
name: "unlocked.png",
attachment: "./assets/img/achievements/achievement_unlocked7.png",
},
],
embeds: [thanks],
embeds: [embed],
});
} catch (e) { /**/ }
} catch (e) {
client.logger.error(`Failed to send welcome message to guild owner: ${e.message}`);
}
if (client.config.support.logs) {
const users = guild.members.cache.filter(m => !m.user.bot).size;
@ -48,14 +50,22 @@ class GuildCreate extends BaseEvent {
const embed = client.embed({
author: {
name: guild.name,
iconURL: guild.iconURL(),
iconURL: guild.iconURL() || client.user.avatarURL(),
},
description: `Joined a new guild **${guild.name}**. It has **${users}** ${client.functions.getNoun(users, client.translate("misc:NOUNS:USERS:1"), client.translate("misc:NOUNS:USERS:2"), client.translate("misc:NOUNS:USERS:5"))} and **${bots}** ${client.functions.getNoun(bots, client.translate("misc:NOUNS:BOTS:1"), client.translate("misc:NOUNS:BOTS:2"), client.translate("misc:NOUNS:BOTS:5"))}`,
description: `Joined a new guild **${guild.name}**. It has **${users}** ${client.functions.getNoun(
users,
client.translate("misc:NOUNS:USERS:1"),
client.translate("misc:NOUNS:USERS:2"),
client.translate("misc:NOUNS:USERS:5"),
)} and **${bots}** ${client.functions.getNoun(bots, client.translate("misc:NOUNS:BOTS:1"), client.translate("misc:NOUNS:BOTS:2"), client.translate("misc:NOUNS:BOTS:5"))}.`,
});
client.channels.cache.get(client.config.support.logs).send({
embeds: [embed],
});
const logChannel = client.channels.cache.get(client.config.support.logs);
if (logChannel)
await logChannel.send({
embeds: [embed],
});
}
}
}

View file

@ -18,14 +18,18 @@ class GuildDelete extends BaseEvent {
const embed = client.embed({
author: {
name: guild.name,
iconURL: guild.iconURL(),
iconURL: guild.iconURL() || client.user.avatarURL(),
},
description: `Left from guild **${guild.name}**.`,
});
client.channels.cache.get(client.config.support.logs).send({
embeds: [embed],
});
const logChannel = client.channels.cache.get(client.config.support.logs);
if (logChannel)
await logChannel.send({
embeds: [embed],
});
else client.logger.warn(`Log channel not found for guild deletion: ${guild.name}`);
}
}
}

View file

@ -1,8 +1,3 @@
// const Canvas = require("@napi-rs/canvas"),
// BaseEvent = require("../../base/BaseEvent"),
// { AttachmentBuilder } = require("discord.js"),
// { applyText } = require("../../helpers/functions");
const BaseEvent = require("../../base/BaseEvent");
class GuildMemberAdd extends BaseEvent {
@ -19,13 +14,18 @@ class GuildMemberAdd extends BaseEvent {
* @param {import("discord.js").GuildMember} member
*/
async execute(client, member) {
if (member.guild && member.guildId === "568120814776614924") return;
await member.guild.members.fetch();
const guildData = await client.getGuildData(member.guild.id);
if (guildData.plugins.autorole.enabled) member.roles.add(guildData.plugins.autorole.role);
if (guildData.plugins.autorole.enabled) {
const role = guildData.plugins.autorole.role;
if (role) {
await member.roles.add(role).catch(err => {
client.logger.error(`Failed to add role to ${member.user.tag}: ${err}`);
});
}
}
if (guildData.plugins.welcome.enabled) {
const channel = member.guild.channels.cache.get(guildData.plugins.welcome.channel);
@ -36,103 +36,11 @@ class GuildMemberAdd extends BaseEvent {
.replace(/{server}/g, member.guild.name)
.replace(/{membercount}/g, member.guild.memberCount);
/*
if (guildData.plugins.welcome.withImage) {
const canvas = Canvas.createCanvas(1024, 450),
ctx = canvas.getContext("2d");
// Draw background
const background = await Canvas.loadImage("./assets/img/greetings_background.png");
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
// Draw layer
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(0, 0, 25, canvas.height);
ctx.fillRect(canvas.width - 25, 0, 25, canvas.height);
ctx.fillRect(25, 0, canvas.width - 50, 25);
ctx.fillRect(25, canvas.height - 25, canvas.width - 50, 25);
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(344, canvas.height - 296, 625, 65);
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(389, canvas.height - 225, 138, 65);
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(308, canvas.height - 110, 672, 65);
// Draw username
ctx.globalAlpha = 1;
ctx.fillStyle = "#FFFFFF";
ctx.font = applyText(canvas, member.user.username, 48, 600, "RubikMonoOne");
ctx.fillText(member.user.username, canvas.width - 670, canvas.height - 250);
// Draw server name
ctx.font = applyText(
canvas,
client.translate("administration/welcome:IMG_WELCOME", {
server: member.guild.name,
}, guildData.language),
53,
625,
"RubikMonoOne",
);
ctx.fillText(
client.translate("administration/welcome:IMG_WELCOME", {
server: member.guild.name,
}, guildData.language),
canvas.width - 700,
canvas.height - 70,
);
// Draw discriminator
ctx.font = "35px RubikMonoOne";
ctx.fillText(member.user.discriminator === "0" ? "" : member.user.discriminator, canvas.width - 623, canvas.height - 178);
// Draw membercount
ctx.font = "22px RubikMonoOne";
ctx.fillText(`${member.guild.memberCount}й ${client.translate("misc:NOUNS:MEMBERS:1", null, guildData.language)}`, 40, canvas.height - 35);
// Draw # for discriminator
ctx.fillStyle = "#FFFFFF";
ctx.font = "70px RubikMonoOne";
ctx.fillText(member.user.discriminator === "0" ? "" : "#", canvas.width - 690, canvas.height - 165);
// Draw title
ctx.font = "45px RubikMonoOne";
ctx.strokeStyle = "#000000";
ctx.lineWidth = 10;
ctx.strokeText(client.translate("administration/welcome:TITLE", null, guildData.language), canvas.width - 670, canvas.height - 330);
ctx.fillStyle = "#FFFFFF";
ctx.fillText(client.translate("administration/welcome:TITLE", null, guildData.language), canvas.width - 670, canvas.height - 330);
// Draw avatar circle
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = "#FFFFFF";
ctx.arc(180, 225, 135, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.clip();
const avatar = await Canvas.loadImage(
member.displayAvatarURL({
extension: "jpg",
}),
);
ctx.drawImage(avatar, 45, 90, 270, 270);
const attachment = new AttachmentBuilder((await canvas.encode("png")), { name: "welcome.png" });
channel.send({
content: message,
files: [attachment],
});
} else */
channel.send({ content: message });
await channel.send({ content: message }).catch(err => {
client.logger.error(`Failed to send welcome message in channel ${channel.id}: ${err}`);
});
} else {
client.logger.warn(`Welcome channel not found: ${guildData.plugins.welcome.channel}`);
}
}
}

View file

@ -1,8 +1,3 @@
// const Canvas = require("@napi-rs/canvas"),
// BaseEvent = require("../../base/BaseEvent"),
// { AttachmentBuilder } = require("discord.js"),
// { applyText } = require("../../helpers/functions");
const BaseEvent = require("../../base/BaseEvent");
class GuildMemberRemove extends BaseEvent {
@ -19,8 +14,6 @@ class GuildMemberRemove extends BaseEvent {
* @param {import("discord.js").GuildMember} member
*/
async execute(client, member) {
if (member.guild && member.guildId === "568120814776614924") return;
await member.guild.members.fetch();
const guildData = await client.getGuildData(member.guild.id);
@ -34,108 +27,11 @@ class GuildMemberRemove extends BaseEvent {
.replace(/{server}/g, member.guild.name)
.replace(/{membercount}/g, member.guild.memberCount);
/*
if (guildData.plugins.goodbye.withImage) {
const canvas = Canvas.createCanvas(1024, 450),
ctx = canvas.getContext("2d");
// Draw background
const background = await Canvas.loadImage("./assets/img/greetings_background.png");
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
// Draw layer
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(0, 0, 25, canvas.height);
ctx.fillRect(canvas.width - 25, 0, 25, canvas.height);
ctx.fillRect(25, 0, canvas.width - 50, 25);
ctx.fillRect(25, canvas.height - 25, canvas.width - 50, 25);
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(344, canvas.height - 296, 625, 65);
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(389, canvas.height - 225, 138, 65);
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = "0.4";
ctx.fillRect(308, canvas.height - 110, 672, 65);
// Draw username
ctx.globalAlpha = 1;
ctx.fillStyle = "#FFFFFF";
ctx.font = applyText(canvas, member.user.username, 48, 600, "RubikMonoOne");
ctx.fillText(member.user.username, canvas.width - 670, canvas.height - 250);
// Draw server name
ctx.font = applyText(
canvas,
client.translate("administration/goodbye:IMG_GOODBYE", {
server: member.guild.name,
}, guildData.language),
53,
625,
"RubikMonoOne",
);
ctx.fillText(
client.translate("administration/goodbye:IMG_GOODBYE", {
server: member.guild.name,
}, guildData.language),
canvas.width - 700,
canvas.height - 70,
);
// Draw discriminator
ctx.font = "35px RubikMonoOne";
ctx.fillText(member.user.discriminator === "0" ? "" : member.user.discriminator, canvas.width - 623, canvas.height - 178);
// Draw membercount
ctx.font = "22px RubikMonoOne";
ctx.fillText(
`${member.guild.memberCount} ${client.functions.getNoun(member.guild.memberCount, client.translate("misc:NOUNS:MEMBERS:1", null, guildData.language), client.translate("misc:NOUNS:MEMBERS:2", null, guildData.language), client.translate("misc:NOUNS:MEMBERS:5", null, guildData.language))}`,
40,
canvas.height - 35,
);
// Draw # for discriminator
ctx.fillStyle = "#FFFFFF";
ctx.font = "70px RubikMonoOne";
ctx.fillText(member.user.discriminator === "0" ? "" : "#", canvas.width - 690, canvas.height - 165);
// Draw title
ctx.font = "45px RubikMonoOne";
ctx.strokeStyle = "#000000";
ctx.lineWidth = 10;
ctx.strokeText(client.translate("administration/goodbye:TITLE", null, guildData.language), canvas.width - 670, canvas.height - 330);
ctx.fillStyle = "#FFFFFF";
ctx.fillText(client.translate("administration/goodbye:TITLE", null, guildData.language), canvas.width - 670, canvas.height - 330);
// Draw avatar circle
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = "#FFFFFF";
ctx.arc(180, 225, 135, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.clip();
const avatar = await Canvas.loadImage(
member.displayAvatarURL({
extension: "png",
size: 512,
}),
);
ctx.drawImage(avatar, 45, 90, 270, 270);
const attachment = new AttachmentBuilder((await canvas.encode("png")), { name: "goodbye-image.png" });
channel.send({
content: message,
files: [attachment],
});
} else */
channel.send({ content: message });
await channel.send({ content: message }).catch(err => {
client.logger.error(`Failed to send goodbye message in channel ${channel.id}: ${err}`);
});
} else {
client.logger.warn(`Goodbye channel not found: ${guildData.plugins.goodbye.channel}`);
}
}
}

Some files were not shown because too many files have changed in this diff Show more