public static void Repack(string sourceDir, string targetDir) { TPF tpf = new TPF(); XmlDocument xml = new XmlDocument(); xml.Load($"{sourceDir}\\_yabber-tpf.xml"); string filename = xml.SelectSingleNode("tpf/filename").InnerText; Enum.TryParse(xml.SelectSingleNode("tpf/compression")?.InnerText ?? "None", out DCX.Type compression); tpf.Compression = compression; tpf.Encoding = Convert.ToByte(xml.SelectSingleNode("tpf/encoding").InnerText, 16); tpf.Flag2 = Convert.ToByte(xml.SelectSingleNode("tpf/flag2").InnerText, 16); foreach (XmlNode texNode in xml.SelectNodes("tpf/textures/texture")) { string name = Path.GetFileNameWithoutExtension(texNode.SelectSingleNode("name").InnerText); byte format = Convert.ToByte(texNode.SelectSingleNode("format").InnerText, 16); byte flags1 = Convert.ToByte(texNode.SelectSingleNode("flags1").InnerText, 16); int flags2 = Convert.ToInt32(texNode.SelectSingleNode("flags2").InnerText, 16); byte[] bytes = File.ReadAllBytes($"{sourceDir}\\{name}.dds"); tpf.Textures.Add(new TPF.Texture(name, format, flags1, bytes)); } string outPath = $"{targetDir}\\{filename}"; YBUtil.Backup(outPath); tpf.Write(outPath); }
public static void CombineDragonTpfs() { // Utility for creating Divine Dragon texbnd. Requires using Yabber to unpack these bnds, and repack after done. string gamePath = GameSpec.ForGame(GameSpec.FromGame.SDT).GameDir; string mainPath = $@"{gamePath}\chr\c5200-texbnd-dcx\chr\c5200\c5200.tpf"; SFUtil.Backup(mainPath); TPF dragon = TPF.Read(mainPath); foreach (string p in Directory.GetFiles($@"{gamePath}\map\m25\m25_0000-tpfbhd", "m25_Dragon*.tpf.dcx")) { TPF t = TPF.Read(p); dragon.Textures.AddRange(t.Textures); } dragon.Write(mainPath); }
public static void Repack(string sourceDir, string targetDir) { TPF tpf = new TPF(); XmlDocument xml = new XmlDocument(); xml.Load($"{sourceDir}\\_yabber-tpf.xml"); string filename = xml.SelectSingleNode("tpf/filename").InnerText; Enum.TryParse(xml.SelectSingleNode("tpf/compression")?.InnerText ?? "None", out tpf.Compression); tpf.Encoding = Convert.ToByte(xml.SelectSingleNode("tpf/encoding").InnerText, 16); tpf.Flag2 = Convert.ToByte(xml.SelectSingleNode("tpf/flag2").InnerText, 16); foreach (XmlNode texNode in xml.SelectNodes("tpf/textures/texture")) { string name = Path.GetFileNameWithoutExtension(texNode.SelectSingleNode("name").InnerText); byte format = Convert.ToByte(texNode.SelectSingleNode("format").InnerText); byte flags1 = Convert.ToByte(texNode.SelectSingleNode("flags1").InnerText, 16); TPF.FloatStruct floatStruct = null; XmlNode floatsNode = texNode.SelectSingleNode("FloatStruct"); if (floatsNode != null) { floatStruct = new TPF.FloatStruct(); floatStruct.Unk00 = int.Parse(floatsNode.Attributes["Unk00"].InnerText); foreach (XmlNode valueNode in floatsNode.SelectNodes("Value")) { floatStruct.Values.Add(float.Parse(valueNode.InnerText)); } } byte[] bytes = File.ReadAllBytes($"{sourceDir}\\{name}.dds"); var texture = new TPF.Texture(name, format, flags1, bytes); texture.FloatStruct = floatStruct; tpf.Textures.Add(texture); } string outPath = $"{targetDir}\\{filename}"; YBUtil.Backup(outPath); tpf.Write(outPath); }
private bool processBDT(BDT bdt, string baseDir, string subPath) { bool edited = false; foreach (BDT.File bdtEntry in bdt.Files) { if (stop) { return(false); } bool dcx = false; byte[] bdtEntryBytes = bdtEntry.Bytes; string bdtEntryExtension = Path.GetExtension(bdtEntry.Name); if (bdtEntryExtension == ".dcx") { dcx = true; bdtEntryBytes = DCX.Decompress(bdtEntryBytes); bdtEntryExtension = Path.GetExtension(bdtEntry.Name.Substring(0, bdtEntry.Name.Length - 4)); } if (bdtEntryExtension == ".tpf") { TPF tpf = TPF.Read(bdtEntryBytes); if (processTPF(tpf, baseDir, subPath)) { bdtEntry.Bytes = tpf.Write(); if (dcx) { bdtEntry.Bytes = DCX.Compress(bdtEntry.Bytes); } edited = true; } } // This whouldn't really be a problem, but I would like to know about it else { appendError("Error: {0}\r\n\u2514\u2500 Non-tpf found in tpfbdt: {1}", subPath, bdtEntry.Name); } } return(edited); }
private void RepackTPFs(ConcurrentQueue <string> filepaths) { string filepath; while (filepaths.TryDequeue(out filepath)) { Log.Enqueue("Repacking texture file " + (fileCount - filepaths.Count) + " of " + fileCount); // These are already full paths, but trust no one, not even yourself string absolute = Path.GetFullPath(filepath); string relative = absolute.Substring(gameDir.Length + 1); bool dcx = false; byte[] bytes = File.ReadAllBytes(absolute); string extension = Path.GetExtension(absolute); string subpath = Path.GetDirectoryName(relative) + "\\" + Path.GetFileNameWithoutExtension(absolute); if (extension == ".dcx") { dcx = true; bytes = DCX.Decompress(bytes); extension = Path.GetExtension(Path.GetFileNameWithoutExtension(absolute)); subpath = subpath.Substring(0, subpath.Length - extension.Length); } switch (extension) { case ".tpf": TPF tpf = TPF.Read(bytes); repackTPF(tpf, looseDir, subpath); byte[] tpfBytes = tpf.Write(); if (dcx) { tpfBytes = DCX.Compress(tpfBytes, DCX.Type.DarkSouls1); } Directory.CreateDirectory(Path.GetDirectoryName(gameDir + "\\TextSoundRando\\Output\\" + relative)); File.WriteAllBytes(gameDir + "\\TextSoundRando\\Output\\" + relative, tpfBytes); break; case ".chrbnd": case ".ffxbnd": case ".fgbnd": case ".objbnd": case ".partsbnd": BND3 bnd = BND3.Read(bytes); foreach (var entry in bnd.Files) { string entryExtension = Path.GetExtension(entry.Name); if (entryExtension == ".tpf") { TPF bndTPF = TPF.Read(entry.Bytes); repackTPF(bndTPF, looseDir, subpath); entry.Bytes = bndTPF.Write(); } } byte[] bndBytes = bnd.Write(); if (dcx) { bndBytes = DCX.Compress(bndBytes, DCX.Type.DarkSouls1); } Directory.CreateDirectory(Path.GetDirectoryName(gameDir + "\\TextSoundRando\\Output\\" + relative)); File.WriteAllBytes(gameDir + "\\TextSoundRando\\Output\\" + relative, bndBytes); break; } } }
private void iterateFiles(ConcurrentQueue <string> filepaths) { while (!stop && filepaths.TryDequeue(out string filepath)) { // These are already full paths, but trust no one, not even yourself string absolute = Path.GetFullPath(filepath); string relative = absolute.Substring(gameDir.Length + 1); if (repack) { appendLog("Checking: " + relative); } else { appendLog("Unpacking: " + relative); } bool dcx = false; byte[] bytes = File.ReadAllBytes(absolute); string extension = Path.GetExtension(absolute); string subpath = Path.GetDirectoryName(relative) + "\\" + Path.GetFileNameWithoutExtension(absolute); if (extension == ".dcx") { dcx = true; bytes = DCX.Decompress(bytes); extension = Path.GetExtension(Path.GetFileNameWithoutExtension(absolute)); subpath = subpath.Substring(0, subpath.Length - extension.Length); } bool edited = false; switch (extension) { case ".tpf": TPF tpf = TPF.Read(bytes); if (processTPF(tpf, looseDir, subpath)) { edited = true; byte[] tpfBytes = tpf.Write(); if (dcx) { tpfBytes = DCX.Compress(tpfBytes); } writeRepack(absolute, tpfBytes); lock (countLock) fileCount++; } break; case ".tpfbhd": string dir = Path.GetDirectoryName(absolute); string name = Path.GetFileNameWithoutExtension(absolute); string bdtPath = dir + "\\" + name + ".tpfbdt"; if (File.Exists(bdtPath)) { byte[] bdtBytes = File.ReadAllBytes(bdtPath); BDT bdt = BDT.Read(bytes, bdtBytes); if (processBDT(bdt, looseDir, subpath)) { edited = true; (byte[], byte[])repacked = bdt.Write(); if (dcx) { repacked.Item1 = DCX.Compress(repacked.Item1); } writeRepack(absolute, repacked.Item1); writeRepack(bdtPath, repacked.Item2); lock (countLock) fileCount++; } } else { throw new FileNotFoundException("Data file not found for header: " + relative); } break; case ".chrbnd": case ".ffxbnd": case ".fgbnd": case ".objbnd": case ".partsbnd": BND bnd = BND.Read(bytes); foreach (BND.File entry in bnd.Files) { if (stop) { break; } string entryExtension = Path.GetExtension(entry.Name); if (entryExtension == ".tpf") { TPF bndTPF = TPF.Read(entry.Bytes); if (processTPF(bndTPF, looseDir, subpath)) { entry.Bytes = bndTPF.Write(); edited = true; } } else if (entryExtension == ".chrtpfbhd") { string bndDir = Path.GetDirectoryName(absolute); string bndName = Path.GetFileNameWithoutExtension(absolute); if (dcx) { bndName = Path.GetFileNameWithoutExtension(bndName); } string bndBDTPath = bndDir + "\\" + bndName + ".chrtpfbdt"; if (File.Exists(bndBDTPath)) { byte[] bdtBytes = File.ReadAllBytes(bndBDTPath); BDT bndBDT = BDT.Read(entry.Bytes, bdtBytes); if (processBDT(bndBDT, looseDir, subpath)) { (byte[], byte[])repacked = bndBDT.Write(); entry.Bytes = repacked.Item1; writeRepack(bndBDTPath, repacked.Item2); edited = true; } } else { throw new FileNotFoundException("Data file not found for header: " + relative); } } } if (edited && !stop) { byte[] bndBytes = bnd.Write(); if (dcx) { bndBytes = DCX.Compress(bndBytes); } writeRepack(absolute, bndBytes); lock (countLock) fileCount++; } break; } if (repack && !edited && !stop) { appendError("Notice: {0}\r\n\u2514\u2500 No overrides found.", relative); } lock (progressLock) progress++; } }