@@ -7,6 +7,7 @@ namespace Discord.Commands | |||||
{ | { | ||||
public string Text { get; } | public string Text { get; } | ||||
public RunMode RunMode { get; set; } = RunMode.Default; | public RunMode RunMode { get; set; } = RunMode.Default; | ||||
public PreconditionsMode PreconditionsMode { get; set; } = PreconditionsMode.Default; | |||||
public CommandAttribute() | public CommandAttribute() | ||||
{ | { | ||||
@@ -20,6 +20,7 @@ namespace Discord.Commands.Builders | |||||
public string Remarks { get; set; } | public string Remarks { get; set; } | ||||
public string PrimaryAlias { get; set; } | public string PrimaryAlias { get; set; } | ||||
public RunMode RunMode { get; set; } | public RunMode RunMode { get; set; } | ||||
public PreconditionsMode PreconditionsMode { get; set; } | |||||
public int Priority { get; set; } | public int Priority { get; set; } | ||||
public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | ||||
@@ -67,6 +68,11 @@ namespace Discord.Commands.Builders | |||||
RunMode = runMode; | RunMode = runMode; | ||||
return this; | return this; | ||||
} | } | ||||
public CommandBuilder WithPreconditionsMode(PreconditionsMode preconditionsMode) | |||||
{ | |||||
PreconditionsMode = preconditionsMode; | |||||
return this; | |||||
} | |||||
public CommandBuilder WithPriority(int priority) | public CommandBuilder WithPriority(int priority) | ||||
{ | { | ||||
Priority = priority; | Priority = priority; | ||||
@@ -128,26 +128,33 @@ namespace Discord.Commands | |||||
foreach (var attribute in attributes) | foreach (var attribute in attributes) | ||||
{ | { | ||||
// TODO: C#7 type switch | |||||
if (attribute is CommandAttribute) | |||||
switch (attribute) | |||||
{ | { | ||||
var cmdAttr = attribute as CommandAttribute; | |||||
builder.AddAliases(cmdAttr.Text); | |||||
builder.RunMode = cmdAttr.RunMode; | |||||
builder.Name = builder.Name ?? cmdAttr.Text; | |||||
case CommandAttribute cmdAttr: | |||||
builder.AddAliases(cmdAttr.Text); | |||||
builder.RunMode = cmdAttr.RunMode; | |||||
builder.PreconditionsMode = cmdAttr.PreconditionsMode; | |||||
builder.Name = builder.Name ?? cmdAttr.Text; | |||||
break; | |||||
case NameAttribute nameAttr: | |||||
builder.Name = nameAttr.Text; | |||||
break; | |||||
case PriorityAttribute priorityAttr: | |||||
builder.Priority = priorityAttr.Priority; | |||||
break; | |||||
case SummaryAttribute summaryAttr: | |||||
builder.Summary = summaryAttr.Text; | |||||
break; | |||||
case RemarksAttribute remarksAttr: | |||||
builder.Remarks = remarksAttr.Text; | |||||
break; | |||||
case AliasAttribute aliasAttr: | |||||
builder.AddAliases(aliasAttr.Aliases); | |||||
break; | |||||
case PreconditionAttribute preconditionAttr: | |||||
builder.AddPrecondition(preconditionAttr); | |||||
break; | |||||
} | } | ||||
else if (attribute is NameAttribute) | |||||
builder.Name = (attribute as NameAttribute).Text; | |||||
else if (attribute is PriorityAttribute) | |||||
builder.Priority = (attribute as PriorityAttribute).Priority; | |||||
else if (attribute is SummaryAttribute) | |||||
builder.Summary = (attribute as SummaryAttribute).Text; | |||||
else if (attribute is RemarksAttribute) | |||||
builder.Remarks = (attribute as RemarksAttribute).Text; | |||||
else if (attribute is AliasAttribute) | |||||
builder.AddAliases((attribute as AliasAttribute).Aliases); | |||||
else if (attribute is PreconditionAttribute) | |||||
builder.AddPrecondition(attribute as PreconditionAttribute); | |||||
} | } | ||||
if (builder.Name == null) | if (builder.Name == null) | ||||
@@ -195,24 +202,27 @@ namespace Discord.Commands | |||||
foreach (var attribute in attributes) | foreach (var attribute in attributes) | ||||
{ | { | ||||
// TODO: C#7 type switch | |||||
if (attribute is SummaryAttribute) | |||||
builder.Summary = (attribute as SummaryAttribute).Text; | |||||
else if (attribute is OverrideTypeReaderAttribute) | |||||
builder.TypeReader = GetTypeReader(service, paramType, (attribute as OverrideTypeReaderAttribute).TypeReader); | |||||
else if (attribute is ParameterPreconditionAttribute) | |||||
builder.AddPrecondition(attribute as ParameterPreconditionAttribute); | |||||
else if (attribute is ParamArrayAttribute) | |||||
{ | |||||
builder.IsMultiple = true; | |||||
paramType = paramType.GetElementType(); | |||||
} | |||||
else if (attribute is RemainderAttribute) | |||||
switch (attribute) | |||||
{ | { | ||||
if (position != count-1) | |||||
throw new InvalidOperationException("Remainder parameters must be the last parameter in a command."); | |||||
builder.IsRemainder = true; | |||||
case SummaryAttribute summaryAttr: | |||||
builder.Summary = summaryAttr.Text; | |||||
break; | |||||
case OverrideTypeReaderAttribute overrideTypeReaderAttr: | |||||
builder.TypeReader = GetTypeReader(service, paramType, | |||||
overrideTypeReaderAttr.TypeReader); | |||||
break; | |||||
case ParameterPreconditionAttribute parameterPreconditionAttr: | |||||
builder.AddPrecondition(parameterPreconditionAttr); | |||||
break; | |||||
case ParamArrayAttribute paramArrayAttr: | |||||
builder.IsMultiple = true; | |||||
paramType = paramType.GetElementType(); | |||||
break; | |||||
case RemainderAttribute remainderAttr: | |||||
if (position != count - 1) | |||||
throw new InvalidOperationException("Remainder parameters must be the last parameter in a command."); | |||||
builder.IsRemainder = true; | |||||
break; | |||||
} | } | ||||
} | } | ||||
@@ -28,6 +28,7 @@ namespace Discord.Commands | |||||
internal readonly bool _caseSensitive, _throwOnError; | internal readonly bool _caseSensitive, _throwOnError; | ||||
internal readonly char _separatorChar; | internal readonly char _separatorChar; | ||||
internal readonly RunMode _defaultRunMode; | internal readonly RunMode _defaultRunMode; | ||||
internal readonly PreconditionsMode _defaultPreconditionsMode; | |||||
internal readonly Logger _cmdLogger; | internal readonly Logger _cmdLogger; | ||||
internal readonly LogManager _logManager; | internal readonly LogManager _logManager; | ||||
@@ -44,6 +45,9 @@ namespace Discord.Commands | |||||
_defaultRunMode = config.DefaultRunMode; | _defaultRunMode = config.DefaultRunMode; | ||||
if (_defaultRunMode == RunMode.Default) | if (_defaultRunMode == RunMode.Default) | ||||
throw new InvalidOperationException("The default run mode cannot be set to Default."); | throw new InvalidOperationException("The default run mode cannot be set to Default."); | ||||
_defaultPreconditionsMode = config.DefaultPreconditionsMode; | |||||
if (_defaultPreconditionsMode == PreconditionsMode.Default) | |||||
throw new InvalidOperationException("The default preconditions mode cannot be set to Default."); | |||||
_logManager = new LogManager(config.LogLevel); | _logManager = new LogManager(config.LogLevel); | ||||
_logManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false); | _logManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false); | ||||
@@ -5,6 +5,9 @@ | |||||
/// <summary> The default RunMode commands should have, if one is not specified on the Command attribute or builder. </summary> | /// <summary> The default RunMode commands should have, if one is not specified on the Command attribute or builder. </summary> | ||||
public RunMode DefaultRunMode { get; set; } = RunMode.Sync; | public RunMode DefaultRunMode { get; set; } = RunMode.Sync; | ||||
/// <summary> The default PreconditionsMode commands should have, if one is not specified on the Command attribute or builder. </summary> | |||||
public PreconditionsMode DefaultPreconditionsMode { get; set; } = PreconditionsMode.RequireAll; | |||||
public char SeparatorChar { get; set; } = ' '; | public char SeparatorChar { get; set; } = ' '; | ||||
/// <summary> Should commands be case-sensitive? </summary> | /// <summary> Should commands be case-sensitive? </summary> | ||||
public bool CaseSensitiveCommands { get; set; } = false; | public bool CaseSensitiveCommands { get; set; } = false; | ||||
@@ -27,6 +27,7 @@ namespace Discord.Commands | |||||
public int Priority { get; } | public int Priority { get; } | ||||
public bool HasVarArgs { get; } | public bool HasVarArgs { get; } | ||||
public RunMode RunMode { get; } | public RunMode RunMode { get; } | ||||
public PreconditionsMode PreconditionsMode { get; } | |||||
public IReadOnlyList<string> Aliases { get; } | public IReadOnlyList<string> Aliases { get; } | ||||
public IReadOnlyList<ParameterInfo> Parameters { get; } | public IReadOnlyList<ParameterInfo> Parameters { get; } | ||||
@@ -41,6 +42,7 @@ namespace Discord.Commands | |||||
Remarks = builder.Remarks; | Remarks = builder.Remarks; | ||||
RunMode = (builder.RunMode == RunMode.Default ? service._defaultRunMode : builder.RunMode); | RunMode = (builder.RunMode == RunMode.Default ? service._defaultRunMode : builder.RunMode); | ||||
PreconditionsMode = (builder.PreconditionsMode == PreconditionsMode.Default ? service._defaultPreconditionsMode : builder.PreconditionsMode); | |||||
Priority = builder.Priority; | Priority = builder.Priority; | ||||
Aliases = module.Aliases | Aliases = module.Aliases | ||||
@@ -75,11 +77,23 @@ namespace Discord.Commands | |||||
return result; | return result; | ||||
} | } | ||||
foreach (PreconditionAttribute precondition in Preconditions) | |||||
if (PreconditionsMode == PreconditionsMode.RequireAll) | |||||
{ | { | ||||
var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); | |||||
if (!result.IsSuccess) | |||||
return result; | |||||
foreach (PreconditionAttribute precondition in Preconditions) | |||||
{ | |||||
var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); | |||||
if (!result.IsSuccess) | |||||
return result; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
foreach (PreconditionAttribute precondition in Preconditions) | |||||
{ | |||||
var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); | |||||
if (result.IsSuccess) | |||||
return result; | |||||
} | |||||
} | } | ||||
return PreconditionResult.FromSuccess(); | return PreconditionResult.FromSuccess(); | ||||
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Commands | |||||
{ | |||||
public enum PreconditionsMode | |||||
{ | |||||
Default, | |||||
RequireAny, | |||||
RequireAll | |||||
} | |||||
} |