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.cs199
1 files changed, 173 insertions, 26 deletions
diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs
index f30a18b..13cb34c 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,111 @@ 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(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 {
77 m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type); 124 m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
78 m_nonSharedModules.Add(node.Type); 125 m_nonSharedModules.Add(node);
79 } 126 }
80 else 127 else
81 m_log.DebugFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type); 128 m_log.DebugFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
82 } 129 }
83 130
84 // now we've got all the region-module classes loaded, create one instance of every ISharedRegionModule, 131 // 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 132 // 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. 133 // no port or the more specific constructor fails.
87 foreach (Type type in m_sharedModules) 134 // This will be removed, so that any module capable of using a port
135 // must provide a constructor with a port in the future.
136 // For now, we do this so migration is easy.
137 //
138 foreach (TypeExtensionNode node in m_sharedModules)
88 { 139 {
89 ISharedRegionModule module = (ISharedRegionModule)Activator.CreateInstance(type); 140 Object[] ctorArgs = new Object[] {0};
141
142 // Read the config again
143 string moduleString =
144 modulesConfig.GetString(node.Id, String.Empty);
145
146 // Get the port number, if there is one
147 if (moduleString != String.Empty)
148 {
149 // Get the port number from the string
150 string[] moduleParts = moduleString.Split(new char[] {'/'},
151 2);
152 if (moduleParts.Length > 1)
153 ctorArgs[0] = Convert.ToUInt32(moduleParts[0]);
154 }
155
156 // Try loading and initilaizing the module, using the
157 // port if appropriate
158 ISharedRegionModule module = null;
159
160 try
161 {
162 module = (ISharedRegionModule)Activator.CreateInstance(
163 node.Type, ctorArgs);
164 }
165 catch
166 {
167 module = (ISharedRegionModule)Activator.CreateInstance(
168 node.Type);
169 }
170
171 // OK, we're up and running
90 m_sharedInstances.Add(module); 172 m_sharedInstances.Add(module);
91 module.Initialise(openSim.ConfigSource.Source); 173 module.Initialise(openSim.ConfigSource.Source);
92 } 174 }
93 175
176 // Immediately run PostInitialise on shared modules
94 foreach (ISharedRegionModule module in m_sharedInstances) 177 foreach (ISharedRegionModule module in m_sharedInstances)
95 { 178 {
96 module.PostInitialise(); 179 module.PostInitialise();
@@ -105,6 +188,8 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
105 188
106#region IPlugin implementation 189#region IPlugin implementation
107 190
191 // We don't do that here
192 //
108 public void Initialise () 193 public void Initialise ()
109 { 194 {
110 throw new System.NotImplementedException(); 195 throw new System.NotImplementedException();
@@ -114,9 +199,11 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
114 199
115#region IDisposable implementation 200#region IDisposable implementation
116 201
202 // Cleanup
203 //
117 public void Dispose () 204 public void Dispose ()
118 { 205 {
119 // we expect that all regions have been removed already 206 // We expect that all regions have been removed already
120 while (m_sharedInstances.Count > 0) 207 while (m_sharedInstances.Count > 0)
121 { 208 {
122 m_sharedInstances[0].Close(); 209 m_sharedInstances[0].Close();
@@ -147,6 +234,11 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
147 234
148#region IRegionModulesController implementation 235#region IRegionModulesController implementation
149 236
237 // The root of all evil.
238 // This is where we handle adding the modules to scenes when they
239 // load. This means that here we deal with replaceable interfaces,
240 // nonshared modules, etc.
241 //
150 public void AddRegionToModules (Scene scene) 242 public void AddRegionToModules (Scene scene)
151 { 243 {
152 Dictionary<Type, ISharedRegionModule> deferredSharedModules = 244 Dictionary<Type, ISharedRegionModule> deferredSharedModules =
@@ -154,12 +246,26 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
154 Dictionary<Type, INonSharedRegionModule> deferredNonSharedModules = 246 Dictionary<Type, INonSharedRegionModule> deferredNonSharedModules =
155 new Dictionary<Type, INonSharedRegionModule>(); 247 new Dictionary<Type, INonSharedRegionModule>();
156 248
249 // We need this to see if a module has already been loaded and
250 // has defined a replaceable interface. It's a generic call,
251 // so this can't be used directly. It will be used later
157 Type s = scene.GetType(); 252 Type s = scene.GetType();
158 MethodInfo mi = s.GetMethod("RequestModuleInterface"); 253 MethodInfo mi = s.GetMethod("RequestModuleInterface");
159 254
160 List<ISharedRegionModule> sharedlist = new List<ISharedRegionModule>(); 255 // This will hold the shared modules we actually load
256 List<ISharedRegionModule> sharedlist =
257 new List<ISharedRegionModule>();
258
259 // Iterate over the shared modules that have been loaded
260 // Add them to the new Scene
161 foreach (ISharedRegionModule module in m_sharedInstances) 261 foreach (ISharedRegionModule module in m_sharedInstances)
162 { 262 {
263 // Here is where we check if a replaceable interface
264 // is defined. If it is, the module is checked against
265 // the interfaces already defined. If the interface is
266 // defined, we simply skip the module. Else, if the module
267 // defines a replaceable interface, we add it to the deferred
268 // list.
163 Type replaceableInterface = module.ReplaceableInterface; 269 Type replaceableInterface = module.ReplaceableInterface;
164 if (replaceableInterface != null) 270 if (replaceableInterface != null)
165 { 271 {
@@ -185,11 +291,41 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
185 sharedlist.Add(module); 291 sharedlist.Add(module);
186 } 292 }
187 293
294 IConfig modulesConfig =
295 m_openSim.ConfigSource.Source.Configs["Modules"];
296
297 // Scan for, and load, nonshared modules
188 List<INonSharedRegionModule> list = new List<INonSharedRegionModule>(); 298 List<INonSharedRegionModule> list = new List<INonSharedRegionModule>();
189 foreach (Type type in m_nonSharedModules) 299 foreach (TypeExtensionNode node in m_nonSharedModules)
190 { 300 {
191 INonSharedRegionModule module = (INonSharedRegionModule)Activator.CreateInstance(type); 301 Object[] ctorArgs = new Object[] {0};
302
303 // Read the config
304 string moduleString =
305 modulesConfig.GetString(node.Id, String.Empty);
306
307 // Get the port number, if there is one
308 if (moduleString != String.Empty)
309 {
310 // Get the port number from the string
311 string[] moduleParts = moduleString.Split(new char[] {'/'},
312 2);
313 if (moduleParts.Length > 1)
314 ctorArgs[0] = Convert.ToUInt32(moduleParts[0]);
315 }
192 316
317 // Actually load it
318 INonSharedRegionModule module = null;
319 try
320 {
321 module = (INonSharedRegionModule)Activator.CreateInstance(node.Type, ctorArgs);
322 }
323 catch
324 {
325 module = (INonSharedRegionModule)Activator.CreateInstance(node.Type);
326 }
327
328 // Check for replaceable interfaces
193 Type replaceableInterface = module.ReplaceableInterface; 329 Type replaceableInterface = module.ReplaceableInterface;
194 if (replaceableInterface != null) 330 if (replaceableInterface != null)
195 { 331 {
@@ -209,11 +345,16 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
209 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}", 345 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}",
210 scene.RegionInfo.RegionName, module.Name); 346 scene.RegionInfo.RegionName, module.Name);
211 347
348 // Initialise the module
212 module.Initialise(m_openSim.ConfigSource.Source); 349 module.Initialise(m_openSim.ConfigSource.Source);
213 350
214 list.Add(module); 351 list.Add(module);
215 } 352 }
216 353
354 // Now add the modules that we found to the scene. If a module
355 // wishes to override a replaceable interface, it needs to
356 // register it in Initialise, so that the deferred module
357 // won't load.
217 foreach (INonSharedRegionModule module in list) 358 foreach (INonSharedRegionModule module in list)
218 { 359 {
219 module.AddRegion(scene); 360 module.AddRegion(scene);
@@ -223,9 +364,9 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
223 // Now all modules without a replaceable base interface are loaded 364 // Now all modules without a replaceable base interface are loaded
224 // Replaceable modules have either been skipped, or omitted. 365 // Replaceable modules have either been skipped, or omitted.
225 // Now scan the deferred modules here 366 // Now scan the deferred modules here
226
227 foreach (ISharedRegionModule module in deferredSharedModules.Values) 367 foreach (ISharedRegionModule module in deferredSharedModules.Values)
228 { 368 {
369 // Determine if the interface has been replaced
229 Type replaceableInterface = module.ReplaceableInterface; 370 Type replaceableInterface = module.ReplaceableInterface;
230 MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); 371 MethodInfo mii = mi.MakeGenericMethod(replaceableInterface);
231 372
@@ -238,15 +379,20 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
238 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)", 379 m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)",
239 scene.RegionInfo.RegionName, module.Name); 380 scene.RegionInfo.RegionName, module.Name);
240 381
382 // Not replaced, load the module
241 module.AddRegion(scene); 383 module.AddRegion(scene);
242 scene.AddRegionModule(module.Name, module); 384 scene.AddRegionModule(module.Name, module);
243 385
244 sharedlist.Add(module); 386 sharedlist.Add(module);
245 } 387 }
246 388
247 List<INonSharedRegionModule> deferredlist = new List<INonSharedRegionModule>(); 389 // Same thing for nonshared modules, load them unless overridden
390 List<INonSharedRegionModule> deferredlist =
391 new List<INonSharedRegionModule>();
392
248 foreach (INonSharedRegionModule module in deferredNonSharedModules.Values) 393 foreach (INonSharedRegionModule module in deferredNonSharedModules.Values)
249 { 394 {
395 // Check interface override
250 Type replaceableInterface = module.ReplaceableInterface; 396 Type replaceableInterface = module.ReplaceableInterface;
251 if (replaceableInterface != null) 397 if (replaceableInterface != null)
252 { 398 {
@@ -268,6 +414,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
268 deferredlist.Add(module); 414 deferredlist.Add(module);
269 } 415 }
270 416
417 // Finally, load valid deferred modules
271 foreach (INonSharedRegionModule module in deferredlist) 418 foreach (INonSharedRegionModule module in deferredlist)
272 { 419 {
273 module.AddRegion(scene); 420 module.AddRegion(scene);