Ejemplo n.º 1
0
        public async Task GetZone([Remainder] string arg0)
        {
            arg0 = StringUtilities.StripOuterQuotes(arg0);

            // Show either the given zone, or all zones of the given type.

            IZone zone = await Db.GetZoneAsync(arg0);

            if (zone.IsValid())
            {
                // The user passed in a valid zone, so show information about that zone.

                await ShowZoneAsync(zone);
            }
            else
            {
                // The user passed in an invalid zone, so check if it's a valid zone type.

                IZoneType zoneType = await Db.GetZoneTypeAsync(arg0);

                if (zoneType.IsValid())
                {
                    // The user passed in a valid zone type, so show all zones with that type.

                    IEnumerable <IZone> zones = (await Db.GetZonesAsync(zoneType));

                    await ShowZonesAsync(zones, zoneType);
                }
                else
                {
                    await this.ReplyValidateZoneAsync(zone, arg0);
                }
            }
        }
Ejemplo n.º 2
0
        public async Task AddZone(string zoneName, string arg1 = "", string arg2 = "")
        {
            // Cases:
            // 1. <zoneName>
            // 2. <zoneName> <zoneTypeName>
            // 3. <zoneName> <zoneTypeName> <description>
            // 4. <zoneName> <description>

            string zoneTypeName = arg1;
            string description  = arg2;

            if (string.IsNullOrEmpty(zoneName))
            {
                // The user must specify a non-empty zone name.

                await ReplyErrorAsync("Zone name cannot be empty.");
            }
            else
            {
                // Allow the user to specify zones with numbers (e.g. "1") or single letters (e.g. "A").
                // Otherwise, the name is taken as-is.

                zoneName = ZoneUtilities.GetFullName(zoneName).ToLowerInvariant();

                IZoneType zoneType = await Db.GetZoneTypeAsync(arg1);

                if (!zoneType.IsValid())
                {
                    // If an invalid type was provided, assume the user meant it as a description instead (4).

                    description = zoneTypeName;

                    // Attempt to determine the zone type automatically based on the zome name.
                    // This is currently only possible for default zones ("aquatic" or "terrestrial").

                    zoneType = await Db.GetDefaultZoneTypeAsync(zoneName);
                }

                if (await Db.GetZoneAsync(zoneName) != null)
                {
                    // Don't attempt to create the zone if it already exists.

                    await ReplyWarningAsync($"A zone named {ZoneUtilities.GetFullName(zoneName).ToBold()} already exists.");
                }
                else
                {
                    // Add the new zone.

                    await Db.AddZoneAsync(new Zone {
                        Name        = zoneName,
                        Description = description,
                        TypeId      = zoneType.Id
                    });

                    await ReplySuccessAsync($"Successfully created new {zoneType.Name.ToLowerInvariant()} zone, {ZoneUtilities.GetFullName(zoneName).ToBold()}.");
                }
            }
        }
Ejemplo n.º 3
0
        public static bool SetColor(this IZoneType zoneType, string hexColor)
        {
            if (StringUtilities.TryParseColor(hexColor, out Color result))
            {
                zoneType.Color = result;

                return(true);
            }

            return(false);
        }
Ejemplo n.º 4
0
        public async Task GetZoneType(string arg0)
        {
            if (!string.IsNullOrEmpty(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.

                IZoneType type = await Db.GetZoneTypeAsync(arg0);

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

                    IZone zone = await Db.GetZoneAsync(arg0);

                    if (zone != null)
                    {
                        type = await Db.GetZoneTypeAsync(zone.TypeId);
                    }
                }

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

                    IEnumerable <IZone> zones = await Db.GetZonesAsync(type);

                    string embedTitle       = string.Format("{0} {1} Zones ({2})", type.Icon, type.Name, zones.Count()).ToTitle();
                    string embedDescription = type.Description + "\n\n";

                    IEnumerable <IEmbed> pages = await BotUtils.ZonesToEmbedPagesAsync(embedTitle.Length + embedDescription.Length, zones, Db, showIcon : false);

                    foreach (IEmbed page in pages)
                    {
                        page.Description = embedDescription + page.Description;
                    }

                    IPaginatedMessage message = new PaginatedMessage(pages);

                    message.SetTitle(embedTitle);
                    message.SetColor(type.Color);

                    await ReplyAsync(message);
                }
                else
                {
                    await ReplyErrorAsync("No such zone type exists.");
                }
            }
            else
            {
                await GetZoneTypes();
            }
        }
        public static async Task AddZoneTypeAsync(this SQLiteDatabase database, IZoneType type)
        {
            using (SQLiteCommand cmd = new SQLiteCommand("INSERT OR REPLACE INTO ZoneTypes(name, icon, color, description) VALUES($name, $icon, $color, $description)")) {
                cmd.Parameters.AddWithValue("$name", type.Name.ToLowerInvariant());
                cmd.Parameters.AddWithValue("$icon", type.Icon);
                cmd.Parameters.AddWithValue("$color", ColorTranslator.ToHtml(type.Color).ToLowerInvariant());
                cmd.Parameters.AddWithValue("$description", type.Description);

                await database.ExecuteNonQueryAsync(cmd);
            }
        }
