diff --git a/.travis.yml b/.travis.yml
index 6e9dfbbbe..bd005d5de 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,7 +19,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
- sudo apt-get install libnunit-cil-dev > /dev/null
script:
diff --git a/configure.ac b/configure.ac
index c8b60427c..711fbc55f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -242,11 +242,15 @@ fi
AC_SUBST(XBUILD_FLAGS)
# Required Libraries
-
if test "x$(uname)" != "xDarwin"; then
+ PKG_CHECK_MODULES(MONO_ADDINS, mono-addins >= 1.0)
+ AC_SUBST(MONO_ADDINS_LIBS)
+ AM_CONDITIONAL([BUNDLE_MONO_ADDINS], false)
+
PKG_CHECK_MODULES([LOG4NET], [log4net])
AM_CONDITIONAL([BUNDLE_LOG4NET], false)
else
+ AM_CONDITIONAL([BUNDLE_MONO_ADDINS], true)
AM_CONDITIONAL([BUNDLE_LOG4NET], true)
fi
diff --git a/lib/Mono.Addins.dll b/lib/Mono.Addins.dll
new file mode 100644
index 000000000..07eeda1ef
Binary files /dev/null and b/lib/Mono.Addins.dll differ
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 b4fbc3cad..ae6dc0f24 100644
--- a/src/Engine-IRC/Makefile.am
+++ b/src/Engine-IRC/Makefile.am
@@ -76,7 +76,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 7fd4b4381..b76c43616 100644
--- a/src/Engine-JabbR/Makefile.am
+++ b/src/Engine-JabbR/Makefile.am
@@ -16,6 +16,9 @@ SOURCES = \
JabbrMessageBuilder.cs \
JabbrProtocolManager.cs
+RESOURCES = \
+ Engine-JabbR.addin.xml
+
REFERENCES = \
System \
System.Web \
@@ -40,5 +43,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 37a0231fa..f06f91e13 100644
--- a/src/Engine-Twitter/Makefile.am
+++ b/src/Engine-Twitter/Makefile.am
@@ -18,6 +18,9 @@ SOURCES = \
Protocols/Twitter/TwitterMessageBuilder.cs \
Protocols/Twitter/TwitterSearchStream.cs
+RESOURCES = \
+ Engine-Twitter.addin.xml
+
REFERENCES = $(LOG4NET_REF_LIBS) \
$(SMARTIRC4NET_LIBS) \
System.Web \
@@ -44,5 +47,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 3eb062c8d..43770252c 100644
--- a/src/Engine-XMPP/Makefile.am
+++ b/src/Engine-XMPP/Makefile.am
@@ -18,6 +18,9 @@ SOURCES = \
Protocols/Xmpp/XmppProtocolManager.cs \
Config/XmppPersonModel.cs
+RESOURCES = \
+ Engine-XMPP.addin.xml
+
REFERENCES = \
System \
System.Core \
@@ -42,5 +45,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 2972c4406..6c670c79c 100644
--- a/src/Engine/Makefile.am
+++ b/src/Engine/Makefile.am
@@ -33,6 +33,13 @@ SMUXI_COMMON_DLL_SOURCE=../../bin/debug/smuxi-common.dll
endif
+if BUNDLE_MONO_ADDINS
+MONO_ADDINS_DLL_SOURCE=../../lib/Mono.Addins.dll
+MONO_ADDINS_REF_LIBS=-r:$(MONO_ADDINS_DLL_SOURCE)
+else
+MONO_ADDINS_REF_LIBS=$(MONO_ADDINS_LIBS)
+endif
+
if BUNDLE_LOG4NET
LOG4NET_DLL_SOURCE=../../lib/log4net.dll
LOG4NET_REF_LIBS=-r:$(LOG4NET_DLL_SOURCE)
@@ -61,6 +68,7 @@ all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG)
FILES = \
../AssemblyVersion.cs \
AssemblyInfo.cs \
+ AddinHost.cs \
CertificateValidator.cs \
CommandModel.cs \
Engine.cs \
@@ -146,6 +154,7 @@ REFERENCES = \
System.Xml \
Mono.Posix \
Mono.Data.Sqlite \
+ $(MONO_ADDINS_REF_LIBS) \
$(NINI_REF_LIBS) \
$(LOG4NET_REF_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);
}