/// <summary> /// 验证并初始化补丁解压流。 /// </summary> public void OpenDecompress() { this.patchBlock = TrySplit(this.patchFile); if (this.patchBlock == null) { throw new Exception("Decompress Error, cannot find patch block from the stream."); } BinaryReader r = new BinaryReader(patchBlock); patchBlock.Seek(8, SeekOrigin.Begin); int ver = r.ReadInt32(); uint checkSum0 = r.ReadUInt32(); uint checkSum1 = CheckSum.ComputeHash(patchBlock, (int)patchBlock.Length - 0x10); VerifyCheckSum(checkSum0, checkSum1, "PatchFile", "0"); patchBlock.Seek(16, SeekOrigin.Begin); byte lb = r.ReadByte(), hb = r.ReadByte(); if (!(lb == 0x78 && (lb * 0x100 + hb) % 31 == 0)) // zlib头标识 没有就把这两字节都当数据段好了.. { patchBlock.Seek(-2, SeekOrigin.Current); } this.inflateStream = new InflateStream(patchBlock); }
public async Task PartialStream_WithOffsetAndLength_Seek_WorksCorrectly() { // Arrange #if !NET461 && !NETCOREAPP2_1 await #endif using var originalStream = new MemoryStream(); await originalStream.FillWithRandomBytesAsync(1024); const int offset = 10; const int length = 100; #if !NET461 && !NETCOREAPP2_1 await #endif using var partialStream = new PartialStream(originalStream, offset, length); // Act const int additionalOffset = 40; partialStream.Seek(additionalOffset, SeekOrigin.Begin); // Assert #if !NET461 && !NETCOREAPP2_1 await #endif using var outputStream = new MemoryStream(); await partialStream.CopyToAsync(outputStream); var originalPortion = originalStream .ToArray() .Skip(offset + additionalOffset) .Take(length - additionalOffset) .ToArray(); outputStream.ToArray().Should().Equal(originalPortion); }
private PartialStream TrySplit(Stream metaStream) { metaStream.Seek(0, SeekOrigin.Begin); BinaryReader r = new BinaryReader(metaStream); PartialStream patchBlock; if (r.ReadUInt16() == 0x5a4d)//"MZ" { metaStream.Seek(-4, SeekOrigin.End); ulong check = r.ReadUInt32(); if (check == 0xf2f7fbf3) { metaStream.Seek(-12, SeekOrigin.End); int patchBlockLength = r.ReadInt32(); int noticeLength = r.ReadInt32(); metaStream.Seek(-12 - noticeLength - patchBlockLength, SeekOrigin.End); patchBlock = new PartialStream(metaStream, metaStream.Position, patchBlockLength); metaStream.Seek(patchBlockLength, SeekOrigin.Current); noticeText = Encoding.Default.GetString(r.ReadBytes(noticeLength)); } else //兼容TMS的patch.exe { metaStream.Seek(-8, SeekOrigin.End); check = r.ReadUInt64(); if (check == 0xf2f7fbf3) { metaStream.Seek(-24, SeekOrigin.End); long patchBlockLength = r.ReadInt64(); long noticeLength = r.ReadInt64(); metaStream.Seek(-24 - noticeLength - patchBlockLength, SeekOrigin.End); patchBlock = new PartialStream(metaStream, metaStream.Position, patchBlockLength); metaStream.Seek(patchBlockLength, SeekOrigin.Current); noticeText = Encoding.Default.GetString(r.ReadBytes((int)noticeLength)); } else { return(null); } } } else { patchBlock = new PartialStream(metaStream, 0, metaStream.Length); } if (patchBlock != null) { patchBlock.Seek(0, SeekOrigin.Begin); r = new BinaryReader(patchBlock); if (Encoding.ASCII.GetString(r.ReadBytes(8)) == "WzPatch\x1A") { patchBlock.Seek(0, SeekOrigin.Begin); } else { return(null); } } return(patchBlock); }