public async Task Roles(string nameOrSpecies)
        {
            // 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.

            Role role = await BotUtils.GetRoleFromDb(nameOrSpecies);

            if (role is null)
            {
                // No such role exists, so check if a species exists with the given name instead.

                Species[] matching_species = await BotUtils.GetSpeciesFromDb("", nameOrSpecies);

                if (matching_species.Count() == 1)
                {
                    // If only one species was returned, show the roles assigned to that species.
                    await Roles(matching_species[0]);
                }

                else if (matching_species.Count() > 1)
                {
                    // If multiple species were returned, provide a list of matching species for the user to choose from.
                    await BotUtils.ReplyValidateSpeciesAsync(Context, matching_species);
                }

                if (matching_species.Count() > 0)
                {
                    return;
                }
            }

            // If we got here, the role is eiher not null, or it is null, but no species with the given name exists.
            // In this case, proceed to validate the role, and display its information if possible.

            if (!await BotUtils.ReplyAsync_ValidateRole(Context, role))
            {
                return;
            }

            // List all extant species with this role.

            List <Species> species_list = new List <Species>(await BotUtils.GetSpeciesFromDbByRole(role));

            species_list.RemoveAll(x => x.IsExtinct);
            species_list.Sort((lhs, rhs) => lhs.ShortName.CompareTo(rhs.ShortName));

            Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder(EmbedUtils.SpeciesListToEmbedPages(species_list,
                                                                                                                   fieldName: string.Format("Extant species with this role ({0}):", species_list.Count())));

            embed.SetTitle(string.Format("Role: {0}", StringUtils.ToTitleCase(role.name)));
            embed.SetDescription(role.GetDescriptionOrDefault());

            await Bot.DiscordUtils.SendMessageAsync(Context, embed.Build());
        }
        private async Task <Bot.PaginatedMessageBuilder> _buildGenerationEmbedAsync(Generation generation)
        {
            Bot.PaginatedMessageBuilder embed = await RecentCommands.BuildRecentEventsEmbedAsync(generation.StartTimestamp, generation.EndTimestamp);

            TimeAmount time_amount_since = new TimeAmount(DateUtils.GetCurrentTimestamp() - generation.EndTimestamp, TimeUnits.Seconds);

            embed.SetTitle(string.Format("{0} ({1})",
                                         generation.Name,
                                         generation.EndTimestamp == DateUtils.GetMaxTimestamp() ? "Current" : time_amount_since.Reduce().ToString() + " ago"));

            return(embed);
        }
        private async Task _displaySpeciesAddedBy(string username, string thumbnailUrl, List <Species> speciesList)
        {
            if (speciesList.Count() <= 0)
            {
                await BotUtils.ReplyAsync_Info(Context, string.Format("**{0}** has not submitted any species yet.", username));
            }
            else
            {
                Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder(EmbedUtils.SpeciesListToEmbedPages(speciesList,
                                                                                                                       fieldName: string.Format("Species owned by {0} ({1})", username, speciesList.Count())));

                embed.SetThumbnailUrl(thumbnailUrl);

                await Bot.DiscordUtils.SendMessageAsync(Context, embed.Build());
            }
        }
        public async Task Extinct()
        {
            List <Species> sp_list = new List <Species>();

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Species WHERE id IN (SELECT species_id FROM Extinctions);"))
                using (DataTable rows = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in rows.Rows)
                    {
                        sp_list.Add(await SpeciesUtils.SpeciesFromDataRow(row));
                    }

            sp_list.Sort((lhs, rhs) => lhs.ShortName.CompareTo(rhs.ShortName));

            Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder();
            embed.AddPages(EmbedUtils.SpeciesListToEmbedPages(sp_list, fieldName: string.Format("Extinct species ({0})", sp_list.Count()), flags: EmbedPagesFlag.None));

            await Bot.DiscordUtils.SendMessageAsync(Context, embed.Build(), "There are currently no extinct species.");
        }
        public async Task GetZoneType(string arg0)
        {
            // If the given argument is a zone type, display information for that type.
            // If the given argument is a zone name, display information for the type corresponding to that zone.

            ZoneType type = await ZoneUtils.GetZoneTypeAsync(arg0);

            if (!ZoneUtils.ZoneTypeIsValid(type))
            {
                // If no zone type exists with this name, attempt to get the type of the zone with this name.

                Zone zone = await ZoneUtils.GetZoneAsync(arg0);

                if (zone != null)
                {
                    type = await ZoneUtils.GetZoneTypeAsync(zone.ZoneTypeId);
                }
            }

            if (ZoneUtils.ZoneTypeIsValid(type))
            {
                // We got a valid zone type, so show information about the zone type.

                Zone[] zones = await ZoneUtils.GetZonesAsync(type);

                Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder {
                    Title       = string.Format("{0} {1} Zones ({2})", type.Icon, type.Name, zones.Count()),
                    Description = type.Description + "\n\n",
                    Color       = Bot.DiscordUtils.ConvertColor(type.Color)
                };

                await BotUtils.ZonesToEmbedPagesAsync(embed, zones, showIcon : false);

                embed.AddPageNumbers();

                await Bot.DiscordUtils.SendMessageAsync(Context, embed.Build());
            }
            else
            {
                await BotUtils.ReplyAsync_Error(Context, "No such zone type exists.");
            }
        }
        public async Task Zone(string arg0 = "")
        {
            ZoneType zone_type = await ZoneUtils.GetZoneTypeAsync(arg0);

            if (string.IsNullOrEmpty(arg0) || ZoneUtils.ZoneTypeIsValid(zone_type))
            {
                // Display all zones, or, if the user passed in a valid zone type, all zones of that type.

                Zone[] zones = await ZoneUtils.GetZonesAsync(zone_type);

                if (zones.Count() > 0)
                {
                    // We need to make sure that even if the "short" description is actually long, we can show n zones per page.

                    Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder {
                        Title       = StringUtils.ToTitleCase(string.Format("{0} zones ({1})", string.IsNullOrEmpty(arg0) ? "All" : arg0, zones.Count())),
                        Description = string.Format("For detailed zone information, use `{0}zone <zone>` (e.g. `{0}zone {1}`).\n\n",
                                                    OurFoodChainBot.Instance.Config.Prefix,
                                                    zones[0].ShortName.Contains(" ") ? string.Format("\"{0}\"", zones[0].ShortName.ToLower()) : zones[0].ShortName.ToLower())
                    };

                    // Build paginated message.

                    await BotUtils.ZonesToEmbedPagesAsync(embed, zones);

                    embed.AddPageNumbers();

                    if (ZoneUtils.ZoneTypeIsValid(zone_type))
                    {
                        embed.SetColor(Bot.DiscordUtils.ConvertColor(zone_type.Color));
                    }

                    await Bot.DiscordUtils.SendMessageAsync(Context, embed.Build());
                }
                else
                {
                    await BotUtils.ReplyAsync_Info(Context, "No zones have been added yet.");
                }

                return;
            }
            else
            {
                Zone zone = await ZoneUtils.GetZoneAsync(arg0);

                if (await BotUtils.ReplyValidateZoneAsync(Context, zone))
                {
                    List <Embed> pages = new List <Embed>();

                    ZoneType type = await ZoneUtils.GetZoneTypeAsync(zone.ZoneTypeId) ?? new ZoneType();

                    string title       = string.Format("{0} {1}", type.Icon, zone.FullName);
                    string description = zone.GetDescriptionOrDefault();
                    Color  color       = Bot.DiscordUtils.ConvertColor(type.Color);

                    // Get all species living in this zone.

                    List <Species> species_list = new List <Species>(await BotUtils.GetSpeciesFromDbByZone(zone));

                    species_list.Sort((lhs, rhs) => lhs.ShortName.CompareTo(rhs.ShortName));

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

                    List <EmbedBuilder>         embed_pages = EmbedUtils.SpeciesListToEmbedPages(species_list, fieldName: (string.Format("Extant species in this zone ({0}):", species_list.Count())));
                    Bot.PaginatedMessageBuilder paginated   = new Bot.PaginatedMessageBuilder(embed_pages);

                    if (embed_pages.Count() <= 0)
                    {
                        embed_pages.Add(new EmbedBuilder());
                    }

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

                    paginated.SetTitle(title);
                    paginated.SetDescription(description);
                    paginated.SetThumbnailUrl(zone.Pics);
                    paginated.SetColor(color);

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

                    if (species_list.Count() > 0)
                    {
                        EmbedBuilder role_page = new EmbedBuilder();

                        role_page.WithTitle(title);
                        role_page.WithDescription(description);
                        //role_page.WithThumbnailUrl(zone.pics);
                        role_page.WithColor(color);

                        Dictionary <string, List <Species> > roles_map = new Dictionary <string, List <Species> >();

                        foreach (Species sp in species_list)
                        {
                            Role[] roles_list = await SpeciesUtils.GetRolesAsync(sp);

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

                                roles_map["no role"].Add(sp);

                                continue;
                            }

                            foreach (Role role in roles_list)
                            {
                                if (!roles_map.ContainsKey(role.name))
                                {
                                    roles_map[role.name] = new List <Species>();
                                }

                                roles_map[role.name].Add(sp);
                            }
                        }

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

                        foreach (List <Species> i in roles_map.Values)
                        {
                            i.Sort((lhs, rhs) => lhs.ShortName.CompareTo(rhs.ShortName));
                        }

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

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

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

                            foreach (Species j in roles_map[i])
                            {
                                lines.AppendLine(j.ShortName);
                            }

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

                        // Add the page to the builder.

                        paginated.AddReaction("🇷");
                        paginated.SetCallback(async(args) => {
                            if (args.Reaction != "🇷")
                            {
                                return;
                            }

                            args.PaginatedMessage.PaginationEnabled = !args.ReactionAdded;

                            if (args.ReactionAdded)
                            {
                                await args.DiscordMessage.ModifyAsync(msg => msg.Embed = role_page.Build());
                            }
                            else
                            {
                                await args.DiscordMessage.ModifyAsync(msg => msg.Embed = args.PaginatedMessage.Pages[args.PaginatedMessage.PageIndex]);
                            }
                        });
                    }

                    await Bot.DiscordUtils.SendMessageAsync(Context, paginated.Build());
                }
            }
        }
        private async Task _showGenerationAsync(ICommandContext context, Generation generation)
        {
            Bot.PaginatedMessageBuilder embed = await _buildGenerationEmbedAsync(generation);

            await Bot.DiscordUtils.SendMessageAsync(context, embed.Build());
        }
        public static async Task ShowSpeciesInfoAsync(ICommandContext context, Species species)
        {
            if (await BotUtils.ReplyValidateSpeciesAsync(context, species))
            {
                EmbedBuilder  embed = new EmbedBuilder();
                StringBuilder descriptionBuilder = new StringBuilder();

                string embed_title = species.FullName;
                Color  embed_color = Color.Blue;

                CommonName[] common_names = await SpeciesUtils.GetCommonNamesAsync(species);

                if (common_names.Count() > 0)
                {
                    embed_title += string.Format(" ({0})", string.Join(", ", (object[])common_names));
                }

                // Show generation only if generations are enabled.

                if (OurFoodChainBot.Instance.Config.GenerationsEnabled)
                {
                    Generation gen = await GenerationUtils.GetGenerationByTimestampAsync(species.Timestamp);

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

                embed.AddField("Owner", await SpeciesUtils.GetOwnerOrDefaultAsync(species, context), inline: true);

                SpeciesZone[] zone_list = await SpeciesUtils.GetZonesAsync(species);

                if (zone_list.Count() > 0)
                {
                    embed_color = Bot.DiscordUtils.ConvertColor((await ZoneUtils.GetZoneTypeAsync(zone_list
                                                                                                  .GroupBy(x => x.Zone.ZoneTypeId)
                                                                                                  .OrderBy(x => x.Count())
                                                                                                  .Last()
                                                                                                  .Key)).Color);
                }

                string zones_value = new SpeciesZoneCollection(zone_list).ToString(SpeciesZoneCollectionToStringOptions.Default, Bot.DiscordUtils.MaxFieldLength);

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

                // Check if the species is extinct.
                using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Extinctions WHERE species_id=$species_id;")) {
                    cmd.Parameters.AddWithValue("$species_id", species.Id);

                    DataRow row = await Database.GetRowAsync(cmd);

                    if (!(row is null))
                    {
                        embed_title = "[EXTINCT] " + embed_title;
                        embed_color = Color.Red;

                        string reason    = row.Field <string>("reason");
                        long   timestamp = (long)row.Field <decimal>("timestamp");

                        if (!string.IsNullOrEmpty(reason))
                        {
                            descriptionBuilder.AppendLine(string.Format("**Extinct ({0}):** _{1}_\n", await BotUtils.TimestampToDateStringAsync(timestamp), reason));
                        }
                    }
                }

                descriptionBuilder.Append(species.GetDescriptionOrDefault());

                embed.WithTitle(embed_title);
                embed.WithThumbnailUrl(species.Picture);
                embed.WithColor(embed_color);

                if (!string.IsNullOrEmpty(OurFoodChainBot.Instance.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 = OurFoodChainBot.Instance.Config.WikiUrlFormat.Replace("%7B0%7D", "{0}");

                    embed.WithUrl(string.Format(format, Uri.EscapeUriString(GetWikiPageTitleForSpecies(species, common_names))));
                }

                if (embed.Length + descriptionBuilder.Length > DiscordUtils.MaxEmbedLength)
                {
                    // If the description puts us over the character limit, we'll paginate.

                    int pageLength = DiscordUtils.MaxEmbedLength - embed.Length;

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

                    foreach (string pageText in new StringPaginator(descriptionBuilder.ToString())
                    {
                        MaxPageLength = pageLength
                    })
                    {
                        EmbedBuilder page = new EmbedBuilder();

                        page.WithTitle(embed.Title);
                        page.WithThumbnailUrl(embed.ThumbnailUrl);
                        page.WithFields(embed.Fields);
                        page.WithDescription(pageText);

                        pages.Add(page);
                    }

                    PaginatedMessageBuilder builder = new Bot.PaginatedMessageBuilder(pages);
                    builder.AddPageNumbers();
                    builder.SetColor(embed_color);

                    await DiscordUtils.SendMessageAsync(context, builder.Build());
                }
                else
                {
                    embed.WithDescription(descriptionBuilder.ToString());

                    await context.Channel.SendMessageAsync("", false, embed.Build());
                }
            }
        }
Esempio n. 9
0
        public static async Task <Bot.PaginatedMessageBuilder> BuildRecentEventsEmbedAsync(long startTimestamp, long endTimestamp, TimeUnits timeUnit = 0)
        {
            // Get all species created within the given timespan.

            List <Species> new_species = new List <Species>();
            TimeAmount     time_amount = new TimeAmount(endTimestamp - startTimestamp, TimeUnits.Seconds);

            if (timeUnit != 0)
            {
                time_amount = time_amount.ConvertTo(timeUnit);
            }
            else
            {
                time_amount = time_amount.Reduce();
            }

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Species WHERE timestamp >= $start_ts AND timestamp < $end_ts")) {
                cmd.Parameters.AddWithValue("$start_ts", startTimestamp);
                cmd.Parameters.AddWithValue("$end_ts", endTimestamp);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        new_species.Add(await SpeciesUtils.SpeciesFromDataRow(row));
                    }
            }

            new_species.Sort();

            // Get all extinctions that occurred recently.

            List <Species> extinct_species = new List <Species>();

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Extinctions WHERE timestamp >= $start_ts AND timestamp < $end_ts")) {
                cmd.Parameters.AddWithValue("$start_ts", startTimestamp);
                cmd.Parameters.AddWithValue("$end_ts", endTimestamp);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        extinct_species.Add(await BotUtils.GetSpeciesFromDb(row.Field <long>("species_id")));
                    }
            }

            extinct_species.Sort();

            // Build embed.

            Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder();
            List <EmbedBuilder>         pages = new List <EmbedBuilder>();
            List <string> field_lines         = new List <string>();

            if (new_species.Count() > 0)
            {
                foreach (Species sp in new_species)
                {
                    field_lines.Add(sp.FullName);
                }

                EmbedUtils.AddLongFieldToEmbedPages(pages, field_lines, fieldName: string.Format("New species ({0})", new_species.Count()));

                field_lines.Clear();
            }

            if (extinct_species.Count() > 0)
            {
                foreach (Species sp in extinct_species)
                {
                    field_lines.Add(sp.FullName);
                }

                EmbedUtils.AddLongFieldToEmbedPages(pages, field_lines, fieldName: string.Format("Extinctions ({0})", extinct_species.Count()));

                field_lines.Clear();
            }

            embed.AddPages(pages);

            embed.SetTitle(string.Format("Recent events ({0})", time_amount.ToString()));
            embed.SetFooter(string.Empty); // remove page numbers added automatically
            embed.AddPageNumbers();

            if (embed.FieldCount <= 0)
            {
                embed.SetDescription("No events");
            }

            return(embed);
        }
Esempio n. 10
0
        public static async Task ShowRecentEventsAsync(ICommandContext context, long startTimestamp, long endTimestamp, TimeUnits timeUnit = 0)
        {
            Bot.PaginatedMessageBuilder embed = await BuildRecentEventsEmbedAsync(startTimestamp, endTimestamp, timeUnit);

            await Bot.DiscordUtils.SendMessageAsync(context, embed.Build());
        }