public override void WriteLocationBundle(string outPath, LocationBundle bundle, List <StreamSection> sections) { using (var bw = new BinaryWriter(File.Open(outPath, FileMode.Create, FileAccess.Write, FileShare.Read))) using (var cs = new ChunkStream(bw)) { // We have to skip null chunks in order to avoid weirdness. foreach (var chunk in bundle.Chunks.Where(c => c.Id != 0)) { if (chunk.PrePadding > 8) // 0x10 - 8 = 8; greater than 8 = align 0x80 { cs.PaddingAlignment2(0x80); } else if (chunk.PrePadding > 0) { cs.PaddingAlignment2(0x10); } if (chunk.Id == 0x00034110) { // Write sections list cs.BeginChunk(0x00034110); foreach (var bundleSection in sections.Cast <WorldStreamSection>()) { var secStruct = new World15Section(); secStruct.Hash = bundleSection.Hash; secStruct.ModelGroupName = bundleSection.Name; secStruct.Blank = new uint[3]; secStruct.Blank2 = new byte[36]; secStruct.StreamChunkNumber = bundleSection.Number; secStruct.StreamChunkNumber2 = bundleSection./*UnknownSectionNumber*/ Number; secStruct.FragmentFileId = bundleSection.FragmentFileId; secStruct.Unknown1 = 2; secStruct.X = bundleSection.Position.X; secStruct.Y = bundleSection.Position.Y; secStruct.Z = bundleSection.Position.Z; secStruct.Type = bundleSection.Type; unchecked { secStruct.Unknown2 = (int)0xffffffff; } secStruct.Parameters = new uint[28]; secStruct.Parameters[(4 * 3 * (secStruct.Type - 1)) >> 2] = bundleSection.Size; secStruct.Parameters[((4 * 3 * (secStruct.Type - 1)) >> 2) + 1] = bundleSection.Size; secStruct.Parameters[((4 * 3 * (secStruct.Type - 1)) >> 2) + 2] = bundleSection.PermSize; //worldSection.Size = section.Parameters[(4 * 3 * (section.Type - 1)) >> 2]; //worldSection.PermSize = section.Parameters[((4 * 3 * (section.Type - 1)) >> 2) + 2]; //if (section.Type == 1) //{ // // if type 1, params[0..2] = size1, size2, size3 // worldSection.Size = section.Parameters[0]; // worldSection.OtherSize = section.Parameters[2]; // worldSection.ParamSize1 = section.Parameters[0]; // worldSection.ParamSize2 = section.Parameters[1]; // worldSection.ParamSize3 = section.Parameters[2]; //} //else //{ // worldSection.ParamTpkDataOff = section.Parameters[2]; // worldSection.ParamTpkNullOff = section.Parameters[0]; // worldSection.TextureContainerOffsets.Add(section.Parameters[3]); // worldSection.TextureContainerOffsets.Add(section.Parameters[6]); // worldSection.TextureContainerOffsets.Add(section.Parameters[9]); // //worldSection.TextureContainerOffsets.Add(section.Parameters[12]); // worldSection.ParamSize1 = worldSection.Size = section.Parameters[12]; //} cs.WriteStruct(secStruct); } cs.EndChunk(); } else { cs.WriteChunk(chunk); } } } }
public override void WriteLocationBundle(string outPath, LocationBundle bundle, List <StreamSection> sections) { // Write master stream var streamPath = Path.Combine( Path.GetDirectoryName(outPath), $"STREAM{bundle.Name}.BUN"); //File.Delete(streamPath); var offsetTable = new List <long>(); using (var mfs = File.Open(streamPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { for (var index = 0; index < sections.Count; index++) { var bundleSection = sections[index]; offsetTable.Add(mfs.Position); mfs.Write(bundleSection.Data, 0, bundleSection.Data.Length); if (mfs.Position % 0x800 != 0 && index != sections.Count - 1) { var align = 0x800 - mfs.Position % 0x800; align -= 8; mfs.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, 4); mfs.Write(BitConverter.GetBytes(align), 0, 4); mfs.Write(new byte[align], 0, (int)align); } } } //File.Delete(outPath); // Write location bundle using (var bw = new BinaryWriter(File.Open(outPath, FileMode.Create, FileAccess.Write, FileShare.Read))) using (var cs = new ChunkStream(bw)) { // We have to skip null chunks in order to avoid weirdness. foreach (var chunk in bundle.Chunks.Where(c => c.Id != 0)) { if (chunk.PrePadding > 8) // 0x10 - 8 = 8; greater than 8 = align 0x80 { cs.PaddingAlignment2(0x80); } else if (chunk.PrePadding > 0) { cs.PaddingAlignment2(0x10); } if (chunk.Id == 0x00034110) { // Write sections list cs.BeginChunk(0x00034110); for (var index = 0; index < sections.Count; index++) { var bundleSection = sections[index]; var sectionStruct = new MostWantedSection(); sectionStruct.ModelGroupName = bundleSection.Name; sectionStruct.Hash = bundleSection.Hash; sectionStruct.MasterStreamChunkOffset = (uint)offsetTable[index]; sectionStruct.MasterStreamChunkNumber = 1; sectionStruct.StreamChunkNumber = bundleSection.Number; sectionStruct.Size1 = sectionStruct.Size2 = bundleSection.Size; //sectionStruct.Unknown2 = bundleSection.UnknownSectionNumber; sectionStruct.Unknown2 = 0; sectionStruct.X = bundleSection.Position.X; sectionStruct.Y = bundleSection.Position.Y; sectionStruct.Z = bundleSection.Position.Z; cs.WriteStruct(sectionStruct); } cs.EndChunk(); } else { cs.WriteChunk(chunk); } } } }