private void CreatePatchInternal() { Source.Position = 0; Target.Position = 0; ulong sourceSize = (ulong)Source.Length; ulong targetSize = (ulong)Target.Length; var sourceChecksum = ChecksumUtils.CalculateCRC32ForEntireStream(Source); var targetChecksum = ChecksumUtils.CalculateCRC32ForEntireStream(Target); // header PatchOut.WriteUInt32(0x31535042, EndianUtils.Endianness.LittleEndian); PatchOut.WriteUnsignedNumber(sourceSize); PatchOut.WriteUnsignedNumber(targetSize); PatchOut.WriteUnsignedNumber(0); // metadata // actions while (Target.Position < Target.Length) { int s; int t; bool advancedS; bool advancedT; if (IsNextByteSameInSourceAndTarget(out s, out t, out advancedS, out advancedT)) { ulong count = 1; while (IsNextByteSameInSourceAndTarget(out s, out t, out advancedS, out advancedT)) { ++count; } if (advancedS) { Source.Position -= 1; } if (advancedT) { Target.Position -= 1; } PatchOut.WriteAction(HyoutaUtils.Bps.Action.SourceRead, count); } else { if (advancedS) { Source.Position -= 1; } if (advancedT) { Target.Position -= 1; } long p = Target.Position; ulong count = 0; while (ShouldWriteNextByteFromTarget(out s, out t, out advancedS, out advancedT)) { ++count; } if (advancedS) { Source.Position -= 1; } PatchOut.WriteAction(HyoutaUtils.Bps.Action.TargetRead, count); Target.Position = p; StreamUtils.CopyStream(Target, PatchOut, (long)count); } } PatchOut.WriteUInt32(sourceChecksum.Value, EndianUtils.Endianness.LittleEndian); PatchOut.WriteUInt32(targetChecksum.Value, EndianUtils.Endianness.LittleEndian); long checksumsize = PatchOut.Position; PatchOut.Position = 0; var patchChecksum = ChecksumUtils.CalculateCRC32FromCurrentPosition(PatchOut, checksumsize); PatchOut.WriteUInt32(patchChecksum.Value, EndianUtils.Endianness.LittleEndian); }