Skip to content

Commit 58917ab

Browse files
committed
[GUI] Add tree view for dump
1 parent b7d21e5 commit 58917ab

File tree

9 files changed

+417
-92
lines changed

9 files changed

+417
-92
lines changed

AssetStudio/Classes/Object.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class Object
2525
public uint byteSize;
2626
[JsonIgnore]
2727
public string Name;
28-
private static JsonSerializerOptions jsonOptions;
28+
private static readonly JsonSerializerOptions jsonOptions;
2929

3030
static Object()
3131
{
@@ -95,6 +95,24 @@ public OrderedDictionary ToType(TypeTree m_Type = null)
9595
return TypeTreeHelper.ReadType(m_Type, reader);
9696
}
9797

98+
public JsonDocument ToJsonDoc(TypeTree m_Type = null)
99+
{
100+
var typeDict = ToType(m_Type);
101+
try
102+
{
103+
if (typeDict != null)
104+
{
105+
return JsonSerializer.SerializeToDocument(typeDict);
106+
}
107+
return JsonSerializer.SerializeToDocument(this, GetType(), jsonOptions);
108+
}
109+
catch
110+
{
111+
//ignore
112+
}
113+
return null;
114+
}
115+
98116
public byte[] GetRawData()
99117
{
100118
reader.Reset();

AssetStudio/TypeTreeHelper.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,21 @@ public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader)
198198
reader.Reset();
199199
var obj = new OrderedDictionary();
200200
var m_Nodes = m_Types.m_Nodes;
201-
for (int i = 1; i < m_Nodes.Count; i++)
201+
var readed = 0L;
202+
try
202203
{
203-
var m_Node = m_Nodes[i];
204-
var varNameStr = m_Node.m_Name;
205-
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
204+
for (int i = 1; i < m_Nodes.Count; i++)
205+
{
206+
var m_Node = m_Nodes[i];
207+
var varNameStr = m_Node.m_Name;
208+
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
209+
}
210+
readed = reader.Position - reader.byteStart;
211+
}
212+
catch (Exception)
213+
{
214+
//Ignore
206215
}
207-
var readed = reader.Position - reader.byteStart;
208216
if (readed != reader.byteSize)
209217
{
210218
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");

AssetStudioGUI/AssetStudioGUIForm.Designer.cs

Lines changed: 133 additions & 61 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

AssetStudioGUI/AssetStudioGUIForm.cs

Lines changed: 106 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace AssetStudioGUI
3434
partial class AssetStudioGUIForm : Form
3535
{
3636
private AssetItem lastSelectedItem;
37+
private AssetItem lastPreviewItem;
3738
private DirectBitmap imageTexture;
3839
private string tempClipboard;
3940

@@ -140,6 +141,7 @@ public AssetStudioGUIForm()
140141
showConsoleToolStripMenuItem.Checked = Properties.Settings.Default.showConsole;
141142
buildTreeStructureToolStripMenuItem.Checked = Properties.Settings.Default.buildTreeStructure;
142143
useAssetLoadingViaTypetreeToolStripMenuItem.Checked = Properties.Settings.Default.useTypetreeLoading;
144+
useDumpTreeViewToolStripMenuItem.Checked = Properties.Settings.Default.useDumpTreeView;
143145
FMODinit();
144146
listSearchFilterMode.SelectedIndex = 0;
145147

@@ -776,7 +778,7 @@ private void assetListView_ColumnClick(object sender, ColumnClickEventArgs e)
776778
var at = a.SubItems[sortColumn].Text.AsSpan();
777779
var bt = b.SubItems[sortColumn].Text.AsSpan();
778780

779-
return reverseSort ? MemoryExtensions.CompareTo(bt, at, StringComparison.OrdinalIgnoreCase) : MemoryExtensions.CompareTo(at, bt, StringComparison.OrdinalIgnoreCase);
781+
return reverseSort ? bt.CompareTo(at, StringComparison.OrdinalIgnoreCase) : at.CompareTo(bt, StringComparison.OrdinalIgnoreCase);
780782
});
781783
}
782784
assetListView.EndUpdate();
@@ -799,22 +801,44 @@ private void selectAsset(object sender, ListViewItemSelectionChangedEventArgs e)
799801

