mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 11:26:27 +00:00
Replace JSON.NET with System.Text.json (#840)
This commit is contained in:
1 parent
e112ca9da8
commit
a340f8822e
63 files changed
+466
-584
No files matched your search
@@ -42,7 +42,6 @@
|
||||
<PackageReference Include="Humanizer.Core" />
|
||||
<PackageReference Include="JetBrains.Annotations" />
|
||||
<PackageReference Include="McMaster.NETCore.Plugins" />
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
<PackageReference Include="RGB.NET.Core" />
|
||||
<PackageReference Include="RGB.NET.Layout" />
|
||||
<PackageReference Include="RGB.NET.Presets" />
|
||||
@@ -50,6 +49,7 @@
|
||||
<PackageReference Include="Serilog.Sinks.Debug" />
|
||||
<PackageReference Include="Serilog.Sinks.File" />
|
||||
<PackageReference Include="SkiaSharp" />
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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
|
||||
/// </summary>
|
||||
public static readonly string LayoutsFolder = Path.Combine(DataFolder, "User Layouts");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The full path to the Artemis user layouts folder
|
||||
/// </summary>
|
||||
@@ -94,20 +92,6 @@ public static class Constants
|
||||
/// </summary>
|
||||
public static readonly Plugin CorePlugin = new(CorePluginInfo, new DirectoryInfo(ApplicationFolder), null);
|
||||
|
||||
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()
|
||||
{
|
||||
Converters = new List<JsonConverter> {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()}
|
||||
};
|
||||
|
||||
internal static JsonSerializerSettings JsonConvertTypedSettings = new()
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All,
|
||||
Converters = new List<JsonConverter> {new SKColorConverter(), new NumericJsonConverter(), new ForgivingIntConverter()}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A read-only collection containing all primitive numeric types
|
||||
/// </summary>
|
||||
@@ -155,4 +139,8 @@ public static class Constants
|
||||
/// Gets the startup arguments provided to the application
|
||||
/// </summary>
|
||||
public static ReadOnlyCollection<string> StartupArguments { get; set; } = null!;
|
||||
|
||||
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 readonly JsonSerializerOptions JsonConvertSettings = new() {Converters = {new SKColorConverter(), new NumericJsonConverter()}};
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Artemis.Core.JsonConverters;
|
||||
|
||||
/// <summary>
|
||||
/// An int converter that, if required, will round float values
|
||||
/// </summary>
|
||||
internal class ForgivingIntConverter : JsonConverter<int>
|
||||
{
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
JValue? jsonValue = serializer.Deserialize<JValue>(reader);
|
||||
if (jsonValue == null)
|
||||
throw new JsonReaderException("Failed to deserialize forgiving int value");
|
||||
|
||||
if (jsonValue.Type == JTokenType.Float)
|
||||
return (int) Math.Round(jsonValue.Value<double>());
|
||||
if (jsonValue.Type == JTokenType.Integer)
|
||||
return jsonValue.Value<int>();
|
||||
|
||||
throw new JsonReaderException("Failed to deserialize forgiving int value");
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core.JsonConverters
|
||||
{
|
||||
/// <summary>
|
||||
/// Version converter that is forgiving of missing parts of the version string,
|
||||
/// setting them to zero instead of -1.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Numeric>
|
||||
namespace Artemis.Core.JsonConverters
|
||||
{
|
||||
#region Overrides of JsonConverter<Numeric>
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void WriteJson(JsonWriter writer, Numeric value, JsonSerializer serializer)
|
||||
internal class NumericJsonConverter : JsonConverter<Numeric>
|
||||
{
|
||||
float floatValue = value;
|
||||
writer.WriteValue(floatValue);
|
||||
}
|
||||
public override void Write(Utf8JsonWriter writer, Numeric value, JsonSerializerOptions options)
|
||||
{
|
||||
float floatValue = value;
|
||||
writer.WriteNumberValue(floatValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<SKColor>
|
||||
namespace Artemis.Core.JsonConverters
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, SKColor value, JsonSerializer serializer)
|
||||
internal class SKColorConverter : JsonConverter<SKColor>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core.JsonConverters;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class StreamConverter : JsonConverter<Stream>
|
||||
{
|
||||
#region Overrides of JsonConverter<Stream>
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void WriteJson(JsonWriter writer, Stream? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
using MemoryStream memoryStream = new();
|
||||
value.Position = 0;
|
||||
value.CopyTo(memoryStream);
|
||||
writer.WriteValue(memoryStream.ToArray());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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
|
||||
}
|
||||
@@ -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<FolderEntity>(CoreJson.SerializeObject(FolderEntity, true), true)!;
|
||||
FolderEntity entityCopy = CoreJson.Deserialize<FolderEntity>(CoreJson.Serialize(FolderEntity))!;
|
||||
entityCopy.Id = Guid.NewGuid();
|
||||
entityCopy.Name += " - Copy";
|
||||
|
||||
|
||||
@@ -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,8 +324,8 @@ public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
|
||||
// Reference types make a deep clone (ab)using JSON
|
||||
else
|
||||
{
|
||||
string json = CoreJson.SerializeObject(DefaultValue, true);
|
||||
SetCurrentValue(CoreJson.DeserializeObject<T>(json)!);
|
||||
string json = CoreJson.Serialize(DefaultValue);
|
||||
SetCurrentValue(CoreJson.Deserialize<T>(json)!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
|
||||
|
||||
try
|
||||
{
|
||||
T? value = CoreJson.DeserializeObject<T>(keyframeEntity.Value);
|
||||
T? value = CoreJson.Deserialize<T>(keyframeEntity.Value);
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
@@ -625,7 +625,7 @@ public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
|
||||
try
|
||||
{
|
||||
if (Entity.Value != null)
|
||||
BaseValue = CoreJson.DeserializeObject<T>(Entity.Value)!;
|
||||
BaseValue = CoreJson.Deserialize<T>(Entity.Value)!;
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
@@ -664,7 +664,7 @@ public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
|
||||
if (!_isInitialized)
|
||||
throw new ArtemisCoreException("Layer property is not yet initialized");
|
||||
|
||||
Entity.Value = CoreJson.SerializeObject(BaseValue);
|
||||
Entity.Value = CoreJson.Serialize(BaseValue);
|
||||
Entity.KeyframesEnabled = KeyframesEnabled;
|
||||
Entity.KeyframeEntities.Clear();
|
||||
Entity.KeyframeEntities.AddRange(Keyframes.Select(k => k.GetKeyframeEntity()));
|
||||
|
||||
@@ -69,7 +69,7 @@ public class LayerPropertyKeyframe<T> : CorePropertyChanged, ILayerPropertyKeyfr
|
||||
{
|
||||
return new KeyframeEntity
|
||||
{
|
||||
Value = CoreJson.SerializeObject(Value),
|
||||
Value = CoreJson.Serialize(Value),
|
||||
Position = Position,
|
||||
EasingFunction = (int) EasingFunction
|
||||
};
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Artemis.Core.JsonConverters;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
/// <summary>
|
||||
/// A model that can be used to serialize a profile configuration, it's profile and it's icon
|
||||
/// </summary>
|
||||
public class ProfileConfigurationExportModel : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the storage entity of the profile configuration
|
||||
/// </summary>
|
||||
public ProfileConfigurationEntity? ProfileConfigurationEntity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the storage entity of the profile
|
||||
/// </summary>
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
public ProfileEntity ProfileEntity { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a stream containing the profile image
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StreamConverter))]
|
||||
public Stream? ProfileImage { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
ProfileImage?.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -3,14 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Plugins;
|
||||
using Humanizer;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Represents basic info about a plugin feature and contains a reference to the instance of said feature
|
||||
/// </summary>
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
{
|
||||
private string? _description;
|
||||
@@ -64,7 +62,6 @@ public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// The name of the feature
|
||||
/// </summary>
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
@@ -74,7 +71,6 @@ public class PluginFeatureInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// A short description of the feature
|
||||
/// </summary>
|
||||
[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.
|
||||
/// <para>Note: always <see langword="true" /> if this is the plugin's only feature</para>
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public bool AlwaysEnabled { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Represents basic info about a plugin and contains a reference to the instance of said plugin
|
||||
/// </summary>
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
{
|
||||
private Version? _api;
|
||||
@@ -28,10 +25,11 @@ 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;
|
||||
|
||||
[JsonConstructor]
|
||||
internal PluginInfo()
|
||||
{
|
||||
}
|
||||
@@ -39,7 +37,8 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// The plugins GUID
|
||||
/// </summary>
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
[JsonRequired]
|
||||
[JsonInclude]
|
||||
public Guid Guid
|
||||
{
|
||||
get => _guid;
|
||||
@@ -49,7 +48,8 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// The name of the plugin
|
||||
/// </summary>
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
[JsonRequired]
|
||||
[JsonInclude]
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
@@ -59,7 +59,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// A short description of the plugin
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Description
|
||||
{
|
||||
get => _description;
|
||||
@@ -69,7 +68,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets the author of this plugin
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Author
|
||||
{
|
||||
get => _author;
|
||||
@@ -79,7 +77,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets the website of this plugin or its author
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Uri? Website
|
||||
{
|
||||
get => _website;
|
||||
@@ -89,7 +86,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets the repository of this plugin
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Uri? Repository
|
||||
{
|
||||
get => _repository;
|
||||
@@ -99,7 +95,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets the help page of this plugin
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Uri? HelpPage
|
||||
{
|
||||
get => _helpPage;
|
||||
@@ -109,7 +104,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets the help page of this plugin
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Uri? License
|
||||
{
|
||||
get => _license;
|
||||
@@ -119,7 +113,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets the author of this plugin
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? LicenseName
|
||||
{
|
||||
get => _licenseName;
|
||||
@@ -130,7 +123,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// The plugins display icon that's shown in the settings see <see href="https://materialdesignicons.com" /> for
|
||||
/// available icons
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Icon
|
||||
{
|
||||
get => _icon;
|
||||
@@ -140,7 +132,8 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// The version of the plugin
|
||||
/// </summary>
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
[JsonRequired]
|
||||
[JsonInclude]
|
||||
public string Version
|
||||
{
|
||||
get => _version;
|
||||
@@ -150,7 +143,8 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// The main entry DLL, should contain a class implementing Plugin
|
||||
/// </summary>
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
[JsonRequired]
|
||||
[JsonInclude]
|
||||
public string Main
|
||||
{
|
||||
get => _main;
|
||||
@@ -161,8 +155,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
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public bool AutoEnableFeatures
|
||||
{
|
||||
get => _autoEnableFeatures;
|
||||
@@ -172,7 +164,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether this plugin requires elevated admin privileges
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
public bool RequiresAdmin
|
||||
{
|
||||
get => _requiresAdmin;
|
||||
@@ -182,8 +174,6 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether hot reloading this plugin is supported
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public bool HotReloadSupported
|
||||
{
|
||||
get => _hotReloadSupported;
|
||||
@@ -193,7 +183,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
public PluginPlatform? Platforms
|
||||
{
|
||||
get => _platforms;
|
||||
@@ -203,8 +193,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets the API version the plugin was built for
|
||||
/// </summary>
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
[JsonConverter(typeof(ForgivingVersionConverter))]
|
||||
[JsonInclude]
|
||||
public Version? Api
|
||||
{
|
||||
get => _api;
|
||||
@@ -214,6 +203,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets the plugin this info is associated with
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Plugin Plugin
|
||||
{
|
||||
get => _plugin;
|
||||
@@ -223,6 +213,7 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
/// <summary>
|
||||
/// Gets a string representing either a full path pointing to an svg or the markdown icon
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string? ResolvedIcon
|
||||
{
|
||||
get
|
||||
@@ -247,9 +238,11 @@ public class PluginInfo : CorePropertyChanged, IPrerequisitesSubject
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public List<PluginPrerequisite> Prerequisites { get; } = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public IEnumerable<PluginPrerequisite> PlatformPrerequisites => Prerequisites.Where(p => p.AppliesToPlatform());
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -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.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum PluginPlatform
|
||||
{
|
||||
/// <summary>The Windows platform.</summary>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -23,9 +23,9 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
||||
Name = pluginSettingEntity.Name;
|
||||
try
|
||||
{
|
||||
_value = CoreJson.DeserializeObject<T>(pluginSettingEntity.Value)!;
|
||||
_value = CoreJson.Deserialize<T>(pluginSettingEntity.Value)!;
|
||||
}
|
||||
catch (JsonReaderException)
|
||||
catch (JsonException)
|
||||
{
|
||||
_value = default!;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
||||
public string Name { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasChanged => CoreJson.SerializeObject(Value) != _pluginSettingEntity.Value;
|
||||
public bool HasChanged => CoreJson.Serialize(Value) != _pluginSettingEntity.Value;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool AutoSave { get; set; }
|
||||
@@ -84,7 +84,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
||||
/// <inheritdoc />
|
||||
public void RejectChanges()
|
||||
{
|
||||
Value = CoreJson.DeserializeObject<T>(_pluginSettingEntity.Value);
|
||||
Value = CoreJson.Deserialize<T>(_pluginSettingEntity.Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -93,7 +93,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
||||
if (!HasChanged)
|
||||
return;
|
||||
|
||||
_pluginSettingEntity.Value = CoreJson.SerializeObject(Value);
|
||||
_pluginSettingEntity.Value = CoreJson.Serialize(Value);
|
||||
_pluginRepository.SaveSetting(_pluginSettingEntity);
|
||||
OnSettingSaved();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class PluginSettings
|
||||
{
|
||||
Name = name,
|
||||
PluginGuid = Plugin.Guid,
|
||||
Value = CoreJson.SerializeObject(defaultValue)
|
||||
Value = CoreJson.Serialize(defaultValue)
|
||||
};
|
||||
_pluginRepository.AddSetting(settingEntity);
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core.Services.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Represents build information related to the currently running Artemis build
|
||||
/// </summary>
|
||||
public class BuildInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique ID of this build
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public int BuildId { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build number. This contains the date and the build count for that day.
|
||||
/// <para>Per example <c>20210108.4</c></para>
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public double BuildNumber { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build number formatted as a string. This contains the date and the build count for that day.
|
||||
/// <para>Per example <c>20210108.4</c></para>
|
||||
/// </summary>
|
||||
public string BuildNumberDisplay => BuildNumber.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the branch of the triggering repo the build was created for.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string SourceBranch { get; internal set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the commit ID used to create this build
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string SourceVersion { get; internal set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the current build is a local build
|
||||
/// </summary>
|
||||
public bool IsLocalBuild { get; internal set; }
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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.Serialize(nodeScript.Entity);
|
||||
}
|
||||
|
||||
public void ImportScript(string json, NodeScript target)
|
||||
{
|
||||
NodeScriptEntity? entity = JsonConvert.DeserializeObject<NodeScriptEntity>(json);
|
||||
NodeScriptEntity? entity = CoreJson.Deserialize<NodeScriptEntity>(json);
|
||||
if (entity == null)
|
||||
throw new ArtemisCoreException("Failed to load node script");
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ internal class PluginManagementService : IPluginManagementService
|
||||
throw new ArtemisPluginException("Couldn't find a plugin.json in " + zipFile.FullName);
|
||||
|
||||
using StreamReader reader = new(metaDataFileEntry.Open());
|
||||
PluginInfo builtInPluginInfo = CoreJson.DeserializeObject<PluginInfo>(reader.ReadToEnd())!;
|
||||
PluginInfo builtInPluginInfo = CoreJson.Deserialize<PluginInfo>(reader.ReadToEnd())!;
|
||||
string preferred = builtInPluginInfo.PreferredPluginDirectory;
|
||||
|
||||
// Find the matching plugin in the plugin folder
|
||||
@@ -360,7 +360,7 @@ internal class PluginManagementService : IPluginManagementService
|
||||
_logger.Warning(new ArtemisPluginException("Couldn't find the plugins metadata file at " + metadataFile), "Plugin exception");
|
||||
|
||||
// PluginInfo contains the ID which we need to move on
|
||||
PluginInfo pluginInfo = CoreJson.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile))!;
|
||||
PluginInfo pluginInfo = CoreJson.Deserialize<PluginInfo>(File.ReadAllText(metadataFile))!;
|
||||
|
||||
if (!pluginInfo.IsCompatible)
|
||||
return null;
|
||||
@@ -610,7 +610,7 @@ internal class PluginManagementService : IPluginManagementService
|
||||
throw new ArtemisPluginException("Couldn't find a plugin.json in " + fileName);
|
||||
|
||||
using StreamReader reader = new(metaDataFileEntry.Open());
|
||||
PluginInfo pluginInfo = CoreJson.DeserializeObject<PluginInfo>(reader.ReadToEnd())!;
|
||||
PluginInfo pluginInfo = CoreJson.Deserialize<PluginInfo>(reader.ReadToEnd())!;
|
||||
if (!pluginInfo.Main.EndsWith(".dll"))
|
||||
throw new ArtemisPluginException("Main entry in plugin.json must point to a .dll file");
|
||||
|
||||
|
||||
@@ -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;
|
||||
/// </summary>
|
||||
public interface IProfileService : IArtemisService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the JSON serializer settings used to import/export profiles.
|
||||
/// </summary>
|
||||
public static JsonSerializerSettings ExportSettings { get; } = new() {TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented};
|
||||
|
||||
/// <summary>
|
||||
/// Gets a read only collection containing all the profile categories.
|
||||
/// </summary>
|
||||
|
||||
@@ -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.Serialize(profileConfiguration.Entity);
|
||||
string profileJson = CoreJson.Serialize(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<JObject>(await configurationReader.ReadToEndAsync(), IProfileService.ExportSettings);
|
||||
JsonObject? configurationJson = CoreJson.Deserialize<JsonObject>(await configurationReader.ReadToEndAsync());
|
||||
// Deserialize profile to JObject
|
||||
await using Stream profileStream = profileEntry.Open();
|
||||
using StreamReader profileReader = new(profileStream);
|
||||
JObject? profileJson = JsonConvert.DeserializeObject<JObject>(await profileReader.ReadToEndAsync(), IProfileService.ExportSettings);
|
||||
JsonObject? profileJson = CoreJson.Deserialize<JsonObject>(await profileReader.ReadToEndAsync());
|
||||
|
||||
// Before deserializing, apply any pending migrations
|
||||
MigrateProfile(configurationJson, profileJson);
|
||||
|
||||
// Deserialize profile configuration to ProfileConfigurationEntity
|
||||
ProfileConfigurationEntity? configurationEntity = configurationJson?.ToObject<ProfileConfigurationEntity>(JsonSerializer.Create(IProfileService.ExportSettings));
|
||||
ProfileConfigurationEntity? configurationEntity = configurationJson?.Deserialize<ProfileConfigurationEntity>(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<ProfileEntity>(JsonSerializer.Create(IProfileService.ExportSettings));
|
||||
ProfileEntity? profileEntity = profileJson?.Deserialize<ProfileEntity>(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<int>())
|
||||
if (profileMigrator.Version <= configurationJson["Version"]!.GetValue<int>())
|
||||
continue;
|
||||
|
||||
profileMigrator.Migrate(configurationJson, profileJson);
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Modules;
|
||||
using EmbedIO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core.Services;
|
||||
|
||||
@@ -15,10 +19,12 @@ namespace Artemis.Core.Services;
|
||||
public class DataModelJsonPluginEndPoint<T> : PluginEndPoint where T : DataModel, new()
|
||||
{
|
||||
private readonly Module<T> _module;
|
||||
private readonly Action<T, T> _update;
|
||||
|
||||
internal DataModelJsonPluginEndPoint(Module<T> module, string name, PluginsModule pluginsModule) : base(module, name, pluginsModule)
|
||||
{
|
||||
_module = module ?? throw new ArgumentNullException(nameof(module));
|
||||
_update = CreateUpdateAction();
|
||||
|
||||
ThrowOnFail = true;
|
||||
Accepts = MimeType.Json;
|
||||
@@ -31,8 +37,6 @@ public class DataModelJsonPluginEndPoint<T> : PluginEndPoint where T : DataModel
|
||||
/// </summary>
|
||||
public bool ThrowOnFail { get; set; }
|
||||
|
||||
#region Overrides of PluginEndPoint
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task ProcessRequest(IHttpContext context)
|
||||
{
|
||||
@@ -44,7 +48,9 @@ public class DataModelJsonPluginEndPoint<T> : PluginEndPoint where T : DataModel
|
||||
using TextReader reader = context.OpenRequestText();
|
||||
try
|
||||
{
|
||||
JsonConvert.PopulateObject(await reader.ReadToEndAsync(), _module.DataModel);
|
||||
T? dataModel = CoreJson.Deserialize<T>(await reader.ReadToEndAsync());
|
||||
if (dataModel != null)
|
||||
_update(dataModel, _module.DataModel);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
@@ -53,5 +59,26 @@ public class DataModelJsonPluginEndPoint<T> : PluginEndPoint where T : DataModel
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
private Action<T, T> CreateUpdateAction()
|
||||
{
|
||||
ParameterExpression sourceParameter = Expression.Parameter(typeof(T), "source");
|
||||
ParameterExpression targetParameter = Expression.Parameter(typeof(T), "target");
|
||||
|
||||
IEnumerable<BinaryExpression> assignments = typeof(T)
|
||||
.GetProperties()
|
||||
.Where(prop => prop.CanWrite && prop.GetSetMethod() != null &&
|
||||
prop.GetSetMethod()!.IsPublic &&
|
||||
!prop.IsDefined(typeof(JsonIgnoreAttribute), false) &&
|
||||
!prop.PropertyType.IsAssignableTo(typeof(IDataModelEvent)))
|
||||
.Select(prop =>
|
||||
{
|
||||
MemberExpression sourceProperty = Expression.Property(sourceParameter, prop);
|
||||
MemberExpression targetProperty = Expression.Property(targetParameter, prop);
|
||||
return Expression.Assign(targetProperty, sourceProperty);
|
||||
});
|
||||
|
||||
BlockExpression body = Expression.Block(assignments);
|
||||
|
||||
return Expression.Lambda<Action<T, T>>(body, sourceParameter, targetParameter).Compile();
|
||||
}
|
||||
}
|
||||
@@ -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<T> : PluginEndPoint
|
||||
object? response = null;
|
||||
try
|
||||
{
|
||||
T? deserialized = JsonConvert.DeserializeObject<T>(await reader.ReadToEndAsync());
|
||||
T? deserialized = JsonSerializer.Deserialize<T>(await reader.ReadToEndAsync());
|
||||
if (deserialized == null)
|
||||
throw new JsonException("Deserialization returned null");
|
||||
|
||||
@@ -74,7 +74,7 @@ public class JsonPluginEndPoint<T> : PluginEndPoint
|
||||
}
|
||||
|
||||
await using TextWriter writer = context.OpenResponseText();
|
||||
await writer.WriteAsync(JsonConvert.SerializeObject(response));
|
||||
await writer.WriteAsync(JsonSerializer.Serialize(response));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using EmbedIO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core.Services;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface IWebServerService : IArtemisService
|
||||
/// <param name="requestHandler"></param>
|
||||
/// <returns>The resulting end point</returns>
|
||||
JsonPluginEndPoint<T> AddResponsiveJsonEndPoint<T>(PluginFeature feature, string endPointName, Func<T, object?> requestHandler);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new endpoint that directly maps received JSON to the data model of the provided <paramref name="module" />.
|
||||
/// </summary>
|
||||
@@ -51,8 +51,9 @@ public interface IWebServerService : IArtemisService
|
||||
/// <param name="module">The module whose datamodel to apply the received JSON to</param>
|
||||
/// <param name="endPointName">The name of the end point, must be unique</param>
|
||||
/// <returns>The resulting end point</returns>
|
||||
[Obsolete("This way of updating is too unpredictable in combination with nested events, use AddJsonEndPoint<T> to update manually instead")]
|
||||
DataModelJsonPluginEndPoint<T> AddDataModelJsonEndPoint<T>(Module<T> module, string endPointName) where T : DataModel, new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new endpoint for the given plugin feature receiving an a <see cref="string" />.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,12 +3,13 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
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 +23,7 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
private readonly PluginSetting<bool> _webServerEnabledSetting;
|
||||
private readonly PluginSetting<int> _webServerPortSetting;
|
||||
private readonly object _webserverLock = new();
|
||||
private readonly JsonSerializerOptions _jsonOptions = new(CoreJson.GetJsonSerializerOptions()) {ReferenceHandler = ReferenceHandler.IgnoreCycles, WriteIndented = true};
|
||||
private CancellationTokenSource? _cts;
|
||||
|
||||
public WebServerService(ILogger logger, ICoreService coreService, ISettingsService settingsService, IPluginManagementService pluginManagementService)
|
||||
@@ -120,7 +122,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 +140,7 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
// Add registered controllers to the API module
|
||||
foreach (WebApiControllerRegistration registration in _controllers)
|
||||
apiModule.RegisterController(registration.ControllerType, (Func<WebApiController>) registration.UntypedFactory);
|
||||
|
||||
|
||||
// Listen for state changes.
|
||||
server.StateChanged += (s, e) => _logger.Verbose("WebServer new state - {state}", e.NewState);
|
||||
|
||||
@@ -173,7 +175,7 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
OnWebServerStarted();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AutoStartWebServer()
|
||||
{
|
||||
try
|
||||
@@ -240,6 +242,7 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
[Obsolete("Use AddJsonEndPoint<T>(PluginFeature feature, string endPointName, Action<T> requestHandler) instead")]
|
||||
public DataModelJsonPluginEndPoint<T> AddDataModelJsonEndPoint<T>(Module<T> module, string endPointName) where T : DataModel, new()
|
||||
{
|
||||
if (module == null) throw new ArgumentNullException(nameof(module));
|
||||
@@ -316,7 +319,7 @@ internal class WebServerService : IWebServerService, IDisposable
|
||||
context.Response.ContentType = MimeType.Json;
|
||||
await using TextWriter writer = context.OpenResponseText();
|
||||
|
||||
string response = JsonConvert.SerializeObject(new Dictionary<string, object?>
|
||||
string response = CoreJson.Serialize(new Dictionary<string, object?>
|
||||
{
|
||||
{"StatusCode", context.Response.StatusCode},
|
||||
{"StackTrace", exception.StackTrace},
|
||||
@@ -331,17 +334,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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,62 +9,36 @@ namespace Artemis.Core;
|
||||
/// </summary>
|
||||
public static class CoreJson
|
||||
{
|
||||
#region Serialize
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the specified object to a JSON string.
|
||||
/// </summary>
|
||||
/// <param name="value">The object to serialize.</param>
|
||||
/// <param name="handleTypeNames">If set to true sets TypeNameHandling to <see cref="TypeNameHandling.All" /></param>
|
||||
/// <returns>A JSON string representation of the object.</returns>
|
||||
[DebuggerStepThrough]
|
||||
public static string SerializeObject(object? value, bool handleTypeNames = false)
|
||||
public static string Serialize(object? value)
|
||||
{
|
||||
return JsonConvert.SerializeObject(value, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings);
|
||||
return JsonSerializer.Serialize(value, Constants.JsonConvertSettings);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Deserialize
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to a .NET object.
|
||||
/// </summary>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <param name="handleTypeNames">If set to true sets TypeNameHandling to <see cref="TypeNameHandling.All" /></param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
[DebuggerStepThrough]
|
||||
public static object? DeserializeObject(string value, bool handleTypeNames = false)
|
||||
{
|
||||
return JsonConvert.DeserializeObject(value, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to the specified .NET type.
|
||||
/// </summary>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <param name="type">The <see cref="Type" /> of object being deserialized.</param>
|
||||
/// <param name="handleTypeNames">If set to true sets TypeNameHandling to <see cref="TypeNameHandling.All" /></param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
[DebuggerStepThrough]
|
||||
public static object? DeserializeObject(string value, Type type, bool handleTypeNames = false)
|
||||
{
|
||||
return JsonConvert.DeserializeObject(value, type, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to the specified .NET type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize to.</typeparam>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <param name="handleTypeNames">If set to true sets TypeNameHandling to <see cref="TypeNameHandling.All" /></param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
[DebuggerStepThrough]
|
||||
[return: MaybeNull]
|
||||
public static T DeserializeObject<T>(string value, bool handleTypeNames = false)
|
||||
public static T Deserialize<T>(string value)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(value, handleTypeNames ? Constants.JsonConvertTypedSettings : Constants.JsonConvertSettings);
|
||||
return JsonSerializer.Deserialize<T>(value, Constants.JsonConvertSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a copy of the JSON serializer options used by Artemis Core
|
||||
/// </summary>
|
||||
/// <returns>A copy of the JSON serializer options used by Artemis Core</returns>
|
||||
public static JsonSerializerOptions GetJsonSerializerOptions()
|
||||
{
|
||||
return new JsonSerializerOptions(Constants.JsonConvertSettings);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -41,12 +41,12 @@ public abstract class Node<TStorage> : Node
|
||||
/// <inheritdoc />
|
||||
public override string SerializeStorage()
|
||||
{
|
||||
return CoreJson.SerializeObject(Storage, true);
|
||||
return CoreJson.Serialize(Storage);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DeserializeStorage(string serialized)
|
||||
{
|
||||
Storage = CoreJson.DeserializeObject<TStorage>(serialized) ?? default(TStorage);
|
||||
Storage = CoreJson.Deserialize<TStorage>(serialized) ?? default(TStorage);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
@@ -10,7 +9,6 @@ public sealed class InputPin<T> : Pin
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
[JsonConstructor]
|
||||
internal InputPin(INode node, string name)
|
||||
: base(node, name)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
@@ -10,7 +9,6 @@ public sealed class OutputPin<T> : Pin
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
[JsonConstructor]
|
||||
internal OutputPin(INode node, string name)
|
||||
: base(node, name)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user