UnityBinFileDefines.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. using static HybridCLR.Editor.GlobalManagers.UnityBinUtils;
  6. namespace HybridCLR.Editor.GlobalManagers
  7. {
  8. public struct FileHeader
  9. {
  10. public const int kSize = 20;
  11. public uint dataSize => fileSize - metadataSize;
  12. public uint metadataSize;
  13. public uint fileSize;
  14. public uint version;
  15. public uint dataOffset;
  16. public byte endianess;
  17. public void LoadFromStream(BinaryReader br)
  18. {
  19. long startPos = br.BaseStream.Position;
  20. metadataSize = br.ReadUInt32();
  21. fileSize = br.ReadUInt32();
  22. version = br.ReadUInt32();
  23. dataOffset = br.ReadUInt32();
  24. endianess = br.ReadByte();
  25. br.BaseStream.Position = startPos + kSize;
  26. SwapEndianess();
  27. }
  28. public long SaveToStream(BinaryWriter bw)
  29. {
  30. SwapEndianess();
  31. long startPos = bw.BaseStream.Position;
  32. bw.Write(metadataSize);
  33. bw.Write(fileSize);
  34. bw.Write(version);
  35. bw.Write(dataOffset);
  36. bw.Write(endianess);
  37. bw.BaseStream.Position = startPos + kSize;
  38. return kSize;
  39. }
  40. void SwapEndianess()
  41. {
  42. SwapUInt(ref metadataSize);
  43. SwapUInt(ref fileSize);
  44. SwapUInt(ref version);
  45. SwapUInt(ref dataOffset);
  46. }
  47. }
  48. public struct MetaData
  49. {
  50. public long dataStartPos;
  51. public string version;
  52. public uint platform;
  53. public bool enableTypeTree;
  54. public int typeCount;
  55. public ObjectType[] types;
  56. public int objectCount;
  57. public Dictionary<long, ObjectInfo> objects;
  58. public int scriptTypeCount;
  59. public ScriptType[] scriptTypes;
  60. public int externalsCount;
  61. public ExternalInfo[] externals;
  62. #if UNITY_2019_2_OR_NEWER
  63. public int refTypeCount;
  64. public ObjectType[] refTypes;
  65. #endif
  66. public string dummyStr;
  67. public void LoadFromStream(BinaryReader br, uint dataOffset)
  68. {
  69. long startPos = br.BaseStream.Position;
  70. dataStartPos = startPos;
  71. version = br.ReadRawString();
  72. platform = br.ReadUInt32();
  73. enableTypeTree = br.ReadBoolean();
  74. typeCount = br.ReadInt32();
  75. types = new ObjectType[typeCount];
  76. for (int i = 0; i < typeCount; i++)
  77. {
  78. types[i].LoadFromStream(br);
  79. }
  80. objectCount = br.ReadInt32();
  81. objects = new Dictionary<long, ObjectInfo>();
  82. for(int i = 0; i < objectCount; i++)
  83. {
  84. long id = br.AlignedReadInt64();
  85. ObjectInfo objInfo = new ObjectInfo();
  86. objInfo.LoadFromStream(br);
  87. objInfo.realPos = objInfo.dataPos + dataOffset;
  88. objects.Add(id, objInfo);
  89. }
  90. scriptTypeCount = br.ReadInt32();
  91. scriptTypes = new ScriptType[scriptTypeCount];
  92. for(int i = 0; i < scriptTypeCount; i++)
  93. {
  94. scriptTypes[i].LoadFromStream(br);
  95. }
  96. externalsCount = br.ReadInt32();
  97. externals = new ExternalInfo[externalsCount];
  98. for(int i = 0; i < externalsCount; i++)
  99. {
  100. externals[i].LoadFromStream(br);
  101. }
  102. #if UNITY_2019_2_OR_NEWER
  103. refTypeCount = br.ReadInt32();
  104. refTypes = new ObjectType[refTypeCount];
  105. for(int i = 0; i < refTypeCount; i++)
  106. {
  107. refTypes[i].LoadFromStream(br);
  108. }
  109. #endif
  110. dummyStr = br.ReadRawString();
  111. }
  112. public long SaveToStream(BinaryWriter bw)
  113. {
  114. long startPos = bw.BaseStream.Position;
  115. bw.WriteRawString(version);
  116. bw.Write(platform);
  117. bw.Write(enableTypeTree);
  118. bw.Write(typeCount);
  119. foreach(var type in types)
  120. type.SaveToStream(bw);
  121. bw.Write(objectCount);
  122. foreach (var kv in objects)
  123. {
  124. bw.AlignedWriteInt64(kv.Key);
  125. kv.Value.SaveToStream(bw);
  126. }
  127. bw.Write(scriptTypeCount);
  128. foreach(var st in scriptTypes)
  129. st.SaveToStream(bw);
  130. bw.Write(externalsCount);
  131. foreach(var external in externals)
  132. external.SaveToStream(bw);
  133. #if UNITY_2019_2_OR_NEWER
  134. bw.Write(refTypeCount);
  135. foreach(var refT in refTypes)
  136. refT.SaveToStream(bw);
  137. #endif
  138. bw.WriteRawString(dummyStr);
  139. return bw.BaseStream.Position - startPos;
  140. }
  141. public ScriptsData GetScriptData(BinaryReader br)
  142. {
  143. ObjectInfo objInfo = objects[UnityBinFile.kMonoManagerIdx];
  144. br.BaseStream.Seek(objInfo.realPos, SeekOrigin.Begin);
  145. ScriptsData data = new ScriptsData();
  146. data.LoadFromStream(br);
  147. return data;
  148. }
  149. }
  150. public struct ObjectType
  151. {
  152. public int typeID;
  153. public bool isStriped;
  154. public short scriptTypeIndex;
  155. public bool needReadScriptHash; // dont save
  156. public Hash scriptSigHash;
  157. public Hash typeHash;
  158. public void LoadFromStream(BinaryReader br)
  159. {
  160. typeID = br.ReadInt32();
  161. isStriped = br.ReadBoolean();
  162. scriptTypeIndex = br.ReadInt16();
  163. needReadScriptHash = typeID == -1 || typeID == 0x72;
  164. if(needReadScriptHash)
  165. scriptSigHash.LoadFromStream(br);
  166. typeHash.LoadFromStream(br);
  167. // GlobalManagers does not has TypeTrees
  168. }
  169. public long SaveToStream(BinaryWriter bw)
  170. {
  171. long startPos = bw.BaseStream.Position;
  172. bw.Write(typeID);
  173. bw.Write(isStriped);
  174. bw.Write(scriptTypeIndex);
  175. if(needReadScriptHash)
  176. scriptSigHash.SaveToStream(bw);
  177. typeHash.SaveToStream(bw);
  178. return bw.BaseStream.Position - startPos;
  179. }
  180. public int Size()
  181. {
  182. int ret = 0;
  183. ret += sizeof(int);
  184. ret += sizeof(bool);
  185. ret += sizeof(short);
  186. if (needReadScriptHash)
  187. ret += Hash.kSize;
  188. ret += Hash.kSize;
  189. return ret;
  190. }
  191. }
  192. public struct ObjectInfo
  193. {
  194. public const int kSize = 12;
  195. public uint dataPos;
  196. public uint size;
  197. public uint typeID;
  198. public uint realPos; // dataPos + Header.dataOffset; // dont save
  199. public void LoadFromStream(BinaryReader br)
  200. {
  201. dataPos = br.ReadUInt32();
  202. size = br.ReadUInt32();
  203. typeID = br.ReadUInt32();
  204. }
  205. public long SaveToStream(BinaryWriter bw)
  206. {
  207. bw.Write(dataPos);
  208. bw.Write(size);
  209. bw.Write(typeID);
  210. return kSize;
  211. }
  212. }
  213. public struct ScriptType
  214. {
  215. public int localFileIndex;
  216. public long localIdentifierOfBin;
  217. public void LoadFromStream(BinaryReader br)
  218. {
  219. localFileIndex = br.ReadInt32();
  220. localIdentifierOfBin = br.AlignedReadInt64();
  221. }
  222. public long SaveToStream(BinaryWriter bw)
  223. {
  224. long startPos = bw.BaseStream.Position;
  225. bw.Write(localFileIndex);
  226. bw.AlignedWriteInt64(localIdentifierOfBin);
  227. return bw.BaseStream.Position - startPos;
  228. }
  229. }
  230. public struct ExternalInfo
  231. {
  232. public string dummy;
  233. public Hash guid;
  234. public int type;
  235. public string name;
  236. public void LoadFromStream(BinaryReader br)
  237. {
  238. dummy = br.ReadRawString();
  239. guid.LoadFromStream(br);
  240. type = br.ReadInt32();
  241. name = br.ReadRawString();
  242. }
  243. public long SaveToStream(BinaryWriter bw)
  244. {
  245. long startPos = bw.BaseStream.Position;
  246. bw.WriteRawString(dummy);
  247. guid.SaveToStream(bw);
  248. bw.Write(type);
  249. bw.WriteRawString(name);
  250. return bw.BaseStream.Position - startPos;
  251. }
  252. }
  253. public struct ScriptsData
  254. {
  255. public ScriptID[] scriptIDs;
  256. public List<string> dllNames;
  257. public List<int> dllTypes; // 16 is user type
  258. public void LoadFromStream(BinaryReader br)
  259. {
  260. {
  261. int count = br.ReadInt32();
  262. scriptIDs = new ScriptID[count];
  263. for(int i = 0; i < count; i++)
  264. scriptIDs[i].LoadFromStream(br);
  265. }
  266. {
  267. int count = br.ReadInt32();
  268. dllNames = new List<string>(count);
  269. for (var i = 0; i < count; i++)
  270. dllNames.Add(br.ReadSizeString());
  271. }
  272. {
  273. int count = br.ReadInt32();
  274. dllTypes = new List<int>(count);
  275. for(var i = 0; i < count; i++)
  276. dllTypes.Add(br.ReadInt32());
  277. }
  278. }
  279. public long SaveToStream(BinaryWriter bw)
  280. {
  281. long startPos = bw.BaseStream.Position;
  282. bw.Write(scriptIDs.Length);
  283. for(int i = 0; i < scriptIDs.Length; i++)
  284. scriptIDs[i].SaveToStream(bw);
  285. bw.Write(dllNames.Count);
  286. for(int i = 0, imax = dllNames.Count; i < imax; i++)
  287. bw.WriteSizeString(dllNames[i]);
  288. bw.Write(dllTypes.Count);
  289. for(int i = 0, imax = dllTypes.Count; i < imax; i++)
  290. bw.Write(dllTypes[i]);
  291. return bw.BaseStream.Position - startPos;
  292. }
  293. }
  294. public struct ScriptID
  295. {
  296. public int fileID;
  297. public long pathID; // localIdentifier
  298. public void LoadFromStream(BinaryReader br)
  299. {
  300. fileID = br.ReadInt32();
  301. pathID = br.ReadInt64();
  302. }
  303. public long SaveToStream(BinaryWriter bw)
  304. {
  305. bw.Write(fileID);
  306. bw.Write(pathID);
  307. return 4 + 8;
  308. }
  309. }
  310. public struct Hash
  311. {
  312. public const int kSize = 16;
  313. public int[] data;
  314. public void LoadFromStream(BinaryReader br)
  315. {
  316. data = new int[4];
  317. for(int i = 0; i < data.Length; i++)
  318. {
  319. data[i] = br.ReadInt32();
  320. }
  321. }
  322. public long SaveToStream(BinaryWriter bw)
  323. {
  324. for(int i = 0; i < data.Length; i++)
  325. {
  326. bw.Write(data[i]);
  327. }
  328. return kSize;
  329. }
  330. }
  331. }