コード例 #1
0
        public async Task Play(CommandContext context, [RemainingText, Description("Ссылка на трек")] Uri trackUri)
        {
            var loadResult = await this.Music.Lavalink.LavalinkNode.GetTracksAsync(trackUri);

            if (loadResult.LoadResultType == LavalinkLoadResultType.LoadFailed || loadResult.LoadResultType == LavalinkLoadResultType.NoMatches || !loadResult.Tracks.Any())
            {
                throw new DiscordUserInputException("Ошибка загрузки треков", nameof(trackUri));
            }

            var tracks      = loadResult.Tracks.Select(x => new RemoteMusicItem(x, context.Member)).ToArray();
            var remoteMusic = this.GuildMusic.MusicSources[(int)MusicSourceType.RemoteMusicData] as RemoteMusicData;

            remoteMusic.Add(tracks);


            await this.GuildMusic.CreatePlayerAsync(context.Member.VoiceState.Channel).ConfigureAwait(false);

            if (this.GuildMusic.IsPlaying)
            {
                await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                           .WithTitle($"{tracks.Length} трек(ов) было добавлено в очередь")).ConfigureAwait(false);
            }
            else
            {
                if (this.GuildMusic.PlayingMessage == null)
                {
                    this.GuildMusic.PlayingMessage = await context.RespondAsync(embed : await this.GuildMusic.NowPlayingEmbedAsync().ConfigureAwait(false)).ConfigureAwait(false);
                }
                await this.GuildMusic.Start();
            }
        }
コード例 #2
0
ファイル: TagCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task ForceDeleteTag(CommandContext context,
                                         [RemainingText, Description("Название тега который нужно удалить")] string name)
        {
            if (string.IsNullOrWhiteSpace(name) || ForbiddenNames.Contains(name.ToLower()))
            {
                throw new DiscordUserInputException("Название тега не может быть пустым, полностью состоять из пробелов или называться также как и команды.", nameof(name));
            }

            name = name.ToLowerInvariant();
            var gId = (long)context.Guild.Id;
            Tag tag = await this.Database.Tags.SingleOrDefaultAsync(t => t.Name == name && t.GuildId == gId).ConfigureAwait(false);

            if (tag == null)
            {
                throw new DiscordUserInputException("Тега с таким названием на этом сервере не существует, убедитесь в правильности написания названия названия тега.", nameof(name));
            }
            else
            {
                this.Database.Tags.Remove(tag);
                int rowsAffected = await this.Database.SaveChangesAsync();

                if (rowsAffected > 0)
                {
                    await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                               .WithTitle($"Тег {name} успешно удален")).ConfigureAwait(false);
                }
                else
                {
                    throw new DatabaseException($"Не удалось удалить тег {name}. Убедитесь в том что тег существует и правильности написания названия.", DatabaseActionType.Remove);
                }
            }
        }
コード例 #3
0
 public async Task Stop(CommandContext context)
 {
     this.GuildMusic.Stop();
     foreach (var musicSource in this.GuildMusic.MusicSources)
     {
         musicSource.ClearQueue();
     }
     await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                .WithTitle("Воспроизведение остановлено и списки очищены")).ConfigureAwait(false);
 }
コード例 #4
0
        public async Task Playlists(CommandContext context)
        {
            var playlists = new List <string>();

            lock (this.Bot.UpdateMusicLock)
            {
                playlists = this.Database.Playlist.Select(x => x.PlaylistName).Distinct().ToList();
            }
            await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                       .WithTitle("Список доступных плейлистов")
                                       .WithDescription(string.Join(',', playlists.Select(x => Formatter.InlineCode(x))))).ConfigureAwait(false);
        }
