private static ModData LoadData([NotNull] Stream stream, [CanBeNull] out Folder archive) { archive = null; try { using (var sr = new StreamReader(DownloadManager.MemoryCache(stream))) using (var jr = new JsonTextReader(sr)) return(new JsonSerializer().Deserialize <ModData>(jr) ?? throw new InvalidOperationException("failed to read metadata")); } catch (JsonReaderException) { } var contents = AssetProcessor.Load(ArchiveExtractor.Read(DownloadManager.MemoryCache(stream), null)); if (contents is File file) { return(LoadData(file.Data, out archive)); } if (!(contents is Folder folder)) { throw new InvalidOperationException(); } if (folder.TryGetFile("dvmod.json", out var dvmod)) { using (var sr = new StreamReader(dvmod.Data)) using (var jr = new JsonTextReader(sr)) return(new JsonSerializer().Deserialize <ModData>(jr) ?? throw new InvalidOperationException("failed to read metadata")); } return(GuessModData(folder)); }
private static void SetProcessors([NotNull] Folder root, [NotNull] Folder folder, [ItemNotNull, NotNull] List <ModAsset> assets, [NotNull] string archivePath) { for (var i = 0; i < folder.Children.Count; i++) { var child = folder.Children[i]; foreach (var asset in assets) { if (IsMatch(asset.Origin.AbsolutePath, archivePath, child.Name, child is File)) { if (asset.Processor == ModAssetProcessor.Archive && child is File f) { child = ArchiveExtractor.Read(f.Data, asset.ArchivePath); if (child is Folder fo) { Load(fo); if (string.IsNullOrEmpty(asset.Path)) { folder.AddItems(fo.Children); } } } if (!string.IsNullOrEmpty(asset.Path)) { folder.Children.RemoveAt(i); i--; var split = asset.Path.Split('/'); var e = ((IEnumerable <string>)split).GetEnumerator(); var croot = folder; if (split[0] == "") { e.MoveNext(); croot = root; } // TODO: set Processor to merge on created folders if (child is Folder fo) { var c = croot.PathAddFolder(e); c.AddItems(fo.Children); while (c != null && c.Processor == ModAssetProcessor.None) { c.Processor = ModAssetProcessor.MergeFolder; c = c.Parent; } } else if (child is File fi) { child = croot.PathAddFile(e, fi.FileData); } } if (asset.Processor != ModAssetProcessor.Archive) { child.Processor = asset.Processor; } } } if (child.Processor == ModAssetProcessor.None && (archivePath != "/" || !string.Equals(child.Name, "meta.json", StringComparison.OrdinalIgnoreCase) && !string.Equals(child.Name, "dvmod.json", StringComparison.OrdinalIgnoreCase)) && child is File) { child.Processor = ModAssetProcessor.Copy; } if (child is Folder fol) { child.Processor = ModAssetProcessor.MergeFolder; SetProcessors(root, fol, assets, archivePath + child.Name + "/"); } } }
public static void LoadAsset([NotNull] Folder root, [NotNull] ModAsset asset, [CanBeNull] Folder bundledFiles) { FileTree data; if (asset.Origin.Scheme == "dvmod" && asset.Origin.Host == "current-archive") { if (bundledFiles is null) { throw new InvalidOperationException("reference ro current-archive from standalone mod info"); } data = bundledFiles.GetPath(asset.Origin.AbsolutePath.TrimStart('/')) ?? throw new FileNotFoundException("referenced file was not found", asset.Origin.ToString()); } else { var stream = DownloadManager.Download(asset.Origin) ?? throw new FileNotFoundException("unable to download asset", asset.Origin.ToString()); data = new File("", FileData.FromStream(stream), null); } if (asset.Processor == ModAssetProcessor.Archive && data is File file) { data = ArchiveExtractor.Read(file.Data, asset.ArchivePath); if (data is Folder fo) { Load(fo); if (string.IsNullOrEmpty(asset.Path)) { root.AddItems(fo.Children); } } } if (!string.IsNullOrEmpty(asset.Path)) { if (data is Folder fo) { var c = root.PathAddFolder(asset.Path); c.AddItems(fo.Children); while (c != null && c.Processor == ModAssetProcessor.None) { c.Processor = ModAssetProcessor.MergeFolder; c = c.Parent; } } else if (data is File fi) { data = root.PathAddFile(asset.Path, fi.FileData); } } else if (data is File) { throw new InvalidOperationException("file assets must specify a folder"); } if (asset.Processor != ModAssetProcessor.Archive) { data.Processor = asset.Processor; } if (data.Processor == ModAssetProcessor.None) { data.Processor = data is File ? ModAssetProcessor.Copy : ModAssetProcessor.MergeFolder; } data = data.Parent; while (data != null && data.Processor == ModAssetProcessor.None) { data.Processor = ModAssetProcessor.MergeFolder; data = data.Parent; } }