From 45556b82bd9fdf46ac585c2b84cc155fc99c3ef4 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Thu, 4 May 2023 21:59:41 -0400 Subject: [PATCH 1/7] Language editor refactor --- BaseHandlers/Properties/AssemblyInfo.cs | 3 +- BundleFormat/Properties/AssemblyInfo.cs | 3 +- BundleManager/MainForm.cs | 5 +- BundleManager/Properties/AssemblyInfo.cs | 3 +- BundleUtilities/Properties/AssemblyInfo.cs | 3 +- BurnoutImage/Properties/AssemblyInfo.cs | 3 +- ComponentTester/Properties/AssemblyInfo.cs | 3 +- HexEditor/Properties/AssemblyInfo.cs | 3 +- IconLibrary/Properties/AssemblyInfo.cs | 3 +- LangEditor/LangEdit.Designer.cs | 208 +++++++++--------- LangEditor/LangEdit.cs | 50 ++--- LangEditor/LangEdit.resx | 62 +----- LangEditor/Language.cs | 125 +++++------ LangEditor/Properties/AssemblyInfo.cs | 3 +- LuaList/Properties/AssemblyInfo.cs | 1 - MathLib/Properties/AssemblyInfo.cs | 3 +- ModelViewer/Properties/AssemblyInfo.cs | 3 +- PVSFormat/Properties/AssemblyInfo.cs | 3 +- PluginAPI/Properties/AssemblyInfo.cs | 3 +- PluginSystem/Properties/AssemblyInfo.cs | 3 +- VaultFormat/Properties/AssemblyInfo.cs | 3 +- VehicleList/Properties/AssemblyInfo.cs | 3 +- .../Properties/AssemblyInfo.cs | 3 +- 23 files changed, 200 insertions(+), 302 deletions(-) diff --git a/BaseHandlers/Properties/AssemblyInfo.cs b/BaseHandlers/Properties/AssemblyInfo.cs index e9da841..2e53270 100644 --- a/BaseHandlers/Properties/AssemblyInfo.cs +++ b/BaseHandlers/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/BundleFormat/Properties/AssemblyInfo.cs b/BundleFormat/Properties/AssemblyInfo.cs index 5809801..b2b9587 100644 --- a/BundleFormat/Properties/AssemblyInfo.cs +++ b/BundleFormat/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/BundleManager/MainForm.cs b/BundleManager/MainForm.cs index b7f6b02..08169c7 100644 --- a/BundleManager/MainForm.cs +++ b/BundleManager/MainForm.cs @@ -158,9 +158,8 @@ private void UpdateDisplay() lstEntries.BeginUpdate(); lstEntries.ListViewItemSorter = null; // Disable sorting while adding - for (int i = 0; i < CurrentArchive.Entries.Count; i++) + foreach (BundleEntry entry in CurrentArchive.Entries) { - BundleEntry entry = CurrentArchive.Entries[i]; if (entry.EntryBlocks[0].Data == null) // Exception occurred { lstEntries.Items.Clear(); @@ -173,7 +172,7 @@ private void UpdateDisplay() } string[] values = new string[] { - i.ToString("d3"), + entry.Index.ToString("d3"), entry.DetectName(), "0x" + entry.ID.ToString("X8"), entry.Type.ToString(), diff --git a/BundleManager/Properties/AssemblyInfo.cs b/BundleManager/Properties/AssemblyInfo.cs index 7ebea07..7b516ea 100644 --- a/BundleManager/Properties/AssemblyInfo.cs +++ b/BundleManager/Properties/AssemblyInfo.cs @@ -1,6 +1,5 @@ -using System.Resources; +using System.Resources; using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/BundleUtilities/Properties/AssemblyInfo.cs b/BundleUtilities/Properties/AssemblyInfo.cs index 3947f77..bb0df43 100644 --- a/BundleUtilities/Properties/AssemblyInfo.cs +++ b/BundleUtilities/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/BurnoutImage/Properties/AssemblyInfo.cs b/BurnoutImage/Properties/AssemblyInfo.cs index 3f367e1..0f751b9 100644 --- a/BurnoutImage/Properties/AssemblyInfo.cs +++ b/BurnoutImage/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/ComponentTester/Properties/AssemblyInfo.cs b/ComponentTester/Properties/AssemblyInfo.cs index 12b1c51..0815971 100644 --- a/ComponentTester/Properties/AssemblyInfo.cs +++ b/ComponentTester/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/HexEditor/Properties/AssemblyInfo.cs b/HexEditor/Properties/AssemblyInfo.cs index 47290f0..f862119 100644 --- a/HexEditor/Properties/AssemblyInfo.cs +++ b/HexEditor/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/IconLibrary/Properties/AssemblyInfo.cs b/IconLibrary/Properties/AssemblyInfo.cs index 50ed3f1..274d978 100644 --- a/IconLibrary/Properties/AssemblyInfo.cs +++ b/IconLibrary/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/LangEditor/LangEdit.Designer.cs b/LangEditor/LangEdit.Designer.cs index 666886e..ad655c7 100644 --- a/LangEditor/LangEdit.Designer.cs +++ b/LangEditor/LangEdit.Designer.cs @@ -1,4 +1,4 @@ -namespace LangEditor +namespace LangEditor { partial class LangEdit { @@ -28,153 +28,145 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.dgvMain = new System.Windows.Forms.DataGridView(); - this.colHashID = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.colText = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.hashToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); - this.applyChangesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit(); - this.menuStrip1.SuspendLayout(); - this.SuspendLayout(); + dgvMain = new System.Windows.Forms.DataGridView(); + colHashID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + colText = new System.Windows.Forms.DataGridViewTextBoxColumn(); + statusStrip1 = new System.Windows.Forms.StatusStrip(); + menuStrip1 = new System.Windows.Forms.MenuStrip(); + fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + applyChangesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + hashToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)dgvMain).BeginInit(); + menuStrip1.SuspendLayout(); + SuspendLayout(); // // dgvMain // - this.dgvMain.AllowUserToOrderColumns = true; - this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dgvMain.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.colHashID, - this.colText}); - this.dgvMain.Dock = System.Windows.Forms.DockStyle.Fill; - this.dgvMain.Location = new System.Drawing.Point(0, 24); - this.dgvMain.Name = "dgvMain"; - this.dgvMain.Size = new System.Drawing.Size(415, 325); - this.dgvMain.TabIndex = 0; - this.dgvMain.RowsAdded += new System.Windows.Forms.DataGridViewRowsAddedEventHandler(this.dgvMain_RowsAdded); + dgvMain.AllowUserToOrderColumns = true; + dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dgvMain.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { colHashID, colText }); + dgvMain.Dock = System.Windows.Forms.DockStyle.Fill; + dgvMain.Location = new System.Drawing.Point(0, 24); + dgvMain.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + dgvMain.Name = "dgvMain"; + dgvMain.Size = new System.Drawing.Size(484, 382); + dgvMain.TabIndex = 0; + dgvMain.RowsAdded += dgvMain_RowsAdded; // // colHashID // - this.colHashID.HeaderText = "Hash ID"; - this.colHashID.Name = "colHashID"; + colHashID.HeaderText = "Hash ID"; + colHashID.Name = "colHashID"; // // colText // - this.colText.HeaderText = "Text"; - this.colText.Name = "colText"; + colText.HeaderText = "Text"; + colText.Name = "colText"; // // statusStrip1 // - this.statusStrip1.Location = new System.Drawing.Point(0, 349); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(415, 22); - this.statusStrip1.TabIndex = 1; - this.statusStrip1.Text = "statusStrip1"; + statusStrip1.Location = new System.Drawing.Point(0, 406); + statusStrip1.Name = "statusStrip1"; + statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0); + statusStrip1.Size = new System.Drawing.Size(484, 22); + statusStrip1.TabIndex = 1; + statusStrip1.Text = "statusStrip1"; // // menuStrip1 // - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.editToolStripMenuItem, - this.toolsToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(415, 24); - this.menuStrip1.TabIndex = 2; - this.menuStrip1.Text = "menuStrip1"; + menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { fileToolStripMenuItem, editToolStripMenuItem, toolsToolStripMenuItem }); + menuStrip1.Location = new System.Drawing.Point(0, 0); + menuStrip1.Name = "menuStrip1"; + menuStrip1.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2); + menuStrip1.Size = new System.Drawing.Size(484, 24); + menuStrip1.TabIndex = 2; + menuStrip1.Text = "menuStrip1"; // // fileToolStripMenuItem // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.importToolStripMenuItem, - this.exportToolStripMenuItem, - this.toolStripMenuItem1, - this.applyChangesToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); - this.fileToolStripMenuItem.Text = "File"; + fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { importToolStripMenuItem, exportToolStripMenuItem, toolStripMenuItem1, applyChangesToolStripMenuItem }); + fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + fileToolStripMenuItem.Text = "File"; // // importToolStripMenuItem // - this.importToolStripMenuItem.Name = "importToolStripMenuItem"; - this.importToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.importToolStripMenuItem.Text = "Import"; - this.importToolStripMenuItem.Click += new System.EventHandler(this.importToolStripMenuItem_Click); + importToolStripMenuItem.Name = "importToolStripMenuItem"; + importToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + importToolStripMenuItem.Text = "Import"; + importToolStripMenuItem.Click += importToolStripMenuItem_Click; // // exportToolStripMenuItem // - this.exportToolStripMenuItem.Name = "exportToolStripMenuItem"; - this.exportToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.exportToolStripMenuItem.Text = "Export"; - this.exportToolStripMenuItem.Click += new System.EventHandler(this.exportToolStripMenuItem_Click); + exportToolStripMenuItem.Name = "exportToolStripMenuItem"; + exportToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + exportToolStripMenuItem.Text = "Export"; + exportToolStripMenuItem.Click += exportToolStripMenuItem_Click; // - // toolsToolStripMenuItem + // toolStripMenuItem1 // - this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.hashToolStripMenuItem}); - this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20); - this.toolsToolStripMenuItem.Text = "Tools"; + toolStripMenuItem1.Name = "toolStripMenuItem1"; + toolStripMenuItem1.Size = new System.Drawing.Size(177, 6); // - // hashToolStripMenuItem + // applyChangesToolStripMenuItem // - this.hashToolStripMenuItem.Name = "hashToolStripMenuItem"; - this.hashToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.hashToolStripMenuItem.Text = "Hash"; - this.hashToolStripMenuItem.Click += new System.EventHandler(this.hashToolStripMenuItem_Click); + applyChangesToolStripMenuItem.Name = "applyChangesToolStripMenuItem"; + applyChangesToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + applyChangesToolStripMenuItem.Text = "Apply Changes"; + applyChangesToolStripMenuItem.Click += applyChangesToolStripMenuItem_Click; // // editToolStripMenuItem // - this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.findToolStripMenuItem}); - this.editToolStripMenuItem.Name = "editToolStripMenuItem"; - this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); - this.editToolStripMenuItem.Text = "Edit"; + editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { findToolStripMenuItem }); + editToolStripMenuItem.Name = "editToolStripMenuItem"; + editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); + editToolStripMenuItem.Text = "Edit"; // // findToolStripMenuItem // - this.findToolStripMenuItem.Name = "findToolStripMenuItem"; - this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); - this.findToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.findToolStripMenuItem.Text = "Find"; - this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); + findToolStripMenuItem.Name = "findToolStripMenuItem"; + findToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F; + findToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + findToolStripMenuItem.Text = "Find"; + findToolStripMenuItem.Click += findToolStripMenuItem_Click; // - // toolStripMenuItem1 + // toolsToolStripMenuItem // - this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(151, 6); + toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { hashToolStripMenuItem }); + toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + toolsToolStripMenuItem.Text = "Tools"; // - // applyChangesToolStripMenuItem + // hashToolStripMenuItem // - this.applyChangesToolStripMenuItem.Name = "applyChangesToolStripMenuItem"; - this.applyChangesToolStripMenuItem.Size = new System.Drawing.Size(154, 22); - this.applyChangesToolStripMenuItem.Text = "Apply Changes"; - this.applyChangesToolStripMenuItem.Click += new System.EventHandler(this.applyChangesToolStripMenuItem_Click); + hashToolStripMenuItem.Name = "hashToolStripMenuItem"; + hashToolStripMenuItem.Size = new System.Drawing.Size(101, 22); + hashToolStripMenuItem.Text = "Hash"; + hashToolStripMenuItem.Click += hashToolStripMenuItem_Click; // // LangEdit // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(415, 371); - this.Controls.Add(this.dgvMain); - this.Controls.Add(this.statusStrip1); - this.Controls.Add(this.menuStrip1); - this.MainMenuStrip = this.menuStrip1; - this.Name = "LangEdit"; - this.Text = "Language Editor"; - ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit(); - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(484, 428); + Controls.Add(dgvMain); + Controls.Add(statusStrip1); + Controls.Add(menuStrip1); + MainMenuStrip = menuStrip1; + Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + Name = "LangEdit"; + Text = "Language Editor"; + ((System.ComponentModel.ISupportInitialize)dgvMain).EndInit(); + menuStrip1.ResumeLayout(false); + menuStrip1.PerformLayout(); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -194,4 +186,4 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem applyChangesToolStripMenuItem; } -} \ No newline at end of file +} diff --git a/LangEditor/LangEdit.cs b/LangEditor/LangEdit.cs index 3159e75..ee0e581 100644 --- a/LangEditor/LangEdit.cs +++ b/LangEditor/LangEdit.cs @@ -25,7 +25,7 @@ public Language Lang _ignoreChanges = false; } } - + public LangEdit() { _ignoreChanges = true; @@ -35,11 +35,8 @@ public LangEdit() public void UpdateDisplay() { - foreach (uint key in _lang.Data.Keys) - { - string txt = _lang.Data[key]; - dgvMain.Rows.Add(key.ToString("X8"), txt); - } + foreach (uint key in _lang.mpEntries.Keys) + dgvMain.Rows.Add(key.ToString("X8"), _lang.mpEntries[key]); } public void RebuildLanguage() @@ -49,21 +46,18 @@ public void RebuildLanguage() Dictionary data = new Dictionary(); - int index = 0; - foreach (DataGridViewRow row in dgvMain.Rows) + for (int i = 0; i < dgvMain.Rows.Count - 1; ++i) { - if (index >= dgvMain.Rows.Count - 1) - break; - string idString = (string) row.Cells[0].Value; + string idString = (string)dgvMain.Rows[i].Cells[0].Value; if (!uint.TryParse(idString, NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out var id)) { - MessageBox.Show(this, "Failed to parse ID for row " + index, "Warning", MessageBoxButtons.OK, + MessageBox.Show(this, "Failed to parse ID \"" + idString + "\"", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } - string value = (string) row.Cells[1].Value; + string value = (string)dgvMain.Rows[i].Cells[1].Value; if (data.ContainsKey(id)) { MessageBox.Show(this, "ID Already In Use " + idString, "Warning", MessageBoxButtons.OK, @@ -71,10 +65,10 @@ public void RebuildLanguage() return; } data.Add(id, value); - - index++; } - _lang.Data = data; + + _lang.mpEntries = data; + Changed?.Invoke(); } @@ -88,14 +82,11 @@ private void exportToolStripMenuItem_Click(object sender, EventArgs e) // TODO: Export CSV } - private void hashToolStripMenuItem_Click(object sender, EventArgs e) + private void applyChangesToolStripMenuItem_Click(object sender, EventArgs e) { - string value = InputDialog.ShowInput(this, "Please enter the value to hash."); - if (value == null) - return; - uint result = Language.HashID(value); + RebuildLanguage(); - MessageBox.Show(this, "Hashed value is: " + result.ToString("X8"), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show(this, "Done!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void findToolStripMenuItem_Click(object sender, EventArgs e) @@ -105,13 +96,13 @@ private void findToolStripMenuItem_Click(object sender, EventArgs e) return; uint result = Language.HashID(value); - dgvMain.ClearSelection(); + string hash; foreach (DataGridViewRow row in dgvMain.Rows) { - string hash = (string)row.Cells[0].Value; + hash = (string)row.Cells[0].Value; if (result.ToString("X8") == hash) { - //MessageBox.Show(this, "FOUND!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + dgvMain.ClearSelection(); dgvMain.CurrentCell = row.Cells[0]; row.Selected = true; return; @@ -121,11 +112,14 @@ private void findToolStripMenuItem_Click(object sender, EventArgs e) MessageBox.Show(this, "Hash not found!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } - private void applyChangesToolStripMenuItem_Click(object sender, EventArgs e) + private void hashToolStripMenuItem_Click(object sender, EventArgs e) { - RebuildLanguage(); + string value = InputDialog.ShowInput(this, "Please enter the value to hash."); + if (value == null) + return; + uint result = Language.HashID(value); - MessageBox.Show(this, "Done!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show(this, "Hashed value is: " + result.ToString("X8"), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void dgvMain_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) diff --git a/LangEditor/LangEdit.resx b/LangEditor/LangEdit.resx index 0452d71..7750ed5 100644 --- a/LangEditor/LangEdit.resx +++ b/LangEditor/LangEdit.resx @@ -1,64 +1,4 @@ - - - + diff --git a/LangEditor/Language.cs b/LangEditor/Language.cs index bd0e546..fe92b22 100644 --- a/LangEditor/Language.cs +++ b/LangEditor/Language.cs @@ -10,46 +10,61 @@ namespace LangEditor { public class Language : IEntryData { - public int Unknown1; - public Dictionary Data; - public int Unknown2; - - public Language() + private enum LanguageId : uint { - Data = new Dictionary(); + E_LANGUAGE_ARABIC, + E_LANGUAGE_CHINESE, + E_LANGUAGE_CHINESE_SIMPLIFIED, + E_LANGUAGE_CHINESE_TRADITIONAL, + E_LANGUAGE_CZECH, + E_LANGUAGE_DANISH, + E_LANGUAGE_DUTCH, + E_LANGUAGE_ENGLISH_US, + E_LANGUAGE_ENGLISH_UK, + E_LANGUAGE_FINNISH, + E_LANGUAGE_FRENCH, + E_LANGUAGE_GERMAN, + E_LANGUAGE_GREEK, + E_LANGUAGE_HEBREW, + E_LANGUAGE_HUNGARIAN, + E_LANGUAGE_ITALIAN, + E_LANGUAGE_JAPANESE, + E_LANGUAGE_KOREAN, + E_LANGUAGE_NORWEGIAN, + E_LANGUAGE_POLISH, + E_LANGUAGE_PORTUGUESE_BRAZIL, + E_LANGUAGE_PORTUGUESE_PORTUGAL, + E_LANGUAGE_SPANISH, + E_LANGUAGE_SWEDISH, + E_LANGUAGE_THAI } + + private LanguageId meLanguageID; + private uint muSize; // Number of entries + internal Dictionary mpEntries; - private void Clear() + public Language() { - Unknown1 = default; - Unknown2 = default; - - Data.Clear(); + mpEntries = new Dictionary(); } public bool Read(BundleEntry entry, ILoader loader = null) { - Clear(); + mpEntries.Clear(); // Clear any entries from a previous Bundle MemoryStream ms = entry.MakeStream(); BinaryReader2 br = new BinaryReader2(ms); br.BigEndian = entry.Console; - Unknown1 = br.ReadInt32(); - int count = br.ReadInt32(); - Unknown2 = br.ReadInt32(); + meLanguageID = (LanguageId)br.ReadUInt32(); + muSize = br.ReadUInt32(); + ms.Position = br.ReadUInt32(); - for (int i = 0; i < count - 1; i++) - { - uint id = br.ReadUInt32(); - string txt = br.ReadCStringPtr(); - Data.Add(id, txt); - } + for (int i = 0; i < muSize; ++i) + mpEntries.Add(br.ReadUInt32(), br.ReadCStringPtr()); + mpEntries.Remove(0); // If padding is present, remove it br.Close(); - ms.Close(); - - //result.Write(entry); return true; } @@ -59,57 +74,33 @@ public bool Write(BundleEntry entry) MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); - bw.Write(Unknown1); - bw.Write(Data.Count + 1); - bw.Write(Unknown2); + bw.Write((uint)meLanguageID); + bw.Write(mpEntries.Count); + bw.Write(0xC); // Pointer is always the same for 32-bit systems - long headPos = bw.BaseStream.Position; - - foreach (uint id in Data.Keys) - { - bw.Write(id); - bw.Write((uint) 0); // offset - } - - bw.Write((uint)0); - bw.Write((uint)0); // offset + // Write at entries position so string position calculations are not needed later + // and to avoid double iteration + ms.Position = mpEntries.Count * 8 + 0xC - 1; + bw.Write((byte)0); + ms.Position = 0xC; - int index = 0; - foreach (uint id in Data.Keys) + long lastPos; + foreach (KeyValuePair langEntry in mpEntries) { - long pos = bw.BaseStream.Position; - - // go back and write offset - bw.BaseStream.Position = headPos + (index * 8) + 4; - bw.Write((uint)pos); - - bw.BaseStream.Position = pos; - if (Data[id] == null) - bw.WriteCStr(""); - else - bw.WriteCStr(Data[id]); - index++; + bw.Write(langEntry.Key); // Hash + padding + bw.Write((uint)ms.Length); // String pointer + lastPos = ms.Position; + ms.Position = ms.Length; + bw.Write(langEntry.Value.ToCharArray()); // String data + bw.Write((byte)0); // Null terminator + ms.Position = lastPos; } - long pos2 = bw.BaseStream.Position; - - // go back and write offset - bw.BaseStream.Position = headPos + (index * 8) + 4; - bw.Write((uint)pos2); - - bw.BaseStream.Position = pos2; - - int paddingCount = (int)(entry.EntryBlocks[0].Data.Length - bw.BaseStream.Position); - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < paddingCount; i++) - sb.Append("A"); - bw.WriteCStr(sb.ToString()); - bw.Flush(); + ms.Position = ms.Length; + bw.Align(0x10); byte[] data = ms.ToArray(); bw.Close(); - ms.Close(); entry.EntryBlocks[0].Data = data; entry.Dirty = true; diff --git a/LangEditor/Properties/AssemblyInfo.cs b/LangEditor/Properties/AssemblyInfo.cs index 133d996..382bac4 100644 --- a/LangEditor/Properties/AssemblyInfo.cs +++ b/LangEditor/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/LuaList/Properties/AssemblyInfo.cs b/LuaList/Properties/AssemblyInfo.cs index 3bcbfaf..dd5e2f5 100644 --- a/LuaList/Properties/AssemblyInfo.cs +++ b/LuaList/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // Allgemeine Informationen über eine Assembly werden über die folgenden diff --git a/MathLib/Properties/AssemblyInfo.cs b/MathLib/Properties/AssemblyInfo.cs index f439018..b1d5e8c 100644 --- a/MathLib/Properties/AssemblyInfo.cs +++ b/MathLib/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/ModelViewer/Properties/AssemblyInfo.cs b/ModelViewer/Properties/AssemblyInfo.cs index cb29d2b..10214ea 100644 --- a/ModelViewer/Properties/AssemblyInfo.cs +++ b/ModelViewer/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/PVSFormat/Properties/AssemblyInfo.cs b/PVSFormat/Properties/AssemblyInfo.cs index 29172b1..35b219c 100644 --- a/PVSFormat/Properties/AssemblyInfo.cs +++ b/PVSFormat/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/PluginAPI/Properties/AssemblyInfo.cs b/PluginAPI/Properties/AssemblyInfo.cs index 9cd8344..00b41c4 100644 --- a/PluginAPI/Properties/AssemblyInfo.cs +++ b/PluginAPI/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/PluginSystem/Properties/AssemblyInfo.cs b/PluginSystem/Properties/AssemblyInfo.cs index 3834efc..81cce25 100644 --- a/PluginSystem/Properties/AssemblyInfo.cs +++ b/PluginSystem/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/VaultFormat/Properties/AssemblyInfo.cs b/VaultFormat/Properties/AssemblyInfo.cs index e11a698..e798581 100644 --- a/VaultFormat/Properties/AssemblyInfo.cs +++ b/VaultFormat/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/VehicleList/Properties/AssemblyInfo.cs b/VehicleList/Properties/AssemblyInfo.cs index 9bcf7bf..0f47f72 100644 --- a/VehicleList/Properties/AssemblyInfo.cs +++ b/VehicleList/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/WorldCollisionHandler/Properties/AssemblyInfo.cs b/WorldCollisionHandler/Properties/AssemblyInfo.cs index 0896ca3..4f1d767 100644 --- a/WorldCollisionHandler/Properties/AssemblyInfo.cs +++ b/WorldCollisionHandler/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following From 133e0f96db17533731f69fb7b3324d8e23aabe95 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Fri, 5 May 2023 00:18:02 -0400 Subject: [PATCH 2/7] Add CSV exporter --- LangEditor/LangEdit.Designer.cs | 6 ++-- LangEditor/LangEdit.cs | 49 +++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/LangEditor/LangEdit.Designer.cs b/LangEditor/LangEdit.Designer.cs index ad655c7..a998ade 100644 --- a/LangEditor/LangEdit.Designer.cs +++ b/LangEditor/LangEdit.Designer.cs @@ -99,14 +99,14 @@ private void InitializeComponent() // importToolStripMenuItem.Name = "importToolStripMenuItem"; importToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - importToolStripMenuItem.Text = "Import"; + importToolStripMenuItem.Text = "Import from CSV"; importToolStripMenuItem.Click += importToolStripMenuItem_Click; // // exportToolStripMenuItem // exportToolStripMenuItem.Name = "exportToolStripMenuItem"; exportToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - exportToolStripMenuItem.Text = "Export"; + exportToolStripMenuItem.Text = "Export to CSV"; exportToolStripMenuItem.Click += exportToolStripMenuItem_Click; // // toolStripMenuItem1 @@ -132,7 +132,7 @@ private void InitializeComponent() // findToolStripMenuItem.Name = "findToolStripMenuItem"; findToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F; - findToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + findToolStripMenuItem.Size = new System.Drawing.Size(137, 22); findToolStripMenuItem.Text = "Find"; findToolStripMenuItem.Click += findToolStripMenuItem_Click; // diff --git a/LangEditor/LangEdit.cs b/LangEditor/LangEdit.cs index ee0e581..cfe4e4a 100644 --- a/LangEditor/LangEdit.cs +++ b/LangEditor/LangEdit.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; +using System.Text; using System.Windows.Forms; namespace LangEditor @@ -52,16 +54,16 @@ public void RebuildLanguage() if (!uint.TryParse(idString, NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out var id)) { - MessageBox.Show(this, "Failed to parse ID \"" + idString + "\"", "Warning", MessageBoxButtons.OK, - MessageBoxIcon.Warning); + MessageBox.Show(this, "Failed to parse ID \"" + idString + "\"", "Warning", + MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string value = (string)dgvMain.Rows[i].Cells[1].Value; if (data.ContainsKey(id)) { - MessageBox.Show(this, "ID Already In Use " + idString, "Warning", MessageBoxButtons.OK, - MessageBoxIcon.Warning); + MessageBox.Show(this, "ID Already In Use " + idString, "Warning", + MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } data.Add(id, value); @@ -79,7 +81,41 @@ private void importToolStripMenuItem_Click(object sender, EventArgs e) private void exportToolStripMenuItem_Click(object sender, EventArgs e) { - // TODO: Export CSV + // TODO: Note when language is dirty, not just bundle + if (MessageBox.Show(this, "Changes must be applied before exporting. Save now?", "Information", + MessageBoxButtons.OKCancel) == DialogResult.Cancel) + return; + + SaveFileDialog saveDialog = new SaveFileDialog(); + saveDialog.Filter = "Column-separated values (*.csv)|*.csv"; + if (saveDialog.ShowDialog() == DialogResult.Cancel) + return; + + RebuildLanguage(); + + // CSV content as a single contiguous string. + // Keys are prepended with 0x and padded to 8 characters. + // In values, incompatible characters are escaped. + // Both keys and values are enclosed in double quotes. + string languageContent = ""; + foreach (KeyValuePair entry in _lang.mpEntries) + { + languageContent += "\"0x" + entry.Key.ToString("X8") + "\","; // Key + string tempValue = entry.Value; + tempValue = tempValue.Replace("\xD", "\\r").Replace("\xA", "\\n"); // Newlines + tempValue = tempValue.Replace("\"", "\"\""); // Quotation marks + if (tempValue != "") // Enclose non-empty strings in double quotes + { + tempValue = "\"" + tempValue; + tempValue += "\""; + } + languageContent += tempValue + "\r\n"; + } + + FileStream file = (FileStream)saveDialog.OpenFile(); + file.Write(Encoding.ASCII.GetBytes(languageContent)); + file.Flush(); + file.Close(); } private void applyChangesToolStripMenuItem_Click(object sender, EventArgs e) @@ -119,7 +155,8 @@ private void hashToolStripMenuItem_Click(object sender, EventArgs e) return; uint result = Language.HashID(value); - MessageBox.Show(this, "Hashed value is: " + result.ToString("X8"), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show(this, "Hashed value is: " + result.ToString("X8"), "Information", + MessageBoxButtons.OK, MessageBoxIcon.Information); } private void dgvMain_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) From c4427a78a396cbddba752fb5890f683dbe23b427 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Fri, 5 May 2023 01:42:53 -0400 Subject: [PATCH 3/7] Add CSV importer --- LangEditor/LangEdit.cs | 48 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/LangEditor/LangEdit.cs b/LangEditor/LangEdit.cs index cfe4e4a..ae01851 100644 --- a/LangEditor/LangEdit.cs +++ b/LangEditor/LangEdit.cs @@ -76,7 +76,43 @@ public void RebuildLanguage() private void importToolStripMenuItem_Click(object sender, EventArgs e) { - // TODO: Import CSV + OpenFileDialog openDialog = new OpenFileDialog(); + openDialog.Filter = "Column-separated values (*.csv)|*.csv|All files(*.*)|*.*"; + if (openDialog.ShowDialog() == DialogResult.Cancel) + return; + + Dictionary data = new Dictionary(); + StreamReader file = new StreamReader(openDialog.FileName); + string line; + while ((line = file.ReadLine()) != null) + { + string[] pair = line.Split(',', 2); + pair[0] = pair[0].Substring(3, 8); // Key + if (pair[1].Length != 0) // Non-empty value + { + pair[1] = pair[1].Substring(1, pair[1].Length - 2); // Remove enclosing double quotes + pair[1] = pair[1].Replace("\"\"", "\""); // Convert double quotes + pair[1] = pair[1].Replace("\\r", "\xD").Replace("\\n", "\xA"); // Convert newlines + } + uint key; + try + { + key = uint.Parse(pair[0], NumberStyles.HexNumber); + } + catch (Exception ex) + { + MessageBox.Show("Could not parse ID " + pair[0] + ". Import cancelled.", ex.Source, MessageBoxButtons.OK); + return; + } + data.Add(key, pair[1]); + } + + _lang.mpEntries = data; + + dgvMain.Rows.Clear(); + UpdateDisplay(); + + MessageBox.Show("Import successful.", "Information", MessageBoxButtons.OK); } private void exportToolStripMenuItem_Click(object sender, EventArgs e) @@ -102,9 +138,9 @@ private void exportToolStripMenuItem_Click(object sender, EventArgs e) { languageContent += "\"0x" + entry.Key.ToString("X8") + "\","; // Key string tempValue = entry.Value; - tempValue = tempValue.Replace("\xD", "\\r").Replace("\xA", "\\n"); // Newlines - tempValue = tempValue.Replace("\"", "\"\""); // Quotation marks - if (tempValue != "") // Enclose non-empty strings in double quotes + tempValue = tempValue.Replace("\xD", "\\r").Replace("\xA", "\\n"); // Convert newlines + tempValue = tempValue.Replace("\"", "\"\""); // Convert double quotes + if (tempValue.Length != 0) // Enclose non-empty strings in double quotes { tempValue = "\"" + tempValue; tempValue += "\""; @@ -113,9 +149,11 @@ private void exportToolStripMenuItem_Click(object sender, EventArgs e) } FileStream file = (FileStream)saveDialog.OpenFile(); - file.Write(Encoding.ASCII.GetBytes(languageContent)); + file.Write(Encoding.UTF8.GetBytes(languageContent)); file.Flush(); file.Close(); + + MessageBox.Show("Export successful.", "Information", MessageBoxButtons.OK); } private void applyChangesToolStripMenuItem_Click(object sender, EventArgs e) From 8a4701fbc58d71f904efc387a43e602cd1064643 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Fri, 5 May 2023 11:18:49 -0400 Subject: [PATCH 4/7] Partial key implementation --- LangEditor/LangEdit.Designer.cs | 38 +-- LangEditor/LangEdit.cs | 71 ++++- LangEditor/LangEdit.resx | 4 +- LangEditor/LangEditor.csproj | 8 + LangEditor/keys/keys.csv | 3 + LangEditor/keys/vehicles.csv | 526 ++++++++++++++++++++++++++++++++ 6 files changed, 615 insertions(+), 35 deletions(-) create mode 100644 LangEditor/keys/keys.csv create mode 100644 LangEditor/keys/vehicles.csv diff --git a/LangEditor/LangEdit.Designer.cs b/LangEditor/LangEdit.Designer.cs index a998ade..5db5f66 100644 --- a/LangEditor/LangEdit.Designer.cs +++ b/LangEditor/LangEdit.Designer.cs @@ -29,8 +29,6 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { dgvMain = new System.Windows.Forms.DataGridView(); - colHashID = new System.Windows.Forms.DataGridViewTextBoxColumn(); - colText = new System.Windows.Forms.DataGridViewTextBoxColumn(); statusStrip1 = new System.Windows.Forms.StatusStrip(); menuStrip1 = new System.Windows.Forms.MenuStrip(); fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -42,6 +40,8 @@ private void InitializeComponent() findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); hashToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + colID = new System.Windows.Forms.DataGridViewTextBoxColumn(); + colString = new System.Windows.Forms.DataGridViewTextBoxColumn(); ((System.ComponentModel.ISupportInitialize)dgvMain).BeginInit(); menuStrip1.SuspendLayout(); SuspendLayout(); @@ -50,7 +50,7 @@ private void InitializeComponent() // dgvMain.AllowUserToOrderColumns = true; dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - dgvMain.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { colHashID, colText }); + dgvMain.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { colID, colString }); dgvMain.Dock = System.Windows.Forms.DockStyle.Fill; dgvMain.Location = new System.Drawing.Point(0, 24); dgvMain.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); @@ -59,16 +59,6 @@ private void InitializeComponent() dgvMain.TabIndex = 0; dgvMain.RowsAdded += dgvMain_RowsAdded; // - // colHashID - // - colHashID.HeaderText = "Hash ID"; - colHashID.Name = "colHashID"; - // - // colText - // - colText.HeaderText = "Text"; - colText.Name = "colText"; - // // statusStrip1 // statusStrip1.Location = new System.Drawing.Point(0, 406); @@ -98,26 +88,26 @@ private void InitializeComponent() // importToolStripMenuItem // importToolStripMenuItem.Name = "importToolStripMenuItem"; - importToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + importToolStripMenuItem.Size = new System.Drawing.Size(163, 22); importToolStripMenuItem.Text = "Import from CSV"; importToolStripMenuItem.Click += importToolStripMenuItem_Click; // // exportToolStripMenuItem // exportToolStripMenuItem.Name = "exportToolStripMenuItem"; - exportToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + exportToolStripMenuItem.Size = new System.Drawing.Size(163, 22); exportToolStripMenuItem.Text = "Export to CSV"; exportToolStripMenuItem.Click += exportToolStripMenuItem_Click; // // toolStripMenuItem1 // toolStripMenuItem1.Name = "toolStripMenuItem1"; - toolStripMenuItem1.Size = new System.Drawing.Size(177, 6); + toolStripMenuItem1.Size = new System.Drawing.Size(160, 6); // // applyChangesToolStripMenuItem // applyChangesToolStripMenuItem.Name = "applyChangesToolStripMenuItem"; - applyChangesToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + applyChangesToolStripMenuItem.Size = new System.Drawing.Size(163, 22); applyChangesToolStripMenuItem.Text = "Apply Changes"; applyChangesToolStripMenuItem.Click += applyChangesToolStripMenuItem_Click; // @@ -150,6 +140,16 @@ private void InitializeComponent() hashToolStripMenuItem.Text = "Hash"; hashToolStripMenuItem.Click += hashToolStripMenuItem_Click; // + // colID + // + colID.HeaderText = "ID"; + colID.Name = "colID"; + // + // colString + // + colString.HeaderText = "String"; + colString.Name = "colString"; + // // LangEdit // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -172,8 +172,6 @@ private void InitializeComponent() #endregion private System.Windows.Forms.DataGridView dgvMain; - private System.Windows.Forms.DataGridViewTextBoxColumn colHashID; - private System.Windows.Forms.DataGridViewTextBoxColumn colText; private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.MenuStrip menuStrip1; private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; @@ -185,5 +183,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem findToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem applyChangesToolStripMenuItem; + private System.Windows.Forms.DataGridViewTextBoxColumn colID; + private System.Windows.Forms.DataGridViewTextBoxColumn colString; } } diff --git a/LangEditor/LangEdit.cs b/LangEditor/LangEdit.cs index ae01851..e846eae 100644 --- a/LangEditor/LangEdit.cs +++ b/LangEditor/LangEdit.cs @@ -15,6 +15,7 @@ public partial class LangEdit : Form, IEntryEditor private bool _ignoreChanges; + private Dictionary dict; private Language _lang; public Language Lang { @@ -32,13 +33,52 @@ public LangEdit() { _ignoreChanges = true; InitializeComponent(); + GenerateDictionary(); _ignoreChanges = false; } + public void GenerateDictionary() + { + dict = new Dictionary(); + StreamReader keys = new StreamReader("keys/keys.csv", Encoding.UTF8); + string key; + while ((key = keys.ReadLine()) != null) + { + key = key.Substring(1, key.Length - 2); + if (key.Contains('<')) + { + int subKeyFilePos = key.IndexOf("<") + 1; + string subKeyFile = key.Substring(subKeyFilePos, key.IndexOf(">") - subKeyFilePos); + StreamReader subKeys = new StreamReader("keys/" + subKeyFile + ".csv", Encoding.UTF8); + string subKey; + while ((subKey = subKeys.ReadLine()) != null) + { + string fullSubKey = key.Replace(subKeyFile, subKey); // Replace file name with subkey + fullSubKey = fullSubKey.Remove(subKeyFilePos - 1, 1); // Remove < + fullSubKey = fullSubKey.Remove(subKeyFilePos - 1 + subKey.Length, 1); // Remove > + dict.Add(Language.HashID(fullSubKey), fullSubKey); + } + + subKeys.Close(); + + continue; + } + + dict.Add(Language.HashID(key), key); + + keys.Close(); + } + } + public void UpdateDisplay() { - foreach (uint key in _lang.mpEntries.Keys) - dgvMain.Rows.Add(key.ToString("X8"), _lang.mpEntries[key]); + foreach (KeyValuePair entry in _lang.mpEntries) + { + if (dict.ContainsKey(entry.Key)) + dgvMain.Rows.Add(dict[entry.Key], entry.Value); + else + dgvMain.Rows.Add("0x" + entry.Key.ToString("X8"), entry.Value); + } } public void RebuildLanguage() @@ -52,11 +92,19 @@ public void RebuildLanguage() { string idString = (string)dgvMain.Rows[i].Cells[0].Value; - if (!uint.TryParse(idString, NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out var id)) + uint id; + if (idString.Length == 8 && idString.StartsWith("0x")) // Hash { - MessageBox.Show(this, "Failed to parse ID \"" + idString + "\"", "Warning", - MessageBoxButtons.OK, MessageBoxIcon.Warning); - return; + if (!uint.TryParse(idString[2..], NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out id)) + { + MessageBox.Show(this, "Failed to parse ID \"" + idString + "\"", "Warning", + MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + } + else // String + { + id = Language.HashID(idString); } string value = (string)dgvMain.Rows[i].Cells[1].Value; @@ -82,7 +130,7 @@ private void importToolStripMenuItem_Click(object sender, EventArgs e) return; Dictionary data = new Dictionary(); - StreamReader file = new StreamReader(openDialog.FileName); + StreamReader file = new StreamReader(openDialog.FileName, Encoding.UTF8); string line; while ((line = file.ReadLine()) != null) { @@ -94,14 +142,9 @@ private void importToolStripMenuItem_Click(object sender, EventArgs e) pair[1] = pair[1].Replace("\"\"", "\""); // Convert double quotes pair[1] = pair[1].Replace("\\r", "\xD").Replace("\\n", "\xA"); // Convert newlines } - uint key; - try - { - key = uint.Parse(pair[0], NumberStyles.HexNumber); - } - catch (Exception ex) + if (!uint.TryParse(pair[0], NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out var key)) { - MessageBox.Show("Could not parse ID " + pair[0] + ". Import cancelled.", ex.Source, MessageBoxButtons.OK); + MessageBox.Show("Could not parse ID " + pair[0] + ". Import cancelled.", "Error", MessageBoxButtons.OK); return; } data.Add(key, pair[1]); diff --git a/LangEditor/LangEdit.resx b/LangEditor/LangEdit.resx index 7750ed5..9dec3c0 100644 --- a/LangEditor/LangEdit.resx +++ b/LangEditor/LangEdit.resx @@ -57,10 +57,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + True - + True diff --git a/LangEditor/LangEditor.csproj b/LangEditor/LangEditor.csproj index 6e1bfe7..e20d58c 100644 --- a/LangEditor/LangEditor.csproj +++ b/LangEditor/LangEditor.csproj @@ -11,6 +11,14 @@ + + + Always + + + Always + + diff --git a/LangEditor/keys/keys.csv b/LangEditor/keys/keys.csv new file mode 100644 index 0000000..cc15e41 --- /dev/null +++ b/LangEditor/keys/keys.csv @@ -0,0 +1,3 @@ +"CAR_" +"CAR_CAPS_" +"CAR_BLURB_" diff --git a/LangEditor/keys/vehicles.csv b/LangEditor/keys/vehicles.csv new file mode 100644 index 0000000..2849724 --- /dev/null +++ b/LangEditor/keys/vehicles.csv @@ -0,0 +1,526 @@ +PUSMC01 +PUSMC1A2 +PUSMC1A3 +PUSMC0G +PUSMC0C +XUSM1B1 +XUSM1B2 +XUSM1B3 +XUSM1BG +XUSM1BC +PUSCLT02 +PUSCT2A2 +PUSCT2A3 +PUSCLT0G +PUSCLT0C +XUSLT2B1 +XUSCT2A2 +XUSCT2A3 +XUSLT2BG +XUSLT2BC +PASBSC01 +PASBSCA2 +PASBSCA3 +PASBSC0G +PASBSC0C +XASBSCB1 +XASBSCB2 +XASBSCB3 +XASBSCBG +XASBSCBC +PUSCC01 +PUSCCA2 +PUSCCA3 +PUSCC0G +PUSCC0C +XUSCCB1 +XUSCCB2 +XUSCCB3 +XUSCCBG +XUSCCBC +PEUSV01 +PEUSVA2 +PEUSVA3 +PEUSV0G +PEUSV0C +XEUSVB1 +XEUSVB2 +XEUSVB3 +XEUSVBG +XEUSVBC +PASBS01 +PASBS1A2 +PASBS1A3 +PASBS0G +PASBS0C +XASBSB1 +XASBS1B2 +XASBS1B3 +XASBSBG +XASBSBC +CARBB1GT +PSPBZ +PASBCC01 +PASBCCA2 +PASBCCA3 +PASBCC0G +PASBCC0C +XASBCB1 +XASBCB2 +XASBCB3 +XASBCBG +XASBCBC +CARBB2CC +PSPYODO +PSPMICR +PUSCT01 +PUSCT1A2 +PUSCT1A3 +PUSCT0G +PUSCT0C +XUSCT01B +XUSCT1B2 +XUSCT1B3 +XUSCT01G +XUSCT01C +PSPTS +PEUBR01 +PEUBRA2 +PEUBRA3 +PEUBR0G +PEUBR0C +XEUBRB +XEUBRB2 +XEUBRB3 +XEUBRG +XEUBRC +PEULM01 +PEULMA2 +PEULMA3 +PEULM0G +PEULM0C +XEULM1B1 +XEULMB2 +XEULMB3 +XEULM1BG +XEULM1BC +PUSBC01 +PUSBCA2 +PUSBCA3 +PUSBC0G +PUSBC0C +XUSBCB1 +XUSBCB2 +XUSBCB3 +XUSBCBG +XUSBCBC +PUSM03 +PUSM3A2 +PUSM3A3 +PUSM0G +PUSM0C +XUSMU3B +XUSM3B2X +XUSM3B3X +XUSM3G +XUSM3C +PUSGA01 +PUSGA1A2 +PUSGA1A3 +PUSGA0G +PUSGA0C +PUSGAB1 +PUSGAB2 +PUSGAB3 +PUSGABG +PUSGABC +PEUSR01 +PEUSRA2 +PEUSRA3 +PEUSR0G +PEUSR0C +XEUSRB1 +XEUSRB2 +XEUSRB3 +XEUSRBG +XEUSRBC +PEUSC03 +PEUS3A2 +PEUS3A3 +PEUSC0G +PEUSC0C +XEUSC3B1 +XEUSC3B2 +XEUSC3B3 +XEUSC3BG +XEUSC3BC +PUSME01 +PUSMEA2 +PUSMEA3 +PUSME0G +PUSME0C +XUSMEB1 +XUSMEB2 +XUSMEB3 +XUSMEBG +XUSMEBC +PEURC03 +PEUR3A2 +PEUR3A3 +PEURC0G +PEURC0C +XEURC3B1 +XEUR3B2 +XEUR3B3 +XEURC3BG +XEURC3BC +PUSSC01 +XUSSCA2 +PUSSCA3 +PUSSC0G +PUSSC0C +XUSSCB1 +XUSSCB2 +XUSSCB3 +XUSSCBG +XUSSCBC +PUSCV01 +PUSCV1A2 +PUSCV1A3 +PUSCV0G +PUSCV0C +PDLCCVFA +PDLCCVL2 +PDLCCVL3 +XUSCV1B1 +XUSCV1B2 +XUSCV1B3 +XUSCV1BG +XUSCV1BC +PEUSC02 +PEUS2A2 +PEUS2A3 +PEUSC02G +PEUSC02C +PBTRT01 +PBTRT0B +PBTRT0C +XEUSC2B +XEUSC2B2 +XEUSC2B3 +XEUSC2G +XEUSC2C +PUSLR01 +PUSLR1A2 +PUSLR1A3 +PUSLR0G +PUSLR0C +XUSLRB1 +XUSLRB2 +XUSLRB3 +XUSLRBG +XUSLRBC +PUSMC02 +PUSM2A2 +PUSM2A3 +PUSM02G +PUSM02C +XUSM2B1 +XUSM2B2 +XUSM2B3 +XUSM2BG +XUSM2BC +PEUSC04 +PEUS4A2 +PEUS4A3 +PEUSC04G +PEUSC04S +PEUS4B1 +PEUS4B2 +PEUS4B3 +PEUS4BG +PEUS4BC +CARBSC04 +PASC01 +PASC1A2 +PASC1A3 +PASC0G +PASC0C +XASC1B1 +XASC1B2 +XASC1B3 +XASC1BG +XASC1BC +PSPGAS +PUSPK01 +PUSPKA2 +PUSPKA3 +PUSPK0G +PUSPK0C +XUSPKB1 +XUSPKB2 +XUSPKB3 +XUSPKBG +XUSPKBC +PUSRC01 +PUSRCA2 +PUSRCA3 +PUSRC0G +PUSRC0C +XUSRCB1 +XUSRCB2 +XUSRCB3 +XUSRCBG +XUSRCBC +PUSRN01 +PUSRNA2 +PUSRNA3 +PUSRN0G +PUSRN0C +PDLCMOR +PDLCML2 +PDLCML3 +XUSRNB1 +XUSRNB2 +XUSRNB3 +XUSRNBG +XUSRNBC +PSPBEST +PUSMC04 +PUSM4A2 +PUSM4A3 +PUSM04G +PUSM04C +PBTTMC04 +PBTTMC2 +PBTTMC3 +XUSM4B1 +XUSM4B2 +XUSM4B3 +XUSM4BG +XUSM4BC +CARBMC04 +PSPMETL +PUSCCO01 +PUSCCOA2 +PUSCCOA3 +PUSCCO0G +PUSCCO0C +XUSCCOB1 +XUSCCOB2 +XUSCCOB3 +XUSCCOBG +XUSCCOBC +PEURR01 +PEURRA2 +PEURRA3 +PEURR0G +PEURR0C +XEURRB1 +XEURRB2 +XEURRB3 +XEURRBG +XEURRBC +PEUS01 +PEUSA2 +PEUSA3 +PEUS0G +PEUS0C +XEUSB1 +XEUSB2 +XEUSB3 +XEUSBG +XEUSBC +CARBRWDS +PSPPS3 +PEURG01 +PEUGTB2 +PEUGTB3 +PEURG0G +PEURG0C +XEURG1BG +XEUGT1BG +XEURG1BC +CARBEAGT +PSPT +PUSCL01 +PUSCL1A2 +PUSCL1A3 +PUSCL0G +PUSCL0C +XUSCL1B1 +XUSCL1BG +XUSCL1BC +PUSBH01 +PUSBHA2 +PUSBHA3 +PUSBH0G +PUSBH0C +XUSBHB1 +XUSBHB2 +XUSBHB3 +XUSBHBG +XUSBHBC +PSPCIR +PUSRI01 +PUSRIA2 +PUSRIA3 +PUSRI0G +PUSRI0C +PUSCPI5 +PUSCPI3 +PUSCPI4 +PUSCPIG +PUSCPIC +PSPWAL +PSPCHRO +PBTSVK01 +PDSVK0B +PDSVK0W +PDRWT01 +PDRWTL2 +PDRWTL3 +PUSMBST +PUSMBS2 +PUSMBSTG +PUSMBS2G +PUSMBSS1 +PUSMBSS2 +PUSMBSSG +PUSMBSG2 +PUSMB01 +PUSMB02 +PUSMB1G +PUSMB2G +PUSMBGP1 +PUSMBG12 +PUSMBG13 +PUSMBG14 +PUSMBG15 +PUSMBG16 +PUSMBG17 +PUSMBG18 +PSDMC01 +PSDMC04 +PSDRI01 +PSDSC01 +PSDBC01 +PSDPK01 +PSDCCO01 +PSDCV01 +PSDGP +PDLCB2F +PDLCGB +PDLCNR01 +PDLCGL +PDSHR01 +PBTHM01 +PBTHM0B +PBTHM0C +PCCMC01 +PCCCLT2 +PCCBSC01 +PCCCO01 +PCCSV01 +PCCBS01 +PCCBCC01 +PCCCT01 +PCCBR01 +PCCLM01 +PCCBC01 +PCCMU3 +PCCGA01 +PCCSR01 +PCCSC03 +PCCME01 +PCCRC03 +PCCSC01 +PCCCV01 +PCCSC02 +PCCLR01 +PCCMC02 +PCCSC04 +PCCC01 +PCCPK01 +PCCRC01 +PCCRN01 +PCCMC04 +PCCRR01 +PCCS01 +PCCRG01 +PCCCC01 +PCCBH01 +PCCSVK01 +PCCRWT01 +PDDK01 +PDDK0A +PDDK0C +PDDK01XS +PBTJPDI +PBTSVK02 +PBTEA01 +PBTEA1B +PBTEA1C +PSDGL01 +PSD88S +PSDNR01 +PSDGB +TUSRV01 +TUSRV02 +TUSLT01 +TUSLT02 +TUSLT03 +TUSLT04 +TUSLT07 +TUSLT08 +TUSLT09 +TUSAC01 +TUSAC02 +TUSSUV01 +TUSSUV02 +TUSDTT01 +TUSDTT1B +TEUMPV01 +TUSCC01 +TASS01 +TUSSL01 +TUSB01 +TUSB02 +TUSSV01 +TUSPK01 +TUSPK01B +TUSSW01 +TUSV01 +TUSV01B +TUSV02 +TUSV02B +TUSSV +TUSGSV +TUSSMT01 +TUSSMT02 +TUSSMT03 +TUSSMT04 +TUSTR01 +TUSTR02 +TUSTR03 +TUSTR04 +TUSTR05 +TUSTR06 +TUSLM01 +BTC03 +PDCT01 +PDTR01 +PDRR01 +PDSSR01 +PDD01 +PEUAS01 +PUSCVFA +PUSRNFA +PBTCGT01 +PBTHH01 +PBTCFB01 +PBTJP01 +PBTKS01 +PBTWRT01 +PBTTHO01 +PBTNI01 From d93e6f89ceb720f0c00f61755103e98c085f1664 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Fri, 5 May 2023 22:35:29 -0400 Subject: [PATCH 5/7] List several keys and add range-based check --- LangEditor/LangEdit.cs | 51 +- LangEditor/LangEditor.csproj | 34 +- LangEditor/keys/challenges.txt | 500 ++++++++++++++++++ LangEditor/keys/keys.csv | 3 - LangEditor/keys/keys.txt | 15 + LangEditor/keys/lualist/descriptions.txt | 36 ++ LangEditor/keys/lualist/goals.txt | 12 + LangEditor/keys/lualist/modifiers.txt | 6 + LangEditor/keys/lualist/names.txt | 36 ++ LangEditor/keys/luascript/messages.txt | 11 + LangEditor/keys/luascript/praises.txt | 4 + LangEditor/keys/luascript/scoretypes.txt | 2 + LangEditor/keys/luascript/titles.txt | 1 + .../keys/{vehicles.csv => vehicles.txt} | 0 14 files changed, 696 insertions(+), 15 deletions(-) create mode 100644 LangEditor/keys/challenges.txt delete mode 100644 LangEditor/keys/keys.csv create mode 100644 LangEditor/keys/keys.txt create mode 100644 LangEditor/keys/lualist/descriptions.txt create mode 100644 LangEditor/keys/lualist/goals.txt create mode 100644 LangEditor/keys/lualist/modifiers.txt create mode 100644 LangEditor/keys/lualist/names.txt create mode 100644 LangEditor/keys/luascript/messages.txt create mode 100644 LangEditor/keys/luascript/praises.txt create mode 100644 LangEditor/keys/luascript/scoretypes.txt create mode 100644 LangEditor/keys/luascript/titles.txt rename LangEditor/keys/{vehicles.csv => vehicles.txt} (100%) diff --git a/LangEditor/LangEdit.cs b/LangEditor/LangEdit.cs index e846eae..e020d77 100644 --- a/LangEditor/LangEdit.cs +++ b/LangEditor/LangEdit.cs @@ -40,45 +40,76 @@ public LangEdit() public void GenerateDictionary() { dict = new Dictionary(); - StreamReader keys = new StreamReader("keys/keys.csv", Encoding.UTF8); + StreamReader keys = new StreamReader("keys/keys.txt", Encoding.UTF8); string key; while ((key = keys.ReadLine()) != null) { - key = key.Substring(1, key.Length - 2); - if (key.Contains('<')) + if (key.Contains("") - subKeyFilePos); - StreamReader subKeys = new StreamReader("keys/" + subKeyFile + ".csv", Encoding.UTF8); + StreamReader subKeys = new StreamReader("keys/" + subKeyFile + ".txt", Encoding.UTF8); string subKey; while ((subKey = subKeys.ReadLine()) != null) { string fullSubKey = key.Replace(subKeyFile, subKey); // Replace file name with subkey - fullSubKey = fullSubKey.Remove(subKeyFilePos - 1, 1); // Remove < - fullSubKey = fullSubKey.Remove(subKeyFilePos - 1 + subKey.Length, 1); // Remove > - dict.Add(Language.HashID(fullSubKey), fullSubKey); + fullSubKey = fullSubKey.Remove(subKeyFilePos - 2, 2); // Remove + try + { + dict.Add(Language.HashID(fullSubKey), fullSubKey); + } + catch + { + MessageBox.Show("ID " + fullSubKey + " (0x" + Language.HashID(fullSubKey).ToString("X8") + ") already exists.", "Error", MessageBoxButtons.OK); + continue; + } } subKeys.Close(); continue; } + else if (key.Contains("") - subKeyRangePos); + int start = int.Parse(subKeyRange.Substring(0, subKeyRange.IndexOf('-'))); + int end = int.Parse(subKeyRange.Substring(subKeyRange.IndexOf('-') + 1)); + for (int i = start; i <= end; ++i) + { + string fullSubKey = key.Replace(subKeyRange, i.ToString()); + fullSubKey = fullSubKey.Remove(subKeyRangePos - 2, 2); // Remove + dict.Add(Language.HashID(fullSubKey), fullSubKey); + } + } dict.Add(Language.HashID(key), key); - - keys.Close(); } + + keys.Close(); } public void UpdateDisplay() { + int resolved = 0, total = 0; foreach (KeyValuePair entry in _lang.mpEntries) { if (dict.ContainsKey(entry.Key)) + { dgvMain.Rows.Add(dict[entry.Key], entry.Value); + total++; + resolved++; + } else + { dgvMain.Rows.Add("0x" + entry.Key.ToString("X8"), entry.Value); + total++; + } } + MessageBox.Show("Resolved " + resolved + "/" + total + " keys.", "Information", + MessageBoxButtons.OK); } public void RebuildLanguage() diff --git a/LangEditor/LangEditor.csproj b/LangEditor/LangEditor.csproj index e20d58c..853dcb2 100644 --- a/LangEditor/LangEditor.csproj +++ b/LangEditor/LangEditor.csproj @@ -12,12 +12,42 @@ - + Always - + Always + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + diff --git a/LangEditor/keys/challenges.txt b/LangEditor/keys/challenges.txt new file mode 100644 index 0000000..3ab7178 --- /dev/null +++ b/LangEditor/keys/challenges.txt @@ -0,0 +1,500 @@ +599594 +600353 +600638 +600356 +580831 +599571 +600300 +730928 +730977 +731298 +730921 +729742 +730648 +730914 +580300 +731718 +599577 +732091 +597194 +599665 +597219 +596329 +731469 +730965 +732136 +597958 +587068 +730982 +599590 +599708 +730465 +731685 +731705 +730973 +731700 +730480 +730470 +599533 +730512 +599622 +599505 +600647 +597168 +599626 +731303 +730475 +599642 +599537 +731024 +730416 +599696 +729826 +731695 +580737 +587738 +731408 +731420 +585634 +730636 +599700 +598014 +731012 +730499 +599546 +732116 +596980 +731016 +731743 +599618 +584992 +599692 +597954 +730644 +599525 +599657 +730969 +730942 +730455 +730640 +730957 +730495 +599610 +599646 +731000 +730652 +596998 +730949 +731728 +731007 +729818 +730656 +599614 +600595 +597178 +603810 +597950 +580469 +596994 +596307 +599688 +731020 +731478 +731723 +731690 +599501 +585926 +599598 +731680 +730935 +729807 +730412 +730459 +730679 +600174 +599556 +597057 +580811 +580355 +730407 +730503 +600577 +731458 +731436 +587033 +731738 +596940 +732126 +730517 +599521 +600051 +730490 +730451 +585272 +730485 +587407 +731733 +598073 +608283 +599513 +598069 +583875 +585329 +580738 +600267 +598065 +608275 +600205 +585363 +597010 +617629 +598214 +586270 +585419 +600650 +597982 +597994 +584817 +600152 +600641 +617612 +597226 +599375 +599634 +596837 +587818 +584851 +599191 +587730 +584795 +585983 +597164 +580465 +597146 +599669 +585475 +600653 +587726 +597974 +597254 +585415 +587830 +599203 +600102 +587931 +599630 +600138 +587684 +600213 +587201 +598496 +587822 +600360 +599037 +587720 +596973 +610480 +599339 +587927 +597402 +586266 +604109 +582508 +600296 +585369 +580807 +580816 +582593 +599471 +587857 +584756 +584980 +599359 +605925 +600573 +584894 +582631 +599239 +580786 +600182 +599602 +612295 +597391 +586212 +580821 +584937 +596932 +600607 +585972 +597427 +600002 +587329 +605961 +605973 +597986 +587842 +598053 +584912 +586199 +587558 +587838 +580801 +610469 +603842 +584906 +605965 +597036 +586944 +597447 +585979 +617621 +600255 +584824 +584887 +586336 +597998 +583157 +599371 +599332 +582515 +597534 +585375 +600538 +585943 +597962 +599344 +584959 +585408 +597527 +586241 +585310 +584880 +585954 +599466 +599564 +585216 +599550 +600656 +585934 +584862 +600194 +597316 +599265 +599712 +580468 +599567 +599019 +583879 +602811 +586252 +599720 +600156 +587886 +597268 +583127 +600170 +600220 +582626 +598018 +584737 +599318 +580347 +600055 +610475 +584593 +598081 +600259 +599638 +598282 +599988 +587867 +582600 +585755 +585468 +584690 +608184 +598183 +605933 +588022 +587044 +585342 +600405 +599954 +600535 +597434 +599380 +599208 +597272 +598258 +615935 +580844 +608198 +585968 +600384 +617635 +587074 +598175 +598269 +597030 +586190 +597230 +597464 +585304 +597990 +596987 +587680 +599131 +600659 +602797 +585244 +599976 +599138 +587814 +597978 +602630 +587848 +585390 +586203 +598218 +582618 +587878 +585346 +586258 +600398 +600243 +585938 +587919 +599684 +580492 +600601 +585949 +585559 +587027 +585397 +618744 +600006 +584902 +582519 +599225 +599044 +582614 +600134 +597323 +602830 +585930 +600528 +597442 +596319 +599348 +599015 +608137 +608212 +607967 +602815 +605989 +598996 +596827 +600518 +598359 +599070 +584685 +584696 +599583 +583142 +600487 +584874 +602821 +582638 +600337 +610173 +600480 +605969 +584748 +605985 +598203 +602806 +584898 +813404 +813641 +815245 +813448 +813574 +813428 +813551 +813614 +813621 +813490 +762126 +762134 +762118 +762105 +762161 +762154 +762142 +762150 +762055 +762059 +762043 +762050 +762084 +762095 +762066 +762077 +762168 +762224 +762232 +762216 +762220 +605977 +761982 +762243 +605981 +762184 +762189 +762175 +762179 +762205 +762212 +762193 +762197 +762033 +761847 +761854 +761840 +761828 +761835 +761889 +761897 +761875 +761861 +761865 +761712 +761718 +761702 +608217 +761345 +761812 +761821 +761805 +761771 +761789 +608189 +761989 +761978 +761961 +761971 +762022 +762026 +762018 +761996 +762003 +761924 +761931 +761918 +761909 +761913 +761950 +761954 +761946 +761935 +761942 diff --git a/LangEditor/keys/keys.csv b/LangEditor/keys/keys.csv deleted file mode 100644 index cc15e41..0000000 --- a/LangEditor/keys/keys.csv +++ /dev/null @@ -1,3 +0,0 @@ -"CAR_" -"CAR_CAPS_" -"CAR_BLURB_" diff --git a/LangEditor/keys/keys.txt b/LangEditor/keys/keys.txt new file mode 100644 index 0000000..7b09073 --- /dev/null +++ b/LangEditor/keys/keys.txt @@ -0,0 +1,15 @@ +CAR_ +CAR_CAPS_ +CAR_BLURB_ +FBCT_ +FBCD_ +FBCD__1 +FBCD__2 + + + + + + + + diff --git a/LangEditor/keys/lualist/descriptions.txt b/LangEditor/keys/lualist/descriptions.txt new file mode 100644 index 0000000..3bffa60 --- /dev/null +++ b/LangEditor/keys/lualist/descriptions.txt @@ -0,0 +1,36 @@ +PP_779691_DESC_SWIMMING_UP_STREAM +PP_786216_DESC_CLEARED_FOR_TAKEOFF +PP_788045_DESC_STAY_ON_TARGET +PP_788397_DESC_SAFE_LANDING +PP_788783_DESC_DEAD_MANS_SPIN +PP_788857_DESC_DOUBLE_TROUBLE +PP_789066_DESC_TOLL_TO_TOLL +PP_789070_DESC_DRIFT_KING +PP_789076_DESC_ROLL_WRECKER +PP_789088_DESC_PICKUP_SMASHUP +PP_789252_DESC_HOLE_IN_ONE +PP_789960_DESC_A_BRIDGE_TOO_FAR +PP_790159_DESC_SWITCHBACK_DRIFTER +PP_790163_DESC_WRONG_WAY_STREET +PP_790166_DESC_TUNNEL_VISION +PP_790203_DESC_DANGER_FALLING_CARS +PP_790249_DESC_SPIN_TO_WIN +PP_790283_DESC_STRAIGHT_8 +PP_790415_DESC_BARREL_ROLL_BASH +PP_790428_DESC_BEACH_BARREL +PP_790445_DESC_DOWNTOWN_DASH +PP_790450_DESC_CARRIAGE_RETURN +PP_790467_DESC_EXPRESS_AIRWAYS +PP_790469_DESC_NEAR_MIST +PP_790471_DESC_WALK_ON_THE_WILD_SIDE +PP_790632_DESC_DAM_BUSTER +PP_790645_DESC_MERRYGO_ROUND +PP_790682_DESC_ROCK_AND_ROLLS +PP_790818_DESC_PARK_AND_FLY +PP_790892_DESC_DOWNHILL_SPRINT +PP_790902_DESC_TWISTED_TRACK +PP_791038_DESC_SUMMITS_SMASH +PP_791222_DESC_PARK_PANIC +PP_791227_DESC_BOARDWALKRUN +PP_792546_DESC_VICE_VERSA +PP_793427_DESC_MIND_THE_STEP diff --git a/LangEditor/keys/lualist/goals.txt b/LangEditor/keys/lualist/goals.txt new file mode 100644 index 0000000..a946a3a --- /dev/null +++ b/LangEditor/keys/lualist/goals.txt @@ -0,0 +1,12 @@ +PP_MOST_NEAR_MISSES_WINS +PP_MOST_AIR_TIME_WINS +PP_MOST_ONCOMING_WINS +PP_788397_LAND_JUMP_TO_PASS +PP_788783_LAND_FLAT_SPIN_TO_PASS +PP_790682_LAND_DOUBLE_BARREL_ROLL_TO_PASS +PP_FASTEST_TIME_WINS +PP_MOST_DRIFT_WINS +PP_790415_BARREL_ROLL_AND_CRASH_TO_PASS +PP_789252_JUMP_THROUGH_THE_ROCK_TO_PASS +PP_790249_LAND_180_DEGREE_FLAT_SPIN_TO_PASS +PP_790428_LAND_BARREL_ROLL_TO_PASS diff --git a/LangEditor/keys/lualist/modifiers.txt b/LangEditor/keys/lualist/modifiers.txt new file mode 100644 index 0000000..3c35062 --- /dev/null +++ b/LangEditor/keys/lualist/modifiers.txt @@ -0,0 +1,6 @@ +K_ACCELERATOR_LOCKED +K_BOOST_LOCKED +K_DO_NOT_CRASH +K_DO_NOT_TOUCH_A_WALL +K_REVERSE_STEERING +K_NO_BRAKES diff --git a/LangEditor/keys/lualist/names.txt b/LangEditor/keys/lualist/names.txt new file mode 100644 index 0000000..b90f59c --- /dev/null +++ b/LangEditor/keys/lualist/names.txt @@ -0,0 +1,36 @@ +PP_779691_NAME_SWIMMING_UP_STREAM +PP_786216_NAME_CLEARED_FOR_TAKEOFF +PP_788045_NAME_STAY_ON_TARGET +PP_788397_NAME_SAFE_LANDING +PP_788783_NAME_DEAD_MANS_SPIN +PP_788857_NAME_DOUBLE_TROUBLE +PP_789066_NAME_TOLL_TO_TOLL +PP_789070_NAME_DRIFT_KING +PP_789076_NAME_ROLL_WRECKER +PP_789088_NAME_PICKUP_SMASHUP +PP_789252_NAME_HOLE_IN_ONE +PP_789960_NAME_A_BRIDGE_TOO_FAR +PP_790159_NAME_SWITCHBACK_DRIFTER +PP_790163_NAME_WRONG_WAY_STREET +PP_790166_NAME_TUNNEL_VISION +PP_790203_NAME_DANGER_FALLING_CARS +PP_790249_NAME_SPIN_TO_WIN +PP_790283_NAME_STRAIGHT_8 +PP_790415_NAME_BARREL_ROLL_BASH +PP_790428_NAME_BEACH_BARREL +PP_790445_NAME_DOWNTOWN_DASH +PP_790450_NAME_CARRIAGE_RETURN +PP_790467_NAME_EXPRESS_AIRWAYS +PP_790469_NAME_NEAR_MIST +PP_790471_NAME_WALK_ON_THE_WILD_SIDE +PP_790632_NAME_DAM_BUSTER +PP_790645_NAME_MERRYGO_ROUND +PP_790682_NAME_ROCK_AND_ROLLS +PP_790818_NAME_PARK_AND_FLY +PP_790892_NAME_DOWNHILL_SPRINT +PP_790902_NAME_TWISTED_TRACK +PP_791038_NAME_SUMMITS_SMASH +PP_791222_NAME_PARK_PANIC +PP_791227_NAME_BOARDWALKRUN +PP_792546_NAME_VICE_VERSA +PP_793427_NAME_MIND_THE_STEP diff --git a/LangEditor/keys/luascript/messages.txt b/LangEditor/keys/luascript/messages.txt new file mode 100644 index 0000000..11cd8ff --- /dev/null +++ b/LangEditor/keys/luascript/messages.txt @@ -0,0 +1,11 @@ +PP_YOU_TOUCHED_A_WALL +PP_790166_YOU_BROKE_THE_CHAIN +PP_KEEP_IT_UP +PP_790166_YOURE_UP_TO_1_NEAR_MISSES +PP_UNLUCKY +PP_790166_YOU_DIDNT_NEAR_MISS_ANY_OTHER_VEHICLES +PP_790166_YOU_GOT_1_NEAR_MISS +PP_790166_YOU_GOT_1_NEAR_MISSES +PP_YOUR_SCORE +PP_X_POINTS +PP_790166_GET_THE_MOST_NEAR_MISSES diff --git a/LangEditor/keys/luascript/praises.txt b/LangEditor/keys/luascript/praises.txt new file mode 100644 index 0000000..4ab347c --- /dev/null +++ b/LangEditor/keys/luascript/praises.txt @@ -0,0 +1,4 @@ +PP_OKAY +PP_GOOD +PP_GREAT +PP_AWESOME diff --git a/LangEditor/keys/luascript/scoretypes.txt b/LangEditor/keys/luascript/scoretypes.txt new file mode 100644 index 0000000..34fda3a --- /dev/null +++ b/LangEditor/keys/luascript/scoretypes.txt @@ -0,0 +1,2 @@ +PP_NEAR_MISSES +PP_TC_NEAR_MISSES diff --git a/LangEditor/keys/luascript/titles.txt b/LangEditor/keys/luascript/titles.txt new file mode 100644 index 0000000..7f3bff7 --- /dev/null +++ b/LangEditor/keys/luascript/titles.txt @@ -0,0 +1 @@ +PP_790166_NEAR_MISS_THE_TRAFFIC_VEHICLES diff --git a/LangEditor/keys/vehicles.csv b/LangEditor/keys/vehicles.txt similarity index 100% rename from LangEditor/keys/vehicles.csv rename to LangEditor/keys/vehicles.txt From 448568b856a22d95ef5c053d82c72ca0e8b473b8 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Sat, 6 May 2023 00:23:12 -0400 Subject: [PATCH 6/7] Fix exporting and importing --- LangEditor/LangEdit.cs | 45 ++++++++++++++++++++---------------------- LangEditor/Language.cs | 2 +- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/LangEditor/LangEdit.cs b/LangEditor/LangEdit.cs index e020d77..43d893d 100644 --- a/LangEditor/LangEdit.cs +++ b/LangEditor/LangEdit.cs @@ -124,7 +124,7 @@ public void RebuildLanguage() string idString = (string)dgvMain.Rows[i].Cells[0].Value; uint id; - if (idString.Length == 8 && idString.StartsWith("0x")) // Hash + if (idString.StartsWith("0x") && idString.Length == 10) // Hash { if (!uint.TryParse(idString[2..], NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out id)) { @@ -141,7 +141,7 @@ public void RebuildLanguage() string value = (string)dgvMain.Rows[i].Cells[1].Value; if (data.ContainsKey(id)) { - MessageBox.Show(this, "ID Already In Use " + idString, "Warning", + MessageBox.Show(this, "ID " + idString + " already in use", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } @@ -166,18 +166,26 @@ private void importToolStripMenuItem_Click(object sender, EventArgs e) while ((line = file.ReadLine()) != null) { string[] pair = line.Split(',', 2); - pair[0] = pair[0].Substring(3, 8); // Key + pair[0] = pair[0].Remove(0, 1).Remove(pair[0].Length - 2, 1); // Remove quotes + uint key; + if (pair[0].StartsWith("0x") && pair[0].Length == 10) + { + if (!uint.TryParse(pair[0][2..], NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out key)) + { + MessageBox.Show("Could not parse ID " + pair[0] + ". Import cancelled.", "Error", MessageBoxButtons.OK); + return; + } + } + else + key = Language.HashID(pair[0]); + if (pair[1].Length != 0) // Non-empty value { pair[1] = pair[1].Substring(1, pair[1].Length - 2); // Remove enclosing double quotes pair[1] = pair[1].Replace("\"\"", "\""); // Convert double quotes pair[1] = pair[1].Replace("\\r", "\xD").Replace("\\n", "\xA"); // Convert newlines } - if (!uint.TryParse(pair[0], NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out var key)) - { - MessageBox.Show("Could not parse ID " + pair[0] + ". Import cancelled.", "Error", MessageBoxButtons.OK); - return; - } + data.Add(key, pair[1]); } @@ -185,33 +193,24 @@ private void importToolStripMenuItem_Click(object sender, EventArgs e) dgvMain.Rows.Clear(); UpdateDisplay(); - - MessageBox.Show("Import successful.", "Information", MessageBoxButtons.OK); } private void exportToolStripMenuItem_Click(object sender, EventArgs e) { - // TODO: Note when language is dirty, not just bundle - if (MessageBox.Show(this, "Changes must be applied before exporting. Save now?", "Information", - MessageBoxButtons.OKCancel) == DialogResult.Cancel) - return; - SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.Filter = "Column-separated values (*.csv)|*.csv"; if (saveDialog.ShowDialog() == DialogResult.Cancel) return; - RebuildLanguage(); - // CSV content as a single contiguous string. // Keys are prepended with 0x and padded to 8 characters. // In values, incompatible characters are escaped. // Both keys and values are enclosed in double quotes. string languageContent = ""; - foreach (KeyValuePair entry in _lang.mpEntries) + for (int i = 0; i < dgvMain.Rows.Count - 1; ++i) { - languageContent += "\"0x" + entry.Key.ToString("X8") + "\","; // Key - string tempValue = entry.Value; + languageContent += "\"" + (string)(dgvMain.Rows[i].Cells[0].Value) + "\","; + string tempValue = (string)dgvMain.Rows[i].Cells[1].Value; tempValue = tempValue.Replace("\xD", "\\r").Replace("\xA", "\\n"); // Convert newlines tempValue = tempValue.Replace("\"", "\"\""); // Convert double quotes if (tempValue.Length != 0) // Enclose non-empty strings in double quotes @@ -242,13 +241,11 @@ private void findToolStripMenuItem_Click(object sender, EventArgs e) string value = InputDialog.ShowInput(this, "Please enter the value to search for."); if (value == null) return; - uint result = Language.HashID(value); - string hash; foreach (DataGridViewRow row in dgvMain.Rows) { - hash = (string)row.Cells[0].Value; - if (result.ToString("X8") == hash) + if (((string)row.Cells[0].Value).Contains(value, StringComparison.CurrentCultureIgnoreCase) + || ((string)row.Cells[1].Value).Contains(value, StringComparison.CurrentCultureIgnoreCase)) { dgvMain.ClearSelection(); dgvMain.CurrentCell = row.Cells[0]; diff --git a/LangEditor/Language.cs b/LangEditor/Language.cs index fe92b22..efb87e8 100644 --- a/LangEditor/Language.cs +++ b/LangEditor/Language.cs @@ -145,7 +145,7 @@ public static uint HashID(string id) return result;*/ - byte[] message = Encoding.ASCII.GetBytes(id); + byte[] message = Encoding.UTF8.GetBytes(id); UInt32 hash = UInt32.MaxValue; for (UInt32 i = 0; i < message.Length; i++) { From 03a75f585dc15afff793bb99df3656077ca13f84 Mon Sep 17 00:00:00 2001 From: burninrubber0 Date: Sat, 6 May 2023 15:23:35 -0400 Subject: [PATCH 7/7] Add keys readme --- LangEditor/keys/README.md | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 LangEditor/keys/README.md diff --git a/LangEditor/keys/README.md b/LangEditor/keys/README.md new file mode 100644 index 0000000..40b5427 --- /dev/null +++ b/LangEditor/keys/README.md @@ -0,0 +1,63 @@ +# Keys +These files store known keys used in Burnout Paradise's Language resources. + +## General format +Keys are plaintext except for the ability to use tags enclosed in `<` and `>`. At present, there are two available tags: +- `f` indicates a text file in the keys folder. For example, `` means `keys/vehicles.txt`. Each line in the file replaces the tag, creating a new key. +- `r` indicates a numeric range formatted as `start-end`. For example, `` denotes a range of 100 to 150. Each number replaces the tag, creating a new key. Both the start and end are **inclusive**. + +Currently, only one tag per line is supported, and tags cannot be used in files accessed through `` (i.e., tagging is not recursive). This may change in the future if there is demand for it. + +**DO NOT ABUSE RANGES.** If you attempt to use it to, for example, find gameDB IDs from 0 to 1000000, **there will be false positives**. This feature is most useful for small ranges that are entirely or mostly sequential. + +## Adding keys +If you have keys to add, you can submit them via the [issue for them](https://github.com/burninrubber0/Bundle-Manager/issues/35) or create a new pull request. + +New keys should be as specific as possible so as to avoid false positives. Keys submitted here must be for the vanilla game—mods should not be included. Keys from development builds are allowed. + +To get a specific set of keys, you can either manually copy them from the game's resources or (preferred) programmatically retrieve them. See the below example for an instance of the latter. + +## Example dumping application +This is a dumper used to get all challenge IDs from the extracted ChallengeList resource of Burnout Paradise Remastered PC. It is a C++ console application using the Qt library. You can view the output in challenges.txt. + +For ChallengeList details, see [Challenge List](https://burnout.wiki/wiki/Challenge_List) on the Burnout Wiki. + +```cpp +#include +#include +#include + +int main(int argc, char *argv[]) +{ + // Take extracted challenge file as only argument + QFile challs(argv[1]); + QDataStream challsStr(&challs); + challsStr.setByteOrder(QDataStream::LittleEndian); + challs.open(QIODeviceBase::ReadOnly); + + // Get num challenges, then IDs + quint32 numEntries, entries; + QList ids; + challsStr >> numEntries; + challsStr >> entries; + challs.seek(entries + 0xC0); + quint64 id = 0; + for (int i = 0; i < numEntries; ++i) + { + challsStr >> id; + ids.append(id); + challs.seek(challs.pos() + 0xD0); + } + challs.close(); + + // Write challenge IDs to text file + QFile out(QString(argv[1]) + ".txt"); + QTextStream outStr(&out); + out.open(QIODeviceBase::WriteOnly); + for (int i = 0; i < ids.count(); ++i) + outStr << ids[i] << '\n'; + out.close(); + + return 0; +} +```