Esempio n. 1
0
        public async Task ReplyLeaderboardAsync(ILeaderboard leaderboard)
        {
            List <string> lines = new List <string>(leaderboard.Select(item => {
                int rankWidth  = leaderboard.Count().ToString().Length;
                int scoreWidth = leaderboard.Max(i => i.Score).ToString().Length;

                return(string.Format("**`{0}.`**{1}`{2}` {3}",
                                     item.Rank.ToString("0".PadRight(rankWidth, '0')),
                                     item.Icon,
                                     item.Score.ToString("0".PadRight(scoreWidth, '0')),
                                     string.Format(item.Rank <= 3 ? "**{0}**" : "{0}", string.IsNullOrEmpty(item.Name) ? "Results" : item.Name.ToTitle())
                                     ));
            }));

            IEnumerable <Discord.Messaging.IEmbed> pages = EmbedUtilities.CreateEmbedPages(string.Empty, lines, itemsPerPage: 20, columnsPerPage: 1, options: EmbedPaginationOptions.AddPageNumbers);

            string title = leaderboard.Title;

            if (string.IsNullOrWhiteSpace(title))
            {
                title = "Leaderboard";
            }

            title = $"🏆 {title.ToTitle()} ({lines.Count()})";

            foreach (Discord.Messaging.IEmbed page in pages)
            {
                page.Title = title;
            }

            await ReplyAsync(new PaginatedMessage(pages));
        }
        public async Task <IResponsiveMessageResponse> GetResponseAsync(ICommandContext context, Messaging.IMessage message, bool allowCancellation = true)
        {
            ResponsiveMessageInfo info = await SendMessageAndReturnInfoAsync(context, message, allowCancellation);

            IResponsiveMessageResponse response = new ResponseMessageResponse(null, true);

            if (info != null)
            {
                // Block until we get a response.

                info.Waiter = new ManualResetEvent(false);
                info.Waiter.WaitOne();

                response = info.Response;

                if (response is null)
                {
                    response = new ResponseMessageResponse(null, true);
                }

                if (response.Canceled)
                {
                    await context.Channel.SendMessageAsync(embed : EmbedUtilities.BuildInfoEmbed("The command has been canceled.").ToDiscordEmbed());
                }
            }

            return(response);
        }
Esempio n. 3
0
        public async Task Roles(string arg0)
        {
            // Possible cases:
            // 1. <role>
            // 2. <species>

            // If a role with this name exists, that's what we'll prioritize (users can use the genus + species overload if they need to).
            // If no such role exists, check for a species with this name instead.

            Common.Roles.IRole role = await Db.GetRoleAsync(arg0);

            if (role.IsValid())
            {
                // The role is valid.
                // List all extant species with this role.

                IEnumerable <ISpecies> species = (await Db.GetSpeciesAsync(role))
                                                 .Where(s => !s.IsExtinct())
                                                 .OrderBy(s => s.GetShortName());

                IEnumerable <Discord.Messaging.IEmbed> pages =
                    EmbedUtilities.CreateEmbedPages($"Extant species with this role ({species.Count()}):", species, options: EmbedPaginationOptions.AddPageNumbers);

                foreach (Discord.Messaging.IEmbed page in pages)
                {
                    page.Title       = $"Role: {role.GetName()}";
                    page.Description = role.GetDescriptionOrDefault();
                }

                await ReplyAsync(new Discord.Messaging.PaginatedMessage(pages));
            }
            else
            {
                // The role is not valid.

                IEnumerable <ISpecies> matchingSpecies = await Db.GetSpeciesAsync(string.Empty, arg0);

                if (matchingSpecies.Count() > 0)
                {
                    ISpecies species = await ReplyValidateSpeciesAsync(matchingSpecies);

                    if (species.IsValid())
                    {
                        await ReplyRolesAsync(matchingSpecies.First());
                    }
                }
                else
                {
                    // There were no matching species, so just say that the role is invalid.

                    await this.ReplyValidateRoleAsync(role);
                }
            }
        }
