[JavaScript, Node.JS] Создание Discord-бота, используя библиотеку discord.js | Часть №2 | Аргументы
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Введение
Аргументы являются важнейшей частью 70% команд — их изредка называют вводом пользователя, что вполне является правильным.
В данной статье я подробно расскажу вам об их использовании, видах, а также o применении в командах для модерации.
Если вы не читали мою предыдущую статью о создании бота и делаете по другой схеме, добавьте в начало вашего кода данную строку:
const args = message.content.slice(prefix.length).split(/ +/);
Если же вы создаёте бота по моим статьям и пишите код в функциях, вам не придётся ничего добавлять.
Конкретный аргумент
Конкретный аргумент можно получить таким образом:
args[0]
В квадратных скобках указывается номер значения в сообщении:
if (mess.content === `${prefix}test`, args[0]){
mess.channel.send(args[0]);
}
В Javascript отсчёт всегда идёт с нуля, поэтому, если мы в квадратных скобках укажем 0, бот отправит в чат сообщение с командой, которую мы вписали — нулевой аргумент:
Примеры:
args[1]
args[10]
if (mess.content === `${prefix}test`, args[0]){
mess.channel.send(args[1] + ' ' + args[2]);
}
Множество аргументов
Все аргументы в сообщении (или по-другому, содержание сообщения) можно получить следующим образом:
args
if (mess.content === `${prefix}test`, args){
mess.channel.send(args)
}
Как видите, бот вывел в чат полное содержание сообщения.
Разделение аргументов
Теперь, когда вы уже немного ознакомились с аргументами, мы можем перейти к наиболее интересной части — их разделению.
Для начала, попробуем разделить содержание сообщения на команду и аргументы после неё:
if (!args[1]) { // Если пользователь не ввёл аргументов после команды, бот отправляет следующее сообщение:
mess.channel.send('Вы не указали никаких аргументов.');
}
if (args[1]) { // Если пользователь ввёл хоть один аргумент, бот отправляет введённую команду:
mess.channel.send(`Команда: ${args[0]}`);
args.shift(); // Удаление введённой пользователем команды
mess.channel.send(`Аргументы: ${args}`) // Отправление сообщения с аргументами после введённой пользователем команды
}
Результат:
Также вы можете добавить определение количества аргументов:
mess.channel.send(`Количество аргументов: ${args.length}`);
Работа с упоминаниями
Для того, чтобы получить упоминание пользователя, мы должны добавить данную строку:
const mention = message.mentions.users.first();
С помощью неё мы получим «первого» упомянутого пользователя.
Далее, выведем в чат имя упомянутого пользователя:
mess.channel.send(`Пользователь, которого вы упомянули: ${mention.username}`);
Но теперь, если мы пропишем команду без упоминания, в консоли появится ошибка:
TypeError: Cannot read property 'username' of undefined
Это легко исправить, добавим следующие строки:
if (!message.mentions.users.size) {
return mess.channel.send('Вы не указали пользователя!');
}
Команды для модерации
Наконец, мы можем приступить к командам для модерации.
Начнём, пожалуй, с команды для предупреждения пользователя.
Для того, чтобы мы в будущем смогли сделать кик/бан после определённого количества предупреждений, нам нужно создать JSON-файл, в котором будет храниться информация о предупреждённом участнике: его ID и количество предупреждений.
Назовём файл data.json и вставим в него две фигурных скобки:
{}
После чего, вернёмся к файлу с нашей командой и добавим в начало кода следующие строки:
const fs = require('fs'); // Подключаем родной модуль файловой системы node.js
var warns = JSON.parse(fs.readFileSync("./data.json", "utf8")); // Объявляем переменную warns, с помощью которой бот сможет прочитать файл data.json
Несколько проверок:
if (!mess.member.hasPermission("KICK_MEMBERS")) return mess.reply("У вас нет прав для использования данной команды"); // Если пользователь попытается предупредить участника сервера без привилегии KICK_MEMBERS, ему будет в этом отказано.
if (!mess.guild.me.hasPermission("KICK_MEMBERS")) return mess.reply("У меня нет прав!") // Если у бота нету привилегии KICK_MEMBERS, он отправит соответствующее сообщение
let wUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0]) // Восприятие упоминания и аргумента
if(wUser.id === mess.author.id) return message.channel.send("Вы не можете выдать предупреждение самому себе!"); // Если пользователь попытается предупредить самого себя, ему будет в этом отказано.
if (!wUser) return mess.reply("Вы не указали пользователя") // Если пользователь не найден/не указан - в предупреждении пользователю будет отказано
Запись данных в .json файл:
if (!warns[wUser.id]) warns[wUser.id] = { // Если ID пользователя не найден, количество предупреждений устанавливается на 0
warns: 0
};
warns[wUser.id].warns++; // Если все проверки прошли успешно, к текущему количеству предупреждений пользователя прибавляется +1
fs.writeFile("./data.json", JSON.stringify(warns), (err) => { // Все данные сохраняются в .json файле
if (err) console.log(err)
});
Перейдём к самой большой и заключительной части кода — она отвечает за кик участника сервера после обнаружения трёх предупреждений, за обнуление счётчика предупреждений и за отправку embed'ов.
if (warns[wUser.id].warns >= 3) { // Если обнаружено 3+ предупреждений, то...
wUser.kick("3/3 предупреждений") // Кикнуть участника сервера по причине "3/3 предупреждений"
if (warns[wUser.id].warns >= 3) warns[wUser.id] = { // Если обнаружено 3+ предупреждений, их количество устанавливается на 0
warns: 0
};
fs.writeFile("./data.json", JSON.stringify(warns), (err) => { // Всё сохраняется в .json файл
if (err) console.log(err)
});
var warn_embed1 = new Discord.MessageEmbed() // Embed, отправляющийся при третьем предупреждении
.setColor('#db0f0f')
.addFields(
{ name: 'Пользователь', value: `<@${mess.author.id}>` },
{ name: 'Выдал предупреждение', value: wUser },
{ name: 'Количество предупреждений', value: '3/3 **[Кик]**' }
);
mess.channel.send(warn_embed1)
} else { // Иначе...
var warn_embed2 = new Discord.MessageEmbed() // Embed, отправляющийся при 1 и 2 предупреждении
.setColor('#db0f0f')
.addFields(
{ name: 'Пользователь', value: `<@${mess.author.id}>` },
{ name: 'Выдал предупреждение', value: wUser },
{ name: 'Количество предупреждений', value: `${warns[wUser.id].warns}/3` }
);
mess.channel.send(warn_embed2)
if (warns[wUser.id].warns >= 3) warns[wUser.id] = { // Если обнаружено 3+ предупреждений, их количество устанавливается на 0
warns: 0
};
fs.writeFile("./data.json", JSON.stringify(warns), (err) => { // Всё сохраняется в .json файле
if (err) console.log(err)
});
}
}
Результат:
После выдачи предупреждения, в файле data.json должна появиться подобная строка:
{"123456789012345678":{"warns":1}}
Это и есть ID предупреждённого пользователя и количество предупреждений.
После достижения трёх предупреждений, их количество устанавливается на 0.
Перейдём к команде для бана, она значительно проще в написании и компактнее в объёме, т.к нам не понадобится .json файл и запись в него данных.
Для начала, добавим уже знакомые нам строки, но немного видоизменённые:
if (!mess.member.hasPermission("BAN_MEMBERS")) return mess.reply("У вас нет прав для использования данной команды");
let bUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0])
if(bUser.id === mess.author.id) return message.channel.send("Вы не можете забанить самого себя!");
if (!mess.guild.me.hasPermission("BAN_MEMBERS")) return mess.reply("У меня нет прав!")
Переназначим переменную args для последующего добавления причины бана:
args = mess.content.split(' '); // Занесли в массив всё содержание сообщения
args.splice(0, 2); // Начиная с позиции 0, удалили 2 элемента из массива
args = args.join(' '); // Объединили все элементы в массиве
Добавим пару проверок и функцию бана:
if (!bUser) return mess.reply("Вы не указали пользователя!")
if (!args) return mess.reply("Вы не указали причину!")
bUser.ban()
И наконец, напишем заключительный embed:
var ban_embed = new Discord.MessageEmbed()
.setColor('#db0f0f')
.addFields(
{ name: 'Пользователь', value: `<@${mess.author.id}>` },
{ name: 'Забанил', value: bUser },
{ name: 'По причине', value: args }
);
mess.channel.send(ban_embed)
Результат:
На команде для кика мы заострять внимание не будем, так как она является точной копией команды для бана.
Код
SPL
if (!mess.member.hasPermission("KICK_MEMBERS")) return mess.reply("У вас нет прав для использования данной команды");
if (!mess.guild.me.hasPermission("KICK_MEMBERS")) return mess.reply("У меня нет прав!")
let kUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0])
if(kUser.id === mess.author.id) return message.channel.send("Вы не можете кикнуть самого себя!");
args = mess.content.split(' ');
args.splice(0, 2);
args = args.join(' ');
if (!kUser) return mess.reply("Вы не указали пользователя!")
if (!args) return mess.reply("Вы не указали причину!")
kUser.kick(args)
var kick_embed = new Discord.MessageEmbed()
.setColor('#db0f0f')
.addFields(
{ name: 'Пользователь', value: `<@${mess.author.id}>` },
{ name: 'Кикнул', value: kUser },
{ name: 'По причине', value: args }
);
mess.channel.send(kick_embed)
Следующая по счёту команда для заглушения пользователя.
Код для данной команды почти ничем не отличается от предыдущих, добавляется лишь несколько строк.
Начнём с объявления привычной нам уже переменной, переназначения переменной args:
let mUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0])
args = mess.content.split(' ');
args.splice(0, 2);
args = args.join(' ');
Добавим обнаружение роли Muted, несколько проверок, выдача роли Muted пользователю:
let muterole = mess.guild.roles.cache.find(role => role.name === "Muted");
if (!mUser) return mess.reply("Вы не указали пользователя!")
if (!args) return mess.reply("Вы не указали причину!")
if (!muterole) return mess.reply("На этом сервере нету роли **Muted**, создайте её!");
mUser.roles.add(muterole)
Два embed'а и их отправка:
var mute_embed = new Discord.MessageEmbed()
.setColor('#db0f0f')
.addFields(
{ name: 'Пользователь', value: `<@${mess.author.id}>` },
{ name: 'Выдал мут', value: mUser },
{ name: 'По причине', value: args }
);
var dm_mute_embed = new Discord.MessageEmbed()
.setColor('#db0f0f')
.addFields(
{ name: 'Пользователь', value: `<@${mess.author.id}>` },
{ name: 'Выдал мут', value: `Вам, ${mUser}` },
{ name: 'На сервере', value: mUser.guild },
{ name: 'По причине', value: args }
);
mUser.send(dm_mute_embed) // Embed отправляется пользователю, которому выдан мут в ЛС
mess.channel.send(mute_embed) // Embed отправляется в чат
Заключение
Из этой статьи мы узнали:
- Как работать с конкретным аргументом
- Как работать с множеством аргументов
- Как разделять аргументы
- Как работать с упоминаниями
А также написали несколько команд для модерации.
Следующая часть будет посвящена embed'ам и работе с ними.
Спасибо за прочтение!
Сайты для самостоятельного изучения
- Основная документация discord.js
- Документация discord.js №2
- Руководство discord.js
- Руководство discord.js №2
Предыдущие статьи
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, Разработка веб-сайтов] Работа с файлами в JavaScript
- [JavaScript, ReactJS, Разработка веб-сайтов] Debouncing с помощью React Hooks: хук для функций
- [JavaScript, Разработка мобильных приложений, Разработка под Android] Как подружить React Native и Java код на Android
- [IT-инфраструктура, Разработка систем связи, Робототехника, Сетевые технологии] Facebook создала робота для автономной намотки оптоволокна на линии электропередач
- [API, JavaScript, VueJS, Учебный процесс в IT] Онлайн-митап сообщества разработчиков MSK VUE.JS
- [Python, Голосовые интерфейсы, Искусственный интеллект] Голосовой бот + телефония на полном OpenSource. Часть 1 — создание и обучение текстового бота RU
- [Космонавтика, Разработка робототехники, Робототехника] НАСА объявило победителей конкурса крошечных лунных роботов
- [JavaScript, PHP, Ненормальное программирование, Программирование, Разработка веб-сайтов] Inertia.js – современный монолит
- [JavaScript, MongoDB, Node.JS, Высокая производительность] Node.js + MongoDB: перформанс транзакций
- [JavaScript, Open source, Программирование] Объектно-ориентированная альтернатива jquery
Теги для поиска: #_javascript, #_node.js, #_discord, #_bot, #_javascript, #_node.js, #_boty (боты), #_javascript, #_node.js
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 05:36
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Введение Аргументы являются важнейшей частью 70% команд — их изредка называют вводом пользователя, что вполне является правильным. В данной статье я подробно расскажу вам об их использовании, видах, а также o применении в командах для модерации. Если вы не читали мою предыдущую статью о создании бота и делаете по другой схеме, добавьте в начало вашего кода данную строку: const args = message.content.slice(prefix.length).split(/ +/);
Если же вы создаёте бота по моим статьям и пишите код в функциях, вам не придётся ничего добавлять. Конкретный аргумент Конкретный аргумент можно получить таким образом: args[0]
В квадратных скобках указывается номер значения в сообщении: if (mess.content === `${prefix}test`, args[0]){
mess.channel.send(args[0]); } В Javascript отсчёт всегда идёт с нуля, поэтому, если мы в квадратных скобках укажем 0, бот отправит в чат сообщение с командой, которую мы вписали — нулевой аргумент: Примеры: args[1]
args[10]
if (mess.content === `${prefix}test`, args[0]){
mess.channel.send(args[1] + ' ' + args[2]); } Множество аргументов Все аргументы в сообщении (или по-другому, содержание сообщения) можно получить следующим образом: args
if (mess.content === `${prefix}test`, args){
mess.channel.send(args) } Как видите, бот вывел в чат полное содержание сообщения. Разделение аргументов Теперь, когда вы уже немного ознакомились с аргументами, мы можем перейти к наиболее интересной части — их разделению. Для начала, попробуем разделить содержание сообщения на команду и аргументы после неё: if (!args[1]) { // Если пользователь не ввёл аргументов после команды, бот отправляет следующее сообщение:
mess.channel.send('Вы не указали никаких аргументов.'); } if (args[1]) { // Если пользователь ввёл хоть один аргумент, бот отправляет введённую команду: mess.channel.send(`Команда: ${args[0]}`); args.shift(); // Удаление введённой пользователем команды mess.channel.send(`Аргументы: ${args}`) // Отправление сообщения с аргументами после введённой пользователем команды } Результат: Также вы можете добавить определение количества аргументов: mess.channel.send(`Количество аргументов: ${args.length}`);
Работа с упоминаниями Для того, чтобы получить упоминание пользователя, мы должны добавить данную строку: const mention = message.mentions.users.first();
С помощью неё мы получим «первого» упомянутого пользователя. Далее, выведем в чат имя упомянутого пользователя: mess.channel.send(`Пользователь, которого вы упомянули: ${mention.username}`);
Но теперь, если мы пропишем команду без упоминания, в консоли появится ошибка: TypeError: Cannot read property 'username' of undefined
Это легко исправить, добавим следующие строки: if (!message.mentions.users.size) {
return mess.channel.send('Вы не указали пользователя!'); } Команды для модерации Наконец, мы можем приступить к командам для модерации. Начнём, пожалуй, с команды для предупреждения пользователя. Для того, чтобы мы в будущем смогли сделать кик/бан после определённого количества предупреждений, нам нужно создать JSON-файл, в котором будет храниться информация о предупреждённом участнике: его ID и количество предупреждений. Назовём файл data.json и вставим в него две фигурных скобки: {}
После чего, вернёмся к файлу с нашей командой и добавим в начало кода следующие строки: const fs = require('fs'); // Подключаем родной модуль файловой системы node.js
var warns = JSON.parse(fs.readFileSync("./data.json", "utf8")); // Объявляем переменную warns, с помощью которой бот сможет прочитать файл data.json Несколько проверок: if (!mess.member.hasPermission("KICK_MEMBERS")) return mess.reply("У вас нет прав для использования данной команды"); // Если пользователь попытается предупредить участника сервера без привилегии KICK_MEMBERS, ему будет в этом отказано.
if (!mess.guild.me.hasPermission("KICK_MEMBERS")) return mess.reply("У меня нет прав!") // Если у бота нету привилегии KICK_MEMBERS, он отправит соответствующее сообщение let wUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0]) // Восприятие упоминания и аргумента if(wUser.id === mess.author.id) return message.channel.send("Вы не можете выдать предупреждение самому себе!"); // Если пользователь попытается предупредить самого себя, ему будет в этом отказано. if (!wUser) return mess.reply("Вы не указали пользователя") // Если пользователь не найден/не указан - в предупреждении пользователю будет отказано Запись данных в .json файл: if (!warns[wUser.id]) warns[wUser.id] = { // Если ID пользователя не найден, количество предупреждений устанавливается на 0
warns: 0 }; warns[wUser.id].warns++; // Если все проверки прошли успешно, к текущему количеству предупреждений пользователя прибавляется +1 fs.writeFile("./data.json", JSON.stringify(warns), (err) => { // Все данные сохраняются в .json файле if (err) console.log(err) }); Перейдём к самой большой и заключительной части кода — она отвечает за кик участника сервера после обнаружения трёх предупреждений, за обнуление счётчика предупреждений и за отправку embed'ов. if (warns[wUser.id].warns >= 3) { // Если обнаружено 3+ предупреждений, то...
wUser.kick("3/3 предупреждений") // Кикнуть участника сервера по причине "3/3 предупреждений" if (warns[wUser.id].warns >= 3) warns[wUser.id] = { // Если обнаружено 3+ предупреждений, их количество устанавливается на 0 warns: 0 }; fs.writeFile("./data.json", JSON.stringify(warns), (err) => { // Всё сохраняется в .json файл if (err) console.log(err) }); var warn_embed1 = new Discord.MessageEmbed() // Embed, отправляющийся при третьем предупреждении .setColor('#db0f0f') .addFields( { name: 'Пользователь', value: `<@${mess.author.id}>` }, { name: 'Выдал предупреждение', value: wUser }, { name: 'Количество предупреждений', value: '3/3 **[Кик]**' } ); mess.channel.send(warn_embed1) } else { // Иначе... var warn_embed2 = new Discord.MessageEmbed() // Embed, отправляющийся при 1 и 2 предупреждении .setColor('#db0f0f') .addFields( { name: 'Пользователь', value: `<@${mess.author.id}>` }, { name: 'Выдал предупреждение', value: wUser }, { name: 'Количество предупреждений', value: `${warns[wUser.id].warns}/3` } ); mess.channel.send(warn_embed2) if (warns[wUser.id].warns >= 3) warns[wUser.id] = { // Если обнаружено 3+ предупреждений, их количество устанавливается на 0 warns: 0 }; fs.writeFile("./data.json", JSON.stringify(warns), (err) => { // Всё сохраняется в .json файле if (err) console.log(err) }); } } Результат: После выдачи предупреждения, в файле data.json должна появиться подобная строка: {"123456789012345678":{"warns":1}}
Это и есть ID предупреждённого пользователя и количество предупреждений. После достижения трёх предупреждений, их количество устанавливается на 0. Перейдём к команде для бана, она значительно проще в написании и компактнее в объёме, т.к нам не понадобится .json файл и запись в него данных. Для начала, добавим уже знакомые нам строки, но немного видоизменённые: if (!mess.member.hasPermission("BAN_MEMBERS")) return mess.reply("У вас нет прав для использования данной команды");
let bUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0]) if(bUser.id === mess.author.id) return message.channel.send("Вы не можете забанить самого себя!"); if (!mess.guild.me.hasPermission("BAN_MEMBERS")) return mess.reply("У меня нет прав!") Переназначим переменную args для последующего добавления причины бана: args = mess.content.split(' '); // Занесли в массив всё содержание сообщения
args.splice(0, 2); // Начиная с позиции 0, удалили 2 элемента из массива args = args.join(' '); // Объединили все элементы в массиве Добавим пару проверок и функцию бана: if (!bUser) return mess.reply("Вы не указали пользователя!")
if (!args) return mess.reply("Вы не указали причину!") bUser.ban() И наконец, напишем заключительный embed: var ban_embed = new Discord.MessageEmbed()
.setColor('#db0f0f') .addFields( { name: 'Пользователь', value: `<@${mess.author.id}>` }, { name: 'Забанил', value: bUser }, { name: 'По причине', value: args } ); mess.channel.send(ban_embed) Результат: На команде для кика мы заострять внимание не будем, так как она является точной копией команды для бана. КодSPLif (!mess.member.hasPermission("KICK_MEMBERS")) return mess.reply("У вас нет прав для использования данной команды");
if (!mess.guild.me.hasPermission("KICK_MEMBERS")) return mess.reply("У меня нет прав!") let kUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0]) if(kUser.id === mess.author.id) return message.channel.send("Вы не можете кикнуть самого себя!"); args = mess.content.split(' '); args.splice(0, 2); args = args.join(' '); if (!kUser) return mess.reply("Вы не указали пользователя!") if (!args) return mess.reply("Вы не указали причину!") kUser.kick(args) var kick_embed = new Discord.MessageEmbed() .setColor('#db0f0f') .addFields( { name: 'Пользователь', value: `<@${mess.author.id}>` }, { name: 'Кикнул', value: kUser }, { name: 'По причине', value: args } ); mess.channel.send(kick_embed) Следующая по счёту команда для заглушения пользователя. Код для данной команды почти ничем не отличается от предыдущих, добавляется лишь несколько строк. Начнём с объявления привычной нам уже переменной, переназначения переменной args: let mUser = mess.guild.member(mess.mentions.users.first()) || mess.guild.members.cache.get(args[0])
args = mess.content.split(' '); args.splice(0, 2); args = args.join(' '); Добавим обнаружение роли Muted, несколько проверок, выдача роли Muted пользователю: let muterole = mess.guild.roles.cache.find(role => role.name === "Muted");
if (!mUser) return mess.reply("Вы не указали пользователя!") if (!args) return mess.reply("Вы не указали причину!") if (!muterole) return mess.reply("На этом сервере нету роли **Muted**, создайте её!"); mUser.roles.add(muterole) Два embed'а и их отправка: var mute_embed = new Discord.MessageEmbed()
.setColor('#db0f0f') .addFields( { name: 'Пользователь', value: `<@${mess.author.id}>` }, { name: 'Выдал мут', value: mUser }, { name: 'По причине', value: args } ); var dm_mute_embed = new Discord.MessageEmbed() .setColor('#db0f0f') .addFields( { name: 'Пользователь', value: `<@${mess.author.id}>` }, { name: 'Выдал мут', value: `Вам, ${mUser}` }, { name: 'На сервере', value: mUser.guild }, { name: 'По причине', value: args } ); mUser.send(dm_mute_embed) // Embed отправляется пользователю, которому выдан мут в ЛС mess.channel.send(mute_embed) // Embed отправляется в чат Заключение Из этой статьи мы узнали:
А также написали несколько команд для модерации. Следующая часть будет посвящена embed'ам и работе с ними. Спасибо за прочтение! Сайты для самостоятельного изучения
Предыдущие статьи =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 05:36
Часовой пояс: UTC + 5