コード例 #5
0
ファイル: TagCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task CreateAsync(CommandContext context,
                                      [Description("Название тега")] string name,
                                      [RemainingText, Description("Содержимое тега")] string contents)
        {
            if (string.IsNullOrWhiteSpace(name) || ForbiddenNames.Contains(name.ToLower()))
            {
                throw new DiscordUserInputException("Название тега не может быть пустым, полностью состоять из пробелов или иметь такое же название как команды.", nameof(name));
            }

            if (string.IsNullOrWhiteSpace(contents))
            {
                throw new DiscordUserInputException("Содержимое тега не может быть пустым или содержать только пробелы.", nameof(contents));
            }

            if (contents.Length > 2000)
            {
                throw new DiscordUserInputException("Длина содержимого тега не может превышать 2000 символов.", nameof(contents));
            }

            name = name.ToLowerInvariant();

            var tag = new Tag
            {
                Id           = Convert.ToInt64(DateTimeOffset.Now.ToUnixTimeMilliseconds()),
                Name         = name,
                TagContent   = contents,
                GuildId      = (long)context.Guild.Id,
                OwnerId      = (long)context.User.Id,
                CreationDate = DateTime.Now,
                TimesUsed    = 0
            };

            if (this.Database.Tags?.Any(t => t.Name == tag.Name && t.GuildId == tag.GuildId) == true)
            {
                throw new DiscordUserInputException("Тег с таким именем существует на данном сервере.", nameof(name));
            }

            await this.Database.Tags.AddAsync(tag).ConfigureAwait(false);

            int rowsAffected = await this.Database.SaveChangesAsync();

            if (rowsAffected > 0)
            {
                await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                           .WithTitle("Тег успешно создан")).ConfigureAwait(false);
            }
            else
            {
                throw new DatabaseException($"Не удалось создать тег {name}. Попробуйте снова.", DatabaseActionType.Add);
            }
        }
コード例 #6
0
        public async Task SwitchPlaylist(CommandContext context, [RemainingText, Description("Название плейлиста")] string playlistName)
        {
            if (string.IsNullOrWhiteSpace(playlistName))
            {
                throw new DiscordUserInputException("Название плейлиста не должно быть пустым", nameof(playlistName));
            }

            var localMS = this.GuildMusic.MusicSources[(int)MusicSourceType.LocalMusicData] as LocalMusicData;

            await localMS.ChangePlaylistAsync(playlistName);

            await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                       .WithTitle($"Плейлист успешно изменен на {playlistName}")).ConfigureAwait(false);
        }
コード例 #7
0
ファイル: TagCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task EditTag(CommandContext context,
                                  [Description("Название тега")] string name,
                                  [RemainingText, Description("Новое содержимое тега")] string newContent)
        {
            if (string.IsNullOrWhiteSpace(name) || ForbiddenNames.Contains(name.ToLower()))
            {
                throw new DiscordUserInputException("Название тега не может быть пустым, полностью состоять из пробелов или называться также как и команды.", nameof(name));
            }


            if (string.IsNullOrWhiteSpace(newContent))
            {
                throw new DiscordUserInputException("Содержимое тега не может быть пустым или содержать одни пробелы.", nameof(newContent));
            }

            if (newContent.Length > 2000)
            {
                throw new DiscordUserInputException("Длина содержимого тега не должна превышать.", nameof(newContent));
            }


            name = name.ToLowerInvariant();

            var gId = (long)context.Guild.Id;
            var uId = (long)context.User.Id;

            Tag tag = await this.Database.Tags.SingleOrDefaultAsync(t => t.Name == name && t.GuildId == gId && t.OwnerId == uId).ConfigureAwait(false);

            if (tag == null)
            {
                throw new DiscordUserInputException("Тега с таким названием на этом сервере не существует, убедитесь в правильности написания названия и в том что вы являетесь владельцем данного тега.", nameof(name));
            }
            else
            {
                tag.TagContent = newContent;
                this.Database.Tags.Update(tag);
                int rowsAffected = await this.Database.SaveChangesAsync();

                if (rowsAffected > 0)
                {
                    await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                               .WithTitle($"Тег {name} успешно изменен")).ConfigureAwait(false);
                }
                else
                {
                    throw new DatabaseException($"Не удалось изменить тег {name}", DatabaseActionType.Update);
                }
            }
        }
コード例 #8
0
        public async Task Shuffle(CommandContext context)
        {
            var remoteMS = this.GuildMusic.MusicSources[(int)MusicSourceType.RemoteMusicData] as RemoteMusicData;

            if (remoteMS.IsPresent())
            {
                remoteMS.Shuffle();
                await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                           .WithTitle("Список из Интернета был перемешан")).ConfigureAwait(false);

                return;
            }

            var localMS = this.GuildMusic.MusicSources[(int)MusicSourceType.LocalMusicData] as LocalMusicData;

            localMS.Shuffle();
            await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                       .WithTitle("Встроенный список был перемешан")).ConfigureAwait(false);
        }