Esempio n. 4
0
        public EmbedBuilder CreateResponseEmbed(ResponseFormat format = ResponseFormat.Default,
                                                string title          = "", string description = "", bool hasDefaultFooter = true)
        {
            var builder = EmbedUtilities.CreateResponseEmbed(format, title, description);

            var defaultFooter = new EmbedFooterBuilder()
                                .WithIconUrl(Context.User.GetAvatarUrl())
                                .WithText($"{(Context.User as IGuildUser).Nickname}#{Context.User.Discriminator}");

            if (hasDefaultFooter)
            {
                builder.WithFooter(defaultFooter);
            }

            return(builder);
        }
Esempio n. 5
0
        private async Task ReadyAsync()
        {
            foreach (IGuild guild in Client.Guilds)
            {
                await OnLogAsync(LogSeverity.Info, Name, $"Joined {guild.Name} ({guild.Id})");
            }

            if (restartChannel != null && restartMessage != null)
            {
                ulong restartMessageId = restartMessage.Id;
                ulong restartChannelId = restartChannel.Id;

                // Attempt to get the channel the bot was restarted from.

                restartChannel = Client.GetChannel(restartChannelId) as IMessageChannel;

                if (restartChannel is null)
                {
                    restartChannel = await Client.GetDMChannelAsync(restartChannelId) as IMessageChannel;
                }

                // Attempt to get the confirmation message.

                if (restartChannel != null)
                {
                    restartMessage = await restartChannel.GetMessageAsync(restartMessageId) as IUserMessage;
                }
                else
                {
                    restartMessage = null;
                }

                if (restartMessage != null)
                {
                    // Modify the confirmation message.

                    await restartMessage.ModifyAsync(async m => {
                        m.Embed = EmbedUtilities.BuildSuccessEmbed($"Restarting {Name.ToBold()}... and we're back!").ToDiscordEmbed();

                        await Task.CompletedTask;
                    });
                }
            }

            restartChannel = null;
            restartMessage = null;
        }
Esempio n. 6
0
        public async Task Prey([Remainder] string speciesName)
        {
            speciesName = StringUtilities.StripOuterQuotes(speciesName);

            ISpecies species = await GetSpeciesOrReplyAsync(speciesName);

            if (species.IsValid())
            {
                // Get the preyed-upon species.

                IEnumerable <IPredationInfo> preySpecies = (await Db.GetPreyAsync(species))
                                                           .OrderBy(info => info.Species.GetShortName());

                if (preySpecies.Count() > 0)
                {
                    List <string> lines = new List <string>();

                    foreach (IPredationInfo preyInfo in preySpecies)
                    {
                        string line = TaxonFormatter.GetString(preyInfo.Species);

                        if (!string.IsNullOrEmpty(preyInfo.Notes))
                        {
                            line += (string.Format(" ({0})", preyInfo.Notes.ToLowerInvariant()));
                        }

                        lines.Add(line);
                    }

                    string title = string.Format("Species preyed upon by {0} ({1})", TaxonFormatter.GetString(species, false), preySpecies.Count());

                    IEnumerable <Discord.Messaging.IEmbed> pages = EmbedUtilities.CreateEmbedPages(string.Empty, lines, columnsPerPage: 2, options: EmbedPaginationOptions.AddPageNumbers);

                    Discord.Messaging.IPaginatedMessage message = new Discord.Messaging.PaginatedMessage(pages);

                    message.SetTitle(title);

                    await ReplyAsync(message);
                }
                else
                {
                    await ReplyInfoAsync(string.Format("**{0}** does not prey upon any other species.", species.GetShortName()));
                }
            }
        }
Esempio n. 7
0
        // Private members

        private async Task ReplySpeciesAddedByAsync(ICreator creator, string thumbnailUrl, IEnumerable <ISpecies> species)
        {
            if (species.Count() <= 0)
            {
                await ReplyInfoAsync($"**{creator}** has not submitted any species yet.");
            }
            else
            {
                IEnumerable <Discord.Messaging.IEmbed> pages = EmbedUtilities.CreateEmbedPages($"Species owned by {creator} ({species.Count()})", species, options: EmbedPaginationOptions.AddPageNumbers);

                foreach (Discord.Messaging.IEmbed page in pages)
                {
                    page.ThumbnailUrl = thumbnailUrl;
                }

                await ReplyAsync(new Discord.Messaging.PaginatedMessage(pages));
            }
        }
