Example #1
0
        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));
        }
Example #2
0
        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 + "/");
                }
            }
        }
Example #3
0
        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;
            }
        }