diff --git a/Unity Studio/Unity Classes/AssetBundle.cs b/Unity Studio/Unity Classes/AssetBundle.cs index da84b17..c68ed8e 100644 --- a/Unity Studio/Unity Classes/AssetBundle.cs +++ b/Unity Studio/Unity Classes/AssetBundle.cs @@ -27,7 +27,7 @@ namespace Unity_Studio public AssetBundle(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); diff --git a/Unity Studio/Unity Classes/AudioClip.cs b/Unity Studio/Unity Classes/AudioClip.cs index 351e337..80d3aa9 100644 --- a/Unity Studio/Unity Classes/AudioClip.cs +++ b/Unity Studio/Unity Classes/AudioClip.cs @@ -38,7 +38,7 @@ namespace Unity_Studio public AudioClip(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) @@ -107,7 +107,10 @@ namespace Unity_Studio if (!File.Exists(resourceFilePath)) { var findFiles = Directory.GetFiles(Path.GetDirectoryName(sourceFile.filePath), resourceFileName, SearchOption.AllDirectories); - if (findFiles.Length > 0) { resourceFilePath = findFiles[0]; } + if (findFiles.Length > 0) + { + resourceFilePath = findFiles[0]; + } } if (File.Exists(resourceFilePath)) { @@ -119,7 +122,7 @@ namespace Unity_Studio } else { - if (UnityStudio.assetsfileandstream.TryGetValue(resourceFileName, out var reader)) + if (UnityStudio.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader)) { reader.Position = m_Offset; m_AudioData = reader.ReadBytes((int)m_Size); diff --git a/Unity Studio/Unity Classes/BuildSettings.cs b/Unity Studio/Unity Classes/BuildSettings.cs index ffd7d5a..10def65 100644 --- a/Unity Studio/Unity Classes/BuildSettings.cs +++ b/Unity Studio/Unity Classes/BuildSettings.cs @@ -12,7 +12,7 @@ namespace Unity_Studio public BuildSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; int levels = a_Stream.ReadInt32(); diff --git a/Unity Studio/Unity Classes/Font.cs b/Unity Studio/Unity Classes/Font.cs index 618d0ce..e03ed5b 100644 --- a/Unity Studio/Unity Classes/Font.cs +++ b/Unity Studio/Unity Classes/Font.cs @@ -13,7 +13,7 @@ namespace Unity_Studio public unityFont(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/GameObject.cs b/Unity Studio/Unity Classes/GameObject.cs index 2749025..cb04981 100644 --- a/Unity Studio/Unity Classes/GameObject.cs +++ b/Unity Studio/Unity Classes/GameObject.cs @@ -25,7 +25,7 @@ namespace Unity_Studio if (preloadData != null) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; uniqueID = preloadData.uniqueID; diff --git a/Unity Studio/Unity Classes/Material.cs b/Unity Studio/Unity Classes/Material.cs index c1d1772..39c3785 100644 --- a/Unity Studio/Unity Classes/Material.cs +++ b/Unity Studio/Unity Classes/Material.cs @@ -19,7 +19,7 @@ namespace Unity_Studio public Material(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/Mesh.cs b/Unity Studio/Unity Classes/Mesh.cs index 99b2fda..0d7c189 100644 --- a/Unity Studio/Unity Classes/Mesh.cs +++ b/Unity Studio/Unity Classes/Mesh.cs @@ -331,7 +331,7 @@ namespace Unity_Studio //Stream = new EndianStream(File.OpenRead(sourceFile.filePath), sourceFile.endianType); //Stream.endian = sourceFile.endianType; var version = MeshPD.sourceFile.version; - a_Stream = MeshPD.sourceFile.a_Stream; + a_Stream = MeshPD.sourceFile.assetsFileReader; a_Stream.Position = MeshPD.Offset; bool m_Use16BitIndices = true; //3.5.0 and newer always uses 16bit indices uint m_MeshCompression = 0; diff --git a/Unity Studio/Unity Classes/MeshFilter.cs b/Unity Studio/Unity Classes/MeshFilter.cs index d5013fd..e1c181a 100644 --- a/Unity Studio/Unity Classes/MeshFilter.cs +++ b/Unity Studio/Unity Classes/MeshFilter.cs @@ -14,7 +14,7 @@ namespace Unity_Studio public MeshFilter(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/MeshRenderer.cs b/Unity Studio/Unity Classes/MeshRenderer.cs index 7535ca9..2c6ea9b 100644 --- a/Unity Studio/Unity Classes/MeshRenderer.cs +++ b/Unity Studio/Unity Classes/MeshRenderer.cs @@ -18,7 +18,7 @@ namespace Unity_Studio public MeshRenderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/MonoBehaviour.cs b/Unity Studio/Unity Classes/MonoBehaviour.cs index 9bca93f..34fcfe7 100644 --- a/Unity Studio/Unity Classes/MonoBehaviour.cs +++ b/Unity Studio/Unity Classes/MonoBehaviour.cs @@ -12,7 +12,7 @@ namespace Unity_Studio public MonoBehaviour(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; var m_GameObject = sourceFile.ReadPPtr(); diff --git a/Unity Studio/Unity Classes/MovieTexture.cs b/Unity Studio/Unity Classes/MovieTexture.cs index da1de63..1ff4390 100644 --- a/Unity Studio/Unity Classes/MovieTexture.cs +++ b/Unity Studio/Unity Classes/MovieTexture.cs @@ -13,7 +13,7 @@ namespace Unity_Studio public MovieTexture(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); diff --git a/Unity Studio/Unity Classes/PlayerSettings.cs b/Unity Studio/Unity Classes/PlayerSettings.cs index 1ce44cf..0e3d6bc 100644 --- a/Unity Studio/Unity Classes/PlayerSettings.cs +++ b/Unity Studio/Unity Classes/PlayerSettings.cs @@ -13,7 +13,7 @@ namespace Unity_Studio public PlayerSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; diff --git a/Unity Studio/Unity Classes/Shader.cs b/Unity Studio/Unity Classes/Shader.cs index b8fc0c2..7d4b540 100644 --- a/Unity Studio/Unity Classes/Shader.cs +++ b/Unity Studio/Unity Classes/Shader.cs @@ -16,7 +16,7 @@ namespace Unity_Studio public Shader(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/SkinnedMeshRenderer.cs b/Unity Studio/Unity Classes/SkinnedMeshRenderer.cs index f9ed968..3a0e4ce 100644 --- a/Unity Studio/Unity Classes/SkinnedMeshRenderer.cs +++ b/Unity Studio/Unity Classes/SkinnedMeshRenderer.cs @@ -21,7 +21,7 @@ namespace Unity_Studio { var sourceFile = preloadData.sourceFile; var version = preloadData.sourceFile.version; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/Sprite.cs b/Unity Studio/Unity Classes/Sprite.cs index 0be2568..83d5d9e 100644 --- a/Unity Studio/Unity Classes/Sprite.cs +++ b/Unity Studio/Unity Classes/Sprite.cs @@ -9,54 +9,61 @@ namespace Unity_Studio class Sprite { public string m_Name; + public RectangleF m_Rect; + public float m_PixelsToUnits; + public PointF m_Pivot; + public Guid first; public PPtr texture; public PPtr m_SpriteAtlas; public RectangleF textureRect; + public PointF[][] m_PhysicsShape; public Sprite(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; - a_Stream.Position = preloadData.Offset; + var reader = preloadData.sourceFile.assetsFileReader; + reader.Position = preloadData.Offset; + var version = sourceFile.version; - m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); + m_Name = reader.ReadAlignedString(reader.ReadInt32()); if (readSwitch) { //Rectf m_Rect - var m_Rect = new RectangleF(a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle()); + m_Rect = new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); //Vector2f m_Offset - a_Stream.Position += 8; - if (sourceFile.version[0] > 4 || (sourceFile.version[0] == 4 && sourceFile.version[1] >= 2)) //4.2 and up + reader.Position += 8; + if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up { //Vector4f m_Border - a_Stream.Position += 16; + reader.Position += 16; } - var m_PixelsToUnits = a_Stream.ReadSingle(); - if (sourceFile.version[0] > 5 - || (sourceFile.version[0] == 5 && sourceFile.version[1] > 4) - || (sourceFile.version[0] == 5 && sourceFile.version[1] == 4 && sourceFile.version[2] >= 2)) //5.4.2 and up + m_PixelsToUnits = reader.ReadSingle(); + if (version[0] > 5 + || (version[0] == 5 && version[1] > 4) + || (version[0] == 5 && version[1] == 4 && version[2] >= 2)) //5.4.2 and up { //Vector2f m_Pivot - a_Stream.Position += 8; + m_Pivot = new PointF(reader.ReadSingle(), reader.ReadSingle()); } - var m_Extrude = a_Stream.ReadUInt32(); - if (sourceFile.version[0] > 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3)) //5.3 and up TODO need more test + var m_Extrude = reader.ReadUInt32(); + if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up TODO need more test { - var m_IsPolygon = a_Stream.ReadBoolean(); - a_Stream.AlignStream(4); + var m_IsPolygon = reader.ReadBoolean(); + reader.AlignStream(4); } - if (sourceFile.version[0] >= 2017) //2017 and up + if (version[0] >= 2017) //2017 and up { //pair m_RenderDataKey - a_Stream.Position += 24; + first = new Guid(reader.ReadBytes(16)); + var second = reader.ReadInt64(); //vector m_AtlasTags - var size = a_Stream.ReadInt32(); + var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { - var data = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); + var data = reader.ReadAlignedString(reader.ReadInt32()); } //PPtr m_SpriteAtlas @@ -67,66 +74,92 @@ namespace Unity_Studio // PPtr texture texture = sourceFile.ReadPPtr(); // PPtr alphaTexture - if (sourceFile.version[0] >= 5) //5.0 and up + if (version[0] >= 5) //5.0 and up { var alphaTexture = sourceFile.ReadPPtr(); } - if (sourceFile.version[0] > 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] >= 6)) //5.6 and up + if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up { // vector m_SubMeshes - var size = a_Stream.ReadInt32(); + var size = reader.ReadInt32(); // SubMesh data - if (sourceFile.version[0] > 2017 || (sourceFile.version[0] == 2017 && sourceFile.version[1] >= 3)) //2017.3 and up + if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up { - a_Stream.Position += 48 * size; + reader.Position += 48 * size; } else { - a_Stream.Position += 44 * size; + reader.Position += 44 * size; } // vector m_IndexBuffer - size = a_Stream.ReadInt32(); - a_Stream.Position += size; //UInt8 data - a_Stream.AlignStream(4); + size = reader.ReadInt32(); + reader.Position += size; //UInt8 data + reader.AlignStream(4); // VertexData m_VertexData - var m_CurrentChannels = a_Stream.ReadInt32(); - var m_VertexCount = a_Stream.ReadUInt32(); + var m_CurrentChannels = reader.ReadInt32(); + var m_VertexCount = reader.ReadUInt32(); // vector m_Channels - size = a_Stream.ReadInt32(); - a_Stream.Position += size * 4; //ChannelInfo data + size = reader.ReadInt32(); + reader.Position += size * 4; //ChannelInfo data // TypelessData m_DataSize - size = a_Stream.ReadInt32(); - a_Stream.Position += size; //UInt8 data - a_Stream.AlignStream(4); + size = reader.ReadInt32(); + reader.Position += size; //UInt8 data + reader.AlignStream(4); } else { // vector vertices - var size = a_Stream.ReadInt32(); + var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { //SpriteVertex data - a_Stream.Position += 12; //Vector3f pos - if (sourceFile.version[0] < 4 || (sourceFile.version[0] == 4 && sourceFile.version[1] <= 3)) //4.3 and down - a_Stream.Position += 8; //Vector2f uv + reader.Position += 12; //Vector3f pos + if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down + reader.Position += 8; //Vector2f uv } // vector indices - size = a_Stream.ReadInt32(); - a_Stream.Position += 2 * size; //UInt16 data - a_Stream.AlignStream(4); + size = reader.ReadInt32(); + reader.Position += 2 * size; //UInt16 data + reader.AlignStream(4); } // Rectf textureRect - textureRect = new RectangleF(a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle()); + textureRect = new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); // Vector2f textureRectOffset + reader.Position += 8; // Vector2f atlasRectOffset - 5.6 and up + if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up + { + reader.Position += 8; + } // unsigned int settingsRaw + reader.Position += 4; // Vector4f uvTransform - 4.5 and up - // float downscaleMultiplier - 2017 and up - //vector m_PhysicsShape - 2017 and up + if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up + { + reader.Position += 16; + } + if (version[0] >= 2017) //2017 and up + { + // float downscaleMultiplier - 2017 and up + reader.Position += 4; + //vector m_PhysicsShape - 2017 and up + var m_PhysicsShape_size = reader.ReadInt32(); + m_PhysicsShape = new PointF[m_PhysicsShape_size][]; + for (int i = 0; i < m_PhysicsShape_size; i++) + { + var data_size = reader.ReadInt32(); + //Vector2f + m_PhysicsShape[i] = new PointF[data_size]; + for (int j = 0; j < data_size; j++) + { + m_PhysicsShape[i][j] = new PointF(reader.ReadSingle(), reader.ReadSingle()); + } + } + } } else { diff --git a/Unity Studio/Unity Classes/SpriteAtlas.cs b/Unity Studio/Unity Classes/SpriteAtlas.cs index 5e0f782..66c1fde 100644 --- a/Unity Studio/Unity Classes/SpriteAtlas.cs +++ b/Unity Studio/Unity Classes/SpriteAtlas.cs @@ -8,55 +8,56 @@ namespace Unity_Studio { class SpriteAtlas { - public List m_PackedSprites = new List(); public List textures = new List(); public List textureRects = new List(); + public List guids = new List(); public SpriteAtlas(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; - a_Stream.Position = preloadData.Offset; + var reader = preloadData.sourceFile.assetsFileReader; + reader.Position = preloadData.Offset; - var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); + var m_Name = reader.ReadAlignedString(reader.ReadInt32()); //vector m_PackedSprites - var size = a_Stream.ReadInt32(); + var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { //PPtr data - m_PackedSprites.Add(sourceFile.ReadPPtr()); + sourceFile.ReadPPtr(); } //vector m_PackedSpriteNamesToIndex - size = a_Stream.ReadInt32(); + size = reader.ReadInt32(); for (int i = 0; i < size; i++) { - var data = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); + var data = reader.ReadAlignedString(reader.ReadInt32()); } //map m_RenderDataMap - size = a_Stream.ReadInt32(); + size = reader.ReadInt32(); for (int i = 0; i < size; i++) { //pair first - a_Stream.Position += 24; + guids.Add(new Guid(reader.ReadBytes(16))); + var second = reader.ReadInt64(); //SpriteAtlasData second // PPtr texture textures.Add(sourceFile.ReadPPtr()); // PPtr alphaTexture var alphaTexture = sourceFile.ReadPPtr(); // Rectf textureRect - textureRects.Add(new RectangleF(a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle())); + textureRects.Add(new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); // Vector2f textureRectOffset - a_Stream.Position += 8; + reader.Position += 8; if (sourceFile.version[0] > 2017 || (sourceFile.version[0] == 2017 && sourceFile.version[1] >= 2))//2017.2 and up { // Vector2f atlasRectOffset - a_Stream.Position += 8; + reader.Position += 8; } // Vector4f uvTransform // float downscaleMultiplier // unsigned int settingsRaw - a_Stream.Position += 24; + reader.Position += 24; } //string m_Tag //bool m_IsVariant diff --git a/Unity Studio/Unity Classes/TextAsset.cs b/Unity Studio/Unity Classes/TextAsset.cs index cab8af9..fe9023a 100644 --- a/Unity Studio/Unity Classes/TextAsset.cs +++ b/Unity Studio/Unity Classes/TextAsset.cs @@ -14,7 +14,7 @@ namespace Unity_Studio public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/Texture2D.cs b/Unity Studio/Unity Classes/Texture2D.cs index b4a6831..5360b47 100644 --- a/Unity Studio/Unity Classes/Texture2D.cs +++ b/Unity Studio/Unity Classes/Texture2D.cs @@ -91,7 +91,7 @@ namespace Unity_Studio public Texture2D(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; version = sourceFile.version; @@ -171,7 +171,10 @@ namespace Unity_Studio if (!File.Exists(resourceFilePath)) { var findFiles = Directory.GetFiles(Path.GetDirectoryName(sourceFile.filePath), resourceFileName, SearchOption.AllDirectories); - if (findFiles.Length > 0) { resourceFilePath = findFiles[0]; } + if (findFiles.Length > 0) + { + resourceFilePath = findFiles[0]; + } } if (File.Exists(resourceFilePath)) { @@ -183,7 +186,7 @@ namespace Unity_Studio } else { - if (UnityStudio.assetsfileandstream.TryGetValue(resourceFileName, out var reader)) + if (UnityStudio.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader)) { reader.Position = offset; image_data = reader.ReadBytes(image_data_size); diff --git a/Unity Studio/Unity Classes/Transform.cs b/Unity Studio/Unity Classes/Transform.cs index acb5f4b..b30ec2a 100644 --- a/Unity Studio/Unity Classes/Transform.cs +++ b/Unity Studio/Unity Classes/Transform.cs @@ -17,7 +17,7 @@ namespace Unity_Studio public Transform(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) diff --git a/Unity Studio/Unity Classes/VideoClip.cs b/Unity Studio/Unity Classes/VideoClip.cs index b925314..32da4a2 100644 --- a/Unity Studio/Unity Classes/VideoClip.cs +++ b/Unity Studio/Unity Classes/VideoClip.cs @@ -15,7 +15,7 @@ namespace Unity_Studio public VideoClip(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; - var a_Stream = preloadData.sourceFile.a_Stream; + var a_Stream = preloadData.sourceFile.assetsFileReader; a_Stream.Position = preloadData.Offset; m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); @@ -47,38 +47,49 @@ namespace Unity_Studio } //StreamedResource m_ExternalResources var m_Source = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); - if (m_Source != "") - m_Source = Path.Combine(Path.GetDirectoryName(sourceFile.filePath), m_Source.Replace("archive:/", "")); var m_Offset = a_Stream.ReadUInt64(); var m_Size = a_Stream.ReadUInt64(); var m_HasSplitAlpha = a_Stream.ReadBoolean(); if (readSwitch) { - if (string.IsNullOrEmpty(m_Source)) + if (!string.IsNullOrEmpty(m_Source)) { - if (m_Size > 0) - m_VideoData = a_Stream.ReadBytes((int)m_Size); - } - else if (File.Exists(m_Source) || File.Exists(m_Source = Path.Combine(Path.GetDirectoryName(sourceFile.filePath), Path.GetFileName(m_Source)))) - { - using (var reader = new BinaryReader(File.OpenRead(m_Source))) + var resourceFileName = Path.GetFileName(m_Source); + var resourceFilePath = Path.GetDirectoryName(sourceFile.filePath) + "\\" + resourceFileName; + if (!File.Exists(resourceFilePath)) { - reader.BaseStream.Position = (long)m_Offset; - m_VideoData = reader.ReadBytes((int)m_Size); + var findFiles = Directory.GetFiles(Path.GetDirectoryName(sourceFile.filePath), resourceFileName, SearchOption.AllDirectories); + if (findFiles.Length > 0) + { + resourceFilePath = findFiles[0]; + } + } + if (File.Exists(resourceFilePath)) + { + using (var reader = new BinaryReader(File.OpenRead(resourceFilePath))) + { + reader.BaseStream.Position = (long)m_Offset; + m_VideoData = reader.ReadBytes((int)m_Size); + } + } + else + { + if (UnityStudio.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader)) + { + reader.Position = (long)m_Offset; + m_VideoData = reader.ReadBytes((int)m_Size); + } + else + { + MessageBox.Show($"can't find the resource file {resourceFileName}"); + } } } else { - if (UnityStudio.assetsfileandstream.TryGetValue(Path.GetFileName(m_Source), out var reader)) - { - reader.Position = (long)m_Offset; - m_VideoData = reader.ReadBytes((int)m_Size); - } - else - { - MessageBox.Show($"can't find the resource file {Path.GetFileName(m_Source)}"); - } + if (m_Size > 0) + m_VideoData = a_Stream.ReadBytes((int)m_Size); } } else diff --git a/Unity Studio/Unity Studio Classes/AssetsFile.cs b/Unity Studio/Unity Studio Classes/AssetsFile.cs index fb91b1a..7b9b456 100644 --- a/Unity Studio/Unity Studio Classes/AssetsFile.cs +++ b/Unity Studio/Unity Studio Classes/AssetsFile.cs @@ -10,10 +10,11 @@ namespace Unity_Studio { public class AssetsFile { - public EndianBinaryReader a_Stream; + public EndianBinaryReader assetsFileReader; public string filePath; public string bundlePath; public string fileName; + public string upperFileName; public int fileGen; public bool valid; public string m_Version = "2.5.0f5"; @@ -144,52 +145,53 @@ namespace Unity_Studio public class UnityShared { - public int Index = -1; //actual index in main list + public int Index = -2; //-2 - Prepare, -1 - Missing public string aName = ""; public string fileName = ""; } - public AssetsFile(string fullName, EndianBinaryReader fileStream) + public AssetsFile(string fullName, EndianBinaryReader reader) { - a_Stream = fileStream; + assetsFileReader = reader; filePath = fullName; fileName = Path.GetFileName(fullName); + upperFileName = fileName.ToUpper(); try { - int tableSize = a_Stream.ReadInt32(); - int dataEnd = a_Stream.ReadInt32(); - fileGen = a_Stream.ReadInt32(); - uint dataOffset = a_Stream.ReadUInt32(); + int tableSize = assetsFileReader.ReadInt32(); + int dataEnd = assetsFileReader.ReadInt32(); + fileGen = assetsFileReader.ReadInt32(); + uint dataOffset = assetsFileReader.ReadUInt32(); sharedAssetsList[0].fileName = Path.GetFileName(fullName); //reference itself because sharedFileIDs start from 1 switch (fileGen) { case 6: //2.5.0 - 2.6.1 { - a_Stream.Position = (dataEnd - tableSize); - a_Stream.Position += 1; + assetsFileReader.Position = (dataEnd - tableSize); + assetsFileReader.Position += 1; break; } case 7: //3.0.0 beta { - a_Stream.Position = (dataEnd - tableSize); - a_Stream.Position += 1; - m_Version = a_Stream.ReadStringToNull(); + assetsFileReader.Position = (dataEnd - tableSize); + assetsFileReader.Position += 1; + m_Version = assetsFileReader.ReadStringToNull(); break; } case 8: //3.0.0 - 3.4.2 { - a_Stream.Position = (dataEnd - tableSize); - a_Stream.Position += 1; - m_Version = a_Stream.ReadStringToNull(); - platform = a_Stream.ReadInt32(); + assetsFileReader.Position = (dataEnd - tableSize); + assetsFileReader.Position += 1; + m_Version = assetsFileReader.ReadStringToNull(); + platform = assetsFileReader.ReadInt32(); break; } case 9: //3.5.0 - 4.6.x { - a_Stream.Position += 4; //azero - m_Version = a_Stream.ReadStringToNull(); - platform = a_Stream.ReadInt32(); + assetsFileReader.Position += 4; //azero + m_Version = assetsFileReader.ReadStringToNull(); + platform = assetsFileReader.ReadInt32(); break; } case 14: //5.0.0 beta and final @@ -197,10 +199,10 @@ namespace Unity_Studio case 16: //??.. no sure case 17: //5.5.0 and up { - a_Stream.Position += 4; //azero - m_Version = a_Stream.ReadStringToNull(); - platform = a_Stream.ReadInt32(); - baseDefinitions = a_Stream.ReadBoolean(); + assetsFileReader.Position += 4; //azero + m_Version = assetsFileReader.ReadStringToNull(); + platform = assetsFileReader.ReadInt32(); + baseDefinitions = assetsFileReader.ReadBoolean(); break; } default: @@ -215,7 +217,7 @@ namespace Unity_Studio byte[] b32 = BitConverter.GetBytes(platform); Array.Reverse(b32); platform = BitConverter.ToInt32(b32, 0); - a_Stream.endian = EndianType.LittleEndian; + assetsFileReader.endian = EndianType.LittleEndian; } switch (platform) @@ -267,16 +269,16 @@ namespace Unity_Studio break; } - int baseCount = a_Stream.ReadInt32(); + int baseCount = assetsFileReader.ReadInt32(); for (int i = 0; i < baseCount; i++) { if (fileGen < 14) { - int classID = a_Stream.ReadInt32(); - string baseType = a_Stream.ReadStringToNull(); - string baseName = a_Stream.ReadStringToNull(); - a_Stream.Position += 20; - int memberCount = a_Stream.ReadInt32(); + int classID = assetsFileReader.ReadInt32(); + string baseType = assetsFileReader.ReadStringToNull(); + string baseName = assetsFileReader.ReadStringToNull(); + assetsFileReader.Position += 20; + int memberCount = assetsFileReader.ReadInt32(); var cb = new List(); for (int m = 0; m < memberCount; m++) @@ -296,10 +298,10 @@ namespace Unity_Studio if (fileGen >= 7 && fileGen < 14) { - a_Stream.Position += 4; //azero + assetsFileReader.Position += 4; //azero } - int assetCount = a_Stream.ReadInt32(); + int assetCount = assetsFileReader.ReadInt32(); #region asset preload table string assetIDfmt = "D" + assetCount.ToString().Length; //format for unique ID @@ -309,29 +311,29 @@ namespace Unity_Studio //each table entry is aligned individually, not the whole table if (fileGen >= 14) { - a_Stream.AlignStream(4); + assetsFileReader.AlignStream(4); } AssetPreloadData asset = new AssetPreloadData(); - asset.m_PathID = fileGen < 14 ? a_Stream.ReadInt32() : a_Stream.ReadInt64(); - asset.Offset = a_Stream.ReadUInt32(); + asset.m_PathID = fileGen < 14 ? assetsFileReader.ReadInt32() : assetsFileReader.ReadInt64(); + asset.Offset = assetsFileReader.ReadUInt32(); asset.Offset += dataOffset; - asset.Size = a_Stream.ReadInt32(); + asset.Size = assetsFileReader.ReadInt32(); if (fileGen > 15) { - int index = a_Stream.ReadInt32(); + int index = assetsFileReader.ReadInt32(); asset.Type1 = classIDs[index][0]; asset.Type2 = classIDs[index][1]; } else { - asset.Type1 = a_Stream.ReadInt32(); - asset.Type2 = a_Stream.ReadUInt16(); - a_Stream.Position += 2; + asset.Type1 = assetsFileReader.ReadInt32(); + asset.Type2 = assetsFileReader.ReadUInt16(); + assetsFileReader.Position += 2; } if (fileGen == 15) { - byte unknownByte = a_Stream.ReadByte(); + byte unknownByte = assetsFileReader.ReadByte(); //this is a single byte, not an int32 //the next entry is aligned after this //but not the last! @@ -356,12 +358,12 @@ namespace Unity_Studio #region read BuildSettings to get version for unity 2.x files if (asset.Type2 == 141 && fileGen == 6) { - long nextAsset = a_Stream.Position; + long nextAsset = assetsFileReader.Position; BuildSettings BSettings = new BuildSettings(asset); m_Version = BSettings.m_Version; - a_Stream.Position = nextAsset; + assetsFileReader.Position = nextAsset; } #endregion } @@ -380,22 +382,22 @@ namespace Unity_Studio if (fileGen >= 14) { //this looks like a list of assets that need to be preloaded in memory before anytihng else - int someCount = a_Stream.ReadInt32(); + int someCount = assetsFileReader.ReadInt32(); for (int i = 0; i < someCount; i++) { - int num1 = a_Stream.ReadInt32(); - a_Stream.AlignStream(4); - long m_PathID = a_Stream.ReadInt64(); + int num1 = assetsFileReader.ReadInt32(); + assetsFileReader.AlignStream(4); + long m_PathID = assetsFileReader.ReadInt64(); } } - int sharedFileCount = a_Stream.ReadInt32(); + int sharedFileCount = assetsFileReader.ReadInt32(); for (int i = 0; i < sharedFileCount; i++) { var shared = new UnityShared(); - shared.aName = a_Stream.ReadStringToNull(); - a_Stream.Position += 20; - var sharedFilePath = a_Stream.ReadStringToNull(); //relative path + shared.aName = assetsFileReader.ReadStringToNull(); + assetsFileReader.Position += 20; + var sharedFilePath = assetsFileReader.ReadStringToNull(); //relative path shared.fileName = Path.GetFileName(sharedFilePath); sharedAssetsList.Add(shared); } @@ -408,14 +410,14 @@ namespace Unity_Studio private void readBase(List cb, int level) { - string varType = a_Stream.ReadStringToNull(); - string varName = a_Stream.ReadStringToNull(); - int size = a_Stream.ReadInt32(); - int index = a_Stream.ReadInt32(); - int isArray = a_Stream.ReadInt32(); - int num0 = a_Stream.ReadInt32(); - int flag = a_Stream.ReadInt32(); - int childrenCount = a_Stream.ReadInt32(); + string varType = assetsFileReader.ReadStringToNull(); + string varName = assetsFileReader.ReadStringToNull(); + int size = assetsFileReader.ReadInt32(); + int index = assetsFileReader.ReadInt32(); + int isArray = assetsFileReader.ReadInt32(); + int num0 = assetsFileReader.ReadInt32(); + int flag = assetsFileReader.ReadInt32(); + int childrenCount = assetsFileReader.ReadInt32(); cb.Add(new ClassMember { @@ -430,12 +432,12 @@ namespace Unity_Studio private void readBase5() { - int classID = a_Stream.ReadInt32(); + int classID = assetsFileReader.ReadInt32(); if (fileGen > 15)//5.5.0 and up { - a_Stream.ReadByte(); + assetsFileReader.ReadByte(); int type1; - if ((type1 = a_Stream.ReadInt16()) >= 0) + if ((type1 = assetsFileReader.ReadInt16()) >= 0) { type1 = -1 - type1; } @@ -446,35 +448,35 @@ namespace Unity_Studio classIDs.Add(new[] { type1, classID }); if (classID == 114) { - a_Stream.Position += 16; + assetsFileReader.Position += 16; } classID = type1; } else if (classID < 0) { - a_Stream.Position += 16; + assetsFileReader.Position += 16; } - a_Stream.Position += 16; + assetsFileReader.Position += 16; if (baseDefinitions) { - int varCount = a_Stream.ReadInt32(); - int stringSize = a_Stream.ReadInt32(); + int varCount = assetsFileReader.ReadInt32(); + int stringSize = assetsFileReader.ReadInt32(); - a_Stream.Position += varCount * 24; - var stringReader = new EndianBinaryReader(new MemoryStream(a_Stream.ReadBytes(stringSize))); + assetsFileReader.Position += varCount * 24; + var stringReader = new EndianBinaryReader(new MemoryStream(assetsFileReader.ReadBytes(stringSize))); string className = ""; var classVar = new List(); //build Class Structures - a_Stream.Position -= varCount * 24 + stringSize; + assetsFileReader.Position -= varCount * 24 + stringSize; for (int i = 0; i < varCount; i++) { - ushort num0 = a_Stream.ReadUInt16(); - byte level = a_Stream.ReadByte(); - bool isArray = a_Stream.ReadBoolean(); + ushort num0 = assetsFileReader.ReadUInt16(); + byte level = assetsFileReader.ReadByte(); + bool isArray = assetsFileReader.ReadBoolean(); - ushort varTypeIndex = a_Stream.ReadUInt16(); - ushort test = a_Stream.ReadUInt16(); + ushort varTypeIndex = assetsFileReader.ReadUInt16(); + ushort test = assetsFileReader.ReadUInt16(); string varTypeStr; if (test == 0) //varType is an offset in the string block { @@ -486,8 +488,8 @@ namespace Unity_Studio varTypeStr = baseStrings.ContainsKey(varTypeIndex) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); } - ushort varNameIndex = a_Stream.ReadUInt16(); - test = a_Stream.ReadUInt16(); + ushort varNameIndex = assetsFileReader.ReadUInt16(); + test = assetsFileReader.ReadUInt16(); string varNameStr; if (test == 0) { @@ -499,9 +501,9 @@ namespace Unity_Studio varNameStr = baseStrings.ContainsKey(varNameIndex) ? baseStrings[varNameIndex] : varNameIndex.ToString(); } - int size = a_Stream.ReadInt32(); - int index = a_Stream.ReadInt32(); - int flag = a_Stream.ReadInt32(); + int size = assetsFileReader.ReadInt32(); + int index = assetsFileReader.ReadInt32(); + int flag = assetsFileReader.ReadInt32(); if (index == 0) { className = varTypeStr + " " + varNameStr; } else @@ -517,7 +519,7 @@ namespace Unity_Studio } } stringReader.Dispose(); - a_Stream.Position += stringSize; + assetsFileReader.Position += stringSize; var aClass = new ClassStruct { ID = classID, Text = className, members = classVar }; aClass.SubItems.Add(classID.ToString()); diff --git a/Unity Studio/Unity Studio Classes/BundleFile.cs b/Unity Studio/Unity Studio Classes/BundleFile.cs index b868752..e07d5b2 100644 --- a/Unity Studio/Unity Studio Classes/BundleFile.cs +++ b/Unity Studio/Unity Studio Classes/BundleFile.cs @@ -18,148 +18,113 @@ namespace Unity_Studio public MemoryStream memStream; } - public BundleFile(string fileName) + + public BundleFile(EndianBinaryReader bundleReader) { - if (Path.GetExtension(fileName) == ".lz4") - { - byte[] filebuffer; - - using (BinaryReader lz4Stream = new BinaryReader(File.OpenRead(fileName))) - { - int version = lz4Stream.ReadInt32(); - int uncompressedSize = lz4Stream.ReadInt32(); - int compressedSize = lz4Stream.ReadInt32(); - int something = lz4Stream.ReadInt32(); //1 - - var lz4buffer = lz4Stream.ReadBytes(compressedSize); - using (var inputStream = new MemoryStream(lz4buffer)) - { - var decoder = new Lz4DecoderStream(inputStream); - filebuffer = new byte[uncompressedSize]; - decoder.Read(filebuffer, 0, uncompressedSize); - decoder.Dispose(); - } - } - using (var b_Stream = new EndianBinaryReader(new MemoryStream(filebuffer))) - { - readBundle(b_Stream); - } - } - else - { - using (var b_Stream = new EndianBinaryReader(File.OpenRead(fileName))) - { - readBundle(b_Stream); - } - } - } - - private void readBundle(EndianBinaryReader b_Stream) - { - var signature = b_Stream.ReadStringToNull(); + var signature = bundleReader.ReadStringToNull(); switch (signature) { case "UnityWeb": case "UnityRaw": case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": { - format = b_Stream.ReadInt32(); - versionPlayer = b_Stream.ReadStringToNull(); - versionEngine = b_Stream.ReadStringToNull(); + format = bundleReader.ReadInt32(); + versionPlayer = bundleReader.ReadStringToNull(); + versionEngine = bundleReader.ReadStringToNull(); if (format < 6) { - int bundleSize = b_Stream.ReadInt32(); + int bundleSize = bundleReader.ReadInt32(); } else if (format == 6) { - ReadFormat6(b_Stream, true); + ReadFormat6(bundleReader, true); return; } - short dummy2 = b_Stream.ReadInt16(); - int offset = b_Stream.ReadInt16(); - int dummy3 = b_Stream.ReadInt32(); - int lzmaChunks = b_Stream.ReadInt32(); + short dummy2 = bundleReader.ReadInt16(); + int offset = bundleReader.ReadInt16(); + int dummy3 = bundleReader.ReadInt32(); + int lzmaChunks = bundleReader.ReadInt32(); int lzmaSize = 0; long streamSize = 0; for (int i = 0; i < lzmaChunks; i++) { - lzmaSize = b_Stream.ReadInt32(); - streamSize = b_Stream.ReadInt32(); + lzmaSize = bundleReader.ReadInt32(); + streamSize = bundleReader.ReadInt32(); } - b_Stream.Position = offset; + bundleReader.Position = offset; switch (signature) { case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": //.bytes case "UnityWeb": { - var lzmaBuffer = b_Stream.ReadBytes(lzmaSize); + var lzmaBuffer = bundleReader.ReadBytes(lzmaSize); using (var lzmaStream = new EndianBinaryReader(SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer)))) { - getFiles(lzmaStream, 0); + GetAssetsFiles(lzmaStream, 0); } break; } case "UnityRaw": { - getFiles(b_Stream, offset); + GetAssetsFiles(bundleReader, offset); break; } } break; } case "UnityFS": - format = b_Stream.ReadInt32(); - versionPlayer = b_Stream.ReadStringToNull(); - versionEngine = b_Stream.ReadStringToNull(); + format = bundleReader.ReadInt32(); + versionPlayer = bundleReader.ReadStringToNull(); + versionEngine = bundleReader.ReadStringToNull(); if (format == 6) { - ReadFormat6(b_Stream); + ReadFormat6(bundleReader); } break; } } - private void getFiles(EndianBinaryReader f_Stream, int offset) + private void GetAssetsFiles(EndianBinaryReader reader, int offset) { - int fileCount = f_Stream.ReadInt32(); + int fileCount = reader.ReadInt32(); for (int i = 0; i < fileCount; i++) { var memFile = new MemoryAssetsFile(); - memFile.fileName = f_Stream.ReadStringToNull(); - int fileOffset = f_Stream.ReadInt32(); + memFile.fileName = reader.ReadStringToNull(); + int fileOffset = reader.ReadInt32(); fileOffset += offset; - int fileSize = f_Stream.ReadInt32(); - long nextFile = f_Stream.Position; - f_Stream.Position = fileOffset; - var buffer = f_Stream.ReadBytes(fileSize); + int fileSize = reader.ReadInt32(); + long nextFile = reader.Position; + reader.Position = fileOffset; + var buffer = reader.ReadBytes(fileSize); memFile.memStream = new MemoryStream(buffer); MemoryAssetsFileList.Add(memFile); - f_Stream.Position = nextFile; + reader.Position = nextFile; } } - private void ReadFormat6(EndianBinaryReader b_Stream, bool padding = false) + private void ReadFormat6(EndianBinaryReader bundleReader, bool padding = false) { - var bundleSize = b_Stream.ReadInt64(); - int compressedSize = b_Stream.ReadInt32(); - int uncompressedSize = b_Stream.ReadInt32(); - int flag = b_Stream.ReadInt32(); + var bundleSize = bundleReader.ReadInt64(); + int compressedSize = bundleReader.ReadInt32(); + int uncompressedSize = bundleReader.ReadInt32(); + int flag = bundleReader.ReadInt32(); if (padding) - b_Stream.ReadByte(); + bundleReader.ReadByte(); byte[] blocksInfoBytes; if ((flag & 0x80) != 0)//at end of file { - var position = b_Stream.Position; - b_Stream.Position = b_Stream.BaseStream.Length - compressedSize; - blocksInfoBytes = b_Stream.ReadBytes(compressedSize); - b_Stream.Position = position; + var position = bundleReader.Position; + bundleReader.Position = bundleReader.BaseStream.Length - compressedSize; + blocksInfoBytes = bundleReader.ReadBytes(compressedSize); + bundleReader.Position = position; } else { - blocksInfoBytes = b_Stream.ReadBytes(compressedSize); + blocksInfoBytes = bundleReader.ReadBytes(compressedSize); } MemoryStream blocksInfoStream; switch (flag & 0x3F) @@ -199,7 +164,7 @@ namespace Unity_Studio uncompressedSize = blocksInfo.ReadInt32(); compressedSize = blocksInfo.ReadInt32(); flag = blocksInfo.ReadInt16(); - var compressedBytes = b_Stream.ReadBytes(compressedSize); + var compressedBytes = bundleReader.ReadBytes(compressedSize); switch (flag & 0x3F) { default://None @@ -235,7 +200,7 @@ namespace Unity_Studio //case 4:LZHAM? } } - using (var assetsData = new EndianBinaryReader(assetsDataStream)) + using (var assetsDataReader = new EndianBinaryReader(assetsDataStream)) { var entryinfo_count = blocksInfo.ReadInt32(); for (int i = 0; i < entryinfo_count; i++) @@ -243,10 +208,10 @@ namespace Unity_Studio var memFile = new MemoryAssetsFile(); var entryinfo_offset = blocksInfo.ReadInt64(); var entryinfo_size = blocksInfo.ReadInt64(); - var unknown = blocksInfo.ReadInt32(); + flag = blocksInfo.ReadInt32(); memFile.fileName = blocksInfo.ReadStringToNull(); - assetsData.Position = entryinfo_offset; - var buffer = assetsData.ReadBytes((int)entryinfo_size); + assetsDataReader.Position = entryinfo_offset; + var buffer = assetsDataReader.ReadBytes((int)entryinfo_size); memFile.memStream = new MemoryStream(buffer); MemoryAssetsFileList.Add(memFile); } diff --git a/Unity Studio/Unity Studio Classes/ClassStruct.cs b/Unity Studio/Unity Studio Classes/ClassStruct.cs index 11b2b7c..68bac55 100644 --- a/Unity Studio/Unity Studio Classes/ClassStruct.cs +++ b/Unity Studio/Unity Studio Classes/ClassStruct.cs @@ -41,7 +41,7 @@ namespace Unity_Studio { public static string ViewStruct(this AssetPreloadData asset) { - var a_Stream = asset.sourceFile.a_Stream; + var a_Stream = asset.sourceFile.assetsFileReader; a_Stream.Position = asset.Offset; if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure)) { diff --git a/Unity Studio/Unity Studio Classes/Helpers.cs b/Unity Studio/Unity Studio Classes/Helpers.cs index fa571fa..921e918 100644 --- a/Unity Studio/Unity Studio Classes/Helpers.cs +++ b/Unity Studio/Unity Studio Classes/Helpers.cs @@ -3,13 +3,15 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using static Unity_Studio.UnityStudio; + namespace Unity_Studio { public class PPtr { //m_FileID 0 means current file - public int m_FileID = -1; + public int m_FileID; //m_PathID acts more like a hash in some games public long m_PathID; } @@ -18,14 +20,28 @@ namespace Unity_Studio { public static PPtr ReadPPtr(this AssetsFile sourceFile) { - PPtr result = new PPtr(); - var a_Stream = sourceFile.a_Stream; + var result = new PPtr(); + var reader = sourceFile.assetsFileReader; - int FileID = a_Stream.ReadInt32(); + int FileID = reader.ReadInt32(); if (FileID >= 0 && FileID < sourceFile.sharedAssetsList.Count) - { result.m_FileID = sourceFile.sharedAssetsList[FileID].Index; } + { + var sharedFile = sourceFile.sharedAssetsList[FileID]; + var index = sharedFile.Index; + if (index == -2) + { + var name = sharedFile.fileName.ToUpper(); + if (!sharedFileIndex.TryGetValue(name, out index)) + { + index = assetsfileList.FindIndex(aFile => aFile.upperFileName == name); + sharedFileIndex.Add(name, index); + } + sharedFile.Index = index; + } + result.m_FileID = index; + } - result.m_PathID = sourceFile.fileGen < 14 ? a_Stream.ReadInt32() : a_Stream.ReadInt64(); + result.m_PathID = sourceFile.fileGen < 14 ? reader.ReadInt32() : reader.ReadInt64(); return result; } diff --git a/Unity Studio/Unity Studio Classes/UnityStudio.cs b/Unity Studio/Unity Studio Classes/UnityStudio.cs index a4ee3b6..ff36fcf 100644 --- a/Unity Studio/Unity Studio Classes/UnityStudio.cs +++ b/Unity Studio/Unity Studio Classes/UnityStudio.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.IO; @@ -19,7 +20,7 @@ namespace Unity_Studio public static List assetsfileList = new List(); //loaded files public static HashSet assetsfileListHash = new HashSet(); //to improve the loading speed public static Dictionary sharedFileIndex = new Dictionary(); //to improve the loading speed - public static Dictionary assetsfileandstream = new Dictionary(); //use for read res files + public static Dictionary resourceFileReaders = new Dictionary(); //use for read res files public static List exportableAssets = new List(); //used to hold all assets while the ListView is filtered private static HashSet exportableAssetsHash = new HashSet(); //avoid the same name asset public static List visibleAssets = new List(); //used to build the ListView from all or filtered assets @@ -39,108 +40,114 @@ namespace Unity_Studio public static Action StatusStripUpdate; public static Action ProgressBarMaximumAdd; - public static void LoadAssetsFile(string fileName) + public static void LoadFile(string fullName) { - if (!assetsfileListHash.Contains(fileName)) + if (CheckBundleFile(fullName, out var reader)) { - AssetsFile assetsFile = new AssetsFile(fileName, new EndianBinaryReader(File.OpenRead(fileName))); - assetsfileList.Add(assetsFile); - assetsfileListHash.Add(fileName); + LoadBundleFile(fullName, reader); + } + else + { + LoadAssetsFile(fullName, reader); + } + } - #region for 2.6.x find mainData and get string version - if (assetsFile.fileGen == 6 && Path.GetFileName(fileName) != "mainData") + private static void LoadAssetsFile(string fullName, EndianBinaryReader reader) + { + var fileName = Path.GetFileName(fullName); + StatusStripUpdate("Loading " + fileName); + if (!assetsfileListHash.Contains(fileName.ToUpper())) + { + var assetsFile = new AssetsFile(fullName, reader); + if (assetsFile.valid) { - AssetsFile mainDataFile = assetsfileList.Find(aFile => aFile.filePath == Path.GetDirectoryName(fileName) + "\\mainData"); - if (mainDataFile != null) - { - assetsFile.m_Version = mainDataFile.m_Version; - assetsFile.version = mainDataFile.version; - assetsFile.buildType = mainDataFile.buildType; - } - else if (File.Exists(Path.GetDirectoryName(fileName) + "\\mainData")) - { - mainDataFile = new AssetsFile(Path.GetDirectoryName(fileName) + "\\mainData", new EndianBinaryReader(File.OpenRead(Path.GetDirectoryName(fileName) + "\\mainData"))); + assetsfileList.Add(assetsFile); + assetsfileListHash.Add(assetsFile.upperFileName); - assetsFile.m_Version = mainDataFile.m_Version; - assetsFile.version = mainDataFile.version; - assetsFile.buildType = mainDataFile.buildType; + #region for 2.6.x find mainData and get string version + if (assetsFile.fileGen == 6 && fileName != "mainData") + { + var mainDataFile = assetsfileList.Find(aFile => aFile.fileName == "mainData"); + if (mainDataFile != null) + { + assetsFile.m_Version = mainDataFile.m_Version; + assetsFile.version = mainDataFile.version; + assetsFile.buildType = mainDataFile.buildType; + } + else if (File.Exists(Path.GetDirectoryName(fullName) + "\\mainData")) + { + mainDataFile = new AssetsFile(Path.GetDirectoryName(fullName) + "\\mainData", new EndianBinaryReader(File.OpenRead(Path.GetDirectoryName(fullName) + "\\mainData"))); + assetsFile.m_Version = mainDataFile.m_Version; + assetsFile.version = mainDataFile.version; + assetsFile.buildType = mainDataFile.buildType; + } } + #endregion + + int value = 0; + foreach (var sharedFile in assetsFile.sharedAssetsList) + { + var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName; + var sharedFileName = sharedFile.fileName; + + if (!unityFilesHash.Contains(sharedFileName.ToUpper())) + { + if (!File.Exists(sharedFilePath)) + { + var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories); + if (findFiles.Length > 0) + { + sharedFilePath = findFiles[0]; + } + } + + if (File.Exists(sharedFilePath)) + { + unityFiles.Add(sharedFilePath); + unityFilesHash.Add(sharedFileName.ToUpper()); + value++; + } + } + } + if (value > 0) + ProgressBarMaximumAdd(value); } - #endregion + } + } - int value = 0; - foreach (var sharedFile in assetsFile.sharedAssetsList) + private static void LoadBundleFile(string fullName, EndianBinaryReader reader) + { + var fileName = Path.GetFileName(fullName); + StatusStripUpdate("Decompressing " + fileName); + var bundleFile = new BundleFile(reader); + foreach (var memFile in bundleFile.MemoryAssetsFileList) + { + if (!assetsfileListHash.Contains(memFile.fileName.ToUpper())) { - string sharedFilePath = Path.GetDirectoryName(fileName) + "\\" + sharedFile.fileName; - string sharedFileName = sharedFile.fileName; - if (!unityFilesHash.Contains(sharedFileName)) + StatusStripUpdate("Loading " + memFile.fileName); + var assetsFile = new AssetsFile(Path.GetDirectoryName(fullName) + "\\" + memFile.fileName, new EndianBinaryReader(memFile.memStream)); + if (assetsFile.valid) { - if (!File.Exists(sharedFilePath)) + assetsFile.bundlePath = fullName; + + if (assetsFile.fileGen == 6) //2.6.x and earlier don't have a string version before the preload table { - var findFiles = Directory.GetFiles(Path.GetDirectoryName(fileName), sharedFileName, SearchOption.AllDirectories); - if (findFiles.Length > 0) { sharedFilePath = findFiles[0]; } + //make use of the bundle file version + assetsFile.m_Version = bundleFile.versionEngine; + assetsFile.version = Array.ConvertAll((from Match m in Regex.Matches(assetsFile.m_Version, @"[0-9]") select m.Value).ToArray(), int.Parse); + assetsFile.buildType = bundleFile.versionEngine.Split(AssetsFile.buildTypeSplit, StringSplitOptions.RemoveEmptyEntries); } - if (File.Exists(sharedFilePath)) - { - //this would get screwed if the file somehow fails to load - sharedFile.Index = unityFiles.Count; - unityFiles.Add(sharedFilePath); - unityFilesHash.Add(sharedFileName); - value++; - } + assetsfileList.Add(assetsFile); + assetsfileListHash.Add(assetsFile.upperFileName); } else { - if (!sharedFileIndex.TryGetValue(sharedFilePath, out var index)) - { - index = unityFiles.IndexOf(sharedFilePath); - sharedFileIndex.Add(sharedFilePath, index); - } - sharedFile.Index = index; + resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.assetsFileReader); } } - if (value > 0) - ProgressBarMaximumAdd(value); - } - } - - public static void LoadBundleFile(string bundleFileName) - { - StatusStripUpdate("Decompressing " + Path.GetFileName(bundleFileName) + "..."); - BundleFile b_File = new BundleFile(bundleFileName); - - foreach (var memFile in b_File.MemoryAssetsFileList) //filter unity files - { - StatusStripUpdate("Loading " + memFile.fileName); - //create dummy path to be used for asset extraction - memFile.fileName = Path.GetDirectoryName(bundleFileName) + "\\" + memFile.fileName; - AssetsFile assetsFile = new AssetsFile(memFile.fileName, new EndianBinaryReader(memFile.memStream)); - if (assetsFile.valid) - { - assetsFile.bundlePath = bundleFileName; - if (assetsFile.fileGen == 6 && Path.GetFileName(bundleFileName) != "mainData") //2.6.x and earlier don't have a string version before the preload table - { - //make use of the bundle file version - assetsFile.m_Version = b_File.versionEngine; - assetsFile.version = Array.ConvertAll((from Match m in Regex.Matches(assetsFile.m_Version, @"[0-9]") select m.Value).ToArray(), int.Parse); - assetsFile.buildType = b_File.versionEngine.Split(AssetsFile.buildTypeSplit, StringSplitOptions.RemoveEmptyEntries); - } - assetsfileList.Add(assetsFile); - } - assetsfileandstream[assetsFile.fileName] = assetsFile.a_Stream; - } - } - - public static void BuildSharedIndex() - { - foreach (var assetsFile in assetsfileList) - { - foreach (var sharedFile in assetsFile.sharedAssetsList) - { - sharedFile.Index = assetsfileList.FindIndex(aFile => aFile.fileName.ToUpper() == sharedFile.fileName.ToUpper()); - } } + reader.Dispose(); } public static void MergeSplitAssets(string dirPath) @@ -167,16 +174,16 @@ namespace Unity_Studio } } - public static int extractBundleFile(string bundleFileName) + public static int ExtractBundleFile(string bundleFileName) { int extractedCount = 0; - if (CheckBundleFile(bundleFileName)) + if (CheckBundleFile(bundleFileName, out var reader)) { StatusStripUpdate($"Decompressing {Path.GetFileName(bundleFileName)} ..."); var extractPath = bundleFileName + "_unpacked\\"; Directory.CreateDirectory(extractPath); - var b_File = new BundleFile(bundleFileName); - foreach (var memFile in b_File.MemoryAssetsFileList) + var bundleFile = new BundleFile(reader); + foreach (var memFile in bundleFile.MemoryAssetsFileList) { var filePath = extractPath + memFile.fileName.Replace('/', '\\'); if (!Directory.Exists(Path.GetDirectoryName(filePath))) @@ -195,6 +202,7 @@ namespace Unity_Studio } } } + reader.Dispose(); return extractedCount; } @@ -1852,8 +1860,8 @@ namespace Unity_Studio var exportFullName = exportPath + asset.Text + asset.extension; if (ExportFileExists(exportFullName)) return false; - asset.sourceFile.a_Stream.Position = asset.Offset; - var bytes = asset.sourceFile.a_Stream.ReadBytes(asset.Size); + asset.sourceFile.assetsFileReader.Position = asset.Offset; + var bytes = asset.sourceFile.assetsFileReader.ReadBytes(asset.Size); File.WriteAllBytes(exportFullName, bytes); return true; } @@ -1874,21 +1882,20 @@ namespace Unity_Studio return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_')); } - public static bool CheckBundleFile(string fileName) + private static bool CheckBundleFile(string fileName, out EndianBinaryReader reader) { - using (var stream = new EndianBinaryReader(File.OpenRead(fileName))) + reader = new EndianBinaryReader(File.OpenRead(fileName)); + var signature = reader.ReadStringToNull(); + reader.Position = 0; + switch (signature) { - var signature = stream.ReadStringToNull(); - switch (signature) - { - case "UnityWeb": - case "UnityRaw": - case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": - case "UnityFS": - return true; - default: - return false; - } + case "UnityWeb": + case "UnityRaw": + case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": + case "UnityFS": + return true; + default: + return false; } } @@ -1909,28 +1916,18 @@ namespace Unity_Studio return selectFile.Distinct().ToArray(); } - //TODO Tight方式的Sprite需要读取多边形信息进行绘图 public static Bitmap GetImageFromSprite(AssetPreloadData asset) { if (spriteCache.TryGetValue(asset, out var bitmap)) return (Bitmap)bitmap.Clone(); var m_Sprite = new Sprite(asset, true); - if (m_Sprite.m_SpriteAtlas != null && assetsfileList.TryGetPD(m_Sprite.m_SpriteAtlas, out var assetPreloadData)) + if (assetsfileList.TryGetPD(m_Sprite.m_SpriteAtlas, out var assetPreloadData)) { var m_SpriteAtlas = new SpriteAtlas(assetPreloadData); - bool find = false; - int index = 0; - for (; index < m_SpriteAtlas.m_PackedSprites.Count; index++) + var index = m_SpriteAtlas.guids.FindIndex(x => x == m_Sprite.first); + if (index >= 0 && assetsfileList.TryGetPD(m_SpriteAtlas.textures[index], out assetPreloadData)) { - if (assetsfileList.TryGetPD(m_SpriteAtlas.m_PackedSprites[index], out assetPreloadData) && assetPreloadData == asset) - { - find = true; - break; - } - } - if (find && assetsfileList.TryGetPD(m_SpriteAtlas.textures[index], out assetPreloadData)) - { - return CutImage(asset, assetPreloadData, m_SpriteAtlas.textureRects[index]); + return CutImage(asset, assetPreloadData, m_SpriteAtlas.textureRects[index], m_Sprite); } } else @@ -1964,5 +1961,45 @@ namespace Unity_Studio return null; } + + private static Bitmap CutImage(AssetPreloadData asset, AssetPreloadData texture2DAsset, RectangleF textureRect, Sprite sprite) + { + var texture2D = new Texture2D(texture2DAsset, true); + using (var originalImage = texture2D.ConvertToBitmap(false)) + { + if (originalImage != null) + { + var info = texture2DAsset.InfoText; + var start = info.IndexOf("Format"); + info = info.Substring(start, info.Length - start); + asset.InfoText = $"Width: {textureRect.Width}\nHeight: {textureRect.Height}\n" + info; + var spriteImage = originalImage.Clone(textureRect, PixelFormat.Format32bppArgb); + using (var brush = new TextureBrush(spriteImage)) + { + using (var path = new GraphicsPath()) + { + foreach (var p in sprite.m_PhysicsShape) + path.AddPolygon(p); + using (var matr = new Matrix()) + { + matr.Translate(sprite.m_Rect.Width * sprite.m_Pivot.X, sprite.m_Rect.Height * sprite.m_Pivot.Y); + matr.Scale(sprite.m_PixelsToUnits, sprite.m_PixelsToUnits); + path.Transform(matr); + var bitmap = new Bitmap((int)textureRect.Width, (int)textureRect.Height); + using (var graphic = Graphics.FromImage(bitmap)) + { + graphic.FillPath(brush, path); + bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); + spriteCache.Add(asset, bitmap); + return (Bitmap)bitmap.Clone(); + } + } + } + } + } + } + + return null; + } } } diff --git a/Unity Studio/UnityStudioForm.Designer.cs b/Unity Studio/UnityStudioForm.Designer.cs index abadf16..328babf 100644 --- a/Unity Studio/UnityStudioForm.Designer.cs +++ b/Unity Studio/UnityStudioForm.Designer.cs @@ -813,7 +813,7 @@ // openFileDialog1 // this.openFileDialog1.AddExtension = false; - this.openFileDialog1.Filter = resources.GetString("openFileDialog1.Filter"); + this.openFileDialog1.Filter = "Unity files|*.*"; this.openFileDialog1.Multiselect = true; this.openFileDialog1.RestoreDirectory = true; // diff --git a/Unity Studio/UnityStudioForm.cs b/Unity Studio/UnityStudioForm.cs index b19c11e..e45c2bf 100644 --- a/Unity Studio/UnityStudioForm.cs +++ b/Unity Studio/UnityStudioForm.cs @@ -84,58 +84,24 @@ namespace Unity_Studio resetForm(); ThreadPool.QueueUserWorkItem(state => { - var bundle = false; - if (openFileDialog1.FilterIndex == 1 || openFileDialog1.FilterIndex == 3) + mainPath = Path.GetDirectoryName(openFileDialog1.FileNames[0]); + MergeSplitAssets(mainPath); + var readFile = ProcessingSplitFiles(openFileDialog1.FileNames.ToList()); + foreach (var i in readFile) { - if (CheckBundleFile(openFileDialog1.FileNames[0])) - { - if (openFileDialog1.FileNames.Length > 1) - { - MessageBox.Show($"{Path.GetFileName(openFileDialog1.FileNames[0])} is bundle file, please select bundle file type to load this file"); - return; - } - bundle = true; - } + unityFiles.Add(i); + unityFilesHash.Add(Path.GetFileName(i).ToUpper()); } - else + SetProgressBarValue(0); + SetProgressBarMaximum(unityFiles.Count); + //use a for loop because list size can change + for (int f = 0; f < unityFiles.Count; f++) { - bundle = true; - } - if (!bundle) - { - mainPath = Path.GetDirectoryName(openFileDialog1.FileNames[0]); - MergeSplitAssets(mainPath); - var readFile = ProcessingSplitFiles(openFileDialog1.FileNames.ToList()); - foreach (var i in readFile) - { - unityFiles.Add(i); - unityFilesHash.Add(Path.GetFileName(i)); - } - SetProgressBarValue(0); - SetProgressBarMaximum(unityFiles.Count); - //use a for loop because list size can change - for (int f = 0; f < unityFiles.Count; f++) - { - var fileName = unityFiles[f]; - StatusStripUpdate("Loading " + Path.GetFileName(fileName)); - LoadAssetsFile(fileName); - ProgressBarPerformStep(); - } - } - else - { - SetProgressBarValue(0); - SetProgressBarMaximum(unityFiles.Count); - foreach (var filename in openFileDialog1.FileNames) - { - LoadBundleFile(filename); - ProgressBarPerformStep(); - } - BuildSharedIndex(); + LoadFile(unityFiles[f]); + ProgressBarPerformStep(); } unityFilesHash.Clear(); assetsfileListHash.Clear(); - sharedFileIndex.Clear(); BuildAssetStrucutres(); }); } @@ -163,14 +129,11 @@ namespace Unity_Studio //use a for loop because list size can change for (int f = 0; f < unityFiles.Count; f++) { - var fileName = unityFiles[f]; - StatusStripUpdate("Loading " + Path.GetFileName(fileName)); - LoadAssetsFile(fileName); + LoadFile(unityFiles[f]); ProgressBarPerformStep(); } unityFilesHash.Clear(); assetsfileListHash.Clear(); - sharedFileIndex.Clear(); BuildAssetStrucutres(); }); } @@ -193,7 +156,7 @@ namespace Unity_Studio { foreach (var fileName in openBundleDialog.FileNames) { - extractedCount += extractBundleFile(fileName); + extractedCount += ExtractBundleFile(fileName); ProgressBarPerformStep(); } StatusStripUpdate($"Finished extracting {extractedCount} files."); @@ -215,7 +178,7 @@ namespace Unity_Studio { foreach (var fileName in bundleFiles) { - extractedCount += extractBundleFile(fileName); + extractedCount += ExtractBundleFile(fileName); ProgressBarPerformStep(); } StatusStripUpdate($"Finished extracting {extractedCount} files."); @@ -1843,7 +1806,9 @@ namespace Unity_Studio assetsfileList.Clear(); exportableAssets.Clear(); visibleAssets.Clear(); - assetsfileandstream.Clear(); + resourceFileReaders.Clear(); + sharedFileIndex.Clear(); + productName = ""; sceneTreeView.Nodes.Clear(); diff --git a/Unity Studio/UnityStudioForm.resx b/Unity Studio/UnityStudioForm.resx index f732ecb..f6015bc 100644 --- a/Unity Studio/UnityStudioForm.resx +++ b/Unity Studio/UnityStudioForm.resx @@ -150,9 +150,6 @@ The quick brown fox jumps over the lazy dog. 1234567890 636, 17 - - Unity asset files|*.*|Unity bundle files|*.*|Unity asset files|level*; globalgamemanagers; mainData; CustomAssetBundle-*; CAB-*; BuildPlayer-*; *.assets; *.sharedAssets|Unity bundle files|*.unity3d; *.unity3d.lz4; *.assetbundle; *.bundle; *.bytes - 784, 17