예제 #1
0
                void DiffChildren(RuntimeAttribute a, RuntimeAttribute b, PatchGroup group)
                {
                    var aChildren = a.Children;
                    var bChildren = b.Children;
                    var aLen      = aChildren.Count;
                    var bLen      = bChildren.Count;
                    var len       = aLen > bLen ? aLen : bLen;

                    var leftIter  = aChildren.GetEnumerator();
                    var rightIter = bChildren.GetEnumerator();

                    for (int i = 0; i < len; i++)
                    {
                        var leftNode  = leftIter.MoveNext() ? leftIter.Current : null;
                        var rightNode = rightIter.MoveNext() ? rightIter.Current : null;

                        if (leftNode == null)
                        {
                            if (rightNode != null)
                            {
                                // Excess nodes in b need to be added
                                group.Append(new PatchOperateInsert(a, rightNode));

                                //// execute once function
                                //group.Append(new PatchOperateOnceFunc(rightNode, rightNode.template.onceExpressList, rightNode.onceExecuteFunc));
                            }
                        }
                        else
                        {
                            Walk(leftNode, rightNode); // change it or remove it.
                        }
                    }
                }
예제 #2
0
                void Walk(RuntimeAttribute a, RuntimeAttribute b)
                {
                    if (a == b)
                    {
                        return;
                    }

                    var group = new PatchGroup();

                    if (a != null && a.IsThunk && b != null && b.IsThunk) // diff thunk
                    {
                        // TODO: ....
                        //var patchDiff = Diff(a, b);
                        //if (patchDiff.HasPatch)
                        //{
                        //    group.Append(new PatchOperateThunk(patchDiff));
                        //}
                    }
                    else if (b == null)
                    {
                        group.Append(new PatchOperateRemove(a));
                    }
                    else if (a.template.TagName == b.template.TagName && a.template.Key == b.template.Key)
                    {
                        //// diff once function
                        //var needToExecute = DiffOnceExpresstion(a.onceExecuteFunc, b.onceExecuteFunc);
                        //if (needToExecute != null)
                        //{
                        //    group.Append(new PatchOperateOnceFunc(a, needToExecute, b.onceExecuteFunc));
                        //}

                        // diff properties
                        var propsPatch = DiffProperties(a.attributes, b.attributes);
                        if (propsPatch != null && propsPatch.Count > 0)
                        {
                            group.Append(new PatchOperateProperties(a, propsPatch));
                        }
                        if (a.textDataBindExpressCurrentValue != b.textDataBindExpressCurrentValue)
                        {
                            group.Append(new PatchOperateText(a, b.textDataBindExpressCurrentValue));
                        }
                        DiffChildren(a, b, group);
                    }
                    else
                    {
                        group.Append(new PatchOperateChange(a, b));

                        //// change the a & b
                        //// execute once function
                        //group.Append(new PatchOperateOnceFunc(b, b.template.onceExpressList, b.onceExecuteFunc));
                    }

                    if (group.HasChange)
                    {
                        groupList.AddLast(group);
                    }
                }
예제 #3
0
파일: Patcher.cs 프로젝트: loudCDPman/HCE
        public static List <PatchGroup> Patches = Reader(); // See Write() for tmp overrides

        /// <summary>
        /// Reads PatchGroups from patches.crk to this instance.
        /// </summary>
        /// <returns>A list of PatchGroups read from the patches.crk file resource.</returns>
        /// <remarks>This is only used for Patches list initialization.</remarks>
        public static List <PatchGroup> Reader()
        {
            /* Get patches.crk resource from assembly resources */
            /* Read strings from memory to...array? */
            var nl         = new string[] { "\r\n" };
            var byteSep    = new string[] { ": ", " " };
            var list       = new List <PatchGroup>();
            var patchGroup = new PatchGroup();
            var file       = Properties.Resources.patches.Split(nl, StringSplitOptions.RemoveEmptyEntries).ToList();

            file.RemoveAt(0);

            /* Remove comments from list */
            {
                var file2 = new List <string>();
                foreach (var line in file)
                {
                    if (!line.StartsWith(";"))
                    {
                        file2.Add(line);
                    }
                }
                file = file2;
            }

            /* Add Name, exe, and patch data to list */
            for (var index = 0; index < file.Count; index++)
            {
                /// If the first char in the line is a letter...     */
                while (index < file.Count && char.IsLetter(file.ElementAt(index).ToCharArray().First()))
                {
                    /** ...skip Name and Executable. Go to patch data. */
                    index += 2;
                    /** Then, if the line is patch data...             */
                    /** ...assign patch name,                          */
                    /** ...assign filename,                            */
                    /** ...and then read patch data.                   */
                    while (index < file.Count && char.IsDigit(file.ElementAt(index).ToCharArray().First()))
                    {
                        patchGroup = new PatchGroup()
                        {
                            DataSets   = new List <DataSet>(),
                            Name       = file.ElementAt(index - 2),
                            Executable = file.ElementAt(index - 1)
                        };

                        while (index < file.Count && char.IsDigit(file.ElementAt(index).ToCharArray().First()))
                        {
                            /** Read Patch Data to List, ...
                             * Assign values{offset, original, patch}
                             * proceed to next Patch Data,
                             * then check if line is Patch Data
                             */
                            List <string> values = file.
                                                   ElementAt(index).Split(byteSep, StringSplitOptions.RemoveEmptyEntries).
                                                   ToList();
                            patchGroup.DataSets.Add(new DataSet {
                                Offset   = int.Parse(values[0], System.Globalization.NumberStyles.HexNumber),
                                Original = byte.Parse(values[1], System.Globalization.NumberStyles.HexNumber),
                                Patch    = byte.Parse(values[2], System.Globalization.NumberStyles.HexNumber)
                            });
                            index++;
                        }
                    }
                    list.Add(patchGroup);
                }
            }


            /* Parse the data to members "PatchGroup" of list "Patches" */

            /* return list */
            return(list);
        }
예제 #4
0
 /// <exception cref="T:PatchworkLauncher.PatchingProcessException">Cannot patch manifest during the patching process</exception>
 public static void TryPatchManifest(this AssemblyPatcher patcher, PatchInstruction patch, PatchGroup patchGroup, ProgressObject patchProgress)
 {
     try
     {
         patcher.PatchManifest(patch.Patch, patchProgress.ToMonitor());
     }
     catch (PatchException patchException)
     {
         throw new PatchingProcessException(patchException)
               {
                   AssociatedInstruction = patch,
                   AssociatedPatchGroup  = patchGroup,
                   Step = PatchProcessingStep.ApplyingSpecificPatch
               };
     }
 }
예제 #5
0
 /// <exception cref="T:PatchworkLauncher.PatchingProcessException">Cannot write to backup to <paramref name="targetFilePath"/> during the patching process</exception>
 public static void TryBackup(this AssemblyPatcher patcher, string targetFilePath, PatchGroup associatedPatchGroup)
 {
     try
     {
         patcher.WriteTo(targetFilePath);
     }
     catch (Exception exception)
     {
         throw new PatchingProcessException(exception)
               {
                   AssociatedInstruction = null,
                   AssociatedPatchGroup  = associatedPatchGroup,
                   Step = PatchProcessingStep.WritingToFile
               };
     }
 }