aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Server/Base/CommandManager.cs359
-rw-r--r--OpenSim/Server/Base/ServerUtils.cs163
-rw-r--r--OpenSim/Server/Base/ServicesServerBase.cs8
-rw-r--r--OpenSim/Server/Handlers/Base/ServerConnector.cs67
-rw-r--r--OpenSim/Server/ServerMain.cs10
5 files changed, 607 insertions, 0 deletions
diff --git a/OpenSim/Server/Base/CommandManager.cs b/OpenSim/Server/Base/CommandManager.cs
new file mode 100644
index 0000000..88aac00
--- /dev/null
+++ b/OpenSim/Server/Base/CommandManager.cs
@@ -0,0 +1,359 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28
29using System;
30using System.Text;
31using System.Linq;
32using System.Collections;
33using System.Collections.Generic;
34using System.Collections.ObjectModel;
35using Mono.Addins;
36// using Mono.Addins.Setup;
37using Mono.Addins.Description;
38using OpenSim.Framework;
39
40namespace OpenSim.Server.Base
41{
42 /// <summary>
43 /// Command manager -
44 /// Wrapper for OpenSim.Framework.PluginManager to allow
45 /// us to add commands to the console to perform operations
46 /// on our repos and plugins
47 /// </summary>
48 public class CommandManager
49 {
50 public AddinRegistry PluginRegistry;
51 protected PluginManager PluginManager;
52
53 public CommandManager(AddinRegistry registry)
54 {
55 PluginRegistry = registry;
56 PluginManager = new PluginManager(PluginRegistry);
57 AddManagementCommands();
58 }
59
60 private void AddManagementCommands()
61 {
62 // add plugin
63 MainConsole.Instance.Commands.AddCommand("Plugin", true,
64 "plugin add", "plugin add \"plugin index\"",
65 "Install plugin from repository.",
66 HandleConsoleInstallPlugin);
67
68 // remove plugin
69 MainConsole.Instance.Commands.AddCommand("Plugin", true,
70 "plugin remove", "plugin remove \"plugin index\"",
71 "Remove plugin from repository",
72 HandleConsoleUnInstallPlugin);
73
74 // list installed plugins
75 MainConsole.Instance.Commands.AddCommand("Plugin", true,
76 "plugin list installed",
77 "plugin list installed","List install plugins",
78 HandleConsoleListInstalledPlugin);
79
80 // list plugins available from registered repositories
81 MainConsole.Instance.Commands.AddCommand("Plugin", true,
82 "plugin list available",
83 "plugin list available","List available plugins",
84 HandleConsoleListAvailablePlugin);
85 // List available updates
86 MainConsole.Instance.Commands.AddCommand("Plugin", true,
87 "plugin updates", "plugin updates","List availble updates",
88 HandleConsoleListUpdates);
89
90 // Update plugin
91 MainConsole.Instance.Commands.AddCommand("Plugin", true,
92 "plugin update", "plugin update \"plugin index\"","Update the plugin",
93 HandleConsoleUpdatePlugin);
94
95 // Add repository
96 MainConsole.Instance.Commands.AddCommand("Repository", true,
97 "repo add", "repo add \"url\"","Add repository",
98 HandleConsoleAddRepo);
99
100 // Refresh repo
101 MainConsole.Instance.Commands.AddCommand("Repository", true,
102 "repo refresh", "repo refresh \"url\"", "Sync with a registered repository",
103 HandleConsoleGetRepo);
104
105 // Remove repository from registry
106 MainConsole.Instance.Commands.AddCommand("Repository", true,
107 "repo remove",
108 "repo remove \"[url | index]\"",
109 "Remove repository from registry",
110 HandleConsoleRemoveRepo);
111
112 // Enable repo
113 MainConsole.Instance.Commands.AddCommand("Repository", true,
114 "repo enable", "repo enable \"[url | index]\"",
115 "Enable registered repository",
116 HandleConsoleEnableRepo);
117
118 // Disable repo
119 MainConsole.Instance.Commands.AddCommand("Repository", true,
120 "repo disable", "repo disable\"[url | index]\"",
121 "Disable registered repository",
122 HandleConsoleDisableRepo);
123
124 // List registered repositories
125 MainConsole.Instance.Commands.AddCommand("Repository", true,
126 "repo list", "repo list",
127 "List registered repositories",
128 HandleConsoleListRepos);
129
130 // *
131 MainConsole.Instance.Commands.AddCommand("Plugin", true,
132 "plugin info", "plugin info \"plugin index\"","Show detailed information for plugin",
133 HandleConsoleShowAddinInfo);
134
135 // Plugin disable
136 MainConsole.Instance.Commands.AddCommand("Plugin", true,
137 "plugin disable", "plugin disable \"plugin index\"",
138 "Disable a plugin",
139 HandleConsoleDisablePlugin);
140
141 // Enable plugin
142 MainConsole.Instance.Commands.AddCommand("Plugin", true,
143 "plugin enable", "plugin enable \"plugin index\"",
144 "Enable the selected plugin plugin",
145 HandleConsoleEnablePlugin);
146 }
147
148 #region console handlers
149 // Handle our console commands
150 //
151 // Install plugin from registered repository
152 /// <summary>
153 /// Handles the console install plugin command. Attempts to install the selected plugin
154 /// and
155 /// </summary>
156 /// <param name='module'>
157 /// Module.
158 /// </param>
159 /// <param name='cmd'>
160 /// Cmd.
161 /// </param>
162 private void HandleConsoleInstallPlugin(string module, string[] cmd)
163 {
164 Dictionary<string, object> result = new Dictionary<string, object>();
165
166 if (cmd.Length == 3)
167 {
168 int ndx = Convert.ToInt16(cmd[2]);
169 if (PluginManager.InstallPlugin(ndx, out result) == true)
170 {
171 ArrayList s = new ArrayList();
172 s.AddRange(result.Keys);
173 s.Sort();
174
175 var list = result.Keys.ToList();
176 list.Sort();
177 foreach (var k in list)
178 {
179 Dictionary<string, object> plugin = (Dictionary<string, object>)result[k];
180 bool enabled = (bool)plugin["enabled"];
181 MainConsole.Instance.OutputFormat("{0}) {1} {2} rev. {3}",
182 k,
183 enabled == true ? "[ ]" : "[X]",
184 plugin["name"], plugin["version"]);
185 }
186 }
187 }
188 return;
189 }
190
191 // Remove installed plugin
192 private void HandleConsoleUnInstallPlugin(string module, string[] cmd)
193 {
194 if (cmd.Length == 3)
195 {
196 int ndx = Convert.ToInt16(cmd[2]);
197 PluginManager.UnInstall(ndx);
198 }
199 return;
200 }
201
202 // List installed plugins
203 private void HandleConsoleListInstalledPlugin(string module, string[] cmd)
204 {
205 Dictionary<string, object> result = new Dictionary<string, object>();
206 PluginManager.ListInstalledAddins(out result);
207
208 ArrayList s = new ArrayList();
209 s.AddRange(result.Keys);
210 s.Sort();
211
212 var list = result.Keys.ToList();
213 list.Sort();
214 foreach (var k in list)
215 {
216 Dictionary<string, object> plugin = (Dictionary<string, object>)result[k];
217 bool enabled = (bool)plugin["enabled"];
218 MainConsole.Instance.OutputFormat("{0}) {1} {2} rev. {3}",
219 k,
220 enabled == true ? "[ ]" : "[X]",
221 plugin["name"], plugin["version"]);
222 }
223 return;
224 }
225
226 // List available plugins on registered repositories
227 private void HandleConsoleListAvailablePlugin(string module, string[] cmd)
228 {
229 Dictionary<string, object> result = new Dictionary<string, object>();
230 PluginManager.ListAvailable(out result);
231
232 var list = result.Keys.ToList();
233 list.Sort();
234 foreach (var k in list)
235 {
236 // name, version, repository
237 Dictionary<string, object> plugin = (Dictionary<string, object>)result[k];
238 MainConsole.Instance.OutputFormat("{0}) {1} rev. {2} {3}",
239 k,
240 plugin["name"],
241 plugin["version"],
242 plugin["repository"]);
243 }
244 return;
245 }
246
247 // List available updates **not ready
248 private void HandleConsoleListUpdates(string module, string[] cmd)
249 {
250 PluginManager.ListUpdates();
251 return;
252 }
253
254 // Update plugin **not ready
255 private void HandleConsoleUpdatePlugin(string module, string[] cmd)
256 {
257 MainConsole.Instance.Output(PluginManager.Update());
258 return;
259 }
260
261 // Register repository
262 private void HandleConsoleAddRepo(string module, string[] cmd)
263 {
264 if ( cmd.Length == 3)
265 {
266 PluginManager.AddRepository(cmd[2]);
267 }
268 return;
269 }
270
271 // Get repository status **not working
272 private void HandleConsoleGetRepo(string module, string[] cmd)
273 {
274 PluginManager.GetRepository();
275 return;
276 }
277
278 // Remove registered repository
279 private void HandleConsoleRemoveRepo(string module, string[] cmd)
280 {
281 if (cmd.Length == 3)
282 PluginManager.RemoveRepository(cmd);
283 return;
284 }
285
286 // Enable repository
287 private void HandleConsoleEnableRepo(string module, string[] cmd)
288 {
289 PluginManager.EnableRepository(cmd);
290 return;
291 }
292
293 // Disable repository
294 private void HandleConsoleDisableRepo(string module, string[] cmd)
295 {
296 PluginManager.DisableRepository(cmd);
297 return;
298 }
299
300 // List repositories
301 private void HandleConsoleListRepos(string module, string[] cmd)
302 {
303 Dictionary<string, object> result = new Dictionary<string, object>();
304 PluginManager.ListRepositories(out result);
305
306 var list = result.Keys.ToList();
307 list.Sort();
308 foreach (var k in list)
309 {
310 Dictionary<string, object> repo = (Dictionary<string, object>)result[k];
311 bool enabled = (bool)repo["enabled"];
312 MainConsole.Instance.OutputFormat("{0}) {1} {2}",
313 k,
314 enabled == true ? "[ ]" : "[X]",
315 repo["name"], repo["url"]);
316 }
317
318 return;
319 }
320
321 // Show description information
322 private void HandleConsoleShowAddinInfo(string module, string[] cmd)
323 {
324 if (cmd.Length >= 3)
325 {
326
327 Dictionary<string, object> result = new Dictionary<string, object>();
328
329 int ndx = Convert.ToInt16(cmd[2]);
330 PluginManager.AddinInfo(ndx, out result);
331
332 MainConsole.Instance.OutputFormat("Name: {0}\nURL: {1}\nFile: {2}\nAuthor: {3}\nCategory: {4}\nDesc: {5}",
333 result["name"],
334 result["url"],
335 result["file_name"],
336 result["author"],
337 result["category"],
338 result["description"]);
339
340 return;
341 }
342 }
343
344 // Disable plugin
345 private void HandleConsoleDisablePlugin(string module, string[] cmd)
346 {
347 PluginManager.DisablePlugin(cmd);
348 return;
349 }
350
351 // Enable plugin
352 private void HandleConsoleEnablePlugin(string module, string[] cmd)
353 {
354 PluginManager.EnablePlugin(cmd);
355 return;
356 }
357 #endregion
358 }
359} \ No newline at end of file
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index 42c82cf..31b0446 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -33,11 +33,137 @@ using System.Xml.Serialization;
33using System.Text; 33using System.Text;
34using System.Collections.Generic; 34using System.Collections.Generic;
35using log4net; 35using log4net;
36using Nini.Config;
36using OpenSim.Framework; 37using OpenSim.Framework;
37using OpenMetaverse; 38using OpenMetaverse;
39using Mono.Addins;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Framework.Servers;
38 42
43
44[assembly:AddinRoot("Robust", "0.1")]
39namespace OpenSim.Server.Base 45namespace 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 AddinManager.Initialize(registryPath);
93 AddinManager.Registry.Update();
94 CommandManager commandmanager = new CommandManager(Registry);
95 AddinManager.AddExtensionNodeHandler("/Robust/Connector", OnExtensionChanged);
96 }
97
98 private void OnExtensionChanged(object s, ExtensionNodeEventArgs args)
99 {
100 IRobustConnector connector = (IRobustConnector)args.ExtensionObject;
101 Addin a = Registry.GetAddin(args.ExtensionNode.Addin.Id);
102
103 if(a == null)
104 {
105 Registry.Rebuild(null);
106 a = Registry.GetAddin(args.ExtensionNode.Addin.Id);
107 }
108
109 switch(args.Change)
110 {
111 case ExtensionChange.Add:
112 if (a.AddinFile.Contains(Registry.DefaultAddinsFolder))
113 {
114 m_log.InfoFormat("[SERVER]: Adding {0} from registry", a.Name);
115 connector.PluginPath = String.Format("{0}/{1}", Registry.DefaultAddinsFolder, a.Name.Replace(',', '.'));
116 }
117 else
118 {
119 m_log.InfoFormat("[SERVER]: Adding {0} from ./bin", a.Name);
120 connector.PluginPath = a.AddinFile;
121 }
122 LoadPlugin(connector);
123 break;
124 case ExtensionChange.Remove:
125 m_log.InfoFormat("[SERVER]: Removing {0}", a.Name);
126 UnloadPlugin(connector);
127 break;
128 }
129 }
130
131 private void LoadPlugin(IRobustConnector connector)
132 {
133 IHttpServer server = null;
134 uint port = connector.Configure(Config);
135
136 if(connector.Enabled)
137 {
138 server = GetServer(connector, port);
139 connector.Initialize(server);
140 }
141 else
142 {
143 m_log.InfoFormat("[SERVER]: {0} Disabled.", connector.ConfigName);
144 }
145 }
146
147 private void UnloadPlugin(IRobustConnector connector)
148 {
149 m_log.InfoFormat("[Server]: Unloading {0}", connector.ConfigName);
150
151 connector.Unload();
152 }
153
154 private IHttpServer GetServer(IRobustConnector connector, uint port)
155 {
156 IHttpServer server;
157
158 if(port != 0)
159 server = MainServer.GetHttpServer(port);
160 else
161 server = MainServer.Instance;
162
163 return server;
164 }
165 }
166
41 public static class ServerUtils 167 public static class ServerUtils
42 { 168 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 169 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -333,5 +459,42 @@ namespace OpenSim.Server.Base
333 459
334 return ret; 460 return ret;
335 } 461 }
462
463 public static IConfig GetConfig(string configFile, string configName)
464 {
465 IConfig config;
466
467 if (File.Exists(configFile))
468 {
469 IConfigSource configsource = new IniConfigSource(configFile);
470 config = configsource.Configs[configName];
471 }
472 else
473 config = null;
474
475 return config;
476 }
477
478 public static IConfigSource LoadInitialConfig(string url)
479 {
480 IConfigSource source = new XmlConfigSource();
481 m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", url);
482
483 // The ini file path is a http URI
484 // Try to read it
485 try
486 {
487 XmlReader r = XmlReader.Create(url);
488 IConfigSource cs = new XmlConfigSource(r);
489 source.Merge(cs);
490 }
491 catch (Exception e)
492 {
493 m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), url);
494 Environment.Exit(1);
495 }
496
497 return source;
498 }
336 } 499 }
337} 500}
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs
index 0cff6ed..2f12288 100644
--- a/OpenSim/Server/Base/ServicesServerBase.cs
+++ b/OpenSim/Server/Base/ServicesServerBase.cs
@@ -64,6 +64,12 @@ namespace OpenSim.Server.Base
64 get { return m_Config; } 64 get { return m_Config; }
65 } 65 }
66 66
67 public string ConfigDirectory
68 {
69 get;
70 private set;
71 }
72
67 // Run flag 73 // Run flag
68 // 74 //
69 private bool m_Running = true; 75 private bool m_Running = true;
@@ -153,6 +159,8 @@ namespace OpenSim.Server.Base
153 startupConfig = m_Config.Configs["Startup"]; 159 startupConfig = m_Config.Configs["Startup"];
154 } 160 }
155 161
162 ConfigDirectory = startupConfig.GetString("ConfigDirectory", ".");
163
156 prompt = startupConfig.GetString("Prompt", prompt); 164 prompt = startupConfig.GetString("Prompt", prompt);
157 165
158 // Allow derived classes to load config before the console is 166 // Allow derived classes to load config before the console is
diff --git a/OpenSim/Server/Handlers/Base/ServerConnector.cs b/OpenSim/Server/Handlers/Base/ServerConnector.cs
index 71876da..72014db 100644
--- a/OpenSim/Server/Handlers/Base/ServerConnector.cs
+++ b/OpenSim/Server/Handlers/Base/ServerConnector.cs
@@ -39,8 +39,75 @@ namespace OpenSim.Server.Handlers.Base
39 39
40 public class ServiceConnector : IServiceConnector 40 public class ServiceConnector : IServiceConnector
41 { 41 {
42 public virtual string ConfigURL
43 {
44 get { return String.Empty; }
45 }
46
47 public virtual string ConfigName
48 {
49 get;
50 protected set;
51 }
52
53 public virtual string ConfigFile
54 {
55 get;
56 protected set;
57 }
58
59 public virtual IConfigSource Config
60 {
61 get;
62 protected set;
63 }
64
65 public ServiceConnector()
66 {
67 }
68
42 public ServiceConnector(IConfigSource config, IHttpServer server, string configName) 69 public ServiceConnector(IConfigSource config, IHttpServer server, string configName)
43 { 70 {
44 } 71 }
72
73 // We call this from our plugin module to get our configuration
74 public IConfig GetConfig()
75 {
76 IConfig config = null;
77 config = ServerUtils.GetConfig(ConfigFile, ConfigName);
78
79 // Our file is not here? We can get one to bootstrap our plugin module
80 if ( config == null )
81 {
82 IConfigSource remotesource = GetConfigSource();
83
84 if (remotesource != null)
85 {
86 IniConfigSource initialconfig = new IniConfigSource();
87 initialconfig.Merge (remotesource);
88 initialconfig.Save(ConfigFile);
89 }
90
91 config = remotesource.Configs[ConfigName];
92 }
93
94 return config;
95 }
96
97 // We get our remote initial configuration for bootstrapping in case
98 // we have no configuration in our main file or in an existing
99 // modular config file. This is the last resort to bootstrap the
100 // configuration, likely a new plugin loading for the first time.
101 private IConfigSource GetConfigSource()
102 {
103 IConfigSource source = null;
104
105 source = ServerUtils.LoadInitialConfig(ConfigURL);
106
107 if (source == null)
108 System.Console.WriteLine(String.Format ("Config Url: {0} Not found!", ConfigURL));
109
110 return source;
111 }
45 } 112 }
46} 113}
diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs
index 45c13fb..8be69a9 100644
--- a/OpenSim/Server/ServerMain.cs
+++ b/OpenSim/Server/ServerMain.cs
@@ -34,6 +34,7 @@ using OpenSim.Framework.Servers;
34using OpenSim.Framework.Servers.HttpServer; 34using OpenSim.Framework.Servers.HttpServer;
35using OpenSim.Server.Base; 35using OpenSim.Server.Base;
36using OpenSim.Server.Handlers.Base; 36using OpenSim.Server.Handlers.Base;
37using Mono.Addins;
37 38
38namespace OpenSim.Server 39namespace OpenSim.Server
39{ 40{
@@ -48,9 +49,13 @@ namespace OpenSim.Server
48 protected static List<IServiceConnector> m_ServiceConnectors = 49 protected static List<IServiceConnector> m_ServiceConnectors =
49 new List<IServiceConnector>(); 50 new List<IServiceConnector>();
50 51
52 protected static PluginLoader loader;
53
51 public static int Main(string[] args) 54 public static int Main(string[] args)
52 { 55 {
53 m_Server = new HttpServerBase("R.O.B.U.S.T.", args); 56 m_Server = new HttpServerBase("R.O.B.U.S.T.", args);
57
58 string registryLocation;
54 59
55 IConfig serverConfig = m_Server.Config.Configs["Startup"]; 60 IConfig serverConfig = m_Server.Config.Configs["Startup"];
56 if (serverConfig == null) 61 if (serverConfig == null)
@@ -60,6 +65,8 @@ namespace OpenSim.Server
60 } 65 }
61 66
62 string connList = serverConfig.GetString("ServiceConnectors", String.Empty); 67 string connList = serverConfig.GetString("ServiceConnectors", String.Empty);
68
69 registryLocation = serverConfig.GetString("RegistryLocation",".");
63 70
64 IConfig servicesConfig = m_Server.Config.Configs["ServiceList"]; 71 IConfig servicesConfig = m_Server.Config.Configs["ServiceList"];
65 if (servicesConfig != null) 72 if (servicesConfig != null)
@@ -141,6 +148,9 @@ namespace OpenSim.Server
141 m_log.InfoFormat("[SERVER]: Failed to load {0}", conn); 148 m_log.InfoFormat("[SERVER]: Failed to load {0}", conn);
142 } 149 }
143 } 150 }
151
152 loader = new PluginLoader(m_Server.Config, registryLocation);
153
144 int res = m_Server.Run(); 154 int res = m_Server.Run();
145 155
146 Environment.Exit(res); 156 Environment.Exit(res);