Browse Source

Added support for unparsed parameters, more cleanup

tags/docs-0.9
RogueException 9 years ago
parent
commit
0fe2785b15
4 changed files with 61 additions and 53 deletions
  1. +2
    -2
      src/Discord.Net.Commands/Command.cs
  2. +3
    -3
      src/Discord.Net.Commands/CommandBuilder.cs
  3. +30
    -23
      src/Discord.Net.Commands/CommandParser.cs
  4. +26
    -25
      src/Discord.Net.Commands/CommandsPlugin.cs

+ 2
- 2
src/Discord.Net.Commands/Command.cs View File

@@ -32,7 +32,7 @@ namespace Discord.Commands
public string Text { get; }
public int? MinArgs { get; private set; }
public int? MaxArgs { get; private set; }
public int MinPerms { get; internal set; }
public int MinPermissions { get; internal set; }
public bool IsHidden { get; internal set; }
public string Description { get; internal set; }

@@ -40,7 +40,7 @@ namespace Discord.Commands
private string[] _aliases;

public IEnumerable<CommandParameter> Parameters => _parameters;
private CommandParameter[] _parameters;
internal CommandParameter[] _parameters;

private Func<CommandEventArgs, Task> _handler;



+ 3
- 3
src/Discord.Net.Commands/CommandBuilder.cs View File

@@ -38,7 +38,7 @@ namespace Discord.Commands
{
if (_isClosed)
throw new Exception($"No parameters may be added after a {nameof(ParameterType.Multiple)} or {nameof(ParameterType.Unparsed)} parameter.");
if (!_allowRequired && type != ParameterType.Required)
if (!_allowRequired && type == ParameterType.Required)
throw new Exception($"{nameof(ParameterType.Required)} parameters may not be added after an optional one");

_params.Add(new CommandParameter(name, type));
@@ -57,7 +57,7 @@ namespace Discord.Commands

public CommandBuilder MinPermissions(int level)
{
_command.MinPerms = level;
_command.MinPermissions = level;
return this;
}

@@ -125,7 +125,7 @@ namespace Discord.Commands
public CommandBuilder CreateCommand(string cmd)
{
var command = new Command(CommandBuilder.AppendPrefix(_prefix, cmd));
command.MinPerms = _defaultMinPermissions;
command.MinPermissions = _defaultMinPermissions;
return new CommandBuilder(_plugin, command, _prefix);
}
}


+ 30
- 23
src/Discord.Net.Commands/CommandParser.cs View File

@@ -2,19 +2,6 @@

namespace Discord.Commands
{
public class CommandPart
{
public string Value { get; }
public int Index { get; }

internal CommandPart(string value, int index)
{
Value = value;
Index = index;
}
}

//TODO: Check support for escaping
internal static class CommandParser
{
private enum CommandParserPart
@@ -69,23 +56,40 @@ namespace Discord.Commands
return command != null;
}

public static bool ParseArgs(string input, int startPos, Command command, out CommandPart[] args)
//TODO: Check support for escaping
public static CommandErrorType? ParseArgs(string input, int startPos, Command command, out string[] args)
{
CommandParserPart currentPart = CommandParserPart.None;
int startPosition = startPos;
int endPosition = startPos;
int inputLength = input.Length;
bool isEscaped = false;
List<CommandPart> argList = new List<CommandPart>();

var expectedArgs = command._parameters;
List<string> argList = new List<string>();
CommandParameter parameter = null;
args = null;

if (input == "")
return false;
return CommandErrorType.InvalidInput;

while (endPosition < inputLength)
{
char currentChar = input[endPosition++];
if (startPosition == endPosition && (parameter == null || parameter.Type != ParameterType.Multiple)) //Is first char of a new arg
{
if (argList.Count == command.MaxArgs)
return CommandErrorType.BadArgCount;

parameter = command._parameters[argList.Count];
if (parameter.Type == ParameterType.Unparsed)
{
argList.Add(input.Substring(startPosition));
break;
}
}

char currentChar = input[endPosition++];
if (isEscaped)
isEscaped = false;
else if (currentChar == '\\')
@@ -113,7 +117,7 @@ namespace Discord.Commands
else
{
currentPart = CommandParserPart.None;
argList.Add(new CommandPart(temp, startPosition));
argList.Add(temp);
startPosition = endPosition;
}
}
@@ -123,28 +127,31 @@ namespace Discord.Commands
{
string temp = input.Substring(startPosition, endPosition - startPosition - 1);
currentPart = CommandParserPart.None;
argList.Add(new CommandPart(temp, startPosition));
argList.Add(temp);
startPosition = endPosition;
}
else if (endPosition >= inputLength)
return false;
return CommandErrorType.InvalidInput;
break;
case CommandParserPart.DoubleQuotedParameter:
if ((!isEscaped && currentChar == '\"'))
{
string temp = input.Substring(startPosition, endPosition - startPosition - 1);
currentPart = CommandParserPart.None;
argList.Add(new CommandPart(temp, startPosition));
argList.Add(temp);
startPosition = endPosition;
}
else if (endPosition >= inputLength)
return false;
return CommandErrorType.InvalidInput;
break;
}
}

