aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs')
-rw-r--r--OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs236
1 files changed, 203 insertions, 33 deletions
diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs
index a868bd0..ddc37ed 100644
--- a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs
@@ -30,24 +30,36 @@ using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins; 32using Mono.Addins;
33using Nini.Config;
33using OpenSim; 34using OpenSim;
34using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
36 37
37namespace OpenSim.ApplicationPlugins.RegionModulesController 38namespace OpenSim.ApplicationPlugins.RegionModulesController
38{ 39{
39 public class RegionModulesControllerPlugin : IRegionModulesController, IApplicationPlugin 40 public class RegionModulesControllerPlugin : IRegionModulesController,
41 IApplicationPlugin
40 { 42 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 // Logger
44 private static readonly ILog m_log =
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
42 47
43 private OpenSimBase m_openSim; // for getting the config 48 // Config access
49 private OpenSimBase m_openSim;
44 50
51 // Our name
45 private string m_name; 52 private string m_name;
46 53
47 private List<Type> m_nonSharedModules = new List<Type>(); 54 // Internal lists to collect information about modules present
48 private List<Type> m_sharedModules = new List<Type>(); 55 private List<TypeExtensionNode> m_nonSharedModules =
56 new List<TypeExtensionNode>();
57 private List<TypeExtensionNode> m_sharedModules =
58 new List<TypeExtensionNode>();
49 59
50 private List<ISharedRegionModule> m_sharedInstances = new List<ISharedRegionModule>(); 60 // List of shared module instances, for adding to Scenes
61 private List<ISharedRegionModule> m_sharedInstances =
62 new List<ISharedRegionModule>();
51 63
52#region IApplicationPlugin implementation 64#region IApplicationPlugin implementation
53 65
@@ -57,40 +69,136 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
57 m_openSim = openSim; 69 m_openSim = openSim;
58 openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this); 70 openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
59 71
72 // Who we are
60 string id = AddinManager.CurrentAddin.Id; 73 string id = AddinManager.CurrentAddin.Id;
61 int pos = id.LastIndexOf(".");
62 if (pos == -1) m_name = id;
63 else m_name = id.Substring(pos + 1);
64 74
65 //ExtensionNodeList list = AddinManager.GetExtensionNodes("/OpenSim/RegionModules"); 75 // Make friendly name
66 // load all the (new) region-module classes 76 int pos = id.LastIndexOf(".");
67 foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/RegionModules")) 77 if (pos == -1)
78 m_name = id;
79 else
80 m_name = id.Substring(pos + 1);
81
82 // The [Modules] section in the ini file
83 IConfig modulesConfig =
84 openSim.ConfigSource.Source.Configs["Modules"];
85 if (modulesConfig == null)
86 modulesConfig = openSim.ConfigSource.Source.AddConfig("Modules");
87
88 // Scan modules and load all that aren't disabled
89 foreach (TypeExtensionNode node in
90 AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
68 { 91 {
69 // TODO why does node.Type.isSubclassOf(typeof(ISharedRegionModule)) not work?
70 if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null) 92 if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
71 { 93 {
94 // Get the config string
95 string moduleString =
96 modulesConfig.GetString("Setup_" + node.Id, String.Empty);
97
98 // We have a selector
99 if (moduleString != String.Empty)
100 {
101 // Allow disabling modules even if they don't have
102 // support for it
103 if (moduleString == "disabled")
104 continue;
105
106 // Split off port, if present
107 string[] moduleParts = moduleString.Split(new char[] {'/'}, 2);
108 // Format is [port/][class]
109 string className = moduleParts[0];
110 if (moduleParts.Length > 1)
111 className = moduleParts[1];
112
113 // Match the class name if given
114 if (className != String.Empty &&
115 node.Type.ToString() != className)
116 continue;
117 }
118
72 m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type); 119 m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
73 m_sharedModules.Add(node.Type); 120 m_sharedModules.Add(node);
74 } 121 }
75 else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null) 122 else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
76 { 123 {
124 // Get the config string
125 string moduleString =
126 modulesConfig.GetString("Setup_" + node.Id, String.Empty);
127
128 // We have a selector
129 if (moduleString != String.Empty)
130 {
131 // Allow disabling modules even if they don't have
132 // support for it
133 if (moduleString == "disabled")
134 continue;
135
136 // Split off port, if present
137 string[] moduleParts = moduleString.Split(new char[] {'/'}, 2);
138 // Format is [port/][class]
139 string className = moduleParts[0];
140 if (moduleParts.Length > 1)
141 className = moduleParts[1];
142
143 // Match the class name if given
144 if (className != String.Empty &&
145 node.Type.ToString() != className)
146 continue;
147 }
148
77 m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type); 149 m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
78 m_nonSharedModules.Add(node.Type); 150 m_nonSharedModules.Add(node);
79 } 151 }
80 else 152 else
81 m_log.DebugFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type); 153 m_log.DebugFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
82 } 154 }
83 155
84 // now we've got all the region-module classes loaded, create one instance of every ISharedRegionModule, 156 // Load and init the module. We try a constructor with a port
85 // initialize and postinitialize it. This Initialise we are in is called before LoadRegion.PostInitialise 157 // if a port was given, fall back to one without if there is
86 // is called (which loads the regions), so we don't have any regions in the server yet. 158 // no port or the more specific constructor fails.
87 foreach (Type type in m_sharedModules) 159 // This will be removed, so that any module capable of using a port
160 // must provide a constructor with a port in the future.
161 // For now, we do this so migration is easy.
162 //
163 foreach (TypeExtensionNode node in m_sharedModules)
88 { 164 {
89 ISharedRegionModule module = (ISharedRegionModule)Activator.CreateInstance(type); 165 Object[] ctorArgs = new Object[] {(uint)0};
166
167 // Read the config again
168 string moduleString =
169 modulesConfig.GetString("Setup_" + node.Id, String.Empty);
170
171 // Get the port number, if there is one
172 if (moduleString != String.Empty)
173 {
174 // Get the port number from the string
175 string[] moduleParts = moduleString.Split(new char[] {'/'},
176 2);
177 if (moduleParts.Length > 1)
178 ctorArgs[0] = Convert.ToUInt32(moduleParts[0]);
179 }
180
181 // Try loading and initilaizing the module, using the
182 // port if appropriate
183 ISharedRegionModule module = null;
184
185 try
186 {
187 module = (ISharedRegionModule)Activator.CreateInstance(
188 node.Type, ctorArgs);
189 }
190 catch
191 {
192 module = (ISharedRegionModule)Activator.CreateInstance(
193 node.Type);
194 }
195
196 // OK, we're up and running
90 m_sharedInstances.Add(module); 197 m_sharedInstances.Add(module);
91 module.Initialise(openSim.ConfigSource.Source); 198 module.Initialise(openSim.ConfigSource.Source);
92 } 199 }
93 200
201 // Immediately run PostInitialise on shared modules
94 foreach (ISharedRegionModule module in m_sharedInstances) 202 foreach (ISharedRegionModule module in m_sharedInstances)
95 { 203 {
96 module.PostInitialise(); 204 module.PostInitialise();
@@ -105,6 +213,8 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
105 213
106#region IPlugin implementation 214#region IPlugin implementation
107 215
216 // We don't do that here
217 //
108 public void Initialise () 218 public void Initialise ()
109 { 219 {
110 throw new System.NotImplementedException(); 220 throw new System.NotImplementedException();
@@ -114,9 +224,11 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
114 224
115#region IDisposable implementation 225#region IDisposable implementation
116 226
227 // Cleanup
228 //
117 public void Dispose () 229 public void Dispose ()
118 { 230 {
119 // we expect that all regions have been removed already 231 // We expect that all regions have been removed already
120 while (m_sharedInstances.Count > 0) 232 while (m_sharedInstances.Count > 0)
121 { 233 {
122 m_sharedInstances[0].Close(); 234 m_sharedInstances[0].Close();
@@ -147,6 +259,11 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
147 259
148#region IRegionModulesController implementation 260#region IRegionModulesController implementation
149 261
262 // The root of all evil.
263 // This is where we handle adding the modules to scenes when they
264 // load. This means that here we deal with replaceable interfaces,
265 // nonshared modules, etc.
266 //
150 public void AddRegionToModules (Scene scene) 267 public void AddRegionToModules (Scene scene)
151 { 268 {
152 Dictionary<Type, ISharedRegionModule> deferredSharedModules = 269 Dictionary<Type, ISharedRegionModule> deferredSharedModules =
@@ -154,12 +271,26 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
154 Dictionary<Type, INonSharedRegionModule> deferredNonSharedModules = 271 Dictionary<Type, INonSharedRegionModule> deferredNonSharedModules =
155 new Dictionary<Type, INonSharedRegionModule>(); 272 new Dictionary<Type, INonSharedRegionModule>();
156 273
274 // We need this to see if a module has already been loaded and
275 // has defined a replaceable interface. It's a generic call,
276 // so this can't be used directly. It will be used later
157 Type s = scene.GetType(); 277 Type s = scene.GetType();
158 MethodInfo mi = s.GetMethod("RequestModuleInterface"); 278 MethodInfo mi = s.GetMethod("RequestModuleInterface");
159 279
160 List<ISharedRegionModule> sharedlist = new List<ISharedRegionModule>(); 280 // This will hold the shared modules we actually load
281 List<ISharedRegionModule> sharedlist =
282 new List<ISharedRegionModule>();
283
284 // Iterate over the shared modules that have been loaded
285 // Add them to the new Scene
161 foreach (ISharedRegionModule module in m_sharedInstances) 286 foreach (ISharedRegionModule module in m_sharedInstances)
162 { 287 {
288 // Here is where we check if a replaceable interface
289 // is defined. If it is, the module is checked against
290 // the interfaces already defined. If the interface is
291 // defined, we simply skip the module. Else, if the module
292 // defines a replaceable interface, we add it to the deferred
293 // list.
163 Type replaceableInterface = module.ReplaceableInterface; 294 Type replaceableInterface = module.ReplaceableInterface;
164 if (replaceableInterface != null) 295 if (replaceableInterface != null)
165 { 296 {
@@ -185,11 +316,41 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
185 sharedlist.Add(module); 316 sharedlist.Add(module);
186 } 317 }
187 318
319 IConfig modulesConfig =
320 m_openSim.ConfigSource.Source.Configs["Modules"];
321
322 // Scan for, and load, nonshared modules
188 List<INonSharedRegionModule> list = new List<INonSharedRegionModule>(); 323 List<INonSharedRegionModule> list = new List<INonSharedRegionModule>();
189 foreach (Type type in m_nonSharedModules) 324 foreach (TypeExtensionNode node in m_nonSharedModules)
190 { 325 {
191 INonSharedRegionModule module = (INonSharedRegionModule)Activator.CreateInstance(type); 326 Object[] ctorArgs = new Object[] {0};
327
328 // Read the config
329 string moduleString =
330 modulesConfig.GetString("Setup_" + node.Id, String.Empty);
331
332 // Get the port number, if there is one
333 if (moduleString != String.Empty)
334 {
335 // Get the port number from the string
336 string[] moduleParts = moduleString.Split(new char[] {'/'},
337 2);
338 if (moduleParts.Length > 1)
339 ctorArgs[0] = Convert.ToUInt32(moduleParts[0]);
340 }
192 341
342 // Actually load it
343 INonSharedRegionModule module = null;
344 try
345 {
346 module = (INonSharedRegionModule)Activator.CreateInstance(node.Type, ctorArgs);
347 }
348 catch
349 {
350 module = (INonSharedRegionModule)Activator.CreateInstance(node.Type);
351 }
352
353 // Check for replaceable interfaces
193 Type replaceableInterface = module.ReplaceableInterface; 354 Type replaceableInterface = module.ReplaceableInterface;
194 if (replaceableInterface != null) 355 if (replaceableInterface != null)
195 { 356 {
@@ -209,11 +370,16 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
209 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}", 370 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}",
210 scene.RegionInfo.RegionName, module.Name); 371 scene.RegionInfo.RegionName, module.Name);
211 372
373 // Initialise the module
212 module.Initialise(m_openSim.ConfigSource.Source); 374 module.Initialise(m_openSim.ConfigSource.Source);
213 375
214 list.Add(module); 376 list.Add(module);
215 } 377 }
216 378
379 // Now add the modules that we found to the scene. If a module
380 // wishes to override a replaceable interface, it needs to
381 // register it in Initialise, so that the deferred module
382 // won't load.
217 foreach (INonSharedRegionModule module in list) 383 foreach (INonSharedRegionModule module in list)
218 { 384 {
219 module.AddRegion(scene); 385 module.AddRegion(scene);
@@ -223,9 +389,9 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
223 // Now all modules without a replaceable base interface are loaded 389 // Now all modules without a replaceable base interface are loaded
224 // Replaceable modules have either been skipped, or omitted. 390 // Replaceable modules have either been skipped, or omitted.
225 // Now scan the deferred modules here 391 // Now scan the deferred modules here
226
227 foreach (ISharedRegionModule module in deferredSharedModules.Values) 392 foreach (ISharedRegionModule module in deferredSharedModules.Values)
228 { 393 {
394 // Determine if the interface has been replaced
229 Type replaceableInterface = module.ReplaceableInterface; 395 Type replaceableInterface = module.ReplaceableInterface;
230 MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); 396 MethodInfo mii = mi.MakeGenericMethod(replaceableInterface);
231 397
@@ -238,15 +404,20 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
238 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)", 404 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)",
239 scene.RegionInfo.RegionName, module.Name); 405 scene.RegionInfo.RegionName, module.Name);
240 406
407 // Not replaced, load the module
241 module.AddRegion(scene); 408 module.AddRegion(scene);
242 scene.AddRegionModule(module.Name, module); 409 scene.AddRegionModule(module.Name, module);
243 410
244 sharedlist.Add(module); 411 sharedlist.Add(module);
245 } 412 }
246 413
247 List<INonSharedRegionModule> deferredlist = new List<INonSharedRegionModule>(); 414 // Same thing for nonshared modules, load them unless overridden
415 List<INonSharedRegionModule> deferredlist =
416 new List<INonSharedRegionModule>();
417
248 foreach (INonSharedRegionModule module in deferredNonSharedModules.Values) 418 foreach (INonSharedRegionModule module in deferredNonSharedModules.Values)
249 { 419 {
420 // Check interface override
250 Type replaceableInterface = module.ReplaceableInterface; 421 Type replaceableInterface = module.ReplaceableInterface;
251 if (replaceableInterface != null) 422 if (replaceableInterface != null)
252 { 423 {
@@ -268,7 +439,8 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
268 deferredlist.Add(module); 439 deferredlist.Add(module);
269 } 440 }
270 441
271 foreach (IRegionModuleBase module in deferredlist) 442 // Finally, load valid deferred modules
443 foreach (INonSharedRegionModule module in deferredlist)
272 { 444 {
273 module.AddRegion(scene); 445 module.AddRegion(scene);
274 scene.AddRegionModule(module.Name, module); 446 scene.AddRegionModule(module.Name, module);
@@ -284,16 +456,14 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
284 // and unneccessary caching logic repeated in all modules. 456 // and unneccessary caching logic repeated in all modules.
285 // The extra function stub is just that much cleaner 457 // The extra function stub is just that much cleaner
286 // 458 //
287 foreach (IRegionModuleBase module in sharedlist) 459 foreach (ISharedRegionModule module in sharedlist)
288 { 460 {
289 try { module.RegionLoaded(scene); } 461 module.RegionLoaded(scene);
290 catch (Exception ex) { m_log.Error("[REGIONMODULE]: Exception while loading shared region module " + module + ": " + ex.Message, ex); }
291 } 462 }
292 463
293 foreach (IRegionModuleBase module in list) 464 foreach (INonSharedRegionModule module in list)
294 { 465 {
295 try { module.RegionLoaded(scene); } 466 module.RegionLoaded(scene);
296 catch (Exception ex) { m_log.Error("[REGIONMODULE]: Exception while loading non-shared region module " + module + ": " + ex.Message, ex); }
297 } 467 }
298 } 468 }
299 469