mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Screenshot metadata dialog (#490)
* docs: Add json schema for screenshot metadata * feat(.NET): Add function to open a file and read screenshot metadata to AppApi * refactor(.NET): Check initial file dialog directory before set Paranoia is fun * refactor(.NET): Stop reading entire png files into memory to check 8 bytes * refactor(.NET): Handle endianness and keyword encoding correctly for screenshots * docs: Add xmldocs and some comments to parts of the screenshot helper * screenshot metadata dialog * screenshot metadata dialog 1 * fix: file dialog open bool not resetting properly * screenshot metadata dialog 2 * fix: Stop png parser from dying on bad files Parser would keep reading past a file's IEND chunk, and it finally found one that had junk data past IEND. It died. This fixes that. It also encapsulates the Read function in a try/catch so VRCX doesn't crash if it fails due to a corrupted file. * fix: buggy carousel transition animation --------- Co-authored-by: Teacup <git@teadev.xyz>
This commit is contained in:
118
AppApi.cs
118
AppApi.cs
@@ -32,6 +32,7 @@ namespace VRCX
|
||||
public static readonly AppApi Instance;
|
||||
|
||||
private static readonly MD5 _hasher = MD5.Create();
|
||||
private static bool dialogOpen;
|
||||
|
||||
static AppApi()
|
||||
{
|
||||
@@ -644,6 +645,123 @@ namespace VRCX
|
||||
ScreenshotHelper.WritePNGDescription(path, metadataString);
|
||||
}
|
||||
|
||||
// Create a function that opens a file dialog so a user can choose a .png file. Print the name of the file after it is chosen
|
||||
public void OpenScreenshotFileDialog()
|
||||
{
|
||||
if (dialogOpen) return;
|
||||
dialogOpen = true;
|
||||
|
||||
var thread = new Thread(() =>
|
||||
{
|
||||
using (var openFileDialog = new OpenFileDialog())
|
||||
{
|
||||
openFileDialog.DefaultExt = ".png";
|
||||
openFileDialog.Filter = "PNG Files (*.png)|*.png";
|
||||
openFileDialog.FilterIndex = 1;
|
||||
openFileDialog.RestoreDirectory = true;
|
||||
|
||||
var initialPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "VRChat");
|
||||
if (Directory.Exists(initialPath))
|
||||
{
|
||||
openFileDialog.InitialDirectory = initialPath;
|
||||
}
|
||||
|
||||
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
||||
{
|
||||
dialogOpen = false;
|
||||
return;
|
||||
}
|
||||
|
||||
dialogOpen = false;
|
||||
|
||||
var path = openFileDialog.FileName;
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return;
|
||||
|
||||
GetScreenshotMetadata(path);
|
||||
}
|
||||
});
|
||||
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
public void GetScreenshotMetadata(string path)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
const string fileNamePrefix = "VRChat_";
|
||||
var metadata = new JObject();
|
||||
|
||||
if (File.Exists(path) && path.EndsWith(".png") && fileName.StartsWith(fileNamePrefix))
|
||||
{
|
||||
string metadataString = null;
|
||||
bool readPNGFailed = false;
|
||||
|
||||
try
|
||||
{
|
||||
metadataString = ScreenshotHelper.ReadPNGDescription(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
metadata.Add("error", $"VRCX encountered an error while trying to parse this file. The file might be an invalid/corrupted PNG file.\n({ex.Message})");
|
||||
readPNGFailed = true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(metadataString))
|
||||
{
|
||||
if (metadataString.StartsWith("lfs") || metadataString.StartsWith("screenshotmanager"))
|
||||
{
|
||||
try
|
||||
{
|
||||
metadata = ScreenshotHelper.ParseLfsPicture(metadataString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
metadata.Add("error", $"This file contains invalid LFS/SSM metadata unable to be parsed by VRCX. \n({ex.Message})\n Text: {metadataString}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
metadata = JObject.Parse(metadataString);
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
{
|
||||
metadata.Add("error", $"This file contains invalid metadata unable to be parsed by VRCX. \n({ex.Message})\n Text: {metadataString}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!readPNGFailed)
|
||||
metadata.Add("error", "No metadata found in this file.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
metadata.Add("error", "Invalid file selected. Please select a valid VRChat screenshot.");
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(Path.GetDirectoryName(path), "*.png");
|
||||
var index = Array.IndexOf(files, path);
|
||||
if (index > 0)
|
||||
{
|
||||
metadata.Add("previousFilePath", files[index - 1]);
|
||||
}
|
||||
|
||||
if (index < files.Length - 1)
|
||||
{
|
||||
metadata.Add("nextFilePath", files[index + 1]);
|
||||
}
|
||||
|
||||
metadata.Add("fileName", fileName);
|
||||
metadata.Add("filePath", path);
|
||||
metadata.Add("fileSize", $"{(new FileInfo(path).Length / 1024f / 1024f).ToString("0.00")} MB");
|
||||
ExecuteAppFunction("displayScreenshotMetadata", metadata.ToString(Formatting.Indented));
|
||||
}
|
||||
|
||||
public void FlashWindow()
|
||||
{
|
||||
MainForm.Instance.BeginInvoke(new MethodInvoker(() => { WinformThemer.Flash(MainForm.Instance); }));
|
||||
|
||||
Reference in New Issue
Block a user