You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CommandMap.cs 2.9 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System.Collections.Concurrent;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace Discord.Commands
  5. {
  6. internal class CommandMap
  7. {
  8. static readonly char[] _whitespaceChars = new char[] { ' ', '\r', '\n' };
  9. private readonly ConcurrentDictionary<string, CommandMapNode> _nodes;
  10. public CommandMap()
  11. {
  12. _nodes = new ConcurrentDictionary<string, CommandMapNode>();
  13. }
  14. public void AddCommand(Command command)
  15. {
  16. foreach (string text in command.Aliases)
  17. {
  18. int nextSpace = NextWhitespace(text);
  19. string name;
  20. if (nextSpace == -1)
  21. name = command.Text;
  22. else
  23. name = command.Text.Substring(0, nextSpace);
  24. lock (this)
  25. {
  26. var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x));
  27. nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command);
  28. }
  29. }
  30. }
  31. public void RemoveCommand(Command command)
  32. {
  33. foreach (string text in command.Aliases)
  34. {
  35. int nextSpace = NextWhitespace(text);
  36. string name;
  37. if (nextSpace == -1)
  38. name = command.Text;
  39. else
  40. name = command.Text.Substring(0, nextSpace);
  41. lock (this)
  42. {
  43. CommandMapNode nextNode;
  44. if (_nodes.TryGetValue(name, out nextNode))
  45. {
  46. nextNode.RemoveCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command);
  47. if (nextNode.IsEmpty)
  48. _nodes.TryRemove(name, out nextNode);
  49. }
  50. }
  51. }
  52. }
  53. public IEnumerable<Command> GetCommands(string text)
  54. {
  55. int nextSpace = NextWhitespace(text);
  56. string name;
  57. if (nextSpace == -1)
  58. name = text;
  59. else
  60. name = text.Substring(0, nextSpace);
  61. lock (this)
  62. {
  63. CommandMapNode nextNode;
  64. if (_nodes.TryGetValue(name, out nextNode))
  65. return nextNode.GetCommands(text, nextSpace + 1);
  66. else
  67. return Enumerable.Empty<Command>();
  68. }
  69. }
  70. private static int NextWhitespace(string text)
  71. {
  72. int lowest = int.MaxValue;
  73. for (int i = 0; i < _whitespaceChars.Length; i++)
  74. {
  75. int index = text.IndexOf(_whitespaceChars[i]);
  76. if (index != -1 && index < lowest)
  77. lowest = index;
  78. }
  79. return (lowest != int.MaxValue) ? lowest : -1;
  80. }
  81. }
  82. }