if (argList.Count < command.MinArgs)
return CommandErrorType.BadArgCount;

args = argList.ToArray();
return true;
return null;
}
}
}

+ 26
- 25
src/Discord.Net.Commands/CommandsPlugin.cs View File

@@ -18,7 +18,11 @@ namespace Discord.Commands
internal CommandMap Map => _map;
private readonly CommandMap _map;

public char ComamndChar { get { return _commandChars[0]; } set { _commandChars = new char[] { value }; } }
public char? ComamndChar
{
get { return _commandChars.Length > 0 ? _commandChars[0] : (char?)null; }
set { _commandChars = value != null ? new char[] { value.Value } : new char[0]; }
}
public IEnumerable<char> CommandChars { get { return _commandChars; } set { _commandChars = value.ToArray(); } }
private char[] _commandChars;
@@ -54,16 +58,20 @@ namespace Discord.Commands
if (e.Args == null)
{
int permissions = getPermissions(e.User);

StringBuilder output = new StringBuilder();
output.AppendLine("These are the commands you can use:");
output.Append("`");
output.Append(string.Join(", ", _commands.Select(x => permissions >= x.MinPerms && !x.IsHidden)));
output.Append(string.Join(", ", _commands.Select(x => permissions >= x.MinPermissions && !x.IsHidden)));
output.Append("`");

if (_commandChars.Length == 1)
output.AppendLine($"\nYou can use `{_commandChars[0]}` to call a command.");
else
output.AppendLine($"\nYou can use `{string.Join(" ", CommandChars.Take(_commandChars.Length - 1))}` and `{_commandChars.Last()}` to call a command.");
if (_commandChars.Length > 0)
{
if (_commandChars.Length == 1)
output.AppendLine($"\nYou can use `{_commandChars[0]}` to call a command.");
else
output.AppendLine($"\nYou can use `{string.Join(" ", CommandChars.Take(_commandChars.Length - 1))}` and `{_commandChars.Last()}` to call a command.");
}

output.AppendLine("`help <command>` can tell you more about how to use a command.");

@@ -84,17 +92,17 @@ namespace Discord.Commands

client.MessageReceived += async (s, e) =>
{
// This will need to be changed once a built in help command is made
if (_commands.Count == 0) return;
if (e.Message.IsAuthor) return;

string msg = e.Message.Text;
if (msg.Length == 0) return;

//Check for command char if one is provided
if (_commandChars.Length > 0)
{
bool isPrivate = e.Message.Channel.IsPrivate;
bool hasCommandChar = CommandChars.Contains(msg[0]);
bool hasCommandChar = _commandChars.Contains(msg[0]);
if (hasCommandChar)
msg = msg.Substring(1);

@@ -116,34 +124,27 @@ namespace Discord.Commands
}
else
{
int userPermissions = _getPermissions != null ? _getPermissions(e.Message.User) : 0;

//Parse arguments
CommandPart[] args;
if (!CommandParser.ParseArgs(msg, argPos, command, out args))
string[] args;
var error = CommandParser.ParseArgs(msg, argPos, command, out args);
if (error != null)
{
CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null, null);
RaiseCommandError(CommandErrorType.InvalidInput, errorArgs);
var errorArgs = new CommandEventArgs(e.Message, command, userPermissions, null);
RaiseCommandError(error.Value, errorArgs);
return;
}
int argCount = args.Length;

//Get information for the rest of the steps
int userPermissions = _getPermissions != null ? _getPermissions(e.Message.User) : 0;
var eventArgs = new CommandEventArgs(e.Message, command, userPermissions, args.Select(x => x.Value).ToArray());
var eventArgs = new CommandEventArgs(e.Message, command, userPermissions, args);

// Check permissions
if (userPermissions < command.MinPerms)
if (userPermissions < command.MinPermissions)
{
RaiseCommandError(CommandErrorType.BadPermissions, eventArgs);
return;
}

//Check arg count
if (argCount < command.MinArgs)
{
RaiseCommandError(CommandErrorType.BadArgCount, eventArgs);
return;
}

// Run the command
try
{


Loading…
Cancel
Save