| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -9,6 +9,6 @@ namespace Discord.API.Rest | |||
| [JsonProperty("username")] | |||
| public Optional<string> Username { get; set; } | |||
| [JsonProperty("avatar")] | |||
| public Optional<Image> Avatar { get; set; } | |||
| public Optional<Image?> Avatar { get; set; } | |||
| } | |||
| } | |||
| @@ -2,7 +2,13 @@ | |||
| { | |||
| public class ModifyGuildChannelsParams | |||
| { | |||
| /// <summary> | |||
| /// The id of the channel to apply this position to. | |||
| /// </summary> | |||
| public ulong Id { get; set; } | |||
| /// <summary> | |||
| /// The new zero-based position of this channel. | |||
| /// </summary> | |||
| public int Position { get; set; } | |||
| public ModifyGuildChannelsParams(ulong id, int position) | |||
| @@ -12,6 +12,10 @@ | |||
| /// <summary> | |||
| /// What channel should the invite place users in, if not null. | |||
| /// </summary> | |||
| public Optional<IChannel> Channel { get; set; } | |||
| /// <summary> | |||
| /// What channel should the invite place users in, if not null. | |||
| /// </summary> | |||
| public Optional<ulong?> ChannelId { get; set; } | |||
| } | |||
| } | |||
| @@ -21,6 +21,10 @@ | |||
| /// </summary> | |||
| public Optional<string> Name { get; set; } | |||
| /// <summary> | |||
| /// The region for the Guild's voice connections | |||
| /// </summary> | |||
| public Optional<IVoiceRegion> Region { get; set; } | |||
| /// <summary> | |||
| /// The ID of the region for the Guild's voice connections | |||
| /// </summary> | |||
| public Optional<string> RegionId { get; set; } | |||
| @@ -48,10 +52,18 @@ | |||
| /// </remarks> | |||
| public Optional<Image?> Splash { get; set; } | |||
| /// <summary> | |||
| /// The IVoiceChannel where AFK users should be sent. | |||
| /// </summary> | |||
| public Optional<IVoiceChannel> AfkChannel { get; set; } | |||
| /// <summary> | |||
| /// The ID of the IVoiceChannel where AFK users should be sent. | |||
| /// </summary> | |||
| public Optional<ulong?> AfkChannelId { get; set; } | |||
| /// <summary> | |||
| /// The owner of this guild. | |||
| /// </summary> | |||
| public Optional<IUser> Owner { get; set; } | |||
| /// <summary> | |||
| /// The ID of the owner of this guild. | |||
| /// </summary> | |||
| public Optional<ulong> OwnerId { get; set; } | |||
| @@ -17,6 +17,7 @@ namespace Discord | |||
| { | |||
| Stream = stream; | |||
| } | |||
| #if NETSTANDARD1_3 | |||
| /// <summary> | |||
| /// Create the image from a file path. | |||
| /// </summary> | |||
| @@ -28,5 +29,6 @@ namespace Discord | |||
| { | |||
| Stream = File.OpenRead(path); | |||
| } | |||
| #endif | |||
| } | |||
| } | |||
| @@ -2,6 +2,9 @@ | |||
| { | |||
| public class ModifyGuildRolesParams : ModifyGuildRoleParams | |||
| { | |||
| /// <summary> | |||
| /// The id of the role to be edited | |||
| /// </summary> | |||
| public ulong Id { get; } | |||
| public ModifyGuildRolesParams(ulong id) | |||
| @@ -1,4 +1,6 @@ | |||
| namespace Discord | |||
| using System.Collections.Generic; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Modify an IGuildUser with the following parameters. | |||
| @@ -42,7 +44,15 @@ | |||
| /// To add a role to a user: <see cref="GuildUserExtensions.AddRolesAsync(IGuildUser, IRole[])"/> | |||
| /// To remove a role from a user: <see cref="GuildUserExtensions.RemoveRolesAsync(IGuildUser, IRole[])"/> | |||
| /// </remarks> | |||
| public Optional<IRole[]> Roles { get; set; } | |||
| public Optional<IEnumerable<IRole>> Roles { get; set; } | |||
| /// <summary> | |||
| /// What roles should the user have? | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// To add a role to a user: <see cref="GuildUserExtensions.AddRolesAsync(IGuildUser, IRole[])"/> | |||
| /// To remove a role from a user: <see cref="GuildUserExtensions.RemoveRolesAsync(IGuildUser, IRole[])"/> | |||
| /// </remarks> | |||
| public Optional<IEnumerable<ulong>> RoleIds { get; set; } | |||
| /// <summary> | |||
| /// Move a user to a voice channel. | |||
| /// </summary> | |||
| @@ -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<ImageModel?>(), | |||
| Name = args.Name, | |||
| OwnerId = args.OwnerId, | |||
| RegionId = args.RegionId, | |||
| Splash = args.Splash.IsSpecified ? ImageModel.Create(args.Splash.Value) : Optional.Create<ImageModel?>(), | |||
| 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<IReadOnlyCollection<RestBan>> GetBansAsync(IGuild guild, BaseDiscordClient client, | |||
| public static async Task<IReadOnlyCollection<RestBan>> 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<IReadOnlyCollection<RestGuildChannel>> GetChannelsAsync(IGuild guild, BaseDiscordClient client, | |||
| public static async Task<IReadOnlyCollection<RestGuildChannel>> 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<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, | |||
| public static async Task<IReadOnlyCollection<RestGuildIntegration>> 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<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(IGuild guild, BaseDiscordClient client, | |||
| public static async Task<IReadOnlyCollection<RestInviteMetadata>> 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<RestGuildUser> GetCurrentUserAsync(IGuild guild, BaseDiscordClient client, | |||
| public static async Task<RestGuildUser> GetCurrentUserAsync(IGuild guild, BaseDiscordClient client, | |||
| RequestOptions options) | |||
| { | |||
| return await GetUserAsync(guild, client, client.CurrentUser.Id, options).ConfigureAwait(false); | |||
| @@ -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<ulong> 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<ModifyGuildMemberParams> 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); | |||
| @@ -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<ImageModel>(), | |||
| Avatar = args.Avatar.IsSpecified ? ImageModel.Create(args.Avatar.Value) : Optional.Create<ImageModel?>(), | |||
| 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<ModifyGuildMemberParams> ModifyAsync(IGuildUser user, BaseDiscordClient client, Action<ModifyGuildMemberParams> func, | |||
| @@ -31,9 +35,14 @@ namespace Discord.Rest | |||
| ChannelId = args.Channel.IsSpecified ? args.Channel.Value.Id : Optional.Create<ulong>(), | |||
| Deaf = args.Deaf, | |||
| Mute = args.Mute, | |||
| Nickname = args.Nickname, | |||
| RoleIds = args.Roles.IsSpecified ? args.Roles.Value.Select(r => r.Id).ToArray() : Optional.Create<ulong[]>(), | |||
| 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; | |||
| } | |||