public static void LoadModZIP(string archive) { if (!File.Exists(archive)) { // Probably a mod in the mod directory archive = Path.Combine(ModsDirectory, archive); } if (!File.Exists(archive)) { // It just doesn't exist. return; } ModLogger.Log("loader", $"Loading mod .zip: {archive}"); GameModMetadata meta = null; Assembly asm = null; using (ZipFile zip = ZipFile.Read(archive)) { Texture2D icon = null; // First read the metadata, ... foreach (ZipEntry entry in zip.Entries) { if (entry.FileName == "metadata.yaml") { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(ms)) meta = GameModMetadata.Parse(archive, "", reader); } continue; } if (entry.FileName == "icon.png") { icon = new Texture2D(2, 2); icon.name = "icon"; using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); icon.LoadImage(ms.GetBuffer()); } icon.filterMode = FilterMode.Point; continue; } } if (meta != null) { // In case the icon appears before the metadata in the .zip if (icon != null) { meta.Icon = icon; } // ... then check if the mod runs on this profile ... if (meta.ProfileID > ModAPI.Profile.Id) { ModLogger.Log("loader", "Mod meant for an in-dev YLMAPI version!"); return; } // ... then check if the dependencies are loaded ... foreach (GameModMetadata dep in meta.Dependencies) { if (!DependencyLoaded(dep)) { ModLogger.Log("loader", $"Dependency {dep} of mod {meta} not loaded!"); return; } } // ... then add an AssemblyResolve handler for all the .zip-ped libraries AppDomain.CurrentDomain.AssemblyResolve += meta._GenerateModAssemblyResolver(); } // ... then the patch (if any) ... if (!string.IsNullOrEmpty(meta?.PatchDLL)) { foreach (ZipEntry entry in zip.Entries) { string entryName = entry.FileName.Replace("\\", "/"); if (entryName != meta.PatchDLL) { continue; } using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); ModRuntimePatcher.LoadPatch(ms); } break; } } // ... then everything else foreach (ZipEntry entry in zip.Entries) { string entryName = entry.FileName.Replace("\\", "/"); if (meta != null && entryName == meta.DLL) { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); if (meta.Prelinked) { asm = Assembly.Load(ms.GetBuffer()); } else { asm = meta.GetRelinkedAssembly(ms); } } } ModContent.AddMapping(entryName, new AssetMetadata(archive, entryName) { AssetType = entry.IsDirectory ? typeof(AssetTypeDirectory) : null }); } } if (meta != null && asm != null) { LoadMod(meta, asm); } }
public static void LoadModDir(string dir) { if (!Directory.Exists(dir)) { // Probably a mod in the mod directory dir = Path.Combine(ModsDirectory, dir); } if (!Directory.Exists(dir)) { // It just doesn't exist. return; } ModLogger.Log("loader", $"Loading mod directory: {dir}"); GameModMetadata meta = null; Assembly asm = null; // First read the metadata, ... string metaPath = Path.Combine(dir, "metadata.yaml"); if (File.Exists(metaPath)) { using (StreamReader reader = new StreamReader(metaPath)) meta = GameModMetadata.Parse("", dir, reader); } if (meta != null) { // ... then check if the mod runs on this profile ... if (meta.ProfileID > ModAPI.Profile.Id) { ModLogger.Log("loader", "Mod meant for an in-dev YLMAPI version!"); return; } // ... then check if the dependencies are loaded ... foreach (GameModMetadata dep in meta.Dependencies) { if (!DependencyLoaded(dep)) { ModLogger.Log("loader", $"Dependency {dep} of mod {meta} not loaded!"); return; } } // ... then add an AssemblyResolve handler for all the .zip-ped libraries AppDomain.CurrentDomain.AssemblyResolve += meta._GenerateModAssemblyResolver(); } // ... then everything else ModContent.Crawl(null, dir); if (meta == null || !File.Exists(meta.DLL)) { return; } if (!string.IsNullOrEmpty(meta.PatchDLL) && File.Exists(meta.PatchDLL)) { using (Stream stream = File.OpenRead(meta.PatchDLL)) ModRuntimePatcher.LoadPatch(stream); } if (meta.Prelinked) { asm = Assembly.LoadFrom(meta.DLL); } else { using (FileStream fs = File.OpenRead(meta.DLL)) asm = meta.GetRelinkedAssembly(fs); } if (asm != null) { LoadMod(meta, asm); } }