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); } }
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; } } } }