예제 #1
0
        /// <summary>
        ///     Store a <see cref="UpdateReport" /> in a <see cref="ZipFile" />.
        /// </summary>
        /// <param name="zip"><see cref="ZipFile" /> to write to.</param>
        /// <param name="report"><see cref="UpdateReport" /> to store.</param>
        private static void StoreReport(ZipFile zip, UpdateReport report)
        {
            var textTarget = string.Format(UpdateReportTextFile, report.PreviousVersion, report.UpdateVersion);

            zip.UpdateEntry(textTarget, string.Join(Environment.NewLine, report.Changes.Select(_ => _.ToString())),
                            ZipEncoding);

            var yamlTarget = string.Format(UpdateReportYamlFile, report.PreviousVersion, report.UpdateVersion);
            var serializer = new Serializer();

            byte[] yamlBuffer;
            using (var ms = new MemoryStream()) {
                using (TextWriter writer = new StreamWriter(ms, ZipEncoding)) {
                    serializer.Serialize(writer, report);
                    writer.Flush();
                    yamlBuffer = ms.ToArray();
                }
            }
            zip.UpdateEntry(yamlTarget, yamlBuffer);

            var binTarget = string.Format(UpdateReportBinFile, report.PreviousVersion, report.UpdateVersion);
            var formatter = new BinaryFormatter();

            byte[] binBuffer;

            using (var ms = new MemoryStream()) {
                formatter.Serialize(ms, report);
                binBuffer = ms.ToArray();
            }

            zip.UpdateEntry(binTarget, binBuffer);
        }
예제 #2
0
        /// <summary>
        ///     Update to the current version.
        /// </summary>
        /// <param name="detectDataChanges">Boolean indicating whether the update should also look for changes in data.</param>
        /// <param name="progress">Optional object to which update progress is reported.</param>
        /// <returns>Returns the <see cref="UpdateReport" /> containing all changes.</returns>
        /// <exception cref="InvalidOperationException">Definition is up-to-date.</exception>
        public UpdateReport Update(bool detectDataChanges, IProgress <UpdateProgress> progress = null)
        {
            if (DefinitionVersion == GameVersion)
            {
                throw new InvalidOperationException();
            }

            var previousVersion = DefinitionVersion;

            var exdPackId          = new PackIdentifier("exd", PackIdentifier.DefaultExpansion, 0);
            var exdPack            = Packs.GetPack(exdPackId);
            var exdOldKeepInMemory = exdPack.KeepInMemory;

            exdPack.KeepInMemory = true;

            string       tempPath = null;
            UpdateReport report;

            try {
                using (var zip = new ZipFile(StateFile.FullName, ZipEncoding)) {
                    tempPath = ExtractPacks(zip, previousVersion);
                    var previousPack = new PackCollection(Path.Combine(tempPath, previousVersion));
                    previousPack.GetPack(exdPackId).KeepInMemory = true;
                    var previousDefinition = ReadDefinition(zip);

                    var updater = new RelationUpdater(previousPack, previousDefinition, Packs, GameVersion, progress);

                    var changes = updater.Update(detectDataChanges);
                    report = new UpdateReport(previousVersion, GameVersion, changes);

                    var definition = updater.Updated;

                    StorePacks(zip);
                    StoreDefinition(zip, definition, DefinitionFile);
                    StoreDefinition(zip, definition, string.Format("{0}/{1}", definition.Version, DefinitionFile));
                    StoreReport(zip, report);
                    zip.Save();

                    GameData.Definition = definition;
                    GameData.Definition.Compile();
                }
            } finally {
                if (exdPack != null)
                {
                    exdPack.KeepInMemory = exdOldKeepInMemory;
                }
                if (tempPath != null)
                {
                    try {
                        Directory.Delete(tempPath, true);
                    } catch {
                        Console.Error.WriteLine("Failed to delete temporary directory {0}.", tempPath);
                    }
                }
            }
            return(report);
        }
