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.8 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. string text = command.Text;
  34. int nextSpace = NextWhitespace(text);
  35. string name;
  36. if (nextSpace == -1)
  37. name = command.Text;
  38. else
  39. name = command.Text.Substring(0, nextSpace);
  40. lock (this)
  41. {
  42. CommandMapNode nextNode;
  43. if (_nodes.TryGetValue(name, out nextNode))
  44. {
  45. nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command);
  46. if (nextNode.IsEmpty)
  47. _nodes.TryRemove(name, out nextNode);
  48. }
  49. }
  50. }
  51. public IEnumerable<Command> GetCommands(string text)
  52. {
  53. int nextSpace = NextWhitespace(text);
  54. string name;
  55. if (nextSpace == -1)
  56. name = text;
  57. else
  58. name = text.Substring(0, nextSpace);
  59. lock (this)
  60. {
  61. CommandMapNode nextNode;
  62. if (_nodes.TryGetValue(name, out nextNode))
  63. return nextNode.GetCommands(text, nextSpace + 1);
  64. else
  65. return Enumerable.Empty<Command>();
  66. }
  67. }
  68. private static int NextWhitespace(string text)
  69. {
  70. int lowest = int.MaxValue;
  71. for (int i = 0; i < _whitespaceChars.Length; i++)
  72. {
  73. int index = text.IndexOf(_whitespaceChars[i]);
  74. if (index != -1 && index < lowest)
  75. lowest = index;
  76. }
  77. return (lowest != int.MaxValue) ? lowest : -1;
  78. }
  79. }
  80. }