diff --git a/AutoLegalityMod/GUI/SimpleHexEditor.Designer.cs b/AutoLegalityMod/GUI/SimpleHexEditor.Designer.cs index 7aa67bf2..8a34de42 100644 --- a/AutoLegalityMod/GUI/SimpleHexEditor.Designer.cs +++ b/AutoLegalityMod/GUI/SimpleHexEditor.Designer.cs @@ -31,10 +31,11 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.RTB_RAM = new System.Windows.Forms.RichTextBox(); + this.RTB_RAM = new AutoModPlugins.GUI.HexRichTextBox(); this.B_Update = new System.Windows.Forms.Button(); this.PG_BlockView = new System.Windows.Forms.PropertyGrid(); this.CB_AutoRefresh = new System.Windows.Forms.CheckBox(); + this.CB_CopyMethod = new System.Windows.Forms.ComboBox(); this.SuspendLayout(); // // RTB_RAM @@ -56,7 +57,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.B_Update.Location = new System.Drawing.Point(9, 308); this.B_Update.Name = "B_Update"; - this.B_Update.Size = new System.Drawing.Size(277, 26); + this.B_Update.Size = new System.Drawing.Size(114, 26); this.B_Update.TabIndex = 1; this.B_Update.Text = "Update"; this.B_Update.UseVisualStyleBackColor = true; @@ -77,7 +78,7 @@ private void InitializeComponent() // this.CB_AutoRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.CB_AutoRefresh.AutoSize = true; - this.CB_AutoRefresh.Location = new System.Drawing.Point(292, 314); + this.CB_AutoRefresh.Location = new System.Drawing.Point(284, 314); this.CB_AutoRefresh.Name = "CB_AutoRefresh"; this.CB_AutoRefresh.Size = new System.Drawing.Size(88, 17); this.CB_AutoRefresh.TabIndex = 16; @@ -86,11 +87,21 @@ private void InitializeComponent() this.CB_AutoRefresh.UseVisualStyleBackColor = true; this.CB_AutoRefresh.CheckedChanged += new System.EventHandler(this.CB_AutoRefresh_CheckedChanged); // + // CB_CopyMethod + // + this.CB_CopyMethod.FormattingEnabled = true; + this.CB_CopyMethod.Location = new System.Drawing.Point(145, 312); + this.CB_CopyMethod.Name = "CB_CopyMethod"; + this.CB_CopyMethod.Size = new System.Drawing.Size(116, 21); + this.CB_CopyMethod.TabIndex = 17; + this.CB_CopyMethod.SelectedIndexChanged += new System.EventHandler(this.ChangeCopyMethod); + // // SimpleHexEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(384, 343); + this.Controls.Add(this.CB_CopyMethod); this.Controls.Add(this.CB_AutoRefresh); this.Controls.Add(this.PG_BlockView); this.Controls.Add(this.B_Update); @@ -109,9 +120,10 @@ private void InitializeComponent() } #endregion - private System.Windows.Forms.RichTextBox RTB_RAM; + private HexRichTextBox RTB_RAM; private Button B_Update; public PropertyGrid PG_BlockView; private CheckBox CB_AutoRefresh; + private ComboBox CB_CopyMethod; } } \ No newline at end of file diff --git a/AutoLegalityMod/GUI/SimpleHexEditor.cs b/AutoLegalityMod/GUI/SimpleHexEditor.cs index f1ea7037..7fb6b2a5 100644 --- a/AutoLegalityMod/GUI/SimpleHexEditor.cs +++ b/AutoLegalityMod/GUI/SimpleHexEditor.cs @@ -28,6 +28,8 @@ public SimpleHexEditor(byte[] originalBytes, PokeSysBotMini? bot = null, ulong a address = addr; method = rwm; psb = bot; + CB_CopyMethod.DataSource = Enum.GetValues(typeof(CopyMethod)).Cast(); + CB_CopyMethod.SelectedItem = CopyMethod.Bytes; RTB_RAM.Text = string.Join(" ", originalBytes.Select(z => $"{z:X2}")); Bytes = originalBytes; } @@ -65,6 +67,11 @@ private void Update_Click(object sender, EventArgs e) Close(); } + private void ChangeCopyMethod(object sender, EventArgs e) + { + RTB_RAM.method = (CopyMethod)CB_CopyMethod.SelectedItem; + } + private void CB_AutoRefresh_CheckedChanged(object sender, EventArgs e) { if (CB_AutoRefresh.Checked) @@ -87,4 +94,47 @@ private void SimpleHexEditor_FormClosing(object sender, FormClosingEventArgs e) refresh.Stop(); } } + + internal class HexRichTextBox : RichTextBox + { + public CopyMethod method = CopyMethod.Bytes; + + protected override bool ProcessCmdKey(ref Message msg, Keys e) + { + bool ctrlV = e == (Keys.Control | Keys.V); + bool shiftIns = e == (Keys.Shift | Keys.Insert); + bool ctrlC = e == (Keys.Control | Keys.C); + bool ctrlX = e == (Keys.Control | Keys.X); + + if (method == CopyMethod.Integers && (ctrlV || shiftIns)) + { + var text = Clipboard.GetText(); + if (text != null) + { + var split = new string[text.Length / 2 + (text.Length % 2 == 0 ? 0 : 1)]; + for (int i = 0; i < split.Length; i++) + split[i] = text.Substring(i * 2, i * 2 + 2 > text.Length ? 1 : 2); + Clipboard.SetText(string.Join(" ", split)); + } + } + var handled = base.ProcessCmdKey(ref msg, e); + if (method == CopyMethod.Integers) + { + if (ctrlC || ctrlX) + { + if (string.IsNullOrWhiteSpace(SelectedText)) + return false; + Clipboard.SetText(string.Join(string.Empty, SelectedText.Split(' ').Reverse())); + return true; + } + } + return handled; + } + } + + internal enum CopyMethod + { + Bytes, + Integers, + } } diff --git a/PKHeX.Core.Injection/Protocols/LPBDSP.cs b/PKHeX.Core.Injection/Protocols/LPBDSP.cs index eefccdd4..027f0f4a 100644 --- a/PKHeX.Core.Injection/Protocols/LPBDSP.cs +++ b/PKHeX.Core.Injection/Protocols/LPBDSP.cs @@ -22,6 +22,9 @@ public static class LPBDSP private const int DAYCARE_BLOCK_SIZE = 0x2C0; private const int DAYCARE_BLOCK_SIZE_RAM = 0x8 * 4; + private const int MYSTATUS_BLOCK_SIZE = 0x50; + private const int MYSTATUS_BLOCK_SIZE_RAM = 0x34; + #pragma warning disable CS8620 // Argument cannot be used for parameter due to differences in the nullability of reference types. public static Dictionary, Action)> FunctionMap = new () { @@ -139,22 +142,26 @@ public static void SendBox(PokeSysBotMini psb, byte[] boxData, int box) var ptr = GetTrainerPointer(lv); if (ptr == null || psb.com is not ICommunicatorNX sb) return null; - var size = RamOffsets.GetTrainerBlockSize(lv); - var retval = new byte[size]; + var retval = new byte[MYSTATUS_BLOCK_SIZE]; + var ram_block = InjectionUtil.GetPointerAddress(sb, ptr); + if (ram_block == InjectionUtil.INVALID_PTR) + throw new Exception("Invalid Pointer string."); - var trainer_name = ptr + "]+14"; + var trainer_name = ptr.ExtendPointer(0x14); var trainer_name_addr = InjectionUtil.GetPointerAddress(sb, trainer_name); if (trainer_name_addr == InjectionUtil.INVALID_PTR) throw new Exception("Invalid Pointer string."); psb.com.ReadBytes(trainer_name_addr, 0x1A).CopyTo(retval); - var trainer_block_ram = InjectionUtil.GetPointerAddress(sb, ptr); - if (trainer_block_ram == InjectionUtil.INVALID_PTR) - throw new Exception("Invalid Pointer string."); - psb.com.ReadBytes(trainer_block_ram + 0x8, size - 0x1A - 0x2).CopyTo(retval, 0x1A + 0x2); - - // manually set ROM Code to avoid throwing exceptions (bad ram possibly) - retval[0x2B] = BrilliantDiamond.Contains(lv) ? (byte)0 : (byte)1; + var extra = psb.com.ReadBytes(ram_block, MYSTATUS_BLOCK_SIZE_RAM); + // TID, SID, Money, Male + extra.Slice(0x8, 0x9).CopyTo(retval, 0x1C); + // Region Code, Badge Count, TrainerView, ROMCode, GameClear + extra.Slice(0x11, 0x5).CopyTo(retval, 0x28); + // BodyType, Fashion ID + extra.Slice(0x16, 0x2).CopyTo(retval, 0x30); + // StarterType, DSPlayer, FollowIndex, X, Y, Height, Rotation + extra.SliceEnd(0x18).CopyTo(retval, 0x34); return retval; }; @@ -227,14 +234,25 @@ public static void SetMyStatusBlock(PokeSysBotMini psb, byte[] data) var ptr = GetTrainerPointer(lv); if (ptr == null || psb.com is not ICommunicatorNX sb) return; - var size = RamOffsets.GetTrainerBlockSize(lv); + var size = MYSTATUS_BLOCK_SIZE; data = data.Slice(0, size); - var trainer_name = ptr + "]+14"; + var trainer_name = ptr.ExtendPointer(0x14); var trainer_name_addr = InjectionUtil.GetPointerAddress(sb, trainer_name); if (trainer_name_addr == InjectionUtil.INVALID_PTR) throw new Exception("Invalid Pointer string."); + + var retval = new byte[MYSTATUS_BLOCK_SIZE_RAM]; + // TID, SID, Money, Male + data.Slice(0x1C, 0x9).CopyTo(retval, 0x8); + // Region Code, Badge Count, TrainerView, ROMCode, GameClear + data.Slice(0x28, 0x5).CopyTo(retval, 0x11); + // BodyType, Fashion ID + data.Slice(0x30, 0x2).CopyTo(retval, 0x16); + // StarterType, DSPlayer, FollowIndex, X, Y, Height, Rotation + data.SliceEnd(0x34).CopyTo(retval, 0x18); + psb.com.WriteBytes(data.Slice(0, 0x1A), trainer_name_addr); - psb.com.WriteBytes(data.SliceEnd(0x1A + 0x2), InjectionUtil.GetPointerAddress(sb, ptr) + 0x8); + psb.com.WriteBytes(retval.SliceEnd(0x8), InjectionUtil.GetPointerAddress(sb, ptr) + 0x8); } public static byte[]? GetDaycareBlock(PokeSysBotMini psb) @@ -244,8 +262,8 @@ public static void SetMyStatusBlock(PokeSysBotMini psb, byte[] data) return null; var nx = (ICommunicatorNX)psb.com; var addr = InjectionUtil.GetPointerAddress(nx, ptr); - var parent_one = psb.com.ReadBytes(InjectionUtil.GetPointerAddress(nx, ptr + "]+20]+20"), 0x158); - var parent_two = psb.com.ReadBytes(InjectionUtil.GetPointerAddress(nx, ptr + "]+28]+20"), 0x158); + var parent_one = psb.com.ReadBytes(InjectionUtil.GetPointerAddress(nx, ptr.ExtendPointer(0x20, 0x20)), 0x158); + var parent_two = psb.com.ReadBytes(InjectionUtil.GetPointerAddress(nx, ptr.ExtendPointer(0x28, 0x20)), 0x158); var extra = psb.com.ReadBytes(addr + 0x8, 0x18); var extra_arr = Core.ArrayUtil.EnumerateSplit(extra, 0x8).ToArray(); var block = new byte[DAYCARE_BLOCK_SIZE]; @@ -264,8 +282,8 @@ public static void SetDaycareBlock(PokeSysBotMini psb, byte[] data) return; var nx = (ICommunicatorNX)psb.com; var addr = InjectionUtil.GetPointerAddress(nx, ptr); - var parent_one_addr = InjectionUtil.GetPointerAddress(nx, ptr + "]+20]+20"); - var parent_two_addr = InjectionUtil.GetPointerAddress(nx, ptr + "]+28]+20"); + var parent_one_addr = InjectionUtil.GetPointerAddress(nx, ptr.ExtendPointer(0x20, 0x20)); + var parent_two_addr = InjectionUtil.GetPointerAddress(nx, ptr.ExtendPointer(0x28, 0x20)); data = data.Slice(0, DAYCARE_BLOCK_SIZE); psb.com.WriteBytes(data.Slice(0, 0x158), parent_one_addr); psb.com.WriteBytes(data.Slice(0x158, 0x158), parent_two_addr); diff --git a/PKHeX.Core.Injection/Util/InjectionUtil.cs b/PKHeX.Core.Injection/Util/InjectionUtil.cs index d3aa9db8..2c390af4 100644 --- a/PKHeX.Core.Injection/Util/InjectionUtil.cs +++ b/PKHeX.Core.Injection/Util/InjectionUtil.cs @@ -39,5 +39,12 @@ public static ulong GetPointerAddress(this ICommunicatorNX sb, string ptr, bool } return address; } + + public static string ExtendPointer(this string pointer, params uint[] jumps) + { + foreach (var jump in jumps) + pointer = $"[{pointer}]+{jump:X}"; + return pointer; + } } }