我的 Discord Bot 不接受用户作为命令的参数

My Discord Bot won't accept Users as parameters for commands

我目前正在开发 Discord 机器人,以学习如何编写代码。我以为我把它弄下来了,但是当我尝试使用以下命令时,它什么也没做:

[Command("ping")]
public async Task Ping(IUser user)
{
  await Context.Channel.SendMessageAsync(user.ToString());
}

它是 public class 的一部分,如果我使用任何其他参数类型(例如 IChannel、bool、int),它就可以工作。只有这一个参数类型。它也不记录任何错误或异常。有什么想法吗?

您可以尝试对您的机器人使用此解决方法:

public async Task SampleCommand(string user="", [Remainder]string message="")
{
    IUser subject = null;
    if (user != "")
    {
        var guilds = (await Context.Client.GetGuildsAsync(Discord.CacheMode.AllowDownload));
        var users = new List<IUser>();
        foreach (var g in guilds)
            users.AddRange(await g.GetUsersAsync(CacheMode.AllowDownload));
        users = users.GroupBy(o => o.Id).Select(o => o.First()).ToList();
        var search = users.Where(o => o.Username.ToLower().Contains(user.ToLower()) || Context.Message.MentionedUserIds.Contains(o.Id) || o.ToString().ToLower().Contains(user.ToLower())).ToArray();
        if (search.Length == 0)
        {
            await ReplyAsync("***Error!*** *Couldn't find that user.*");
            return;
        }
        else if (search.Length > 1)
        {
            await ReplyAsync("***Error!*** *Found more than one matching users.*");
            return;
        }
        subject = search.First();
    }
    // ...
    // execute command

或者您可以将其包装在一个方法中,以便于访问和重用。

基本上,它的作用是查找与给定字符串匹配的可用用户(昵称、用户名或提及。如果需要,您也可以让它检查 ID)。

编辑:在我的例子中,我允许人们提及与机器人共享服务器的任何人,但在你的例子中,只使用 Context.Guild 并取消命令可能更有益直接消息案例。

[Command("ping")]
public async Task Ping(IUser user)
{
  await Context.Channel.SendMessageAsync(user.ToString());
}

您的代码 ID 完美。但是想一想,用户属于 IUser 类型,而您对 sting 的转换使它变得模糊。试试这个:

[Command("ping")]
public async Task Ping(SocketGuildUser user)
{
   await Context.Channel.SendMessageAsync(user.Username);
}

如果您想对用户执行 ping 操作,请尝试 user.Mention

另外,当我开始学习时,我也制作了一个机器人。 Here 是源代码。它非常非常非常基本。一定会有帮助。

我最终采纳了 Reynevan 的建议,并编写了一个将提及项转换为 IUser 的方法。只需调用 CustomUserTypereader.GetUser(mention_parameter, Context.Guild);

using System.Threading.Tasks;
using Discord;

public class CustomUserTypereader
{
    public static async Task<IUser> GetUserFromString(string s, IGuild server)
    {
        if (s.IndexOf('@') == -1 || s.Replace("<", "").Replace(">", "").Length != s.Length - 2)
            throw new System.Exception("Not a valid user mention.");

        string idStr = s.Replace("<", "").Replace(">", "").Replace("@", "");

        try
        {
            ulong id = ulong.Parse(idStr);
            return await server.GetUserAsync(id);
        }
        catch
        {
            throw new System.Exception("Could not parse User ID. Are you sure the user is still on the server?");
        }
    }
}