private void OnRead(IAsyncResult base_ares)
        {
            ReadBufferState       rb   = (ReadBufferState)base_ares.AsyncState;
            HttpStreamAsyncResult ares = rb.Ares;

            try
            {
                int nread = base.EndRead(base_ares);
                decoder.Write(ares.Buffer, ares.Offset, nread);
                nread      = decoder.Read(rb.Buffer, rb.Offset, rb.Count);
                rb.Offset += nread;
                rb.Count  -= nread;
                if (rb.Count == 0 || !decoder.WantMore || nread == 0)
                {
                    no_more_data = !decoder.WantMore && nread == 0;
                    ares.Count   = rb.InitialCount - rb.Count;
                    ares.Complete();
                    return;
                }
                ares.Offset = 0;
                ares.Count  = Math.Min(8192, decoder.ChunkLeft + 6);
                base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
            }
            catch (Exception e)
            {
                context.Connection.SendError(e.Message, 400);
                ares.Complete(e);
            }
        }
Ejemplo n.º 2
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;
                    }
                }
            }
        }