mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-07-08 12:09:06 +00:00
Ayyyy, welcome to the UI: Actions Menu → Amiibo & Skylanders PR!
WOOOOO!!!!
This is the third PR in a series aimed at delivering the largest overhaul and improvements to the `Actions` menu yet.
This PR introduces visual and functionality improvements to the two `Scan Amiibo` options, as well as improving `Scan Skylanders`.
### GENERAL
* **Renamed:** Open Mii Applet → Open Mii Editor in `MainMenuBarView.axaml.cs`
### LOCALISATION
* **Fractured:** More locales
* `Amiibo.json` - all UI-related locales to the `Scan Amiibo` window
* `Common_Buttons.json` - all locales related to buttons
* `Common_FilePicker.json` - all locales related to the file picker that are implemented in many places
* `Dialog_Amiibo.json` - all Amiibo dialogs
* `Dialog_Skylanders.json` - all Skylander dialogs
* **Removed:** Some weird duplicated locales (they appeared after some sort of rebase, but they were few)
**NOTE:** `Common_Buttons.json` and `Common_FilePicker.json` were not fully populated, but many more locales will be added and cleaned up in future PRs.
### SCAN AMIIBO (WINDOW)
* **Improved:** The UI
* The UI now more cleanly utilises both Normal and Flush Controls.
* All buttons have been moved to the top row and features a whole lot more updates (read below).
* **Reworded:** `Hack: Random UUID Tag` → `Use Random UUID`
* The option is inherently already a hack/workaround, therefore, having "Hack" is not necessary. It is also implied that it's a tag.
* **Implemented:** [Feature Request #271](https://github.com/Ryubing/Issues/issues/271)
* The feature request is for the ability to pause emulation while navigating the `Scan Amiibo` window (so as to reduce/remove timeouts) and for an Amiibo "name" sorting feature. You asked, we deliver!
* **Pause Emulation:**
* The top row now features a "setting" button dropdown, which houses `Use Random UUID` and `Pause Emulation While Scanning`
* Note: Both options were moved to a button dropdown so as to not have to increase window size by a 1000x
* `Pause Emulation While Scanning` is a dynamic, real-time implementation.
* By default, the checkbox is not checked.
* When it's checked, emulation _instantly_ pauses for the duration while the window is open. Pressing "Scan Amiibo" or "Cancel" resumes emulation. Reopening the window pauses the emulation instantly as well.
* This setting persists both while in-game and upon restarting Ryujinx, so users don't have to constantly go back and check the option again.
* Additionally, this feature has been propagated to `Scan Amiibo (BIN)`. Perhaps some users would also want emulation to pause while scanning via BIN, so if the checkbox is checked, it'll pause emulation when the file picker is open as well.
* **Sorting & Search:**
* Additionally, implemented a simple "sort by name", in ascending and descending order.
* Added a search bar (related to the change below) to help with searching through the long Amiibo list.
* Search is semi-alphabetical, semi-series based. If I want to search for Samus Amiibo, then if I type "Samus", it'll first show Dark Samus, as it appears in a series earlier in the list. This behaviour can be modified to just be alphabetical, but it is also more categorisation.
* **Modified & Renamed:** `Show Incompatible Amiibo` → `Show All Amiibo`
* Pressing `Show Incompatible Amiibo` would display all Amiibo available, so the option was renamed.
* The option now forces all Amiibo to appear in a list, without a preselected series. Unchecked the option restores original behaviour by breaking down Amiibo by their series (and only those directly compatible with the game).
* **Removed:** Series label
* It's clear that it's an Amiibo series.
* **Fixed:** Amiibo Usage visual structure
* When an Amiibo had multiple in-game usages (multiple purposes), they would all be squished together with no spaces in between them, reducing readability.
* Now, they are all separated and given an extra line between each usage.
* Additionally, fixed "Unknown" text position as well by giving it another extra empty line.
* **Renamed:** Writeable to Usage (Can Save Data)
* Usage and Usage (Can Save Data) are separate strings because some languages must add space before or after the colon
* **Fixed:** Sometimes incorrect Amiibo images could be shown when pressing `Show Incompatible Amiibo`/`Show All Amiibo` in certain instances.
* Sometimes = pressing the checkbox 10 or 20...maybe 30 times in a row (I pressed it a lot!)
* **Reworded:** Cabinet Dialog strings
* Cabinet Dialog is the dialog that appears when you want to rename your Amiibo. Previously, the options didn't reflect the actual window and what they were asking the user, but now clearly tell the user that they are renaming their Amiibo, and when the dialog prompts the user to scan their amiibo again.
### SCAN AMIIBO (BIN)
* **Renamed:** `Scan Amiibo (.BIN)` to `Scan Amiibo (BIN)` to be similar to `Install Keys` > `KEYS` and similar menu items
* **Adjusted:** File picker title when loading Amiibo from BIN to...literally tell the user what to select and what will happen (similar to `Install Firmware` and `Install Keys` file picker titles)
### SCAN/REMOVE SKYLANDER
* **Merged:** `Scan Skylander` and `Remove Skylander`
* Instead of having two separate buttons, let's have one button that actively updates state. Instead of using two shortcuts, it now uses one, and the label updates based on whether the game is asking to `Scan Skylander` or whether you can `Remove Skylander`.
* **Fixed:** `Scan Skylander`/`Remove Skylander` were not visible properly
* Initial implementation only displayed the menu options/buttons when a particular Skylander Imaginators game was being played (i.e. specific ID)
* While there is only one Skylander game on the Switch, the game has been distributed in multiple regions under different game IDs and has different languages. People who owned Skylander Imaginators with a 0100ccc0002e6000 ID could use this feature and _nobody else._
* This has now been fixed by allowing those options to be visible at all times, regardless of the game
* For Skylander games, this is not an issue because the backend implementation for scanning/removing a skylander is the same (tested)
* For other games, then it doesn't matter since the feature is not used, but it will let users know the feature exists, in case they wished to previously play the game, but couldn't due to the missing backend.
* **Renamed:** Skylander functions and methods
* You don't open a window (like Scan Amiibo) but you open a file picker.
* **Fixed:** Inconsistent button state and shortcut update
* This was a bug in the previous implementation as well - you couldn't scan/remove skylander with the keyboard shortcut unless you opened the `Actions` menu (and only then would the shortcut register). This has been fixed.
As such...Skylanders Imaginators are now **Playable**! Updated the entry and added another game ID.
_If there are any features or changes that you wish to be implemented, please comment down below and I'll be happy to accommodate!_
Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/158
587 lines
19 KiB
C#
587 lines
19 KiB
C#
using Ryujinx.Ava.Systems.Configuration.System;
|
|
using Ryujinx.Ava.Systems.Configuration.UI;
|
|
using Ryujinx.Common.Configuration;
|
|
using Ryujinx.Common.Configuration.Hid;
|
|
using Ryujinx.Common.Configuration.Multiplayer;
|
|
using Ryujinx.Common.Logging;
|
|
using Ryujinx.Common.Utilities;
|
|
using Ryujinx.HLE;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
|
|
namespace Ryujinx.Ava.Systems.Configuration
|
|
{
|
|
public class ConfigurationFileFormat
|
|
{
|
|
/// <summary>
|
|
/// The current version of the file format
|
|
/// </summary>
|
|
public const int CurrentVersion = 73;
|
|
|
|
/// <summary>
|
|
/// Version of the configuration file format
|
|
/// </summary>
|
|
public int Version { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables logging to a file on disk
|
|
/// </summary>
|
|
public bool EnableFileLog { get; set; }
|
|
|
|
/// <summary>
|
|
/// Whether or not backend threading is enabled. The "Auto" setting will determine whether threading should be enabled at runtime.
|
|
/// </summary>
|
|
public BackendThreading BackendThreading { get; set; }
|
|
|
|
/// <summary>
|
|
/// Resolution Scale. An integer scale applied to applicable render targets. Values 1-4, or -1 to use a custom floating point scale instead.
|
|
/// </summary>
|
|
public int ResScale { get; set; }
|
|
|
|
/// <summary>
|
|
/// Custom Resolution Scale. A custom floating point scale applied to applicable render targets. Only active when Resolution Scale is -1.
|
|
/// </summary>
|
|
public float ResScaleCustom { get; set; }
|
|
|
|
/// <summary>
|
|
/// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
|
|
/// </summary>
|
|
public float MaxAnisotropy { get; set; }
|
|
|
|
/// <summary>
|
|
/// Aspect Ratio applied to the renderer window.
|
|
/// </summary>
|
|
public AspectRatio AspectRatio { get; set; }
|
|
|
|
/// <summary>
|
|
/// Applies anti-aliasing to the renderer.
|
|
/// </summary>
|
|
public AntiAliasing AntiAliasing { get; set; }
|
|
|
|
/// <summary>
|
|
/// Sets the framebuffer upscaling type.
|
|
/// </summary>
|
|
public ScalingFilter ScalingFilter { get; set; }
|
|
|
|
/// <summary>
|
|
/// Sets the framebuffer upscaling level.
|
|
/// </summary>
|
|
public int ScalingFilterLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Dumps shaders in this local directory
|
|
/// </summary>
|
|
public string GraphicsShadersDumpPath { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing debug log messages
|
|
/// </summary>
|
|
public bool LoggingEnableDebug { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing stub log messages
|
|
/// </summary>
|
|
public bool LoggingEnableStub { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing info log messages
|
|
/// </summary>
|
|
public bool LoggingEnableInfo { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing warning log messages
|
|
/// </summary>
|
|
public bool LoggingEnableWarn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing error log messages
|
|
/// </summary>
|
|
public bool LoggingEnableError { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing trace log messages
|
|
/// </summary>
|
|
public bool LoggingEnableTrace { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing guest log messages
|
|
/// </summary>
|
|
public bool LoggingEnableGuest { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing FS access log messages
|
|
/// </summary>
|
|
public bool LoggingEnableFsAccessLog { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables printing network log messages
|
|
/// </summary>
|
|
public bool LoggingEnableNetLog { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables log messages from Avalonia
|
|
/// </summary>
|
|
public bool LoggingEnableAvalonia { get; set; }
|
|
|
|
/// <summary>
|
|
/// Controls which log messages are written to the log targets
|
|
/// </summary>
|
|
public LogClass[] LoggingFilteredClasses { get; set; }
|
|
|
|
/// <summary>
|
|
/// Change Graphics API debug log level
|
|
/// </summary>
|
|
public GraphicsDebugLevel LoggingGraphicsDebugLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Change System Language
|
|
/// </summary>
|
|
public Language SystemLanguage { get; set; }
|
|
|
|
/// <summary>
|
|
/// Change System Region
|
|
/// </summary>
|
|
public Region SystemRegion { get; set; }
|
|
|
|
/// <summary>
|
|
/// Change System TimeZone
|
|
/// </summary>
|
|
public string SystemTimeZone { get; set; }
|
|
|
|
/// <summary>
|
|
/// Change System Time Offset in seconds
|
|
/// </summary>
|
|
public long SystemTimeOffset { get; set; }
|
|
|
|
/// <summary>
|
|
/// Instead of setting the time via configuration, use the values provided by the system.
|
|
/// </summary>
|
|
public bool MatchSystemTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enable or disable use global input config (Independent from controllers binding)
|
|
/// </summary>
|
|
public bool UseInputGlobalConfig { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables Docked Mode
|
|
/// </summary>
|
|
public bool DockedMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables Discord Rich Presence
|
|
/// </summary>
|
|
public bool EnableDiscordIntegration { get; set; }
|
|
|
|
/// <summary>
|
|
/// DEPRECATED: Checks for updates when Ryujinx starts when enabled
|
|
/// </summary>
|
|
public bool CheckUpdatesOnStart { get; set; }
|
|
|
|
/// <summary>
|
|
/// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
|
|
/// </summary>
|
|
public UpdaterType UpdateCheckerType { get; set; }
|
|
|
|
/// <summary>
|
|
/// How the emulator should behave when you click off/on the window.
|
|
/// </summary>
|
|
public FocusLostType FocusLostActionType { get; set; }
|
|
|
|
/// <summary>
|
|
/// Show "Confirm Exit" Dialog
|
|
/// </summary>
|
|
public bool ShowConfirmExit { get; set; }
|
|
|
|
/// <summary>
|
|
/// Ignore Controller Applet dialog
|
|
/// </summary>
|
|
public bool IgnoreApplet { get; set; }
|
|
|
|
/// <summary>
|
|
/// Skip user profiles manager dialog during gameplay(the used profile in the configuration will be selected)
|
|
/// </summary>
|
|
public bool SkipUserProfiles { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables save window size, position and state on close.
|
|
/// </summary>
|
|
public bool RememberWindowState { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables the redesigned title bar
|
|
/// </summary>
|
|
public bool ShowTitleBar { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables hardware-accelerated rendering for Avalonia
|
|
/// </summary>
|
|
public bool EnableHardwareAcceleration { get; set; }
|
|
|
|
/// <summary>
|
|
/// Whether to hide cursor on idle, always or never
|
|
/// </summary>
|
|
public HideCursorMode HideCursor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables Vertical Sync
|
|
/// </summary>
|
|
/// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks>
|
|
/// TODO: Remove this when those older versions aren't in use anymore.
|
|
public bool EnableVsync { get; set; }
|
|
|
|
/// <summary>
|
|
/// Current VSync mode; 60 (Switch), unbounded ("Vsync off"), or custom
|
|
/// </summary>
|
|
public VSyncMode VSyncMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables the custom present interval
|
|
/// </summary>
|
|
public bool EnableCustomVSyncInterval { get; set; }
|
|
|
|
/// <summary>
|
|
/// The custom present interval value
|
|
/// </summary>
|
|
public int CustomVSyncInterval { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables Shader cache
|
|
/// </summary>
|
|
public bool EnableShaderCache { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables texture recompression
|
|
/// </summary>
|
|
public bool EnableTextureRecompression { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables Macro high-level emulation
|
|
/// </summary>
|
|
public bool EnableMacroHLE { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables color space passthrough, if available.
|
|
/// </summary>
|
|
public bool EnableColorSpacePassthrough { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables profiled translation cache persistency
|
|
/// </summary>
|
|
public bool EnablePtc { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables low-power profiled translation cache persistency loading
|
|
/// </summary>
|
|
public bool EnableLowPowerPtc { get; set; }
|
|
|
|
/// <summary>
|
|
/// Clock tick scalar, in percent points (100 = 1.0).
|
|
/// </summary>
|
|
public long TickScalar { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables guest Internet access
|
|
/// </summary>
|
|
public bool EnableInternetAccess { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables integrity checks on Game content files
|
|
/// </summary>
|
|
public bool EnableFsIntegrityChecks { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables FS access log output to the console. Possible modes are 0-3
|
|
/// </summary>
|
|
public int FsGlobalAccessLogMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// The selected audio backend
|
|
/// </summary>
|
|
public AudioBackend AudioBackend { get; set; }
|
|
|
|
/// <summary>
|
|
/// The audio volume
|
|
/// </summary>
|
|
public float AudioVolume { get; set; }
|
|
|
|
/// <summary>
|
|
/// The selected memory manager mode
|
|
/// </summary>
|
|
public MemoryManagerMode MemoryManagerMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Expands the RAM amount on the emulated system
|
|
/// </summary>
|
|
public MemoryConfiguration DramSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enable or disable ignoring missing services
|
|
/// </summary>
|
|
public bool IgnoreMissingServices { get; set; }
|
|
|
|
/// <summary>
|
|
/// Used to toggle columns in the GUI
|
|
/// </summary>
|
|
public GuiColumns GuiColumns { get; set; }
|
|
|
|
/// <summary>
|
|
/// Used to configure column sort settings in the GUI
|
|
/// </summary>
|
|
public ColumnSort ColumnSort { get; set; }
|
|
|
|
/// <summary>
|
|
/// A list of directories containing games to be used to load games into the games list
|
|
/// </summary>
|
|
public List<string> GameDirs { get; set; }
|
|
|
|
/// <summary>
|
|
/// A list of directories containing DLC/updates the user wants to autoload during library refreshes
|
|
/// </summary>
|
|
public List<string> AutoloadDirs { get; set; }
|
|
|
|
/// <summary>
|
|
/// A list of file types to be hidden in the games List
|
|
/// </summary>
|
|
public ShownFileTypes ShownFileTypes { get; set; }
|
|
|
|
/// <summary>
|
|
/// Main window start-up position, size and state
|
|
/// </summary>
|
|
public WindowStartup WindowStartup { get; set; }
|
|
|
|
/// <summary>
|
|
/// Language Code for the UI
|
|
/// </summary>
|
|
public string LanguageCode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Chooses the base style // Not Used
|
|
/// </summary>
|
|
public string BaseStyle { get; set; }
|
|
|
|
/// <summary>
|
|
/// Chooses the view mode of the game list // Not Used
|
|
/// </summary>
|
|
public int GameListViewMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Show application name in Grid Mode // Not Used
|
|
/// </summary>
|
|
public bool ShowNames { get; set; }
|
|
|
|
/// <summary>
|
|
/// Sets App Icon Size // Not Used
|
|
/// </summary>
|
|
public int GridSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Sorts Apps in the game list // Not Used
|
|
/// </summary>
|
|
public int ApplicationSort { get; set; }
|
|
|
|
/// <summary>
|
|
/// Sets if Grid is ordered in Ascending Order // Not Used
|
|
/// </summary>
|
|
public bool IsAscendingOrder { get; set; }
|
|
|
|
/// <summary>
|
|
/// Start games in fullscreen mode
|
|
/// </summary>
|
|
public bool StartFullscreen { get; set; }
|
|
|
|
/// <summary>
|
|
/// Start games with UI hidden
|
|
/// </summary>
|
|
public bool StartNoUI { get; set; }
|
|
|
|
/// <summary>
|
|
/// Show console window
|
|
/// </summary>
|
|
public bool ShowConsole { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enable or disable keyboard support (Independent from controllers binding)
|
|
/// </summary>
|
|
public bool EnableKeyboard { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enable or disable mouse support (Independent from controllers binding)
|
|
/// </summary>
|
|
public bool EnableMouse { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enable/disable the ability to control Ryujinx when it's not the currently focused window.
|
|
/// </summary>
|
|
public bool DisableInputWhenOutOfFocus { get; set; }
|
|
|
|
/// <summary>
|
|
/// Hotkey Keyboard Bindings
|
|
/// </summary>
|
|
public KeyboardHotkeys Hotkeys { get; set; }
|
|
|
|
/// <summary>
|
|
/// Input configurations
|
|
/// </summary>
|
|
public List<InputConfig> InputConfig { get; set; }
|
|
|
|
/// <summary>
|
|
/// Player-level input routing assignments
|
|
/// </summary>
|
|
public List<PlayerInputAssignment> PlayerInputAssignments { get; set; }
|
|
|
|
/// <summary>
|
|
/// Whether to allow mapping the same input device to multiple players.
|
|
/// </summary>
|
|
public bool AllowDuplicateDeviceAssignment { get; set; }
|
|
|
|
/// <summary>
|
|
/// The speed of spectrum cycling for the Rainbow LED feature.
|
|
/// </summary>
|
|
public float RainbowSpeed { get; set; }
|
|
|
|
/// <summary>
|
|
/// Graphics backend
|
|
/// </summary>
|
|
public GraphicsBackend GraphicsBackend { get; set; }
|
|
|
|
/// <summary>
|
|
/// Preferred GPU
|
|
/// </summary>
|
|
public string PreferredGpu { get; set; }
|
|
|
|
/// <summary>
|
|
/// Multiplayer Mode
|
|
/// </summary>
|
|
public MultiplayerMode MultiplayerMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// GUID for the network interface used by LAN (or 0 for default)
|
|
/// </summary>
|
|
public string MultiplayerLanInterfaceId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Disable P2p Toggle
|
|
/// </summary>
|
|
public bool MultiplayerDisableP2p { get; set; }
|
|
|
|
/// <summary>
|
|
/// Local network passphrase, for private networks.
|
|
/// </summary>
|
|
public string MultiplayerLdnPassphrase { get; set; }
|
|
|
|
/// <summary>
|
|
/// Custom LDN Server
|
|
/// </summary>
|
|
public string LdnServer { get; set; }
|
|
|
|
/// <summary>
|
|
/// Uses Hypervisor over JIT if available
|
|
/// </summary>
|
|
public bool UseHypervisor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enable or disable low-latency mode for garbage collection
|
|
/// </summary>
|
|
public bool GCLowLatency { get; set; }
|
|
|
|
/// <summary>
|
|
/// Enables or disables the GDB stub
|
|
/// </summary>
|
|
public bool EnableGdbStub { get; set; }
|
|
|
|
/// <summary>
|
|
/// Which TCP port should the GDB stub listen on
|
|
/// </summary>
|
|
public ushort GdbStubPort { get; set; }
|
|
|
|
/// <summary>
|
|
/// Suspend execution when starting an application
|
|
/// </summary>
|
|
public bool DebuggerSuspendOnStart { get; set; }
|
|
|
|
/// <summary>
|
|
/// Show toggles for dirty hacks in the UI.
|
|
/// </summary>
|
|
public bool ShowDirtyHacks { get; set; }
|
|
|
|
/// <summary>
|
|
/// The packed values of the enabled dirty hacks.
|
|
/// </summary>
|
|
public ulong[] DirtyHacks { get; set; }
|
|
|
|
/// <summary>
|
|
/// Pause emulation while scanning Amiibo
|
|
/// </summary>
|
|
public bool PauseEmulationWhileScanningAmiibo { get; set; }
|
|
|
|
/// <summary>
|
|
/// Loads a configuration file from disk
|
|
/// </summary>
|
|
/// <param name="path">The path to the JSON configuration file</param>
|
|
/// <param name="configurationFileFormat">Parsed configuration file</param>
|
|
public static bool TryLoad(string path, out ConfigurationFileFormat configurationFileFormat)
|
|
{
|
|
try
|
|
{
|
|
configurationFileFormat = JsonHelper.DeserializeFromFile(path, ConfigurationFileFormatSettings.SerializerContext.ConfigurationFileFormat);
|
|
|
|
return configurationFileFormat.Version != 0;
|
|
}
|
|
catch
|
|
{
|
|
configurationFileFormat = null;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renames the configuration file when it is deemed invalid
|
|
/// </summary>
|
|
/// <param name="path">The path to the invalid JSON configuration file</param>
|
|
/// <returns>The path of the renamed invalid JSON configuration file, or null if the rename failed</returns>
|
|
public static string RenameInvalidConfigFile(string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
string directory = Path.GetDirectoryName(path) ?? string.Empty;
|
|
string originalFileName = Path.GetFileName(path);
|
|
if (string.IsNullOrWhiteSpace(originalFileName))
|
|
{
|
|
return null;
|
|
}
|
|
string renamedFileName = $"{originalFileName}.{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.invalid";
|
|
string renamedPath = string.IsNullOrEmpty(directory) ? renamedFileName : Path.Combine(directory, renamedFileName);
|
|
|
|
File.Move(path, renamedPath, overwrite: false);
|
|
|
|
Logger.Warning?.PrintMsg(LogClass.Application, $"Invalid configuration renamed to: {renamedPath}");
|
|
|
|
return renamedPath;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error?.PrintMsg(LogClass.Application, $"Failed to rename invalid configuration file \"{path}\": {ex}");
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save a configuration file to disk
|
|
/// </summary>
|
|
/// <param name="path">The path to the JSON configuration file</param>
|
|
public void SaveConfig(string path)
|
|
{
|
|
JsonHelper.SerializeToFile(path, this, ConfigurationFileFormatSettings.SerializerContext.ConfigurationFileFormat);
|
|
}
|
|
}
|
|
}
|