public static void Crawl(ContentModMetadata meta, string dir, string root = null) { if (meta == null) { Mods.Add(meta = new ContentModMetadata() { PathDirectory = dir }); } if (root == null) { root = dir; } string[] files = Directory.GetFiles(dir); for (int i = 0; i < files.Length; i++) { string file = files[i]; Add(file.Substring(root.Length + 1), new AssetMetadata(file)); } files = Directory.GetDirectories(dir); for (int i = 0; i < files.Length; i++) { string file = files[i]; Crawl(meta, file, root); } }
/// <summary> /// Crawl through the content mod and automatically fill the mod asset map. /// </summary> /// <param name="meta">The content mod to crawl through.</param> public static void Crawl(ContentModMetadata meta) { if (Mods.Contains(meta)) { Mods.Add(meta); } if (meta.PathDirectory != null) { if (Directory.Exists(meta.PathDirectory)) { Crawl(meta, meta.PathDirectory); } } else if (meta.PathArchive != null) { if (File.Exists(meta.PathArchive)) { using (ZipFile zip = new ZipFile(meta.PathArchive)) Crawl(meta, meta.PathArchive, zip); } } else if (meta.Assembly != null) { Crawl(meta, meta.Assembly); } }
internal static void Crawl(ContentModMetadata meta, string archive, ZipFile zip) { foreach (ZipEntry entry in zip.Entries) { string entryName = entry.FileName.Replace('\\', '/'); if (entryName.EndsWith("/")) { continue; } Add(entryName, new ModAsset(archive, entryName)); } }
internal static void Crawl(ContentModMetadata meta, string dir, string root = null) { if (root == null) { root = dir; } string[] files = Directory.GetFiles(dir); for (int i = 0; i < files.Length; i++) { string file = files[i]; Add(file.Substring(root.Length + 1), new ModAsset(file)); } files = Directory.GetDirectories(dir); for (int i = 0; i < files.Length; i++) { string file = files[i]; Crawl(meta, file, root); } }
public static void Crawl(ContentModMetadata meta, string archive, ZipArchive zip) { if (meta == null) { Mods.Add(meta = new ContentModMetadata() { PathArchive = archive }); } foreach (ZipArchiveEntry entry in zip.Entries) { string entryName = entry.FullName.Replace('\\', '/'); if (entryName.EndsWith("/")) { continue; } Add(entryName, new AssetMetadata(archive, entryName)); } }
internal static void Crawl(ContentModMetadata meta, Assembly asm) { if (meta == null) { Mods.Add(meta = new ContentModMetadata { Assembly = asm }); } string[] resourceNames = asm.GetManifestResourceNames(); for (int i = 0; i < resourceNames.Length; i++) { string name = resourceNames[i]; int indexOfContent = name.IndexOf("Content"); if (indexOfContent < 0) { continue; } name = name.Substring(indexOfContent + 8); Add(name, new ModAsset(asm, resourceNames[i])); } }
public static void Crawl(ContentModMetadata meta) { if (meta.PathDirectory != null) { if (Directory.Exists(meta.PathDirectory)) { Crawl(meta, meta.PathDirectory); } } else if (meta.PathArchive != null) { if (File.Exists(meta.PathArchive)) { using (Stream zipStream = File.OpenRead(meta.PathArchive)) using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Read)) Crawl(meta, meta.PathArchive, zip); } } else if (meta.Assembly != null) { Crawl(meta, meta.Assembly); } }
/// <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; // 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") { using (MemoryStream stream = entry.ExtractStream()) using (StreamReader reader = new StreamReader(stream)) { try { 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; } } ContentModMetadata contentMeta = new ContentModMetadata { PathArchive = archive }; Action contentCrawl = () => { if (contentMeta == null) { return; } Content.Crawl(contentMeta); contentMeta = null; }; if (multimetas != null) { foreach (EverestModuleMetadata multimeta in multimetas) { LoadModDelayed(multimeta, contentCrawl); } } LoadModDelayed(meta, contentCrawl); }
/// <summary> /// Load a mod from a directory at runtime. /// </summary> /// <param name="dir">The path to the mod directory.</param> public static void LoadDir(string dir) { if (!Flags.SupportRuntimeMods) { Logger.Log(LogLevel.Warn, "loader", "Loader disabled!"); return; } if (!Directory.Exists(dir)) // Relative path? { dir = Path.Combine(PathMods, dir); } if (!Directory.Exists(dir)) // It just doesn't exist. { return; } Logger.Log(LogLevel.Verbose, "loader", $"Loading mod directory: {dir}"); EverestModuleMetadata meta = null; EverestModuleMetadata[] multimetas = null; string metaPath = Path.Combine(dir, "metadata.yaml"); if (File.Exists(metaPath)) { using (StreamReader reader = new StreamReader(metaPath)) { try { meta = YamlHelper.Deserializer.Deserialize <EverestModuleMetadata>(reader); meta.PathDirectory = dir; meta.PostParse(); } catch (Exception e) { Logger.Log(LogLevel.Warn, "loader", $"Failed parsing metadata.yaml in {dir}: {e}"); } } } metaPath = Path.Combine(dir, "multimetadata.yaml"); if (File.Exists(metaPath)) { using (StreamReader reader = new StreamReader(metaPath)) { try { multimetas = YamlHelper.Deserializer.Deserialize <EverestModuleMetadata[]>(reader); foreach (EverestModuleMetadata multimeta in multimetas) { multimeta.PathDirectory = dir; multimeta.PostParse(); } } catch (Exception e) { Logger.Log(LogLevel.Warn, "loader", $"Failed parsing multimetadata.yaml in {dir}: {e}"); } } } ContentModMetadata contentMeta = new ContentModMetadata { PathDirectory = dir }; Action contentCrawl = () => { if (contentMeta == null) { return; } Content.Crawl(contentMeta); contentMeta = null; }; if (multimetas != null) { foreach (EverestModuleMetadata multimeta in multimetas) { LoadModDelayed(multimeta, contentCrawl); } } LoadModDelayed(meta, contentCrawl); }