移动GetVersion至SpineHelper

This commit is contained in:
ww-rm
2025-03-29 17:04:26 +08:00
parent ad39a04fff
commit 5e3bd972e5
5 changed files with 62 additions and 69 deletions

View File

@@ -8,6 +8,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.IO; using System.IO;
using SpineViewer.Spine;
namespace SpineViewer.Controls namespace SpineViewer.Controls
{ {
@@ -33,14 +34,14 @@ namespace SpineViewer.Controls
{ {
if (File.Exists(path)) if (File.Exists(path))
{ {
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower())) if (SpineHelper.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
listBox.Items.Add(Path.GetFullPath(path)); listBox.Items.Add(Path.GetFullPath(path));
} }
else if (Directory.Exists(path)) else if (Directory.Exists(path))
{ {
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)) foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{ {
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower())) if (SpineHelper.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
listBox.Items.Add(file); listBox.Items.Add(file);
} }
} }
@@ -57,7 +58,7 @@ namespace SpineViewer.Controls
{ {
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)) foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{ {
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower())) if (SpineHelper.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
listBox.Items.Add(file); listBox.Items.Add(file);
} }
} }

View File

@@ -199,14 +199,14 @@ namespace SpineViewer.Controls
{ {
if (File.Exists(path)) if (File.Exists(path))
{ {
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower())) if (SpineHelper.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
validPaths.Add(path); validPaths.Add(path);
} }
else if (Directory.Exists(path)) else if (Directory.Exists(path))
{ {
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)) foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{ {
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower())) if (SpineHelper.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
validPaths.Add(file); validPaths.Add(file);
} }
} }

View File

@@ -204,7 +204,7 @@ namespace SpineViewer
{ {
try try
{ {
srcCvter = SkeletonConverter.New(Spine.Spine.GetVersion(skelPath)); srcCvter = SkeletonConverter.New(SpineHelper.GetVersion(skelPath));
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -23,11 +23,6 @@ namespace SpineViewer.Spine
/// </summary> /// </summary>
public abstract class Spine : ImplementationResolver<Spine, SpineImplementationAttribute, SpineVersion>, SFML.Graphics.Drawable, IDisposable public abstract class Spine : ImplementationResolver<Spine, SpineImplementationAttribute, SpineVersion>, SFML.Graphics.Drawable, IDisposable
{ {
/// <summary>
/// 常规骨骼文件后缀集合
/// </summary>
public static readonly ImmutableHashSet<string> CommonSkelSuffix = [".skel", ".json"];
/// <summary> /// <summary>
/// 空动画标记 /// 空动画标记
/// </summary> /// </summary>
@@ -48,66 +43,13 @@ namespace SpineViewer.Spine
/// </summary> /// </summary>
public const float SCALE_MIN = 0.001f; public const float SCALE_MIN = 0.001f;
/// <summary>
/// 尝试检测骨骼文件版本
/// </summary>
/// <param name="skelPath"></param>
/// <returns></returns>
/// <exception cref="InvalidDataException"></exception>
public static SpineVersion GetVersion(string skelPath)
{
string versionString = null;
using var input = File.OpenRead(skelPath);
var reader = new SkeletonConverter.BinaryReader(input);
// try json format
try
{
if (JsonNode.Parse(input) is JsonObject root && root.TryGetPropertyValue("skeleton", out var node) &&
node is JsonObject _skeleton && _skeleton.TryGetPropertyValue("spine", out var _version))
versionString = (string)_version;
}
catch { }
// try v4 binary format
if (versionString is null)
{
try
{
input.Position = 0;
var hash = reader.ReadLong();
var versionPosition = input.Position;
var versionByteCount = reader.ReadVarInt();
input.Position = versionPosition;
if (versionByteCount <= 13)
versionString = reader.ReadString();
}
catch { }
}
// try v3 binary format
if (versionString is null)
{
try
{
input.Position = 0;
var hash = reader.ReadString();
versionString = reader.ReadString();
}
catch { }
}
if (versionString is null)
throw new InvalidDataException($"No verison detected: {skelPath}");
return SpineHelper.GetVersion(versionString);
}
/// <summary> /// <summary>
/// 创建特定版本的 Spine /// 创建特定版本的 Spine
/// </summary> /// </summary>
public static Spine New(SpineVersion version, string skelPath, string? atlasPath = null) public static Spine New(SpineVersion version, string skelPath, string? atlasPath = null)
{ {
if (version == SpineVersion.Auto) version = GetVersion(skelPath); if (version == SpineVersion.Auto) version = SpineHelper.GetVersion(skelPath);
var spine = New(version, [skelPath, atlasPath]); var spine = New(version, [skelPath, atlasPath]);
// 统一初始化 // 统一初始化

View File

@@ -1,10 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SpineViewer.Spine namespace SpineViewer.Spine
@@ -87,14 +89,62 @@ namespace SpineViewer.Spine
} }
/// <summary> /// <summary>
/// 获取字符串对应的版本号 /// 常规骨骼文件后缀集合
/// </summary> /// </summary>
/// <param name="versionString"></param> public static readonly ImmutableHashSet<string> CommonSkelSuffix = [".skel", ".json"];
/// <summary>
/// 尝试检测骨骼文件版本
/// </summary>
/// <param name="skelPath"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="InvalidDataException"></exception> /// <exception cref="InvalidDataException"></exception>
public static SpineVersion GetVersion(string versionString) public static SpineVersion GetVersion(string skelPath)
{ {
ArgumentNullException.ThrowIfNullOrEmpty(versionString); string versionString = null;
using var input = File.OpenRead(skelPath);
var reader = new SkeletonConverter.BinaryReader(input);
// try json format
try
{
if (JsonNode.Parse(input) is JsonObject root && root.TryGetPropertyValue("skeleton", out var node) &&
node is JsonObject _skeleton && _skeleton.TryGetPropertyValue("spine", out var _version))
versionString = (string)_version;
}
catch { }
// try v4 binary format
if (versionString is null)
{
try
{
input.Position = 0;
var hash = reader.ReadLong();
var versionPosition = input.Position;
var versionByteCount = reader.ReadVarInt();
input.Position = versionPosition;
if (versionByteCount <= 13)
versionString = reader.ReadString();
}
catch { }
}
// try v3 binary format
if (versionString is null)
{
try
{
input.Position = 0;
var hash = reader.ReadString();
versionString = reader.ReadString();
}
catch { }
}
if (versionString is null)
throw new InvalidDataException($"No verison detected: {skelPath}");
if (versionString.StartsWith("2.1.")) return SpineVersion.V21; if (versionString.StartsWith("2.1.")) return SpineVersion.V21;
else if (versionString.StartsWith("3.6.")) return SpineVersion.V36; else if (versionString.StartsWith("3.6.")) return SpineVersion.V36;
else if (versionString.StartsWith("3.7.")) return SpineVersion.V37; else if (versionString.StartsWith("3.7.")) return SpineVersion.V37;