Esempio n. 8
0
        public static async Task <IEnumerable <Discord.Messaging.IEmbed> > ZonesToEmbedPagesAsync(int existingLength, IEnumerable <IZone> zones, SQLiteDatabase database, bool showIcon = true)
        {
            List <string> lines          = new List <string>();
            int           zones_per_page = 20;
            int           maxLineLength  = Math.Min(showIcon ? 78 : 80, (DiscordUtils.MaxEmbedLength - existingLength) / zones_per_page);

            foreach (IZone zone in zones)
            {
                IZoneType type = await database.GetZoneTypeAsync(zone.TypeId);

                StringBuilder lineBuilder = new StringBuilder();

                if (showIcon)
                {
                    lineBuilder.Append((type ?? new ZoneType()).Icon);
                    lineBuilder.Append(" ");
                }

                lineBuilder.Append(zone.GetFullName().ToBold());

                if (!string.IsNullOrWhiteSpace(zone.Description))
                {
                    lineBuilder.Append("\t—\t");
                    lineBuilder.Append(zone.Description.GetFirstSentence());
                }

                string line = lineBuilder.ToString();

                if (line.Length > maxLineLength)
                {
                    line = line.Substring(0, maxLineLength - 3) + "...";
                }

                lines.Add(line);
            }

            return(EmbedUtilities.CreateEmbedPages(string.Empty, lines, itemsPerPage: 20, columnsPerPage: 1, options: EmbedPaginationOptions.AddPageNumbers));
        }
Esempio n. 9
0
        public async Task ReplyTaxonAsync(TaxonRankType rank)
        {
            // List all taxa of the given rank.

            IEnumerable <ITaxon> taxa  = (await Db.GetTaxaAsync(rank)).OrderBy(t => t.GetName());
            List <string>        lines = new List <string>();

            foreach (ITaxon taxon in taxa)
            {
                // Count the number of items under this taxon.

                int subtaxaCount = (await Db.GetSubtaxaAsync(taxon)).Count();

                if (subtaxaCount > 0)
                {
                    lines.Add($"{taxon.GetName().ToTitle()} ({subtaxaCount})");
                }
            }

            if (lines.Count() <= 0)
            {
                await ReplyInfoAsync($"No {rank.GetName(true)} have been added yet.");
            }
            else
            {
                string title = $"All {rank.GetName(true)} ({lines.Count()})";

                IEnumerable <Discord.Messaging.IEmbed> pages = EmbedUtilities.CreateEmbedPages(title.ToTitle(), lines, options: EmbedPaginationOptions.AddPageNumbers);

                foreach (Discord.Messaging.IEmbed page in pages)
                {
                    page.Footer += $" — Empty {rank.GetName(true)} are not listed.";
                }

                await ReplyAsync(new PaginatedMessage(pages));
            }
        }
        public static async Task <IPaginatedMessage> BuildRecentEventsMessageAsync(this OfcModuleBase moduleBase, DateTimeOffset start, DateTimeOffset end)
        {
            IEnumerable <ISpecies> newSpecies     = (await moduleBase.Db.GetSpeciesAsync(start, end)).OrderBy(species => moduleBase.TaxonFormatter.GetString(species, false));
            IEnumerable <ISpecies> extinctSpecies = (await moduleBase.Db.GetExtinctSpeciesAsync(start, end)).OrderBy(species => moduleBase.TaxonFormatter.GetString(species, false));

            List <IEmbed> pages = new List <IEmbed>();

            if (newSpecies.Count() > 0)
            {
                EmbedUtilities.AppendEmbedPages(pages, EmbedUtilities.CreateEmbedPages($"New species ({newSpecies.Count()})", newSpecies.Select(species => moduleBase.TaxonFormatter.GetString(species))));
            }

            if (extinctSpecies.Count() > 0)
            {
                EmbedUtilities.AppendEmbedPages(pages, EmbedUtilities.CreateEmbedPages($"Extinctions ({extinctSpecies.Count()})", extinctSpecies.Select(species => moduleBase.TaxonFormatter.GetString(species, false))));
            }

            EmbedUtilities.AddPageNumbers(pages);

            if (pages.Count() <= 0)
            {
                pages.Add(new Embed()
                {
                    Description = "No events"
                });
            }

            foreach (IEmbed page in pages)
            {
                page.Title = $"Recent events ({DateUtilities.GetTimeSpanString(end - start)})";
            }

            IPaginatedMessage message = new PaginatedMessage(pages);

            return(message);
        }
