示例#1
0
        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);
                        }
                    }
                }
        }
示例#2
0
        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);
                        }
                    }
                }
        }
示例#3
0
        public override void WriteLocationBundle(string outPath, LocationBundle bundle, List <StreamSection> sections)
        {
            var chunkManager = new ChunkManager(GameDetector.Game.Undercover);

            chunkManager.Read(bundle.File);

            var masterStreamPath = Path.Combine(Path.GetDirectoryName(outPath), $"STREAM{bundle.Name}.BUN");
            var sectionInfoMap   = new Dictionary <uint, StreamChunkInfo>();
            var sectionDataMap   = new Dictionary <uint, byte[]>();

            using (var fs = new FileStream(masterStreamPath, FileMode.Open))
                using (var br = new BinaryReader(fs))
                {
                    foreach (var section in bundle.Sections)
                    {
                        sectionDataMap[section.Number] = new byte[0];

                        //var sectionPath = Path.Combine(sectionsPath, $"STREAM{bundle.Name}_{section.Number}.BUN");

                        //if (File.Exists(sectionPath))
                        //{
                        //    sectionDataMap[section.Number] = File.ReadAllBytes(sectionPath);
                        //}
                        //else
                        //{
                        //    br.BaseStream.Position = section.Offset;

                        //    sectionDataMap[section.Number] = new byte[section.Size];
                        //    br.Read(sectionDataMap[section.Number], 0, (int)section.Size);
                        //}
                    }
                }

            using (var fs = new FileStream(masterStreamPath, FileMode.Create))
                using (var bw = new BinaryWriter(fs))
                {
                    for (var index = 0; index < bundle.Sections.Count; index++)
                    {
                        var section = bundle.Sections[index];

                        sectionInfoMap[section.Number] = new StreamChunkInfo
                        {
                            Offset = bw.BaseStream.Position,
                            Size   = (uint)sectionDataMap[section.Number].Length
                        };

                        bw.Write(sectionDataMap[section.Number]);

                        if (index != bundle.Sections.Count - 1)
                        {
                            // calculate and write alignment chunk, align by 0x800 bytes
                            var alignSize = sectionDataMap[section.Number].Length + 8 -
                                            (sectionDataMap[section.Number].Length + 8) % 0x800 + 0x1000;
                            alignSize -= sectionDataMap[section.Number].Length + 8;

                            bw.Write(0x00000000);
                            bw.Write(alignSize);
                            bw.BaseStream.Position += alignSize;
                        }
                    }
                }

            using (var fs = new FileStream(outPath, FileMode.Create))
            {
                using (var chunkStream = new ChunkStream(new BinaryWriter(fs)))
                {
                    Chunk previousChunk = null;

                    foreach (var chunk in chunkManager.Chunks.Where(c => c.Id != 0))
                    {
                        if (previousChunk != null && previousChunk.Size > 0)
                        {
                            chunkStream.PaddingAlignment(0x10);
                        }

                        chunkStream.BeginChunk(chunk.Id);

                        if (chunk.Id == 0x00034110)
                        {
                            // write sections
                            foreach (var bundleSection in bundle.Sections)
                            {
                                var sectionStruct = new UndercoverSection
                                {
                                    Hash                    = bundleSection.Hash,
                                    ModelGroupName          = bundleSection.Name,
                                    MasterStreamChunkNumber = 0,
                                    StreamChunkNumber       = bundleSection.Number,
                                    Size1                   = sectionInfoMap[bundleSection.Number].Size,
                                    Size2                   = sectionInfoMap[bundleSection.Number].Size,
                                    Size3                   = sectionInfoMap[bundleSection.Number].Size,
                                    X = bundleSection.Position.X,
                                    Y = bundleSection.Position.Y,
                                    Z = bundleSection.Position.Z,
                                    MasterStreamChunkOffset = (uint)sectionInfoMap[bundleSection.Number].Offset
                                };

                                chunkStream.WriteStruct(sectionStruct);
                            }
                        }
                        else
                        {
                            chunkStream.Write(chunk.Data);
                        }

                        chunkStream.EndChunk();

                        previousChunk = chunk;
                    }
                }
            }
        }