Перенесена категория Moderation, возможность проигрывания музыки с YouTube Music

This commit is contained in:
JonnyBro 2022-08-06 20:47:47 +05:00
parent cf72d6e33a
commit 4756b42622
34 changed files with 716 additions and 512 deletions

View file

@ -1,39 +0,0 @@
const Command = require("../../base/Command"),
{ parseEmoji } = require("discord.js");
class Stealemoji extends Command {
constructor(client) {
super(client, {
name: "stealemoji",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["steale"],
memberPermissions: ["MANAGE_GUILD"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args) {
if (!args.length) return message.error("administration/stealemoji:MISSING_EMOJI");
for (const rawEmoji of args) {
const parsedEmoji = parseEmoji(rawEmoji);
const extension = parsedEmoji.animated ? "gif" : "png";
message.guild.emojis
.create(`https://cdn.discordapp.com/emojis/${parsedEmoji.id}.${extension}`, parsedEmoji.name)
.then(emoji => message.success("administration/stealemoji:SUCCESS", {
emoji: emoji.name
}))
.catch(() => message.error("administration/stealemoji:ERROR", {
emoji: parsedEmoji.name
}));
}
}
}
module.exports = Stealemoji;

View file

@ -1,80 +0,0 @@
const Command = require("../../base/Command");
class Clear extends Command {
constructor(client) {
super(client, {
name: "clear",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["cl", "purge"],
memberPermissions: ["MANAGE_MESSAGES"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "MANAGE_MESSAGES"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args) {
if (args[0] === "all") {
message.channel.send(message.translate("moderation/clear:ALL_CONFIRM"));
const filter = m => m.author.id === message.author.id && m.content === "confirm";
const collector = message.channel.createMessageCollector({
filter,
time: 120000 // 2 minutes
});
collector.on("collect", async message => {
const position = message.channel.position;
const newChannel = await message.channel.clone();
await message.channel.delete();
newChannel.setPosition(position);
return newChannel.send({
content: message.translate("moderation/clear:CHANNEL_CLEARED")
});
});
collector.on("end", (_, reason) => {
if (reason === "time") return message.error("misc:TIMES_UP");
});
} else {
const amount = args[0];
if (!amount || isNaN(amount) || parseInt(amount) < 1) return message.error("moderation/clear:MISSING_AMOUNT");
await message.delete();
const user = message.mentions.users.first();
let messages = await message.channel.messages.fetch({
limit: amount
});
if (user) messages = messages.filter((m) => m.author.id === user.id);
if (messages.length > amount) messages.length = parseInt(amount, 10);
messages = messages.filter((m) => !m.pinned);
message.channel.bulkDelete(messages, true);
let toDelete = null;
if (user) {
toDelete = await message.channel.send(message.translate("moderation/clear:CLEARED_MEMBER", {
amount: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:MESSAGES:1"), message.translate("misc:NOUNS:MESSAGES:2"), message.translate("misc:NOUNS:MESSAGES:5"))}`,
username: user.tag
}));
} else {
toDelete = await message.channel.send(message.translate("moderation/clear:CLEARED", {
amount: `${amount} ${message.getNoun(amount, message.translate("misc:NOUNS:MESSAGES:1"), message.translate("misc:NOUNS:MESSAGES:2"), message.translate("misc:NOUNS:MESSAGES:5"))}`
}));
}
setTimeout(function () {
toDelete.delete();
}, 2000);
}
}
}
module.exports = Clear;

View file

@ -1,35 +0,0 @@
const Command = require("../../base/Command");
class Clearwarns extends Command {
constructor(client) {
super(client, {
name: "clearwarns",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["clearw", "clw"],
memberPermissions: ["MANAGE_MESSAGES"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args) {
const member = await this.client.resolveMember(args[0], message.guild);
if (!member) return message.error("moderation/clearwarns:MISSING_MEMBER");
const memberData = await this.client.findOrCreateMember({
id: member.id,
guildID: message.guild.id
});
memberData.sanctions = [];
memberData.save();
message.success("moderation/clearwarns:SUCCESS", {
username: member.user.tag
});
}
}
module.exports = Clearwarns;

View file

@ -1,127 +0,0 @@
const Command = require("../../base/Command"),
ms = require("ms");
class Giveaway extends Command {
constructor(client) {
super(client, {
name: "giveaway",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["gaway"],
memberPermissions: ["MENTION_EVERYONE"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const status = args[0];
if (!status) return message.error("moderation/giveaway:MISSING_STATUS");
if (status === "create") {
const currentGiveaways = this.client.giveawaysManager.giveaways.filter((g) => g.guildId === message.guild.id && !g.ended).length;
if (currentGiveaways > 3) return message.error("moderation/giveaway:MAX_COUNT");
const time = args[1];
if (!time) return message.error("moderation/giveaway:INVALID_CREATE", { prefix: data.guild.prefix });
if (isNaN(ms(time))) return message.error("misc:INVALID_TIME");
if (ms(time) > ms("15d")) return message.error("moderation/giveaway:MAX_DURATION");
const winnersCount = args[2];
if (!winnersCount) return message.error("moderation/giveaway:INVALID_CREATE", { prefix: data.guild.prefix });
if (isNaN(winnersCount) || winnersCount > 10 || winnersCount < 1) return message.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: 10 });
const drop = (args[3] === "true");
let prize = args.slice(3).join(" ");
if (drop) prize = args.slice(4).join(" ");
else prize = args.slice(3).join(" ");
if (!prize) return message.error("moderation/giveaway:INVALID_CREATE", { prefix: data.guild.prefix });
this.client.giveawaysManager.start(message.channel, {
duration: ms(time),
winnerCount: parseInt(winnersCount, 10),
prize: prize,
hostedBy: message.author,
isDrop: drop,
messages: {
giveaway: message.translate("moderation/giveaway:TITLE"),
giveawayEnded: message.translate("moderation/giveaway:ENDED"),
timeRemaining: message.translate("moderation/giveaway:TIME_REMAINING"),
inviteToParticipate: message.translate("moderation/giveaway:INVITE_PARTICIPATE"),
winMessage: message.translate("moderation/giveaway:WIN_MESSAGE"),
drawing: message.translate("moderation/giveaway:DRAWING"),
dropMessage: message.translate("moderation/giveaway:DROP"),
embedFooter: message.translate("moderation/giveaway:FOOTER"),
noWinner: message.translate("moderation/giveaway:NO_WINNER"),
winners: message.translate("moderation/giveaway:WINNERS"),
endedAt: message.translate("moderation/giveaway:END_AT"),
hostedBy: message.translate("moderation/giveaway:HOSTEDBY"),
units: {
seconds: message.translate("time:SECONDS", {
amount: ""
}).trim(),
minutes: message.translate("time:MINUTES", {
amount: ""
}).trim(),
hours: message.translate("time:HOURS", {
amount: ""
}).trim(),
days: message.translate("time:DAYS", {
amount: ""
}).trim()
}
}
}).then(() => {
message.success("moderation/giveaway:GIVEAWAY_CREATED");
});
} else if (status === "reroll") {
const messageID = args[1];
if (!messageID) return message.error("moderation/giveaway:MISSING_ID");
this.client.giveawaysManager.reroll(messageID, {
messages: {
congrat: message.translate("moderation/giveaway:REROLL_CONGRAT"),
error: message.translate("moderation/giveaway:REROLL_ERROR")
}
}).then(() => {
return message.success("moderation/giveaway:GIVEAWAY_REROLLED");
}).catch(() => {
return message.error("moderation/giveaway:NOT_FOUND_ENDED", {
messageID
});
});
} else if (status === "delete") {
const messageID = args[1];
if (!messageID) return message.error("moderation/giveaway:MISSING_ID");
this.client.giveawaysManager.delete(messageID).then(() => {
return message.success("moderation/giveaway:GIVEAWAY_DELETED");
}).catch(() => {
return message.error("moderation/giveaway:NOT_FOUND", {
messageID
});
});
} else if (status === "end") {
const messageID = args[1];
if (!messageID) return message.error("moderation/giveaway:MISSING_ID");
try {
this.client.giveawaysManager.end(messageID);
return message.success("moderation/giveaway:GIVEAWAY_ENDED");
} catch (e) {
return message.error("moderation/giveaway:NOT_FOUND", {
messageID
});
}
} else {
return message.error("moderation/giveaway:MISSING_STATUS");
}
}
}
module.exports = Giveaway;

View file

@ -1,114 +0,0 @@
const Command = require("../../base/Command"),
Discord = require("discord.js");
class Poll extends Command {
constructor(client) {
super(client, {
name: "poll",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["po"],
memberPermissions: ["MANAGE_MESSAGES"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args, data) {
const question = args.join(" ");
if (!question) return message.error("moderation/poll:MISSING_QUESTION");
let mention = null;
const msg = await message.sendT("moderation/announcement:MENTION_PROMPT");
const filter = m => m.author.id === message.author.id;
const collector = new Discord.MessageCollector(message.channel, {
filter,
time: 240000
});
collector.on("collect", async tmsg => {
if (tmsg.content.toLowerCase() === message.translate("common:NO").toLowerCase()) {
tmsg.delete();
msg.delete();
collector.stop(true);
message.delete();
}
if (tmsg.content.toLowerCase() === message.translate("common:YES").toLowerCase()) {
tmsg.delete();
msg.delete();
const tmsg1 = await message.channel.send(message.translate("moderation/announcement:MENTION_TYPE_PROMPT"));
const filter = m => m.author.id === message.author.id;
const c = new Discord.MessageCollector(message.channel, {
filter,
time: 60000
});
c.on("collect", (m) => {
if (m.content.toLowerCase() === "here") {
mention = "@here";
tmsg1.delete();
m.delete();
collector.stop(true);
c.stop(true);
} else if (m.content.toLowerCase() === "everyone") {
mention = "@everyone";
tmsg1.delete();
m.delete();
collector.stop(true);
c.stop(true);
}
});
c.on("end", (collected, reason) => {
if (reason === "time") return message.error("misc:TIMES_UP");
});
message.delete();
}
});
collector.on("end", (collected, reason) => {
if (reason === "time") return message.error("misc:TIMES_UP");
const success = this.client.customEmojis.success.split(":")[1];
const error = this.client.customEmojis.error.split(":")[1];
const emojis = [
this.client.emojis.cache.find(e => e.name === success),
this.client.emojis.cache.find(e => e.name === error)
];
const embed = new Discord.EmbedBuilder()
.setAuthor({
name: message.translate("moderation/poll:TITLE")
})
.setColor(data.config.embed.color)
.addFields([
{
name: question,
value: message.translate("moderation/poll:REACT", {
success: emojis[0].toString(),
error: emojis[1].toString()
})
}
]);
message.channel.send({
content: mention,
embeds: [embed]
}).then(async (m) => {
await m.react(emojis[0]);
await m.react(emojis[1]);
});
});
}
}
module.exports = Poll;

View file

@ -1,60 +0,0 @@
const Command = require("../../base/Command");
class Unban extends Command {
constructor(client) {
super(client, {
name: "unban",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["ub"],
memberPermissions: ["BAN_MEMBERS"],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "BAN_MEMBERS"],
nsfw: false,
ownerOnly: false,
cooldown: 1000
});
}
async run(message, args) {
let user = null;
if (!args[0]) return message.error("moderation/unban:MISSING_ID");
// Check if the arg is an ID or a username
const isId = !isNaN(args[0]);
if (isId) {
// Try to find a user with that ID
await this.client.users.fetch(args[0]).then((u) => {
// if a user was found
user = u;
}).catch(() => {});
} else if (!isId) {
const arr = args[0].split("#");
if (arr.length < 2) {
return message.error("misc:NO_USER_FOUND_ID", {
id: args[0]
});
}
user = this.client.users.filter((u) => u.username === arr[0]).find((u) => u.discriminator === arr[1]);
}
if (!user) return message.error("misc:NO_USER_FOUND_ID", { id: args[0] });
// check if the user is banned
const banned = await message.guild.bans.fetch();
if (!banned.some((e) => e.user.id === user.id)) return message.success("moderation/unban:NOT_BANNED", { username: user.tag });
// Unban user
message.guild.members.unban(user).catch(() => {});
// Send a success message in the current channel
message.success("moderation/unban:UNBANNED", {
username: user.tag,
server: message.guild.name
});
}
}
module.exports = Unban;

View file

@ -0,0 +1,57 @@
const { SlashCommandBuilder, parseEmoji, PermissionFlagsBits } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Stealemoji extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("stealemoji")
.setDescription(client.translate("administration/stealemoji:DESCRIPTION"))
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
.addStringOption(option => option.setName("emoji")
.setDescription(client.translate("common:EMOJI"))
.setRequired(true)),
aliases: [],
dirname: __dirname,
guildOnly: true
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const parsedEmoji = parseEmoji(interaction.options.getString("emoji"));
const ext = parsedEmoji.animated ? "gif" : "png";
interaction.guild.emojis
.create({
name: parsedEmoji.name,
attachment: `https://cdn.discordapp.com/emojis/${parsedEmoji.id}.${ext}`
})
.then(emoji => interaction.success("administration/stealemoji:SUCCESS", {
emoji: emoji.name
}, { ephemeral: true }))
.catch(e => {
console.log(e);
interaction.error("administration/stealemoji:ERROR", {
emoji: parsedEmoji.name
}, { ephemeral: true });
});
}
}
module.exports = Stealemoji;

View file

@ -53,14 +53,16 @@ class Memes extends BaseCommand {
fetchReply: true
});
const filter = i => i.customId === "memes_select" && i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, {
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: 60 * 1000
idle: 30 * 1000
});
collector.on("collect", async msg => {
const tag = msg?.values[0];
collector.on("collect", async i => {
const tag = i?.values[0];
const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json());
const embed = new EmbedBuilder()
@ -72,7 +74,7 @@ class Memes extends BaseCommand {
.setImage(res.url)
.setTimestamp();
await msg.update({
await i.update({
embeds: [embed]
});
});

View file

@ -59,14 +59,16 @@ class Activity extends BaseCommand {
fetchReply: true
});
const filter = i => i.customId === "activity_select" && i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, {
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: 60 * 1000
idle: 30 * 1000
});
collector.on("collect", async msg => {
const activity = msg?.values[0];
collector.on("collect", async i => {
const activity = i?.values[0];
const invite = await client.discordTogether.createTogetherCode(voice.id, activity);
const embed = new EmbedBuilder()
@ -78,7 +80,7 @@ class Activity extends BaseCommand {
})
.setTimestamp();
await msg.update({
await i.update({
embeds: [embed],
components: []
});

View file

@ -59,6 +59,10 @@ class Emoji extends BaseCommand {
{
name: interaction.translate("general/emoji:ID"),
value: parsedEmoji.id?.toString() || interaction.translate("general/emoji:STANDART")
},
{
name: interaction.translate("general/emoji:LINK"),
value: `https://cdn.discordapp.com/emojis/${parsedEmoji.id}.${parsedEmoji.animated ? "gif" : "png"}`
}
]);

View file

@ -37,7 +37,6 @@ class Report extends BaseCommand {
* @param {Array} data
*/
async execute(client, interaction) {
if (interaction.user.id === "285109105717280768") return interaction.reply({ content: "Пошёл нахуй фахон" });
const repChannel = interaction.guild.channels.cache.get(interaction.guild.data.plugins.reports);
if (!repChannel) return interaction.error("general/report:MISSING_CHANNEL");
const member = interaction.options.getMember("user");
@ -85,7 +84,7 @@ class Report extends BaseCommand {
repChannel.send({
embeds: [embed]
}).then(async (m) => {
}).then(async m => {
await m.react(success);
await m.react(error);
});

View file

@ -34,7 +34,6 @@ class Suggest extends BaseCommand {
* @param {Array} data
*/
async execute(client, interaction) {
if (interaction.user.id === "285109105717280768") return interaction.reply({ content: "Пошёл нахуй фахон" });
const suggChannel = interaction.guild.channels.cache.get(interaction.guild.data.plugins.suggestions);
if (!suggChannel) return interaction.error("general/suggest:MISSING_CHANNEL");
const suggestion = interaction.options.getString("message");
@ -74,7 +73,7 @@ class Suggest extends BaseCommand {
suggChannel.send({
embeds: [embed]
}).then(async (m) => {
}).then(async m => {
await m.react(success);
await m.react(error);
});

View file

@ -0,0 +1,110 @@
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionFlagsBits } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Clear extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("clear")
.setDescription(client.translate("moderation/clear:DESCRIPTION"))
.setDefaultMemberPermissions(PermissionFlagsBits.ModerateMembers && PermissionFlagsBits.ManageMessages)
.addStringOption(option => option.setName("option")
.setDescription(client.translate("moderation/clear:OPTION"))
.setRequired(true))
.addUserOption(option => option.setName("user")
.setDescription(client.translate("common:USER"))),
aliases: [],
dirname: __dirname,
guildOnly: true
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const option = interaction.options.getString("option");
const member = interaction.options.getMember("user");
if (option === "all") {
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId("clear_confirm_yes")
.setLabel(interaction.translate("common:ACCEPT"))
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId("clear_confirm_no")
.setLabel(interaction.translate("common:CANCEL"))
.setStyle(ButtonStyle.Secondary),
);
await interaction.reply({
content: interaction.translate("moderation/clear:ALL_CONFIRM"),
ephemeral: true,
components: [row]
});
const filter = i => i.user.id === interaction.user.id;
const collector = interaction.channel.createMessageComponentCollector({ filter, time: 15000 });
collector.on("collect", async i => {
if (i.isButton()) {
if (i.customId === "clear_confirm_yes") {
const position = interaction.channel.position;
const newChannel = await interaction.channel.clone();
await interaction.channel.delete();
newChannel.setPosition(position);
await newChannel.send({
content: interaction.translate("moderation/clear:CHANNEL_CLEARED")
});
} else if (i.customId === "clear_confirm_no") {
row.components[0].setDisabled(true);
row.components[1].setDisabled(true);
i.update({
content: interaction.translate("misc:SELECT_CANCELED")
});
}
}
});
} else {
if (isNaN(option) || parseInt(option) < 1) return interaction.error("moderation/clear:OPTION_NAN", null, { ephemeral: true });
let messages = await interaction.channel.messages.fetch({
limit: option
});
if (member) messages = messages.filter(m => m.author.id === member.id);
if (messages.length > option) messages.length = parseInt(option, 10);
interaction.channel.bulkDelete(messages.filter(m => !m.pinned), true);
if (member) {
interaction.replyT("moderation/clear:CLEARED_MEMBER", {
amount: `${option} ${client.getNoun(option, interaction.translate("misc:NOUNS:MESSAGES:1"), interaction.translate("misc:NOUNS:MESSAGES:2"), interaction.translate("misc:NOUNS:MESSAGES:5"))}`,
username: member.user.tag
}, { ephemeral: true });
} else {
interaction.replyT("moderation/clear:CLEARED", {
amount: `${option} ${client.getNoun(option, interaction.translate("misc:NOUNS:MESSAGES:1"), interaction.translate("misc:NOUNS:MESSAGES:2"), interaction.translate("misc:NOUNS:MESSAGES:5"))}`
}, { ephemeral: true });
}
}
}
}
module.exports = Clear;

View file

@ -0,0 +1,52 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Clearwarns extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("clearwarns")
.setDescription(client.translate("moderation/clearwarns:DESCRIPTION"))
.setDefaultMemberPermissions(PermissionFlagsBits.ModerateMembers && PermissionFlagsBits.ManageMessages)
.addUserOption(option => option.setName("user")
.setDescription(client.translate("common:USER"))
.setRequired(true)),
aliases: [],
dirname: __dirname,
guildOnly: true
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const member = interaction.options.getMember("user");
const memberData = await client.findOrCreateMember({
id: member.id,
guildID: interaction.guildId
});
memberData.sanctions = [];
memberData.save();
interaction.success("moderation/clearwarns:SUCCESS", {
username: member.user.tag
});
}
}
module.exports = Clearwarns;

View file

@ -0,0 +1,196 @@
const { SlashCommandBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, ComponentType, PermissionFlagsBits } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"),
ms = require("ms");
class Giveaway extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("giveaway")
.setDescription(client.translate("moderation/giveaway:DESCRIPTION"))
.setDefaultMemberPermissions(PermissionFlagsBits.ModerateMembers && PermissionFlagsBits.ManageMessages)
.addStringOption(option => option.setName("giveaway_id")
.setDescription(client.translate("moderation/giveaway:GIVEAWAY_ID")))
.addStringOption(option => option.setName("duration")
.setDescription(client.translate("common:DURATION")))
.addStringOption(option => option.setName("winners_count")
.setDescription(client.translate("moderation/giveaway:WINNERS_COUNT")))
.addStringOption(option => option.setName("prize")
.setDescription(client.translate("moderation/giveaway:PRIZE")))
.addBooleanOption(option => option.setName("isdrop")
.setDescription(client.translate("moderation/giveaway:ISDROP"))),
aliases: [],
dirname: __dirname,
guildOnly: true
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const options = ["create", "reroll", "delete", "end"].map(tag =>
JSON.parse(JSON.stringify({
label: tag,
value: tag
}))
);
const row = new ActionRowBuilder()
.addComponents(
new SelectMenuBuilder()
.setCustomId("giveaway_select")
.setPlaceholder(client.translate("common:NOTHING_SELECTED"))
.addOptions(options)
);
const msg = await interaction.reply({
content: interaction.translate("common:AVAILABLE_CATEGORIES"),
components: [row],
ephemeral: true,
fetchReply: true
});
const filter = i => i.customId === "giveaway_select" && i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, {
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: 30 * 1000
});
collector.on("collect", async i => {
const option = i?.values[0];
if (option === "create") {
const currentGiveaways = client.giveawaysManager.giveaways.filter(g => g.guildId === interaction.guild.id && !g.ended).length;
if (currentGiveaways > 5) return i.update({ content: interaction.translate("moderation/giveaway:MAX_COUNT") });
const duration = interaction.options.getString("duration");
if (!duration) return i.update({ content: interaction.translate("moderation/giveaway:INVALID_CREATE") });
if (ms(duration) > ms("10d")) return i.update({ content: interaction.translate("moderation/giveaway:MAX_DURATION") });
const winnersCount = interaction.options.getString("winners_count");
if (!winnersCount) return i.update({ content: interaction.translate("moderation/giveaway:INVALID_CREATE") });
if (isNaN(winnersCount) || winnersCount > 10 || winnersCount < 1) return i.update({ content: interaction.translate("misc:INVALID_NUMBER_RANGE", { min: 1, max: 10 }) });
const prize = interaction.options.getString("prize");
if (!prize) return i.update({ content: interaction.translate("moderation/giveaway:INVALID_CREATE") });
const isdrop = interaction.options.getString("isdrop");
client.giveawaysManager.start(interaction.channel, {
duration: ms(duration),
winnerCount: winnersCount,
prize: prize,
hostedBy: interaction.user,
isDrop: isdrop,
messages: {
giveaway: interaction.translate("moderation/giveaway:TITLE"),
giveawayEnded: interaction.translate("moderation/giveaway:ENDED"),
timeRemaining: interaction.translate("moderation/giveaway:TIME_REMAINING"),
inviteToParticipate: interaction.translate("moderation/giveaway:INVITE_PARTICIPATE"),
winMessage: interaction.translate("moderation/giveaway:WIN_MESSAGE"),
drawing: interaction.translate("moderation/giveaway:DRAWING"),
dropMessage: interaction.translate("moderation/giveaway:DROP"),
embedFooter: interaction.translate("moderation/giveaway:FOOTER"),
noWinner: interaction.translate("moderation/giveaway:NO_WINNER"),
winners: interaction.translate("moderation/giveaway:WINNERS"),
endedAt: interaction.translate("moderation/giveaway:END_AT"),
hostedBy: interaction.translate("moderation/giveaway:HOSTEDBY"),
// units: {
// seconds: interaction.translate("time:SECONDS", {
// amount: ""
// }).trim(),
// minutes: interaction.translate("time:MINUTES", {
// amount: ""
// }).trim(),
// hours: interaction.translate("time:HOURS", {
// amount: ""
// }).trim(),
// days: interaction.translate("time:DAYS", {
// amount: ""
// }).trim()
// }
}
}).then(() => {
return i.update({
content: interaction.translate("moderation/giveaway:GIVEAWAY_CREATED"),
components: []
});
});
} else if (option === "reroll") {
const giveaway_id = interaction.options.getString("giveaway_id");
if (!giveaway_id) return i.update({ content: interaction.translate("moderation/giveaway:MISSING_ID"), components: [] });
client.giveawaysManager.reroll(giveaway_id, {
messages: {
congrat: interaction.translate("moderation/giveaway:REROLL_CONGRAT"),
error: interaction.translate("moderation/giveaway:REROLL_ERROR")
}
}).then(() => {
return i.update({
content: interaction.translate("moderation/giveaway:GIVEAWAY_REROLLED"),
components: []
});
}).catch(() => {
return i.update({
content: interaction.translate("moderation/giveaway:NOT_FOUND_ENDED", {
messageId: giveaway_id
}),
components: []
});
});
} else if (option === "delete") {
const giveaway_id = interaction.options.getString("giveaway_id");
if (!giveaway_id) return i.update({ content: interaction.translate("moderation/giveaway:MISSING_ID"), components: [] });
client.giveawaysManager.delete(giveaway_id).then(() => {
return i.update({
content: interaction.translate("moderation/giveaway:GIVEAWAY_DELETED"),
components: []
});
}).catch(() => {
return i.update({
content: interaction.translate("moderation/giveaway:NOT_FOUND", {
messageId: giveaway_id
}),
components: []
});
});
} else if (option === "end") {
const giveaway_id = interaction.options.getString("giveaway_id");
if (!giveaway_id) return i.update({ content: interaction.translate("moderation/giveaway:MISSING_ID"), components: [] });
try {
client.giveawaysManager.end(giveaway_id);
return i.update({
content: interaction.translate("moderation/giveaway:GIVEAWAY_ENDED"),
components: []
});
} catch (e) {
return i.update({
content: interaction.translate("moderation/giveaway:NOT_FOUND", {
messageId: giveaway_id
}),
components: []
});
}
}
});
}
}
module.exports = Giveaway;

127
commands/Moderation/poll.js Normal file
View file

@ -0,0 +1,127 @@
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionFlagsBits } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Poll extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("poll")
.setDescription(client.translate("moderation/poll:DESCRIPTION"))
.setDefaultMemberPermissions(PermissionFlagsBits.ModerateMembers && PermissionFlagsBits.ManageMessages)
.addStringOption(option => option.setName("question")
.setDescription(client.translate("moderation/poll:QUESTION"))
.setRequired(true)),
aliases: [],
dirname: __dirname,
guildOnly: true
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const question = interaction.options.getString("question");
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId("poll_everyone")
.setLabel(interaction.translate("moderation/poll:EVERYONE"))
.setStyle(ButtonStyle.Primary),
new ButtonBuilder()
.setCustomId("poll_here")
.setLabel(interaction.translate("moderation/poll: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, time: 15000 });
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 = new EmbedBuilder()
.setAuthor({
name: interaction.translate("moderation/poll:TITLE")
})
.setColor(client.config.embed.color)
.addFields([
{
name: question,
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

@ -0,0 +1,49 @@
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand");
class Unban extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("unban")
.setDescription(client.translate("moderation/unban:DESCRIPTION"))
.setDefaultMemberPermissions(PermissionFlagsBits.ModerateMembers && PermissionFlagsBits.ManageMessages)
.addStringOption(option => option.setName("user_id")
.setDescription(client.translate("moderation/unban:ID"))
.setRequired(true)),
aliases: [],
dirname: __dirname,
guildOnly: true
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const id = interaction.options.getString("user_id");
const banned = await interaction.guild.bans.fetch();
if (!banned.find(u => u.user.id === id)) return interaction.error("moderation/unban:NOT_BANNED", { id });
interaction.guild.bans.remove(id);
interaction.success("moderation/unban:UNBANNED", {
id
});
}
}
module.exports = Unban;

View file

@ -48,13 +48,11 @@ class Warn extends BaseCommand {
.setTitle(interaction.translate("moderation/warn:MODAL_TITLE"));
const reasonInput = new TextInputBuilder()
.setCustomId("reason")
.setCustomId("warn_reason")
.setLabel(interaction.translate("moderation/warn:REASON"))
.setStyle(TextInputStyle.Short);
const firstActionRow = new ActionRowBuilder().addComponents(reasonInput);
modal.addComponents(firstActionRow);
modal.addComponents(new ActionRowBuilder().addComponents(reasonInput));
await interaction.showModal(modal);
@ -63,8 +61,8 @@ class Warn extends BaseCommand {
filter: i => i.user.id === interaction.member.id,
});
if (submitted) {
const reason = submitted.fields.getTextInputValue("reason");
if (submitted && submitted.customId === "warn_modal") {
const reason = submitted.fields.getTextInputValue("warn_reason");
const sanctions = memberData.sanctions.filter((s) => s.type === "warn").length;
const banCount = data.guildData.plugins.warnsSanctions.ban;

View file

@ -30,7 +30,7 @@ class Warns extends BaseCommand {
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").UserContextMenuCommandInteraction} interaction
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {

View file

@ -58,26 +58,28 @@ class Clips extends BaseCommand {
fetchReply: true
});
const filter = i => i.customId === "clips_select" && i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, {
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: 60 * 1000
idle: 30 * 1000
});
collector.on("collect", async msg => {
const clip = msg?.values[0];
const voice = msg.member.voice.channel;
if (!voice) return msg.update({ content: interaction.translate("music/play:NO_VOICE_CHANNEL"), components: [] });
const queue = client.player.getQueue(msg.guild.id);
if (queue) return msg.update({ content: interaction.translate("music/clips:ACTIVE_QUEUE"), components: [] });
if (getVoiceConnection(msg.guild.id)) return msg.update({ content: interaction.translate("music/clips:ACTIVE_CLIP"), components: [] });
if (!fs.existsSync(`./clips/${clip}.mp3`)) return msg.update({ content: interaction.translate("music/clips:NO_FILE", { file: clip }), components: [] });
collector.on("collect", async i => {
const clip = i?.values[0];
const voice = i.member.voice.channel;
if (!voice) return i.update({ content: interaction.translate("music/play:NO_VOICE_CHANNEL"), components: [] });
const queue = client.player.getQueue(i.guild.id);
if (queue) return i.update({ content: interaction.translate("music/clips:ACTIVE_QUEUE"), components: [] });
if (getVoiceConnection(i.guild.id)) return i.update({ content: interaction.translate("music/clips:ACTIVE_CLIP"), components: [] });
if (!fs.existsSync(`./clips/${clip}.mp3`)) return i.update({ content: interaction.translate("music/clips:NO_FILE", { file: clip }), components: [] });
try {
const connection = joinVoiceChannel({
channelId: voice.id,
guildId: msg.guild.id,
adapterCreator: msg.guild.voiceAdapterCreator
guildId: i.guild.id,
adapterCreator: i.guild.voiceAdapterCreator
});
const resource = createAudioResource(fs.createReadStream(`./clips/${clip}.mp3`));
@ -97,7 +99,7 @@ class Clips extends BaseCommand {
console.error(error);
}
await msg.update({
await i.update({
content: interaction.translate("music/clips:PLAYING", {
clip
}),

View file

@ -56,14 +56,16 @@ class NSFW extends BaseCommand {
fetchReply: true
});
const filter = i => i.customId === "nsfw_select" && i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, {
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: 60 * 1000
});
collector.on("collect", async msg => {
const tag = msg?.values[0];
collector.on("collect", async i => {
const tag = i?.values[0];
const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json());
const embed = new EmbedBuilder()
@ -75,7 +77,7 @@ class NSFW extends BaseCommand {
.setImage(res.url)
.setTimestamp();
await msg.update({
await i.update({
embeds: [embed]
});
});

View file

@ -27,7 +27,7 @@ class Debug extends BaseCommand {
.setDescription(client.translate("owner/debug:TARGET"))
.setRequired(true))
.addIntegerOption(option => option.setName("int")
.setDescription(client.translate("owner/debug:INT"))
.setDescription(client.translate("common:INT"))
.setRequired(true))
)
.addSubcommand(subcommand => subcommand.setName("add")

View file

@ -1,5 +1,11 @@
const { Message, CommandInteraction } = require("discord.js");
/**
*
* @param {String} key
* @param {Array} args
* @returns {String}
*/
CommandInteraction.prototype.translate = function (key, args) {
const language = this.client.translations.get(this.guild ? this.guild.data.language : "ru-RU");
if (!language) throw "Message: Invalid language set in data.";
@ -7,6 +13,13 @@ CommandInteraction.prototype.translate = function (key, args) {
return language(key, args);
};
/**
*
* @param {String} key
* @param {Array} args
* @param {Array} options
* @returns {import("discord.js").BaseCommandInteraction}
*/
CommandInteraction.prototype.replyT = function (key, args, options = {}) {
let string = this.translate(key, args, this.guild ? this.guild.data.language : "ru-RU");
if (options.prefixEmoji) string = `${this.client.customEmojis[options.prefixEmoji]} | ${string}`;
@ -15,12 +28,26 @@ CommandInteraction.prototype.replyT = function (key, args, options = {}) {
else return this.reply({ content: string, ephemeral: options.ephemeral || false });
};
/**
*
* @param {String} key
* @param {Array} args
* @param {Array} options
* @returns {import("discord.js").BaseCommandInteraction}
*/
CommandInteraction.prototype.error = function (key, args, options = {}) {
options.prefixEmoji = "error";
return this.replyT(key, args, options);
};
/**
*
* @param {String} key
* @param {Array} args
* @param {Array} options
* @returns {import("discord.js").BaseCommandInteraction}
*/
CommandInteraction.prototype.success = function (key, args, options = {}) {
options.prefixEmoji = "success";

View file

@ -14,7 +14,7 @@ const Youtube = require("youtube-sr").default;
thanks :)
-nize
-nize
*/
module.exports = {
@ -85,7 +85,7 @@ module.exports = {
duration: spotifyTrack.duration_ms,
thumbnail: info.image,
async engine() {
return (await playdl.stream(await Youtube.search(`${info.artist} ${info.title} lyric`, {limit: 1, type: "video", safeSearch: true}).then(x => x[0] ? `https://youtu.be/${x[0].id}` : "https://youtu.be/Wch3gJG2GJ4"), { discordPlayerCompatibility : true })).stream;
return (await playdl.stream(await Youtube.search(`${info.artist} ${info.title} lyric`, { limit: 1, type: "video", safeSearch: true }).then(x => x[0] ? `https://youtu.be/${x[0].id}` : "https://youtu.be/Wch3gJG2GJ4"), { discordPlayerCompatibility : true })).stream;
},
views: 0,
author: info.artist,
@ -102,7 +102,7 @@ module.exports = {
duration: track.duration_ms,
thumbnail: track.album && track.album.images.length ? track.album.images[0].url : null,
async engine() {
return (await playdl.stream(await Youtube.search(`${track.artists[0].name} ${track.name} lyric`, {limit: 1, type: "video", safeSearch: true}).then(x => x[0] ? `https://youtu.be/${x[0].id}` : "https://youtu.be/Wch3gJG2GJ4"), { discordPlayerCompatibility : true })).stream;
return (await playdl.stream(await Youtube.search(`${track.artists[0].name} ${track.name} lyric`, { limit: 1, type: "video", safeSearch: true }).then(x => x[0] ? `https://youtu.be/${x[0].id}` : "https://youtu.be/Wch3gJG2GJ4"), { discordPlayerCompatibility : true })).stream;
},
views: 0,
author: track.artists ? track.artists[0].name : null,
@ -131,7 +131,28 @@ module.exports = {
query = query.split("&")[0];
}
if (query.startsWith("https") && playdl.yt_validate(query) === "video") {
const info = await Youtube.search(query, {limit: 1, type: "video", safeSearch: true});
if (query.includes("music.youtube")) {
const info = await playdl.video_info(query);
if(!info)
return resolve({ playlist: null, info: null });
const track = {
title: info.video_details.title,
duration: info.video_details.duration,
thumbnail: info.video_details.thumbnails[0].url,
async engine() {
return (await playdl.stream(`https://music.youtube.com/watch?v=${info.video_details.id}`, { discordPlayerCompatibility : true })).stream;
},
views: info.video_details.views,
author: info.video_details.channel.name,
description: "",
url: `https://music.youtube.com/watch?v=${info.video_details.id}`,
source: "youtube-music-custom"
};
return resolve({ playlist: null, info: [track] });
}
const info = await Youtube.search(query, { limit: 1, type: "video", safeSearch: true });
if(!info || !info.length)
return resolve({ playlist: null, info: null });
@ -158,7 +179,7 @@ module.exports = {
duration: track.durationInSec * 1000,
thumbnail: track.thumbnails ? track.thumbnails[0] ? track.thumbnails[0].url : null : null,
async engine() {
return (await playdl.stream(await Youtube.search(track.url, {limit: 1, type: "video", safeSearch: true}).then(x => x[0] ? `https://youtu.be/${x[0].id}` : "https://youtu.be/Wch3gJG2GJ4"), { discordPlayerCompatibility : true })).stream;
return (await playdl.stream(await Youtube.search(track.url, { limit: 1, type: "video", safeSearch: true }).then(x => x[0] ? `https://youtu.be/${x[0].id}` : "https://youtu.be/Wch3gJG2GJ4"), { discordPlayerCompatibility : true })).stream;
},
views: track.views,
author: track.channel.name,

View file

@ -1,8 +1,9 @@
{
"YES": "Да",
"NO": "Нет",
"ACCEPT": "Принять",
"CANCEL": "Отменить",
"NOT_DEFINED": "Не установлено",
"AND_MORE": "И т.д...",
"AUTHOR": "Автор",
"DATE": "Дата",
"MISSING": "Отсутствует",
@ -51,6 +52,7 @@
"CONFIGURATION": "Настройки",
"EMOJI": "Эмодзи",
"IP": "IP адрес",
"INT": "Целое число",
"LANGUAGE": "Язык",
"CHANNEL": "Канал",
"UPDATE": "Обновить",

View file

@ -6,5 +6,6 @@
"NAME": "Название",
"ANIMATED": "Анимирован",
"ID": "ID",
"LINK": "Ссылка",
"STANDART": "Стандартный эмодзи"
}

View file

@ -1,7 +1,8 @@
{
"CLICK_HERE": "Нажмите сюда, чтобы начать {{activity}} в {{channel}}",
"TIMES_UP": "Время вышло! Используйте команду снова!",
"INVALID_YES_NO": "Отправьте `да` или `нет` (регистр не важен)!",
"SELECT_CANCELED": "Выбор отменён",
"INVALID_NUMBER_RANGE": "Укажите число от **{{min}}** до **{{max}}**!",
"FORCE_STOP": "Игра принудительно окончена {{user}}, никто не победил!",
"STATS_FOOTER": "● [Панель управления]({{dashboardLink}})\n● [Документация]({{docsLink}})\n● [Пригласить JaBa на свой сервер]({{inviteLink}})\n● [Поддержать]({{donateLink}}) (укажите ваш Discord тэг для выдачи ачивки, для других способов поддержки пишите в ЛС <@{{owner}}>)",
"BOT_USER": "Вы не можете сделать это с ботом!",

View file

@ -1,9 +1,10 @@
{
"DESCRIPTION": "Удалить сообщения!",
"USAGE": "clear [кол-во_сообщений] (@пользователь)",
"EXAMPLES": "clear 10\nclear 10 @Jonny_Bro#4226\nclear all",
"MISSING_AMOUNT": "Укажите кол-во сообщений для удаления!",
"ALL_CONFIRM": "Все сообщения в канале будут удалены! Введите `confirm` для подтверждения",
"EXAMPLES": "clear 10\r 10 @Jonny_Bro#4226\nclear all",
"OPTION_NAN": "Укажите целое число больше 0 или `all`",
"OPTION": "Целое число / all",
"ALL_CONFIRM": "**Все сообщения в канале будут удалены! Вы уверены?**",
"CHANNEL_CLEARED": "Канал очищен!",
"CLEARED": "Было удалено **{{amount}}**!",
"CLEARED_MEMBER": "Было удалено **{{amount}}** от **{{username}}**!"

View file

@ -2,13 +2,16 @@
"DESCRIPTION": "Управление раздачами!",
"USAGE": "giveaway [create/reroll/delete/end] [время] [кол-во победителей] (Дроп? true) [приз]",
"EXAMPLES": "giveaway create 1d 2 100 рублей на карту!\ngiveaway create 1d 2 true 100 рублей на карту\ngiveaway reroll 597812898022031374",
"MISSING_STATUS": "Выберите действие: `create`, `reroll`, `end` или `delete`!",
"INVALID_CREATE": "Какой-то из аргументов указан неверно, попробуйте снова!",
"GIVEAWAY_ID": "ID сообщения раздачи",
"WINNERS_COUNT": "Количество победителей",
"PRIZE": "Приз",
"ISDROP": "Это дроп?",
"MISSING_ID": "Укажите ID сообщения раздачи!",
"NOT_FOUND": "Раздач с ID `{{messageID}}` не найдено!",
"NOT_FOUND_ENDED": "**Оконченных** раздач с ID `{{messageID}} не найдено!`!",
"MAX_DURATION": "Максимальная длительность раздачи - 15 дней.",
"MAX_COUNT": "Одновременно можно создать только 4 раздачи.",
"NOT_FOUND": "Раздач с ID `{{messageId}}` не найдено!",
"NOT_FOUND_ENDED": "**Оконченных** раздач с ID `{{messageId}} не найдено!`!",
"MAX_DURATION": "Максимальная длительность раздачи - 10 дней.",
"MAX_COUNT": "Одновременно можно создать только 5 раздач.",
"TITLE": "🎉🎉 **РАЗДАЧА** 🎉🎉",
"ENDED": "🎉🎉 **РАЗДАЧА ОКОНЧЕНА** 🎉🎉",
"TIME_REMAINING": "Оставшееся время: **{duration}**!",

View file

@ -2,7 +2,12 @@
"DESCRIPTION": "Запустить опрос в текущем канале!",
"USAGE": "poll [вопрос]",
"EXAMPLES": "poll Земля плоская?",
"MISSING_QUESTION": "Введите вопрос!",
"QUESTION": "Текст вопроса",
"HERE": "@here",
"EVERYONE": "@everyone",
"NOTHING": "Без упоминания",
"SELECT_MENTION": "Выберите упоминание:",
"POLL_SENDED": "Опрос отправлен",
"REACT": "Отреагируйте {{success}} или {{error}}!",
"TITLE": "📊 Опрос:"
}

View file

@ -1,8 +1,8 @@
{
"DESCRIPTION": "Разбанить пользователя на сервере!",
"DESCRIPTION": "Разбанить пользователя на сервере",
"USAGE": "unban [ID]",
"EXAMPLES": "unban 281361531411890186",
"MISSING_ID": "Укажите ID пользователя!",
"NOT_BANNED": "**{{username}}** не забанен!",
"UNBANNED": "**{{username}}** был разбанен на сервере **{{server}}**!"
"ID": "ID пользователя",
"NOT_BANNED": "Пользователь с ID **{{id}}** не найден",
"UNBANNED": "**{{id}}** разбанен!"
}

View file

@ -2,7 +2,7 @@
"DESCRIPTION": "Начать воспроизведение трека",
"USAGE": "play [название-трека/ссылка]",
"EXAMPLES": "play Never Gonna Give You Up",
"QUERY": "Название/Прямая ссылка/Ссылка на YouTube, Spotify или SoundCloud",
"QUERY": "Название / Прямая ссылка / Ссылка на YouTube, Spotify или SoundCloud",
"NO_VOICE_CHANNEL": "Вы должны находиться в голосовом канале!",
"VOICE_CHANNEL_CONNECT": "Я не могу присоедениться к вашему голосовому каналу!",
"RESULTS_FOOTER": "Укажите число от 1 до 10 (без префикса).",

View file

@ -5,7 +5,6 @@
"TYPE": "Тип данных",
"SET": "Установить значение",
"ADD": "Добавить к значению",
"INT": "Целое число",
"SUCCESS_LEVEL": "Уровень пользователя **{{username}}** изменён на **{{amount}}**!",
"SUCCESS_XP": "XP пользователя **{{username}}** изменён на **{{amount}}**!",
"SUCCESS_CREDITS": "Кредиты пользователя **{{username}}** изменены на **{{amount}}**!",