Ejemplo n.º 6
0
        public async Task SetZoneType(string zoneName, string zoneType)
        {
            IZone zone = await Db.GetZoneAsync(zoneName);

            IZoneType type = await Db.GetZoneTypeAsync(zoneType);

            if (await BotUtils.ReplyValidateZoneAsync(Context, zone) && await BotUtils.ReplyValidateZoneTypeAsync(Context, type))
            {
                zone.TypeId = type.Id;

                await Db.UpdateZoneAsync(zone);

                await BotUtils.ReplyAsync_Success(Context, string.Format("Successfully set the type of {0}**{1}** to **{2}**.",
                                                                         zone.GetFullName().StartsWith("Zone") ? string.Empty : "zone ",
                                                                         zone.GetFullName(),
                                                                         type.Name));
            }
        }
Ejemplo n.º 7
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));
        }
Ejemplo n.º 8
0
        // Private members

        private async Task ShowZonesAsync(IEnumerable <IZone> zones, IZoneType 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.

                string embedTitle       = string.Format("{0} zones ({1})", type.IsValid() ? type.Name : "All", zones.Count()).ToTitle();
                string embedDescription = string.Format("For detailed zone information, use `{0}zone <zone>` (e.g. `{0}zone {1}`).\n\n",
                                                        Config.Prefix,
                                                        zones.First().GetShortName().Contains(" ") ? string.Format("\"{0}\"", zones.First().GetShortName().ToLowerInvariant()) : zones.First().GetShortName().ToLowerInvariant());

                // Build paginated message.

                IEnumerable <IEmbed> pages = await BotUtils.ZonesToEmbedPagesAsync(embedTitle.Length + embedDescription.Length, zones, Db);

                foreach (IEmbed page in pages)
                {
                    page.Description = embedDescription + page.Description;
                }

                IPaginatedMessage message = new PaginatedMessage(pages);

                message.SetTitle(embedTitle);

                if (type.IsValid())
                {
                    message.SetColor(type.Color);
                }

                await ReplyAsync(message);
            }
            else
            {
                await ReplyInfoAsync("No zones have been added yet.");
            }
        }
Ejemplo n.º 9
0
 public static bool IsValid(this IZoneType zoneType)
 {
     return(zoneType != null && zoneType.Id.HasValue && zoneType.Id >= 0);
 }
Ejemplo n.º 10
0
 public static void SetColor(this IZoneType zoneType, Color color)
 {
     zoneType.Color = color;
 }
Ejemplo 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);
            }
        }
Ejemplo n.º 12
0
        public static async Task <bool> ReplyValidateZoneTypeAsync(ICommandContext context, IZoneType zoneType)
        {
            if (!zoneType.IsValid())
            {
                await context.Channel.SendMessageAsync("No such zone type exists.");

                return(false);
            }

            return(true);
        }
        public static async Task <IEnumerable <IZone> > GetZonesAsync(this SQLiteDatabase database, IZoneType zoneType)
        {
            // Returns all zones of the given type.
            // If the zone type is invalid (null or has an invalid id), returns all zones.

            return((await GetZonesAsync(database))
                   .Where(zone => zoneType is null || !zoneType.Id.HasValue || zone.TypeId == zoneType.Id));
        }