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.

CommandParser.cs 4.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System.Collections.Generic;
  2. namespace Discord.Commands
  3. {
  4. internal static class CommandParser
  5. {
  6. private enum CommandParserPart
  7. {
  8. None,
  9. Parameter,
  10. QuotedParameter,
  11. DoubleQuotedParameter
  12. }
  13. public static bool ParseCommand(string input, CommandMap map, out Command command, out int endPos)
  14. {
  15. int startPosition = 0;
  16. int endPosition = 0;
  17. int inputLength = input.Length;
  18. bool isEscaped = false;
  19. command = null;
  20. endPos = 0;
  21. if (input == "")
  22. return false;
  23. while (endPosition < inputLength)
  24. {
  25. char currentChar = input[endPosition++];
  26. if (isEscaped)
  27. isEscaped = false;
  28. else if (currentChar == '\\')
  29. isEscaped = true;
  30. if ((!isEscaped && currentChar == ' ') || endPosition >= inputLength)
  31. {
  32. int length = (currentChar == ' ' ? endPosition - 1 : endPosition) - startPosition;
  33. string temp = input.Substring(startPosition, length);
  34. if (temp == "")
  35. startPosition = endPosition;
  36. else
  37. {
  38. var newMap = map.GetMap(temp);
  39. if (newMap != null)
  40. {
  41. map = newMap;
  42. endPos = endPosition;
  43. }
  44. else
  45. break;
  46. startPosition = endPosition;
  47. }
  48. }
  49. }
  50. command = map.GetCommand(); //Work our way backwards to find a command that matches our input
  51. return command != null;
  52. }
  53. //TODO: Check support for escaping
  54. public static CommandErrorType? ParseArgs(string input, int startPos, Command command, out string[] args)
  55. {
  56. CommandParserPart currentPart = CommandParserPart.None;
  57. int startPosition = startPos;
  58. int endPosition = startPos;
  59. int inputLength = input.Length;
  60. bool isEscaped = false;
  61. var expectedArgs = command._parameters;
  62. List<string> argList = new List<string>();
  63. CommandParameter parameter = null;
  64. args = null;
  65. if (input == "")
  66. return CommandErrorType.InvalidInput;
  67. while (endPosition < inputLength)
  68. {
  69. if (startPosition == endPosition && (parameter == null || parameter.Type != ParameterType.Multiple)) //Is first char of a new arg
  70. {
  71. if (argList.Count == command.MaxArgs)
  72. return CommandErrorType.BadArgCount;
  73. parameter = command._parameters[argList.Count];
  74. if (parameter.Type == ParameterType.Unparsed)
  75. {
  76. argList.Add(input.Substring(startPosition));
  77. break;
  78. }
  79. }
  80. char currentChar = input[endPosition++];
  81. if (isEscaped)
  82. isEscaped = false;
  83. else if (currentChar == '\\')
  84. isEscaped = true;
  85. switch (currentPart)
  86. {
  87. case CommandParserPart.None:
  88. if ((!isEscaped && currentChar == '\"'))
  89. {
  90. currentPart = CommandParserPart.DoubleQuotedParameter;
  91. startPosition = endPosition;
  92. }
  93. else if ((!isEscaped && currentChar == '\''))
  94. {
  95. currentPart = CommandParserPart.QuotedParameter;
  96. startPosition = endPosition;
  97. }
  98. else if ((!isEscaped && currentChar == ' ') || endPosition >= inputLength)
  99. {
  100. int length = (currentChar == ' ' ? endPosition - 1 : endPosition) - startPosition;
  101. string temp = input.Substring(startPosition, length);
  102. if (temp == "")
  103. startPosition = endPosition;
  104. else
  105. {
  106. currentPart = CommandParserPart.None;
  107. argList.Add(temp);
  108. startPosition = endPosition;
  109. }
  110. }
  111. break;
  112. case CommandParserPart.QuotedParameter:
  113. if ((!isEscaped && currentChar == '\''))
  114. {
  115. string temp = input.Substring(startPosition, endPosition - startPosition - 1);
  116. currentPart = CommandParserPart.None;
  117. argList.Add(temp);
  118. startPosition = endPosition;
  119. }
  120. else if (endPosition >= inputLength)
  121. return CommandErrorType.InvalidInput;
  122. break;
  123. case CommandParserPart.DoubleQuotedParameter:
  124. if ((!isEscaped && currentChar == '\"'))
  125. {
  126. string temp = input.Substring(startPosition, endPosition - startPosition - 1);
  127. currentPart = CommandParserPart.None;
  128. argList.Add(temp);
  129. startPosition = endPosition;
  130. }
  131. else if (endPosition >= inputLength)
  132. return CommandErrorType.InvalidInput;
  133. break;
  134. }
  135. }
  136. if (argList.Count < command.MinArgs)
  137. return CommandErrorType.BadArgCount;
  138. args = argList.ToArray();
  139. return null;
  140. }
  141. }
  142. }