Перенесена activity

discord-together удалён, использую его переделанные мною исходники
This commit is contained in:
JonnyBro 2022-07-31 20:43:08 +05:00
parent 06a5fbd724
commit 0f6bf647fb
17 changed files with 232 additions and 285 deletions

View file

@ -1,263 +0,0 @@
const Command = require("../../base/Command"),
{ PermissionsBitField } = require("discord.js");
class Activity extends Command {
constructor(client) {
super(client, {
name: "activity",
dirname: __dirname,
enabled: true,
guildOnly: true,
aliases: ["act"],
memberPermissions: [],
botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
nsfw: false,
ownerOnly: false,
cooldown: 2000
});
}
async run(message, args, data) {
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
const perms = voice.permissionsFor(this.client.user);
if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return message.error("music/play:VOICE_CHANNEL_CONNECT");
const activities = [
"betrayal",
`checkers (${message.translate("general/activity:NO_BOOST")})`,
`chess (${message.translate("general/activity:NO_BOOST")})`,
"sketchheads",
`ocho (${message.translate("general/activity:NO_BOOST")})`,
"fishing",
"lettertile",
`poker (${message.translate("general/activity:NO_BOOST")})`,
`spellcast (${message.translate("general/activity:NO_BOOST")})`,
"wordsnack",
"puttparty",
"youtube"
];
const activity = args[0];
switch (activity) {
case "betrayal":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "betrayal").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Betrayal.io")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Betrayal.io", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "checkers":
if (message.guild.premiumTier === "NONE") return message.error("general/activity:NO_BOOST");
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "checkers").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Checkers In The Park")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Checkers In The Park", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "chess":
if (message.guild.premiumTier === "NONE") return message.error("general/activity:NO_BOOST");
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "chess").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Chess In The Park")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Chess In The Park", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "sketchheads":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "sketchheads").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Sketch Heads")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Sketch Heads", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "ocho":
if (message.guild.premiumTier === "NONE") return message.error("general/activity:NO_BOOST");
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "ocho").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Ocho")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Ocho", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "fishing":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "fishing").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Fishington.io")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Fishington.io", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "lettertile":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "lettertile").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Letter Tile")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Letter Tile", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "poker":
if (message.guild.premiumTier === "NONE") return message.error("general/activity:NO_BOOST");
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "poker").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Poker Night")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Poker Night", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "spellcast":
if (message.guild.premiumTier === "NONE") return message.error("general/activity:NO_BOOST");
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "spellcast").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Spell Cast")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Spell Cast", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "wordsnack":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "wordsnack").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Words Snack")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Words Snack", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "puttparty":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "puttparty").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Puttparty")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Puttparty", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
case "youtube":
this.client.discordTogether.createTogetherCode(message.member.voice.channelId, "youtube").then(async invite => {
const embed = new Discord.EmbedBuilder()
.setTitle("Youtube Together")
.setColor(data.config.embed.color)
.setDescription(`**[${message.translate("misc:CLICK_HERE", { activity: "Youtube Together", channel: voice.name })}](${invite.code})**`)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
return message.reply({
embeds: [embed]
});
});
break;
default: {
const embed = new Discord.EmbedBuilder()
.setTitle(message.translate("general/activity:TITLE"))
.setDescription(activities.join("\n"))
.setColor(data.config.embed.color)
.setFooter({
text: message.translate("general/activity:FOOTER")
})
.setTimestamp();
message.reply({
embeds: [embed]
});
}
}
}
}
module.exports = Activity;

View file

