diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index 8d5e691bf..8263d2339 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -74,17 +74,56 @@ namespace Discord.Commands string msg = e.Message.RawText; if (msg.Length == 0) return; - //Check for command char if one is provided - var chars = Config.CommandChars; - if (chars.Length > 0) + bool activated = false; // Either this or nested if statements + // Also needs a clearer name + + if ((Config.ActivationMode & ActivationMode.Char) != 0) { - if (!chars.Contains(msg[0])) - return; - msg = msg.Substring(1); + //Check for command char if one is provided + var chars = Config.CommandChars; + if (chars.Length > 0) + { + if (chars.Contains(msg[0])) + { + msg = msg.Substring(1); + activated = true; + } + } } - //Parse command - IEnumerable commands; + if (!activated && (Config.ActivationMode & ActivationMode.Mention) != 0) + { + if (e.Message.IsMentioningMe() && msg.StartsWith(e.Server.CurrentUser.Mention)) + { + msg = msg.Substring(e.Server.CurrentUser.Mention.Length); + activated = true; + } + else if (e.Channel.IsPrivate && msg.StartsWith($"@{client.CurrentUser.Name}")) + { + msg = msg.Substring(client.CurrentUser.Name.Length); + activated = true; + } + } + + // Checking if that's null with the Custom flag set on launch and throwing an + // exception (similar to commands with several unparsed parameters) would probably be better than the null check here + if (!activated && (Config.ActivationMode & ActivationMode.Custom) != 0 && Config.CustomActivator != null) + { + int index = Config.CustomActivator(e.Message); + if (index > 0) + { + msg = msg.Substring(index); + activated = true; + } + } + + // This kills trying to parse messages when you don't have a command char set, + // but also keeps it from trying to parse everything when you *do* have something set + if (!activated) + return; + + //Parse command + IEnumerable commands; int argPos; CommandParser.ParseCommand(msg, _map, out commands, out argPos); if (commands == null) @@ -283,10 +322,10 @@ namespace Discord.Commands output.Append($" [{param.Name}]"); break; case ParameterType.Multiple: - output.Append(" [...]"); + output.Append($" [{param.Name}]"); break; case ParameterType.Unparsed: - output.Append(" [--]"); + output.Append($" {param.Name}"); break; } } diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs index c72cbbe81..d8ba31fc2 100644 --- a/src/Discord.Net.Commands/CommandServiceConfig.cs +++ b/src/Discord.Net.Commands/CommandServiceConfig.cs @@ -11,6 +11,17 @@ namespace Discord.Commands /// Use the automatic help command and respond in a private message. Private } + [Flags] + public enum ActivationMode + { + // All of these probably need to be changed + /// Enable command activation by char. + Char = 0x1, + /// Enable command activation when mentioned. + Mention = 0x2, + /// Enable command activation by custom function. + Custom = 0x4 + } public class CommandServiceConfig { public char? CommandChar @@ -29,10 +40,16 @@ namespace Discord.Commands } public char[] CommandChars { get { return _commandChars; } set { SetValue(ref _commandChars, value); } } private char[] _commandChars = new char[] { '!' }; + + public Func CustomActivator { get { return _customActivator; } set { SetValue(ref _customActivator, value); } } + private Func _customActivator = null; public HelpMode HelpMode { get { return _helpMode; } set { SetValue(ref _helpMode, value); } } private HelpMode _helpMode = HelpMode.Disable; + public ActivationMode ActivationMode { get { return _activationMode; } set { SetValue(ref _activationMode, value); } } + private ActivationMode _activationMode = ActivationMode.Char; // Set char as default, not sure if it's the best method of doing it + //Lock protected bool _isLocked; internal void Lock() { _isLocked = true; }