From 6d8572cce00d47ab69f2ad02e58d512bd9dc98aa Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 26 Feb 2024 22:38:42 +0100 Subject: [PATCH] Core - Replaced JSON.NET with System.Text.Json --- src/Artemis.Core/Artemis.Core.csproj | 2 +- src/Artemis.Core/Constants.cs | 18 +- .../JsonConverters/ForgivingIntConverter.cs | 48 +++--- .../ForgivingVersionConverter.cs | 26 --- .../JsonConverters/NumericJsonConverter.cs | 36 ++-- .../JsonConverters/SKColorConverter.cs | 29 ++-- .../JsonConverters/StreamConverter.cs | 55 +++--- src/Artemis.Core/Models/Profile/Folder.cs | 2 +- .../Profile/LayerProperties/LayerProperty.cs | 4 +- .../ProfileConfigurationExportModel.cs | 4 +- src/Artemis.Core/Plugins/Modules/DataModel.cs | 2 +- src/Artemis.Core/Plugins/PluginFeatureInfo.cs | 5 - src/Artemis.Core/Plugins/PluginInfo.cs | 31 +--- src/Artemis.Core/Plugins/PluginPlatform.cs | 5 +- .../Plugins/Settings/PluginSetting.cs | 4 +- src/Artemis.Core/Services/Core/BuildInfo.cs | 46 ----- src/Artemis.Core/Services/ModuleService.cs | 1 - src/Artemis.Core/Services/NodeService.cs | 5 +- .../Storage/Interfaces/IProfileService.cs | 6 - .../Services/Storage/ProfileService.cs | 20 +-- .../EndPoints/DataModelJsonPluginEndPoint.cs | 57 ------- .../WebServer/EndPoints/JsonPluginEndPoint.cs | 6 +- .../WebServer/EndPoints/PluginEndPoint.cs | 2 +- .../WebServer/Interfaces/IWebServerService.cs | 11 +- .../Services/WebServer/WebServerService.cs | 30 ++-- src/Artemis.Core/Utilities/CoreJson.cs | 42 +---- .../VisualScripting/Nodes/NodeTStorage.cs | 2 +- .../VisualScripting/Pins/InputPin.cs | 2 - .../VisualScripting/Pins/OutputPin.cs | 2 - src/Artemis.Storage/Artemis.Storage.csproj | 2 +- .../Migrations/IProfileMigration.cs | 4 +- .../Migrations/Profile/M0001NodeProviders.cs | 159 +++++++++--------- .../M0002NodeProvidersProfileConfig.cs | 19 ++- .../DefaultDataModelDisplayViewModel.cs | 13 +- .../Extensions/ClipboardExtensions.cs | 2 +- .../Commands/ResetLayerProperty.cs | 2 +- .../Extensions/ProfileElementExtensions.cs | 6 +- src/Artemis.UI/Models/FolderClipboardModel.cs | 5 +- src/Artemis.UI/Models/IClipboardModel.cs | 11 ++ .../Models/KeyframeClipboardModel.cs | 6 +- src/Artemis.UI/Models/LayerClipboardModel.cs | 13 ++ src/Artemis.UI/Models/NodesClipboardModel.cs | 4 +- .../Tabs/Workshop/WorkshopDebugViewModel.cs | 7 +- .../Panels/MenuBar/MenuBarViewModel.cs | 1 - .../ProfileTree/FolderTreeItemViewModel.cs | 2 +- .../ProfileTree/LayerTreeItemViewModel.cs | 2 +- .../Keyframes/TimelineKeyframeViewModel.cs | 2 +- .../Sidebar/SidebarCategoryViewModel.cs | 7 +- .../VisualScripting/NodeScriptViewModel.cs | 4 +- .../LayoutEntryUploadHandler.cs | 4 +- .../PluginEntryUploadHandler.cs | 4 +- .../ProfileEntryUploadHandler.cs | 5 +- src/Directory.Packages.props | 2 +- 53 files changed, 296 insertions(+), 493 deletions(-) delete mode 100644 src/Artemis.Core/JsonConverters/ForgivingVersionConverter.cs delete mode 100644 src/Artemis.Core/Services/Core/BuildInfo.cs delete mode 100644 src/Artemis.Core/Services/WebServer/EndPoints/DataModelJsonPluginEndPoint.cs create mode 100644 src/Artemis.UI/Models/IClipboardModel.cs create mode 100644 src/Artemis.UI/Models/LayerClipboardModel.cs diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index e81dc0d64..75fa9a3a1 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -42,7 +42,6 @@ - @@ -50,6 +49,7 @@ + diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs index ce374ca88..56912df74 100644 --- a/src/Artemis.Core/Constants.cs +++ b/src/Artemis.Core/Constants.cs @@ -4,10 +4,8 @@ using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Reflection; +using System.Text.Json; using Artemis.Core.JsonConverters; -using Artemis.Core.Services; -using Artemis.Core.SkiaSharp; -using Newtonsoft.Json; namespace Artemis.Core; @@ -62,7 +60,7 @@ public static class Constants /// The full path to the Artemis user layouts folder /// public static readonly string LayoutsFolder = Path.Combine(DataFolder, "User Layouts"); - + /// /// The full path to the Artemis user layouts folder /// @@ -97,17 +95,11 @@ public static class Constants internal static readonly CorePluginFeature CorePluginFeature = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Core")}; internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Effect Placeholder")}; - internal static JsonSerializerSettings JsonConvertSettings = new() + internal static JsonSerializerOptions JsonConvertSettings = new() { - Converters = new List {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()} + Converters = {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()} }; - - internal static JsonSerializerSettings JsonConvertTypedSettings = new() - { - TypeNameHandling = TypeNameHandling.All, - Converters = new List {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()} - }; - + /// /// A read-only collection containing all primitive numeric types /// diff --git a/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs b/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs index c43fa7bf8..5663c73bc 100644 --- a/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs +++ b/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs @@ -1,32 +1,34 @@ using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; -namespace Artemis.Core.JsonConverters; - -/// -/// An int converter that, if required, will round float values -/// -internal class ForgivingIntConverter : JsonConverter +namespace Artemis.Core.JsonConverters { - public override bool CanWrite => false; - - public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer) + /// + /// An int converter that, if required, will round float values + /// + internal class ForgivingIntConverter : JsonConverter { - throw new NotImplementedException(); - } + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + throw new JsonException("Cannot convert null value."); - public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer) - { - JValue? jsonValue = serializer.Deserialize(reader); - if (jsonValue == null) - throw new JsonReaderException("Failed to deserialize forgiving int value"); + if (reader.TokenType == JsonTokenType.Number) + { + if (reader.TryGetInt32(out int intValue)) + return intValue; - if (jsonValue.Type == JTokenType.Float) - return (int) Math.Round(jsonValue.Value()); - if (jsonValue.Type == JTokenType.Integer) - return jsonValue.Value(); + if (reader.TryGetDouble(out double doubleValue)) + return (int)Math.Round(doubleValue); + } - throw new JsonReaderException("Failed to deserialize forgiving int value"); + throw new JsonException("Failed to deserialize forgiving int value"); + } + + public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/src/Artemis.Core/JsonConverters/ForgivingVersionConverter.cs b/src/Artemis.Core/JsonConverters/ForgivingVersionConverter.cs deleted file mode 100644 index 8a325f7e0..000000000 --- a/src/Artemis.Core/JsonConverters/ForgivingVersionConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using System; - -namespace Artemis.Core.JsonConverters -{ - /// - /// Version converter that is forgiving of missing parts of the version string, - /// setting them to zero instead of -1. - /// - internal class ForgivingVersionConverter : VersionConverter - { - public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) - { - object? obj = base.ReadJson(reader, objectType, existingValue, serializer); - if (obj is not Version v) - return obj; - - int major = v.Major == -1 ? 0 : v.Major; - int minor = v.Minor == -1 ? 0 : v.Minor; - int build = v.Build == -1 ? 0 : v.Build; - int revision = v.Revision == -1 ? 0 : v.Revision; - return new Version(major, minor, build, revision); - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/JsonConverters/NumericJsonConverter.cs b/src/Artemis.Core/JsonConverters/NumericJsonConverter.cs index 0dea83b5e..3d018c4c2 100644 --- a/src/Artemis.Core/JsonConverters/NumericJsonConverter.cs +++ b/src/Artemis.Core/JsonConverters/NumericJsonConverter.cs @@ -1,24 +1,26 @@ using System; -using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; -namespace Artemis.Core.JsonConverters; - -internal class NumericJsonConverter : JsonConverter +namespace Artemis.Core.JsonConverters { - #region Overrides of JsonConverter - - /// - public override void WriteJson(JsonWriter writer, Numeric value, JsonSerializer serializer) + internal class NumericJsonConverter : JsonConverter { - float floatValue = value; - writer.WriteValue(floatValue); - } + public override void Write(Utf8JsonWriter writer, Numeric value, JsonSerializerOptions options) + { + float floatValue = value; + writer.WriteNumberValue(floatValue); + } - /// - public override Numeric ReadJson(JsonReader reader, Type objectType, Numeric existingValue, bool hasExistingValue, JsonSerializer serializer) - { - return new Numeric(reader.Value); - } + public override Numeric Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.Number) + { + throw new JsonException($"Expected a number token, but got {reader.TokenType}."); + } - #endregion + float floatValue = reader.GetSingle(); + return new Numeric(floatValue); + } + } } \ No newline at end of file diff --git a/src/Artemis.Core/JsonConverters/SKColorConverter.cs b/src/Artemis.Core/JsonConverters/SKColorConverter.cs index 40912c153..b2818d754 100644 --- a/src/Artemis.Core/JsonConverters/SKColorConverter.cs +++ b/src/Artemis.Core/JsonConverters/SKColorConverter.cs @@ -1,21 +1,26 @@ using System; -using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using SkiaSharp; -namespace Artemis.Core.JsonConverters; - -internal class SKColorConverter : JsonConverter +namespace Artemis.Core.JsonConverters { - public override void WriteJson(JsonWriter writer, SKColor value, JsonSerializer serializer) + internal class SKColorConverter : JsonConverter { - writer.WriteValue(value.ToString()); - } + public override void Write(Utf8JsonWriter writer, SKColor value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } - public override SKColor ReadJson(JsonReader reader, Type objectType, SKColor existingValue, bool hasExistingValue, JsonSerializer serializer) - { - if (reader.Value is string value && !string.IsNullOrWhiteSpace(value)) - return SKColor.Parse(value); + public override SKColor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + { + throw new JsonException($"Expected a string token, but got {reader.TokenType}."); + } - return SKColor.Empty; + string colorString = reader.GetString() ?? string.Empty; + return SKColor.TryParse(colorString, out SKColor color) ? color : SKColor.Empty; + } } } \ No newline at end of file diff --git a/src/Artemis.Core/JsonConverters/StreamConverter.cs b/src/Artemis.Core/JsonConverters/StreamConverter.cs index 7ce3529ee..8ea7b9abd 100644 --- a/src/Artemis.Core/JsonConverters/StreamConverter.cs +++ b/src/Artemis.Core/JsonConverters/StreamConverter.cs @@ -1,44 +1,31 @@ using System; using System.IO; -using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; -namespace Artemis.Core.JsonConverters; - -/// -public class StreamConverter : JsonConverter +namespace Artemis.Core.JsonConverters { - #region Overrides of JsonConverter - - /// - public override void WriteJson(JsonWriter writer, Stream? value, JsonSerializer serializer) + internal class StreamConverter : JsonConverter { - if (value == null) + public override void Write(Utf8JsonWriter writer, Stream value, JsonSerializerOptions options) { - writer.WriteNull(); - return; + using MemoryStream memoryStream = new(); + value.Position = 0; + value.CopyTo(memoryStream); + writer.WriteBase64StringValue(memoryStream.ToArray()); } - using MemoryStream memoryStream = new(); - value.Position = 0; - value.CopyTo(memoryStream); - writer.WriteValue(memoryStream.ToArray()); + public override Stream Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + throw new JsonException($"Expected a string token, but got {reader.TokenType}."); + + string base64 = reader.GetString() ?? string.Empty; + + if (typeToConvert == typeof(MemoryStream)) + return new MemoryStream(Convert.FromBase64String(base64)); + + throw new InvalidOperationException("StreamConverter only supports reading to MemoryStream"); + } } - - /// - public override Stream? ReadJson(JsonReader reader, Type objectType, Stream? existingValue, bool hasExistingValue, JsonSerializer serializer) - { - if (reader.Value is not string base64) - return null; - - if (existingValue == null || !hasExistingValue || !existingValue.CanRead) - return new MemoryStream(Convert.FromBase64String(base64)); - - using MemoryStream memoryStream = new(Convert.FromBase64String(base64)); - existingValue.Position = 0; - memoryStream.CopyTo(existingValue); - existingValue.Position = 0; - return existingValue; - } - - #endregion } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs index ec3496955..c86fdb46c 100644 --- a/src/Artemis.Core/Models/Profile/Folder.cs +++ b/src/Artemis.Core/Models/Profile/Folder.cs @@ -164,7 +164,7 @@ public sealed class Folder : RenderProfileElement if (Parent == null) throw new ArtemisCoreException("Cannot create a copy of a folder without a parent"); - FolderEntity entityCopy = CoreJson.DeserializeObject(CoreJson.SerializeObject(FolderEntity, true), true)!; + FolderEntity entityCopy = CoreJson.DeserializeObject(CoreJson.SerializeObject(FolderEntity))!; entityCopy.Id = Guid.NewGuid(); entityCopy.Name += " - Copy"; diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs index ff9a7d514..6304bd388 100644 --- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs +++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerProperty.cs @@ -2,8 +2,8 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Text.Json; using Artemis.Storage.Entities.Profile; -using Newtonsoft.Json; namespace Artemis.Core; @@ -324,7 +324,7 @@ public class LayerProperty : CorePropertyChanged, ILayerProperty // Reference types make a deep clone (ab)using JSON else { - string json = CoreJson.SerializeObject(DefaultValue, true); + string json = CoreJson.SerializeObject(DefaultValue); SetCurrentValue(CoreJson.DeserializeObject(json)!); } } diff --git a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationExportModel.cs b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationExportModel.cs index 075c5f54b..5febcbe25 100644 --- a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationExportModel.cs +++ b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationExportModel.cs @@ -1,8 +1,8 @@ using System; using System.IO; +using System.Text.Json.Serialization; using Artemis.Core.JsonConverters; using Artemis.Storage.Entities.Profile; -using Newtonsoft.Json; namespace Artemis.Core; @@ -19,7 +19,7 @@ public class ProfileConfigurationExportModel : IDisposable /// /// Gets or sets the storage entity of the profile /// - [JsonProperty(Required = Required.Always)] + [JsonRequired] public ProfileEntity ProfileEntity { get; set; } = null!; /// diff --git a/src/Artemis.Core/Plugins/Modules/DataModel.cs b/src/Artemis.Core/Plugins/Modules/DataModel.cs index 6d80e3b29..1bdf68094 100644 --- a/src/Artemis.Core/Plugins/Modules/DataModel.cs +++ b/src/Artemis.Core/Plugins/Modules/DataModel.cs @@ -4,8 +4,8 @@ using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; +using System.Text.Json.Serialization; using Humanizer; -using Newtonsoft.Json; namespace Artemis.Core.Modules; diff --git a/src/Artemis.Core/Plugins/PluginFeatureInfo.cs b/src/Artemis.Core/Plugins/PluginFeatureInfo.cs index ccd9f4c9f..6c084ff51 100644 --- a/src/Artemis.Core/Plugins/PluginFeatureInfo.cs +++ b/src/Artemis.Core/Plugins/PluginFeatureInfo.cs @@ -3,14 +3,12 @@ using System.Collections.Generic; using System.Linq; using Artemis.Storage.Entities.Plugins; using Humanizer; -using Newtonsoft.Json; namespace Artemis.Core; /// /// Represents basic info about a plugin feature and contains a reference to the instance of said feature /// -[JsonObject(MemberSerialization.OptIn)] public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject { private string? _description; @@ -64,7 +62,6 @@ public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject /// /// The name of the feature /// - [JsonProperty(Required = Required.Always)] public string Name { get => _name; @@ -74,7 +71,6 @@ public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject /// /// A short description of the feature /// - [JsonProperty] public string? Description { get => _description; @@ -85,7 +81,6 @@ public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject /// Marks the feature to always be enabled as long as the plugin is enabled and cannot be disabled. /// Note: always if this is the plugin's only feature /// - [JsonProperty] public bool AlwaysEnabled { get; internal set; } /// diff --git a/src/Artemis.Core/Plugins/PluginInfo.cs b/src/Artemis.Core/Plugins/PluginInfo.cs index 91e49eeab..da280694c 100644 --- a/src/Artemis.Core/Plugins/PluginInfo.cs +++ b/src/Artemis.Core/Plugins/PluginInfo.cs @@ -1,16 +1,13 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; -using Artemis.Core.JsonConverters; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Artemis.Core; /// /// Represents basic info about a plugin and contains a reference to the instance of said plugin /// -[JsonObject(MemberSerialization.OptIn)] public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject { private Version? _api; @@ -28,7 +25,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject private string _version = null!; private Uri? _website; private Uri? _helpPage; - private bool _hotReloadSupported; + private bool _hotReloadSupported = true; private Uri? _license; private string? _licenseName; @@ -39,7 +36,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// The plugins GUID /// - [JsonProperty(Required = Required.Always)] + [JsonRequired] public Guid Guid { get => _guid; @@ -49,7 +46,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// The name of the plugin /// - [JsonProperty(Required = Required.Always)] + [JsonRequired] public string Name { get => _name; @@ -59,7 +56,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// A short description of the plugin /// - [JsonProperty] public string? Description { get => _description; @@ -69,7 +65,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets the author of this plugin /// - [JsonProperty] public string? Author { get => _author; @@ -79,7 +74,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets the website of this plugin or its author /// - [JsonProperty] public Uri? Website { get => _website; @@ -89,7 +83,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets the repository of this plugin /// - [JsonProperty] public Uri? Repository { get => _repository; @@ -99,7 +92,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets the help page of this plugin /// - [JsonProperty] public Uri? HelpPage { get => _helpPage; @@ -109,7 +101,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets the help page of this plugin /// - [JsonProperty] public Uri? License { get => _license; @@ -119,7 +110,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets the author of this plugin /// - [JsonProperty] public string? LicenseName { get => _licenseName; @@ -130,7 +120,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// The plugins display icon that's shown in the settings see for /// available icons /// - [JsonProperty] public string? Icon { get => _icon; @@ -140,7 +129,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// The version of the plugin /// - [JsonProperty(Required = Required.Always)] + [JsonRequired] public string Version { get => _version; @@ -150,7 +139,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// The main entry DLL, should contain a class implementing Plugin /// - [JsonProperty(Required = Required.Always)] + [JsonRequired] public string Main { get => _main; @@ -161,8 +150,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// Gets or sets a boolean indicating whether this plugin should automatically enable all its features when it is first /// loaded /// - [DefaultValue(true)] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] public bool AutoEnableFeatures { get => _autoEnableFeatures; @@ -172,7 +159,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets a boolean indicating whether this plugin requires elevated admin privileges /// - [JsonProperty] public bool RequiresAdmin { get => _requiresAdmin; @@ -182,8 +168,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets or sets a boolean indicating whether hot reloading this plugin is supported /// - [DefaultValue(true)] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] public bool HotReloadSupported { get => _hotReloadSupported; @@ -193,7 +177,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets /// - [JsonProperty] public PluginPlatform? Platforms { get => _platforms; @@ -203,8 +186,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject /// /// Gets the API version the plugin was built for /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - [JsonConverter(typeof(ForgivingVersionConverter))] public Version? Api { get => _api; diff --git a/src/Artemis.Core/Plugins/PluginPlatform.cs b/src/Artemis.Core/Plugins/PluginPlatform.cs index 6f5ce1c34..bc10a703f 100644 --- a/src/Artemis.Core/Plugins/PluginPlatform.cs +++ b/src/Artemis.Core/Plugins/PluginPlatform.cs @@ -1,6 +1,5 @@ using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using System.Text.Json.Serialization; namespace Artemis.Core; @@ -8,7 +7,7 @@ namespace Artemis.Core; /// Specifies OS platforms a plugin may support. /// [Flags] -[JsonConverter(typeof(StringEnumConverter))] +[JsonConverter(typeof(JsonStringEnumConverter))] public enum PluginPlatform { /// The Windows platform. diff --git a/src/Artemis.Core/Plugins/Settings/PluginSetting.cs b/src/Artemis.Core/Plugins/Settings/PluginSetting.cs index cd94e48d6..3b1e43cce 100644 --- a/src/Artemis.Core/Plugins/Settings/PluginSetting.cs +++ b/src/Artemis.Core/Plugins/Settings/PluginSetting.cs @@ -1,7 +1,7 @@ using System; +using System.Text.Json; using Artemis.Storage.Entities.Plugins; using Artemis.Storage.Repositories.Interfaces; -using Newtonsoft.Json; namespace Artemis.Core; @@ -25,7 +25,7 @@ public class PluginSetting : CorePropertyChanged, IPluginSetting { _value = CoreJson.DeserializeObject(pluginSettingEntity.Value)!; } - catch (JsonReaderException) + catch (JsonException) { _value = default!; } diff --git a/src/Artemis.Core/Services/Core/BuildInfo.cs b/src/Artemis.Core/Services/Core/BuildInfo.cs deleted file mode 100644 index 2c694d67a..000000000 --- a/src/Artemis.Core/Services/Core/BuildInfo.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Globalization; -using Newtonsoft.Json; - -namespace Artemis.Core.Services.Core; - -/// -/// Represents build information related to the currently running Artemis build -/// -public class BuildInfo -{ - /// - /// Gets the unique ID of this build - /// - [JsonProperty] - public int BuildId { get; internal set; } - - /// - /// Gets the build number. This contains the date and the build count for that day. - /// Per example 20210108.4 - /// - [JsonProperty] - public double BuildNumber { get; internal set; } - - /// - /// Gets the build number formatted as a string. This contains the date and the build count for that day. - /// Per example 20210108.4 - /// - public string BuildNumberDisplay => BuildNumber.ToString(CultureInfo.InvariantCulture); - - /// - /// Gets the branch of the triggering repo the build was created for. - /// - [JsonProperty] - public string SourceBranch { get; internal set; } = null!; - - /// - /// Gets the commit ID used to create this build - /// - [JsonProperty] - public string SourceVersion { get; internal set; } = null!; - - /// - /// Gets a boolean indicating whether the current build is a local build - /// - public bool IsLocalBuild { get; internal set; } -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/ModuleService.cs b/src/Artemis.Core/Services/ModuleService.cs index 1050484c0..e72ea6882 100644 --- a/src/Artemis.Core/Services/ModuleService.cs +++ b/src/Artemis.Core/Services/ModuleService.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Threading.Tasks; using System.Timers; using Artemis.Core.Modules; -using Newtonsoft.Json; using Serilog; namespace Artemis.Core.Services; diff --git a/src/Artemis.Core/Services/NodeService.cs b/src/Artemis.Core/Services/NodeService.cs index 96a0b617b..11f6eb565 100644 --- a/src/Artemis.Core/Services/NodeService.cs +++ b/src/Artemis.Core/Services/NodeService.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using Artemis.Storage.Entities.Profile.Nodes; -using Newtonsoft.Json; using SkiaSharp; namespace Artemis.Core.Services; @@ -42,12 +41,12 @@ internal class NodeService : INodeService public string ExportScript(NodeScript nodeScript) { nodeScript.Save(); - return JsonConvert.SerializeObject(nodeScript.Entity, IProfileService.ExportSettings); + return CoreJson.SerializeObject(nodeScript.Entity); } public void ImportScript(string json, NodeScript target) { - NodeScriptEntity? entity = JsonConvert.DeserializeObject(json); + NodeScriptEntity? entity = CoreJson.DeserializeObject(json); if (entity == null) throw new ArtemisCoreException("Failed to load node script"); diff --git a/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs b/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs index 4e8d357fa..2d2dfae7c 100644 --- a/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs +++ b/src/Artemis.Core/Services/Storage/Interfaces/IProfileService.cs @@ -2,7 +2,6 @@ using System.Collections.ObjectModel; using System.IO; using System.Threading.Tasks; -using Newtonsoft.Json; using SkiaSharp; namespace Artemis.Core.Services; @@ -12,11 +11,6 @@ namespace Artemis.Core.Services; /// public interface IProfileService : IArtemisService { - /// - /// Gets the JSON serializer settings used to import/export profiles. - /// - public static JsonSerializerSettings ExportSettings { get; } = new() {TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented}; - /// /// Gets a read only collection containing all the profile categories. /// diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index d9f50cd1a..7846fe3d3 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -5,13 +5,13 @@ using System.IO; using System.IO.Compression; using System.Linq; using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Threading.Tasks; using Artemis.Core.Modules; using Artemis.Storage.Entities.Profile; using Artemis.Storage.Migrations; using Artemis.Storage.Repositories.Interfaces; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Serilog; using SkiaSharp; @@ -410,8 +410,8 @@ internal class ProfileService : IProfileService if (profileEntity == null) throw new ArtemisCoreException("Could not locate profile entity"); - string configurationJson = JsonConvert.SerializeObject(profileConfiguration.Entity, IProfileService.ExportSettings); - string profileJson = JsonConvert.SerializeObject(profileEntity, IProfileService.ExportSettings); + string configurationJson = CoreJson.SerializeObject(profileConfiguration.Entity); + string profileJson = CoreJson.SerializeObject(profileEntity); MemoryStream archiveStream = new(); @@ -461,21 +461,21 @@ internal class ProfileService : IProfileService // Deserialize profile configuration to JObject await using Stream configurationStream = configurationEntry.Open(); using StreamReader configurationReader = new(configurationStream); - JObject? configurationJson = JsonConvert.DeserializeObject(await configurationReader.ReadToEndAsync(), IProfileService.ExportSettings); + JsonObject? configurationJson = CoreJson.DeserializeObject(await configurationReader.ReadToEndAsync()); // Deserialize profile to JObject await using Stream profileStream = profileEntry.Open(); using StreamReader profileReader = new(profileStream); - JObject? profileJson = JsonConvert.DeserializeObject(await profileReader.ReadToEndAsync(), IProfileService.ExportSettings); + JsonObject? profileJson = CoreJson.DeserializeObject(await profileReader.ReadToEndAsync()); // Before deserializing, apply any pending migrations MigrateProfile(configurationJson, profileJson); // Deserialize profile configuration to ProfileConfigurationEntity - ProfileConfigurationEntity? configurationEntity = configurationJson?.ToObject(JsonSerializer.Create(IProfileService.ExportSettings)); + ProfileConfigurationEntity? configurationEntity = configurationJson?.Deserialize(Constants.JsonConvertSettings); if (configurationEntity == null) throw new ArtemisCoreException("Could not import profile, failed to deserialize configuration.json"); // Deserialize profile to ProfileEntity - ProfileEntity? profileEntity = profileJson?.ToObject(JsonSerializer.Create(IProfileService.ExportSettings)); + ProfileEntity? profileEntity = profileJson?.Deserialize(Constants.JsonConvertSettings); if (profileEntity == null) throw new ArtemisCoreException("Could not import profile, failed to deserialize profile.json"); @@ -559,7 +559,7 @@ internal class ProfileService : IProfileService } } - private void MigrateProfile(JObject? configurationJson, JObject? profileJson) + private void MigrateProfile(JsonObject? configurationJson, JsonObject? profileJson) { if (configurationJson == null || profileJson == null) return; @@ -568,7 +568,7 @@ internal class ProfileService : IProfileService foreach (IProfileMigration profileMigrator in _profileMigrators.OrderBy(m => m.Version)) { - if (profileMigrator.Version <= configurationJson["Version"]!.Value()) + if (profileMigrator.Version <= configurationJson["Version"]!.GetValue()) continue; profileMigrator.Migrate(configurationJson, profileJson); diff --git a/src/Artemis.Core/Services/WebServer/EndPoints/DataModelJsonPluginEndPoint.cs b/src/Artemis.Core/Services/WebServer/EndPoints/DataModelJsonPluginEndPoint.cs deleted file mode 100644 index e9aa58ad1..000000000 --- a/src/Artemis.Core/Services/WebServer/EndPoints/DataModelJsonPluginEndPoint.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.IO; -using System.Threading.Tasks; -using Artemis.Core.Modules; -using EmbedIO; -using Newtonsoft.Json; - -namespace Artemis.Core.Services; - -/// -/// Represents a plugin web endpoint receiving an object of type and returning any -/// or . -/// Note: Both will be deserialized and serialized respectively using JSON. -/// -public class DataModelJsonPluginEndPoint : PluginEndPoint where T : DataModel, new() -{ - private readonly Module _module; - - internal DataModelJsonPluginEndPoint(Module module, string name, PluginsModule pluginsModule) : base(module, name, pluginsModule) - { - _module = module ?? throw new ArgumentNullException(nameof(module)); - - ThrowOnFail = true; - Accepts = MimeType.Json; - } - - /// - /// Whether or not the end point should throw an exception if deserializing the received JSON fails. - /// If set to malformed JSON is silently ignored; if set to malformed - /// JSON throws a . - /// - public bool ThrowOnFail { get; set; } - - #region Overrides of PluginEndPoint - - /// - protected override async Task ProcessRequest(IHttpContext context) - { - if (context.Request.HttpVerb != HttpVerbs.Post && context.Request.HttpVerb != HttpVerbs.Put) - throw HttpException.MethodNotAllowed("This end point only accepts POST and PUT calls"); - - context.Response.ContentType = MimeType.Json; - - using TextReader reader = context.OpenRequestText(); - try - { - JsonConvert.PopulateObject(await reader.ReadToEndAsync(), _module.DataModel); - } - catch (JsonException) - { - if (ThrowOnFail) - throw; - } - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/WebServer/EndPoints/JsonPluginEndPoint.cs b/src/Artemis.Core/Services/WebServer/EndPoints/JsonPluginEndPoint.cs index 355a233ec..2fc5c6977 100644 --- a/src/Artemis.Core/Services/WebServer/EndPoints/JsonPluginEndPoint.cs +++ b/src/Artemis.Core/Services/WebServer/EndPoints/JsonPluginEndPoint.cs @@ -1,8 +1,8 @@ using System; using System.IO; +using System.Text.Json; using System.Threading.Tasks; using EmbedIO; -using Newtonsoft.Json; namespace Artemis.Core.Services; @@ -52,7 +52,7 @@ public class JsonPluginEndPoint : PluginEndPoint object? response = null; try { - T? deserialized = JsonConvert.DeserializeObject(await reader.ReadToEndAsync()); + T? deserialized = JsonSerializer.Deserialize(await reader.ReadToEndAsync()); if (deserialized == null) throw new JsonException("Deserialization returned null"); @@ -74,7 +74,7 @@ public class JsonPluginEndPoint : PluginEndPoint } await using TextWriter writer = context.OpenResponseText(); - await writer.WriteAsync(JsonConvert.SerializeObject(response)); + await writer.WriteAsync(JsonSerializer.Serialize(response)); } #endregion diff --git a/src/Artemis.Core/Services/WebServer/EndPoints/PluginEndPoint.cs b/src/Artemis.Core/Services/WebServer/EndPoints/PluginEndPoint.cs index 55cbbd3d9..fed0e033a 100644 --- a/src/Artemis.Core/Services/WebServer/EndPoints/PluginEndPoint.cs +++ b/src/Artemis.Core/Services/WebServer/EndPoints/PluginEndPoint.cs @@ -1,7 +1,7 @@ using System; +using System.Text.Json.Serialization; using System.Threading.Tasks; using EmbedIO; -using Newtonsoft.Json; namespace Artemis.Core.Services; diff --git a/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs b/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs index d185d33c9..938b86c78 100644 --- a/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs +++ b/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs @@ -43,16 +43,7 @@ public interface IWebServerService : IArtemisService /// /// The resulting end point JsonPluginEndPoint AddResponsiveJsonEndPoint(PluginFeature feature, string endPointName, Func requestHandler); - - /// - /// Adds a new endpoint that directly maps received JSON to the data model of the provided . - /// - /// The data model type of the module - /// The module whose datamodel to apply the received JSON to - /// The name of the end point, must be unique - /// The resulting end point - DataModelJsonPluginEndPoint AddDataModelJsonEndPoint(Module module, string endPointName) where T : DataModel, new(); - + /// /// Adds a new endpoint for the given plugin feature receiving an a . /// diff --git a/src/Artemis.Core/Services/WebServer/WebServerService.cs b/src/Artemis.Core/Services/WebServer/WebServerService.cs index 263d95315..206444543 100644 --- a/src/Artemis.Core/Services/WebServer/WebServerService.cs +++ b/src/Artemis.Core/Services/WebServer/WebServerService.cs @@ -3,12 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Artemis.Core.Modules; using EmbedIO; using EmbedIO.WebApi; -using Newtonsoft.Json; using Serilog; namespace Artemis.Core.Services; @@ -22,6 +21,7 @@ internal class WebServerService : IWebServerService, IDisposable private readonly PluginSetting _webServerEnabledSetting; private readonly PluginSetting _webServerPortSetting; private readonly object _webserverLock = new(); + private readonly JsonSerializerOptions _jsonOptions = new() {WriteIndented = true}; private CancellationTokenSource? _cts; public WebServerService(ILogger logger, ICoreService coreService, ISettingsService settingsService, IPluginManagementService pluginManagementService) @@ -120,7 +120,7 @@ internal class WebServerService : IWebServerService, IDisposable Server = null; } - WebApiModule apiModule = new("/", JsonNetSerializer); + WebApiModule apiModule = new("/", SystemTextJsonSerializer); PluginsModule.ServerUrl = $"http://localhost:{_webServerPortSetting.Value}/"; WebServer server = new WebServer(o => o.WithUrlPrefix($"http://*:{_webServerPortSetting.Value}/").WithMode(HttpListenerMode.EmbedIO)) .WithLocalSessionManager() @@ -138,7 +138,7 @@ internal class WebServerService : IWebServerService, IDisposable // Add registered controllers to the API module foreach (WebApiControllerRegistration registration in _controllers) apiModule.RegisterController(registration.ControllerType, (Func) registration.UntypedFactory); - + // Listen for state changes. server.StateChanged += (s, e) => _logger.Verbose("WebServer new state - {state}", e.NewState); @@ -173,7 +173,7 @@ internal class WebServerService : IWebServerService, IDisposable OnWebServerStarted(); } } - + private void AutoStartWebServer() { try @@ -239,16 +239,7 @@ internal class WebServerService : IWebServerService, IDisposable PluginsModule.AddPluginEndPoint(endPoint); return endPoint; } - - public DataModelJsonPluginEndPoint AddDataModelJsonEndPoint(Module module, string endPointName) where T : DataModel, new() - { - if (module == null) throw new ArgumentNullException(nameof(module)); - if (endPointName == null) throw new ArgumentNullException(nameof(endPointName)); - DataModelJsonPluginEndPoint endPoint = new(module, endPointName, PluginsModule); - PluginsModule.AddPluginEndPoint(endPoint); - return endPoint; - } - + public void RemovePluginEndPoint(PluginEndPoint endPoint) { PluginsModule.RemovePluginEndPoint(endPoint); @@ -316,7 +307,7 @@ internal class WebServerService : IWebServerService, IDisposable context.Response.ContentType = MimeType.Json; await using TextWriter writer = context.OpenResponseText(); - string response = JsonConvert.SerializeObject(new Dictionary + string response = CoreJson.SerializeObject(new Dictionary { {"StatusCode", context.Response.StatusCode}, {"StackTrace", exception.StackTrace}, @@ -331,17 +322,16 @@ internal class WebServerService : IWebServerService, IDisposable await writer.WriteAsync(response); } - private async Task JsonNetSerializer(IHttpContext context, object? data) + private async Task SystemTextJsonSerializer(IHttpContext context, object? data) { context.Response.ContentType = MimeType.Json; await using TextWriter writer = context.OpenResponseText(); - string json = JsonConvert.SerializeObject(data, new JsonSerializerSettings {PreserveReferencesHandling = PreserveReferencesHandling.Objects}); - await writer.WriteAsync(json); + await writer.WriteAsync(JsonSerializer.Serialize(data, _jsonOptions)); } private async Task HandleHttpExceptionJson(IHttpContext context, IHttpException httpException) { - await context.SendStringAsync(JsonConvert.SerializeObject(httpException, Formatting.Indented), MimeType.Json, Encoding.UTF8); + await context.SendStringAsync(JsonSerializer.Serialize(httpException, _jsonOptions), MimeType.Json, Encoding.UTF8); } #endregion diff --git a/src/Artemis.Core/Utilities/CoreJson.cs b/src/Artemis.Core/Utilities/CoreJson.cs index 1cb870e61..5f1ff4a9d 100644 --- a/src/Artemis.Core/Utilities/CoreJson.cs +++ b/src/Artemis.Core/Utilities/CoreJson.cs @@ -1,7 +1,6 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using Newtonsoft.Json; +using System.Text.Json; namespace Artemis.Core; @@ -16,55 +15,28 @@ public static class CoreJson /// Serializes the specified object to a JSON string. /// /// The object to serialize. - /// If set to true sets TypeNameHandling to /// A JSON string representation of the object. [DebuggerStepThrough] - public static string SerializeObject(object? value, bool handleTypeNames = false) + public static string SerializeObject(object? value) { - return JsonConvert.SerializeObject(value, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings); + return JsonSerializer.Serialize(value, Constants.JsonConvertSettings); } #endregion #region Deserialize - - /// - /// Deserializes the JSON to a .NET object. - /// - /// The JSON to deserialize. - /// If set to true sets TypeNameHandling to - /// The deserialized object from the JSON string. - [DebuggerStepThrough] - public static object? DeserializeObject(string value, bool handleTypeNames = false) - { - return JsonConvert.DeserializeObject(value, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings); - } - - /// - /// Deserializes the JSON to the specified .NET type. - /// - /// The JSON to deserialize. - /// The of object being deserialized. - /// If set to true sets TypeNameHandling to - /// The deserialized object from the JSON string. - [DebuggerStepThrough] - public static object? DeserializeObject(string value, Type type, bool handleTypeNames = false) - { - return JsonConvert.DeserializeObject(value, type, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings); - } - + /// /// Deserializes the JSON to the specified .NET type. /// /// The type of the object to deserialize to. /// The JSON to deserialize. - /// If set to true sets TypeNameHandling to /// The deserialized object from the JSON string. [DebuggerStepThrough] [return: MaybeNull] - public static T DeserializeObject(string value, bool handleTypeNames = false) + public static T DeserializeObject(string value) { - return JsonConvert.DeserializeObject(value, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings); + return JsonSerializer.Deserialize(value, Constants.JsonConvertSettings); } #endregion diff --git a/src/Artemis.Core/VisualScripting/Nodes/NodeTStorage.cs b/src/Artemis.Core/VisualScripting/Nodes/NodeTStorage.cs index 81d9e7eac..fafb4e37f 100644 --- a/src/Artemis.Core/VisualScripting/Nodes/NodeTStorage.cs +++ b/src/Artemis.Core/VisualScripting/Nodes/NodeTStorage.cs @@ -41,7 +41,7 @@ public abstract class Node : Node /// public override string SerializeStorage() { - return CoreJson.SerializeObject(Storage, true); + return CoreJson.SerializeObject(Storage); } /// diff --git a/src/Artemis.Core/VisualScripting/Pins/InputPin.cs b/src/Artemis.Core/VisualScripting/Pins/InputPin.cs index 8addc4627..a183885c5 100644 --- a/src/Artemis.Core/VisualScripting/Pins/InputPin.cs +++ b/src/Artemis.Core/VisualScripting/Pins/InputPin.cs @@ -1,5 +1,4 @@ using System; -using Newtonsoft.Json; namespace Artemis.Core; @@ -10,7 +9,6 @@ public sealed class InputPin : Pin { #region Constructors - [JsonConstructor] internal InputPin(INode node, string name) : base(node, name) { diff --git a/src/Artemis.Core/VisualScripting/Pins/OutputPin.cs b/src/Artemis.Core/VisualScripting/Pins/OutputPin.cs index 52bd0993a..8397eddf6 100644 --- a/src/Artemis.Core/VisualScripting/Pins/OutputPin.cs +++ b/src/Artemis.Core/VisualScripting/Pins/OutputPin.cs @@ -1,5 +1,4 @@ using System; -using Newtonsoft.Json; namespace Artemis.Core; @@ -10,7 +9,6 @@ public sealed class OutputPin : Pin { #region Constructors - [JsonConstructor] internal OutputPin(INode node, string name) : base(node, name) { diff --git a/src/Artemis.Storage/Artemis.Storage.csproj b/src/Artemis.Storage/Artemis.Storage.csproj index cc0ac235f..b01c7ef62 100644 --- a/src/Artemis.Storage/Artemis.Storage.csproj +++ b/src/Artemis.Storage/Artemis.Storage.csproj @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/IProfileMigration.cs b/src/Artemis.Storage/Migrations/IProfileMigration.cs index c4fb710ec..d0e1b2126 100644 --- a/src/Artemis.Storage/Migrations/IProfileMigration.cs +++ b/src/Artemis.Storage/Migrations/IProfileMigration.cs @@ -1,9 +1,9 @@ -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace Artemis.Storage.Migrations; public interface IProfileMigration { int Version { get; } - void Migrate(JObject configurationJson, JObject profileJson); + void Migrate(JsonObject configurationJson, JsonObject profileJson); } \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs b/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs index a1006bab8..347de14c3 100644 --- a/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs +++ b/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs @@ -1,88 +1,95 @@ -using Newtonsoft.Json.Linq; +using System; +using System.Text.Json; +using System.Text.Json.Nodes; +using Serilog.Core; -namespace Artemis.Storage.Migrations.Profile; - -/// -/// Migrates nodes to be provider-based. -/// This requires giving them a ProviderId and updating the their namespaces to match the namespace of the new plugin. -/// -internal class M0001NodeProviders : IProfileMigration +namespace Artemis.Storage.Migrations.Profile { - /// - public int Version => 1; - - /// - public void Migrate(JObject configurationJson, JObject profileJson) + /// + /// Migrates nodes to be provider-based. + /// This requires giving them a ProviderId and updating the their namespaces to match the namespace of the new plugin. + /// + internal class M0001NodeProviders : IProfileMigration { - JArray? folders = (JArray?) profileJson["Folders"]?["$values"]; - JArray? layers = (JArray?) profileJson["Layers"]?["$values"]; + /// + public int Version => 1; - if (folders != null) + /// + public void Migrate(JsonObject configurationJson, JsonObject profileJson) { - foreach (JToken folder in folders) - MigrateProfileElement(folder); + JsonArray? folders = (JsonArray?) profileJson["Folders"]?["values"]; + JsonArray? layers = (JsonArray?) profileJson["Layers"]?["values"]; + + if (folders != null) + { + foreach (JsonValue folder in folders) + MigrateProfileElement(folder); + } + + if (layers != null) + { + foreach (JsonValue layer in layers) + { + MigrateProfileElement(layer); + MigratePropertyGroup(layer["GeneralPropertyGroup"]); + MigratePropertyGroup(layer["TransformPropertyGroup"]); + MigratePropertyGroup(layer["LayerBrush"]?["PropertyGroup"]); + } + } } - if (layers != null) + private void MigrateProfileElement(JsonNode profileElement) { - foreach (JToken layer in layers) + JsonArray? layerEffects = (JsonArray?) profileElement["LayerEffects"]?["values"]; + if (layerEffects != null) { - MigrateProfileElement(layer); - MigratePropertyGroup(layer["GeneralPropertyGroup"]); - MigratePropertyGroup(layer["TransformPropertyGroup"]); - MigratePropertyGroup(layer["LayerBrush"]?["PropertyGroup"]); + foreach (JsonValue layerEffect in layerEffects) + MigratePropertyGroup(layerEffect["PropertyGroup"]); + } + + JsonNode? displayCondition = profileElement["DisplayCondition"]; + if (displayCondition != null) + MigrateNodeScript(displayCondition["Script"]); + } + + private void MigratePropertyGroup(JsonNode? propertyGroup) + { + if (propertyGroup == null) + return; + + JsonArray? properties = (JsonArray?) propertyGroup["Properties"]?["values"]; + JsonArray? propertyGroups = (JsonArray?) propertyGroup["PropertyGroups"]?["values"]; + + if (properties != null) + { + foreach (JsonValue property in properties) + MigrateNodeScript(property["DataBinding"]?["NodeScript"]); + } + + if (propertyGroups != null) + { + foreach (JsonValue childPropertyGroup in propertyGroups) + MigratePropertyGroup(childPropertyGroup); + } + } + + private void MigrateNodeScript(JsonNode? nodeScript) + { + if (nodeScript == null) + return; + + JsonArray? nodes = nodeScript["Nodes"]?.AsArray(); + if (nodes == null) + return; + + foreach (JsonNode? jsonNode in nodes) + { + if (jsonNode == null) + continue; + JsonObject nodeObject = jsonNode.AsObject(); + nodeObject["Type"] = nodeObject["Type"]?.GetValue().Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); + nodeObject["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; } } } - - private void MigrateProfileElement(JToken profileElement) - { - JArray? layerEffects = (JArray?) profileElement["LayerEffects"]?["$values"]; - if (layerEffects != null) - { - foreach (JToken layerEffect in layerEffects) - MigratePropertyGroup(layerEffect["PropertyGroup"]); - } - - JToken? displayCondition = profileElement["DisplayCondition"]; - if (displayCondition != null) - MigrateNodeScript(displayCondition["Script"]); - } - - private void MigratePropertyGroup(JToken? propertyGroup) - { - if (propertyGroup == null || !propertyGroup.HasValues) - return; - - JArray? properties = (JArray?) propertyGroup["Properties"]?["$values"]; - JArray? propertyGroups = (JArray?) propertyGroup["PropertyGroups"]?["$values"]; - - if (properties != null) - { - foreach (JToken property in properties) - MigrateNodeScript(property["DataBinding"]?["NodeScript"]); - } - - if (propertyGroups != null) - { - foreach (JToken childPropertyGroup in propertyGroups) - MigratePropertyGroup(childPropertyGroup); - } - } - - private void MigrateNodeScript(JToken? nodeScript) - { - if (nodeScript == null || !nodeScript.HasValues) - return; - - JArray? nodes = (JArray?) nodeScript["Nodes"]?["$values"]; - if (nodes == null) - return; - - foreach (JToken node in nodes) - { - node["Type"] = node["Type"]?.Value()?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); - node["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; - } - } -} \ No newline at end of file +} diff --git a/src/Artemis.Storage/Migrations/Profile/M0002NodeProvidersProfileConfig.cs b/src/Artemis.Storage/Migrations/Profile/M0002NodeProvidersProfileConfig.cs index 9c35a961a..e201dea21 100644 --- a/src/Artemis.Storage/Migrations/Profile/M0002NodeProvidersProfileConfig.cs +++ b/src/Artemis.Storage/Migrations/Profile/M0002NodeProvidersProfileConfig.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace Artemis.Storage.Migrations.Profile; @@ -12,24 +12,27 @@ internal class M0002NodeProvidersProfileConfig : IProfileMigration public int Version => 2; /// - public void Migrate(JObject configurationJson, JObject profileJson) + public void Migrate(JsonObject configurationJson, JsonObject profileJson) { MigrateNodeScript(configurationJson["ActivationCondition"]); } - private void MigrateNodeScript(JToken? nodeScript) + private void MigrateNodeScript(JsonNode? nodeScript) { - if (nodeScript == null || !nodeScript.HasValues) + if (nodeScript == null) return; - JArray? nodes = (JArray?) nodeScript["Nodes"]?["$values"]; + JsonArray? nodes = nodeScript["Nodes"]?.AsArray(); if (nodes == null) return; - foreach (JToken node in nodes) + foreach (JsonNode? jsonNode in nodes) { - node["Type"] = node["Type"]?.Value()?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); - node["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; + if (jsonNode == null) + continue; + JsonObject nodeObject = jsonNode.AsObject(); + nodeObject["Type"] = nodeObject["Type"]?.GetValue().Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); + nodeObject["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; } } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayViewModel.cs b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayViewModel.cs index 71e06013d..4ffea1412 100644 --- a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayViewModel.cs +++ b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayViewModel.cs @@ -1,7 +1,8 @@ using System; +using System.Text.Json; +using System.Text.Json.Serialization; using Artemis.Core; using Artemis.UI.Shared.DataModelVisualization; -using Newtonsoft.Json; namespace Artemis.UI.Shared.DefaultTypes.DataModel.Display; @@ -11,16 +12,12 @@ namespace Artemis.UI.Shared.DefaultTypes.DataModel.Display; /// internal class DefaultDataModelDisplayViewModel : DataModelDisplayViewModel { - private readonly JsonSerializerSettings _serializerSettings; + private readonly JsonSerializerOptions _serializerSettings; private string _display; public DefaultDataModelDisplayViewModel() { - _serializerSettings = new JsonSerializerSettings - { - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - PreserveReferencesHandling = PreserveReferencesHandling.None - }; + _serializerSettings = new JsonSerializerOptions() {ReferenceHandler = ReferenceHandler.IgnoreCycles}; _display = "null"; } @@ -35,7 +32,7 @@ internal class DefaultDataModelDisplayViewModel : DataModelDisplayViewModel GetJsonAsync(this IClipboard clipboard, string format) { byte[]? bytes = (byte[]?) await clipboard.GetDataAsync(format); - return bytes == null ? default : CoreJson.DeserializeObject(Encoding.Unicode.GetString(bytes), true); + return bytes == null ? default : CoreJson.DeserializeObject(Encoding.Unicode.GetString(bytes)); } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ResetLayerProperty.cs b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ResetLayerProperty.cs index 6e8b9c90d..944d82cfe 100644 --- a/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ResetLayerProperty.cs +++ b/src/Artemis.UI.Shared/Services/ProfileEditor/Commands/ResetLayerProperty.cs @@ -32,7 +32,7 @@ public class ResetLayerProperty : IProfileEditorCommand /// public void Execute() { - string json = CoreJson.SerializeObject(_layerProperty.DefaultValue, true); + string json = CoreJson.SerializeObject(_layerProperty.DefaultValue); if (_keyframesEnabled) _layerProperty.KeyframesEnabled = false; diff --git a/src/Artemis.UI/Extensions/ProfileElementExtensions.cs b/src/Artemis.UI/Extensions/ProfileElementExtensions.cs index 8f811bd14..e91aa0807 100644 --- a/src/Artemis.UI/Extensions/ProfileElementExtensions.cs +++ b/src/Artemis.UI/Extensions/ProfileElementExtensions.cs @@ -19,7 +19,7 @@ public static class ProfileElementExtensions public static async Task CopyToClipboard(this Folder folder) { DataObject dataObject = new(); - string copy = CoreJson.SerializeObject(new FolderClipboardModel(folder), true); + string copy = CoreJson.SerializeObject(new FolderClipboardModel(folder)); dataObject.Set(ClipboardDataFormat, copy); await Shared.UI.Clipboard.SetDataObjectAsync(dataObject); } @@ -27,7 +27,7 @@ public static class ProfileElementExtensions public static async Task CopyToClipboard(this Layer layer) { DataObject dataObject = new(); - string copy = CoreJson.SerializeObject(layer.LayerEntity, true); + string copy = CoreJson.SerializeObject(layer.LayerEntity); dataObject.Set(ClipboardDataFormat, copy); await Shared.UI.Clipboard.SetDataObjectAsync(dataObject); } @@ -39,7 +39,7 @@ public static class ProfileElementExtensions if (bytes == null!) return null; - object? entity = CoreJson.DeserializeObject(Encoding.Unicode.GetString(bytes), true); + object? entity = CoreJson.DeserializeObject(Encoding.Unicode.GetString(bytes)); switch (entity) { case FolderClipboardModel folderClipboardModel: diff --git a/src/Artemis.UI/Models/FolderClipboardModel.cs b/src/Artemis.UI/Models/FolderClipboardModel.cs index 98301d394..a8f4eaedb 100644 --- a/src/Artemis.UI/Models/FolderClipboardModel.cs +++ b/src/Artemis.UI/Models/FolderClipboardModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text.Json.Serialization; using Artemis.Core; using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile.Abstract; @@ -7,7 +8,7 @@ using Artemis.UI.Exceptions; namespace Artemis.UI.Models; -public class FolderClipboardModel +public class FolderClipboardModel: IClipboardModel { public FolderClipboardModel(Folder folder) { @@ -20,7 +21,7 @@ public class FolderClipboardModel Layers.Add(allLayer.LayerEntity); } - // ReSharper disable once UnusedMember.Global - For JSON.NET + [JsonConstructor] public FolderClipboardModel() { FolderEntity = null; diff --git a/src/Artemis.UI/Models/IClipboardModel.cs b/src/Artemis.UI/Models/IClipboardModel.cs new file mode 100644 index 000000000..00273ee92 --- /dev/null +++ b/src/Artemis.UI/Models/IClipboardModel.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace Artemis.UI.Models; + +[JsonDerivedType(typeof(LayerClipboardModel))] +[JsonDerivedType(typeof(FolderClipboardModel))] +[JsonDerivedType(typeof(KeyframeClipboardModel))] +[JsonDerivedType(typeof(NodesClipboardModel))] +public interface IClipboardModel +{ +} \ No newline at end of file diff --git a/src/Artemis.UI/Models/KeyframeClipboardModel.cs b/src/Artemis.UI/Models/KeyframeClipboardModel.cs index e225fe225..0a57f2823 100644 --- a/src/Artemis.UI/Models/KeyframeClipboardModel.cs +++ b/src/Artemis.UI/Models/KeyframeClipboardModel.cs @@ -1,10 +1,10 @@ -using Artemis.Core; +using System.Text.Json.Serialization; +using Artemis.Core; using Artemis.Storage.Entities.Profile; -using Newtonsoft.Json; namespace Artemis.UI.Models; -public class KeyframeClipboardModel +public class KeyframeClipboardModel: IClipboardModel { public const string ClipboardDataFormat = "Artemis.Keyframes"; diff --git a/src/Artemis.UI/Models/LayerClipboardModel.cs b/src/Artemis.UI/Models/LayerClipboardModel.cs new file mode 100644 index 000000000..7fcb184d2 --- /dev/null +++ b/src/Artemis.UI/Models/LayerClipboardModel.cs @@ -0,0 +1,13 @@ +using Artemis.Core; + +namespace Artemis.UI.Models; + +public class LayerClipboardModel : IClipboardModel +{ + public LayerClipboardModel(Layer layer) + { + Layer = layer; + } + + public Layer Layer { get; set; } +} \ No newline at end of file diff --git a/src/Artemis.UI/Models/NodesClipboardModel.cs b/src/Artemis.UI/Models/NodesClipboardModel.cs index 42cd9832f..5aef8b9b0 100644 --- a/src/Artemis.UI/Models/NodesClipboardModel.cs +++ b/src/Artemis.UI/Models/NodesClipboardModel.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Serialization; using Artemis.Core; using Artemis.Storage.Entities.Profile.Nodes; namespace Artemis.UI.Models; -public class NodesClipboardModel +public class NodesClipboardModel: IClipboardModel { public NodesClipboardModel(NodeScript nodeScript, List nodes) { @@ -18,6 +19,7 @@ public class NodesClipboardModel Connections = nodeScript.Entity.Connections.Where(e => nodes.Any(n => n.Id == e.SourceNode) && nodes.Any(n => n.Id == e.TargetNode)).ToList(); } + [JsonConstructor] public NodesClipboardModel() { Nodes = new List(); diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Workshop/WorkshopDebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Workshop/WorkshopDebugViewModel.cs index 26a1e031f..e58a4fe22 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Workshop/WorkshopDebugViewModel.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Workshop/WorkshopDebugViewModel.cs @@ -1,15 +1,14 @@ +using System.Text.Json; using System.Threading; using Artemis.UI.Extensions; using Artemis.UI.Shared; using Artemis.WebClient.Workshop.Services; -using Newtonsoft.Json; using PropertyChanged.SourceGenerator; namespace Artemis.UI.Screens.Debugger.Workshop; public partial class WorkshopDebugViewModel : ActivatableViewModelBase { - [Notify] private string? _token; [Notify] private bool _emailVerified; [Notify] private string? _claims; @@ -18,12 +17,12 @@ public partial class WorkshopDebugViewModel : ActivatableViewModelBase public WorkshopDebugViewModel(IWorkshopService workshopService, IAuthenticationService authenticationService) { DisplayName = "Workshop"; - + this.WhenActivatedAsync(async _ => { Token = await authenticationService.GetBearer(); EmailVerified = authenticationService.GetIsEmailVerified(); - Claims = JsonConvert.SerializeObject(authenticationService.Claims, Formatting.Indented); + Claims = JsonSerializer.Serialize(authenticationService.Claims, new JsonSerializerOptions {WriteIndented = true}); WorkshopStatus = await workshopService.GetWorkshopStatus(CancellationToken.None); }); } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs index 3faad62e1..0cf1a7ce2 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarViewModel.cs @@ -14,7 +14,6 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; -using Newtonsoft.Json; using PropertyChanged.SourceGenerator; using ReactiveUI; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemViewModel.cs index df30c8b48..fc47438fc 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemViewModel.cs @@ -36,7 +36,7 @@ public class FolderTreeItemViewModel : TreeItemViewModel { await ProfileEditorService.SaveProfileAsync(); - FolderEntity copy = CoreJson.DeserializeObject(CoreJson.SerializeObject(Folder.FolderEntity, true), true)!; + FolderEntity copy = CoreJson.DeserializeObject(CoreJson.SerializeObject(Folder.FolderEntity))!; copy.Id = Guid.NewGuid(); copy.Name = Folder.Parent.GetNewFolderName(copy.Name + " - copy"); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemViewModel.cs index 83554ac12..77112701a 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemViewModel.cs @@ -37,7 +37,7 @@ public class LayerTreeItemViewModel : TreeItemViewModel { await ProfileEditorService.SaveProfileAsync(); - LayerEntity copy = CoreJson.DeserializeObject(CoreJson.SerializeObject(Layer.LayerEntity, true), true)!; + LayerEntity copy = CoreJson.DeserializeObject(CoreJson.SerializeObject(Layer.LayerEntity))!; copy.Id = Guid.NewGuid(); copy.Name = Layer.Parent.GetNewFolderName(copy.Name + " - copy"); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeViewModel.cs index a0d2b5de6..6a92ba3ad 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeViewModel.cs @@ -135,7 +135,7 @@ public partial class TimelineKeyframeViewModel : ActivatableViewModelBase, IT else keyframes.AddRange(_profileEditorService.SelectedKeyframes.Select(k => new KeyframeClipboardModel(k))); - string copy = CoreJson.SerializeObject(keyframes, true); + string copy = CoreJson.SerializeObject(keyframes); DataObject dataObject = new(); dataObject.Set(KeyframeClipboardModel.ClipboardDataFormat, copy); await Shared.UI.Clipboard.SetDataObjectAsync(dataObject); diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarCategoryViewModel.cs b/src/Artemis.UI/Screens/Sidebar/SidebarCategoryViewModel.cs index 5b8ad504b..67b642428 100644 --- a/src/Artemis.UI/Screens/Sidebar/SidebarCategoryViewModel.cs +++ b/src/Artemis.UI/Screens/Sidebar/SidebarCategoryViewModel.cs @@ -18,7 +18,6 @@ using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; using DynamicData; using DynamicData.Binding; -using Newtonsoft.Json; using PropertyChanged.SourceGenerator; using ReactiveUI; @@ -162,7 +161,7 @@ public partial class SidebarCategoryViewModel : ActivatableViewModelBase // Removing this at some point in the future if (result[0].EndsWith("json")) { - ProfileConfigurationExportModel? exportModel = JsonConvert.DeserializeObject(await File.ReadAllTextAsync(result[0]), IProfileService.ExportSettings); + ProfileConfigurationExportModel? exportModel = CoreJson.DeserializeObject(await File.ReadAllTextAsync(result[0])); if (exportModel == null) { await _windowService.ShowConfirmContentDialog("Import profile", "Failed to import this profile, make sure it is a valid Artemis profile.", "Confirm", null); @@ -235,8 +234,8 @@ public partial class SidebarCategoryViewModel : ActivatableViewModelBase { MemoryStream archiveStream = new(); - string configurationJson = JsonConvert.SerializeObject(exportModel.ProfileConfigurationEntity, IProfileService.ExportSettings); - string profileJson = JsonConvert.SerializeObject(exportModel.ProfileEntity, IProfileService.ExportSettings); + string configurationJson = CoreJson.SerializeObject(exportModel.ProfileConfigurationEntity); + string profileJson = CoreJson.SerializeObject(exportModel.ProfileEntity); // Create a ZIP archive using (ZipArchive archive = new(archiveStream, ZipArchiveMode.Create, true)) diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs index 9ffb3b2db..ad86a82fa 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeScriptViewModel.cs @@ -277,7 +277,7 @@ public partial class NodeScriptViewModel : ActivatableViewModelBase { List nodes = NodeViewModels.Where(vm => vm.IsSelected).Select(vm => vm.Node).Where(n => !n.IsDefaultNode && !n.IsExitNode).ToList(); DataObject dataObject = new(); - string copy = CoreJson.SerializeObject(new NodesClipboardModel(NodeScript, nodes), true); + string copy = CoreJson.SerializeObject(new NodesClipboardModel(NodeScript, nodes)); dataObject.Set(CLIPBOARD_DATA_FORMAT, copy); await Shared.UI.Clipboard.SetDataObjectAsync(dataObject); } @@ -288,7 +288,7 @@ public partial class NodeScriptViewModel : ActivatableViewModelBase if (bytes == null!) return; - NodesClipboardModel? nodesClipboardModel = CoreJson.DeserializeObject(Encoding.Unicode.GetString(bytes), true); + NodesClipboardModel? nodesClipboardModel = CoreJson.DeserializeObject(Encoding.Unicode.GetString(bytes)); if (nodesClipboardModel == null) return; diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs index 334055b3b..d607fd536 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs @@ -1,10 +1,8 @@ using System.IO.Compression; using System.Net.Http.Headers; using Artemis.Core; -using Artemis.UI.Shared.Utilities; using Artemis.WebClient.Workshop.Entities; using Artemis.WebClient.Workshop.Exceptions; -using Newtonsoft.Json; using RGB.NET.Layout; namespace Artemis.WebClient.Workshop.Handlers.UploadHandlers; @@ -70,7 +68,7 @@ public class LayoutEntryUploadHandler : IEntryUploadHandler if (!response.IsSuccessStatusCode) return EntryUploadResult.FromFailure($"{response.StatusCode} - {await response.Content.ReadAsStringAsync(cancellationToken)}"); - Release? release = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync(cancellationToken)); + Release? release = CoreJson.DeserializeObject(await response.Content.ReadAsStringAsync(cancellationToken)); return release != null ? EntryUploadResult.FromSuccess(release) : EntryUploadResult.FromFailure("Failed to deserialize response"); } diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/PluginEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/PluginEntryUploadHandler.cs index 50fa0a283..0296c297f 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/PluginEntryUploadHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/PluginEntryUploadHandler.cs @@ -1,6 +1,6 @@ using System.Net.Http.Headers; +using Artemis.Core; using Artemis.WebClient.Workshop.Entities; -using Newtonsoft.Json; namespace Artemis.WebClient.Workshop.Handlers.UploadHandlers; @@ -34,7 +34,7 @@ public class PluginEntryUploadHandler : IEntryUploadHandler if (!response.IsSuccessStatusCode) return EntryUploadResult.FromFailure($"{response.StatusCode} - {await response.Content.ReadAsStringAsync(cancellationToken)}"); - Release? release = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync(cancellationToken)); + Release? release = CoreJson.DeserializeObject(await response.Content.ReadAsStringAsync(cancellationToken)); return release != null ? EntryUploadResult.FromSuccess(release) : EntryUploadResult.FromFailure("Failed to deserialize response"); } } \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs index e5a5fa961..2280d4215 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs @@ -1,8 +1,7 @@ using System.Net.Http.Headers; +using Artemis.Core; using Artemis.Core.Services; -using Artemis.UI.Shared.Utilities; using Artemis.WebClient.Workshop.Entities; -using Newtonsoft.Json; namespace Artemis.WebClient.Workshop.Handlers.UploadHandlers; @@ -39,7 +38,7 @@ public class ProfileEntryUploadHandler : IEntryUploadHandler if (!response.IsSuccessStatusCode) return EntryUploadResult.FromFailure($"{response.StatusCode} - {await response.Content.ReadAsStringAsync(cancellationToken)}"); - Release? release = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync(cancellationToken)); + Release? release = CoreJson.DeserializeObject(await response.Content.ReadAsStringAsync(cancellationToken)); return release != null ? EntryUploadResult.FromSuccess(release) : EntryUploadResult.FromFailure("Failed to deserialize response"); } } \ No newline at end of file diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 51e95be43..214bbcd9c 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -33,7 +33,6 @@ - @@ -52,6 +51,7 @@ + \ No newline at end of file