diff --git a/ReClass.NET/Controls/MemoryViewControl.cs b/ReClass.NET/Controls/MemoryViewControl.cs index 64b8dfa4..d323903b 100644 --- a/ReClass.NET/Controls/MemoryViewControl.cs +++ b/ReClass.NET/Controls/MemoryViewControl.cs @@ -704,5 +704,23 @@ public void Reset() VerticalScroll.Value = VerticalScroll.Minimum; } + + public void InitCurrentClassFromRTTI(ClassNode classNode) + { + var args = new DrawContextRequestEventArgs { Node = classNode }; + + var requestHandler = DrawContextRequested; + requestHandler?.Invoke(this, args); + var view = new DrawContext + { + Settings = args.Settings, + Process = args.Process, + Memory = args.Memory, + CurrentTime = args.CurrentTime, + Address = args.BaseAddress, + Level = 0, + }; + classNode.InitFromRTTI(view); + } } } diff --git a/ReClass.NET/Forms/MainForm.Designer.cs b/ReClass.NET/Forms/MainForm.Designer.cs index e2b2a199..081e2c0d 100644 --- a/ReClass.NET/Forms/MainForm.Designer.cs +++ b/ReClass.NET/Forms/MainForm.Designer.cs @@ -77,6 +77,7 @@ private void InitializeComponent() this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); this.createClassFromNodesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator(); + this.initClassToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.dissectNodesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator(); this.searchForEqualValuesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -106,6 +107,7 @@ private void InitializeComponent() this.saveToolStripButton = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); this.newClassToolStripButton = new System.Windows.Forms.ToolStripButton(); + this.initClassFromRTTIToolStripBarMenuItem = new ReClassNET.Controls.TypeToolStripMenuItem(); this.addBytesToolStripDropDownButton = new System.Windows.Forms.ToolStripDropDownButton(); this.add4BytesToolStripMenuItem = new ReClassNET.Controls.IntegerToolStripMenuItem(); this.add8BytesToolStripMenuItem = new ReClassNET.Controls.IntegerToolStripMenuItem(); @@ -202,7 +204,7 @@ private void InitializeComponent() // this.splitContainer.Panel2.BackColor = System.Drawing.SystemColors.Control; this.splitContainer.Panel2.Controls.Add(this.memoryViewControl); - this.splitContainer.Size = new System.Drawing.Size(1141, 524); + this.splitContainer.Size = new System.Drawing.Size(1313, 524); this.splitContainer.SplitterDistance = 201; this.splitContainer.TabIndex = 4; // @@ -364,7 +366,7 @@ private void InitializeComponent() this.memoryViewControl.Location = new System.Drawing.Point(0, 0); this.memoryViewControl.Name = "memoryViewControl"; this.memoryViewControl.NodeContextMenuStrip = this.selectedNodeContextMenuStrip; - this.memoryViewControl.Size = new System.Drawing.Size(936, 524); + this.memoryViewControl.Size = new System.Drawing.Size(1108, 524); this.memoryViewControl.TabIndex = 0; this.memoryViewControl.DrawContextRequested += new ReClassNET.Controls.DrawContextRequestEventHandler(this.memoryViewControl_DrawContextRequested); this.memoryViewControl.SelectionChanged += new System.EventHandler(this.memoryViewControl_SelectionChanged); @@ -382,6 +384,7 @@ private void InitializeComponent() this.toolStripSeparator8, this.createClassFromNodesToolStripMenuItem, this.toolStripSeparator13, + this.initClassToolStripMenuItem, this.dissectNodesToolStripMenuItem, this.toolStripSeparator9, this.searchForEqualValuesToolStripMenuItem, @@ -402,7 +405,7 @@ private void InitializeComponent() this.showCodeOfClassToolStripMenuItem, this.shrinkClassToolStripMenuItem}); this.selectedNodeContextMenuStrip.Name = "selectedNodeContextMenuStrip"; - this.selectedNodeContextMenuStrip.Size = new System.Drawing.Size(270, 410); + this.selectedNodeContextMenuStrip.Size = new System.Drawing.Size(270, 432); this.selectedNodeContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.selectedNodeContextMenuStrip_Opening); // // changeTypeToolStripMenuItem @@ -604,6 +607,16 @@ private void InitializeComponent() this.toolStripSeparator13.Name = "toolStripSeparator13"; this.toolStripSeparator13.Size = new System.Drawing.Size(266, 6); // + // initClassToolStripMenuItem + // + this.initClassToolStripMenuItem.Image = global::ReClassNET.Properties.Resources.B16x16_Button_AutoName; + this.initClassToolStripMenuItem.Name = "initClassToolStripMenuItem"; + this.initClassToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.N))); + this.initClassToolStripMenuItem.Size = new System.Drawing.Size(269, 22); + this.initClassToolStripMenuItem.Text = "Init Class from RTTI"; + this.initClassToolStripMenuItem.Click += new System.EventHandler(this.initClassToolStripMenuItem_Click); + // // dissectNodesToolStripMenuItem // this.dissectNodesToolStripMenuItem.Image = global::ReClassNET.Properties.Resources.B16x16_Camera; @@ -771,12 +784,13 @@ private void InitializeComponent() this.saveToolStripButton, this.toolStripSeparator7, this.newClassToolStripButton, + this.initClassFromRTTIToolStripBarMenuItem, this.addBytesToolStripDropDownButton, this.insertBytesToolStripDropDownButton, this.nodeTypesToolStripSeparator}); this.toolStrip.Location = new System.Drawing.Point(0, 24); this.toolStrip.Name = "toolStrip"; - this.toolStrip.Size = new System.Drawing.Size(1141, 25); + this.toolStrip.Size = new System.Drawing.Size(1313, 25); this.toolStrip.TabIndex = 3; // // attachToProcessToolStripSplitButton @@ -832,6 +846,19 @@ private void InitializeComponent() this.newClassToolStripButton.ToolTipText = "Add a new class to this project"; this.newClassToolStripButton.Click += new System.EventHandler(this.newClassToolStripButton_Click); // + // initClassFromRTTIToolStripBarMenuItem + // + this.initClassFromRTTIToolStripBarMenuItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.initClassFromRTTIToolStripBarMenuItem.Image = global::ReClassNET.Properties.Resources.B16x16_Button_AutoName; + this.initClassFromRTTIToolStripBarMenuItem.Name = "initClassFromRTTIToolStripBarMenuItem"; + this.initClassFromRTTIToolStripBarMenuItem.Overflow = System.Windows.Forms.ToolStripItemOverflow.AsNeeded; + this.initClassFromRTTIToolStripBarMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.N))); + this.initClassFromRTTIToolStripBarMenuItem.Size = new System.Drawing.Size(28, 25); + this.initClassFromRTTIToolStripBarMenuItem.ToolTipText = "Init selected class from RTTI info"; + this.initClassFromRTTIToolStripBarMenuItem.Value = null; + this.initClassFromRTTIToolStripBarMenuItem.Click += new System.EventHandler(this.initClassToolStripMenuItem_Click); + // // addBytesToolStripDropDownButton // this.addBytesToolStripDropDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; @@ -1023,7 +1050,7 @@ private void InitializeComponent() this.infoToolStripStatusLabel}); this.statusStrip.Location = new System.Drawing.Point(0, 573); this.statusStrip.Name = "statusStrip"; - this.statusStrip.Size = new System.Drawing.Size(1141, 22); + this.statusStrip.Size = new System.Drawing.Size(1313, 22); this.statusStrip.TabIndex = 1; // // processInfoToolStripStatusLabel @@ -1048,7 +1075,7 @@ private void InitializeComponent() this.helpToolStripMenuItem}); this.mainMenuStrip.Location = new System.Drawing.Point(0, 0); this.mainMenuStrip.Name = "mainMenuStrip"; - this.mainMenuStrip.Size = new System.Drawing.Size(1141, 24); + this.mainMenuStrip.Size = new System.Drawing.Size(1313, 24); this.mainMenuStrip.TabIndex = 2; // // fileToolStripMenuItem @@ -1372,11 +1399,12 @@ private void InitializeComponent() this.AllowDrop = true; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1141, 595); + this.ClientSize = new System.Drawing.Size(1313, 595); this.Controls.Add(this.splitContainer); this.Controls.Add(this.toolStrip); this.Controls.Add(this.statusStrip); this.Controls.Add(this.mainMenuStrip); + this.KeyPreview = true; this.MainMenuStrip = this.mainMenuStrip; this.MinimumSize = new System.Drawing.Size(200, 100); this.Name = "MainForm"; @@ -1542,6 +1570,8 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem showEnumsToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator23; private System.Windows.Forms.ToolStripMenuItem isLittleEndianToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem initClassToolStripMenuItem; + private TypeToolStripMenuItem initClassFromRTTIToolStripBarMenuItem; } } diff --git a/ReClass.NET/Forms/MainForm.cs b/ReClass.NET/Forms/MainForm.cs index e771a10d..11c0d42d 100644 --- a/ReClass.NET/Forms/MainForm.cs +++ b/ReClass.NET/Forms/MainForm.cs @@ -835,6 +835,8 @@ private void memoryViewControl_SelectionChanged(object sender, EventArgs e) addBytesToolStripDropDownButton.Enabled = parentContainer != null || isContainerNode; insertBytesToolStripDropDownButton.Enabled = selectedNodes.Count == 1 && parentContainer != null && !isContainerNode; + initClassToolStripMenuItem.Enabled = nodeIsClass; + initClassFromRTTIToolStripBarMenuItem.Enabled = nodeIsClass; var enabled = selectedNodes.Count > 0 && !nodeIsClass; toolStrip.Items.OfType().ForEach(b => b.Enabled = enabled); @@ -1027,7 +1029,7 @@ private void memoryViewControl_DrawContextRequested(object sender, DrawContextRe { var process = Program.RemoteProcess; - var classNode = CurrentClassNode; + var classNode = (args.Node as ClassNode) ?? CurrentClassNode; if (classNode != null) { memoryViewBuffer.Size = classNode.MemorySize; @@ -1051,5 +1053,16 @@ private void memoryViewControl_DrawContextRequested(object sender, DrawContextRe args.BaseAddress = address; } } + + private void initClassToolStripMenuItem_Click(object sender, EventArgs e) + { + var selectedNodes = memoryViewControl.GetSelectedNodes(); + var node = selectedNodes.FirstOrDefault()?.Node; + if (node == null || !(node is ClassNode)) + { + return; + } + memoryViewControl.InitCurrentClassFromRTTI(node as ClassNode); + } } } diff --git a/ReClass.NET/Forms/MainForm.resx b/ReClass.NET/Forms/MainForm.resx index c430dab3..0e88c503 100644 --- a/ReClass.NET/Forms/MainForm.resx +++ b/ReClass.NET/Forms/MainForm.resx @@ -206,6 +206,6 @@ - 42 + 104 \ No newline at end of file diff --git a/ReClass.NET/Memory/MemoryBuffer.cs b/ReClass.NET/Memory/MemoryBuffer.cs index e1b515a4..cb7361ec 100644 --- a/ReClass.NET/Memory/MemoryBuffer.cs +++ b/ReClass.NET/Memory/MemoryBuffer.cs @@ -366,5 +366,17 @@ public bool HasChanged(int offset, int length) return false; } + + public UInt64FloatDoubleData InterpretData64(int offset) => new UInt64FloatDoubleData + { + Raw1 = ReadInt32(offset), + Raw2 = ReadInt32(offset + sizeof(int)) + }; + + + public UInt32FloatData InterpretData32(int offset) => new UInt32FloatData + { + Raw = ReadInt32(offset) + }; } } diff --git a/ReClass.NET/Nodes/BaseContainerNode.cs b/ReClass.NET/Nodes/BaseContainerNode.cs index 6926111f..aa106dd0 100644 --- a/ReClass.NET/Nodes/BaseContainerNode.cs +++ b/ReClass.NET/Nodes/BaseContainerNode.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -183,8 +183,8 @@ public void ReplaceChildNode(BaseNode oldNode, BaseNode newNode, ref ListGets or sets the parent node. public BaseNode ParentNode { get; internal set; } - /// Gets a value indicating whether this node is wrapped into an other node. + /// Gets a value indicating whether this node is wrapped into an other node. public bool IsWrapped => ParentNode is BaseWrapperNode; + /// All nodes that are wrapped can't be selected except classnodes because they have a context menu + public bool CanBeSelected => !IsWrapped || (this is ClassNode); + /// Gets or sets a value indicating whether this node is hidden. public bool IsHidden { get; set; } @@ -236,6 +239,15 @@ public virtual void ClearSelection() /// The calculated height. public abstract int CalculateDrawnHeight(DrawContext context); + /// + /// Called when this node has been created, initialized and the parent node has been assigned. For some nodes + /// Additional work has to be performed, this work can be done in a derived method of this method. + /// + public virtual void PerformPostInitWork() + { + // nop + } + /// Updates the node from the given . Sets the and of the node. /// The spot. public virtual void Update(HotSpot spot) @@ -367,7 +379,7 @@ protected void AddSelection(DrawContext context, int x, int y, int height) Contract.Requires(context != null); Contract.Requires(context.Graphics != null); - if (y > context.ClientArea.Bottom || y + height < 0 || IsWrapped) + if (y > context.ClientArea.Bottom || y + height < 0 || !CanBeSelected) { return; } diff --git a/ReClass.NET/Nodes/ClassNode.cs b/ReClass.NET/Nodes/ClassNode.cs index 9b144061..fe51a32f 100644 --- a/ReClass.NET/Nodes/ClassNode.cs +++ b/ReClass.NET/Nodes/ClassNode.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Drawing; using System.Linq; @@ -51,7 +52,48 @@ public static ClassNode Create() return new ClassNode(true); } + + /// + /// Initializes the class' name and vtable node from RTTI information, if it's not set already + /// + /// + public void InitFromRTTI(DrawContext context) + { + // first node should be a VTable node or a hex64/32 node + if (Nodes.Count <= 0) + { + return; + } + + var rttiInfoFromFirstNode = string.Empty; + var firstNode = Nodes[0]; + if (firstNode is VirtualMethodTableNode vtableNode) + { + rttiInfoFromFirstNode = vtableNode.GetAssociatedRemoteRuntimeTypeInformation(context); + } + else if (firstNode is BaseHexCommentNode baseHexCommentNode) + { + // ask it as if it might point to a vtable + var value = context.Memory.InterpretData64(Offset); + rttiInfoFromFirstNode = baseHexCommentNode.GetAssociatedRemoteRuntimeTypeInformation(context, value.IntPtr); + if (!string.IsNullOrEmpty(rttiInfoFromFirstNode)) + { + // convert first node to vtable node + var newVTableNode = BaseNode.CreateInstanceFromType(typeof(VirtualMethodTableNode)); + var createdNodes = new List(); + this.ReplaceChildNode(firstNode, newVTableNode, ref createdNodes); + } + } + if (string.IsNullOrEmpty(rttiInfoFromFirstNode)) + { + return; + } + + var fragments = rttiInfoFromFirstNode.Split(':'); + this.Name = fragments[0]; + } + public override void GetUserInterfaceInfo(out string name, out Image icon) { throw new InvalidOperationException($"The '{nameof(ClassNode)}' node should not be accessible from the ui."); diff --git a/ReClass.NET/Nodes/Hex32Node.cs b/ReClass.NET/Nodes/Hex32Node.cs index c7b54027..2329c954 100644 --- a/ReClass.NET/Nodes/Hex32Node.cs +++ b/ReClass.NET/Nodes/Hex32Node.cs @@ -18,7 +18,7 @@ public override void GetUserInterfaceInfo(out string name, out Image icon) public override bool UseMemoryPreviewToolTip(HotSpot spot, out IntPtr address) { - var value = ReadFromBuffer(spot.Memory, Offset); + var value = spot.Memory.InterpretData32(Offset); address = value.IntPtr; @@ -27,7 +27,7 @@ public override bool UseMemoryPreviewToolTip(HotSpot spot, out IntPtr address) public override string GetToolTipText(HotSpot spot) { - var value = ReadFromBuffer(spot.Memory, Offset); + var value = spot.Memory.InterpretData32(Offset); return $"Int32: {value.IntValue}\nUInt32: 0x{value.UIntValue:X08}\nFloat: {value.FloatValue:0.000}"; } @@ -46,16 +46,11 @@ protected override int AddComment(DrawContext context, int x, int y) { x = base.AddComment(context, x, y); - var value = ReadFromBuffer(context.Memory, Offset); + var value = context.Memory.InterpretData32(Offset); x = AddComment(context, x, y, value.FloatValue, value.IntPtr, value.UIntPtr); return x; } - - private static UInt32FloatData ReadFromBuffer(MemoryBuffer memory, int offset) => new UInt32FloatData - { - Raw = memory.ReadInt32(offset) - }; } } diff --git a/ReClass.NET/Nodes/Hex64Node.cs b/ReClass.NET/Nodes/Hex64Node.cs index d54f1e71..61749e46 100644 --- a/ReClass.NET/Nodes/Hex64Node.cs +++ b/ReClass.NET/Nodes/Hex64Node.cs @@ -18,7 +18,7 @@ public override void GetUserInterfaceInfo(out string name, out Image icon) public override bool UseMemoryPreviewToolTip(HotSpot spot, out IntPtr address) { - var value = ReadFromBuffer(spot.Memory, Offset); + var value = spot.Memory.InterpretData64(Offset); address = value.IntPtr; @@ -27,7 +27,7 @@ public override bool UseMemoryPreviewToolTip(HotSpot spot, out IntPtr address) public override string GetToolTipText(HotSpot spot) { - var value = ReadFromBuffer(spot.Memory, Offset); + var value = spot.Memory.InterpretData64(Offset); return $"Int64: {value.LongValue}\nUInt64: 0x{value.ULongValue:X016}\nFloat: {value.FloatValue:0.000}\nDouble: {value.DoubleValue:0.000}"; } @@ -46,17 +46,11 @@ protected override int AddComment(DrawContext context, int x, int y) { x = base.AddComment(context, x, y); - var value = ReadFromBuffer(context.Memory, Offset); + var value = context.Memory.InterpretData64(Offset); x = AddComment(context, x, y, value.FloatValue, value.IntPtr, value.UIntPtr); return x; } - - private static UInt64FloatDoubleData ReadFromBuffer(MemoryBuffer memory, int offset) => new UInt64FloatDoubleData - { - Raw1 = memory.ReadInt32(offset), - Raw2 = memory.ReadInt32(offset + sizeof(int)) - }; } } diff --git a/ReClass.NET/Nodes/PointerNode.cs b/ReClass.NET/Nodes/PointerNode.cs index 027b0d28..9df3b8b0 100644 --- a/ReClass.NET/Nodes/PointerNode.cs +++ b/ReClass.NET/Nodes/PointerNode.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using ReClassNET.AddressParser; using ReClassNET.Controls; using ReClassNET.Memory; using ReClassNET.UI; @@ -134,5 +135,39 @@ public override int CalculateDrawnHeight(DrawContext context) } return height; } + + public override void PerformPostInitWork() + { + base.PerformPostInitWork(); + + var parentClass = ParentNode as ClassNode; + if (parentClass == null) + { + return; + } + + var process = Program.RemoteProcess; + IntPtr address; + try + { + address = process.ParseAddress(parentClass.AddressFormula); + } + catch (ParseException) + { + address = IntPtr.Zero; + } + + var memoryBuffer = new MemoryBuffer() { Size = parentClass.MemorySize}; + memoryBuffer.UpdateFrom(process, address); + var ptr = memoryBuffer.ReadIntPtr(Offset); + + var classNode = ((ClassInstanceNode)InnerNode)?.InnerNode as ClassNode; + if (classNode == null) + { + return; + } + + classNode.AddressFormula = ptr.ToString(Constants.AddressHexFormat); + } } } diff --git a/ReClass.NET/Nodes/VirtualMethodTableNode.cs b/ReClass.NET/Nodes/VirtualMethodTableNode.cs index 9e82ab40..2c9099a0 100644 --- a/ReClass.NET/Nodes/VirtualMethodTableNode.cs +++ b/ReClass.NET/Nodes/VirtualMethodTableNode.cs @@ -33,7 +33,33 @@ public override void Initialize() AddNode(CreateDefaultNodeForSize(IntPtr.Size)); } } + + protected override int AddComment(DrawContext context, int x, int y) + { + x = base.AddComment(context, x, y); + + if (context.Settings.ShowCommentRtti) + { + var rtti = GetAssociatedRemoteRuntimeTypeInformation(context); + if (!string.IsNullOrEmpty(rtti)) + { + x = AddText(context, x, y, context.Settings.OffsetColor, HotSpot.ReadOnlyId, rtti) + context.Font.Width; + } + } + return x; + } + + public string GetAssociatedRemoteRuntimeTypeInformation(DrawContext context) + { + var addressFirstVTableFunction = context.Memory.InterpretData64(Offset).IntPtr; + if (addressFirstVTableFunction != IntPtr.Zero) + { + return context.Process.ReadRemoteRuntimeTypeInformation(addressFirstVTableFunction); + } + return string.Empty; + } + public override Size Draw(DrawContext context, int x, int y) { if (IsHidden && !IsWrapped) diff --git a/ReClass.NET/Properties/Resources.Designer.cs b/ReClass.NET/Properties/Resources.Designer.cs index 3d412074..3738ffbc 100644 --- a/ReClass.NET/Properties/Resources.Designer.cs +++ b/ReClass.NET/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ReClassNET.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -190,6 +190,16 @@ internal static System.Drawing.Bitmap B16x16_Button_Array { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap B16x16_Button_AutoName { + get { + object obj = ResourceManager.GetObject("B16x16_Button_AutoName", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -1371,7 +1381,7 @@ internal static System.Drawing.Bitmap B32x32_Plugin { } /// - /// Looks up a localized string similar to 2020/10/17 09:45:04 + /// Looks up a localized string similar to 2023/07/03 12:55:32 ///. /// internal static string BuildDate { diff --git a/ReClass.NET/Properties/Resources.resx b/ReClass.NET/Properties/Resources.resx index 48c2c826..3cee6c55 100644 --- a/ReClass.NET/Properties/Resources.resx +++ b/ReClass.NET/Properties/Resources.resx @@ -517,4 +517,7 @@ ..\Resources\Images\B16x16_Button_NUInt.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Images\B16x16_Button_AutoName.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/ReClass.NET/ReClass.NET.csproj b/ReClass.NET/ReClass.NET.csproj index 0c990cc2..6422eb12 100644 --- a/ReClass.NET/ReClass.NET.csproj +++ b/ReClass.NET/ReClass.NET.csproj @@ -1023,6 +1023,9 @@ + + + powershell -Command "((Get-Date).ToUniversalTime()).ToString(\"yyyy\/MM\/dd HH:mm:ss\") | Out-File '$(ProjectDir)Resources\BuildDate.txt'" diff --git a/ReClass.NET/Resources/Images/B16x16_Button_AutoName.png b/ReClass.NET/Resources/Images/B16x16_Button_AutoName.png new file mode 100644 index 00000000..bfdd7e64 Binary files /dev/null and b/ReClass.NET/Resources/Images/B16x16_Button_AutoName.png differ diff --git a/ReClass.NET/Settings.cs b/ReClass.NET/Settings.cs index b5d9268b..32eafc3d 100644 --- a/ReClass.NET/Settings.cs +++ b/ReClass.NET/Settings.cs @@ -1,11 +1,36 @@ -using System.Drawing; +using System; +using System.Collections.Generic; +using System.Drawing; using System.Text; +using System.Windows.Forms; +using ReClassNET.Nodes; using ReClassNET.Util; namespace ReClassNET { public class Settings { + private readonly Dictionary _shortcutKeyPerNode; + + public Settings() + { + _shortcutKeyPerNode = new Dictionary + { + { typeof(Hex64Node), Keys.Control | Keys.Shift | Keys.D6 }, + { typeof(ClassInstanceNode), Keys.Control | Keys.Shift | Keys.C }, + { typeof(FloatNode), Keys.Control | Keys.Shift | Keys.F }, + { typeof(Hex8Node), Keys.Control | Keys.Shift | Keys.B }, + { typeof(PointerNode), Keys.Control | Keys.Shift | Keys.P }, + { typeof(Vector2Node), Keys.Control | Keys.Shift | Keys.D2 }, + { typeof(Vector3Node), Keys.Control | Keys.Shift | Keys.D3 }, + { typeof(Vector4Node), Keys.Control | Keys.Shift | Keys.D4 }, + { typeof(VirtualMethodTableNode), Keys.Control | Keys.Shift | Keys.V }, + { typeof(BoolNode), Keys.Control | Keys.Shift | Keys.O }, + { typeof(EnumNode), Keys.Control | Keys.Shift | Keys.E }, + { typeof(Int32Node), Keys.Control | Keys.Shift | Keys.I } + }; + } + // Application Settings public string LastProcess { get; set; } = string.Empty; @@ -75,6 +100,11 @@ public class Settings public Color PluginColor { get; set; } = Color.FromArgb(255, 0, 255); public CustomDataMap CustomData { get; } = new CustomDataMap(); + + public Keys GetShortcutKeyForNodeType(Type nodeType) + { + return !_shortcutKeyPerNode.TryGetValue(nodeType, out var shortcutKeys) ? Keys.None : shortcutKeys; + } public Settings Clone() => MemberwiseClone() as Settings; } diff --git a/ReClass.NET/UI/HotSpot.cs b/ReClass.NET/UI/HotSpot.cs index 3a0d4bc0..27b949d0 100644 --- a/ReClass.NET/UI/HotSpot.cs +++ b/ReClass.NET/UI/HotSpot.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Drawing; using ReClassNET.Memory; using ReClassNET.Nodes; diff --git a/ReClass.NET/UI/NodeTypesBuilder.cs b/ReClass.NET/UI/NodeTypesBuilder.cs index 8d519022..b0badd25 100644 --- a/ReClass.NET/UI/NodeTypesBuilder.cs +++ b/ReClass.NET/UI/NodeTypesBuilder.cs @@ -57,14 +57,15 @@ public static IEnumerable CreateToolStripButtons(Action han return CreateToolStripItems(t => { - GetNodeInfoFromType(t, out var label, out var icon); + GetNodeInfoFromType(t, out var label, out var icon, out var shortcutKeys); - var item = new TypeToolStripButton + var item = new TypeToolStripMenuItem { Value = t, ToolTipText = label, DisplayStyle = ToolStripItemDisplayStyle.Image, - Image = icon + Image = icon, + ShortcutKeys = shortcutKeys, }; item.Click += clickHandler; return item; @@ -74,7 +75,7 @@ public static IEnumerable CreateToolStripButtons(Action han Image = p.Icon }, t => { - GetNodeInfoFromType(t, out var label, out var icon); + GetNodeInfoFromType(t, out var label, out var icon, out var shortcutKeys); var item = new TypeToolStripMenuItem { @@ -95,13 +96,14 @@ public static IEnumerable CreateToolStripMenuItems(Action h var items = CreateToolStripItems(t => { - GetNodeInfoFromType(t, out var label, out var icon); + GetNodeInfoFromType(t, out var label, out var icon, out var shortcutKeys); var item = new TypeToolStripMenuItem { Value = t, Text = label, - Image = icon + Image = icon, + ShortcutKeys = shortcutKeys, }; item.Click += clickHandler; return item; @@ -166,10 +168,12 @@ private static IEnumerable CreateToolStripItems(Func