| @@ -27,7 +27,7 @@ namespace Discord.API | |||||
| [JsonProperty("mention_everyone")] | [JsonProperty("mention_everyone")] | ||||
| public Optional<bool> MentionEveryone { get; set; } | public Optional<bool> MentionEveryone { get; set; } | ||||
| [JsonProperty("mentions")] | [JsonProperty("mentions")] | ||||
| public Optional<User[]> UserMentions { get; set; } | |||||
| public Optional<ObjectOrId<User>[]> UserMentions { get; set; } | |||||
| [JsonProperty("mention_roles")] | [JsonProperty("mention_roles")] | ||||
| public Optional<ulong[]> RoleMentions { get; set; } | public Optional<ulong[]> RoleMentions { get; set; } | ||||
| [JsonProperty("attachments")] | [JsonProperty("attachments")] | ||||
| @@ -0,0 +1,19 @@ | |||||
| namespace Discord.API | |||||
| { | |||||
| public struct ObjectOrId<T> | |||||
| { | |||||
| public ulong Id { get; } | |||||
| public T Object { get; } | |||||
| public ObjectOrId(ulong id) | |||||
| { | |||||
| Id = id; | |||||
| Object = default(T); | |||||
| } | |||||
| public ObjectOrId(T obj) | |||||
| { | |||||
| Id = 0; | |||||
| Object = obj; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -24,8 +24,9 @@ namespace Discord.Net.Converters | |||||
| { | { | ||||
| JsonConverter converter; | JsonConverter converter; | ||||
| var type = propInfo.PropertyType; | var type = propInfo.PropertyType; | ||||
| Type genericType = type.IsConstructedGenericType ? type.GetGenericTypeDefinition() : null; | |||||
| if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Optional<>)) | |||||
| if (genericType == typeof(Optional<>)) | |||||
| { | { | ||||
| var typeInput = propInfo.DeclaringType; | var typeInput = propInfo.DeclaringType; | ||||
| var innerTypeOutput = type.GenericTypeArguments[0]; | var innerTypeOutput = type.GenericTypeArguments[0]; | ||||
| @@ -46,6 +47,20 @@ namespace Discord.Net.Converters | |||||
| instanceField.SetValue(null, converter); | instanceField.SetValue(null, converter); | ||||
| } | } | ||||
| } | } | ||||
| else if (genericType == typeof(ObjectOrId<>)) | |||||
| { | |||||
| var innerTypeOutput = type.GenericTypeArguments[0]; | |||||
| var converterType = typeof(ObjectOrIdConverter<>).MakeGenericType(innerTypeOutput).GetTypeInfo(); | |||||
| var instanceField = converterType.GetDeclaredField("Instance"); | |||||
| converter = instanceField.GetValue(null) as JsonConverter; | |||||
| if (converter == null) | |||||
| { | |||||
| var innerConverter = GetConverter(propInfo, innerTypeOutput); | |||||
| converter = converterType.DeclaredConstructors.First().Invoke(new object[] { innerConverter }) as JsonConverter; | |||||
| instanceField.SetValue(null, converter); | |||||
| } | |||||
| } | |||||
| else | else | ||||
| converter = GetConverter(propInfo, type); | converter = GetConverter(propInfo, type); | ||||
| @@ -0,0 +1,39 @@ | |||||
| using Discord.API; | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| namespace Discord.Net.Converters | |||||
| { | |||||
| public class ObjectOrIdConverter<T> : JsonConverter | |||||
| { | |||||
| internal static ObjectOrIdConverter<T> Instance; | |||||
| private readonly JsonConverter _innerConverter; | |||||
| public override bool CanConvert(Type objectType) => true; | |||||
| public override bool CanRead => true; | |||||
| public override bool CanWrite => false; | |||||
| public ObjectOrIdConverter(JsonConverter innerConverter) | |||||
| { | |||||
| _innerConverter = innerConverter; | |||||
| } | |||||
| public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |||||
| { | |||||
| switch (reader.TokenType) | |||||
| { | |||||
| case JsonToken.String: | |||||
| case JsonToken.Integer: | |||||
| return new ObjectOrId<T>(ulong.Parse(reader.ReadAsString())); | |||||
| default: | |||||
| return new ObjectOrId<T>(serializer.Deserialize<T>(reader)); | |||||
| } | |||||
| } | |||||
| public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||||
| { | |||||
| throw new InvalidOperationException(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -5,7 +5,7 @@ namespace Discord.Net.Converters | |||||
| { | { | ||||
| public class OptionalConverter<T> : JsonConverter | public class OptionalConverter<T> : JsonConverter | ||||
| { | { | ||||
| public static OptionalConverter<T> Instance; | |||||
| internal static OptionalConverter<T> Instance; | |||||
| private readonly JsonConverter _innerConverter; | private readonly JsonConverter _innerConverter; | ||||
| @@ -94,7 +94,11 @@ namespace Discord.Rest | |||||
| { | { | ||||
| var newMentions = ImmutableArray.CreateBuilder<IUser>(value.Length); | var newMentions = ImmutableArray.CreateBuilder<IUser>(value.Length); | ||||
| for (int i = 0; i < value.Length; i++) | for (int i = 0; i < value.Length; i++) | ||||
| newMentions.Add(RestUser.Create(Discord, value[i])); | |||||
| { | |||||
| var val = value[i]; | |||||
| if (val.Object != null) | |||||
| newMentions.Add(RestUser.Create(Discord, val.Object)); | |||||
| } | |||||
| mentions = newMentions.ToImmutable(); | mentions = newMentions.ToImmutable(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -92,7 +92,11 @@ namespace Discord.WebSocket | |||||
| { | { | ||||
| var newMentions = ImmutableArray.CreateBuilder<IUser>(value.Length); | var newMentions = ImmutableArray.CreateBuilder<IUser>(value.Length); | ||||
| for (int i = 0; i < value.Length; i++) | for (int i = 0; i < value.Length; i++) | ||||
| newMentions.Add(SocketSimpleUser.Create(Discord, Discord.State, value[i])); | |||||
| { | |||||
| var val = value[i]; | |||||
| if (val.Object != null) | |||||
| newMentions.Add(SocketSimpleUser.Create(Discord, Discord.State, val.Object)); | |||||
| } | |||||
| mentions = newMentions.ToImmutable(); | mentions = newMentions.ToImmutable(); | ||||
| } | } | ||||
| } | } | ||||