public static string GetScriptString(AssetPreloadData assetPreloadData) { if (!moduleLoaded) { var openFolderDialog = new OpenFolderDialog(); openFolderDialog.Title = "Select Assembly Folder"; if (openFolderDialog.ShowDialog() == DialogResult.OK) { var files = Directory.GetFiles(openFolderDialog.Folder, "*.dll"); var moduleContext = new ModuleContext(); var asmResolver = new AssemblyResolver(moduleContext, true); var resolver = new Resolver(asmResolver); moduleContext.AssemblyResolver = asmResolver; moduleContext.Resolver = resolver; try { foreach (var file in files) { var module = ModuleDefMD.Load(file, moduleContext); LoadedModuleDic.Add(Path.GetFileName(file), module); } } catch { // ignored } } moduleLoaded = true; } var m_MonoBehaviour = new MonoBehaviour(assetPreloadData); var sb = new StringBuilder(); sb.AppendLine("PPtr<GameObject> m_GameObject"); sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_GameObject.m_FileID}"); sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_GameObject.m_PathID}"); sb.AppendLine($"UInt8 m_Enabled = {m_MonoBehaviour.m_Enabled}"); sb.AppendLine("PPtr<MonoScript> m_Script"); sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_Script.m_FileID}"); sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_Script.m_PathID}"); sb.AppendLine($"string m_Name = \"{m_MonoBehaviour.m_Name}\""); if (assetsfileList.TryGetPD(m_MonoBehaviour.m_Script, out var script)) { var m_Script = new MonoScript(script); if (!LoadedModuleDic.TryGetValue(m_Script.m_AssemblyName, out var module)) { /*using (var openFileDialog = new OpenFileDialog()) * { * openFileDialog.Title = $"Select {m_Script.m_AssemblyName}"; * openFileDialog.FileName = m_Script.m_AssemblyName; * openFileDialog.Filter = $"{m_Script.m_AssemblyName}|{m_Script.m_AssemblyName}"; * if (openFileDialog.ShowDialog() == DialogResult.OK) * { * var moduleContext = new ModuleContext(); * var asmResolver = new AssemblyResolver(moduleContext, true); * var resolver = new Resolver(asmResolver); * moduleContext.AssemblyResolver = asmResolver; * moduleContext.Resolver = resolver; * module = ModuleDefMD.Load(openFileDialog.FileName, moduleContext); * LoadedModule.Add(m_Script.m_AssemblyName, module); * } * else * { * return sb.ToString(); * } * }*/ return(sb.ToString()); } var typeDef = module.Assembly.Find(m_Script.m_Namespace != "" ? $"{m_Script.m_Namespace}.{m_Script.m_ClassName}" : m_Script.m_ClassName, false); if (typeDef != null) { try { DumpType(typeDef.ToTypeSig(), sb, assetPreloadData.sourceFile, null, -1, true); } catch { sb = new StringBuilder(); sb.AppendLine("PPtr<GameObject> m_GameObject"); sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_GameObject.m_FileID}"); sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_GameObject.m_PathID}"); sb.AppendLine($"UInt8 m_Enabled = {m_MonoBehaviour.m_Enabled}"); sb.AppendLine("PPtr<MonoScript> m_Script"); sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_Script.m_FileID}"); sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_Script.m_PathID}"); sb.AppendLine($"string m_Name = \"{m_MonoBehaviour.m_Name}\""); } } } return(sb.ToString()); }
private void ReadAssets() { Logger.Info("Read assets..."); var progressCount = assetsFileList.Sum(x => x.m_Objects.Count); int i = 0; Progress.Reset(); foreach (var assetsFile in assetsFileList) { foreach (var objectInfo in assetsFile.m_Objects) { var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo); try { Object obj; switch (objectReader.type) { case ClassIDType.Animation: obj = new Animation(objectReader); break; case ClassIDType.AnimationClip: obj = new AnimationClip(objectReader); break; case ClassIDType.Animator: obj = new Animator(objectReader); break; case ClassIDType.AnimatorController: obj = new AnimatorController(objectReader); break; case ClassIDType.AnimatorOverrideController: obj = new AnimatorOverrideController(objectReader); break; case ClassIDType.AssetBundle: obj = new AssetBundle(objectReader); break; case ClassIDType.AudioClip: obj = new AudioClip(objectReader); break; case ClassIDType.Avatar: obj = new Avatar(objectReader); break; case ClassIDType.Font: obj = new Font(objectReader); break; case ClassIDType.GameObject: obj = new GameObject(objectReader); break; case ClassIDType.Material: obj = new Material(objectReader); break; case ClassIDType.Mesh: obj = new Mesh(objectReader); break; case ClassIDType.MeshFilter: obj = new MeshFilter(objectReader); break; case ClassIDType.MeshRenderer: obj = new MeshRenderer(objectReader); break; case ClassIDType.MonoBehaviour: obj = new MonoBehaviour(objectReader); break; case ClassIDType.MonoScript: obj = new MonoScript(objectReader); break; case ClassIDType.MovieTexture: obj = new MovieTexture(objectReader); break; case ClassIDType.PlayerSettings: obj = new PlayerSettings(objectReader); break; case ClassIDType.RectTransform: obj = new RectTransform(objectReader); break; case ClassIDType.Shader: obj = new Shader(objectReader); break; case ClassIDType.SkinnedMeshRenderer: obj = new SkinnedMeshRenderer(objectReader); break; case ClassIDType.Sprite: obj = new Sprite(objectReader); break; case ClassIDType.SpriteAtlas: obj = new SpriteAtlas(objectReader); break; case ClassIDType.TextAsset: obj = new TextAsset(objectReader); break; case ClassIDType.Texture2D: obj = new Texture2D(objectReader); break; case ClassIDType.Transform: obj = new Transform(objectReader); break; case ClassIDType.VideoClip: obj = new VideoClip(objectReader); break; default: obj = new Object(objectReader); break; } assetsFile.AddObject(obj); } catch (Exception e) { /*var sb = new StringBuilder(); * sb.AppendLine("Unable to load object") * .AppendLine($"Assets {assetsFile.fileName}") * .AppendLine($"Type {objectReader.type}") * .AppendLine($"PathID {objectInfo.m_PathID}") * .Append(e); * Logger.Error(sb.ToString());*/ } Progress.Report(++i, progressCount); } } }
public static void BuildAssetStructures(bool loadAssets, bool displayAll, bool buildHierarchy, bool buildClassStructures, bool displayOriginalName, out List <GameObject> fileNodes) { fileNodes = null; #region first loop - read asset data & create list if (loadAssets) { SetProgressBarValue(0); SetProgressBarMaximum(assetsfileList.Sum(x => x.preloadTable.Values.Count)); StatusStripUpdate("Building asset list..."); string fileIDfmt = "D" + assetsfileList.Count.ToString().Length; for (var i = 0; i < assetsfileList.Count; i++) { var assetsFile = assetsfileList[i]; string fileID = i.ToString(fileIDfmt); AssetBundle ab = null; foreach (var asset in assetsFile.preloadTable.Values) { asset.uniqueID = fileID + asset.uniqueID; var exportable = false; switch (asset.Type) { case ClassIDReference.GameObject: { GameObject m_GameObject = new GameObject(asset); assetsFile.GameObjectList.Add(asset.m_PathID, m_GameObject); break; } case ClassIDReference.Transform: { Transform m_Transform = new Transform(asset); assetsFile.TransformList.Add(asset.m_PathID, m_Transform); break; } case ClassIDReference.RectTransform: { RectTransform m_Rect = new RectTransform(asset); assetsFile.TransformList.Add(asset.m_PathID, m_Rect.m_Transform); break; } case ClassIDReference.Texture2D: { Texture2D m_Texture2D = new Texture2D(asset, false); exportable = true; break; } case ClassIDReference.Shader: { Shader m_Shader = new Shader(asset, false); exportable = true; break; } case ClassIDReference.TextAsset: { TextAsset m_TextAsset = new TextAsset(asset, false); exportable = true; break; } case ClassIDReference.AudioClip: { AudioClip m_AudioClip = new AudioClip(asset, false); exportable = true; break; } case ClassIDReference.MonoBehaviour: { var m_MonoBehaviour = new MonoBehaviour(asset); if (m_MonoBehaviour.m_Name == "" && assetsfileList.TryGetPD(m_MonoBehaviour.m_Script, out var script)) { var m_Script = new MonoScript(script); asset.Text = m_Script.m_ClassName; } else { asset.Text = m_MonoBehaviour.m_Name; } exportable = true; break; } case ClassIDReference.Font: { UFont m_Font = new UFont(asset, false); exportable = true; break; } case ClassIDReference.PlayerSettings: { var plSet = new PlayerSettings(asset); productName = plSet.productName; break; } case ClassIDReference.Mesh: { Mesh m_Mesh = new Mesh(asset, false); exportable = true; break; } case ClassIDReference.AssetBundle: { ab = new AssetBundle(asset); break; } case ClassIDReference.VideoClip: { var m_VideoClip = new VideoClip(asset, false); exportable = true; break; } case ClassIDReference.MovieTexture: { var m_MovieTexture = new MovieTexture(asset, false); exportable = true; break; } case ClassIDReference.Sprite: { var m_Sprite = new Sprite(asset, false); exportable = true; break; } case ClassIDReference.Animator: { exportable = true; break; } case ClassIDReference.AnimationClip: { exportable = true; var reader = asset.sourceFile.reader; reader.Position = asset.Offset; asset.Text = reader.ReadAlignedString(); break; } } if (asset.Text == "") { asset.Text = asset.TypeString + " #" + asset.uniqueID; } asset.SubItems.AddRange(new[] { asset.TypeString, asset.fullSize.ToString() }); //处理同名文件 if (!assetsNameHash.Add((asset.TypeString + asset.Text).ToUpper())) { asset.Text += " #" + asset.uniqueID; } //处理非法文件名 asset.Text = FixFileName(asset.Text); if (displayAll) { exportable = true; } if (exportable) { assetsFile.exportableAssets.Add(asset); } ProgressBarPerformStep(); } if (displayOriginalName) { assetsFile.exportableAssets.ForEach(x => { var replacename = ab?.m_Container.Find(y => y.second.asset.m_PathID == x.m_PathID)?.first; if (!string.IsNullOrEmpty(replacename)) { var ex = Path.GetExtension(replacename); x.Text = !string.IsNullOrEmpty(ex) ? replacename.Replace(ex, "") : replacename; } }); } exportableAssets.AddRange(assetsFile.exportableAssets); } visibleAssets = exportableAssets; assetsNameHash.Clear(); } #endregion #region second loop - build tree structure if (buildHierarchy) { fileNodes = new List <GameObject>(); var gameObjectCount = assetsfileList.Sum(x => x.GameObjectList.Values.Count); if (gameObjectCount > 0) { SetProgressBarValue(0); SetProgressBarMaximum(gameObjectCount); StatusStripUpdate("Building tree structure..."); foreach (var assetsFile in assetsfileList) { GameObject fileNode = new GameObject(null); fileNode.Text = Path.GetFileName(assetsFile.filePath); fileNode.m_Name = "RootNode"; foreach (var m_GameObject in assetsFile.GameObjectList.Values) { foreach (var m_Component in m_GameObject.m_Components) { if (m_Component.m_FileID >= 0 && m_Component.m_FileID < assetsfileList.Count) { var sourceFile = assetsfileList[m_Component.m_FileID]; if (sourceFile.preloadTable.TryGetValue(m_Component.m_PathID, out var asset)) { switch (asset.Type) { case ClassIDReference.Transform: { m_GameObject.m_Transform = m_Component; break; } case ClassIDReference.MeshRenderer: { m_GameObject.m_MeshRenderer = m_Component; break; } case ClassIDReference.MeshFilter: { m_GameObject.m_MeshFilter = m_Component; if (assetsfileList.TryGetPD(m_Component, out var assetPreloadData)) { var m_MeshFilter = new MeshFilter(assetPreloadData); if (assetsfileList.TryGetPD(m_MeshFilter.m_Mesh, out assetPreloadData)) { assetPreloadData.gameObject = m_GameObject; } } break; } case ClassIDReference.SkinnedMeshRenderer: { m_GameObject.m_SkinnedMeshRenderer = m_Component; if (assetsfileList.TryGetPD(m_Component, out var assetPreloadData)) { var m_SkinnedMeshRenderer = new SkinnedMeshRenderer(assetPreloadData); if (assetsfileList.TryGetPD(m_SkinnedMeshRenderer.m_Mesh, out assetPreloadData)) { assetPreloadData.gameObject = m_GameObject; } } break; } case ClassIDReference.Animator: { m_GameObject.m_Animator = m_Component; asset.Text = m_GameObject.asset.Text; break; } } } } } var parentNode = fileNode; if (assetsfileList.TryGetTransform(m_GameObject.m_Transform, out var m_Transform)) { if (assetsfileList.TryGetTransform(m_Transform.m_Father, out var m_Father)) { if (assetsfileList.TryGetGameObject(m_Father.m_GameObject, out parentNode)) { } } } parentNode.Nodes.Add(m_GameObject); ProgressBarPerformStep(); } if (fileNode.Nodes.Count > 0) { fileNodes.Add(fileNode); } } } } #endregion #region build list of class strucutres if (buildClassStructures) { //group class structures by versionv foreach (var assetsFile in assetsfileList) { if (AllClassStructures.TryGetValue(assetsFile.m_Version, out var curVer)) { foreach (var uClass in assetsFile.ClassStructures) { curVer[uClass.Key] = uClass.Value; } } else { AllClassStructures.Add(assetsFile.m_Version, assetsFile.ClassStructures); } } } #endregion }
public static void BuildAssetStructures(bool loadAssets, bool displayAll, bool buildHierarchy, bool buildClassStructures, bool displayOriginalName) { #region first loop - read asset data & create list if (loadAssets) { SetProgressBarValue(0); SetProgressBarMaximum(assetsfileList.Sum(x => x.preloadTable.Values.Count)); StatusStripUpdate("Building asset list..."); string fileIDfmt = "D" + assetsfileList.Count.ToString().Length; for (var i = 0; i < assetsfileList.Count; i++) { var assetsFile = assetsfileList[i]; string fileID = i.ToString(fileIDfmt); AssetBundle ab = null; foreach (var asset in assetsFile.preloadTable.Values) { asset.uniqueID = fileID + asset.uniqueID; var exportable = false; switch (asset.Type) { case ClassIDType.GameObject: { var m_GameObject = new GameObject(asset); asset.Text = m_GameObject.m_Name; assetsFile.GameObjectList.Add(asset.m_PathID, m_GameObject); break; } case ClassIDType.Transform: { var m_Transform = new Transform(asset); assetsFile.TransformList.Add(asset.m_PathID, m_Transform); break; } case ClassIDType.RectTransform: { var m_Rect = new RectTransform(asset); assetsFile.TransformList.Add(asset.m_PathID, m_Rect); break; } case ClassIDType.Texture2D: { var m_Texture2D = new Texture2D(asset, false); if (!string.IsNullOrEmpty(m_Texture2D.path)) { asset.FullSize = asset.Size + m_Texture2D.size; } goto case ClassIDType.NamedObject; } case ClassIDType.AudioClip: { var m_AudioClip = new AudioClip(asset, false); if (!string.IsNullOrEmpty(m_AudioClip.m_Source)) { asset.FullSize = asset.Size + m_AudioClip.m_Size; } goto case ClassIDType.NamedObject; } case ClassIDType.VideoClip: { var m_VideoClip = new VideoClip(asset, false); if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath)) { asset.FullSize = asset.Size + (long)m_VideoClip.m_Size; } goto case ClassIDType.NamedObject; } case ClassIDType.NamedObject: case ClassIDType.Mesh: case ClassIDType.Shader: case ClassIDType.TextAsset: case ClassIDType.AnimationClip: case ClassIDType.Font: case ClassIDType.MovieTexture: case ClassIDType.Sprite: { var obj = new NamedObject(asset); asset.Text = obj.m_Name; exportable = true; break; } case ClassIDType.Avatar: case ClassIDType.AnimatorController: case ClassIDType.AnimatorOverrideController: case ClassIDType.Material: case ClassIDType.MonoScript: case ClassIDType.SpriteAtlas: { var obj = new NamedObject(asset); asset.Text = obj.m_Name; break; } case ClassIDType.Animator: { exportable = true; break; } case ClassIDType.MonoBehaviour: { var m_MonoBehaviour = new MonoBehaviour(asset); if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGetPD(out var script)) { var m_Script = new MonoScript(script); asset.Text = m_Script.m_ClassName; } else { asset.Text = m_MonoBehaviour.m_Name; } exportable = true; break; } case ClassIDType.PlayerSettings: { var plSet = new PlayerSettings(asset); productName = plSet.productName; break; } case ClassIDType.AssetBundle: { ab = new AssetBundle(asset); asset.Text = ab.m_Name; break; } } if (asset.Text == "") { asset.Text = asset.TypeString + " #" + asset.uniqueID; } asset.SubItems.AddRange(new[] { asset.TypeString, asset.FullSize.ToString() }); //处理同名文件 if (!assetsNameHash.Add((asset.TypeString + asset.Text).ToUpper())) { asset.Text += " #" + asset.uniqueID; } //处理非法文件名 asset.Text = FixFileName(asset.Text); if (displayAll) { exportable = true; } if (exportable) { assetsFile.exportableAssets.Add(asset); } ProgressBarPerformStep(); } if (displayOriginalName) { assetsFile.exportableAssets.ForEach(x => { var replacename = ab?.m_Container.Find(y => y.second.asset.m_PathID == x.m_PathID)?.first; if (!string.IsNullOrEmpty(replacename)) { var ex = Path.GetExtension(replacename); x.Text = !string.IsNullOrEmpty(ex) ? replacename.Replace(ex, "") : replacename; } }); } exportableAssets.AddRange(assetsFile.exportableAssets); } visibleAssets = exportableAssets; assetsNameHash.Clear(); } #endregion #region second loop - build tree structure if (buildHierarchy) { var gameObjectCount = assetsfileList.Sum(x => x.GameObjectList.Values.Count); if (gameObjectCount > 0) { SetProgressBarValue(0); SetProgressBarMaximum(gameObjectCount); StatusStripUpdate("Building tree structure..."); foreach (var assetsFile in assetsfileList) { var fileNode = new GameObjectTreeNode(null); //RootNode fileNode.Text = assetsFile.fileName; foreach (var m_GameObject in assetsFile.GameObjectList.Values) { foreach (var m_Component in m_GameObject.m_Components) { if (m_Component.TryGetPD(out var asset)) { switch (asset.Type) { case ClassIDType.Transform: { m_GameObject.m_Transform = m_Component; break; } case ClassIDType.MeshRenderer: { m_GameObject.m_MeshRenderer = m_Component; break; } case ClassIDType.MeshFilter: { m_GameObject.m_MeshFilter = m_Component; if (m_Component.TryGetPD(out var assetPreloadData)) { var m_MeshFilter = new MeshFilter(assetPreloadData); if (m_MeshFilter.m_Mesh.TryGetPD(out assetPreloadData)) { assetPreloadData.gameObject = m_GameObject; } } break; } case ClassIDType.SkinnedMeshRenderer: { m_GameObject.m_SkinnedMeshRenderer = m_Component; if (m_Component.TryGetPD(out var assetPreloadData)) { var m_SkinnedMeshRenderer = new SkinnedMeshRenderer(assetPreloadData); if (m_SkinnedMeshRenderer.m_Mesh.TryGetPD(out assetPreloadData)) { assetPreloadData.gameObject = m_GameObject; } } break; } case ClassIDType.Animator: { m_GameObject.m_Animator = m_Component; asset.Text = m_GameObject.preloadData.Text; break; } } } } var parentNode = fileNode; if (m_GameObject.m_Transform != null && m_GameObject.m_Transform.TryGetTransform(out var m_Transform)) { if (m_Transform.m_Father.TryGetTransform(out var m_Father)) { if (m_Father.m_GameObject.TryGetGameObject(out var parentGameObject)) { if (!treeNodeDictionary.TryGetValue(parentGameObject, out parentNode)) { parentNode = new GameObjectTreeNode(parentGameObject); treeNodeDictionary.Add(parentGameObject, parentNode); } } } } if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode)) { currentNode = new GameObjectTreeNode(m_GameObject); treeNodeDictionary.Add(m_GameObject, currentNode); } parentNode.Nodes.Add(currentNode); ProgressBarPerformStep(); } if (fileNode.Nodes.Count > 0) { treeNodeCollection.Add(fileNode); } } } } #endregion #region build list of class strucutres if (buildClassStructures) { foreach (var assetsFile in assetsfileList) { if (AllTypeMap.TryGetValue(assetsFile.unityVersion, out var curVer)) { foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null)) { var key = type.classID; if (type.m_ScriptTypeIndex >= 0) { key = -1 - type.m_ScriptTypeIndex; } curVer[key] = new TypeTreeItem(key, type.m_Nodes); } } else { var items = new SortedDictionary <int, TypeTreeItem>(); foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null)) { var key = type.classID; if (type.m_ScriptTypeIndex >= 0) { key = -1 - type.m_ScriptTypeIndex; } items.Add(key, new TypeTreeItem(key, type.m_Nodes)); } AllTypeMap.Add(assetsFile.unityVersion, items); } } } #endregion }