| @@ -47,6 +47,14 @@ namespace Discord | |||||
| return $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.{extension}?size={size}"; | return $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.{extension}?size={size}"; | ||||
| } | } | ||||
| public static string GetGuildUserAvatarUrl(ulong userId, ulong guildId, string avatarId, ushort size, ImageFormat format) | |||||
| { | |||||
| if (avatarId == null) | |||||
| return null; | |||||
| string extension = FormatToExtension(format, avatarId); | |||||
| return $"{DiscordConfig.CDNUrl}guilds/{guildId}/users/{userId}/avatars/{avatarId}.{extension}?size={size}"; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns a user banner URL. | /// Returns a user banner URL. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -25,6 +25,13 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| string Nickname { get; } | string Nickname { get; } | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the guild specific avatar for this users. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// The users guild avatar hash if they have one; otherwise <see langword="null"/>. | |||||
| /// </returns> | |||||
| string GuildAvatarId { get; } | |||||
| /// <summary> | |||||
| /// Gets the guild-level permissions for this user. | /// Gets the guild-level permissions for this user. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| @@ -96,6 +103,20 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| ChannelPermissions GetPermissions(IGuildChannel channel); | ChannelPermissions GetPermissions(IGuildChannel channel); | ||||
| /// <summary> | |||||
| /// Gets the guild avatar URL for this user. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// This property retrieves a URL for this guild user's guild specific avatar. In event that the user does not have a valid guild avatar | |||||
| /// (i.e. their avatar identifier is not set), this method will return <c>null</c>. | |||||
| /// </remarks> | |||||
| /// <param name="format">The format to return.</param> | |||||
| /// <param name="size">The size of the image to return in. This can be any power of two between 16 and 2048. | |||||
| /// </param> | |||||
| /// <returns> | |||||
| /// A string representing the user's avatar URL; <c>null</c> if the user does not have an avatar in place. | |||||
| /// </returns> | |||||
| string GetGuildAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128); | |||||
| /// <summary> | /// <summary> | ||||
| /// Kicks this user from this guild. | /// Kicks this user from this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -9,6 +9,8 @@ namespace Discord.API | |||||
| public User User { get; set; } | public User User { get; set; } | ||||
| [JsonProperty("nick")] | [JsonProperty("nick")] | ||||
| public Optional<string> Nick { get; set; } | public Optional<string> Nick { get; set; } | ||||
| [JsonProperty("avatar")] | |||||
| public Optional<string> Avatar { get; set; } | |||||
| [JsonProperty("roles")] | [JsonProperty("roles")] | ||||
| public Optional<ulong[]> Roles { get; set; } | public Optional<ulong[]> Roles { get; set; } | ||||
| [JsonProperty("joined_at")] | [JsonProperty("joined_at")] | ||||
| @@ -21,6 +21,8 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string Nickname { get; private set; } | public string Nickname { get; private set; } | ||||
| /// <inheritdoc/> | |||||
| public string GuildAvatarId { get; private set; } | |||||
| internal IGuild Guild { get; private set; } | internal IGuild Guild { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public bool IsDeafened { get; private set; } | public bool IsDeafened { get; private set; } | ||||
| @@ -80,6 +82,8 @@ namespace Discord.Rest | |||||
| _joinedAtTicks = model.JoinedAt.Value.UtcTicks; | _joinedAtTicks = model.JoinedAt.Value.UtcTicks; | ||||
| if (model.Nick.IsSpecified) | if (model.Nick.IsSpecified) | ||||
| Nickname = model.Nick.Value; | Nickname = model.Nick.Value; | ||||
| if (model.Avatar.IsSpecified) | |||||
| GuildAvatarId = model.Avatar.Value; | |||||
| if (model.Deaf.IsSpecified) | if (model.Deaf.IsSpecified) | ||||
| IsDeafened = model.Deaf.Value; | IsDeafened = model.Deaf.Value; | ||||
| if (model.Mute.IsSpecified) | if (model.Mute.IsSpecified) | ||||
| @@ -156,6 +160,9 @@ namespace Discord.Rest | |||||
| var guildPerms = GuildPermissions; | var guildPerms = GuildPermissions; | ||||
| return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); | return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); | ||||
| } | } | ||||
| public string GetGuildAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | |||||
| => CDN.GetGuildUserAvatarUrl(Id, GuildId, GuildAvatarId, size, format); | |||||
| #endregion | #endregion | ||||
| #region IGuildUser | #region IGuildUser | ||||
| @@ -54,6 +54,10 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| string IGuildUser.Nickname => null; | string IGuildUser.Nickname => null; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| string IGuildUser.GuildAvatarId => null; | |||||
| /// <inheritdoc /> | |||||
| string IGuildUser.GetGuildAvatarUrl(ImageFormat format, ushort size) => null; | |||||
| /// <inheritdoc /> | |||||
| bool? IGuildUser.IsPending => null; | bool? IGuildUser.IsPending => null; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| int IGuildUser.Hierarchy => 0; | int IGuildUser.Hierarchy => 0; | ||||
| @@ -30,7 +30,8 @@ namespace Discord.WebSocket | |||||
| public SocketGuild Guild { get; } | public SocketGuild Guild { get; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string Nickname { get; private set; } | public string Nickname { get; private set; } | ||||
| /// <inheritdoc/> | |||||
| public string GuildAvatarId { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override bool IsBot { get { return GlobalUser.IsBot; } internal set { GlobalUser.IsBot = value; } } | public override bool IsBot { get { return GlobalUser.IsBot; } internal set { GlobalUser.IsBot = value; } } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -154,6 +155,8 @@ namespace Discord.WebSocket | |||||
| _joinedAtTicks = model.JoinedAt.Value.UtcTicks; | _joinedAtTicks = model.JoinedAt.Value.UtcTicks; | ||||
| if (model.Nick.IsSpecified) | if (model.Nick.IsSpecified) | ||||
| Nickname = model.Nick.Value; | Nickname = model.Nick.Value; | ||||
| if (model.Avatar.IsSpecified) | |||||
| GuildAvatarId = model.Avatar.Value; | |||||
| if (model.Roles.IsSpecified) | if (model.Roles.IsSpecified) | ||||
| UpdateRoles(model.Roles.Value); | UpdateRoles(model.Roles.Value); | ||||
| if (model.PremiumSince.IsSpecified) | if (model.PremiumSince.IsSpecified) | ||||
| @@ -218,6 +221,8 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public ChannelPermissions GetPermissions(IGuildChannel channel) | public ChannelPermissions GetPermissions(IGuildChannel channel) | ||||
| => new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, GuildPermissions.RawValue)); | => new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, GuildPermissions.RawValue)); | ||||
| public string GetGuildAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | |||||
| => CDN.GetGuildUserAvatarUrl(Id, Guild.Id, GuildAvatarId, size, format); | |||||
| private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Guild)"; | private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Guild)"; | ||||
| internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser; | internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser; | ||||
| @@ -52,6 +52,9 @@ namespace Discord.WebSocket | |||||
| get => GuildUser.AvatarId; | get => GuildUser.AvatarId; | ||||
| internal set => GuildUser.AvatarId = value; | internal set => GuildUser.AvatarId = value; | ||||
| } | } | ||||
| /// <inheritdoc/> | |||||
| public string GuildAvatarId | |||||
| => GuildUser.GuildAvatarId; | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public override string BannerId | public override string BannerId | ||||
| @@ -205,6 +208,8 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| IReadOnlyCollection<ulong> IGuildUser.RoleIds => GuildUser.Roles.Select(x => x.Id).ToImmutableArray(); | IReadOnlyCollection<ulong> IGuildUser.RoleIds => GuildUser.Roles.Select(x => x.Id).ToImmutableArray(); | ||||
| string IGuildUser.GetGuildAvatarUrl(ImageFormat format, ushort size) => GuildUser.GetGuildAvatarUrl(format, size); | |||||
| internal override SocketGlobalUser GlobalUser => GuildUser.GlobalUser; | internal override SocketGlobalUser GlobalUser => GuildUser.GlobalUser; | ||||
| internal override SocketPresence Presence { get => GuildUser.Presence; set => GuildUser.Presence = value; } | internal override SocketPresence Presence { get => GuildUser.Presence; set => GuildUser.Presence = value; } | ||||
| @@ -81,6 +81,10 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| string IGuildUser.Nickname => null; | string IGuildUser.Nickname => null; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| string IGuildUser.GuildAvatarId => null; | |||||
| /// <inheritdoc /> | |||||
| string IGuildUser.GetGuildAvatarUrl(ImageFormat format, ushort size) => null; | |||||
| /// <inheritdoc /> | |||||
| DateTimeOffset? IGuildUser.PremiumSince => null; | DateTimeOffset? IGuildUser.PremiumSince => null; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| bool? IGuildUser.IsPending => null; | bool? IGuildUser.IsPending => null; | ||||