コード例 #9
0
ファイル: TagCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task TransferTag(CommandContext context,
                                      [Description("Участник сервера которому нужно передать владельство над тегом")] DiscordMember memberToGive,
                                      [RemainingText, Description("Название тега")] string name)
        {
            if (string.IsNullOrWhiteSpace(name) || ForbiddenNames.Contains(name.ToLower()))
            {
                throw new DiscordUserInputException("Название тега не может быть пустым, полностью состоять из пробелов или называться как команды.", nameof(name));
            }
            if (memberToGive.Id == context.Member.Id)
            {
                throw new DiscordUserInputException("Вы не можете передать себе владельство над тегом", nameof(memberToGive));
            }

            name = name.ToLowerInvariant();

            var gId = (long)context.Guild.Id;
            var uId = (long)context.User.Id;

            var tag = await this.Database.Tags.SingleOrDefaultAsync(t => t.Name == name && t.GuildId == gId && t.OwnerId == uId).ConfigureAwait(false);

            if (tag == null)
            {
                throw new DiscordUserInputException("Тега с таким названием на этом сервере не существует, убедитесь в правильности написания названия и в том что вы являетесь владельцем данного тега.", nameof(name));
            }
            else
            {
                tag.OwnerId = (long)memberToGive.Id;
                this.Database.Tags.Update(tag);
                int rowsAffected = await this.Database.SaveChangesAsync();

                if (rowsAffected > 0)
                {
                    await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                               .WithTitle($"Владельство над тегом {Formatter.InlineCode(tag.Name)} успешно передано {memberToGive.Mention}"))
                    .ConfigureAwait(false);
                }
                else
                {
                    throw new DatabaseException($"Не удалось передать владельство над тегом { Formatter.InlineCode(tag.Name) } - { memberToGive.Mention}", DatabaseActionType.Update);
                }
            }
        }
コード例 #10
0
ファイル: TagCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task List(CommandContext context)
        {
            var gId = (long)context.Guild.Id;

            var tagsList = this.Database.Tags.Where(t => t.GuildId == gId).ToList();

            if (tagsList?.Any() == true)
            {
                var tagNames = tagsList.OrderBy(x => x.Name).Select(x => $"{Formatter.InlineCode(x.Name)},").ToList();
                // Deleting last comma
                tagNames[tagNames.Count - 1] = tagNames[tagNames.Count - 1].Remove(tagNames[tagNames.Count - 1].Length - 1);

                int length = 0;
                foreach (var tagName in tagNames)
                {
                    length += tagName.Length;
                }

                var embedRespond = EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                   .WithTitle("Теги на этом сервере");

                if (length > 600)
                {
                    var interactivity = context.Client.GetInteractivity();
                    var tagsPaginated = Helpers.GeneratePagesInEmbed(tagNames, embedRespond, 500);
                    await interactivity.SendPaginatedMessageAsync
                        (context.Channel, context.User, tagsPaginated, behaviour : PaginationBehaviour.WrapAround, deletion : PaginationDeletion.DeleteEmojis);
                }
                else
                {
                    string tags = string.Join(' ', tagNames);
                    await context.RespondAsync(embed : embedRespond.WithDescription(tags)).ConfigureAwait(false);
                }
            }
            else
            {
                await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                           .WithTitle($"Тегов на данном сервере не найдено, вы можете создать новый используя {Formatter.InlineCode("J!tag create \"название тега\" \"его содержание\"")}"))
                .ConfigureAwait(false);
            }
        }
コード例 #11
0
        public async Task PlayNextFile(CommandContext context, [RemainingText, Description("Путь к файлу")] string pathToFile)
        {
            if (string.IsNullOrWhiteSpace(pathToFile))
            {
                throw new DiscordUserInputException("Путь к файлу не может быть пустым", nameof(pathToFile));
            }

            if (!File.Exists(pathToFile))
            {
                throw new DiscordUserInputException("Такого файла не существует", nameof(pathToFile));
            }

            var pnData = this.GuildMusic.MusicSources[(int)MusicSourceType.PlayNextData] as PlayNextData;

            pnData.Enqueue(pathToFile);
            using (var file = TagLib.File.Create(pathToFile))
            {
                await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                           .WithDescription($"Следующей песней будет {file.Tag.Title} - {file.Tag.FirstPerformer}.")).ConfigureAwait(false);
            }
        }
