diff --git a/EventLogger.cs b/EventLogger.cs new file mode 100644 index 0000000..61afdb5 --- /dev/null +++ b/EventLogger.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace InfiniteRuntimeTagViewer +{ + public class EventLogger + { + + public static void LogEvent(string message) + { + //Log to file + + using (StreamWriter w = File.AppendText("log.txt")) + { + w.WriteLine(message); + } + + } + + } + + +} diff --git a/MainWindow.xaml b/MainWindow.xaml index cf1020b..093287b 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -237,7 +237,7 @@ - + @@ -257,8 +257,16 @@ - + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 796f767..846af2d 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -24,6 +24,7 @@ using Newtonsoft.Json.Linq; using System.Xml; using InfiniteRuntimeTagViewer.Halo.TagStructDump; +using System.Text; namespace InfiniteRuntimeTagViewer { @@ -167,6 +168,9 @@ private void window_SizeChanged(object sender, SizeChangedEventArgs e) } } + + + private void BtnReloadProcessClick(object sender, RoutedEventArgs e) { foreach (Process? process in Process.GetProcessesByName("HaloInfinite")) @@ -289,6 +293,7 @@ private void Search() string search = Searchbox.Text; foreach (TreeViewItem tv in TagsTree.Items) { + if (!tv.Header.ToString().Contains(search)) { tv.Visibility = Visibility.Collapsed; @@ -315,6 +320,11 @@ private void Search() } } } + + private void Tv_Expanded(object sender, RoutedEventArgs e) + { + throw new NotImplementedException(); + } #endregion #region MenuCommands @@ -338,7 +348,7 @@ public ProcessSelector GetProcessSelector() public void UnloadTags(object sender, RoutedEventArgs e) { - TagsTree.Items.Clear(); + Tags.Clear(); loadedTags = false; } @@ -730,7 +740,7 @@ private void UpdateOption_for_hiding_unloaded(object sender, RoutedEventArgs e) // load tags from Mem public void BtnReLoadTags_Click(object sender, RoutedEventArgs e) { - TagsTree.Items.Clear(); + Tags.Clear(); groups_headers.Clear(); tags_headers.Clear(); HookAndLoad(); @@ -738,6 +748,7 @@ public void BtnReLoadTags_Click(object sender, RoutedEventArgs e) private void BtnLoadTags_Click(object sender, RoutedEventArgs e) { + //Tags.Clear(); HookAndLoad(); Reload_Button.IsEnabled = true; } @@ -827,7 +838,7 @@ public bool SlientHookAndLoad(bool load_tags_too) { if (load_tags_too) { - TagsTree.Items.Clear(); + Tags.Clear(); groups_headers.Clear(); tags_headers.Clear(); LoadTagsMem(true); @@ -854,7 +865,7 @@ private async Task HookProcessAsync() BaseAddress = -1; hooked = false; loadedTags = false; - TagsTree.Items.Clear(); + Tags.Clear(); } if (!hooked || reset) @@ -1007,102 +1018,139 @@ await Task.Run((Action) (() => } } - public void Loadtags() + public string GetTagNameFromCache(string objectId) { - Dictionary tags_headers_diff = new(); - Dictionary groups_headers_diff = new(); - loadedTags = true; - - for (int i = 0; i < TagGroups.Count; i++) + if (InhaledTagnames.TryGetValue(objectId, out string tagName)) + { + return tagName; + } + else + { + // Handle the case where the objectId is not in the cache + // This could involve fetching the tag name from a database or file, for example + // For simplicity, we'll just return the objectId + return objectId; + } + } + private ObservableCollection _tags = new ObservableCollection(); + public ObservableCollection Tags + { + get { return _tags; } + set { - KeyValuePair goop = TagGroups.ElementAt(i); + _tags = value; + OnPropertyChanged("Tags"); + } + } - if (groups_headers.Keys.Contains(goop.Key)) - { - TreeViewItem t = groups_headers[goop.Key]; - groups_headers_diff.Add(goop.Key, t); - groups_headers.Remove(goop.Key); + public event PropertyChangedEventHandler PropertyChanged; - GroupTagStruct displayGroup = goop.Value; - displayGroup.TagCategory = t; - TagGroups[goop.Key] = displayGroup; - } - else - { - GroupTagStruct displayGroup = goop.Value; - TreeViewItem sortheader = new(); + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + public async void Loadtags() + { + + if (TagsTree.ItemsSource == null) + { + TagsTree.Items.Clear(); + } - sortheader.Header = displayGroup.TagGroupName + " (" + displayGroup.TagGroupDesc + ")"; - sortheader.ToolTip = new TextBlock { Foreground = Brushes.Black, Text = displayGroup.TagGroupDefinitition }; - displayGroup.TagCategory = sortheader; + TagsTree.ItemsSource = Tags; - TagGroups[goop.Key] = displayGroup; - TagsTree.Items.Add(sortheader); + Dictionary tempTagGroups = new(TagGroups); + Dictionary tags_headers_diff = new(); + Dictionary groups_headers_diff = new(); + loadedTags = true; - groups_headers_diff.Add(goop.Key, sortheader); + foreach (var goop in tempTagGroups) + { + if (!groups_headers.TryGetValue(goop.Key, out TreeViewItem t)) + { + GroupTagStruct displayGroup = goop.Value; + // Check if the tree view item already exists in the UI + if (!Tags.Any(item => item.Header.ToString() == new StringBuilder().Append(displayGroup.TagGroupName).Append(" (").Append(displayGroup.TagGroupDesc).Append(")").ToString())) + { + t = new TreeViewItem + { + Header = new StringBuilder().Append(displayGroup.TagGroupName).Append(" (").Append(displayGroup.TagGroupDesc).Append(")").ToString(), + ToolTip = new TextBlock { Foreground = Brushes.Black, Text = displayGroup.TagGroupDefinitition }, + + + }; + displayGroup.TagCategory = t; + Tags.Add(t); + } } + + TagGroups[goop.Key] = goop.Value; + groups_headers_diff.Add(goop.Key, t); } - foreach (KeyValuePair curr_tag in TagsList.OrderBy(key => key.Value.TagFullName)) + + foreach (KeyValuePair curr_tag in TagsList) { if (!curr_tag.Value.unloaded) { - if (tags_headers.Keys.Contains(curr_tag.Key)) + if (tags_headers.TryGetValue(curr_tag.Key, out TreeViewItem t)) { - TreeViewItem t = tags_headers[curr_tag.Key]; t.Tag = curr_tag.Key; tags_headers_diff.Add(curr_tag.Key, t); - tags_headers.Remove(curr_tag.Key); } else { - TreeViewItem t = new(); - TagStruct tag = curr_tag.Value; - TagGroups.TryGetValue(tag.TagGroup, out GroupTagStruct? dictTagGroup); + // Check if a TreeViewItem with the same tag datnum and object id already exists + bool itemExists = false; + if (Tags.Count > 0) + { + itemExists = Tags.Any(item => item.Tag != null && ((string) item.Tag).Split(' ')[0] == curr_tag.Value.Datnum && ((string) item.Tag).Split(' ')[1] == GetTagNameFromCache(curr_tag.Value.ObjectId)); + + } - t.Header = "(" + tag.Datnum + ") " + convert_ID_to_tag_name(tag.ObjectId); - t.Tag = curr_tag.Key; - t.Selected += Select_Tag_click; - if (dictTagGroup != null && dictTagGroup.TagCategory != null) + if (!itemExists) { - dictTagGroup.TagCategory.Items.Add(t); - } + TreeViewItem tr = new(); + TagStruct tag = curr_tag.Value; + TagGroups.TryGetValue(tag.TagGroup, out GroupTagStruct? dictTagGroup); - tags_headers_diff.Add(curr_tag.Key, t); - } - } - } + tr.Header = new StringBuilder().Append("(").Append(tag.Datnum).Append(") ").Append(GetTagNameFromCache(tag.ObjectId)).ToString(); + tr.Tag = curr_tag.Key; + tr.Selected += Select_Tag_click; - foreach (KeyValuePair poop in groups_headers) - { - if (poop.Value != null) - { - TagsTree.Items.Remove(poop.Value); - } - } + if (dictTagGroup != null && dictTagGroup.TagCategory != null) + { + dictTagGroup.TagCategory.Items.Add(tr); + } - foreach (KeyValuePair poop in tags_headers) - { - if (poop.Value != null) - { - TreeViewItem ownber = (TreeViewItem) poop.Value.Parent; - ownber.Items.Remove(poop.Value); + tags_headers_diff.Add(curr_tag.Key, tr); + } + } } } - tags_headers = tags_headers_diff; - groups_headers = groups_headers_diff; - if (TagsTree.Items.Count < 1) - { - loadedTags = false; - } + //foreach (var item in tags_headers.Values) + // { + // TreeViewItem owner = (TreeViewItem)item.Parent; + // owner.Items.Remove(item); + // } + + tags_headers = tags_headers_diff; + groups_headers = groups_headers_diff; + + if (TagsTree.Items.Count < 1) + { + loadedTags = false; + } + TagsTree.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending)); - SetStatus("Loaded Tags!"); - } + SetStatus("Loaded Tags!"); + } + public async Task ScanMem() { @@ -1160,7 +1208,17 @@ public async Task ScanMem() Settings.Default.ProcAsyncBaseAddr = "HaloInfinite.exe+0x" + (pointer - haloInfinite).ToString("X"); Settings.Default.Save(); Debug.WriteLine(Settings.Default.ProcAsyncBaseAddr); - + EventLogger.LogEvent("AOB Scan Dump:"); + EventLogger.LogEvent("AOB Scan: " + aobSingle); + EventLogger.LogEvent("AOB Scan Result: " + aobScan.ToString("X")); + EventLogger.LogEvent("AOB Scan Result (Reversed): " + aobSingle); + EventLogger.LogEvent("AOB Scan Result (Pointer): " + pointer.ToString("X")); + EventLogger.LogEvent("AOB Scan Result (Pointer - HaloInfinite.exe): " + (pointer - haloInfinite).ToString("X")); + EventLogger.LogEvent("AOB Scan Result (HaloInfinite.exe+0x): " + Settings.Default.ProcAsyncBaseAddr); + foreach (long aobResult in aobScanResults) + { + EventLogger.LogEvent("AOB Scan Result (All): " + aobResult.ToString("X")); + } } // Failed to find base tag address @@ -1178,9 +1236,11 @@ public async Task ScanMem() hooked = true; } } - catch (Exception) + catch (Exception ex) { SetStatus("Cant find HaloInfinite.exe"); + EventLogger.LogEvent("Exception Thrown:"); + EventLogger.LogEvent(ex.ToString()); } } }