diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index 9420476d5..77f586efc 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -20,6 +20,7 @@ namespace Discord.Commands private readonly CommandMap _map; internal readonly RunMode _defaultRunMode; + internal readonly string _nodeSeparator; public IEnumerable Modules => _moduleDefs.Select(x => x); public IEnumerable Commands => _moduleDefs.SelectMany(x => x.Commands); @@ -30,7 +31,6 @@ namespace Discord.Commands _moduleLock = new SemaphoreSlim(1, 1); _typedModuleDefs = new ConcurrentDictionary(); _moduleDefs = new ConcurrentBag(); - _map = new CommandMap(); _typeReaders = new ConcurrentDictionary { [typeof(bool)] = new SimpleTypeReader(), @@ -68,6 +68,8 @@ namespace Discord.Commands [typeof(IGuildUser)] = new UserTypeReader(), }; _defaultRunMode = config.DefaultRunMode; + _nodeSeparator = config.NodeSeparator; + _map = new CommandMap(this); } //Modules diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs index 97c98a54c..66ddade10 100644 --- a/src/Discord.Net.Commands/CommandServiceConfig.cs +++ b/src/Discord.Net.Commands/CommandServiceConfig.cs @@ -4,5 +4,7 @@ { /// The default RunMode commands should have, if one is not specified on the Command attribute or builder. public RunMode DefaultRunMode { get; set; } = RunMode.Mixed; + /// What character should be used between command nodes + public string NodeSeparator { get; set; } = " "; } } diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs index 2ca8b1651..a386c75ca 100644 --- a/src/Discord.Net.Commands/Info/CommandInfo.cs +++ b/src/Discord.Net.Commands/Info/CommandInfo.cs @@ -42,7 +42,7 @@ namespace Discord.Commands // both command and module provide aliases if (module.Aliases.Count > 0 && builder.Aliases.Count > 0) - Aliases = module.Aliases.Permutate(builder.Aliases, (first, second) => second != null ? first + " " + second : first).ToImmutableArray(); + Aliases = module.Aliases.Permutate(builder.Aliases, (first, second) => second != null ? first + service._nodeSeparator + second : first).ToImmutableArray(); // only module provides aliases else if (module.Aliases.Count > 0) Aliases = module.Aliases.ToImmutableArray(); diff --git a/src/Discord.Net.Commands/Map/CommandMap.cs b/src/Discord.Net.Commands/Map/CommandMap.cs index 3a5239878..fee60d86a 100644 --- a/src/Discord.Net.Commands/Map/CommandMap.cs +++ b/src/Discord.Net.Commands/Map/CommandMap.cs @@ -7,9 +7,9 @@ namespace Discord.Commands private readonly CommandMapNode _root; private static readonly string[] _blankAliases = new[] { "" }; - public CommandMap() + public CommandMap(CommandService service) { - _root = new CommandMapNode(""); + _root = new CommandMapNode("", service); } public void AddCommand(CommandInfo command) diff --git a/src/Discord.Net.Commands/Map/CommandMapNode.cs b/src/Discord.Net.Commands/Map/CommandMapNode.cs index a86c0643d..5d2691336 100644 --- a/src/Discord.Net.Commands/Map/CommandMapNode.cs +++ b/src/Discord.Net.Commands/Map/CommandMapNode.cs @@ -7,25 +7,25 @@ namespace Discord.Commands { internal class CommandMapNode { - private static readonly char[] _whitespaceChars = new char[] { ' ', '\r', '\n' }; - private readonly ConcurrentDictionary _nodes; private readonly string _name; private readonly object _lockObj = new object(); + private readonly CommandService _service; private ImmutableArray _commands; public bool IsEmpty => _commands.Length == 0 && _nodes.Count == 0; - public CommandMapNode(string name) + public CommandMapNode(string name, CommandService service) { _name = name; _nodes = new ConcurrentDictionary(); _commands = ImmutableArray.Create(); + _service = service; } public void AddCommand(string text, int index, CommandInfo command) { - int nextSpace = NextWhitespace(text, index); + int nextSpace = NextSeparator(text, index); string name; lock (_lockObj) @@ -43,14 +43,14 @@ namespace Discord.Commands else name = text.Substring(index, nextSpace - index); - var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x)); + var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x, _service)); nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command); } } } public void RemoveCommand(string text, int index, CommandInfo command) { - int nextSpace = NextWhitespace(text, index); + int nextSpace = NextSeparator(text, index); string name; lock (_lockObj) @@ -77,7 +77,7 @@ namespace Discord.Commands public IEnumerable GetCommands(string text, int index) { - int nextSpace = NextWhitespace(text, index); + int nextSpace = NextSeparator(text, index); string name; var commands = _commands; @@ -100,15 +100,12 @@ namespace Discord.Commands } } - private static int NextWhitespace(string text, int startIndex) + private int NextSeparator(string text, int startIndex) { int lowest = int.MaxValue; - for (int i = 0; i < _whitespaceChars.Length; i++) - { - int index = text.IndexOf(_whitespaceChars[i], startIndex); - if (index != -1 && index < lowest) + int index = text.IndexOf(_service._nodeSeparator, startIndex); + if (index != -1 && index < lowest) lowest = index; - } return (lowest != int.MaxValue) ? lowest : -1; } }