예제 #3
0
        /// <summary>
        ///     Store a <see cref="UpdateReport" /> in a <see cref="ZipFile" />.
        /// </summary>
        /// <param name="zip"><see cref="ZipFile" /> to write to.</param>
        /// <param name="report"><see cref="UpdateReport" /> to store.</param>
        private static void StoreReport(ZipFile zip, UpdateReport report)
        {
            var textTarget = string.Format(UpdateReportTextFile, report.PreviousVersion, report.UpdateVersion);

            zip.UpdateEntry(textTarget, string.Join(Environment.NewLine, report.Changes.Select(_ => _.ToString())),
                            ZipEncoding);

            var jsonTarget = string.Format(UpdateReportJsonFile, report.PreviousVersion, report.UpdateVersion);
            var obj        = report.ToJson();
            var json       = JsonConvert.SerializeObject(obj, Formatting.Indented);

            zip.UpdateEntry(jsonTarget, json);
        }
예제 #4
0
        /// <summary>
        ///     Update to the current version.
        /// </summary>
        /// <param name="detectDataChanges">Boolean indicating whether the update should also look for changes in data.</param>
        /// <param name="progress">Optional object to which update progress is reported.</param>
        /// <returns>Returns the <see cref="UpdateReport" /> containing all changes.</returns>
        /// <exception cref="InvalidOperationException">Definition is up-to-date.</exception>
        public UpdateReport Update(bool detectDataChanges, IProgress <UpdateProgress> progress = null)
        {
            if (DefinitionVersion == GameVersion)
            {
                throw new InvalidOperationException();
            }

            var previousVersion = DefinitionVersion;

            var exdPackId          = new PackIdentifier("exd", PackIdentifier.DefaultExpansion, 0);
            var exdPack            = Packs.GetPack(exdPackId);
            var exdOldKeepInMemory = exdPack.KeepInMemory;

            exdPack.KeepInMemory = true;

            string       tempPath = null;
            UpdateReport report;

            try {
                using (var zip = new ZipFile(StateFile.FullName, ZipEncoding)) {
                    tempPath = ExtractPacks(zip, previousVersion);
                    var previousPack = new PackCollection(Path.Combine(tempPath, previousVersion));
                    previousPack.GetPack(exdPackId).KeepInMemory = true;

                    RelationDefinition previousDefinition;
                    if (previousVersion == _GameData.Definition.Version)
                    {
                        // Override previous definition when current definition version matches.
                        // Definitions may have changed since this was recorded and we want to compare that.
                        previousDefinition = _GameData.Definition;
                    }
                    else
                    {
                        // Otherwise, read the previous definition from the zip.
                        previousDefinition = ReadDefinition(zip, previousVersion);
                    }

                    var updater = new RelationUpdater(previousPack, previousDefinition, Packs, GameVersion, progress);

                    var changes = updater.Update(detectDataChanges);
                    report = new UpdateReport(previousVersion, GameVersion, changes);

                    var definition = updater.Updated;

                    StorePacks(zip);
                    StoreDefinitionInZip(zip, definition);
                    StoreDefinitionOnFilesystem(definition, "");

                    if (Debugger.IsAttached)
                    {
                        // Little QOL path - when updating with the debugger attached,
                        // also write to the project definitions path so no need to copy
                        // them manually afterward.
                        var projectDefinitionsPath = "../../../SaintCoinach";
                        if (Directory.Exists(projectDefinitionsPath))
                        {
                            StoreDefinitionOnFilesystem(definition, projectDefinitionsPath);
                        }
                    }

                    StoreReport(zip, report);
                    UpdateVersion(zip);
                    zip.Save();

                    GameData.Definition = definition;
                    GameData.Definition.Compile();
                }
            } finally {
                if (exdPack != null)
                {
                    exdPack.KeepInMemory = exdOldKeepInMemory;
                }
                if (tempPath != null)
                {
                    try {
                        Directory.Delete(tempPath, true);
                    } catch {
                        Console.Error.WriteLine("Failed to delete temporary directory {0}.", tempPath);
                    }
                }
            }
            return(report);
        }