diff --git a/Il2CppInspector.GUI/MainWindow.xaml b/Il2CppInspector.GUI/MainWindow.xaml index 1f53649..ef63427 100644 --- a/Il2CppInspector.GUI/MainWindow.xaml +++ b/Il2CppInspector.GUI/MainWindow.xaml @@ -3,9 +3,10 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:Il2CppInspectorGUI" xmlns:gif="https://github.com/XamlAnimatedGif/XamlAnimatedGif" mc:Ignorable="d" - Title="Il2CppInspector" Height="570" Width="900" Background="White"> + Title="Il2CppInspector" Height="590" Width="970" Background="White"> @@ -82,6 +83,11 @@ + + + + + @@ -101,7 +107,7 @@ - + @@ -182,10 +188,10 @@ - - - - + + + + @@ -209,7 +215,7 @@ Suppress pointer, offset and index metadata comments - Attempt to generate output that compiles + Attempt to generate code that compiles Place assembly-level attributes in separate files Visual Studio solution @@ -226,6 +232,7 @@ IDAPython script + No configuration required for IDA script output diff --git a/Il2CppInspector.GUI/MainWindow.xaml.cs b/Il2CppInspector.GUI/MainWindow.xaml.cs index 1231981..b5b3445 100644 --- a/Il2CppInspector.GUI/MainWindow.xaml.cs +++ b/Il2CppInspector.GUI/MainWindow.xaml.cs @@ -16,6 +16,7 @@ using System.Windows.Navigation; using System.Windows.Shapes; using Microsoft.Win32; using Il2CppInspector; +using Il2CppInspector.Reflection; namespace Il2CppInspectorGUI { @@ -86,6 +87,7 @@ namespace Il2CppInspectorGUI rectModalLightBoxBackground.Visibility = Visibility.Hidden; lstImages.ItemsSource = app.Il2CppModels; + lstImages.SelectedIndex = 0; } else { areaBusyIndicator.Visibility = Visibility.Hidden; @@ -98,13 +100,54 @@ namespace Il2CppInspectorGUI /// /// Reset binary and metadata files and start again /// - /// - /// private void BtnBack_OnClick(object sender, RoutedEventArgs e) { rectModalLightBoxBackground.Visibility = Visibility.Visible; lstImages.ItemsSource = null; btnSelectBinaryFile.Visibility = Visibility.Hidden; btnSelectMetadataFile.Visibility = Visibility.Visible; } + + /// + /// User has selected an image + /// + private void LstImages_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { + // Selection has been removed? + if (((ListBox) sender).SelectedItem == null) { + trvNamespaces.ItemsSource = null; + return; + } + + // Get selected image + var model = (Il2CppModel) ((ListBox) sender).SelectedItem; + + // Get namespaces + var namespaces = model.Assemblies.SelectMany(x => x.DefinedTypes).GroupBy(t => t.Namespace).Select(n => n.Key); + + // Break namespaces down into a tree + var namespaceTree = deconstructNamespaces(namespaces); + + // Populate TreeView with namespace hierarchy + trvNamespaces.ItemsSource = namespaceTree; + } + + private IEnumerable deconstructNamespaces(IEnumerable input) { + if (!input.Any()) + return null; + + var rootAndChildren = input.Select(s => string.IsNullOrEmpty(s)? "" : s) + .GroupBy(n => n.IndexOf(".") != -1 ? n.Substring(0, n.IndexOf(".")) : n).OrderBy(g => g.Key); + + return rootAndChildren.Select(i => new CheckboxNode {Name = i.Key, IsChecked = true, Children = deconstructNamespaces( + i.Where(s => s.IndexOf(".") != -1).Select(s => s.Substring(s.IndexOf(".") + 1)) + )}).ToList(); + } + } + + // Replacement for TreeViewItem that includes checkbox state + internal class CheckboxNode + { + public string Name { get; set; } + public bool IsChecked { get; set; } + public IEnumerable Children { get; set; } } }