PatchworkLauncher.LaunchManager.ApplyInstructions C# (CSharp) Méthode

ApplyInstructions() private méthode

private ApplyInstructions ( IEnumerable patchGroups, ProgressObject po ) : void
patchGroups IEnumerable
po Patchwork.Utility.ProgressObject
Résultat void
		private void ApplyInstructions(IEnumerable<PatchGroup> patchGroups, ProgressObject po) {
			//TODO: Use a different progress tracking system and make the entire patching operation more recoverable and fault-tolerant.
			//TODO: Refactor this method.
			patchGroups = patchGroups.ToList();
			var appInfo = AppInfo;
			var logger = Logger;
			var fileProgress = new ProgressObject();
			po.Child.Value = fileProgress;
			var patchProgress = new ProgressObject();
			fileProgress.Child.Value = patchProgress;
			var myAttributesAssembly = typeof (AppInfo).Assembly;
			var attributesAssemblyName = Path.GetFileName(myAttributesAssembly.Location);
			var history = new List<XmlFileHistory>();
			po.TaskTitle.Value = "Patching Game";
			po.TaskText.Value = appInfo.AppName;
			po.Total.Value = patchGroups.Count();

			foreach (var patchGroup in patchGroups) {
				var patchCount = patchGroup.Instructions.Count;
				po.TaskTitle.Value = $"Patching {appInfo.AppName}";
				var targetFile = patchGroup.TargetPath;
				po.TaskText.Value = Path.GetFileName(targetFile);
				//Note that Path.Combine(FILENAME, "..", OTHER_FILENAME) doesn't work on Mono but does work on .NET.
				var dir = Path.GetDirectoryName(targetFile);

				var localAssemblyName = Path.Combine(dir, attributesAssemblyName);
				var copy = true;
				fileProgress.TaskTitle.Value = "Patching File";
				fileProgress.Total.Value = 2 + patchCount;
				fileProgress.Current.Value++;

				var backupModified = PatchingHelper.GetBackupForModified(targetFile);
				var backupOrig = PatchingHelper.GetBackupForOriginal(targetFile);
				fileProgress.TaskText.Value = "Applying Patch";

				if (!PatchingHelper.DoesFileMatchPatchList(backupModified, targetFile, patchGroup.Instructions)
					|| Preferences.AlwaysPatch) {
					if (File.Exists(localAssemblyName)) {
						try {
							var localAssembly = AssemblyCache.Default.ReadAssembly(localAssemblyName);
							if (localAssembly.GetAssemblyMetadataString() == myAttributesAssembly.GetAssemblyMetadataString()) {
								copy = false;
							}
						}
						catch (Exception ex) {
							Logger.Warning(ex, $"Failed to read local attributes assembly so it will be overwritten.");
							//if reading the assembly failed for any reason, just ignore...
						}
					}
					if (copy) {
						File.Copy(myAttributesAssembly.Location, localAssemblyName, true);
					}

					var patcher = new AssemblyPatcher(targetFile, logger) {
						EmbedHistory = true
					};

					foreach (var patch in patchGroup.Instructions) {
						try {
							patcher.PatchManifest(patch.Patch, patchProgress.ToMonitor());
						}
						catch (PatchException ex) {
							throw new PatchingProcessException(ex) {
								AssociatedInstruction = patch,
								AssociatedPatchGroup = patchGroup,
								Step = PatchProcessingStep.ApplyingSpecificPatch
							};
						}
						fileProgress.Current.Value++;
					}
					patchProgress.TaskText.Value = "";
					patchProgress.TaskTitle.Value = "";


					fileProgress.Current.Value++;
					fileProgress.TaskText.Value = "Writing Assembly";
					if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
						fileProgress.TaskText.Value = "Running PEVerify...";
						var targetFolder = Path.GetDirectoryName(targetFile);
						try {
							var peOutput = patcher.RunPeVerify(new PEVerifyInput {
								AssemblyResolutionFolder = targetFolder,
								IgnoreErrors = AppInfo.IgnorePEVerifyErrors.ToList()
							});
							logger.Information(peOutput.Output);
						}
						catch (Exception ex) {
							logger.Error(ex, "Failed to run PEVerify on the assembly.");
						}
					}

					try {
						patcher.WriteTo(backupModified);
					}
					catch (Exception ex) {
						throw new PatchingProcessException(ex) {
							AssociatedInstruction = null,
							AssociatedPatchGroup = patchGroup,
							Step = PatchProcessingStep.WritingToFile
						};
					}
				} else {
					fileProgress.Current.Value += patchCount;
				}
				try {
					PatchingHelper.SwitchFilesSafely(backupModified, targetFile, backupOrig);
				}
				catch (Exception ex) {
					throw new PatchingProcessException(ex) {
						AssociatedInstruction = null,
						AssociatedPatchGroup = patchGroup,
						Step = PatchProcessingStep.PerformingSwitch
					};
				}
				AssemblyCache.Default.ClearCache();
				po.Current.Value++;
			}
		}
	}