merge
This commit is contained in:
mafaca 2018-03-01 02:32:09 +03:00
commit aa653cd508
28 changed files with 480 additions and 447 deletions

View File

@ -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());

View File

@ -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);

View File

@ -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();

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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();

View File

@ -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());

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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<SpriteAtlas> m_SpriteAtlas
@ -67,66 +74,92 @@ namespace Unity_Studio
// PPtr<Texture2D> texture
texture = sourceFile.ReadPPtr();
// PPtr<Texture2D> 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
{

View File

@ -8,55 +8,56 @@ namespace Unity_Studio
{
class SpriteAtlas
{
public List<PPtr> m_PackedSprites = new List<PPtr>();
public List<PPtr> textures = new List<PPtr>();
public List<RectangleF> textureRects = new List<RectangleF>();
public List<Guid> guids = new List<Guid>();
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<Sprite> 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<Texture2D> texture
textures.Add(sourceFile.ReadPPtr());
// PPtr<Texture2D> 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

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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<ClassMember>();
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<ClassMember> 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<ClassMember>();
//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());

View File

@ -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);
}

View File

@ -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))
{

View File

@ -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;
}

View File

@ -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<AssetsFile> assetsfileList = new List<AssetsFile>(); //loaded files
public static HashSet<string> assetsfileListHash = new HashSet<string>(); //to improve the loading speed
public static Dictionary<string, int> sharedFileIndex = new Dictionary<string, int>(); //to improve the loading speed
public static Dictionary<string, EndianBinaryReader> assetsfileandstream = new Dictionary<string, EndianBinaryReader>(); //use for read res files
public static Dictionary<string, EndianBinaryReader> resourceFileReaders = new Dictionary<string, EndianBinaryReader>(); //use for read res files
public static List<AssetPreloadData> exportableAssets = new List<AssetPreloadData>(); //used to hold all assets while the ListView is filtered
private static HashSet<string> exportableAssetsHash = new HashSet<string>(); //avoid the same name asset
public static List<AssetPreloadData> visibleAssets = new List<AssetPreloadData>(); //used to build the ListView from all or filtered assets
@ -39,108 +40,114 @@ namespace Unity_Studio
public static Action<string> StatusStripUpdate;
public static Action<int> 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;
}
}
}

View File

@ -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;
//

View File

@ -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();

View File

@ -150,9 +150,6 @@ The quick brown fox jumps over the lazy dog. 1234567890</value>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>636, 17</value>
</metadata>
<data name="openFileDialog1.Filter" xml:space="preserve">
<value>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</value>
</data>
<metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>784, 17</value>
</metadata>