From 440726250cc2a523463f575b682a6ddb6242408c Mon Sep 17 00:00:00 2001
From: BlueWall
Date: Sat, 6 Oct 2012 11:48:21 -0400
Subject: Added parts to manage repositories and plugin management

  This is working - more testing to follow, then soem documentation
---
 OpenSim/Server/Base/CommandManager.cs           | 353 +++++++++++++++
 OpenSim/Server/Base/PluginManager.cs            | 555 ++++++++++++++++++++++++
 OpenSim/Server/Base/ServerUtils.cs              | 106 +++++
 OpenSim/Server/Handlers/Base/ServerConnector.cs |   4 +
 OpenSim/Server/ServerMain.cs                    |  10 +
 bin/Robust.HG.ini.example                       |   8 +
 bin/Robust.ini.example                          |   8 +
 prebuild.xml                                    |   8 +-
 8 files changed, 1051 insertions(+), 1 deletion(-)
 create mode 100644 OpenSim/Server/Base/CommandManager.cs
 create mode 100644 OpenSim/Server/Base/PluginManager.cs

diff --git a/OpenSim/Server/Base/CommandManager.cs b/OpenSim/Server/Base/CommandManager.cs
new file mode 100644
index 0000000..45652b3
--- /dev/null
+++ b/OpenSim/Server/Base/CommandManager.cs
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+using System;
+using System.Text;
+using System.Linq;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Mono.Addins;
+using Mono.Addins.Setup;
+using Mono.Addins.Description;
+using OpenSim.Framework;
+
+namespace OpenSim.Server.Base
+{
+	public class CommandManager
+	{
+		protected AddinRegistry PluginRegistry;
+		protected PluginManager PluginManager;
+
+		public CommandManager(AddinRegistry registry)
+        {
+			PluginRegistry = registry;
+			PluginManager = new PluginManager(PluginRegistry);
+			AddManagementCommands();
+		}
+
+		private void AddManagementCommands()
+		{
+			// add plugin
+			MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin add", "plugin add \"plugin index\"",
+			                                         "Install plugin from repository.",
+                                                     HandleConsoleInstallPlugin);
+
+			// remove plugin
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin remove", "plugin remove \"plugin index\"",
+			                                         "Remove plugin from repository",
+                                                     HandleConsoleUnInstallPlugin);
+
+			// list installed plugins
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin list installed", 
+			                                         "plugin list installed","List install plugins",
+                                                     HandleConsoleListInstalledPlugin);
+
+			// list plugins available from registered repositories
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin list available",
+			                                         "plugin list available","List available plugins",
+                                                     HandleConsoleListAvailablePlugin);
+			// List available updates
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin updates", "plugin updates","List availble updates",
+                                                     HandleConsoleListUpdates);
+
+			// Update plugin
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin update", "plugin update \"plugin index\"","Update the plugin",
+                                                     HandleConsoleUpdatePlugin);
+
+			// Add repository
+            MainConsole.Instance.Commands.AddCommand("Repository", true,
+                                                     "repo add", "repo add \"url\"","Add repository",
+                                                     HandleConsoleAddRepo);
+
+			// Refresh repo
+            MainConsole.Instance.Commands.AddCommand("Repository", true,
+                                                     "repo refresh", "repo refresh \"url\"", "Sync with a registered repository",
+                                                     HandleConsoleGetRepo);
+
+			// Remove repository from registry
+            MainConsole.Instance.Commands.AddCommand("Repository", true,
+                                                     "repo remove",
+			                                         "repo remove \"[url | index]\"",
+			                                         "Remove repository from registry",
+                                                     HandleConsoleRemoveRepo);
+
+			// Enable repo
+            MainConsole.Instance.Commands.AddCommand("Repository", true,
+                                                     "repo enable", "repo enable \"[url | index]\"",
+			                                         "Enable registered repository",
+                                                     HandleConsoleEnableRepo);
+
+			// Disable repo
+            MainConsole.Instance.Commands.AddCommand("Repository", true,
+                                                     "repo disable", "repo disable\"[url | index]\"",
+			                                         "Disable registered repository",
+                                                     HandleConsoleDisableRepo);
+
+			// List registered repositories
+            MainConsole.Instance.Commands.AddCommand("Repository", true,
+                                                     "repo list", "repo list",
+			                                         "List registered repositories",
+                                                     HandleConsoleListRepos);
+
+			// *
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin info", "plugin info \"plugin index\"","Show detailed information for plugin",
+                                                     HandleConsoleShowAddinInfo);
+
+			// Plugin disable
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin disable", "plugin disable \"plugin index\"",
+			                                         "Disable a plugin",
+                                                     HandleConsoleDisablePlugin);
+
+			// Enable plugin
+            MainConsole.Instance.Commands.AddCommand("Plugin", true,
+                                                     "plugin enable", "plugin enable \"plugin index\"",
+			                                         "Enable the selected plugin plugin",
+                                                     HandleConsoleEnablePlugin);
+        }
+		
+        #region console handlers
+        // Handle our console commands
+        //
+        // Install plugin from registered repository
+        /// <summary>
+        /// Handles the console install plugin command. Attempts to install the selected plugin
+        /// and 
+        /// </summary>
+        /// <param name='module'>
+        /// Module.
+        /// </param>
+        /// <param name='cmd'>
+        /// Cmd.
+        /// </param>
+        private void HandleConsoleInstallPlugin(string module, string[] cmd)
+        {
+            Dictionary<string, object> result = new Dictionary<string, object>();
+
+            if (cmd.Length == 3)
+            {
+                int ndx = Convert.ToInt16(cmd[2]);
+                if (PluginManager.InstallPlugin(ndx, out result) == true)
+                {
+                    ArrayList s = new ArrayList();
+                    s.AddRange(result.Keys);
+                    s.Sort();
+
+                    var list = result.Keys.ToList();
+                    list.Sort();
+                    foreach (var k in list)
+                    {
+                        Dictionary<string, object> plugin = (Dictionary<string, object>)result[k];
+                        bool enabled = (bool)plugin["enabled"];
+                        MainConsole.Instance.OutputFormat("{0}) {1} {2} rev. {3}",
+                                                  k,
+                                                  enabled == true ? "[ ]" : "[X]",
+                                                  plugin["name"], plugin["version"]);
+                    }
+                }
+            }
+            return;
+        }
+
+        // Remove installed plugin
+        private void HandleConsoleUnInstallPlugin(string module, string[] cmd)
+        {
+            if (cmd.Length == 3)
+            {
+                int ndx = Convert.ToInt16(cmd[2]);
+                PluginManager.UnInstall(ndx);
+            }
+            return;
+        }
+
+        // List installed plugins
+        private void HandleConsoleListInstalledPlugin(string module, string[] cmd)
+        {
+            Dictionary<string, object> result = new Dictionary<string, object>();
+            PluginManager.ListInstalledAddins(out result);
+
+            ArrayList s = new ArrayList();
+            s.AddRange(result.Keys);
+            s.Sort();
+
+            var list = result.Keys.ToList();
+            list.Sort();
+            foreach (var k in list)
+            {
+                Dictionary<string, object> plugin = (Dictionary<string, object>)result[k];
+                bool enabled = (bool)plugin["enabled"];
+                MainConsole.Instance.OutputFormat("{0}) {1} {2} rev. {3}",
+                                                  k,
+                                                  enabled == true ? "[ ]" : "[X]",
+                                                  plugin["name"], plugin["version"]);
+            }
+            return;
+        }
+
+        // List available plugins on registered repositories
+        private void HandleConsoleListAvailablePlugin(string module, string[] cmd)
+        {
+            Dictionary<string, object> result = new Dictionary<string, object>();
+            PluginManager.ListAvailable(out result);
+
+            var list = result.Keys.ToList();
+            list.Sort();
+            foreach (var k in list)
+            {
+                // name, version, repository
+                Dictionary<string, object> plugin = (Dictionary<string, object>)result[k];
+                MainConsole.Instance.OutputFormat("{0}) {1} rev. {2} {3}",
+                                                  k,
+                                                  plugin["name"],
+                                                  plugin["version"],
+                                                  plugin["repository"]);
+            }
+            return;
+        }
+
+        // List available updates **not ready
+        private void HandleConsoleListUpdates(string module, string[] cmd)
+        {
+            PluginManager.ListUpdates();
+            return;
+        }
+
+        // Update plugin **not ready
+        private void HandleConsoleUpdatePlugin(string module, string[] cmd)
+        {
+            MainConsole.Instance.Output(PluginManager.Update());
+            return;
+        }
+
+        // Register repository
+        private void HandleConsoleAddRepo(string module, string[] cmd)
+        {
+            if ( cmd.Length == 3)
+            {
+                PluginManager.AddRepository(cmd[2]);
+            }
+            return;
+        }
+
+        // Get repository status **not working
+        private void HandleConsoleGetRepo(string module, string[] cmd)
+        {
+            PluginManager.GetRepository();
+            return;
+        }
+
+        // Remove registered repository
+        private void HandleConsoleRemoveRepo(string module, string[] cmd)
+        {
+            if (cmd.Length == 3)
+                PluginManager.RemoveRepository(cmd);
+            return;
+        }
+
+        // Enable repository
+        private void HandleConsoleEnableRepo(string module, string[] cmd)
+        {
+            PluginManager.EnableRepository(cmd);
+            return;
+        }
+
+        // Disable repository
+        private void HandleConsoleDisableRepo(string module, string[] cmd)
+        {
+            PluginManager.DisableRepository(cmd);
+            return;
+        }
+
+        // List repositories
+        private void HandleConsoleListRepos(string module, string[] cmd)
+        {
+            Dictionary<string, object> result = new Dictionary<string, object>();
+            PluginManager.ListRepositories(out result);
+
+            var list = result.Keys.ToList();
+            list.Sort();
+            foreach (var k in list)
+            {
+                Dictionary<string, object> repo = (Dictionary<string, object>)result[k];
+                bool enabled = (bool)repo["enabled"];
+                MainConsole.Instance.OutputFormat("{0}) {1} {2}",
+                                                  k,
+                                                  enabled == true ? "[ ]" : "[X]",
+                                                  repo["name"], repo["url"]);
+            }
+
+            return;
+        }
+
+        // Show description information
+        private void HandleConsoleShowAddinInfo(string module, string[] cmd)
+        {
+            if (cmd.Length >= 3)
+            {
+                
+                Dictionary<string, object> result = new Dictionary<string, object>();
+
+                int ndx = Convert.ToInt16(cmd[2]);
+                PluginManager.AddinInfo(ndx, out result);
+
+                MainConsole.Instance.OutputFormat("Name: {0}\nURL: {1}\nFile: {2}\nAuthor: {3}\nCategory: {4}\nDesc: {5}",
+                                                  result["name"],
+                                                  result["url"],
+                                                  result["file_name"],
+                                                  result["author"],
+                                                  result["category"],
+                                                  result["description"]);
+
+                return;
+            }
+        }
+
+        // Disable plugin
+        private void HandleConsoleDisablePlugin(string module, string[] cmd)
+        {
+            PluginManager.DisablePlugin(cmd);
+            return;
+        }
+
+        // Enable plugin
+        private void HandleConsoleEnablePlugin(string module, string[] cmd)
+        {
+            PluginManager.EnablePlugin(cmd);
+            return;
+        }
+        #endregion
+	}
+}
\ No newline at end of file
diff --git a/OpenSim/Server/Base/PluginManager.cs b/OpenSim/Server/Base/PluginManager.cs
new file mode 100644
index 0000000..6248e74
--- /dev/null
+++ b/OpenSim/Server/Base/PluginManager.cs
@@ -0,0 +1,555 @@
+
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+using System;
+using System.Text;
+using System.Linq;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Mono.Addins;
+using Mono.Addins.Setup;
+using Mono.Addins.Description;
+using OpenSim.Framework;
+
+namespace OpenSim.Server.Base
+{
+	public class PluginManager : SetupService
+	{
+		protected AddinRegistry PluginRegistry;
+
+		internal PluginManager(AddinRegistry registry): base (registry)
+        {
+			PluginRegistry = registry;
+
+		}
+
+		        /// <summary>
+        /// Installs the plugin.
+        /// </summary>
+        /// <returns>
+        /// The plugin.
+        /// </returns>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public bool InstallPlugin(int ndx, out Dictionary<string, object> result)
+        {
+            Dictionary<string, object> res = new Dictionary<string, object>();
+
+            PackageCollection pack = new PackageCollection();
+            PackageCollection toUninstall;
+            DependencyCollection unresolved;
+
+            IProgressStatus ps = new ConsoleProgressStatus(false);
+
+            AddinRepositoryEntry[] available = GetSortedAvailbleAddins();
+
+            if (ndx > (available.Length - 1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                result = res;
+                return false;
+            }
+
+            AddinRepositoryEntry aentry = available[ndx];
+
+            Package p = Package.FromRepository(aentry);
+            pack.Add(p);
+
+            ResolveDependencies(ps, pack, out toUninstall, out unresolved);
+
+            // Attempt to install the plugin disabled
+            if (Install(ps, pack) == true)
+            {
+                PluginRegistry.Update(ps);
+                Addin addin = PluginRegistry.GetAddin(aentry.Addin.Id);
+                PluginRegistry.DisableAddin(addin.Id);
+                addin.Enabled = false;
+                
+                MainConsole.Instance.Output("Installation Success");
+                ListInstalledAddins(out res);
+                result = res;
+                return true;
+            } 
+            else
+            {                
+                MainConsole.Instance.Output("Installation Failed");
+                result = res;
+                return false;
+            }
+        }
+
+        // Remove plugin
+        /// <summary>
+        /// Uns the install.
+        /// </summary>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public void UnInstall(int ndx)
+        {
+            Addin[] addins = GetSortedAddinList("RobustPlugin");
+
+            if (ndx > (addins.Length -1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return;
+            }
+
+            Addin addin = addins[ndx];
+            MainConsole.Instance.OutputFormat("Uninstalling plugin {0}", addin.Id);
+            AddinManager.Registry.DisableAddin(addin.Id);
+            addin.Enabled = false;
+            IProgressStatus ps = new ConsoleProgressStatus(false);
+            Uninstall(ps, addin.Id);
+            MainConsole.Instance.Output("Uninstall Success - restart to complete operation");
+            return;
+        }
+
+        /// <summary>
+        /// Checks the installed.
+        /// </summary>
+        /// <returns>
+        /// The installed.
+        /// </returns>
+        public string CheckInstalled()
+        {
+            return "CheckInstall";
+        }
+
+        /// <summary>
+        /// Lists the installed addins.
+        /// </summary>
+        /// <param name='result'>
+        /// Result.
+        /// </param>
+        public void ListInstalledAddins(out Dictionary<string, object> result)
+        {
+            Dictionary<string, object> res = new Dictionary<string, object>();
+
+			Addin[] addins = GetSortedAddinList("RobustPlugin");
+			if(addins.Count() < 1)
+			{
+				MainConsole.Instance.Output("Error!");
+			}
+            int count = 0;
+            foreach (Addin addin in addins)
+            {
+                Dictionary<string, object> r = new Dictionary<string, object>();
+                r["enabled"] = addin.Enabled == true ? true : false;
+                r["name"] = addin.LocalId;
+                r["version"] = addin.Version;
+
+                res.Add(count.ToString(), r);
+
+                count++;
+            }
+            result = res;
+            return;
+        }
+
+        // List compatible plugins in registered repositories
+        /// <summary>
+        /// Lists the available.
+        /// </summary>
+        /// <param name='result'>
+        /// Result.
+        /// </param>
+        public void ListAvailable(out Dictionary<string, object> result)
+        {
+            Dictionary<string, object> res = new Dictionary<string, object>();
+
+            AddinRepositoryEntry[] addins = GetSortedAvailbleAddins();
+
+            int count = 0;
+            foreach (AddinRepositoryEntry addin in addins)
+            {
+                Dictionary<string, object> r = new Dictionary<string, object>();
+                r["name"] = addin.Addin.Name;
+                r["version"] = addin.Addin.Version;
+                r["repository"] = addin.RepositoryName;
+
+                res.Add(count.ToString(), r);
+                count++;
+            }
+            result = res;
+            return;
+        }
+
+        // List available updates ** 1
+        /// <summary>
+        /// Lists the updates.
+        /// </summary>
+        public void ListUpdates()
+        {
+            IProgressStatus ps = new ConsoleProgressStatus(true);
+            Console.WriteLine ("Looking for updates...");
+            Repositories.UpdateAllRepositories (ps);
+            Console.WriteLine ("Available add-in updates:");
+            bool found = false;
+            AddinRepositoryEntry[] entries = Repositories.GetAvailableUpdates();
+
+            foreach (AddinRepositoryEntry entry in entries)
+            {
+                Console.WriteLine(String.Format("{0}",entry.Addin.Id));
+            }
+        }
+
+        // Sync to repositories
+        /// <summary>
+        /// Update this instance.
+        /// </summary>
+        public string Update()
+        {
+            IProgressStatus ps = new ConsoleProgressStatus(true);
+            Repositories.UpdateAllRepositories(ps);
+            return "Update";
+        }
+
+        // Register a repository
+        /// <summary>
+        /// Register a repository with our server.
+        /// </summary>
+        /// <returns>
+        /// result of the action
+        /// </returns>
+        /// <param name='repo'>
+        /// The URL of the repository we want to add
+        /// </param>
+        public bool AddRepository(string repo)
+        {
+            Repositories.RegisterRepository(null, repo, true);
+            return true;
+        }
+
+        /// <summary>
+        /// Gets the repository.
+        /// </summary>
+        public void GetRepository()
+        {
+            Repositories.UpdateAllRepositories(new ConsoleProgressStatus(false));
+        }
+
+        // Remove a repository from the list
+        /// <summary>
+        /// Removes the repository.
+        /// </summary>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public void RemoveRepository(string[] args)
+        {
+            AddinRepository[] reps = Repositories.GetRepositories();
+            Array.Sort(reps, (r1,r2) => r1.Title.CompareTo(r2.Title));
+            if (reps.Length == 0)
+            {
+                MainConsole.Instance.Output("No repositories have been registered.");
+                return;
+            }
+
+            int n = Convert.ToInt16(args[2]);
+            if (n > (reps.Length -1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return;
+            }
+
+            AddinRepository rep = reps[n];
+            Repositories.RemoveRepository(rep.Url);
+            return;
+        }
+
+        // Enable repository
+        /// <summary>
+        /// Enables the repository.
+        /// </summary>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public void EnableRepository(string[] args)
+        {
+            AddinRepository[] reps = Repositories.GetRepositories();
+            Array.Sort(reps, (r1,r2) => r1.Title.CompareTo(r2.Title));
+            if (reps.Length == 0)
+            {
+                MainConsole.Instance.Output("No repositories have been registered.");
+                return;
+            }
+
+            int n = Convert.ToInt16(args[2]);
+            if (n > (reps.Length -1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return;
+            }
+
+            AddinRepository rep = reps[n];
+            Repositories.SetRepositoryEnabled(rep.Url, true);
+            return;
+        }
+
+        // Disable a repository
+        /// <summary>
+        /// Disables the repository.
+        /// </summary>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public void DisableRepository(string[] args)
+        {
+            AddinRepository[] reps = Repositories.GetRepositories();
+            Array.Sort(reps, (r1,r2) => r1.Title.CompareTo(r2.Title));
+            if (reps.Length == 0)
+            {
+                MainConsole.Instance.Output("No repositories have been registered.");
+                return;
+            }
+
+            int n = Convert.ToInt16(args[2]);
+            if (n > (reps.Length -1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return;
+            }
+
+            AddinRepository rep = reps[n];
+            Repositories.SetRepositoryEnabled(rep.Url, false);
+            return;
+        }
+
+        // List registered repositories
+        /// <summary>
+        /// Lists the repositories.
+        /// </summary>
+        /// <param name='result'>
+        /// Result.
+        /// </param>
+        public void ListRepositories(out Dictionary<string, object> result)
+        {
+            Dictionary<string, object> res = new Dictionary<string, object>();
+            result = res;
+
+            AddinRepository[] reps = GetSortedAddinRepo();
+            if (reps.Length == 0)
+            {
+                MainConsole.Instance.Output("No repositories have been registered.");
+                return;
+            }
+
+            int count = 0;
+            foreach (AddinRepository rep in reps)
+            {
+                Dictionary<string, object> r = new Dictionary<string, object>();
+                r["enabled"] = rep.Enabled == true ? true : false;
+                r["name"] = rep.Name;
+                r["url"] = rep.Url;
+                
+                res.Add(count.ToString(), r);
+                count++;
+            }
+            return;
+        }
+
+        /// <summary>
+        /// Updates the registry.
+        /// </summary>
+        public void UpdateRegistry()
+        {
+            PluginRegistry.Update();
+        }
+
+        // Show plugin info
+        /// <summary>
+        /// Addins the info.
+        /// </summary>
+        /// <returns>
+        /// The info.
+        /// </returns>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public bool AddinInfo(int ndx, out Dictionary<string, object> result)
+        {
+            Dictionary<string, object> res = new Dictionary<string, object>();
+            result = res;
+
+            Addin[] addins = GetSortedAddinList("RobustPlugin");
+
+            if (ndx > (addins.Length - 1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return false;
+            }
+            // author category description
+            Addin addin = addins[ndx];
+
+            res["author"] = addin.Description.Author;
+            res["category"] = addin.Description.Category;
+            res["description"] = addin.Description.Description;
+            res["name"] = addin.Name;
+            res["url"] = addin.Description.Url;
+            res["file_name"] = addin.Description.FileName;
+
+            result = res;
+            return true;
+        }
+
+        // Disable a plugin
+        /// <summary>
+        /// Disables the plugin.
+        /// </summary>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public void DisablePlugin(string[] args)
+        {
+            Addin[] addins = GetSortedAddinList("RobustPlugin");
+
+            int n = Convert.ToInt16(args[2]);
+            if (n > (addins.Length -1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return;
+            }
+
+            Addin addin = addins[n];
+            AddinManager.Registry.DisableAddin(addin.Id);
+            addin.Enabled = false;
+            return;
+        }
+
+        // Enable plugin
+        /// <summary>
+        /// Enables the plugin.
+        /// </summary>
+        /// <param name='args'>
+        /// Arguments.
+        /// </param>
+        public void EnablePlugin(string[] args)
+        {
+            Addin[] addins = GetSortedAddinList("RobustPlugin");
+
+            int n = Convert.ToInt16(args[2]);
+            if (n > (addins.Length -1))
+            {
+                MainConsole.Instance.Output("Selection out of range");
+                return;
+            }
+
+            Addin addin = addins[n];
+
+            addin.Enabled = true;
+            AddinManager.Registry.EnableAddin(addin.Id);
+            // AddinManager.Registry.Update();
+            if(PluginRegistry.IsAddinEnabled(addin.Id))
+            {
+                ConsoleProgressStatus ps = new ConsoleProgressStatus(false);
+                if (!AddinManager.AddinEngine.IsAddinLoaded(addin.Id))
+                {
+                    AddinManager.Registry.Rebuild(ps);
+                    AddinManager.AddinEngine.LoadAddin(ps, addin.Id);
+                }
+            }
+            else
+            {
+                MainConsole.Instance.OutputFormat("Not Enabled in this domain {0}", addin.Name);
+            }
+            return;
+        }
+
+
+		
+        #region Util
+        private void Testing()
+        {
+            Addin[] list = Registry.GetAddins();
+
+            var addins = list.Where( a => a.Description.Category == "RobustPlugin");
+
+            foreach (Addin addin in addins)
+            {
+                MainConsole.Instance.OutputFormat("Addin {0}", addin.Name);
+            }
+        }
+
+        // These will let us deal with numbered lists instead
+        // of needing to type in the full ids
+        private AddinRepositoryEntry[] GetSortedAvailbleAddins()
+        {
+            ArrayList list = new ArrayList();
+            list.AddRange(Repositories.GetAvailableAddins());
+
+            AddinRepositoryEntry[] addins = list.ToArray(typeof(AddinRepositoryEntry)) as AddinRepositoryEntry[];
+
+            Array.Sort(addins,(r1,r2) => r1.Addin.Id.CompareTo(r2.Addin.Id));
+
+            return addins;
+        }
+
+        private AddinRepository[] GetSortedAddinRepo()
+        {
+            ArrayList list = new ArrayList();
+            list.AddRange(Repositories.GetRepositories());
+
+            AddinRepository[] repos = list.ToArray(typeof(AddinRepository)) as AddinRepository[];
+            Array.Sort (repos,(r1,r2) => r1.Name.CompareTo(r2.Name));
+
+            return repos;
+        }
+
+        private Addin[] GetSortedAddinList(string category)
+        {
+
+            ArrayList xlist = new ArrayList();
+            ArrayList list = new ArrayList();
+			try 
+			{
+            	list.AddRange(PluginRegistry.GetAddins());
+			}
+			catch(Exception e)
+			{
+				Addin[] x = xlist.ToArray(typeof(Addin)) as Addin[];
+				return x;
+			}
+
+            foreach (Addin addin in list)
+            {
+                if (addin.Description.Category == category)
+                    xlist.Add(addin);
+            }
+
+            Addin[] addins = xlist.ToArray(typeof(Addin)) as Addin[];
+            Array.Sort(addins,(r1,r2) => r1.Id.CompareTo(r2.Id));
+
+            return addins;
+        }
+        #endregion Util
+	}
+}
\ No newline at end of file
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index 4a696c4..6c6af62 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -36,9 +36,115 @@ using log4net;
 using Nini.Config;
 using OpenSim.Framework;
 using OpenMetaverse;
+using Mono.Addins;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Framework.Servers;
 
+
+[assembly:AddinRoot("Robust", "0.1")]
 namespace OpenSim.Server.Base
 {
+    [TypeExtensionPoint(Path="/Robust/Connector", Name="RobustConnector")]
+    public interface IRobustConnector
+    {
+        string ConfigName
+        {
+            get;
+        }
+
+        bool Enabled
+        {
+            get;
+        }
+
+        string PluginPath
+        {
+            get;
+            set;
+        }
+
+        uint Configure(IConfigSource config);
+        void Initialize(IHttpServer server);
+    }
+
+    public class PluginLoader
+    {
+        static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        public AddinRegistry Registry
+        {
+            get;
+            private set;
+        }
+
+        public IConfigSource Config
+        {
+            get;
+            private set;
+        }
+
+        public PluginLoader(IConfigSource config, string registryPath)
+        {
+            Config = config;
+
+            Registry = new AddinRegistry(registryPath, ".");
+            AddinManager.Initialize(registryPath);
+            AddinManager.Registry.Update();
+            CommandManager commandmanager = new CommandManager(Registry);
+            AddinManager.AddExtensionNodeHandler("/Robust/Connector", OnExtensionChanged);
+        }
+
+        private void OnExtensionChanged(object s, ExtensionNodeEventArgs args)
+        {
+            IRobustConnector connector = (IRobustConnector)args.ExtensionObject;
+
+            Addin a = Registry.GetAddin(args.ExtensionNode.Addin.Id);
+            m_log.InfoFormat("[SERVER]: Extension Change: {0}/{1}", Registry.DefaultAddinsFolder, a.Name.Replace(',', '.'));
+
+            switch(args.Change)
+            {
+                case ExtensionChange.Add:
+                    connector.PluginPath = String.Format("{0}/{1}", Registry.DefaultAddinsFolder, a.Name.Replace(',', '.'));
+                    LoadPlugin(connector);
+                    break;
+                case ExtensionChange.Remove:
+                    UnloadPlugin(connector);
+                    break;
+            }
+        }
+
+        private void LoadPlugin(IRobustConnector connector)
+        {
+            IHttpServer server = null;
+            uint port = connector.Configure(Config);
+
+            if(connector.Enabled)
+            {
+                server = GetServer(connector, port);
+                m_log.InfoFormat("[SERVER]: Path is {0}", connector.PluginPath);
+                connector.Initialize(server);
+            }
+            else
+                m_log.InfoFormat("[SERVER]: {0} Disabled.", connector.ConfigName);
+        }
+
+        private void UnloadPlugin(IRobustConnector connector)
+        {
+        }
+
+        private IHttpServer GetServer(IRobustConnector connector, uint port)
+        {
+            IHttpServer server;
+
+            if(port != 0)
+                server = MainServer.GetHttpServer(port);
+            else    
+                server = MainServer.Instance;
+
+            return server;
+        }
+    }
+
     public static class ServerUtils
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Server/Handlers/Base/ServerConnector.cs b/OpenSim/Server/Handlers/Base/ServerConnector.cs
index 951cd89..067fd2a 100644
--- a/OpenSim/Server/Handlers/Base/ServerConnector.cs
+++ b/OpenSim/Server/Handlers/Base/ServerConnector.cs
@@ -63,6 +63,10 @@ namespace OpenSim.Server.Handlers.Base
             protected set;
         }
 
+        public ServiceConnector()
+        {
+        }
+
         public ServiceConnector(IConfigSource config, IHttpServer server, string configName)
         {
         }
diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs
index 21fb678..575d560 100644
--- a/OpenSim/Server/ServerMain.cs
+++ b/OpenSim/Server/ServerMain.cs
@@ -34,6 +34,7 @@ using OpenSim.Framework.Servers;
 using OpenSim.Framework.Servers.HttpServer;
 using OpenSim.Server.Base;
 using OpenSim.Server.Handlers.Base;
+using Mono.Addins;
 
 namespace OpenSim.Server
 {
@@ -48,9 +49,13 @@ namespace OpenSim.Server
         protected static List<IServiceConnector> m_ServiceConnectors =
                 new List<IServiceConnector>();
 
+        protected static PluginLoader loader;
+
         public static int Main(string[] args)
         {
             m_Server = new HttpServerBase("R.O.B.U.S.T.", args);
+            
+            string registryLocation;
 
             IConfig serverConfig = m_Server.Config.Configs["Startup"];
             if (serverConfig == null)
@@ -61,6 +66,8 @@ namespace OpenSim.Server
 
             string connList = serverConfig.GetString("ServiceConnectors", String.Empty);
             string[] conns = connList.Split(new char[] {',', ' '});
+            
+            registryLocation = serverConfig.GetString("RegistryLocation",".");
 
 //            int i = 0;
             foreach (string c in conns)
@@ -123,6 +130,9 @@ namespace OpenSim.Server
                     m_log.InfoFormat("[SERVER]: Failed to load {0}", conn);
                 }
             }
+
+            loader = new PluginLoader(m_Server.Config, registryLocation);
+
             int res = m_Server.Run();
 
             Environment.Exit(res);
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index 995f181..107a42d 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -23,8 +23,16 @@
 [Startup]
 ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector,8002/OpenSim.Server.Handlers.dll:HGFriendsServerConnector,8002/OpenSim.Server.Handlers.dll:InstantMessageServerConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
 
+; Plugin Registry Location
+; Set path to directory for plugin registry. Information
+; about the registered repositories and installed plugins
+; will be stored here
+; The Robust.exe process must hvae R/W access to the location 
+RegistryLocation = "."
+
 ; Modular configurations
 ; Set path to directory for modular ini files...
+; The Robust.exe process must hvae R/W access to the location 
 ConfigDirectory = "/home/opensim/etc/Configs"
 
 ; * This is common for all services, it's the network setup for the entire
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index 7b8e83d..430be26 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -15,9 +15,17 @@
 [Startup]
 ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
 
+; Plugin Registry Location
+; Set path to directory for plugin registry. Information
+; about the registered repositories and installed plugins
+; will be stored here
+; The Robust.exe process must hvae R/W access to the location 
+RegistryLocation = "."
+
 
 ; Modular configurations
 ; Set path to directory for modular ini files...
+; The Robust.exe process must hvae R/W access to the location 
 ConfigDirectory = "/home/opensim/etc/Configs"
 
 ; * This is common for all services, it's the network setup for the entire
diff --git a/prebuild.xml b/prebuild.xml
index d3af892..fe8dcef 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -733,7 +733,10 @@
       <Reference name="System.Xml"/>
       <Reference name="System.Web"/>
       <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
+      <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
       <Reference name="OpenMetaverse" path="../../../bin/"/>
+      <Reference name="Mono.Addins" path="../../../bin/"/>
+      <Reference name="Mono.Addins.Setup" path="../../../bin/"/>
       <Reference name="OpenSim.Framework"/>
       <Reference name="OpenSim.Framework.Console"/>
       <Reference name="OpenSim.Framework.Servers"/>
@@ -856,6 +859,7 @@
       <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
       <Reference name="OpenMetaverse" path="../../../bin/"/>
       <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
+      <Reference name="Mono.Addins" path="../../../bin/"/>
       <Reference name="OpenSim.Data"/>
       <Reference name="OpenSim.Framework"/>
       <Reference name="OpenSim.Framework.Communications"/>
@@ -864,7 +868,6 @@
       <Reference name="OpenSim.Server.Base"/>
       <Reference name="OpenSim.Services.Base"/>
       <Reference name="OpenSim.Services.Interfaces"/>
-      <Reference name="Mono.Addins" path="../../../bin/"/>
       <Reference name="Nini" path="../../../bin/"/>
       <Reference name="log4net" path="../../../bin/"/>
       <Reference name="XMLRPC" path="../../../bin/"/>
@@ -1260,6 +1263,7 @@
       <Reference name="Nini" path="../../../bin/"/>
       <Reference name="log4net" path="../../../bin/"/>
       <Reference name="DotNetOpenId" path="../../../bin/"/>
+      <Reference name="Mono.Addins" path="../../../bin/"/>
 
       <Files>
         <Match pattern="*.cs" recurse="true">
@@ -1336,6 +1340,8 @@
       <Reference name="OpenSim.Server.Handlers"/>
       <Reference name="Nini" path="../../bin/"/>
       <Reference name="log4net" path="../../bin/"/>
+      <Reference name="Mono.Addins" path="../../bin/"/>
+      <Reference name="Mono.Addins.Setup" path="../../bin/"/>
 
       <Files>
         <Match pattern="*.cs" recurse="false">
-- 
cgit v1.1