@@ -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; | |||||
} | |||||
} | |||||
} |
@@ -1,7 +0,0 @@ | |||||
using System; | |||||
namespace Discord.API | |||||
{ | |||||
[AttributeUsage(AttributeTargets.Property)] | |||||
public class ImageAttribute : Attribute { } | |||||
} |
@@ -10,7 +10,13 @@ namespace Discord.API.Rest | |||||
[JsonProperty("region")] | [JsonProperty("region")] | ||||
public string Region { get; set; } | public string Region { get; set; } | ||||
[JsonProperty("icon"), Image] | |||||
public Optional<Stream> Icon { get; set; } | |||||
[JsonProperty("icon")] | |||||
private Optional<Image> _icon { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<Stream> Icon | |||||
{ | |||||
get { return _icon.IsSpecified ? _icon.Value.Stream : null; } | |||||
set { _icon = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
} | } | ||||
} | } |
@@ -7,7 +7,20 @@ namespace Discord.API.Rest | |||||
{ | { | ||||
[JsonProperty("username")] | [JsonProperty("username")] | ||||
public Optional<string> Username { get; set; } | public Optional<string> Username { get; set; } | ||||
[JsonProperty("avatar"), Image] | |||||
public Optional<Stream> Avatar { get; set; } | |||||
[JsonProperty("avatar")] | |||||
private Optional<Image> _avatar { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<Stream> Avatar | |||||
{ | |||||
get { return _avatar.IsSpecified ? _avatar.Value.Stream : null; } | |||||
set { _avatar = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
[JsonIgnore] | |||||
internal Optional<string> AvatarHash | |||||
{ | |||||
get { return _avatar.IsSpecified ? _avatar.Value.Hash : null; } | |||||
set { _avatar = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
} | } | ||||
} | } |
@@ -4,7 +4,10 @@ using System.IO; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
public class ModifyGuildParams | public class ModifyGuildParams | ||||
{ | |||||
{ | |||||
[JsonProperty("username")] | |||||
public Optional<string> Username { get; set; } | |||||
[JsonProperty("name")] | [JsonProperty("name")] | ||||
public Optional<string> Name { get; set; } | public Optional<string> Name { get; set; } | ||||
[JsonProperty("region")] | [JsonProperty("region")] | ||||
@@ -15,10 +18,36 @@ namespace Discord.API.Rest | |||||
public Optional<DefaultMessageNotifications> DefaultMessageNotifications { get; set; } | public Optional<DefaultMessageNotifications> DefaultMessageNotifications { get; set; } | ||||
[JsonProperty("afk_timeout")] | [JsonProperty("afk_timeout")] | ||||
public Optional<int> AFKTimeout { get; set; } | public Optional<int> AFKTimeout { get; set; } | ||||
[JsonProperty("icon"), Image] | |||||
public Optional<Stream> Icon { get; set; } | |||||
[JsonProperty("splash"), Image] | |||||
public Optional<Stream> Splash { get; set; } | |||||
[JsonProperty("icon")] | |||||
private Optional<Image> _icon { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<Stream> Icon | |||||
{ | |||||
get { return _icon.IsSpecified ? _icon.Value.Stream : null; } | |||||
set { _icon = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
[JsonIgnore] | |||||
internal Optional<string> IconHash | |||||
{ | |||||
get { return _icon.IsSpecified ? _icon.Value.Hash : null; } | |||||
set { _icon = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
[JsonProperty("splash")] | |||||
private Optional<Image> _splash { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<Stream> Splash | |||||
{ | |||||
get { return _splash.IsSpecified ? _splash.Value.Stream : null; } | |||||
set { _splash = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
[JsonIgnore] | |||||
internal Optional<string> SplashHash | |||||
{ | |||||
get { return _splash.IsSpecified ? _splash.Value.Hash : null; } | |||||
set { _splash = value.IsSpecified ? new Image(value.Value) : Optional.Create<Image>(); } | |||||
} | |||||
[JsonProperty("afk_channel_id")] | [JsonProperty("afk_channel_id")] | ||||
public Optional<ulong?> AFKChannelId { get; set; } | public Optional<ulong?> AFKChannelId { get; set; } | ||||
@@ -121,6 +121,12 @@ namespace Discord | |||||
var args = new ModifyGuildParams(); | var args = new ModifyGuildParams(); | ||||
func(args); | 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); | var model = await Discord.ApiClient.ModifyGuildAsync(Id, args).ConfigureAwait(false); | ||||
Update(model, UpdateSource.Rest); | Update(model, UpdateSource.Rest); | ||||
} | } | ||||
@@ -52,6 +52,8 @@ namespace Discord | |||||
if (!args.Username.IsSpecified) | if (!args.Username.IsSpecified) | ||||
args.Username = Username; | args.Username = Username; | ||||
if (args.Avatar.IsSpecified && _avatarId != null) | |||||
args.AvatarHash = _avatarId; | |||||
var model = await Discord.ApiClient.ModifySelfAsync(args).ConfigureAwait(false); | var model = await Discord.ApiClient.ModifySelfAsync(args).ConfigureAwait(false); | ||||
Update(model, UpdateSource.Rest); | Update(model, UpdateSource.Rest); | ||||
@@ -7,7 +7,7 @@ namespace Discord | |||||
[DebuggerDisplay("{DebuggerDisplay,nq}")] | [DebuggerDisplay("{DebuggerDisplay,nq}")] | ||||
internal class User : SnowflakeEntity, IUser | internal class User : SnowflakeEntity, IUser | ||||
{ | { | ||||
private string _avatarId; | |||||
protected string _avatarId; | |||||
public bool IsBot { get; private set; } | public bool IsBot { get; private set; } | ||||
public string Username { get; private set; } | public string Username { get; private set; } | ||||
@@ -56,12 +56,14 @@ namespace Discord.Net.Converters | |||||
property.MemberConverter = converter; | property.MemberConverter = converter; | ||||
} | } | ||||
} | } | ||||
else | |||||
throw new InvalidOperationException($"{member.DeclaringType.FullName}.{member.Name} is not a property."); | |||||
return 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<Int53Attribute>() != null; | |||||
bool hasInt53 = member.GetCustomAttribute<Int53Attribute>() != null; | |||||
//Primitives | //Primitives | ||||
if (!hasInt53) | if (!hasInt53) | ||||
@@ -81,9 +83,8 @@ namespace Discord.Net.Converters | |||||
return UserStatusConverter.Instance; | return UserStatusConverter.Instance; | ||||
//Special | //Special | ||||
if (type == typeof(Stream) && propInfo.GetCustomAttribute<ImageAttribute>() != null) | |||||
return ImageConverter.Instance; | |||||
if (type == typeof(Image)) | |||||
return ImageConverter.Instance; | |||||
if (typeInfo == null) typeInfo = type.GetTypeInfo(); | if (typeInfo == null) typeInfo = type.GetTypeInfo(); | ||||
@@ -1,6 +1,6 @@ | |||||
using Newtonsoft.Json; | |||||
using Discord.API; | |||||
using Newtonsoft.Json; | |||||
using System; | using System; | ||||
using System.IO; | |||||
namespace Discord.Net.Converters | namespace Discord.Net.Converters | ||||
{ | { | ||||
@@ -19,13 +19,18 @@ namespace Discord.Net.Converters | |||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | 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); | |||||
} | } | ||||
} | } | ||||
} | } |