/// <summary> /// Calls a method in every module, passing down the result to the next call. /// </summary> /// <typeparam name="T">Type of the result.</typeparam> /// <param name="methodName">Method name of the method to call.</param> /// <param name="arg">Argument to pass.</param> public static T CallInEachModule <T>(string methodName, T arg) { Type[] argsTypes = { typeof(T) }; T[] args = { arg }; for (int i = 0; i < AllMods.Count; i++) { ETGModule module = AllMods[i]; //TODO use module method cache MethodInfo method = module.GetType().GetMethod(methodName, argsTypes); if (method == null) { continue; } args[0] = (T)ReflectionHelper.InvokeMethod(method, module, args); } return(args[0]); }
protected virtual IEnumerator _RefreshMods() { ModListGroup.Children.Clear(); for (int i = 0; i < ETGMod.GameMods.Count; i++) { ETGModule mod = ETGMod.GameMods[i]; ETGModuleMetadata meta = mod.Metadata; ModListGroup.Children.Add(NewEntry(meta.Name, meta.Icon)); yield return(null); } DisabledListGroup.Children.Clear(); string[] files = Directory.GetFiles(ETGMod.ModsDirectory); for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (!file.EndsWithInvariant(".zip")) { continue; } if (ETGMod.GameMods.Exists(mod => mod.Metadata.Archive == files[i])) { continue; } DisabledListGroup.Children.Add(NewEntry(file.Substring(0, file.Length - 4), IconZip)); yield return(null); } files = Directory.GetDirectories(ETGMod.ModsDirectory); for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file == "RelinkCache") { continue; } if (ETGMod.GameMods.Exists(mod => mod.Metadata.Directory == files[i])) { continue; } DisabledListGroup.Children.Add(NewEntry($"{file}/", IconDir)); yield return(null); } }
public static void InitModDir(string dir) { Debug.Log("Initializing mod directory " + dir + " with Mods.txt is bad"); if (!Directory.Exists(dir)) { dir = Path.Combine(ETGMod.ModsDirectory, dir); } ETGModuleMetadata etgmoduleMetadata = new ETGModuleMetadata { Name = Path.GetFileName(dir), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly assembly = null; string path = Path.Combine(dir, "metadata.txt"); if (File.Exists(path)) { using (FileStream fileStream = File.OpenRead(path)) { etgmoduleMetadata = (ETGModuleMetadata)parseMethod.Invoke(null, new object[] { "", dir, fileStream }); } } foreach (ETGModuleMetadata etgmoduleMetadata2 in etgmoduleMetadata.Dependencies) { if (!ETGMod.DependencyLoaded(etgmoduleMetadata2)) { Debug.LogWarning(string.Concat(new object[] { "DEPENDENCY ", etgmoduleMetadata2, " OF ", etgmoduleMetadata, " NOT LOADED with Mods.txt is bad!" })); return; } } AppDomain.CurrentDomain.AssemblyResolve += (ResolveEventHandler)generateModAssemblyMethod.Invoke(null, new object[] { etgmoduleMetadata }); if (!File.Exists(etgmoduleMetadata.DLL)) { return; } if (etgmoduleMetadata.Prelinked) { assembly = Assembly.LoadFrom(etgmoduleMetadata.DLL); } else { using (FileStream fileStream2 = File.OpenRead(etgmoduleMetadata.DLL)) { assembly = etgmoduleMetadata.GetRelinkedAssembly(fileStream2); } } assembly.MapAssets(); ETGMod.Assets.Crawl(dir, null); foreach (Type type in assembly.GetTypes()) { if (typeof(ETGModule).IsAssignableFrom(type) && !type.IsAbstract) { ETGModule etgmodule = (ETGModule)type.GetConstructor((Type[])emptyTypeArrayInfo.GetValue(null)).Invoke((object[])emptyObjectArrayInfo.GetValue(null)); if (!ETGMod.AllMods.Contains(etgmodule)) { etgmodule.Metadata = etgmoduleMetadata; ETGMod.GameMods.Add(etgmodule); ETGMod.AllMods.Add(etgmodule); loadedMods.Add(etgmodule); addedModuleTypes.Add(type); addedModuleMethods.Add(new Dictionary <string, MethodInfo>()); } } } Debug.Log("Mod " + etgmoduleMetadata.Name + " initialized with Mods.txt is bad."); }
public static void InitModZIP(string archive) { Debug.Log("Initializing mod ZIP " + archive + " with Mods.txt is bad."); if (!File.Exists(archive)) { archive = Path.Combine(ETGMod.ModsDirectory, archive); } ETGModuleMetadata etgmoduleMetadata = new ETGModuleMetadata { Name = Path.GetFileNameWithoutExtension(archive), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly assembly = null; using (ZipFile zipFile = ZipFile.Read(archive)) { Texture2D texture2D = null; foreach (ZipEntry zipEntry in zipFile.Entries) { if (zipEntry.FileName == "metadata.txt") { using (MemoryStream memoryStream = new MemoryStream()) { zipEntry.Extract(memoryStream); memoryStream.Seek(0L, SeekOrigin.Begin); etgmoduleMetadata = (ETGModuleMetadata)parseMethod.Invoke(null, new object[] { archive, "", memoryStream }); continue; } } if (zipEntry.FileName == "icon.png") { texture2D = new Texture2D(2, 2); texture2D.name = "icon"; using (MemoryStream memoryStream2 = new MemoryStream()) { zipEntry.Extract(memoryStream2); memoryStream2.Seek(0L, SeekOrigin.Begin); texture2D.LoadImage(memoryStream2.GetBuffer()); } texture2D.filterMode = FilterMode.Point; } } if (texture2D != null) { etgmoduleMetadata.Icon = texture2D; } if (!etgmoduleMetadata.Profile.RunsOn(ETGMod.BaseProfile)) { return; } foreach (ETGModuleMetadata etgmoduleMetadata2 in etgmoduleMetadata.Dependencies) { if (!ETGMod.DependencyLoaded(etgmoduleMetadata2)) { Debug.LogWarning(string.Concat(new object[] { "DEPENDENCY ", etgmoduleMetadata2, " OF ", etgmoduleMetadata, " NOT LOADED with Mods.txt is bad!" })); return; } } AppDomain.CurrentDomain.AssemblyResolve += (ResolveEventHandler)generateModAssemblyMethod.Invoke(null, new object[] { etgmoduleMetadata }); foreach (ZipEntry zipEntry2 in zipFile.Entries) { string text = zipEntry2.FileName.Replace("\\", "/"); if (text == etgmoduleMetadata.DLL) { using (MemoryStream memoryStream3 = new MemoryStream()) { zipEntry2.Extract(memoryStream3); memoryStream3.Seek(0L, SeekOrigin.Begin); if (etgmoduleMetadata.Prelinked) { assembly = Assembly.Load(memoryStream3.GetBuffer()); continue; } assembly = etgmoduleMetadata.GetRelinkedAssembly(memoryStream3); continue; } } ETGMod.Assets.AddMapping(text, new AssetMetadata(archive, text) { AssetType = (zipEntry2.IsDirectory ? ETGMod.Assets.t_AssetDirectory : null) }); } } if (assembly == null) { return; } assembly.MapAssets(); foreach (Type type in assembly.GetTypes()) { if (typeof(ETGModule).IsAssignableFrom(type) && !type.IsAbstract) { ETGModule etgmodule = (ETGModule)type.GetConstructor((Type[])emptyTypeArrayInfo.GetValue(null)).Invoke((object[])emptyObjectArrayInfo.GetValue(null)); if (!ETGMod.AllMods.Contains(etgmodule)) { etgmodule.Metadata = etgmoduleMetadata; ETGMod.GameMods.Add(etgmodule); ETGMod.AllMods.Add(etgmodule); loadedMods.Add(etgmodule); addedModuleTypes.Add(type); addedModuleMethods.Add(new Dictionary <string, MethodInfo>()); } } } Debug.Log("Mod " + etgmoduleMetadata.Name + " initialized with Mods.txt is bad."); }
public static void InitModDir(string dir) { Debug.Log("Initializing mod directory " + dir); if (!Directory.Exists(dir)) { // Probably a mod in the mod directory dir = Path.Combine(ModsDirectory, dir); } // Fallback metadata in case none is found ETGModuleMetadata metadata = new ETGModuleMetadata() { Name = Path.GetFileName(dir), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly asm = null; // First read the metadata, ... string metadataPath = Path.Combine(dir, "metadata.txt"); if (File.Exists(metadataPath)) { using (FileStream fs = File.OpenRead(metadataPath)) { metadata = ETGModuleMetadata.Parse("", dir, fs); } } // ... then check if the dependencies are loaded ... foreach (ETGModuleMetadata dependency in metadata.Dependencies) { if (!DependencyLoaded(dependency)) { Debug.LogWarning("DEPENDENCY " + dependency + " OF " + metadata + " NOT LOADED!"); return; } } // ... then add an AssemblyResolve handler for all the .zip-ped libraries AppDomain.CurrentDomain.AssemblyResolve += metadata.GenerateModAssemblyResolver(); // ... then everything else if (!File.Exists(metadata.DLL)) { return; } if (metadata.Prelinked) { asm = Assembly.LoadFrom(metadata.DLL); } else { using (FileStream fs = File.OpenRead(metadata.DLL)) { asm = metadata.GetRelinkedAssembly(fs); } } Assets.Crawl(dir); Type[] types = asm.GetTypes(); for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (!typeof(ETGModule).IsAssignableFrom(type) || type.IsAbstract) { continue; } ETGModule module = (ETGModule)type.GetConstructor(a_Type_0).Invoke(a_object_0); module.Metadata = metadata; GameMods.Add(module); AllMods.Add(module); ModuleTypes.Add(type); ModuleMethods.Add(new Dictionary <string, MethodInfo>()); } Debug.Log("Mod " + metadata.Name + " initialized."); }
public static void InitModZIP(string archive) { Debug.Log("Initializing mod ZIP " + archive); if (!File.Exists(archive)) { // Probably a mod in the mod directory archive = Path.Combine(ModsDirectory, archive); } // Fallback metadata in case none is found ETGModuleMetadata metadata = new ETGModuleMetadata() { Name = Path.GetFileNameWithoutExtension(archive), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly asm = null; using (ZipFile zip = ZipFile.Read(archive)) { // First read the metadata, ... foreach (ZipEntry entry in zip.Entries) { if (entry.FileName == "metadata.txt") { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); metadata = ETGModuleMetadata.Parse(archive, "", ms); } break; } } // ... then check if the dependencies are loaded ... foreach (ETGModuleMetadata dependency in metadata.Dependencies) { if (!DependencyLoaded(dependency)) { Debug.LogWarning("DEPENDENCY " + dependency + " OF " + metadata + " NOT LOADED!"); return; } } // ... then add an AssemblyResolve handler for all the .zip-ped libraries AppDomain.CurrentDomain.AssemblyResolve += metadata.GenerateModAssemblyResolver(); // ... then everything else foreach (ZipEntry entry in zip.Entries) { string entryName = entry.FileName.Replace("\\", "/"); if (entryName == metadata.DLL) { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); if (metadata.Prelinked) { asm = Assembly.Load(ms.GetBuffer()); } else { asm = metadata.GetRelinkedAssembly(ms); } } } else { Assets.Map[Assets.RemoveExtension(entryName)] = new ETGModAssetMetadata(archive, entryName); } } } if (asm == null) { return; } Type[] types = asm.GetTypes(); for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (!typeof(ETGModule).IsAssignableFrom(type) || type.IsAbstract) { continue; } ETGModule module = (ETGModule)type.GetConstructor(a_Type_0).Invoke(a_object_0); module.Metadata = metadata; GameMods.Add(module); AllMods.Add(module); ModuleTypes.Add(type); ModuleMethods.Add(new Dictionary <string, MethodInfo>()); } Debug.Log("Mod " + metadata.Name + " initialized."); }