using System; using System.Drawing; using System.Linq; using DiscordChatExporter.Core.Models; using DiscordChatExporter.Core.Services.Internal; using Newtonsoft.Json.Linq; using Tyrrrz.Extensions; namespace DiscordChatExporter.Core.Services { public partial class DataService { private User ParseUser(JToken json) { var id = json["id"].Value(); var discriminator = json["discriminator"].Value(); var name = json["username"].Value(); var avatarHash = json["avatar"].Value(); return new User(id, discriminator, name, avatarHash); } private Guild ParseGuild(JToken json) { var id = json["id"].Value(); var name = json["name"].Value(); var iconHash = json["icon"].Value(); return new Guild(id, name, iconHash); } private Channel ParseChannel(JToken json) { // Get basic data var id = json["id"].Value(); var parentId = json["parent_id"]?.Value(); var type = (ChannelType) json["type"].Value(); var topic = json["topic"]?.Value(); // Try to extract guild ID var guildId = json["guild_id"]?.Value(); // If the guild ID is blank, it's direct messages if (guildId == null) guildId = Guild.DirectMessages.Id; // Try to extract name var name = json["name"]?.Value(); // If the name is blank, it's direct messages if (name == null) name = json["recipients"].Select(ParseUser).Select(u => u.Name).JoinToString(", "); return new Channel(id, parentId, guildId, name, topic, type); } private Role ParseRole(JToken json) { var id = json["id"].Value(); var name = json["name"].Value(); return new Role(id, name); } private Attachment ParseAttachment(JToken json) { var id = json["id"].Value(); var url = json["url"].Value(); var width = json["width"]?.Value(); var height = json["height"]?.Value(); var fileName = json["filename"].Value(); var fileSizeBytes = json["size"].Value(); var fileSize = new FileSize(fileSizeBytes); return new Attachment(id, width, height, url, fileName, fileSize); } private EmbedAuthor ParseEmbedAuthor(JToken json) { var name = json["name"]?.Value(); var url = json["url"]?.Value(); var iconUrl = json["icon_url"]?.Value(); return new EmbedAuthor(name, url, iconUrl); } private EmbedField ParseEmbedField(JToken json) { var name = json["name"].Value(); var value = json["value"].Value(); var isInline = json["inline"]?.Value() ?? false; return new EmbedField(name, value, isInline); } private EmbedImage ParseEmbedImage(JToken json) { var url = json["url"]?.Value(); var width = json["width"]?.Value(); var height = json["height"]?.Value(); return new EmbedImage(url, width, height); } private EmbedFooter ParseEmbedFooter(JToken json) { var text = json["text"].Value(); var iconUrl = json["icon_url"]?.Value(); return new EmbedFooter(text, iconUrl); } private Embed ParseEmbed(JToken json) { // Get basic data var title = json["title"]?.Value(); var description = json["description"]?.Value(); var url = json["url"]?.Value(); var timestamp = json["timestamp"]?.Value(); // Get color var color = json["color"] != null ? Color.FromArgb(json["color"].Value()).ResetAlpha() : Color.FromArgb(79, 84, 92); // default color // Get author var author = json["author"] != null ? ParseEmbedAuthor(json["author"]) : null; // Get fields var fields = json["fields"].EmptyIfNull().Select(ParseEmbedField).ToArray(); // Get thumbnail var thumbnail = json["thumbnail"] != null ? ParseEmbedImage(json["thumbnail"]) : null; // Get image var image = json["image"] != null ? ParseEmbedImage(json["image"]) : null; // Get footer var footer = json["footer"] != null ? ParseEmbedFooter(json["footer"]) : null; return new Embed(title, url, timestamp, color, author, description, fields, thumbnail, image, footer); } private Emoji ParseEmoji(JToken json) { var id = json["id"]?.Value(); var name = json["name"]?.Value(); var isAnimated = json["animated"]?.Value() ?? false; return new Emoji(id, name, isAnimated); } private Reaction ParseReaction(JToken json) { var count = json["count"].Value(); var emoji = ParseEmoji(json["emoji"]); return new Reaction(count, emoji); } private Message ParseMessage(JToken json) { // Get basic data var id = json["id"].Value(); var channelId = json["channel_id"].Value(); var timestamp = json["timestamp"].Value(); var editedTimestamp = json["edited_timestamp"]?.Value(); var content = json["content"].Value(); var type = (MessageType) json["type"].Value(); // Workarounds for non-default types if (type == MessageType.RecipientAdd) content = "Added a recipient."; else if (type == MessageType.RecipientRemove) content = "Removed a recipient."; else if (type == MessageType.Call) content = "Started a call."; else if (type == MessageType.ChannelNameChange) content = "Changed the channel name."; else if (type == MessageType.ChannelIconChange) content = "Changed the channel icon."; else if (type == MessageType.ChannelPinnedMessage) content = "Pinned a message."; else if (type == MessageType.GuildMemberJoin) content = "Joined the server."; // Get author var author = ParseUser(json["author"]); // Get attachments var attachments = json["attachments"].EmptyIfNull().Select(ParseAttachment).ToArray(); // Get embeds var embeds = json["embeds"].EmptyIfNull().Select(ParseEmbed).ToArray(); // Get reactions var reactions = json["reactions"].EmptyIfNull().Select(ParseReaction).ToArray(); // Get mentioned users var mentionedUsers = json["mentions"].EmptyIfNull().Select(ParseUser).ToArray(); return new Message(id, channelId, type, author, timestamp, editedTimestamp, content, attachments, embeds, reactions, mentionedUsers); } } }