private static void ProcessUMFMod(string modName) { Logger.Log("Processing UMF mod '" + modName + "'"); Type[] gadgetTypes = GadgetCoreAPI.GetUMFAPI().GetModAssembly(modName).GetExportedTypes().Where(x => x.IsSubclassOf(typeof(Gadget)) && x.GetCustomAttributes(typeof(GadgetAttribute), true).FirstOrDefault() != null).ToArray(); List <GadgetInfo> gadgets = new List <GadgetInfo>(); for (int i = 0; i < gadgetTypes.Length; i++) { Type type = gadgetTypes[i]; GadgetAttribute attribute = (GadgetAttribute)type.GetCustomAttributes(typeof(GadgetAttribute), true).FirstOrDefault(); if (gadgets.Any(x => x.Attribute.Name == attribute.Name)) { throw new InvalidOperationException("It is illegal for a mod to contain multiple Gadgets with the same name: " + attribute.Name); } int[] targetVersionNums = attribute.TargetGCVersion.Split('.').Select(x => int.Parse(x)).ToArray(); if (targetVersionNums.Length != 4) { Array.Resize(ref targetVersionNums, 4); } if ((attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && (GadgetCoreAPI.currentVersionNums[1] > targetVersionNums[1] || (GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && (GadgetCoreAPI.currentVersionNums[2] > targetVersionNums[2] || (GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]))))) || (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && (GadgetCoreAPI.currentVersionNums[2] > targetVersionNums[2] || (GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]))) || (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]) || (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] == targetVersionNums[3])) { Gadget gadget = null; try { gadget = Activator.CreateInstance(type) as Gadget; if (gadget != null) { Logger.Log("Found Gadget to load: " + attribute.Name + ", in UMF mod: {" + modName + "}"); GadgetInfo info = new GadgetInfo(gadget, attribute, modName); gadget.Logger = new GadgetLogger(modName, attribute.Name); gadget.Config = new GadgetConfig(Path.Combine(GadgetPaths.ConfigsPath, modName + ".ini"), attribute.Name); Gadgets.RegisterGadget(info); gadgets.Add(info); if (!BatchLoading) { QueuedGadgets.Add(info); EnableQueuedGadgets(); } } } catch (Exception) { } finally { if (gadget == null) { Logger.LogWarning("Found Gadget that could not be constructed: " + attribute.Name + ", in UMF mod: {" + modName + "}"); } } } else { int rD = (int)attribute.GadgetCoreVersionSpecificity; Logger.LogWarning("Found Gadget with an incompatible version: " + attribute.Name + ", in UMF mod: {" + modName + "}. Requires version: " + new string(attribute.TargetGCVersion.TakeWhile(x => (x == '.' ? --rD : rD) > 0).ToArray())); } } }
private static void LoadGadgetMod(GadgetMod mod) { Logger.Log("Loading mod '" + mod.Name + "'"); if (mod.ModDependencies.Any(x => GadgetMods.GetModByName(x) == null)) { m_IncompatibleMods.Add(mod); Logger.LogWarning("Aborted loading mod '" + mod.Name + "' because of the following missing dependencies: " + mod.ModDependencies.Where(x => GadgetMods.GetModByName(x) == null).Concat()); return; } Type[] gadgetTypes = mod.Assembly.GetExportedTypes().Where(x => x.IsSubclassOf(typeof(Gadget)) && x.GetCustomAttributes(typeof(GadgetAttribute), true).FirstOrDefault() != null).ToArray(); if (gadgetTypes.Length == 0) { m_EmptyMods.Add(mod); Logger.LogWarning("Aborted loading mod '" + mod.Name + "' because it does not contain any Gadgets"); } mod.m_LoadedGadgets = new List <GadgetInfo>(); mod.LoadedGadgets = new ReadOnlyCollection <GadgetInfo>(mod.m_LoadedGadgets); mod.m_UnloadedGadgets = new List <GadgetInfo>(); mod.UnloadedGadgets = new ReadOnlyCollection <GadgetInfo>(mod.m_UnloadedGadgets); for (int i = 0; i < gadgetTypes.Length; i++) { Type type = gadgetTypes[i]; GadgetAttribute attribute = (GadgetAttribute)type.GetCustomAttributes(typeof(GadgetAttribute), true).FirstOrDefault(); if (mod.m_LoadedGadgets.Any(x => x.Attribute.Name == attribute.Name)) { throw new InvalidOperationException("It is illegal for a mod to contain multiple Gadgets with the same name: " + attribute.Name); } int[] targetVersionNums = attribute.TargetGCVersion.Split('.').Select(x => int.Parse(x)).ToArray(); if (targetVersionNums.Length != 4) { Array.Resize(ref targetVersionNums, 4); } if ((attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && (GadgetCoreAPI.currentVersionNums[1] > targetVersionNums[1] || (GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && (GadgetCoreAPI.currentVersionNums[2] > targetVersionNums[2] || (GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]))))) || (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && (GadgetCoreAPI.currentVersionNums[2] > targetVersionNums[2] || (GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]))) || (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]) || (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] == targetVersionNums[3])) { Gadget gadget = null; try { gadget = Activator.CreateInstance(type) as Gadget; } catch (Exception e) { Logger.LogWarning("Found Gadget that could not be constructed: " + attribute.Name + ", in mod: {" + mod.Name + "}: Error: " + e); } if (gadget != null) { try { Logger.Log("Found Gadget to load: " + attribute.Name + ", in mod: {" + mod.Name + "}"); gadget.CreateSingleton(gadget); GadgetInfo info = new GadgetInfo(gadget, attribute, mod); gadget.Logger = new GadgetLogger(mod.Name, attribute.Name); gadget.Config = new GadgetConfig(Path.Combine(GadgetPaths.ConfigsPath, mod.Name + ".ini"), attribute.Name); Gadgets.RegisterGadget(info); mod.m_LoadedGadgets.Add(info); if (!BatchLoading) { QueuedGadgets.Add(info); EnableQueuedGadgets(); } } catch (Exception e) { Logger.LogWarning("Found Gadget that had an error during registration: " + attribute.Name + ", in mod: {" + mod.Name + "}. Error: " + e); if (Gadgets.GetGadgetInfo(attribute.Name) != null) { Gadgets.UnregisterGadget(Gadgets.GetGadgetInfo(attribute.Name)); } } } } else { int rD = (int)attribute.GadgetCoreVersionSpecificity; Logger.LogWarning("Found Gadget with an incompatible version: " + attribute.Name + ", in mod: {" + mod.Name + "}. Requires version: " + new string(attribute.TargetGCVersion.TakeWhile(x => (x == '.' ? --rD : rD) > 0).ToArray())); } } mod.IsLoaded = true; }