コード例 #1
0
ファイル: AddQuote.cs プロジェクト: mmattbtw/Kaguya
        public async Task Command([Remainder] string text)
        {
            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            IEnumerable <Quote> quotes = server.Quotes;
            int quoteCount             = quotes?.Count() ?? 0;

            if (quoteCount > 0)
            {
                if (server.Quotes.Any(x => x.Text.Equals(text)))
                {
                    var cEmbed = new KaguyaEmbedBuilder(EmbedColor.YELLOW)
                    {
                        Description = "A quote with the same text already exists. Do you want to create this one anyway?"
                    };

                    var data = new ReactionCallbackData("", cEmbed.Build(), true, true, TimeSpan.FromSeconds(120));
                    data.AddCallBack(GlobalProperties.CheckMarkEmoji(), async(c, r) => { await InsertQuote(Context, server, text); });

                    data.AddCallBack(GlobalProperties.NoEntryEmoji(),
                                     async(c, r) => { await SendBasicErrorEmbedAsync("Okay, no action will be taken."); });

                    await InlineReactionReplyAsync(data);

                    return;
                }
            }

            await InsertQuote(Context, server, text);
        }
コード例 #2
0
        public async Task Command()
        {
            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            List <Fish> userFish = await DatabaseQueries.GetAllForUserAsync <Fish>(user.UserId);

            var countFishDicts = new List <Dictionary <FishType, int> >();

            if (userFish.Count == 0)
            {
                await SendBasicErrorEmbedAsync($"You have never fished before. Try it out with " +
                                               $"`{server.CommandPrefix}fish`!");

                return;
            }

            string ownedFishString  = "";
            int    curFishValue     = 0;
            int    allTimeFishValue = 0;

            foreach (FishType type in Enum.GetValues(typeof(FishType)))
            {
                // Creates a new dictionary of how many unsold fish the user has of the given type.
                var         dic = new Dictionary <FishType, int>();
                List <Fish> fishMatchingType = await DatabaseQueries.GetUnsoldFishForUserAsync(user.UserId);

                fishMatchingType = fishMatchingType.Where(x => x.FishType == type).ToList(); // Filter the fish.

                if (userFish.Count == 0)
                {
                    ownedFishString = $"You currently don't own any fish, go catch some!";

                    goto StatsEmbed;
                }

                // We don't care about BAIT_STOLEN because it's not actually a fish.
                if (fishMatchingType.Count != 0)
                {
                    dic.Add(type, fishMatchingType.Count);
                    countFishDicts.Add(dic);
                }
            }

            foreach (Fish fish in userFish)
            {
                allTimeFishValue += fish.Value;
                if (!fish.Sold)
                {
                    curFishValue += Fish.GetPayoutForFish(fish, user.FishExp);
                }
            }

            foreach (Dictionary <FishType, int> dic in countFishDicts)
            {
                ownedFishString += $"Fish: `{dic.Keys.First().ToString()}` - Count: `{dic.Values.First():N0}` - " +
                                   $"Value: `{Fish.GetPayoutForFish(userFish.Where(x => x.FishType == dic.Keys.First() && !x.Sold).ToList(), user.FishExp):N0}` points\n";
            }

            if (ownedFishString.IsNullOrEmpty())
            {
                ownedFishString = "`No fish currently owned.`";
            }

StatsEmbed:
            string rarestFish = null;

            if (userFish.Count(x => !x.Sold && x.FishType != FishType.BAIT_STOLEN) != 0)
            {
                rarestFish = userFish
                             .OrderBy(x => x.FishType)
                             .First(x => x.Sold == false && x.FishType != FishType.BAIT_STOLEN)
                             .FishType
                             .ToString();
            }

            var embed = new KaguyaEmbedBuilder
            {
                Title  = $"Kaguya Fishing - Stats for {Context.User}",
                Fields = new List <EmbedFieldBuilder>
                {
                    new EmbedFieldBuilder
                    {
                        Name  = "Fish Level",
                        Value = $"Fish Exp: `{user.FishExp:N0}` exp.\n" +
                                $"Fish Level: `{(int) FishHandler.GetFishLevel(user.FishExp):N0}`\n" +
                                $"{FishHandler.GetRewardString(user.FishExp, user, false)}"
                    },
                    new EmbedFieldBuilder
                    {
                        Name  = "Statistics",
                        Value = $"Bait stolen: `{userFish.Count(x => x.FishType == FishType.BAIT_STOLEN):N0} times`\n" +
                                $"All-time fish count: `{userFish.Count(x => x.FishType != FishType.BAIT_STOLEN):N0}`\n" +
                                $"All-time fish value: `{allTimeFishValue:N0}` points\n" +
                                $"Unsold fish value: `{curFishValue:N0}` points\n" +
                                $"Total fish sold: `{userFish.Count(x => x.Sold && x.FishType != FishType.BAIT_STOLEN):N0}`\n" +
                                $"Rarest owned fish: `{rarestFish ?? "No fish currently owned."}`\n" +
                                $"Number of owned, unsold fish: `{userFish.Count(x => x.FishType != FishType.BAIT_STOLEN && !x.Sold):N0}`"
                    },
                    new EmbedFieldBuilder
                    {
                        Name  = "Currently Owned Fish",
                        Value = ownedFishString
                    }
                },
                Footer = new EmbedFooterBuilder
                {
                    Text = $"React with a checkmark if you would like all of your Fish IDs DM'd to you!"
                }
            };

            // If they don't have any fish, we don't need to show them.
            if (rarestFish != null && rarestFish.ToLower().Contains("no fish"))
            {
                embed.Fields.RemoveAt(1);
            }

            await InlineReactionReplyAsync(new ReactionCallbackData("",
                                                                    embed.Build(), true, true, TimeSpan.FromSeconds(90))
                                           .AddCallBack(GlobalProperties.CheckMarkEmoji(), async(c, r) =>
            {
                using (var stream = new MemoryStream())
                {
                    var writer = new StreamWriter(stream);
                    foreach (Fish fish in userFish.Where(x => x.FishType != FishType.BAIT_STOLEN && !x.Sold))
                    {
                        await writer.WriteLineAsync($"Fish ID: {fish.FishId} - " +
                                                    $"Fish Type: {fish.FishType.ToString()} - " +
                                                    $"Value: {fish.Value}");
                    }

                    await writer.FlushAsync();
                    stream.Seek(0, SeekOrigin.Begin);

                    await c.User.SendFileAsync(stream, $"Fish for {c.User}.txt");
                    await c.Channel.SendBasicSuccessEmbedAsync($"{c.User.Mention} Alright, I've gone ahead " +
                                                               $"and DM'd you all of your fish!");
                }
            })
                                           .AddCallBack(GlobalProperties.NoEntryEmoji(),
                                                        async(c, r) => { await SendBasicErrorEmbedAsync("Okay, no action will be taken."); }));
        }
