Example #1
0
        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);
                    }
                }
            }
        }
Example #2
0
        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);
                    }
                }
            }
        }