diff options
Diffstat (limited to 'OpenSim/Server/Base/ServerUtils.cs')
-rw-r--r-- | OpenSim/Server/Base/ServerUtils.cs | 222 |
1 files changed, 212 insertions, 10 deletions
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 42c82cf..2e6d279 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs | |||
@@ -33,11 +33,163 @@ using System.Xml.Serialization; | |||
33 | using System.Text; | 33 | using System.Text; |
34 | using System.Collections.Generic; | 34 | using System.Collections.Generic; |
35 | using log4net; | 35 | using log4net; |
36 | using Nini.Config; | ||
36 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
37 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using Mono.Addins; | ||
40 | using OpenSim.Framework.Servers.HttpServer; | ||
41 | using OpenSim.Framework.Servers; | ||
38 | 42 | ||
43 | |||
44 | [assembly:AddinRoot("Robust", "0.1")] | ||
39 | namespace OpenSim.Server.Base | 45 | namespace OpenSim.Server.Base |
40 | { | 46 | { |
47 | [TypeExtensionPoint(Path="/Robust/Connector", Name="RobustConnector")] | ||
48 | public interface IRobustConnector | ||
49 | { | ||
50 | string ConfigName | ||
51 | { | ||
52 | get; | ||
53 | } | ||
54 | |||
55 | bool Enabled | ||
56 | { | ||
57 | get; | ||
58 | } | ||
59 | |||
60 | string PluginPath | ||
61 | { | ||
62 | get; | ||
63 | set; | ||
64 | } | ||
65 | |||
66 | uint Configure(IConfigSource config); | ||
67 | void Initialize(IHttpServer server); | ||
68 | void Unload(); | ||
69 | } | ||
70 | |||
71 | public class PluginLoader | ||
72 | { | ||
73 | static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
74 | |||
75 | public AddinRegistry Registry | ||
76 | { | ||
77 | get; | ||
78 | private set; | ||
79 | } | ||
80 | |||
81 | public IConfigSource Config | ||
82 | { | ||
83 | get; | ||
84 | private set; | ||
85 | } | ||
86 | |||
87 | public PluginLoader(IConfigSource config, string registryPath) | ||
88 | { | ||
89 | Config = config; | ||
90 | |||
91 | Registry = new AddinRegistry(registryPath, "."); | ||
92 | suppress_console_output_(true); | ||
93 | AddinManager.Initialize(registryPath); | ||
94 | suppress_console_output_(false); | ||
95 | AddinManager.Registry.Update(); | ||
96 | CommandManager commandmanager = new CommandManager(Registry); | ||
97 | AddinManager.AddExtensionNodeHandler("/Robust/Connector", OnExtensionChanged); | ||
98 | } | ||
99 | |||
100 | private static TextWriter prev_console_; | ||
101 | // Temporarily masking the errors reported on start | ||
102 | // This is caused by a non-managed dll in the ./bin dir | ||
103 | // when the registry is initialized. The dll belongs to | ||
104 | // libomv, which has a hard-coded path to "." for pinvoke | ||
105 | // to load the openjpeg dll | ||
106 | // | ||
107 | // Will look for a way to fix, but for now this keeps the | ||
108 | // confusion to a minimum. this was copied from our region | ||
109 | // plugin loader, we have been doing this in there for a long time. | ||
110 | // | ||
111 | public void suppress_console_output_(bool save) | ||
112 | { | ||
113 | if (save) | ||
114 | { | ||
115 | prev_console_ = System.Console.Out; | ||
116 | System.Console.SetOut(new StreamWriter(Stream.Null)); | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | if (prev_console_ != null) | ||
121 | System.Console.SetOut(prev_console_); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | private void OnExtensionChanged(object s, ExtensionNodeEventArgs args) | ||
126 | { | ||
127 | IRobustConnector connector = (IRobustConnector)args.ExtensionObject; | ||
128 | Addin a = Registry.GetAddin(args.ExtensionNode.Addin.Id); | ||
129 | |||
130 | if(a == null) | ||
131 | { | ||
132 | Registry.Rebuild(null); | ||
133 | a = Registry.GetAddin(args.ExtensionNode.Addin.Id); | ||
134 | } | ||
135 | |||
136 | switch(args.Change) | ||
137 | { | ||
138 | case ExtensionChange.Add: | ||
139 | if (a.AddinFile.Contains(Registry.DefaultAddinsFolder)) | ||
140 | { | ||
141 | m_log.InfoFormat("[SERVER]: Adding {0} from registry", a.Name); | ||
142 | connector.PluginPath = System.IO.Path.Combine(Registry.DefaultAddinsFolder,a.Name.Replace(',', '.')); } | ||
143 | else | ||
144 | { | ||
145 | m_log.InfoFormat("[SERVER]: Adding {0} from ./bin", a.Name); | ||
146 | connector.PluginPath = a.AddinFile; | ||
147 | } | ||
148 | LoadPlugin(connector); | ||
149 | break; | ||
150 | case ExtensionChange.Remove: | ||
151 | m_log.InfoFormat("[SERVER]: Removing {0}", a.Name); | ||
152 | UnloadPlugin(connector); | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | private void LoadPlugin(IRobustConnector connector) | ||
158 | { | ||
159 | IHttpServer server = null; | ||
160 | uint port = connector.Configure(Config); | ||
161 | |||
162 | if(connector.Enabled) | ||
163 | { | ||
164 | server = GetServer(connector, port); | ||
165 | connector.Initialize(server); | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | m_log.InfoFormat("[SERVER]: {0} Disabled.", connector.ConfigName); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | private void UnloadPlugin(IRobustConnector connector) | ||
174 | { | ||
175 | m_log.InfoFormat("[Server]: Unloading {0}", connector.ConfigName); | ||
176 | |||
177 | connector.Unload(); | ||
178 | } | ||
179 | |||
180 | private IHttpServer GetServer(IRobustConnector connector, uint port) | ||
181 | { | ||
182 | IHttpServer server; | ||
183 | |||
184 | if(port != 0) | ||
185 | server = MainServer.GetHttpServer(port); | ||
186 | else | ||
187 | server = MainServer.Instance; | ||
188 | |||
189 | return server; | ||
190 | } | ||
191 | } | ||
192 | |||
41 | public static class ServerUtils | 193 | public static class ServerUtils |
42 | { | 194 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 195 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -63,20 +215,30 @@ namespace OpenSim.Server.Base | |||
63 | /// <param name="dllName"></param> | 215 | /// <param name="dllName"></param> |
64 | /// <param name="args">The arguments which control which constructor is invoked on the plugin</param> | 216 | /// <param name="args">The arguments which control which constructor is invoked on the plugin</param> |
65 | /// <returns></returns> | 217 | /// <returns></returns> |
66 | public static T LoadPlugin<T>(string dllName, Object[] args) where T:class | 218 | public static T LoadPlugin<T> (string dllName, Object[] args) where T:class |
67 | { | 219 | { |
68 | // This is good to debug configuration problems | 220 | // This is good to debug configuration problems |
69 | //if (dllName == string.Empty) | 221 | //if (dllName == string.Empty) |
70 | // Util.PrintCallStack(); | 222 | // Util.PrintCallStack(); |
71 | 223 | ||
72 | string[] parts = dllName.Split(new char[] {':'}); | ||
73 | |||
74 | dllName = parts[0]; | ||
75 | |||
76 | string className = String.Empty; | 224 | string className = String.Empty; |
77 | 225 | ||
78 | if (parts.Length > 1) | 226 | // The path for a dynamic plugin will contain ":" on Windows |
79 | className = parts[1]; | 227 | string[] parts = dllName.Split (new char[] {':'}); |
228 | |||
229 | if (parts [0].Length > 1) | ||
230 | { | ||
231 | dllName = parts [0]; | ||
232 | if (parts.Length > 1) | ||
233 | className = parts[1]; | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | // This is Windows - we must replace the ":" in the path | ||
238 | dllName = String.Format ("{0}:{1}", parts [0], parts [1]); | ||
239 | if (parts.Length > 2) | ||
240 | className = parts[2]; | ||
241 | } | ||
80 | 242 | ||
81 | return LoadPlugin<T>(dllName, className, args); | 243 | return LoadPlugin<T>(dllName, className, args); |
82 | } | 244 | } |
@@ -118,8 +280,11 @@ namespace OpenSim.Server.Base | |||
118 | { | 280 | { |
119 | if (!(e is System.MissingMethodException)) | 281 | if (!(e is System.MissingMethodException)) |
120 | { | 282 | { |
121 | m_log.ErrorFormat("Error loading plugin {0} from {1}. Exception: {2}", | 283 | m_log.ErrorFormat("Error loading plugin {0} from {1}. Exception: {2}, {3}", |
122 | interfaceName, dllName, e.InnerException == null ? e.Message : e.InnerException.Message); | 284 | interfaceName, |
285 | dllName, | ||
286 | e.InnerException == null ? e.Message : e.InnerException.Message, | ||
287 | e.StackTrace); | ||
123 | } | 288 | } |
124 | return null; | 289 | return null; |
125 | } | 290 | } |
@@ -333,5 +498,42 @@ namespace OpenSim.Server.Base | |||
333 | 498 | ||
334 | return ret; | 499 | return ret; |
335 | } | 500 | } |
501 | |||
502 | public static IConfig GetConfig(string configFile, string configName) | ||
503 | { | ||
504 | IConfig config; | ||
505 | |||
506 | if (File.Exists(configFile)) | ||
507 | { | ||
508 | IConfigSource configsource = new IniConfigSource(configFile); | ||
509 | config = configsource.Configs[configName]; | ||
510 | } | ||
511 | else | ||
512 | config = null; | ||
513 | |||
514 | return config; | ||
515 | } | ||
516 | |||
517 | public static IConfigSource LoadInitialConfig(string url) | ||
518 | { | ||
519 | IConfigSource source = new XmlConfigSource(); | ||
520 | m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", url); | ||
521 | |||
522 | // The ini file path is a http URI | ||
523 | // Try to read it | ||
524 | try | ||
525 | { | ||
526 | XmlReader r = XmlReader.Create(url); | ||
527 | IConfigSource cs = new XmlConfigSource(r); | ||
528 | source.Merge(cs); | ||
529 | } | ||
530 | catch (Exception e) | ||
531 | { | ||
532 | m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), url); | ||
533 | Environment.Exit(1); | ||
534 | } | ||
535 | |||
536 | return source; | ||
537 | } | ||
336 | } | 538 | } |
337 | } | 539 | } |