/// <summary> /// Gets extended atributes for plugin /// </summary> /// <param name="plug">Plugin to lookup extra attributes</param> /// <returns>Extended atributes for plugin</returns> public static PluginAttribute GetAttributes(IMETAboltPlugin plug) { PluginAttribute a = null; foreach (Attribute attr in Attribute.GetCustomAttributes(plug.GetType())) { if (attr is PluginAttribute) { a = (PluginAttribute)attr; } } if (a == null) { a = new PluginAttribute(); a.Name = plug.GetType().FullName; } return(a); }
/// <summary> /// Scans assembly for supported types and loads it into it's own domain /// </summary> /// <param name="loadfilename">File name from which assembly was loaded</param> /// <param name="startPlugins">Start plugins found in the assembly after complilation</param> public void LoadAssembly(string loadfilename, Assembly assembly, bool startPlugins) { if (null != PluginsLoaded.Find((PluginInfo info) => { return(info.FileName == loadfilename); })) { Logger.Log("Plugin already loaded, skipping: " + loadfilename, Helpers.LogLevel.Info); if (startPlugins) { instance.TabConsole.DisplayNotificationInChat("Plugin already loaded, skipping: " + loadfilename); } return; } AppDomain domain = null; if (assembly == null) { // Don't load ourselves into a domain if (Path.GetFileName(Assembly.GetEntryAssembly().Location) == Path.GetFileName(loadfilename)) { assembly = Assembly.GetEntryAssembly(); } else { assembly = Assembly.LoadFile(loadfilename); /* Disable creation of domains for now * domain = AppDomain.CreateDomain("Domain for: " + loadfilename); * var loader = (RemoteLoader)domain.CreateInstanceAndUnwrap("METAbolt", "METAbolt.RemoteLoader"); * assembly = loader.Load(loadfilename); */ } } bool loadedTypesFromAssembly = false; foreach (Type type in assembly.GetTypes()) { if (typeof(IMETAboltPlugin).IsAssignableFrom(type)) { if (type.IsInterface) { continue; } try { IMETAboltPlugin plug = null; ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { typeof(METAboltInstance) }); if (constructorInfo != null) { plug = (IMETAboltPlugin)constructorInfo.Invoke(new[] { instance }); } else { constructorInfo = type.GetConstructor(new Type[] { }); if (constructorInfo != null) { plug = (IMETAboltPlugin)constructorInfo.Invoke(new object[0]); } else { Logger.Log("ERROR Constructing METAbolt Plugin: " + loadfilename + " because " + type + " has no usable constructor.", Helpers.LogLevel.Debug); continue; } } loadedTypesFromAssembly = true; PluginInfo info = new PluginInfo() { FileName = loadfilename, Plugin = plug, Started = false, Domain = domain }; lock (PluginsLoaded) PluginsLoaded.Add(info); if (startPlugins && plug != null) { try { plug.StartPlugin(instance); info.Started = true; } catch (Exception ex) { Logger.Log(string.Format("Failed starting plugin {0}:", type), Helpers.LogLevel.Error, ex); } } } catch (Exception ex) { Logger.Log("ERROR Constructing METAbolt Plugin: " + loadfilename + " because " + ex, Helpers.LogLevel.Debug); } } else { try { loadedTypesFromAssembly |= instance.CommandsManager.LoadType(type); loadedTypesFromAssembly |= instance.ContextActionManager.LoadType(type); } catch (Exception ex) { Logger.Log("ERROR in METAbolt Plugin: " + loadfilename + " Command: " + type + " because " + ex.Message + " " + ex.StackTrace, Helpers.LogLevel.Debug); } } } if (domain != null && !loadedTypesFromAssembly) { AppDomain.Unload(domain); } }