コード例 #1
0
        private static PatchResult ExecuteModsInternal(string gamedir, FileStorage storage, List <FileMod> mods, ProgressReporter progress, bool revert)
        {
            int total   = mods.Count;
            int success = 0;

            for (int i = 0; i < mods.Count; i++)
            {
                FileMod mod = mods[i];
                progress.Message(string.Format("{0}: {1}...", revert ? "Restoring" : "Patching", mod.GetDescription()), i, total);

                var results = mod.TryApply(storage);
                if (results == null)
                {
                    progress.Error(string.Format("Failed to generate data: {0}", mod.GetDescription()));
                    continue;
                }

                bool diskWriteSuccess = true;
                foreach (FileModResult result in results)
                {
                    string path = Path.Combine(gamedir, result.TargetPath);
                    if (result.ResultData != null)
                    {
                        if (!SenUtils.TryWriteFileIfDifferent(result.ResultData, path))
                        {
                            progress.Error(string.Format("Failed to write to disk: {0}", path));
                            diskWriteSuccess = false;
                        }
                    }
                    else
                    {
                        if (!SenUtils.TryDeleteFile(path))
                        {
                            progress.Error(string.Format("Failed to delete from disk: {0}", path));
                            diskWriteSuccess = false;
                        }
                    }
                }

                if (diskWriteSuccess)
                {
                    ++success;
                }
            }

            progress.Message(string.Format("Finished {0}.", revert ? "restoring files" : "applying patches"), total, total);
            return(new PatchResult(total, success));
        }
        private void ProcessSync(ProgressReporter progress)
        {
            foreach (var configuration in ResolveConfigurations())
            {
                using (new LoggingContext(progress, configuration))
                {
                    try
                    {
                        progress.ReportSimple("Control Panel Sync: Processing Unicorn configuration " +
                                              configuration.Name, MessageLevel.Info);

                        var pathResolver       = configuration.Resolve <PredicateRootPathResolver>();
                        var retryer            = configuration.Resolve <IDeserializeFailureRetryer>();
                        var consistencyChecker = configuration.Resolve <IConsistencyChecker>();
                        var loader             = configuration.Resolve <SerializationLoader>();
                        var roots = pathResolver.GetRootSerializedItems();
                        int index = 1;
                        loader.LoadAll(roots, retryer, consistencyChecker, item =>
                        {
                            progress.ReportProgress((int)((index / (double)roots.Length) * 100));
                            index++;
                        });
                        progress.ReportSimple("Control Panel Sync: Completed syncing Unicorn configuration " +
                                              configuration.Name, MessageLevel.Info);
                    }
                    catch (Exception ex)
                    {
                        progress.Error(ex);
                        break;
                    }
                }
            }
        }
コード例 #3
0
        public static FileStorage.InitReturnValue InitializeAndPersistFileStorage(string baseDir, KnownFile[] knownFiles, ProgressReporter progress)
        {
            if (!Directory.Exists(baseDir))
            {
                progress.Error(string.Format("No directory found at {0}.", baseDir));
                return(null);
            }

            string backupArchivePath = Path.Combine(baseDir, "senpatcher_rerun_revert_data.bin");

            FileStorage.InitReturnValue fileStoreReturnValue = null;
            using (HyoutaUtils.HyoutaArchive.HyoutaArchiveContainer backupArchive = TryLoadBackupArchive(backupArchivePath, progress)) {
                progress.Message("Reading and identifying game files...");
                fileStoreReturnValue = FileStorage.InitializeFromKnownFiles(baseDir, knownFiles, backupArchive);
            }

            foreach (var perFileErrors in fileStoreReturnValue.Errors)
            {
                foreach (var errorMessage in perFileErrors.errors)
                {
                    progress.Error(errorMessage);
                    break;                     // only show first error to the user, this is really confusing otherwise
                }
            }

            if (fileStoreReturnValue.ShouldWriteBackupArchive)
            {
                progress.Message(string.Format("Writing backup archive to {0}...", backupArchivePath));
                Stream ms = new MemoryStream();
                fileStoreReturnValue.Storage.WriteToHyoutaArchive(ms);
                using (var fs = new FileStream(backupArchivePath, FileMode.Create)) {
                    ms.Position = 0;
                    HyoutaUtils.StreamUtils.CopyStream(ms, fs);
                }
            }

            return(fileStoreReturnValue);
        }
