diff --git a/OpenSim/Data/IPresenceData.cs b/OpenSim/Data/IPresenceData.cs
index b871f5636c..9ec48b0e2a 100644
--- a/OpenSim/Data/IPresenceData.cs
+++ b/OpenSim/Data/IPresenceData.cs
@@ -53,5 +53,6 @@ namespace OpenSim.Data
bool ReportAgent(UUID sessionID, UUID regionID);
PresenceData[] Get(string field, string data);
bool Delete(string field, string val);
+ bool VerifyAgent(UUID agentId, UUID secureSessionID);
}
}
diff --git a/OpenSim/Data/MSSQL/MSSQLPresenceData.cs b/OpenSim/Data/MSSQL/MSSQLPresenceData.cs
index e7b3d9c367..deff2ed437 100644
--- a/OpenSim/Data/MSSQL/MSSQLPresenceData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLPresenceData.cs
@@ -100,5 +100,18 @@ namespace OpenSim.Data.MSSQL
return true;
}
+ public bool VerifyAgent(UUID agentId, UUID secureSessionID)
+ {
+ PresenceData[] ret = Get("SecureSessionID",
+ secureSessionID.ToString());
+
+ if (ret.Length == 0)
+ return false;
+
+ if(ret[0].UserID != agentId.ToString())
+ return false;
+
+ return true;
+ }
}
}
diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs
index 780806087f..3f906399ec 100644
--- a/OpenSim/Data/MySQL/MySQLPresenceData.cs
+++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs
@@ -95,5 +95,19 @@ namespace OpenSim.Data.MySQL
return true;
}
+
+ public bool VerifyAgent(UUID agentId, UUID secureSessionID)
+ {
+ PresenceData[] ret = Get("SecureSessionID",
+ secureSessionID.ToString());
+
+ if (ret.Length == 0)
+ return false;
+
+ if(ret[0].UserID != agentId.ToString())
+ return false;
+
+ return true;
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs
index c06c223a81..b85b95e566 100644
--- a/OpenSim/Data/Null/NullPresenceData.cs
+++ b/OpenSim/Data/Null/NullPresenceData.cs
@@ -222,5 +222,13 @@ namespace OpenSim.Data.Null
return true;
}
+ public bool VerifyAgent(UUID agentId, UUID secureSessionID)
+ {
+ if (Instance != this)
+ return Instance.VerifyAgent(agentId, secureSessionID);
+
+ return false;
+ }
+
}
}
diff --git a/OpenSim/Framework/PluginManager.cs b/OpenSim/Framework/PluginManager.cs
new file mode 100644
index 0000000000..23d594598a
--- /dev/null
+++ b/OpenSim/Framework/PluginManager.cs
@@ -0,0 +1,561 @@
+
+/*
+ * 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.Framework
+{
+ ///
+ /// Manager for registries and plugins
+ ///
+ public class PluginManager : SetupService
+ {
+ public AddinRegistry PluginRegistry;
+
+ public PluginManager(AddinRegistry registry): base (registry)
+ {
+ PluginRegistry = registry;
+
+ }
+
+ ///
+ /// Installs the plugin.
+ ///
+ ///
+ /// The plugin.
+ ///
+ ///
+ /// Arguments.
+ ///
+ public bool InstallPlugin(int ndx, out Dictionary result)
+ {
+ Dictionary res = new Dictionary();
+
+ 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
+ ///
+ /// Uns the install.
+ ///
+ ///
+ /// Arguments.
+ ///
+ 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;
+ }
+
+ ///
+ /// Checks the installed.
+ ///
+ ///
+ /// The installed.
+ ///
+ public string CheckInstalled()
+ {
+ return "CheckInstall";
+ }
+
+ ///
+ /// Lists the installed addins.
+ ///
+ ///
+ /// Result.
+ ///
+ public void ListInstalledAddins(out Dictionary result)
+ {
+ Dictionary res = new Dictionary();
+
+ Addin[] addins = GetSortedAddinList("RobustPlugin");
+ if(addins.Count() < 1)
+ {
+ MainConsole.Instance.Output("Error!");
+ }
+ int count = 0;
+ foreach (Addin addin in addins)
+ {
+ Dictionary r = new Dictionary();
+ 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
+ ///
+ /// Lists the available.
+ ///
+ ///
+ /// Result.
+ ///
+ public void ListAvailable(out Dictionary result)
+ {
+ Dictionary res = new Dictionary();
+
+ AddinRepositoryEntry[] addins = GetSortedAvailbleAddins();
+
+ int count = 0;
+ foreach (AddinRepositoryEntry addin in addins)
+ {
+ Dictionary r = new Dictionary();
+ 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
+ ///
+ /// Lists the updates.
+ ///
+ 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
+ ///
+ /// Update this instance.
+ ///
+ public string Update()
+ {
+ IProgressStatus ps = new ConsoleProgressStatus(true);
+ Repositories.UpdateAllRepositories(ps);
+ return "Update";
+ }
+
+ // Register a repository
+ ///
+ /// Register a repository with our server.
+ ///
+ ///
+ /// result of the action
+ ///
+ ///
+ /// The URL of the repository we want to add
+ ///
+ public bool AddRepository(string repo)
+ {
+ Repositories.RegisterRepository(null, repo, true);
+ PluginRegistry.Rebuild(null);
+
+ return true;
+ }
+
+ ///
+ /// Gets the repository.
+ ///
+ public void GetRepository()
+ {
+ Repositories.UpdateAllRepositories(new ConsoleProgressStatus(false));
+ }
+
+ // Remove a repository from the list
+ ///
+ /// Removes the repository.
+ ///
+ ///
+ /// Arguments.
+ ///
+ 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
+ ///
+ /// Enables the repository.
+ ///
+ ///
+ /// Arguments.
+ ///
+ 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
+ ///
+ /// Disables the repository.
+ ///
+ ///
+ /// Arguments.
+ ///
+ 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
+ ///
+ /// Lists the repositories.
+ ///
+ ///
+ /// Result.
+ ///
+ public void ListRepositories(out Dictionary result)
+ {
+ Dictionary res = new Dictionary();
+ 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 r = new Dictionary();
+ r["enabled"] = rep.Enabled == true ? true : false;
+ r["name"] = rep.Name;
+ r["url"] = rep.Url;
+
+ res.Add(count.ToString(), r);
+ count++;
+ }
+ return;
+ }
+
+ ///
+ /// Updates the registry.
+ ///
+ public void UpdateRegistry()
+ {
+ PluginRegistry.Update();
+ }
+
+ // Show plugin info
+ ///
+ /// Addins the info.
+ ///
+ ///
+ /// The info.
+ ///
+ ///
+ /// Arguments.
+ ///
+ public bool AddinInfo(int ndx, out Dictionary result)
+ {
+ Dictionary res = new Dictionary();
+ 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
+ ///
+ /// Disables the plugin.
+ ///
+ ///
+ /// Arguments.
+ ///
+ 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
+ ///
+ /// Enables the plugin.
+ ///
+ ///
+ /// Arguments.
+ ///
+ 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
+ }
+}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 4cfa33d567..ae58dfd369 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -316,76 +316,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
}
}
- // Disabled for now as it looks like http://opensimulator.org/mantis/view.php?id=6311 was fixed by fixes
- // to inventory folder versioning allowing the viewer to move the received folder itself as happens on the
- // LL grid. Doing it again server-side then wrongly does a second create and move
-// // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~
-// // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis
-// // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously
-// // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here.
-// else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
-// {
-// UUID destinationFolderID = UUID.Zero;
-//
-// if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
-// {
-// destinationFolderID = new UUID(im.binaryBucket, 0);
-// }
-//
-// if (destinationFolderID != UUID.Zero)
-// {
-// InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId);
-// if (destinationFolder == null)
-// {
-// m_log.WarnFormat(
-// "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist",
-// client.Name, scene.Name, destinationFolderID);
-//
-// return;
-// }
-//
-// IInventoryService invService = scene.InventoryService;
-//
-// UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
-//
-// InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
-// item = invService.GetItem(item);
-// InventoryFolderBase folder = null;
-// UUID? previousParentFolderID = null;
-//
-// if (item != null) // It's an item
-// {
-// previousParentFolderID = item.Folder;
-// item.Folder = destinationFolderID;
-//
-// invService.DeleteItems(item.Owner, new List() { item.ID });
-// scene.AddInventoryItem(client, item);
-// }
-// else
-// {
-// folder = new InventoryFolderBase(inventoryID, client.AgentId);
-// folder = invService.GetFolder(folder);
-//
-// if (folder != null) // It's a folder
-// {
-// previousParentFolderID = folder.ParentID;
-// folder.ParentID = destinationFolderID;
-// invService.MoveFolder(folder);
-// }
-// }
-//
-// // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
-// if (previousParentFolderID != null)
-// {
-// InventoryFolderBase previousParentFolder
-// = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
-// previousParentFolder = invService.GetFolder(previousParentFolder);
-// scene.SendInventoryUpdate(client, previousParentFolder, true, true);
-//
-// scene.SendInventoryUpdate(client, destinationFolder, true, true);
-// }
-// }
-// }
+ // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~
+ // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be
+ // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet
+ // happening, possibly because we are not sending the correct inventory update messages with the correct
+ // transaction IDs
+ else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
+ {
+ UUID destinationFolderID = UUID.Zero;
+
+ if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
+ {
+ destinationFolderID = new UUID(im.binaryBucket, 0);
+ }
+
+ if (destinationFolderID != UUID.Zero)
+ {
+ InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId);
+ if (destinationFolder == null)
+ {
+ m_log.WarnFormat(
+ "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist",
+ client.Name, scene.Name, destinationFolderID);
+
+ return;
+ }
+
+ IInventoryService invService = scene.InventoryService;
+
+ UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
+
+ InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
+ item = invService.GetItem(item);
+ InventoryFolderBase folder = null;
+ UUID? previousParentFolderID = null;
+
+ if (item != null) // It's an item
+ {
+ previousParentFolderID = item.Folder;
+ item.Folder = destinationFolderID;
+
+ invService.DeleteItems(item.Owner, new List() { item.ID });
+ scene.AddInventoryItem(client, item);
+ }
+ else
+ {
+ folder = new InventoryFolderBase(inventoryID, client.AgentId);
+ folder = invService.GetFolder(folder);
+
+ if (folder != null) // It's a folder
+ {
+ previousParentFolderID = folder.ParentID;
+ folder.ParentID = destinationFolderID;
+ invService.MoveFolder(folder);
+ }
+ }
+
+ // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
+ if (previousParentFolderID != null)
+ {
+ InventoryFolderBase previousParentFolder
+ = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
+ previousParentFolder = invService.GetFolder(previousParentFolder);
+ scene.SendInventoryUpdate(client, previousParentFolder, true, true);
+
+ scene.SendInventoryUpdate(client, destinationFolder, true, true);
+ }
+ }
+ }
else if (
im.dialog == (byte)InstantMessageDialog.InventoryDeclined
|| im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index b9c2cf967f..1f7c398396 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -59,7 +59,7 @@ public sealed class BSLinksetCompound : BSLinkset
// refresh will happen once after all the other taints are applied.
public override void Refresh(BSPhysObject requestor)
{
- // External request for Refresh (from BSPrim) is not necessary
+ // External request for Refresh (from BSPrim) doesn't need to do anything
// InternalRefresh(requestor);
}
@@ -86,7 +86,7 @@ public sealed class BSLinksetCompound : BSLinkset
DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
if (!IsRoot(child))
{
- // Physical children are removed from the world as the shape ofthe root compound
+ // The origional prims are removed from the world as the shape of the root compound
// shape takes over.
BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
@@ -118,7 +118,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Called at taint-time!!
public override void UpdateProperties(BSPhysObject updated)
{
- // Nothing to do for constraints on property updates
+ // Nothing to do for compound linksets on property updates
}
// The children move around in relationship to the root.
@@ -257,6 +257,11 @@ public sealed class BSLinksetCompound : BSLinkset
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot);
}
}
+
+ // TODO: need to phantomize the child prims left behind.
+ // Maybe just destroy the children bodies and shapes and have them rebuild on unlink.
+ // Selection/deselection might cause way too many build/destructions esp. for LARGE linksets.
+
return false; // 'false' says to move onto the next child in the list
});
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 62aaf800c6..4d203ffc48 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -190,12 +190,15 @@ public sealed class BSPrim : BSPhysObject
}
public override bool Selected {
set {
- _isSelected = value;
- PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
+ if (value != _isSelected)
{
- DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
- SetObjectDynamic(false);
- });
+ _isSelected = value;
+ PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
+ {
+ DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
+ SetObjectDynamic(false);
+ });
+ }
}
}
public override void CrossingFailure() { return; }
@@ -678,8 +681,11 @@ public sealed class BSPrim : BSPhysObject
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
// Stop all movement
ZeroMotion(true);
- // Center of mass is at the center of the object
- // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
+
+ // Set various physical properties so other object interact properly
+ BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction);
+ BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution);
+
// Mass is zero which disables a bunch of physics stuff in Bullet
UpdatePhysicalMassProperties(0f);
// Set collision detection parameters
@@ -688,13 +694,15 @@ public sealed class BSPrim : BSPhysObject
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
}
- // There can be special things needed for implementing linksets
- Linkset.MakeStatic(this);
+
// The activation state is 'disabled' so Bullet will not try to act on it.
// BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
// Start it out sleeping and physical actions could wake it up.
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
+ // There can be special things needed for implementing linksets
+ Linkset.MakeStatic(this);
+
PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup;
PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask;
}
@@ -1326,7 +1334,7 @@ public sealed class BSPrim : BSPhysObject
// Rebuild the geometry and object.
// This is called when the shape changes so we need to recreate the mesh/hull.
// Called at taint-time!!!
- private void CreateGeomAndObject(bool forceRebuild)
+ public void CreateGeomAndObject(bool forceRebuild)
{
// If this prim is part of a linkset, we must remove and restore the physical
// links if the body is rebuilt.
@@ -1341,7 +1349,7 @@ public sealed class BSPrim : BSPhysObject
{
// Called if the current prim body is about to be destroyed.
// Remove all the physical dependencies on the old body.
- // (Maybe someday make the changing of BSShape an event handled by BSLinkset.)
+ // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this);
});
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index a5e5754b7a..a77dee9b9b 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -415,7 +415,7 @@ public sealed class BSShapeCollection : IDisposable
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
{
// an avatar capsule is close to a native shape (it is not shared)
- ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
+ GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
FixedShapeKey.KEY_CAPSULE, shapeCallback);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
ret = true;
@@ -423,7 +423,7 @@ public sealed class BSShapeCollection : IDisposable
}
// Compound shapes are handled special as they are rebuilt from scratch.
- // This isn't too great a hardship since most of the child shapes will already been created.
+ // This isn't too great a hardship since most of the child shapes will have already been created.
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
{
ret = GetReferenceToCompoundShape(prim, shapeCallback);
@@ -460,6 +460,9 @@ public sealed class BSShapeCollection : IDisposable
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
&& pbs.PathShearX == 0 && pbs.PathShearY == 0) ) )
{
+ if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}",
+ prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type);
+
// It doesn't look like Bullet scales spheres so make sure the scales are all equal
if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)
@@ -538,6 +541,8 @@ public sealed class BSShapeCollection : IDisposable
if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
prim.LocalID, newShape, prim.Scale);
+ // native shapes are scaled by Bullet
+ prim.Scale = prim.Size;
prim.PhysShape = newShape;
return true;
}
@@ -550,8 +555,8 @@ public sealed class BSShapeCollection : IDisposable
ShapeData nativeShapeData = new ShapeData();
nativeShapeData.Type = shapeType;
nativeShapeData.ID = prim.LocalID;
- nativeShapeData.Scale = prim.Scale;
- nativeShapeData.Size = prim.Scale; // unneeded, I think.
+ nativeShapeData.Scale = prim.Size;
+ nativeShapeData.Size = prim.Size; // unneeded, I think.
nativeShapeData.MeshKey = (ulong)shapeKey;
nativeShapeData.HullKey = (ulong)shapeKey;
@@ -566,8 +571,6 @@ public sealed class BSShapeCollection : IDisposable
else
{
// Native shapes are scaled in Bullet so set the scaling to the size
- prim.Scale = prim.Size;
- nativeShapeData.Scale = prim.Scale;
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
}
if (newShape.ptr == IntPtr.Zero)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index d51003c40b..a2161c3460 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -5,6 +5,9 @@ CRASHES
20121128.1600: mesh object not rezzing (no physics mesh).
Causes many errors. Doesn't stop after first error with box shape.
Eventually crashes when deleting the object.
+20121206.1434: rez Sam-pan into OSGrid BulletSim11 region
+ Immediate simulator crash. Mono does not output any stacktrace and
+ log just stops after reporting taint-time linking of the linkset.
VEHICLES TODO LIST:
=================================================
@@ -23,9 +26,12 @@ After getting off a vehicle, the root prim is phantom (can be walked through)
Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
Implement referenceFrame for all the motion routines.
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
+Border crossing with linked vehicle causes crash
BULLETSIM TODO LIST:
=================================================
+Duplicating a physical prim causes old prim to jump away
+ Dup a phys prim and the original become unselected and thus interacts w/ selected prim.
Disable activity of passive linkset children.
Since the linkset is a compound object, the old prims are left lying
around and need to be phantomized so they don't collide, ...
@@ -96,7 +102,7 @@ Breakout code for mesh/hull/compound/native into separate BSShape* classes
Generalize Dynamics and PID with standardized motors.
Generalize Linkset and vehicles into PropertyManagers
Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
- Possibly generalized a 'pre step action' registration.
+ Potentially add events for shape destruction, etc.
Complete implemention of preStepActions
Replace vehicle step call with prestep event.
Is there a need for postStepActions? postStepTaints?
diff --git a/OpenSim/Server/Base/CommandManager.cs b/OpenSim/Server/Base/CommandManager.cs
new file mode 100644
index 0000000000..bd18485f7b
--- /dev/null
+++ b/OpenSim/Server/Base/CommandManager.cs
@@ -0,0 +1,359 @@
+/*
+ * 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.Setup;
+using Mono.Addins;
+using Mono.Addins.Description;
+using OpenSim.Framework;
+
+namespace OpenSim.Server.Base
+{
+ ///
+ /// Command manager -
+ /// Wrapper for OpenSim.Framework.PluginManager to allow
+ /// us to add commands to the console to perform operations
+ /// on our repos and plugins
+ ///
+ public class CommandManager
+ {
+ public 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
+ ///
+ /// Handles the console install plugin command. Attempts to install the selected plugin
+ /// and
+ ///
+ ///
+ /// Module.
+ ///
+ ///
+ /// Cmd.
+ ///
+ private void HandleConsoleInstallPlugin(string module, string[] cmd)
+ {
+ Dictionary result = new Dictionary();
+
+ 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 plugin = (Dictionary)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 result = new Dictionary();
+ 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 plugin = (Dictionary)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 result = new Dictionary();
+ PluginManager.ListAvailable(out result);
+
+ var list = result.Keys.ToList();
+ list.Sort();
+ foreach (var k in list)
+ {
+ // name, version, repository
+ Dictionary plugin = (Dictionary)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 result = new Dictionary();
+ PluginManager.ListRepositories(out result);
+
+ var list = result.Keys.ToList();
+ list.Sort();
+ foreach (var k in list)
+ {
+ Dictionary repo = (Dictionary)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 result = new Dictionary();
+
+ 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/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index 42c82cf34c..31b04465b6 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -33,11 +33,137 @@ using System.Xml.Serialization;
using System.Text;
using System.Collections.Generic;
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);
+ void Unload();
+ }
+
+ 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);
+
+ if(a == null)
+ {
+ Registry.Rebuild(null);
+ a = Registry.GetAddin(args.ExtensionNode.Addin.Id);
+ }
+
+ switch(args.Change)
+ {
+ case ExtensionChange.Add:
+ if (a.AddinFile.Contains(Registry.DefaultAddinsFolder))
+ {
+ m_log.InfoFormat("[SERVER]: Adding {0} from registry", a.Name);
+ connector.PluginPath = String.Format("{0}/{1}", Registry.DefaultAddinsFolder, a.Name.Replace(',', '.'));
+ }
+ else
+ {
+ m_log.InfoFormat("[SERVER]: Adding {0} from ./bin", a.Name);
+ connector.PluginPath = a.AddinFile;
+ }
+ LoadPlugin(connector);
+ break;
+ case ExtensionChange.Remove:
+ m_log.InfoFormat("[SERVER]: Removing {0}", a.Name);
+ UnloadPlugin(connector);
+ break;
+ }
+ }
+
+ private void LoadPlugin(IRobustConnector connector)
+ {
+ IHttpServer server = null;
+ uint port = connector.Configure(Config);
+
+ if(connector.Enabled)
+ {
+ server = GetServer(connector, port);
+ connector.Initialize(server);
+ }
+ else
+ {
+ m_log.InfoFormat("[SERVER]: {0} Disabled.", connector.ConfigName);
+ }
+ }
+
+ private void UnloadPlugin(IRobustConnector connector)
+ {
+ m_log.InfoFormat("[Server]: Unloading {0}", connector.ConfigName);
+
+ connector.Unload();
+ }
+
+ 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);
@@ -333,5 +459,42 @@ namespace OpenSim.Server.Base
return ret;
}
+
+ public static IConfig GetConfig(string configFile, string configName)
+ {
+ IConfig config;
+
+ if (File.Exists(configFile))
+ {
+ IConfigSource configsource = new IniConfigSource(configFile);
+ config = configsource.Configs[configName];
+ }
+ else
+ config = null;
+
+ return config;
+ }
+
+ public static IConfigSource LoadInitialConfig(string url)
+ {
+ IConfigSource source = new XmlConfigSource();
+ m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", url);
+
+ // The ini file path is a http URI
+ // Try to read it
+ try
+ {
+ XmlReader r = XmlReader.Create(url);
+ IConfigSource cs = new XmlConfigSource(r);
+ source.Merge(cs);
+ }
+ catch (Exception e)
+ {
+ m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), url);
+ Environment.Exit(1);
+ }
+
+ return source;
+ }
}
}
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs
index 5b23149c39..ecd69b0572 100644
--- a/OpenSim/Server/Base/ServicesServerBase.cs
+++ b/OpenSim/Server/Base/ServicesServerBase.cs
@@ -56,6 +56,12 @@ namespace OpenSim.Server.Base
//
protected string[] m_Arguments;
+ public string ConfigDirectory
+ {
+ get;
+ private set;
+ }
+
// Run flag
//
private bool m_Running = true;
@@ -134,6 +140,8 @@ namespace OpenSim.Server.Base
startupConfig = Config.Configs["Startup"];
}
+ ConfigDirectory = startupConfig.GetString("ConfigDirectory", ".");
+
prompt = startupConfig.GetString("Prompt", prompt);
// Allow derived classes to load config before the console is
@@ -242,4 +250,4 @@ namespace OpenSim.Server.Base
{
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Server/Handlers/Base/ServerConnector.cs b/OpenSim/Server/Handlers/Base/ServerConnector.cs
index 71876dabbd..72014dba7d 100644
--- a/OpenSim/Server/Handlers/Base/ServerConnector.cs
+++ b/OpenSim/Server/Handlers/Base/ServerConnector.cs
@@ -39,8 +39,75 @@ namespace OpenSim.Server.Handlers.Base
public class ServiceConnector : IServiceConnector
{
+ public virtual string ConfigURL
+ {
+ get { return String.Empty; }
+ }
+
+ public virtual string ConfigName
+ {
+ get;
+ protected set;
+ }
+
+ public virtual string ConfigFile
+ {
+ get;
+ protected set;
+ }
+
+ public virtual IConfigSource Config
+ {
+ get;
+ protected set;
+ }
+
+ public ServiceConnector()
+ {
+ }
+
public ServiceConnector(IConfigSource config, IHttpServer server, string configName)
{
}
+
+ // We call this from our plugin module to get our configuration
+ public IConfig GetConfig()
+ {
+ IConfig config = null;
+ config = ServerUtils.GetConfig(ConfigFile, ConfigName);
+
+ // Our file is not here? We can get one to bootstrap our plugin module
+ if ( config == null )
+ {
+ IConfigSource remotesource = GetConfigSource();
+
+ if (remotesource != null)
+ {
+ IniConfigSource initialconfig = new IniConfigSource();
+ initialconfig.Merge (remotesource);
+ initialconfig.Save(ConfigFile);
+ }
+
+ config = remotesource.Configs[ConfigName];
+ }
+
+ return config;
+ }
+
+ // We get our remote initial configuration for bootstrapping in case
+ // we have no configuration in our main file or in an existing
+ // modular config file. This is the last resort to bootstrap the
+ // configuration, likely a new plugin loading for the first time.
+ private IConfigSource GetConfigSource()
+ {
+ IConfigSource source = null;
+
+ source = ServerUtils.LoadInitialConfig(ConfigURL);
+
+ if (source == null)
+ System.Console.WriteLine(String.Format ("Config Url: {0} Not found!", ConfigURL));
+
+ return source;
+ }
}
}
diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs
index 45c13fb944..8be69a93a4 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 m_ServiceConnectors =
new List();
+ 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)
@@ -60,6 +65,8 @@ namespace OpenSim.Server
}
string connList = serverConfig.GetString("ServiceConnectors", String.Empty);
+
+ registryLocation = serverConfig.GetString("RegistryLocation",".");
IConfig servicesConfig = m_Server.Config.Configs["ServiceList"];
if (servicesConfig != null)
@@ -141,6 +148,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/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 508baf7e5d..ef2494a2f8 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -315,7 +315,7 @@ namespace OpenSim.Services.Connectors.Simulation
try
{
- OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000, false);
+ OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 30000, false);
bool success = result["success"].AsBoolean();
if (result.ContainsKey("_Result"))
{
diff --git a/bin/Mono.Addins.CecilReflector.dll b/bin/Mono.Addins.CecilReflector.dll
index a1a638265c..fb95e00d22 100755
Binary files a/bin/Mono.Addins.CecilReflector.dll and b/bin/Mono.Addins.CecilReflector.dll differ
diff --git a/bin/Mono.Addins.Setup.dll b/bin/Mono.Addins.Setup.dll
index 8aa6d5f2cf..502ad1866b 100755
Binary files a/bin/Mono.Addins.Setup.dll and b/bin/Mono.Addins.Setup.dll differ
diff --git a/bin/Mono.Addins.dll b/bin/Mono.Addins.dll
index ea330fdc9b..1bc4c557f3 100755
Binary files a/bin/Mono.Addins.dll and b/bin/Mono.Addins.dll differ
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index 4ecc6b0040..55b6f90eea 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -54,6 +54,18 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset
;; WifiServerConnector = "8002/Diva.Wifi.dll:WifiServerConnector"
+; 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
; * server instance, if none is specified above
; *
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index 7503c5e0a2..8ec6d75da7 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -31,6 +31,19 @@ FriendsServiceConnector = "8003/OpenSim.Server.Handlers.dll:FriendsServiceConnec
MapAddServiceConnector = "8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector"
MapGetServiceConnector = "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
; * server instance, if none is specified above
; *
diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example
index 79f7ed6c3f..e53fccabbe 100644
--- a/bin/config-include/GridCommon.ini.example
+++ b/bin/config-include/GridCommon.ini.example
@@ -137,6 +137,11 @@
;; uncomment the next line. You may want to do this on sims that have licensed content.
; OutboundPermission = False
+ ;; Send visual reminder to local users that their inventories are unavailable while they are traveling
+ ;; and available when they return. True by default.
+ ;RestrictInventoryAccessAbroad = True
+
+
[HGAssetService]
;
; === HG ONLY ===
diff --git a/prebuild.xml b/prebuild.xml
index 8bf537419c..ebf0f1fa22 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -105,6 +105,7 @@
+
@@ -851,10 +852,14 @@
../../../bin/
+
+
+
+
@@ -977,6 +982,7 @@
+
@@ -985,7 +991,6 @@
-
@@ -1384,6 +1389,7 @@
+
@@ -1460,6 +1466,8 @@
+
+