From ced88fefa3f70c47d547b85f1ff8c51fbd979c6e Mon Sep 17 00:00:00 2001 From: RogueException Date: Sun, 29 Nov 2015 02:32:14 -0400 Subject: [PATCH] Fixed exceptions during message importing --- src/Discord.Net/DiscordClient.Messages.cs | 25 ++++++++-- src/Discord.Net/DiscordClient.cs | 56 ++++++++++++----------- src/Discord.Net/Models/Message.cs | 6 +-- src/Discord.Net/project.json | 1 + 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/Discord.Net/DiscordClient.Messages.cs b/src/Discord.Net/DiscordClient.Messages.cs index 72c4a0b3b..d49e2c08f 100644 --- a/src/Discord.Net/DiscordClient.Messages.cs +++ b/src/Discord.Net/DiscordClient.Messages.cs @@ -1,7 +1,9 @@ using Discord.API; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; @@ -29,8 +31,8 @@ namespace Discord return msg; } } - public void Import(Message[] messages) - => Import(messages.ToDictionary(x => x.Id)); + public void Import(Dictionary messages) + => base.Import(messages); } public class MessageEventArgs : EventArgs @@ -261,10 +263,23 @@ namespace Discord public void ImportMessages(string json) { if (json == null) throw new ArgumentNullException(nameof(json)); - - var msgs = JsonConvert.DeserializeObject(json); - _messages.Import(msgs); + + var dic = JArray.Parse(json) + .Select(x => + { + var msg = new Message(this, + x["Id"].Value(), + x["ChannelId"].Value(), + x["UserId"].Value()); + + var reader = x.CreateReader(); + _messageImporter.Populate(reader, msg); + return msg; + }) + .ToDictionary(x => x.Id); + _messages.Import(dic); } + /// Serializes the message cache for a given channel to JSON. public string ExportMessages(Channel channel) { diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 71abfd31c..1b8e5dced 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -14,7 +14,7 @@ namespace Discord { private readonly DiscordAPIClient _api; private readonly Random _rand; - private readonly JsonSerializer _serializer; + private readonly JsonSerializer _socketSerializer, _messageImporter; private readonly ConcurrentQueue _pendingMessages; private readonly ConcurrentDictionary _voiceClients; private readonly Dictionary _services; @@ -163,12 +163,14 @@ namespace Discord if (Config.UseMessageQueue) _pendingMessages = new ConcurrentQueue(); - _serializer = new JsonSerializer(); - _serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; + _socketSerializer = new JsonSerializer(); + _socketSerializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; #if TEST_RESPONSES _serializer.CheckAdditionalContent = true; _serializer.MissingMemberHandling = MissingMemberHandling.Error; #endif + + _messageImporter = new JsonSerializer(); } internal override VoiceWebSocket CreateVoiceSocket() { @@ -311,7 +313,7 @@ namespace Discord case "READY": //Resync { base.OnReceivedEvent(e).Wait(); //This cannot be an await, or we'll get later messages before we're ready - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); _privateUser = _users.GetOrAdd(data.User.Id, null); _privateUser.Update(data.User); _privateUser.Global.Update(data.User); @@ -336,7 +338,7 @@ namespace Discord //Servers case "GUILD_CREATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); if (data.Unavailable != true) { var server = _servers.GetOrAdd(data.Id); @@ -350,7 +352,7 @@ namespace Discord break; case "GUILD_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var server = _servers[data.Id]; if (server != null) { @@ -361,7 +363,7 @@ namespace Discord break; case "GUILD_DELETE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var server = _servers.TryRemove(data.Id); if (server != null) { @@ -376,7 +378,7 @@ namespace Discord //Channels case "CHANNEL_CREATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); Channel channel; if (data.IsPrivate) { @@ -392,7 +394,7 @@ namespace Discord break; case "CHANNEL_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var channel = _channels[data.Id]; if (channel != null) { @@ -403,7 +405,7 @@ namespace Discord break; case "CHANNEL_DELETE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var channel = _channels.TryRemove(data.Id); if (channel != null) RaiseChannelDestroyed(channel); @@ -413,7 +415,7 @@ namespace Discord //Members case "GUILD_MEMBER_ADD": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var user = _users.GetOrAdd(data.User.Id, data.GuildId); user.Update(data); if (Config.TrackActivity) @@ -423,7 +425,7 @@ namespace Discord break; case "GUILD_MEMBER_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var user = _users[data.User.Id, data.GuildId]; if (user != null) { @@ -434,7 +436,7 @@ namespace Discord break; case "GUILD_MEMBER_REMOVE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var user = _users.TryRemove(data.UserId, data.GuildId); if (user != null) RaiseUserLeft(user); @@ -442,7 +444,7 @@ namespace Discord break; case "GUILD_MEMBERS_CHUNK": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); foreach (var memberData in data.Members) { var user = _users.GetOrAdd(memberData.User.Id, memberData.GuildId); @@ -455,7 +457,7 @@ namespace Discord //Roles case "GUILD_ROLE_CREATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var role = _roles.GetOrAdd(data.Data.Id, data.GuildId); role.Update(data.Data); var server = _servers[data.GuildId]; @@ -466,7 +468,7 @@ namespace Discord break; case "GUILD_ROLE_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var role = _roles[data.Data.Id]; if (role != null) { @@ -477,7 +479,7 @@ namespace Discord break; case "GUILD_ROLE_DELETE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var role = _roles.TryRemove(data.RoleId); if (role != null) { @@ -492,7 +494,7 @@ namespace Discord //Bans case "GUILD_BAN_ADD": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var server = _servers[data.GuildId]; if (server != null) { @@ -504,7 +506,7 @@ namespace Discord break; case "GUILD_BAN_REMOVE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var server = _servers[data.GuildId]; if (server != null) { @@ -518,7 +520,7 @@ namespace Discord //Messages case "MESSAGE_CREATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); Message msg = null; bool isAuthor = data.Author.Id == _userId; @@ -545,7 +547,7 @@ namespace Discord break; case "MESSAGE_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var msg = _messages[data.Id]; if (msg != null) { @@ -556,7 +558,7 @@ namespace Discord break; case "MESSAGE_DELETE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var msg = _messages.TryRemove(data.Id); if (msg != null) RaiseMessageDeleted(msg); @@ -564,7 +566,7 @@ namespace Discord break; case "MESSAGE_ACK": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var msg = GetMessage(data.MessageId); if (msg != null) RaiseMessageReadRemotely(msg); @@ -574,7 +576,7 @@ namespace Discord //Statuses case "PRESENCE_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var user = _users.GetOrAdd(data.User.Id, data.GuildId); if (user != null) { @@ -585,7 +587,7 @@ namespace Discord break; case "TYPING_START": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var channel = _channels[data.ChannelId]; if (channel != null) { @@ -611,7 +613,7 @@ namespace Discord //Voice case "VOICE_STATE_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var user = _users[data.UserId, data.GuildId]; if (user != null) { @@ -630,7 +632,7 @@ namespace Discord //Settings case "USER_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_socketSerializer); var user = _globalUsers[data.Id]; if (user != null) { diff --git a/src/Discord.Net/Models/Message.cs b/src/Discord.Net/Models/Message.cs index 3151a2b5f..7cffb483d 100644 --- a/src/Discord.Net/Models/Message.cs +++ b/src/Discord.Net/Models/Message.cs @@ -123,7 +123,7 @@ namespace Discord [JsonProperty] private IEnumerable MentionedUserIds { - get { return MentionedUsers.Select(x => x.Id); } + get { return MentionedUsers?.Select(x => x.Id); } set { MentionedUsers = value.Select(x => _client.GetUser(Server, x)).Where(x => x != null); } } @@ -133,7 +133,7 @@ namespace Discord [JsonProperty] private IEnumerable MentionedChannelIds { - get { return MentionedChannels.Select(x => x.Id); } + get { return MentionedChannels?.Select(x => x.Id); } set { MentionedChannels = value.Select(x => _client.GetChannel(x)).Where(x => x != null); } } @@ -143,7 +143,7 @@ namespace Discord [JsonProperty] private IEnumerable MentionedRoleIds { - get { return MentionedRoles.Select(x => x.Id); } + get { return MentionedRoles?.Select(x => x.Id); } set { MentionedRoles = value.Select(x => _client.GetRole(x)).Where(x => x != null); } } diff --git a/src/Discord.Net/project.json b/src/Discord.Net/project.json index 7a00691da..72f9b52c0 100644 --- a/src/Discord.Net/project.json +++ b/src/Discord.Net/project.json @@ -44,6 +44,7 @@ "dependencies": { "System.Collections": "4.0.11-beta-23516", "System.Collections.Concurrent": "4.0.11-beta-23516", + "System.Dynamic.Runtime": "4.0.11-beta-23516", "System.IO.Compression": "4.1.0-beta-23516", "System.Linq": "4.0.1-beta-23516", "System.Net.NameResolution": "4.0.0-beta-23516",