mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
[unity] Now failing more gracefully when loading of binary skeleton data fails. Fixed memory leak when loading incompatible binary skeleton asset. Closes #1799. See #1497.
This commit is contained in:
parent
f42f4bc3b3
commit
b62c531487
@ -122,8 +122,8 @@ namespace Spine {
|
|||||||
skeletonData.hash = hash == 0 ? null : hash.ToString();
|
skeletonData.hash = hash == 0 ? null : hash.ToString();
|
||||||
skeletonData.version = input.ReadString();
|
skeletonData.version = input.ReadString();
|
||||||
if (skeletonData.version.Length == 0) skeletonData.version = null;
|
if (skeletonData.version.Length == 0) skeletonData.version = null;
|
||||||
if ("3.8.75" == skeletonData.version)
|
// early return for old 3.8 format instead of reading past the end
|
||||||
throw new Exception("Unsupported skeleton data, please export with a newer version of Spine.");
|
if (skeletonData.version.Length > 13) return null;
|
||||||
skeletonData.x = input.ReadFloat();
|
skeletonData.x = input.ReadFloat();
|
||||||
skeletonData.y = input.ReadFloat();
|
skeletonData.y = input.ReadFloat();
|
||||||
skeletonData.width = input.ReadFloat();
|
skeletonData.width = input.ReadFloat();
|
||||||
@ -1049,13 +1049,42 @@ namespace Spine {
|
|||||||
/// <summary>Returns the version string of binary skeleton data.</summary>
|
/// <summary>Returns the version string of binary skeleton data.</summary>
|
||||||
public string GetVersionString () {
|
public string GetVersionString () {
|
||||||
try {
|
try {
|
||||||
|
// try reading 4.0+ format
|
||||||
|
var initialPosition = input.Position;
|
||||||
ReadLong(); // long hash
|
ReadLong(); // long hash
|
||||||
|
|
||||||
|
var stringPosition = input.Position;
|
||||||
|
int stringByteCount = ReadInt(true);
|
||||||
|
input.Position = stringPosition;
|
||||||
|
if (stringByteCount <= 13) {
|
||||||
string version = ReadString();
|
string version = ReadString();
|
||||||
|
if (char.IsDigit(version[0]))
|
||||||
return version;
|
return version;
|
||||||
|
}
|
||||||
|
// fallback to old version format
|
||||||
|
input.Position = initialPosition;
|
||||||
|
return GetVersionStringOld3X();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ArgumentException("Stream does not contain a valid binary Skeleton Data.\n" + e, "input");
|
throw new ArgumentException("Stream does not contain a valid binary Skeleton Data.\n" + e, "input");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Returns old 3.8 and earlier format version string of binary skeleton data.</summary>
|
||||||
|
public string GetVersionStringOld3X () {
|
||||||
|
// Hash.
|
||||||
|
int byteCount = ReadInt(true);
|
||||||
|
if (byteCount > 1) input.Position += byteCount - 1;
|
||||||
|
|
||||||
|
// Version.
|
||||||
|
byteCount = ReadInt(true);
|
||||||
|
if (byteCount > 1) {
|
||||||
|
byteCount--;
|
||||||
|
var buffer = new byte[byteCount];
|
||||||
|
ReadFully(buffer, 0, byteCount);
|
||||||
|
return System.Text.Encoding.UTF8.GetString(buffer, 0, byteCount);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -602,12 +602,12 @@ namespace Spine.Unity.Editor {
|
|||||||
warnings.Add("Skeleton data file is not a valid Spine JSON or binary file.");
|
warnings.Add("Skeleton data file is not a valid Spine JSON or binary file.");
|
||||||
} else {
|
} else {
|
||||||
#if SPINE_TK2D
|
#if SPINE_TK2D
|
||||||
bool searchForSpineAtlasAssets = true;
|
bool searchForSpineAtlasAssets = (compatibilityProblemInfo == null);
|
||||||
bool isSpriteCollectionNull = spriteCollection.objectReferenceValue == null;
|
bool isSpriteCollectionNull = spriteCollection.objectReferenceValue == null;
|
||||||
if (!isSpriteCollectionNull) searchForSpineAtlasAssets = false;
|
if (!isSpriteCollectionNull) searchForSpineAtlasAssets = false;
|
||||||
#else
|
#else
|
||||||
// Analysis disable once ConvertToConstant.Local
|
// Analysis disable once ConvertToConstant.Local
|
||||||
bool searchForSpineAtlasAssets = true;
|
bool searchForSpineAtlasAssets = (compatibilityProblemInfo == null);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (searchForSpineAtlasAssets) {
|
if (searchForSpineAtlasAssets) {
|
||||||
|
|||||||
@ -152,15 +152,19 @@ namespace Spine.Unity.Editor {
|
|||||||
forceReloadQueued = true;
|
forceReloadQueued = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUILayout.PropertyField(material);
|
|
||||||
EditorGUILayout.PropertyField(color);
|
|
||||||
|
|
||||||
if (thisSkeletonGraphic.skeletonDataAsset == null) {
|
if (thisSkeletonGraphic.skeletonDataAsset == null) {
|
||||||
EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info);
|
EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info);
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!SpineEditorUtilities.SkeletonDataAssetIsValid(thisSkeletonGraphic.skeletonDataAsset)) {
|
||||||
|
EditorGUILayout.HelpBox("Skeleton Data Asset error. Please check Skeleton Data Asset.", MessageType.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.PropertyField(material);
|
||||||
|
EditorGUILayout.PropertyField(color);
|
||||||
|
|
||||||
string errorMessage = null;
|
string errorMessage = null;
|
||||||
if (SpineEditorUtilities.Preferences.componentMaterialWarning &&
|
if (SpineEditorUtilities.Preferences.componentMaterialWarning &&
|
||||||
|
|||||||
@ -54,6 +54,7 @@ namespace Spine.Unity.Editor {
|
|||||||
[CanEditMultipleObjects]
|
[CanEditMultipleObjects]
|
||||||
public class SkeletonRendererInspector : UnityEditor.Editor {
|
public class SkeletonRendererInspector : UnityEditor.Editor {
|
||||||
public static bool advancedFoldout;
|
public static bool advancedFoldout;
|
||||||
|
protected bool loadingFailed = false;
|
||||||
|
|
||||||
const string SeparatorSlotNamesFieldName = "separatorSlotNames";
|
const string SeparatorSlotNamesFieldName = "separatorSlotNames";
|
||||||
|
|
||||||
@ -107,6 +108,7 @@ namespace Spine.Unity.Editor {
|
|||||||
isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab);
|
isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab);
|
||||||
#endif
|
#endif
|
||||||
SpineEditorUtilities.ConfirmInitialization();
|
SpineEditorUtilities.ConfirmInitialization();
|
||||||
|
loadingFailed = false;
|
||||||
|
|
||||||
// Labels
|
// Labels
|
||||||
SkeletonDataAssetLabel = new GUIContent("SkeletonData Asset", Icons.spine);
|
SkeletonDataAssetLabel = new GUIContent("SkeletonData Asset", Icons.spine);
|
||||||
@ -160,7 +162,14 @@ namespace Spine.Unity.Editor {
|
|||||||
|
|
||||||
public void OnSceneGUI () {
|
public void OnSceneGUI () {
|
||||||
var skeletonRenderer = (SkeletonRenderer)target;
|
var skeletonRenderer = (SkeletonRenderer)target;
|
||||||
|
if (loadingFailed)
|
||||||
|
return;
|
||||||
|
|
||||||
var skeleton = skeletonRenderer.Skeleton;
|
var skeleton = skeletonRenderer.Skeleton;
|
||||||
|
if (skeleton == null) {
|
||||||
|
loadingFailed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
var transform = skeletonRenderer.transform;
|
var transform = skeletonRenderer.transform;
|
||||||
if (skeleton == null) return;
|
if (skeleton == null) return;
|
||||||
|
|
||||||
|
|||||||
@ -91,7 +91,8 @@ namespace Spine.Unity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (System.Exception e) {
|
catch (System.Exception e) {
|
||||||
Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e);
|
Debug.LogError(string.Format("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}",
|
||||||
|
asset.name, e), asset);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,13 +104,13 @@ namespace Spine.Unity {
|
|||||||
else {
|
else {
|
||||||
object obj = Json.Deserialize(new StringReader(asset.text));
|
object obj = Json.Deserialize(new StringReader(asset.text));
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name);
|
Debug.LogError(string.Format("'{0}' is not valid JSON.", asset.name), asset);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var root = obj as Dictionary<string, object>;
|
var root = obj as Dictionary<string, object>;
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
Debug.LogErrorFormat("'{0}' is not compatible JSON. Parser returned an incorrect type while parsing version info.", asset.name);
|
Debug.LogError(string.Format("'{0}' is not compatible JSON. Parser returned an incorrect type while parsing version info.", asset.name), asset);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +134,8 @@ namespace Spine.Unity {
|
|||||||
int.Parse(versionSplit[1], CultureInfo.InvariantCulture) };
|
int.Parse(versionSplit[1], CultureInfo.InvariantCulture) };
|
||||||
}
|
}
|
||||||
catch (System.Exception e) {
|
catch (System.Exception e) {
|
||||||
Debug.LogErrorFormat("Failed to read version info at skeleton '{0}'. It is likely not a valid Spine SkeletonData file.\n{1}", asset.name, e);
|
Debug.LogError(string.Format("Failed to read version info at skeleton '{0}'. It is likely not a valid Spine SkeletonData file.\n{1}",
|
||||||
|
asset.name, e), asset);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return fileVersion;
|
return fileVersion;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user