private static Mod Instantiate(LoadedMod mod) { try { Type modType = mod.assembly.GetTypes().SingleOrDefault(t => t.IsSubclassOf(typeof(Mod))); if (modType == null) { throw new Exception("It looks like this mod doesn't have a class extending Mod. Mods need a Mod class to function.") { HelpLink = "https://github.com/blushiemagic/tModLoader/wiki/Basic-tModLoader-Modding-FAQ#sequence-contains-no-matching-element-error" } } ; var m = (Mod)Activator.CreateInstance(modType); m.File = mod.modFile; m.Code = mod.assembly; m.Side = mod.properties.side; m.DisplayName = mod.properties.displayName; return(m); } catch (Exception e) { e.Data["mod"] = mod.Name; throw; } }
private static Mod Instantiate(LoadedMod mod) { try { Type modType = mod.assembly.GetTypes().SingleOrDefault(t => t.IsSubclassOf(typeof(Mod))); if (modType == null) { throw new Exception(mod.Name + " does not have a class extending Mod. Mods need a Mod class to function.") { HelpLink = "https://github.com/blushiemagic/tModLoader/wiki/Basic-tModLoader-Modding-FAQ#sequence-contains-no-matching-element-error" } } ; var m = (Mod)Activator.CreateInstance(modType); m.File = mod.modFile; m.Code = mod.assembly; m.Logger = LogManager.GetLogger(m.Name); m.Side = mod.properties.side; m.DisplayName = mod.properties.displayName; m.tModLoaderVersion = mod.properties.buildVersion; return(m); } catch (Exception e) { e.Data["mod"] = mod.Name; throw; } finally { MemoryTracking.Update(mod.Name).code += mod.bytesLoaded; } }
// Get the def set of a specific type for a specific mod /* * public static ModDefSet<T> DefSetOfTypeForMod<T>( LoadedMod mod ) where T : Def, new() * { * if( mod == null ) * { * return null; * } * var defSets = typeof( LoadedMod ).GetField( "defSets", BindingFlags.Instance | BindingFlags.NonPublic ).GetValue( mod ) as Dictionary<System.Type, ModDefSet>; * ModDefSet modDefSet = (ModDefSet) null; * if( !defSets.TryGetValue( typeof (T), out modDefSet ) ) * { * return null; * } * return (ModDefSet<T>) modDefSet; * } */ // Get the def of a specific type for a specific mod public static Def DefOfTypeForMod(LoadedMod mod, Def searchDef) { if (mod == null) { return(null); } return(mod.AllDefs.FirstOrDefault(def => ( (def.GetType() == searchDef.GetType()) && (def.defName == searchDef.defName) ))); }
// Get the def list of a specific type for a specific mod public static List <T> DefListOfTypeForMod <T>(LoadedMod mod) where T : Def, new() { if (mod == null) { return(null); } var list = mod.AllDefs.Where(def => ( (def.GetType() == typeof(T)) )).ToList(); return(list.ConvertAll(def => ((T)def))); }
// Get the ModHelperDef for a mod public static ModHelperDef ModHelperDefForMod(LoadedMod mod) { if (mod == null) { return(null); } var rVal = (ModHelperDef)null; if (Controller.Data.DictModHelperDefs.TryGetValue(mod, out rVal)) { return(rVal); } return(null); }
// Get a mods index in the load order by mod public static int ModIndexByMod(LoadedMod mod) { if (mod == null) { return(-1); } var allMods = Controller.Data.Mods; for (int i = 0; i < allMods.Count; i++) { if (allMods[i] == mod) { return(i); } } return(-1); }
internal static void Initialize(string[] args = null) { if (args != null) { for (int i = 0; i < args.Length; i++) { if (args[i] == "--mod" && Directory.Exists(Path.Combine(Application.StartupPath, "mods", args[i + 1]))) { ModName = args[i + 1]; } if (args[i] == "--visisble3d") //this opens a form and renders the gameplay in realtime(will certainly make it slower, well, unsure. Since otherwise it would be rendered in memory) { new FrmMain().Show(); //requires client zips } } } EventRegistry = new GameEventRegistry(); BF2Engine = new BF2Engine(); if (string.IsNullOrEmpty(ModName)) { Console.WriteLine("No mod was defined, which mod would you like to load?"); var directories = Directory.EnumerateDirectories(Path.Combine(Application.StartupPath, "mods")).Select(d => new DirectoryInfo(d).Name); for (int i = 0; i < directories.Count(); i++) { Console.WriteLine("[" + i + "] " + directories.ToArray()[i]); } Console.Write(">"); var mod = Console.ReadLine(); if (!directories.Contains(mod)) { Console.WriteLine("Invalid mod! Press any key to exit..."); Console.ReadKey(); Environment.Exit(-1); } ModName = "mods/" + mod; ModAssembly = Assembly.Load(File.ReadAllBytes(Path.Combine(Application.StartupPath, ModName, "phoenixmod.dll"))); ModPath = Path.Combine(Application.StartupPath, ModName); LoadedMod = (IMod)Activator.CreateInstance(ModAssembly.GetTypes().Where(x => x.GetInterfaces().Contains(typeof(IMod))).First()); ConFileProcessor = LoadedMod.GetConFileProcessor(); } LoadedMod.Initialize(BF2Engine, EventRegistry); Console.WriteLine("Loaded " + LoadedMod.Name); BF2Engine.InitEngine(); BF2Engine.LoadServerArchives(); }
public void AddDependency(LoadedMod dep) { dependencies.Add(dep); dep.dependents.Add(this); }
// Validate ModHelperDefs, CCL load order, CCL versioning public override bool Validate() { // Hopefully... var stringBuilder = new StringBuilder(); var rVal = true; CCL_Log.CaptureBegin(stringBuilder); // Limit one ModHelperDef per mod // Create the ordered list by inserting dummies for mods which don't have one var allMods = LoadedModManager.LoadedMods.ToList(); // Find Core and CCL in the mod order coreModIndex = -1; cclModIndex = -1; for (int i = 0; i < allMods.Count; ++i) { LoadedMod mod = allMods[i]; if (mod.name == "Core") { coreModIndex = i; } if (mod.name == Controller.Data.UnityObjectName) { cclModIndex = i; } } if (coreModIndex == -1) { LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow); stringBuilder.AppendLine("\tUnable to find 'Core' in mod load order!"); //rVal = false; // Don't throw as an error, will be caught special } else if (coreModIndex != 0) { LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow); stringBuilder.AppendLine("\t'Core' must be first in mod load order!"); //rVal = false; // Don't throw as an error, will be caught special } if (cclModIndex == -1) { LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow); stringBuilder.Append("\tUnable to find '"); stringBuilder.Append(Controller.Data.UnityObjectName); stringBuilder.AppendLine("' in mod load order!"); //rVal = false; // Don't throw as an error, will be caught special } else if (cclModIndex != 1) { LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow); stringBuilder.Append("\t'"); stringBuilder.Append(Controller.Data.UnityObjectName); stringBuilder.AppendLine("' must be second in mod load order, immediately after 'Core'! :: Current position is #" + (cclModIndex + 1).ToString()); //rVal = false; // Don't throw as an error, will be caught special } if (rVal) { for (int i = 0; i < allMods.Count; i++) { var modHelperDef = (ModHelperDef)null; var mod = allMods[i]; var modHelperDefs = Find_Extensions.DefListOfTypeForMod <ModHelperDef>(mod); if (!modHelperDefs.NullOrEmpty()) { if (modHelperDefs.Count > 1) { stringBuilder.Append("\t" + mod.name); CCL_Log.AppendSectionNewLine(ref stringBuilder, "Multiple ModHelperDefs detected"); rVal = false; } else { // Validate the def modHelperDef = modHelperDefs.First(); if (!modHelperDef.IsValid) { // Don't do anything special with broken mods stringBuilder.Append("\t" + mod.name); CCL_Log.AppendSectionNewLine(ref stringBuilder, "ModHelperDef is invalid"); rVal = false; } else if (!modHelperDef.dummy) { // Don't show validation message for dummy defs stringBuilder.Append("\t" + mod.name); CCL_Log.AppendSection(ref stringBuilder, "ModHelperDef"); CCL_Log.AppendSectionNewLine(ref stringBuilder, "Passed validation, requesting v" + modHelperDef.minCCLVersion); } } } else if (rVal == true) { // Doesn't exist, create a dummy for logging but only // create if we're not just checking for remaining errors modHelperDef = new ModHelperDef(); modHelperDef.defName = mod.name + "_ModHelperDef"; modHelperDef.minCCLVersion = Version.Minimum.ToString(); modHelperDef.ModName = mod.name; modHelperDef.Verbosity = Verbosity.NonFatalErrors; modHelperDef.dummy = true; } if (rVal == true) { // No errors, def is valid or a dummy // Associate the def with the mod (the dictionary is to go the other way) modHelperDef.mod = mod; // Insert it into it's ordered place in the lists Controller.Data.Mods.Insert(i, mod); Controller.Data.ModHelperDefs.Insert(i, modHelperDef); // Add a dictionary entry Controller.Data.DictModHelperDefs.Add(mod, modHelperDef); } } // Should now be a complete pair of lists in mod load order // as well as a dictionary of mods and their defs #if DEVELOPER //Dump ordered list of mods and their defs string dump = "Mod load order:\n"; for (int i = 0; i < Controller.Data.Mods.Count; i++) { dump += "\t[" + i + "] - " + Controller.Data.Mods[i].name + " - " + Controller.Data.ModHelperDefs[i].defName + (Controller.Data.ModHelperDefs[i].dummy ? " - dummy" : "") + "\n"; } CCL_Log.Write(dump); #endif if (rVal) { LoadedMod CCL_Mod = Controller.Data.Mods[cclModIndex]; ModHelperDef CCL_HelperDef = Find_Extensions.ModHelperDefForMod(CCL_Mod); // Validate xml version with assembly version var vc = Version.Compare(CCL_HelperDef.minCCLVersion); if (vc != Version.VersionCompare.ExactMatch) { stringBuilder.AppendLine("\tModHelperDef version mismatch for Community Core Library!"); rVal = false; } // CCL rank is #2 in load order and def version matches library Controller.Data.cclMod = CCL_Mod; Controller.Data.cclHelperDef = CCL_HelperDef; } } // Should be all good or up until the first error encountered CCL_Log.CaptureEnd( stringBuilder, rVal ? "Validated" : "Errors during validation" ); strReturn = stringBuilder.ToString(); // Return true if all mods OK, false if any failed validation State = rVal ? SubControllerState.Validated : SubControllerState.ValidationError; return(rVal); }
public static void TraceMod(LoadedMod mod, Verbosity Severity, string content, string category = null) { var modHelperDef = Find_Extensions.ModHelperDefForMod(mod); _Trace(modHelperDef, Severity, content, null, category); }