예제 #1
0
        /// <summary>
        ///     Patches the file segments in a stream.
        /// </summary>
        /// <param name="changes">The changes to make to the segments and their data.</param>
        /// <param name="stream">The stream to write changes to.</param>
        public static void PatchSegments(IEnumerable <SegmentChange> changes, IStream stream)
        {
            // Sort changes by their offsets
            var changesByOffset = new SortedList <uint, SegmentChange>();

            foreach (SegmentChange change in changes)
            {
                changesByOffset[change.OldOffset] = change;
            }

            // Now adjust each segment
            foreach (SegmentChange change in changesByOffset.Values)
            {
                // Resize it if necessary
                if (change.NewSize != change.OldSize)
                {
                    if (change.ResizeAtEnd)
                    {
                        stream.SeekTo(change.NewOffset + change.OldSize);
                    }
                    else
                    {
                        stream.SeekTo(change.NewOffset);
                    }

                    StreamUtil.Insert(stream, change.NewSize - change.OldSize, 0);
                }

                // Patch its data
                DataPatcher.PatchData(change.DataChanges, change.NewOffset, stream);
            }
        }
예제 #2
0
        /// <summary>
        ///     Applies a patch to a cache file.
        /// </summary>
        /// <param name="patch">The patch to apply.</param>
        /// <param name="cacheFile">The cache file to apply the patch to. After the patch is applied, it may have to be reloaded.</param>
        /// <param name="stream">The stream to write changes to.</param>
        public static void ApplyPatch(Patch patch, ICacheFile cacheFile, IStream stream)
        {
            if (patch.MapInternalName != cacheFile.InternalName)
            {
                throw new ArgumentException("The patch is for a different cache file. Expected \"" + patch.MapInternalName +
                                            "\" but got \"" + cacheFile.InternalName + "\".");
            }

            SegmentPatcher.PatchSegments(patch.SegmentChanges, stream);

            #region Deprecated

            DataPatcher.PatchData(patch.MetaChanges, (uint)-cacheFile.MetaArea.PointerMask, stream);
            if (patch.LanguageChanges.Count > 0)
            {
                LocalePatcher.WriteLanguageChanges(patch.LanguageChanges, cacheFile, stream);
                cacheFile.SaveChanges(stream);
            }

            #endregion
        }