diff --git a/src/Discord.Net.Core/API/Image.cs b/src/Discord.Net.Core/API/Image.cs index 44c58f344..a500ebfd5 100644 --- a/src/Discord.Net.Core/API/Image.cs +++ b/src/Discord.Net.Core/API/Image.cs @@ -18,9 +18,16 @@ namespace Discord.API Hash = hash; } - public static Image Create(Discord.Image image) + internal static Image Create(Discord.Image image) { return new Image(image.Stream); } + internal static Image? Create(Discord.Image? image) + { + if (image.HasValue) + return new Image(image.Value.Stream); + else + return null; + } } } diff --git a/src/Discord.Net.Core/API/Rest/ModifyCurrentUserParams.cs b/src/Discord.Net.Core/API/Rest/ModifyCurrentUserParams.cs index d11ef2b77..3f7afe187 100644 --- a/src/Discord.Net.Core/API/Rest/ModifyCurrentUserParams.cs +++ b/src/Discord.Net.Core/API/Rest/ModifyCurrentUserParams.cs @@ -9,6 +9,6 @@ namespace Discord.API.Rest [JsonProperty("username")] public Optional Username { get; set; } [JsonProperty("avatar")] - public Optional Avatar { get; set; } + public Optional Avatar { get; set; } } } diff --git a/src/Discord.Net.Core/Entities/Channels/ModifyGuildChannelsParams.cs b/src/Discord.Net.Core/Entities/Channels/ModifyGuildChannelsParams.cs index e46e172b9..14b77457f 100644 --- a/src/Discord.Net.Core/Entities/Channels/ModifyGuildChannelsParams.cs +++ b/src/Discord.Net.Core/Entities/Channels/ModifyGuildChannelsParams.cs @@ -2,7 +2,13 @@ { public class ModifyGuildChannelsParams { + /// + /// The id of the channel to apply this position to. + /// public ulong Id { get; set; } + /// + /// The new zero-based position of this channel. + /// public int Position { get; set; } public ModifyGuildChannelsParams(ulong id, int position) diff --git a/src/Discord.Net.Core/Entities/Guilds/ModifyGuildEmbedParams.cs b/src/Discord.Net.Core/Entities/Guilds/ModifyGuildEmbedParams.cs index 11b72774c..f5d212e17 100644 --- a/src/Discord.Net.Core/Entities/Guilds/ModifyGuildEmbedParams.cs +++ b/src/Discord.Net.Core/Entities/Guilds/ModifyGuildEmbedParams.cs @@ -12,6 +12,10 @@ /// /// What channel should the invite place users in, if not null. /// + public Optional Channel { get; set; } + /// + /// What channel should the invite place users in, if not null. + /// public Optional ChannelId { get; set; } } } diff --git a/src/Discord.Net.Core/Entities/Guilds/ModifyGuildParams.cs b/src/Discord.Net.Core/Entities/Guilds/ModifyGuildParams.cs index 08deff727..ec7866b8a 100644 --- a/src/Discord.Net.Core/Entities/Guilds/ModifyGuildParams.cs +++ b/src/Discord.Net.Core/Entities/Guilds/ModifyGuildParams.cs @@ -21,6 +21,10 @@ /// public Optional Name { get; set; } /// + /// The region for the Guild's voice connections + /// + public Optional Region { get; set; } + /// /// The ID of the region for the Guild's voice connections /// public Optional RegionId { get; set; } @@ -48,10 +52,18 @@ /// public Optional Splash { get; set; } /// + /// The IVoiceChannel where AFK users should be sent. + /// + public Optional AfkChannel { get; set; } + /// /// The ID of the IVoiceChannel where AFK users should be sent. /// public Optional AfkChannelId { get; set; } /// + /// The owner of this guild. + /// + public Optional Owner { get; set; } + /// /// The ID of the owner of this guild. /// public Optional OwnerId { get; set; } diff --git a/src/Discord.Net.Core/Entities/Image.cs b/src/Discord.Net.Core/Entities/Image.cs index 538d82730..e92342e7a 100644 --- a/src/Discord.Net.Core/Entities/Image.cs +++ b/src/Discord.Net.Core/Entities/Image.cs @@ -17,6 +17,7 @@ namespace Discord { Stream = stream; } +#if NETSTANDARD1_3 /// /// Create the image from a file path. /// @@ -28,5 +29,6 @@ namespace Discord { Stream = File.OpenRead(path); } +#endif } } diff --git a/src/Discord.Net.Core/Entities/Roles/ModifyGuildRolesParams.cs b/src/Discord.Net.Core/Entities/Roles/ModifyGuildRolesParams.cs index 4d6a0f63b..5140f4dae 100644 --- a/src/Discord.Net.Core/Entities/Roles/ModifyGuildRolesParams.cs +++ b/src/Discord.Net.Core/Entities/Roles/ModifyGuildRolesParams.cs @@ -2,6 +2,9 @@ { public class ModifyGuildRolesParams : ModifyGuildRoleParams { + /// + /// The id of the role to be edited + /// public ulong Id { get; } public ModifyGuildRolesParams(ulong id) diff --git a/src/Discord.Net.Core/Entities/Users/ModifyGuildMemberParams.cs b/src/Discord.Net.Core/Entities/Users/ModifyGuildMemberParams.cs index 57909cd03..50f535a4c 100644 --- a/src/Discord.Net.Core/Entities/Users/ModifyGuildMemberParams.cs +++ b/src/Discord.Net.Core/Entities/Users/ModifyGuildMemberParams.cs @@ -1,4 +1,6 @@ -namespace Discord +using System.Collections.Generic; + +namespace Discord { /// /// Modify an IGuildUser with the following parameters. @@ -42,7 +44,15 @@ /// To add a role to a user: /// To remove a role from a user: /// - public Optional Roles { get; set; } + public Optional> Roles { get; set; } + /// + /// What roles should the user have? + /// + /// + /// To add a role to a user: + /// To remove a role from a user: + /// + public Optional> RoleIds { get; set; } /// /// Move a user to a voice channel. /// diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs index 428541509..5c6f1cb0e 100644 --- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -27,16 +27,31 @@ namespace Discord.Rest AfkChannelId = args.AfkChannelId, AfkTimeout = args.AfkTimeout, DefaultMessageNotifications = args.DefaultMessageNotifications, + Icon = args.Icon.IsSpecified ? ImageModel.Create(args.Icon.Value) : Optional.Create(), Name = args.Name, - OwnerId = args.OwnerId, - RegionId = args.RegionId, + Splash = args.Splash.IsSpecified ? ImageModel.Create(args.Splash.Value) : Optional.Create(), Username = args.Username, VerificationLevel = args.VerificationLevel }; - if (apiArgs.Splash.IsSpecified && guild.SplashId != null) + if (args.AfkChannel.IsSpecified) + apiArgs.AfkChannelId = args.AfkChannel.Value.Id; + else if (args.AfkChannelId.IsSpecified) + apiArgs.AfkChannelId = args.AfkChannelId.Value; + + if (args.Owner.IsSpecified) + apiArgs.OwnerId = args.Owner.Value.Id; + else if (args.OwnerId.IsSpecified) + apiArgs.OwnerId = args.OwnerId.Value; + + if (args.Region.IsSpecified) + apiArgs.RegionId = args.Region.Value.Id; + else if (args.RegionId.IsSpecified) + apiArgs.RegionId = args.RegionId.Value; + + if (!apiArgs.Splash.IsSpecified && guild.SplashId != null) apiArgs.Splash = new ImageModel(guild.SplashId); - if (apiArgs.Icon.IsSpecified && guild.IconId != null) + if (!apiArgs.Icon.IsSpecified && guild.IconId != null) apiArgs.Icon = new ImageModel(guild.IconId); return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false); @@ -50,9 +65,14 @@ namespace Discord.Rest func(args); var apiArgs = new API.Rest.ModifyGuildEmbedParams { - ChannelId = args.ChannelId, Enabled = args.Enabled }; + + if (args.Channel.IsSpecified) + apiArgs.ChannelId = args.Channel.Value?.Id; + else if (args.ChannelId.IsSpecified) + apiArgs.ChannelId = args.ChannelId.Value; + return await client.ApiClient.ModifyGuildEmbedAsync(guild.Id, apiArgs, options).ConfigureAwait(false); } public static async Task ModifyChannelsAsync(IGuild guild, BaseDiscordClient client, @@ -74,32 +94,32 @@ namespace Discord.Rest }); return await client.ApiClient.ModifyGuildRolesAsync(guild.Id, apiArgs, options).ConfigureAwait(false); } - public static async Task LeaveAsync(IGuild guild, BaseDiscordClient client, + public static async Task LeaveAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { await client.ApiClient.LeaveGuildAsync(guild.Id, options).ConfigureAwait(false); } - public static async Task DeleteAsync(IGuild guild, BaseDiscordClient client, + public static async Task DeleteAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false); } //Bans - public static async Task> GetBansAsync(IGuild guild, BaseDiscordClient client, + public static async Task> GetBansAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { var models = await client.ApiClient.GetGuildBansAsync(guild.Id, options).ConfigureAwait(false); return models.Select(x => RestBan.Create(client, x)).ToImmutableArray(); } - - public static async Task AddBanAsync(IGuild guild, BaseDiscordClient client, + + public static async Task AddBanAsync(IGuild guild, BaseDiscordClient client, ulong userId, int pruneDays, RequestOptions options) { var args = new CreateGuildBanParams { DeleteMessageDays = pruneDays }; await client.ApiClient.CreateGuildBanAsync(guild.Id, userId, args, options).ConfigureAwait(false); - } - public static async Task RemoveBanAsync(IGuild guild, BaseDiscordClient client, + } + public static async Task RemoveBanAsync(IGuild guild, BaseDiscordClient client, ulong userId, RequestOptions options) { await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false); @@ -114,7 +134,7 @@ namespace Discord.Rest return RestGuildChannel.Create(client, guild, model); return null; } - public static async Task> GetChannelsAsync(IGuild guild, BaseDiscordClient client, + public static async Task> GetChannelsAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { var models = await client.ApiClient.GetGuildChannelsAsync(guild.Id, options).ConfigureAwait(false); @@ -140,7 +160,7 @@ namespace Discord.Rest } //Integrations - public static async Task> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, + public static async Task> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { var models = await client.ApiClient.GetGuildIntegrationsAsync(guild.Id, options).ConfigureAwait(false); @@ -155,7 +175,7 @@ namespace Discord.Rest } //Invites - public static async Task> GetInvitesAsync(IGuild guild, BaseDiscordClient client, + public static async Task> GetInvitesAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { var models = await client.ApiClient.GetGuildInvitesAsync(guild.Id, options).ConfigureAwait(false); @@ -191,7 +211,7 @@ namespace Discord.Rest return RestGuildUser.Create(client, guild, model); return null; } - public static async Task GetCurrentUserAsync(IGuild guild, BaseDiscordClient client, + public static async Task GetCurrentUserAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) { return await GetUserAsync(guild, client, client.CurrentUser.Id, options).ConfigureAwait(false); diff --git a/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs b/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs index 180ad38bc..40d57c511 100644 --- a/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs +++ b/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Linq; using System.Threading.Tasks; using Model = Discord.API.GuildMember; @@ -30,7 +31,7 @@ namespace Discord.Rest } } public IReadOnlyCollection RoleIds => _roleIds; - + public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks); internal RestGuildUser(BaseDiscordClient discord, IGuild guild, ulong id) @@ -61,21 +62,25 @@ namespace Discord.Rest roles.Add(roleIds[i]); _roleIds = roles.ToImmutable(); } - + public override async Task UpdateAsync(RequestOptions options = null) { var model = await Discord.ApiClient.GetGuildMemberAsync(GuildId, Id, options).ConfigureAwait(false); Update(model); } public async Task ModifyAsync(Action func, RequestOptions options = null) - { + { var args = await UserHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); if (args.Deaf.IsSpecified) IsDeafened = args.Deaf.Value; if (args.Mute.IsSpecified) IsMuted = args.Mute.Value; - if (args.RoleIds.IsSpecified) - UpdateRoles(args.RoleIds.Value); + if (args.Nickname.IsSpecified) + Nickname = args.Nickname.Value; + if (args.Roles.IsSpecified) + UpdateRoles(args.Roles.Value.Select(x => x.Id).ToArray()); + else if (args.RoleIds.IsSpecified) + UpdateRoles(args.RoleIds.Value.ToArray()); } public Task KickAsync(RequestOptions options = null) => UserHelper.KickAsync(this, Discord, options); diff --git a/src/Discord.Net.Rest/Entities/Users/UserHelper.cs b/src/Discord.Net.Rest/Entities/Users/UserHelper.cs index dbfa2f2e5..e23c1cbb0 100644 --- a/src/Discord.Net.Rest/Entities/Users/UserHelper.cs +++ b/src/Discord.Net.Rest/Entities/Users/UserHelper.cs @@ -16,9 +16,13 @@ namespace Discord.Rest func(args); var apiArgs = new API.Rest.ModifyCurrentUserParams { - Avatar = args.Avatar.IsSpecified ? ImageModel.Create(args.Avatar.Value) : Optional.Create(), + Avatar = args.Avatar.IsSpecified ? ImageModel.Create(args.Avatar.Value) : Optional.Create(), Username = args.Username }; + + if (!apiArgs.Avatar.IsSpecified && user.AvatarId != null) + apiArgs.Avatar = new ImageModel(user.AvatarId); + return await client.ApiClient.ModifySelfAsync(apiArgs, options).ConfigureAwait(false); } public static async Task ModifyAsync(IGuildUser user, BaseDiscordClient client, Action func, @@ -31,9 +35,14 @@ namespace Discord.Rest ChannelId = args.Channel.IsSpecified ? args.Channel.Value.Id : Optional.Create(), Deaf = args.Deaf, Mute = args.Mute, - Nickname = args.Nickname, - RoleIds = args.Roles.IsSpecified ? args.Roles.Value.Select(r => r.Id).ToArray() : Optional.Create(), + Nickname = args.Nickname }; + + if (args.Roles.IsSpecified) + apiArgs.RoleIds = args.Roles.Value.Select(x => x.Id).ToArray(); + else if (args.RoleIds.IsSpecified) + apiArgs.RoleIds = args.RoleIds.Value.ToArray(); + await client.ApiClient.ModifyGuildMemberAsync(user.GuildId, user.Id, apiArgs, options).ConfigureAwait(false); return args; }