コード例 #12
0
ファイル: TagCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task Claim(CommandContext context, [RemainingText, Description("Название тега")] string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new DiscordUserInputException("Название тега не должно быть пустым", nameof(name));
            }
            var gId = (long)context.Guild.Id;
            var tag = await this.Database.Tags.SingleOrDefaultAsync(t => t.Name == name && t.GuildId == gId).ConfigureAwait(false);

            DiscordUser owner = null;
            var         ownId = (ulong)tag.OwnerId;

            try
            {
                owner = await context.Guild.GetMemberAsync(ownId).ConfigureAwait(false);
            }
            catch (NotFoundException)
            {
                tag.OwnerId = (long)context.User.Id;
                this.Database.Tags.Update(tag);
                int rowsAffected = await this.Database.SaveChangesAsync();

                if (rowsAffected > 0)
                {
                    await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                               .WithTitle($"Вы успешно получили владельство над тегом {tag.Name}")).ConfigureAwait(false);

                    return;
                }
                else
                {
                    throw new DatabaseException("Не удалось обновить владельство над тегом  хотя его владелец покинул сервер", DatabaseActionType.Save);
                }
            }

            owner = await context.Client.GetUserAsync(ownId).ConfigureAwait(false);

            await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                       .WithDescription($"Не удалось получить владельство над тегом {tag.Name}, так как его владелец {owner.Mention} все еще находится на сервере")).ConfigureAwait(false);
        }
コード例 #13
0
        public async Task Statistics(CommandContext context)
        {
            var  curProcess  = Process.GetCurrentProcess();
            long memoryBytes = curProcess.PrivateMemorySize64;

            var guildsMembersIds = context.Client.Guilds.Values.Select(x => x.Members.Values.Where(y => !y.IsBot).Select(z => z.Id));
            var ids = new List <ulong>();

            foreach (var el in guildsMembersIds)
            {
                ids.AddRange(el);
            }

            long uniqueUsers = ids.Distinct().LongCount();

            var description = new StringBuilder();

            description.AppendLine("Статистика бота")
            .AppendLine("```cs")
            .AppendLine($"Память занимаемая приложением — {memoryBytes.ToSize(SizeUnits.MB)} MБ")
            .AppendLine($"Время работы бота — {Helpers.GetProcessUptime(curProcess).ToReadableString()}")
            .AppendLine($"Пинг — {context.Client.Ping} мс")
            .AppendLine($"Количество обслуживаемых серверов — {context.Client.Guilds.Count}")
            .AppendLine($"Количество уникальных пользователей — {uniqueUsers}")
            .AppendLine("```")
            .AppendLine("Статистика Lavalink сервера")
            .AppendLine($"```cs")
            .AppendLine($"Активных плееров — {this.Lavalink.Statistics.ActivePlayers}")
            .AppendLine(
                $"Использование ОЗУ Lavalink сервером — {this.Lavalink.Statistics.RamUsed.ToSize(SizeUnits.MB)}МБ")
            .AppendLine($"Время работы Lavalink сервера — {this.Lavalink.Statistics.Uptime.ToReadableString()}")
            .AppendLine("```");

            var embed = EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                        .WithDescription(description.ToString());

            await context.RespondAsync(embed : embed).ConfigureAwait(false);
        }
