diff --git a/CompatBot/Commands/Sudo.Bot.Configuration.cs b/CompatBot/Commands/Sudo.Bot.Configuration.cs new file mode 100644 index 00000000..ceb1a2cb --- /dev/null +++ b/CompatBot/Commands/Sudo.Bot.Configuration.cs @@ -0,0 +1,76 @@ +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CompatBot.Commands.Attributes; +using CompatBot.Database; +using CompatBot.Database.Providers; +using CompatBot.Utils; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; +using Microsoft.EntityFrameworkCore; + +namespace CompatBot.Commands +{ + internal partial class Sudo + { + public sealed partial class Bot + { + [Group("config"), RequiresBotSudoerRole] + [Description("Commands to set or clear bot configuration variables")] + public sealed partial class Configuration : BaseCommandModule + { + [Command("list"), Aliases("show")] + [Description("Lists set variable names")] + public async Task List(CommandContext ctx) + { + using var db = new BotDb(); + var setVars = await db.BotState.AsNoTracking().Where(v => v.Key.StartsWith(SqlConfiguration.ConfigVarPrefix)).ToListAsync().ConfigureAwait(false); + if (setVars.Any()) + { + var result = new StringBuilder("Set variables:").AppendLine(); + foreach (var v in setVars) + result.AppendLine(v.Key[(SqlConfiguration.ConfigVarPrefix.Length)..]); + await ctx.RespondAsync(result.ToString()).ConfigureAwait(false); + } + else + await ctx.RespondAsync("No variables were set yet").ConfigureAwait(false); + } + + [Command("set")] + [Description("Sets configuration variable")] + public async Task Set(CommandContext ctx, string key, [RemainingText] string value) + { + Config.inMemorySettings[key] = value; + key = SqlConfiguration.ConfigVarPrefix + key; + using var db = new BotDb(); + var v = await db.BotState.Where(v => v.Key == key).FirstOrDefaultAsync().ConfigureAwait(false); + if (v == null) + { + v = new BotState {Key = key, Value = value}; + db.BotState.Add(v); + } + else + v.Value = value; + await db.SaveChangesAsync().ConfigureAwait(false); + await ctx.ReactWithAsync(Config.Reactions.Success, "Set variable successfully").ConfigureAwait(false); + } + + [Command("clear"), Aliases("unset", "remove")] + [Description("Removes configuration variable")] + public async Task Clear(CommandContext ctx, string key) + { + Config.inMemorySettings.TryRemove(key, out _); + key = SqlConfiguration.ConfigVarPrefix + key; + using var db = new BotDb(); + var v = await db.BotState.Where(v => v.Key == key).FirstOrDefaultAsync().ConfigureAwait(false); + if (v != null) + { + db.BotState.Remove(v); + await db.SaveChangesAsync().ConfigureAwait(false); + } + await ctx.ReactWithAsync(Config.Reactions.Success, "Removed variable successfully").ConfigureAwait(false); + } + } + } + } +} \ No newline at end of file diff --git a/CompatBot/Commands/Sudo.Bot.cs b/CompatBot/Commands/Sudo.Bot.cs index e513df44..6c0af4a7 100644 --- a/CompatBot/Commands/Sudo.Bot.cs +++ b/CompatBot/Commands/Sudo.Bot.cs @@ -20,7 +20,7 @@ namespace CompatBot.Commands [Group("bot"), Aliases("kot")] [Description("Commands to manage the bot instance")] - public sealed class Bot: BaseCommandModuleCustom + public sealed partial class Bot: BaseCommandModuleCustom { [Command("version")] [Description("Returns currently checked out bot commit")] diff --git a/CompatBot/Database/Providers/SqlConfiguration.cs b/CompatBot/Database/Providers/SqlConfiguration.cs new file mode 100644 index 00000000..8b2f2240 --- /dev/null +++ b/CompatBot/Database/Providers/SqlConfiguration.cs @@ -0,0 +1,19 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace CompatBot.Database.Providers +{ + internal static class SqlConfiguration + { + internal const string ConfigVarPrefix = "ENV-"; + + public static async Task RestoreAsync() + { + using var db = new BotDb(); + var setVars = await db.BotState.AsNoTracking().Where(v => v.Key.StartsWith(ConfigVarPrefix)).ToListAsync().ConfigureAwait(false); + foreach (var v in setVars) + Config.inMemorySettings[v.Key[(ConfigVarPrefix.Length)..]] = v.Value; + } + } +} diff --git a/CompatBot/Program.cs b/CompatBot/Program.cs index 597e0d9e..c8dd7c64 100644 --- a/CompatBot/Program.cs +++ b/CompatBot/Program.cs @@ -99,6 +99,9 @@ namespace CompatBot if (!await DbImporter.UpgradeAsync(db, Config.Cts.Token)) return; + await SqlConfiguration.RestoreAsync().ConfigureAwait(false); + Config.Log.Debug("Restored configuration variables from persistent storage"); + await StatsStorage.RestoreAsync().ConfigureAwait(false); Config.Log.Debug("Restored stats from persistent storage");