diff --git a/locale/Messages.resx b/locale/Messages.resx index 7f7e209..da1496e 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -486,7 +486,7 @@ Display name - + Information about {0} @@ -546,4 +546,22 @@ Offset: {0} + + Guild description + + + Creation date + + + Guild owner + + + Server Boost + + + Boost level + + + Boost count + diff --git a/locale/Messages.ru.resx b/locale/Messages.ru.resx index 5f3dcf5..e3f507e 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -486,7 +486,7 @@ Отображаемое имя - + Информация о {0} @@ -546,4 +546,22 @@ Офсет: {0} + + Описание сервера + + + Дата создания + + + Владелец сервера + + + Буст сервера + + + Уровень буста + + + Количество бустов + diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index ce0ef61..1e784d9 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -486,7 +486,7 @@ дисплейнейм - + деанон {0} @@ -546,4 +546,22 @@ офсет: {0} + + дескрипшон гильдии + + + создался + + + админ гильдии + + + буст гильдии + + + уровень + + + кол-во бустов + diff --git a/src/Commands/ToolsCommandGroup.cs b/src/Commands/ToolsCommandGroup.cs index f478907..d8f0723 100644 --- a/src/Commands/ToolsCommandGroup.cs +++ b/src/Commands/ToolsCommandGroup.cs @@ -19,7 +19,7 @@ using Remora.Results; namespace Octobot.Commands; /// -/// Handles tool commands: /showinfo, /random, /timestamp. +/// Handles tool commands: /showinfo, /guildinfo, /random, /timestamp. /// [UsedImplicitly] public class ToolsCommandGroup : CommandGroup @@ -155,10 +155,10 @@ public class ToolsCommandGroup : CommandGroup } var embed = new EmbedBuilder().WithSmallTitle( - string.Format(Messages.ShowInfoTitle, target.GetTag()), bot) + string.Format(Messages.InformationAbout, target.GetTag()), bot) .WithDescription(builder.ToString()) .WithColour(embedColor) - .WithLargeAvatar(target) + .WithLargeUserAvatar(target) .WithFooter($"ID: {target.ID.ToString()}") .Build(); @@ -229,6 +229,91 @@ public class ToolsCommandGroup : CommandGroup } } + /// + /// A slash command that shows guild information. + /// + /// + /// Information in the output: + /// + /// Guild description + /// Creation date + /// Guild's language + /// Guild's owner + /// Boost level + /// Boost count + /// + /// + /// + /// A feedback sending result which may or may not have succeeded. + /// + [Command("guildinfo")] + [DiscordDefaultDMPermission(false)] + [Description("Shows info current guild")] + [UsedImplicitly] + public async Task ExecuteGuildInfoAsync() + { + if (!_context.TryGetContextIDs(out var guildId, out _, out _)) + { + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); + } + + var botResult = await _userApi.GetCurrentUserAsync(CancellationToken); + if (!botResult.IsDefined(out var bot)) + { + return Result.FromError(botResult); + } + + var guildResult = await _guildApi.GetGuildAsync(guildId, ct: CancellationToken); + if (!guildResult.IsDefined(out var guild)) + { + return Result.FromError(guildResult); + } + + var data = await _guildData.GetData(guildId, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(data.Settings); + + return await ShowGuildInfoAsync(bot, guild, CancellationToken); + } + + private async Task ShowGuildInfoAsync(IUser bot, IGuild guild, CancellationToken ct) + { + var description = new StringBuilder().AppendLine($"## {guild.Name}"); + + if (guild.Description is not null) + { + description.Append("- ").AppendLine(Messages.GuildInfoDescription) + .AppendLine(Markdown.InlineCode(guild.Description)); + } + + description.Append("- ").AppendLine(Messages.GuildInfoCreatedAt) + .AppendLine(Markdown.Timestamp(guild.ID.Timestamp)) + .Append("- ").AppendLine(Messages.GuildInfoOwner) + .AppendLine(Mention.User(guild.OwnerID)); + + var embedColor = ColorsList.Cyan; + + if (guild.PremiumTier > PremiumTier.None) + { + description.Append("### ").AppendLine(Messages.GuildInfoServerBoost) + .Append("- ").Append(Messages.GuildInfoBoostTier) + .Append(": ").AppendLine(Markdown.InlineCode(guild.PremiumTier.ToString())) + .Append("- ").Append(Messages.GuildInfoBoostCount) + .Append(": ").AppendLine(Markdown.InlineCode(guild.PremiumSubscriptionCount.ToString())); + embedColor = ColorsList.Magenta; + } + + var embed = new EmbedBuilder().WithSmallTitle( + string.Format(Messages.InformationAbout, guild.Name), bot) + .WithDescription(description.ToString()) + .WithColour(embedColor) + .WithLargeGuildIcon(guild) + .WithGuildBanner(guild) + .WithFooter($"ID: {guild.ID.ToString()}") + .Build(); + + return await _feedback.SendContextualEmbedResultAsync(embed, ct); + } + /// /// A slash command that generates a random number using maximum and minimum numbers. /// diff --git a/src/Extensions.cs b/src/Extensions.cs index 20b15e6..00d3d36 100644 --- a/src/Extensions.cs +++ b/src/Extensions.cs @@ -64,7 +64,7 @@ public static class Extensions /// The builder to add the thumbnail to. /// The user whose avatar to use in the thumbnail field. /// The builder with the added avatar in the thumbnail field. - public static EmbedBuilder WithLargeAvatar( + public static EmbedBuilder WithLargeUserAvatar( this EmbedBuilder builder, IUser avatarSource) { var avatarUrlResult = CDN.GetUserAvatarUrl(avatarSource, imageSize: 256); @@ -75,6 +75,35 @@ public static class Extensions return builder.WithThumbnailUrl(avatarUrl.AbsoluteUri); } + /// + /// Adds a guild icon in the thumbnail field. + /// + /// The builder to add the thumbnail to. + /// The guild whose icon to use in the thumbnail field. + /// The builder with the added icon in the thumbnail field. + public static EmbedBuilder WithLargeGuildIcon( + this EmbedBuilder builder, IGuild iconSource) + { + var iconUrlResult = CDN.GetGuildIconUrl(iconSource, imageSize: 256); + return iconUrlResult.IsSuccess + ? builder.WithThumbnailUrl(iconUrlResult.Entity.AbsoluteUri) + : builder; + } + + /// + /// Adds a guild banner in the image field. + /// + /// The builder to add the image to. + /// The guild whose banner to use in the image field. + /// The builder with the added banner in the image field. + public static EmbedBuilder WithGuildBanner( + this EmbedBuilder builder, IGuild bannerSource) + { + return bannerSource.Banner is not null + ? builder.WithImageUrl(CDN.GetGuildBannerUrl(bannerSource).Entity.AbsoluteUri) + : builder; + } + /// /// Adds a footer representing that the action was performed in the . /// diff --git a/src/Messages.Designer.cs b/src/Messages.Designer.cs index bcdc9cd..83d596b 100644 --- a/src/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -798,9 +798,9 @@ namespace Octobot { } } - internal static string ShowInfoTitle { + internal static string InformationAbout { get { - return ResourceManager.GetString("ShowInfoTitle", resourceCulture); + return ResourceManager.GetString("InformationAbout", resourceCulture); } } @@ -932,5 +932,53 @@ namespace Octobot { return ResourceManager.GetString("TimestampOffset", resourceCulture); } } + + internal static string GuildInfoDescription + { + get + { + return ResourceManager.GetString("GuildInfoDescription", resourceCulture); + } + } + + internal static string GuildInfoCreatedAt + { + get + { + return ResourceManager.GetString("GuildInfoCreatedAt", resourceCulture); + } + } + + internal static string GuildInfoOwner + { + get + { + return ResourceManager.GetString("GuildInfoOwner", resourceCulture); + } + } + + internal static string GuildInfoServerBoost + { + get + { + return ResourceManager.GetString("GuildInfoServerBoost", resourceCulture); + } + } + + internal static string GuildInfoBoostTier + { + get + { + return ResourceManager.GetString("GuildInfoBoostTier", resourceCulture); + } + } + + internal static string GuildInfoBoostCount + { + get + { + return ResourceManager.GetString("GuildInfoBoostCount", resourceCulture); + } + } } }