diff --git a/AssetStudioUtility/AssetStudioUtility.csproj b/AssetStudioUtility/AssetStudioUtility.csproj
index c56d460..a3bb459 100644
--- a/AssetStudioUtility/AssetStudioUtility.csproj
+++ b/AssetStudioUtility/AssetStudioUtility.csproj
@@ -9,7 +9,6 @@
-
diff --git a/AssetStudioUtility/CubismLive2DExtractor/BlendType.cs b/AssetStudioUtility/CubismLive2DExtractor/BlendType.cs
index f43daeb..5b00627 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/BlendType.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/BlendType.cs
@@ -2,8 +2,8 @@
{
public enum BlendType
{
+ Overwrite,
Add,
Multiply,
- Overwrite,
}
}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismExpression3Json.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismExpression3Json.cs
index 3927131..572aa91 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/CubismExpression3Json.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismExpression3Json.cs
@@ -1,4 +1,6 @@
-namespace CubismLive2DExtractor
+using System.Text.Json.Serialization;
+
+namespace CubismLive2DExtractor
{
public class CubismExpression3Json
{
@@ -11,6 +13,7 @@
{
public string Id { get; set; }
public float Value { get; set; }
+ [JsonConverter(typeof(JsonStringEnumConverter))]
public BlendType Blend { get; set; }
}
}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterBool.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterBool.cs
new file mode 100644
index 0000000..f41c601
--- /dev/null
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterBool.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace CubismLive2DExtractor.CubismJsonConverters
+{
+ public sealed class MyJsonConverterBool : JsonConverter
+ {
+ public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch(reader.TokenType)
+ {
+ case JsonTokenType.True: return true;
+ case JsonTokenType.False: return false;
+ case JsonTokenType.Number: return reader.GetByte() == 1;
+ default: throw new JsonException($"Unable to convert \"{reader.TokenType}\" token to boolean.");
+ }
+ }
+
+ public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
+ {
+ writer.WriteBooleanValue(value);
+ }
+ }
+}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterFloat.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterFloat.cs
new file mode 100644
index 0000000..6cf056d
--- /dev/null
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterFloat.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Globalization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace CubismLive2DExtractor.CubismJsonConverters
+{
+ public class MyJsonConverterFloat : JsonConverter
+ {
+ private readonly bool _asDecimal;
+
+ public MyJsonConverterFloat(bool asDecimal = false)
+ {
+ _asDecimal = asDecimal;
+ }
+
+ public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return JsonSerializer.Deserialize(ref reader, new JsonSerializerOptions
+ {
+ NumberHandling = options.NumberHandling
+ });
+ }
+
+ public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)
+ {
+ if (float.IsNaN(value) || float.IsInfinity(value))
+ {
+ if (options.NumberHandling == JsonNumberHandling.AllowNamedFloatingPointLiterals)
+ {
+ writer.WriteStringValue($"{value.ToString(CultureInfo.InvariantCulture)}");
+ }
+ else
+ {
+ writer.WriteStringValue(JsonSerializer.Serialize(value));
+ }
+ }
+ else
+ {
+ if (_asDecimal && value.Equals((int)value))
+ {
+ writer.WriteNumberValue((decimal)value + 0.0m);
+ }
+ else
+ {
+ writer.WriteNumberValue(MathF.Round(value, 3));
+ }
+ }
+ }
+ }
+}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterFloatList.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterFloatList.cs
new file mode 100644
index 0000000..bd3ee81
--- /dev/null
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismJsonConverters/MyJsonConverterFloatList.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace CubismLive2DExtractor.CubismJsonConverters
+{
+ public class MyJsonConverterFloatList : JsonConverter>
+ {
+ public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return JsonSerializer.Deserialize>(ref reader, new JsonSerializerOptions
+ {
+ NumberHandling = options.NumberHandling
+ });
+ }
+
+ public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options)
+ {
+ writer.WriteStartArray();
+ foreach (var n in value)
+ {
+ if (float.IsNaN(n) || float.IsInfinity(n))
+ {
+ if (options.NumberHandling == JsonNumberHandling.AllowNamedFloatingPointLiterals)
+ {
+ writer.WriteStringValue($"{n.ToString(CultureInfo.InvariantCulture)}");
+ }
+ else
+ {
+ writer.WriteStringValue(JsonSerializer.Serialize(value));
+ }
+ }
+ else
+ {
+ writer.WriteNumberValue(MathF.Round(n, 3));
+ }
+ }
+ writer.WriteEndArray();
+ }
+ }
+}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismModel3Json.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismModel3Json.cs
index 95a1115..3ec0b67 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/CubismModel3Json.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismModel3Json.cs
@@ -1,4 +1,4 @@
-using Newtonsoft.Json.Linq;
+using System.Text.Json.Nodes;
namespace CubismLive2DExtractor
{
@@ -16,8 +16,8 @@ namespace CubismLive2DExtractor
public string Physics;
public string Pose;
public string DisplayInfo;
- public JObject Motions;
- public JArray Expressions;
+ public JsonObject Motions;
+ public JsonArray Expressions;
}
public class SerializableGroup
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismMotion3Json.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismMotion3Json.cs
index 36fe956..c3c9927 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/CubismMotion3Json.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismMotion3Json.cs
@@ -1,10 +1,12 @@
// File Format Specifications
// https://github.com/Live2D/CubismSpecs/blob/master/FileFormats/motion3.json.md
+using AssetStudio;
+using CubismLive2DExtractor.CubismJsonConverters;
using System;
using System.Collections.Generic;
using System.Linq;
-using AssetStudio;
+using System.Text.Json.Serialization;
namespace CubismLive2DExtractor
{
@@ -36,6 +38,7 @@ namespace CubismLive2DExtractor
public string Id;
public float FadeInTime;
public float FadeOutTime;
+ [JsonConverter(typeof(MyJsonConverterFloatList))]
public List Segments;
}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismParsers.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismParsers.cs
index d75b083..cc2dc3a 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/CubismParsers.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismParsers.cs
@@ -1,14 +1,18 @@
-using System;
+using AssetStudio;
+using CubismLive2DExtractor.CubismJsonConverters;
+using CubismLive2DExtractor.CubismUnityClasses;
+using System;
using System.Collections.Specialized;
using System.Linq;
-using AssetStudio;
-using CubismLive2DExtractor.CubismUnityClasses;
-using Newtonsoft.Json;
+using System.Text.Json;
+using System.Text.Json.Serialization;
namespace CubismLive2DExtractor
{
public static class CubismParsers
{
+ public static readonly JsonSerializerOptions CubismJsonOptions;
+
public enum CubismMonoBehaviourType
{
FadeController,
@@ -24,9 +28,21 @@ namespace CubismLive2DExtractor
RenderTexture,
}
+ static CubismParsers()
+ {
+ CubismJsonOptions = new JsonSerializerOptions
+ {
+ Converters = { new MyJsonConverterFloat(asDecimal: true) },
+ NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
+ PropertyNameCaseInsensitive = true,
+ IncludeFields = true,
+ WriteIndented = true,
+ };
+ }
+
public static string ParsePhysics(OrderedDictionary physicsDict, float motionFps)
{
- var cubismPhysicsRig = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(physicsDict)).Rig;
+ var cubismPhysicsRig = JsonSerializer.Deserialize(JsonSerializer.SerializeToUtf8Bytes(physicsDict, CubismJsonOptions), CubismJsonOptions).Rig;
var physicsSettings = new CubismPhysics3Json.SerializablePhysicsSettings[cubismPhysicsRig.SubRigs.Length];
for (var i = 0; i < physicsSettings.Length; i++)
@@ -129,7 +145,10 @@ namespace CubismLive2DExtractor
},
PhysicsSettings = physicsSettings
};
- return JsonConvert.SerializeObject(physicsJson, Formatting.Indented, new MyJsonConverter2());
+ var physicsOptions = new JsonSerializerOptions(CubismJsonOptions);
+ physicsOptions.Converters.Clear();
+ physicsOptions.Converters.Add(new MyJsonConverterFloat());
+ return JsonSerializer.Serialize(physicsJson, physicsOptions);
}
public static OrderedDictionary ParseMonoBehaviour(MonoBehaviour m_MonoBehaviour, CubismMonoBehaviourType cubismMonoBehaviourType, AssemblyLoader assemblyLoader)
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismFadeMotionData.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismFadeMotionData.cs
index f5e6272..d00541f 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismFadeMotionData.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismFadeMotionData.cs
@@ -1,5 +1,5 @@
-using System;
-using AssetStudio;
+using AssetStudio;
+using System;
namespace CubismLive2DExtractor.CubismUnityClasses
{
diff --git a/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismPhysics.cs b/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismPhysics.cs
index 210c705..6f54afd 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismPhysics.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/CubismUnityClasses/CubismPhysics.cs
@@ -1,5 +1,6 @@
using AssetStudio;
-using Newtonsoft.Json;
+using CubismLive2DExtractor.CubismJsonConverters;
+using System.Text.Json.Serialization;
namespace CubismLive2DExtractor.CubismUnityClasses
{
@@ -33,6 +34,7 @@ namespace CubismLive2DExtractor.CubismUnityClasses
public float AngleScale { get; set; }
public float Weight { get; set; }
public CubismPhysicsSourceComponent SourceComponent { get; set; }
+ [JsonConverter(typeof(MyJsonConverterBool))]
public bool IsInverted { get; set; }
}
@@ -50,6 +52,7 @@ namespace CubismLive2DExtractor.CubismUnityClasses
public float AngleScale { get; set; }
public float Weight { get; set; }
public CubismPhysicsSourceComponent SourceComponent { get; set; }
+ [JsonConverter(typeof(MyJsonConverterBool))]
public bool IsInverted { get; set; }
}
@@ -71,7 +74,7 @@ namespace CubismLive2DExtractor.CubismUnityClasses
public sealed class CubismPhysics : MonoBehaviour
{
- [JsonProperty("_rig")]
+ [JsonPropertyName("_rig")]
public CubismPhysicsRig Rig { get; set; }
}
}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs b/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs
index 732c961..28db231 100644
--- a/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs
+++ b/AssetStudioUtility/CubismLive2DExtractor/Live2DExtractor.cs
@@ -6,8 +6,6 @@
using AssetStudio;
using AssetStudio.Addons.CubismLive2D;
using CubismLive2DExtractor.CubismUnityClasses;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -15,6 +13,8 @@ using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
+using System.Text.Json;
+using System.Text.Json.Nodes;
using System.Threading.Tasks;
using static CubismLive2DExtractor.CubismParsers;
using Object = AssetStudio.Object;
@@ -315,7 +315,7 @@ namespace CubismLive2DExtractor
#endregion
#region motion3.json
- var motions = new SortedDictionary();
+ var motions = new SortedDictionary();
var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar;
var motionFps = 0f;
@@ -327,7 +327,7 @@ namespace CubismLive2DExtractor
var fadeMotionLstDict = ParseMonoBehaviour(FadeMotionLst, CubismMonoBehaviourType.FadeMotionList, Assembly);
if (fadeMotionLstDict != null)
{
- var cubismFadeList = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(fadeMotionLstDict));
+ var cubismFadeList = JsonSerializer.Deserialize(JsonSerializer.SerializeToUtf8Bytes(fadeMotionLstDict, CubismJsonOptions), CubismJsonOptions);
var fadeMotionAssetSet = new HashSet();
foreach (var motionPPtr in cubismFadeList.CubismFadeMotionObjects)
{
@@ -389,7 +389,7 @@ namespace CubismLive2DExtractor
#endregion
#region exp3.json
- var expressions = new JArray();
+ var expressions = new JsonArray();
var destExpressionPath = Path.Combine(destPath, "expressions") + Path.DirectorySeparatorChar;
if (ExpressionLst != null) //Expressions from Expression List
@@ -398,7 +398,7 @@ namespace CubismLive2DExtractor
var expLstDict = ParseMonoBehaviour(ExpressionLst, CubismMonoBehaviourType.ExpressionList, Assembly);
if (expLstDict != null)
{
- var cubismExpList = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(expLstDict));
+ var cubismExpList = JsonSerializer.Deserialize(JsonSerializer.SerializeToUtf8Bytes(expLstDict, CubismJsonOptions), CubismJsonOptions);
var expAssetSet = new HashSet();
foreach (var expPPtr in cubismExpList.CubismExpressionObjects)
{
@@ -427,14 +427,14 @@ namespace CubismLive2DExtractor
if (expressionDict == null)
continue;
- var expression = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(expressionDict));
+ var expression = JsonSerializer.Deserialize(JsonSerializer.SerializeToUtf8Bytes(expressionDict, CubismJsonOptions), CubismJsonOptions);
- expressions.Add(new JObject
+ expressions.Add(new JsonObject
{
- { "Name", expressionName },
- { "File", $"expressions/{expressionName}.exp3.json" }
+ ["Name"] = expressionName,
+ ["File"] = $"expressions/{expressionName}.exp3.json",
});
- File.WriteAllText($"{destExpressionPath}{expressionName}.exp3.json", JsonConvert.SerializeObject(expression, Formatting.Indented));
+ File.WriteAllBytes($"{destExpressionPath}{expressionName}.exp3.json", JsonSerializer.SerializeToUtf8Bytes(expression, CubismJsonOptions));
}
#endregion
@@ -519,16 +519,16 @@ namespace CubismLive2DExtractor
Physics = isPhysicsExported ? $"{modelName}.physics3.json" : null,
Pose = isPoseExported ? $"{modelName}.pose3.json" : null,
DisplayInfo = isCdiExported ? $"{modelName}.cdi3.json" : null,
- Motions = JObject.FromObject(motions),
+ Motions = new JsonObject(motions),
Expressions = expressions,
},
Groups = groups.ToArray()
};
- File.WriteAllText($"{destPath}{modelName}.model3.json", JsonConvert.SerializeObject(model3, Formatting.Indented));
+ File.WriteAllBytes($"{destPath}{modelName}.model3.json", JsonSerializer.SerializeToUtf8Bytes(model3, CubismJsonOptions));
#endregion
}
- private void ExportFadeMotions(string destMotionPath, SortedDictionary motions, ref float fps)
+ private void ExportFadeMotions(string destMotionPath, SortedDictionary motions, ref float fps)
{
Directory.CreateDirectory(destMotionPath);
foreach (var fadeMotionMono in FadeMotions)
@@ -536,8 +536,8 @@ namespace CubismLive2DExtractor
var fadeMotionDict = ParseMonoBehaviour(fadeMotionMono, CubismMonoBehaviourType.FadeMotion, Assembly);
if (fadeMotionDict == null)
continue;
-
- var fadeMotion = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(fadeMotionDict));
+
+ var fadeMotion = JsonSerializer.Deserialize(JsonSerializer.SerializeToUtf8Bytes(fadeMotionDict, CubismJsonOptions), CubismJsonOptions);
if (fadeMotion.ParameterIds.Length == 0)
continue;
@@ -551,13 +551,13 @@ namespace CubismLive2DExtractor
if (motions.ContainsKey(animName))
continue;
}
- var motionPath = new JObject(new JProperty("File", $"motions/{animName}.motion3.json"));
- motions.Add(animName, new JArray(motionPath));
- File.WriteAllText($"{destMotionPath}{animName}.motion3.json", JsonConvert.SerializeObject(motionJson, Formatting.Indented, new MyJsonConverter()));
+ var motionPath = new JsonObject { ["File"] = $"motions/{animName}.motion3.json" };
+ motions.Add(animName, new JsonArray(motionPath));
+ File.WriteAllBytes($"{destMotionPath}{animName}.motion3.json", JsonSerializer.SerializeToUtf8Bytes(motionJson, CubismJsonOptions));
}
}
- private void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, SortedDictionary motions, ref float fps)
+ private void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, SortedDictionary motions, ref float fps)
{
if (converter == null)
return;
@@ -584,9 +584,9 @@ namespace CubismLive2DExtractor
if (motions.ContainsKey(animName))
continue;
}
- var motionPath = new JObject(new JProperty("File", $"motions/{animName}.motion3.json"));
- motions.Add(animName, new JArray(motionPath));
- File.WriteAllText($"{destMotionPath}{animName}.motion3.json", JsonConvert.SerializeObject(motionJson, Formatting.Indented, new MyJsonConverter()));
+ var motionPath = new JsonObject { ["File"] = $"motions/{animName}.motion3.json" };
+ motions.Add(animName, new JsonArray(motionPath));
+ File.WriteAllBytes($"{destMotionPath}{animName}.motion3.json", JsonSerializer.SerializeToUtf8Bytes(motionJson, CubismJsonOptions));
}
}
@@ -631,7 +631,7 @@ namespace CubismLive2DExtractor
{
poseJson.Groups[i++] = nodeList.ToArray();
}
- File.WriteAllText($"{destPath}{modelName}.pose3.json", JsonConvert.SerializeObject(poseJson, Formatting.Indented));
+ File.WriteAllBytes($"{destPath}{modelName}.pose3.json", JsonSerializer.SerializeToUtf8Bytes(poseJson, CubismJsonOptions));
return true;
}
@@ -681,7 +681,7 @@ namespace CubismLive2DExtractor
if (parts.Count == 0 && parameters.Count == 0)
return false;
- File.WriteAllText($"{destPath}{modelName}.cdi3.json", JsonConvert.SerializeObject(cdiJson, Formatting.Indented));
+ File.WriteAllBytes($"{destPath}{modelName}.cdi3.json", JsonSerializer.SerializeToUtf8Bytes(cdiJson, CubismJsonOptions));
return true;
}
diff --git a/AssetStudioUtility/CubismLive2DExtractor/MyJsonConverter.cs b/AssetStudioUtility/CubismLive2DExtractor/MyJsonConverter.cs
deleted file mode 100644
index c8056e9..0000000
--- a/AssetStudioUtility/CubismLive2DExtractor/MyJsonConverter.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-
-namespace CubismLive2DExtractor
-{
- public class MyJsonConverter : JsonConverter
- {
- public override bool CanConvert(Type objectType)
- {
- return objectType == typeof(List);
- }
-
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- throw new NotImplementedException();
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- writer.WriteStartArray();
- Convert(writer, (List)value);
- writer.WriteEndArray();
- }
-
- private void Convert(JsonWriter writer, List array)
- {
- foreach (var n in array)
- {
- var v = n.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture);
- writer.WriteRawValue(v);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/AssetStudioUtility/CubismLive2DExtractor/MyJsonConverter2.cs b/AssetStudioUtility/CubismLive2DExtractor/MyJsonConverter2.cs
deleted file mode 100644
index 89e4256..0000000
--- a/AssetStudioUtility/CubismLive2DExtractor/MyJsonConverter2.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using Newtonsoft.Json;
-
-namespace CubismLive2DExtractor
-{
- public class MyJsonConverter2 : JsonConverter
- {
- public override bool CanConvert(Type objectType)
- {
- return objectType == typeof(float);
- }
-
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- throw new NotImplementedException();
- }
-
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- Convert(writer, (float)value);
- }
-
- private void Convert(JsonWriter writer, float value)
- {
- writer.WriteRawValue(value.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture));
- }
- }
-}