mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Custom save locations for prints & stickers (#1041)
This commit is contained in:
@@ -38,12 +38,12 @@ namespace VRCX
|
||||
ProcessMonitor.Instance.ProcessStarted += Instance.OnProcessStateChanged;
|
||||
ProcessMonitor.Instance.ProcessExited += Instance.OnProcessStateChanged;
|
||||
}
|
||||
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Create Instance before Cef tries to bind it
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Computes the MD5 hash of the file represented by the specified base64-encoded string.
|
||||
/// </summary>
|
||||
@@ -68,7 +68,7 @@ namespace VRCX
|
||||
{
|
||||
using var fileMemoryStream = new MemoryStream(imageData);
|
||||
var image = new Bitmap(fileMemoryStream);
|
||||
|
||||
|
||||
// for APNG, check if image is png format and less than maxSize
|
||||
if ((!matchingDimensions || image.Width == image.Height) &&
|
||||
image.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png) &&
|
||||
@@ -78,7 +78,7 @@ namespace VRCX
|
||||
{
|
||||
return imageData;
|
||||
}
|
||||
|
||||
|
||||
if (image.Width > maxWidth)
|
||||
{
|
||||
var sizingFactor = image.Width / (double)maxWidth;
|
||||
@@ -101,14 +101,14 @@ namespace VRCX
|
||||
image.Dispose();
|
||||
image = newImage;
|
||||
}
|
||||
|
||||
|
||||
SaveToFileToUpload();
|
||||
for (int i = 0; i < 250 && imageData.Length > maxSize; i++)
|
||||
{
|
||||
SaveToFileToUpload();
|
||||
if (imageData.Length < maxSize)
|
||||
break;
|
||||
|
||||
|
||||
int newWidth;
|
||||
int newHeight;
|
||||
if (image.Width > image.Height)
|
||||
@@ -138,13 +138,13 @@ namespace VRCX
|
||||
imageData = imageSaveMemoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public byte[] ResizePrintImage(byte[] imageData)
|
||||
{
|
||||
var inputImage = ResizeImageToFitLimits(imageData, false, 1920, 1080);
|
||||
using var fileMemoryStream = new MemoryStream(inputImage);
|
||||
var image = new Bitmap(fileMemoryStream);
|
||||
|
||||
|
||||
// increase size to 1920x1080
|
||||
if (image.Width < 1920 || image.Height < 1080)
|
||||
{
|
||||
@@ -180,11 +180,11 @@ namespace VRCX
|
||||
graphics.DrawImage(image, new Rectangle(xOffset, yOffset, image.Width, image.Height));
|
||||
image.Dispose();
|
||||
image = newImage;
|
||||
|
||||
|
||||
using var imageSaveMemoryStream = new MemoryStream();
|
||||
image.Save(imageSaveMemoryStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
return imageSaveMemoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the signature of the file represented by the specified base64-encoded string using the librsync library.
|
||||
@@ -283,7 +283,7 @@ namespace VRCX
|
||||
{
|
||||
MainForm.Instance.Browser.SetZoomLevel(zoomLevel);
|
||||
}
|
||||
|
||||
|
||||
public async Task<double> GetZoom()
|
||||
{
|
||||
return await MainForm.Instance.Browser.GetZoomLevelAsync();
|
||||
@@ -340,7 +340,7 @@ namespace VRCX
|
||||
public void RestartApplication(bool isUpgrade)
|
||||
{
|
||||
var args = new List<string>();
|
||||
|
||||
|
||||
if (isUpgrade)
|
||||
args.Add(StartupArgs.VrcxLaunchArguments.IsUpgradePrefix);
|
||||
|
||||
@@ -597,7 +597,7 @@ namespace VRCX
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Flashes the window of the main form.
|
||||
/// </summary>
|
||||
@@ -629,7 +629,7 @@ namespace VRCX
|
||||
|
||||
public async Task<bool> SavePrintToFile(string url, string path, string fileName)
|
||||
{
|
||||
var folder = Path.Combine(GetVRChatPhotosLocation(), "Prints", MakeValidFileName(path));
|
||||
var folder = Path.Combine(GetUGCPhotoLocation(), "Prints", MakeValidFileName(path));
|
||||
Directory.CreateDirectory(folder);
|
||||
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
||||
if (File.Exists(filePath))
|
||||
@@ -640,7 +640,7 @@ namespace VRCX
|
||||
|
||||
public async Task<bool> SaveStickerToFile(string url, string path, string fileName)
|
||||
{
|
||||
var folder = Path.Combine(GetVRChatPhotosLocation(), "Stickers", MakeValidFileName(path));
|
||||
var folder = Path.Combine(GetUGCPhotoLocation(), "Stickers", MakeValidFileName(path));
|
||||
Directory.CreateDirectory(folder);
|
||||
var filePath = Path.Combine(folder, MakeValidFileName(fileName));
|
||||
if (File.Exists(filePath))
|
||||
@@ -648,7 +648,7 @@ namespace VRCX
|
||||
|
||||
return await ImageCache.SaveImageToFile(url, filePath);
|
||||
}
|
||||
|
||||
|
||||
public bool IsRunningUnderWine()
|
||||
{
|
||||
return Wine.GetIfWine();
|
||||
|
||||
@@ -6,6 +6,9 @@ using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.Win32;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VRCX
|
||||
{
|
||||
@@ -34,7 +37,7 @@ namespace VRCX
|
||||
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"Low\VRChat\VRChat";
|
||||
}
|
||||
|
||||
|
||||
public string GetVRChatPhotosLocation()
|
||||
{
|
||||
var json = ReadConfigFile();
|
||||
@@ -50,10 +53,37 @@ namespace VRCX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "VRChat");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder the user has selected for User-Generated content such as prints / stickers from the JS side.
|
||||
/// If there is no override on the folder, it returns the default VRChat Photos path.
|
||||
/// </summary>
|
||||
/// <returns>The UGC Photo Location.</returns>
|
||||
public string GetUGCPhotoLocation(string path = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return GetVRChatPhotosLocation();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
return GetVRChatPhotosLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetSteamUserdataPathFromRegistry()
|
||||
{
|
||||
string steamUserdataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Steam\userdata");
|
||||
@@ -85,20 +115,20 @@ namespace VRCX
|
||||
var steamUserdataPath = GetSteamUserdataPathFromRegistry();
|
||||
var screenshotPath = string.Empty;
|
||||
var latestWriteTime = DateTime.MinValue;
|
||||
if (!Directory.Exists(steamUserdataPath))
|
||||
if (!Directory.Exists(steamUserdataPath))
|
||||
return screenshotPath;
|
||||
|
||||
|
||||
var steamUserDirs = Directory.GetDirectories(steamUserdataPath);
|
||||
foreach (var steamUserDir in steamUserDirs)
|
||||
{
|
||||
var screenshotDir = Path.Combine(steamUserDir, @"760\remote\438100\screenshots");
|
||||
if (!Directory.Exists(screenshotDir))
|
||||
continue;
|
||||
|
||||
|
||||
var lastWriteTime = File.GetLastWriteTime(screenshotDir);
|
||||
if (lastWriteTime <= latestWriteTime)
|
||||
continue;
|
||||
|
||||
|
||||
latestWriteTime = lastWriteTime;
|
||||
screenshotPath = screenshotDir;
|
||||
}
|
||||
@@ -114,13 +144,13 @@ namespace VRCX
|
||||
{
|
||||
return Path.Combine(GetVRChatAppDataLocation(), "Cache-WindowsPlayer");
|
||||
}
|
||||
|
||||
|
||||
public bool OpenVrcxAppDataFolder()
|
||||
{
|
||||
var path = Program.AppDataDirectory;
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
|
||||
OpenFolderAndSelectItem(path, true);
|
||||
return true;
|
||||
}
|
||||
@@ -130,27 +160,37 @@ namespace VRCX
|
||||
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"Low\VRChat\VRChat";
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
|
||||
OpenFolderAndSelectItem(path, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public bool OpenVrcPhotosFolder()
|
||||
{
|
||||
var path = GetVRChatPhotosLocation();
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
|
||||
OpenFolderAndSelectItem(path, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public bool OpenUGCPhotosFolder(string ugcPath = "")
|
||||
{
|
||||
var path = GetUGCPhotoLocation(ugcPath);
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
OpenFolderAndSelectItem(path, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OpenVrcScreenshotsFolder()
|
||||
{
|
||||
var path = GetVRChatScreenshotsLocation();
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
|
||||
OpenFolderAndSelectItem(path, true);
|
||||
return true;
|
||||
}
|
||||
@@ -160,7 +200,7 @@ namespace VRCX
|
||||
var path = Path.Combine(Path.GetTempPath(), "VRChat", "VRChat", "Crashes");
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
|
||||
OpenFolderAndSelectItem(path, true);
|
||||
return true;
|
||||
}
|
||||
@@ -231,7 +271,7 @@ namespace VRCX
|
||||
Marshal.FreeCoTaskMem(pidlFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OpenFolderAndSelectItemFallback(string path)
|
||||
{
|
||||
if (!File.Exists(path) && !Directory.Exists(path))
|
||||
@@ -247,7 +287,45 @@ namespace VRCX
|
||||
Process.Start("explorer.exe", $"/select,\"{path}\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Opens a folder dialog to select a folder and pass it back to the JS side.
|
||||
/// </summary>
|
||||
/// <param name="defaultPath">The default path for the folder picker.</param>
|
||||
public async Task<string> OpenFolderSelectorDialog(string defaultPath = "")
|
||||
{
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
var staThread = new Thread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var openFolderDialog = new FolderBrowserDialog())
|
||||
{
|
||||
openFolderDialog.InitialDirectory = Directory.Exists(defaultPath) ? defaultPath : GetVRChatPhotosLocation();
|
||||
|
||||
var dialogResult = openFolderDialog.ShowDialog(MainForm.nativeWindow);
|
||||
if (dialogResult == DialogResult.OK)
|
||||
{
|
||||
tcs.SetResult(openFolderDialog.SelectedPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs.SetResult(defaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
});
|
||||
|
||||
staThread.SetApartmentState(ApartmentState.STA);
|
||||
staThread.Start();
|
||||
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
private static readonly Regex _folderRegex = new Regex(string.Format(@"([{0}]*\.+$)|([{0}]+)",
|
||||
Regex.Escape(new string(Path.GetInvalidPathChars()))));
|
||||
|
||||
@@ -260,7 +338,7 @@ namespace VRCX
|
||||
name = name.Replace("\\", "");
|
||||
name = _folderRegex.Replace(name, "");
|
||||
name = _fileRegex.Replace(name, "");
|
||||
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace VRCX
|
||||
public partial class MainForm : WinformBase
|
||||
{
|
||||
public static MainForm Instance;
|
||||
public static NativeWindow nativeWindow;
|
||||
private static NLog.Logger jslogger = NLog.LogManager.GetLogger("Javascript");
|
||||
public ChromiumWebBrowser Browser;
|
||||
private readonly Timer _saveTimer;
|
||||
@@ -43,6 +44,7 @@ namespace VRCX
|
||||
{
|
||||
Instance = this;
|
||||
InitializeComponent();
|
||||
nativeWindow = NativeWindow.FromHandle(this.Handle);
|
||||
|
||||
// adding a 5s delay here to avoid excessive writes to disk
|
||||
_saveTimer = new Timer();
|
||||
|
||||
Reference in New Issue
Block a user