Ejemplo n.º 1
0
        /// <summary>
        /// Searches for a track from YouTube, Soundcloud, or Spotify
        /// </summary>
        /// <param name="context">context for message</param>
        /// <param name="query">Query for YouTube, Soundcloud, or Spotify</param>
        /// <returns></returns>
        public async Task SearchForTrack(SocketCommandContext context, string query)
        {
            Victoria.Responses.Rest.SearchResponse search;
            Regex regex;
            Match match;

            if (!SpotifyLogin)
            {
                return;
            }

            if (!Node.TryGetPlayer(context.Guild, out var player))
            {
                await Node.JoinAsync((context.User as IGuildUser)?.VoiceChannel, context.Channel as ITextChannel);

                player = Node.GetPlayer(context.Guild);
                await player.UpdateVolumeAsync(Program.BotConfig.Volume);
            }

            if (!query.IsUri(out var uri))
            {
                search = await Node.SearchYouTubeAsync(query.Trim());
                await QueueTracksToPlayer(player, search, requester : context.User as IGuildUser);

                return;
            }

            if (uri.Host.ToLower() == "open.spotify.com")
            {
                var tracks = await SearchSpotify(context.Channel, query);

                if (tracks != null)
                {
                    await QueueSpotifyToPlayer(player, tracks, context.User as IGuildUser);
                }
                return;
            }

            search = await Node.SearchAsync(query);

            if (search.LoadStatus is LoadStatus.LoadFailed or LoadStatus.NoMatches)
            {
                var msg = await embedHelper.BuildErrorEmbed($"The link `{query}` failed to load.", "Is this a private video or playlist? Double check if the resource is available for public viewing or not region locked.");

                regex = new Regex(@"(?<vid>(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?v=[\w-]{11})(?:&list=.+)?");
                match = regex.Match(query);

                if (!match.Success)
                {
                    await context.Channel.SendAndRemove(embed : msg, timeout : 15000);

                    return;
                }

                string type = match.Groups["vid"].Value;
                search = await Node.SearchYouTubeAsync(type);

                if (search.LoadStatus == LoadStatus.LoadFailed || search.LoadStatus == LoadStatus.NoMatches)
                {
                    await context.Channel.SendAndRemove(embed : msg, timeout : 15000);

                    return;
                }
            }

            regex = new Regex(@"https?:\/\/(?:www\.)?(?:youtube|youtu)\.(?:com|be)\/?(?:watch\?v=)?(?:[A-z0-9_-]{1,11})(?:\?t=(?<time>\d+))?(&t=(?<time2>\d+)\w)?");
            match = regex.Match(query);
            double time = match switch
            {
                _ when match.Groups["time"].Value != "" => double.Parse(match.Groups["time"].Value),
                   _ when match.Groups["time2"].Value != "" => double.Parse(match.Groups["time2"].Value),
                   _ => - 1
            };
            TimeSpan?timeSpan = (time == -1) ? (TimeSpan?)null : TimeSpan.FromSeconds(time);

            await QueueTracksToPlayer(player, search, timeSpan, context.User as IGuildUser);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// On Reaction handler
        /// </summary>
        /// <param name="message">Cacheable struct from Discord</param>
        /// <param name="messageChannel">SocketChannel reaction occurred in</param>
        /// <param name="reaction">Reaction added</param>
        /// <returns></returns>
        private async Task OnReactionAdded(Cacheable <IUserMessage, ulong> message, Cacheable <IMessageChannel, ulong> messageChannel, SocketReaction reaction)
        {
            var channel = await messageChannel.GetOrDownloadAsync();

            if (channel is not IGuildChannel guildChannel)
            {
                return;
            }
            var msg = await message.GetOrDownloadAsync();

            if (channel.Id != Program.BotConfig.ChannelId && msg.Id != Program.BotConfig.MessageId && !Emojis.Contains(reaction.Emote))
            {
                await Task.CompletedTask;
                return;
            }

            _ = Task.Run(async() =>
            {
                EmojiStates currentState = (EmojiStates)Array.IndexOf(Emojis, reaction.Emote);

                if (reaction.UserId == discord.CurrentUser.Id)
                {
                    await Task.CompletedTask;
                    return;
                }

                await msg.RemoveReactionAsync(reaction.Emote, reaction.User.Value, options: new RequestOptions {
                    RetryMode = RetryMode.RetryRatelimit
                });

                try
                {
                    if (!node.HasPlayer(guildChannel.Guild))
                    {
                        return;
                    }
                }
                catch
                {
                    var error = await embedHelper.BuildErrorEmbed("Guild ID Error", $"Your Guild ID in **{ConfigHelper.ConfigName}** is most likely incorrect.");
                    await channel.SendAndRemove(embed: error, timeout: 15000);
                }

                var player = node.GetPlayer(guildChannel.Guild);

                if (!(player.PlayerState is PlayerState.Playing or PlayerState.Paused) && currentState != EmojiStates.Eject)
                {
                    return;
                }

                switch (currentState)
                {
                case EmojiStates.Previous:
                    {
                        await player.PreviousAsync();
                        break;
                    }

                case EmojiStates.PlayPause:
                    {
                        await player.PauseResumeAsync(embedHelper, player.PlayerState == PlayerState.Paused);
                        break;
                    }

                case EmojiStates.Next:
                    {
                        await player.NextTrackAsync(embedHelper);
                        break;
                    }

                case EmojiStates.Loop:
                    {
                        await player.LoopAsync(audioHelper, embedHelper, channel);
                        break;
                    }

                case EmojiStates.Shuffle:
                    {
                        await player.ShuffleAsync(audioHelper, embedHelper, channel);
                        break;
                    }

                case EmojiStates.Eject:
                    {
                        try
                        {
                            await node.EjectAsync(embedHelper, guildChannel.Guild);
                        }
                        catch
                        {
                            // ignored
                        }

                        break;
                    }

                default:
                    return;
                }
            });
        }