diff --git a/src/Discord.Net/API/Image.cs b/src/Discord.Net/API/Image.cs new file mode 100644 index 000000000..b2357a0a6 --- /dev/null +++ b/src/Discord.Net/API/Image.cs @@ -0,0 +1,21 @@ +using System.IO; + +namespace Discord.API +{ + internal struct Image + { + public Stream Stream { get; } + public string Hash { get; } + + public Image(Stream stream) + { + Stream = stream; + Hash = null; + } + public Image(string hash) + { + Stream = null; + Hash = hash; + } + } +} diff --git a/src/Discord.Net/API/ImageAttribute.cs b/src/Discord.Net/API/ImageAttribute.cs deleted file mode 100644 index c31c6d982..000000000 --- a/src/Discord.Net/API/ImageAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; - -namespace Discord.API -{ - [AttributeUsage(AttributeTargets.Property)] - public class ImageAttribute : Attribute { } -} diff --git a/src/Discord.Net/API/Rest/CreateGuildParams.cs b/src/Discord.Net/API/Rest/CreateGuildParams.cs index 09c294b5e..75892a0e2 100644 --- a/src/Discord.Net/API/Rest/CreateGuildParams.cs +++ b/src/Discord.Net/API/Rest/CreateGuildParams.cs @@ -10,7 +10,13 @@ namespace Discord.API.Rest [JsonProperty("region")] public string Region { get; set; } - [JsonProperty("icon"), Image] - public Optional Icon { get; set; } + [JsonProperty("icon")] + private Optional _icon { get; set; } + [JsonIgnore] + public Optional Icon + { + get { return _icon.IsSpecified ? _icon.Value.Stream : null; } + set { _icon = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } } } diff --git a/src/Discord.Net/API/Rest/ModifyCurrentUserParams.cs b/src/Discord.Net/API/Rest/ModifyCurrentUserParams.cs index 7e9b668ef..03fe3550c 100644 --- a/src/Discord.Net/API/Rest/ModifyCurrentUserParams.cs +++ b/src/Discord.Net/API/Rest/ModifyCurrentUserParams.cs @@ -7,7 +7,20 @@ namespace Discord.API.Rest { [JsonProperty("username")] public Optional Username { get; set; } - [JsonProperty("avatar"), Image] - public Optional Avatar { get; set; } + + [JsonProperty("avatar")] + private Optional _avatar { get; set; } + [JsonIgnore] + public Optional Avatar + { + get { return _avatar.IsSpecified ? _avatar.Value.Stream : null; } + set { _avatar = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } + [JsonIgnore] + internal Optional AvatarHash + { + get { return _avatar.IsSpecified ? _avatar.Value.Hash : null; } + set { _avatar = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } } } diff --git a/src/Discord.Net/API/Rest/ModifyGuildParams.cs b/src/Discord.Net/API/Rest/ModifyGuildParams.cs index bbdd46d28..f111ceaea 100644 --- a/src/Discord.Net/API/Rest/ModifyGuildParams.cs +++ b/src/Discord.Net/API/Rest/ModifyGuildParams.cs @@ -4,7 +4,10 @@ using System.IO; namespace Discord.API.Rest { public class ModifyGuildParams - { + { + [JsonProperty("username")] + public Optional Username { get; set; } + [JsonProperty("name")] public Optional Name { get; set; } [JsonProperty("region")] @@ -15,10 +18,36 @@ namespace Discord.API.Rest public Optional DefaultMessageNotifications { get; set; } [JsonProperty("afk_timeout")] public Optional AFKTimeout { get; set; } - [JsonProperty("icon"), Image] - public Optional Icon { get; set; } - [JsonProperty("splash"), Image] - public Optional Splash { get; set; } + + [JsonProperty("icon")] + private Optional _icon { get; set; } + [JsonIgnore] + public Optional Icon + { + get { return _icon.IsSpecified ? _icon.Value.Stream : null; } + set { _icon = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } + [JsonIgnore] + internal Optional IconHash + { + get { return _icon.IsSpecified ? _icon.Value.Hash : null; } + set { _icon = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } + + [JsonProperty("splash")] + private Optional _splash { get; set; } + [JsonIgnore] + public Optional Splash + { + get { return _splash.IsSpecified ? _splash.Value.Stream : null; } + set { _splash = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } + [JsonIgnore] + internal Optional SplashHash + { + get { return _splash.IsSpecified ? _splash.Value.Hash : null; } + set { _splash = value.IsSpecified ? new Image(value.Value) : Optional.Create(); } + } [JsonProperty("afk_channel_id")] public Optional AFKChannelId { get; set; } diff --git a/src/Discord.Net/Entities/Guilds/Guild.cs b/src/Discord.Net/Entities/Guilds/Guild.cs index 0031fad85..3eed4ce8f 100644 --- a/src/Discord.Net/Entities/Guilds/Guild.cs +++ b/src/Discord.Net/Entities/Guilds/Guild.cs @@ -121,6 +121,12 @@ namespace Discord var args = new ModifyGuildParams(); func(args); + + if (args.Splash.IsSpecified && _splashId != null) + args.SplashHash = _splashId; + if (args.Icon.IsSpecified && _iconId != null) + args.IconHash = _iconId; + var model = await Discord.ApiClient.ModifyGuildAsync(Id, args).ConfigureAwait(false); Update(model, UpdateSource.Rest); } diff --git a/src/Discord.Net/Entities/Users/SelfUser.cs b/src/Discord.Net/Entities/Users/SelfUser.cs index 0e696aea4..91cd08b92 100644 --- a/src/Discord.Net/Entities/Users/SelfUser.cs +++ b/src/Discord.Net/Entities/Users/SelfUser.cs @@ -52,6 +52,8 @@ namespace Discord if (!args.Username.IsSpecified) args.Username = Username; + if (args.Avatar.IsSpecified && _avatarId != null) + args.AvatarHash = _avatarId; var model = await Discord.ApiClient.ModifySelfAsync(args).ConfigureAwait(false); Update(model, UpdateSource.Rest); diff --git a/src/Discord.Net/Entities/Users/User.cs b/src/Discord.Net/Entities/Users/User.cs index 490128e82..f1f14607c 100644 --- a/src/Discord.Net/Entities/Users/User.cs +++ b/src/Discord.Net/Entities/Users/User.cs @@ -7,7 +7,7 @@ namespace Discord [DebuggerDisplay("{DebuggerDisplay,nq}")] internal class User : SnowflakeEntity, IUser { - private string _avatarId; + protected string _avatarId; public bool IsBot { get; private set; } public string Username { get; private set; } diff --git a/src/Discord.Net/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net/Net/Converters/DiscordContractResolver.cs index f30e38cdd..d0f51dc59 100644 --- a/src/Discord.Net/Net/Converters/DiscordContractResolver.cs +++ b/src/Discord.Net/Net/Converters/DiscordContractResolver.cs @@ -56,12 +56,14 @@ namespace Discord.Net.Converters property.MemberConverter = converter; } } + else + throw new InvalidOperationException($"{member.DeclaringType.FullName}.{member.Name} is not a property."); return property; } - private JsonConverter GetConverter(PropertyInfo propInfo, Type type, TypeInfo typeInfo = null) + private JsonConverter GetConverter(MemberInfo member, Type type, TypeInfo typeInfo = null) { - bool hasInt53 = propInfo.GetCustomAttribute() != null; + bool hasInt53 = member.GetCustomAttribute() != null; //Primitives if (!hasInt53) @@ -81,9 +83,8 @@ namespace Discord.Net.Converters return UserStatusConverter.Instance; //Special - if (type == typeof(Stream) && propInfo.GetCustomAttribute() != null) - return ImageConverter.Instance; - + if (type == typeof(Image)) + return ImageConverter.Instance; if (typeInfo == null) typeInfo = type.GetTypeInfo(); diff --git a/src/Discord.Net/Net/Converters/ImageConverter.cs b/src/Discord.Net/Net/Converters/ImageConverter.cs index 3446d2b2e..88e205688 100644 --- a/src/Discord.Net/Net/Converters/ImageConverter.cs +++ b/src/Discord.Net/Net/Converters/ImageConverter.cs @@ -1,6 +1,6 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System; -using System.IO; namespace Discord.Net.Converters { @@ -19,13 +19,18 @@ namespace Discord.Net.Converters public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - var stream = value as Stream; + var image = (Image)value; - byte[] bytes = new byte[stream.Length - stream.Position]; - stream.Read(bytes, 0, bytes.Length); + if (image.Stream != null) + { + byte[] bytes = new byte[image.Stream.Length - image.Stream.Position]; + image.Stream.Read(bytes, 0, bytes.Length); - string base64 = Convert.ToBase64String(bytes); - writer.WriteValue($"data:image/jpeg;base64,{base64}"); + string base64 = Convert.ToBase64String(bytes); + writer.WriteValue($"data:image/jpeg;base64,{base64}"); + } + else if (image.Hash != null) + writer.WriteValue(image.Hash); } } }