Use the official JSON parser (#1151)
This remove Utf8son and JsonPrettyPrinter dependencies. NOTE: the standard JSON parser doesn't support configurable indentation, as a result, all the pretty printed JSON are indented with 2 spaces.
This commit is contained in:
parent
7ab3fccd4d
commit
886e42fb19
19 changed files with 388 additions and 396 deletions
|
@ -1,103 +1,103 @@
|
|||
{
|
||||
"version": 5,
|
||||
"max_anisotropy": -1,
|
||||
"graphics_shaders_dump_path": "",
|
||||
"logging_enable_debug": false,
|
||||
"logging_enable_stub": true,
|
||||
"logging_enable_info": true,
|
||||
"logging_enable_warn": true,
|
||||
"logging_enable_error": true,
|
||||
"logging_enable_guest": true,
|
||||
"logging_enable_fs_access_log": false,
|
||||
"logging_filtered_classes": [],
|
||||
"enable_file_log": true,
|
||||
"system_language": "AmericanEnglish",
|
||||
"system_region": "USA",
|
||||
"system_time_zone": "UTC",
|
||||
"system_time_offset": 0,
|
||||
"docked_mode": false,
|
||||
"enable_discord_integration": true,
|
||||
"enable_vsync": true,
|
||||
"enable_multicore_scheduling": true,
|
||||
"enable_fs_integrity_checks": true,
|
||||
"fs_global_access_log_mode": 0,
|
||||
"ignore_missing_services": false,
|
||||
"controller_type": "Handheld",
|
||||
"gui_columns": {
|
||||
"fav_column": true,
|
||||
"icon_column": true,
|
||||
"app_column": true,
|
||||
"dev_column": true,
|
||||
"version_column": true,
|
||||
"time_played_column": true,
|
||||
"last_played_column": true,
|
||||
"file_ext_column": true,
|
||||
"file_size_column": true,
|
||||
"path_column": true
|
||||
"version": 5,
|
||||
"max_anisotropy": -1,
|
||||
"graphics_shaders_dump_path": "",
|
||||
"logging_enable_debug": false,
|
||||
"logging_enable_stub": true,
|
||||
"logging_enable_info": true,
|
||||
"logging_enable_warn": true,
|
||||
"logging_enable_error": true,
|
||||
"logging_enable_guest": true,
|
||||
"logging_enable_fs_access_log": false,
|
||||
"logging_filtered_classes": [],
|
||||
"enable_file_log": true,
|
||||
"system_language": "AmericanEnglish",
|
||||
"system_region": "USA",
|
||||
"system_time_zone": "UTC",
|
||||
"system_time_offset": 0,
|
||||
"docked_mode": false,
|
||||
"enable_discord_integration": true,
|
||||
"enable_vsync": true,
|
||||
"enable_multicore_scheduling": true,
|
||||
"enable_fs_integrity_checks": true,
|
||||
"fs_global_access_log_mode": 0,
|
||||
"ignore_missing_services": false,
|
||||
"controller_type": "Handheld",
|
||||
"gui_columns": {
|
||||
"fav_column": true,
|
||||
"icon_column": true,
|
||||
"app_column": true,
|
||||
"dev_column": true,
|
||||
"version_column": true,
|
||||
"time_played_column": true,
|
||||
"last_played_column": true,
|
||||
"file_ext_column": true,
|
||||
"file_size_column": true,
|
||||
"path_column": true
|
||||
},
|
||||
"game_dirs": [],
|
||||
"enable_custom_theme": false,
|
||||
"custom_theme_path": "",
|
||||
"enable_keyboard": false,
|
||||
"keyboard_controls": {
|
||||
"left_joycon": {
|
||||
"stick_up": "W",
|
||||
"stick_down": "S",
|
||||
"stick_left": "A",
|
||||
"stick_right": "D",
|
||||
"stick_button": "F",
|
||||
"dpad_up": "Up",
|
||||
"dpad_down": "Down",
|
||||
"dpad_left": "Left",
|
||||
"dpad_right": "Right",
|
||||
"button_minus": "Minus",
|
||||
"button_l": "E",
|
||||
"button_zl": "Q"
|
||||
},
|
||||
"game_dirs": [],
|
||||
"enable_custom_theme": false,
|
||||
"custom_theme_path": "",
|
||||
"enable_keyboard": false,
|
||||
"keyboard_controls": {
|
||||
"left_joycon": {
|
||||
"stick_up": "W",
|
||||
"stick_down": "S",
|
||||
"stick_left": "A",
|
||||
"stick_right": "D",
|
||||
"stick_button": "F",
|
||||
"dpad_up": "Up",
|
||||
"dpad_down": "Down",
|
||||
"dpad_left": "Left",
|
||||
"dpad_right": "Right",
|
||||
"button_minus": "Minus",
|
||||
"button_l": "E",
|
||||
"button_zl": "Q"
|
||||
},
|
||||
"right_joycon": {
|
||||
"stick_up": "I",
|
||||
"stick_down": "K",
|
||||
"stick_left": "J",
|
||||
"stick_right": "L",
|
||||
"stick_button": "H",
|
||||
"button_a": "Z",
|
||||
"button_b": "X",
|
||||
"button_x": "C",
|
||||
"button_y": "V",
|
||||
"button_plus": "Plus",
|
||||
"button_r": "U",
|
||||
"button_zr": "O"
|
||||
},
|
||||
"hotkeys": {
|
||||
"toggle_vsync": "Tab"
|
||||
}
|
||||
"right_joycon": {
|
||||
"stick_up": "I",
|
||||
"stick_down": "K",
|
||||
"stick_left": "J",
|
||||
"stick_right": "L",
|
||||
"stick_button": "H",
|
||||
"button_a": "Z",
|
||||
"button_b": "X",
|
||||
"button_x": "C",
|
||||
"button_y": "V",
|
||||
"button_plus": "Plus",
|
||||
"button_r": "U",
|
||||
"button_zr": "O"
|
||||
},
|
||||
"joystick_controls": {
|
||||
"enabled": true,
|
||||
"index": 0,
|
||||
"deadzone": 0.05,
|
||||
"trigger_threshold": 0.5,
|
||||
"left_joycon": {
|
||||
"stick": "Axis0",
|
||||
"stick_button": "Button8",
|
||||
"button_minus": "Button6",
|
||||
"button_l": "Button4",
|
||||
"button_zl": "Axis2",
|
||||
"dpad_up": "Hat0Up",
|
||||
"dpad_down": "Hat0Down",
|
||||
"dpad_left": "Hat0Left",
|
||||
"dpad_right": "Hat0Right"
|
||||
},
|
||||
"right_joycon": {
|
||||
"stick": "Axis3",
|
||||
"stick_button": "Button9",
|
||||
"button_a": "Button1",
|
||||
"button_b": "Button0",
|
||||
"button_x": "Button3",
|
||||
"button_y": "Button2",
|
||||
"button_plus": "Button7",
|
||||
"button_r": "Button5",
|
||||
"button_zr": "Axis5"
|
||||
}
|
||||
"hotkeys": {
|
||||
"toggle_vsync": "Tab"
|
||||
}
|
||||
},
|
||||
"joystick_controls": {
|
||||
"enabled": true,
|
||||
"index": 0,
|
||||
"deadzone": 0.05,
|
||||
"trigger_threshold": 0.5,
|
||||
"left_joycon": {
|
||||
"stick": "Axis0",
|
||||
"stick_button": "Button8",
|
||||
"button_minus": "Button6",
|
||||
"button_l": "Button4",
|
||||
"button_zl": "Axis2",
|
||||
"dpad_up": "Hat0Up",
|
||||
"dpad_down": "Hat0Down",
|
||||
"dpad_left": "Hat0Left",
|
||||
"dpad_right": "Hat0Right"
|
||||
},
|
||||
"right_joycon": {
|
||||
"stick": "Axis3",
|
||||
"stick_button": "Button9",
|
||||
"button_a": "Button1",
|
||||
"button_b": "Button0",
|
||||
"button_x": "Button3",
|
||||
"button_y": "Button2",
|
||||
"button_plus": "Button7",
|
||||
"button_r": "Button5",
|
||||
"button_zr": "Axis5"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,8 @@
|
|||
using Gtk;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Utf8Json;
|
||||
using Utf8Json.Resolvers;
|
||||
|
||||
using GUI = Gtk.Builder.ObjectAttribute;
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Utf8Json;
|
||||
using Utf8Json.Resolvers;
|
||||
using System.Text.Json;
|
||||
|
||||
using RightsId = LibHac.Fs.RightsId;
|
||||
using JsonHelper = Ryujinx.Common.Utilities.JsonHelper;
|
||||
|
||||
namespace Ryujinx.Ui
|
||||
{
|
||||
|
@ -509,8 +509,6 @@ namespace Ryujinx.Ui
|
|||
string metadataFolder = Path.Combine(_virtualFileSystem.GetBasePath(), "games", titleId, "gui");
|
||||
string metadataFile = Path.Combine(metadataFolder, "metadata.json");
|
||||
|
||||
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
|
||||
|
||||
ApplicationMetadata appMetadata;
|
||||
|
||||
if (!File.Exists(metadataFile))
|
||||
|
@ -526,27 +524,24 @@ namespace Ryujinx.Ui
|
|||
|
||||
using (FileStream stream = File.Create(metadataFile, 4096, FileOptions.WriteThrough))
|
||||
{
|
||||
JsonSerializer.Serialize(stream, appMetadata, resolver);
|
||||
JsonHelper.Serialize(stream, appMetadata, true);
|
||||
}
|
||||
}
|
||||
|
||||
using (Stream stream = File.OpenRead(metadataFile))
|
||||
try
|
||||
{
|
||||
try
|
||||
appMetadata = JsonHelper.DeserializeFromFile<ApplicationMetadata>(metadataFile);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"Failed to parse metadata json for {titleId}. Loading defaults.");
|
||||
|
||||
appMetadata = new ApplicationMetadata
|
||||
{
|
||||
appMetadata = JsonSerializer.Deserialize<ApplicationMetadata>(stream, resolver);
|
||||
}
|
||||
catch (JsonParsingException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"Failed to parse metadata json for {titleId}. Loading defaults.");
|
||||
|
||||
appMetadata = new ApplicationMetadata
|
||||
{
|
||||
Favorite = false,
|
||||
TimePlayed = 0,
|
||||
LastPlayed = "Never"
|
||||
};
|
||||
}
|
||||
Favorite = false,
|
||||
TimePlayed = 0,
|
||||
LastPlayed = "Never"
|
||||
};
|
||||
}
|
||||
|
||||
if (modifyFunction != null)
|
||||
|
@ -555,7 +550,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
using (FileStream stream = File.Create(metadataFile, 4096, FileOptions.WriteThrough))
|
||||
{
|
||||
JsonSerializer.Serialize(stream, appMetadata, resolver);
|
||||
JsonHelper.Serialize(stream, appMetadata, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,57 +648,53 @@ namespace Ryujinx.Ui
|
|||
|
||||
if (File.Exists(jsonPath))
|
||||
{
|
||||
using (Stream stream = File.OpenRead(jsonPath))
|
||||
string updatePath = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(jsonPath).Selected;
|
||||
|
||||
if (!File.Exists(updatePath))
|
||||
{
|
||||
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
|
||||
string updatePath = JsonSerializer.Deserialize<TitleUpdateMetadata>(stream, resolver).Selected;
|
||||
version = "";
|
||||
|
||||
if (!File.Exists(updatePath))
|
||||
return false;
|
||||
}
|
||||
|
||||
using (FileStream file = new FileStream(updatePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
|
||||
|
||||
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
|
||||
{
|
||||
version = "";
|
||||
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
|
||||
|
||||
return false;
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
Ticket ticket = new Ticket(ticketFile.AsStream());
|
||||
|
||||
_virtualFileSystem.KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(_virtualFileSystem.KeySet)));
|
||||
}
|
||||
}
|
||||
|
||||
using (FileStream file = new FileStream(updatePath, FileMode.Open, FileAccess.Read))
|
||||
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
|
||||
{
|
||||
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
|
||||
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
|
||||
|
||||
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != titleId)
|
||||
{
|
||||
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
Ticket ticket = new Ticket(ticketFile.AsStream());
|
||||
|
||||
_virtualFileSystem.KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(_virtualFileSystem.KeySet)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
|
||||
if (nca.Header.ContentType == NcaContentType.Control)
|
||||
{
|
||||
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
ApplicationControlProperty controlData = new ApplicationControlProperty();
|
||||
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
|
||||
nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(out IFile nacpFile, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != titleId)
|
||||
{
|
||||
break;
|
||||
}
|
||||
nacpFile.Read(out long _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
|
||||
|
||||
if (nca.Header.ContentType == NcaContentType.Control)
|
||||
{
|
||||
ApplicationControlProperty controlData = new ApplicationControlProperty();
|
||||
version = controlData.DisplayVersion.ToString();
|
||||
|
||||
nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(out IFile nacpFile, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
nacpFile.Read(out long _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
|
||||
|
||||
version = controlData.DisplayVersion.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using LibHac.Ns;
|
|||
using LibHac.Spl;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
@ -19,8 +20,6 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Utf8Json;
|
||||
using Utf8Json.Resolvers;
|
||||
using static LibHac.Fs.ApplicationSaveDataManagement;
|
||||
using GUI = Gtk.Builder.ObjectAttribute;
|
||||
|
||||
|
@ -274,43 +273,39 @@ namespace Ryujinx.Ui
|
|||
|
||||
if (File.Exists(titleUpdateMetadataPath))
|
||||
{
|
||||
using (Stream stream = File.OpenRead(titleUpdateMetadataPath))
|
||||
string updatePath = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(titleUpdateMetadataPath).Selected;
|
||||
|
||||
if (File.Exists(updatePath))
|
||||
{
|
||||
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
|
||||
string updatePath = JsonSerializer.Deserialize<TitleUpdateMetadata>(stream, resolver).Selected;
|
||||
FileStream updateFile = new FileStream(updatePath, FileMode.Open, FileAccess.Read);
|
||||
PartitionFileSystem nsp = new PartitionFileSystem(updateFile.AsStorage());
|
||||
|
||||
if (File.Exists(updatePath))
|
||||
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
|
||||
{
|
||||
FileStream updateFile = new FileStream(updatePath, FileMode.Open, FileAccess.Read);
|
||||
PartitionFileSystem nsp = new PartitionFileSystem(updateFile.AsStorage());
|
||||
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
|
||||
|
||||
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
|
||||
Ticket ticket = new Ticket(ticketFile.AsStream());
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
Ticket ticket = new Ticket(ticketFile.AsStream());
|
||||
_virtualFileSystem.KeySet.ExternalKeySet.Add(new LibHac.Fs.RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(_virtualFileSystem.KeySet)));
|
||||
}
|
||||
}
|
||||
|
||||
_virtualFileSystem.KeySet.ExternalKeySet.Add(new LibHac.Fs.RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(_virtualFileSystem.KeySet)));
|
||||
}
|
||||
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
|
||||
{
|
||||
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
|
||||
|
||||
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != mainNca.Header.TitleId.ToString("x16"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
|
||||
if (nca.Header.ContentType == NcaContentType.Program)
|
||||
{
|
||||
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
|
||||
|
||||
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != mainNca.Header.TitleId.ToString("x16"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (nca.Header.ContentType == NcaContentType.Program)
|
||||
{
|
||||
patchNca = nca;
|
||||
}
|
||||
patchNca = nca;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using Gtk;
|
||||
using JsonPrettyPrinterPlus;
|
||||
using LibHac;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
@ -12,11 +11,9 @@ using Ryujinx.HLE.FileSystem;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Utf8Json;
|
||||
using Utf8Json.Resolvers;
|
||||
|
||||
using GUI = Gtk.Builder.ObjectAttribute;
|
||||
using JsonHelper = Ryujinx.Common.Utilities.JsonHelper;
|
||||
|
||||
namespace Ryujinx.Ui
|
||||
{
|
||||
|
@ -47,12 +44,9 @@ namespace Ryujinx.Ui
|
|||
|
||||
try
|
||||
{
|
||||
using (Stream stream = File.OpenRead(System.IO.Path.Combine(_virtualFileSystem.GetBasePath(), "games", _titleId, "updates.json")))
|
||||
{
|
||||
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
|
||||
string path = System.IO.Path.Combine(_virtualFileSystem.GetBasePath(), "games", _titleId, "updates.json");
|
||||
|
||||
_titleUpdateWindowData = JsonSerializer.Deserialize<TitleUpdateMetadata>(stream, resolver);
|
||||
}
|
||||
_titleUpdateWindowData = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -185,12 +179,9 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
}
|
||||
|
||||
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
|
||||
|
||||
string path = System.IO.Path.Combine(_virtualFileSystem.GetBasePath(), "games", _titleId, "updates.json");
|
||||
byte[] data = JsonSerializer.Serialize(_titleUpdateWindowData, resolver);
|
||||
|
||||
File.WriteAllText(path, Encoding.UTF8.GetString(data, 0, data.Length).PrettyPrintJson());
|
||||
File.WriteAllText(path, JsonHelper.Serialize(_titleUpdateWindowData, true));
|
||||
|
||||
MainWindow.UpdateGameTable();
|
||||
Dispose();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue