diff --git a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs index 582e9e7a7..492cb9566 100644 --- a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs +++ b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs @@ -113,7 +113,15 @@ namespace Discord /// A task that represents the asynchronous modification operation. /// Task ModifyAsync(Action func, RequestOptions options = null); - + /// + /// Adds the specified role to this user in the guild. + /// + /// The role to be added to the user. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous role addition operation. + /// + Task AddRoleAsync(ulong roleId, RequestOptions options = null); /// /// Adds the specified role to this user in the guild. /// @@ -124,6 +132,15 @@ namespace Discord /// Task AddRoleAsync(IRole role, RequestOptions options = null); /// + /// Adds the specified to this user in the guild. + /// + /// The roles to be added to the user. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous role addition operation. + /// + Task AddRolesAsync(IEnumerable roleIds, RequestOptions options = null); + /// /// Adds the specified to this user in the guild. /// /// The roles to be added to the user. @@ -133,6 +150,15 @@ namespace Discord /// Task AddRolesAsync(IEnumerable roles, RequestOptions options = null); /// + /// Removes the specified from this user in the guild. + /// + /// The role to be removed from the user. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous role removal operation. + /// + Task RemoveRoleAsync(ulong roleId, RequestOptions options = null); + /// /// Removes the specified from this user in the guild. /// /// The role to be removed from the user. @@ -142,6 +168,15 @@ namespace Discord /// Task RemoveRoleAsync(IRole role, RequestOptions options = null); /// + /// Removes the specified from this user in the guild. + /// + /// The roles to be removed from the user. + /// The options to be used when sending the request. + /// + /// A task that represents the asynchronous role removal operation. + /// + Task RemoveRolesAsync(IEnumerable roleIds, RequestOptions options = null); + /// /// Removes the specified from this user in the guild. /// /// The roles to be removed from the user. diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs index 8910e999a..b60c02cab 100644 --- a/src/Discord.Net.Rest/ClientHelper.cs +++ b/src/Discord.Net.Rest/ClientHelper.cs @@ -17,7 +17,7 @@ namespace Discord.Rest return RestApplication.Create(client, model); } - public static async Task GetChannelAsync(BaseDiscordClient client, + public static async Task GetChannelAsync(BaseDiscordClient client, ulong id, RequestOptions options) { var model = await client.ApiClient.GetChannelAsync(id, options).ConfigureAwait(false); @@ -45,13 +45,13 @@ namespace Discord.Rest .Where(x => x.Type == ChannelType.Group) .Select(x => RestGroupChannel.Create(client, x)).ToImmutableArray(); } - + public static async Task> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options) { var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false); return models.Select(RestConnection.Create).ToImmutableArray(); } - + public static async Task GetInviteAsync(BaseDiscordClient client, string inviteId, RequestOptions options) { @@ -60,7 +60,7 @@ namespace Discord.Rest return RestInviteMetadata.Create(client, null, null, model); return null; } - + public static async Task GetGuildAsync(BaseDiscordClient client, ulong id, bool withCounts, RequestOptions options) { @@ -85,7 +85,7 @@ namespace Discord.Rest return RestGuildWidget.Create(model); return null; } - public static IAsyncEnumerable> GetGuildSummariesAsync(BaseDiscordClient client, + public static IAsyncEnumerable> GetGuildSummariesAsync(BaseDiscordClient client, ulong? fromGuildId, int? limit, RequestOptions options) { return new PagedAsyncEnumerable( @@ -136,7 +136,7 @@ namespace Discord.Rest var model = await client.ApiClient.CreateGuildAsync(args, options).ConfigureAwait(false); return RestGuild.Create(client, model); } - + public static async Task GetUserAsync(BaseDiscordClient client, ulong id, RequestOptions options) { @@ -201,5 +201,9 @@ namespace Discord.Rest } }; } + public static Task AddRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) + => client.ApiClient.AddRoleAsync(guildId, userId, roleId, options); + public static Task RemoveRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) + => client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options); } } diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index cdf312c3d..7eff7363c 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -107,6 +107,10 @@ namespace Discord.Rest => ClientHelper.GetVoiceRegionAsync(this, id, options); public Task GetWebhookAsync(ulong id, RequestOptions options = null) => ClientHelper.GetWebhookAsync(this, id, options); + public Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId) + => ClientHelper.AddRoleAsync(this, guildId, userId, roleId); + public Task RemoveRoleAsync(ulong guildId, ulong userId, ulong roleId) + => ClientHelper.RemoveRoleAsync(this, guildId, userId, roleId); public Task AddReactionAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null) => MessageHelper.AddReactionAsync(channelId, messageId, emote, this, options); diff --git a/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs b/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs index 4a6bc1025..6e6bbe09c 100644 --- a/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs +++ b/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs @@ -112,17 +112,29 @@ namespace Discord.Rest public Task KickAsync(string reason = null, RequestOptions options = null) => UserHelper.KickAsync(this, Discord, reason, options); /// + public Task AddRoleAsync(ulong roleId, RequestOptions options = null) + => AddRolesAsync(new[] { roleId }, options); + /// public Task AddRoleAsync(IRole role, RequestOptions options = null) - => AddRolesAsync(new[] { role }, options); + => AddRoleAsync(role.Id, options); + /// + public Task AddRolesAsync(IEnumerable roleIds, RequestOptions options = null) + => UserHelper.AddRolesAsync(this, Discord, roleIds, options); /// public Task AddRolesAsync(IEnumerable roles, RequestOptions options = null) - => UserHelper.AddRolesAsync(this, Discord, roles, options); + => AddRolesAsync(roles.Select(x => x.Id), options); + /// + public Task RemoveRoleAsync(ulong roleId, RequestOptions options = null) + => RemoveRolesAsync(new[] { roleId }, options); /// public Task RemoveRoleAsync(IRole role, RequestOptions options = null) - => RemoveRolesAsync(new[] { role }, options); + => RemoveRoleAsync(role.Id, options); + /// + public Task RemoveRolesAsync(IEnumerable roleIds, RequestOptions options = null) + => UserHelper.RemoveRolesAsync(this, Discord, roleIds, options); /// public Task RemoveRolesAsync(IEnumerable roles, RequestOptions options = null) - => UserHelper.RemoveRolesAsync(this, Discord, roles, options); + => RemoveRolesAsync(roles.Select(x => x.Id)); /// /// Resolving permissions requires the parent guild to be downloaded. diff --git a/src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs b/src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs index a06916c9b..2131fec93 100644 --- a/src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs +++ b/src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs @@ -59,27 +59,35 @@ namespace Discord.Rest /// ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) => Permissions.ToChannelPerms(channel, GuildPermissions.Webhook.RawValue); /// - Task IGuildUser.KickAsync(string reason, RequestOptions options) => + Task IGuildUser.KickAsync(string reason, RequestOptions options) => throw new NotSupportedException("Webhook users cannot be kicked."); /// - Task IGuildUser.ModifyAsync(Action func, RequestOptions options) => + Task IGuildUser.ModifyAsync(Action func, RequestOptions options) => throw new NotSupportedException("Webhook users cannot be modified."); - /// - Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) => + Task IGuildUser.AddRoleAsync(ulong role, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); - /// - Task IGuildUser.AddRolesAsync(IEnumerable roles, RequestOptions options) => + Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); - /// - Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) => + Task IGuildUser.AddRolesAsync(IEnumerable roles, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + /// + Task IGuildUser.AddRolesAsync(IEnumerable roles, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + /// + Task IGuildUser.RemoveRoleAsync(ulong role, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + /// + Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + /// + Task IGuildUser.RemoveRolesAsync(IEnumerable roles, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); - /// - Task IGuildUser.RemoveRolesAsync(IEnumerable roles, RequestOptions options) => + Task IGuildUser.RemoveRolesAsync(IEnumerable roles, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); //IVoiceState diff --git a/src/Discord.Net.Rest/Entities/Users/UserHelper.cs b/src/Discord.Net.Rest/Entities/Users/UserHelper.cs index 58e8cd417..3a19fcfc1 100644 --- a/src/Discord.Net.Rest/Entities/Users/UserHelper.cs +++ b/src/Discord.Net.Rest/Entities/Users/UserHelper.cs @@ -73,16 +73,16 @@ namespace Discord.Rest return RestDMChannel.Create(client, await client.ApiClient.CreateDMChannelAsync(args, options).ConfigureAwait(false)); } - public static async Task AddRolesAsync(IGuildUser user, BaseDiscordClient client, IEnumerable roles, RequestOptions options) + public static async Task AddRolesAsync(IGuildUser user, BaseDiscordClient client, IEnumerable roleIds, RequestOptions options) { - foreach (var role in roles) - await client.ApiClient.AddRoleAsync(user.Guild.Id, user.Id, role.Id, options).ConfigureAwait(false); + foreach (var roleId in roleIds) + await client.ApiClient.AddRoleAsync(user.Guild.Id, user.Id, roleId, options).ConfigureAwait(false); } - public static async Task RemoveRolesAsync(IGuildUser user, BaseDiscordClient client, IEnumerable roles, RequestOptions options) + public static async Task RemoveRolesAsync(IGuildUser user, BaseDiscordClient client, IEnumerable roleIds, RequestOptions options) { - foreach (var role in roles) - await client.ApiClient.RemoveRoleAsync(user.Guild.Id, user.Id, role.Id, options).ConfigureAwait(false); + foreach (var roleId in roleIds) + await client.ApiClient.RemoveRoleAsync(user.Guild.Id, user.Id, roleId, options).ConfigureAwait(false); } } } diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs index c0a681d9d..9263fe642 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs @@ -63,7 +63,7 @@ namespace Discord.WebSocket /// /// Returns a collection of roles that the user possesses. /// - public IReadOnlyCollection Roles + public IReadOnlyCollection Roles => _roleIds.Select(id => Guild.GetRole(id)).Where(x => x != null).ToReadOnlyCollection(() => _roleIds.Length); /// /// Returns the voice channel the user is in, or null if none. @@ -177,17 +177,29 @@ namespace Discord.WebSocket public Task KickAsync(string reason = null, RequestOptions options = null) => UserHelper.KickAsync(this, Discord, reason, options); /// + public Task AddRoleAsync(ulong roleId, RequestOptions options = null) + => AddRolesAsync(new[] { roleId }, options); + /// public Task AddRoleAsync(IRole role, RequestOptions options = null) - => AddRolesAsync(new[] { role }, options); + => AddRoleAsync(role.Id, options); + /// + public Task AddRolesAsync(IEnumerable roleIds, RequestOptions options = null) + => UserHelper.AddRolesAsync(this, Discord, roleIds, options); /// public Task AddRolesAsync(IEnumerable roles, RequestOptions options = null) - => UserHelper.AddRolesAsync(this, Discord, roles, options); + => AddRolesAsync(roles.Select(x => x.Id), options); + /// + public Task RemoveRoleAsync(ulong roleId, RequestOptions options = null) + => RemoveRolesAsync(new[] { roleId }, options); /// public Task RemoveRoleAsync(IRole role, RequestOptions options = null) - => RemoveRolesAsync(new[] { role }, options); + => RemoveRoleAsync(role.Id, options); + /// + public Task RemoveRolesAsync(IEnumerable roleIds, RequestOptions options = null) + => UserHelper.RemoveRolesAsync(this, Discord, roleIds, options); /// public Task RemoveRolesAsync(IEnumerable roles, RequestOptions options = null) - => UserHelper.RemoveRolesAsync(this, Discord, roles, options); + => RemoveRolesAsync(roles.Select(x => x.Id)); /// public ChannelPermissions GetPermissions(IGuildChannel channel) diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs index 5103aa8b3..c22164f95 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs @@ -31,7 +31,7 @@ namespace Discord.WebSocket public override bool IsWebhook => true; /// internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null, null); } set { } } - internal override SocketGlobalUser GlobalUser => + internal override SocketGlobalUser GlobalUser => throw new NotSupportedException(); internal SocketWebhookUser(SocketGuild guild, ulong id, ulong webhookId) @@ -73,32 +73,52 @@ namespace Discord.WebSocket ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) => Permissions.ToChannelPerms(channel, GuildPermissions.Webhook.RawValue); /// /// Webhook users cannot be kicked. - Task IGuildUser.KickAsync(string reason, RequestOptions options) => + Task IGuildUser.KickAsync(string reason, RequestOptions options) => throw new NotSupportedException("Webhook users cannot be kicked."); /// /// Webhook users cannot be modified. - Task IGuildUser.ModifyAsync(Action func, RequestOptions options) => + Task IGuildUser.ModifyAsync(Action func, RequestOptions options) => throw new NotSupportedException("Webhook users cannot be modified."); /// /// Roles are not supported on webhook users. - Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) => + Task IGuildUser.AddRoleAsync(ulong roleId, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); /// /// Roles are not supported on webhook users. - Task IGuildUser.AddRolesAsync(IEnumerable roles, RequestOptions options) => + Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); /// /// Roles are not supported on webhook users. - Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) => + Task IGuildUser.AddRolesAsync(IEnumerable roleIds, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); /// /// Roles are not supported on webhook users. - Task IGuildUser.RemoveRolesAsync(IEnumerable roles, RequestOptions options) => + Task IGuildUser.AddRolesAsync(IEnumerable roles, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + + /// + /// Roles are not supported on webhook users. + Task IGuildUser.RemoveRoleAsync(ulong roleId, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + + /// + /// Roles are not supported on webhook users. + Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + + /// + /// Roles are not supported on webhook users. + Task IGuildUser.RemoveRolesAsync(IEnumerable roles, RequestOptions options) => + throw new NotSupportedException("Roles are not supported on webhook users."); + + /// + /// Roles are not supported on webhook users. + Task IGuildUser.RemoveRolesAsync(IEnumerable roles, RequestOptions options) => throw new NotSupportedException("Roles are not supported on webhook users."); //IVoiceState