/// <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));
        }
Esempio n. 2
0
        /// <summary>
        /// Exports the asynchronous.
        /// </summary>
        /// <param name="modHashes">The mod hashes.</param>
        /// <param name="path">The path.</param>
        /// <returns>Task&lt;System.Boolean&gt;.</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));
        }
Esempio n. 3
0
        /// <summary>
        /// Exports the files asynchronous.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>Task&lt;System.Boolean&gt;.</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)));
        }
Esempio n. 4
0
        /// <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));
        }