public void Start() { if (Util.IsDllLoaded || (Util.FindKerbalismBin() != null)) { print("[KerbalismBootstrap] WARNING: KERBALISM HAS ALREADY LOADED BEFORE US!"); } string our_bin = Path.Combine(AssemblyDirectory(Assembly.GetExecutingAssembly()), Util.BinName + ".bin"); string possible_dll = Path.Combine(AssemblyDirectory(Assembly.GetExecutingAssembly()), "Kerbalism.dll"); if (File.Exists(our_bin)) { print("[KerbalismBootstrap] Found Kerbalism bin file at '" + our_bin + "'"); if (File.Exists(possible_dll)) { try { File.Delete(possible_dll); print("[KerbalismBootstrap] Deleted non-bin DLL at '" + possible_dll + "'"); } catch { print("[KerbalismBootstrap] Could not delete non-bin DLL at '" + possible_dll + "'"); } } } else { print("[KerbalismBootstrap] ERROR: COULD NOT FIND KERBALISM BIN FILE (" + Util.BinName + ".bin" + ")! Ditching!"); return; } if (Util.IsDllLoaded) { print("[KerbalismBootstrap] Kerbalism non-bin DLL already loaded! Ditching!"); return; } AssemblyLoader.LoadPlugin(new FileInfo(our_bin), our_bin, null); AssemblyLoader.LoadedAssembly loadedAssembly = Util.FindKerbalismBin(); if (loadedAssembly == null) { print("[KerbalismBootstrap] Kerbalism failed to load! Ditching!"); return; } else { print("[KerbalismBootstrap] Kerbalism loaded!"); } loadedAssembly.Load(); foreach (Type type in loadedAssembly.assembly.GetTypes()) { foreach (Type loadedType in AssemblyLoader.loadedTypes) { if (loadedType.IsAssignableFrom(type)) { loadedAssembly.types.Add(loadedType, type); PropertyInfo temp = typeof(AssemblyLoader.LoadedAssembly).GetProperty("typesDictionary"); if (temp != null) { Dictionary <Type, Dictionary <String, Type> > dict = (Dictionary <Type, Dictionary <String, Type> >)temp.GetValue(loadedAssembly, null); Util.AddToLoadedTypesDict(ref dict, loadedType, type); } } } if (type.IsSubclassOf(typeof(MonoBehaviour))) { KSPAddon addonAttribute = (KSPAddon)type.GetCustomAttributes(typeof(KSPAddon), true).FirstOrDefault(); if (addonAttribute != null && addonAttribute.startup == KSPAddon.Startup.Instantly) { AddonLoaderWrapper.StartAddon(loadedAssembly, type, addonAttribute, KSPAddon.Startup.Instantly); } } } }
public void Start() { // get assembly path string codeBase = Assembly.GetExecutingAssembly().CodeBase; UriBuilder uri = new UriBuilder(codeBase); string path = Uri.UnescapeDataString(uri.Path); string assemblyPath = Path.GetDirectoryName(path); // check if the assembly exists as a dll file, or is already loaded. If it's the case, we assume it has priority over the kbins. if (File.Exists(Path.Combine(assemblyPath, assemblyName + ".dll")) || AssemblyLoader.loadedAssemblies.Any(p => p.name == assemblyName)) { print("[KerbalismBootstrap] WARNING : " + assemblyName + ".dll exists, aborting! Note : this is normal if you are running a debug build)"); return; } // Check that the KSP load method has been acquired if (!AddonLoaderWrapper.IsValid) { print("[KerbalismBootstrap] ERROR : the AddonLoader.StartAddon() method hasn't been found"); return; } // load the xml version file but remove namespaces XmlDocument versionConfig = new XmlDocument(); using (XmlTextReader textReader = new XmlTextReader(Path.Combine(assemblyPath, "VersionConfig.xml"))) { textReader.Namespaces = false; versionConfig.Load(textReader); } // get the kbin nodes list (should match the *.kbin files present in the assemblyPath) XmlNodeList kbinXmlList = versionConfig.GetElementsByTagName("KBinVersionConstant"); // parse each kbin xml node to get the name of the *.kbin file and the max / min KSP version this kbin is made for. Kbins = new List <Kbin>(); foreach (XmlNode kbinXml in kbinXmlList) { Kbin kbin = new Kbin(); string versionConstant = kbinXml.Attributes["Include"].Value; kbin.KbinAssemblyName = assemblyName + versionConstant; kbin.KbinFilePath = Path.Combine(assemblyPath, kbin.KbinAssemblyName + ".kbin"); kbin.KSPVersionMin = new Version(ParseKbinVersion(kbinXml, "KSPMinMajor"), ParseKbinVersion(kbinXml, "KSPMinMinor"), ParseKbinVersion(kbinXml, "KSPMinBuild")); kbin.KSPVersionMax = new Version(ParseKbinVersion(kbinXml, "KSPMaxMajor"), ParseKbinVersion(kbinXml, "KSPMaxMinor"), ParseKbinVersion(kbinXml, "KSPMaxBuild")); if (File.Exists(kbin.KbinFilePath)) { Kbins.Add(kbin); } else { print("[KerbalismBootstrap] WARNING : Can't find '" + kbin.KbinFilePath + "' defined in VersionConfig.xml"); } } // get the KSP version KSPVersion = new Version(Versioning.version_major, Versioning.version_minor, Versioning.Revision); // get the Kbin matching the KSP version Kbin kbinToLoad = Kbins.Find(p => KSPVersion >= p.KSPVersionMin && KSPVersion <= p.KSPVersionMax); if (kbinToLoad == null) { print("[KerbalismBootstrap] ERROR : No *.kbin file available for KSP " + KSPVersion + " - " + assemblyName + " wasn't loaded. Check the supported versions in VersionConfig.xml"); return; } // load the kbin in the KSP assembly loader AssemblyLoader.LoadPlugin(new FileInfo(kbinToLoad.KbinFilePath), kbinToLoad.KbinFilePath, null); AssemblyLoader.LoadedAssembly loadedKbin = AssemblyLoader.loadedAssemblies.FirstOrDefault(p => p.name == kbinToLoad.KbinAssemblyName); if (loadedKbin == null) { print("[KerbalismBootstrap] ERROR : kbin '" + kbinToLoad.KbinFilePath + "' failed to load!"); return; } else { print("[KerbalismBootstrap] " + kbinToLoad.KbinAssemblyName + ".kbin for KSP version " + KSPVersion + " successfully loaded"); } // Gotmachine 08-2019 : I'm not sure exactly how the following code work and I don't have time to investigate. // Shame on the guy that created this for not adding a single comment on a super hacky piece of code loadedKbin.Load(); foreach (Type type in loadedKbin.assembly.GetTypes()) { foreach (Type loadedType in AssemblyLoader.loadedTypes) { if (loadedType.IsAssignableFrom(type)) { loadedKbin.types.Add(loadedType, type); PropertyInfo temp = typeof(AssemblyLoader.LoadedAssembly).GetProperty("typesDictionary"); if (temp != null) { Dictionary <Type, Dictionary <String, Type> > dict = (Dictionary <Type, Dictionary <String, Type> >)temp.GetValue(loadedKbin, null); // Here is the only comment on this thing : // This is just so we have 1.3 compat! if (!dict.ContainsKey(loadedType)) { dict[loadedType] = new Dictionary <string, Type>(); } dict[loadedType][type.Name] = type; } } } if (type.IsSubclassOf(typeof(MonoBehaviour))) { KSPAddon addonAttribute = (KSPAddon)type.GetCustomAttributes(typeof(KSPAddon), true).FirstOrDefault(); if (addonAttribute != null && addonAttribute.startup == KSPAddon.Startup.Instantly) { AddonLoaderWrapper.StartAddon(loadedKbin, type, addonAttribute, KSPAddon.Startup.Instantly); } } } }