/// <summary> /// write descriptor as an asynchronous operation. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="writeDescriptorInModDirectory">if set to <c>true</c> [write descriptor in mod directory].</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public async Task <bool> WriteDescriptorAsync(ModWriterParameters parameters, bool writeDescriptorInModDirectory) { async Task <bool> writeDescriptors() { // If needed I've got a much more complex serializer, it is written for Kerbal Space Program but the structure seems to be the same though this is much more simpler var fullPath = Path.Combine(parameters.RootDirectory ?? string.Empty, parameters.Path ?? string.Empty); await writeDescriptor(fullPath); // Attempt to fix issues where the game decides to delete local zipped mod descriptors (I'm assuming this happens to all pdx games) if (parameters.LockDescriptor) { if (File.Exists(fullPath)) { _ = new System.IO.FileInfo(fullPath) { IsReadOnly = true }; } } if (writeDescriptorInModDirectory) { var modPath = Path.Combine(parameters.Mod.FileName, Shared.Constants.DescriptorFile); await writeDescriptor(modPath); } return(true); } async Task <bool> writeDescriptor(string fullPath) { bool?state = null; if (File.Exists(fullPath)) { var fileInfo = new System.IO.FileInfo(fullPath); state = fileInfo.IsReadOnly; fileInfo.IsReadOnly = false; } using var fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.Read); var result = await WriteDescriptorToStreamAsync(parameters, fs); if (state.HasValue) { var fileInfo = new System.IO.FileInfo(fullPath); fileInfo.IsReadOnly = state.GetValueOrDefault(); } return(result); } var retry = new RetryStrategy(); return(await retry.RetryActionAsync(writeDescriptors)); }
/// <summary> /// Exports the asynchronous. /// </summary> /// <param name="modHashes">The mod hashes.</param> /// <param name="path">The path.</param> /// <returns>Task<System.Boolean>.</returns> public Task <bool> ExportAsync(IEnumerable <IHashReport> modHashes, string path) { var retryStrategy = new RetryStrategy(); if (modHashes?.Count() > 0) { var json = JsonDISerializer.Serialize(modHashes); return(retryStrategy.RetryActionAsync(async() => { await File.WriteAllTextAsync(path, json); return true; })); } return(Task.FromResult(false)); }
/// <summary> /// Exports the files asynchronous. /// </summary> /// <param name="parameters">The parameters.</param> /// <returns>Task<System.Boolean>.</returns> /// <exception cref="ArgumentNullException">parameters - ExportPath.</exception> /// <exception cref="ArgumentNullException">parameters - ExportFile.</exception> /// <exception cref="ArgumentNullException">parameters - RootModPath</exception> public Task <bool> ExportFilesAsync(ModMergeFileExporterParameters parameters) { if (string.IsNullOrWhiteSpace(parameters.ExportPath)) { throw new ArgumentNullException(nameof(parameters), "ExportPath."); } if (string.IsNullOrWhiteSpace(parameters.ExportFile)) { throw new ArgumentNullException(nameof(parameters), "ExportFile."); } if (string.IsNullOrWhiteSpace(parameters.RootModPath)) { throw new ArgumentNullException(nameof(parameters), "RootModPath"); } var retry = new RetryStrategy(); return(retry.RetryActionAsync(() => CopyStreamAsync(parameters.RootModPath, parameters.ExportFile, parameters.ExportPath))); }
/// <summary> /// write descriptor as an asynchronous operation. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="writeDescriptorInModDirectory">if set to <c>true</c> [write descriptor in mod directory].</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public async Task <bool> WriteDescriptorAsync(ModWriterParameters parameters, bool writeDescriptorInModDirectory) { async Task <bool> writeDescriptors() { // If needed I've got a much more complex serializer, it is written for Kerbal Space Program but the structure seems to be the same though this is much more simpler var fullPath = Path.Combine(parameters.RootDirectory ?? string.Empty, parameters.Path ?? string.Empty); await writeDescriptor(fullPath); if (writeDescriptorInModDirectory) { var modPath = Path.Combine(parameters.Mod.FileName, Shared.Constants.DescriptorFile); await writeDescriptor(modPath); } return(true); } async Task <bool> writeDescriptor(string fullPath) { using var fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.Read); using var sw = new StreamWriter(fs); var props = parameters.Mod.GetType().GetProperties().Where(p => Attribute.IsDefined(p, typeof(DescriptorPropertyAttribute))); foreach (var prop in props) { var attr = Attribute.GetCustomAttribute(prop, typeof(DescriptorPropertyAttribute), true) as DescriptorPropertyAttribute; var val = prop.GetValue(parameters.Mod, null); if (val is IEnumerable <string> col) { if (col.Count() > 0) { await sw.WriteLineAsync($"{attr.PropertyName}={{"); foreach (var item in col) { await sw.WriteLineAsync($"\t\"{item}\""); } await sw.WriteLineAsync("}"); } } else { if (!string.IsNullOrWhiteSpace(val != null ? val.ToString() : string.Empty)) { if (attr.AlternateNameEndsWithCondition?.Count() > 0 && attr.AlternateNameEndsWithCondition.Any(p => val.ToString().EndsWith(p, StringComparison.OrdinalIgnoreCase))) { await sw.WriteLineAsync($"{attr.AlternatePropertyName}=\"{val}\""); } else { await sw.WriteLineAsync($"{attr.PropertyName}=\"{val}\""); } } } } await sw.FlushAsync(); return(true); } var retry = new RetryStrategy(); return(await retry.RetryActionAsync(writeDescriptors)); }