@@ -18,9 +18,16 @@ namespace Discord.API | |||||
Hash = hash; | Hash = hash; | ||||
} | } | ||||
public static Image Create(Discord.Image image) | |||||
internal static Image Create(Discord.Image image) | |||||
{ | { | ||||
return new Image(image.Stream); | 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")] | [JsonProperty("username")] | ||||
public Optional<string> Username { get; set; } | public Optional<string> Username { get; set; } | ||||
[JsonProperty("avatar")] | [JsonProperty("avatar")] | ||||
public Optional<Image> Avatar { get; set; } | |||||
public Optional<Image?> Avatar { get; set; } | |||||
} | } | ||||
} | } |
@@ -2,7 +2,13 @@ | |||||
{ | { | ||||
public class ModifyGuildChannelsParams | public class ModifyGuildChannelsParams | ||||
{ | { | ||||
/// <summary> | |||||
/// The id of the channel to apply this position to. | |||||
/// </summary> | |||||
public ulong Id { get; set; } | public ulong Id { get; set; } | ||||
/// <summary> | |||||
/// The new zero-based position of this channel. | |||||
/// </summary> | |||||
public int Position { get; set; } | public int Position { get; set; } | ||||
public ModifyGuildChannelsParams(ulong id, int position) | public ModifyGuildChannelsParams(ulong id, int position) | ||||
@@ -12,6 +12,10 @@ | |||||
/// <summary> | /// <summary> | ||||
/// What channel should the invite place users in, if not null. | /// What channel should the invite place users in, if not null. | ||||
/// </summary> | /// </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; } | public Optional<ulong?> ChannelId { get; set; } | ||||
} | } | ||||
} | } |
@@ -21,6 +21,10 @@ | |||||
/// </summary> | /// </summary> | ||||
public Optional<string> Name { get; set; } | public Optional<string> Name { get; set; } | ||||
/// <summary> | /// <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 | /// The ID of the region for the Guild's voice connections | ||||
/// </summary> | /// </summary> | ||||
public Optional<string> RegionId { get; set; } | public Optional<string> RegionId { get; set; } | ||||
@@ -48,10 +52,18 @@ | |||||
/// </remarks> | /// </remarks> | ||||
public Optional<Image?> Splash { get; set; } | public Optional<Image?> Splash { get; set; } | ||||
/// <summary> | /// <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. | /// The ID of the IVoiceChannel where AFK users should be sent. | ||||
/// </summary> | /// </summary> | ||||
public Optional<ulong?> AfkChannelId { get; set; } | public Optional<ulong?> AfkChannelId { get; set; } | ||||
/// <summary> | /// <summary> | ||||
/// The owner of this guild. | |||||
/// </summary> | |||||
public Optional<IUser> Owner { get; set; } | |||||
/// <summary> | |||||
/// The ID of the owner of this guild. | /// The ID of the owner of this guild. | ||||
/// </summary> | /// </summary> | ||||
public Optional<ulong> OwnerId { get; set; } | public Optional<ulong> OwnerId { get; set; } | ||||
@@ -17,6 +17,7 @@ namespace Discord | |||||
{ | { | ||||
Stream = stream; | Stream = stream; | ||||
} | } | ||||
#if NETSTANDARD1_3 | |||||
/// <summary> | /// <summary> | ||||
/// Create the image from a file path. | /// Create the image from a file path. | ||||
/// </summary> | /// </summary> | ||||
@@ -28,5 +29,6 @@ namespace Discord | |||||
{ | { | ||||
Stream = File.OpenRead(path); | Stream = File.OpenRead(path); | ||||
} | } | ||||
#endif | |||||
} | } | ||||
} | } |
@@ -2,6 +2,9 @@ | |||||
{ | { | ||||
public class ModifyGuildRolesParams : ModifyGuildRoleParams | public class ModifyGuildRolesParams : ModifyGuildRoleParams | ||||
{ | { | ||||
/// <summary> | |||||
/// The id of the role to be edited | |||||
/// </summary> | |||||
public ulong Id { get; } | public ulong Id { get; } | ||||
public ModifyGuildRolesParams(ulong id) | public ModifyGuildRolesParams(ulong id) | ||||
@@ -1,4 +1,6 @@ | |||||
namespace Discord | |||||
using System.Collections.Generic; | |||||
namespace Discord | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Modify an IGuildUser with the following parameters. | /// 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 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[])"/> | /// To remove a role from a user: <see cref="GuildUserExtensions.RemoveRolesAsync(IGuildUser, IRole[])"/> | ||||
/// </remarks> | /// </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> | /// <summary> | ||||
/// Move a user to a voice channel. | /// Move a user to a voice channel. | ||||
/// </summary> | /// </summary> | ||||
@@ -27,16 +27,31 @@ namespace Discord.Rest | |||||
AfkChannelId = args.AfkChannelId, | AfkChannelId = args.AfkChannelId, | ||||
AfkTimeout = args.AfkTimeout, | AfkTimeout = args.AfkTimeout, | ||||
DefaultMessageNotifications = args.DefaultMessageNotifications, | DefaultMessageNotifications = args.DefaultMessageNotifications, | ||||
Icon = args.Icon.IsSpecified ? ImageModel.Create(args.Icon.Value) : Optional.Create<ImageModel?>(), | |||||
Name = args.Name, | Name = args.Name, | ||||
OwnerId = args.OwnerId, | |||||
RegionId = args.RegionId, | |||||
Splash = args.Splash.IsSpecified ? ImageModel.Create(args.Splash.Value) : Optional.Create<ImageModel?>(), | |||||
Username = args.Username, | Username = args.Username, | ||||
VerificationLevel = args.VerificationLevel | 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); | 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); | apiArgs.Icon = new ImageModel(guild.IconId); | ||||
return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | ||||
@@ -50,9 +65,14 @@ namespace Discord.Rest | |||||
func(args); | func(args); | ||||
var apiArgs = new API.Rest.ModifyGuildEmbedParams | var apiArgs = new API.Rest.ModifyGuildEmbedParams | ||||
{ | { | ||||
ChannelId = args.ChannelId, | |||||
Enabled = args.Enabled | 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); | return await client.ApiClient.ModifyGuildEmbedAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | ||||
} | } | ||||
public static async Task ModifyChannelsAsync(IGuild guild, BaseDiscordClient client, | 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); | 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) | RequestOptions options) | ||||
{ | { | ||||
await client.ApiClient.LeaveGuildAsync(guild.Id, options).ConfigureAwait(false); | 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) | RequestOptions options) | ||||
{ | { | ||||
await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false); | await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false); | ||||
} | } | ||||
//Bans | //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) | RequestOptions options) | ||||
{ | { | ||||
var models = await client.ApiClient.GetGuildBansAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildBansAsync(guild.Id, options).ConfigureAwait(false); | ||||
return models.Select(x => RestBan.Create(client, x)).ToImmutableArray(); | 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) | ulong userId, int pruneDays, RequestOptions options) | ||||
{ | { | ||||
var args = new CreateGuildBanParams { DeleteMessageDays = pruneDays }; | var args = new CreateGuildBanParams { DeleteMessageDays = pruneDays }; | ||||
await client.ApiClient.CreateGuildBanAsync(guild.Id, userId, args, options).ConfigureAwait(false); | 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) | ulong userId, RequestOptions options) | ||||
{ | { | ||||
await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false); | await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false); | ||||
@@ -114,7 +134,7 @@ namespace Discord.Rest | |||||
return RestGuildChannel.Create(client, guild, model); | return RestGuildChannel.Create(client, guild, model); | ||||
return null; | 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) | RequestOptions options) | ||||
{ | { | ||||
var models = await client.ApiClient.GetGuildChannelsAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildChannelsAsync(guild.Id, options).ConfigureAwait(false); | ||||
@@ -140,7 +160,7 @@ namespace Discord.Rest | |||||
} | } | ||||
//Integrations | //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) | RequestOptions options) | ||||
{ | { | ||||
var models = await client.ApiClient.GetGuildIntegrationsAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildIntegrationsAsync(guild.Id, options).ConfigureAwait(false); | ||||
@@ -155,7 +175,7 @@ namespace Discord.Rest | |||||
} | } | ||||
//Invites | //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) | RequestOptions options) | ||||
{ | { | ||||
var models = await client.ApiClient.GetGuildInvitesAsync(guild.Id, options).ConfigureAwait(false); | 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 RestGuildUser.Create(client, guild, model); | ||||
return null; | return null; | ||||
} | } | ||||
public static async Task<RestGuildUser> GetCurrentUserAsync(IGuild guild, BaseDiscordClient client, | |||||
public static async Task<RestGuildUser> GetCurrentUserAsync(IGuild guild, BaseDiscordClient client, | |||||
RequestOptions options) | RequestOptions options) | ||||
{ | { | ||||
return await GetUserAsync(guild, client, client.CurrentUser.Id, options).ConfigureAwait(false); | return await GetUserAsync(guild, client, client.CurrentUser.Id, options).ConfigureAwait(false); | ||||
@@ -3,6 +3,7 @@ using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
using System.Diagnostics; | using System.Diagnostics; | ||||
using System.Linq; | |||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Model = Discord.API.GuildMember; | using Model = Discord.API.GuildMember; | ||||
@@ -30,7 +31,7 @@ namespace Discord.Rest | |||||
} | } | ||||
} | } | ||||
public IReadOnlyCollection<ulong> RoleIds => _roleIds; | public IReadOnlyCollection<ulong> RoleIds => _roleIds; | ||||
public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks); | public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks); | ||||
internal RestGuildUser(BaseDiscordClient discord, IGuild guild, ulong id) | internal RestGuildUser(BaseDiscordClient discord, IGuild guild, ulong id) | ||||
@@ -61,21 +62,25 @@ namespace Discord.Rest | |||||
roles.Add(roleIds[i]); | roles.Add(roleIds[i]); | ||||
_roleIds = roles.ToImmutable(); | _roleIds = roles.ToImmutable(); | ||||
} | } | ||||
public override async Task UpdateAsync(RequestOptions options = null) | public override async Task UpdateAsync(RequestOptions options = null) | ||||
{ | { | ||||
var model = await Discord.ApiClient.GetGuildMemberAsync(GuildId, Id, options).ConfigureAwait(false); | var model = await Discord.ApiClient.GetGuildMemberAsync(GuildId, Id, options).ConfigureAwait(false); | ||||
Update(model); | Update(model); | ||||
} | } | ||||
public async Task ModifyAsync(Action<ModifyGuildMemberParams> func, RequestOptions options = null) | public async Task ModifyAsync(Action<ModifyGuildMemberParams> func, RequestOptions options = null) | ||||
{ | |||||
{ | |||||
var args = await UserHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); | var args = await UserHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); | ||||
if (args.Deaf.IsSpecified) | if (args.Deaf.IsSpecified) | ||||
IsDeafened = args.Deaf.Value; | IsDeafened = args.Deaf.Value; | ||||
if (args.Mute.IsSpecified) | if (args.Mute.IsSpecified) | ||||
IsMuted = args.Mute.Value; | 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) | public Task KickAsync(RequestOptions options = null) | ||||
=> UserHelper.KickAsync(this, Discord, options); | => UserHelper.KickAsync(this, Discord, options); | ||||
@@ -16,9 +16,13 @@ namespace Discord.Rest | |||||
func(args); | func(args); | ||||
var apiArgs = new API.Rest.ModifyCurrentUserParams | 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 | 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); | return await client.ApiClient.ModifySelfAsync(apiArgs, options).ConfigureAwait(false); | ||||
} | } | ||||
public static async Task<ModifyGuildMemberParams> ModifyAsync(IGuildUser user, BaseDiscordClient client, Action<ModifyGuildMemberParams> func, | 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>(), | ChannelId = args.Channel.IsSpecified ? args.Channel.Value.Id : Optional.Create<ulong>(), | ||||
Deaf = args.Deaf, | Deaf = args.Deaf, | ||||
Mute = args.Mute, | 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); | await client.ApiClient.ModifyGuildMemberAsync(user.GuildId, user.Id, apiArgs, options).ConfigureAwait(false); | ||||
return args; | return args; | ||||
} | } | ||||