From 25d725e1b3f61c4e8a640c32c06fa41a3d9c035e Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sat, 26 Aug 2023 21:31:29 +0100 Subject: [PATCH] feat: add /info command (resolves #2) --- VPLink/Commands/InfoCommand.cs | 57 +++++++++++++++++++++++++++++ VPLink/Program.cs | 2 + VPLink/Services/BotService.cs | 61 +++++++++++++++++++++++++++++++ VPLink/Services/DiscordService.cs | 1 + 4 files changed, 121 insertions(+) create mode 100644 VPLink/Commands/InfoCommand.cs create mode 100644 VPLink/Services/BotService.cs diff --git a/VPLink/Commands/InfoCommand.cs b/VPLink/Commands/InfoCommand.cs new file mode 100644 index 0000000..6f34be0 --- /dev/null +++ b/VPLink/Commands/InfoCommand.cs @@ -0,0 +1,57 @@ +using System.Text; +using Discord; +using Discord.Interactions; +using Discord.WebSocket; +using VPLink.Services; + +namespace VPLink.Commands; + +/// +/// Represents a class which implements the info command. +/// +internal sealed class InfoCommand : InteractionModuleBase +{ + private readonly BotService _botService; + private readonly DiscordSocketClient _discordClient; + + /// + /// Initializes a new instance of the class. + /// + /// The bot service. + /// + public InfoCommand(BotService botService, DiscordSocketClient discordClient) + { + _botService = botService; + _discordClient = discordClient; + } + + [SlashCommand("info", "Displays information about the bot.")] + [RequireContext(ContextType.Guild)] + public async Task InfoAsync() + { + SocketGuildUser member = Context.Guild.GetUser(_discordClient.CurrentUser.Id); + string pencilVersion = _botService.Version; + + SocketRole? highestRole = member.Roles.Where(r => r.Color != Color.Default).MaxBy(r => r.Position); + + var embed = new EmbedBuilder(); + embed.WithAuthor(member); + embed.WithColor(highestRole?.Color ?? Color.Default); + embed.WithThumbnailUrl(member.GetAvatarUrl()); + embed.WithTitle($"VPLink v{pencilVersion}"); + embed.WithDescription("Created by <@94248427663130624>, hosted [on GitHub](https://github.com/oliverbooth/VPLink)."); + embed.AddField("Ping", $"{_discordClient.Latency} ms", true); + embed.AddField("Started", $"", true); + + var builder = new StringBuilder(); + builder.AppendLine($"VPLink: {pencilVersion}"); + builder.AppendLine($"Discord.Net: {_botService.DiscordNetVersion}"); + builder.AppendLine($"VP#: {_botService.VpSharpVersion}"); + builder.AppendLine($"CLR: {Environment.Version.ToString(3)}"); + builder.AppendLine($"Host: {Environment.OSVersion}"); + + embed.AddField("Version", $"```\n{builder}\n```"); + + await RespondAsync(embed: embed.Build(), ephemeral: true).ConfigureAwait(false); + } +} diff --git a/VPLink/Program.cs b/VPLink/Program.cs index 2cb9a15..621a79f 100644 --- a/VPLink/Program.cs +++ b/VPLink/Program.cs @@ -25,6 +25,8 @@ builder.Configuration.AddTomlFile("data/config.toml", true, true); builder.Logging.ClearProviders(); builder.Logging.AddSerilog(); +builder.Services.AddHostedSingleton(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/VPLink/Services/BotService.cs b/VPLink/Services/BotService.cs new file mode 100644 index 0000000..52c558e --- /dev/null +++ b/VPLink/Services/BotService.cs @@ -0,0 +1,61 @@ +using System.Reflection; +using Discord.WebSocket; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using VpSharp; + +namespace VPLink.Services; + +internal sealed class BotService : BackgroundService +{ + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The logger. + public BotService(ILogger logger) + { + _logger = logger; + var attribute = typeof(BotService).Assembly.GetCustomAttribute(); + Version = attribute?.InformationalVersion ?? "Unknown"; + + attribute = typeof(DiscordSocketClient).Assembly.GetCustomAttribute(); + DiscordNetVersion = attribute?.InformationalVersion ?? "Unknown"; + + attribute = typeof(VirtualParadiseClient).Assembly.GetCustomAttribute(); + VpSharpVersion = attribute?.InformationalVersion ?? "Unknown"; + } + + /// + /// Gets the Discord.Net version. + /// + /// The Discord.Net version. + public string DiscordNetVersion { get; } + + /// + /// Gets the date and time at which the bot was started. + /// + /// The start timestamp. + public DateTimeOffset StartedAt { get; private set; } + + /// + /// Gets the bot version. + /// + /// The bot version. + public string Version { get; } + + /// + /// Gets the VP# version. + /// + /// The VP# version. + public string VpSharpVersion { get; } + + /// + protected override Task ExecuteAsync(CancellationToken stoppingToken) + { + StartedAt = DateTimeOffset.UtcNow; + _logger.LogInformation("VPLink v{Version} is starting...", Version); + return Task.CompletedTask; + } +} diff --git a/VPLink/Services/DiscordService.cs b/VPLink/Services/DiscordService.cs index 530bf02..1ba757d 100644 --- a/VPLink/Services/DiscordService.cs +++ b/VPLink/Services/DiscordService.cs @@ -44,6 +44,7 @@ internal sealed class DiscordService : BackgroundService _logger.LogInformation("Establishing relay"); _logger.LogInformation("Adding command modules"); + await _interactionService.AddModuleAsync(_serviceProvider).ConfigureAwait(false); await _interactionService.AddModuleAsync(_serviceProvider).ConfigureAwait(false); _discordClient.Ready += OnReady;