コード例 #3
0
ファイル: Search.cs プロジェクト: kaguyabot/Kaguya
        /// <summary>
        ///     Searches the specified <see cref="SearchProvider" /> for the provided <see cref="query" />.
        ///     This method also adds the song to the guild's player queue and will even join the user's voice
        ///     channel automatically.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="query">The song to search for, user input.</param>
        /// <param name="playFirst"></param>
        /// <param name="provider"></param>
        /// <returns></returns>
        public async Task <ReactionCallbackData> SearchAndPlayAsync(ShardedCommandContext context,
                                                                    string query,
                                                                    bool playFirst          = false,
                                                                    SearchProvider provider = SearchProvider.YOU_TUBE)
        {
            User user = await DatabaseQueries.GetOrCreateUserAsync(context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(context.Guild.Id);

            LavaNode           node  = ConfigProperties.LavaNode;
            SocketVoiceChannel curVc = (context.User as SocketGuildUser).VoiceChannel;

            await ConsoleLogger.LogAsync($"Found node and voice channel for guild {context.Guild.Id}.", LogLvl.TRACE);

            if (curVc == null)
            {
                await context.Channel.SendMessageAsync($"{context.User.Mention} You must be in a voice " +
                                                       "channel to use this command.");

                await ConsoleLogger.LogAsync("User was not in voice channel, cancelling music search operation.", LogLvl.TRACE);

                return(null);
            }

            SearchResponse result = provider switch
            {
                SearchProvider.YOU_TUBE => await node.SearchYouTubeAsync(query),
                SearchProvider.SOUNDCLOUD => await node.SearchSoundCloudAsync(query),
                _ => await node.SearchAsync(query)
            };

            if (provider == SearchProvider.TWITCH)
            {
                const string PROVIDER_URL = "www.twitch.tv";
                string       errorString  = "Your search returned no results. Ensure you are only " +
                                            "typing the name of the streamer who you want to watch or a direct link to their stream.\n\n" +
                                            "Note: The streamer must be live for this feature to work.";

                if (!query.ToLower().Contains(PROVIDER_URL))
                {
                    result = await node.SearchAsync($"https://{PROVIDER_URL}/{query}");

                    if (result.Tracks.Count == 0)
                    {
                        await context.Channel.SendBasicErrorEmbedAsync(errorString);

                        await ConsoleLogger.LogAsync($"No livestream found for search {query} in guild {context.Guild.Id}.", LogLvl.TRACE);

                        return(null);
                    }
                }
                else
                {
                    if ((await node.SearchAsync($"https://{PROVIDER_URL}/{query.Split('\\').Last()}")).Tracks.Count == 0 &&
                        (await node.SearchAsync(query)).Tracks.Count == 0)
                    {
                        await context.Channel.SendBasicErrorEmbedAsync(errorString);

                        await ConsoleLogger.LogAsync($"No livestream found for search {query} in guild {context.Guild.Id}.", LogLvl.TRACE);

                        return(null);
                    }
                }
            }

            var tracks = new List <LavaTrack>();

            if (user.IsPremium || server.IsPremium)
            {
                if (result.Tracks.Any())
                {
                    tracks.AddRange(result.Tracks);
                }
            }
            else
            {
                // Limit track duration to 10 minutes for non-premium servers/users.
                if (result.Tracks.Any())
                {
                    tracks.AddRange(result.Tracks.Where(x => x.Duration.TotalMinutes < 10).ToList());
                }
            }

            if (!tracks.Any())
            {
                string suppString = user.IsPremium
                    ? ""
                    : "If you are " +
                                    $"not a [Kaguya Premium Subscriber]({ConfigProperties.KAGUYA_STORE_URL}), " +
                                    "you are only limited to playing songs less than `10 minutes` in duration.";

                await context.Channel.SendBasicErrorEmbedAsync($"Your requested search returned no results. {suppString}");

                await ConsoleLogger.LogAsync("Search request returned no usable " +
                                             $"results in guild {Context.Guild.Id} for query {query}", LogLvl.TRACE);
            }

            var fields    = new List <EmbedFieldBuilder>();
            var callbacks = new List <(IEmote, Func <SocketCommandContext, SocketReaction, Task>)>();

            Emoji[] emojiNums = GlobalProperties.EmojisOneThroughNine();

            LavaPlayer player = node.HasPlayer(context.Guild)
                ? node.GetPlayer(context.Guild)
                : await node.JoinAsync(curVc);

            await ConsoleLogger.LogAsync($"Player found for guild {context.Guild.Id}. Connected to voice channel.", LogLvl.TRACE);

            #region If the track is a livestream:
            if (tracks.Any(x => x.IsStream))
            {
                LavaTrack trackSel   = tracks.First(x => x.IsStream); // Gathers the first stream from the collection.
                string    twitchName = (await ConfigProperties.TwitchApi.V5.Users.GetUserByNameAsync(trackSel.Author)).Matches[0].DisplayName;
                string    playString = player.PlayerState == PlayerState.Playing
                    ? $"Queued stream into position {player.Queue.Count}."
                    : $"Now playing `{twitchName}`'s stream.";

                if (player.PlayerState == PlayerState.Playing)
                {
                    try
                    {
                        player.Queue.Enqueue(trackSel);
                        await ConsoleLogger.LogAsync($"Enqueued livestream {trackSel.Title} in guild {context.Guild.Id}",
                                                     LogLvl.TRACE);
                    }
                    catch (Exception e)
                    {
                        await ConsoleLogger.LogAsync("An exception was thrown when trying to enqueue the livestream " +
                                                     $"{trackSel.Title} in guild {Context.Guild.Id}.\n" +
                                                     $"Exception Message: {e.Message}\n" +
                                                     $"Stack Trace: {e.StackTrace}", LogLvl.WARN);
                    }
                }
                else
                {
                    try
                    {
                        await player.PlayAsync(trackSel);

                        await ConsoleLogger.LogAsync($"Playing livestream {trackSel.Title} in guild {context.Guild.Id}",
                                                     LogLvl.TRACE);
                    }
                    catch (Exception e)
                    {
                        await ConsoleLogger.LogAsync("An exception was thrown when trying to play track " +
                                                     $"{trackSel.Title} in guild {Context.Guild.Id}.\n" +
                                                     $"Exception Message: {e.Message}\n" +
                                                     $"Stack Trace: {e.StackTrace}", LogLvl.WARN);
                    }
                }

                var field = new EmbedFieldBuilder
                {
                    Name  = $"`{twitchName}`'s Stream",
                    Value = $"{playString}\n" // We get rid of backticks for formatting.
                };

                var embed = new KaguyaEmbedBuilder
                {
                    Fields = new List <EmbedFieldBuilder>
                    {
                        field
                    }
                };

                await context.Channel.SendEmbedAsync(embed);

                return(null);
            }
            #endregion

            #region If we have chosen to only play the default track (via $play).
            if (playFirst && tracks.Any())
            {
                LavaTrack trackSel = tracks[0];
                var       field    = new EmbedFieldBuilder
                {
                    Name  = "Track #1.",
                    Value = $"Title: `{trackSel.Title.Replace("`", "")}`\n" + // We get rid of backticks for formatting.
                            $"Duration: `{trackSel.Duration.Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 3)}`\n" +
                            $"Uploader: `{trackSel.Author}`"
                };

                string playString = player.PlayerState == PlayerState.Playing && !player.Track.IsStream
                    ? $"Queued track #1 into position {player.Queue.Count + 1}."
                    : "Now playing track #1.";

                if (player.PlayerState == PlayerState.Playing)
                {
                    if (player.Queue.Count() == 50 && !server.IsPremium)
                    {
                        await ConsoleLogger.LogAsync($"Queue is full in {context.Guild.Id}, sending error.", LogLvl.TRACE);
                        await SendBasicErrorEmbedAsync("Your queue is full! `50 songs` is the maximum " +
                                                       $"for non [Kaguya Premium]({ConfigProperties.KAGUYA_STORE_URL}) " +
                                                       "servers.");
                    }
                    else
                    {
                        player.Queue.Enqueue(trackSel);
                        await ConsoleLogger.LogAsync($"Enqueued track {trackSel.Title} in guild {context.Guild.Id}.", LogLvl.TRACE);

                        if (player.Track.IsStream)
                        {
                            await player.SkipAsync();

                            await ConsoleLogger.LogAsync($"Skipped livestream to play incoming track in guild {context.Guild.Id}.", LogLvl.TRACE);
                        }
                    }
                }
                else
                {
                    try
                    {
                        await player.PlayAsync(trackSel);

                        await ConsoleLogger.LogAsync($"Playing track {trackSel.Title} in guild {context.Guild.Id}",
                                                     LogLvl.TRACE);
                    }
                    catch (Exception e)
                    {
                        await ConsoleLogger.LogAsync("An exception was thrown when trying to play track " +
                                                     $"{trackSel.Title} in guild {Context.Guild.Id}.\n" +
                                                     $"Exception Message: {e.Message}\n" +
                                                     $"Stack Trace: {e.StackTrace}", LogLvl.WARN);
                    }
                }

                if (player.Volume == 0 && player.PlayerState == PlayerState.Playing)
                {
                    await player.UpdateVolumeAsync(75); // Sets the volume back to default if it is muted.

                    await ConsoleLogger.LogAsync($"Automatically set player volume to 75 in guild {context.Guild.Id}.", LogLvl.TRACE);
                }

                var embed = new KaguyaEmbedBuilder
                {
                    Title        = $"Kaguya Music {Centvrio.Emoji.Music.Notes}",
                    Description  = playString,
                    ThumbnailUrl = await trackSel.FetchArtworkAsync(),
                    Fields       = new List <EmbedFieldBuilder>
                    {
                        field
                    }
                };

                await SendEmbedAsync(embed, context);

                return(null);
            }
            #endregion

            int h = tracks.Count;
            for (int i = 0; i < (h < 7 ? h : 7); i++)
            {
                int       i1       = i;
                LavaTrack trackSel = tracks[i];
                var       field    = new EmbedFieldBuilder
                {
                    Name  = $"Track {i1 + 1}.",
                    Value = $"Title: `{trackSel.Title.Replace("`", "")}`\n" + // We get rid of backticks for formatting.
                            $"Duration: `{trackSel.Duration.Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Hour, precision: 3)}`\n" +
                            $"Uploader: `{trackSel.Author}`"
                };

                fields.Add(field);
                callbacks.Add((emojiNums[i], async(c, r) =>
                {
                    string playString = player.PlayerState == PlayerState.Playing && !player.Track.IsStream
                                ? $"Queued track #{i1 + 1} into position {player.Queue.Count + 1}."
                                : $"Now playing track #{i1 + 1}.";

                    if (player.PlayerState == PlayerState.Playing)
                    {
                        if (player.Queue.Count() == 50 && !server.IsPremium)
                        {
                            await ConsoleLogger.LogAsync($"Queue was full in guild {context.Guild.Id}. Sending error message.", LogLvl.TRACE);
                            await SendBasicErrorEmbedAsync("Your queue is full! `50 songs` is the maximum " +
                                                           $"for non [Kaguya Premium]({ConfigProperties.KAGUYA_STORE_URL}) " +
                                                           "servers.");

                            return;
                        }

                        player.Queue.Enqueue(trackSel);
                        await ConsoleLogger.LogAsync($"Enqueued track {trackSel} in guild {context.Guild.Id}", LogLvl.TRACE);

                        if (player.Track.IsStream)
                        {
                            await player.SkipAsync();
                            await ConsoleLogger.LogAsync("Automatically skipped livestream to play" +
                                                         $" incoming track in guild {context.Guild.Id}", LogLvl.TRACE);
                        }
                    }
                    else
                    {
                        try
                        {
                            await player.PlayAsync(trackSel);
                            await ConsoleLogger.LogAsync($"Playing track {trackSel.Title} in guild {context.Guild.Id}",
                                                         LogLvl.TRACE);
                        }
                        catch (Exception e)
                        {
                            await ConsoleLogger.LogAsync("An exception was thrown when trying to play track " +
                                                         $"{trackSel.Title} in guild {Context.Guild.Id}.\n" +
                                                         $"Exception Message: {e.Message}\n" +
                                                         $"Stack Trace: {e.StackTrace}", LogLvl.WARN);
                        }
                    }

                    if (player.Volume == 0 && player.PlayerState == PlayerState.Playing)
                    {
                        await player.UpdateVolumeAsync(75);         // Sets the volume back to default if it is muted.
                        await ConsoleLogger.LogAsync($"Automatically set volume to 75 in guild {context.Guild.Id}", LogLvl.TRACE);
                    }

                    var embed = new KaguyaEmbedBuilder
                    {
                        Title = $"Kaguya Music {Centvrio.Emoji.Music.Notes}",
                        Description = playString,
                        ThumbnailUrl = await trackSel.FetchArtworkAsync(),
                        Fields = new List <EmbedFieldBuilder>
                        {
                            field
                        }
                    };

                    await SendEmbedAsync(embed);
                }
                               ));
            }

            callbacks.Add((GlobalProperties.NoEntryEmoji(), async(c, r) =>
            {
                await c.Message.DeleteAsync();
                await r.Message.Value.DeleteAsync();
            }));

            string s = tracks.Count == 1 ? "" : "s";
            var    songDisplayEmbed = new KaguyaEmbedBuilder
            {
                Title       = "Kaguya Music Search Results",
                Description = $" I found {tracks.Count} track{s} from {provider}, " +
                              $"{(tracks.Count > 5 ? "but here are the top 5" : "here they are")}. " +
                              "Please select a track to play.",
                Fields = fields
            };

            var data = new ReactionCallbackData("", songDisplayEmbed.Build(), false, false,
                                                TimeSpan.FromSeconds(60));

            data.SetCallbacks(callbacks);

            return(data);
        }
    }