Esempio n. 11
0
        private async Task ShowZoneAsync(IZone zone)
        {
            if (await this.ReplyValidateZoneAsync(zone))
            {
                // Get all species living in this zone.

                List <ISpecies> speciesList = new List <ISpecies>((await Db.GetSpeciesAsync(zone)).Where(species => !species.IsExtinct()));

                speciesList.Sort((lhs, rhs) => TaxonFormatter.GetString(lhs, false).CompareTo(TaxonFormatter.GetString(rhs, false)));

                // Starting building a paginated message.
                // The message will have a paginated species list, and a toggle button to display the species sorted by role.

                string description = zone.GetDescriptionOrDefault();

                if (!speciesList.Any())
                {
                    description += "\n\nThis zone does not contain any species.";
                }

                List <IEmbed> embedPages = new List <IEmbed>();

                if (zone.Fields.Any())
                {
                    embedPages.Add(new Embed());

                    foreach (IZoneField field in zone.Fields)
                    {
                        if (!string.IsNullOrWhiteSpace(field.GetName()) && !string.IsNullOrWhiteSpace(field.GetValue()))
                        {
                            embedPages.Last().AddField(field.GetName(), field.GetValue(), true);
                        }
                    }

                    embedPages.Last().Description = description;
                }

                embedPages.AddRange(EmbedUtilities.CreateEmbedPages(string.Format("Extant species in this zone ({0}):", speciesList.Count()), speciesList, formatter: TaxonFormatter));

                // Add title, decription, etc., to all pages.

                if (!embedPages.Any())
                {
                    embedPages.Add(new Embed());
                }

                IZoneType type = await Db.GetZoneTypeAsync(zone.TypeId) ?? new ZoneType();

                string aliases = zone.Aliases.Any() ? string.Format("({0})", string.Join(", ", zone.Aliases.Select(alias => alias.ToTitle()))) : string.Empty;
                string title   = string.Format("{0} {1} {2}", type.Icon, zone.GetFullName(), aliases).Trim();

                System.Drawing.Color color = type.Color;

                foreach (IEmbed page in embedPages)
                {
                    page.Title        = title;
                    page.ThumbnailUrl = zone.Pictures.FirstOrDefault()?.Url;
                    page.Color        = color;

                    // Add the zone description to all pages if the zone doesn't have any fields (because the info page will be missing).

                    if (!zone.Fields.Any())
                    {
                        page.Description = description;
                    }
                }

                IPaginatedMessage message = new PaginatedMessage(embedPages);

                message.AddPageNumbers();

                // This page will have species organized by role.
                // Only bother with the role page if species actually exist in this zone.

                if (speciesList.Count() > 0)
                {
                    IEmbed rolesPage = new Embed {
                        Title        = title,
                        ThumbnailUrl = zone.GetPictureUrl(),
                        Color        = color
                    };

                    Dictionary <string, List <ISpecies> > rolesMap = new Dictionary <string, List <ISpecies> >();

                    foreach (ISpecies species in speciesList)
                    {
                        IEnumerable <Common.Roles.IRole> roles_list = await Db.GetRolesAsync(species);

                        if (roles_list.Count() <= 0)
                        {
                            if (!rolesMap.ContainsKey("no role"))
                            {
                                rolesMap["no role"] = new List <ISpecies>();
                            }

                            rolesMap["no role"].Add(species);

                            continue;
                        }

                        foreach (Common.Roles.IRole role in roles_list)
                        {
                            if (!rolesMap.ContainsKey(role.GetName()))
                            {
                                rolesMap[role.GetName()] = new List <ISpecies>();
                            }

                            rolesMap[role.GetName()].Add(species);
                        }
                    }

                    // Sort the list of species belonging to each role.

                    foreach (List <ISpecies> i in rolesMap.Values)
                    {
                        i.Sort((lhs, rhs) => TaxonFormatter.GetString(lhs, false).CompareTo(TaxonFormatter.GetString(rhs, false)));
                    }

                    // Create a sorted list of keys so that the roles are in order.

                    List <string> sorted_keys = new List <string>(rolesMap.Keys);
                    sorted_keys.Sort();

                    foreach (string i in sorted_keys)
                    {
                        StringBuilder lines = new StringBuilder();

                        foreach (ISpecies j in rolesMap[i])
                        {
                            lines.AppendLine(TaxonFormatter.GetString(j));
                        }

                        rolesPage.AddField(string.Format("{0}s ({1})", StringUtilities.ToTitleCase(i), rolesMap[i].Count()), lines.ToString(), inline: true);
                    }

                    // Add the page to the builder.

                    message.AddReaction("🇷", async(args) => {
                        if (args.Emoji != "🇷")
                        {
                            return;
                        }

                        args.Message.PaginationEnabled = !args.ReactionAdded;

                        if (args.ReactionAdded)
                        {
                            args.Message.CurrentPage = new Message()
                            {
                                Embed = rolesPage
                            }
                        }
                        ;
                        else
                        {
                            args.Message.CurrentPage = null;
                        }

                        await Task.CompletedTask;
                    });
                }

                await ReplyAsync(message);
            }
        }
