Implement suggestions; minor command refactoring
This commit is contained in:
parent
cc148d5257
commit
986d9e4ff3
11 changed files with 33 additions and 40 deletions
|
@ -22,9 +22,7 @@ class Ban : BanKick {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Kick : BanKick {
|
class Kick(ModCommands module, JObject config) : BanKick(module, config, false) {
|
||||||
public Kick(ModCommands module, JObject config) : base(module, config, false) { }
|
|
||||||
|
|
||||||
protected override async Task ContinueInvoke(SocketGuild g, SocketMessage msg, string? reason,
|
protected override async Task ContinueInvoke(SocketGuild g, SocketMessage msg, string? reason,
|
||||||
ulong targetId, CachedGuildUser? targetQuery, SocketUser? targetUser) {
|
ulong targetId, CachedGuildUser? targetQuery, SocketUser? targetUser) {
|
||||||
// Kick: Unlike ban, must find the guild user in order to proceed
|
// Kick: Unlike ban, must find the guild user in order to proceed
|
||||||
|
@ -76,7 +74,7 @@ abstract class BanKick : CommandConfig {
|
||||||
|
|
||||||
// Usage: (command) (user) (reason)
|
// Usage: (command) (user) (reason)
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
string targetstr;
|
string targetstr;
|
||||||
string? reason;
|
string? reason;
|
||||||
if (line.Length < 2) {
|
if (line.Length < 2) {
|
||||||
|
|
|
@ -3,16 +3,10 @@ using System.Diagnostics;
|
||||||
|
|
||||||
namespace RegexBot.Modules.ModCommands.Commands;
|
namespace RegexBot.Modules.ModCommands.Commands;
|
||||||
[DebuggerDisplay("Command definition '{Label}'")]
|
[DebuggerDisplay("Command definition '{Label}'")]
|
||||||
abstract class CommandConfig {
|
abstract class CommandConfig(ModCommands module, JObject config) {
|
||||||
public string Label { get; }
|
public string Label { get; } = config[nameof(Label)]!.Value<string>()!;
|
||||||
public string Command { get; }
|
public string Command { get; } = config[nameof(Command)]!.Value<string>()!;
|
||||||
protected ModCommands Module { get; }
|
protected ModCommands Module { get; } = module;
|
||||||
|
|
||||||
protected CommandConfig(ModCommands module, JObject config) {
|
|
||||||
Module = module;
|
|
||||||
Label = config[nameof(Label)]!.Value<string>()!;
|
|
||||||
Command = config[nameof(Command)]!.Value<string>()!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Task Invoke(SocketGuild g, SocketMessage msg);
|
public abstract Task Invoke(SocketGuild g, SocketMessage msg);
|
||||||
|
|
||||||
|
@ -20,6 +14,7 @@ abstract class CommandConfig {
|
||||||
protected const string TargetNotFound = ":x: **Unable to find the given user.**";
|
protected const string TargetNotFound = ":x: **Unable to find the given user.**";
|
||||||
|
|
||||||
protected abstract string DefaultUsageMsg { get; }
|
protected abstract string DefaultUsageMsg { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends out the default usage message (<see cref="DefaultUsageMsg"/>) within an embed.
|
/// Sends out the default usage message (<see cref="DefaultUsageMsg"/>) within an embed.
|
||||||
/// An optional message can be included, for uses such as notifying users of incorrect usage.
|
/// An optional message can be included, for uses such as notifying users of incorrect usage.
|
||||||
|
@ -36,4 +31,15 @@ abstract class CommandConfig {
|
||||||
};
|
};
|
||||||
await target.SendMessageAsync(message ?? "", embed: usageEmbed.Build());
|
await target.SendMessageAsync(message ?? "", embed: usageEmbed.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static readonly char[] separator = [' '];
|
||||||
|
/// <summary>
|
||||||
|
/// For the given message's content, assumes its message is a command and returns its parameters
|
||||||
|
/// as an array of substrings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">The incoming message to process.</param>
|
||||||
|
/// <param name="maxParams">The number of parameters to expect.</param>
|
||||||
|
/// <returns>A string array with 0 to maxParams - 1 elements.</returns>
|
||||||
|
protected static string[] SplitToParams(SocketMessage msg, int maxParams)
|
||||||
|
=> msg.Content.Split(separator, maxParams, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
namespace RegexBot.Modules.ModCommands.Commands;
|
namespace RegexBot.Modules.ModCommands.Commands;
|
||||||
class ConfReload : CommandConfig {
|
class ConfReload(ModCommands module, JObject config) : CommandConfig(module, config) {
|
||||||
protected override string DefaultUsageMsg => null!;
|
protected override string DefaultUsageMsg => null!;
|
||||||
|
|
||||||
// No configuration.
|
|
||||||
public ConfReload(ModCommands module, JObject config) : base(module, config) { }
|
|
||||||
|
|
||||||
// Usage: (command)
|
// Usage: (command)
|
||||||
public override Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -2,9 +2,7 @@ using RegexBot.Common;
|
||||||
|
|
||||||
namespace RegexBot.Modules.ModCommands.Commands;
|
namespace RegexBot.Modules.ModCommands.Commands;
|
||||||
// Note and Warn commands are highly similar in implementnation, and thus are handled in a single class.
|
// Note and Warn commands are highly similar in implementnation, and thus are handled in a single class.
|
||||||
class Note : NoteWarn {
|
class Note(ModCommands module, JObject config) : NoteWarn(module, config) {
|
||||||
public Note(ModCommands module, JObject config) : base(module, config) { }
|
|
||||||
|
|
||||||
protected override string DefaultUsageMsg => string.Format(_usageHeader, Command)
|
protected override string DefaultUsageMsg => string.Format(_usageHeader, Command)
|
||||||
+ "Appends a note to the moderation log for the given user.";
|
+ "Appends a note to the moderation log for the given user.";
|
||||||
protected override async Task ContinueInvoke(SocketGuild g, SocketMessage msg, string logMessage, SocketUser targetUser) {
|
protected override async Task ContinueInvoke(SocketGuild g, SocketMessage msg, string logMessage, SocketUser targetUser) {
|
||||||
|
@ -13,9 +11,7 @@ class Note : NoteWarn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Warn : NoteWarn {
|
class Warn(ModCommands module, JObject config) : NoteWarn(module, config) {
|
||||||
public Warn(ModCommands module, JObject config) : base(module, config) { }
|
|
||||||
|
|
||||||
protected override string DefaultUsageMsg => string.Format(_usageHeader, Command)
|
protected override string DefaultUsageMsg => string.Format(_usageHeader, Command)
|
||||||
+ "Issues a warning to the given user, logging the instance to this bot's moderation log "
|
+ "Issues a warning to the given user, logging the instance to this bot's moderation log "
|
||||||
+ "and notifying the offending user over DM of the issued warning.";
|
+ "and notifying the offending user over DM of the issued warning.";
|
||||||
|
@ -45,7 +41,7 @@ abstract class NoteWarn : CommandConfig {
|
||||||
|
|
||||||
// Usage: (command) (user) (message)
|
// Usage: (command) (user) (message)
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
if (line.Length != 3) {
|
if (line.Length != 3) {
|
||||||
await SendUsageMessageAsync(msg.Channel, ":x: Not all required parameters were specified.");
|
await SendUsageMessageAsync(msg.Channel, ":x: Not all required parameters were specified.");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
using RegexBot.Common;
|
using RegexBot.Common;
|
||||||
|
|
||||||
namespace RegexBot.Modules.ModCommands.Commands;
|
namespace RegexBot.Modules.ModCommands.Commands;
|
||||||
class RoleAdd : RoleManipulation {
|
class RoleAdd(ModCommands module, JObject config) : RoleManipulation(module, config) {
|
||||||
protected override (string, string) String1 => ("Adds", "to");
|
protected override (string, string) String1 => ("Adds", "to");
|
||||||
protected override string String2 => "set";
|
protected override string String2 => "set";
|
||||||
public RoleAdd(ModCommands module, JObject config) : base(module, config) { }
|
|
||||||
protected override async Task ContinueInvoke(SocketGuildUser target, SocketRole role) => await target.AddRoleAsync(role);
|
protected override async Task ContinueInvoke(SocketGuildUser target, SocketRole role) => await target.AddRoleAsync(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoleDel : RoleManipulation {
|
class RoleDel(ModCommands module, JObject config) : RoleManipulation(module, config) {
|
||||||
protected override (string, string) String1 => ("Removes", "from");
|
protected override (string, string) String1 => ("Removes", "from");
|
||||||
protected override string String2 => "unset";
|
protected override string String2 => "unset";
|
||||||
public RoleDel(ModCommands module, JObject config) : base(module, config) { }
|
|
||||||
protected override async Task ContinueInvoke(SocketGuildUser target, SocketRole role) => await target.RemoveRoleAsync(role);
|
protected override async Task ContinueInvoke(SocketGuildUser target, SocketRole role) => await target.RemoveRoleAsync(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +44,7 @@ abstract class RoleManipulation : CommandConfig {
|
||||||
|
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
// TODO reason in further parameters?
|
// TODO reason in further parameters?
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
string targetstr;
|
string targetstr;
|
||||||
if (line.Length < 2) {
|
if (line.Length < 2) {
|
||||||
await SendUsageMessageAsync(msg.Channel, null);
|
await SendUsageMessageAsync(msg.Channel, null);
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Say : CommandConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
if (line.Length <= 1) {
|
if (line.Length <= 1) {
|
||||||
await SendUsageMessageAsync(msg.Channel, ":x: You must specify a channel.");
|
await SendUsageMessageAsync(msg.Channel, ":x: You must specify a channel.");
|
||||||
return;
|
return;
|
||||||
|
@ -23,7 +23,7 @@ class Say : CommandConfig {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var getCh = Utilities.ChannelMention.Match(line[1]);
|
var getCh = Utilities.ChannelMentionRegex().Match(line[1]);
|
||||||
if (!getCh.Success) {
|
if (!getCh.Success) {
|
||||||
await SendUsageMessageAsync(msg.Channel, ":x: Unable to find given channel.");
|
await SendUsageMessageAsync(msg.Channel, ":x: Unable to find given channel.");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ShowModLogs : CommandConfig {
|
||||||
|
|
||||||
// Usage: (command) (query) [page]
|
// Usage: (command) (query) [page]
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
if (line.Length < 2) {
|
if (line.Length < 2) {
|
||||||
await SendUsageMessageAsync(msg.Channel, null);
|
await SendUsageMessageAsync(msg.Channel, null);
|
||||||
return;
|
return;
|
||||||
|
@ -47,13 +47,12 @@ class ShowModLogs : CommandConfig {
|
||||||
.Where(l => l.GuildId == query.GuildId && l.UserId == query.UserId)
|
.Where(l => l.GuildId == query.GuildId && l.UserId == query.UserId)
|
||||||
.Count();
|
.Count();
|
||||||
totalPages = (int)Math.Ceiling((double)totalEntries / LogEntriesPerMessage);
|
totalPages = (int)Math.Ceiling((double)totalEntries / LogEntriesPerMessage);
|
||||||
results = db.ModLogs
|
results = [.. db.ModLogs
|
||||||
.Where(l => l.GuildId == query.GuildId && l.UserId == query.UserId)
|
.Where(l => l.GuildId == query.GuildId && l.UserId == query.UserId)
|
||||||
.OrderByDescending(l => l.LogId)
|
.OrderByDescending(l => l.LogId)
|
||||||
.Skip((pagenum - 1) * LogEntriesPerMessage)
|
.Skip((pagenum - 1) * LogEntriesPerMessage)
|
||||||
.Take(LogEntriesPerMessage)
|
.Take(LogEntriesPerMessage)
|
||||||
.AsNoTracking()
|
.AsNoTracking()];
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultList = new EmbedBuilder() {
|
var resultList = new EmbedBuilder() {
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Timeout : CommandConfig {
|
||||||
|
|
||||||
// Usage: (command) (user) (duration) (reason)
|
// Usage: (command) (user) (duration) (reason)
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 4);
|
||||||
string targetstr;
|
string targetstr;
|
||||||
string? reason;
|
string? reason;
|
||||||
if (line.Length < 3) {
|
if (line.Length < 3) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Unban : CommandConfig {
|
||||||
|
|
||||||
// Usage: (command) (user query)
|
// Usage: (command) (user query)
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
string targetstr;
|
string targetstr;
|
||||||
if (line.Length < 2) {
|
if (line.Length < 2) {
|
||||||
await SendUsageMessageAsync(msg.Channel, null);
|
await SendUsageMessageAsync(msg.Channel, null);
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Untimeout : CommandConfig {
|
||||||
|
|
||||||
// Usage: (command) (user query)
|
// Usage: (command) (user query)
|
||||||
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
|
||||||
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
|
var line = SplitToParams(msg, 3);
|
||||||
string targetstr;
|
string targetstr;
|
||||||
if (line.Length < 2) {
|
if (line.Length < 2) {
|
||||||
await SendUsageMessageAsync(msg.Channel, null);
|
await SendUsageMessageAsync(msg.Channel, null);
|
||||||
|
|
|
@ -12,6 +12,5 @@ class ModuleConfig {
|
||||||
} catch (FormatException) {
|
} catch (FormatException) {
|
||||||
throw new ModuleLoadException("Name specified in configuration is not a role.");
|
throw new ModuleLoadException("Name specified in configuration is not a role.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue