diff --git a/Directory.Build.props b/Directory.Build.props index b285aa87..ac531727 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,6 +12,7 @@ latest-all Debug;Release;Docker;Docker-debug + true True True disable diff --git a/src/AzzyBot.Bot/Extensions/IServiceCollectionExtensions.cs b/src/AzzyBot.Bot/Extensions/IServiceCollectionExtensions.cs index 149e17e2..2bd7f8a8 100644 --- a/src/AzzyBot.Bot/Extensions/IServiceCollectionExtensions.cs +++ b/src/AzzyBot.Bot/Extensions/IServiceCollectionExtensions.cs @@ -33,7 +33,9 @@ public static class IServiceCollectionExtensions public static void AzzyBotServices(this IServiceCollection services, bool isDev, bool isDocker, int logDays = 7) { IServiceProvider serviceProvider = services.BuildServiceProvider(); - AzzyBotSettings settings = serviceProvider.GetRequiredService(); + DatabaseSettings dbSettings = serviceProvider.GetRequiredService>().Value; + AzzyBotSettings botSettings = serviceProvider.GetRequiredService>().Value; + MusicStreamingSettings musicSettings = serviceProvider.GetRequiredService>().Value; // Need to register as Singleton first // Otherwise DI doesn't work properly @@ -41,10 +43,10 @@ public static void AzzyBotServices(this IServiceCollection services, bool isDev, services.AddHostedService(static s => s.GetRequiredService()); // Register the database services - services.AzzyBotDataServices(isDev, settings.Database!.EncryptionKey, settings.Database.Host, settings.Database.Port, settings.Database.User, settings.Database.Password, settings.Database.DatabaseName); + services.AzzyBotDataServices(isDev, dbSettings.EncryptionKey, dbSettings.Host, dbSettings.Port, dbSettings.User, dbSettings.Password, dbSettings.DatabaseName); - services.DiscordClient(settings.BotToken); - services.DiscordClientCommands(settings); + services.DiscordClient(botSettings.BotToken); + services.DiscordClientCommands(botSettings); services.DiscordClientInteractivity(); services.AddSingleton(); @@ -70,23 +72,23 @@ public static void AzzyBotServices(this IServiceCollection services, bool isDev, services.ConfigureLavalink(config => { Uri baseAddress = (isDocker) ? new("http://AzzyBot-Ms:2333") : new("http://localhost:2333"); - if (settings.MusicStreaming is not null) + if (musicSettings is not null) { - if (!string.IsNullOrWhiteSpace(settings.MusicStreaming.LavalinkHost) && settings.MusicStreaming.LavalinkPort is not 0) + if (!string.IsNullOrWhiteSpace(musicSettings.LavalinkHost) && musicSettings.LavalinkPort is not 0) { - baseAddress = new($"http://{settings.MusicStreaming.LavalinkHost}:{settings.MusicStreaming.LavalinkPort}"); + baseAddress = new($"http://{musicSettings.LavalinkHost}:{musicSettings.LavalinkPort}"); } - else if (!string.IsNullOrWhiteSpace(settings.MusicStreaming.LavalinkHost) && settings.MusicStreaming.LavalinkPort is 0) + else if (!string.IsNullOrWhiteSpace(musicSettings.LavalinkHost) && musicSettings.LavalinkPort is 0) { - baseAddress = new($"http://{settings.MusicStreaming.LavalinkHost}:2333"); + baseAddress = new($"http://{musicSettings.LavalinkHost}:2333"); } - else if (string.IsNullOrWhiteSpace(settings.MusicStreaming.LavalinkHost) && settings.MusicStreaming.LavalinkPort is not 0) + else if (string.IsNullOrWhiteSpace(musicSettings.LavalinkHost) && musicSettings.LavalinkPort is not 0) { - baseAddress = (isDocker) ? new($"http://AzzyBot-Ms:{settings.MusicStreaming.LavalinkPort}") : new($"http://localhost:{settings.MusicStreaming.LavalinkPort}"); + baseAddress = (isDocker) ? new($"http://AzzyBot-Ms:{musicSettings.LavalinkPort}") : new($"http://localhost:{musicSettings.LavalinkPort}"); } - if (!string.IsNullOrWhiteSpace(settings.MusicStreaming.LavalinkPassword)) - config.Passphrase = settings.MusicStreaming.LavalinkPassword; + if (!string.IsNullOrWhiteSpace(musicSettings.LavalinkPassword)) + config.Passphrase = musicSettings.LavalinkPassword; } config.BaseAddress = baseAddress; @@ -100,17 +102,17 @@ public static void AzzyBotServices(this IServiceCollection services, bool isDev, public static void AddAppSettings(this IServiceCollection services) { services.AddSingleton, AzzyBotSettingsValidator>().AddOptionsWithValidateOnStart(); - services.AddSingleton, DatabaseSettingsValidator>().AddOptionsWithValidateOnStart(); - services.AddSingleton, DiscordStatusSettingsValidator>().AddOptionsWithValidateOnStart(); - services.AddSingleton, MusicStreamingSettingsValidator>().AddOptionsWithValidateOnStart(); - services.AddSingleton, CoreUpdaterValidator>().AddOptionsWithValidateOnStart(); + services.AddSingleton, DatabaseSettingsValidator>().AddOptionsWithValidateOnStart(); + services.AddSingleton, DiscordStatusSettingsValidator>().AddOptionsWithValidateOnStart(); + services.AddSingleton, MusicStreamingSettingsValidator>().AddOptionsWithValidateOnStart(); + services.AddSingleton, CoreUpdaterValidator>().AddOptionsWithValidateOnStart(); services.AddSingleton, AppStatsValidator>().AddOptionsWithValidateOnStart(); services.AddOptions().BindConfiguration(nameof(AzzyBotSettings)); - services.AddOptions().BindConfiguration(nameof(AppDatabaseSettings)); - services.AddOptions().BindConfiguration(nameof(DiscordStatus)); - services.AddOptions().BindConfiguration(nameof(MusicStreaming)); - services.AddOptions().BindConfiguration(nameof(CoreUpdater)); + services.AddOptions().BindConfiguration(nameof(DatabaseSettings)); + services.AddOptions().BindConfiguration(nameof(DiscordStatusSettings)); + services.AddOptions().BindConfiguration(nameof(MusicStreamingSettings)); + services.AddOptions().BindConfiguration(nameof(CoreUpdaterSettings)); services.AddOptions().BindConfiguration(nameof(AppStats)); } diff --git a/src/AzzyBot.Bot/Services/DiscordBotService.cs b/src/AzzyBot.Bot/Services/DiscordBotService.cs index 4b9377a3..e968f4e7 100644 --- a/src/AzzyBot.Bot/Services/DiscordBotService.cs +++ b/src/AzzyBot.Bot/Services/DiscordBotService.cs @@ -24,13 +24,14 @@ using DSharpPlus.Entities; using DSharpPlus.Exceptions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AzzyBot.Bot.Services; -public sealed class DiscordBotService(ILogger logger, AzzyBotSettings settings, DbActions dbActions, DiscordClient client) +public sealed class DiscordBotService(ILogger logger, IOptions settings, DbActions dbActions, DiscordClient client) { private readonly ILogger _logger = logger; - private readonly AzzyBotSettings _settings = settings; + private readonly AzzyBotSettings _settings = settings.Value; private readonly DbActions _dbActions = dbActions; private readonly DiscordClient _client = client; private const string BugReportMessage = "Send a [bug report]([BugReportUri]) to help us fixing this issue!\nPlease include a screenshot of this exception embed and the attached StackTrace file.\nYour Contribution is very welcome."; diff --git a/src/AzzyBot.Bot/Services/DiscordBotServiceHost.cs b/src/AzzyBot.Bot/Services/DiscordBotServiceHost.cs index 7770e3c8..ff361457 100644 --- a/src/AzzyBot.Bot/Services/DiscordBotServiceHost.cs +++ b/src/AzzyBot.Bot/Services/DiscordBotServiceHost.cs @@ -6,21 +6,22 @@ using DSharpPlus.Entities; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AzzyBot.Bot.Services; -public sealed class DiscordBotServiceHost(ILogger logger, AzzyBotSettings settings, DiscordClient client) : IHostedService +public sealed class DiscordBotServiceHost(ILogger logger, IOptions settings, DiscordClient client) : IHostedService { private readonly ILogger _logger = logger; - private readonly AzzyBotSettings _settings = settings; + private readonly DiscordStatusSettings _settings = settings.Value; private readonly DiscordClient _client = client; public async Task StartAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - DiscordActivity activity = DiscordBotService.SetBotStatusActivity(_settings.DiscordStatus?.Activity ?? 2, _settings.DiscordStatus?.Doing ?? "Music", _settings.DiscordStatus?.StreamUrl); - DiscordUserStatus status = DiscordBotService.SetBotStatusUserStatus(_settings.DiscordStatus?.Status ?? 1); + DiscordActivity activity = DiscordBotService.SetBotStatusActivity(_settings.Activity, _settings.Doing, _settings.StreamUrl); + DiscordUserStatus status = DiscordBotService.SetBotStatusUserStatus(_settings.Status); await _client.ConnectAsync(activity, status); diff --git a/src/AzzyBot.Bot/Services/DiscordEvents/DiscordGuildsHandler.cs b/src/AzzyBot.Bot/Services/DiscordEvents/DiscordGuildsHandler.cs index f64f9dfc..2e20abd3 100644 --- a/src/AzzyBot.Bot/Services/DiscordEvents/DiscordGuildsHandler.cs +++ b/src/AzzyBot.Bot/Services/DiscordEvents/DiscordGuildsHandler.cs @@ -11,13 +11,14 @@ using DSharpPlus.Entities; using DSharpPlus.EventArgs; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AzzyBot.Bot.Services.DiscordEvents; -public sealed class DiscordGuildsHandler(ILogger logger, AzzyBotSettings settings, DiscordBotService botService, DbActions dbActions) : IEventHandler, IEventHandler, IEventHandler +public sealed class DiscordGuildsHandler(ILogger logger, IOptions settings, DiscordBotService botService, DbActions dbActions) : IEventHandler, IEventHandler, IEventHandler { private readonly ILogger _logger = logger; - private readonly AzzyBotSettings _settings = settings; + private readonly AzzyBotSettings _settings = settings.Value; private readonly DbActions _dbActions = dbActions; private readonly DiscordBotService _botService = botService; diff --git a/src/AzzyBot.Bot/Services/Modules/CoreServiceHost.cs b/src/AzzyBot.Bot/Services/Modules/CoreServiceHost.cs index 5a044911..c7ba5c3f 100644 --- a/src/AzzyBot.Bot/Services/Modules/CoreServiceHost.cs +++ b/src/AzzyBot.Bot/Services/Modules/CoreServiceHost.cs @@ -12,17 +12,23 @@ using AzzyBot.Core.Utilities.Encryption; using AzzyBot.Data; using AzzyBot.Data.Entities; +using AzzyBot.Data.Settings; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AzzyBot.Bot.Services.Modules; -public sealed class CoreServiceHost(ILogger logger, AzzyBotSettings settings, AzzyDbContext dbContext) : IHostedService +public sealed class CoreServiceHost(ILogger logger, IOptions azzySettings, IOptions updaterSettings, IOptions dbSettings, IOptions discordSettings, IOptions musicStreamingSettings, AzzyDbContext dbContext) : IHostedService { private readonly ILogger _logger = logger; - private readonly AzzyBotSettings _settings = settings; + private readonly AzzyBotSettings _azzySettings = azzySettings.Value; + private readonly CoreUpdaterSettings _updaterSettings = updaterSettings.Value; + private readonly DatabaseSettings _dbSettings = dbSettings.Value; + private readonly DiscordStatusSettings _discordSettings = discordSettings.Value; + private readonly MusicStreamingSettings _musicStreamingSettings = musicStreamingSettings.Value; private readonly AzzyDbContext _dbContext = dbContext; private readonly Task _completed = Task.CompletedTask; @@ -36,7 +42,7 @@ public async Task StartAsync(CancellationToken cancellationToken) _logger.BotStarting(name, version, os, arch, dotnet); - if (_settings.Database is not null && !string.IsNullOrWhiteSpace(_settings.Database.NewEncryptionKey) && (_settings.Database.NewEncryptionKey != _settings.Database.EncryptionKey)) + if (!string.IsNullOrWhiteSpace(_dbSettings.NewEncryptionKey) && (_dbSettings.NewEncryptionKey != _dbSettings.EncryptionKey)) await ReencryptDatabaseAsync(); } @@ -49,14 +55,13 @@ public Task StopAsync(CancellationToken cancellationToken) private async Task ReencryptDatabaseAsync() { - ArgumentNullException.ThrowIfNull(_settings.Database); - ArgumentException.ThrowIfNullOrWhiteSpace(_settings.Database.EncryptionKey); - ArgumentException.ThrowIfNullOrWhiteSpace(_settings.Database.NewEncryptionKey); - ArgumentException.ThrowIfNullOrWhiteSpace(_settings.SettingsFile); + ArgumentException.ThrowIfNullOrWhiteSpace(_dbSettings.EncryptionKey); + ArgumentException.ThrowIfNullOrWhiteSpace(_dbSettings.NewEncryptionKey); + ArgumentException.ThrowIfNullOrWhiteSpace(_azzySettings.SettingsFile); _logger.DatabaseReencryptionStart(); - byte[] newEncryptionKey = Encoding.UTF8.GetBytes(_settings.Database.NewEncryptionKey); + byte[] newEncryptionKey = Encoding.UTF8.GetBytes(_dbSettings.NewEncryptionKey); await using IDbContextTransaction transaction = await _dbContext.Database.BeginTransactionAsync(); @@ -90,11 +95,20 @@ private async Task ReencryptDatabaseAsync() } Crypto.EncryptionKey = newEncryptionKey; - _settings.Database.EncryptionKey = _settings.Database.NewEncryptionKey; - _settings.Database.NewEncryptionKey = string.Empty; + _dbSettings.EncryptionKey = _dbSettings.NewEncryptionKey; + _dbSettings.NewEncryptionKey = string.Empty; - string json = JsonSerializer.Serialize(_settings, JsonSerializationSourceGen.Default.AzzyBotSettingsRecord); - await FileOperations.WriteToFileAsync(_settings.SettingsFile, json); + AppSettingsRecord appSettings = new() + { + AzzyBotSettings = _azzySettings, + DatabaseSettings = _dbSettings, + DiscordStatusSettings = _discordSettings, + MusicStreamingSettings = _musicStreamingSettings, + CoreUpdaterSettings = _updaterSettings + }; + + string json = JsonSerializer.Serialize(appSettings, JsonSerializationSourceGen.Default.AppSettingsRecord); + await FileOperations.WriteToFileAsync(_azzySettings.SettingsFile, json); _logger.DatabaseReencryptionComplete(); } diff --git a/src/AzzyBot.Bot/Services/UpdaterService.cs b/src/AzzyBot.Bot/Services/UpdaterService.cs index cc04ee74..9254ec2f 100644 --- a/src/AzzyBot.Bot/Services/UpdaterService.cs +++ b/src/AzzyBot.Bot/Services/UpdaterService.cs @@ -10,13 +10,15 @@ using AzzyBot.Core.Utilities; using DSharpPlus.Entities; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AzzyBot.Bot.Services; -public sealed class UpdaterService(ILogger logger, AzzyBotSettings settings, DiscordBotService botService, WebRequestService webService) +public sealed class UpdaterService(ILogger logger, IOptions botSettings, IOptions updaterSettings, DiscordBotService botService, WebRequestService webService) { private readonly ILogger _logger = logger; - private readonly AzzyBotSettings _settings = settings; + private readonly AzzyBotSettings _botSettings = botSettings.Value; + private readonly CoreUpdaterSettings _updaterSettings = updaterSettings.Value; private readonly DiscordBotService _botService = botService; private readonly WebRequestService _webService = webService; private DateTimeOffset _lastAzzyUpdateNotificationTime = DateTimeOffset.MinValue; @@ -102,26 +104,26 @@ private async Task SendUpdateMessageAsync(string updateVersion, DateTimeOffset r EmbedBuilder.BuildAzzyUpdatesAvailableEmbed(updateVersion, releaseDate, _latestUrl) }; - if (_settings.Updater.DisplayChangelog) + if (_updaterSettings.DisplayChangelog) embeds.Add(EmbedBuilder.BuildAzzyUpdatesChangelogEmbed(changelog, _latestUrl)); - if (_settings.Updater.DisplayInstructions) + if (_updaterSettings.DisplayInstructions) embeds.Add(EmbedBuilder.BuildAzzyUpdatesInstructionsEmbed()); DiscordGuild? discordGuild = _botService.GetDiscordGuild(); if (discordGuild is null) { - _logger.DiscordItemNotFound(nameof(DiscordGuild), _settings.ServerId); + _logger.DiscordItemNotFound(nameof(DiscordGuild), _botSettings.ServerId); return; } - ulong channelId = _settings.NotificationChannelId; + ulong channelId = _botSettings.NotificationChannelId; if (channelId is 0) { DiscordChannel? discordChannel = await discordGuild.GetSystemChannelAsync(); if (discordChannel is null) { - _logger.DiscordItemNotFound(nameof(DiscordChannel), _settings.ServerId); + _logger.DiscordItemNotFound(nameof(DiscordChannel), _botSettings.ServerId); return; } diff --git a/src/AzzyBot.Bot/Settings/AppSettingsRecord.cs b/src/AzzyBot.Bot/Settings/AppSettingsRecord.cs new file mode 100644 index 00000000..8b6b4c4c --- /dev/null +++ b/src/AzzyBot.Bot/Settings/AppSettingsRecord.cs @@ -0,0 +1,12 @@ +using AzzyBot.Data.Settings; + +namespace AzzyBot.Bot.Settings; + +public sealed record AppSettingsRecord +{ + public required AzzyBotSettings AzzyBotSettings { get; init; } + public required DatabaseSettings DatabaseSettings { get; init; } + public required DiscordStatusSettings DiscordStatusSettings { get; init; } + public required MusicStreamingSettings MusicStreamingSettings { get; init; } + public required CoreUpdaterSettings CoreUpdaterSettings { get; init; } +} diff --git a/src/AzzyBot.Bot/Settings/AzzyBotSettings-Docker.json b/src/AzzyBot.Bot/Settings/AzzyBotSettings-Docker.json index 746fe4bd..41ef626c 100644 --- a/src/AzzyBot.Bot/Settings/AzzyBotSettings-Docker.json +++ b/src/AzzyBot.Bot/Settings/AzzyBotSettings-Docker.json @@ -5,20 +5,20 @@ "ErrorChannelId": 0, "NotificationChannelId": 0 }, - "Database": { + "DatabaseSettings": { "EncryptionKey": null, "NewEncryptionKey": null }, - "DiscordStatus": { + "DiscordStatusSettings": { "Activity": 2, "Doing": "Music", "Status": 1, "StreamUrl": null }, - "MusicStreaming": { + "MusicStreamingSettings": { "LavalinkPassword": "AzzyB0TMus1cStr3am!ng" }, - "CoreUpdater": { + "CoreUpdaterSettings": { "DisplayChangelog": true, "DisplayInstructions": true } diff --git a/src/AzzyBot.Bot/Settings/AzzyBotSettings.cs b/src/AzzyBot.Bot/Settings/AzzyBotSettings.cs index a0bb46fd..9b96dda9 100644 --- a/src/AzzyBot.Bot/Settings/AzzyBotSettings.cs +++ b/src/AzzyBot.Bot/Settings/AzzyBotSettings.cs @@ -7,53 +7,53 @@ namespace AzzyBot.Bot.Settings; public sealed record AzzyBotSettings { [Required] - public required string BotToken { get; init; } + public required string BotToken { get; set; } [Required, Range(ulong.MinValue, ulong.MaxValue)] - public required ulong ServerId { get; init; } + public required ulong ServerId { get; set; } [Required, Range(ulong.MinValue, ulong.MaxValue)] - public required ulong ErrorChannelId { get; init; } + public required ulong ErrorChannelId { get; set; } [Required, Range(ulong.MinValue, ulong.MaxValue)] - public required ulong NotificationChannelId { get; init; } + public required ulong NotificationChannelId { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public string? SettingsFile { get; set; } } -public sealed record DiscordStatus +public sealed record DiscordStatusSettings { [Range(0, 5), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public int Activity { get; init; } = 2; + public int Activity { get; set; } = 2; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public string? Doing { get; init; } = "Music"; + public string Doing { get; set; } = "Music"; [Range(0, 5), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public int Status { get; init; } = 1; + public int Status { get; set; } = 1; [Url, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public Uri? StreamUrl { get; init; } + public Uri? StreamUrl { get; set; } } -public sealed record MusicStreaming +public sealed record MusicStreamingSettings { [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? LavalinkHost { get; init; } = "AzzyBot-Ms"; + public string? LavalinkHost { get; set; } = "AzzyBot-Ms"; [Range(0, ushort.MaxValue), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public int LavalinkPort { get; init; } = 2333; + public int LavalinkPort { get; set; } = 2333; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? LavalinkPassword { get; init; } = "AzzyB0TMus1cStr3am!ng"; + public string? LavalinkPassword { get; set; } = "AzzyB0TMus1cStr3am!ng"; } -public sealed record CoreUpdater +public sealed record CoreUpdaterSettings { [Required] - public required bool DisplayChangelog { get; init; } + public required bool DisplayChangelog { get; set; } [Required] - public required bool DisplayInstructions { get; init; } + public required bool DisplayInstructions { get; set; } } diff --git a/src/AzzyBot.Bot/Settings/AzzyBotSettings.json b/src/AzzyBot.Bot/Settings/AzzyBotSettings.json index fb0c58a5..2cf988ab 100644 --- a/src/AzzyBot.Bot/Settings/AzzyBotSettings.json +++ b/src/AzzyBot.Bot/Settings/AzzyBotSettings.json @@ -5,7 +5,7 @@ "ErrorChannelId": 0, "NotificationChannelId": 0 }, - "Database": { + "DatabaseSettings": { "EncryptionKey": null, "NewEncryptionKey": null, "Host": "localhost", @@ -14,18 +14,18 @@ "Password": null, "DatabaseName": "azzybot" }, - "DiscordStatus": { + "DiscordStatusSettings": { "Activity": 2, "Doing": "Music", "Status": 1, "StreamUrl": null }, - "MusicStreaming": { + "MusicStreamingSettings": { "LavalinkHost": "localhost", "LavalinkPort": 2333, "LavalinkPassword": "AzzyB0TMus1cStr3am!ng" }, - "CoreUpdater": { + "CoreUpdaterSettings": { "DisplayChangelog": true, "DisplayInstructions": true } diff --git a/src/AzzyBot.Bot/Settings/Validators/CoreUpdaterValidator.cs b/src/AzzyBot.Bot/Settings/Validators/CoreUpdaterValidator.cs index ed07e8a7..122ea289 100644 --- a/src/AzzyBot.Bot/Settings/Validators/CoreUpdaterValidator.cs +++ b/src/AzzyBot.Bot/Settings/Validators/CoreUpdaterValidator.cs @@ -3,6 +3,6 @@ namespace AzzyBot.Bot.Settings.Validators; [OptionsValidator] -public sealed partial class CoreUpdaterValidator : IValidateOptions +public sealed partial class CoreUpdaterValidator : IValidateOptions { } diff --git a/src/AzzyBot.Bot/Settings/Validators/DatabaseSettingsValidator.cs b/src/AzzyBot.Bot/Settings/Validators/DatabaseSettingsValidator.cs index bc467dce..1459b3ef 100644 --- a/src/AzzyBot.Bot/Settings/Validators/DatabaseSettingsValidator.cs +++ b/src/AzzyBot.Bot/Settings/Validators/DatabaseSettingsValidator.cs @@ -4,6 +4,6 @@ namespace AzzyBot.Bot.Settings.Validators; [OptionsValidator] -public sealed partial class DatabaseSettingsValidator : IValidateOptions +public sealed partial class DatabaseSettingsValidator : IValidateOptions { } diff --git a/src/AzzyBot.Bot/Settings/Validators/DiscordStatusSettingsValidator.cs b/src/AzzyBot.Bot/Settings/Validators/DiscordStatusSettingsValidator.cs index 19604d06..a818b8fe 100644 --- a/src/AzzyBot.Bot/Settings/Validators/DiscordStatusSettingsValidator.cs +++ b/src/AzzyBot.Bot/Settings/Validators/DiscordStatusSettingsValidator.cs @@ -3,6 +3,6 @@ namespace AzzyBot.Bot.Settings.Validators; [OptionsValidator] -public sealed partial class DiscordStatusSettingsValidator : IValidateOptions +public sealed partial class DiscordStatusSettingsValidator : IValidateOptions { } diff --git a/src/AzzyBot.Bot/Settings/Validators/MusicStreamingSettingsValidator.cs b/src/AzzyBot.Bot/Settings/Validators/MusicStreamingSettingsValidator.cs index 56d96b87..16672357 100644 --- a/src/AzzyBot.Bot/Settings/Validators/MusicStreamingSettingsValidator.cs +++ b/src/AzzyBot.Bot/Settings/Validators/MusicStreamingSettingsValidator.cs @@ -3,6 +3,6 @@ namespace AzzyBot.Bot.Settings.Validators; [OptionsValidator] -public sealed partial class MusicStreamingSettingsValidator : IValidateOptions +public sealed partial class MusicStreamingSettingsValidator : IValidateOptions { } diff --git a/src/AzzyBot.Bot/Utilities/JsonSerializationSourceGen.cs b/src/AzzyBot.Bot/Utilities/JsonSerializationSourceGen.cs index 17b87f29..4c15c71b 100644 --- a/src/AzzyBot.Bot/Utilities/JsonSerializationSourceGen.cs +++ b/src/AzzyBot.Bot/Utilities/JsonSerializationSourceGen.cs @@ -8,10 +8,10 @@ namespace AzzyBot.Bot.Utilities; [SuppressMessage("Roslynator", "RCS1251:Remove unnecessary braces from record declaration", Justification = "Class has to be empty.")] [JsonSourceGenerationOptions(WriteIndented = true, GenerationMode = JsonSourceGenerationMode.Serialization)] +[JsonSerializable(typeof(AppSettingsRecord))] [JsonSerializable(typeof(AzuraAdminStationConfigRecord))] [JsonSerializable(typeof(AzuraFileUploadRecord))] [JsonSerializable(typeof(AzuraInternalRequestRecord))] -[JsonSerializable(typeof(AzzyBotSettings))] [JsonSerializable(typeof(SerializableExceptionsRecord))] public sealed partial class JsonSerializationSourceGen : JsonSerializerContext { diff --git a/src/AzzyBot.Core/Settings/SettingsCheck.cs b/src/AzzyBot.Core/Settings/SettingsCheck.cs deleted file mode 100644 index 58777393..00000000 --- a/src/AzzyBot.Core/Settings/SettingsCheck.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using AzzyBot.Core.Utilities; - -namespace AzzyBot.Core.Settings; - -public static class SettingsCheck -{ - public static int CheckSettings(T? settings, IEnumerable? excluded = null, bool isClass = false) - { - if (settings is null) - throw new InvalidOperationException("Settings is null"); - - int missingSettings = 0; - void LogAndIncrement(string settingName) - { - Console.Error.WriteLine("{0} has to be filled out!", settingName); - missingSettings++; - } - - if (settings is ISettings settingsInterface) - { - foreach (KeyValuePair kvp in settingsInterface.GetProperties().Where(p => excluded?.Contains(p.Key) is false)) - { - switch (kvp.Value) - { - case int i when i is 0: - case ulong ul when ul is 0: - case string str when string.IsNullOrWhiteSpace(str): - case TimeSpan ts when ts == TimeSpan.Zero: - LogAndIncrement(kvp.Key); - break; - - case ISettings nestedSettings: - missingSettings += CheckSettings(nestedSettings, excluded, true); - break; - } - } - } - else - { - throw new InvalidOperationException($"Settings object does not implement {nameof(ISettings)} interface"); - } - - if (missingSettings is 0 || isClass) - return missingSettings; - - if (!SoftwareStats.GetAppName.Contains("Docker", StringComparison.OrdinalIgnoreCase)) - { - Console.Error.WriteLine("Press any key to continue"); - Console.ReadKey(); - } - - Environment.Exit(1); - - return 0; - } -} - -public interface ISettings -{ - public Dictionary GetProperties(); -} diff --git a/src/AzzyBot.Core/Utilities/Records/AppStats.cs b/src/AzzyBot.Core/Utilities/Records/AppStats.cs index a96b4a1c..a6aa8e13 100644 --- a/src/AzzyBot.Core/Utilities/Records/AppStats.cs +++ b/src/AzzyBot.Core/Utilities/Records/AppStats.cs @@ -1,5 +1,5 @@ using System; -using System.Diagnostics.CodeAnalysis; +using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace AzzyBot.Core.Utilities.Records; @@ -12,26 +12,18 @@ public sealed record AppStats /// /// The commit hash. /// - [JsonPropertyName(nameof(Commit))] - public string Commit { get; init; } + [Length(0, 40, ErrorMessage = "CommitHash must be exactly 40 characters long."), JsonPropertyName(nameof(Commit))] + public string Commit { get; set; } = "Unknown"; /// /// The compilation date. /// [JsonPropertyName(nameof(CompilationDate))] - public DateTimeOffset CompilationDate { get; init; } + public DateTimeOffset CompilationDate { get; set; } = DateTimeOffset.UtcNow; /// /// The lines of code in C#. /// [JsonPropertyName(nameof(LocCs))] - public int LocCs { get; init; } - - [SuppressMessage("Roslynator", "RCS1231:Make parameter ref read-only", Justification = "This is a constructor and does not allow referencing.")] - public AppStats(string commit, DateTimeOffset compilationDate, int locCs) - { - Commit = commit; - CompilationDate = compilationDate; - LocCs = locCs; - } + public int LocCs { get; set; } } diff --git a/src/AzzyBot.Data/Settings/AppDatabaseSettings.cs b/src/AzzyBot.Data/Settings/DatabaseSettings.cs similarity index 64% rename from src/AzzyBot.Data/Settings/AppDatabaseSettings.cs rename to src/AzzyBot.Data/Settings/DatabaseSettings.cs index 8f841a0e..f0ad6c1c 100644 --- a/src/AzzyBot.Data/Settings/AppDatabaseSettings.cs +++ b/src/AzzyBot.Data/Settings/DatabaseSettings.cs @@ -3,26 +3,26 @@ namespace AzzyBot.Data.Settings; -public sealed record AppDatabaseSettings +public sealed record DatabaseSettings { [Required, Length(32, 32, ErrorMessage = $"The {nameof(EncryptionKey)} must contain exactly 32 characters!")] public required string EncryptionKey { get; set; } - [Length(32, 32, ErrorMessage = $"The {nameof(NewEncryptionKey)} must contain exactly 32 characters!")] + [Length(0, 32, ErrorMessage = $"The {nameof(NewEncryptionKey)} must contain exactly 32 characters!")] public string? NewEncryptionKey { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public string Host { get; init; } = "AzzyBot-Db"; + public string Host { get; set; } = "AzzyBot-Db"; [Range(0, ushort.MaxValue), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public int Port { get; init; } = 5432; + public int Port { get; set; } = 5432; [Length(1, 63), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public string User { get; init; } = "azzybot"; + public string User { get; set; } = "azzybot"; [Length(1, 1000), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public string Password { get; init; } = "thisIsAzzyB0!P@ssw0rd"; + public string Password { get; set; } = "thisIsAzzyB0!P@ssw0rd"; [Length(1, 63), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] - public string DatabaseName { get; init; } = "azzybot"; + public string DatabaseName { get; set; } = "azzybot"; }