Removed manual module name setting
Modules will now be named based on their existing class name. Their respective configuration sections are now also defined by the same value. Documentation has been updated to reflect this.
This commit is contained in:
parent
8e80e0241b
commit
287bb33d77
21 changed files with 33 additions and 106 deletions
25
BotModule.cs
25
BotModule.cs
|
@ -13,8 +13,8 @@ namespace Noikoio.RegexBot
|
|||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly AsyncLogger _logger;
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
public string Name => this.GetType().Name;
|
||||
protected DiscordSocketClient Client => _client;
|
||||
|
||||
public BotModule(DiscordSocketClient client)
|
||||
|
@ -80,25 +80,4 @@ namespace Noikoio.RegexBot
|
|||
public sealed override int GetHashCode() => base.GetHashCode();
|
||||
public sealed override string ToString() => base.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which section under an individual Discord guild configuration should be passed to the
|
||||
/// module's <see cref="BotModule.ProcessConfiguration(JToken)"/> method during configuration load.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||
public class ConfigSectionAttribute : Attribute
|
||||
{
|
||||
private readonly string _sectionName;
|
||||
|
||||
public string SectionName => _sectionName;
|
||||
|
||||
public ConfigSectionAttribute(string sectionName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sectionName))
|
||||
{
|
||||
throw new ArgumentNullException("Configuration section name cannot be blank.");
|
||||
}
|
||||
_sectionName = sectionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,16 +162,12 @@ namespace Noikoio.RegexBot
|
|||
Dictionary<BotModule, object> customConfs = new Dictionary<BotModule, object>();
|
||||
foreach (var item in _bot.Modules)
|
||||
{
|
||||
var attr = item.GetType().GetTypeInfo()
|
||||
.GetMethod("ProcessConfiguration").GetCustomAttribute<ConfigSectionAttribute>();
|
||||
if (attr == null)
|
||||
{
|
||||
await SLog("No additional configuration for " + item.Name);
|
||||
continue;
|
||||
}
|
||||
var section = sconf[attr.SectionName];
|
||||
var confSection = item.Name;
|
||||
|
||||
var section = sconf[confSection];
|
||||
if (section == null)
|
||||
{
|
||||
// Section not in config. Do not call loader method.
|
||||
await SLog("Additional configuration not defined for " + item.Name);
|
||||
continue;
|
||||
}
|
||||
|
@ -191,8 +187,7 @@ namespace Noikoio.RegexBot
|
|||
customConfs.Add(item, result);
|
||||
}
|
||||
|
||||
|
||||
// Switch to using new data
|
||||
// Switch to new configuration
|
||||
List<Tuple<Regex, string[]>> rulesfinal = new List<Tuple<Regex, string[]>>();
|
||||
newservers.Add(new ServerConfig(sid, mods, new ReadOnlyDictionary<BotModule, object>(customConfs)));
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@ namespace Noikoio.RegexBot.EntityCache
|
|||
{
|
||||
private readonly DatabaseConfig _db;
|
||||
|
||||
public override string Name => nameof(EntityCache);
|
||||
|
||||
public Module(DiscordSocketClient client) : base(client)
|
||||
{
|
||||
if (RegexBot.Config.DatabaseAvailable)
|
||||
|
|
|
@ -16,15 +16,12 @@ namespace Noikoio.RegexBot.Module.AutoMod
|
|||
/// </remarks>
|
||||
class AutoMod : BotModule
|
||||
{
|
||||
public override string Name => "AutoMod";
|
||||
|
||||
public AutoMod(DiscordSocketClient client) : base(client)
|
||||
{
|
||||
client.MessageReceived += CMessageReceived;
|
||||
client.MessageUpdated += CMessageUpdated;
|
||||
}
|
||||
|
||||
[ConfigSection("automod")]
|
||||
|
||||
public override async Task<object> ProcessConfiguration(JToken configSection)
|
||||
{
|
||||
List<ConfigItem> rules = new List<ConfigItem>();
|
||||
|
|
|
@ -22,8 +22,6 @@ namespace Noikoio.RegexBot.Module.AutoRespond
|
|||
partial class AutoRespond : BotModule
|
||||
{
|
||||
#region BotModule implementation
|
||||
public override string Name => "AutoRespond";
|
||||
|
||||
public AutoRespond(DiscordSocketClient client) : base(client)
|
||||
{
|
||||
client.MessageReceived += Client_MessageReceived;
|
||||
|
@ -41,8 +39,7 @@ namespace Noikoio.RegexBot.Module.AutoRespond
|
|||
foreach (var def in defs)
|
||||
await Task.Run(async () => await ProcessMessage(arg, def));
|
||||
}
|
||||
|
||||
[ConfigSection("autoresponses")]
|
||||
|
||||
public override async Task<object> ProcessConfiguration(JToken configSection)
|
||||
{
|
||||
var responses = new List<ConfigItem>();
|
||||
|
|
|
@ -12,8 +12,6 @@ namespace Noikoio.RegexBot.Module.DMLogger
|
|||
/// </summary>
|
||||
class DMLogger : BotModule
|
||||
{
|
||||
public override string Name => nameof(DMLogger);
|
||||
|
||||
public DMLogger(DiscordSocketClient client) : base(client)
|
||||
{
|
||||
client.MessageReceived += Client_MessageReceived;
|
||||
|
|
|
@ -14,8 +14,6 @@ namespace Noikoio.RegexBot.Module.EntryAutoRole
|
|||
/// </summary>
|
||||
class EntryAutoRole : BotModule
|
||||
{
|
||||
public override string Name => "EntryAutoRole";
|
||||
|
||||
private List<AutoRoleEntry> _roleWaitlist;
|
||||
private object _roleWaitLock = new object();
|
||||
|
||||
|
@ -37,8 +35,7 @@ namespace Noikoio.RegexBot.Module.EntryAutoRole
|
|||
_workerCancel = new CancellationTokenSource();
|
||||
Task.Factory.StartNew(Worker, _workerCancel.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
[ConfigSection("EntryAutoRole")]
|
||||
|
||||
public override Task<object> ProcessConfiguration(JToken configSection)
|
||||
{
|
||||
if (configSection.Type != JTokenType.Object)
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
// "notifymsg" - Message to send to the target user being acted upon. Default message is used
|
||||
// if the value is not specified. If a blank value is given, the feature is disabled.
|
||||
// Takes the special values $s for server name and $r for reason text.
|
||||
protected BanKick(CommandListener l, string label, JObject conf, CommandMode mode) : base(l, label, conf)
|
||||
protected BanKick(ModCommands l, string label, JObject conf, CommandMode mode) : base(l, label, conf)
|
||||
{
|
||||
_mode = mode;
|
||||
_forceReason = conf["forcereason"]?.Value<bool>() ?? false;
|
||||
|
@ -199,13 +199,13 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
|
||||
class Ban : BanKick
|
||||
{
|
||||
public Ban(CommandListener l, string label, JObject conf)
|
||||
public Ban(ModCommands l, string label, JObject conf)
|
||||
: base(l, label, conf, CommandMode.Ban) { }
|
||||
}
|
||||
|
||||
class Kick : BanKick
|
||||
{
|
||||
public Kick(CommandListener l, string label, JObject conf)
|
||||
public Kick(ModCommands l, string label, JObject conf)
|
||||
: base(l, label, conf, CommandMode.Kick) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
class ConfReload : Command
|
||||
{
|
||||
// No configuration.
|
||||
public ConfReload(CommandListener l, string label, JObject conf) : base(l, label, conf) { }
|
||||
public ConfReload(ModCommands l, string label, JObject conf) : base(l, label, conf) { }
|
||||
|
||||
// Usage: (command)
|
||||
public override async Task Invoke(SocketGuild g, SocketMessage msg)
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
// "role" - string; The given role that applies to this command.
|
||||
// "successmsg" - string; Messages to display on command success. Overrides default.
|
||||
|
||||
protected RoleManipulation(CommandListener l, string label, JObject conf, CommandMode mode) : base(l, label, conf)
|
||||
protected RoleManipulation(ModCommands l, string label, JObject conf, CommandMode mode) : base(l, label, conf)
|
||||
{
|
||||
_mode = mode;
|
||||
var rolestr = conf["role"]?.Value<string>();
|
||||
|
@ -123,11 +123,11 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
|
||||
class RoleAdd : RoleManipulation
|
||||
{
|
||||
public RoleAdd(CommandListener l, string label, JObject conf) : base(l, label, conf, CommandMode.Add) { }
|
||||
public RoleAdd(ModCommands l, string label, JObject conf) : base(l, label, conf, CommandMode.Add) { }
|
||||
}
|
||||
|
||||
class RoleDel : RoleManipulation
|
||||
{
|
||||
public RoleDel(CommandListener l, string label, JObject conf) : base(l, label, conf, CommandMode.Del) { }
|
||||
public RoleDel(ModCommands l, string label, JObject conf) : base(l, label, conf, CommandMode.Del) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
{
|
||||
// No configuration at the moment.
|
||||
// TODO: Whitelist/blacklist - to limit which channels it can "say" into
|
||||
public Say(CommandListener l, string label, JObject conf) : base(l, label, conf) {
|
||||
public Say(ModCommands l, string label, JObject conf) : base(l, label, conf) {
|
||||
DefaultUsageMsg = $"{this.Trigger} [channel] [message]\n"
|
||||
+ "Displays the given message exactly as specified to the given channel.";
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
// No configuration.
|
||||
// TODO bring in some options from BanKick. Particularly custom success msg.
|
||||
// TODO when ModLogs fully implemented, add a reason?
|
||||
public Unban(CommandListener l, string label, JObject conf) : base(l, label, conf) {
|
||||
public Unban(ModCommands l, string label, JObject conf) : base(l, label, conf) {
|
||||
DefaultUsageMsg = $"{this.Trigger} [user or user ID]\n"
|
||||
+ "Unbans the given user, allowing them to rejoin the server.";
|
||||
}
|
||||
|
|
|
@ -16,20 +16,20 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
/// <summary>
|
||||
/// Base class for a command within the module.
|
||||
/// After implementing, don't forget to add a reference to
|
||||
/// <see cref="CreateInstance(CommandListener, JProperty)"/>.
|
||||
/// <see cref="CreateInstance(ModCommands, JProperty)"/>.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("Command def: {Label}")]
|
||||
abstract class Command
|
||||
{
|
||||
private readonly CommandListener _mod;
|
||||
private readonly ModCommands _mod;
|
||||
private readonly string _label;
|
||||
private readonly string _command;
|
||||
|
||||
protected CommandListener Module => _mod;
|
||||
protected ModCommands Module => _mod;
|
||||
public string Label => _label;
|
||||
public string Trigger => _command;
|
||||
|
||||
public Command(CommandListener l, string label, JObject conf)
|
||||
public Command(ModCommands l, string label, JObject conf)
|
||||
{
|
||||
_mod = l;
|
||||
_label = label;
|
||||
|
@ -58,7 +58,7 @@ namespace Noikoio.RegexBot.Module.ModCommands.Commands
|
|||
{ "delrole", typeof(RoleDel) }
|
||||
});
|
||||
|
||||
public static Command CreateInstance(CommandListener root, JProperty def)
|
||||
public static Command CreateInstance(ModCommands root, JProperty def)
|
||||
{
|
||||
string label = def.Name;
|
||||
if (string.IsNullOrWhiteSpace(label)) throw new RuleImportException("Label cannot be blank.");
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Noikoio.RegexBot.Module.ModCommands
|
|||
|
||||
public ReadOnlyDictionary<string, Command> Commands => _cmdInstances;
|
||||
|
||||
public ConfigItem(CommandListener instance, JToken inconf)
|
||||
public ConfigItem(ModCommands instance, JToken inconf)
|
||||
{
|
||||
if (inconf.Type != JTokenType.Object)
|
||||
{
|
||||
|
|
|
@ -17,11 +17,9 @@ namespace Noikoio.RegexBot.Module.ModCommands
|
|||
/// done in a way that would easily allow for flexibility and modifications during runtime.
|
||||
/// Thus, reinventing the wheel right here.
|
||||
/// </remarks>
|
||||
class CommandListener : BotModule
|
||||
class ModCommands : BotModule
|
||||
{
|
||||
public override string Name => "ModCommands";
|
||||
|
||||
public CommandListener(DiscordSocketClient client) : base(client)
|
||||
public ModCommands(DiscordSocketClient client) : base(client)
|
||||
{
|
||||
client.MessageReceived += Client_MessageReceived;
|
||||
}
|
||||
|
@ -34,7 +32,6 @@ namespace Noikoio.RegexBot.Module.ModCommands
|
|||
if (arg.Channel is IGuildChannel) await CommandCheckInvoke(arg);
|
||||
}
|
||||
|
||||
[ConfigSection("ModCommands")]
|
||||
public override async Task<object> ProcessConfiguration(JToken configSection)
|
||||
{
|
||||
// Constructor throws exception on config errors
|
|
@ -1,28 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.WebSocket;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Noikoio.RegexBot.Module.ModLogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Listens for Discord-based events and writes them to the log (database).
|
||||
/// Additionally writes certain messages to a designated logging channel if configured.
|
||||
/// </summary>
|
||||
class EventListener : BotModule
|
||||
{
|
||||
public override string Name => "ModLogs";
|
||||
public EventListener(DiscordSocketClient client) : base(client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[ConfigSection("modlogs")]
|
||||
public override Task<object> ProcessConfiguration(JToken configSection)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,8 +11,6 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
|||
/// </summary>
|
||||
class ModLogs : BotModule
|
||||
{
|
||||
public override string Name => "ModLogs";
|
||||
|
||||
private readonly MessageCache _msgCacheInstance;
|
||||
|
||||
public ModLogs(DiscordSocketClient client) : base(client)
|
||||
|
@ -26,8 +24,7 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
|||
// TODO add handlers for detecting joins, leaves, bans, kicks, user edits (nick/username/discr)
|
||||
// TODO add handler for processing the log query command
|
||||
}
|
||||
|
||||
[ConfigSection("ModLogs")]
|
||||
|
||||
public override async Task<object> ProcessConfiguration(JToken configSection)
|
||||
{
|
||||
if (configSection.Type != JTokenType.Object)
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Noikoio.RegexBot
|
|||
{
|
||||
new Module.DMLogger.DMLogger(_client),
|
||||
new Module.AutoMod.AutoMod(_client),
|
||||
new Module.ModCommands.CommandListener(_client),
|
||||
new Module.ModCommands.ModCommands(_client),
|
||||
new Module.AutoRespond.AutoRespond(_client),
|
||||
new Module.EntryAutoRole.EntryAutoRole(_client),
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ AutoMod is set up by defining rules within a JSON object named `automod` within
|
|||
|
||||
Sample within a [server definition](serverdef.html):
|
||||
```
|
||||
"automod": {
|
||||
"AutoMod": {
|
||||
"Delete bilingual pirates": {
|
||||
"regex": [ "pira(te|cy)", "pirat(a|ería)", ],
|
||||
"response": [
|
||||
|
|
|
@ -6,7 +6,7 @@ This may seem like a redundant feature, given that the same can be accomplished
|
|||
|
||||
Sample within a [server definition](serverdef.html):
|
||||
```
|
||||
"autorespond": {
|
||||
"AutoRespond": {
|
||||
"Help command": {
|
||||
"regex": "^!help$",
|
||||
"reply": "You can't be helped. Try again in 45 minutes.",
|
||||
|
|
|
@ -26,8 +26,8 @@ The following is a list of accepted members within a server definition.
|
|||
* id (*integer*) - **Required.** A value containing the server's [unique ID](https://support.discordapp.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-).
|
||||
* name (*string*) - Preferably a readable version of the server's name. Not used for anything other than internal logging.
|
||||
* moderators (*[entity list](entitylist.html)*) - A list of entities to consider as moderators. Actions done by members of this list are able to execute *ModCommands* commands and are exempt from certain *AutoMod* rules. See their respective pages for more details.
|
||||
* [automod](automod.html) - See respective page.
|
||||
* [autoresponses](autorespond.html) - See respective page.
|
||||
* [AutoMod](automod.html) - See respective page.
|
||||
* [AutoRespond](autorespond.html) - See respective page.
|
||||
* [EntryAutoRole](entryautorole.html) - See respective page.
|
||||
* [ModCommands](modcommands.html) - See respective page.
|
||||
* [ModLogs](modlogs.html) - See respective page.
|
Loading…
Reference in a new issue