예제 #1
0
        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
        }