diff --git a/.travis.yml b/.travis.yml
index c80b99209..82d9917ff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,7 +23,7 @@ install:
- sudo apt-get build-dep smuxi > /dev/null
- sudo apt-get install devscripts equivs > /dev/null
- sudo mk-build-deps --install debian/control > /dev/null
- - sudo apt-get install mono-devel nunit-console moreutils gtk-sharp2-gapi libgtkspell-dev > /dev/null
+ - sudo apt-get install mono-devel nunit-console moreutils gtk-sharp2-gapi libgtkspell-dev libmono-addins-cil-dev > /dev/null
script:
- ./autogen.sh MCS=/usr/bin/dmcs
diff --git a/configure.ac b/configure.ac
index d19501086..487e311f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -242,6 +242,9 @@ fi
AC_SUBST(XBUILD_FLAGS)
# Required Libraries
+PKG_CHECK_MODULES(MONO_ADDINS, mono-addins >= 1.0)
+AC_SUBST(MONO_ADDINS_LIBS)
+
PKG_CHECK_MODULES([LOG4NET], [log4net])
PKG_CHECK_EXISTS([nini-1.1], FOUND_NINI=yes, FOUND_NINI=no)
diff --git a/src/Engine-Campfire/Engine-Campfire.addin.xml b/src/Engine-Campfire/Engine-Campfire.addin.xml
new file mode 100644
index 000000000..4dc6f952a
--- /dev/null
+++ b/src/Engine-Campfire/Engine-Campfire.addin.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Engine-Campfire/Engine-Campfire.csproj b/src/Engine-Campfire/Engine-Campfire.csproj
index 4311eb553..cfcff9d22 100644
--- a/src/Engine-Campfire/Engine-Campfire.csproj
+++ b/src/Engine-Campfire/Engine-Campfire.csproj
@@ -69,4 +69,9 @@
ServiceStack.Interfaces
+
+
+ Enging-Campfire.addin.xml
+
+
\ No newline at end of file
diff --git a/src/Engine-Campfire/Makefile.am b/src/Engine-Campfire/Makefile.am
index 7c89dfd14..cebdb3b77 100644
--- a/src/Engine-Campfire/Makefile.am
+++ b/src/Engine-Campfire/Makefile.am
@@ -11,6 +11,9 @@ SOURCES = \
Protocols/Campfire/CampfireEventStream.cs \
Protocols/Campfire/DTO.cs
+RESOURCES = \
+ Engine-Campfire.addin.xml
+
REFERENCES = \
System \
System.Web \
@@ -36,5 +39,5 @@ include $(top_srcdir)/Makefile.include
all: $(ASSEMBLY_TARGET)
-$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES)
- $(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD)
+$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES) $(build_resources)
+ $(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD) $(build_resources_embed)
diff --git a/src/Engine-IRC/Engine-IRC.addin.xml b/src/Engine-IRC/Engine-IRC.addin.xml
new file mode 100644
index 000000000..9253c2670
--- /dev/null
+++ b/src/Engine-IRC/Engine-IRC.addin.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Engine-IRC/Engine-IRC.csproj b/src/Engine-IRC/Engine-IRC.csproj
index fba339f53..675ed2432 100644
--- a/src/Engine-IRC/Engine-IRC.csproj
+++ b/src/Engine-IRC/Engine-IRC.csproj
@@ -79,4 +79,9 @@
+
+
+ Engine-IRC.addin.xml
+
+
\ No newline at end of file
diff --git a/src/Engine-IRC/Makefile.am b/src/Engine-IRC/Makefile.am
index 8ed53dda7..bbc999a0d 100644
--- a/src/Engine-IRC/Makefile.am
+++ b/src/Engine-IRC/Makefile.am
@@ -71,7 +71,8 @@ FILES = \
DATA_FILES =
-RESOURCES =
+RESOURCES = \
+ Engine-IRC.addin.xml
EXTRAS = \
smuxi-engine-irc.pc.in
diff --git a/src/Engine-JabbR/Engine-JabbR.addin.xml b/src/Engine-JabbR/Engine-JabbR.addin.xml
new file mode 100644
index 000000000..e094fb9ce
--- /dev/null
+++ b/src/Engine-JabbR/Engine-JabbR.addin.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Engine-JabbR/Engine-JabbR.csproj b/src/Engine-JabbR/Engine-JabbR.csproj
index 9129518ea..2b381bf35 100644
--- a/src/Engine-JabbR/Engine-JabbR.csproj
+++ b/src/Engine-JabbR/Engine-JabbR.csproj
@@ -63,4 +63,9 @@
+
+
+ Engine-JabbR.addin.xml
+
+
\ No newline at end of file
diff --git a/src/Engine-JabbR/Makefile.am b/src/Engine-JabbR/Makefile.am
index 140958eb8..3a8a65f61 100644
--- a/src/Engine-JabbR/Makefile.am
+++ b/src/Engine-JabbR/Makefile.am
@@ -9,6 +9,9 @@ SOURCES = \
JabbrMessageBuilder.cs \
JabbrProtocolManager.cs
+RESOURCES = \
+ Engine-JabbR.addin.xml
+
REFERENCES = \
System \
System.Web \
@@ -33,5 +36,5 @@ include $(top_srcdir)/Makefile.include
all: $(ASSEMBLY_TARGET)
-$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES)
- $(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD)
+$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES) $(build_resources)
+ $(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD) $(build_resources_embed)
diff --git a/src/Engine-Twitter/Engine-Twitter.addin.xml b/src/Engine-Twitter/Engine-Twitter.addin.xml
new file mode 100644
index 000000000..4942b9e8e
--- /dev/null
+++ b/src/Engine-Twitter/Engine-Twitter.addin.xml
@@ -0,0 +1,22 @@
+
+
diff --git a/src/Engine-Twitter/Engine-Twitter.csproj b/src/Engine-Twitter/Engine-Twitter.csproj
index b1266fdf1..59b776950 100644
--- a/src/Engine-Twitter/Engine-Twitter.csproj
+++ b/src/Engine-Twitter/Engine-Twitter.csproj
@@ -69,4 +69,9 @@
+
+
+ Engine-Twitter.addin.xml
+
+
\ No newline at end of file
diff --git a/src/Engine-Twitter/Makefile.am b/src/Engine-Twitter/Makefile.am
index ee35f3351..ee63c25ec 100644
--- a/src/Engine-Twitter/Makefile.am
+++ b/src/Engine-Twitter/Makefile.am
@@ -11,6 +11,9 @@ SOURCES = \
Protocols/Twitter/TwitterMessageBuilder.cs \
Protocols/Twitter/TwitterSearchStream.cs
+RESOURCES = \
+ Engine-Twitter.addin.xml
+
REFERENCES = $(LOG4NET_LIBS) \
$(SMARTIRC4NET_LIBS) \
System.Web \
@@ -37,5 +40,5 @@ include $(top_srcdir)/Makefile.include
all: $(ASSEMBLY_TARGET)
-$(ASSEMBLY_TARGET): $(SOURCES) $(DLL_REFERENCES)
- $(MCS) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD)
+$(ASSEMBLY_TARGET): $(SOURCES) $(DLL_REFERENCES) $(build_resources)
+ $(MCS) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD) $(build_resources_embed)
diff --git a/src/Engine-XMPP/Engine-XMPP.addin.xml b/src/Engine-XMPP/Engine-XMPP.addin.xml
new file mode 100644
index 000000000..4cbd51819
--- /dev/null
+++ b/src/Engine-XMPP/Engine-XMPP.addin.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Engine-XMPP/Engine-XMPP.csproj b/src/Engine-XMPP/Engine-XMPP.csproj
index 0e8121077..7ce13f4cb 100644
--- a/src/Engine-XMPP/Engine-XMPP.csproj
+++ b/src/Engine-XMPP/Engine-XMPP.csproj
@@ -74,4 +74,9 @@
+
+
+ Engine-XMPP.addin.xml
+
+
diff --git a/src/Engine-XMPP/Makefile.am b/src/Engine-XMPP/Makefile.am
index f66ee9774..bd4f576c3 100644
--- a/src/Engine-XMPP/Makefile.am
+++ b/src/Engine-XMPP/Makefile.am
@@ -11,6 +11,9 @@ SOURCES = \
Protocols/Xmpp/XmppProtocolManager.cs \
Config/XmppPersonModel.cs
+RESOURCES = \
+ Engine-XMPP.addin.xml
+
REFERENCES = \
System \
System.Core \
@@ -35,5 +38,6 @@ include $(top_srcdir)/Makefile.include
all: $(ASSEMBLY_TARGET)
-$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES)
- $(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD)
+$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES) $(build_resources)
+ $(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$(ASSEMBLY_TARGET) $(SOURCES_BUILD) $(build_resources_embed)
+
diff --git a/src/Engine/AddinHost.cs b/src/Engine/AddinHost.cs
new file mode 100644
index 000000000..405112cf0
--- /dev/null
+++ b/src/Engine/AddinHost.cs
@@ -0,0 +1,25 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2016 Andrés G. Aragoneses
+//
+// Full GPL License:
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using Mono.Addins;
+
+[assembly:AddinRoot("smuxi-engine", "1.1")]
+[assembly:AddinDescription("This add-in root provides the engine extension point for add-in protocols to hook")]
+[assembly:ExtensionPoint("/Smuxi/Server/Engine", NodeName="Engine")]
diff --git a/src/Engine/Engine.csproj b/src/Engine/Engine.csproj
index 717332e9a..2cbe7fe67 100644
--- a/src/Engine/Engine.csproj
+++ b/src/Engine/Engine.csproj
@@ -44,6 +44,7 @@
+
@@ -150,6 +151,9 @@
+
+ mono-addins
+
diff --git a/src/Engine/Makefile.am b/src/Engine/Makefile.am
index 2168cec20..ffd81b6f1 100644
--- a/src/Engine/Makefile.am
+++ b/src/Engine/Makefile.am
@@ -49,6 +49,7 @@ all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG)
FILES = \
../AssemblyVersion.cs \
AssemblyInfo.cs \
+ AddinHost.cs \
CertificateValidator.cs \
CommandModel.cs \
Engine.cs \
@@ -134,6 +135,7 @@ REFERENCES = \
System.Xml \
Mono.Posix \
Mono.Data.Sqlite \
+ $(MONO_ADDINS_LIBS) \
$(NINI_LIBS) \
$(LOG4NET_LIBS) \
$(DB4O_LIBS) \
diff --git a/src/Engine/Protocols/ProtocolManagerFactory.cs b/src/Engine/Protocols/ProtocolManagerFactory.cs
index c0140ea0e..cda82e71e 100644
--- a/src/Engine/Protocols/ProtocolManagerFactory.cs
+++ b/src/Engine/Protocols/ProtocolManagerFactory.cs
@@ -8,6 +8,7 @@
* Smuxi - Smart MUltipleXed Irc
*
* Copyright (c) 2005-2006 Mirco Bauer
+ * Copyright (c) 2016 Andrés G. Aragoneses
*
* Full GPL License:
*
@@ -30,6 +31,9 @@
using System.IO;
using System.Reflection;
using System.Collections.Generic;
+
+using Mono.Addins;
+
using Smuxi.Common;
namespace Smuxi.Engine
@@ -50,80 +54,41 @@ public IList ProtocolManagerInfos {
public ProtocolManagerFactory()
{
}
-
- public void LoadProtocolManager(string filename)
+
+ public void LoadAllProtocolManagers(string path)
{
- Trace.Call(filename);
-
- Assembly asm = Assembly.LoadFile(filename);
- Type[] types;
- try {
- types = asm.GetTypes();
- } catch (ReflectionTypeLoadException ex) {
-#if LOG4NET
- _Logger.WarnFormat(
- "LoadProtocolManager(): GetTypes() on {0} threw exceptions",
- filename
- );
- foreach (var loaderEx in ex.LoaderExceptions) {
- _Logger.Warn(
- "LoadProtocolManager(): LoaderException: ",
- loaderEx
- );
- _Logger.Warn(
- "LoadProtocolManager(): LoaderException.InnerException: ",
- loaderEx.InnerException
- );
- }
-#endif
- types = ex.Types;
- }
-
- foreach (Type type in types) {
- if (type.IsAbstract) {
- continue;
- }
-
- Type foundType = null;
- Type[] interfaceTypes = type.GetInterfaces();
- foreach (Type interfaceType in interfaceTypes) {
- if (interfaceType == typeof(IProtocolManager)) {
+ Trace.Call(path);
+
+ AddinManager.AddinLoadError += (o, a) => {
+ //try {
+ // AddinManager.Registry.DisableAddin (a.AddinId);
+ //} catch {}
+ throw new Exception(a.Message, a.Exception);
+ };
+
+ AddinManager.Initialize(path);
+
+ var engineAddinNodes = AddinManager.GetExtensionNodes("/Smuxi/Server/Engine");
+
+ foreach(TypeExtensionNode protocolManagerNode in engineAddinNodes) {
+ Type foundType = protocolManagerNode.Type;
#if LOG4NET
- _Logger.Debug("LoadProtocolManager(): found " + type);
+ _Logger.Debug("LoadAllProtocolManagers(): found " + foundType);
#endif
- foundType = type;
- break;
- }
- }
-
- if (foundType == null) {
- continue;
- }
-
// let's get the info attribute
object[] attrs = foundType.GetCustomAttributes(typeof(ProtocolManagerInfoAttribute), true);
if (attrs == null || attrs.Length == 0) {
throw new ArgumentException("Assembly contains IProtocolManager but misses ProtocolManagerInfoAttribute", "filename");
//continue;
}
-
+
ProtocolManagerInfoAttribute attr = (ProtocolManagerInfoAttribute) attrs[0];
ProtocolManagerInfoModel info = new ProtocolManagerInfoModel(attr.Name, attr.Description, attr.Alias);
-
+
_ProtocolManagerTypes.Add(info, foundType);
}
}
- public void LoadAllProtocolManagers(string path)
- {
- Trace.Call(path);
-
- string[] filenames = Directory.GetFiles(path, "smuxi-engine*.dll");
- foreach (string filename in filenames) {
- LoadProtocolManager(filename);
- }
- }
-
public ProtocolManagerInfoModel GetProtocolManagerInfoByAlias(string alias)
{
foreach (ProtocolManagerInfoModel info in _ProtocolManagerTypes.Keys) {
@@ -155,7 +120,7 @@ public IProtocolManager CreateProtocolManager(ProtocolManagerInfoModel info, Ses
if (session == null) {
throw new ArgumentNullException("session");
}
-
+
Type type = _ProtocolManagerTypes[info];
return (IProtocolManager) Activator.CreateInstance(type, session);
}