public void PatchPartition(string folder, string partition) { if (!InitializePartition(partition)) { return; } var resource = LS.TryGetValue(partition); if (resource == null) { return; } Console.WriteLine($"------{partition}------"); foreach (string key in Files.Keys) { string filepath = $"{folder}/{key}"; if (File.Exists(filepath)) { Console.WriteLine($"Patch: {key}"); var tpl = Files[key]; var rsobj = tpl.Item2; int index = RF.ResourceEntries.IndexOf(rsobj); byte[] data = File.ReadAllBytes(filepath); byte[] cmp = Util.Compress(data); using (FileStream stream = File.Open(DTFiles[tpl.Item1.DTIndex], FileMode.Open)) { // Overwrite existing data stream.Seek(tpl.Item1.DTOffset + rsobj.OffInPack, SeekOrigin.Begin); for (int i = 0; i < rsobj.CmpSize; i++) { stream.WriteByte(0xCC); } // Get how much space we have to work with stream.Seek(tpl.Item1.DTOffset + rsobj.OffInPack, SeekOrigin.Begin); int len = 0; while (stream.ReadByte() == 0xCC) { len++; } // If the new file is within range, write the new data stream.Seek(tpl.Item1.DTOffset + rsobj.OffInPack, SeekOrigin.Begin); if (cmp.Length <= len) { stream.Write(cmp, 0, cmp.Length); } } rsobj.DecSize = data.Length; rsobj.CmpSize = cmp.Length; RF[index] = rsobj; } } RF.UpdateEntries(); RF.WorkingSource.Close(); byte[] resbytes = RF.GetBytes(); using (var stream = File.Open(DTFiles[resource.DTIndex], FileMode.Open)) { stream.Seek(resource.DTOffset, SeekOrigin.Begin); stream.Write(resbytes, 0, resbytes.Length); } resource.Size = resbytes.Length; LS.TrySetValue(partition, resource); LS.UpdateEntries(); }
public void BuildPartitions(string folder) { if (DTFiles == null) { return; } FileStream dtstrm = File.Create("dt_rebuild"); string tmpfile = Path.GetTempFileName(); FileStream packstrm = File.Create(tmpfile); foreach (string str in Directory.EnumerateDirectories(folder)) { if (!str.Contains("data")) { return; } string partition = "resource"; if (str.Contains("(")) { partition += str.Substring(str.IndexOf("(")); } var rf = new RFFile(); LSEntry curPacked = null; int pad = 0; string packKey = ""; foreach (string key in Files.Keys) { Console.WriteLine(key); var tpl = Files[key]; if (tpl.Item2.Packed) { if (curPacked != null) { int aligned = (int)packstrm.Position.RoundUp(0x10) + 0x60; while (packstrm.Position < aligned) { packstrm.WriteByte(0xBB); } curPacked.Size = (int)packstrm.Length; LS.TrySetValue(packKey, curPacked); packstrm.WriteTo(dtstrm); packstrm.Close(); packstrm = File.Open(tmpfile, FileMode.Truncate); } curPacked = tpl.Item1; packKey = key; curPacked.DTOffset = (uint)dtstrm.Position; var data = File.ReadAllBytes($"{folder}/{key}"); for (pad = 0; pad < data.Length && data[pad] == 0xCC; pad++) { packstrm.WriteByte(0xCC); } } else if (!tpl.Item2.EntryString.EndsWith("/")) { var filedata = File.ReadAllBytes($"{folder}/{key}"); var cmp = Util.Compress(filedata); ResourceEntry rsobj = tpl.Item2; int rIndex = RF.ResourceEntries.IndexOf(rsobj); rsobj.OffInPack = (uint)packstrm.Position; rsobj.CmpSize = cmp.Length; rsobj.DecSize = filedata.Length; RF[rIndex] = rsobj; packstrm.Write(cmp, 0, cmp.Length); int aligned = (int)packstrm.Position.RoundUp(0x10) + 0x20; while (packstrm.Position % 0x10 > 0) { packstrm.WriteByte(0xCC); } } } if (curPacked != null) { curPacked.Size = (int)packstrm.Length; LS.TrySetValue(packKey, curPacked); packstrm.WriteTo(dtstrm); } RF.UpdateEntries(); byte[] full = RF.GetBytes(); var resource = LS.TryGetValue(partition); resource.DTOffset = (uint)dtstrm.Position; dtstrm.Write(full, 0, full.Length); resource.Size = full.Length; LS.TrySetValue(partition, resource); LS.UpdateEntries(); dtstrm.Close(); packstrm.Close(); } }