diff options
author | Sean Dague | 2009-02-16 12:20:31 +0000 |
---|---|---|
committer | Sean Dague | 2009-02-16 12:20:31 +0000 |
commit | f4bec00057fb6987f4ea166347156e1abb985ec1 (patch) | |
tree | a8b4e9461b077f1e2e36876d0aea263eb2ceb177 | |
parent | cosmetic: adding region name to logging statement (diff) | |
download | opensim-SC_OLD-f4bec00057fb6987f4ea166347156e1abb985ec1.zip opensim-SC_OLD-f4bec00057fb6987f4ea166347156e1abb985ec1.tar.gz opensim-SC_OLD-f4bec00057fb6987f4ea166347156e1abb985ec1.tar.bz2 opensim-SC_OLD-f4bec00057fb6987f4ea166347156e1abb985ec1.tar.xz |
From: Alan Webb <awebb@linux.vnet.ibm.com>
The change makes two principal implementation changes:
[1] It removes the hard coded set of possible asset server client
implementations, allowing any arbitrary implementation that has been
identified to the PluginLoader as an appropriate extension. The
extension point for asset server client extension
is /OpenSim/AssetServerClient. All of the old configuration rules have
been preserved, and any of the legacy configuration values will still
work as they did before, except the implementation is now loaded as a
plug-in, rather than as a hard-coded instantiation of a specific class.
The re-hashing of IAssetServer as an extension of IPlugin made upgrading
of the implementation classes a necessity.
Caveat: I have not been able to meaningfully test the crypto-grid
clients. I believe they should work correctly, but the refactoring
necessary to handle plug-in based initialization (vs constructor-based
initialisation) admits the possibility of a problem.
[2] The asset cache implementation, previously introduce as a hard-code
class instantiation is now implemented as an IPlugin. Once again the
previous (configurationless) behavior has been preserved. But now it is
possible for those interested in experimenting with cache technologies
to do so simply by introducing a new extension for the asset cache
extension point (/OpenSim/AssetCache).
I've tested all of the configuration settings, after applying the patch
to a newly extracted tree, and they seem to work OK.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Communications/Cache/AssetCache.cs | 80 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Cache/AssetServerBase.cs | 55 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Cache/CryptoGridAssetClient.cs | 48 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Cache/FileAssetClient.cs | 37 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Cache/GridAssetClient.cs | 31 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Cache/SQLAssetServer.cs | 29 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Resources/AssetCache.addin.xml | 17 | ||||
-rw-r--r-- | OpenSim/Framework/ConfigSettings.cs | 8 | ||||
-rw-r--r-- | OpenSim/Framework/IAssetCache.cs | 22 | ||||
-rw-r--r-- | OpenSim/Framework/IAssetServer.cs | 59 | ||||
-rw-r--r-- | OpenSim/Region/Application/ConfigurationLoader.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Application/OpenSimBase.cs | 168 | ||||
-rw-r--r-- | bin/OpenSim.addin.xml | 8 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 13 | ||||
-rw-r--r-- | prebuild.xml | 1 |
15 files changed, 530 insertions, 47 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index 1c8f9d6..76c6045 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs | |||
@@ -48,8 +48,67 @@ namespace OpenSim.Framework.Communications.Cache | |||
48 | /// sends packetised data directly back to the client. The only point where they meet is AssetReceived() and | 48 | /// sends packetised data directly back to the client. The only point where they meet is AssetReceived() and |
49 | /// AssetNotFound(), which means they do share the same asset and texture caches.I agr | 49 | /// AssetNotFound(), which means they do share the same asset and texture caches.I agr |
50 | 50 | ||
51 | public class AssetCache : IAssetCache, IAssetReceiver | 51 | public class AssetCache : IAssetCache |
52 | { | 52 | { |
53 | |||
54 | #region IPlugin | ||
55 | |||
56 | /// <summary> | ||
57 | /// The methods and properties in this section are needed to | ||
58 | /// support the IPlugin interface. They cann all be overridden | ||
59 | /// as needed by a derived class. | ||
60 | /// </summary> | ||
61 | |||
62 | public virtual string Name | ||
63 | { | ||
64 | get { return "OpenSim.Framework.Communications.Cache.AssetCache"; } | ||
65 | } | ||
66 | |||
67 | public virtual string Version | ||
68 | { | ||
69 | get { return "1.0"; } | ||
70 | } | ||
71 | |||
72 | public virtual void Initialise() | ||
73 | { | ||
74 | m_log.Debug("[ASSET CACHE]: Asset cache null initialisation"); | ||
75 | } | ||
76 | |||
77 | public virtual void Initialise(IAssetServer assetServer) | ||
78 | { | ||
79 | m_log.Debug("[ASSET CACHE]: Asset cache server-specified initialisation"); | ||
80 | m_log.InfoFormat("[ASSET CACHE]: Asset cache initialisation [{0}/{1}]", Name, Version); | ||
81 | |||
82 | Initialize(); | ||
83 | |||
84 | m_assetServer = assetServer; | ||
85 | m_assetServer.SetReceiver(this); | ||
86 | |||
87 | Thread assetCacheThread = new Thread(RunAssetManager); | ||
88 | assetCacheThread.Name = "AssetCacheThread"; | ||
89 | assetCacheThread.IsBackground = true; | ||
90 | assetCacheThread.Start(); | ||
91 | ThreadTracker.Add(assetCacheThread); | ||
92 | |||
93 | } | ||
94 | |||
95 | public virtual void Initialise(ConfigSettings settings, IAssetServer assetServer) | ||
96 | { | ||
97 | m_log.Debug("[ASSET CACHE]: Asset cache configured initialisation"); | ||
98 | Initialise(assetServer); | ||
99 | } | ||
100 | |||
101 | public AssetCache() | ||
102 | { | ||
103 | m_log.Debug("[ASSET CACHE]: Asset cache (plugin constructor)"); | ||
104 | } | ||
105 | |||
106 | public void Dispose() | ||
107 | { | ||
108 | } | ||
109 | |||
110 | #endregion | ||
111 | |||
53 | protected ICache m_memcache = new SimpleMemoryCache(); | 112 | protected ICache m_memcache = new SimpleMemoryCache(); |
54 | 113 | ||
55 | private static readonly ILog m_log | 114 | private static readonly ILog m_log |
@@ -83,7 +142,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
83 | /// <summary> | 142 | /// <summary> |
84 | /// The 'server' from which assets can be requested and to which assets are persisted. | 143 | /// The 'server' from which assets can be requested and to which assets are persisted. |
85 | /// </summary> | 144 | /// </summary> |
86 | private readonly IAssetServer m_assetServer; | 145 | private IAssetServer m_assetServer; |
87 | 146 | ||
88 | public IAssetServer AssetServer | 147 | public IAssetServer AssetServer |
89 | { | 148 | { |
@@ -132,17 +191,8 @@ namespace OpenSim.Framework.Communications.Cache | |||
132 | /// <param name="assetServer"></param> | 191 | /// <param name="assetServer"></param> |
133 | public AssetCache(IAssetServer assetServer) | 192 | public AssetCache(IAssetServer assetServer) |
134 | { | 193 | { |
135 | m_log.Info("[ASSET CACHE]: Creating Asset cache"); | 194 | m_log.Info("[ASSET CACHE]: Asset cache direct constructor"); |
136 | Initialize(); | 195 | Initialise(assetServer); |
137 | |||
138 | m_assetServer = assetServer; | ||
139 | m_assetServer.SetReceiver(this); | ||
140 | |||
141 | Thread assetCacheThread = new Thread(RunAssetManager); | ||
142 | assetCacheThread.Name = "AssetCacheThread"; | ||
143 | assetCacheThread.IsBackground = true; | ||
144 | assetCacheThread.Start(); | ||
145 | ThreadTracker.Add(assetCacheThread); | ||
146 | } | 196 | } |
147 | 197 | ||
148 | /// <summary> | 198 | /// <summary> |
@@ -342,7 +392,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
342 | } | 392 | } |
343 | 393 | ||
344 | // See IAssetReceiver | 394 | // See IAssetReceiver |
345 | public void AssetReceived(AssetBase asset, bool IsTexture) | 395 | public virtual void AssetReceived(AssetBase asset, bool IsTexture) |
346 | { | 396 | { |
347 | 397 | ||
348 | AssetInfo assetInf = new AssetInfo(asset); | 398 | AssetInfo assetInf = new AssetInfo(asset); |
@@ -393,7 +443,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
393 | } | 443 | } |
394 | 444 | ||
395 | // See IAssetReceiver | 445 | // See IAssetReceiver |
396 | public void AssetNotFound(UUID assetID, bool IsTexture) | 446 | public virtual void AssetNotFound(UUID assetID, bool IsTexture) |
397 | { | 447 | { |
398 | // m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID); | 448 | // m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID); |
399 | 449 | ||
diff --git a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs index 5c902ec..7bb2ab9 100644 --- a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs +++ b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs | |||
@@ -46,6 +46,61 @@ namespace OpenSim.Framework.Communications.Cache | |||
46 | protected Thread m_localAssetServerThread; | 46 | protected Thread m_localAssetServerThread; |
47 | protected IAssetDataPlugin m_assetProvider; | 47 | protected IAssetDataPlugin m_assetProvider; |
48 | 48 | ||
49 | #region IPlugin | ||
50 | |||
51 | /// <summary> | ||
52 | /// The methods and properties in this region are needed to implement | ||
53 | /// the IPlugin interface and its local extensions. | ||
54 | /// These can all be overridden as appropriate by a derived class. | ||
55 | /// These methods are only applicable when a class is loaded by the | ||
56 | /// IPlugin mechanism. | ||
57 | /// | ||
58 | /// Note that in the case of AssetServerBase, all initialization is | ||
59 | /// performed by the default constructor, so nothing additional is | ||
60 | /// required here. A derived class may wish to do more. | ||
61 | /// </summary> | ||
62 | |||
63 | public virtual string Name | ||
64 | { | ||
65 | // get { return "OpenSim.Framework.Communications.Cache.AssetServerBase"; } | ||
66 | get { return "AssetServerBase"; } | ||
67 | } | ||
68 | |||
69 | public virtual string Version | ||
70 | { | ||
71 | get { return "1.0"; } | ||
72 | } | ||
73 | |||
74 | public virtual void Initialise() | ||
75 | { | ||
76 | m_log.Debug("[ASSET SERVER]: IPlugin null initialization"); | ||
77 | } | ||
78 | |||
79 | public virtual void Initialise(ConfigSettings settings) | ||
80 | { | ||
81 | m_log.Debug("[ASSET SERVER]: IPlugin null configured initialization(1)"); | ||
82 | m_log.InfoFormat("[ASSET SERVER]: Initializing client [{0}/{1}", Name, Version); | ||
83 | } | ||
84 | |||
85 | public virtual void Initialise(ConfigSettings settings, string p_url) | ||
86 | { | ||
87 | m_log.Debug("[ASSET SERVER]: IPlugin null configured initialization(2)"); | ||
88 | m_log.InfoFormat("[ASSET SERVER]: Initializing client [{0}/{1}", Name, Version); | ||
89 | } | ||
90 | |||
91 | public virtual void Initialise(ConfigSettings settings, string p_url, string p_dir, bool p_t) | ||
92 | { | ||
93 | m_log.Debug("[ASSET SERVER]: IPlugin null configured initialization(3)"); | ||
94 | m_log.InfoFormat("[ASSET SERVER]: Initializing client [{0}/{1}", Name, Version); | ||
95 | } | ||
96 | |||
97 | public virtual void Dispose() | ||
98 | { | ||
99 | m_log.Debug("[ASSET SERVER]: dispose"); | ||
100 | } | ||
101 | |||
102 | #endregion | ||
103 | |||
49 | public IAssetDataPlugin AssetProviderPlugin | 104 | public IAssetDataPlugin AssetProviderPlugin |
50 | { | 105 | { |
51 | get { return m_assetProvider; } | 106 | get { return m_assetProvider; } |
diff --git a/OpenSim/Framework/Communications/Cache/CryptoGridAssetClient.cs b/OpenSim/Framework/Communications/Cache/CryptoGridAssetClient.cs index 55db289..0f4e8ac 100644 --- a/OpenSim/Framework/Communications/Cache/CryptoGridAssetClient.cs +++ b/OpenSim/Framework/Communications/Cache/CryptoGridAssetClient.cs | |||
@@ -44,9 +44,37 @@ namespace OpenSim.Framework.Communications.Cache | |||
44 | { | 44 | { |
45 | public class CryptoGridAssetClient : AssetServerBase | 45 | public class CryptoGridAssetClient : AssetServerBase |
46 | { | 46 | { |
47 | |||
48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private string _assetServerUrl; | ||
51 | private bool m_encryptOnUpload; | ||
52 | private RjinKeyfile m_encryptKey; | ||
53 | private readonly Dictionary<string,RjinKeyfile> m_keyfiles = new Dictionary<string, RjinKeyfile>(); | ||
54 | |||
55 | #region IPlugin | ||
56 | |||
57 | public override string Name | ||
58 | { | ||
59 | get { return "Crypto"; } | ||
60 | } | ||
61 | |||
62 | public override string Version | ||
63 | { | ||
64 | get { return "1.0"; } | ||
65 | } | ||
66 | |||
67 | public override void Initialise(ConfigSettings p_set, string p_url, string p_dir, bool p_t) | ||
68 | { | ||
69 | m_log.Debug("[CRYPTOGRID] Plugin configured initialisation"); | ||
70 | Initialise(p_url, p_dir, p_t); | ||
71 | } | ||
72 | |||
73 | #endregion | ||
74 | |||
47 | #region Keyfile Classes | 75 | #region Keyfile Classes |
48 | [Serializable] | 76 | [Serializable] |
49 | private class RjinKeyfile | 77 | public class RjinKeyfile |
50 | { | 78 | { |
51 | public string Secret; | 79 | public string Secret; |
52 | public string AlsoKnownAs; | 80 | public string AlsoKnownAs; |
@@ -94,7 +122,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
94 | /// this may not be the most efficient way of handling encryption, so - as | 122 | /// this may not be the most efficient way of handling encryption, so - as |
95 | /// soon as you feel comfortable with it - you may want to redesign this class. | 123 | /// soon as you feel comfortable with it - you may want to redesign this class. |
96 | /// </summary> | 124 | /// </summary> |
97 | private class UtilRijndael | 125 | public class UtilRijndael |
98 | { | 126 | { |
99 | /// <summary> | 127 | /// <summary> |
100 | /// Encrypts specified plaintext using Rijndael symmetric key algorithm | 128 | /// Encrypts specified plaintext using Rijndael symmetric key algorithm |
@@ -332,15 +360,19 @@ namespace OpenSim.Framework.Communications.Cache | |||
332 | } | 360 | } |
333 | #endregion | 361 | #endregion |
334 | 362 | ||
335 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 363 | public CryptoGridAssetClient() {} |
336 | |||
337 | private readonly string _assetServerUrl; | ||
338 | private readonly bool m_encryptOnUpload; | ||
339 | private readonly RjinKeyfile m_encryptKey; | ||
340 | private readonly Dictionary<string,RjinKeyfile> m_keyfiles = new Dictionary<string, RjinKeyfile>(); | ||
341 | 364 | ||
342 | public CryptoGridAssetClient(string serverUrl, string keydir, bool decOnly) | 365 | public CryptoGridAssetClient(string serverUrl, string keydir, bool decOnly) |
343 | { | 366 | { |
367 | m_log.Debug("[CRYPTOGRID] Direct constructor"); | ||
368 | Initialise(serverUrl, keydir, decOnly); | ||
369 | } | ||
370 | |||
371 | public void Initialise(string serverUrl, string keydir, bool decOnly) | ||
372 | { | ||
373 | |||
374 | m_log.Debug("[CRYPTOGRID] Common constructor"); | ||
375 | |||
344 | _assetServerUrl = serverUrl; | 376 | _assetServerUrl = serverUrl; |
345 | 377 | ||
346 | string[] keys = Directory.GetFiles(keydir, "*.deckey"); | 378 | string[] keys = Directory.GetFiles(keydir, "*.deckey"); |
diff --git a/OpenSim/Framework/Communications/Cache/FileAssetClient.cs b/OpenSim/Framework/Communications/Cache/FileAssetClient.cs index 9a60b53..e6574a1 100644 --- a/OpenSim/Framework/Communications/Cache/FileAssetClient.cs +++ b/OpenSim/Framework/Communications/Cache/FileAssetClient.cs | |||
@@ -26,16 +26,49 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.IO; | 28 | using System.IO; |
29 | using System.Reflection; | ||
30 | using log4net; | ||
29 | using System.Xml.Serialization; | 31 | using System.Xml.Serialization; |
30 | 32 | ||
31 | namespace OpenSim.Framework.Communications.Cache | 33 | namespace OpenSim.Framework.Communications.Cache |
32 | { | 34 | { |
33 | public class FileAssetClient : AssetServerBase | 35 | public class FileAssetClient : AssetServerBase |
34 | { | 36 | { |
35 | private readonly string m_dir; | 37 | |
38 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
39 | |||
40 | #region IPlugin | ||
41 | |||
42 | public override string Name | ||
43 | { | ||
44 | get { return "File"; } | ||
45 | } | ||
46 | |||
47 | public override string Version | ||
48 | { | ||
49 | get { return "1.0"; } | ||
50 | } | ||
51 | |||
52 | public override void Initialise(ConfigSettings p_set, string p_url) | ||
53 | { | ||
54 | m_log.Debug("[FILEASSET] Plugin configured initialisation"); | ||
55 | Initialise(p_url); | ||
56 | } | ||
57 | |||
58 | #endregion | ||
59 | |||
60 | private string m_dir; | ||
36 | private readonly XmlSerializer m_xs = new XmlSerializer(typeof(AssetBase)); | 61 | private readonly XmlSerializer m_xs = new XmlSerializer(typeof(AssetBase)); |
37 | 62 | ||
38 | public FileAssetClient(string dir) | 63 | public FileAssetClient() {} |
64 | |||
65 | public FileAssetClient(string p_url) | ||
66 | { | ||
67 | m_log.Debug("[FILEASSET] Direct constructor"); | ||
68 | Initialise(p_url); | ||
69 | } | ||
70 | |||
71 | public void Initialise(string dir) | ||
39 | { | 72 | { |
40 | if (!Directory.Exists(dir)) | 73 | if (!Directory.Exists(dir)) |
41 | { | 74 | { |
diff --git a/OpenSim/Framework/Communications/Cache/GridAssetClient.cs b/OpenSim/Framework/Communications/Cache/GridAssetClient.cs index 1cc9833..6522ad0 100644 --- a/OpenSim/Framework/Communications/Cache/GridAssetClient.cs +++ b/OpenSim/Framework/Communications/Cache/GridAssetClient.cs | |||
@@ -36,11 +36,40 @@ namespace OpenSim.Framework.Communications.Cache | |||
36 | { | 36 | { |
37 | public class GridAssetClient : AssetServerBase | 37 | public class GridAssetClient : AssetServerBase |
38 | { | 38 | { |
39 | |||
40 | #region IPlugin | ||
41 | |||
42 | public override string Name | ||
43 | { | ||
44 | get { return "Grid"; } | ||
45 | } | ||
46 | |||
47 | public override string Version | ||
48 | { | ||
49 | get { return "1.0"; } | ||
50 | } | ||
51 | |||
52 | public override void Initialise(ConfigSettings p_set, string p_url) | ||
53 | { | ||
54 | m_log.Debug("[GRIDASSET] Plugin configured initialisation"); | ||
55 | Initialise(p_url); | ||
56 | } | ||
57 | |||
58 | #endregion | ||
59 | |||
39 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 60 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
40 | 61 | ||
41 | private string _assetServerUrl; | 62 | private string _assetServerUrl; |
42 | 63 | ||
43 | public GridAssetClient(string serverUrl) | 64 | public GridAssetClient() {} |
65 | |||
66 | public GridAssetClient(string p_url) | ||
67 | { | ||
68 | m_log.Debug("[GRIDASSET] Direct constructor"); | ||
69 | Initialise(p_url); | ||
70 | } | ||
71 | |||
72 | public void Initialise(string serverUrl) | ||
44 | { | 73 | { |
45 | _assetServerUrl = serverUrl; | 74 | _assetServerUrl = serverUrl; |
46 | } | 75 | } |
diff --git a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs index 6266bf0..5274288 100644 --- a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs +++ b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs | |||
@@ -34,10 +34,39 @@ namespace OpenSim.Framework.Communications.Cache | |||
34 | { | 34 | { |
35 | public class SQLAssetServer : AssetServerBase | 35 | public class SQLAssetServer : AssetServerBase |
36 | { | 36 | { |
37 | |||
37 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 38 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
38 | 39 | ||
40 | #region IPlugin | ||
41 | |||
42 | public override string Name | ||
43 | { | ||
44 | get { return "SQL"; } | ||
45 | } | ||
46 | |||
47 | public override string Version | ||
48 | { | ||
49 | get { return "1.0"; } | ||
50 | } | ||
51 | |||
52 | public override void Initialise(ConfigSettings p_set) | ||
53 | { | ||
54 | m_log.Debug("[SQLASSET] Plugin configured initialisation"); | ||
55 | Initialise(p_set.StandaloneAssetPlugin,p_set.StandaloneAssetSource); | ||
56 | } | ||
57 | |||
58 | #endregion | ||
59 | |||
60 | public SQLAssetServer() {} | ||
61 | |||
39 | public SQLAssetServer(string pluginName, string connect) | 62 | public SQLAssetServer(string pluginName, string connect) |
40 | { | 63 | { |
64 | m_log.Debug("[SQLASSET] Direct constructor"); | ||
65 | Initialise(pluginName, connect); | ||
66 | } | ||
67 | |||
68 | public void Initialise(string pluginName, string connect) | ||
69 | { | ||
41 | AddPlugin(pluginName, connect); | 70 | AddPlugin(pluginName, connect); |
42 | } | 71 | } |
43 | 72 | ||
diff --git a/OpenSim/Framework/Communications/Resources/AssetCache.addin.xml b/OpenSim/Framework/Communications/Resources/AssetCache.addin.xml new file mode 100644 index 0000000..61a9f0f --- /dev/null +++ b/OpenSim/Framework/Communications/Resources/AssetCache.addin.xml | |||
@@ -0,0 +1,17 @@ | |||
1 | <Addin id="OpenSim.Framework.Communications" version="1.0"> | ||
2 | <Runtime> | ||
3 | <Import assembly="OpenSim.Framework.Communications.dll"/> | ||
4 | </Runtime> | ||
5 | <Dependencies> | ||
6 | <Addin id="OpenSim" version="0.5" /> | ||
7 | </Dependencies> | ||
8 | <Extension path="/OpenSim/AssetCache"> | ||
9 | <Cache id="Default" provider="Default" type="OpenSim.Framework.Communications.Cache.AssetCache" /> | ||
10 | </Extension> | ||
11 | <Extension path="/OpenSim/AssetServerClient"> | ||
12 | <ServerClient id="Crypto" provider="Crypto" type="OpenSim.Framework.Communications.Cache.CryptoGridAssetClient" /> | ||
13 | <ServerClient id="Grid" provider="Grid" type="OpenSim.Framework.Communications.Cache.GridAssetClient" /> | ||
14 | <ServerClient id="File" provider="File" type="OpenSim.Framework.Communications.Cache.FileAssetClient" /> | ||
15 | <ServerClient id="SQL" provider="SQL" type="OpenSim.Framework.Communications.Cache.SQLAssetServer" /> | ||
16 | </Extension> | ||
17 | </Addin> | ||
diff --git a/OpenSim/Framework/ConfigSettings.cs b/OpenSim/Framework/ConfigSettings.cs index 3d66311..5f5e16f 100644 --- a/OpenSim/Framework/ConfigSettings.cs +++ b/OpenSim/Framework/ConfigSettings.cs | |||
@@ -156,6 +156,14 @@ namespace OpenSim.Framework | |||
156 | set { m_assetStorage = value; } | 156 | set { m_assetStorage = value; } |
157 | } | 157 | } |
158 | 158 | ||
159 | private string m_assetCache; | ||
160 | |||
161 | public string AssetCache | ||
162 | { | ||
163 | get { return m_assetCache; } | ||
164 | set { m_assetCache = value; } | ||
165 | } | ||
166 | |||
159 | protected string m_storageConnectionString; | 167 | protected string m_storageConnectionString; |
160 | 168 | ||
161 | public string StorageConnectionString | 169 | public string StorageConnectionString |
diff --git a/OpenSim/Framework/IAssetCache.cs b/OpenSim/Framework/IAssetCache.cs index b90dffc..22f5755 100644 --- a/OpenSim/Framework/IAssetCache.cs +++ b/OpenSim/Framework/IAssetCache.cs | |||
@@ -33,7 +33,7 @@ namespace OpenSim.Framework | |||
33 | 33 | ||
34 | public delegate void AssetRequestCallback(UUID assetId, AssetBase asset); | 34 | public delegate void AssetRequestCallback(UUID assetId, AssetBase asset); |
35 | 35 | ||
36 | public interface IAssetCache : IAssetReceiver | 36 | public interface IAssetCache : IAssetReceiver, IPlugin |
37 | { | 37 | { |
38 | 38 | ||
39 | IAssetServer AssetServer { get; } | 39 | IAssetServer AssetServer { get; } |
@@ -47,5 +47,25 @@ namespace OpenSim.Framework | |||
47 | void ExpireAsset(UUID assetID); | 47 | void ExpireAsset(UUID assetID); |
48 | void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest); | 48 | void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest); |
49 | 49 | ||
50 | void Initialise(ConfigSettings cs, IAssetServer server); | ||
51 | |||
52 | } | ||
53 | |||
54 | public class AssetCachePluginInitialiser : PluginInitialiserBase | ||
55 | { | ||
56 | private ConfigSettings config; | ||
57 | private IAssetServer server; | ||
58 | |||
59 | public AssetCachePluginInitialiser (ConfigSettings p_sv, IAssetServer p_as) | ||
60 | { | ||
61 | config = p_sv; | ||
62 | server = p_as; | ||
63 | } | ||
64 | public override void Initialise (IPlugin plugin) | ||
65 | { | ||
66 | IAssetCache p = plugin as IAssetCache; | ||
67 | p.Initialise (config, server); | ||
68 | } | ||
50 | } | 69 | } |
70 | |||
51 | } | 71 | } |
diff --git a/OpenSim/Framework/IAssetServer.cs b/OpenSim/Framework/IAssetServer.cs index d2f5ce7..0d9afe9 100644 --- a/OpenSim/Framework/IAssetServer.cs +++ b/OpenSim/Framework/IAssetServer.cs | |||
@@ -32,8 +32,11 @@ namespace OpenSim.Framework | |||
32 | /// <summary> | 32 | /// <summary> |
33 | /// Description of IAssetServer. | 33 | /// Description of IAssetServer. |
34 | /// </summary> | 34 | /// </summary> |
35 | public interface IAssetServer | 35 | public interface IAssetServer : IPlugin |
36 | { | 36 | { |
37 | void Initialise(ConfigSettings settings); | ||
38 | void Initialise(ConfigSettings settings, string url, string dir, bool test); | ||
39 | void Initialise(ConfigSettings settings, string url); | ||
37 | void SetReceiver(IAssetReceiver receiver); | 40 | void SetReceiver(IAssetReceiver receiver); |
38 | void RequestAsset(UUID assetID, bool isTexture); | 41 | void RequestAsset(UUID assetID, bool isTexture); |
39 | void StoreAsset(AssetBase asset); | 42 | void StoreAsset(AssetBase asset); |
@@ -62,8 +65,62 @@ namespace OpenSim.Framework | |||
62 | void AssetNotFound(UUID assetID, bool IsTexture); | 65 | void AssetNotFound(UUID assetID, bool IsTexture); |
63 | } | 66 | } |
64 | 67 | ||
68 | public class AssetServerClientPluginInitialiser : PluginInitialiserBase | ||
69 | { | ||
70 | private ConfigSettings config; | ||
71 | |||
72 | public AssetServerClientPluginInitialiser (ConfigSettings p_sv) | ||
73 | { | ||
74 | config = p_sv; | ||
75 | } | ||
76 | public override void Initialise (IPlugin plugin) | ||
77 | { | ||
78 | IAssetServer p = plugin as IAssetServer; | ||
79 | p.Initialise (config); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | public class LegacyAssetServerClientPluginInitialiser : PluginInitialiserBase | ||
84 | { | ||
85 | private ConfigSettings config; | ||
86 | private string assetURL; | ||
87 | |||
88 | public LegacyAssetServerClientPluginInitialiser (ConfigSettings p_sv, string p_url) | ||
89 | { | ||
90 | config = p_sv; | ||
91 | assetURL = p_url; | ||
92 | } | ||
93 | public override void Initialise (IPlugin plugin) | ||
94 | { | ||
95 | IAssetServer p = plugin as IAssetServer; | ||
96 | p.Initialise (config, assetURL); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | public class CryptoAssetServerClientPluginInitialiser : PluginInitialiserBase | ||
101 | { | ||
102 | private ConfigSettings config; | ||
103 | private string assetURL; | ||
104 | private string currdir; | ||
105 | private bool test; | ||
106 | |||
107 | public CryptoAssetServerClientPluginInitialiser (ConfigSettings p_sv, string p_url, string p_dir, bool p_test) | ||
108 | { | ||
109 | config = p_sv; | ||
110 | assetURL = p_url; | ||
111 | currdir = p_dir; | ||
112 | test = p_test; | ||
113 | } | ||
114 | public override void Initialise (IPlugin plugin) | ||
115 | { | ||
116 | IAssetServer p = plugin as IAssetServer; | ||
117 | p.Initialise (config, assetURL, currdir, test); | ||
118 | } | ||
119 | } | ||
120 | |||
65 | public interface IAssetPlugin | 121 | public interface IAssetPlugin |
66 | { | 122 | { |
67 | IAssetServer GetAssetServer(); | 123 | IAssetServer GetAssetServer(); |
68 | } | 124 | } |
125 | |||
69 | } | 126 | } |
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index 228c0aa..638125c 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs | |||
@@ -268,6 +268,7 @@ namespace OpenSim | |||
268 | m_configSettings.StorageConnectionString = startupConfig.GetString("storage_connection_string"); | 268 | m_configSettings.StorageConnectionString = startupConfig.GetString("storage_connection_string"); |
269 | m_configSettings.EstateConnectionString = startupConfig.GetString("estate_connection_string", m_configSettings.StorageConnectionString); | 269 | m_configSettings.EstateConnectionString = startupConfig.GetString("estate_connection_string", m_configSettings.StorageConnectionString); |
270 | m_configSettings.AssetStorage = startupConfig.GetString("asset_database"); | 270 | m_configSettings.AssetStorage = startupConfig.GetString("asset_database"); |
271 | m_configSettings.AssetCache = startupConfig.GetString("AssetCache"); | ||
271 | m_configSettings.ClientstackDll = startupConfig.GetString("clientstack_plugin"); | 272 | m_configSettings.ClientstackDll = startupConfig.GetString("clientstack_plugin"); |
272 | } | 273 | } |
273 | 274 | ||
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 914bd7e..8198138 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -55,6 +55,12 @@ namespace OpenSim | |||
55 | { | 55 | { |
56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
57 | 57 | ||
58 | // These are the names of the plugin-points extended by this | ||
59 | // class during system startup. | ||
60 | |||
61 | private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache"; | ||
62 | private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetServerClient"; | ||
63 | |||
58 | protected string proxyUrl; | 64 | protected string proxyUrl; |
59 | protected int proxyOffset = 0; | 65 | protected int proxyOffset = 0; |
60 | 66 | ||
@@ -309,57 +315,183 @@ namespace OpenSim | |||
309 | } | 315 | } |
310 | 316 | ||
311 | /// <summary> | 317 | /// <summary> |
312 | /// Initialises the assetcache | 318 | /// Initialises the asset cache. This supports legacy configuration values |
319 | /// to ensure consistent operation, but values outside of that namespace | ||
320 | /// are handled by the more generic resolution mechanism provided by | ||
321 | /// the ResolveAssetServer virtual method. If extended resolution fails, | ||
322 | /// then the normal default action is taken. | ||
323 | /// Creation of the AssetCache is handled by ResolveAssetCache. This | ||
324 | /// function accepts a reference to the instantiated AssetServer and | ||
325 | /// returns an IAssetCache implementation, if possible. This is a virtual | ||
326 | /// method. | ||
313 | /// </summary> | 327 | /// </summary> |
328 | |||
314 | protected virtual void InitialiseAssetCache() | 329 | protected virtual void InitialiseAssetCache() |
315 | { | 330 | { |
316 | 331 | ||
332 | LegacyAssetServerClientPluginInitialiser linit = null; | ||
333 | CryptoAssetServerClientPluginInitialiser cinit = null; | ||
334 | AssetServerClientPluginInitialiser init = null; | ||
335 | |||
317 | IAssetServer assetServer = null; | 336 | IAssetServer assetServer = null; |
318 | string mode = m_configSettings.AssetStorage; | 337 | string mode = m_configSettings.AssetStorage; |
319 | 338 | ||
320 | if (m_configSettings.Standalone == false && | 339 | if (mode == null | mode == String.Empty) |
321 | m_configSettings.AssetStorage == "default") | 340 | mode = "default"; |
322 | mode = "grid"; | ||
323 | 341 | ||
324 | switch (mode) | 342 | // If "default" is specified, then the value is adjusted |
343 | // according to whether or not the server is running in | ||
344 | // standalone mode. | ||
345 | |||
346 | if (mode.ToLower() == "default") | ||
325 | { | 347 | { |
348 | if (m_configSettings.Standalone == false) | ||
349 | mode = "grid"; | ||
350 | else | ||
351 | mode = "local"; | ||
352 | } | ||
353 | |||
354 | switch (mode.ToLower()) | ||
355 | { | ||
356 | |||
357 | // If grid is specified then the grid server is chose regardless | ||
358 | // of whether the server is standalone. | ||
359 | |||
326 | case "grid" : | 360 | case "grid" : |
327 | assetServer = new GridAssetClient(m_networkServersInfo.AssetURL); | 361 | linit = new LegacyAssetServerClientPluginInitialiser(m_configSettings, m_networkServersInfo.AssetURL); |
362 | assetServer = loadAssetServer("Grid", linit); | ||
328 | break; | 363 | break; |
364 | |||
365 | |||
366 | // If cryptogrid is specified then the cryptogrid server is chose regardless | ||
367 | // of whether the server is standalone. | ||
368 | |||
329 | case "cryptogrid" : | 369 | case "cryptogrid" : |
330 | assetServer = new CryptoGridAssetClient(m_networkServersInfo.AssetURL, | 370 | cinit = new CryptoAssetServerClientPluginInitialiser(m_configSettings, m_networkServersInfo.AssetURL, |
331 | Environment.CurrentDirectory, true); | 371 | Environment.CurrentDirectory, true); |
372 | assetServer = loadAssetServer("Crypto", cinit); | ||
332 | break; | 373 | break; |
374 | |||
375 | // If cryptogrid_eou is specified then the cryptogrid_eou server is chose regardless | ||
376 | // of whether the server is standalone. | ||
377 | |||
333 | case "cryptogrid_eou" : | 378 | case "cryptogrid_eou" : |
334 | assetServer = new CryptoGridAssetClient(m_networkServersInfo.AssetURL, | 379 | cinit = new CryptoAssetServerClientPluginInitialiser(m_configSettings, m_networkServersInfo.AssetURL, |
335 | Environment.CurrentDirectory, false); | 380 | Environment.CurrentDirectory, false); |
381 | assetServer = loadAssetServer("Crypto", cinit); | ||
336 | break; | 382 | break; |
383 | |||
384 | // If file is specified then the file server is chose regardless | ||
385 | // of whether the server is standalone. | ||
386 | |||
337 | case "file" : | 387 | case "file" : |
338 | assetServer = new FileAssetClient(m_networkServersInfo.AssetURL); | 388 | linit = new LegacyAssetServerClientPluginInitialiser(m_configSettings, m_networkServersInfo.AssetURL); |
389 | assetServer = loadAssetServer("File", linit); | ||
390 | break; | ||
391 | |||
392 | // If local is specified then we're going to use the local SQL server | ||
393 | // implementation. We drop through, because that will be the fallback | ||
394 | // for the following default clause too. | ||
395 | |||
396 | case "local" : | ||
339 | break; | 397 | break; |
398 | |||
399 | // If the asset_database value is none of the previously mentioned strings, then we | ||
400 | // try to load a turnkey plugin that matches this value. If not we drop through to | ||
401 | // a local default. | ||
402 | |||
340 | default : | 403 | default : |
341 | if (!ResolveAssetServer(out assetServer)) | 404 | try |
342 | { | 405 | { |
343 | SQLAssetServer sqlAssetServer = new SQLAssetServer(m_configSettings.StandaloneAssetPlugin, m_configSettings.StandaloneAssetSource); | 406 | init = new AssetServerClientPluginInitialiser(m_configSettings); |
344 | sqlAssetServer.LoadDefaultAssets(m_configSettings.AssetSetsXMLFile); | 407 | assetServer = loadAssetServer(m_configSettings.AssetStorage, init); |
345 | assetServer = sqlAssetServer; | 408 | break; |
346 | } | 409 | } |
410 | catch {} | ||
411 | m_log.Info("[OPENSIMBASE] Default assetserver will be used"); | ||
347 | break; | 412 | break; |
413 | |||
414 | } | ||
415 | |||
416 | // Open the local SQL-based database asset server | ||
417 | |||
418 | if (assetServer == null) | ||
419 | { | ||
420 | init = new AssetServerClientPluginInitialiser(m_configSettings); | ||
421 | SQLAssetServer sqlAssetServer = (SQLAssetServer) loadAssetServer("SQL", init); | ||
422 | sqlAssetServer.LoadDefaultAssets(m_configSettings.AssetSetsXMLFile); | ||
423 | assetServer = sqlAssetServer; | ||
348 | } | 424 | } |
349 | 425 | ||
426 | // Initialize the asset cache, passing a reference to the selected | ||
427 | // asset server interface. | ||
428 | |||
350 | m_assetCache = ResolveAssetCache(assetServer); | 429 | m_assetCache = ResolveAssetCache(assetServer); |
351 | 430 | ||
352 | } | 431 | } |
353 | 432 | ||
354 | private bool ResolveAssetServer(out IAssetServer assetServer) | 433 | // This method loads the identified asset server, passing an approrpiately |
434 | // initialized Initialise wrapper. There should to be exactly one match, | ||
435 | // if not, then the first match is used. | ||
436 | |||
437 | private IAssetServer loadAssetServer(string id, PluginInitialiserBase pi) | ||
355 | { | 438 | { |
356 | assetServer = null; | 439 | |
357 | return false; | 440 | m_log.DebugFormat("[OPENSIMBASE] Attempting to load asset server id={0}", id); |
441 | |||
442 | PluginLoader<IAssetServer> loader = new PluginLoader<IAssetServer>(pi); | ||
443 | loader.AddFilter(PLUGIN_ASSET_SERVER_CLIENT, new PluginProviderFilter(id)); | ||
444 | loader.Load(PLUGIN_ASSET_SERVER_CLIENT); | ||
445 | if (loader.Plugins.Count > 0) | ||
446 | return (IAssetServer) loader.Plugins[0]; | ||
447 | else | ||
448 | return null; | ||
449 | |||
358 | } | 450 | } |
359 | 451 | ||
360 | private IAssetCache ResolveAssetCache(IAssetServer assetServer) | 452 | /// <summary> |
453 | /// Attempt to instantiate an IAssetCache implementation, using the | ||
454 | /// provided IAssetServer reference. | ||
455 | /// An asset cache implementation must provide a constructor that | ||
456 | /// accepts two parameters; | ||
457 | /// [1] A ConfigSettings reference. | ||
458 | /// [2] An IAssetServer reference. | ||
459 | /// The AssetCache value is obtained from the | ||
460 | /// [StartUp]/AssetCache value in the configuration file. | ||
461 | /// </summary> | ||
462 | |||
463 | protected virtual IAssetCache ResolveAssetCache(IAssetServer assetServer) | ||
361 | { | 464 | { |
362 | return new AssetCache(assetServer); | 465 | |
466 | IAssetCache assetCache = null; | ||
467 | |||
468 | m_log.DebugFormat("[OPENSIMBASE] Attempting to load asset cache id={0}", m_configSettings.AssetCache); | ||
469 | |||
470 | if (m_configSettings.AssetCache != null && m_configSettings.AssetCache != String.Empty) | ||
471 | { | ||
472 | try | ||
473 | { | ||
474 | |||
475 | PluginInitialiserBase init = new AssetCachePluginInitialiser(m_configSettings, assetServer); | ||
476 | PluginLoader<IAssetCache> loader = new PluginLoader<IAssetCache>(init); | ||
477 | loader.AddFilter(PLUGIN_ASSET_SERVER_CLIENT, new PluginProviderFilter(m_configSettings.AssetCache)); | ||
478 | |||
479 | loader.Load(PLUGIN_ASSET_CACHE); | ||
480 | if (loader.Plugins.Count > 0) | ||
481 | assetCache = (IAssetCache) loader.Plugins[0]; | ||
482 | |||
483 | } | ||
484 | catch (Exception e) | ||
485 | { | ||
486 | m_log.Debug("[OPENSIMBASE] ResolveAssetCache completed"); | ||
487 | m_log.Debug(e); | ||
488 | } | ||
489 | } | ||
490 | |||
491 | // If everything else fails, we force load the built-in asset cache | ||
492 | |||
493 | return (IAssetCache) ((assetCache != null) ? assetCache : new AssetCache(assetServer)); | ||
494 | |||
363 | } | 495 | } |
364 | 496 | ||
365 | public void ProcessLogin(bool LoginEnabled) | 497 | public void ProcessLogin(bool LoginEnabled) |
diff --git a/bin/OpenSim.addin.xml b/bin/OpenSim.addin.xml index 122a1a8..707eaf3 100644 --- a/bin/OpenSim.addin.xml +++ b/bin/OpenSim.addin.xml | |||
@@ -3,7 +3,13 @@ | |||
3 | <Import assembly="OpenSim.exe"/> | 3 | <Import assembly="OpenSim.exe"/> |
4 | <Import assembly="OpenSim.Framework.dll"/> | 4 | <Import assembly="OpenSim.Framework.dll"/> |
5 | </Runtime> | 5 | </Runtime> |
6 | <ExtensionPoint path = "/OpenSim/Startup"> | 6 | <ExtensionPoint path="/OpenSim/Startup"> |
7 | <ExtensionNode name="Plugin" type="OpenSim.Framework.PluginExtensionNode" objectType="OpenSim.IApplicationPlugin"/> | 7 | <ExtensionNode name="Plugin" type="OpenSim.Framework.PluginExtensionNode" objectType="OpenSim.IApplicationPlugin"/> |
8 | </ExtensionPoint> | 8 | </ExtensionPoint> |
9 | <ExtensionPoint path="/OpenSim/AssetCache" name="Region Asset Cache Plugin-point" > | ||
10 | <ExtensionNode name="Cache" type="OpenSim.Framework.PluginExtensionNode" objectType="OpenSim.Framework.IAssetCache"/> | ||
11 | </ExtensionPoint> | ||
12 | <ExtensionPoint path="/OpenSim/AssetServerClient" name="Region Asset Cache Server Interface Plugin-point"> | ||
13 | <ExtensionNode name="ServerClient" type="OpenSim.Framework.PluginExtensionNode" objectType="OpenSim.Framework.IAssetServer"/> | ||
14 | </ExtensionPoint> | ||
9 | </Addin> | 15 | </Addin> |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 0e1958e..3469c2a 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -110,6 +110,8 @@ | |||
110 | ; | 110 | ; |
111 | ; If set to local then the local database based asset service will be used in standalone and grid modes | 111 | ; If set to local then the local database based asset service will be used in standalone and grid modes |
112 | ; If set to grid then the grid based asset service will be used in standalone and grid modes | 112 | ; If set to grid then the grid based asset service will be used in standalone and grid modes |
113 | ; All other values will cause a search for a matching assembly that contains an asset server client. | ||
114 | ; See also: AssetCache | ||
113 | asset_database = "default" | 115 | asset_database = "default" |
114 | 116 | ||
115 | ; Persistence of changed objects happens during regular sweeps. The following control that behaviour to | 117 | ; Persistence of changed objects happens during regular sweeps. The following control that behaviour to |
@@ -197,6 +199,17 @@ | |||
197 | ;WorldMapModule = "WorldMap" | 199 | ;WorldMapModule = "WorldMap" |
198 | ;MapImageModule = "MapImageModule" | 200 | ;MapImageModule = "MapImageModule" |
199 | 201 | ||
202 | ; ## | ||
203 | ; ## Customized Cache Implementation | ||
204 | ; ## | ||
205 | ; | ||
206 | ; The AssetCache value allows the name of an alternative caching | ||
207 | ; implementation to be specified. This can normally be omitted. | ||
208 | ; This value corresponds to the provider value associated with the | ||
209 | ; intended cache implementation plugin. | ||
210 | ; See also: asset_database | ||
211 | |||
212 | ; AssetCache = "OpenSim.Framework.Communications.Cache.AssetCache" | ||
200 | 213 | ||
201 | ; ## | 214 | ; ## |
202 | ; ## EMAIL MODULE | 215 | ; ## EMAIL MODULE |
diff --git a/prebuild.xml b/prebuild.xml index 30cb8c6..887ac8a 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -540,6 +540,7 @@ | |||
540 | <Match pattern="*.cs" recurse="true"> | 540 | <Match pattern="*.cs" recurse="true"> |
541 | <Exclude name="Tests" pattern="Tests"/> | 541 | <Exclude name="Tests" pattern="Tests"/> |
542 | </Match> | 542 | </Match> |
543 | <Match pattern="*.addin.xml" path="Resources" buildAction="EmbeddedResource" recurse="true"/> | ||
543 | </Files> | 544 | </Files> |
544 | </Project> | 545 | </Project> |
545 | 546 | ||