/// <summary> /// This function will load the plugin. It will take hte plugin info make sure the file exsits /// and then load the dll, find the class that needs to be loaded and then load that class. /// There is no checking in place to make sure the plugins do not conflict. /// </summary> /// <param name="pluginInfo">This is the plugin that will be loaded.</param> public static void LoadPlugin(PluginInfo pluginInfo) { if (pluginInfo.IsLoaded) { return; } pluginInfo.ShouldLoadPlugin = true; FileInfo info = new FileInfo("./saves/" + pluginInfo.FileName); if (info.Exists) { //make sure the file is there try { //loading new domains do not work for some reason //pluginInfo.appDomain = AppDomain.CreateDomain("Testdomain"); //AssemblyName assemblyName = new AssemblyName(); //assemblyName.CodeBase = pluginInfo.fileName; //pluginInfo.assembly = pluginInfo.appDomain.Load(pluginInfo.fileName); pluginInfo.Assembly = Assembly.LoadFile("./saves/" + pluginInfo.FileName); //load file if (pluginInfo.Assembly != null) { Type[] types = pluginInfo.Assembly.GetTypes(); //get all classes out of file for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (typeof(IPlugin).IsAssignableFrom(type) && type.IsClass) { //find the one that is a plugin pluginInfo.Plugin = (IPlugin)Activator.CreateInstance(type); //create that class } } } else { GUIWindowModOptions.DisplayErrorMessage("Assemply is null on load of '" + pluginInfo.FileName + "'"); AManager<GUIManager>.getInstance().AddTextLine("Assemply is null on load of '" + pluginInfo.FileName + "'"); } } catch (Exception ex) { GUIWindowModOptions.DisplayErrorMessage("Could not load assembly: '" + pluginInfo.FileName + "'"); AManager<GUIManager>.getInstance().AddTextLine("Could not load assembly: '" + pluginInfo.FileName + "'"); AManager<GUIManager>.getInstance().AddTextLine(" " + ex.Message); pluginInfo.ShouldLoadPlugin = false; pluginInfo.IsLoaded = false; } if (pluginInfo.Plugin != null) { //make sure we created the class try { pluginInfo.Plugin.OnLoad(); //load hte plugin } catch (Exception ex) { GUIWindowModOptions.DisplayErrorMessage("Assembly " + pluginInfo.Assembly.GetName().Name + " crashed in OnLoad"); AManager<GUIManager>.getInstance().AddTextLine("Assembly " + pluginInfo.Assembly.GetName().Name + " crashed in OnLoad with exception: " + ex.Message); pluginInfo.ShouldLoadPlugin = false; pluginInfo.IsLoaded = false; } try { pluginInfo.Plugin.OnEnable(); //enable the plugin } catch (Exception ex) { GUIWindowModOptions.DisplayErrorMessage("Assembly " + pluginInfo.Assembly.GetName().Name + " crashed in OnEnable"); AManager<GUIManager>.getInstance().AddTextLine("Assembly " + pluginInfo.Assembly.GetName().Name + " crashed in OnEnable with exception: " + ex.Message); pluginInfo.ShouldLoadPlugin = false; pluginInfo.IsLoaded = false; } pluginInfo.IsLoaded = true; } else { GUIWindowModOptions.DisplayErrorMessage("Plugin is null"); AManager<GUIManager>.getInstance().AddTextLine("Plugin is null"); pluginInfo.ShouldLoadPlugin = false; pluginInfo.IsLoaded = false; } } else { GUIWindowModOptions.DisplayErrorMessage("File name does not exist: '" + pluginInfo.FileName + "'"); AManager<GUIManager>.getInstance().AddTextLine("File name does not exist: '" + pluginInfo.FileName + "'"); pluginInfo.ShouldLoadPlugin = false; pluginInfo.IsLoaded = false; } }
/// <summary> /// This function will unload the plugin. Currently it does not work as the only way to unload a plugin /// is to unload the app domain it is in, Currently I cannot create app domains so all I do to unload plugin /// is flag it to make sure it does not get loaded on next start. /// </summary> /// <param name="pluginInfo">The plugin to get unlaoded from the mod.</param> public static void UnLoadPlugin(PluginInfo pluginInfo) { if (pluginInfo.Plugin != null) { pluginInfo.Plugin.OnDisable(); } if (pluginInfo.AppDomain != null) { AppDomain.Unload(pluginInfo.AppDomain); } pluginInfo.RemoveFromListAtClose = true; pluginInfo.ShouldLoadPlugin = false; pluginInfo.AppDomain = null; pluginInfo.Plugin = null; pluginInfo.Assembly = null; }
//this function will extract a plugin info out of the buffer. private static void HandlePluginFile(int numberOfPlugins, string buffer) { var index = buffer.IndexOf("PluginFileName" + numberOfPlugins, StringComparison.Ordinal); if (index == -1) return; var temp = buffer.Substring(index); string[] settings = temp.Split(); try { PluginInfo pluginInfo = new PluginInfo(settings[1].Trim()) { ShouldLoadPlugin = Convert.ToBoolean(settings[2].Trim()) }; PluginList.Add(pluginInfo); } catch (Exception e) { Console.WriteLine("Exception: " + e.Message); GUIManager.getInstance().AddTextLine("Failed to load settings for plugin '" + settings[1] + "' Plugin Info will be discarded."); } }
/// <summary> /// This function will load the plugin. It will take hte plugin info make sure the file exsits /// and then load the dll, find the class that needs to be loaded and then load that class. /// There is no checking in place to make sure the plugins do not conflict. /// </summary> /// <param name="pluginInfo">This is the plugin that will be loaded.</param> public static void loadPlugin(PluginInfo pluginInfo) { if (pluginInfo.isLoaded) { return; } pluginInfo.shouldLoadPlugin = true; FileInfo info = new FileInfo("./saves/" + pluginInfo.fileName); if (info != null && info.Exists == true) //make sure the file is there { try { //loading new domains do not work for some reason //pluginInfo.appDomain = AppDomain.CreateDomain("Testdomain"); //AssemblyName assemblyName = new AssemblyName(); //assemblyName.CodeBase = pluginInfo.fileName; //pluginInfo.assembly = pluginInfo.appDomain.Load(pluginInfo.fileName); pluginInfo.assembly = Assembly.LoadFile("./saves/" + pluginInfo.fileName); //load file if (pluginInfo.assembly != null) { Type[] types = pluginInfo.assembly.GetTypes(); //get all classes out of file for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (typeof(IPlugin).IsAssignableFrom(type) && type.IsClass) //find the one that is a plugin { pluginInfo.plugin = (IPlugin)Activator.CreateInstance(type); //create that class } } } else { GUIWindowModOptions.displayErrorMessage("Assemply is null on load of '" + pluginInfo.fileName + "'"); AManager <GUIManager> .getInstance().AddTextLine("Assemply is null on load of '" + pluginInfo.fileName + "'"); } } catch (Exception ex) { GUIWindowModOptions.displayErrorMessage("Could not load assembly: '" + pluginInfo.fileName + "'"); AManager <GUIManager> .getInstance().AddTextLine("Could not load assembly: '" + pluginInfo.fileName + "'"); AManager <GUIManager> .getInstance().AddTextLine(" " + ex.Message); pluginInfo.shouldLoadPlugin = false; pluginInfo.isLoaded = false; } if (pluginInfo.plugin != null) //make sure we created the class { try { pluginInfo.plugin.OnLoad(); //load hte plugin } catch (Exception ex) { GUIWindowModOptions.displayErrorMessage("Assembly " + pluginInfo.assembly.GetName().Name + " crashed in OnLoad"); AManager <GUIManager> .getInstance().AddTextLine("Assembly " + pluginInfo.assembly.GetName().Name + " crashed in OnLoad with exception: " + ex.Message); pluginInfo.shouldLoadPlugin = false; pluginInfo.isLoaded = false; } try { pluginInfo.plugin.OnEnable(); //enable the plugin } catch (Exception ex) { GUIWindowModOptions.displayErrorMessage("Assembly " + pluginInfo.assembly.GetName().Name + " crashed in OnEnable"); AManager <GUIManager> .getInstance().AddTextLine("Assembly " + pluginInfo.assembly.GetName().Name + " crashed in OnEnable with exception: " + ex.Message); pluginInfo.shouldLoadPlugin = false; pluginInfo.isLoaded = false; } pluginInfo.isLoaded = true; } else { GUIWindowModOptions.displayErrorMessage("Plugin is null"); AManager <GUIManager> .getInstance().AddTextLine("Plugin is null"); pluginInfo.shouldLoadPlugin = false; pluginInfo.isLoaded = false; } } else { GUIWindowModOptions.displayErrorMessage("File name does not exist: '" + pluginInfo.fileName + "'"); AManager <GUIManager> .getInstance().AddTextLine("File name does not exist: '" + pluginInfo.fileName + "'"); pluginInfo.shouldLoadPlugin = false; pluginInfo.isLoaded = false; } }
private void GetDllName() { Rect location = new Rect(Screen.width - 380, 300f, 320f, 120f); guiMgr.DrawWindow(location, "Add dll From Another Mod", false); if (location.Contains(Event.current.mousePosition)) { guiMgr.mouseInGUI = true; } GUI.Box(new Rect(location.xMin + 20f, location.yMin + 42f, location.width - 40f, 24f), string.Empty, guiMgr.boxStyle); tempName = guiMgr.DrawTextFieldCenteredWhite("dll Name", new Rect(location.xMin + 16f, location.yMin + 42f, location.width - 32f, 24f), tempName, 20); if (guiMgr.DrawButton(new Rect(location.xMin + 24f, location.yMin + 80f, 100f, 28f), "Confirm")) { if (IsValidFilename(tempName)) { FileInfo info = new FileInfo("./saves/" + tempName); if (info.Exists) {//{ ... }; //if (File.Exists("saves\\" + tempName)) { int index = SettingsManager.PluginList.FindIndex(x => x.FileName == tempName); if (index == -1) { //plugin is not in list make a new plugin PluginInfo newPlugin = new PluginInfo(tempName); SettingsManager.PluginList.Add(newPlugin); DisplayMessage("Plugin Added", "Activation Needed\n(Check the box next to it)"); } else { SettingsManager.PluginList[index].RemoveFromListAtClose = false; SettingsManager.PluginList[index].ShouldLoadPlugin = true; } } else { DisplayErrorMessage("File does not exist fileName: " + "saves\\" + tempName); } } else { DisplayErrorMessage("Invalid file name. Make sure there are no spaces"); } displayGetDllName = false; } if (guiMgr.DrawButton(new Rect(location.xMax - 24f - 100f, location.yMin + 80f, 100f, 28f), "Cancel")) { displayGetDllName = false; } }