Update VRC image metadata parsing

This commit is contained in:
Natsumi
2025-08-01 16:55:59 +12:00
parent 3c21d88efa
commit 592983673d
5 changed files with 47 additions and 23 deletions

View File

@@ -170,15 +170,15 @@ namespace VRCX
{
var xmlString = metadataString.Substring(xmlIndex);
// everything after index
var result = ParseVRCPrint(xmlString.Substring(xmlIndex - 7));
var result = ParseVRCImage(xmlString);
result.SourceFile = path;
return result;
}
catch (Exception ex)
{
Logger.Error(ex, "Failed to parse VRCPrint XML metadata for file '{0}'", path);
return ScreenshotMetadata.JustError(path, "Failed to parse VRCPrint metadata.");
Logger.Error(ex, "Failed to parse VRC image XML metadata for file '{0}'", path);
return ScreenshotMetadata.JustError(path, "Failed to parse VRC image metadata.");
}
}
@@ -204,7 +204,7 @@ namespace VRCX
}
}
public static ScreenshotMetadata ParseVRCPrint(string xmlString)
public static ScreenshotMetadata ParseVRCImage(string xmlString)
{
var doc = new XmlDocument();
doc.LoadXml(xmlString);
@@ -217,10 +217,22 @@ namespace VRCX
nsManager.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");
nsManager.AddNamespace("vrc", "http://ns.vrchat.com/vrc/1.0/");
var creatorTool = root.SelectSingleNode("//xmp:CreatorTool", nsManager)?.InnerText;
var authorId = root.SelectSingleNode("//xmp:Author", nsManager)?.InnerText;
var authorName = root.SelectSingleNode("//xmp:Author", nsManager)?.InnerText; // legacy, it was authorId
var dateTime = root.SelectSingleNode("//tiff:DateTime", nsManager)?.InnerText;
var note = root.SelectSingleNode("//dc:title/rdf:Alt/rdf:li", nsManager)?.InnerText;
var worldId = root.SelectSingleNode("//vrc:World", nsManager)?.InnerText;
var worldId = root.SelectSingleNode("//vrc:WorldID", nsManager)?.InnerText;
var worldDisplayName = root.SelectSingleNode("//vrc:WorldDisplayName", nsManager)?.InnerText; // new, 01.08.2025
var authorId = root.SelectSingleNode("//vrc:AuthorID", nsManager)?.InnerText; // new, 01.08.2025
if (string.IsNullOrEmpty(worldId))
worldId = root.SelectSingleNode("//vrc:World", nsManager)?.InnerText; // legacy, it's gone now
if (string.IsNullOrEmpty(authorId))
{
// If authorId is not set, we assume legacy metadata format where authorName is used as authorId.
authorId = authorName;
authorName = null;
}
return new ScreenshotMetadata
{
@@ -229,13 +241,13 @@ namespace VRCX
Author = new ScreenshotMetadata.AuthorDetail
{
Id = authorId,
DisplayName = null
DisplayName = authorName
},
World = new ScreenshotMetadata.WorldDetail
{
Id = worldId,
InstanceId = worldId,
Name = null
Name = worldDisplayName
},
Timestamp = DateTime.TryParse(dateTime, out var dt) ? dt : null,
Note = note
@@ -254,16 +266,21 @@ namespace VRCX
/// </returns>
public static bool WritePNGDescription(string path, string text)
{
if (!File.Exists(path) || !IsPNGFile(path)) return false;
if (!File.Exists(path) || !IsPNGFile(path))
return false;
var png = File.ReadAllBytes(path);
var newChunkIndex = FindEndOfChunk(png, "IHDR");
if (newChunkIndex == -1) return false;
if (newChunkIndex == -1)
return false;
// If this file already has a text chunk, chances are it got logged twice for some reason. Stop.
// var existingiTXt = FindChunkIndex(png, "iTXt");
// if (existingiTXt != -1) return false;
var screenShotMetadata = GetScreenshotMetadata(path);
if (screenShotMetadata != null && screenShotMetadata.Application == "VRCX")
{
Logger.Error("Screenshot file '{0}' already has VRCX metadata", path);
return false;
}
var newChunk = new PNGChunk("iTXt");
newChunk.InitializeTextChunk("Description", text);

View File

@@ -96,10 +96,10 @@
<PackageReference Include="DiscordRichPresence" Version="1.3.0.28" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="6.0.1" />
<PackageReference Include="NLog" Version="6.0.2" />
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.6" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />

View File

@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<BaseIntermediateOutputPath>obj1\</BaseIntermediateOutputPath>
<OutputPath>..\build\Electron\</OutputPath>
@@ -98,10 +98,10 @@
<PackageReference Include="DiscordRichPresence" Version="1.3.0.28" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="6.0.1" />
<PackageReference Include="NLog" Version="6.0.2" />
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.6" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />