diff --git a/ConfigItem/EntityList.cs b/ConfigItem/EntityList.cs
index a448757..2a3893b 100644
--- a/ConfigItem/EntityList.cs
+++ b/ConfigItem/EntityList.cs
@@ -7,8 +7,6 @@ using System.Linq;
namespace Noikoio.RegexBot.ConfigItem
{
- enum FilterType { None, Whitelist, Blacklist }
-
///
/// Represents a structure in bot configuration that contains a list of
/// channels, roles, and users.
@@ -70,7 +68,7 @@ namespace Noikoio.RegexBot.ConfigItem
///
/// An incoming message.
///
- /// True if the occurred within a channel specified in this list,
+ /// True if '' occurred within a channel specified in this list,
/// or if the message author belongs to one or more roles in this list, or if the user itself
/// is defined within this list.
///
@@ -125,28 +123,5 @@ namespace Noikoio.RegexBot.ConfigItem
// No match.
return false;
}
-
- ///
- /// Helper method for reading whitelist and blacklist filtering lists.
- ///
- ///
- /// A JSON object which presumably contains an array named "whitelist" or "blacklist".
- ///
- public static (FilterType, EntityList) GetFilterList(JObject section)
- {
- var mode = FilterType.None;
- EntityList list;
- if (section["whitelist"] != null) mode = FilterType.Whitelist;
- if (section["blacklist"] != null)
- {
- if (mode == FilterType.Whitelist)
- throw new 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?
- else list = new EntityList(section[mode == FilterType.Whitelist ? "whitelist" : "blacklist"]);
-
- return (mode, list);
- }
}
}
diff --git a/ConfigItem/FilterList.cs b/ConfigItem/FilterList.cs
new file mode 100644
index 0000000..972f78e
--- /dev/null
+++ b/ConfigItem/FilterList.cs
@@ -0,0 +1,91 @@
+using Discord.WebSocket;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Noikoio.RegexBot.ConfigItem
+{
+ enum FilterType { None, Whitelist, Blacklist }
+
+ ///
+ /// Represents whitelist/blacklist configuration, including exemptions.
+ ///
+ struct FilterList
+ {
+ FilterType _type;
+ EntityList _filterList;
+ EntityList _exemptions;
+
+ public FilterType FilterMode => _type;
+ public EntityList FilterEntities => _filterList;
+ public EntityList FilterExemptions => _exemptions;
+
+ ///
+ /// Gets the
+ ///
+ ///
+ /// A JSON object which presumably contains an array named "whitelist" or "blacklist",
+ /// and optionally one named "exempt".
+ ///
+ ///
+ /// Thrown if both "whitelist" and "blacklist" definitions were found, if
+ /// "exempt" was found without a corresponding "whitelist" or "blacklist",
+ /// or if there was an issue parsing an EntityList within these definitions.
+ ///
+ public FilterList(JObject conf)
+ {
+ _type = FilterType.None;
+
+ if (conf["whitelist"] != null) _type = FilterType.Whitelist;
+ if (conf["blacklist"] != null)
+ {
+ if (_type != FilterType.None)
+ throw new RuleImportException("Cannot have both 'whitelist' and 'blacklist' values defined.");
+ _type = FilterType.Blacklist;
+ }
+ if (_type == FilterType.None)
+ {
+ _filterList = null;
+ _exemptions = null;
+ if (conf["exempt"] != null)
+ throw new RuleImportException("Cannot have 'exempt' defined if no corresponding " +
+ "'whitelist' or 'blacklist' has been defined in the same section.");
+ }
+ else
+ {
+ _filterList = new EntityList(conf[_type == FilterType.Whitelist ? "whitelist" : "blacklist"]);
+ _exemptions = new EntityList(conf["exempt"]); // EntityList constructor checks for null value
+ }
+ }
+
+ ///
+ /// Determines if the parameters of '' are a match with filtering
+ /// rules defined in this instance.
+ ///
+ /// An incoming message.
+ ///
+ /// True if the user or channel specified by '' is filtered by
+ /// the configuration defined in this instance.
+ ///
+ public bool IsFiltered(SocketMessage msg)
+ {
+ if (FilterMode == FilterType.None) return false;
+
+ bool inFilter = FilterEntities.ExistsInList(msg);
+
+ if (FilterMode == FilterType.Whitelist)
+ {
+ if (!inFilter) return true;
+ return FilterExemptions.ExistsInList(msg);
+ }
+ else if (FilterMode == FilterType.Blacklist)
+ {
+ if (!inFilter) return false;
+ return !FilterExemptions.ExistsInList(msg);
+ }
+
+ throw new Exception("this shouldn't happen");
+ }
+ }
+}
diff --git a/Feature/RegexResponder/EventProcessor.cs b/Feature/RegexResponder/EventProcessor.cs
index 75d0af2..e78f50e 100644
--- a/Feature/RegexResponder/EventProcessor.cs
+++ b/Feature/RegexResponder/EventProcessor.cs
@@ -128,7 +128,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
// Moderator bypass check
if (rule.AllowModBypass == true && srv.Moderators.ExistsInList(msg)) return;
// Individual rule filtering check
- if (IsFiltered(rule, msg)) return;
+ if (rule.Filter.IsFiltered(msg)) return;
// And finally, pattern matching checks
bool success = false;
@@ -220,26 +220,6 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
return result.ToString();
}
-
- private bool IsFiltered(RuleConfig r, SocketMessage m)
- {
- if (r.FilterMode == FilterType.None) return false;
-
- bool inFilter = r.FilterList.ExistsInList(m);
-
- if (r.FilterMode == FilterType.Whitelist)
- {
- if (!inFilter) return true;
- return r.FilterExemptions.ExistsInList(m);
- }
- else if (r.FilterMode == FilterType.Blacklist)
- {
- if (!inFilter) return false;
- return !r.FilterExemptions.ExistsInList(m);
- }
-
- return false; // this shouldn't happen™
- }
private string[] SplitParams(string cmd, int? limit = null)
{
diff --git a/Feature/RegexResponder/RuleConfig.cs b/Feature/RegexResponder/RuleConfig.cs
index f263d18..8668c9e 100644
--- a/Feature/RegexResponder/RuleConfig.cs
+++ b/Feature/RegexResponder/RuleConfig.cs
@@ -15,9 +15,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
private string _displayName;
private IEnumerable _regex;
private IEnumerable _responses;
- private FilterType _filtermode;
- private EntityList _filterlist;
- private EntityList _filterexempt;
+ private FilterList _filter;
private int? _minLength;
private int? _maxLength;
private bool _modBypass;
@@ -26,9 +24,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
public string DisplayName => _displayName;
public IEnumerable Regex => _regex;
public IEnumerable Responses => _responses;
- public FilterType FilterMode => _filtermode;
- public EntityList FilterList => _filterlist;
- public EntityList FilterExemptions => _filterexempt;
+ public FilterList Filter => _filter;
public int? MinLength => _minLength;
public int? MaxLength => _maxLength;
public bool AllowModBypass => _modBypass;
@@ -131,9 +127,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
_responses = responses.ToArray();
// (white|black)list filtering
- (_filtermode, _filterlist) = EntityList.GetFilterList(ruleconf);
- // filtering exemptions
- _filterexempt = new EntityList(ruleconf["exempt"]);
+ _filter = new FilterList(ruleconf);
// moderator bypass toggle - true by default, must be explicitly set to false
bool? modoverride = ruleconf["AllowModBypass"]?.Value();