public FileReversePart(PatchPart part) { this.Part = part; }
public void Build() { List <FileReversePart> preReverse = new List <FileReversePart>(); using (FileStream fs = new FileStream(patchFileName, FileMode.Open, FileAccess.Read)) { fs.Position = 18; InflateStream stream = new InflateStream(fs, true); WzPatcherReader reader = new WzPatcherReader(stream); PatchPart filePart; PatchPart reversePart; while ((filePart = reader.ReadPart()) != null) { switch (filePart.Type) { case PatchType.Create: if (filePart.FileLength > 0) { stream.Seek(filePart.FileLength, SeekOrigin.Current); //在原文件夹寻找同名文件 string oldFile = Path.Combine(msDir, filePart.FileName); if (File.Exists(oldFile)) { reversePart = new PatchPart() { Type = PatchType.Create }; reversePart.FileName = filePart.FileName; reversePart.FileLength = (int)new FileInfo(oldFile).Length; preReverse.Add(new FileReversePart(reversePart)); } else { reversePart = new PatchPart() { Type = PatchType.Delete }; reversePart.FileName = filePart.FileName; preReverse.Add(new FileReversePart(reversePart)); } } break; case PatchType.Rebuild: reversePart = new PatchPart() { Type = PatchType.Rebuild, OldChecksum = filePart.Checksum, Checksum = filePart.OldChecksum, FileName = filePart.FileName }; List <FileReverseInst> instList = new List <FileReverseInst>(); BuildInstruction inst; int filePos = 0; while ((inst = reader.ReadInst()).Type != null) { if (inst.Type == BuildType.Ending) { break; } switch (inst.Type) { case BuildType.FromPatcher: stream.Seek(inst.Length, SeekOrigin.Current); break; case BuildType.FillBytes: break; case BuildType.FromOldFile: instList.Add(new FileReverseInst() { Inst = inst, NewFilePosition = filePos }); break; } filePos += inst.Length; } preReverse.Add(new FileReversePart(reversePart) { InstList = instList }); break; case PatchType.Delete: { string oldFile = Path.Combine(msDir, filePart.FileName); if (File.Exists(oldFile)) { reversePart = new PatchPart() { Type = PatchType.Create }; reversePart.FileName = filePart.FileName; reversePart.FileLength = (int)new FileInfo(oldFile).Length; preReverse.Add(new FileReversePart(reversePart)); } } break; } } //end while } //end using preReverse.Sort(); using (FileStream dest = new FileStream(outputFileName, FileMode.Create)) { WzPatcherWriter writer = new WzPatcherWriter(dest); writer.Begin(); foreach (var part in preReverse) { string oldFileName = Path.Combine(msDir, part.Part.FileName); switch (part.Part.Type) { case PatchType.Create: //计算hash copy文件 using (FileStream oldFs = new FileStream(oldFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { part.Part.FileLength = (int)oldFs.Length; part.Part.Checksum = CheckSum.ComputeHash(oldFs, part.Part.FileLength); oldFs.Position = 0; writer.WritePart(part.Part); writer.WriteContent(oldFs, part.Part.FileLength); } break; case PatchType.Rebuild: writer.WritePart(part.Part); using (FileStream oldFs = new FileStream(oldFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { //计算指令 var instList = Work(part.InstList, (int)oldFs.Length); //开始执行 foreach (var inst in instList) { switch (inst.Inst.Type) { case BuildType.FromOldFile: //参数反转 inst.Inst.OldFilePosition = inst.NewFilePosition; writer.WriteInst(inst.Inst); break; case BuildType.FromPatcher: //go 待优化 writer.WriteInst(inst.Inst); oldFs.Position = inst.NewFilePosition; writer.WriteContent(oldFs, inst.Inst.Length); break; } } //结束执行 writer.WriteInst(new BuildInstruction(BuildType.Ending)); } break; case PatchType.Delete: writer.WritePart(part.Part); break; } } writer.End(); } }