diff --git a/src/Discord.Net.Core/API/Common/Message.cs b/src/Discord.Net.Core/API/Common/Message.cs index 58871fd73..52de6f97b 100644 --- a/src/Discord.Net.Core/API/Common/Message.cs +++ b/src/Discord.Net.Core/API/Common/Message.cs @@ -27,7 +27,7 @@ namespace Discord.API [JsonProperty("mention_everyone")] public Optional MentionEveryone { get; set; } [JsonProperty("mentions")] - public Optional UserMentions { get; set; } + public Optional[]> UserMentions { get; set; } [JsonProperty("mention_roles")] public Optional RoleMentions { get; set; } [JsonProperty("attachments")] diff --git a/src/Discord.Net.Core/API/ObjectOrId.cs b/src/Discord.Net.Core/API/ObjectOrId.cs new file mode 100644 index 000000000..813aff906 --- /dev/null +++ b/src/Discord.Net.Core/API/ObjectOrId.cs @@ -0,0 +1,19 @@ +namespace Discord.API +{ + public struct ObjectOrId + { + 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; + } + } +} diff --git a/src/Discord.Net.Core/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Core/Net/Converters/DiscordContractResolver.cs index 413fd512f..0fb676f1c 100644 --- a/src/Discord.Net.Core/Net/Converters/DiscordContractResolver.cs +++ b/src/Discord.Net.Core/Net/Converters/DiscordContractResolver.cs @@ -24,8 +24,9 @@ namespace Discord.Net.Converters { JsonConverter converter; 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 innerTypeOutput = type.GenericTypeArguments[0]; @@ -46,6 +47,20 @@ namespace Discord.Net.Converters 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 converter = GetConverter(propInfo, type); diff --git a/src/Discord.Net.Core/Net/Converters/ObjectOrIdConverter.cs b/src/Discord.Net.Core/Net/Converters/ObjectOrIdConverter.cs new file mode 100644 index 000000000..a83edb60e --- /dev/null +++ b/src/Discord.Net.Core/Net/Converters/ObjectOrIdConverter.cs @@ -0,0 +1,39 @@ +using Discord.API; +using Newtonsoft.Json; +using System; + +namespace Discord.Net.Converters +{ + public class ObjectOrIdConverter : JsonConverter + { + internal static ObjectOrIdConverter 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(ulong.Parse(reader.ReadAsString())); + default: + return new ObjectOrId(serializer.Deserialize(reader)); + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new InvalidOperationException(); + } + } +} diff --git a/src/Discord.Net.Core/Net/Converters/OptionalConverter.cs b/src/Discord.Net.Core/Net/Converters/OptionalConverter.cs index 260d642d4..37bce7b28 100644 --- a/src/Discord.Net.Core/Net/Converters/OptionalConverter.cs +++ b/src/Discord.Net.Core/Net/Converters/OptionalConverter.cs @@ -5,7 +5,7 @@ namespace Discord.Net.Converters { public class OptionalConverter : JsonConverter { - public static OptionalConverter Instance; + internal static OptionalConverter Instance; private readonly JsonConverter _innerConverter; diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs index 655929a61..4e73ad328 100644 --- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs +++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs @@ -94,7 +94,11 @@ namespace Discord.Rest { var newMentions = ImmutableArray.CreateBuilder(value.Length); 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(); } } diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs index ecad183b0..91d798f5b 100644 --- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs +++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs @@ -92,7 +92,11 @@ namespace Discord.WebSocket { var newMentions = ImmutableArray.CreateBuilder(value.Length); 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(); } }