private static void CreateDiffFiles(String ATmpDirectory, String ARootPatchDirectory, String AOldDirectory, String ANewDirectory, String ARecursiveSubDir) { string OldDirectory = AOldDirectory + '/' + ARecursiveSubDir; string NewDirectory = ANewDirectory + '/' + ARecursiveSubDir; string PatchDirectory = ARootPatchDirectory + '/' + ARecursiveSubDir; if (!Directory.Exists(PatchDirectory)) { Directory.CreateDirectory(PatchDirectory); } if (!Directory.Exists(OldDirectory)) { Directory.CreateDirectory(OldDirectory); } string[] directories = Directory.GetDirectories(NewDirectory); foreach (string dir in directories) { CreateDiffFiles(ATmpDirectory, ARootPatchDirectory, AOldDirectory, ANewDirectory, dir.Substring(ANewDirectory.Length + 1)); } // compare the files file by file TLogging.Log("enter directory " + OldDirectory, TLoggingType.ToConsole); string[] files = System.IO.Directory.GetFiles(OldDirectory); foreach (string filenameLoop in files) { bool OldPatchFileReused = false; string filename = Path.GetFileName(filenameLoop); if (System.IO.File.Exists(NewDirectory + '/' + filename)) { TPatchTools patch = new TPatchTools(); // compare if files are actually different if (!patch.IsSame(filenameLoop, NewDirectory + '/' + Path.GetFileName(filename))) { // create binary diff if (!Directory.Exists(PatchDirectory)) { Directory.CreateDirectory(PatchDirectory); } string OldPatchFile = ARootPatchDirectory + "bak" + PatchDirectory.Substring(ARootPatchDirectory.Length) + '/' + Path.GetFileName(filename) + ".patch"; if (System.IO.File.Exists(OldPatchFile)) { // could reuse, if checksum of the result is the same TPatchFileInfo OldPatchFileInfo; patch.ReadHeader(OldPatchFile, out OldPatchFileInfo); if (patch.CheckMd5Sum(NewDirectory + '/' + Path.GetFileName(filename), OldPatchFileInfo.NewMd5sum) && patch.CheckMd5Sum(filenameLoop, OldPatchFileInfo.OldMd5sum)) { // found a match, so no need for recreating the patch file; just copy it TLogging.Log("reusing diff " + OldPatchFile, TLoggingType.ToConsole); System.IO.File.Copy(OldPatchFile, PatchDirectory + '/' + Path.GetFileName(filename) + ".patch"); OldPatchFileReused = true; } } if (!OldPatchFileReused) { TLogging.Log("create diff " + PatchDirectory + '/' + Path.GetFileName(filename), TLoggingType.ToConsole); patch.CreateDiff(filenameLoop, NewDirectory + '/' + Path.GetFileName(filename), PatchDirectory + '/' + Path.GetFileName(filename) + ".patch"); } // if this is a file required for the patch program, include the new version if ((Path.GetFileName(filename) == "Ict.Common.dll") || (Path.GetFileName(filename) == "Ict.Common.IO.dll") || (Path.GetFileName(filename) == "ICSharpCode.SharpZipLib.dll") || (Path.GetFileName(filename).ToLower() == "Ict.Tools.PatchTool.exe".ToLower())) { // don't compress here: // the whole patch directory is zipped anyways in the end; // and it is easier to extract before running the patch System.IO.File.Copy(NewDirectory + '/' + Path.GetFileName(filename), PatchDirectory + '/' + Path.GetFileName( filename), true); } } } } // add new files (zip them) files = System.IO.Directory.GetFiles(NewDirectory); foreach (string filename in files) { if (!System.IO.File.Exists(OldDirectory + '/' + Path.GetFileName(filename))) { TLogging.Log("zip a new file " + NewDirectory + '/' + Path.GetFileName(filename), TLoggingType.ToConsole); if (!Directory.Exists(PatchDirectory)) { Directory.CreateDirectory(PatchDirectory); } try { BZip2.Compress(System.IO.File.OpenRead(NewDirectory + '/' + Path.GetFileName(filename)), System.IO.File.OpenWrite(PatchDirectory + '/' + Path.GetFileName(filename) + ".new"), true, 4096); } catch (Exception) { throw new Exception("Cannot write to file " + PatchDirectory + '/' + Path.GetFileName(filename) + ".new"); } } } // tell to remove files files = System.IO.Directory.GetFiles(OldDirectory); foreach (string filename in files) { if (!System.IO.File.Exists(NewDirectory + '/' + Path.GetFileName(filename))) { TLogging.Log("file removed: " + OldDirectory + '/' + Path.GetFileName(filename), TLoggingType.ToConsole); FileStream stream = System.IO.File.OpenWrite(PatchDirectory + '/' + Path.GetFileName(filename) + ".rem"); stream.Close(); } } // todo: something about changes to config files? xml file with instructions? // todo: check if all files can be matched when installing the patch }