diff --git a/AssetStudio/AssetStudio-x86.csproj b/AssetStudio/AssetStudio-x86.csproj index 356cc54..fa8e70a 100644 --- a/AssetStudio/AssetStudio-x86.csproj +++ b/AssetStudio/AssetStudio-x86.csproj @@ -58,24 +58,28 @@ False - library\BrotliSharpLib.dll + Library\BrotliSharpLib.dll False False - library\OpenTK.dll + Library\OpenTK.dll False False - library\OpenTK.GLControl.dll + Library\OpenTK.GLControl.dll + False + + + Library\SharpDX.Mathematics.dll False False - library\System.Half.dll + Library\System.Half.dll False @@ -142,6 +146,12 @@ AssetStudioForm.cs + + + + + + @@ -151,6 +161,8 @@ + + diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index 052d503..6f1e6c6 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -58,24 +58,28 @@ False - library\BrotliSharpLib.dll + Library\BrotliSharpLib.dll False False - library\OpenTK.dll + Library\OpenTK.dll False False - library\OpenTK.GLControl.dll + Library\OpenTK.GLControl.dll + False + + + Library\SharpDX.Mathematics.dll False False - library\System.Half.dll + Library\System.Half.dll False @@ -136,7 +140,15 @@ Code + + + + + + + + diff --git a/AssetStudio/Classes/Animation.cs b/AssetStudio/Classes/Animation.cs new file mode 100644 index 0000000..5cf4160 --- /dev/null +++ b/AssetStudio/Classes/Animation.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + class Animation + { + public PPtr m_GameObject; + public List m_Animations; + + public Animation(AssetPreloadData preloadData) + { + var sourceFile = preloadData.sourceFile; + var reader = preloadData.InitReader(); + reader.Position = preloadData.Offset; + + m_GameObject = sourceFile.ReadPPtr(); + var m_Enabled = reader.ReadByte(); + reader.AlignStream(4); + var m_Animation = sourceFile.ReadPPtr(); + int numAnimations = reader.ReadInt32(); + m_Animations = new List(numAnimations); + for (int i = 0; i < numAnimations; i++) + { + m_Animations.Add(sourceFile.ReadPPtr()); + } + } + } +} diff --git a/AssetStudio/Classes/AnimationClip.cs b/AssetStudio/Classes/AnimationClip.cs new file mode 100644 index 0000000..2aacd8a --- /dev/null +++ b/AssetStudio/Classes/AnimationClip.cs @@ -0,0 +1,763 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Text; +using SharpDX; + +namespace AssetStudio +{ + public class Keyframe + { + public float time { get; set; } + public T value { get; set; } + public T inSlope { get; set; } + public T outSlope { get; set; } + + public Keyframe(EndianBinaryReader reader, Func readerFunc) + { + time = reader.ReadSingle(); + value = readerFunc(); + inSlope = readerFunc(); + outSlope = readerFunc(); + } + } + + public class AnimationCurve + { + public List> m_Curve { get; set; } + public int m_PreInfinity { get; set; } + public int m_PostInfinity { get; set; } + public int m_RotationOrder { get; set; } + + public AnimationCurve(EndianBinaryReader reader, Func readerFunc, int[] version) + { + int numCurves = reader.ReadInt32(); + m_Curve = new List>(numCurves); + for (int i = 0; i < numCurves; i++) + { + m_Curve.Add(new Keyframe(reader, readerFunc)); + } + + m_PreInfinity = reader.ReadInt32(); + m_PostInfinity = reader.ReadInt32(); + if (version[0] >= 5)//5.0 and up + { + m_RotationOrder = reader.ReadInt32(); + } + } + } + + public class QuaternionCurve + { + public AnimationCurve curve { get; set; } + public string path { get; set; } + + public QuaternionCurve(EndianBinaryReader reader, int[] version) + { + curve = new AnimationCurve(reader, reader.ReadQuaternion, version); + path = reader.ReadAlignedString(); + } + } + + public class PackedBitVector + { + public uint m_NumItems { get; set; } + public float m_Range { get; set; } + public float m_Start { get; set; } + public byte[] m_Data { get; set; } + public byte m_BitSize { get; set; } + + public PackedBitVector(EndianBinaryReader reader) + { + m_NumItems = reader.ReadUInt32(); + m_Range = reader.ReadSingle(); + m_Start = reader.ReadSingle(); + + int numData = reader.ReadInt32(); + m_Data = reader.ReadBytes(numData); + reader.AlignStream(4); + + m_BitSize = reader.ReadByte(); + reader.AlignStream(4); + } + } + + public class PackedBitVector2 + { + public uint m_NumItems { get; set; } + public byte[] m_Data { get; set; } + public byte m_BitSize { get; set; } + + public PackedBitVector2(EndianBinaryReader reader) + { + m_NumItems = reader.ReadUInt32(); + + int numData = reader.ReadInt32(); + m_Data = reader.ReadBytes(numData); + reader.AlignStream(4); + + m_BitSize = reader.ReadByte(); + reader.AlignStream(4); + } + } + + public class PackedBitVector3 + { + public uint m_NumItems { get; set; } + public byte[] m_Data { get; set; } + + public PackedBitVector3(EndianBinaryReader reader) + { + m_NumItems = reader.ReadUInt32(); + + int numData = reader.ReadInt32(); + m_Data = reader.ReadBytes(numData); + + reader.AlignStream(4); + } + } + + public class CompressedAnimationCurve + { + public string m_Path { get; set; } + public PackedBitVector2 m_Times { get; set; } + public PackedBitVector3 m_Values { get; set; } + public PackedBitVector m_Slopes { get; set; } + public int m_PreInfinity { get; set; } + public int m_PostInfinity { get; set; } + + public CompressedAnimationCurve(EndianBinaryReader reader) + { + m_Path = reader.ReadAlignedString(); + m_Times = new PackedBitVector2(reader); + m_Values = new PackedBitVector3(reader); + m_Slopes = new PackedBitVector(reader); + m_PreInfinity = reader.ReadInt32(); + m_PostInfinity = reader.ReadInt32(); + } + } + + public class Vector3Curve + { + public AnimationCurve curve { get; set; } + public string path { get; set; } + + public Vector3Curve(EndianBinaryReader reader, int[] version) + { + curve = new AnimationCurve(reader, reader.ReadVector3, version); + path = reader.ReadAlignedString(); + } + } + + public class FloatCurve + { + public AnimationCurve curve { get; set; } + public string attribute { get; set; } + public string path { get; set; } + public int classID { get; set; } + public PPtr script { get; set; } + + + public FloatCurve(AssetPreloadData preloadData) + { + var reader = preloadData.sourceFile.assetsFileReader; + curve = new AnimationCurve(reader, reader.ReadSingle, preloadData.sourceFile.version); + attribute = reader.ReadAlignedString(); + path = reader.ReadAlignedString(); + classID = reader.ReadInt32(); + script = preloadData.sourceFile.ReadPPtr(); + } + } + + public class PPtrKeyframe + { + public float time { get; set; } + public PPtr value { get; set; } + + + public PPtrKeyframe(AssetPreloadData preloadData) + { + var reader = preloadData.sourceFile.assetsFileReader; + time = reader.ReadSingle(); + value = preloadData.sourceFile.ReadPPtr(); + } + } + + public class PPtrCurve + { + public List curve { get; set; } + public string attribute { get; set; } + public string path { get; set; } + public int classID { get; set; } + public PPtr script { get; set; } + + + public PPtrCurve(AssetPreloadData preloadData) + { + var reader = preloadData.sourceFile.assetsFileReader; + + int numCurves = reader.ReadInt32(); + curve = new List(numCurves); + for (int i = 0; i < numCurves; i++) + { + curve.Add(new PPtrKeyframe(preloadData)); + } + + attribute = reader.ReadAlignedString(); + path = reader.ReadAlignedString(); + classID = reader.ReadInt32(); + script = preloadData.sourceFile.ReadPPtr(); + } + } + + public class AABB + { + public Vector3 m_Center { get; set; } + public Vector3 m_Extend { get; set; } + + public AABB(EndianBinaryReader reader) + { + m_Center = reader.ReadVector3(); + m_Extend = reader.ReadVector3(); + } + } + + public class xform + { + public object t { get; set; } + public Quaternion q { get; set; } + public object s { get; set; } + + public xform(EndianBinaryReader reader, int[] version) + { + t = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up + q = reader.ReadQuaternion(); + s = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up + } + } + + public class HandPose + { + public xform m_GrabX { get; set; } + public float[] m_DoFArray { get; set; } + public float m_Override { get; set; } + public float m_CloseOpen { get; set; } + public float m_InOut { get; set; } + public float m_Grab { get; set; } + + public HandPose(EndianBinaryReader reader, int[] version) + { + m_GrabX = new xform(reader, version); + + int numDoFs = reader.ReadInt32(); + m_DoFArray = reader.ReadSingleArray(numDoFs); + + m_Override = reader.ReadSingle(); + m_CloseOpen = reader.ReadSingle(); + m_InOut = reader.ReadSingle(); + m_Grab = reader.ReadSingle(); + } + } + + public class HumanGoal + { + public xform m_X { get; set; } + public float m_WeightT { get; set; } + public float m_WeightR { get; set; } + public object m_HintT { get; set; } + public float m_HintWeightT { get; set; } + + public HumanGoal(EndianBinaryReader reader, int[] version) + { + m_X = new xform(reader, version); + m_WeightT = reader.ReadSingle(); + m_WeightR = reader.ReadSingle(); + if (version[0] >= 5)//5.0 and up + { + m_HintT = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up + m_HintWeightT = reader.ReadSingle(); + } + } + } + + public class HumanPose + { + public xform m_RootX { get; set; } + public object m_LookAtPosition { get; set; } + public Vector4 m_LookAtWeight { get; set; } + public List m_GoalArray { get; set; } + public HandPose m_LeftHandPose { get; set; } + public HandPose m_RightHandPose { get; set; } + public float[] m_DoFArray { get; set; } + public object[] m_TDoFArray { get; set; } + + public HumanPose(EndianBinaryReader reader, int[] version) + { + m_RootX = new xform(reader, version); + m_LookAtPosition = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up + m_LookAtWeight = reader.ReadVector4(); + + int numGoals = reader.ReadInt32(); + m_GoalArray = new List(numGoals); + for (int i = 0; i < numGoals; i++) + { + m_GoalArray.Add(new HumanGoal(reader, version)); + } + + m_LeftHandPose = new HandPose(reader, version); + m_RightHandPose = new HandPose(reader, version); + + int numDoFs = reader.ReadInt32(); + m_DoFArray = reader.ReadSingleArray(numDoFs); + + if (version[0] >= 5)//5.0 and up + { + int numTDof = reader.ReadInt32(); + m_TDoFArray = new object[numTDof]; + for (int i = 0; i < numTDof; i++) + { + m_TDoFArray[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up + } + } + } + } + + public class StreamedClip + { + public uint[] data { get; set; } + public uint curveCount { get; set; } + + public StreamedClip(EndianBinaryReader reader) + { + int numData = reader.ReadInt32(); + data = reader.ReadUInt32Array(numData); + curveCount = reader.ReadUInt32(); + } + + public class StreamedCurveKey + { + public int index { get; set; } + public Vector3 tcb { get; set; } + public float value { get; set; } + public StreamedCurveKey(BinaryReader reader) + { + index = reader.ReadInt32(); + tcb = reader.ReadVector3(); + value = reader.ReadSingle(); + } + } + + public class StreamedFrame + { + public float time { get; set; } + public List keyList { get; set; } + + public StreamedFrame(BinaryReader reader) + { + time = reader.ReadSingle(); + + int numKeys = reader.ReadInt32(); + keyList = new List(numKeys); + for (int i = 0; i < numKeys; i++) + { + keyList.Add(new StreamedCurveKey(reader)); + } + } + } + + public List ReadData() + { + List frameList = new List(); + using (Stream stream = new MemoryStream()) + { + BinaryWriter writer = new BinaryWriter(stream); + writer.Write(data); + stream.Position = 0; + while (stream.Position < stream.Length) + { + frameList.Add(new StreamedFrame(new BinaryReader(stream))); + } + } + return frameList; + } + } + + public class DenseClip + { + public int m_FrameCount { get; set; } + public uint m_CurveCount { get; set; } + public float m_SampleRate { get; set; } + public float m_BeginTime { get; set; } + public float[] m_SampleArray { get; set; } + + public DenseClip(EndianBinaryReader reader) + { + m_FrameCount = reader.ReadInt32(); + m_CurveCount = reader.ReadUInt32(); + m_SampleRate = reader.ReadSingle(); + m_BeginTime = reader.ReadSingle(); + + int numSamples = reader.ReadInt32(); + m_SampleArray = reader.ReadSingleArray(numSamples); + } + } + + public class ConstantClip + { + public float[] data { get; set; } + + public ConstantClip(EndianBinaryReader reader) + { + int numData = reader.ReadInt32(); + data = reader.ReadSingleArray(numData); + } + } + + public class ValueConstant + { + public uint m_ID { get; set; } + public uint m_TypeID { get; set; } + public uint m_Type { get; set; } + public uint m_Index { get; set; } + + public ValueConstant(EndianBinaryReader reader, int[] version) + { + m_ID = reader.ReadUInt32(); + if (version[0] < 5 || (version[0] == 5 && version[1] < 5))//5.5 down + { + m_TypeID = reader.ReadUInt32(); + } + m_Type = reader.ReadUInt32(); + m_Index = reader.ReadUInt32(); + } + } + + public class ValueArrayConstant + { + public List m_ValueArray { get; set; } + + public ValueArrayConstant(EndianBinaryReader reader, int[] version) + { + int numVals = reader.ReadInt32(); + m_ValueArray = new List(numVals); + for (int i = 0; i < numVals; i++) + { + m_ValueArray.Add(new ValueConstant(reader, version)); + } + } + } + + public class Clip + { + public StreamedClip m_StreamedClip { get; set; } + public DenseClip m_DenseClip { get; set; } + public ConstantClip m_ConstantClip { get; set; } + public ValueArrayConstant m_Binding { get; set; } + + public Clip(EndianBinaryReader reader, int[] version) + { + m_StreamedClip = new StreamedClip(reader); + m_DenseClip = new DenseClip(reader); + m_ConstantClip = new ConstantClip(reader); + m_Binding = new ValueArrayConstant(reader, version); + } + } + + public class ValueDelta + { + public float m_Start { get; set; } + public float m_Stop { get; set; } + + public ValueDelta(EndianBinaryReader reader) + { + m_Start = reader.ReadSingle(); + m_Stop = reader.ReadSingle(); + } + } + + public class ClipMuscleConstant + { + public HumanPose m_DeltaPose { get; set; } + public xform m_StartX { get; set; } + public xform m_StopX { get; set; } + public xform m_LeftFootStartX { get; set; } + public xform m_RightFootStartX { get; set; } + public xform m_MotionStartX { get; set; } + public xform m_MotionStopX { get; set; } + public object m_AverageSpeed { get; set; } + public Clip m_Clip { get; set; } + public float m_StartTime { get; set; } + public float m_StopTime { get; set; } + public float m_OrientationOffsetY { get; set; } + public float m_Level { get; set; } + public float m_CycleOffset { get; set; } + public float m_AverageAngularSpeed { get; set; } + public int[] m_IndexArray { get; set; } + public List m_ValueArrayDelta { get; set; } + public float[] m_ValueArrayReferencePose { get; set; } + public bool m_Mirror { get; set; } + public bool m_LoopTime { get; set; } + public bool m_LoopBlend { get; set; } + public bool m_LoopBlendOrientation { get; set; } + public bool m_LoopBlendPositionY { get; set; } + public bool m_LoopBlendPositionXZ { get; set; } + public bool m_StartAtOrigin { get; set; } + public bool m_KeepOriginalOrientation { get; set; } + public bool m_KeepOriginalPositionY { get; set; } + public bool m_KeepOriginalPositionXZ { get; set; } + public bool m_HeightFromFeet { get; set; } + + public ClipMuscleConstant(EndianBinaryReader reader, int[] version) + { + m_DeltaPose = new HumanPose(reader, version); + m_StartX = new xform(reader, version); + if (version[0] > 5 || (version[0] == 5 && version[1] >= 5))//5.5 and up + { + m_StopX = new xform(reader, version); + } + m_LeftFootStartX = new xform(reader, version); + m_RightFootStartX = new xform(reader, version); + if (version[0] < 5)//5.0 down + { + m_MotionStartX = new xform(reader, version); + m_MotionStopX = new xform(reader, version); + } + m_AverageSpeed = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up + m_Clip = new Clip(reader, version); + m_StartTime = reader.ReadSingle(); + m_StopTime = reader.ReadSingle(); + m_OrientationOffsetY = reader.ReadSingle(); + m_Level = reader.ReadSingle(); + m_CycleOffset = reader.ReadSingle(); + m_AverageAngularSpeed = reader.ReadSingle(); + + int numIndices = reader.ReadInt32(); + m_IndexArray = reader.ReadInt32Array(numIndices); + + int numDeltas = reader.ReadInt32(); + m_ValueArrayDelta = new List(numDeltas); + for (int i = 0; i < numDeltas; i++) + { + m_ValueArrayDelta.Add(new ValueDelta(reader)); + } + if (version[0] >= 5)//5.0 and up + { + m_ValueArrayReferencePose = reader.ReadSingleArray(reader.ReadInt32()); + } + + m_Mirror = reader.ReadBoolean(); + m_LoopTime = reader.ReadBoolean(); + m_LoopBlend = reader.ReadBoolean(); + m_LoopBlendOrientation = reader.ReadBoolean(); + m_LoopBlendPositionY = reader.ReadBoolean(); + m_LoopBlendPositionXZ = reader.ReadBoolean(); + if (version[0] > 5 || (version[0] == 5 && version[1] >= 5))//5.5 and up + { + m_StartAtOrigin = reader.ReadBoolean(); + } + m_KeepOriginalOrientation = reader.ReadBoolean(); + m_KeepOriginalPositionY = reader.ReadBoolean(); + m_KeepOriginalPositionXZ = reader.ReadBoolean(); + m_HeightFromFeet = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class GenericBinding + { + public uint path { get; set; } + public uint attribute { get; set; } + public PPtr script { get; set; } + public int typeID { get; set; } + public byte customType { get; set; } + public byte isPPtrCurve { get; set; } + + public GenericBinding(AssetPreloadData preloadData) + { + var reader = preloadData.sourceFile.assetsFileReader; + var version = preloadData.sourceFile.version; + path = reader.ReadUInt32(); + attribute = reader.ReadUInt32(); + script = preloadData.sourceFile.ReadPPtr(); + if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up + { + typeID = reader.ReadInt32(); + } + else + { + typeID = reader.ReadUInt16(); + } + customType = reader.ReadByte(); + isPPtrCurve = reader.ReadByte(); + reader.AlignStream(4); + } + } + + public class AnimationClipBindingConstant + { + public List genericBindings { get; set; } + public List pptrCurveMapping { get; set; } + + public AnimationClipBindingConstant(AssetPreloadData preloadData) + { + var reader = preloadData.sourceFile.assetsFileReader; + int numBindings = reader.ReadInt32(); + genericBindings = new List(numBindings); + for (int i = 0; i < numBindings; i++) + { + genericBindings.Add(new GenericBinding(preloadData)); + } + + int numMappings = reader.ReadInt32(); + pptrCurveMapping = new List(numMappings); + for (int i = 0; i < numMappings; i++) + { + pptrCurveMapping.Add(preloadData.sourceFile.ReadPPtr()); + } + } + + public GenericBinding FindBinding(int index) + { + int curves = 0; + for (int i = 0; i < genericBindings.Count; i++) + { + GenericBinding b = genericBindings[i]; + curves += b.attribute == 2 ? 4 : b.attribute <= 4 ? 3 : 1; + if (curves > index) + { + return b; + } + } + + return null; + } + + public GenericBinding FindBinding(uint path, uint attribute) + { + return genericBindings.Find + ( + delegate (GenericBinding b) + { + return b.path == path && b.attribute == attribute; + } + ); + } + } + + public class AnimationClip + { + public string m_Name { get; set; } + public int m_AnimationType { get; set; } + public bool m_Legacy { get; set; } + public bool m_Compressed { get; set; } + public bool m_UseHighQualityCurve { get; set; } + public List m_RotationCurves { get; set; } + public List m_CompressedRotationCurves { get; set; } + public List m_EulerCurves { get; set; } + public List m_PositionCurves { get; set; } + public List m_ScaleCurves { get; set; } + public List m_FloatCurves { get; set; } + public List m_PPtrCurves { get; set; } + public float m_SampleRate { get; set; } + public int m_WrapMode { get; set; } + public AABB m_Bounds { get; set; } + public uint m_MuscleClipSize { get; set; } + public ClipMuscleConstant m_MuscleClip { get; set; } + public AnimationClipBindingConstant m_ClipBindingConstant { get; set; } + //public List m_Events { get; set; } + + + public AnimationClip(AssetPreloadData preloadData) + { + var sourceFile = preloadData.sourceFile; + var version = sourceFile.version; + var reader = preloadData.InitReader(); + reader.Position = preloadData.Offset; + + m_Name = reader.ReadAlignedString(); + if (version[0] >= 5)//5.0 and up + { + m_Legacy = reader.ReadBoolean(); + } + else + { + m_AnimationType = reader.ReadInt32(); + } + m_Compressed = reader.ReadBoolean(); + m_UseHighQualityCurve = reader.ReadBoolean(); + reader.AlignStream(4); + if (m_Compressed) + { + //TODO + } + + int numRCurves = reader.ReadInt32(); + m_RotationCurves = new List(numRCurves); + for (int i = 0; i < numRCurves; i++) + { + m_RotationCurves.Add(new QuaternionCurve(reader, version)); + } + + int numCRCurves = reader.ReadInt32(); + m_CompressedRotationCurves = new List(numCRCurves); + for (int i = 0; i < numCRCurves; i++) + { + m_CompressedRotationCurves.Add(new CompressedAnimationCurve(reader)); + } + + if (version[0] >= 5)//5.0 and up + { + int numEulerCurves = reader.ReadInt32(); + m_EulerCurves = new List(numEulerCurves); + for (int i = 0; i < numEulerCurves; i++) + { + m_EulerCurves.Add(new Vector3Curve(reader, version)); + } + } + + int numPCurves = reader.ReadInt32(); + m_PositionCurves = new List(numPCurves); + for (int i = 0; i < numPCurves; i++) + { + m_PositionCurves.Add(new Vector3Curve(reader, version)); + } + + int numSCurves = reader.ReadInt32(); + m_ScaleCurves = new List(numSCurves); + for (int i = 0; i < numSCurves; i++) + { + m_ScaleCurves.Add(new Vector3Curve(reader, version)); + } + + int numFCurves = reader.ReadInt32(); + m_FloatCurves = new List(numFCurves); + for (int i = 0; i < numFCurves; i++) + { + m_FloatCurves.Add(new FloatCurve(preloadData)); + } + + int numPtrCurves = reader.ReadInt32(); + m_PPtrCurves = new List(numPtrCurves); + for (int i = 0; i < numPtrCurves; i++) + { + m_PPtrCurves.Add(new PPtrCurve(preloadData)); + } + + m_SampleRate = reader.ReadSingle(); + m_WrapMode = reader.ReadInt32(); + m_Bounds = new AABB(reader); + m_MuscleClipSize = reader.ReadUInt32(); + m_MuscleClip = new ClipMuscleConstant(reader, version); + m_ClipBindingConstant = new AnimationClipBindingConstant(preloadData); + + /*int numEvents = reader.ReadInt32(); + m_Events = new List(numEvents); + for (int i = 0; i < numEvents; i++) + { + m_Events.Add(new AnimationEvent(stream, file.Version[0] - '0')); + }*/ + } + } +} diff --git a/AssetStudio/Classes/Animator.cs b/AssetStudio/Classes/Animator.cs new file mode 100644 index 0000000..ac7e962 --- /dev/null +++ b/AssetStudio/Classes/Animator.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + class Animator + { + public PPtr m_GameObject; + public PPtr m_Avatar; + public PPtr m_Controller; + + public Animator(AssetPreloadData preloadData) + { + var sourceFile = preloadData.sourceFile; + var reader = preloadData.InitReader(); + reader.Position = preloadData.Offset; + + m_GameObject = sourceFile.ReadPPtr(); + var m_Enabled = reader.ReadByte(); + reader.AlignStream(4); + m_Avatar = sourceFile.ReadPPtr(); + m_Controller = sourceFile.ReadPPtr(); + } + } +} diff --git a/AssetStudio/Classes/AnimatorController.cs b/AssetStudio/Classes/AnimatorController.cs new file mode 100644 index 0000000..bd21e51 --- /dev/null +++ b/AssetStudio/Classes/AnimatorController.cs @@ -0,0 +1,560 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SharpDX; + +namespace AssetStudio +{ + public class HumanPoseMask + { + public uint word0 { get; set; } + public uint word1 { get; set; } + public uint word2 { get; set; } + + public HumanPoseMask(EndianBinaryReader reader, int[] version) + { + word0 = reader.ReadUInt32(); + word1 = reader.ReadUInt32(); + if (version[0] >= 5) //5.0 and up + { + word2 = reader.ReadUInt32(); + } + } + } + + public class SkeletonMaskElement + { + public uint m_PathHash { get; set; } + public float m_Weight { get; set; } + + public SkeletonMaskElement(EndianBinaryReader reader) + { + m_PathHash = reader.ReadUInt32(); + m_Weight = reader.ReadSingle(); + } + } + + public class SkeletonMask + { + public SkeletonMaskElement[] m_Data { get; set; } + + public SkeletonMask(EndianBinaryReader reader) + { + int numElements = reader.ReadInt32(); + m_Data = new SkeletonMaskElement[numElements]; + for (int i = 0; i < numElements; i++) + { + m_Data[i] = new SkeletonMaskElement(reader); + } + } + } + + public class LayerConstant + { + public uint m_StateMachineIndex { get; set; } + public uint m_StateMachineMotionSetIndex { get; set; } + public HumanPoseMask m_BodyMask { get; set; } + public SkeletonMask m_SkeletonMask { get; set; } + public uint m_Binding { get; set; } + public int m_LayerBlendingMode { get; set; } + public float m_DefaultWeight { get; set; } + public bool m_IKPass { get; set; } + public bool m_SyncedLayerAffectsTiming { get; set; } + + public LayerConstant(EndianBinaryReader reader, int[] version) + { + m_StateMachineIndex = reader.ReadUInt32(); + m_StateMachineMotionSetIndex = reader.ReadUInt32(); + m_BodyMask = new HumanPoseMask(reader, version); + m_SkeletonMask = new SkeletonMask(reader); + m_Binding = reader.ReadUInt32(); + m_LayerBlendingMode = reader.ReadInt32(); + m_DefaultWeight = reader.ReadSingle(); + m_IKPass = reader.ReadBoolean(); + m_SyncedLayerAffectsTiming = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class ConditionConstant + { + public uint m_ConditionMode { get; set; } + public uint m_EventID { get; set; } + public float m_EventThreshold { get; set; } + public float m_ExitTime { get; set; } + + public ConditionConstant(EndianBinaryReader reader) + { + m_ConditionMode = reader.ReadUInt32(); + m_EventID = reader.ReadUInt32(); + m_EventThreshold = reader.ReadSingle(); + m_ExitTime = reader.ReadSingle(); + } + } + + public class TransitionConstant + { + public ConditionConstant[] m_ConditionConstantArray { get; set; } + public uint m_DestinationState { get; set; } + public uint m_FullPathID { get; set; } + public uint m_ID { get; set; } + public uint m_UserID { get; set; } + public float m_TransitionDuration { get; set; } + public float m_TransitionOffset { get; set; } + public float m_ExitTime { get; set; } + public bool m_HasExitTime { get; set; } + public bool m_HasFixedDuration { get; set; } + public int m_InterruptionSource { get; set; } + public bool m_OrderedInterruption { get; set; } + public bool m_Atomic { get; set; } + public bool m_CanTransitionToSelf { get; set; } + + public TransitionConstant(EndianBinaryReader reader, int[] version) + { + int numConditions = reader.ReadInt32(); + m_ConditionConstantArray = new ConditionConstant[numConditions]; + for (int i = 0; i < numConditions; i++) + { + m_ConditionConstantArray[i] = new ConditionConstant(reader); + } + + m_DestinationState = reader.ReadUInt32(); + if (version[0] >= 5) //5.0 and up + { + m_FullPathID = reader.ReadUInt32(); + } + + m_ID = reader.ReadUInt32(); + m_UserID = reader.ReadUInt32(); + m_TransitionDuration = reader.ReadSingle(); + m_TransitionOffset = reader.ReadSingle(); + if (version[0] >= 5) //5.0 and up + { + m_ExitTime = reader.ReadSingle(); + m_HasExitTime = reader.ReadBoolean(); + m_HasFixedDuration = reader.ReadBoolean(); + reader.AlignStream(4); + m_InterruptionSource = reader.ReadInt32(); + m_OrderedInterruption = reader.ReadBoolean(); + } + else + { + m_Atomic = reader.ReadBoolean(); + } + + m_CanTransitionToSelf = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class LeafInfoConstant + { + public uint[] m_IDArray { get; set; } + public uint m_IndexOffset { get; set; } + + public LeafInfoConstant(EndianBinaryReader reader) + { + m_IDArray = reader.ReadUInt32Array(reader.ReadInt32()); + m_IndexOffset = reader.ReadUInt32(); + } + } + + public class MotionNeighborList + { + public uint[] m_NeighborArray { get; set; } + + public MotionNeighborList(EndianBinaryReader reader) + { + m_NeighborArray = reader.ReadUInt32Array(reader.ReadInt32()); + } + } + + public class Blend2dDataConstant + { + public Vector2[] m_ChildPositionArray { get; set; } + public float[] m_ChildMagnitudeArray { get; set; } + public Vector2[] m_ChildPairVectorArray { get; set; } + public float[] m_ChildPairAvgMagInvArray { get; set; } + public MotionNeighborList[] m_ChildNeighborListArray { get; set; } + + public Blend2dDataConstant(EndianBinaryReader reader) + { + m_ChildPositionArray = reader.ReadVector2Array(reader.ReadInt32()); + m_ChildMagnitudeArray = reader.ReadSingleArray(reader.ReadInt32()); + m_ChildPairVectorArray = reader.ReadVector2Array(reader.ReadInt32()); + m_ChildPairAvgMagInvArray = reader.ReadSingleArray(reader.ReadInt32()); + + int numNeighbours = reader.ReadInt32(); + m_ChildNeighborListArray = new MotionNeighborList[numNeighbours]; + for (int i = 0; i < numNeighbours; i++) + { + m_ChildNeighborListArray[i] = new MotionNeighborList(reader); + } + } + } + + public class Blend1dDataConstant // wrong labeled + { + public float[] m_ChildThresholdArray { get; set; } + + public Blend1dDataConstant(EndianBinaryReader reader) + { + m_ChildThresholdArray = reader.ReadSingleArray(reader.ReadInt32()); + } + } + + public class BlendDirectDataConstant + { + public uint[] m_ChildBlendEventIDArray { get; set; } + public bool m_NormalizedBlendValues { get; set; } + + public BlendDirectDataConstant(EndianBinaryReader reader) + { + m_ChildBlendEventIDArray = reader.ReadUInt32Array(reader.ReadInt32()); + m_NormalizedBlendValues = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class BlendTreeNodeConstant + { + public uint m_BlendType { get; set; } + public uint m_BlendEventID { get; set; } + public uint m_BlendEventYID { get; set; } + public uint[] m_ChildIndices { get; set; } + public Blend1dDataConstant m_Blend1dData { get; set; } + public Blend2dDataConstant m_Blend2dData { get; set; } + public BlendDirectDataConstant m_BlendDirectData { get; set; } + public uint m_ClipID { get; set; } + public uint m_ClipIndex { get; set; } + public float m_Duration { get; set; } + public float m_CycleOffset { get; set; } + public bool m_Mirror { get; set; } + + public BlendTreeNodeConstant(EndianBinaryReader reader, int[] version) + { + m_BlendType = reader.ReadUInt32(); + m_BlendEventID = reader.ReadUInt32(); + m_BlendEventYID = reader.ReadUInt32(); + m_ChildIndices = reader.ReadUInt32Array(reader.ReadInt32()); + m_Blend1dData = new Blend1dDataConstant(reader); + m_Blend2dData = new Blend2dDataConstant(reader); + if (version[0] >= 5) //5.0 and up + { + m_BlendDirectData = new BlendDirectDataConstant(reader); + } + + m_ClipID = reader.ReadUInt32(); + if (version[0] < 5) //5.0 down + { + m_ClipIndex = reader.ReadUInt32(); + } + + m_Duration = reader.ReadSingle(); + m_CycleOffset = reader.ReadSingle(); + m_Mirror = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class BlendTreeConstant + { + public BlendTreeNodeConstant[] m_NodeArray { get; set; } + + public BlendTreeConstant(EndianBinaryReader reader, int[] version) + { + int numNodes = reader.ReadInt32(); + m_NodeArray = new BlendTreeNodeConstant[numNodes]; + for (int i = 0; i < numNodes; i++) + { + m_NodeArray[i] = new BlendTreeNodeConstant(reader, version); + } + } + } + + + public class StateConstant + { + public TransitionConstant[] m_TransitionConstantArray { get; set; } + public int[] m_BlendTreeConstantIndexArray { get; set; } + public LeafInfoConstant[] m_LeafInfoArray { get; set; } + public BlendTreeConstant[] m_BlendTreeConstantArray { get; set; } + public uint m_NameID { get; set; } + public uint m_PathID { get; set; } + public uint m_FullPathID { get; set; } + public uint m_TagID { get; set; } + public uint m_SpeedParamID { get; set; } + public uint m_MirrorParamID { get; set; } + public uint m_CycleOffsetParamID { get; set; } + public float m_Speed { get; set; } + public float m_CycleOffset { get; set; } + public bool m_IKOnFeet { get; set; } + public bool m_WriteDefaultValues { get; set; } + public bool m_Loop { get; set; } + public bool m_Mirror { get; set; } + + public StateConstant(EndianBinaryReader reader, int[] version) + { + int numTransistions = reader.ReadInt32(); + m_TransitionConstantArray = new TransitionConstant[numTransistions]; + for (int i = 0; i < numTransistions; i++) + { + m_TransitionConstantArray[i] = new TransitionConstant(reader, version); + } + + int numBlendIndices = reader.ReadInt32(); + m_BlendTreeConstantIndexArray = new int[numBlendIndices]; + for (int i = 0; i < numBlendIndices; i++) + { + m_BlendTreeConstantIndexArray[i] = reader.ReadInt32(); + } + + if (version[0] < 5) //5.0 down + { + int numInfos = reader.ReadInt32(); + m_LeafInfoArray = new LeafInfoConstant[numInfos]; + for (int i = 0; i < numInfos; i++) + { + m_LeafInfoArray[i] = new LeafInfoConstant(reader); + } + } + + int numBlends = reader.ReadInt32(); + m_BlendTreeConstantArray = new BlendTreeConstant[numBlends]; + for (int i = 0; i < numBlends; i++) + { + m_BlendTreeConstantArray[i] = new BlendTreeConstant(reader, version); + } + + m_NameID = reader.ReadUInt32(); + m_PathID = reader.ReadUInt32(); + if (version[0] >= 5) //5.0 and up + { + m_FullPathID = reader.ReadUInt32(); + } + + m_TagID = reader.ReadUInt32(); + if (version[0] >= 5) //5.0 and up + { + m_SpeedParamID = reader.ReadUInt32(); + m_MirrorParamID = reader.ReadUInt32(); + m_CycleOffsetParamID = reader.ReadUInt32(); + } + + if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up + { + var m_TimeParamID = reader.ReadUInt32(); + } + + m_Speed = reader.ReadSingle(); + m_CycleOffset = reader.ReadSingle(); + m_IKOnFeet = reader.ReadBoolean(); + if (version[0] >= 5) //5.0 and up + { + m_WriteDefaultValues = reader.ReadBoolean(); + } + + m_Loop = reader.ReadBoolean(); + m_Mirror = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class SelectorTransitionConstant + { + public uint m_Destination { get; set; } + public ConditionConstant[] m_ConditionConstantArray { get; set; } + + public SelectorTransitionConstant(EndianBinaryReader reader) + { + m_Destination = reader.ReadUInt32(); + + int numConditions = reader.ReadInt32(); + m_ConditionConstantArray = new ConditionConstant[numConditions]; + for (int i = 0; i < numConditions; i++) + { + m_ConditionConstantArray[i] = new ConditionConstant(reader); + } + } + } + + public class SelectorStateConstant + { + public SelectorTransitionConstant[] m_TransitionConstantArray { get; set; } + public uint m_FullPathID { get; set; } + public bool m_isEntry { get; set; } + + public SelectorStateConstant(EndianBinaryReader reader) + { + int numTransitions = reader.ReadInt32(); + m_TransitionConstantArray = new SelectorTransitionConstant[numTransitions]; + for (int i = 0; i < numTransitions; i++) + { + m_TransitionConstantArray[i] = new SelectorTransitionConstant(reader); + } + + m_FullPathID = reader.ReadUInt32(); + m_isEntry = reader.ReadBoolean(); + reader.AlignStream(4); + } + } + + public class StateMachineConstant + { + public StateConstant[] m_StateConstantArray { get; set; } + public TransitionConstant[] m_AnyStateTransitionConstantArray { get; set; } + public SelectorStateConstant[] m_SelectorStateConstantArray { get; set; } + public uint m_DefaultState { get; set; } + public uint m_MotionSetCount { get; set; } + + public StateMachineConstant(EndianBinaryReader reader, int[] version) + { + int numStates = reader.ReadInt32(); + m_StateConstantArray = new StateConstant[numStates]; + for (int i = 0; i < numStates; i++) + { + m_StateConstantArray[i] = new StateConstant(reader, version); + } + + int numAnyStates = reader.ReadInt32(); + m_AnyStateTransitionConstantArray = new TransitionConstant[numAnyStates]; + for (int i = 0; i < numAnyStates; i++) + { + m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader, version); + } + + if (version[0] >= 5) //5.0 and up + { + int numSelectors = reader.ReadInt32(); + m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors]; + for (int i = 0; i < numSelectors; i++) + { + m_SelectorStateConstantArray[i] = new SelectorStateConstant(reader); + } + } + + m_DefaultState = reader.ReadUInt32(); + m_MotionSetCount = reader.ReadUInt32(); + } + } + + public class ValueArray + { + public bool[] m_BoolValues { get; set; } + public int[] m_IntValues { get; set; } + public float[] m_FloatValues { get; set; } + public object[] m_PositionValues { get; set; } + public Vector4[] m_QuaternionValues { get; set; } + public object[] m_ScaleValues { get; set; } + + public ValueArray(EndianBinaryReader reader, int[] version) + { + if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down + { + int numBools = reader.ReadInt32(); + m_BoolValues = new bool[numBools]; + for (int i = 0; i < numBools; i++) + { + m_BoolValues[i] = reader.ReadBoolean(); + } + + reader.AlignStream(4); + + m_IntValues = reader.ReadInt32Array(reader.ReadInt32()); + m_FloatValues = reader.ReadSingleArray(reader.ReadInt32()); + } + + int numPosValues = reader.ReadInt32(); + m_PositionValues = new object[numPosValues]; + for (int i = 0; i < numPosValues; i++) + { + m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4(); //5.4 and up + } + + m_QuaternionValues = reader.ReadVector4Array(reader.ReadInt32()); + + int numScaleValues = reader.ReadInt32(); + m_ScaleValues = new object[numScaleValues]; + for (int i = 0; i < numScaleValues; i++) + { + m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4(); //5.4 adn up + } + + if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up + { + m_FloatValues = reader.ReadSingleArray(reader.ReadInt32()); + m_IntValues = reader.ReadInt32Array(reader.ReadInt32()); + + int numBools = reader.ReadInt32(); + m_BoolValues = new bool[numBools]; + for (int i = 0; i < numBools; i++) + { + m_BoolValues[i] = reader.ReadBoolean(); + } + + reader.AlignStream(4); + } + } + } + + public class ControllerConstant + { + public LayerConstant[] m_LayerArray { get; set; } + public StateMachineConstant[] m_StateMachineArray { get; set; } + public ValueArrayConstant m_Values { get; set; } + public ValueArray m_DefaultValues { get; set; } + + public ControllerConstant(EndianBinaryReader reader, int[] version) + { + int numLayers = reader.ReadInt32(); + m_LayerArray = new LayerConstant[numLayers]; + for (int i = 0; i < numLayers; i++) + { + m_LayerArray[i] = new LayerConstant(reader, version); + } + + int numStates = reader.ReadInt32(); + m_StateMachineArray = new StateMachineConstant[numStates]; + for (int i = 0; i < numStates; i++) + { + m_StateMachineArray[i] = new StateMachineConstant(reader, version); + } + + m_Values = new ValueArrayConstant(reader, version); + m_DefaultValues = new ValueArray(reader, version); + } + } + + public class AnimatorController + { + public string m_Name; + public PPtr[] m_AnimationClips; + + public AnimatorController(AssetPreloadData preloadData) + { + var sourceFile = preloadData.sourceFile; + var version = preloadData.sourceFile.version; + var reader = preloadData.InitReader(); + reader.Position = preloadData.Offset; + + m_Name = reader.ReadAlignedString(); + var m_ControllerSize = reader.ReadUInt32(); + var m_Controller = new ControllerConstant(reader, version); + + int tosSize = reader.ReadInt32(); + var m_TOS = new List>(tosSize); + for (int i = 0; i < tosSize; i++) + { + m_TOS.Add(new KeyValuePair(reader.ReadUInt32(), reader.ReadAlignedString())); + } + + int numClips = reader.ReadInt32(); + m_AnimationClips = new PPtr[numClips]; + for (int i = 0; i < numClips; i++) + { + m_AnimationClips[i] = sourceFile.ReadPPtr(); + } + } + } +} diff --git a/AssetStudio/Classes/AnimatorOverrideController.cs b/AssetStudio/Classes/AnimatorOverrideController.cs new file mode 100644 index 0000000..4fe8fbb --- /dev/null +++ b/AssetStudio/Classes/AnimatorOverrideController.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + class AnimatorOverrideController + { + public string m_Name; + public PPtr m_Controller; + public PPtr[][] m_Clips; + + public AnimatorOverrideController(AssetPreloadData preloadData) + { + var sourceFile = preloadData.sourceFile; + var reader = preloadData.InitReader(); + reader.Position = preloadData.Offset; + + m_Name = reader.ReadAlignedString(); + m_Controller = sourceFile.ReadPPtr(); + + int numOverrides = reader.ReadInt32(); + m_Clips = new PPtr[numOverrides][]; + for (int i = 0; i < numOverrides; i++) + { + m_Clips[i] = new PPtr[2]; + m_Clips[i][0] = sourceFile.ReadPPtr(); + m_Clips[i][1] = sourceFile.ReadPPtr(); + } + } + } +} diff --git a/AssetStudio/Classes/AssetBundle.cs b/AssetStudio/Classes/AssetBundle.cs index a99f78b..64d8537 100644 --- a/AssetStudio/Classes/AssetBundle.cs +++ b/AssetStudio/Classes/AssetBundle.cs @@ -27,9 +27,9 @@ namespace AssetStudio public AssetBundle(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); - var m_Name = reader.ReadAlignedString(reader.ReadInt32()); + var m_Name = reader.ReadAlignedString(); var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { @@ -39,7 +39,7 @@ namespace AssetStudio for (int i = 0; i < size; i++) { var temp = new ContainerData(); - temp.first = reader.ReadAlignedString(reader.ReadInt32()); + temp.first = reader.ReadAlignedString(); temp.second = new AssetInfo(); temp.second.preloadIndex = reader.ReadInt32(); temp.second.preloadSize = reader.ReadInt32(); diff --git a/AssetStudio/Classes/AudioClip.cs b/AssetStudio/Classes/AudioClip.cs index 13f16d2..9a4a7b2 100644 --- a/AssetStudio/Classes/AudioClip.cs +++ b/AssetStudio/Classes/AudioClip.cs @@ -38,7 +38,7 @@ namespace AssetStudio public AudioClip(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { @@ -47,7 +47,7 @@ namespace AssetStudio PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); version5 = sourceFile.version[0] >= 5; if (sourceFile.version[0] < 5) { @@ -91,7 +91,7 @@ namespace AssetStudio reader.Position += 1; m_3D = m_Legacy3D; - m_Source = reader.ReadAlignedString(reader.ReadInt32()); + m_Source = reader.ReadAlignedString(); m_Offset = reader.ReadInt64(); m_Size = reader.ReadInt64(); m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32(); diff --git a/AssetStudio/Classes/Avatar.cs b/AssetStudio/Classes/Avatar.cs new file mode 100644 index 0000000..cff9081 --- /dev/null +++ b/AssetStudio/Classes/Avatar.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + class Avatar + { + public string m_Name; + private List> m_TOS; + + public Avatar(AssetPreloadData preloadData) + { + var sourceFile = preloadData.sourceFile; + var version = sourceFile.version; + var reader = preloadData.InitReader(); + reader.Position = preloadData.Offset; + + m_Name = reader.ReadAlignedString(); + var m_AvatarSize = reader.ReadUInt32(); + //AvatarConstant m_Avatar + //- OffsetPtr m_AvatarSkeleton + //-- Skeleton data + //--- vector m_Node + var numNodes = reader.ReadInt32(); + for (int i = 0; i < numNodes; i++) + { + reader.Position += 8; + } + //--- vector m_ID + int numIDs = reader.ReadInt32(); + for (int i = 0; i < numIDs; i++) + { + reader.Position += 4; + } + //--- vector m_AxesArray + int numAxes = reader.ReadInt32(); + for (int i = 0; i < numAxes; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 76; + else + reader.Position += 88; + } + //- OffsetPtr m_AvatarSkeletonPose + //-- SkeletonPose data + int numXforms = reader.ReadInt32(); + for (int i = 0; i < numXforms; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 40; + else + reader.Position += 48; + } + //- OffsetPtr m_DefaultPose + //-- SkeletonPose data + numXforms = reader.ReadInt32(); + for (int i = 0; i < numXforms; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 40; + else + reader.Position += 48; + } + //- vector m_SkeletonNameIDArray + numIDs = reader.ReadInt32(); + for (int i = 0; i < numIDs; i++) + { + reader.Position += 4; + } + //- OffsetPtr m_Human + //-- Human data + //--- xform m_RootX + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 40; + else + reader.Position += 48; + //--- OffsetPtr m_Skeleton + //---- Skeleton data + numNodes = reader.ReadInt32(); + for (int i = 0; i < numNodes; i++) + { + reader.Position += 8; + } + //--- vector m_ID + numIDs = reader.ReadInt32(); + for (int i = 0; i < numIDs; i++) + { + reader.Position += 4; + } + //--- vector m_AxesArray + numAxes = reader.ReadInt32(); + for (int i = 0; i < numAxes; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 76; + else + reader.Position += 88; + } + //--- OffsetPtr m_SkeletonPose + //---- SkeletonPose data + numXforms = reader.ReadInt32(); + for (int i = 0; i < numXforms; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 40; + else + reader.Position += 48; + } + //--- OffsetPtr m_LeftHand + //---- Hand data + //----- staticvector m_HandBoneIndex + int numIndexes = reader.ReadInt32(); + for (int i = 0; i < numIndexes; i++) + { + reader.Position += 4; + } + //--- OffsetPtr m_RightHand + numIndexes = reader.ReadInt32(); + for (int i = 0; i < numIndexes; i++) + { + reader.Position += 4; + } + //--- vector m_Handles + int numHandles = reader.ReadInt32(); + for (int i = 0; i < numHandles; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 48; + else + reader.Position += 56; + } + //--- vector m_ColliderArray + int numColliders = reader.ReadInt32(); + for (int i = 0; i < numColliders; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 72; + else + reader.Position += 80; + } + //--- staticvector m_HumanBoneIndex + numIndexes = reader.ReadInt32(); + for (int i = 0; i < numIndexes; i++) + { + reader.Position += 4; + } + //--- staticvector m_HumanBoneMass + int numMasses = reader.ReadInt32(); + for (int i = 0; i < numMasses; i++) + { + reader.Position += 4; + } + //--- staticvector m_ColliderIndex + int numColliderIndexes = reader.ReadInt32(); + for (int i = 0; i < numColliderIndexes; i++) + { + reader.Position += 4; + } + var m_Scale = reader.ReadSingle(); + var m_ArmTwist = reader.ReadSingle(); + var m_ForeArmTwist = reader.ReadSingle(); + var m_UpperLegTwist = reader.ReadSingle(); + var m_LegTwist = reader.ReadSingle(); + var m_ArmStretch = reader.ReadSingle(); + var m_LegStretch = reader.ReadSingle(); + var m_FeetSpacing = reader.ReadSingle(); + var m_HasLeftHand = reader.ReadBoolean(); + var m_HasRightHand = reader.ReadBoolean(); + var m_HasTDoF = reader.ReadBoolean(); + reader.AlignStream(4); + //- vector m_HumanSkeletonIndexArray + numIndexes = reader.ReadInt32(); + for (int i = 0; i < numIndexes; i++) + { + reader.Position += 4; + } + //- vector m_HumanSkeletonReverseIndexArray + int numReverseIndexes = reader.ReadInt32(); + for (int i = 0; i < numReverseIndexes; i++) + { + reader.Position += 4; + } + var m_RootMotionBoneIndex = reader.ReadInt32(); + //- xform m_RootMotionBoneX + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 40; + else + reader.Position += 48; + //- OffsetPtr m_RootMotionSkeleton + //-- Skeleton data + //--- vector m_Node + numNodes = reader.ReadInt32(); + for (int i = 0; i < numNodes; i++) + { + reader.Position += 8; + } + //--- vector m_ID + numIDs = reader.ReadInt32(); + for (int i = 0; i < numIDs; i++) + { + reader.Position += 4; + } + //--- vector m_AxesArray + numAxes = reader.ReadInt32(); + for (int i = 0; i < numAxes; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 76; + else + reader.Position += 88; + } + //- OffsetPtr m_RootMotionSkeletonPose + //-- SkeletonPose data + numXforms = reader.ReadInt32(); + for (int i = 0; i < numXforms; i++) + { + if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up + reader.Position += 40; + else + reader.Position += 48; + } + //- vector m_RootMotionSkeletonIndexArray + int numMotionIndexes = reader.ReadInt32(); + for (int i = 0; i < numMotionIndexes; i++) + { + reader.Position += 4; + } + //map m_TOS + int numTOS = reader.ReadInt32(); + m_TOS = new List>(numTOS); + for (int i = 0; i < numTOS; i++) + { + m_TOS.Add(new KeyValuePair(reader.ReadUInt32(), reader.ReadAlignedString())); + } + } + + public string FindBoneName(uint hash) + { + foreach (var pair in m_TOS) + { + if (pair.Key == hash) + { + return pair.Value.Substring(pair.Value.LastIndexOf('/') + 1); + } + } + return null; + } + } +} diff --git a/AssetStudio/Classes/BuildSettings.cs b/AssetStudio/Classes/BuildSettings.cs index d6f0473..911fe8e 100644 --- a/AssetStudio/Classes/BuildSettings.cs +++ b/AssetStudio/Classes/BuildSettings.cs @@ -12,15 +12,15 @@ namespace AssetStudio public BuildSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); int levels = reader.ReadInt32(); - for (int l = 0; l < levels; l++) { string level = reader.ReadAlignedString(reader.ReadInt32()); } + for (int l = 0; l < levels; l++) { string level = reader.ReadAlignedString(); } if (sourceFile.version[0] == 5) { int preloadedPlugins = reader.ReadInt32(); - for (int l = 0; l < preloadedPlugins; l++) { string preloadedPlugin = reader.ReadAlignedString(reader.ReadInt32()); } + for (int l = 0; l < preloadedPlugins; l++) { string preloadedPlugin = reader.ReadAlignedString(); } } reader.Position += 4; //bool flags @@ -31,7 +31,7 @@ namespace AssetStudio (sourceFile.version[1] == 2 && sourceFile.buildType[0] != "a")))) { reader.Position += 4; } //bool flags - m_Version = reader.ReadAlignedString(reader.ReadInt32()); + m_Version = reader.ReadAlignedString(); } } } diff --git a/AssetStudio/Classes/Font.cs b/AssetStudio/Classes/Font.cs index 5d84fa9..c35f997 100644 --- a/AssetStudio/Classes/Font.cs +++ b/AssetStudio/Classes/Font.cs @@ -13,7 +13,7 @@ namespace AssetStudio public UFont(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { @@ -22,7 +22,7 @@ namespace AssetStudio PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (readSwitch) { @@ -166,7 +166,7 @@ namespace AssetStudio int m_FontNames = reader.ReadInt32(); for (int i = 0; i < m_FontNames; i++) { - string m_FontName = reader.ReadAlignedString(reader.ReadInt32()); + string m_FontName = reader.ReadAlignedString(); } if (sourceFile.version[0] >= 4) diff --git a/AssetStudio/Classes/GameObject.cs b/AssetStudio/Classes/GameObject.cs index 3e8a548..2360ada 100644 --- a/AssetStudio/Classes/GameObject.cs +++ b/AssetStudio/Classes/GameObject.cs @@ -25,7 +25,7 @@ namespace AssetStudio if (preloadData != null) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); uniqueID = preloadData.uniqueID; @@ -51,7 +51,7 @@ namespace AssetStudio } m_Layer = reader.ReadInt32(); - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (m_Name == "") { m_Name = "GameObject #" + uniqueID; } m_Tag = reader.ReadUInt16(); m_IsActive = reader.ReadBoolean(); diff --git a/AssetStudio/Classes/Material.cs b/AssetStudio/Classes/Material.cs index d12e4bb..d6d999c 100644 --- a/AssetStudio/Classes/Material.cs +++ b/AssetStudio/Classes/Material.cs @@ -38,7 +38,7 @@ namespace AssetStudio public Material(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { @@ -47,7 +47,7 @@ namespace AssetStudio PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); m_Shader = sourceFile.ReadPPtr(); if (sourceFile.version[0] == 4 && (sourceFile.version[1] >= 2 || (sourceFile.version[1] == 1 && sourceFile.buildType[0] != "a"))) @@ -55,12 +55,12 @@ namespace AssetStudio m_ShaderKeywords = new string[reader.ReadInt32()]; for (int i = 0; i < m_ShaderKeywords.Length; i++) { - m_ShaderKeywords[i] = reader.ReadAlignedString(reader.ReadInt32()); + m_ShaderKeywords[i] = reader.ReadAlignedString(); } } else if (sourceFile.version[0] >= 5)//5.0 and up { - m_ShaderKeywords = new[] { reader.ReadAlignedString(reader.ReadInt32()) }; + m_ShaderKeywords = new[] { reader.ReadAlignedString() }; uint m_LightmapFlags = reader.ReadUInt32(); if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 6 || sourceFile.version[0] > 5)//5.6.0 and up { @@ -77,7 +77,7 @@ namespace AssetStudio string[][] stringTagMap = new string[reader.ReadInt32()][]; for (int i = 0; i < stringTagMap.Length; i++) { - stringTagMap[i] = new[] { reader.ReadAlignedString(reader.ReadInt32()), reader.ReadAlignedString(reader.ReadInt32()) }; + stringTagMap[i] = new[] { reader.ReadAlignedString(), reader.ReadAlignedString() }; } } //disabledShaderPasses @@ -86,7 +86,7 @@ namespace AssetStudio var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { - reader.ReadAlignedString(reader.ReadInt32()); + reader.ReadAlignedString(); } } //m_SavedProperties @@ -95,7 +95,7 @@ namespace AssetStudio { TexEnv m_TexEnv = new TexEnv() { - name = reader.ReadAlignedString(reader.ReadInt32()), + name = reader.ReadAlignedString(), m_Texture = sourceFile.ReadPPtr(), m_Scale = new[] { reader.ReadSingle(), reader.ReadSingle() }, m_Offset = new[] { reader.ReadSingle(), reader.ReadSingle() } @@ -108,7 +108,7 @@ namespace AssetStudio { strFloatPair m_Float = new strFloatPair() { - first = reader.ReadAlignedString(reader.ReadInt32()), + first = reader.ReadAlignedString(), second = reader.ReadSingle() }; m_Floats[i] = m_Float; @@ -119,7 +119,7 @@ namespace AssetStudio { strColorPair m_Color = new strColorPair() { - first = reader.ReadAlignedString(reader.ReadInt32()), + first = reader.ReadAlignedString(), second = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() } }; m_Colors[i] = m_Color; diff --git a/AssetStudio/Classes/Mesh.cs b/AssetStudio/Classes/Mesh.cs index 15f9316..e64f49b 100644 --- a/AssetStudio/Classes/Mesh.cs +++ b/AssetStudio/Classes/Mesh.cs @@ -331,7 +331,7 @@ namespace AssetStudio //Stream = new EndianStream(File.OpenRead(sourceFile.filePath), sourceFile.endianType); //Stream.endian = sourceFile.endianType; var version = MeshPD.sourceFile.version; - reader = MeshPD.Reader; + reader = MeshPD.InitReader(); bool m_Use16BitIndices = true; //3.5.0 and newer always uses 16bit indices uint m_MeshCompression = 0; @@ -343,7 +343,7 @@ namespace AssetStudio PPtr m_PrefabInternal = MeshPD.sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (readSwitch) { @@ -409,7 +409,7 @@ namespace AssetStudio } for (int s = 0; s < m_Shapes_size; s++) //untested { - string shape_name = reader.ReadAlignedString(reader.ReadInt32()); + string shape_name = reader.ReadAlignedString(); reader.Position += 36; //uint firstVertex, vertexCount; Vector3f aabbMinDelta, aabbMaxDelta; bool hasNormals, hasTangents } @@ -433,7 +433,7 @@ namespace AssetStudio int channels_size = reader.ReadInt32(); for (int c = 0; c < channels_size; c++) { - string channel_name = reader.ReadAlignedString(reader.ReadInt32()); + string channel_name = reader.ReadAlignedString(); reader.Position += 12; //uint nameHash; int frameIndex, frameCount } diff --git a/AssetStudio/Classes/MeshFilter.cs b/AssetStudio/Classes/MeshFilter.cs index ef45f2f..aafa0d9 100644 --- a/AssetStudio/Classes/MeshFilter.cs +++ b/AssetStudio/Classes/MeshFilter.cs @@ -14,7 +14,7 @@ namespace AssetStudio public MeshFilter(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { diff --git a/AssetStudio/Classes/MeshRenderer.cs b/AssetStudio/Classes/MeshRenderer.cs index fa58249..c1d2f61 100644 --- a/AssetStudio/Classes/MeshRenderer.cs +++ b/AssetStudio/Classes/MeshRenderer.cs @@ -18,7 +18,7 @@ namespace AssetStudio public MeshRenderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { diff --git a/AssetStudio/Classes/MonoBehaviour.cs b/AssetStudio/Classes/MonoBehaviour.cs index aff8518..a575fef 100644 --- a/AssetStudio/Classes/MonoBehaviour.cs +++ b/AssetStudio/Classes/MonoBehaviour.cs @@ -12,13 +12,13 @@ namespace AssetStudio public MonoBehaviour(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); var m_GameObject = sourceFile.ReadPPtr(); var m_Enabled = reader.ReadByte(); reader.AlignStream(4); var m_Script = sourceFile.ReadPPtr(); - var m_Name = reader.ReadAlignedString(reader.ReadInt32()); + var m_Name = reader.ReadAlignedString(); if (readSwitch) { if ((serializedText = preloadData.ViewStruct()) == null) diff --git a/AssetStudio/Classes/MovieTexture.cs b/AssetStudio/Classes/MovieTexture.cs index 9849d9b..5b7e657 100644 --- a/AssetStudio/Classes/MovieTexture.cs +++ b/AssetStudio/Classes/MovieTexture.cs @@ -13,9 +13,9 @@ namespace AssetStudio public MovieTexture(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (readSwitch) { var m_Loop = reader.ReadBoolean(); diff --git a/AssetStudio/Classes/PlayerSettings.cs b/AssetStudio/Classes/PlayerSettings.cs index b8e9afd..0a7c010 100644 --- a/AssetStudio/Classes/PlayerSettings.cs +++ b/AssetStudio/Classes/PlayerSettings.cs @@ -13,7 +13,7 @@ namespace AssetStudio public PlayerSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if ((sourceFile.version[0] == 5 && sourceFile.version[1] >= 4) || sourceFile.version[0] > 5)//5.4.0 nad up @@ -26,7 +26,7 @@ namespace AssetStudio } if (sourceFile.version[0] >= 3) { - if (sourceFile.version[0] == 3 && sourceFile.version[1] < 2) { string AndroidLicensePublicKey = reader.ReadAlignedString(reader.ReadInt32()); } + if (sourceFile.version[0] == 3 && sourceFile.version[1] < 2) { string AndroidLicensePublicKey = reader.ReadAlignedString(); } else { bool AndroidProfiler = reader.ReadBoolean(); reader.AlignStream(4); } int defaultScreenOrientation = reader.ReadInt32(); @@ -49,8 +49,8 @@ namespace AssetStudio else { int accelerometerFrequency = reader.ReadInt32(); }//3.5.0 and up } //fail in version 5 beta - companyName = reader.ReadAlignedString(reader.ReadInt32()); - productName = reader.ReadAlignedString(reader.ReadInt32()); + companyName = reader.ReadAlignedString(); + productName = reader.ReadAlignedString(); } } } diff --git a/AssetStudio/Classes/Shader.cs b/AssetStudio/Classes/Shader.cs index a60f988..48e85b3 100644 --- a/AssetStudio/Classes/Shader.cs +++ b/AssetStudio/Classes/Shader.cs @@ -16,7 +16,7 @@ namespace AssetStudio public Shader(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { @@ -25,7 +25,7 @@ namespace AssetStudio PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (readSwitch) { @@ -56,7 +56,7 @@ namespace AssetStudio if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3) //5.3 - 5.4 { reader.AlignStream(4); - reader.ReadAlignedString(reader.ReadInt32());//m_PathName + reader.ReadAlignedString();//m_PathName var decompressedSize = reader.ReadUInt32(); var m_SubProgramBlob = reader.ReadBytes(reader.ReadInt32()); var decompressedBytes = new byte[decompressedSize]; diff --git a/AssetStudio/Classes/SkinnedMeshRenderer.cs b/AssetStudio/Classes/SkinnedMeshRenderer.cs index 28a34e2..e9b7441 100644 --- a/AssetStudio/Classes/SkinnedMeshRenderer.cs +++ b/AssetStudio/Classes/SkinnedMeshRenderer.cs @@ -21,7 +21,7 @@ namespace AssetStudio { var sourceFile = preloadData.sourceFile; var version = preloadData.sourceFile.version; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { diff --git a/AssetStudio/Classes/Sprite.cs b/AssetStudio/Classes/Sprite.cs index e01397b..8e652df 100644 --- a/AssetStudio/Classes/Sprite.cs +++ b/AssetStudio/Classes/Sprite.cs @@ -21,10 +21,10 @@ namespace AssetStudio public Sprite(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); var version = sourceFile.version; - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (readSwitch) { //Rectf m_Rect @@ -62,7 +62,7 @@ namespace AssetStudio var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { - var data = reader.ReadAlignedString(reader.ReadInt32()); + var data = reader.ReadAlignedString(); } //PPtr m_SpriteAtlas diff --git a/AssetStudio/Classes/SpriteAtlas.cs b/AssetStudio/Classes/SpriteAtlas.cs index fbf8be0..8241eb3 100644 --- a/AssetStudio/Classes/SpriteAtlas.cs +++ b/AssetStudio/Classes/SpriteAtlas.cs @@ -16,9 +16,9 @@ namespace AssetStudio public SpriteAtlas(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); - var m_Name = reader.ReadAlignedString(reader.ReadInt32()); + var m_Name = reader.ReadAlignedString(); //vector m_PackedSprites var size = reader.ReadInt32(); for (int i = 0; i < size; i++) @@ -30,7 +30,7 @@ namespace AssetStudio size = reader.ReadInt32(); for (int i = 0; i < size; i++) { - var data = reader.ReadAlignedString(reader.ReadInt32()); + var data = reader.ReadAlignedString(); } //map m_RenderDataMap size = reader.ReadInt32(); diff --git a/AssetStudio/Classes/TextAsset.cs b/AssetStudio/Classes/TextAsset.cs index 5c7f063..89fabfe 100644 --- a/AssetStudio/Classes/TextAsset.cs +++ b/AssetStudio/Classes/TextAsset.cs @@ -14,7 +14,7 @@ namespace AssetStudio public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { @@ -23,7 +23,7 @@ namespace AssetStudio PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (readSwitch) { diff --git a/AssetStudio/Classes/Texture2D.cs b/AssetStudio/Classes/Texture2D.cs index bfd659d..d54191e 100644 --- a/AssetStudio/Classes/Texture2D.cs +++ b/AssetStudio/Classes/Texture2D.cs @@ -91,7 +91,7 @@ namespace AssetStudio public Texture2D(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); version = sourceFile.version; if (sourceFile.platform == -2) @@ -101,7 +101,7 @@ namespace AssetStudio PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } - m_Name = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3))//2017.3 and up { var m_ForcedFallbackFormat = reader.ReadInt32(); @@ -158,7 +158,7 @@ namespace AssetStudio offset = reader.ReadUInt32(); size = reader.ReadUInt32(); image_data_size = (int)size; - path = reader.ReadAlignedString(reader.ReadInt32()); + path = reader.ReadAlignedString(); } if (readSwitch) diff --git a/AssetStudio/Classes/Transform.cs b/AssetStudio/Classes/Transform.cs index fbe8c28..41cb3fd 100644 --- a/AssetStudio/Classes/Transform.cs +++ b/AssetStudio/Classes/Transform.cs @@ -17,7 +17,7 @@ namespace AssetStudio public Transform(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); if (sourceFile.platform == -2) { diff --git a/AssetStudio/Classes/VideoClip.cs b/AssetStudio/Classes/VideoClip.cs index d54ee65..360385d 100644 --- a/AssetStudio/Classes/VideoClip.cs +++ b/AssetStudio/Classes/VideoClip.cs @@ -15,10 +15,10 @@ namespace AssetStudio public VideoClip(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var reader = preloadData.Reader; + var reader = preloadData.InitReader(); - m_Name = reader.ReadAlignedString(reader.ReadInt32()); - var m_OriginalPath = reader.ReadAlignedString(reader.ReadInt32()); + m_Name = reader.ReadAlignedString(); + var m_OriginalPath = reader.ReadAlignedString(); var m_ProxyWidth = reader.ReadUInt32(); var m_ProxyHeight = reader.ReadUInt32(); var Width = reader.ReadUInt32(); @@ -42,10 +42,10 @@ namespace AssetStudio size = reader.ReadInt32(); for (int i = 0; i < size; i++) { - reader.ReadAlignedString(reader.ReadInt32()); + reader.ReadAlignedString(); } //StreamedResource m_ExternalResources - var m_Source = reader.ReadAlignedString(reader.ReadInt32()); + var m_Source = reader.ReadAlignedString(); var m_Offset = reader.ReadUInt64(); var m_Size = reader.ReadUInt64(); var m_HasSplitAlpha = reader.ReadBoolean(); diff --git a/AssetStudio/Library/SharpDX.Mathematics.dll b/AssetStudio/Library/SharpDX.Mathematics.dll new file mode 100644 index 0000000..4c0da9c Binary files /dev/null and b/AssetStudio/Library/SharpDX.Mathematics.dll differ diff --git a/AssetStudio/StudioClasses/AssetPreloadData.cs b/AssetStudio/StudioClasses/AssetPreloadData.cs index 9cc1554..a3313b4 100644 --- a/AssetStudio/StudioClasses/AssetPreloadData.cs +++ b/AssetStudio/StudioClasses/AssetPreloadData.cs @@ -23,14 +23,11 @@ namespace AssetStudio public AssetsFile sourceFile; public string uniqueID; - public EndianBinaryReader Reader + public EndianBinaryReader InitReader() { - get - { - var reader = sourceFile.assetsFileReader; - reader.Position = Offset; - return reader; - } + var reader = sourceFile.assetsFileReader; + reader.Position = Offset; + return reader; } } } diff --git a/AssetStudio/StudioClasses/AssetsFile.cs b/AssetStudio/StudioClasses/AssetsFile.cs index 0d7b10d..43cbd4c 100644 --- a/AssetStudio/StudioClasses/AssetsFile.cs +++ b/AssetStudio/StudioClasses/AssetsFile.cs @@ -417,66 +417,69 @@ namespace AssetStudio int stringSize = assetsFileReader.ReadInt32(); assetsFileReader.Position += varCount * 24; - var stringReader = new EndianBinaryReader(new MemoryStream(assetsFileReader.ReadBytes(stringSize))); - string className = ""; - var classVar = new List(); - //build Class Structures - assetsFileReader.Position -= varCount * 24 + stringSize; - for (int i = 0; i < varCount; i++) + using (var stringReader = new BinaryReader(new MemoryStream(assetsFileReader.ReadBytes(stringSize)))) { - ushort num0 = assetsFileReader.ReadUInt16(); - byte level = assetsFileReader.ReadByte(); - bool isArray = assetsFileReader.ReadBoolean(); + string className = ""; + var classVar = new List(); + //build Class Structures + assetsFileReader.Position -= varCount * 24 + stringSize; + for (int i = 0; i < varCount; i++) + { + ushort num0 = assetsFileReader.ReadUInt16(); + byte level = assetsFileReader.ReadByte(); + bool isArray = assetsFileReader.ReadBoolean(); - ushort varTypeIndex = assetsFileReader.ReadUInt16(); - ushort test = assetsFileReader.ReadUInt16(); - string varTypeStr; - if (test == 0) //varType is an offset in the string block - { - stringReader.Position = varTypeIndex; - varTypeStr = stringReader.ReadStringToNull(); - } - else //varType is an index in an internal strig array - { - varTypeStr = baseStrings.ContainsKey(varTypeIndex) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); - } - - ushort varNameIndex = assetsFileReader.ReadUInt16(); - test = assetsFileReader.ReadUInt16(); - string varNameStr; - if (test == 0) - { - stringReader.Position = varNameIndex; - varNameStr = stringReader.ReadStringToNull(); - } - else - { - varNameStr = baseStrings.ContainsKey(varNameIndex) ? baseStrings[varNameIndex] : varNameIndex.ToString(); - } - - int size = assetsFileReader.ReadInt32(); - int index = assetsFileReader.ReadInt32(); - int flag = assetsFileReader.ReadInt32(); - - if (index == 0) { className = varTypeStr + " " + varNameStr; } - else - { - classVar.Add(new ClassMember + ushort varTypeIndex = assetsFileReader.ReadUInt16(); + ushort test = assetsFileReader.ReadUInt16(); + string varTypeStr; + if (test == 0) //varType is an offset in the string block { - Level = level - 1, - Type = varTypeStr, - Name = varNameStr, - Size = size, - Flag = flag - }); - } - } - stringReader.Dispose(); - assetsFileReader.Position += stringSize; + stringReader.BaseStream.Position = varTypeIndex; + varTypeStr = stringReader.ReadStringToNull(); + } + else //varType is an index in an internal strig array + { + varTypeStr = baseStrings.ContainsKey(varTypeIndex) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); + } - var aClass = new ClassStruct { ID = classID, Text = className, members = classVar }; - aClass.SubItems.Add(classID.ToString()); - ClassStructures[classID] = aClass; + ushort varNameIndex = assetsFileReader.ReadUInt16(); + test = assetsFileReader.ReadUInt16(); + string varNameStr; + if (test == 0) + { + stringReader.BaseStream.Position = varNameIndex; + varNameStr = stringReader.ReadStringToNull(); + } + else + { + varNameStr = baseStrings.ContainsKey(varNameIndex) ? baseStrings[varNameIndex] : varNameIndex.ToString(); + } + + int size = assetsFileReader.ReadInt32(); + int index = assetsFileReader.ReadInt32(); + int flag = assetsFileReader.ReadInt32(); + + if (index == 0) + { + className = varTypeStr + " " + varNameStr; + } + else + { + classVar.Add(new ClassMember + { + Level = level - 1, + Type = varTypeStr, + Name = varNameStr, + Size = size, + Flag = flag + }); + } + } + assetsFileReader.Position += stringSize; + var aClass = new ClassStruct { ID = classID, Text = className, members = classVar }; + aClass.SubItems.Add(classID.ToString()); + ClassStructures[classID] = aClass; + } } } } diff --git a/AssetStudio/StudioClasses/BinaryReaderExtensions.cs b/AssetStudio/StudioClasses/BinaryReaderExtensions.cs new file mode 100644 index 0000000..8c8f1f0 --- /dev/null +++ b/AssetStudio/StudioClasses/BinaryReaderExtensions.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using SharpDX; + +namespace AssetStudio +{ + public static class BinaryReaderExtensions + { + public static void AlignStream(this BinaryReader reader, int alignment) + { + var pos = reader.BaseStream.Position; + var mod = pos % alignment; + if (mod != 0) + { + reader.BaseStream.Position += alignment - mod; + } + } + + public static string ReadAlignedString(this BinaryReader reader) + { + return ReadAlignedString(reader, reader.ReadInt32()); + } + + public static string ReadAlignedString(this BinaryReader reader, int length) + { + if (length > 0 && length < (reader.BaseStream.Length - reader.BaseStream.Position)) + { + var stringData = reader.ReadBytes(length); + var result = Encoding.UTF8.GetString(stringData); + reader.AlignStream(4); + return result; + } + return ""; + } + + public static string ReadStringToNull(this BinaryReader reader) + { + var bytes = new List(); + byte b; + while (reader.BaseStream.Position != reader.BaseStream.Length && (b = reader.ReadByte()) != 0) + bytes.Add(b); + return Encoding.UTF8.GetString(bytes.ToArray()); + } + + public static Quaternion ReadQuaternion(this BinaryReader reader) + { + var q = new Quaternion + { + X = reader.ReadSingle(), + Y = reader.ReadSingle(), + Z = reader.ReadSingle(), + W = reader.ReadSingle() + }; + return q; + } + + public static Vector2 ReadVector2(this BinaryReader reader) + { + Vector2 v = new Vector2 + { + X = reader.ReadSingle(), + Y = reader.ReadSingle() + }; + return v; + } + + public static Vector3 ReadVector3(this BinaryReader reader) + { + var v = new Vector3 + { + X = reader.ReadSingle(), + Y = reader.ReadSingle(), + Z = reader.ReadSingle() + }; + return v; + } + + public static Vector4 ReadVector4(this BinaryReader reader) + { + var v = new Vector4 + { + X = reader.ReadSingle(), + Y = reader.ReadSingle(), + Z = reader.ReadSingle(), + W = reader.ReadSingle() + }; + return v; + } + + private static T[] ReadArray(Func del, int length) + { + var array = new T[length]; + for (int i = 0; i < array.Length; i++) + { + array[i] = del(); + } + return array; + } + + public static int[] ReadInt32Array(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadInt32, length); + } + + public static uint[] ReadUInt32Array(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadUInt32, length); + } + + public static float[] ReadSingleArray(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadSingle, length); + } + + public static Vector2[] ReadVector2Array(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadVector2, length); + } + + public static Vector4[] ReadVector4Array(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadVector4, length); + } + } +} diff --git a/AssetStudio/StudioClasses/BinaryWriterExtensions.cs b/AssetStudio/StudioClasses/BinaryWriterExtensions.cs new file mode 100644 index 0000000..017d077 --- /dev/null +++ b/AssetStudio/StudioClasses/BinaryWriterExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + public static class BinaryWriterExtensions + { + private static void WriteArray(Action del, T[] array) + { + foreach (var item in array) + { + del(item); + } + } + + public static void Write(this BinaryWriter writer, uint[] array) + { + WriteArray(writer.Write, array); + } + } +} diff --git a/AssetStudio/StudioClasses/ClassStruct.cs b/AssetStudio/StudioClasses/ClassStruct.cs index 303dc9e..47f2d5e 100644 --- a/AssetStudio/StudioClasses/ClassStruct.cs +++ b/AssetStudio/StudioClasses/ClassStruct.cs @@ -41,7 +41,7 @@ namespace AssetStudio { public static string ViewStruct(this AssetPreloadData asset) { - var reader = asset.Reader; + var reader = asset.InitReader(); if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure)) { var sb = new StringBuilder(); @@ -108,7 +108,7 @@ namespace AssetStudio break; case "string": append = false; - var str = reader.ReadAlignedString(reader.ReadInt32()); + var str = reader.ReadAlignedString(); sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str); i += 3;//skip break; diff --git a/AssetStudio/StudioClasses/EndianBinaryReader.cs b/AssetStudio/StudioClasses/EndianBinaryReader.cs index 751a834..1ee5197 100644 --- a/AssetStudio/StudioClasses/EndianBinaryReader.cs +++ b/AssetStudio/StudioClasses/EndianBinaryReader.cs @@ -115,38 +115,5 @@ namespace AssetStudio } return base.ReadDouble(); } - - public string ReadASCII(int length) - { - return Encoding.ASCII.GetString(ReadBytes(length)); - } - - public void AlignStream(int alignment) - { - var pos = BaseStream.Position; - var mod = pos % alignment; - if (mod != 0) { BaseStream.Position += alignment - mod; } - } - - public string ReadAlignedString(int length) - { - if (length > 0 && length < (BaseStream.Length - BaseStream.Position)) - { - var stringData = ReadBytes(length); - var result = Encoding.UTF8.GetString(stringData); - AlignStream(4); - return result; - } - return ""; - } - - public string ReadStringToNull() - { - var bytes = new List(); - byte b; - while (BaseStream.Position != BaseStream.Length && (b = ReadByte()) != 0) - bytes.Add(b); - return Encoding.UTF8.GetString(bytes.ToArray()); - } } } diff --git a/AssetStudio/StudioClasses/Exporter.cs b/AssetStudio/StudioClasses/Exporter.cs index 04f7c71..cc33be9 100644 --- a/AssetStudio/StudioClasses/Exporter.cs +++ b/AssetStudio/StudioClasses/Exporter.cs @@ -302,7 +302,7 @@ namespace AssetStudio var exportFullName = exportPath + asset.Text + asset.extension; if (ExportFileExists(exportFullName)) return false; - var bytes = asset.Reader.ReadBytes(asset.Size); + var bytes = asset.InitReader().ReadBytes(asset.Size); File.WriteAllBytes(exportFullName, bytes); return true; }