コード例 #14
0
ファイル: OwnerCommands.cs プロジェクト: N0D4N/JazzBot
        public async Task Evaluate(CommandContext context, [RemainingText, Description("С# код")] string code)
        {
            var codeStart = code.IndexOf("```") + 3;

            codeStart = code.IndexOf("\n", codeStart) + 1;
            var codeEnd = code.LastIndexOf("```");

            if (codeStart == -1 || codeEnd == -1)
            {
                throw new DiscordUserInputException("Код должен находиться внутри в блоке кода", nameof(code));
            }

            code = code.Substring(codeStart, codeEnd - codeStart);

            var embed = EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                        .WithTitle("Код компилируется и выполняется");

            var msg = await context.RespondAsync(embed : embed);

            var globals = new Globals()
            {
                Bot = this.Bot, Context = context, Database = this.Database
            };

            var scriptsOptions = ScriptOptions.Default
                                 .WithImports("System", "System.Diagnostics", "System.Reflection", "System.Text", "System.Collections.Generic", "System.Linq", "System.Threading.Tasks", "DSharpPlus", "DSharpPlus.CommandsNext",
                                              "DSharpPlus.Entities", "JazzBot.Data", "JazzBot.Enums", "JazzBot.Services", "JazzBot.Utilities", "Microsoft.EntityFrameworkCore")
                                 .WithReferences(AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.IsDynamic && !string.IsNullOrWhiteSpace(x.Location)));

            var compileSW      = Stopwatch.StartNew();
            var codeScript     = CSharpScript.Create(code, scriptsOptions, typeof(Globals));
            var compiledScript = codeScript.Compile();

            compileSW.Stop();

            if (compiledScript.Any(x => x.Severity == DiagnosticSeverity.Error))
            {
                embed = EmbedTemplates.ErrorEmbed()
                        .WithDescription(compiledScript.Length > 1 ? $"Произошло {compiledScript.Length} ошибки/ошибок времени компиляции" : "Произошла ошибка компиляции");

                foreach (var error in compiledScript.Take(5))
                {
                    var ls = error.Location.GetLineSpan();
                    embed.AddField($"Ошибка в {ls.StartLinePosition.Line}", Formatter.InlineCode(error.GetMessage()));
                }

                await msg.ModifyAsync(embed : embed.Build());

                return;
            }

            Exception runtimeException = null;

            ScriptState <object> css = null;

            var runtimeSW = Stopwatch.StartNew();

            try
            {
                css = await codeScript.RunAsync(globals).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                runtimeException = ex;
            }
            runtimeSW.Stop();

            if (runtimeException != null)
            {
                embed = EmbedTemplates.ErrorEmbed().WithDescription($"Произошла ошибка времени выполнения после {runtimeSW.ElapsedMilliseconds} мс");

                await msg.ModifyAsync(embed : embed.Build());

                return;
            }

            embed = EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember).WithDescription("Команда выполнена успешно");

            embed.AddField("Результат выполнения", css.ReturnValue == null ? "Значения не возвращено" : Formatter.InlineCode(css.ReturnValue.ToString()))
            .AddField("Время компиляции", compileSW.ElapsedMilliseconds.ToString("#,##0") + "мс", true)
            .AddField("Время выполнения", runtimeSW.ElapsedMilliseconds.ToString("#,##0") + "мс", true);

            if (css.ReturnValue != null)
            {
                embed.AddField("Тип результата", css.ReturnValue.GetType().ToString());
            }

            await msg.ModifyAsync(embed : embed.Build());
        }
コード例 #15
0
 public async Task Playlist(CommandContext context)
 {
     await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                .WithTitle("Все песни в плейлистах")
                                .WithUrl(this.Bot.Config.Miscellaneous.PlaylistLink)).ConfigureAwait(false);
 }
コード例 #16
0
        public async Task PlayNext(CommandContext context, [RemainingText, Description("Название песни")] string songName)
        {
            if (string.IsNullOrWhiteSpace(songName))
            {
                throw new DiscordUserInputException("Название песни не должно быть пустым", nameof(songName));
            }

            var songs = new List <Songs>();

            lock (this.Bot.UpdateMusicLock)
            {
                songs = this.Database.Playlist.ToList();
            }
            var playNexts = new List <PlayNextElement>();
            var nL        = new NormalizedLevenshtein();

            foreach (var song in songs)
            {
                playNexts.Add(new PlayNextElement(song.Path, song.Name, nL.Distance(song.Name, songName)));
            }
            playNexts = playNexts.OrderBy(s => s.Coefficient).ToList();
            var interactivity = context.Client.GetInteractivity();
            var description   = new StringBuilder();

            for (int i = 0; i < 10; i++)
            {
                description.AppendLine($"\n№ {i + 1}; Name: {playNexts[i].Title}.");
            }

            var listMsg = await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                                     .WithTitle("Предолагаемый список песен")
                                                     .WithDescription(description.ToString())
                                                     .WithFooter($"Отправьте {Formatter.InlineCode("0")} для отмены")).ConfigureAwait(false);

            var msg = await interactivity.WaitForMessageAsync(xm => xm.Author.Id == context.User.Id, TimeSpan.FromSeconds(45));

            if (!msg.TimedOut)
            {
                if (int.TryParse(msg.Result.Content, out int res))
                {
                    if (res >= 1 && res <= playNexts.Count)
                    {
                        var pNData = this.GuildMusic.MusicSources[(int)MusicSourceType.PlayNextData] as PlayNextData;
                        pNData.Enqueue(playNexts[res - 1].PathToFile);

                        await listMsg.ModifyAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                                  .WithTitle($"Следующей песней будет {playNexts[res - 1].Title}").Build()).ConfigureAwait(false);
                    }
                    else if (res == 0)
                    {
                        await listMsg.ModifyAsync("Выбор отменен", null).ConfigureAwait(false);
                    }
                    else
                    {
                        await listMsg.ModifyAsync("Данное число выходит за границы", null).ConfigureAwait(false);
                    }
                }
                else
                {
                    await listMsg.ModifyAsync("Ответ не является числом или время вышло", null).ConfigureAwait(false);
                }
            }
            await Task.Delay(TimeSpan.FromSeconds(30));

            await listMsg.DeleteAsync();
        }
