diff --git a/AssetStudio/Classes/Object.cs b/AssetStudio/Classes/Object.cs index 471480e..ad2c6a1 100644 --- a/AssetStudio/Classes/Object.cs +++ b/AssetStudio/Classes/Object.cs @@ -25,7 +25,7 @@ namespace AssetStudio public uint byteSize; [JsonIgnore] public string Name; - private static JsonSerializerOptions jsonOptions; + private static readonly JsonSerializerOptions jsonOptions; static Object() { @@ -95,6 +95,24 @@ namespace AssetStudio return TypeTreeHelper.ReadType(m_Type, reader); } + public JsonDocument ToJsonDoc(TypeTree m_Type = null) + { + var typeDict = ToType(m_Type); + try + { + if (typeDict != null) + { + return JsonSerializer.SerializeToDocument(typeDict); + } + return JsonSerializer.SerializeToDocument(this, GetType(), jsonOptions); + } + catch + { + //ignore + } + return null; + } + public byte[] GetRawData() { reader.Reset(); diff --git a/AssetStudio/TypeTreeHelper.cs b/AssetStudio/TypeTreeHelper.cs index 8d88f60..237653d 100644 --- a/AssetStudio/TypeTreeHelper.cs +++ b/AssetStudio/TypeTreeHelper.cs @@ -198,13 +198,21 @@ namespace AssetStudio reader.Reset(); var obj = new OrderedDictionary(); var m_Nodes = m_Types.m_Nodes; - for (int i = 1; i < m_Nodes.Count; i++) + var readed = 0L; + try { - var m_Node = m_Nodes[i]; - var varNameStr = m_Node.m_Name; - obj[varNameStr] = ReadValue(m_Nodes, reader, ref i); + for (int i = 1; i < m_Nodes.Count; i++) + { + var m_Node = m_Nodes[i]; + var varNameStr = m_Node.m_Name; + obj[varNameStr] = ReadValue(m_Nodes, reader, ref i); + } + readed = reader.Position - reader.byteStart; + } + catch (Exception) + { + //Ignore } - var readed = reader.Position - reader.byteStart; if (readed != reader.byteSize) { Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes"); diff --git a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs index a325b29..462cfc3 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs @@ -43,6 +43,7 @@ this.assetLoadingToolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); this.enablePreview = new System.Windows.Forms.ToolStripMenuItem(); this.displayInfo = new System.Windows.Forms.ToolStripMenuItem(); + this.useDumpTreeViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.buildTreeStructureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.customCompressionTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.customCompressionZstdToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -138,17 +139,18 @@ this.textPreviewBox = new System.Windows.Forms.TextBox(); this.classTextBox = new System.Windows.Forms.TextBox(); this.tabPage5 = new System.Windows.Forms.TabPage(); + this.dumpTreeView = new System.Windows.Forms.TreeView(); this.dumpTextBox = new System.Windows.Forms.TextBox(); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); - this.contextMenuStrip2 = new System.Windows.Forms.ContextMenuStrip(this.components); - this.showRelatedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); - this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.clearSelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this.expandAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.collapseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sceneContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.shShowRelatedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.shSelectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shSlearSelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.shExpandAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shCollapseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.timer = new System.Windows.Forms.Timer(this.components); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); @@ -162,6 +164,11 @@ this.exportL2DWithClipsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.dumpTreeViewContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.tvCopyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.tvToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.tvExpandAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.tvCollapseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); @@ -182,8 +189,9 @@ ((System.ComponentModel.ISupportInitialize)(this.FMODvolumeBar)).BeginInit(); this.tabPage5.SuspendLayout(); this.statusStrip1.SuspendLayout(); - this.contextMenuStrip2.SuspendLayout(); + this.sceneContextMenuStrip.SuspendLayout(); this.contextMenuStrip1.SuspendLayout(); + this.dumpTreeViewContextMenuStrip.SuspendLayout(); this.SuspendLayout(); // // menuStrip1 @@ -257,6 +265,7 @@ this.assetLoadingToolStripSeparator, this.enablePreview, this.displayInfo, + this.useDumpTreeViewToolStripMenuItem, this.buildTreeStructureToolStripMenuItem, this.customCompressionTypeToolStripMenuItem, this.toolStripMenuItem14, @@ -316,6 +325,14 @@ "t, audio bitrate, etc."; this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check); // + // useDumpTreeViewToolStripMenuItem + // + this.useDumpTreeViewToolStripMenuItem.CheckOnClick = true; + this.useDumpTreeViewToolStripMenuItem.Name = "useDumpTreeViewToolStripMenuItem"; + this.useDumpTreeViewToolStripMenuItem.Size = new System.Drawing.Size(241, 22); + this.useDumpTreeViewToolStripMenuItem.Text = "Use tree view to display dump"; + this.useDumpTreeViewToolStripMenuItem.CheckedChanged += new System.EventHandler(this.useDumpTreeViewToolStripMenuItem_CheckedChanged); + // // buildTreeStructureToolStripMenuItem // this.buildTreeStructureToolStripMenuItem.Checked = true; @@ -1271,6 +1288,7 @@ // // tabPage5 // + this.tabPage5.Controls.Add(this.dumpTreeView); this.tabPage5.Controls.Add(this.dumpTextBox); this.tabPage5.Location = new System.Drawing.Point(4, 22); this.tabPage5.Name = "tabPage5"; @@ -1279,6 +1297,16 @@ this.tabPage5.Text = "Dump"; this.tabPage5.UseVisualStyleBackColor = true; // + // dumpTreeView + // + this.dumpTreeView.Dock = System.Windows.Forms.DockStyle.Fill; + this.dumpTreeView.Location = new System.Drawing.Point(0, 0); + this.dumpTreeView.Name = "dumpTreeView"; + this.dumpTreeView.Size = new System.Drawing.Size(768, 607); + this.dumpTreeView.TabIndex = 1; + this.dumpTreeView.Visible = false; + this.dumpTreeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.DumpTreeView_NodeMouseClick); + // // dumpTextBox // this.dumpTextBox.BackColor = System.Drawing.SystemColors.Window; @@ -1313,64 +1341,64 @@ this.toolStripStatusLabel1.Text = "Ready to go"; this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // - // contextMenuStrip2 + // sceneContextMenuStrip // - this.contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.showRelatedAssetsToolStripMenuItem, - this.toolStripSeparator7, - this.selectAllToolStripMenuItem, - this.clearSelectionToolStripMenuItem, - this.toolStripSeparator5, - this.expandAllToolStripMenuItem, - this.collapseAllToolStripMenuItem}); - this.contextMenuStrip2.Name = "contextMenuStrip2"; - this.contextMenuStrip2.Size = new System.Drawing.Size(152, 126); - this.contextMenuStrip2.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip2_Opening); + this.sceneContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.shShowRelatedAssetsToolStripMenuItem, + this.shToolStripSeparator1, + this.shSelectAllToolStripMenuItem, + this.shSlearSelectionToolStripMenuItem, + this.shToolStripSeparator2, + this.shExpandAllToolStripMenuItem, + this.shCollapseAllToolStripMenuItem}); + this.sceneContextMenuStrip.Name = "contextMenuStrip2"; + this.sceneContextMenuStrip.Size = new System.Drawing.Size(152, 126); + this.sceneContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip2_Opening); // - // showRelatedAssetsToolStripMenuItem + // shShowRelatedAssetsToolStripMenuItem // - this.showRelatedAssetsToolStripMenuItem.Name = "showRelatedAssetsToolStripMenuItem"; - this.showRelatedAssetsToolStripMenuItem.Size = new System.Drawing.Size(151, 22); - this.showRelatedAssetsToolStripMenuItem.Text = "Related assets"; - this.showRelatedAssetsToolStripMenuItem.Click += new System.EventHandler(this.showRelatedAssetsToolStripMenuItem_Click); + this.shShowRelatedAssetsToolStripMenuItem.Name = "shShowRelatedAssetsToolStripMenuItem"; + this.shShowRelatedAssetsToolStripMenuItem.Size = new System.Drawing.Size(151, 22); + this.shShowRelatedAssetsToolStripMenuItem.Text = "Related assets"; + this.shShowRelatedAssetsToolStripMenuItem.Click += new System.EventHandler(this.showRelatedAssetsToolStripMenuItem_Click); // - // toolStripSeparator7 + // shToolStripSeparator1 // - this.toolStripSeparator7.Name = "toolStripSeparator7"; - this.toolStripSeparator7.Size = new System.Drawing.Size(148, 6); + this.shToolStripSeparator1.Name = "shToolStripSeparator1"; + this.shToolStripSeparator1.Size = new System.Drawing.Size(148, 6); // - // selectAllToolStripMenuItem + // shSelectAllToolStripMenuItem // - this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; - this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22); - this.selectAllToolStripMenuItem.Text = "Select all"; - this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click); + this.shSelectAllToolStripMenuItem.Name = "shSelectAllToolStripMenuItem"; + this.shSelectAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22); + this.shSelectAllToolStripMenuItem.Text = "Select all"; + this.shSelectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click); // - // clearSelectionToolStripMenuItem + // shSlearSelectionToolStripMenuItem // - this.clearSelectionToolStripMenuItem.Name = "clearSelectionToolStripMenuItem"; - this.clearSelectionToolStripMenuItem.Size = new System.Drawing.Size(151, 22); - this.clearSelectionToolStripMenuItem.Text = "Clear selection"; - this.clearSelectionToolStripMenuItem.Click += new System.EventHandler(this.clearSelectionToolStripMenuItem_Click); + this.shSlearSelectionToolStripMenuItem.Name = "shSlearSelectionToolStripMenuItem"; + this.shSlearSelectionToolStripMenuItem.Size = new System.Drawing.Size(151, 22); + this.shSlearSelectionToolStripMenuItem.Text = "Clear selection"; + this.shSlearSelectionToolStripMenuItem.Click += new System.EventHandler(this.clearSelectionToolStripMenuItem_Click); // - // toolStripSeparator5 + // shToolStripSeparator2 // - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(148, 6); + this.shToolStripSeparator2.Name = "shToolStripSeparator2"; + this.shToolStripSeparator2.Size = new System.Drawing.Size(148, 6); // - // expandAllToolStripMenuItem + // shExpandAllToolStripMenuItem // - this.expandAllToolStripMenuItem.Name = "expandAllToolStripMenuItem"; - this.expandAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22); - this.expandAllToolStripMenuItem.Text = "Expand all"; - this.expandAllToolStripMenuItem.Click += new System.EventHandler(this.expandAllToolStripMenuItem_Click); + this.shExpandAllToolStripMenuItem.Name = "shExpandAllToolStripMenuItem"; + this.shExpandAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22); + this.shExpandAllToolStripMenuItem.Text = "Expand all"; + this.shExpandAllToolStripMenuItem.Click += new System.EventHandler(this.expandAllToolStripMenuItem_Click); // - // collapseAllToolStripMenuItem + // shCollapseAllToolStripMenuItem // - this.collapseAllToolStripMenuItem.Name = "collapseAllToolStripMenuItem"; - this.collapseAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22); - this.collapseAllToolStripMenuItem.Text = "Collapse all"; - this.collapseAllToolStripMenuItem.Click += new System.EventHandler(this.collapseAllToolStripMenuItem_Click); + this.shCollapseAllToolStripMenuItem.Name = "shCollapseAllToolStripMenuItem"; + this.shCollapseAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22); + this.shCollapseAllToolStripMenuItem.Text = "Collapse all"; + this.shCollapseAllToolStripMenuItem.Click += new System.EventHandler(this.collapseAllToolStripMenuItem_Click); // // timer // @@ -1478,6 +1506,42 @@ this.showOriginalFileToolStripMenuItem.Visible = false; this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click); // + // dumpTreeViewContextMenuStrip + // + this.dumpTreeViewContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tvCopyToolStripMenuItem, + this.tvToolStripSeparator1, + this.tvExpandAllToolStripMenuItem, + this.tvCollapseAllToolStripMenuItem}); + this.dumpTreeViewContextMenuStrip.Name = "contextMenuStrip3"; + this.dumpTreeViewContextMenuStrip.Size = new System.Drawing.Size(135, 76); + // + // tvCopyToolStripMenuItem + // + this.tvCopyToolStripMenuItem.Name = "tvCopyToolStripMenuItem"; + this.tvCopyToolStripMenuItem.Size = new System.Drawing.Size(134, 22); + this.tvCopyToolStripMenuItem.Text = "Copy"; + this.tvCopyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem1_Click); + // + // tvToolStripSeparator1 + // + this.tvToolStripSeparator1.Name = "tvToolStripSeparator1"; + this.tvToolStripSeparator1.Size = new System.Drawing.Size(131, 6); + // + // tvExpandAllToolStripMenuItem + // + this.tvExpandAllToolStripMenuItem.Name = "tvExpandAllToolStripMenuItem"; + this.tvExpandAllToolStripMenuItem.Size = new System.Drawing.Size(134, 22); + this.tvExpandAllToolStripMenuItem.Text = "Expand all"; + this.tvExpandAllToolStripMenuItem.Click += new System.EventHandler(this.expandAllToolStripMenuItem1_Click); + // + // tvCollapseAllToolStripMenuItem + // + this.tvCollapseAllToolStripMenuItem.Name = "tvCollapseAllToolStripMenuItem"; + this.tvCollapseAllToolStripMenuItem.Size = new System.Drawing.Size(134, 22); + this.tvCollapseAllToolStripMenuItem.Text = "Collapse all"; + this.tvCollapseAllToolStripMenuItem.Click += new System.EventHandler(this.collapseAllToolStripMenuItem1_Click); + // // AssetStudioGUIForm // this.AllowDrop = true; @@ -1522,8 +1586,9 @@ this.tabPage5.PerformLayout(); this.statusStrip1.ResumeLayout(false); this.statusStrip1.PerformLayout(); - this.contextMenuStrip2.ResumeLayout(false); + this.sceneContextMenuStrip.ResumeLayout(false); this.contextMenuStrip1.ResumeLayout(false); + this.dumpTreeViewContextMenuStrip.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -1626,20 +1691,20 @@ private System.Windows.Forms.ToolStripTextBox specifyUnityVersion; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem15; private System.Windows.Forms.ToolStripMenuItem dumpSelectedAssetsToolStripMenuItem; - private System.Windows.Forms.ContextMenuStrip contextMenuStrip2; - private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem clearSelectionToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; - private System.Windows.Forms.ToolStripMenuItem collapseAllToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem expandAllToolStripMenuItem; + private System.Windows.Forms.ContextMenuStrip sceneContextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem shSelectAllToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem shSlearSelectionToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator shToolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem shCollapseAllToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem shExpandAllToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.ComboBox listSearchFilterMode; private System.Windows.Forms.ComboBox listSearchHistory; private System.Windows.Forms.RichTextBox listSearch; private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; - private System.Windows.Forms.ToolStripMenuItem showRelatedAssetsToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripMenuItem shShowRelatedAssetsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator shToolStripSeparator1; private System.Windows.Forms.ListView assetListView; private System.Windows.Forms.ToolStripMenuItem showConsoleToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem writeLogToFileToolStripMenuItem; @@ -1659,6 +1724,13 @@ private System.Windows.Forms.ToolStripMenuItem customCompressionLZ4ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem useAssetLoadingViaTypetreeToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator assetLoadingToolStripSeparator; + private System.Windows.Forms.TreeView dumpTreeView; + private System.Windows.Forms.ContextMenuStrip dumpTreeViewContextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem tvCopyToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator tvToolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem tvExpandAllToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem tvCollapseAllToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem useDumpTreeViewToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem colorThemeToolStripMenu; private System.Windows.Forms.ToolStripMenuItem colorThemeAutoToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem colorThemeLightToolStripMenuItem; diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 8a17621..def3d58 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -34,6 +34,7 @@ namespace AssetStudioGUI partial class AssetStudioGUIForm : Form { private AssetItem lastSelectedItem; + private AssetItem lastPreviewItem; private DirectBitmap imageTexture; private string tempClipboard; @@ -140,6 +141,7 @@ namespace AssetStudioGUI showConsoleToolStripMenuItem.Checked = Properties.Settings.Default.showConsole; buildTreeStructureToolStripMenuItem.Checked = Properties.Settings.Default.buildTreeStructure; useAssetLoadingViaTypetreeToolStripMenuItem.Checked = Properties.Settings.Default.useTypetreeLoading; + useDumpTreeViewToolStripMenuItem.Checked = Properties.Settings.Default.useDumpTreeView; FMODinit(); listSearchFilterMode.SelectedIndex = 0; @@ -776,7 +778,7 @@ namespace AssetStudioGUI var at = a.SubItems[sortColumn].Text.AsSpan(); var bt = b.SubItems[sortColumn].Text.AsSpan(); - return reverseSort ? MemoryExtensions.CompareTo(bt, at, StringComparison.OrdinalIgnoreCase) : MemoryExtensions.CompareTo(at, bt, StringComparison.OrdinalIgnoreCase); + return reverseSort ? bt.CompareTo(at, StringComparison.OrdinalIgnoreCase) : at.CompareTo(bt, StringComparison.OrdinalIgnoreCase); }); } assetListView.EndUpdate(); @@ -799,22 +801,44 @@ namespace AssetStudioGUI lastSelectedItem = (AssetItem)e.Item; - if (e.IsSelected) + if (!e.IsSelected) + return; + + switch (tabControl2.SelectedIndex) { - if (tabControl2.SelectedIndex == 1) - { - dumpTextBox.Text = DumpAsset(lastSelectedItem.Asset); - } - if (enablePreview.Checked) - { - PreviewAsset(lastSelectedItem); - if (displayInfo.Checked && lastSelectedItem.InfoText != null) + case 0: //Preview + if (enablePreview.Checked) { - assetInfoLabel.Text = lastSelectedItem.InfoText; - assetInfoLabel.Visible = true; + PreviewAsset(lastSelectedItem); + if (displayInfo.Checked && lastSelectedItem.InfoText != null) + { + assetInfoLabel.Text = lastSelectedItem.InfoText; + assetInfoLabel.Visible = true; + } } + break; + case 1: //Dump + DumpAsset(lastSelectedItem); + break; + } + } + + private void DumpAsset(AssetItem assetItem) + { + if (assetItem == null) + return; + + if (useDumpTreeViewToolStripMenuItem.Checked) + { + using (var jsonDoc = DumpAssetToJsonDoc(assetItem.Asset)) + { + dumpTreeView.LoadFromJson(jsonDoc, assetItem.Text); } } + else + { + dumpTextBox.Text = Studio.DumpAsset(assetItem.Asset); + } } private void classesListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) @@ -830,6 +854,7 @@ namespace AssetStudioGUI if (e.IsSelected) { classTextBox.Text = ((TypeTreeItem)classesListView.SelectedItems[0]).ToString(); + lastSelectedItem = null; } } @@ -844,6 +869,7 @@ namespace AssetStudioGUI private void PreviewAsset(AssetItem assetItem) { + lastPreviewItem = assetItem; if (assetItem == null) return; try @@ -1527,9 +1553,22 @@ namespace AssetStudioGUI private void tabControl2_SelectedIndexChanged(object sender, EventArgs e) { - if (tabControl2.SelectedIndex == 1 && lastSelectedItem != null) + switch (tabControl2.SelectedIndex) { - dumpTextBox.Text = DumpAsset(lastSelectedItem.Asset); + case 0: //Preview + if (lastPreviewItem != lastSelectedItem) + { + PreviewAsset(lastSelectedItem); + if (displayInfo.Checked && lastSelectedItem?.InfoText != null) + { + assetInfoLabel.Text = lastSelectedItem.InfoText; + assetInfoLabel.Visible = true; + } + } + break; + case 1: //Dump + DumpAsset(lastSelectedItem); + break; } } @@ -2047,7 +2086,7 @@ namespace AssetStudioGUI if (e.Button == MouseButtons.Right) { sceneTreeView.SelectedNode = e.Node; - contextMenuStrip2.Show(sceneTreeView, e.Location.X, e.Location.Y); + sceneContextMenuStrip.Show(sceneTreeView, e.Location.X, e.Location.Y); } } @@ -2162,7 +2201,7 @@ namespace AssetStudioGUI { var selectedNode = sceneTreeView.SelectedNode; var relatedAssets = visibleAssets.FindAll(x => x.TreeNode == selectedNode); - showRelatedAssetsToolStripMenuItem.DropDownItems.Clear(); + shShowRelatedAssetsToolStripMenuItem.DropDownItems.Clear(); if (relatedAssets.Count > 1) { var assetItem = new ToolStripMenuItem @@ -2173,7 +2212,7 @@ namespace AssetStudioGUI Text = "Select all" }; assetItem.Click += selectAllRelatedAssets; - showRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem); + shShowRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem); } foreach (var asset in relatedAssets) { @@ -2186,7 +2225,7 @@ namespace AssetStudioGUI Text = $"({asset.TypeString}) {asset.Text}" }; assetItem.Click += selectRelatedAsset; - showRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem); + shShowRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem); } } @@ -2462,6 +2501,55 @@ namespace AssetStudioGUI MessageBox.Show(msg, "Info", MessageBoxButtons.OK); } + private void DumpTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + dumpTreeView.SelectedNode = e.Node; + tempClipboard = string.IsNullOrEmpty((string)e.Node.Tag) + ? e.Node.Text + : $"{e.Node.Name}: {e.Node.Tag}"; + dumpTreeViewContextMenuStrip.Show(dumpTreeView, e.Location.X, e.Location.Y); + } + } + + private void copyToolStripMenuItem1_Click(object sender, EventArgs e) + { + Clipboard.SetDataObject(tempClipboard); + } + + private void expandAllToolStripMenuItem1_Click(object sender, EventArgs e) + { + dumpTreeView.BeginUpdate(); + foreach (TreeNode node in dumpTreeView.Nodes) + { + node.ExpandAll(); + } + dumpTreeView.EndUpdate(); + } + + private void collapseAllToolStripMenuItem1_Click(object sender, EventArgs e) + { + dumpTreeView.BeginUpdate(); + foreach (TreeNode node in dumpTreeView.Nodes) + { + node.Collapse(ignoreChildren: false); + } + dumpTreeView.EndUpdate(); + } + + private void useDumpTreeViewToolStripMenuItem_CheckedChanged(object sender, EventArgs e) + { + var isTreeViewEnabled = useDumpTreeViewToolStripMenuItem.Checked; + dumpTreeView.Visible = isTreeViewEnabled; + Properties.Settings.Default.useDumpTreeView = isTreeViewEnabled; + Properties.Settings.Default.Save(); + if (tabControl2.SelectedIndex == 1) + { + DumpAsset(lastSelectedItem); + } + } + #region FMOD private void FMODinit() { diff --git a/AssetStudioGUI/AssetStudioGUIForm.resx b/AssetStudioGUI/AssetStudioGUIForm.resx index 4c9e06c..cd1b776 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.resx +++ b/AssetStudioGUI/AssetStudioGUIForm.resx @@ -141,7 +141,7 @@ The quick brown fox jumps over the lazy dog. 1234567890 432, 17 - + 775, 21 @@ -153,7 +153,7 @@ The quick brown fox jumps over the lazy dog. 1234567890 147, 17 - + 930, 21 diff --git a/AssetStudioGUI/Components/JsonTreeView.cs b/AssetStudioGUI/Components/JsonTreeView.cs new file mode 100644 index 0000000..c2c2b42 --- /dev/null +++ b/AssetStudioGUI/Components/JsonTreeView.cs @@ -0,0 +1,105 @@ +using System.Text.Json; +using System.Windows.Forms; +using AssetStudio; + +namespace AssetStudioGUI +{ + public static class JsonTreeView + { + public static void LoadFromJson(this TreeView treeView, JsonDocument jsonDoc, string rootName) + { + if (jsonDoc == null) + { + Logger.Info("Unable to build tree view of current object"); + return; + } + + try + { + treeView.BeginUpdate(); + treeView.Nodes.Clear(); + var rootNode = treeView.Nodes[treeView.Nodes.Add(new TreeNode(rootName))]; + + foreach (var property in jsonDoc.RootElement.EnumerateObject()) + { + var childNode = rootNode.Nodes[rootNode.Nodes.Add(new TreeNode(property.Name))]; + AddNodes(property.Value, childNode); + } + + rootNode.Expand(); + rootNode.EnsureVisible(); + } + finally + { + treeView.EndUpdate(); + } + } + + private static void AddNodes(JsonElement jsonElement, TreeNode treeNode) + { + switch (jsonElement.ValueKind) + { + case JsonValueKind.Object: + foreach (var property in jsonElement.EnumerateObject()) + { + var childNode = treeNode.Nodes[treeNode.Nodes.Add(new TreeNode(property.Name))]; + AddNodes(property.Value, childNode); + } + break; + case JsonValueKind.Array: + const int arrayLenLimit = 500; + var arrayLen = jsonElement.GetArrayLength(); + if (arrayLen == 0) + { + SetValue(jsonElement, treeNode); + } + else + { + var i = 0; + foreach (var jsonArrayElem in jsonElement.EnumerateArray()) + { + if (jsonArrayElem.ValueKind == JsonValueKind.Number) //number array + { + SetValue(jsonElement, treeNode); + break; + } + + if (i > arrayLenLimit) + { + treeNode.Nodes.Add(new TreeNode($"[{i++}-{arrayLen - 1}] Skipped. Too many elements to display")); + break; + } + + var childNode = treeNode.Nodes[treeNode.Nodes.Add(new TreeNode($"[{i++}]"))]; + AddNodes(jsonArrayElem, childNode); + } + } + break; + default: + SetValue(jsonElement, treeNode); + break; + } + } + + private static void SetValue(JsonElement jsonElem, TreeNode node) + { + const int maxStrLen = 128; + var endStr = "..."; + var strValue = jsonElem.ToString(); + if (jsonElem.ValueKind == JsonValueKind.Array) + { + strValue = strValue.Replace("\r", "").Replace("\n", "").Replace(" ", "").Replace(",", ", "); + endStr += "]"; + } + if (jsonElem.ValueKind == JsonValueKind.Null) + { + strValue = jsonElem.GetRawText(); + } + node.Name = node.Text; + node.Text += strValue?.Length > maxStrLen + ? $": {strValue.Substring(0, maxStrLen)}{endStr}" + : $": {strValue}"; + node.Tag = strValue; + } + } +} diff --git a/AssetStudioGUI/Properties/Settings.Designer.cs b/AssetStudioGUI/Properties/Settings.Designer.cs index 89dc268..8be7e78 100644 --- a/AssetStudioGUI/Properties/Settings.Designer.cs +++ b/AssetStudioGUI/Properties/Settings.Designer.cs @@ -430,5 +430,17 @@ namespace AssetStudioGUI.Properties { this["l2dAssetSearchByFilename"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool useDumpTreeView { + get { + return ((bool)(this["useDumpTreeView"])); + } + set { + this["useDumpTreeView"] = value; + } + } } } diff --git a/AssetStudioGUI/Properties/Settings.settings b/AssetStudioGUI/Properties/Settings.settings index b4b2b74..b32f490 100644 --- a/AssetStudioGUI/Properties/Settings.settings +++ b/AssetStudioGUI/Properties/Settings.settings @@ -104,5 +104,8 @@ False + + False + \ No newline at end of file diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs index 2879f76..0b5b87e 100644 --- a/AssetStudioGUI/Studio.cs +++ b/AssetStudioGUI/Studio.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -304,12 +305,15 @@ namespace AssetStudioGUI { preloadTable = m_AssetBundle.m_PreloadTable; } - assetItem.Text = string.IsNullOrEmpty(m_AssetBundle.m_AssetBundleName) ? m_AssetBundle.m_Name : m_AssetBundle.m_AssetBundleName; - + assetItem.Text = string.IsNullOrEmpty(m_AssetBundle.m_AssetBundleName) + ? m_AssetBundle.m_Name + : m_AssetBundle.m_AssetBundleName; foreach (var m_Container in m_AssetBundle.m_Container) { var preloadIndex = m_Container.Value.preloadIndex; - var preloadSize = isStreamedSceneAssetBundle ? preloadTable.Length : m_Container.Value.preloadSize; + var preloadSize = isStreamedSceneAssetBundle + ? preloadTable.Length + : m_Container.Value.preloadSize; var preloadEnd = preloadIndex + preloadSize; for (var k = preloadIndex; k < preloadEnd; k++) { @@ -689,7 +693,9 @@ namespace AssetStudioGUI Logger.Error(ex.Value); } - var statusText = exportedCount == 0 ? "Nothing exported." : $"Finished {mode.ToLower()}ing [{exportedCount}/{toExportCount}] assets."; + var statusText = exportedCount == 0 + ? "Nothing exported." + : $"Finished {mode.ToLower()}ing [{exportedCount}/{toExportCount}] assets."; if (toExportCount > exportedCount) { statusText += exceptionMsgs.IsEmpty @@ -779,7 +785,7 @@ namespace AssetStudioGUI //每个文件存放在单独的文件夹 var targetPath = $"{savePath}{filename}{Path.DirectorySeparatorChar}"; //重名文件处理 - for (int i = 1; ; i++) + for (int i = 1;; i++) { if (Directory.Exists(targetPath)) { @@ -965,6 +971,19 @@ namespace AssetStudioGUI return str; } + public static JsonDocument DumpAssetToJsonDoc(Object obj) + { + if (obj == null) + return null; + + if (obj is MonoBehaviour m_MonoBehaviour) + { + var type = obj.serializedType?.m_Type ?? MonoBehaviourToTypeTree(m_MonoBehaviour); + return m_MonoBehaviour.ToJsonDoc(type); + } + return obj.ToJsonDoc(); + } + public static void OpenFolderInExplorer(string path) { if (!path.EndsWith($"{Path.DirectorySeparatorChar}"))