mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-07-15 11:04:16 -04:00
Code moved out of UnityStudioForm and into new class UnityStudio.cs (#17)
This commit is contained in:
24
Unity Studio/Unity Studio Classes/AssetPreloadData.cs
Normal file
24
Unity Studio/Unity Studio Classes/AssetPreloadData.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public class AssetPreloadData : ListViewItem
|
||||
{
|
||||
public long m_PathID;
|
||||
public uint Offset;
|
||||
public int Size;
|
||||
public int Type1;
|
||||
public ushort Type2;
|
||||
|
||||
public string TypeString;
|
||||
public string InfoText;
|
||||
public string extension;
|
||||
|
||||
public AssetsFile sourceFile;
|
||||
public string uniqueID;
|
||||
}
|
||||
}
|
465
Unity Studio/Unity Studio Classes/AssetsFile.cs
Normal file
465
Unity Studio/Unity Studio Classes/AssetsFile.cs
Normal file
@ -0,0 +1,465 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public class AssetsFile
|
||||
{
|
||||
public EndianStream a_Stream;
|
||||
public string filePath;
|
||||
public string fileName;
|
||||
public int fileGen;
|
||||
public string m_Version = "2.5.0f5";
|
||||
public int[] version = new int[4] { 0, 0, 0, 0 };
|
||||
public string[] buildType;
|
||||
public int platform = 100663296;
|
||||
public string platformStr = "";
|
||||
//public EndianType endianType = EndianType.BigEndian;
|
||||
//public List<AssetPreloadData> preloadTable = new List<AssetPreloadData>();
|
||||
public Dictionary<long, AssetPreloadData> preloadTable = new Dictionary<long, AssetPreloadData>();
|
||||
public Dictionary<long, GameObject> GameObjectList = new Dictionary<long, GameObject>();
|
||||
public Dictionary<long, Transform> TransformList = new Dictionary<long, Transform>();
|
||||
|
||||
public List<AssetPreloadData> exportableAssets = new List<AssetPreloadData>();
|
||||
public List<UnityShared> sharedAssetsList = new List<UnityShared>() { new UnityShared() };
|
||||
private ClassIDReference UnityClassID = new ClassIDReference();
|
||||
|
||||
public SortedDictionary<int, ClassStruct> ClassStructures = new SortedDictionary<int, ClassStruct>();
|
||||
|
||||
private bool baseDefinitions = false;
|
||||
private List<int[]> classIDs = new List<int[]>();//use for 5.5.0
|
||||
|
||||
public class UnityShared
|
||||
{
|
||||
public int Index = -1; //actual index in main list
|
||||
public string aName = "";
|
||||
public string fileName = "";
|
||||
}
|
||||
|
||||
public AssetsFile(string fullName, EndianStream fileStream)
|
||||
{
|
||||
//if (memFile != null) { Stream = new EndianStream(memFile, endianType); }
|
||||
//else { Stream = new EndianStream(File.OpenRead(fileName), endianType); }
|
||||
a_Stream = fileStream;
|
||||
|
||||
filePath = fullName;
|
||||
fileName = Path.GetFileName(fullName);
|
||||
int tableSize = a_Stream.ReadInt32();
|
||||
int dataEnd = a_Stream.ReadInt32();
|
||||
fileGen = a_Stream.ReadInt32();
|
||||
uint dataOffset = a_Stream.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;
|
||||
break;
|
||||
}
|
||||
case 7://3.0.0 beta
|
||||
{
|
||||
a_Stream.Position = (dataEnd - tableSize);
|
||||
a_Stream.Position += 1;
|
||||
m_Version = a_Stream.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();
|
||||
break;
|
||||
}
|
||||
case 9://3.5.0 - 4.6.x
|
||||
{
|
||||
a_Stream.Position += 4;//azero
|
||||
m_Version = a_Stream.ReadStringToNull();
|
||||
platform = a_Stream.ReadInt32();
|
||||
break;
|
||||
}
|
||||
case 14://5.0.0 beta and final
|
||||
case 15://5.0.1 - 5.4
|
||||
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();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//MessageBox.Show("Unsupported Unity version!" + fileGen, "Unity Studio Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (platform > 255 || platform < 0)
|
||||
{
|
||||
byte[] b32 = BitConverter.GetBytes(platform);
|
||||
Array.Reverse(b32);
|
||||
platform = BitConverter.ToInt32(b32, 0);
|
||||
//endianType = EndianType.LittleEndian;
|
||||
a_Stream.endian = EndianType.LittleEndian;
|
||||
}
|
||||
|
||||
switch (platform)
|
||||
{
|
||||
case -2: platformStr = "Unity Package"; break;
|
||||
case 4: platformStr = "OSX"; break;
|
||||
case 5: platformStr = "PC"; break;
|
||||
case 6: platformStr = "Web"; break;
|
||||
case 7: platformStr = "Web streamed"; break;
|
||||
case 9: platformStr = "iOS"; break;
|
||||
case 10: platformStr = "PS3"; break;
|
||||
case 11: platformStr = "Xbox 360"; break;
|
||||
case 13: platformStr = "Android"; break;
|
||||
case 16: platformStr = "Google NaCl"; break;
|
||||
case 21: platformStr = "WP8"; break;
|
||||
case 25: platformStr = "Linux"; break;
|
||||
default: platformStr = "Unknown Platform"; break;
|
||||
}
|
||||
|
||||
int baseCount = a_Stream.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();
|
||||
|
||||
var cb = new List<ClassMember>();
|
||||
for (int m = 0; m < memberCount; m++) { readBase(cb, 1); }
|
||||
|
||||
var aClass = new ClassStruct() { ID = classID, Text = (baseType + " " + baseName), members = cb };
|
||||
aClass.SubItems.Add(classID.ToString());
|
||||
ClassStructures.Add(classID, aClass);
|
||||
}
|
||||
else { readBase5(); }
|
||||
}
|
||||
|
||||
if (fileGen >= 7 && fileGen < 14) { a_Stream.Position += 4; }//azero
|
||||
|
||||
int assetCount = a_Stream.ReadInt32();
|
||||
|
||||
#region asset preload table
|
||||
string assetIDfmt = "D" + assetCount.ToString().Length.ToString(); //format for unique ID
|
||||
|
||||
for (int i = 0; i < assetCount; i++)
|
||||
{
|
||||
//each table entry is aligned individually, not the whole table
|
||||
if (fileGen >= 14) { a_Stream.AlignStream(4); }
|
||||
|
||||
AssetPreloadData asset = new AssetPreloadData();
|
||||
if (fileGen < 14) { asset.m_PathID = a_Stream.ReadInt32(); }
|
||||
else { asset.m_PathID = a_Stream.ReadInt64(); }
|
||||
asset.Offset = a_Stream.ReadUInt32();
|
||||
asset.Offset += dataOffset;
|
||||
asset.Size = a_Stream.ReadInt32();
|
||||
if (fileGen > 15)
|
||||
{
|
||||
int index = a_Stream.ReadInt32();
|
||||
asset.Type1 = classIDs[index][0];
|
||||
asset.Type2 = (ushort)classIDs[index][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
asset.Type1 = a_Stream.ReadInt32();
|
||||
asset.Type2 = a_Stream.ReadUInt16();
|
||||
a_Stream.Position += 2;
|
||||
}
|
||||
if (fileGen == 15)
|
||||
{
|
||||
byte unknownByte = a_Stream.ReadByte();
|
||||
//this is a single byte, not an int32
|
||||
//the next entry is aligned after this
|
||||
//but not the last!
|
||||
if (unknownByte != 0)
|
||||
{
|
||||
//bool investigate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnityClassID.Names[asset.Type2] != null)
|
||||
{
|
||||
asset.TypeString = UnityClassID.Names[asset.Type2];
|
||||
}
|
||||
else
|
||||
{
|
||||
asset.TypeString = "Unknown Type " + asset.Type2;
|
||||
}
|
||||
|
||||
asset.uniqueID = i.ToString(assetIDfmt);
|
||||
|
||||
asset.sourceFile = this;
|
||||
|
||||
preloadTable.Add(asset.m_PathID, asset);
|
||||
|
||||
#region read BuildSettings to get version for unity 2.x files
|
||||
if (asset.Type2 == 141 && fileGen == 6)
|
||||
{
|
||||
long nextAsset = a_Stream.Position;
|
||||
|
||||
BuildSettings BSettings = new BuildSettings(asset);
|
||||
m_Version = BSettings.m_Version;
|
||||
|
||||
a_Stream.Position = nextAsset;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
buildType = m_Version.Split(new string[] { ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] strver = (m_Version.Split(new string[] { ".", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "\n" }, StringSplitOptions.RemoveEmptyEntries));
|
||||
version = Array.ConvertAll(strver, int.Parse);
|
||||
|
||||
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();
|
||||
for (int i = 0; i < someCount; i++)
|
||||
{
|
||||
int num1 = a_Stream.ReadInt32();
|
||||
a_Stream.AlignStream(4);
|
||||
long m_PathID = a_Stream.ReadInt64();
|
||||
}
|
||||
}
|
||||
|
||||
int sharedFileCount = a_Stream.ReadInt32();
|
||||
for (int i = 0; i < sharedFileCount; i++)
|
||||
{
|
||||
UnityShared shared = new UnityShared();
|
||||
shared.aName = a_Stream.ReadStringToNull();
|
||||
a_Stream.Position += 20;
|
||||
string sharedFileName = a_Stream.ReadStringToNull(); //relative path
|
||||
shared.fileName = sharedFileName.Replace("/", "\\");
|
||||
sharedAssetsList.Add(shared);
|
||||
}
|
||||
}
|
||||
|
||||
private void readBase(List<ClassMember> cb, int level)
|
||||
{
|
||||
string varType = a_Stream.ReadStringToNull();
|
||||
string varName = a_Stream.ReadStringToNull();
|
||||
//a_Stream.Position += 20;
|
||||
int size = a_Stream.ReadInt32();
|
||||
int index = a_Stream.ReadInt32();
|
||||
int isArray = a_Stream.ReadInt32();
|
||||
int num0 = a_Stream.ReadInt32();
|
||||
int num1 = a_Stream.ReadInt16();
|
||||
int num2 = a_Stream.ReadInt16();
|
||||
int childrenCount = a_Stream.ReadInt32();
|
||||
|
||||
//Debug.WriteLine(baseFormat + " " + baseName + " " + childrenCount);
|
||||
cb.Add(new ClassMember()
|
||||
{
|
||||
Level = level - 1,
|
||||
Type = varType,
|
||||
Name = varName,
|
||||
Size = size
|
||||
});
|
||||
for (int i = 0; i < childrenCount; i++) { readBase(cb, level + 1); }
|
||||
}
|
||||
|
||||
private void readBase5()
|
||||
{
|
||||
int classID = a_Stream.ReadInt32();
|
||||
if (fileGen > 15)
|
||||
{
|
||||
if (classID == 0)//TODO 暂时用这种方法解决
|
||||
{
|
||||
a_Stream.Position += 12;
|
||||
classID = a_Stream.ReadInt32();
|
||||
}
|
||||
a_Stream.ReadByte();
|
||||
int type1;
|
||||
if ((type1 = a_Stream.ReadInt16()) >= 0)
|
||||
{
|
||||
type1 = -1 - type1;
|
||||
a_Stream.Position += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
type1 = classID;
|
||||
}
|
||||
classIDs.Add(new int[] { type1, classID });
|
||||
classID = type1;
|
||||
}
|
||||
else if (classID < 0)
|
||||
{
|
||||
a_Stream.Position += 16;
|
||||
}
|
||||
a_Stream.Position += 16;
|
||||
|
||||
if (baseDefinitions)
|
||||
{
|
||||
#region cmmon string array
|
||||
string[] baseStrings = new string[1043];
|
||||
baseStrings[0] = "AABB";
|
||||
baseStrings[5] = "AnimationClip";
|
||||
baseStrings[19] = "AnimationCurve";
|
||||
baseStrings[34] = "AnimationState";
|
||||
baseStrings[49] = "Array";
|
||||
baseStrings[55] = "Base";
|
||||
baseStrings[60] = "BitField";
|
||||
baseStrings[69] = "bitset";
|
||||
baseStrings[76] = "bool";
|
||||
baseStrings[81] = "char";
|
||||
baseStrings[86] = "ColorRGBA";
|
||||
baseStrings[96] = "Component";
|
||||
baseStrings[106] = "data";
|
||||
baseStrings[111] = "deque";
|
||||
baseStrings[117] = "double";
|
||||
baseStrings[124] = "dynamic_array";
|
||||
baseStrings[138] = "FastPropertyName";
|
||||
baseStrings[155] = "first";
|
||||
baseStrings[161] = "float";
|
||||
baseStrings[167] = "Font";
|
||||
baseStrings[172] = "GameObject";
|
||||
baseStrings[183] = "Generic Mono";
|
||||
baseStrings[196] = "GradientNEW";
|
||||
baseStrings[208] = "GUID";
|
||||
baseStrings[213] = "GUIStyle";
|
||||
baseStrings[222] = "int";
|
||||
baseStrings[226] = "list";
|
||||
baseStrings[231] = "long long";
|
||||
baseStrings[241] = "map";
|
||||
baseStrings[245] = "Matrix4x4f";
|
||||
baseStrings[256] = "MdFour";
|
||||
baseStrings[263] = "MonoBehaviour";
|
||||
baseStrings[277] = "MonoScript";
|
||||
baseStrings[288] = "m_ByteSize";
|
||||
baseStrings[299] = "m_Curve";
|
||||
baseStrings[307] = "m_EditorClassIdentifier";
|
||||
baseStrings[331] = "m_EditorHideFlags";
|
||||
baseStrings[349] = "m_Enabled";
|
||||
baseStrings[359] = "m_ExtensionPtr";
|
||||
baseStrings[374] = "m_GameObject";
|
||||
baseStrings[387] = "m_Index";
|
||||
baseStrings[395] = "m_IsArray";
|
||||
baseStrings[405] = "m_IsStatic";
|
||||
baseStrings[416] = "m_MetaFlag";
|
||||
baseStrings[427] = "m_Name";
|
||||
baseStrings[434] = "m_ObjectHideFlags";
|
||||
baseStrings[452] = "m_PrefabInternal";
|
||||
baseStrings[469] = "m_PrefabParentObject";
|
||||
baseStrings[490] = "m_Script";
|
||||
baseStrings[499] = "m_StaticEditorFlags";
|
||||
baseStrings[519] = "m_Type";
|
||||
baseStrings[526] = "m_Version";
|
||||
baseStrings[536] = "Object";
|
||||
baseStrings[543] = "pair";
|
||||
baseStrings[548] = "PPtr<Component>";
|
||||
baseStrings[564] = "PPtr<GameObject>";
|
||||
baseStrings[581] = "PPtr<Material>";
|
||||
baseStrings[596] = "PPtr<MonoBehaviour>";
|
||||
baseStrings[616] = "PPtr<MonoScript>";
|
||||
baseStrings[633] = "PPtr<Object>";
|
||||
baseStrings[646] = "PPtr<Prefab>";
|
||||
baseStrings[659] = "PPtr<Sprite>";
|
||||
baseStrings[672] = "PPtr<TextAsset>";
|
||||
baseStrings[688] = "PPtr<Texture>";
|
||||
baseStrings[702] = "PPtr<Texture2D>";
|
||||
baseStrings[718] = "PPtr<Transform>";
|
||||
baseStrings[734] = "Prefab";
|
||||
baseStrings[741] = "Quaternionf";
|
||||
baseStrings[753] = "Rectf";
|
||||
baseStrings[759] = "RectInt";
|
||||
baseStrings[767] = "RectOffset";
|
||||
baseStrings[778] = "second";
|
||||
baseStrings[785] = "set";
|
||||
baseStrings[789] = "short";
|
||||
baseStrings[795] = "size";
|
||||
baseStrings[800] = "SInt16";
|
||||
baseStrings[807] = "SInt32";
|
||||
baseStrings[814] = "SInt64";
|
||||
baseStrings[821] = "SInt8";
|
||||
baseStrings[827] = "staticvector";
|
||||
baseStrings[840] = "string";
|
||||
baseStrings[847] = "TextAsset";
|
||||
baseStrings[857] = "TextMesh";
|
||||
baseStrings[866] = "Texture";
|
||||
baseStrings[874] = "Texture2D";
|
||||
baseStrings[884] = "Transform";
|
||||
baseStrings[894] = "TypelessData";
|
||||
baseStrings[907] = "UInt16";
|
||||
baseStrings[914] = "UInt32";
|
||||
baseStrings[921] = "UInt64";
|
||||
baseStrings[928] = "UInt8";
|
||||
baseStrings[934] = "unsigned int";
|
||||
baseStrings[947] = "unsigned long long";
|
||||
baseStrings[966] = "unsigned short";
|
||||
baseStrings[981] = "vector";
|
||||
baseStrings[988] = "Vector2f";
|
||||
baseStrings[997] = "Vector3f";
|
||||
baseStrings[1006] = "Vector4f";
|
||||
baseStrings[1015] = "m_ScriptingClassIdentifier";
|
||||
baseStrings[1042] = "Gradient";
|
||||
#endregion
|
||||
|
||||
int varCount = a_Stream.ReadInt32();
|
||||
int stringSize = a_Stream.ReadInt32();
|
||||
|
||||
a_Stream.Position += varCount * 24;
|
||||
string varStrings = Encoding.UTF8.GetString(a_Stream.ReadBytes(stringSize));
|
||||
string className = "";
|
||||
var classVar = new List<ClassMember>();
|
||||
//build Class Structures
|
||||
a_Stream.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 varTypeIndex = a_Stream.ReadUInt16();
|
||||
ushort test = a_Stream.ReadUInt16();
|
||||
string varTypeStr;
|
||||
if (test == 0) //varType is an offset in the string block
|
||||
{ varTypeStr = varStrings.Substring(varTypeIndex, varStrings.IndexOf('\0', varTypeIndex) - varTypeIndex); }//substringToNull
|
||||
else //varType is an index in an internal strig array
|
||||
{ varTypeStr = ((varTypeIndex < baseStrings.Length) && (baseStrings[varTypeIndex] != null)) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); }
|
||||
|
||||
ushort varNameIndex = a_Stream.ReadUInt16();
|
||||
test = a_Stream.ReadUInt16();
|
||||
string varNameStr;
|
||||
if (test == 0) { varNameStr = varStrings.Substring(varNameIndex, varStrings.IndexOf('\0', varNameIndex) - varNameIndex); }
|
||||
else { varNameStr = baseStrings[varNameIndex] != null ? baseStrings[varNameIndex] : varNameIndex.ToString(); }
|
||||
|
||||
int size = a_Stream.ReadInt32();
|
||||
int index = a_Stream.ReadInt32();
|
||||
int num1 = a_Stream.ReadInt32();
|
||||
|
||||
if (index == 0) { className = varTypeStr + " " + varNameStr; }
|
||||
else
|
||||
{
|
||||
classVar.Add(new ClassMember()
|
||||
{
|
||||
Level = level - 1,
|
||||
Type = varTypeStr,
|
||||
Name = varNameStr,
|
||||
Size = size
|
||||
});
|
||||
}
|
||||
|
||||
//for (int t = 0; t < level; t++) { Debug.Write("\t"); }
|
||||
//Debug.WriteLine(varTypeStr + " " + varNameStr + " " + size);
|
||||
}
|
||||
a_Stream.Position += stringSize;
|
||||
|
||||
var aClass = new ClassStruct() { ID = classID, Text = className, members = classVar };
|
||||
aClass.SubItems.Add(classID.ToString());
|
||||
ClassStructures.Add(classID, aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
257
Unity Studio/Unity Studio Classes/BundleFile.cs
Normal file
257
Unity Studio/Unity Studio Classes/BundleFile.cs
Normal file
@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Lz4;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public class BundleFile
|
||||
{
|
||||
public int format;
|
||||
public string versionPlayer;
|
||||
public string versionEngine;
|
||||
public List<MemoryAssetsFile> MemoryAssetsFileList = new List<MemoryAssetsFile>();
|
||||
|
||||
public class MemoryAssetsFile
|
||||
{
|
||||
public string fileName;
|
||||
public MemoryStream memStream;
|
||||
}
|
||||
|
||||
public BundleFile(string fileName)
|
||||
{
|
||||
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
|
||||
|
||||
byte[] lz4buffer = new byte[compressedSize];
|
||||
lz4Stream.Read(lz4buffer, 0, 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 EndianStream(new MemoryStream(filebuffer), EndianType.BigEndian))
|
||||
{
|
||||
readBundle(b_Stream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var b_Stream = new EndianStream(File.OpenRead(fileName), EndianType.BigEndian))
|
||||
{
|
||||
readBundle(b_Stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readBundle(EndianStream b_Stream)
|
||||
{
|
||||
var signature = b_Stream.ReadStringToNull();
|
||||
|
||||
if (signature == "UnityWeb" || signature == "UnityRaw" || signature == "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA")
|
||||
{
|
||||
format = b_Stream.ReadInt32();
|
||||
versionPlayer = b_Stream.ReadStringToNull();
|
||||
versionEngine = b_Stream.ReadStringToNull();
|
||||
if (format < 6)
|
||||
{
|
||||
int bundleSize = b_Stream.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
long bundleSize = b_Stream.ReadInt64();
|
||||
return;
|
||||
}
|
||||
short dummy2 = b_Stream.ReadInt16();
|
||||
int offset = b_Stream.ReadInt16();
|
||||
int dummy3 = b_Stream.ReadInt32();
|
||||
int lzmaChunks = b_Stream.ReadInt32();
|
||||
|
||||
int lzmaSize = 0;
|
||||
long streamSize = 0;
|
||||
|
||||
for (int i = 0; i < lzmaChunks; i++)
|
||||
{
|
||||
lzmaSize = b_Stream.ReadInt32();
|
||||
streamSize = b_Stream.ReadInt32();
|
||||
}
|
||||
|
||||
b_Stream.Position = offset;
|
||||
switch (signature)
|
||||
{
|
||||
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": //.bytes
|
||||
case "UnityWeb":
|
||||
{
|
||||
byte[] lzmaBuffer = new byte[lzmaSize];
|
||||
b_Stream.Read(lzmaBuffer, 0, lzmaSize);
|
||||
|
||||
using (var lzmaStream = new EndianStream(SevenZip.Compression.LZMA.SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer)), EndianType.BigEndian))
|
||||
{
|
||||
getFiles(lzmaStream, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "UnityRaw":
|
||||
{
|
||||
getFiles(b_Stream, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (signature == "UnityFS")
|
||||
{
|
||||
format = b_Stream.ReadInt32();
|
||||
versionPlayer = b_Stream.ReadStringToNull();
|
||||
versionEngine = b_Stream.ReadStringToNull();
|
||||
if (format == 6)
|
||||
{
|
||||
var bundleSize = b_Stream.ReadInt64();
|
||||
int compressedSize = b_Stream.ReadInt32();
|
||||
int uncompressedSize = b_Stream.ReadInt32();
|
||||
int flag = b_Stream.ReadInt32();
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
blocksInfoBytes = b_Stream.ReadBytes(compressedSize);
|
||||
}
|
||||
EndianStream blocksInfo;
|
||||
switch (flag & 0x3F)
|
||||
{
|
||||
default:
|
||||
case 0://None
|
||||
{
|
||||
blocksInfo = new EndianStream(new MemoryStream(blocksInfoBytes), EndianType.BigEndian);
|
||||
break;
|
||||
}
|
||||
case 1://LZMA
|
||||
{
|
||||
blocksInfo = new EndianStream(SevenZip.Compression.LZMA.SevenZipHelper.StreamDecompress(new MemoryStream(blocksInfoBytes)), EndianType.BigEndian);
|
||||
break;
|
||||
}
|
||||
case 2://LZ4
|
||||
case 3://LZ4HC
|
||||
{
|
||||
byte[] uncompressedBytes = new byte[uncompressedSize];
|
||||
using (var mstream = new MemoryStream(blocksInfoBytes))
|
||||
{
|
||||
var decoder = new Lz4DecoderStream(mstream);
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedSize);
|
||||
decoder.Dispose();
|
||||
}
|
||||
blocksInfo = new EndianStream(new MemoryStream(uncompressedBytes), EndianType.BigEndian);
|
||||
break;
|
||||
}
|
||||
//case 4:LZHAM?
|
||||
}
|
||||
using (blocksInfo)
|
||||
{
|
||||
blocksInfo.Position = 0x10;
|
||||
int blockcount = blocksInfo.ReadInt32();
|
||||
EndianStream assetsData;
|
||||
var assetsDataStream = new MemoryStream();
|
||||
for (int i = 0; i < blockcount; i++)
|
||||
{
|
||||
uncompressedSize = blocksInfo.ReadInt32();
|
||||
compressedSize = blocksInfo.ReadInt32();
|
||||
flag = blocksInfo.ReadInt16();
|
||||
var compressedBytes = b_Stream.ReadBytes(compressedSize);
|
||||
switch (flag & 0x3F)
|
||||
{
|
||||
default:
|
||||
case 0://None
|
||||
{
|
||||
assetsDataStream.Write(compressedBytes, 0, compressedSize);
|
||||
break;
|
||||
}
|
||||
case 1://LZMA
|
||||
{
|
||||
var uncompressedBytes = new byte[uncompressedSize];
|
||||
using (var mstream = new MemoryStream(compressedBytes))
|
||||
{
|
||||
var decoder = SevenZip.Compression.LZMA.SevenZipHelper.StreamDecompress(mstream, uncompressedSize);
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedSize);
|
||||
decoder.Dispose();
|
||||
}
|
||||
assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
|
||||
break;
|
||||
}
|
||||
case 2://LZ4
|
||||
case 3://LZ4HC
|
||||
{
|
||||
var uncompressedBytes = new byte[uncompressedSize];
|
||||
using (var mstream = new MemoryStream(compressedBytes))
|
||||
{
|
||||
var decoder = new Lz4DecoderStream(mstream);
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedSize);
|
||||
decoder.Dispose();
|
||||
}
|
||||
assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
|
||||
break;
|
||||
}
|
||||
//case 4:LZHAM?
|
||||
}
|
||||
}
|
||||
assetsData = new EndianStream(assetsDataStream, EndianType.BigEndian);
|
||||
using (assetsData)
|
||||
{
|
||||
var entryinfo_count = blocksInfo.ReadInt32();
|
||||
for (int i = 0; i < entryinfo_count; i++)
|
||||
{
|
||||
var memFile = new MemoryAssetsFile();
|
||||
var entryinfo_offset = blocksInfo.ReadInt64();
|
||||
var entryinfo_size = blocksInfo.ReadInt64();
|
||||
var unknown = blocksInfo.ReadInt32();
|
||||
memFile.fileName = blocksInfo.ReadStringToNull();
|
||||
assetsData.Position = entryinfo_offset;
|
||||
var buffer = new byte[entryinfo_size];
|
||||
assetsData.Read(buffer, 0, (int)entryinfo_size);
|
||||
memFile.memStream = new MemoryStream(buffer);
|
||||
MemoryAssetsFileList.Add(memFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getFiles(EndianStream f_Stream, int offset)
|
||||
{
|
||||
int fileCount = f_Stream.ReadInt32();
|
||||
for (int i = 0; i < fileCount; i++)
|
||||
{
|
||||
MemoryAssetsFile memFile = new MemoryAssetsFile();
|
||||
memFile.fileName = f_Stream.ReadStringToNull();
|
||||
int fileOffset = f_Stream.ReadInt32();
|
||||
fileOffset += offset;
|
||||
int fileSize = f_Stream.ReadInt32();
|
||||
long nextFile = f_Stream.Position;
|
||||
f_Stream.Position = fileOffset;
|
||||
|
||||
byte[] buffer = new byte[fileSize];
|
||||
f_Stream.Read(buffer, 0, fileSize);
|
||||
memFile.memStream = new MemoryStream(buffer);
|
||||
MemoryAssetsFileList.Add(memFile);
|
||||
f_Stream.Position = nextFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
283
Unity Studio/Unity Studio Classes/ClassIDReference.cs
Normal file
283
Unity Studio/Unity Studio Classes/ClassIDReference.cs
Normal file
@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public class ClassStruct : ListViewItem
|
||||
{
|
||||
public int ID;
|
||||
public List<ClassMember> members;
|
||||
|
||||
public string membersstr
|
||||
{
|
||||
get
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var i in members)
|
||||
{
|
||||
sb.AppendFormat("{0}{1} {2} {3}\r\n", (new string('\t', i.Level)), i.Type, i.Name, i.Size);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassMember
|
||||
{
|
||||
public int Level;
|
||||
public string Type;
|
||||
public string Name;
|
||||
public int Size;
|
||||
}
|
||||
|
||||
public class ClassIDReference
|
||||
{
|
||||
public string[] Names = new string[1121];
|
||||
|
||||
public ClassIDReference()
|
||||
{
|
||||
Names[1] = "GameObject";
|
||||
Names[2] = "Component";
|
||||
Names[3] = "LevelGameManager";
|
||||
Names[4] = "Transform";
|
||||
Names[5] = "TimeManager";
|
||||
Names[6] = "GlobalGameManager";
|
||||
Names[8] = "Behaviour";
|
||||
Names[9] = "GameManager";
|
||||
Names[11] = "AudioManager";
|
||||
Names[12] = "ParticleAnimator";
|
||||
Names[13] = "InputManager";
|
||||
Names[15] = "EllipsoidParticleEmitter";
|
||||
Names[17] = "Pipeline";
|
||||
Names[18] = "EditorExtension";
|
||||
Names[19] = "Physics2DSettings";
|
||||
Names[20] = "Camera";
|
||||
Names[21] = "Material";
|
||||
Names[23] = "MeshRenderer";
|
||||
Names[25] = "Renderer";
|
||||
Names[26] = "ParticleRenderer";
|
||||
Names[27] = "Texture";
|
||||
Names[28] = "Texture2D";
|
||||
Names[29] = "SceneSettings";
|
||||
Names[30] = "GraphicsSettings";
|
||||
Names[33] = "MeshFilter";
|
||||
Names[41] = "OcclusionPortal";
|
||||
Names[43] = "Mesh";
|
||||
Names[45] = "Skybox";
|
||||
Names[47] = "QualitySettings";
|
||||
Names[48] = "Shader";
|
||||
Names[49] = "TextAsset";
|
||||
Names[50] = "Rigidbody2D";
|
||||
Names[51] = "Physics2DManager";
|
||||
Names[53] = "Collider2D";
|
||||
Names[54] = "Rigidbody";
|
||||
Names[55] = "PhysicsManager";
|
||||
Names[56] = "Collider";
|
||||
Names[57] = "Joint";
|
||||
Names[58] = "CircleCollider2D";
|
||||
Names[59] = "HingeJoint";
|
||||
Names[60] = "PolygonCollider2D";
|
||||
Names[61] = "BoxCollider2D";
|
||||
Names[62] = "PhysicsMaterial2D";
|
||||
Names[64] = "MeshCollider";
|
||||
Names[65] = "BoxCollider";
|
||||
Names[66] = "SpriteCollider2D";
|
||||
Names[68] = "EdgeCollider2D";
|
||||
Names[72] = "ComputeShader";
|
||||
Names[74] = "AnimationClip";
|
||||
Names[75] = "ConstantForce";
|
||||
Names[76] = "WorldParticleCollider";
|
||||
Names[78] = "TagManager";
|
||||
Names[81] = "AudioListener";
|
||||
Names[82] = "AudioSource";
|
||||
Names[83] = "AudioClip";
|
||||
Names[84] = "RenderTexture";
|
||||
Names[87] = "MeshParticleEmitter";
|
||||
Names[88] = "ParticleEmitter";
|
||||
Names[89] = "Cubemap";
|
||||
Names[90] = "Avatar";
|
||||
Names[91] = "AnimatorController";
|
||||
Names[92] = "GUILayer";
|
||||
Names[93] = "RuntimeAnimatorController";
|
||||
Names[94] = "ScriptMapper";
|
||||
Names[95] = "Animator";
|
||||
Names[96] = "TrailRenderer";
|
||||
Names[98] = "DelayedCallManager";
|
||||
Names[102] = "TextMesh";
|
||||
Names[104] = "RenderSettings";
|
||||
Names[108] = "Light";
|
||||
Names[109] = "CGProgram";
|
||||
Names[110] = "BaseAnimationTrack";
|
||||
Names[111] = "Animation";
|
||||
Names[114] = "MonoBehaviour";
|
||||
Names[115] = "MonoScript";
|
||||
Names[116] = "MonoManager";
|
||||
Names[117] = "Texture3D";
|
||||
Names[118] = "NewAnimationTrack";
|
||||
Names[119] = "Projector";
|
||||
Names[120] = "LineRenderer";
|
||||
Names[121] = "Flare";
|
||||
Names[122] = "Halo";
|
||||
Names[123] = "LensFlare";
|
||||
Names[124] = "FlareLayer";
|
||||
Names[125] = "HaloLayer";
|
||||
Names[126] = "NavMeshAreas";
|
||||
Names[127] = "HaloManager";
|
||||
Names[128] = "Font";
|
||||
Names[129] = "PlayerSettings";
|
||||
Names[130] = "NamedObject";
|
||||
Names[131] = "GUITexture";
|
||||
Names[132] = "GUIText";
|
||||
Names[133] = "GUIElement";
|
||||
Names[134] = "PhysicMaterial";
|
||||
Names[135] = "SphereCollider";
|
||||
Names[136] = "CapsuleCollider";
|
||||
Names[137] = "SkinnedMeshRenderer";
|
||||
Names[138] = "FixedJoint";
|
||||
Names[140] = "RaycastCollider";
|
||||
Names[141] = "BuildSettings";
|
||||
Names[142] = "AssetBundle";
|
||||
Names[143] = "CharacterController";
|
||||
Names[144] = "CharacterJoint";
|
||||
Names[145] = "SpringJoint";
|
||||
Names[146] = "WheelCollider";
|
||||
Names[147] = "ResourceManager";
|
||||
Names[148] = "NetworkView";
|
||||
Names[149] = "NetworkManager";
|
||||
Names[150] = "PreloadData";
|
||||
Names[152] = "MovieTexture";
|
||||
Names[153] = "ConfigurableJoint";
|
||||
Names[154] = "TerrainCollider";
|
||||
Names[155] = "MasterServerInterface";
|
||||
Names[156] = "TerrainData";
|
||||
Names[157] = "LightmapSettings";
|
||||
Names[158] = "WebCamTexture";
|
||||
Names[159] = "EditorSettings";
|
||||
Names[160] = "InteractiveCloth";
|
||||
Names[161] = "ClothRenderer";
|
||||
Names[162] = "EditorUserSettings";
|
||||
Names[163] = "SkinnedCloth";
|
||||
Names[164] = "AudioReverbFilter";
|
||||
Names[165] = "AudioHighPassFilter";
|
||||
Names[166] = "AudioChorusFilter";
|
||||
Names[167] = "AudioReverbZone";
|
||||
Names[168] = "AudioEchoFilter";
|
||||
Names[169] = "AudioLowPassFilter";
|
||||
Names[170] = "AudioDistortionFilter";
|
||||
Names[171] = "SparseTexture";
|
||||
Names[180] = "AudioBehaviour";
|
||||
Names[181] = "AudioFilter";
|
||||
Names[182] = "WindZone";
|
||||
Names[183] = "Cloth";
|
||||
Names[184] = "SubstanceArchive";
|
||||
Names[185] = "ProceduralMaterial";
|
||||
Names[186] = "ProceduralTexture";
|
||||
Names[191] = "OffMeshLink";
|
||||
Names[192] = "OcclusionArea";
|
||||
Names[193] = "Tree";
|
||||
Names[194] = "NavMeshObsolete";
|
||||
Names[195] = "NavMeshAgent";
|
||||
Names[196] = "NavMeshSettings";
|
||||
Names[197] = "LightProbesLegacy";
|
||||
Names[198] = "ParticleSystem";
|
||||
Names[199] = "ParticleSystemRenderer";
|
||||
Names[200] = "ShaderVariantCollection";
|
||||
Names[205] = "LODGroup";
|
||||
Names[206] = "BlendTree";
|
||||
Names[207] = "Motion";
|
||||
Names[208] = "NavMeshObstacle";
|
||||
Names[210] = "TerrainInstance";
|
||||
Names[212] = "SpriteRenderer";
|
||||
Names[213] = "Sprite";
|
||||
Names[214] = "CachedSpriteAtlas";
|
||||
Names[215] = "ReflectionProbe";
|
||||
Names[216] = "ReflectionProbes";
|
||||
Names[220] = "LightProbeGroup";
|
||||
Names[221] = "AnimatorOverrideController";
|
||||
Names[222] = "CanvasRenderer";
|
||||
Names[223] = "Canvas";
|
||||
Names[224] = "RectTransform";
|
||||
Names[225] = "CanvasGroup";
|
||||
Names[226] = "BillboardAsset";
|
||||
Names[227] = "BillboardRenderer";
|
||||
Names[228] = "SpeedTreeWindAsset";
|
||||
Names[229] = "AnchoredJoint2D";
|
||||
Names[230] = "Joint2D";
|
||||
Names[231] = "SpringJoint2D";
|
||||
Names[232] = "DistanceJoint2D";
|
||||
Names[233] = "HingeJoint2D";
|
||||
Names[234] = "SliderJoint2D";
|
||||
Names[235] = "WheelJoint2D";
|
||||
Names[238] = "NavMeshData";
|
||||
Names[240] = "AudioMixer";
|
||||
Names[241] = "AudioMixerController";
|
||||
Names[243] = "AudioMixerGroupController";
|
||||
Names[244] = "AudioMixerEffectController";
|
||||
Names[245] = "AudioMixerSnapshotController";
|
||||
Names[246] = "PhysicsUpdateBehaviour2D";
|
||||
Names[247] = "ConstantForce2D";
|
||||
Names[248] = "Effector2D";
|
||||
Names[249] = "AreaEffector2D";
|
||||
Names[250] = "PointEffector2D";
|
||||
Names[251] = "PlatformEffector2D";
|
||||
Names[252] = "SurfaceEffector2D";
|
||||
Names[258] = "LightProbes";
|
||||
Names[271] = "SampleClip";
|
||||
Names[272] = "AudioMixerSnapshot";
|
||||
Names[273] = "AudioMixerGroup";
|
||||
Names[290] = "AssetBundleManifest";
|
||||
Names[300] = "RuntimeInitializeOnLoadManager";
|
||||
Names[301] = "CloudWebServicesManager";
|
||||
Names[310] = "UnityConnectSettings";
|
||||
Names[1001] = "Prefab";
|
||||
Names[1002] = "EditorExtensionImpl";
|
||||
Names[1003] = "AssetImporter";
|
||||
Names[1004] = "AssetDatabase";
|
||||
Names[1005] = "Mesh3DSImporter";
|
||||
Names[1006] = "TextureImporter";
|
||||
Names[1007] = "ShaderImporter";
|
||||
Names[1008] = "ComputeShaderImporter";
|
||||
Names[1011] = "AvatarMask";
|
||||
Names[1020] = "AudioImporter";
|
||||
Names[1026] = "HierarchyState";
|
||||
Names[1027] = "GUIDSerializer";
|
||||
Names[1028] = "AssetMetaData";
|
||||
Names[1029] = "DefaultAsset";
|
||||
Names[1030] = "DefaultImporter";
|
||||
Names[1031] = "TextScriptImporter";
|
||||
Names[1032] = "SceneAsset";
|
||||
Names[1034] = "NativeFormatImporter";
|
||||
Names[1035] = "MonoImporter";
|
||||
Names[1037] = "AssetServerCache";
|
||||
Names[1038] = "LibraryAssetImporter";
|
||||
Names[1040] = "ModelImporter";
|
||||
Names[1041] = "FBXImporter";
|
||||
Names[1042] = "TrueTypeFontImporter";
|
||||
Names[1044] = "MovieImporter";
|
||||
Names[1045] = "EditorBuildSettings";
|
||||
Names[1046] = "DDSImporter";
|
||||
Names[1048] = "InspectorExpandedState";
|
||||
Names[1049] = "AnnotationManager";
|
||||
Names[1050] = "PluginImporter";
|
||||
Names[1051] = "EditorUserBuildSettings";
|
||||
Names[1052] = "PVRImporter";
|
||||
Names[1053] = "ASTCImporter";
|
||||
Names[1054] = "KTXImporter";
|
||||
Names[1101] = "AnimatorStateTransition";
|
||||
Names[1102] = "AnimatorState";
|
||||
Names[1105] = "HumanTemplate";
|
||||
Names[1107] = "AnimatorStateMachine";
|
||||
Names[1108] = "PreviewAssetType";
|
||||
Names[1109] = "AnimatorTransition";
|
||||
Names[1110] = "SpeedTreeImporter";
|
||||
Names[1111] = "AnimatorTransitionBase";
|
||||
Names[1112] = "SubstanceImporter";
|
||||
Names[1113] = "LightmapParameters";
|
||||
Names[1120] = "LightmapSnapshot";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
157
Unity Studio/Unity Studio Classes/EndianStream.cs
Normal file
157
Unity Studio/Unity Studio Classes/EndianStream.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public enum EndianType
|
||||
{
|
||||
BigEndian,
|
||||
LittleEndian
|
||||
}
|
||||
|
||||
public class EndianStream : BinaryReader
|
||||
{
|
||||
public EndianType endian;
|
||||
private byte[] a16 = new byte[2];
|
||||
private byte[] a32 = new byte[4];
|
||||
private byte[] a64 = new byte[8];
|
||||
|
||||
public EndianStream(Stream stream, EndianType endian) : base(stream) { }
|
||||
|
||||
public long Position { get { return base.BaseStream.Position; } set { base.BaseStream.Position = value; } }
|
||||
|
||||
public override short ReadInt16()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a16 = base.ReadBytes(2);
|
||||
Array.Reverse(a16);
|
||||
return BitConverter.ToInt16(a16, 0);
|
||||
}
|
||||
else return base.ReadInt16();
|
||||
}
|
||||
|
||||
public override int ReadInt32()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a32 = base.ReadBytes(4);
|
||||
Array.Reverse(a32);
|
||||
return BitConverter.ToInt32(a32, 0);
|
||||
}
|
||||
else return base.ReadInt32();
|
||||
}
|
||||
|
||||
public override long ReadInt64()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a64 = base.ReadBytes(8);
|
||||
Array.Reverse(a64);
|
||||
return BitConverter.ToInt64(a64, 0);
|
||||
}
|
||||
else return base.ReadInt64();
|
||||
}
|
||||
|
||||
public override ushort ReadUInt16()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a16 = base.ReadBytes(2);
|
||||
Array.Reverse(a16);
|
||||
return BitConverter.ToUInt16(a16, 0);
|
||||
}
|
||||
else return base.ReadUInt16();
|
||||
}
|
||||
|
||||
public override uint ReadUInt32()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a32 = base.ReadBytes(4);
|
||||
Array.Reverse(a32);
|
||||
return BitConverter.ToUInt32(a32, 0);
|
||||
}
|
||||
else return base.ReadUInt32();
|
||||
}
|
||||
|
||||
public override ulong ReadUInt64()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a64 = base.ReadBytes(8);
|
||||
Array.Reverse(a64);
|
||||
return BitConverter.ToUInt64(a64, 0);
|
||||
}
|
||||
else return base.ReadUInt64();
|
||||
}
|
||||
|
||||
public override float ReadSingle()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a32 = base.ReadBytes(4);
|
||||
Array.Reverse(a32);
|
||||
return BitConverter.ToSingle(a32, 0);
|
||||
}
|
||||
else return base.ReadSingle();
|
||||
}
|
||||
|
||||
public override double ReadDouble()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a64 = base.ReadBytes(8);
|
||||
Array.Reverse(a64);
|
||||
return BitConverter.ToUInt64(a64, 0);
|
||||
}
|
||||
else return base.ReadDouble();
|
||||
}
|
||||
|
||||
public string ReadASCII(int length)
|
||||
{
|
||||
return Encoding.ASCII.GetString(base.ReadBytes(length));
|
||||
}
|
||||
|
||||
public void AlignStream(int alignment)
|
||||
{
|
||||
long pos = base.BaseStream.Position;
|
||||
//long padding = alignment - pos + (pos / alignment) * alignment;
|
||||
//if (padding != alignment) { base.BaseStream.Position += padding; }
|
||||
if ((pos % alignment) != 0) { base.BaseStream.Position += alignment - (pos % alignment); }
|
||||
}
|
||||
|
||||
public string ReadAlignedString(int length)
|
||||
{
|
||||
if (length > 0 && length < (base.BaseStream.Length - base.BaseStream.Position))//crude failsafe
|
||||
{
|
||||
byte[] stringData = new byte[length];
|
||||
base.Read(stringData, 0, length);
|
||||
var result = Encoding.UTF8.GetString(stringData); //must verify strange characters in PS3
|
||||
|
||||
/*string result = "";
|
||||
char c;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
c = (char)base.ReadByte();
|
||||
result += c.ToString();
|
||||
}*/
|
||||
|
||||
AlignStream(4);
|
||||
return result;
|
||||
}
|
||||
else { return ""; }
|
||||
}
|
||||
|
||||
public string ReadStringToNull()
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
byte b;
|
||||
while ((b = ReadByte()) != 0)
|
||||
bytes.Add(b);
|
||||
return Encoding.UTF8.GetString(bytes.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
544
Unity Studio/Unity Studio Classes/Lz4DecoderStream.cs
Normal file
544
Unity Studio/Unity Studio Classes/Lz4DecoderStream.cs
Normal file
@ -0,0 +1,544 @@
|
||||
#define CHECK_ARGS
|
||||
#define CHECK_EOF
|
||||
//#define LOCAL_SHADOW
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Lz4
|
||||
{
|
||||
public class Lz4DecoderStream : Stream
|
||||
{
|
||||
public Lz4DecoderStream()
|
||||
{
|
||||
}
|
||||
|
||||
public Lz4DecoderStream( Stream input, long inputLength = long.MaxValue )
|
||||
{
|
||||
Reset( input, inputLength );
|
||||
}
|
||||
|
||||
public void Reset( Stream input, long inputLength = long.MaxValue )
|
||||
{
|
||||
this.inputLength = inputLength;
|
||||
this.input = input;
|
||||
|
||||
phase = DecodePhase.ReadToken;
|
||||
|
||||
decodeBufferPos = 0;
|
||||
|
||||
litLen = 0;
|
||||
matLen = 0;
|
||||
matDst = 0;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
this.input = null;
|
||||
}
|
||||
|
||||
private long inputLength;
|
||||
private Stream input;
|
||||
|
||||
//because we might not be able to match back across invocations,
|
||||
//we have to keep the last window's worth of bytes around for reuse
|
||||
//we use a circular buffer for this - every time we write into this
|
||||
//buffer, we also write the same into our output buffer
|
||||
|
||||
private const int DecBufLen = 0x10000;
|
||||
private const int DecBufMask = 0xFFFF;
|
||||
|
||||
private const int InBufLen = 128;
|
||||
|
||||
private byte[] decodeBuffer = new byte[DecBufLen + InBufLen];
|
||||
private int decodeBufferPos, inBufPos, inBufEnd;
|
||||
|
||||
//we keep track of which phase we're in so that we can jump right back
|
||||
//into the correct part of decoding
|
||||
|
||||
private DecodePhase phase;
|
||||
|
||||
private enum DecodePhase
|
||||
{
|
||||
ReadToken,
|
||||
ReadExLiteralLength,
|
||||
CopyLiteral,
|
||||
ReadOffset,
|
||||
ReadExMatchLength,
|
||||
CopyMatch,
|
||||
}
|
||||
|
||||
//state within interruptable phases and across phase boundaries is
|
||||
//kept here - again, so that we can punt out and restart freely
|
||||
|
||||
private int litLen, matLen, matDst;
|
||||
|
||||
public override int Read( byte[] buffer, int offset, int count )
|
||||
{
|
||||
#if CHECK_ARGS
|
||||
if( buffer == null )
|
||||
throw new ArgumentNullException( "buffer" );
|
||||
if( offset < 0 || count < 0 || buffer.Length - count < offset )
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if( input == null )
|
||||
throw new InvalidOperationException();
|
||||
#endif
|
||||
int nRead, nToRead = count;
|
||||
|
||||
var decBuf = decodeBuffer;
|
||||
|
||||
//the stringy gotos are obnoxious, but their purpose is to
|
||||
//make it *blindingly* obvious how the state machine transitions
|
||||
//back and forth as it reads - remember, we can yield out of
|
||||
//this routine in several places, and we must be able to re-enter
|
||||
//and pick up where we left off!
|
||||
|
||||
#if LOCAL_SHADOW
|
||||
var phase = this.phase;
|
||||
var inBufPos = this.inBufPos;
|
||||
var inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
switch( phase )
|
||||
{
|
||||
case DecodePhase.ReadToken:
|
||||
goto readToken;
|
||||
|
||||
case DecodePhase.ReadExLiteralLength:
|
||||
goto readExLiteralLength;
|
||||
|
||||
case DecodePhase.CopyLiteral:
|
||||
goto copyLiteral;
|
||||
|
||||
case DecodePhase.ReadOffset:
|
||||
goto readOffset;
|
||||
|
||||
case DecodePhase.ReadExMatchLength:
|
||||
goto readExMatchLength;
|
||||
|
||||
case DecodePhase.CopyMatch:
|
||||
goto copyMatch;
|
||||
}
|
||||
|
||||
readToken:
|
||||
int tok;
|
||||
if( inBufPos < inBufEnd )
|
||||
{
|
||||
tok = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
|
||||
tok = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if( tok == -1 )
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
litLen = tok >> 4;
|
||||
matLen = (tok & 0xF) + 4;
|
||||
|
||||
switch( litLen )
|
||||
{
|
||||
case 0:
|
||||
phase = DecodePhase.ReadOffset;
|
||||
goto readOffset;
|
||||
|
||||
case 0xF:
|
||||
phase = DecodePhase.ReadExLiteralLength;
|
||||
goto readExLiteralLength;
|
||||
|
||||
default:
|
||||
phase = DecodePhase.CopyLiteral;
|
||||
goto copyLiteral;
|
||||
}
|
||||
|
||||
readExLiteralLength:
|
||||
int exLitLen;
|
||||
if( inBufPos < inBufEnd )
|
||||
{
|
||||
exLitLen = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
exLitLen = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
|
||||
#if CHECK_EOF
|
||||
if( exLitLen == -1 )
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
litLen += exLitLen;
|
||||
if( exLitLen == 255 )
|
||||
goto readExLiteralLength;
|
||||
|
||||
phase = DecodePhase.CopyLiteral;
|
||||
goto copyLiteral;
|
||||
|
||||
copyLiteral:
|
||||
int nReadLit = litLen < nToRead ? litLen : nToRead;
|
||||
if( nReadLit != 0 )
|
||||
{
|
||||
if( inBufPos + nReadLit <= inBufEnd )
|
||||
{
|
||||
int ofs = offset;
|
||||
|
||||
for( int c = nReadLit; c-- != 0; )
|
||||
buffer[ofs++] = decBuf[inBufPos++];
|
||||
|
||||
nRead = nReadLit;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
nRead = ReadCore( buffer, offset, nReadLit );
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if( nRead == 0 )
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
offset += nRead;
|
||||
nToRead -= nRead;
|
||||
|
||||
litLen -= nRead;
|
||||
|
||||
if( litLen != 0 )
|
||||
goto copyLiteral;
|
||||
}
|
||||
|
||||
if( nToRead == 0 )
|
||||
goto finish;
|
||||
|
||||
phase = DecodePhase.ReadOffset;
|
||||
goto readOffset;
|
||||
|
||||
readOffset:
|
||||
if( inBufPos + 1 < inBufEnd )
|
||||
{
|
||||
matDst = (decBuf[inBufPos + 1] << 8) | decBuf[inBufPos];
|
||||
inBufPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
matDst = ReadOffsetCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if( matDst == -1 )
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
if( matLen == 15 + 4 )
|
||||
{
|
||||
phase = DecodePhase.ReadExMatchLength;
|
||||
goto readExMatchLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
phase = DecodePhase.CopyMatch;
|
||||
goto copyMatch;
|
||||
}
|
||||
|
||||
readExMatchLength:
|
||||
int exMatLen;
|
||||
if( inBufPos < inBufEnd )
|
||||
{
|
||||
exMatLen = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
exMatLen = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if( exMatLen == -1 )
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
matLen += exMatLen;
|
||||
if( exMatLen == 255 )
|
||||
goto readExMatchLength;
|
||||
|
||||
phase = DecodePhase.CopyMatch;
|
||||
goto copyMatch;
|
||||
|
||||
copyMatch:
|
||||
int nCpyMat = matLen < nToRead ? matLen : nToRead;
|
||||
if( nCpyMat != 0 )
|
||||
{
|
||||
nRead = count - nToRead;
|
||||
|
||||
int bufDst = matDst - nRead;
|
||||
if( bufDst > 0 )
|
||||
{
|
||||
//offset is fairly far back, we need to pull from the buffer
|
||||
|
||||
int bufSrc = decodeBufferPos - bufDst;
|
||||
if( bufSrc < 0 )
|
||||
bufSrc += DecBufLen;
|
||||
int bufCnt = bufDst < nCpyMat ? bufDst : nCpyMat;
|
||||
|
||||
for( int c = bufCnt; c-- != 0; )
|
||||
buffer[offset++] = decBuf[bufSrc++ & DecBufMask];
|
||||
}
|
||||
else
|
||||
{
|
||||
bufDst = 0;
|
||||
}
|
||||
|
||||
int sOfs = offset - matDst;
|
||||
for( int i = bufDst; i < nCpyMat; i++ )
|
||||
buffer[offset++] = buffer[sOfs++];
|
||||
|
||||
nToRead -= nCpyMat;
|
||||
matLen -= nCpyMat;
|
||||
}
|
||||
|
||||
if( nToRead == 0 )
|
||||
goto finish;
|
||||
|
||||
phase = DecodePhase.ReadToken;
|
||||
goto readToken;
|
||||
|
||||
finish:
|
||||
nRead = count - nToRead;
|
||||
|
||||
int nToBuf = nRead < DecBufLen ? nRead : DecBufLen;
|
||||
int repPos = offset - nToBuf;
|
||||
|
||||
if( nToBuf == DecBufLen )
|
||||
{
|
||||
Buffer.BlockCopy( buffer, repPos, decBuf, 0, DecBufLen );
|
||||
decodeBufferPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int decPos = decodeBufferPos;
|
||||
|
||||
while( nToBuf-- != 0 )
|
||||
decBuf[decPos++ & DecBufMask] = buffer[repPos++];
|
||||
|
||||
decodeBufferPos = decPos & DecBufMask;
|
||||
}
|
||||
|
||||
#if LOCAL_SHADOW
|
||||
this.phase = phase;
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
return nRead;
|
||||
}
|
||||
|
||||
private int ReadByteCore()
|
||||
{
|
||||
var buf = decodeBuffer;
|
||||
|
||||
if( inBufPos == inBufEnd )
|
||||
{
|
||||
int nRead = input.Read( buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength );
|
||||
|
||||
#if CHECK_EOF
|
||||
if( nRead == 0 )
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
}
|
||||
|
||||
return buf[inBufPos++];
|
||||
}
|
||||
|
||||
private int ReadOffsetCore()
|
||||
{
|
||||
var buf = decodeBuffer;
|
||||
|
||||
if( inBufPos == inBufEnd )
|
||||
{
|
||||
int nRead = input.Read( buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength );
|
||||
|
||||
#if CHECK_EOF
|
||||
if( nRead == 0 )
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
}
|
||||
|
||||
if( inBufEnd - inBufPos == 1 )
|
||||
{
|
||||
buf[DecBufLen] = buf[inBufPos];
|
||||
|
||||
int nRead = input.Read( buf, DecBufLen + 1,
|
||||
InBufLen - 1 < inputLength ? InBufLen - 1 : (int)inputLength );
|
||||
|
||||
#if CHECK_EOF
|
||||
if( nRead == 0 )
|
||||
{
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead + 1;
|
||||
}
|
||||
|
||||
int ret = (buf[inBufPos + 1] << 8) | buf[inBufPos];
|
||||
inBufPos += 2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int ReadCore( byte[] buffer, int offset, int count )
|
||||
{
|
||||
int nToRead = count;
|
||||
|
||||
var buf = decodeBuffer;
|
||||
int inBufLen = inBufEnd - inBufPos;
|
||||
|
||||
int fromBuf = nToRead < inBufLen ? nToRead : inBufLen;
|
||||
if( fromBuf != 0 )
|
||||
{
|
||||
var bufPos = inBufPos;
|
||||
|
||||
for( int c = fromBuf; c-- != 0; )
|
||||
buffer[offset++] = buf[bufPos++];
|
||||
|
||||
inBufPos = bufPos;
|
||||
nToRead -= fromBuf;
|
||||
}
|
||||
|
||||
if( nToRead != 0 )
|
||||
{
|
||||
int nRead;
|
||||
|
||||
if( nToRead >= InBufLen )
|
||||
{
|
||||
nRead = input.Read( buffer, offset,
|
||||
nToRead < inputLength ? nToRead : (int)inputLength );
|
||||
nToRead -= nRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRead = input.Read( buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength );
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
|
||||
fromBuf = nToRead < nRead ? nToRead : nRead;
|
||||
|
||||
var bufPos = inBufPos;
|
||||
|
||||
for( int c = fromBuf; c-- != 0; )
|
||||
buffer[offset++] = buf[bufPos++];
|
||||
|
||||
inBufPos = bufPos;
|
||||
nToRead -= fromBuf;
|
||||
}
|
||||
|
||||
inputLength -= nRead;
|
||||
}
|
||||
|
||||
return count - nToRead;
|
||||
}
|
||||
|
||||
#region Stream internals
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get { throw new NotSupportedException(); }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public override long Seek( long offset, SeekOrigin origin )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength( long value )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write( byte[] buffer, int offset, int count )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
1750
Unity Studio/Unity Studio Classes/UnityStudio.cs
Normal file
1750
Unity Studio/Unity Studio Classes/UnityStudio.cs
Normal file
File diff suppressed because it is too large
Load Diff
152
Unity Studio/Unity Studio Classes/helpers.cs
Normal file
152
Unity Studio/Unity Studio Classes/helpers.cs
Normal file
@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public class PPtr
|
||||
{
|
||||
//m_FileID 0 means current file
|
||||
public int m_FileID = -1;
|
||||
//m_PathID acts more like a hash in some games
|
||||
public long m_PathID = 0;
|
||||
}
|
||||
|
||||
public static class PPtrHelpers
|
||||
{
|
||||
public static PPtr ReadPPtr(this AssetsFile sourceFile)
|
||||
{
|
||||
PPtr result = new PPtr();
|
||||
var a_Stream = sourceFile.a_Stream;
|
||||
|
||||
int FileID = a_Stream.ReadInt32();
|
||||
if (FileID >= 0 && FileID < sourceFile.sharedAssetsList.Count)
|
||||
{ result.m_FileID = sourceFile.sharedAssetsList[FileID].Index; }
|
||||
|
||||
if (sourceFile.fileGen < 14) { result.m_PathID = a_Stream.ReadInt32(); }
|
||||
else { result.m_PathID = a_Stream.ReadInt64(); }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool TryGetPD(this List<AssetsFile> assetsfileList, PPtr m_elm, out AssetPreloadData result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (m_elm != null && m_elm.m_FileID >= 0 && m_elm.m_FileID < assetsfileList.Count)
|
||||
{
|
||||
AssetsFile sourceFile = assetsfileList[m_elm.m_FileID];
|
||||
|
||||
//TryGetValue should be safe because m_PathID is 0 when initialized and PathID values range from 1
|
||||
if (sourceFile.preloadTable.TryGetValue(m_elm.m_PathID, out result)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetTransform(this List<AssetsFile> assetsfileList, PPtr m_elm, out Transform m_Transform)
|
||||
{
|
||||
m_Transform = null;
|
||||
|
||||
if (m_elm != null && m_elm.m_FileID >= 0 && m_elm.m_FileID < assetsfileList.Count)
|
||||
{
|
||||
AssetsFile sourceFile = assetsfileList[m_elm.m_FileID];
|
||||
|
||||
if (sourceFile.TransformList.TryGetValue(m_elm.m_PathID, out m_Transform)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetGameObject(this List<AssetsFile> assetsfileList, PPtr m_elm, out GameObject m_GameObject)
|
||||
{
|
||||
m_GameObject = null;
|
||||
|
||||
if (m_elm != null && m_elm.m_FileID >= 0 && m_elm.m_FileID < assetsfileList.Count)
|
||||
{
|
||||
AssetsFile sourceFile = assetsfileList[m_elm.m_FileID];
|
||||
|
||||
if (sourceFile.GameObjectList.TryGetValue(m_elm.m_PathID, out m_GameObject)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void ParseGameObject(this List<AssetsFile> assetsfileList, GameObject m_GameObject)
|
||||
{
|
||||
foreach (var m_Component in m_GameObject.m_Components)
|
||||
{
|
||||
if (m_Component.m_FileID >= 0 && m_Component.m_FileID < assetsfileList.Count)
|
||||
{
|
||||
AssetsFile sourceFile = assetsfileList[m_Component.m_FileID];
|
||||
AssetPreloadData asset;
|
||||
if (sourceFile.preloadTable.TryGetValue(m_Component.m_PathID, out asset))
|
||||
{
|
||||
switch (asset.Type2)
|
||||
{
|
||||
case 4: //Transform
|
||||
{
|
||||
m_GameObject.m_Transform = m_Component;
|
||||
break;
|
||||
}
|
||||
case 23: //MeshRenderer
|
||||
{
|
||||
m_GameObject.m_MeshRenderer = m_Component;
|
||||
break;
|
||||
}
|
||||
case 33: //MeshFilter
|
||||
{
|
||||
m_GameObject.m_MeshFilter = m_Component;
|
||||
break;
|
||||
}
|
||||
case 137: //SkinnedMeshRenderer
|
||||
{
|
||||
m_GameObject.m_SkinnedMeshRenderer = m_Component;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TexEnv
|
||||
{
|
||||
public string name;
|
||||
public PPtr m_Texture;
|
||||
public float[] m_Scale;
|
||||
public float[] m_Offset;
|
||||
}
|
||||
|
||||
class strFloatPair
|
||||
{
|
||||
public string first;
|
||||
public float second;
|
||||
}
|
||||
|
||||
class strColorPair
|
||||
{
|
||||
public string first;
|
||||
public float[] second;
|
||||
}
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the string against a given pattern.
|
||||
/// </summary>
|
||||
/// <param name="str">The string.</param>
|
||||
/// <param name="pattern">The pattern to match, where "*" means any sequence of characters, and "?" means any single character.</param>
|
||||
/// <returns><c>true</c> if the string matches the given pattern; otherwise <c>false</c>.</returns>
|
||||
public static bool Like(this string str, string pattern)
|
||||
{
|
||||
return new Regex(
|
||||
"^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Singleline
|
||||
).IsMatch(str);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user