diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 624fcd27..fd7d8238 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -5,7 +5,7 @@ Debug AnyCPU {8FABCD3A-9D55-4B54-B237-B259D815DEB8} - Exe + WinExe FModel FModel v4.7.1 @@ -128,7 +128,7 @@ - + diff --git a/FModel/MainWindow.Designer.cs b/FModel/MainWindow.Designer.cs index 9a640f53..9260a787 100644 --- a/FModel/MainWindow.Designer.cs +++ b/FModel/MainWindow.Designer.cs @@ -71,7 +71,6 @@ this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); this.backgroundWorker2 = new System.ComponentModel.BackgroundWorker(); - this.locresStringFinderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout(); this.panel1.SuspendLayout(); @@ -204,8 +203,7 @@ // filesToolStripMenuItem // this.filesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.searchToolStripMenuItem, - this.locresStringFinderToolStripMenuItem}); + this.searchToolStripMenuItem}); this.filesToolStripMenuItem.Name = "filesToolStripMenuItem"; this.filesToolStripMenuItem.Size = new System.Drawing.Size(42, 20); this.filesToolStripMenuItem.Text = "Files"; @@ -213,7 +211,7 @@ // searchToolStripMenuItem // this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - this.searchToolStripMenuItem.Size = new System.Drawing.Size(109, 22); + this.searchToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.searchToolStripMenuItem.Text = "Search"; this.searchToolStripMenuItem.Click += new System.EventHandler(this.searchToolStripMenuItem_Click); // @@ -471,13 +469,6 @@ this.backgroundWorker2.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker2_DoWork); this.backgroundWorker2.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker2_RunWorkerCompleted); // - // locresStringFinderToolStripMenuItem - // - this.locresStringFinderToolStripMenuItem.Name = "locresStringFinderToolStripMenuItem"; - this.locresStringFinderToolStripMenuItem.Size = new System.Drawing.Size(181, 22); - this.locresStringFinderToolStripMenuItem.Text = "LocRes String Finder"; - this.locresStringFinderToolStripMenuItem.Click += new System.EventHandler(this.LocresStringFinderToolStripMenuItem_Click); - // // MainWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -552,7 +543,6 @@ private System.ComponentModel.BackgroundWorker backgroundWorker2; private System.Windows.Forms.ToolStripMenuItem filesToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem searchToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem locresStringFinderToolStripMenuItem; } } diff --git a/FModel/MainWindow.cs b/FModel/MainWindow.cs index 2e0609b5..7abc9ff3 100644 --- a/FModel/MainWindow.cs +++ b/FModel/MainWindow.cs @@ -1110,6 +1110,10 @@ namespace FModel scintilla1.Text = File.ReadAllText(ExtractedFilePath); })); } + if (ExtractedFilePath.Contains(".locres") && !ExtractedFilePath.Contains("EngineOverrides")) + { + SerializeLocRes(); + } } else UpdateConsole("Error while extracting " + ThePak.CurrentUsedItem, Color.FromArgb(255, 244, 66, 66), "Error"); @@ -1333,6 +1337,31 @@ namespace FModel } } + /// + /// because the filename is usually the same for each language, John Wick extract all of them + /// but then i have to manually get the right path from the treeview + /// TODO: find bug for EngineOverrides + /// + private void SerializeLocRes() + { + Invoke(new Action(() => + { + string treeviewPath = treeView1.SelectedNode.FullPath; + if (treeviewPath.StartsWith("..\\")) { treeviewPath = treeviewPath.Substring(3); } //if loading all paks + + string filePath = App.DefaultOutputPath + "\\Extracted\\" + treeviewPath + "\\" + listBox1.SelectedItem; + Console.WriteLine(filePath); + if (File.Exists(filePath)) + { + scintilla1.Text = LocResSerializer.StringFinder(filePath); + } + else + { + AppendText("Error while searching " + listBox1.SelectedItem, Color.DarkRed, true); + } + })); + } + private void ConvertTexture2D() { UpdateConsole(ThePak.CurrentUsedItem + " is a Texture2D", Color.FromArgb(255, 66, 244, 66), "Success"); @@ -1483,20 +1512,5 @@ namespace FModel ImagesMerger.AskMergeImages(); } #endregion - - private void LocresStringFinderToolStripMenuItem_Click(object sender, EventArgs e) - { - if (Directory.Exists(App.DefaultOutputPath + "\\Extracted\\FortniteGame\\Content\\Localization\\")) - { - Invoke(new Action(() => - { - scintilla1.Text = TempStringFinder.locresOpenFile(App.DefaultOutputPath + "\\Extracted\\FortniteGame\\Content\\Localization\\"); - })); - } - else - { - AppendText("No .locres file currently extracted", Color.DarkRed, true); - } - } } } diff --git a/FModel/MainWindow.resx b/FModel/MainWindow.resx index ee40d54f..bb448221 100644 --- a/FModel/MainWindow.resx +++ b/FModel/MainWindow.resx @@ -131,7 +131,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABa - CAAAAk1TRnQBSQFMAgEBAgEAAdgBAAHYAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CAAAAk1TRnQBSQFMAgEBAgEAAegBAAHoAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/FModel/Methods/LocRes/LocResSerializer.cs b/FModel/Methods/LocRes/LocResSerializer.cs new file mode 100644 index 00000000..6afba453 --- /dev/null +++ b/FModel/Methods/LocRes/LocResSerializer.cs @@ -0,0 +1,160 @@ +using Newtonsoft.Json; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace FModel +{ + static class LocResSerializer + { + //TODO: refactor + private static long LocalizedStringArrayOffset { get; set; } + private static string[] LocalizedStringArray { get; set; } + private static int stringIndex { get; set; } + private static string NamespacesString { get; set; } + private static string myKey = "LocResText"; + private static Dictionary> LocResDict { get; set; } + + public static string StringFinder(string filepath) + { + LocResDict = new Dictionary>(); + + using (BinaryReader reader = new BinaryReader(File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.GetEncoding(1252))) + { + byte[] MagicNumber = reader.ReadBytes(16); + + byte VersionNumber = reader.ReadByte(); + + LocalizedStringArrayOffset = -1; + LocalizedStringArrayOffset = reader.ReadInt64(); + if (LocalizedStringArrayOffset != -1) + { + long CurrentFileOffset = reader.BaseStream.Position; + + reader.BaseStream.Seek(LocalizedStringArrayOffset, SeekOrigin.Begin); + int arrayLength = reader.ReadInt32(); + + reader.BaseStream.Seek(LocalizedStringArrayOffset, SeekOrigin.Begin); + + LocalizedStringArray = new string[arrayLength]; + for (int i = 0; i < LocalizedStringArray.Length; i++) + { + LocalizedStringArray[i] = readCleanString(reader); + } + + reader.BaseStream.Seek(CurrentFileOffset, SeekOrigin.Begin); + + uint NamespaceCount = reader.ReadUInt32(); + reader.ReadBytes(17); + + for (uint i = 0; i < NamespaceCount; i++) + { + reader.ReadInt32(); + readNamespaces(reader); + } + } + } + + return JsonConvert.SerializeObject(LocResDict, Formatting.Indented); + } + + private static string readCleanString(BinaryReader reader) + { + reader.ReadInt32(); + int stringLength = 0; + if (reader.BaseStream.Position != reader.BaseStream.Length) + { + stringLength = reader.ReadInt32(); + } + + if (stringLength < 0) + { + byte[] data = reader.ReadBytes((-1 - stringLength) * 2); + reader.ReadBytes(2); + return Encoding.Unicode.GetString(data); + } + else if (stringLength == 0) + { + return ""; + } + else + { + return Encoding.GetEncoding(1252).GetString(reader.ReadBytes(stringLength)).TrimEnd('\0'); + } + } + + private static void readNamespaces(BinaryReader br) + { + if (br.BaseStream.Position > LocalizedStringArrayOffset) { return; } + + int stringLength = br.ReadInt32(); + if (stringLength > 0) + { + NamespacesString = Encoding.GetEncoding(1252).GetString(br.ReadBytes(stringLength)).TrimEnd('\0'); + } + else if (stringLength == 0) + { + NamespacesString = ""; + } + else + { + byte[] data = br.ReadBytes((-1 - stringLength) * 2); + br.ReadBytes(2); + NamespacesString = Encoding.Unicode.GetString(data); + } + + br.ReadInt32(); + stringIndex = br.ReadInt32(); + if (stringIndex > LocalizedStringArray.Length || stringIndex < 0) + { + if (!LocResDict.ContainsKey(NamespacesString)) + { + LocResDict[NamespacesString] = new Dictionary(); + } + + long newOffset = br.BaseStream.Position - 8; + br.BaseStream.Seek(newOffset, SeekOrigin.Begin); + + int KeyCount = br.ReadInt32(); + for (int i = 0; i < KeyCount; i++) + { + readNpKeys(br); + } + } + else + { + if (!LocResDict.ContainsKey(NamespacesString)) + { + LocResDict[NamespacesString] = new Dictionary(); + LocResDict[NamespacesString][myKey] = LocalizedStringArray[stringIndex]; + } + } + } + + private static void readNpKeys(BinaryReader reader) + { + reader.ReadInt32(); + int stringLength = reader.ReadInt32(); + + if (stringLength < 0) + { + byte[] data = reader.ReadBytes((-1 - stringLength) * 2); + reader.ReadBytes(2); + myKey = Encoding.Unicode.GetString(data); + } + else if (stringLength == 0) + { + myKey = ""; + } + else + { + myKey = Encoding.GetEncoding(1252).GetString(reader.ReadBytes(stringLength)).TrimEnd('\0'); + } + + reader.ReadInt32(); + stringIndex = reader.ReadInt32(); + + LocResDict[NamespacesString][myKey] = LocalizedStringArray[stringIndex]; + } + } +} diff --git a/FModel/Methods/LocRes/TempStringFinder.cs b/FModel/Methods/LocRes/TempStringFinder.cs deleted file mode 100644 index 9f45e17d..00000000 --- a/FModel/Methods/LocRes/TempStringFinder.cs +++ /dev/null @@ -1,107 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using System.Windows.Forms; - -namespace FModel -{ - static class TempStringFinder - { - /// - /// - /// - /// - /// - private static string StringFinder(string filepath) - { - var dict = new Dictionary(); - - using (BinaryReader reader = new BinaryReader(File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.GetEncoding(1252))) - { - byte[] MagicNumber = reader.ReadBytes(16); - - byte VersionNumber = reader.ReadByte(); - - long LocalizedStringArrayOffset = -1; - LocalizedStringArrayOffset = reader.ReadInt64(); - if (LocalizedStringArrayOffset != -1) - { - long CurrentFileOffset = reader.BaseStream.Position; - - reader.BaseStream.Seek(LocalizedStringArrayOffset, SeekOrigin.Begin); - int arrayLength = reader.ReadInt32(); - Console.WriteLine("arrayLength: " + arrayLength); - - reader.BaseStream.Seek(LocalizedStringArrayOffset, SeekOrigin.Begin); - - string[] LocalizedStringArray = new string[arrayLength]; - for (int i = 0; i < LocalizedStringArray.Length; i++) - { - if (!dict.ContainsKey("key " + i)) - { - dict.Add("key " + i, readCleanString(reader)); - } - } - - reader.BaseStream.Seek(CurrentFileOffset, SeekOrigin.Begin); - } - - /*uint NamespaceCount = reader.ReadUInt32(); - Console.WriteLine("NamespaceCount: " + NamespaceCount); - - uint KeyCount = reader.ReadUInt32(); - Console.WriteLine("KeyCount: " + KeyCount);*/ - } - - return JsonConvert.SerializeObject(dict, Formatting.Indented); - } - - /// - /// - /// - /// - /// - private static string readCleanString(BinaryReader reader) - { - reader.ReadInt32(); - int stringLength = 0; - if (reader.BaseStream.Position != reader.BaseStream.Length) - { - stringLength = reader.ReadInt32(); - } - - if (stringLength < 0) - { - byte[] data = reader.ReadBytes((-1 - stringLength) * 2); - reader.ReadBytes(2); - return Encoding.Unicode.GetString(data); - } - else if (stringLength == 0) - { - return ""; - } - else - { - return Encoding.GetEncoding(1252).GetString(reader.ReadBytes(stringLength)).TrimEnd('\0'); - } - } - - public static string locresOpenFile(string defaultPath) - { - OpenFileDialog theDialog = new OpenFileDialog(); - theDialog.Multiselect = false; - theDialog.InitialDirectory = defaultPath; - theDialog.Title = @"Choose your LocRes file"; - theDialog.Filter = @"All Files (*.*)|*.*"; - - if (theDialog.ShowDialog() == DialogResult.OK) - { - return StringFinder(theDialog.FileName); - } - else { return null; } - } - } -}