From ba43fd90c6a5dea68465ea2593dfdafa6424d9ea Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 27 Jun 2024 11:16:17 +0200 Subject: [PATCH] Adds admin option to set custom replacements --- Tools/BiblioTech/CommandHandler.cs | 6 +- Tools/BiblioTech/Commands/AdminCommand.cs | 62 ++++++++++++++++++- Tools/BiblioTech/Program.cs | 5 +- Tools/BiblioTech/Rewards/ChainEventsSender.cs | 12 +++- Tools/BiblioTech/Rewards/CustomReplacement.cs | 34 ++++++++++ Tools/BiblioTech/Rewards/RoleDriver.cs | 4 +- 6 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 Tools/BiblioTech/Rewards/CustomReplacement.cs diff --git a/Tools/BiblioTech/CommandHandler.cs b/Tools/BiblioTech/CommandHandler.cs index 4f6d7b8..29a1777 100644 --- a/Tools/BiblioTech/CommandHandler.cs +++ b/Tools/BiblioTech/CommandHandler.cs @@ -10,12 +10,14 @@ namespace BiblioTech public class CommandHandler { private readonly DiscordSocketClient client; + private readonly CustomReplacement replacement; private readonly BaseCommand[] commands; private readonly ILog log; - public CommandHandler(ILog log, DiscordSocketClient client, params BaseCommand[] commands) + public CommandHandler(ILog log, DiscordSocketClient client, CustomReplacement replacement, params BaseCommand[] commands) { this.client = client; + this.replacement = replacement; this.commands = commands; this.log = log; client.Ready += Client_Ready; @@ -31,7 +33,7 @@ namespace BiblioTech var adminChannels = guild.TextChannels.Where(Program.AdminChecker.IsAdminChannel).ToArray(); if (adminChannels == null || !adminChannels.Any()) throw new Exception("No admin message channel"); Program.AdminChecker.SetAdminChannel(adminChannels.First()); - Program.RoleDriver = new RoleDriver(client, log); + Program.RoleDriver = new RoleDriver(client, log, replacement); var builders = commands.Select(c => { diff --git a/Tools/BiblioTech/Commands/AdminCommand.cs b/Tools/BiblioTech/Commands/AdminCommand.cs index 698fb00..d80326f 100644 --- a/Tools/BiblioTech/Commands/AdminCommand.cs +++ b/Tools/BiblioTech/Commands/AdminCommand.cs @@ -1,4 +1,5 @@ using BiblioTech.Options; +using BiblioTech.Rewards; namespace BiblioTech.Commands { @@ -10,12 +11,14 @@ namespace BiblioTech.Commands private readonly AddSprCommand addSprCommand; private readonly ClearSprsCommand clearSprsCommand; private readonly GetSprCommand getSprCommand; + private readonly LogReplaceCommand logReplaceCommand; - public AdminCommand(SprCommand sprCommand) + public AdminCommand(SprCommand sprCommand, CustomReplacement replacement) { addSprCommand = new AddSprCommand(sprCommand); clearSprsCommand = new ClearSprsCommand(sprCommand); getSprCommand = new GetSprCommand(sprCommand); + logReplaceCommand = new LogReplaceCommand(replacement); } public override string Name => "admin"; @@ -29,7 +32,8 @@ namespace BiblioTech.Commands whoIsCommand, addSprCommand, clearSprsCommand, - getSprCommand + getSprCommand, + logReplaceCommand }; protected override async Task Invoke(CommandContext context) @@ -52,6 +56,7 @@ namespace BiblioTech.Commands await addSprCommand.CommandHandler(context); await clearSprsCommand.CommandHandler(context); await getSprCommand.CommandHandler(context); + await logReplaceCommand.CommandHandler(context); } public class ClearUserAssociationCommand : SubCommandOption @@ -194,7 +199,7 @@ namespace BiblioTech.Commands } } - public class GetSprCommand: SubCommandOption + public class GetSprCommand : SubCommandOption { private readonly SprCommand sprCommand; @@ -210,5 +215,56 @@ namespace BiblioTech.Commands await context.Followup("SPRs: " + string.Join(", ", sprCommand.Get().Select(s => $"'{s}'"))); } } + + public class LogReplaceCommand : SubCommandOption + { + private readonly CustomReplacement replacement; + private readonly StringOption fromOption = new StringOption("from", "string to replace", true); + private readonly StringOption toOption = new StringOption("to", "string to replace with", false); + + public LogReplaceCommand(CustomReplacement replacement) + : base(name: "logreplace", + description: "Replaces all occurances of 'from' with 'to' in ChainEvent messages. Leave 'to' empty to remove a replacement.") + { + this.replacement = replacement; + } + + public override CommandOption[] Options => new[] { fromOption, toOption }; + + protected override async Task onSubCommand(CommandContext context) + { + var from = await fromOption.Parse(context); + var to = await toOption.Parse(context); + + if (string.IsNullOrEmpty(from)) + { + await context.Followup("'from' not received"); + return; + } + + if (from.Length < 5) + { + await context.Followup("'from' must be length 5 or greater."); + return; + } + + if (string.IsNullOrEmpty(to)) + { + replacement.Remove(from); + await context.Followup($"Replace for '{from}' removed."); + } + else + { + if (to.Length < 5) + { + await context.Followup("'to' must be length 5 or greater."); + return; + } + + replacement.Add(from, to); + await context.Followup($"Replace added '{from}' -->> '{to}'."); + } + } + } } } diff --git a/Tools/BiblioTech/Program.cs b/Tools/BiblioTech/Program.cs index 39bd58b..587c3a8 100644 --- a/Tools/BiblioTech/Program.cs +++ b/Tools/BiblioTech/Program.cs @@ -11,6 +11,7 @@ namespace BiblioTech public class Program { private DiscordSocketClient client = null!; + private readonly CustomReplacement replacement = new CustomReplacement(); public static Configuration Config { get; private set; } = null!; public static UserRepo UserRepo { get; } = new UserRepo(); @@ -73,13 +74,13 @@ namespace BiblioTech var notifyCommand = new NotifyCommand(); var associateCommand = new UserAssociateCommand(notifyCommand); var sprCommand = new SprCommand(); - var handler = new CommandHandler(Log, client, + var handler = new CommandHandler(Log, client, replacement, new GetBalanceCommand(associateCommand), new MintCommand(associateCommand), sprCommand, associateCommand, notifyCommand, - new AdminCommand(sprCommand), + new AdminCommand(sprCommand, replacement), new MarketCommand() ); diff --git a/Tools/BiblioTech/Rewards/ChainEventsSender.cs b/Tools/BiblioTech/Rewards/ChainEventsSender.cs index bbad804..0ec88d1 100644 --- a/Tools/BiblioTech/Rewards/ChainEventsSender.cs +++ b/Tools/BiblioTech/Rewards/ChainEventsSender.cs @@ -6,11 +6,13 @@ namespace BiblioTech.Rewards public class ChainEventsSender { private readonly ILog log; - private SocketTextChannel? eventsChannel; + private readonly CustomReplacement replacement; + private readonly SocketTextChannel? eventsChannel; - public ChainEventsSender(ILog log, SocketTextChannel? eventsChannel) + public ChainEventsSender(ILog log, CustomReplacement replacement, SocketTextChannel? eventsChannel) { this.log = log; + this.replacement = replacement; this.eventsChannel = eventsChannel; } @@ -43,6 +45,7 @@ namespace BiblioTech.Rewards private string ApplyReplacements(UserData[] users, string msg) { var result = ApplyUserAddressReplacements(users, msg); + result = ApplyCustomReplacements(result); return result; } @@ -60,5 +63,10 @@ namespace BiblioTech.Rewards return msg; } + + private string ApplyCustomReplacements(string result) + { + return replacement.Apply(result); + } } } diff --git a/Tools/BiblioTech/Rewards/CustomReplacement.cs b/Tools/BiblioTech/Rewards/CustomReplacement.cs new file mode 100644 index 0000000..359411a --- /dev/null +++ b/Tools/BiblioTech/Rewards/CustomReplacement.cs @@ -0,0 +1,34 @@ +namespace BiblioTech.Rewards +{ + public class CustomReplacement + { + private readonly Dictionary replacements = new Dictionary(); + + public void Add(string from, string to) + { + if (replacements.ContainsKey(from)) + { + replacements[from] = to; + } + else + { + replacements.Add(from, to); + } + } + + public void Remove(string from) + { + replacements.Remove(from); + } + + public string Apply(string msg) + { + var result = msg; + foreach (var pair in replacements) + { + result.Replace(pair.Key, pair.Value); + } + return result; + } + } +} diff --git a/Tools/BiblioTech/Rewards/RoleDriver.cs b/Tools/BiblioTech/Rewards/RoleDriver.cs index 6f1819d..71019b7 100644 --- a/Tools/BiblioTech/Rewards/RoleDriver.cs +++ b/Tools/BiblioTech/Rewards/RoleDriver.cs @@ -14,12 +14,12 @@ namespace BiblioTech.Rewards private readonly ChainEventsSender eventsSender; private readonly RewardRepo repo = new RewardRepo(); - public RoleDriver(DiscordSocketClient client, ILog log) + public RoleDriver(DiscordSocketClient client, ILog log, CustomReplacement replacement) { this.client = client; this.log = log; rewardsChannel = GetChannel(Program.Config.RewardsChannelId); - eventsSender = new ChainEventsSender(log, GetChannel(Program.Config.ChainEventsChannelId)); + eventsSender = new ChainEventsSender(log, replacement, GetChannel(Program.Config.ChainEventsChannelId)); } public async Task GiveRewards(GiveRewardsCommand rewards)