diff options
Diffstat (limited to 'src/Ryujinx.Ui.Common/Helper')
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/CommandLineState.cs | 99 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs | 50 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs | 202 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs | 62 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs | 160 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/OpenHelper.cs | 112 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/SetupValidator.cs | 114 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs | 162 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/TitleHelper.cs | 30 | ||||
| -rw-r--r-- | src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs | 219 |
10 files changed, 0 insertions, 1210 deletions
diff --git a/src/Ryujinx.Ui.Common/Helper/CommandLineState.cs b/src/Ryujinx.Ui.Common/Helper/CommandLineState.cs deleted file mode 100644 index 714cf2f0..00000000 --- a/src/Ryujinx.Ui.Common/Helper/CommandLineState.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Ryujinx.Common.Logging; -using System.Collections.Generic; - -namespace Ryujinx.Ui.Common.Helper -{ - public static class CommandLineState - { - public static string[] Arguments { get; private set; } - - public static bool? OverrideDockedMode { get; private set; } - public static string OverrideGraphicsBackend { get; private set; } - public static string OverrideHideCursor { get; private set; } - public static string BaseDirPathArg { get; private set; } - public static string Profile { get; private set; } - public static string LaunchPathArg { get; private set; } - public static bool StartFullscreenArg { get; private set; } - - public static void ParseArguments(string[] args) - { - List<string> arguments = new(); - - // Parse Arguments. - for (int i = 0; i < args.Length; ++i) - { - string arg = args[i]; - - switch (arg) - { - case "-r": - case "--root-data-dir": - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - BaseDirPathArg = args[++i]; - - arguments.Add(arg); - arguments.Add(args[i]); - break; - case "-p": - case "--profile": - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - Profile = args[++i]; - - arguments.Add(arg); - arguments.Add(args[i]); - break; - case "-f": - case "--fullscreen": - StartFullscreenArg = true; - - arguments.Add(arg); - break; - case "-g": - case "--graphics-backend": - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - OverrideGraphicsBackend = args[++i]; - break; - case "--docked-mode": - OverrideDockedMode = true; - break; - case "--handheld-mode": - OverrideDockedMode = false; - break; - case "--hide-cursor": - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - OverrideHideCursor = args[++i]; - break; - default: - LaunchPathArg = arg; - break; - } - } - - Arguments = arguments.ToArray(); - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs b/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs deleted file mode 100644 index 65155641..00000000 --- a/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Ui.Common.Helper -{ - public static partial class ConsoleHelper - { - public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows(); - - public static void SetConsoleWindowState(bool show) - { - if (OperatingSystem.IsWindows()) - { - SetConsoleWindowStateWindows(show); - } - else if (show == false) - { - Logger.Warning?.Print(LogClass.Application, "OS doesn't support hiding console window"); - } - } - - [SupportedOSPlatform("windows")] - private static void SetConsoleWindowStateWindows(bool show) - { - const int SW_HIDE = 0; - const int SW_SHOW = 5; - - IntPtr hWnd = GetConsoleWindow(); - - if (hWnd == IntPtr.Zero) - { - Logger.Warning?.Print(LogClass.Application, "Attempted to show/hide console window but console window does not exist"); - return; - } - - ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); - } - - [SupportedOSPlatform("windows")] - [LibraryImport("kernel32")] - private static partial IntPtr GetConsoleWindow(); - - [SupportedOSPlatform("windows")] - [LibraryImport("user32")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool ShowWindow(IntPtr hWnd, int nCmdShow); - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs deleted file mode 100644 index daa59d25..00000000 --- a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs +++ /dev/null @@ -1,202 +0,0 @@ -using Microsoft.Win32; -using Ryujinx.Common; -using Ryujinx.Common.Logging; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Ui.Common.Helper -{ - public static partial class FileAssociationHelper - { - private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" }; - - [SupportedOSPlatform("linux")] - private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime"); - - private const int SHCNE_ASSOCCHANGED = 0x8000000; - private const int SHCNF_FLUSH = 0x1000; - - [LibraryImport("shell32.dll", SetLastError = true)] - public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); - - public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild; - - [SupportedOSPlatform("linux")] - private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml")); - - [SupportedOSPlatform("linux")] - private static bool InstallLinuxMimeTypes(bool uninstall = false) - { - string installKeyword = uninstall ? "uninstall" : "install"; - - if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux())) - { - string mimeTypesFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mime", "Ryujinx.xml"); - string additionalArgs = !uninstall ? "--novendor" : ""; - - using Process mimeProcess = new(); - - mimeProcess.StartInfo.FileName = "xdg-mime"; - mimeProcess.StartInfo.Arguments = $"{installKeyword} {additionalArgs} --mode user {mimeTypesFile}"; - - mimeProcess.Start(); - mimeProcess.WaitForExit(); - - if (mimeProcess.ExitCode != 0) - { - Logger.Error?.PrintMsg(LogClass.Application, $"Unable to {installKeyword} mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}"); - - return false; - } - - using Process updateMimeProcess = new(); - - updateMimeProcess.StartInfo.FileName = "update-mime-database"; - updateMimeProcess.StartInfo.Arguments = _mimeDbPath; - - updateMimeProcess.Start(); - updateMimeProcess.WaitForExit(); - - if (updateMimeProcess.ExitCode != 0) - { - Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}"); - } - } - - return true; - } - - [SupportedOSPlatform("windows")] - private static bool AreMimeTypesRegisteredWindows() - { - static bool CheckRegistering(string ext) - { - RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}"); - - if (key is null) - { - return false; - } - - var openCmd = key.OpenSubKey(@"shell\open\command"); - - string keyValue = (string)openCmd.GetValue(""); - - return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName)); - } - - bool registered = false; - - foreach (string ext in _fileExtensions) - { - registered |= CheckRegistering(ext); - } - - return registered; - } - - [SupportedOSPlatform("windows")] - private static bool InstallWindowsMimeTypes(bool uninstall = false) - { - static bool RegisterExtension(string ext, bool uninstall = false) - { - string keyString = @$"Software\Classes\{ext}"; - - if (uninstall) - { - // If the types don't already exist, there's nothing to do and we can call this operation successful. - if (!AreMimeTypesRegisteredWindows()) - { - return true; - } - Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}"); - Registry.CurrentUser.DeleteSubKeyTree(keyString); - Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}"); - } - else - { - using var key = Registry.CurrentUser.CreateSubKey(keyString); - - if (key is null) - { - return false; - } - - Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}"); - using var openCmd = key.CreateSubKey(@"shell\open\command"); - openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\""); - Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}"); - - } - - return true; - } - - bool registered = false; - - foreach (string ext in _fileExtensions) - { - registered |= RegisterExtension(ext, uninstall); - } - - // Notify Explorer the file association has been changed. - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero); - - return registered; - } - - public static bool AreMimeTypesRegistered() - { - if (OperatingSystem.IsLinux()) - { - return AreMimeTypesRegisteredLinux(); - } - - if (OperatingSystem.IsWindows()) - { - return AreMimeTypesRegisteredWindows(); - } - - // TODO: Add macOS support. - - return false; - } - - public static bool Install() - { - if (OperatingSystem.IsLinux()) - { - return InstallLinuxMimeTypes(); - } - - if (OperatingSystem.IsWindows()) - { - return InstallWindowsMimeTypes(); - } - - // TODO: Add macOS support. - - return false; - } - - public static bool Uninstall() - { - if (OperatingSystem.IsLinux()) - { - return InstallLinuxMimeTypes(true); - } - - if (OperatingSystem.IsWindows()) - { - return InstallWindowsMimeTypes(true); - } - - // TODO: Add macOS support. - - return false; - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs b/src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs deleted file mode 100644 index bf647719..00000000 --- a/src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.Versioning; - -namespace Ryujinx.Ui.Common.Helper -{ - [SupportedOSPlatform("linux")] - public static class LinuxHelper - { - // NOTE: This value was determined by manual tests and might need to be increased again. - public const int RecommendedVmMaxMapCount = 524288; - public const string VmMaxMapCountPath = "/proc/sys/vm/max_map_count"; - public const string SysCtlConfigPath = "/etc/sysctl.d/99-Ryujinx.conf"; - public static int VmMaxMapCount => int.Parse(File.ReadAllText(VmMaxMapCountPath)); - public static string PkExecPath { get; } = GetBinaryPath("pkexec"); - - private static string GetBinaryPath(string binary) - { - string pathVar = Environment.GetEnvironmentVariable("PATH"); - - if (pathVar is null || string.IsNullOrEmpty(binary)) - { - return null; - } - - foreach (var searchPath in pathVar.Split(":", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) - { - string binaryPath = Path.Combine(searchPath, binary); - - if (File.Exists(binaryPath)) - { - return binaryPath; - } - } - - return null; - } - - public static int RunPkExec(string command) - { - if (PkExecPath == null) - { - return 1; - } - - using Process process = new() - { - StartInfo = - { - FileName = PkExecPath, - ArgumentList = { "sh", "-c", command }, - }, - }; - - process.Start(); - process.WaitForExit(); - - return process.ExitCode; - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs b/src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs deleted file mode 100644 index af8723e2..00000000 --- a/src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Ui.Common.Helper -{ - [SupportedOSPlatform("macos")] - public static partial class ObjectiveC - { - private const string ObjCRuntime = "/usr/lib/libobjc.A.dylib"; - - [LibraryImport(ObjCRuntime, StringMarshalling = StringMarshalling.Utf8)] - private static partial IntPtr sel_getUid(string name); - - [LibraryImport(ObjCRuntime, StringMarshalling = StringMarshalling.Utf8)] - private static partial IntPtr objc_getClass(string name); - - [LibraryImport(ObjCRuntime)] - private static partial void objc_msgSend(IntPtr receiver, Selector selector); - - [LibraryImport(ObjCRuntime)] - private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value); - - [LibraryImport(ObjCRuntime)] - private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value); - - [LibraryImport(ObjCRuntime)] - private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point); - - [LibraryImport(ObjCRuntime)] - private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value); - - [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")] - private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector); - - [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")] - private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector, IntPtr param); - - [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend", StringMarshalling = StringMarshalling.Utf8)] - private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector, string param); - - [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool bool_objc_msgSend(IntPtr receiver, Selector selector, IntPtr param); - - public readonly struct Object - { - public readonly IntPtr ObjPtr; - - private Object(IntPtr pointer) - { - ObjPtr = pointer; - } - - public Object(string name) - { - ObjPtr = objc_getClass(name); - } - - public void SendMessage(Selector selector) - { - objc_msgSend(ObjPtr, selector); - } - - public void SendMessage(Selector selector, byte value) - { - objc_msgSend(ObjPtr, selector, value); - } - - public void SendMessage(Selector selector, Object obj) - { - objc_msgSend(ObjPtr, selector, obj.ObjPtr); - } - - public void SendMessage(Selector selector, NSRect point) - { - objc_msgSend(ObjPtr, selector, point); - } - - public void SendMessage(Selector selector, double value) - { - objc_msgSend(ObjPtr, selector, value); - } - - public Object GetFromMessage(Selector selector) - { - return new Object(IntPtr_objc_msgSend(ObjPtr, selector)); - } - - public Object GetFromMessage(Selector selector, Object obj) - { - return new Object(IntPtr_objc_msgSend(ObjPtr, selector, obj.ObjPtr)); - } - - public Object GetFromMessage(Selector selector, NSString nsString) - { - return new Object(IntPtr_objc_msgSend(ObjPtr, selector, nsString.StrPtr)); - } - - public Object GetFromMessage(Selector selector, string param) - { - return new Object(IntPtr_objc_msgSend(ObjPtr, selector, param)); - } - - public bool GetBoolFromMessage(Selector selector, Object obj) - { - return bool_objc_msgSend(ObjPtr, selector, obj.ObjPtr); - } - } - - public readonly struct Selector - { - public readonly IntPtr SelPtr; - - private Selector(string name) - { - SelPtr = sel_getUid(name); - } - - public static implicit operator Selector(string value) => new(value); - } - - public readonly struct NSString - { - public readonly IntPtr StrPtr; - - public NSString(string aString) - { - IntPtr nsString = objc_getClass("NSString"); - StrPtr = IntPtr_objc_msgSend(nsString, "stringWithUTF8String:", aString); - } - - public static implicit operator IntPtr(NSString nsString) => nsString.StrPtr; - } - - public readonly struct NSPoint - { - public readonly double X; - public readonly double Y; - - public NSPoint(double x, double y) - { - X = x; - Y = y; - } - } - - public readonly struct NSRect - { - public readonly NSPoint Pos; - public readonly NSPoint Size; - - public NSRect(double x, double y, double width, double height) - { - Pos = new NSPoint(x, y); - Size = new NSPoint(width, height); - } - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs b/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs deleted file mode 100644 index 04ebbf3b..00000000 --- a/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs +++ /dev/null @@ -1,112 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; - -namespace Ryujinx.Ui.Common.Helper -{ - public static partial class OpenHelper - { - [LibraryImport("shell32.dll", SetLastError = true)] - private static partial int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, IntPtr apidl, uint dwFlags); - - [LibraryImport("shell32.dll", SetLastError = true)] - private static partial void ILFree(IntPtr pidlList); - - [LibraryImport("shell32.dll", SetLastError = true)] - private static partial IntPtr ILCreateFromPathW([MarshalAs(UnmanagedType.LPWStr)] string pszPath); - - public static void OpenFolder(string path) - { - if (Directory.Exists(path)) - { - Process.Start(new ProcessStartInfo - { - FileName = path, - UseShellExecute = true, - Verb = "open", - }); - } - else - { - Logger.Notice.Print(LogClass.Application, $"Directory \"{path}\" doesn't exist!"); - } - } - - public static void LocateFile(string path) - { - if (File.Exists(path)) - { - if (OperatingSystem.IsWindows()) - { - IntPtr pidlList = ILCreateFromPathW(path); - if (pidlList != IntPtr.Zero) - { - try - { - Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0)); - } - finally - { - ILFree(pidlList); - } - } - } - else if (OperatingSystem.IsMacOS()) - { - ObjectiveC.NSString nsStringPath = new(path); - ObjectiveC.Object nsUrl = new("NSURL"); - var urlPtr = nsUrl.GetFromMessage("fileURLWithPath:", nsStringPath); - - ObjectiveC.Object nsArray = new("NSArray"); - ObjectiveC.Object urlArray = nsArray.GetFromMessage("arrayWithObject:", urlPtr); - - ObjectiveC.Object nsWorkspace = new("NSWorkspace"); - ObjectiveC.Object sharedWorkspace = nsWorkspace.GetFromMessage("sharedWorkspace"); - - sharedWorkspace.SendMessage("activateFileViewerSelectingURLs:", urlArray); - } - else if (OperatingSystem.IsLinux()) - { - Process.Start("dbus-send", $"--session --print-reply --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 org.freedesktop.FileManager1.ShowItems array:string:\"file://{path}\" string:\"\""); - } - else - { - OpenFolder(Path.GetDirectoryName(path)); - } - } - else - { - Logger.Notice.Print(LogClass.Application, $"File \"{path}\" doesn't exist!"); - } - } - - public static void OpenUrl(string url) - { - if (OperatingSystem.IsWindows()) - { - Process.Start(new ProcessStartInfo("cmd", $"/c start {url.Replace("&", "^&")}")); - } - else if (OperatingSystem.IsLinux()) - { - Process.Start("xdg-open", url); - } - else if (OperatingSystem.IsMacOS()) - { - ObjectiveC.NSString nsStringPath = new(url); - ObjectiveC.Object nsUrl = new("NSURL"); - var urlPtr = nsUrl.GetFromMessage("URLWithString:", nsStringPath); - - ObjectiveC.Object nsWorkspace = new("NSWorkspace"); - ObjectiveC.Object sharedWorkspace = nsWorkspace.GetFromMessage("sharedWorkspace"); - - sharedWorkspace.GetBoolFromMessage("openURL:", urlPtr); - } - else - { - Logger.Notice.Print(LogClass.Application, $"Cannot open url \"{url}\" on this platform!"); - } - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs b/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs deleted file mode 100644 index 65c38d7b..00000000 --- a/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs +++ /dev/null @@ -1,114 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.HLE.FileSystem; -using System; -using System.IO; - -namespace Ryujinx.Ui.Common.Helper -{ - /// <summary> - /// Ensure installation validity - /// </summary> - public static class SetupValidator - { - public static bool IsFirmwareValid(ContentManager contentManager, out UserError error) - { - bool hasFirmware = contentManager.GetCurrentFirmwareVersion() != null; - - if (hasFirmware) - { - error = UserError.Success; - - return true; - } - - error = UserError.NoFirmware; - - return false; - } - - public static bool CanFixStartApplication(ContentManager contentManager, string baseApplicationPath, UserError error, out SystemVersion firmwareVersion) - { - try - { - firmwareVersion = contentManager.VerifyFirmwarePackage(baseApplicationPath); - } - catch (Exception) - { - firmwareVersion = null; - } - - return error == UserError.NoFirmware && Path.GetExtension(baseApplicationPath).ToLowerInvariant() == ".xci" && firmwareVersion != null; - } - - public static bool TryFixStartApplication(ContentManager contentManager, string baseApplicationPath, UserError error, out UserError outError) - { - if (error == UserError.NoFirmware) - { - string baseApplicationExtension = Path.GetExtension(baseApplicationPath).ToLowerInvariant(); - - // If the target app to start is a XCI, try to install firmware from it - if (baseApplicationExtension == ".xci") - { - SystemVersion firmwareVersion; - - try - { - firmwareVersion = contentManager.VerifyFirmwarePackage(baseApplicationPath); - } - catch (Exception) - { - firmwareVersion = null; - } - - // The XCI is a valid firmware package, try to install the firmware from it! - if (firmwareVersion != null) - { - try - { - Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}"); - - contentManager.InstallFirmware(baseApplicationPath); - - Logger.Info?.Print(LogClass.Application, $"System version {firmwareVersion.VersionString} successfully installed."); - - outError = UserError.Success; - - return true; - } - catch (Exception) { } - } - - outError = error; - - return false; - } - } - - outError = error; - - return false; - } - - public static bool CanStartApplication(ContentManager contentManager, string baseApplicationPath, out UserError error) - { - if (Directory.Exists(baseApplicationPath) || File.Exists(baseApplicationPath)) - { - string baseApplicationExtension = Path.GetExtension(baseApplicationPath).ToLowerInvariant(); - - // NOTE: We don't force homebrew developers to install a system firmware. - if (baseApplicationExtension == ".nro" || baseApplicationExtension == ".nso") - { - error = UserError.Success; - - return true; - } - - return IsFirmwareValid(contentManager, out error); - } - - error = UserError.ApplicationNotFound; - - return false; - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs b/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs deleted file mode 100644 index 3d27d3ff..00000000 --- a/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs +++ /dev/null @@ -1,162 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Common.Configuration; -using ShellLink; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Versioning; - -namespace Ryujinx.Ui.Common.Helper -{ - public static class ShortcutHelper - { - [SupportedOSPlatform("windows")] - private static void CreateShortcutWindows(string applicationFilePath, byte[] iconData, string iconPath, string cleanedAppName, string desktopPath) - { - string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.FriendlyName + ".exe"); - iconPath += ".ico"; - - MemoryStream iconDataStream = new(iconData); - var image = Image.Load(iconDataStream); - image.Mutate(x => x.Resize(128, 128)); - SaveBitmapAsIcon(image, iconPath); - - var shortcut = Shortcut.CreateShortcut(basePath, GetArgsString(applicationFilePath), iconPath, 0); - shortcut.StringData.NameString = cleanedAppName; - shortcut.WriteToFile(Path.Combine(desktopPath, cleanedAppName + ".lnk")); - } - - [SupportedOSPlatform("linux")] - private static void CreateShortcutLinux(string applicationFilePath, byte[] iconData, string iconPath, string desktopPath, string cleanedAppName) - { - string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.sh"); - var desktopFile = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-template.desktop"); - iconPath += ".png"; - - var image = Image.Load<Rgba32>(iconData); - image.SaveAsPng(iconPath); - - using StreamWriter outputFile = new(Path.Combine(desktopPath, cleanedAppName + ".desktop")); - outputFile.Write(desktopFile, cleanedAppName, iconPath, $"{basePath} {GetArgsString(applicationFilePath)}"); - } - - [SupportedOSPlatform("macos")] - private static void CreateShortcutMacos(string appFilePath, byte[] iconData, string desktopPath, string cleanedAppName) - { - string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"); - var plistFile = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-template.plist"); - var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-launch-script.sh"); - // Macos .App folder - string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents"); - string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS"); - - if (!Directory.Exists(scriptFolderPath)) - { - Directory.CreateDirectory(scriptFolderPath); - } - - // Runner script - const string ScriptName = "runner.sh"; - string scriptPath = Path.Combine(scriptFolderPath, ScriptName); - using StreamWriter scriptFile = new(scriptPath); - - scriptFile.Write(shortcutScript, basePath, GetArgsString(appFilePath)); - - // Set execute permission - FileInfo fileInfo = new(scriptPath); - fileInfo.UnixFileMode |= UnixFileMode.UserExecute; - - // img - string resourceFolderPath = Path.Combine(contentFolderPath, "Resources"); - if (!Directory.Exists(resourceFolderPath)) - { - Directory.CreateDirectory(resourceFolderPath); - } - - const string IconName = "icon.png"; - var image = Image.Load<Rgba32>(iconData); - image.SaveAsPng(Path.Combine(resourceFolderPath, IconName)); - - // plist file - using StreamWriter outputFile = new(Path.Combine(contentFolderPath, "Info.plist")); - outputFile.Write(plistFile, ScriptName, cleanedAppName, IconName); - } - - public static void CreateAppShortcut(string applicationFilePath, string applicationName, string applicationId, byte[] iconData) - { - string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); - string cleanedAppName = string.Join("_", applicationName.Split(Path.GetInvalidFileNameChars())); - - if (OperatingSystem.IsWindows()) - { - string iconPath = Path.Combine(AppDataManager.BaseDirPath, "games", applicationId, "app"); - - CreateShortcutWindows(applicationFilePath, iconData, iconPath, cleanedAppName, desktopPath); - - return; - } - - if (OperatingSystem.IsLinux()) - { - string iconPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "icons", "Ryujinx"); - - Directory.CreateDirectory(iconPath); - CreateShortcutLinux(applicationFilePath, iconData, Path.Combine(iconPath, applicationId), desktopPath, cleanedAppName); - - return; - } - - if (OperatingSystem.IsMacOS()) - { - CreateShortcutMacos(applicationFilePath, iconData, desktopPath, cleanedAppName); - - return; - } - - throw new NotImplementedException("Shortcut support has not been implemented yet for this OS."); - } - - private static string GetArgsString(string appFilePath) - { - // args are first defined as a list, for easier adjustments in the future - var argsList = new List<string>(); - - if (!string.IsNullOrEmpty(CommandLineState.BaseDirPathArg)) - { - argsList.Add("--root-data-dir"); - argsList.Add($"\"{CommandLineState.BaseDirPathArg}\""); - } - - argsList.Add($"\"{appFilePath}\""); - - return String.Join(" ", argsList); - } - - /// <summary> - /// Creates a Icon (.ico) file using the source bitmap image at the specified file path. - /// </summary> - /// <param name="source">The source bitmap image that will be saved as an .ico file</param> - /// <param name="filePath">The location that the new .ico file will be saved too (Make sure to include '.ico' in the path).</param> - [SupportedOSPlatform("windows")] - private static void SaveBitmapAsIcon(Image source, string filePath) - { - // Code Modified From https://stackoverflow.com/a/11448060/368354 by Benlitz - byte[] header = { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 0, 0 }; - using FileStream fs = new(filePath, FileMode.Create); - - fs.Write(header); - // Writing actual data - source.Save(fs, PngFormat.Instance); - // Getting data length (file length minus header) - long dataLength = fs.Length - header.Length; - // Write it in the correct place - fs.Seek(14, SeekOrigin.Begin); - fs.WriteByte((byte)dataLength); - fs.WriteByte((byte)(dataLength >> 8)); - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs b/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs deleted file mode 100644 index 089b5215..00000000 --- a/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Ryujinx.HLE.Loaders.Processes; -using System; - -namespace Ryujinx.Ui.Common.Helper -{ - public static class TitleHelper - { - public static string ActiveApplicationTitle(ProcessResult activeProcess, string applicationVersion, string pauseString = "") - { - if (activeProcess == null) - { - return String.Empty; - } - - string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}"; - string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}"; - string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})"; - string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)"; - - string appTitle = $"Ryujinx {applicationVersion} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; - - if (!string.IsNullOrEmpty(pauseString)) - { - appTitle += $" ({pauseString})"; - } - - return appTitle; - } - } -} diff --git a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs b/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs deleted file mode 100644 index b1597a7c..00000000 --- a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs +++ /dev/null @@ -1,219 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; - -namespace Ryujinx.Ui.Common.Helper -{ - public static class ValueFormatUtils - { - private static readonly string[] _fileSizeUnitStrings = - { - "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", // Base 10 units, used for formatting and parsing - "KB", "MB", "GB", "TB", "PB", "EB", // Base 2 units, used for parsing legacy values - }; - - /// <summary> - /// Used by <see cref="FormatFileSize"/>. - /// </summary> - public enum FileSizeUnits - { - Auto = -1, - Bytes = 0, - Kibibytes = 1, - Mebibytes = 2, - Gibibytes = 3, - Tebibytes = 4, - Pebibytes = 5, - Exbibytes = 6, - Kilobytes = 7, - Megabytes = 8, - Gigabytes = 9, - Terabytes = 10, - Petabytes = 11, - Exabytes = 12, - } - - private const double SizeBase10 = 1000; - private const double SizeBase2 = 1024; - private const int UnitEBIndex = 6; - - #region Value formatters - - /// <summary> - /// Creates a human-readable string from a <see cref="TimeSpan"/>. - /// </summary> - /// <param name="timeSpan">The <see cref="TimeSpan"/> to be formatted.</param> - /// <returns>A formatted string that can be displayed in the UI.</returns> - public static string FormatTimeSpan(TimeSpan? timeSpan) - { - if (!timeSpan.HasValue || timeSpan.Value.TotalSeconds < 1) - { - // Game was never played - return TimeSpan.Zero.ToString("c", CultureInfo.InvariantCulture); - } - - if (timeSpan.Value.TotalDays < 1) - { - // Game was played for less than a day - return timeSpan.Value.ToString("c", CultureInfo.InvariantCulture); - } - - // Game was played for more than a day - TimeSpan onlyTime = timeSpan.Value.Subtract(TimeSpan.FromDays(timeSpan.Value.Days)); - string onlyTimeString = onlyTime.ToString("c", CultureInfo.InvariantCulture); - - return $"{timeSpan.Value.Days}d, {onlyTimeString}"; - } - - /// <summary> - /// Creates a human-readable string from a <see cref="DateTime"/>. - /// </summary> - /// <param name="utcDateTime">The <see cref="DateTime"/> to be formatted. This is expected to be UTC-based.</param> - /// <param name="culture">The <see cref="CultureInfo"/> that's used in formatting. Defaults to <see cref="CultureInfo.CurrentCulture"/>.</param> - /// <returns>A formatted string that can be displayed in the UI.</returns> - public static string FormatDateTime(DateTime? utcDateTime, CultureInfo culture = null) - { - culture ??= CultureInfo.CurrentCulture; - - if (!utcDateTime.HasValue) - { - // In the Avalonia UI, this is turned into a localized version of "Never" by LocalizedNeverConverter. - return "Never"; - } - - return utcDateTime.Value.ToLocalTime().ToString(culture); - } - - /// <summary> - /// Creates a human-readable file size string. - /// </summary> - /// <param name="size">The file size in bytes.</param> - /// <param name="forceUnit">Formats the passed size value as this unit, bypassing the automatic unit choice.</param> - /// <returns>A human-readable file size string.</returns> - public static string FormatFileSize(long size, FileSizeUnits forceUnit = FileSizeUnits.Auto) - { - if (size <= 0) - { - return $"0 {_fileSizeUnitStrings[0]}"; - } - - int unitIndex = (int)forceUnit; - if (forceUnit == FileSizeUnits.Auto) - { - unitIndex = Convert.ToInt32(Math.Floor(Math.Log(size, SizeBase10))); - - // Apply an upper bound so that exabytes are the biggest unit used when formatting. - if (unitIndex > UnitEBIndex) - { - unitIndex = UnitEBIndex; - } - } - - double sizeRounded; - - if (unitIndex > UnitEBIndex) - { - sizeRounded = Math.Round(size / Math.Pow(SizeBase10, unitIndex - UnitEBIndex), 1); - } - else - { - sizeRounded = Math.Round(size / Math.Pow(SizeBase2, unitIndex), 1); - } - - string sizeFormatted = sizeRounded.ToString(CultureInfo.InvariantCulture); - - return $"{sizeFormatted} {_fileSizeUnitStrings[unitIndex]}"; - } - - #endregion - - #region Value parsers - - /// <summary> - /// Parses a string generated by <see cref="FormatTimeSpan"/> and returns the original <see cref="TimeSpan"/>. - /// </summary> - /// <param name="timeSpanString">A string representing a <see cref="TimeSpan"/>.</param> - /// <returns>A <see cref="TimeSpan"/> object. If the input string couldn't been parsed, <see cref="TimeSpan.Zero"/> is returned.</returns> - public static TimeSpan ParseTimeSpan(string timeSpanString) - { - TimeSpan returnTimeSpan = TimeSpan.Zero; - - // An input string can either look like "01:23:45" or "1d, 01:23:45" if the timespan represents a duration of more than a day. - // Here, we split the input string to check if it's the former or the latter. - var valueSplit = timeSpanString.Split(", "); - if (valueSplit.Length > 1) - { - var dayPart = valueSplit[0].Split("d")[0]; - if (int.TryParse(dayPart, out int days)) - { - returnTimeSpan = returnTimeSpan.Add(TimeSpan.FromDays(days)); - } - } - - if (TimeSpan.TryParse(valueSplit.Last(), out TimeSpan parsedTimeSpan)) - { - returnTimeSpan = returnTimeSpan.Add(parsedTimeSpan); - } - - return returnTimeSpan; - } - - /// <summary> - /// Parses a string generated by <see cref="FormatDateTime"/> and returns the original <see cref="DateTime"/>. - /// </summary> - /// <param name="dateTimeString">The string representing a <see cref="DateTime"/>.</param> - /// <returns>A <see cref="DateTime"/> object. If the input string couldn't be parsed, <see cref="DateTime.UnixEpoch"/> is returned.</returns> - public static DateTime ParseDateTime(string dateTimeString) - { - if (!DateTime.TryParse(dateTimeString, CultureInfo.CurrentCulture, out DateTime parsedDateTime)) - { - // Games that were never played are supposed to appear before the oldest played games in the list, - // so returning DateTime.UnixEpoch here makes sense. - return DateTime.UnixEpoch; - } - - return parsedDateTime; - } - - /// <summary> - /// Parses a string generated by <see cref="FormatFileSize"/> and returns a <see cref="long"/> representing a number of bytes. - /// </summary> - /// <param name="sizeString">A string representing a file size formatted with <see cref="FormatFileSize"/>.</param> - /// <returns>A <see cref="long"/> representing a number of bytes.</returns> - public static long ParseFileSize(string sizeString) - { - // Enumerating over the units backwards because otherwise, sizeString.EndsWith("B") would exit the loop in the first iteration. - for (int i = _fileSizeUnitStrings.Length - 1; i >= 0; i--) - { - string unit = _fileSizeUnitStrings[i]; - if (!sizeString.EndsWith(unit)) - { - continue; - } - - string numberString = sizeString.Split(" ")[0]; - if (!double.TryParse(numberString, CultureInfo.InvariantCulture, out double number)) - { - break; - } - - double sizeBase = SizeBase2; - - // If the unit index is one that points to a base 10 unit in the FileSizeUnitStrings array, subtract 6 to arrive at a usable power value. - if (i > UnitEBIndex) - { - i -= UnitEBIndex; - sizeBase = SizeBase10; - } - - number *= Math.Pow(sizeBase, i); - - return Convert.ToInt64(number); - } - - return 0; - } - - #endregion - } -} |
