예제 #1
0
        /// <summary>
        /// Gets the definitions asynchronous.
        /// </summary>
        /// <param name="storagePath">The storage path.</param>
        /// <param name="game">The game.</param>
        /// <param name="path">The path.</param>
        /// <returns>Task&lt;IEnumerable&lt;IDefinition&gt;&gt;.</returns>
        public virtual async Task <IEnumerable <IDefinition> > GetDefinitionsAsync(string storagePath, IGame game, string path)
        {
            storagePath = ResolveStoragePath(storagePath);
            path        = SanitizePath(path);
            var fullPath = Path.Combine(storagePath, game.Type, path);

            if (File.Exists(fullPath))
            {
                var bytes = await File.ReadAllBytesAsync(fullPath);

                if (bytes.Any())
                {
                    using var source      = new MemoryStream(bytes);
                    using var destination = new MemoryStream();
                    using var compress    = new DeflateStream(source, CompressionMode.Decompress);
                    await compress.CopyToAsync(destination);

                    var text = Encoding.UTF8.GetString(destination.ToArray());
                    if (!string.IsNullOrWhiteSpace(text))
                    {
                        var result = JsonDISerializer.Deserialize <List <IDefinition> >(text);
                        return(result);
                    }
                }
            }
            return(null);
        }
예제 #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));
        }
예제 #3
0
        /// <summary>
        /// import as an asynchronous operation.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>Task&lt;IEnumerable&lt;IModHashFileReport&gt;&gt;.</returns>
        public async Task <IEnumerable <IHashReport> > ImportAsync(string path)
        {
            if (File.Exists(path))
            {
                var json = await File.ReadAllTextAsync(path);

                if (!string.IsNullOrWhiteSpace(json))
                {
                    try
                    {
                        var result = JsonDISerializer.Deserialize <IEnumerable <IHashReport> >(json);
                        return(result);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex);
                    }
                }
            }
            return(null);
        }
        /// <summary>
        /// Export as an asynchronous operation.
        /// </summary>
        /// <param name="params">The parameters.</param>
        /// <returns>A Task&lt;System.Boolean&gt; representing the asynchronous operation.</returns>
        public async Task <bool> ExportAsync(ModCollectionExporterParams @params)
        {
            // Paradox launcher only exports pdx or steam mods, local mods are not exported
            var validMods = @params.ExportMods.Where(p => p.Source != ModSource.Local).ToList();
            var modInfo   = new ModInfo()
            {
                Game = @params.Game.ParadoxGameId,
                Name = @params.Mod.Name,
                Mods = validMods.Select(p => new Models.Paradox.Json.v3.Mods()
                {
                    DisplayName = p.Name,
                    Enabled     = true,
                    Position    = validMods.IndexOf(p),
                    SteamId     = p.Source == ModSource.Steam ? p.RemoteId.ToString() : null,
                    PdxId       = p.Source == ModSource.Paradox ? p.RemoteId.ToString() : null
                }).ToList()
            };
            var json = JsonDISerializer.Serialize(modInfo);
            await File.WriteAllTextAsync(@params.File, json);

            return(true);
        }