Esempio n. 12
0
 public static void AddLines(this IPaginatedMessage message, string listTitle, IEnumerable <string> listItems, int itemsPerPage = EmbedUtilities.DefaultItemsPerPage, int columnsPerPage = EmbedUtilities.DefaultColumnsPerPage, EmbedPaginationOptions options = EmbedPaginationOptions.None)
 {
     message.AddPages(EmbedUtilities.CreateEmbedPages(listTitle, listItems, itemsPerPage, columnsPerPage, options));
 }
Esempio n. 13
0
        public async Task Help([Remainder] string commandName)
        {
            ICommandHelpInfo helpInfo = await HelpService.GetCommandHelpInfoAsync(commandName.Trim());

            await ReplyAsync(embed : EmbedUtilities.BuildCommandHelpInfoEmbed(helpInfo, Config).ToDiscordEmbed());
        }
Esempio n. 14
0
        public async Task Help()
        {
            IEnumerable <ICommandHelpInfo> helpInfos = await HelpService.GetCommandHelpInfoAsync(Context);

            await ReplyAsync(embed : EmbedUtilities.BuildCommandHelpInfoEmbed(helpInfos, Config).ToDiscordEmbed());
        }
Esempio n. 15
0
        public async Task EvaluateAsync([Remainder, Summary("Code to evaluate.")] string input)
        {
            var codeblockRegex = new Regex(@"((?<=^```[a-z]*?)\n[.\s\S]*(?=(\n)?```$))|((?<=^```)(.*)(?=```$))",
                                           RegexOptions.Compiled | RegexOptions.IgnoreCase);

            var matches = codeblockRegex.Matches(input);

            if (matches.Count is 0)
            {
                throw new ArgumentException("You need to wrap the code into a code block.", nameof(input));
            }

            var code = matches.First().Value;

            var msg = await EmbedUtilities.EmbedResponseAsync(Context.Message, ResponseFormat.Default, "Evaluating...");

            var globals = new EvaluationUtilities.EvaluationEnvironment()
            {
                Client  = Context.Client,
                Context = Context,
                Message = Context.Message
            };

            var scriptOptions = EvaluationUtilities.ScriptOptions;

            var compilationStopwatch = Stopwatch.StartNew();
            var script   = CSharpScript.Create(code, scriptOptions, typeof(EvaluationUtilities.EvaluationEnvironment));
            var compiled = script.Compile();

            compilationStopwatch.Stop();

            if (compiled.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                var errorCompilationTime   = compilationStopwatch.ElapsedMilliseconds.ToString("#,##0");
                var errorCompilationErrors = compiled.Length.ToString("#,##0");
                var errorDescription       = $"Compilation failed after {Format.Code($"{errorCompilationTime}ms")} " +
                                             $"with {errorCompilationErrors} error{(errorCompilationErrors != "1" ? "s" : "")}";

                var errorEmbed = EmbedUtilities.CreateResponseEmbed(ResponseFormat.Error, description: errorDescription);

                foreach (var error in compiled.Take(3))
                {
                    var ls = error.Location.GetLineSpan();

                    var errorLine = ls.StartLinePosition.Line.ToString("#,##0");
                    var errorChar = ls.StartLinePosition.Character.ToString("#,##0");

                    errorEmbed.AddField(
                        $"Error at {Format.Code($"{errorLine}, {errorChar}")}",
                        Format.Code(error.GetMessage(), "ini"),
                        false
                        );
                }

                if (compiled.Length > 3)
                {
                    var errorsOmitted = (compiled.Length - 3).ToString("#,##0");
                    errorEmbed.AddField("Some errors omitted", $"{errorsOmitted} more errors not displayed.", false);
                }

                await msg.ModifyAsync(props =>
                {
                    props.Embed = errorEmbed.Build();
                });

                return;
            }

            Exception            exception = null;
            ScriptState <object> state     = null;
            var executionStopwatch         = Stopwatch.StartNew();

            try
            {
                state = await script.RunAsync(globals);

                exception = state.Exception;
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            executionStopwatch.Stop();

            if (exception != null)
            {
                var executionErrorTime = executionStopwatch.ElapsedMilliseconds.ToString("#,##0");

                var description = $"Execution failed after {Format.Code($"{executionErrorTime}ms")}" +
                                  $"{exception.GetType()}: {Format.Code(exception.Message, "ini")}";


                var embed = CreateResponseEmbed(ResponseFormat.Error, description: description);

                await Context.AnswerAsync(embed : embed.Build());

                return;
            }

            // Execution Succeeded
            var compilationTime = compilationStopwatch.ElapsedMilliseconds.ToString("#,##0");
            var executionTime   = executionStopwatch.ElapsedMilliseconds.ToString("#,##0");

            var result = state.ReturnValue != null?state.ReturnValue.ToString() : "No value returned.";

            var successEmbed = CreateResponseEmbed(ResponseFormat.Success)
                               .WithDescription($"Took {Format.Code($"{compilationTime}ms")} to compile, " +
                                                $"{Format.Code($"{executionTime}ms")} to execute.")
                               .AddField("Result", Format.Code(result, "json"), false)
                               .WithFooter(new EmbedFooterBuilder().WithText($"· react with ❌ to delete."));

            if (state.ReturnValue != null)
            {
                successEmbed.AddField("Return Type", Format.Code(state.ReturnValue.GetType().ToString()), true);
            }

            await msg.ModifyAsync(props =>
            {
                props.Embed = successEmbed.Build();
            });

            _ = Interactivity.NextReactionAsync(actions: (r, _) =>
            {
                if (r.Emote.Name is "❌")
                {
                    return(msg.DeleteAsync());
                }
                else
                {
                    return(Task.CompletedTask);
                }
            });
        }
Esempio n. 16
0
 public static void AddPageNumbers(this IPaginatedMessage message)
 {
     EmbedUtilities.AddPageNumbers(message.Select(page => page.Embed).Where(embed => embed != null));
 }
Esempio n. 17
0
        public async Task HandleCommandResult(ShadeContext context, IResult result)
        {
            if (result.IsSuccess)
            {
                return;
            }

            _logger.Error(result.ErrorReason);

            switch (result.Error)
            {
            case CommandError.UnknownCommand:
            {
                // Fail silently.
            }
            break;

            case CommandError.ParseFailed:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;

            case CommandError.BadArgCount:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;

            case CommandError.ObjectNotFound:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;

            case CommandError.MultipleMatches:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;

            case CommandError.UnmetPrecondition:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;

            case CommandError.Exception:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;

            default:
            case CommandError.Unsuccessful:
            {
                await EmbedUtilities.EmbedResponseAsync(context.Message, ResponseFormat.Error,
                                                        description : result.ErrorReason);
            }
            break;
            }
        }
Esempio n. 18
0
        public async Task <IPaginatedMessage> BuildSpeciesMessageAsync(ISpecies species)
        {
            if (!species.IsValid())
            {
                return(null);
            }

            Discord.Messaging.Embed embed = new Discord.Messaging.Embed {
                Title = species.GetFullName()
            };

            if (species.CommonNames.Count() > 0)
            {
                embed.Title += string.Format(" ({0})", string.Join(", ", species.CommonNames.Select(name => name.ToTitle())));
            }

            if (Config.GenerationsEnabled)
            {
                // Add a field for the generation.

                IGeneration gen = await Db.GetGenerationByDateAsync(species.CreationDate);

                embed.AddField("Gen", gen is null ? "???" : gen.Number.ToString(), inline: true);
            }

            // Add a field for the species owner.

            embed.AddField("Owner", await GetCreatorAsync(species.Creator), inline: true);

            // Add a field for the species' zones.

            IEnumerable <ISpeciesZoneInfo> speciesZoneList = (await Db.GetZonesAsync(species))
                                                             .Where(info => !info.Zone.Flags.HasFlag(ZoneFlags.Retired));

            string zonesFieldValue = speciesZoneList.ToString(ZoneListToStringOptions.Default, DiscordUtilities.MaxFieldLength);

            embed.AddField("Zone(s)", string.IsNullOrEmpty(zonesFieldValue) ? "None" : zonesFieldValue, inline: true);

            // Add the species' description.

            StringBuilder descriptionBuilder = new StringBuilder();

            if (species.IsExtinct())
            {
                embed.Title = "[EXTINCT] " + embed.Title;

                if (!string.IsNullOrEmpty(species.Status.Reason))
                {
                    descriptionBuilder.AppendLine(string.Format("**Extinct ({0}):** _{1}_\n", await BotUtils.TimestampToDateStringAsync(DateUtilities.GetTimestampFromDate((DateTimeOffset)species.Status.Date), BotContext), species.Status.Reason));
                }
            }

            descriptionBuilder.Append(species.GetDescriptionOrDefault());

            embed.Description = descriptionBuilder.ToString();

            // Add the species' picture.

            embed.ThumbnailUrl = species.GetPictureUrl();

            if (!string.IsNullOrEmpty(Config.WikiUrlFormat))
            {
                // Discord automatically encodes certain characters in URIs, which doesn't allow us to update the config via Discord when we have "{0}" in the URL.
                // Replace this with the proper string before attempting to call string.Format.

                string format = Config.WikiUrlFormat.Replace("%7B0%7D", "{0}");

                embed.Url = string.Format(format, Uri.EscapeUriString(WikiUtilities.GetWikiPageTitle(species)));
            }

            // Create embed pages.

            IEnumerable <Discord.Messaging.IEmbed> embedPages = EmbedUtilities.CreateEmbedPages(embed, EmbedPaginationOptions.AddPageNumbers | EmbedPaginationOptions.CopyFields);
            IPaginatedMessage paginatedMessage = new PaginatedMessage(embedPages);

            if (speciesZoneList.Count() > 0)
            {
                paginatedMessage.SetColor((await Db.GetZoneTypeAsync(speciesZoneList.GroupBy(x => x.Zone.TypeId).OrderBy(x => x.Count()).Last().Key)).Color);
            }

            if (species.IsExtinct())
            {
                paginatedMessage.SetColor(Color.Red);
            }

            return(paginatedMessage);
        }
Esempio n. 19
0
        protected async Task <IUserMessage> ReplyNewEmbed(string text, Color color)
        {
            var embed = EmbedUtilities.CreateEmbed(text, color);

            return(await ReplyAsync(embed : embed));
        }
Esempio n. 20
0
        public async Task <IPaginatedMessage> BuildTaxonMessageAsync(ITaxon taxon)
        {
            if (!taxon.IsValid())
            {
                return(null);
            }

            List <string> subItems = new List <string>();

            if (taxon.Rank.Type == TaxonRankType.Species)
            {
                ISpecies species = await Db.GetSpeciesAsync(taxon.Id);

                return(await BuildSpeciesMessageAsync(species));
            }
            else if (taxon.Rank.Type == TaxonRankType.Genus)
            {
                // For genera, get all species underneath it.
                // This will let us check if the species is extinct, and cross it out if that's the case.

                List <ISpecies> speciesList = new List <ISpecies>();

                foreach (ITaxon subtaxon in await Db.GetSubtaxaAsync(taxon))
                {
                    speciesList.Add(await Db.GetSpeciesAsync(subtaxon.Id));
                }

                speciesList.Sort((lhs, rhs) => TaxonFormatter.GetString(lhs, false).CompareTo(TaxonFormatter.GetString(rhs, false)));

                foreach (ISpecies species in speciesList.Where(s => s.IsValid()))
                {
                    subItems.Add(TaxonFormatter.GetString(species));
                }
            }
            else
            {
                // Get all subtaxa under this taxon.

                IEnumerable <ITaxon> subtaxa = await Db.GetSubtaxaAsync(taxon);

                // Add all subtaxa to the list.

                foreach (ITaxon subtaxon in subtaxa)
                {
                    if (subtaxon.Rank.Type == TaxonRankType.Species)
                    {
                        // Do not attempt to count sub-taxa for species.

                        subItems.Add(subtaxon.GetName());
                    }
                    else
                    {
                        // Count the number of species under this taxon.
                        // Taxa with no species under them will not be displayed.

                        long speciesCount = await Db.GetSpeciesCountAsync(subtaxon);

                        if (speciesCount > 0)
                        {
                            // Count the sub-taxa under this taxon.

                            long subtaxaCount = (await Db.GetSubtaxaAsync(subtaxon)).Count();

                            // Add the taxon to the list.

                            if (subtaxaCount > 0)
                            {
                                subItems.Add(string.Format("{0} ({1})", subtaxon.GetName(), subtaxaCount));
                            }
                        }
                    }
                }
            }

            // Generate embed pages.

            string title        = taxon.CommonNames.Count() <= 0 ? taxon.GetName() : string.Format("{0} ({1})", taxon.GetName(), taxon.GetCommonName());
            string fieldTitle   = string.Format("{0} in this {1} ({2}):", taxon.GetChildRank().GetName(true).ToTitle(), taxon.GetRank().GetName().ToLowerInvariant(), subItems.Count());
            string thumbnailUrl = taxon.GetPictureUrl();

            StringBuilder description = new StringBuilder();

            description.AppendLine(taxon.GetDescriptionOrDefault());

            if (subItems.Count() <= 0)
            {
                description.AppendLine();
                description.AppendLine(string.Format("This {0} contains no {1}.", taxon.GetRank().GetName(), taxon.GetChildRank().GetName(true)));
            }

            List <Discord.Messaging.IEmbed> pages = new List <Discord.Messaging.IEmbed>(EmbedUtilities.CreateEmbedPages(fieldTitle, subItems, options: EmbedPaginationOptions.AddPageNumbers));

            if (!pages.Any())
            {
                pages.Add(new Discord.Messaging.Embed());
            }

            IPaginatedMessage paginatedMessage = new PaginatedMessage(pages);

            foreach (Discord.Messaging.IEmbed page in paginatedMessage.Select(m => m.Embed))
            {
                page.Title        = title;
                page.ThumbnailUrl = thumbnailUrl;
                page.Description  = description.ToString();

                if (subItems.Count() > 0 && taxon.GetRank() != TaxonRankType.Genus)
                {
                    page.Footer += string.Format(" — Empty {0} are not listed.", taxon.GetChildRank().GetName(true));
                }
            }

            return(paginatedMessage);
        }