diff --git a/ConfigItem/EntityList.cs b/ConfigItem/EntityList.cs index 8cdf6e5..a8af63a 100644 --- a/ConfigItem/EntityList.cs +++ b/ConfigItem/EntityList.cs @@ -75,7 +75,7 @@ namespace Noikoio.RegexBot.ConfigItem if (section["blacklist"] != null) { if (mode == FilterType.Whitelist) - throw new Rule.RuleImportException("Cannot have whitelist AND blacklist defined."); + throw new RuleConfig.RuleImportException("Cannot have whitelist AND blacklist defined."); mode = FilterType.Blacklist; } if (mode == FilterType.None) list = new EntityList(); // might even be fine to keep it null? diff --git a/ConfigItem/Server.cs b/ConfigItem/Server.cs index 5c3e44d..428a612 100644 --- a/ConfigItem/Server.cs +++ b/ConfigItem/Server.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Noikoio.RegexBot.Feature.RegexResponder; +using System.Collections.Generic; using System.Diagnostics; namespace Noikoio.RegexBot.ConfigItem @@ -10,17 +11,17 @@ namespace Noikoio.RegexBot.ConfigItem { private readonly string _name; private ulong? _id; - private IEnumerable _rules; + private IEnumerable _rules; private EntityList _moderators; public string Name => _name; public ulong? Id { get => _id; set { if (!_id.HasValue) _id = value; } } - public IEnumerable MatchResponseRules => _rules; + public IEnumerable MatchResponseRules => _rules; public EntityList Moderators => _moderators; - public Server(string name, ulong? id, IEnumerable rules, EntityList moderators) + public Server(string name, ulong? id, IEnumerable rules, EntityList moderators) { _name = name; _id = id; diff --git a/ConfigLoader.cs b/ConfigLoader.cs index e4b93c1..98c5fc5 100644 --- a/ConfigLoader.cs +++ b/ConfigLoader.cs @@ -147,7 +147,7 @@ namespace Noikoio.RegexBot // Read rules // Also, parsed rules require a server reference. Creating it here. - List rules = new List(); + List rules = new List(); Server newserver = new Server(sname, sid, rules, mods); foreach (JObject ruleconf in sconf["rules"]) @@ -161,11 +161,11 @@ namespace Noikoio.RegexBot } await SLog($"Adding rule \"{name}\""); - Rule rule; + RuleConfig rule; try { - rule = new Rule(newserver, ruleconf); - } catch (Rule.RuleImportException ex) + rule = new RuleConfig(newserver, ruleconf); + } catch (RuleConfig.RuleImportException ex) { await SLog("-> Error: " + ex.Message); return false; diff --git a/RuleResponder.cs b/Feature/RegexResponder/EventProcessor.cs similarity index 96% rename from RuleResponder.cs rename to Feature/RegexResponder/EventProcessor.cs index 428d629..b8c546d 100644 --- a/RuleResponder.cs +++ b/Feature/RegexResponder/EventProcessor.cs @@ -8,17 +8,18 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Noikoio.RegexBot +namespace Noikoio.RegexBot.Feature.RegexResponder { /// - /// Bot subsystem that implements regex matching and response processing. + /// Implements per-message regex matching and executes customizable responses. + /// Namesake of this project. /// - partial class RuleResponder + partial class EventProcessor { private readonly DiscordSocketClient _client; private readonly ConfigLoader _conf; - public RuleResponder(DiscordSocketClient client, ConfigLoader conf) + public EventProcessor(DiscordSocketClient client, ConfigLoader conf) { _client = client; _conf = conf; @@ -98,7 +99,7 @@ namespace Noikoio.RegexBot /// Uses information from a single rule and checks if the incoming message is a match. /// If it matches, the rule's responses are executed. To be run in the thread pool. /// - private async Task ProcessMessage(Server srv, Rule rule, SocketMessage msg) + private async Task ProcessMessage(Server srv, RuleConfig rule, SocketMessage msg) { string msgcontent; @@ -182,7 +183,7 @@ namespace Noikoio.RegexBot return result.ToString(); } - private bool IsFiltered(Rule r, SocketMessage m) + private bool IsFiltered(RuleConfig r, SocketMessage m) { if (r.FilterMode == FilterType.None) return false; diff --git a/RuleResponder_Responses.cs b/Feature/RegexResponder/Responses.cs similarity index 95% rename from RuleResponder_Responses.cs rename to Feature/RegexResponder/Responses.cs index 59cb3ed..d2d0c85 100644 --- a/RuleResponder_Responses.cs +++ b/Feature/RegexResponder/Responses.cs @@ -1,18 +1,17 @@ using Discord; using Discord.WebSocket; -using Noikoio.RegexBot.ConfigItem; using System; using System.Collections.ObjectModel; using System.Diagnostics; using System.Text; using System.Threading.Tasks; -namespace Noikoio.RegexBot +namespace Noikoio.RegexBot.Feature.RegexResponder { // Contains code for handling each response in a rule. - partial class RuleResponder + partial class RegexResponder { - private delegate Task ResponseProcessor(AsyncLogger l, string cmd, Rule r, SocketMessage m); + private delegate Task ResponseProcessor(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m); private readonly ReadOnlyDictionary _commands; #if DEBUG @@ -20,7 +19,7 @@ namespace Noikoio.RegexBot /// Throws an exception. Meant to be a quick error handling test. /// No parameters. /// - private async Task RP_Crash(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_Crash(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { await l("Will throw an exception."); throw new Exception("Requested in response."); @@ -31,7 +30,7 @@ namespace Noikoio.RegexBot /// The guild info displayed is the one in which the command is invoked. /// No parameters. /// - private Task RP_DumpID(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private Task RP_DumpID(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { var g = ((SocketGuildUser)m.Author).Guild; var result = new StringBuilder(); @@ -56,7 +55,7 @@ namespace Noikoio.RegexBot /// Sends a message to a specified channel. /// Parameters: say (channel) (message) /// - private async Task RP_Say(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_Say(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { string[] @in = SplitParams(cmd, 3); if (@in.Length != 3) @@ -81,7 +80,7 @@ namespace Noikoio.RegexBot /// Reports the incoming message to a given channel. /// Parameters: report (channel) /// - private async Task RP_Report(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_Report(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { string[] @in = SplitParams(cmd); if (@in.Length != 2) @@ -137,7 +136,7 @@ namespace Noikoio.RegexBot /// Deletes the incoming message. /// No parameters. /// - private async Task RP_Remove(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_Remove(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { // Parameters are not checked await m.DeleteAsync(); @@ -147,7 +146,7 @@ namespace Noikoio.RegexBot /// Executes an external program and sends standard output to the given channel. /// Parameters: exec (channel) (command line) /// - private async Task RP_Exec(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_Exec(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { var @in = SplitParams(cmd, 4); if (@in.Length < 3) @@ -198,7 +197,7 @@ namespace Noikoio.RegexBot /// No parameters. /// // TODO add parameter for message auto-deleting - private async Task RP_Ban(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_Ban(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { SocketGuild g = ((SocketGuildUser)m.Author).Guild; await g.AddBanAsync(m.Author); @@ -208,7 +207,7 @@ namespace Noikoio.RegexBot /// Grants or revokes a specified role to/from a given user. /// Parameters: grantrole/revokerole (user ID or @_) (role ID) /// - private async Task RP_GrantRevokeRole(AsyncLogger l, string cmd, Rule r, SocketMessage m) + private async Task RP_GrantRevokeRole(AsyncLogger l, string cmd, RuleConfig r, SocketMessage m) { string[] @in = SplitParams(cmd); if (@in.Length != 3) diff --git a/ConfigItem/Rule.cs b/Feature/RegexResponder/RuleConfig.cs similarity index 97% rename from ConfigItem/Rule.cs rename to Feature/RegexResponder/RuleConfig.cs index 2b2d2ec..93113f4 100644 --- a/ConfigItem/Rule.cs +++ b/Feature/RegexResponder/RuleConfig.cs @@ -1,15 +1,16 @@ using Newtonsoft.Json.Linq; +using Noikoio.RegexBot.ConfigItem; using System; using System.Collections.Generic; using System.Text.RegularExpressions; -namespace Noikoio.RegexBot.ConfigItem +namespace Noikoio.RegexBot.Feature.RegexResponder { /// /// Represents configuration for a single rule. /// [System.Diagnostics.DebuggerDisplay("Rule: {DisplayName}")] - internal struct Rule + internal struct RuleConfig { private string _displayName; private Server _server; @@ -42,7 +43,7 @@ namespace Noikoio.RegexBot.ConfigItem /// /// Thrown when encountering a missing or invalid value. /// - public Rule(Server serverref, JObject ruleconf) + public RuleConfig(Server serverref, JObject ruleconf) { _server = serverref; diff --git a/RegexBot.cs b/RegexBot.cs index ce6e4e2..f5df43c 100644 --- a/RegexBot.cs +++ b/RegexBot.cs @@ -12,8 +12,8 @@ namespace Noikoio.RegexBot { private readonly ConfigLoader _config; private readonly DiscordSocketClient _client; - private readonly RuleResponder _responder; + // Constructor loads all subsystems. Subsystem constructors hook up their event delegates. internal RegexBot(ConfigLoader conf) { _client = new DiscordSocketClient(new DiscordSocketConfig() @@ -24,8 +24,11 @@ namespace Noikoio.RegexBot }); _config = conf; + // Hook up handlers for basic functions _client.Connected += _client_Connected; - _responder = new RuleResponder(_client, _config); + + // Initialize features + new Feature.RegexResponder.EventProcessor(_client, _config); } internal async Task Start() diff --git a/RegexBot.csproj b/RegexBot.csproj index 59d9814..791a982 100644 --- a/RegexBot.csproj +++ b/RegexBot.csproj @@ -4,8 +4,10 @@ Exe netcoreapp1.1 Noikoio.RegexBot - 0.14.0.0 + 0.15.0.0 Highly configurable Discord moderation bot + Noikoio +