我的 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?");
}
}
}
我目前正在开发 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?");
}
}
}