コード例 #17
0
        public async Task Play(CommandContext context, [RemainingText, Description("Текст для поиска")] string searchQuery)
        {
            if (string.IsNullOrWhiteSpace(searchQuery))
            {
                throw new DiscordUserInputException("Название песни для поиска не может быть пустым или состоять из пробелов", nameof(searchQuery));
            }

            var searchResults = (await this.Youtube.SearchAsync(searchQuery)).ToArray();
            var description   = new StringBuilder();
            int i             = 1;

            foreach (var el in searchResults)
            {
                description.AppendLine($"{i}. {Formatter.InlineCode(el.VideoTitle)} {Formatter.Bold("—")} {Formatter.InlineCode(el.ChannelName)}");
                i++;
            }
            if (!searchResults.Any())
            {
                throw new DiscordUserInputException("По заданному запросу на Youtube ничего не было найдено", nameof(searchQuery));
            }

            var interactivity = context.Client.GetInteractivity();

            var msg = await context.RespondAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                                 .WithTitle("Выберите песню (ответьте 0 если чтобы отменить команду)")
                                                 .WithDescription(description.ToString())).ConfigureAwait(false);

            var intRes = await interactivity.WaitForMessageAsync(x => x.Author.Id == context.User.Id, TimeSpan.FromSeconds(10));

            if (intRes.TimedOut || !int.TryParse(intRes.Result.Content, out int result))
            {
                await msg.ModifyAsync("Время вышло или ответ не является числом", null).ConfigureAwait(false);

                return;
            }

            if (result < 0 || result > searchResults.Length + 1)
            {
                await msg.ModifyAsync("Число выходит за заданные границы", null).ConfigureAwait(false);

                return;
            }
            if (result == 0)
            {
                await msg.ModifyAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                      .WithTitle("Поиск отменен").Build()).ConfigureAwait(false);

                return;
            }

            var selectedTrack = searchResults[result - 1];
            var loadResult    = await this.Music.Lavalink.LavalinkNode.GetTracksAsync(new Uri($"https://youtu.be/{selectedTrack.VideoId}"));

            if (loadResult.LoadResultType == LavalinkLoadResultType.LoadFailed || !loadResult.Tracks.Any())
            {
                throw new DiscordUserInputException("По данной ссылке ничего не было найдено", nameof(selectedTrack));
            }

            var tracks = loadResult.Tracks.Select(x => new RemoteMusicItem(x, context.Member)).ToArray();

            var remoteMusic = this.GuildMusic.MusicSources[(int)MusicSourceType.RemoteMusicData] as RemoteMusicData;

            remoteMusic.Add(tracks);

            await this.GuildMusic.CreatePlayerAsync(context.Member.VoiceState.Channel).ConfigureAwait(false);

            if (this.GuildMusic.IsPlaying)
            {
                await msg.ModifyAsync(embed : EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                                      .WithTitle($"{tracks.Length} трек(ов) было добавлено в очередь").Build()).ConfigureAwait(false);
            }
            else
            {
                var playingEmbed = await this.GuildMusic.NowPlayingEmbedAsync();

                if (this.GuildMusic.PlayingMessage == null)
                {
                    this.GuildMusic.PlayingMessage = await msg.ModifyAsync(embed : new DiscordEmbedBuilder(playingEmbed)
                    {
                        Description = $"{tracks.Length} трек(ов) было добавлено в очередь\n{playingEmbed.Description}"
                    }.Build()).ConfigureAwait(false);
                }

                await this.GuildMusic.Start();
            }
        }