800802
lastSelectedItem = (AssetItem)e.Item;
801803

802-
if (e.IsSelected)
804+
if (!e.IsSelected)
805+
return;
806+
807+
switch (tabControl2.SelectedIndex)
803808
{
804-
if (tabControl2.SelectedIndex == 1)
805-
{
806-
dumpTextBox.Text = DumpAsset(lastSelectedItem.Asset);
807-
}
808-
if (enablePreview.Checked)
809-
{
810-
PreviewAsset(lastSelectedItem);
811-
if (displayInfo.Checked && lastSelectedItem.InfoText != null)
809+
case 0: //Preview
810+
if (enablePreview.Checked)
812811
{
813-
assetInfoLabel.Text = lastSelectedItem.InfoText;
814-
assetInfoLabel.Visible = true;
812+
PreviewAsset(lastSelectedItem);
813+
if (displayInfo.Checked && lastSelectedItem.InfoText != null)
814+
{
815+
assetInfoLabel.Text = lastSelectedItem.InfoText;
816+
assetInfoLabel.Visible = true;
817+
}
815818
}
819+
break;
820+
case 1: //Dump
821+
DumpAsset(lastSelectedItem);
822+
break;
823+
}
824+
}
825+
826+
private void DumpAsset(AssetItem assetItem)
827+
{
828+
if (assetItem == null)
829+
return;
830+
831+
if (useDumpTreeViewToolStripMenuItem.Checked)
832+
{
833+
using (var jsonDoc = DumpAssetToJsonDoc(assetItem.Asset))
834+
{
835+
dumpTreeView.LoadFromJson(jsonDoc, assetItem.Text);
816836
}
817837
}
838+
else
839+
{
840+
dumpTextBox.Text = Studio.DumpAsset(assetItem.Asset);
841+
}
818842
}
819843

820844
private void classesListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
@@ -830,6 +854,7 @@ private void classesListView_ItemSelectionChanged(object sender, ListViewItemSel
830854
if (e.IsSelected)
831855
{
832856
classTextBox.Text = ((TypeTreeItem)classesListView.SelectedItems[0]).ToString();
857+
lastSelectedItem = null;
833858
}
834859
}
835860

@@ -844,6 +869,7 @@ private void preview_Resize(object sender, EventArgs e)
844869

845870
private void PreviewAsset(AssetItem assetItem)
846871
{
872+
lastPreviewItem = assetItem;
847873
if (assetItem == null)
848874
return;
849875
try
@@ -1527,9 +1553,22 @@ private void ResetForm()
15271553

15281554
private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
15291555
{
1530-
if (tabControl2.SelectedIndex == 1 && lastSelectedItem != null)
1556+
switch (tabControl2.SelectedIndex)
15311557
{
1532-
dumpTextBox.Text = DumpAsset(lastSelectedItem.Asset);
1558+
case 0: //Preview
1559+
if (lastPreviewItem != lastSelectedItem)
1560+
{
1561+
PreviewAsset(lastSelectedItem);
1562+
if (displayInfo.Checked && lastSelectedItem?.InfoText != null)
1563+
{
1564+
assetInfoLabel.Text = lastSelectedItem.InfoText;
1565+
assetInfoLabel.Visible = true;
1566+
}
1567+
}
1568+
break;
1569+
case 1: //Dump
1570+
DumpAsset(lastSelectedItem);
1571+
break;
15331572
}
15341573
}
15351574

@@ -2047,7 +2086,7 @@ private void sceneTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEvent
20472086
if (e.Button == MouseButtons.Right)
20482087
{
20492088
sceneTreeView.SelectedNode = e.Node;
2050-
contextMenuStrip2.Show(sceneTreeView, e.Location.X, e.Location.Y);
2089+
sceneContextMenuStrip.Show(sceneTreeView, e.Location.X, e.Location.Y);
20512090
}
20522091
}
20532092

