public static void Repack(string sourceFile) { FMG fmg = new FMG(); XmlDocument xml = new XmlDocument(); xml.Load(sourceFile); Enum.TryParse(xml.SelectSingleNode("fmg/compression")?.InnerText ?? "None", out DCX.Type compression); fmg.Compression = compression; fmg.Version = (FMG.FMGVersion)Enum.Parse(typeof(FMG.FMGVersion), xml.SelectSingleNode("fmg/version").InnerText); fmg.BigEndian = bool.Parse(xml.SelectSingleNode("fmg/bigendian").InnerText); foreach (XmlNode textNode in xml.SelectNodes("fmg/entries/text")) { int id = int.Parse(textNode.Attributes["id"].InnerText); // \r\n is drawn as two newlines ingame string text = textNode.InnerText.Replace("\r", ""); if (text == "%null%") { text = null; } fmg.Entries.Add(new FMG.Entry(id, text)); } string outPath = sourceFile.Replace(".fmg.xml", ".fmg"); YBUtil.Backup(outPath); fmg.Write(outPath); }
public void Save(bool needsUpgrade = false) { if (needsUpgrade) { SetUpgradeTexts(); } Proper.Entries.Sort((x, y) => x.ID.CompareTo(y.ID)); FileProper.Bytes = Proper.Write(); if (FilePatch != null) { Patch.Entries.Sort((x, y) => x.ID.CompareTo(y.ID)); FilePatch.Bytes = Patch.Write(); } }
private static void PatchFMG(IBinder sourceBND, IBinder destBND, IBinder refBND, string destLang) { int iFile = 0; //File counter int iRef = 0; //Reference index counter int entriesAdded = 0; //Total added per file int entriesOverwritten = 0; //Total overwritten per file Log.Add($"{ new DirectoryInfo(Path.GetDirectoryName(destLang)).Name } { Path.GetFileName(destLang) } start"); foreach (var file in sourceBND.Files) //For each FMG in the source BND file { if (file.ID > destBND.Files[iFile].ID) //Compatability for using program from non-English folders. Does nothing in the English folder. { while ((file.ID > destBND.Files[iFile].ID) && (iFile < destBND.Files.Count - 1)) { //ConsoleLog("Skipped " + destBND.Files[iFile].ID); //Debug if (iFile < destBND.Files.Count - 1) { iFile++; } } } if (file.ID == destBND.Files[iFile].ID) //If the file IDs match, update. If not, skip until they do match { //Add the source and destination FMG Log.Add($"Destination: { Path.GetFileName(destBND.Files[iFile].Name) } / Source: { Path.GetFileName(file.Name) }"); //ConsoleLog(file.ID + " = true"); // Debug FMG sourceFMG = FMG.Read(file.Bytes); FMG destFMG = FMG.Read((destBND.Files[iFile]).Bytes); //Make dictionaries out of the FMG files Dictionary <int, string> sourceDict = sourceFMG.Entries.GroupBy(x => x.ID).Select(x => x.First()).ToDictionary(x => x.ID, x => x.Text); Dictionary <int, string> destDict = destFMG.Entries.GroupBy(x => x.ID).Select(x => x.First()).ToDictionary(x => x.ID, x => x.Text); entriesAdded = AddNew(entriesAdded, sourceDict, destDict); //Make a refFMG and refDict if refBND isn't null Dictionary <int, string> refDict = MakeRef(refBND, iRef); //Make dicitonary based on comparing sourceDict to refDict if (refDict != null) { entriesOverwritten = UpdateText(entriesOverwritten, refDict, sourceDict, destDict); } //Clear and rewrite FMG file RewriteFMG(destFMG, destDict); //Replace old null entries if no reference. if (NoRef) { Log.Add("Changed:"); entriesOverwritten = NullOverwrite(entriesOverwritten, sourceFMG, destFMG); } #region Debug Stuff //foreach (var entry in destFMG.Entries) //{ // ConsoleLog(entry); //} #endregion //Write the new files destBND.Files[iFile].Bytes = destFMG.Write(); //Add to counter if it's not already maxed if (iFile < destBND.Files.Count - 1) { iFile++; } } #region Debug Stuff //else //Debug //{ // ConsoleLog(file.ID + " = false"); //} #endregion iRef++; } //Print stats for entire BND file ConsoleLog($"Patched: { new DirectoryInfo(Path.GetDirectoryName(destLang)).Name } { Path.GetFileName(destLang) }: { entriesAdded } entries added and { entriesOverwritten } entries overwritten"); //Append log file Log.Add($"{ new DirectoryInfo(Path.GetDirectoryName(destLang)).Name } { Path.GetFileName(destLang) } end"); File.AppendAllLines($@"{ Directory.GetCurrentDirectory() }\LangPatchLog.txt", Log); Log.Clear(); }