Exemple #1
0
 public static PatchInfo FromOldDiff(byte[] diffData, FileValidation oldChk)
 {
     return(new PatchInfo
     {
         Metadata = oldChk,
         Data = diffData
     });
 }
Exemple #2
0
        public bool PatchStream(Stream input, FileValidation targetChk, Stream output, out FileValidation outputChk)
        {
            unsafe
            {
                fixed(byte *pPatch = Data)
                Diff.Apply(input, pPatch, Data.LongLength, output);
            }

            output.Seek(0, SeekOrigin.Begin);
            outputChk = new FileValidation(output, targetChk.Type);

            return(targetChk == outputChk);
        }
Exemple #3
0
        /// <summary>
        /// Deserialize a PatchInfo
        /// </summary>
        /// <param name="reader">A reader aligned to a serialized PatchInfo</param>
        public PatchInfo(BinaryReader reader)
        {
            //reading a FV (metadata) now
            Metadata = FileValidation.ReadFrom(reader);

            //reading data now
            var dataSize = reader.ReadUInt32();

            Debug.Assert((int)dataSize == dataSize);
            if (dataSize > 0)
            {
                Data = reader.ReadBytes((int)dataSize);
            }
        }
Exemple #4
0
        private Patch ReadPatches(BinaryReader reader)
        {
            var target = FileValidation.ReadFrom(reader);

            var patchCount = reader.ReadInt32();
            var patches    = new PatchInfo[patchCount];

            for (int i = 0; i < patchCount; i++)
            {
                patches[i] = new PatchInfo(reader);
            }

            return(new Patch(target, patches));
        }
Exemple #5
0
        public void WriteTo(BinaryWriter writer)
        {
            FileValidation.WriteTo(writer, Metadata);

            if (Data != null)
            {
                writer.Write((uint)Data.LongLength);
                if (Data.Length > 0)
                {
                    writer.Write(Data);
                }
            }
            else
            {
                writer.Write(0U);
            }
        }
Exemple #6
0
        public bool PatchBytes(byte[] inputBytes, FileValidation targetChk, out byte[] outputBytes, out FileValidation outputChk)
        {
            using (var output = new MemoryStream())
            {
                unsafe
                {
                    fixed(byte *pInput = inputBytes)
                    fixed(byte *pPatch = Data)
                    Diff.Apply(pInput, inputBytes.LongLength, pPatch, Data.LongLength, output);
                }

                outputBytes = output.ToArray();

                output.Seek(0, SeekOrigin.Begin);
                outputChk = new FileValidation(outputBytes, targetChk.Type);

                return(targetChk == outputChk);
            }
        }
Exemple #7
0
        public static PatchDict FromOldDatabase(IDictionary <string, string> oldDict, string prefix, Func <byte[], byte[]> convertPatch)
        {
            Debug.Assert(oldDict != null);
            var patchDict = new PatchDict(oldDict.Count);

            foreach (var kvp in oldDict)
            {
                var file   = kvp.Key;
                var newMd5 = Util.FromMD5String(kvp.Value);

                Debug.Assert(Util.MakeMD5String(newMd5) == kvp.Value);

                var newChk = new FileValidation(newMd5, 0, FileValidation.ChecksumType.Md5);

                var patches = new List <PatchInfo>();

                var diffPath = Path.Combine(prefix, file + ".." + kvp.Value + ".diff");

                //diffPath doesn't exist, so this will include the "right" diff
                var diffs = Util.FindAlternateVersions(diffPath);
                if (diffs != null)
                {
                    foreach (var diff in diffs)
                    {
                        //var altDiffBytes = convertPatch(altDiff.Item1, Diff.SIG_LZDIFF41);
                        var diffBytes = convertPatch(File.ReadAllBytes(diff.Item1));
                        var diffChk   = new FileValidation(diff.Item2, 0, FileValidation.ChecksumType.Md5);

                        patches.Add(PatchInfo.FromOldDiff(diffBytes, diffChk));
                    }
                }

                patchDict.Add(file, new Patch(newChk, patches.ToArray()));
            }

            return(patchDict);
        }
Exemple #8
0
        private byte[] WritePatches(Patch patch)
        {
            using (var ms = new MemoryStream())
                using (var writer = new BinaryWriter(ms))
                {
                    FileValidation.WriteTo(writer, patch.Item1);

                    var patchInfos = patch.Item2;
                    if (patchInfos != null)
                    {
                        writer.Write(patchInfos.Length);
                        foreach (var patchInfo in patchInfos)
                        {
                            patchInfo.WriteTo(writer);
                        }
                    }
                    else
                    {
                        writer.Write(0);
                    }

                    return(ms.ToArray());
                }
        }
Exemple #9
0
        private void HandleFile(InstallStatus opChk, PatchJoin join)
        {
            try
            {
                var newFile = join.Item1;
                var oldFile = join.Item2;

                var filepath = newFile.Filename;
                var filename = newFile.Name;

                if (oldFile == null)
                {
                    Log.Dual("ERROR: File not found: " + filepath);
                    return;
                }

                var patchTuple = join.Item3;
                var newChk = patchTuple.Item1;
                var patches = patchTuple.Item2;

                if (filepath.StartsWith(Resources.VoicePrefix) && (patches == null || patches.Length == 0))
                {
                    opChk.CurrentOperation = "Skipping " + filename;
                    //Log.File("Skipping voice file: " + filepath);
                    return;
                }

                using (var curChk = FileValidation.FromBSAFile(oldFile, newChk.Type))
                    if (newChk == curChk)
                    {
                        opChk.CurrentOperation = "Compressing " + filename;
                        newFile.Cache();
                    }
                    else
                    {
                        //YOUR HANDY GUIDEBOOK FOR STRANGE CHECKSUM ACRONYMS!
                        //newChk - the checksum for the expected final result (after patching)
                        //oldChk - the checksum for the original file a diff is built against
                        //curChk - the checksum for the current file being compared or patched
                        //tstChk - the checksum for the current file, in the format of oldChk
                        //patChk - the checksum for the current file, after patching or failure
                        foreach (var patchInfo in patches)
                        {
                            var oldChk = patchInfo.Metadata;

                            if (curChk.Type != oldChk.Type)
                            {
                                using (var tstChk = FileValidation.FromBSAFile(oldFile, oldChk.Type))
                                    if (oldChk != tstChk)
                                        //this is a patch for a different original
                                        continue;
                            }
                            else if (oldChk != curChk)
                                //this is a patch for a different original
                                continue;

                            //patch is for this original
                            opChk.CurrentOperation = "Patching " + filename;

                            if (PatchBsaFile(newFile, patchInfo, newChk))
                                return;
                            else
                                Log.Dual("ERROR: Patching " + filepath + " failed");
                        }

                        using (var patChk = FileValidation.FromBSAFile(newFile, newChk.Type))
                            if (newChk != patChk)
                            {
                                //no patch exists for the file
                                Log.Dual("WARNING: File is of an unexpected version: " + newFile.Filename + " - " + patChk);
                                Log.Dual("This file cannot be patched. Errors may occur.");
                            }
                    }
            }
            finally
            {
                opChk.Step();
            }
        }