@@ -2162,7 +2201,7 @@ private void contextMenuStrip2_Opening(object sender, System.ComponentModel.Canc
21622201
{
21632202
var selectedNode = sceneTreeView.SelectedNode;
21642203
var relatedAssets = visibleAssets.FindAll(x => x.TreeNode == selectedNode);
2165-
showRelatedAssetsToolStripMenuItem.DropDownItems.Clear();
2204+
shShowRelatedAssetsToolStripMenuItem.DropDownItems.Clear();
21662205
if (relatedAssets.Count > 1)
21672206
{
21682207
var assetItem = new ToolStripMenuItem
@@ -2173,7 +2212,7 @@ private void contextMenuStrip2_Opening(object sender, System.ComponentModel.Canc
21732212
Text = "Select all"
21742213
};
21752214
assetItem.Click += selectAllRelatedAssets;
2176-
showRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem);
2215+
shShowRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem);
21772216
}
21782217
foreach (var asset in relatedAssets)
21792218
{
@@ -2186,7 +2225,7 @@ private void contextMenuStrip2_Opening(object sender, System.ComponentModel.Canc
21862225
Text = $"({asset.TypeString}) {asset.Text}"
21872226
};
21882227
assetItem.Click += selectRelatedAsset;
2189-
showRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem);
2228+
shShowRelatedAssetsToolStripMenuItem.DropDownItems.Add(assetItem);
21902229
}
21912230
}
21922231

@@ -2462,6 +2501,55 @@ private static void ShowThemeChangingMsg()
24622501
MessageBox.Show(msg, "Info", MessageBoxButtons.OK);
24632502
}
24642503

