Details: There is nothing really to be said, it's simple and self-explanatory. The only thing I would want to implement is to add support for bool? and int? param types because, as of now, you don't know if the user passed False or just didn't pass anything. In any case, I personally don't suspect it's going to be hard to do. After I implement this I will create a PR on the original Discord.Net Repo.pull/1733/head^2^2
@@ -21,7 +21,10 @@ namespace SlashCommandsExample.Modules | |||||
} | } | ||||
[SlashCommand("echo", "I'll repeate everything you said to me, word for word.")] | [SlashCommand("echo", "I'll repeate everything you said to me, word for word.")] | ||||
public async Task EchoAsync([Description("The message you want repetead")]string message) | |||||
public async Task EchoAsync( | |||||
[Description("The message you want repetead")] | |||||
[Required] | |||||
string message) | |||||
{ | { | ||||
await Reply($"{Interaction.Member?.Nickname ?? Interaction.Member?.Username} told me to say this: \r\n{message}"); | await Reply($"{Interaction.Member?.Nickname ?? Interaction.Member?.Username} told me to say this: \r\n{message}"); | ||||
} | } | ||||
@@ -40,6 +43,21 @@ namespace SlashCommandsExample.Modules | |||||
} | } | ||||
[SlashCommand("stats","Get the stats from Game(tm) for players or teams.")] | |||||
public async Task GetStatsAsync( | |||||
[Required] | |||||
[Choice("XBOX","xbox")] | |||||
[Choice("PlayStation","ps")] | |||||
[Choice("PC","pc")] | |||||
string platform, | |||||
[Choice("Player",1)] | |||||
[Choice("Team",2)] | |||||
int searchType | |||||
) | |||||
{ | |||||
await Reply($"Well I got this: {platform}, {searchType}"); | |||||
} | |||||
[CommandGroup("root")] | [CommandGroup("root")] | ||||
//[Global] | //[Global] | ||||
public class DevModule_Root : SlashCommandModule<SocketInteraction> | public class DevModule_Root : SlashCommandModule<SocketInteraction> | ||||
@@ -0,0 +1,41 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace Discord.SlashCommands | |||||
{ | |||||
/// <summary> | |||||
/// Defines the parameter as a choice. | |||||
/// </summary> | |||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true)] | |||||
public class Choice : Attribute | |||||
{ | |||||
/// <summary> | |||||
/// The internal value of this choice. | |||||
/// </summary> | |||||
public string choiceStringValue; | |||||
/// <summary> | |||||
/// The internal value of this choice. | |||||
/// </summary> | |||||
public int? choiceIntValue = null; | |||||
/// <summary> | |||||
/// The display value of this choice. | |||||
/// </summary> | |||||
public string choiceName; | |||||
public Choice(string choiceName, string choiceValue) | |||||
{ | |||||
this.choiceName = choiceName; | |||||
this.choiceStringValue = choiceValue; | |||||
} | |||||
public Choice(string choiceName, int choiceValue) | |||||
{ | |||||
this.choiceName = choiceName; | |||||
this.choiceIntValue = choiceValue; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace Discord.SlashCommands | |||||
{ | |||||
/// <summary> | |||||
/// An Attribute that gives the command parameter a description. | |||||
/// </summary> | |||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] | |||||
public class Required : Attribute | |||||
{ | |||||
} | |||||
} |
@@ -257,7 +257,33 @@ namespace Discord.SlashCommands | |||||
// And get the parameter type | // And get the parameter type | ||||
newParameter.Type = TypeFromMethodParameter(methodParameter); | newParameter.Type = TypeFromMethodParameter(methodParameter); | ||||
// TODO: implement more attributes, such as [Required] | |||||
// [Required] Parameter | |||||
var requiredAttributes = methodParameter.GetCustomAttributes(typeof(Required)); | |||||
if (requiredAttributes.Count() == 1) | |||||
newParameter.Required = true; | |||||
else if (requiredAttributes.Count() > 1) | |||||
throw new Exception($"Too many Required attributes on a single parameter ({method.Name} -> {methodParameter.Name}). It can only contain one!"); | |||||
// [Choice] Parameter | |||||
foreach (Choice choice in methodParameter.GetCustomAttributes(typeof(Choice))) | |||||
{ | |||||
if (newParameter.Type == ApplicationCommandOptionType.String) | |||||
{ | |||||
if(String.IsNullOrEmpty(choice.choiceStringValue)) | |||||
{ | |||||
throw new Exception($"Parameter ({method.Name} -> {methodParameter.Name}) is of type string, but choice is of type int!"); | |||||
} | |||||
newParameter.AddChoice(choice.choiceName, choice.choiceStringValue); | |||||
} | |||||
if (newParameter.Type == ApplicationCommandOptionType.Integer) | |||||
{ | |||||
if (choice.choiceIntValue == null) | |||||
{ | |||||
throw new Exception($"Parameter ({method.Name} -> {methodParameter.Name}) is of type int, but choice is of type string!"); | |||||
} | |||||
newParameter.AddChoice(choice.choiceName, (int)choice.choiceIntValue); | |||||
} | |||||
} | |||||
finalParameters.Add(newParameter); | finalParameters.Add(newParameter); | ||||
} | } | ||||