|
|
|
@ -12,10 +12,10 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
{
|
|
|
|
|
private User ParseUser(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var id = json["id"].Value<string>();
|
|
|
|
|
var discriminator = json["discriminator"].Value<int>();
|
|
|
|
|
var name = json["username"].Value<string>();
|
|
|
|
|
var avatarHash = json["avatar"].Value<string>();
|
|
|
|
|
var id = json["id"]!.Value<string>();
|
|
|
|
|
var discriminator = json["discriminator"]!.Value<int>();
|
|
|
|
|
var name = json["username"]!.Value<string>();
|
|
|
|
|
var avatarHash = json["avatar"]!.Value<string>();
|
|
|
|
|
var isBot = json["bot"]?.Value<bool>() ?? false;
|
|
|
|
|
|
|
|
|
|
return new User(id, discriminator, name, avatarHash, isBot);
|
|
|
|
@ -23,9 +23,9 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
|
|
|
|
|
private Guild ParseGuild(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var id = json["id"].Value<string>();
|
|
|
|
|
var name = json["name"].Value<string>();
|
|
|
|
|
var iconHash = json["icon"].Value<string>();
|
|
|
|
|
var id = json["id"]!.Value<string>();
|
|
|
|
|
var name = json["name"]!.Value<string>();
|
|
|
|
|
var iconHash = json["icon"]!.Value<string>();
|
|
|
|
|
|
|
|
|
|
return new Guild(id, name, iconHash);
|
|
|
|
|
}
|
|
|
|
@ -33,23 +33,23 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
private Channel ParseChannel(JToken json)
|
|
|
|
|
{
|
|
|
|
|
// Get basic data
|
|
|
|
|
var id = json["id"].Value<string>();
|
|
|
|
|
var id = json["id"]!.Value<string>();
|
|
|
|
|
var parentId = json["parent_id"]?.Value<string>();
|
|
|
|
|
var type = (ChannelType) json["type"].Value<int>();
|
|
|
|
|
var type = (ChannelType) json["type"]!.Value<int>();
|
|
|
|
|
var topic = json["topic"]?.Value<string>();
|
|
|
|
|
|
|
|
|
|
// Try to extract guild ID
|
|
|
|
|
var guildId = json["guild_id"]?.Value<string>();
|
|
|
|
|
|
|
|
|
|
// If the guild ID is blank, it's direct messages
|
|
|
|
|
if (guildId.IsNullOrWhiteSpace())
|
|
|
|
|
if (string.IsNullOrWhiteSpace(guildId))
|
|
|
|
|
guildId = Guild.DirectMessages.Id;
|
|
|
|
|
|
|
|
|
|
// Try to extract name
|
|
|
|
|
var name = json["name"]?.Value<string>();
|
|
|
|
|
|
|
|
|
|
// If the name is blank, it's direct messages
|
|
|
|
|
if (name.IsNullOrWhiteSpace())
|
|
|
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
|
|
|
name = json["recipients"].Select(ParseUser).Select(u => u.Name).JoinToString(", ");
|
|
|
|
|
|
|
|
|
|
return new Channel(id, parentId, guildId, name, topic, type);
|
|
|
|
@ -57,20 +57,20 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
|
|
|
|
|
private Role ParseRole(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var id = json["id"].Value<string>();
|
|
|
|
|
var name = json["name"].Value<string>();
|
|
|
|
|
var id = json["id"]!.Value<string>();
|
|
|
|
|
var name = json["name"]!.Value<string>();
|
|
|
|
|
|
|
|
|
|
return new Role(id, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Attachment ParseAttachment(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var id = json["id"].Value<string>();
|
|
|
|
|
var url = json["url"].Value<string>();
|
|
|
|
|
var id = json["id"]!.Value<string>();
|
|
|
|
|
var url = json["url"]!.Value<string>();
|
|
|
|
|
var width = json["width"]?.Value<int>();
|
|
|
|
|
var height = json["height"]?.Value<int>();
|
|
|
|
|
var fileName = json["filename"].Value<string>();
|
|
|
|
|
var fileSizeBytes = json["size"].Value<long>();
|
|
|
|
|
var fileName = json["filename"]!.Value<string>();
|
|
|
|
|
var fileSizeBytes = json["size"]!.Value<long>();
|
|
|
|
|
|
|
|
|
|
var fileSize = new FileSize(fileSizeBytes);
|
|
|
|
|
|
|
|
|
@ -88,8 +88,8 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
|
|
|
|
|
private EmbedField ParseEmbedField(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var name = json["name"].Value<string>();
|
|
|
|
|
var value = json["value"].Value<string>();
|
|
|
|
|
var name = json["name"]!.Value<string>();
|
|
|
|
|
var value = json["value"]!.Value<string>();
|
|
|
|
|
var isInline = json["inline"]?.Value<bool>() ?? false;
|
|
|
|
|
|
|
|
|
|
return new EmbedField(name, value, isInline);
|
|
|
|
@ -106,7 +106,7 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
|
|
|
|
|
private EmbedFooter ParseEmbedFooter(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var text = json["text"].Value<string>();
|
|
|
|
|
var text = json["text"]!.Value<string>();
|
|
|
|
|
var iconUrl = json["icon_url"]?.Value<string>();
|
|
|
|
|
|
|
|
|
|
return new EmbedFooter(text, iconUrl);
|
|
|
|
@ -122,23 +122,23 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
|
|
|
|
|
// Get color
|
|
|
|
|
var color = json["color"] != null
|
|
|
|
|
? Color.FromArgb(json["color"].Value<int>()).ResetAlpha()
|
|
|
|
|
? Color.FromArgb(json["color"]!.Value<int>()).ResetAlpha()
|
|
|
|
|
: Color.FromArgb(79, 84, 92); // default color
|
|
|
|
|
|
|
|
|
|
// Get author
|
|
|
|
|
var author = json["author"] != null ? ParseEmbedAuthor(json["author"]) : null;
|
|
|
|
|
var author = json["author"] != null ? ParseEmbedAuthor(json["author"]!) : null;
|
|
|
|
|
|
|
|
|
|
// Get fields
|
|
|
|
|
var fields = json["fields"].EmptyIfNull().Select(ParseEmbedField).ToArray();
|
|
|
|
|
var fields = (json["fields"] ?? Enumerable.Empty<JToken>()).Select(ParseEmbedField).ToArray();
|
|
|
|
|
|
|
|
|
|
// Get thumbnail
|
|
|
|
|
var thumbnail = json["thumbnail"] != null ? ParseEmbedImage(json["thumbnail"]) : null;
|
|
|
|
|
var thumbnail = json["thumbnail"] != null ? ParseEmbedImage(json["thumbnail"]!) : null;
|
|
|
|
|
|
|
|
|
|
// Get image
|
|
|
|
|
var image = json["image"] != null ? ParseEmbedImage(json["image"]) : null;
|
|
|
|
|
var image = json["image"] != null ? ParseEmbedImage(json["image"]!) : null;
|
|
|
|
|
|
|
|
|
|
// Get footer
|
|
|
|
|
var footer = json["footer"] != null ? ParseEmbedFooter(json["footer"]) : null;
|
|
|
|
|
var footer = json["footer"] != null ? ParseEmbedFooter(json["footer"]!) : null;
|
|
|
|
|
|
|
|
|
|
return new Embed(title, url, timestamp, color, author, description, fields, thumbnail, image, footer);
|
|
|
|
|
}
|
|
|
|
@ -146,7 +146,7 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
private Emoji ParseEmoji(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var id = json["id"]?.Value<string>();
|
|
|
|
|
var name = json["name"]?.Value<string>();
|
|
|
|
|
var name = json["name"]!.Value<string>();
|
|
|
|
|
var isAnimated = json["animated"]?.Value<bool>() ?? false;
|
|
|
|
|
|
|
|
|
|
return new Emoji(id, name, isAnimated);
|
|
|
|
@ -154,8 +154,8 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
|
|
|
|
|
private Reaction ParseReaction(JToken json)
|
|
|
|
|
{
|
|
|
|
|
var count = json["count"].Value<int>();
|
|
|
|
|
var emoji = ParseEmoji(json["emoji"]);
|
|
|
|
|
var count = json["count"]!.Value<int>();
|
|
|
|
|
var emoji = ParseEmoji(json["emoji"]!);
|
|
|
|
|
|
|
|
|
|
return new Reaction(count, emoji);
|
|
|
|
|
}
|
|
|
|
@ -163,12 +163,12 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
private Message ParseMessage(JToken json)
|
|
|
|
|
{
|
|
|
|
|
// Get basic data
|
|
|
|
|
var id = json["id"].Value<string>();
|
|
|
|
|
var channelId = json["channel_id"].Value<string>();
|
|
|
|
|
var timestamp = json["timestamp"].Value<DateTime>().ToDateTimeOffset();
|
|
|
|
|
var id = json["id"]!.Value<string>();
|
|
|
|
|
var channelId = json["channel_id"]!.Value<string>();
|
|
|
|
|
var timestamp = json["timestamp"]!.Value<DateTime>().ToDateTimeOffset();
|
|
|
|
|
var editedTimestamp = json["edited_timestamp"]?.Value<DateTime?>()?.ToDateTimeOffset();
|
|
|
|
|
var content = json["content"].Value<string>();
|
|
|
|
|
var type = (MessageType) json["type"].Value<int>();
|
|
|
|
|
var content = json["content"]!.Value<string>();
|
|
|
|
|
var type = (MessageType) json["type"]!.Value<int>();
|
|
|
|
|
|
|
|
|
|
// Workarounds for non-default types
|
|
|
|
|
if (type == MessageType.RecipientAdd)
|
|
|
|
@ -187,22 +187,22 @@ namespace DiscordChatExporter.Core.Services
|
|
|
|
|
content = "Joined the server.";
|
|
|
|
|
|
|
|
|
|
// Get author
|
|
|
|
|
var author = ParseUser(json["author"]);
|
|
|
|
|
var author = ParseUser(json["author"]!);
|
|
|
|
|
|
|
|
|
|
// Get attachments
|
|
|
|
|
var attachments = json["attachments"].EmptyIfNull().Select(ParseAttachment).ToArray();
|
|
|
|
|
var attachments = (json["attachments"] ?? Enumerable.Empty<JToken>()).Select(ParseAttachment).ToArray();
|
|
|
|
|
|
|
|
|
|
// Get embeds
|
|
|
|
|
var embeds = json["embeds"].EmptyIfNull().Select(ParseEmbed).ToArray();
|
|
|
|
|
var embeds = (json["embeds"] ?? Enumerable.Empty<JToken>()).Select(ParseEmbed).ToArray();
|
|
|
|
|
|
|
|
|
|
// Get reactions
|
|
|
|
|
var reactions = json["reactions"].EmptyIfNull().Select(ParseReaction).ToArray();
|
|
|
|
|
var reactions = (json["reactions"] ?? Enumerable.Empty<JToken>()).Select(ParseReaction).ToArray();
|
|
|
|
|
|
|
|
|
|
// Get mentioned users
|
|
|
|
|
var mentionedUsers = json["mentions"].EmptyIfNull().Select(ParseUser).ToArray();
|
|
|
|
|
var mentionedUsers = (json["mentions"] ?? Enumerable.Empty<JToken>()).Select(ParseUser).ToArray();
|
|
|
|
|
|
|
|
|
|
// Get whether this message is pinned
|
|
|
|
|
var isPinned = json["pinned"].Value<bool>();
|
|
|
|
|
var isPinned = json["pinned"]!.Value<bool>();
|
|
|
|
|
|
|
|
|
|
return new Message(id, channelId, type, author, timestamp, editedTimestamp, content, attachments, embeds,
|
|
|
|
|
reactions, mentionedUsers, isPinned);
|
|
|
|
|