2504+
private void DumpTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
2505+
{
2506+
if (e.Button == MouseButtons.Right)
2507+
{
2508+
dumpTreeView.SelectedNode = e.Node;
2509+
tempClipboard = string.IsNullOrEmpty((string)e.Node.Tag)
2510+
? e.Node.Text
2511+
: $"{e.Node.Name}: {e.Node.Tag}";
2512+
dumpTreeViewContextMenuStrip.Show(dumpTreeView, e.Location.X, e.Location.Y);
2513+
}
2514+
}
2515+
2516+
private void copyToolStripMenuItem1_Click(object sender, EventArgs e)
2517+
{
2518+
Clipboard.SetDataObject(tempClipboard);
2519+
}
2520+
2521+
private void expandAllToolStripMenuItem1_Click(object sender, EventArgs e)
2522+
{
2523+
dumpTreeView.BeginUpdate();
2524+
foreach (TreeNode node in dumpTreeView.Nodes)
2525+
{
2526+
node.ExpandAll();
2527+
}
2528+
dumpTreeView.EndUpdate();
2529+
}
2530+
2531+
private void collapseAllToolStripMenuItem1_Click(object sender, EventArgs e)
2532+
{
2533+
dumpTreeView.BeginUpdate();
2534+
foreach (TreeNode node in dumpTreeView.Nodes)
2535+
{
2536+
node.Collapse(ignoreChildren: false);
2537+
}
2538+
dumpTreeView.EndUpdate();
2539+
}
2540+
2541+
private void useDumpTreeViewToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
2542+
{
2543+
var isTreeViewEnabled = useDumpTreeViewToolStripMenuItem.Checked;
2544+
dumpTreeView.Visible = isTreeViewEnabled;
2545+
Properties.Settings.Default.useDumpTreeView = isTreeViewEnabled;
2546+
Properties.Settings.Default.Save();
2547+
if (tabControl2.SelectedIndex == 1)
2548+
{
2549+
DumpAsset(lastSelectedItem);
2550+
}
2551+
}
2552+
24652553
#region FMOD
24662554
private void FMODinit()
24672555
{

AssetStudioGUI/AssetStudioGUIForm.resx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ The quick brown fox jumps over the lazy dog. 1234567890</value>
141141
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
142142
<value>432, 17</value>
143143
</metadata>
144-
<metadata name="contextMenuStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
144+
<metadata name="sceneContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
145145
<value>775, 21</value>
146146
</metadata>
147147
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@@ -153,7 +153,7 @@ The quick brown fox jumps over the lazy dog. 1234567890</value>
153153
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
154154
<value>147, 17</value>
155155
</metadata>
156-
<metadata name="contextMenuStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
156+
<metadata name="dumpTreeViewContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
157157
<value>930, 21</value>
158158
</metadata>
159159
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System.Text.Json;
2+
using System.Windows.Forms;
3+
using AssetStudio;
4+
5+
namespace AssetStudioGUI
6+
{
7+
public static class JsonTreeView
8+
{
9+
public static void LoadFromJson(this TreeView treeView, JsonDocument jsonDoc, string rootName)
10+
{
11+
if (jsonDoc == null)
12+
{
13+
Logger.Info("Unable to build tree view of current object");
14+
return;
15+
}
16+
17+
try
18+
{
19+
treeView.BeginUpdate();
20+
treeView.Nodes.Clear();
21+
var rootNode = treeView.Nodes[treeView.Nodes.Add(new TreeNode(rootName))];
22+
23+
foreach (var property in jsonDoc.RootElement.EnumerateObject())
24+
{
25+
var childNode = rootNode.Nodes[rootNode.Nodes.Add(new TreeNode(property.Name))];
26+
AddNodes(property.Value, childNode);
27+
}
28+
29+
rootNode.Expand();
30+
rootNode.EnsureVisible();
31+
}
32+
finally
33+
{
34+
treeView.EndUpdate();
35+
}
36+
}
37+
38+
private static void AddNodes(JsonElement jsonElement, TreeNode treeNode)
39+
{
40+
switch (jsonElement.ValueKind)
41+
{
42+
case JsonValueKind.Object:
43+
foreach (var property in jsonElement.EnumerateObject())
44+
{
45+
var childNode = treeNode.Nodes[treeNode.Nodes.Add(new TreeNode(property.Name))];
46+
AddNodes(property.Value, childNode);
47+
}
48+
break;
49+
case JsonValueKind.Array:
50+
const int arrayLenLimit = 500;
51+
var arrayLen = jsonElement.GetArrayLength();
52+
if (arrayLen == 0)
53+
{
54+
SetValue(jsonElement, treeNode);
55+
}
56+
else
57+
{
58+
var i = 0;
59+
foreach (var jsonArrayElem in jsonElement.EnumerateArray())
60+
{
61+
if (jsonArrayElem.ValueKind == JsonValueKind.Number) //number array
62+
{
63+
SetValue(jsonElement, treeNode);
64+
break;
65+
}
66+
67+
if (i > arrayLenLimit)
68+
{
69+
treeNode.Nodes.Add(new TreeNode($"[{i++}-{arrayLen - 1}] Skipped. Too many elements to display"));
70+
break;
71+
}
72+
73+
var childNode = treeNode.Nodes[treeNode.Nodes.Add(new TreeNode($"[{i++}]"))];
74+
AddNodes(jsonArrayElem, childNode);
75+
}
76+
}
77+
break;
78+
default:
79+
SetValue(jsonElement, treeNode);
80+
break;
81+
}
82+
}
83+
84+
private static void SetValue(JsonElement jsonElem, TreeNode node)
85+
{
86+
const int maxStrLen = 128;
87+
var endStr = "...";
88+
var strValue = jsonElem.ToString();
89+
if (jsonElem.ValueKind == JsonValueKind.Array)
90+
{
91+
strValue = strValue.Replace("\r", "").Replace("\n", "").Replace(" ", "").Replace(",", ", ");
92+
endStr += "]";
93+
}
94+
if (jsonElem.ValueKind == JsonValueKind.Null)
95+
{
96+
strValue = jsonElem.GetRawText();
97+
}
98+
node.Name = node.Text;
99+
node.Text += strValue?.Length > maxStrLen
100+
? $": {strValue.Substring(0, maxStrLen)}{endStr}"
101+
: $": {strValue}";
102+
node.Tag = strValue;
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)