From f73cde6c99e38ece6b24305e5d550f19f2ed7bc7 Mon Sep 17 00:00:00 2001 From: avan Date: Sun, 18 Feb 2024 15:19:19 +0800 Subject: [PATCH] Added support for "Invert checked Hidden" and "Disable checked Hidden" in the right-click context menu of the SectionView in the Query window. Disable checked Hidden: Executing "Disable checked Hidden" will set the Valid of the checked Hidden sections to Disable, and update the settings written to the Hidden configuration file at the "path to PS4CheaterNeo\sections\[GAME_ID].conf" path. To revert, manual editing of the conf file is required, changing the Valid of the Hidden sections from False to True. Note: The Query window needs to Refresh Processes to incorporate the new Hidden conf settings. --- PS4CheaterNeo/Main.cs | 18 +- PS4CheaterNeo/Properties/AssemblyInfo.cs | 4 +- PS4CheaterNeo/Query.Designer.cs | 203 ++++++++++-------- PS4CheaterNeo/Query.cs | 88 ++++++-- PS4CheaterNeo/Query.resx | 32 +-- PS4CheaterNeo/common/LanguageJson.cs | 9 + .../languages/LanguageFile_Chinese.json | 3 + .../languages/LanguageFile_English.json | 13 +- .../languages/LanguageFile_French.json | 3 + .../languages/LanguageFile_German.json | 3 + .../languages/LanguageFile_Italian.json | 3 + .../languages/LanguageFile_Japanese.json | 3 + .../languages/LanguageFile_Korean.json | 3 + .../languages/LanguageFile_Russian.json | 3 + .../languages/LanguageFile_Spanish.json | 3 + README.md | 11 +- assets/query_SectionViewMenu.webp | Bin 14930 -> 18508 bytes 17 files changed, 272 insertions(+), 130 deletions(-) diff --git a/PS4CheaterNeo/Main.cs b/PS4CheaterNeo/Main.cs index c8c5a9b..a17d045 100644 --- a/PS4CheaterNeo/Main.cs +++ b/PS4CheaterNeo/Main.cs @@ -79,7 +79,11 @@ public void ParseLanguageJson() string codes = Properties.Settings.Default.UILanguage.Value.ToString(); string path = "languages\\LanguageFile_" + codes + ".json"; - if (!File.Exists(path)) return; + if (!File.Exists(path)) + { + path = "languages\\LanguageFile_" + LanguageCodes.English.ToString() + ".json"; + if (!File.Exists(path)) return; + } using (StreamReader sr = new StreamReader(path)) using (Stream stream = sr.BaseStream) @@ -875,7 +879,8 @@ private void SaveCheatJson() string cheatDesc = row.Cells[(int)ChertCol.CheatListDesc].ToString(); ScanType scanType = this.ParseFromDescription(row.Cells[(int)ChertCol.CheatListType].ToString()); string on = row.Cells[(int)ChertCol.CheatListValue].ToString(); - if (scanType != ScanType.Hex) + if (!string.IsNullOrWhiteSpace((string)row.Cells[(int)ChertCol.CheatListOn])) on = row.Cells[(int)ChertCol.CheatListOn].ToString(); + else if (scanType != ScanType.Hex) { byte[] bytes = ScanTool.ValueStringToByte(scanType, on); on = ScanTool.BytesToString(scanType, bytes, true, on.StartsWith("-")); @@ -887,6 +892,7 @@ private void SaveCheatJson() cheatDesc = m1.Groups[1].Value; off = m1.Groups[3].Value; } + //When opening JSON or SHN files, if cheats have the same description, they will automatically be numbered. When saving the file, the automatically added numbers will be removed. cheatDesc = Regex.Replace(cheatDesc, @"_\d+$", ""); if (modBak != null && modBak.Name == cheatDesc) cheatJson.Mods[cheatJson.Mods.Count - 1].Memory.Add(new CheatJson.Memory(offsetAddr.ToString("X"), on, off)); @@ -936,7 +942,8 @@ private void SaveCheatShn() string cheatDesc = row.Cells[(int)ChertCol.CheatListDesc].ToString(); ScanType scanType = this.ParseFromDescription(row.Cells[(int)ChertCol.CheatListType].ToString()); string on = row.Cells[(int)ChertCol.CheatListValue].ToString(); - if (scanType != ScanType.Hex) + if (!string.IsNullOrWhiteSpace((string)row.Cells[(int)ChertCol.CheatListOn])) on = row.Cells[(int)ChertCol.CheatListOn].ToString(); + else if (scanType != ScanType.Hex) { byte[] bytes = ScanTool.ValueStringToByte(scanType, on); on = ScanTool.BytesToString(scanType, bytes, true, on.StartsWith("-")); @@ -948,8 +955,9 @@ private void SaveCheatShn() cheatDesc = m1.Groups[1].Value; off = m1.Groups[3].Value; } - on = Regex.Replace(on, @"(\w\w)(?=\w)", @"$1-"); - off = Regex.Replace(off, @"(\w\w)(?=\w)", @"$1-"); + on = Regex.Replace(on, @"(\w\w)(?=\w)", @"$1-"); //Separate Hex values with "-" + off = Regex.Replace(off, @"(\w\w)(?=\w)", @"$1-"); //Separate Hex values with "-" + //When opening JSON or SHN files, if cheats have the same description, they will automatically be numbered. When saving the file, the automatically added numbers will be removed. cheatDesc = Regex.Replace(cheatDesc, @"_\d+$", ""); if (cheatBak != null && cheatBak.Text == cheatDesc) cheatTrainer.Cheats[cheatTrainer.Cheats.Count - 1].Cheatlines.Add(new CheatTrainer.Cheatline(offsetAddr.ToString("X"), section.SN, on, off)); diff --git a/PS4CheaterNeo/Properties/AssemblyInfo.cs b/PS4CheaterNeo/Properties/AssemblyInfo.cs index f6f49cc..fc7980f 100644 --- a/PS4CheaterNeo/Properties/AssemblyInfo.cs +++ b/PS4CheaterNeo/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.2.5")] -[assembly: AssemblyFileVersion("1.0.2.5")] +[assembly: AssemblyVersion("1.0.2.6")] +[assembly: AssemblyFileVersion("1.0.2.6")] diff --git a/PS4CheaterNeo/Query.Designer.cs b/PS4CheaterNeo/Query.Designer.cs index a37e2e1..4b975d6 100644 --- a/PS4CheaterNeo/Query.Designer.cs +++ b/PS4CheaterNeo/Query.Designer.cs @@ -34,34 +34,37 @@ private void InitializeComponent() this.ResultViewMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.ResultViewAddToCheatGrid = new System.Windows.Forms.ToolStripMenuItem(); this.ResultViewSelectAll = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.ResultViewMenu_ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.ResultViewHexEditor = new System.Windows.Forms.ToolStripMenuItem(); this.ResultViewCopyAddress = new System.Windows.Forms.ToolStripMenuItem(); this.ResultViewDump = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.ResultViewMenu_ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.ResultViewFindPointer = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.SectionViewHexEditor = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.SectionViewMenu_ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.SectionViewCheck = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.SectionViewMenu_ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.SectionViewItems = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewCheckAll = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewUnCheckAll = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewInvertChecked = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.SectionViewMenu_ToolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); this.SectionViewCheckContains = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewUnCheckContains = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewTextContains = new System.Windows.Forms.ToolStripTextBox(); - this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.SectionViewMenu_ToolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); this.SectionViewCheckProt = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewUnCheckProt = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewTextProt = new System.Windows.Forms.ToolStripTextBox(); - this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this.SectionViewHiddens = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewCheckAllHidden = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewUnCheckAllHidden = new System.Windows.Forms.ToolStripMenuItem(); + this.SectionViewInvertCheckedHidden = new System.Windows.Forms.ToolStripMenuItem(); + this.SectionViewDisableCheckedHidden = new System.Windows.Forms.ToolStripMenuItem(); + this.SectionViewMenu_ToolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); this.SectionViewDump = new System.Windows.Forms.ToolStripMenuItem(); this.SectionViewImport = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); this.Panel1 = new System.Windows.Forms.Panel(); this.SplitContainer1 = new PS4CheaterNeo.CollapsibleSplitContainer(); this.ResultView = new System.Windows.Forms.ListView(); @@ -157,11 +160,11 @@ private void InitializeComponent() this.ResultViewMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ResultViewAddToCheatGrid, this.ResultViewSelectAll, - this.ToolStripSeparator1, + this.ResultViewMenu_ToolStripSeparator1, this.ResultViewHexEditor, this.ResultViewCopyAddress, this.ResultViewDump, - this.ToolStripSeparator2, + this.ResultViewMenu_ToolStripSeparator2, this.ResultViewFindPointer}); this.ResultViewMenu.Name = "ResultViewMenu"; this.ResultViewMenu.Size = new System.Drawing.Size(177, 148); @@ -180,10 +183,10 @@ private void InitializeComponent() this.ResultViewSelectAll.Text = "Select All"; this.ResultViewSelectAll.Click += new System.EventHandler(this.ResultViewSelectAll_Click); // - // ToolStripSeparator1 + // ResultViewMenu_ToolStripSeparator1 // - this.ToolStripSeparator1.Name = "ToolStripSeparator1"; - this.ToolStripSeparator1.Size = new System.Drawing.Size(173, 6); + this.ResultViewMenu_ToolStripSeparator1.Name = "ResultViewMenu_ToolStripSeparator1"; + this.ResultViewMenu_ToolStripSeparator1.Size = new System.Drawing.Size(173, 6); // // ResultViewHexEditor // @@ -207,10 +210,10 @@ private void InitializeComponent() this.ResultViewDump.Text = "Dump"; this.ResultViewDump.Click += new System.EventHandler(this.ResultViewDump_Click); // - // ToolStripSeparator2 + // ResultViewMenu_ToolStripSeparator2 // - this.ToolStripSeparator2.Name = "ToolStripSeparator2"; - this.ToolStripSeparator2.Size = new System.Drawing.Size(173, 6); + this.ResultViewMenu_ToolStripSeparator2.Name = "ResultViewMenu_ToolStripSeparator2"; + this.ResultViewMenu_ToolStripSeparator2.Size = new System.Drawing.Size(173, 6); // // ResultViewFindPointer // @@ -223,78 +226,84 @@ private void InitializeComponent() // this.SectionViewMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.SectionViewHexEditor, - this.ToolStripSeparator3, + this.SectionViewMenu_ToolStripSeparator1, this.SectionViewCheck, - this.ToolStripSeparator4, - this.SectionViewCheckAll, - this.SectionViewUnCheckAll, - this.SectionViewInvertChecked, - this.ToolStripSeparator5, - this.SectionViewCheckContains, - this.SectionViewUnCheckContains, - this.SectionViewTextContains, - this.toolStripSeparator6, - this.SectionViewCheckProt, - this.SectionViewUnCheckProt, - this.SectionViewTextProt, - this.toolStripSeparator7, - this.SectionViewCheckAllHidden, - this.SectionViewUnCheckAllHidden, + this.SectionViewMenu_ToolStripSeparator2, + this.SectionViewItems, + this.SectionViewHiddens, + this.SectionViewMenu_ToolStripSeparator3, this.SectionViewDump, - this.SectionViewImport, - this.toolStripSeparator8}); + this.SectionViewImport}); this.SectionViewMenu.Name = "SectionViewMenu"; - this.SectionViewMenu.Size = new System.Drawing.Size(208, 362); + this.SectionViewMenu.Size = new System.Drawing.Size(150, 154); // // SectionViewHexEditor // this.SectionViewHexEditor.Name = "SectionViewHexEditor"; - this.SectionViewHexEditor.Size = new System.Drawing.Size(207, 22); + this.SectionViewHexEditor.Size = new System.Drawing.Size(149, 22); this.SectionViewHexEditor.Text = "Hex Editor"; this.SectionViewHexEditor.Click += new System.EventHandler(this.SectionViewHexEditor_Click); // - // ToolStripSeparator3 + // SectionViewMenu_ToolStripSeparator1 // - this.ToolStripSeparator3.Name = "ToolStripSeparator3"; - this.ToolStripSeparator3.Size = new System.Drawing.Size(204, 6); + this.SectionViewMenu_ToolStripSeparator1.Name = "SectionViewMenu_ToolStripSeparator1"; + this.SectionViewMenu_ToolStripSeparator1.Size = new System.Drawing.Size(146, 6); // // SectionViewCheck // this.SectionViewCheck.Name = "SectionViewCheck"; - this.SectionViewCheck.Size = new System.Drawing.Size(207, 22); + this.SectionViewCheck.Size = new System.Drawing.Size(149, 22); this.SectionViewCheck.Text = "Check"; this.SectionViewCheck.Click += new System.EventHandler(this.SectionViewCheck_Click); // - // ToolStripSeparator4 + // SectionViewMenu_ToolStripSeparator2 + // + this.SectionViewMenu_ToolStripSeparator2.Name = "SectionViewMenu_ToolStripSeparator2"; + this.SectionViewMenu_ToolStripSeparator2.Size = new System.Drawing.Size(146, 6); + // + // SectionViewItems // - this.ToolStripSeparator4.Name = "ToolStripSeparator4"; - this.ToolStripSeparator4.Size = new System.Drawing.Size(204, 6); + this.SectionViewItems.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.SectionViewCheckAll, + this.SectionViewUnCheckAll, + this.SectionViewInvertChecked, + this.SectionViewMenu_ToolStripSeparator4, + this.SectionViewCheckContains, + this.SectionViewUnCheckContains, + this.SectionViewTextContains, + this.SectionViewMenu_ToolStripSeparator5, + this.SectionViewCheckProt, + this.SectionViewUnCheckProt, + this.SectionViewTextProt}); + this.SectionViewItems.Name = "SectionViewItems"; + this.SectionViewItems.Size = new System.Drawing.Size(149, 22); + this.SectionViewItems.Text = "Items"; // // SectionViewCheckAll // this.SectionViewCheckAll.Name = "SectionViewCheckAll"; this.SectionViewCheckAll.Size = new System.Drawing.Size(207, 22); - this.SectionViewCheckAll.Text = "Check All"; + this.SectionViewCheckAll.Text = "Check all"; this.SectionViewCheckAll.Click += new System.EventHandler(this.SectionViewCheckAll_Click); // // SectionViewUnCheckAll // this.SectionViewUnCheckAll.Name = "SectionViewUnCheckAll"; this.SectionViewUnCheckAll.Size = new System.Drawing.Size(207, 22); - this.SectionViewUnCheckAll.Text = "Un-Check All"; + this.SectionViewUnCheckAll.Text = "Un-Check all"; this.SectionViewUnCheckAll.Click += new System.EventHandler(this.SectionViewUnCheckAll_Click); // // SectionViewInvertChecked // this.SectionViewInvertChecked.Name = "SectionViewInvertChecked"; this.SectionViewInvertChecked.Size = new System.Drawing.Size(207, 22); - this.SectionViewInvertChecked.Text = "Invert Checked"; + this.SectionViewInvertChecked.Text = "Invert checked"; this.SectionViewInvertChecked.Click += new System.EventHandler(this.SectionViewInvertChecked_Click); // - // ToolStripSeparator5 + // SectionViewMenu_ToolStripSeparator4 // - this.ToolStripSeparator5.Name = "ToolStripSeparator5"; - this.ToolStripSeparator5.Size = new System.Drawing.Size(204, 6); + this.SectionViewMenu_ToolStripSeparator4.Name = "SectionViewMenu_ToolStripSeparator4"; + this.SectionViewMenu_ToolStripSeparator4.Size = new System.Drawing.Size(204, 6); // // SectionViewCheckContains // @@ -314,13 +323,14 @@ private void InitializeComponent() // this.SectionViewTextContains.BackColor = System.Drawing.SystemColors.ActiveCaption; this.SectionViewTextContains.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.SectionViewTextContains.Font = new System.Drawing.Font("Microsoft JhengHei UI", 9F); this.SectionViewTextContains.Name = "SectionViewTextContains"; this.SectionViewTextContains.Size = new System.Drawing.Size(145, 16); // - // toolStripSeparator6 + // SectionViewMenu_ToolStripSeparator5 // - this.toolStripSeparator6.Name = "toolStripSeparator6"; - this.toolStripSeparator6.Size = new System.Drawing.Size(204, 6); + this.SectionViewMenu_ToolStripSeparator5.Name = "SectionViewMenu_ToolStripSeparator5"; + this.SectionViewMenu_ToolStripSeparator5.Size = new System.Drawing.Size(204, 6); // // SectionViewCheckProt // @@ -340,47 +350,68 @@ private void InitializeComponent() // this.SectionViewTextProt.BackColor = System.Drawing.SystemColors.ActiveCaption; this.SectionViewTextProt.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.SectionViewTextProt.Font = new System.Drawing.Font("Microsoft JhengHei UI", 9F); this.SectionViewTextProt.Name = "SectionViewTextProt"; this.SectionViewTextProt.Size = new System.Drawing.Size(145, 16); // - // toolStripSeparator7 + // SectionViewHiddens // - this.toolStripSeparator7.Name = "toolStripSeparator7"; - this.toolStripSeparator7.Size = new System.Drawing.Size(204, 6); + this.SectionViewHiddens.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.SectionViewCheckAllHidden, + this.SectionViewUnCheckAllHidden, + this.SectionViewInvertCheckedHidden, + this.SectionViewDisableCheckedHidden}); + this.SectionViewHiddens.Name = "SectionViewHiddens"; + this.SectionViewHiddens.Size = new System.Drawing.Size(149, 22); + this.SectionViewHiddens.Text = "Hidden Items"; // // SectionViewCheckAllHidden // this.SectionViewCheckAllHidden.Name = "SectionViewCheckAllHidden"; - this.SectionViewCheckAllHidden.Size = new System.Drawing.Size(207, 22); - this.SectionViewCheckAllHidden.Text = "Check All Hidden"; + this.SectionViewCheckAllHidden.Size = new System.Drawing.Size(211, 22); + this.SectionViewCheckAllHidden.Text = "Check all Hidden"; this.SectionViewCheckAllHidden.Click += new System.EventHandler(this.SectionViewCheckAllHidden_Click); // // SectionViewUnCheckAllHidden // this.SectionViewUnCheckAllHidden.Name = "SectionViewUnCheckAllHidden"; - this.SectionViewUnCheckAllHidden.Size = new System.Drawing.Size(207, 22); - this.SectionViewUnCheckAllHidden.Text = "Un-Check All Hidden"; + this.SectionViewUnCheckAllHidden.Size = new System.Drawing.Size(211, 22); + this.SectionViewUnCheckAllHidden.Text = "Un-Check all Hidden"; this.SectionViewUnCheckAllHidden.Click += new System.EventHandler(this.SectionViewUnCheckAllHidden_Click); // + // SectionViewInvertCheckedHidden + // + this.SectionViewInvertCheckedHidden.Name = "SectionViewInvertCheckedHidden"; + this.SectionViewInvertCheckedHidden.Size = new System.Drawing.Size(211, 22); + this.SectionViewInvertCheckedHidden.Text = "Invert checked Hidden"; + this.SectionViewInvertCheckedHidden.Click += new System.EventHandler(this.SectionViewInvertCheckedHidden_Click); + // + // SectionViewDisableCheckedHidden + // + this.SectionViewDisableCheckedHidden.Name = "SectionViewDisableCheckedHidden"; + this.SectionViewDisableCheckedHidden.Size = new System.Drawing.Size(211, 22); + this.SectionViewDisableCheckedHidden.Text = "Disable checked Hidden"; + this.SectionViewDisableCheckedHidden.Click += new System.EventHandler(this.SectionViewDisableCheckedHidden_Click); + // + // SectionViewMenu_ToolStripSeparator3 + // + this.SectionViewMenu_ToolStripSeparator3.Name = "SectionViewMenu_ToolStripSeparator3"; + this.SectionViewMenu_ToolStripSeparator3.Size = new System.Drawing.Size(146, 6); + // // SectionViewDump // this.SectionViewDump.Name = "SectionViewDump"; - this.SectionViewDump.Size = new System.Drawing.Size(207, 22); + this.SectionViewDump.Size = new System.Drawing.Size(149, 22); this.SectionViewDump.Text = "Dump"; this.SectionViewDump.Click += new System.EventHandler(this.SectionViewDump_Click); // // SectionViewImport // this.SectionViewImport.Name = "SectionViewImport"; - this.SectionViewImport.Size = new System.Drawing.Size(207, 22); + this.SectionViewImport.Size = new System.Drawing.Size(149, 22); this.SectionViewImport.Text = "Import"; this.SectionViewImport.Click += new System.EventHandler(this.SectionViewImport_Click); // - // toolStripSeparator8 - // - this.toolStripSeparator8.Name = "toolStripSeparator8"; - this.toolStripSeparator8.Size = new System.Drawing.Size(204, 6); - // // Panel1 // this.Panel1.Controls.Add(this.SplitContainer1); @@ -792,7 +823,7 @@ private void InitializeComponent() this.TableLayoutRightBottom.Controls.Add(this.CompareTypeBox, 0, 4); this.TableLayoutRightBottom.Controls.Add(this.ScanTypeBox, 0, 3); this.TableLayoutRightBottom.Dock = System.Windows.Forms.DockStyle.Bottom; - this.TableLayoutRightBottom.Location = new System.Drawing.Point(0, 0); + this.TableLayoutRightBottom.Location = new System.Drawing.Point(0, 1); this.TableLayoutRightBottom.Margin = new System.Windows.Forms.Padding(0); this.TableLayoutRightBottom.Name = "TableLayoutRightBottom"; this.TableLayoutRightBottom.Padding = new System.Windows.Forms.Padding(3, 0, 0, 0); @@ -1263,7 +1294,6 @@ private void InitializeComponent() this.Load += new System.EventHandler(this.Query_Load); this.ResultViewMenu.ResumeLayout(false); this.SectionViewMenu.ResumeLayout(false); - this.SectionViewMenu.PerformLayout(); this.Panel1.ResumeLayout(false); this.SplitContainer1.Panel1.ResumeLayout(false); this.SplitContainer1.Panel1.PerformLayout(); @@ -1323,15 +1353,15 @@ private void InitializeComponent() private System.Windows.Forms.ProgressBar ToolStripBar; private System.Windows.Forms.ContextMenuStrip ResultViewMenu; private System.Windows.Forms.ToolStripMenuItem ResultViewAddToCheatGrid; - private System.Windows.Forms.ToolStripSeparator ToolStripSeparator1; + private System.Windows.Forms.ToolStripSeparator ResultViewMenu_ToolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem ResultViewHexEditor; private System.Windows.Forms.ToolStripMenuItem ResultViewDump; - private System.Windows.Forms.ToolStripSeparator ToolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator ResultViewMenu_ToolStripSeparator2; private System.Windows.Forms.ToolStripMenuItem ResultViewFindPointer; private System.Windows.Forms.ContextMenuStrip SectionViewMenu; private System.Windows.Forms.ToolStripMenuItem SectionViewHexEditor; private System.Windows.Forms.ToolStripMenuItem SectionViewDump; - private System.Windows.Forms.ToolStripSeparator ToolStripSeparator3; + private System.Windows.Forms.ToolStripSeparator SectionViewMenu_ToolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem SectionViewCheck; private System.Windows.Forms.TextBox AddrMinBox; private System.Windows.Forms.TextBox AddrMaxBox; @@ -1370,29 +1400,32 @@ private void InitializeComponent() private System.Windows.Forms.TableLayoutPanel TableLayoutRightTop; private System.Windows.Forms.TableLayoutPanel TableLayoutRightTop1; private System.Windows.Forms.Button SectionSearchBtn; - private System.Windows.Forms.ToolStripSeparator ToolStripSeparator4; + private System.Windows.Forms.ToolStripSeparator SectionViewMenu_ToolStripSeparator2; + private System.Windows.Forms.ToolStripSeparator SectionViewMenu_ToolStripSeparator3; + private System.Windows.Forms.CheckBox CompareFirstBox; + private System.Windows.Forms.ToolStripMenuItem ResultViewSelectAll; + private System.Windows.Forms.CheckBox AddrIsFilterBox; + private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom1; + private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom; + private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom4; + private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom5; + private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom3; + private System.Windows.Forms.ToolStripMenuItem SectionViewItems; + private System.Windows.Forms.ToolStripMenuItem SectionViewCheckAll; private System.Windows.Forms.ToolStripMenuItem SectionViewUnCheckAll; private System.Windows.Forms.ToolStripMenuItem SectionViewInvertChecked; - private System.Windows.Forms.ToolStripSeparator ToolStripSeparator5; - private System.Windows.Forms.ToolStripMenuItem SectionViewCheckAll; - private System.Windows.Forms.CheckBox CompareFirstBox; + private System.Windows.Forms.ToolStripSeparator SectionViewMenu_ToolStripSeparator4; private System.Windows.Forms.ToolStripMenuItem SectionViewCheckContains; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; private System.Windows.Forms.ToolStripMenuItem SectionViewUnCheckContains; private System.Windows.Forms.ToolStripTextBox SectionViewTextContains; + private System.Windows.Forms.ToolStripSeparator SectionViewMenu_ToolStripSeparator5; private System.Windows.Forms.ToolStripMenuItem SectionViewCheckProt; private System.Windows.Forms.ToolStripMenuItem SectionViewUnCheckProt; private System.Windows.Forms.ToolStripTextBox SectionViewTextProt; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; - private System.Windows.Forms.ToolStripMenuItem ResultViewSelectAll; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator8; + private System.Windows.Forms.ToolStripMenuItem SectionViewHiddens; private System.Windows.Forms.ToolStripMenuItem SectionViewCheckAllHidden; private System.Windows.Forms.ToolStripMenuItem SectionViewUnCheckAllHidden; - private System.Windows.Forms.CheckBox AddrIsFilterBox; - private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom1; - private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom; - private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom4; - private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom5; - private System.Windows.Forms.TableLayoutPanel TableLayoutRightBottom3; + private System.Windows.Forms.ToolStripMenuItem SectionViewInvertCheckedHidden; + private System.Windows.Forms.ToolStripMenuItem SectionViewDisableCheckedHidden; } } \ No newline at end of file diff --git a/PS4CheaterNeo/Query.cs b/PS4CheaterNeo/Query.cs index 90273d2..3155471 100644 --- a/PS4CheaterNeo/Query.cs +++ b/PS4CheaterNeo/Query.cs @@ -104,19 +104,21 @@ public void ApplyUI(LanguageJson langJson) SectionViewOffset.Text = langJson.QueryForm.SectionViewOffset; SectionViewEnd.Text = langJson.QueryForm.SectionViewEnd; - SectionViewHexEditor.Text = langJson.QueryForm.SectionViewHexEditor; - SectionViewCheck.Text = langJson.QueryForm.SectionViewCheck; - SectionViewCheckAll.Text = langJson.QueryForm.SectionViewCheckAll; - SectionViewUnCheckAll.Text = langJson.QueryForm.SectionViewUnCheckAll; - SectionViewInvertChecked.Text = langJson.QueryForm.SectionViewInvertChecked; - SectionViewCheckContains.Text = langJson.QueryForm.SectionViewCheckContains; - SectionViewUnCheckContains.Text = langJson.QueryForm.SectionViewUnCheckContains; - SectionViewCheckProt.Text = langJson.QueryForm.SectionViewCheckProt; - SectionViewUnCheckProt.Text = langJson.QueryForm.SectionViewUnCheckProt; - SectionViewCheckAllHidden.Text = langJson.QueryForm.SectionViewCheckAllHidden; - SectionViewUnCheckAllHidden.Text = langJson.QueryForm.SectionViewUnCheckAllHidden; - SectionViewDump.Text = langJson.QueryForm.SectionViewDump; - SectionViewImport.Text = langJson.QueryForm.SectionViewImport; + SectionViewHexEditor.Text = langJson.QueryForm.SectionViewHexEditor; + SectionViewCheck.Text = langJson.QueryForm.SectionViewCheck; + SectionViewCheckAll.Text = langJson.QueryForm.SectionViewCheckAll; + SectionViewUnCheckAll.Text = langJson.QueryForm.SectionViewUnCheckAll; + SectionViewInvertChecked.Text = langJson.QueryForm.SectionViewInvertChecked; + SectionViewCheckContains.Text = langJson.QueryForm.SectionViewCheckContains; + SectionViewUnCheckContains.Text = langJson.QueryForm.SectionViewUnCheckContains; + SectionViewCheckProt.Text = langJson.QueryForm.SectionViewCheckProt; + SectionViewUnCheckProt.Text = langJson.QueryForm.SectionViewUnCheckProt; + SectionViewCheckAllHidden.Text = langJson.QueryForm.SectionViewCheckAllHidden; + SectionViewUnCheckAllHidden.Text = langJson.QueryForm.SectionViewUnCheckAllHidden; + SectionViewInvertCheckedHidden.Text = langJson.QueryForm.SectionViewInvertCheckedHidden; + SectionViewDisableCheckedHidden.Text = langJson.QueryForm.SectionViewDisableCheckedHidden; + SectionViewDump.Text = langJson.QueryForm.SectionViewDump; + SectionViewImport.Text = langJson.QueryForm.SectionViewImport; AddrMinLabel.Text = langJson.QueryForm.AddrMinLabel; AddrMaxLabel.Text = langJson.QueryForm.AddrMaxLabel; @@ -284,8 +286,8 @@ private void ProcessesBox_SelectedIndexChanged(object sender, EventArgs e) { try { - SectionViewCheckAllHidden.Visible = SectionViewDetectHiddenSection; - SectionViewUnCheckAllHidden.Visible = SectionViewDetectHiddenSection; + SectionViewHiddens.Visible = SectionViewDetectHiddenSection; + SectionViewDisableCheckedHidden.Visible = WriteHiddenSectionConf; SectionView.BeginUpdate(); SectionView.VirtualListSize = 0; @@ -2036,6 +2038,62 @@ private void SectionViewProtection(bool isProt) ToolStripMsg.Text = string.Format("Total section: {0}, Selected section: {1}, Search size: {2}MB", sectionItems.Count, sectionTool.TotalSelected, sectionTool.TotalMemorySize / (1024 * 1024)); SectionView.EndUpdate(); } + + private void SectionViewInvertCheckedHidden_Click(object sender, EventArgs e) + { + if (sectionItems.Count == 0) return; + + SectionView.BeginUpdate(); + for (int idx = 0; idx < sectionItems.Count; ++idx) + { + ListViewItem item = sectionItems[idx]; + uint sid = uint.Parse(item.SubItems[(int)SectionCol.SectionViewSID].Text); + string name = item.SubItems[(int)SectionCol.SectionViewName].Text; + if (!name.Contains("Hidden")) continue; + + item.Checked = !item.Checked; + SectionCheckUpdate(item.Checked, sid); + } + if (AddrMinBox.Tag != null) AddrMinBox.Text = ((ulong)AddrMinBox.Tag).ToString("X"); + if (AddrMaxBox.Tag != null) AddrMaxBox.Text = ((ulong)AddrMaxBox.Tag).ToString("X"); + ToolStripMsg.Text = string.Format("Total section: {0}, Selected section: {1}, Search size: {2}MB", sectionItems.Count, sectionTool.TotalSelected, sectionTool.TotalMemorySize / (1024 * 1024)); + SectionView.EndUpdate(); + } + + private void SectionViewDisableCheckedHidden_Click(object sender, EventArgs e) + { + if (sectionItems.Count == 0) return; + if (MessageBox.Show(mainForm.langJson != null ? mainForm.langJson.QueryForm.SectionViewDisableCheckedHiddenWarning : "Warning", "Disable checked Hidden", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return; + + mainForm.InitGameInfo(); + mainForm.InitLocalHiddenSections(); + if (mainForm.LocalHiddenSections.Count == 0) + { + MessageBox.Show(string.Format("Hidden Sections data (sections{0}{1}.conf) was not found locally. \nYou need to enable the \"WriteHiddenSectionConf\" option and \nrestart the Query window to initialize the configuration file.", Path.DirectorySeparatorChar, mainForm.GameID), "Scan", MessageBoxButtons.OK); + return; + } + + SectionView.BeginUpdate(); + for (int idx = 0; idx < sectionItems.Count; ++idx) + { + ListViewItem item = sectionItems[idx]; + uint sid = uint.Parse(item.SubItems[(int)SectionCol.SectionViewSID].Text); + string name = item.SubItems[(int)SectionCol.SectionViewName].Text; + if (!name.Contains("Hidden") || !item.Checked) continue; + + if (mainForm.LocalHiddenSections.TryGetValue(sid, out (ulong Start, ulong End, bool Valid, byte Prot, string Name) localHiddenSection)) + { + localHiddenSection.Valid = false; + mainForm.LocalHiddenSections[sid] = localHiddenSection; + } + item.Checked = false; + SectionCheckUpdate(item.Checked, sid, true); + } + mainForm.UpdateLocalHiddenSections(); + ToolStripMsg.Text = string.Format("Total section: {0}, Selected section: {1}, Search size: {2}MB", sectionItems.Count, sectionTool.TotalSelected, sectionTool.TotalMemorySize / (1024 * 1024)); + SectionView.EndUpdate(); + + } #endregion #region ResultViewMenu diff --git a/PS4CheaterNeo/Query.resx b/PS4CheaterNeo/Query.resx index 4c5895f..0a5ff7b 100644 --- a/PS4CheaterNeo/Query.resx +++ b/PS4CheaterNeo/Query.resx @@ -127,22 +127,6 @@ 17, 17 - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAAGdJREFUOE9jIAa8f/9e4OvXrwFQLmkApPnbt28XXr9+/f/79+8JUGHiAExza2vr - /+Tk5P8kGYKs2cnJ6b+vr+//K1euEGfASNQMAhQbAAKjhmACZENITsowADOELM0wADIEe3ZmYAAA/e0P - NJCgSVgAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAAGdJREFUOE9jIAa8f/9e4OvXrwFQLmkApPnbt28XXr9+/f/79+8JUGHiAExza2vr - /+Tk5P8kGYKs2cnJ6b+vr+//K1euEGfASNQMAhQbAAKjhmACZENITsowADOELM0wADIEe3ZmYAAA/e0P - NJCgSVgAAAAASUVORK5CYII= - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO @@ -192,6 +176,22 @@ 3P9mFVVgtriCvC4EPVEFh94ThpfOuPhAtNHmwZIgVEHytFSW9plskRsMlhDxMPwC/ozns7RxRaITCfGj BEQKONTYyAM8+F9JjYDDjVEkvwScKJJAAUeVNKU2vM2PuC0ioQKOJ1ncK0E333h40i3J/CngeJKgYQ4A 7Qc/8U6/HCfp8gAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAAGdJREFUOE9jIAa8f/9e4OvXrwFQLmkApPnbt28XXr9+/f/79+8JUGHiAExza2vr + /+Tk5P8kGYKs2cnJ6b+vr+//K1euEGfASNQMAhQbAAKjhmACZENITsowADOELM0wADIEe3ZmYAAA/e0P + NJCgSVgAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAAGdJREFUOE9jIAa8f/9e4OvXrwFQLmkApPnbt28XXr9+/f/79+8JUGHiAExza2vr + /+Tk5P8kGYKs2cnJ6b+vr+//K1euEGfASNQMAhQbAAKjhmACZENITsowADOELM0wADIEe3ZmYAAA/e0P + NJCgSVgAAAAASUVORK5CYII= diff --git a/PS4CheaterNeo/common/LanguageJson.cs b/PS4CheaterNeo/common/LanguageJson.cs index 6a3cde1..458acee 100644 --- a/PS4CheaterNeo/common/LanguageJson.cs +++ b/PS4CheaterNeo/common/LanguageJson.cs @@ -278,6 +278,15 @@ public partial class QueryForm [System.Runtime.Serialization.DataMemberAttribute()] public string SectionViewUnCheckAllHidden; + [System.Runtime.Serialization.DataMemberAttribute()] + public string SectionViewInvertCheckedHidden; + + [System.Runtime.Serialization.DataMemberAttribute()] + public string SectionViewDisableCheckedHidden; + + [System.Runtime.Serialization.DataMemberAttribute()] + public string SectionViewDisableCheckedHiddenWarning; + [System.Runtime.Serialization.DataMemberAttribute()] public string SectionViewDump; diff --git a/PS4CheaterNeo/languages/LanguageFile_Chinese.json b/PS4CheaterNeo/languages/LanguageFile_Chinese.json index 4a77f98..09d52ff 100644 --- a/PS4CheaterNeo/languages/LanguageFile_Chinese.json +++ b/PS4CheaterNeo/languages/LanguageFile_Chinese.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "勾選非Prot:", "SectionViewCheckAllHidden": "勾選Hidden", "SectionViewUnCheckAllHidden": "勾選非Hidden", + "SectionViewInvertCheckedHidden": "反轉勾選Hidden", + "SectionViewDisableCheckedHidden": "停用勾選的Hidden", + "SectionViewDisableCheckedHiddenWarning": "警告! \n\n執行\"停用勾選的Hidden\"會將已勾選的Hidden sections的Valid設置為Disable,並將設定更新寫入至\"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\"路徑的Hidden設定檔案。\n\n若要復原需要手動編輯conf檔案,將Hidden sections的Valid由False改為True。\n\n是否繼續執行? \n\n注: Query視窗需要Refresh Processes才會帶入新的Hidden conf設定", "SectionViewDump": "傾印", "SectionViewImport": "匯入", diff --git a/PS4CheaterNeo/languages/LanguageFile_English.json b/PS4CheaterNeo/languages/LanguageFile_English.json index 0152817..39af26c 100644 --- a/PS4CheaterNeo/languages/LanguageFile_English.json +++ b/PS4CheaterNeo/languages/LanguageFile_English.json @@ -74,15 +74,18 @@ "SectionViewHexEditor": "Hex Editor", "SectionViewCheck": "Check", - "SectionViewCheckAll": "Check All", - "SectionViewUnCheckAll": "Un-Check All", - "SectionViewInvertChecked": "Invert Checked", + "SectionViewCheckAll": "Check all", + "SectionViewUnCheckAll": "Un-Check all", + "SectionViewInvertChecked": "Invert checked", "SectionViewCheckContains": "Check that contains:", "SectionViewUnCheckContains": "Un-Check that contains:", "SectionViewCheckProt": "Check that has prot:", "SectionViewUnCheckProt": "Un-Check that has prot:", - "SectionViewCheckAllHidden": "Check All Hidden", - "SectionViewUnCheckAllHidden": "Un-Check All Hidden", + "SectionViewCheckAllHidden": "Check all Hidden", + "SectionViewUnCheckAllHidden": "Un-Check all Hidden", + "SectionViewInvertCheckedHidden": "Invert checked Hidden", + "SectionViewDisableCheckedHidden": "Disable checked Hidden", + "SectionViewDisableCheckedHiddenWarning": "Warning! \n\nExecuting \"Disable checked Hidden\" will set the Valid of the checked Hidden sections to Disable, and update the settings written to the Hidden configuration file at the \"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\" path. \n\nTo revert, manual editing of the conf file is required, changing the Valid of the Hidden sections from False to True. \n\nDo you want to continue executing? \n\nNote: The Query window needs to Refresh Processes to incorporate the new Hidden conf settings.", "SectionViewDump": "Dump", "SectionViewImport": "Import", diff --git a/PS4CheaterNeo/languages/LanguageFile_French.json b/PS4CheaterNeo/languages/LanguageFile_French.json index 2fdad78..16ac359 100644 --- a/PS4CheaterNeo/languages/LanguageFile_French.json +++ b/PS4CheaterNeo/languages/LanguageFile_French.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "Décocher ceux qui ont le prot:", "SectionViewCheckAllHidden": "Tout cocher (caché)", "SectionViewUnCheckAllHidden": "Tout décocher (caché)", + "SectionViewInvertCheckedHidden": "Inverser les éléments masqués cochés", + "SectionViewDisableCheckedHidden": "Désactiver les éléments masqués cochés", + "SectionViewDisableCheckedHiddenWarning": "Attention ! \n\nL'exécution de \"Désactiver les sections cachées cochées\" définira la validité des sections cachées cochées sur Désactiver, et mettra à jour les paramètres écrits dans le fichier de configuration caché situé dans le chemin \"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\". \n\nPour revenir en arrière, une édition manuelle du fichier de configuration est nécessaire, en changeant la validité des sections cachées de Faux à Vrai. \n\nVoulez-vous continuer l'exécution ? \n\nRemarque : La fenêtre de requête doit actualiser les processus pour incorporer les nouveaux paramètres de configuration cachés.", "SectionViewDump": "Extraction", "SectionViewImport": "Importer", diff --git a/PS4CheaterNeo/languages/LanguageFile_German.json b/PS4CheaterNeo/languages/LanguageFile_German.json index 0297c58..371ca3c 100644 --- a/PS4CheaterNeo/languages/LanguageFile_German.json +++ b/PS4CheaterNeo/languages/LanguageFile_German.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "Nicht überprüfen, dass es Prot hat:", "SectionViewCheckAllHidden": "Alle versteckten überprüfen", "SectionViewUnCheckAllHidden": "Alle versteckten nicht überprüfen", + "SectionViewInvertCheckedHidden": "Ausgewählte versteckte Elemente umkehren", + "SectionViewDisableCheckedHidden": "Ausgewählte versteckte Elemente deaktivieren", + "SectionViewDisableCheckedHiddenWarning": "Warnung! \n\nDie Ausführung von \"Ausgewählte versteckte deaktivieren\" setzt die Gültigkeit der ausgewählten versteckten Abschnitte auf Deaktiviert und aktualisiert die Einstellungen, die in der versteckten Konfigurationsdatei im Pfad \"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\" geschrieben wurden. \n\nZurückkehren erfordert manuelles Bearbeiten der Konfigurationsdatei, indem die Gültigkeit der versteckten Abschnitte von Falsch auf Wahr geändert wird. \n\nMöchten Sie mit der Ausführung fortsetzen? \n\nHinweis: Das Abfragefenster muss die Prozesse aktualisieren, um die neuen versteckten Konfigurationseinstellungen zu übernehmen.", "SectionViewDump": "Dump", "SectionViewImport": "Importieren", diff --git a/PS4CheaterNeo/languages/LanguageFile_Italian.json b/PS4CheaterNeo/languages/LanguageFile_Italian.json index 2f6cc84..31dc0f4 100644 --- a/PS4CheaterNeo/languages/LanguageFile_Italian.json +++ b/PS4CheaterNeo/languages/LanguageFile_Italian.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "Deseleziona Non Prot:", "SectionViewCheckAllHidden": "Seleziona Nascosto", "SectionViewUnCheckAllHidden": "Deseleziona Non Nascosto", + "SectionViewInvertCheckedHidden": "Inverti elementi nascosti selezionati", + "SectionViewDisableCheckedHidden": "Disattiva elementi nascosti selezionati", + "SectionViewDisableCheckedHiddenWarning": "Avviso! \n\nL'esecuzione di \"Disabilita nascosti selezionati\" imposterà il Valido delle sezioni nascoste selezionate su Disabilita e aggiornerà le impostazioni scritte nel file di configurazione nascosto nel percorso \"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\". \n\nPer ripristinare, è necessaria la modifica manuale del file di configurazione, cambiando il Valido delle sezioni nascoste da Falso a Vero. \n\nVuoi continuare l'esecuzione? \n\nNota: La finestra di Query deve aggiornare i processi per incorporare le nuove impostazioni di configurazione nascoste.", "SectionViewDump": "Dump", "SectionViewImport": "Importa", diff --git a/PS4CheaterNeo/languages/LanguageFile_Japanese.json b/PS4CheaterNeo/languages/LanguageFile_Japanese.json index 78d9782..26a8b2f 100644 --- a/PS4CheaterNeo/languages/LanguageFile_Japanese.json +++ b/PS4CheaterNeo/languages/LanguageFile_Japanese.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "指定したProt以外をチェック:", "SectionViewCheckAllHidden": "すべてHiddenをチェック", "SectionViewUnCheckAllHidden": "Hidden以外をチェック", + "SectionViewInvertCheckedHidden": "チェックされたHiddenを反転", + "SectionViewDisableCheckedHidden": "チェックされたHiddenを無効にする", + "SectionViewDisableCheckedHiddenWarning": "警告!\n\n\"チェックされたHiddenを無効にする\"を実行すると、選択した非表示セクションのValidがDisableに設定され、\"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\"パスに書き込まれた設定が更新されます。\n\n元に戻すには、confファイルを手動で編集し、非表示セクションのValidをFalseからTrueに変更する必要があります。\n\n実行を続行しますか?\n\n注:新しい非表示の設定を取り込むには、クエリウィンドウでプロセスを更新する必要があります。", "SectionViewDump": "Dump", "SectionViewImport": "インポート", diff --git a/PS4CheaterNeo/languages/LanguageFile_Korean.json b/PS4CheaterNeo/languages/LanguageFile_Korean.json index dd74214..6800a14 100644 --- a/PS4CheaterNeo/languages/LanguageFile_Korean.json +++ b/PS4CheaterNeo/languages/LanguageFile_Korean.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "비Prot확인:", "SectionViewCheckAllHidden": "숨겨진 모두 확인", "SectionViewUnCheckAllHidden": "숨겨진 모두 해제", + "SectionViewInvertCheckedHidden": "선택된 숨겨진 항목 반전", + "SectionViewDisableCheckedHidden": "선택된 숨겨진 항목 비활성화", + "SectionViewDisableCheckedHiddenWarning": "경고!\n\n\"선택된 숨겨진 항목 비활성화\"를 실행하면 선택된 숨겨진 섹션의 유효성이 비활성화되고, \"path to PS4CheaterNeo\\sections\\[GAME_ID].conf\" 경로에 쓰여진 설정이 업데이트됩니다.\n\n복원하려면, conf 파일을 수동으로 편집하여 숨겨진 섹션의 유효성을 False에서 True로 변경해야 합니다.\n\n실행을 계속하시겠습니까?\n\n참고: 쿼리 창에서 새로운 숨겨진 설정을 반영하려면 프로세스를 새로 고쳐야 합니다.", "SectionViewDump": "덤프", "SectionViewImport": "가져오기", diff --git a/PS4CheaterNeo/languages/LanguageFile_Russian.json b/PS4CheaterNeo/languages/LanguageFile_Russian.json index f0b6a33..b6e358d 100644 --- a/PS4CheaterNeo/languages/LanguageFile_Russian.json +++ b/PS4CheaterNeo/languages/LanguageFile_Russian.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "Отменить выбор тех, у которых prot:", "SectionViewCheckAllHidden": "Выбрать все скрытые", "SectionViewUnCheckAllHidden": "Отменить выбор всех скрытых", + "SectionViewInvertCheckedHidden": "Инвертировать отмеченные скрытые", + "SectionViewDisableCheckedHidden": "Отключить отмеченные скрытые", + "SectionViewDisableCheckedHiddenWarning": "Предупреждение!\n\nВыполнение \"Отключить отмеченные скрытые\" установит Валидность отмеченных скрытых секций на Отключено и обновит настройки, записанные в файле конфигурации скрытых по пути \"путь к PS4CheaterNeo\\sections\\[GAME_ID].conf\". \n\nЧтобы вернуть, требуется ручное редактирование файла конфигурации, изменение Валидности скрытых секций с Ложь на Истина. \n\nЖелаете продолжить выполнение? \n\nПримечание: Окно запроса должно обновить процессы, чтобы включить новые настройки скрытых секций.", "SectionViewDump": "Выгрузка", "SectionViewImport": "Импорт", diff --git a/PS4CheaterNeo/languages/LanguageFile_Spanish.json b/PS4CheaterNeo/languages/LanguageFile_Spanish.json index 836ff7b..93d3ba6 100644 --- a/PS4CheaterNeo/languages/LanguageFile_Spanish.json +++ b/PS4CheaterNeo/languages/LanguageFile_Spanish.json @@ -83,6 +83,9 @@ "SectionViewUnCheckProt": "Desmarcar los que tienen prot:", "SectionViewCheckAllHidden": "Marcar Todos Ocultos", "SectionViewUnCheckAllHidden": "Desmarcar Todos Ocultos", + "SectionViewInvertCheckedHidden": "Oculto marcado invertido", + "SectionViewDisableCheckedHidden": "Oculto marcado deshabilitado", + "SectionViewDisableCheckedHiddenWarning": "¡Advertencia! \n\nLa ejecución de \"Desactivar ocultos marcados\" establecerá el Valido de las secciones ocultas marcadas en Desactivado, y actualizará la configuración escrita en el archivo de configuración oculto en la ruta \"ruta a PS4CheaterNeo\\sections\\[GAME_ID].conf\". \n\nPara revertir, se requiere la edición manual del archivo de configuración, cambiando el Valido de las secciones ocultas de Falso a Verdadero. \n\n¿Desea continuar con la ejecución? \n\nNota: La ventana de consulta necesita actualizar los procesos para incorporar la nueva configuración de ocultos.", "SectionViewDump": "Volcar", "SectionViewImport": "Importar", diff --git a/README.md b/README.md index 46be7c4..24c08e7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ PS4CheaterNeo is a program to find game cheat codes, and it is based on [`ps4debug`](https://github.com/jogolden/ps4debug) and [`.Net Framework 4.8`](https://support.microsoft.com/en-us/topic/microsoft-net-framework-4-8-offline-installer-for-windows-9d23f658-3b97-68ab-d013-aa3c3e7495e0). -Currently in `version 1.0.2.5` +Currently in `version 1.0.2.6` ## Table of Contents @@ -183,10 +183,17 @@ Note: Enabling this option will significantly increase the number of results and ![query_section_count_1](assets/query_section_count_1.webp) ![query_section_count_2](assets/query_section_count_2.webp) -- Added support for "Check All", "Uncheck All", and "Invert Checked" in the right-click context menu of the SectionView in the Query window. (0.9.9.1) +- Added support for "Check all", "Uncheck all", and "Invert checked" in the right-click context menu of the SectionView in the Query window. (0.9.9.1) - Added support for "Check that contains", "Uncheck that contains", "Check that has prot" and "Uncheck that has prot" in the right-click menu of the SectionView in the Query window. (0.9.9.3) - Added support for inputting multiple prot values in the 'Check/Uncheck that has prot' function in SectionView. The program will now automatically detect delimiter symbols, including ',', '-', ';', '|', and spaces. (0.9.9.5) - Added support for "Check that contains Hidden", "Uncheck that contains Hidden" in the right-click menu of the SectionView in the Query window. (0.9.9.8) +- Move the "Check all," "Uncheck all," "Invert checked," "Check that contains..." menus into the submenu of the Items menu. (1.0.2.6) +- Move the "Check all Hidden," "Un-Check all Hidden..." menus into the submenu of the Hidden Items menu. (1.0.2.6) +- Added support for "Invert checked Hidden" and "Disable checked Hidden" in the right-click context menu of the SectionView in the Query window. (1.0.2.6) +- Disable checked Hidden +Executing "Disable checked Hidden" will set the Valid of the checked Hidden sections to Disable, and update the settings written to the Hidden configuration file at the "path to PS4CheaterNeo\\sections\\[GAME_ID].conf" path. +To revert, manual editing of the conf file is required, changing the Valid of the Hidden sections from False to True. +Note: The Query window needs to Refresh Processes to incorporate the new Hidden conf settings. ![query_SectionViewMenu](assets/query_SectionViewMenu.webp) diff --git a/assets/query_SectionViewMenu.webp b/assets/query_SectionViewMenu.webp index 7ad9967f00bf63dc0bc430420e6e1d57097cb3df..c7cca040a4683cf216311a8fec6e68d2f7fda3f7 100644 GIT binary patch literal 18508 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 R#L4jw{g;iAf#E;i{{{KX_j>>U