コード例 #4
0
 private static HyoutaUtils.HyoutaArchive.HyoutaArchiveContainer TryLoadBackupArchive(string backupArchivePath, ProgressReporter progress)
 {
     try {
         if (File.Exists(backupArchivePath))
         {
             progress.Message(string.Format("Loading backup archive at {0}...", backupArchivePath));
             using (var fs = new HyoutaUtils.Streams.DuplicatableFileStream(backupArchivePath)) {
                 return(new HyoutaUtils.HyoutaArchive.HyoutaArchiveContainer(fs));
             }
         }
     } catch (Exception ex) {
         progress.Error(string.Format("Failed to load backup file archive: {0}", ex.Message));
     }
     return(null);
 }
コード例 #5
0
        public void Run()
        {
            if (Progress == null)
            {
                Progress = new DummyProgressReporter();
            }

            try {
                Result = FileModExec.ExecuteMods(Path, Storage, Mods, Progress);
            } catch (Exception ex) {
                Progress.Error("Error while patching game files: " + ex.Message);
                Progress.Finish(false);
                return;
            }

            Progress.Message("Successfully patched game files.");
            Progress.Finish(true);
        }
コード例 #6
0
            public void Cs1GameInit()
            {
                int  CurrentProgress       = 0;
                int  TotalProgress         = 4;
                bool shouldAutoCloseWindow = true;

                try {
                    Progress.Message("Checking Sen1Launcher.exe...", CurrentProgress++, TotalProgress);
                    using (var fs = new HyoutaUtils.Streams.DuplicatableFileStream(Sen1LauncherPath)) {
                        SHA1 hash = ChecksumUtils.CalculateSHA1ForEntireStream(fs);
                        if (hash != new SHA1(0x8dde2b39f128179aul, 0x0beb3301cfd56a98ul, 0xc0f98a55u))
                        {
                            Progress.Error("Selected file does not appear to be Sen1Launcher.exe of version 1.6.");
                            Progress.Finish(false);
                            return;
                        }
                    }
                } catch (Exception ex) {
                    Progress.Error("Error while validating Sen1Launcher.exe: " + ex.Message);
                    Progress.Finish(false);
                    return;
                }

                try {
                    Path = System.IO.Path.GetDirectoryName(Sen1LauncherPath);
                    Progress.Message("Checking if we have encoding errors in filenames...", CurrentProgress++, TotalProgress);
                    if (FilenameFix.FixupIncorrectEncodingInFilenames(Path, 1, false, Progress))
                    {
                        if (!FilenameFix.FixupIncorrectEncodingInFilenames(Path, 1, true, Progress))
                        {
                            Progress.Error("Failed to fix encoding errors in filenames, attempting to proceed anyway...");
                            shouldAutoCloseWindow = false;
                        }
                    }
                    Progress.Message("Initializing patch data...", CurrentProgress++, TotalProgress);
                    var files = Sen1KnownFiles.Files;
                    Progress.Message("Initializing game data...", CurrentProgress++, TotalProgress);
                    var storageInit = FileModExec.InitializeAndPersistFileStorage(Path, files, Progress);
                    Storage = storageInit?.Storage;
                    if (storageInit == null || storageInit.Errors.Count != 0)
                    {
                        shouldAutoCloseWindow = false;
                    }
                } catch (Exception ex) {
                    Progress.Error("Error while initializing CS1 patch/game data: " + ex.Message);
                    Progress.Finish(false);
                    return;
                }

                ShouldProceedToPatchOptionWindow = Path != null && Storage != null;
                if (shouldAutoCloseWindow)
                {
                    Progress.Message("Initialized CS1 data, proceeding to patch options...", CurrentProgress, TotalProgress);
                }
                else
                {
                    Progress.Message("", CurrentProgress, TotalProgress);
                    if (ShouldProceedToPatchOptionWindow)
                    {
                        Progress.Error(
                            "Encountered problems while initializing CS1 data. "
                            + "Closing this window will proceed to the patch options anyway, but be aware that some patches may not work correctly. "
                            + "It is recommended to verify the game files using Steam or GOG Galaxy's build-in feature to do so, or to reinstall the game. "
                            + "Please also ensure you're trying to patch a compatible version of the game. (XSEED release version 1.6; other game versions are not compatible)"
                            );
                    }
                    else
                    {
                        Progress.Error(
                            "Unrecoverable issues while initializing CS1 data. "
                            + "Please ensure SenPatcher has read and write access to the selected game directory, then try again."
                            );
                    }
                }
                Progress.Finish(shouldAutoCloseWindow);
            }