예제 #5
0
        /// <summary>
        /// Saves the definitions asynchronous.
        /// </summary>
        /// <param name="storagePath">The storage path.</param>
        /// <param name="game">The game.</param>
        /// <param name="definitions">The definitions.</param>
        /// <returns>Task&lt;System.Boolean&gt;.</returns>
        /// <exception cref="ArgumentException">Definitions types differ.</exception>
        public virtual async Task <bool> SaveDefinitionsAsync(string storagePath, IGame game, IEnumerable <IDefinition> definitions)
        {
            storagePath = ResolveStoragePath(storagePath);
            if (definitions.GroupBy(p => p.ParentDirectory).Count() > 1)
            {
                throw new ArgumentException("Definitions types differ.");
            }
            if (definitions == null || !definitions.Any())
            {
                return(false);
            }
            var path     = SanitizePath(definitions.FirstOrDefault().ParentDirectory);
            var fullPath = Path.Combine(storagePath, game.Type, path);

            if (File.Exists(fullPath))
            {
                DiskOperations.DeleteFile(fullPath);
            }
            var json  = JsonDISerializer.Serialize(definitions.ToList());
            var bytes = Encoding.UTF8.GetBytes(json);

            using var source      = new MemoryStream(bytes);
            using var destination = new MemoryStream();
            using var compress    = new DeflateStream(destination, CompressionLevel.Fastest, true);
            await source.CopyToAsync(compress);

            await compress.FlushAsync();

            if (!Directory.Exists(Path.GetDirectoryName(fullPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
            }
            await File.WriteAllBytesAsync(fullPath, destination.ToArray());

            return(true);
        }
예제 #6
0
        /// <summary>
        /// json import as an asynchronous operation.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        /// <exception cref="System.AggregateException"></exception>
        public virtual async Task <ICollectionImportResult> JsonImportAsync(ModCollectionExporterParams parameters)
        {
            async Task <(Exception, ICollectionImportResult)> parseV2()
            {
                var content = await File.ReadAllTextAsync(parameters.File);

                if (!string.IsNullOrWhiteSpace(content))
                {
                    Models.Paradox.Json.v2.ModInfo model = null;
                    try
                    {
                        model = JsonDISerializer.Deserialize <Models.Paradox.Json.v2.ModInfo>(content);
                    }
                    catch (Exception ex)
                    {
                        return(ex, null);
                    }
                    if (!string.IsNullOrWhiteSpace(model.Game) && !string.IsNullOrWhiteSpace(model.Name))
                    {
                        // Validate whether this really is v2 (execting length larger than 4 as a dumb best guess)
                        if (model.Mods.Any(p => p.Position.Length >= 4))
                        {
                            var result = DIResolver.Get <ICollectionImportResult>();
                            result.Name = model.Name;
                            // Will need to lookup the game and mod ids in the mod service
                            result.Game = model.Game;
                            var mods = model.Mods.Where(p => p.Enabled).OrderBy(p => p.Position);
                            result.ModIds = mods.Select(p => !string.IsNullOrWhiteSpace(p.PdxId) ? p.PdxId : p.SteamId).ToList();
                            return(null, result);
                        }
                    }
                }
                return(null, null);
            }

            async Task <(Exception, ICollectionImportResult)> parseV3()
            {
                var content = await File.ReadAllTextAsync(parameters.File);

                if (!string.IsNullOrWhiteSpace(content))
                {
                    Models.Paradox.Json.v3.ModInfo model = null;
                    try
                    {
                        model = JsonDISerializer.Deserialize <Models.Paradox.Json.v3.ModInfo>(content);
                    }
                    catch (Exception ex)
                    {
                        return(ex, null);
                    }
                    if (!string.IsNullOrWhiteSpace(model.Game) && !string.IsNullOrWhiteSpace(model.Name))
                    {
                        var result = DIResolver.Get <ICollectionImportResult>();
                        result.Name = model.Name;
                        // Will need to lookup the game and mod ids in the mod service
                        result.Game = model.Game;
                        var mods = model.Mods.Where(p => p.Enabled).OrderBy(p => p.Position);
                        result.ModIds = mods.Select(p => !string.IsNullOrWhiteSpace(p.PdxId) ? p.PdxId : p.SteamId).ToList();
                        return(null, result);
                    }
                }
                return(null, null);
            }

            if (File.Exists(parameters.File))
            {
                var exceptions = new List <Exception>();
                var result     = await parseV2();

                if (result.Item2 != null)
                {
                    return(result.Item2);
                }
                if (result.Item1 != null)
                {
                    exceptions.Add(result.Item1);
                }
                result = await parseV3();

                if (result.Item2 != null)
                {
                    return(result.Item2);
                }
                if (result.Item1 != null)
                {
                    exceptions.Add(result.Item1);
                }
                if (exceptions.Any())
                {
                    throw new AggregateException(exceptions);
                }
            }
            return(null);
        }
 /// <summary>
 /// Parses the paradoxos as json.
 /// </summary>
 /// <param name="content">The content.</param>
 /// <returns>ParadoxosExportedList.</returns>
 private ParadoxosExportedList ParseParadoxosAsJSON(string content)
 {
     return(JsonDISerializer.Deserialize <ParadoxosExportedList>(content));
 }
예제 #8
0
        /// <summary>
        /// Imports the internal.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <param name="importInstance">if set to <c>true</c> [import instance].</param>
        /// <param name="collectionImportResult">The collection import result.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool ImportInternal(ModCollectionExporterParams parameters, bool importInstance, out ICollectionImportResult collectionImportResult)
        {
            ICollectionImportResult importResult = null;

            if (importInstance)
            {
                importResult = DIResolver.Get <ICollectionImportResult>();
            }
            if (!importInstance)
            {
                if (Directory.Exists(parameters.ModDirectory))
                {
                    DiskOperations.DeleteDirectory(parameters.ModDirectory, true);
                }
            }

            var result = false;

            int getTotalFileCount()
            {
                var count = 0;

                using var fileStream = File.OpenRead(parameters.File);
                using var reader     = ReaderFactory.Open(fileStream);
                while (reader.MoveToNextEntry())
                {
                    if (!reader.Entry.IsDirectory)
                    {
                        count++;
                    }
                }
                fileStream.Close();
                fileStream.Dispose();
                return(count);
            }

            void parseUsingReaderFactory()
            {
                double total = getTotalFileCount();

                using var fileStream = File.OpenRead(parameters.File);
                using var reader     = ReaderFactory.Open(fileStream);
                double processed        = 0;
                double previousProgress = 0;

                while (reader.MoveToNextEntry())
                {
                    if (!reader.Entry.IsDirectory)
                    {
                        var relativePath = reader.Entry.Key.StandardizeDirectorySeparator().Trim(Path.DirectorySeparatorChar);
                        if (reader.Entry.Key.Equals(Common.Constants.ExportedModContentId, StringComparison.OrdinalIgnoreCase))
                        {
                            if (importInstance)
                            {
                                using var entryStream  = reader.OpenEntryStream();
                                using var memoryStream = new MemoryStream();
                                entryStream.CopyTo(memoryStream);
                                memoryStream.Seek(0, SeekOrigin.Begin);
                                using var streamReader = new StreamReader(memoryStream, true);
                                var text = streamReader.ReadToEnd();
                                streamReader.Close();
                                streamReader.Dispose();
                                var model = JsonDISerializer.Deserialize <IModCollection>(text);
                                mapper.Map(model, importResult);
                                importResult.ModNames    = model.ModNames;
                                importResult.Descriptors = model.Mods;
                                result = true;
                                break;
                            }
                        }
                        else
                        {
                            if (!importInstance)
                            {
                                var exportFileName = Path.Combine(relativePath.StartsWith(Common.Constants.ModExportPath + Path.DirectorySeparatorChar) ? parameters.ExportModDirectory : parameters.ModDirectory, relativePath.Replace(Common.Constants.ModExportPath + Path.DirectorySeparatorChar, string.Empty));
                                if (!Directory.Exists(Path.GetDirectoryName(exportFileName)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(exportFileName));
                                }
                                reader.WriteEntryToFile(exportFileName, ZipExtractionOpts.GetExtractionOptions());
                            }
                        }
                        processed++;
                        var perc = GetProgressPercentage(total, processed, 100);
                        if (perc != previousProgress)
                        {
                            messageBus.Publish(new ModExportProgressEvent(perc));
                            previousProgress = perc;
                        }
                    }
                }
            }

            void parseUsingArchiveFactory()
            {
                using var fileStream = File.OpenRead(parameters.File);
                using var reader     = ArchiveFactory.Open(fileStream);
                var    entries = reader.Entries.Where(entry => !entry.IsDirectory);
                double total   = !importInstance?entries.Count() : 1;

                double processed        = 0;
                double previousProgress = 0;

                foreach (var entry in entries)
                {
                    var relativePath = entry.Key.StandardizeDirectorySeparator().Trim(Path.DirectorySeparatorChar);
                    if (entry.Key.Equals(Common.Constants.ExportedModContentId, StringComparison.OrdinalIgnoreCase))
                    {
                        if (importInstance)
                        {
                            using var entryStream  = entry.OpenEntryStream();
                            using var memoryStream = new MemoryStream();
                            entryStream.CopyTo(memoryStream);
                            memoryStream.Seek(0, SeekOrigin.Begin);
                            using var streamReader = new StreamReader(memoryStream, true);
                            var text = streamReader.ReadToEnd();
                            streamReader.Close();
                            streamReader.Dispose();
                            var model = JsonDISerializer.Deserialize <IModCollection>(text);
                            mapper.Map(model, importResult);
                            importResult.ModNames    = model.ModNames;
                            importResult.Descriptors = model.Mods;
                            result = true;
                            break;
                        }
                    }
                    else
                    {
                        if (!importInstance)
                        {
                            var exportFileName = Path.Combine(relativePath.StartsWith(Common.Constants.ModExportPath + Path.DirectorySeparatorChar) ? parameters.ExportModDirectory : parameters.ModDirectory, relativePath.Replace(Common.Constants.ModExportPath + Path.DirectorySeparatorChar, string.Empty));
                            if (!Directory.Exists(Path.GetDirectoryName(exportFileName)))
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(exportFileName));
                            }
                            entry.WriteToFile(exportFileName, ZipExtractionOpts.GetExtractionOptions());
                        }
                    }
                    processed++;
                    var perc = GetProgressPercentage(total, processed, 100);
                    if (perc != previousProgress)
                    {
                        messageBus.Publish(new ModExportProgressEvent(perc));
                        previousProgress = perc;
                    }
                }
            }

            try
            {
                parseUsingArchiveFactory();
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                result = false;
                parseUsingReaderFactory();
            }
            collectionImportResult = importResult;
            return(!importInstance || result);
        }