@ -8,6 +8,7 @@ const { EmbedBuilder, Client, Collection, SlashCommandBuilder, ContextMenuComman
const BaseEvent = require("./BaseEvent.js"), const BaseEvent = require("./BaseEvent.js"),
BaseCommand = require("./BaseCommand.js"), BaseCommand = require("./BaseCommand.js"),
{ DiscordTogether } = require("../helpers/discordTogether"),
AmeClient = require("amethyste-api"), AmeClient = require("amethyste-api"),
path = require("path"), path = require("path"),
fs = require("fs").promises, fs = require("fs").promises,
@ -49,6 +50,8 @@ class JaBa extends Client {
if (this.config.apiKeys.amethyste) this.AmeAPI = new AmeClient(this.config.apiKeys.amethyste); if (this.config.apiKeys.amethyste) this.AmeAPI = new AmeClient(this.config.apiKeys.amethyste);
this.discordTogether = new DiscordTogether(this);
this.player = new DisTube.default(this, { this.player = new DisTube.default(this, {
plugins: [ plugins: [
new SpotifyPlugin({ new SpotifyPlugin({

View file

@ -0,0 +1,87 @@
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, PermissionsBitField } = require("discord.js"),
{ defaultApplications } = require("../../helpers/discordTogether");
const BaseCommand = require("../../base/BaseCommand");
class Activity extends BaseCommand {
/**
*
* @param {import("../base/JaBa")} client
*/
constructor(client) {
super({
command: new SlashCommandBuilder()
.setName("activity")
.setDescription(client.translate("general/activity:DESCRIPTION")),
aliases: [],
dirname: __dirname,
guildOnly: true,
ownerOnly: false
});
}
/**
*
* @param {import("../../base/JaBa")} client
*/
async onLoad() {
//...
}
/**
*
* @param {import("../../base/JaBa")} client
* @param {import("discord.js").CommandInteraction} interaction
* @param {Array} data
*/
async execute(client, interaction) {
const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL");
const perms = voice.permissionsFor(client.user);
if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return interaction.error("music/play:VOICE_CHANNEL_CONNECT");
const activities = defaultApplications.map(a => {
return {
label: `${a.name} ${a.premium_tier_level ? `(${interaction.translate("general/activity:BOOST_NEEDED")})` : ""}`,
value: a.id
};
});
const row = new ActionRowBuilder()
.addComponents(
new SelectMenuBuilder()
.setCustomId("activity_select")
.setPlaceholder(client.translate("common:NOTHING_SELECTED"))
.addOptions(activities)
);
const msg = await interaction.reply({
content: interaction.translate("general/activity:AVAILABLE_ACTIVITIES"),
components: [row],
fetchReply: true
});
const collector = new InteractionCollector(client, {
message: msg,
idle: 60 * 1000
});
collector.on("collect", async (msg) => {
const activity = msg?.values[0];
const invite = await client.discordTogether.createTogetherCode(voice.id, activity);
const embed = new EmbedBuilder()
.setTitle(activity)
.setColor(client.config.embed.color)
.setDescription(`**[${interaction.translate("misc:CLICK_HERE", { activity: defaultApplications.find(a => a.id === activity).name, channel: voice.name })}](${invite.code})**`)
.setFooter({
text: client.config.embed.footer
})
.setTimestamp();
msg.update({
embeds: [embed]
});
});
}
}
module.exports = Activity;

View file

@ -23,10 +23,6 @@ class Ready extends BaseEvent {
client.logger.log(`${client.user.tag}, ready to serve ${tUsers} users in ${tServers} servers.`, "ready"); client.logger.log(`${client.user.tag}, ready to serve ${tUsers} users in ${tServers} servers.`, "ready");
client.logger.log(`Invite Link: ${client.generateInvite({ scopes: ["bot", "applications.commands"] , permissions: [ PermissionsBitField.Flags.Administrator ] })}`, "ready"); client.logger.log(`Invite Link: ${client.generateInvite({ scopes: ["bot", "applications.commands"] , permissions: [ PermissionsBitField.Flags.Administrator ] })}`, "ready");
// Discord Together
const discordtogether = require("../helpers/discordTogether");
discordtogether.init(client);
// Birthday Announce // Birthday Announce
const birthdays = require("../helpers/birthdays"); const birthdays = require("../helpers/birthdays");
birthdays.init(client); birthdays.init(client);

View file

@ -1,4 +1,129 @@
module.exports.init = function (client) { /*
const { DiscordTogether } = require("discord-together"); Thanks to discord-together =)
client.discordTogether = new DiscordTogether(client); List of IDs from here: https://gist.github.com/GeneralSadaf/42d91a2b6a93a7db7a39208f2d8b53ad
*/
const fetch = require("node-fetch");
const defaultApplications = [
{ id: "880218394199220334", name: "Watch Together", nitro_requirement: false, premium_tier_level: 0, max_participants: -1, use: true },
{ id: "902271654783242291", name: "Sketch Heads", nitro_requirement: false, premium_tier_level: 0, max_participants: 8, use: true },
{ id: "879863976006127627", name: "Word Snacks", nitro_requirement: false, premium_tier_level: 0, max_participants: 8, use: true },
{ id: "878067389634314250", name: "Doodle Crew", nitro_requirement: false, premium_tier_level: 0, max_participants: 16, use: true }, // not in Discord Games Lab guild
{ id: "755827207812677713", name: "Poker Night", nitro_requirement: false, premium_tier_level: 1, max_participants: 7, use: true },
{ id: "832012774040141894", name: "Chess In The Park", nitro_requirement: false, premium_tier_level: 1, max_participants: -1, use: true },
{ id: "879863686565621790", name: "Letter League", nitro_requirement: false, premium_tier_level: 1, max_participants: 8, use: true },
{ id: "852509694341283871", name: "SpellCast", nitro_requirement: false, premium_tier_level: 1, max_participants: 6, use: true },
{ id: "832013003968348200", name: "Checkers In The Park", nitro_requirement: false, premium_tier_level: 1, max_participants: -1, use: true },
{ id: "832025144389533716", name: "Blazing 8s", nitro_requirement: false, premium_tier_level: 1, max_participants: 8, use: true },
{ id: "945737671223947305", name: "Putt Party", nitro_requirement: false, premium_tier_level: 1, max_participants: 8, use: true },
{ id: "903769130790969345", name: "Land-io", nitro_requirement: false, premium_tier_level: 1, max_participants: 16, use: true },
{ id: "947957217959759964", name: "Bobble League", nitro_requirement: false, premium_tier_level: 1, max_participants: 8, use: true },
{ id: "976052223358406656", name: "Ask Away", nitro_requirement: false, premium_tier_level: 1, max_participants: 10, use: true },
{ id: "950505761862189096", name: "Know What I Meme", nitro_requirement: false, premium_tier_level: 1, max_participants: 8, use: true },
// not public
/*
{ id: "773336526917861400", name: "Betrayal.io", nitro_requirement: false, premium_tier_level: 0, max_participants: null, use: false },
{ id: "814288819477020702", name: "Fishington.io", nitro_requirement: false, premium_tier_level: 0, max_participants: null, use: false },
{ id: "879864070101172255", name: "Sketchy Artist", nitro_requirement: false, premium_tier_level: 0, max_participants: 12, use: false },
{ id: "879863881349087252", name: "Awkword", nitro_requirement: false, premium_tier_level: 0, max_participants: 12, use: false },
*/
];
/**
* Class symbolizing a DiscordTogether
* @template {Object.<String, String>} T
*/
class DiscordTogether {
/**
* Create a new DiscordTogether
* @param {import("../base/JaBa")} client
* @param {T} applications
* @example
* const Discord = require("discord.js");
* const client = new Discord.Client({ intents: [Discord.Intents.FLAGS.GUILDS, Discord.Intents.FLAGS.GUILD_MESSAGES] });
* const { DiscordTogether } = require("discord-together");
*
* client.discordTogether = new DiscordTogether(client);
*
* client.on("message", async message => {
* if (message.content === "start") {
* client.discordTogether.createTogetherCode(message.member.voice.channelID, "puttparty").then(async invite => {
* return message.channel.send(`${invite.code}`);
* });
* };
* });
*
* client.login("your token");
*/
constructor(client) {
if (!client) throw new SyntaxError("Invalid Discord.Client !");
/**
* Discord.Client
*/
this.client = client;
/**
* Discord Together applications
*/
this.applications = defaultApplications;
}
/**
* Create a Discord Together invite code (note: send the invite using markdown link)
* @param {String} voiceChannelId
* @param {keyof (defaultApplications & T)} option
* @example
* client.on("message", async message => {
* if (message.content === "start") {
* client.discordTogether.createTogetherCode(message.member.voice.channelID, "youtube").then(async invite => {
* return message.channel.send(`${invite.code}`); // Click the blue link
* });
* };
* });
* @returns {Promise<{ code: String; }>}
*/
async createTogetherCode(voiceChannelId, option) {
/**
* @param {String} code The invite link (only use the blue link)
*/
const returnData = {
code: "none",
};
if (option && this.applications.find(apps => apps.id === option).id) {
const applicationID = this.applications.find(apps => apps.id === option).id;
try {
await fetch(`https://discord.com/api/v10/channels/${voiceChannelId}/invites`, {
method: "POST",
body: JSON.stringify({
max_age: 86400,
max_uses: 0,
temporary: false,
target_type: 2,
target_application_id: applicationID
}),
headers: {
Authorization: `Bot ${this.client.config.token}`,
"Content-Type": "application/json",
},
}).then((res) => res.json())
.then((invite) => {
if (invite.error || !invite.code) throw new Error("An error occured while retrieving data !");
if (Number(invite.code) === 50013) console.warn("Your bot lacks permissions to perform that action");
returnData.code = `https://discord.com/invite/${invite.code}`;
});
} catch (err) {
throw new Error("An error occured while starting Youtube together !");
}
return returnData;
} else {
throw new SyntaxError("Invalid option !");
}
}
}
module.exports = {
DiscordTogether,
defaultApplications
}; };

View file

@ -1,8 +1,7 @@
{ {
"DESCRIPTION": "Создать активность в голосовом канале!", "DESCRIPTION": "Создать активность в голосовом канале",
"USAGE": "activity (активность)", "USAGE": "activity (активность)",
"EXAMPLES": "activity\nactivity chess", "EXAMPLES": "activity\nactivity chess",
"TITLE": "Список доступных активностей", "AVAILABLE_ACTIVITIES": "Доступные активности:",
"FOOTER": "JaBa | Discord Together", "BOOST_NEEDED": "Необходим первый уровень буста или выше!"
"NO_BOOST": "Необходим первый уровень буста или выше!"
} }

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать информацию об эмодзи!", "DESCRIPTION": "Показать информацию об эмодзи",
"USAGE": "emoji [эмодзи]", "USAGE": "emoji [эмодзи]",
"EXAMPLES": "emoji :tada:", "EXAMPLES": "emoji :tada:",
"TITLE": "Информация об {{emoji}}", "TITLE": "Информация об {{emoji}}",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать список команд или помощь по данной команде.", "DESCRIPTION": "Показать список команд или помощь по данной команде",
"USAGE": "help (команда)", "USAGE": "help (команда)",
"EXAMPLES": "help\nhelp ping", "EXAMPLES": "help\nhelp ping",
"CUSTOM": "У добавленных команд нет описания.", "CUSTOM": "У добавленных команд нет описания.",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать информацию о Minecraft сервере!", "DESCRIPTION": "Показать информацию о Minecraft сервере",
"USAGE": "minecraft [IP]", "USAGE": "minecraft [IP]",
"EXAMPLES": "minecraft mc.hypixel.net", "EXAMPLES": "minecraft mc.hypixel.net",
"MISSING_IP": "Укажите IP сервера!", "MISSING_IP": "Укажите IP сервера!",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Отправить жалобу в специальный канал!", "DESCRIPTION": "Отправить жалобу в специальный канал",
"USAGE": "report [@пользователь] (причина)", "USAGE": "report [@пользователь] (причина)",
"EXAMPLES": "report @Jonny_Bro#4226 Нарушение правил", "EXAMPLES": "report @Jonny_Bro#4226 Нарушение правил",
"MISSING_CHANNEL": "Канал для жалоб не настроен!", "MISSING_CHANNEL": "Канал для жалоб не настроен!",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать информацию о сервере!", "DESCRIPTION": "Показать информацию о сервере",
"USAGE": "serverinfo [ID/название]", "USAGE": "serverinfo [ID/название]",
"EXAMPLES": "serverinfo кык\nserverinfo", "EXAMPLES": "serverinfo кык\nserverinfo",
"AFK_CHANNEL": "AFK канал", "AFK_CHANNEL": "AFK канал",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Укоротить ссылку!", "DESCRIPTION": "Укоротить ссылку",
"USAGE": "shorturl [URL]", "USAGE": "shorturl [URL]",
"EXAMPLES": "shorturl https://google.com", "EXAMPLES": "shorturl https://google.com",
"MISSING_URL": "Введите ссылку!" "MISSING_URL": "Введите ссылку!"

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать список администрации сервера!", "DESCRIPTION": "Показать список администрации сервера",
"USAGE": "staff", "USAGE": "staff",
"EXAMPLES": "staff", "EXAMPLES": "staff",
"TITLE": "Персонал {{guild}}", "TITLE": "Персонал {{guild}}",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать статистику бота!", "DESCRIPTION": "Показать статистику бота",
"USAGE": "stats", "USAGE": "stats",
"EXAMPLES": "stats", "EXAMPLES": "stats",
"COUNTS_TITLE": "• __Статистика__", "COUNTS_TITLE": "• __Статистика__",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Отправить предложение в специальный канал!", "DESCRIPTION": "Отправить предложение в специальный канал",
"USAGE": "suggest [предложение]", "USAGE": "suggest [предложение]",
"EXAMPLES": "suggest Новый канал #nsfw :smiling_imp:", "EXAMPLES": "suggest Новый канал #nsfw :smiling_imp:",
"MISSING_CHANNEL": "Канал для предложений не настроен!", "MISSING_CHANNEL": "Канал для предложений не настроен!",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Показать информацию о пользователе!", "DESCRIPTION": "Показать информацию о пользователе",
"USAGE": "userinfo (@пользователь/ID)", "USAGE": "userinfo (@пользователь/ID)",
"EXAMPLES": "userinfo\nuserinfo @Jonny_Bro#4226\nuserinfo 281361531411890186", "EXAMPLES": "userinfo\nuserinfo @Jonny_Bro#4226\nuserinfo 281361531411890186",
"INVALID_USER": "Пользователь с ID `{{search}}` не найден!", "INVALID_USER": "Пользователь с ID `{{search}}` не найден!",

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Получить информацию об IP адресе!", "DESCRIPTION": "Получить информацию об IP адресе",
"USAGE": "whois (IP)", "USAGE": "whois (IP)",
"EXAMPLES": "whois 1.1.1.1", "EXAMPLES": "whois 1.1.1.1",
"NO_IP": "Укажите IP адрес!", "NO_IP": "Укажите IP адрес!",