internal static async Task <int> ExtractAddonFile(FileInfo file, DirectoryInfo folderOutput, bool warninvalid = false) { if (folderOutput == null) { folderOutput = new DirectoryInfo(Path.Combine(file.Directory.FullName, Path.GetFileNameWithoutExtension(file.FullName))); } if (!folderOutput.Exists) { folderOutput.Create(); } using var gmadFileStream = file.OpenRead(); Dictionary <string, Stream> files = new Dictionary <string, Stream>(); var jsonFileInfo = new FileInfo(Path.Combine(folderOutput.FullName, "addon.json")); //in case of re-extraction, we don't want to overwrite a manually written json for whatever reason AddonInfo addonInfo = await OpenAddonInfo(jsonFileInfo) ?? new AddonInfo(); bool success = await Addon.Extract(gmadFileStream, (relativeFilePath) => { Console.WriteLine($"Extracting {relativeFilePath}"); var outputFileInfo = new FileInfo(Path.Combine(folderOutput.FullName, relativeFilePath)); //create the subfolder first outputFileInfo.Directory.Create(); if (!outputFileInfo.FullName.StartsWith(folderOutput.FullName)) { throw new IOException($"Addon extraction somehow ended up outside main folder {outputFileInfo.FullName}, the relative path was {relativeFilePath}"); } Stream fileStream = null; try { fileStream = outputFileInfo.OpenWrite(); files.Add(relativeFilePath, fileStream); } catch (Exception) { Console.WriteLine($"Could not open {relativeFilePath} for writing"); } return(fileStream); }, addonInfo); foreach (var kv in files) { kv.Value.Dispose(); } if (success) { SaveAddonInfo(jsonFileInfo, addonInfo); } return(Convert.ToInt32(!success)); }