Пример #1
0
            /// <summary>
            /// Load a mod from a .zip archive at runtime.
            /// </summary>
            /// <param name="archive">The path to the mod .zip archive.</param>
            public static void LoadZip(string archive)
            {
                if (!Flags.SupportRuntimeMods)
                {
                    Logger.Log(LogLevel.Warn, "loader", "Loader disabled!");
                    return;
                }

                if (!File.Exists(archive)) // Relative path? Let's just make it absolute.
                {
                    archive = Path.Combine(PathMods, archive);
                }
                if (!File.Exists(archive)) // It just doesn't exist.
                {
                    return;
                }

                Logger.Log(LogLevel.Verbose, "loader", $"Loading mod .zip: {archive}");

                EverestModuleMetadata meta = null;

                EverestModuleMetadata[] multimetas = null;

                using (ZipFile zip = new ZipFile(archive)) {
                    foreach (ZipEntry entry in zip.Entries)
                    {
                        if (entry.FileName == "metadata.yaml")
                        {
                            using (MemoryStream stream = entry.ExtractStream())
                                using (StreamReader reader = new StreamReader(stream)) {
                                    try {
                                        meta             = YamlHelper.Deserializer.Deserialize <EverestModuleMetadata>(reader);
                                        meta.PathArchive = archive;
                                        meta.PostParse();
                                    } catch (Exception e) {
                                        Logger.Log(LogLevel.Warn, "loader", $"Failed parsing metadata.yaml in {archive}: {e}");
                                        FilesWithMetadataLoadFailures.Add(archive);
                                    }
                                }
                            continue;
                        }
                        if (entry.FileName == "multimetadata.yaml" ||
                            entry.FileName == "everest.yaml" ||
                            entry.FileName == "everest.yml")
                        {
                            using (MemoryStream stream = entry.ExtractStream())
                                using (StreamReader reader = new StreamReader(stream)) {
                                    try {
                                        if (!reader.EndOfStream)
                                        {
                                            multimetas = YamlHelper.Deserializer.Deserialize <EverestModuleMetadata[]>(reader);
                                            foreach (EverestModuleMetadata multimeta in multimetas)
                                            {
                                                multimeta.PathArchive = archive;
                                                multimeta.PostParse();
                                            }
                                        }
                                    } catch (Exception e) {
                                        Logger.Log(LogLevel.Warn, "loader", $"Failed parsing everest.yaml in {archive}: {e}");
                                        FilesWithMetadataLoadFailures.Add(archive);
                                    }
                                }
                            continue;
                        }
                    }
                }

                ZipModContent         contentMeta       = new ZipModContent(archive);
                EverestModuleMetadata contentMetaParent = null;

                Action contentCrawl = () => {
                    if (contentMeta == null)
                    {
                        return;
                    }
                    if (contentMetaParent != null)
                    {
                        contentMeta.Mod  = contentMetaParent;
                        contentMeta.Name = contentMetaParent.Name;
                    }
                    OnCrawlMod?.Invoke(archive, contentMetaParent);
                    Content.Crawl(contentMeta);
                    contentMeta = null;
                };

                if (multimetas != null)
                {
                    foreach (EverestModuleMetadata multimeta in multimetas)
                    {
                        multimeta.Multimeta = multimetas;
                        if (contentMetaParent == null)
                        {
                            contentMetaParent = multimeta;
                        }
                        LoadModDelayed(multimeta, contentCrawl);
                    }
                }
                else
                {
                    if (meta == null)
                    {
                        meta = new EverestModuleMetadata()
                        {
                            Name          = "_zip_" + Path.GetFileNameWithoutExtension(archive),
                            VersionString = "0.0.0-dummy",
                            PathArchive   = archive
                        };
                        meta.PostParse();
                    }
                    contentMetaParent = meta;
                    LoadModDelayed(meta, contentCrawl);
                }
            }
Пример #2
0
            /// <summary>
            /// Load a mod from a .zip archive at runtime.
            /// </summary>
            /// <param name="archive">The path to the mod .zip archive.</param>
            public static void LoadZip(string archive) {
                if (Flags.IsDisabled || !Flags.SupportRuntimeMods) {
                    Logger.Log(LogLevel.Warn, "loader", "Loader disabled!");
                    return;
                }

                if (!File.Exists(archive)) // Relative path? Let's just make it absolute.
                    archive = Path.Combine(PathMods, archive);
                if (!File.Exists(archive)) // It just doesn't exist.
                    return;

                Logger.Log(LogLevel.Verbose, "loader", $"Loading mod .zip: {archive}");

                EverestModuleMetadata meta = null;
                EverestModuleMetadata[] multimetas = null;

                // In case the icon appears before the metadata in the .zip, store it temporarily, set it later.
                Texture2D icon = null;
                using (ZipFile zip = new ZipFile(archive)) {
                    foreach (ZipEntry entry in zip.Entries) {
                        if (entry.FileName == "metadata.yaml") {
                            using (MemoryStream stream = entry.ExtractStream())
                            using (StreamReader reader = new StreamReader(stream)) {
                                try {
                                    meta = YamlHelper.Deserializer.Deserialize<EverestModuleMetadata>(reader);
                                    meta.PathArchive = archive;
                                    meta.PostParse();
                                } catch (Exception e) {
                                    Logger.Log(LogLevel.Warn, "loader", $"Failed parsing metadata.yaml in {archive}: {e}");
                                }
                            }
                            continue;
                        }
                        if (entry.FileName == "multimetadata.yaml" ||
                            entry.FileName == "everest.yaml" ||
                            entry.FileName == "everest.yml") {
                            using (MemoryStream stream = entry.ExtractStream())
                            using (StreamReader reader = new StreamReader(stream)) {
                                try {
                                    if (!reader.EndOfStream) {
                                        multimetas = YamlHelper.Deserializer.Deserialize<EverestModuleMetadata[]>(reader);
                                        foreach (EverestModuleMetadata multimeta in multimetas) {
                                            multimeta.PathArchive = archive;
                                            multimeta.PostParse();
                                        }
                                    }
                                } catch (Exception e) {
                                    Logger.Log(LogLevel.Warn, "loader", $"Failed parsing multimetadata.yaml in {archive}: {e}");
                                }
                            }
                            continue;
                        }
                        if (entry.FileName == "icon.png") {
                            using (Stream stream = entry.ExtractStream())
                                icon = Texture2D.FromStream(Celeste.Instance.GraphicsDevice, stream);
                            continue;
                        }
                    }
                }

                if (meta != null) {
                    if (icon != null)
                        meta.Icon = icon;
                }

                ZipModContent contentMeta = new ZipModContent(archive);
                EverestModuleMetadata contentMetaParent = null;

                Action contentCrawl = () => {
                    if (contentMeta == null)
                        return;
                    if (contentMetaParent != null) {
                        contentMeta.Mod = contentMetaParent;
                        contentMeta.Name = contentMetaParent.Name;
                    }
                    Content.Crawl(contentMeta);
                    contentMeta = null;
                };

                if (multimetas != null) {
                    foreach (EverestModuleMetadata multimeta in multimetas) {
                        multimeta.Multimeta = multimetas;
                        if (contentMetaParent == null)
                            contentMetaParent = multimeta;
                        LoadModDelayed(multimeta, contentCrawl);
                    }
                } else {
                    if (meta == null) {
                        meta = new EverestModuleMetadata() {
                            Name = "_zip_" + Path.GetFileNameWithoutExtension(archive),
                            VersionString = "0.0.0-dummy",
                            PathArchive = archive
                        };
                        meta.PostParse();
                    }
                    contentMetaParent = meta;
                    LoadModDelayed(meta, contentCrawl);
                }
            }