From 20406498711d1f26037ae32e1b7f8378b01ad848 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 11 Mar 2010 10:05:03 -0800 Subject: Adding the SimianGrid connectors --- .../SimianGrid/SimianInventoryServiceConnector.cs | 880 +++++++++++++++++++++ 1 file changed, 880 insertions(+) create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs (limited to 'OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs') diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs new file mode 100644 index 0000000..c812899 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -0,0 +1,880 @@ +/* + * 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.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Permissions bitflags + /// + [Flags] + public enum PermissionMask : uint + { + None = 0, + Transfer = 1 << 13, + Modify = 1 << 14, + Copy = 1 << 15, + Move = 1 << 19, + Damage = 1 << 20, + All = 0x7FFFFFFF + } + + /// + /// Connects avatar inventories to the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + private string m_userServerUrl = String.Empty; + private object m_gestureSyncRoot = new object(); + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianInventoryServiceConnector() { } + public string Name { get { return "SimianInventoryServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianInventoryServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["InventoryService"]; + if (gridConfig == null) + { + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + throw new Exception("Inventory connector init error"); + } + + string serviceUrl = gridConfig.GetString("InventoryServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); + throw new Exception("Inventory connector init error"); + } + + // FIXME: Get the user server URL too + + m_serverUrl = serviceUrl; + } + + /// + /// Create the entire inventory for a given user + /// + /// + /// + public bool CreateUserInventory(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddInventory" }, + { "OwnerID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString()); + + return success; + } + + /// + /// Gets the skeleton of the inventory -- folders only + /// + /// + /// + public List GetInventorySkeleton(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", userID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "0" }, + { "ChildrenOnly", "0" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + return GetFoldersFromResponse(items, userID, true); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " + + response["Message"].AsString()); + return new List(0); + } + } + + /// + /// Synchronous inventory fetch. + /// + /// + /// + [Obsolete] + public InventoryCollection GetUserInventory(UUID userID) + { + m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID); + + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = userID; + inventory.Folders = new List(); + inventory.Items = new List(); + + return inventory; + } + + /// + /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the + /// inventory has been received + /// + /// + /// + [Obsolete] + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID); + callback(new List(0), new List(0)); + } + + /// + /// Retrieve the root inventory folder for the given user. + /// + /// + /// null if no root folder was found + public InventoryFolderBase GetRootFolder(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", userID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "0" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + List folders = GetFoldersFromResponse(items, userID, true); + + if (folders.Count > 0) + return folders[0]; + } + + return null; + } + + /// + /// Gets the user folder for the given folder-type + /// + /// + /// + /// + public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + { + string contentType = SLUtil.SLAssetTypeToContentType((int)type); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetFolderForType" }, + { "ContentType", contentType }, + { "OwnerID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Folder"] is OSDMap) + { + OSDMap folder = (OSDMap)response["Folder"]; + + return new InventoryFolderBase( + folder["ID"].AsUUID(), + folder["Name"].AsString(), + folder["OwnerID"].AsUUID(), + (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()), + folder["ParentID"].AsUUID(), + (ushort)folder["Version"].AsInteger() + ); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Default folder not found for content type " + contentType); + return GetRootFolder(userID); + } + } + + /// + /// Get an item, given by its UUID + /// + /// + /// + public InventoryItemBase GetItem(InventoryItemBase item) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", item.ID.ToString() }, + { "OwnerID", item.Owner.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "1" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + List items = GetItemsFromResponse((OSDArray)response["Items"]); + if (items.Count > 0) + { + // The requested item should be the first in this list, but loop through + // and sanity check just in case + for (int i = 0; i < items.Count; i++) + { + if (items[i].ID == item.ID) + return items[i]; + } + } + } + + m_log.Warn("[INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found"); + return null; + } + + /// + /// Get a folder, given by its UUID + /// + /// + /// + public InventoryFolderBase GetFolder(InventoryFolderBase folder) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", folder.ID.ToString() }, + { "OwnerID", folder.Owner.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "0" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + List folders = GetFoldersFromResponse(items, folder.ID, true); + + if (folders.Count > 0) + return folders[0]; + } + + return null; + } + + /// + /// Gets everything (folders and items) inside a folder + /// + /// + /// + /// + public InventoryCollection GetFolderContent(UUID userID, UUID folderID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = userID; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", folderID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "1" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + + inventory.Folders = GetFoldersFromResponse(items, folderID, false); + inventory.Items = GetItemsFromResponse(items); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " + + response["Message"].AsString()); + inventory.Folders = new List(0); + inventory.Items = new List(0); + } + + return inventory; + } + + /// + /// Gets the items inside a folder + /// + /// + /// + /// + public List GetFolderItems(UUID userID, UUID folderID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = userID; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", folderID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "0" }, + { "IncludeItems", "1" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + return GetItemsFromResponse(items); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " + + response["Message"].AsString()); + return new List(0); + } + } + + /// + /// Add a new folder to the user's inventory + /// + /// + /// true if the folder was successfully added + public bool AddFolder(InventoryFolderBase folder) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddInventoryFolder" }, + { "FolderID", folder.ID.ToString() }, + { "ParentID", folder.ParentID.ToString() }, + { "OwnerID", folder.Owner.ToString() }, + { "Name", folder.Name }, + { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " + + response["Message"].AsString()); + } + + return success; + } + + /// + /// Update a folder in the user's inventory + /// + /// + /// true if the folder was successfully updated + public bool UpdateFolder(InventoryFolderBase folder) + { + return AddFolder(folder); + } + + /// + /// Move an inventory folder to a new location + /// + /// A folder containing the details of the new location + /// true if the folder was successfully moved + public bool MoveFolder(InventoryFolderBase folder) + { + return AddFolder(folder); + } + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + //bool DeleteItem(InventoryItemBase item); + public bool DeleteFolders(UUID userID, List folderIDs) + { + return DeleteItems(userID, folderIDs); + } + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + public bool DeleteItems(UUID userID, List itemIDs) + { + // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes + bool allSuccess = true; + + for (int i = 0; i < itemIDs.Count; i++) + { + UUID itemID = itemIDs[i]; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveInventoryNode" }, + { "OwnerID", userID.ToString() }, + { "ItemID", itemID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " + + response["Message"].AsString()); + allSuccess = false; + } + } + + return allSuccess; + } + + /// + /// Purge an inventory folder of all its items and subfolders. + /// + /// + /// true if the folder was successfully purged + public bool PurgeFolder(InventoryFolderBase folder) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "PurgeInventoryFolder" }, + { "OwnerID", folder.Owner.ToString() }, + { "FolderID", folder.ID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " + + response["Message"].AsString()); + } + + return success; + } + + /// + /// Add a new item to the user's inventory + /// + /// + /// true if the item was successfully added + public bool AddItem(InventoryItemBase item) + { + // A folder of UUID.Zero means we need to find the most appropriate home for this item + if (item.Folder == UUID.Zero) + { + InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType); + if (folder != null && folder.ID != UUID.Zero) + item.Folder = folder.ID; + else + item.Folder = item.Owner; // Root folder + } + + if ((AssetType)item.AssetType == AssetType.Gesture) + UpdateGesture(item.Owner, item.ID, item.Flags == 1); + + if (item.BasePermissions == 0) + m_log.WarnFormat("[INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID); + + OSDMap permissions = new OSDMap + { + { "BaseMask", OSD.FromInteger(item.BasePermissions) }, + { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) }, + { "GroupMask", OSD.FromInteger(item.GroupPermissions) }, + { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) }, + { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) } + }; + + OSDMap extraData = new OSDMap() + { + { "Flags", OSD.FromInteger(item.Flags) }, + { "GroupID", OSD.FromUUID(item.GroupID) }, + { "GroupOwned", OSD.FromBoolean(item.GroupOwned) }, + { "SalePrice", OSD.FromInteger(item.SalePrice) }, + { "SaleType", OSD.FromInteger(item.SaleType) }, + { "Permissions", permissions } + }; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddInventoryItem" }, + { "ItemID", item.ID.ToString() }, + { "AssetID", item.AssetID.ToString() }, + { "ParentID", item.Folder.ToString() }, + { "OwnerID", item.Owner.ToString() }, + { "Name", item.Name }, + { "Description", item.Description }, + { "CreatorID", item.CreatorId }, + { "ExtraData", OSDParser.SerializeJsonString(extraData) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " + + response["Message"].AsString()); + } + + return success; + } + + /// + /// Update an item in the user's inventory + /// + /// + /// true if the item was successfully updated + public bool UpdateItem(InventoryItemBase item) + { + if (item.AssetID != UUID.Zero) + { + return AddItem(item); + } + else + { + // This is actually a folder update + InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0); + return UpdateFolder(folder); + } + } + + public bool MoveItems(UUID ownerID, List items) + { + bool success = true; + + while (items.Count > 0) + { + List currentItems = new List(); + UUID destFolderID = items[0].Folder; + + // Find all of the items being moved to the current destination folder + for (int i = 0; i < items.Count; i++) + { + InventoryItemBase item = items[i]; + if (item.Folder == destFolderID) + currentItems.Add(item); + } + + // Do the inventory move for the current items + success &= MoveItems(ownerID, items, destFolderID); + + // Remove the processed items from the list + for (int i = 0; i < currentItems.Count; i++) + items.Remove(currentItems[i]); + } + + return success; + } + + /// + /// Does the given user have an inventory structure? + /// + /// + /// + public bool HasInventoryForUser(UUID userID) + { + return GetRootFolder(userID) != null; + } + + /// + /// Get the active gestures of the agent. + /// + /// + /// + public List GetActiveGestures(UUID userID) + { + OSDArray items = FetchGestures(userID); + + string[] itemIDs = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + itemIDs[i] = items[i].AsUUID().ToString(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNodes" }, + { "OwnerID", userID.ToString() }, + { "Items", String.Join(",", itemIDs) } + }; + + // FIXME: Implement this in SimianGrid + return new List(0); + } + + /// + /// Get the union of permissions of all inventory items + /// that hold the given assetID. + /// + /// + /// + /// The permissions or 0 if no such asset is found in + /// the user's inventory + public int GetAssetPermissions(UUID userID, UUID assetID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNodes" }, + { "OwnerID", userID.ToString() }, + { "AssetID", assetID.ToString() } + }; + + // FIXME: Implement this in SimianGrid + return (int)PermissionMask.All; + } + + private List GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder) + { + List invFolders = new List(items.Count); + + for (int i = 0; i < items.Count; i++) + { + OSDMap item = items[i] as OSDMap; + + if (item != null && item["Type"].AsString() == "Folder") + { + UUID folderID = item["ID"].AsUUID(); + + if (folderID == baseFolder && !includeBaseFolder) + continue; + + invFolders.Add(new InventoryFolderBase( + folderID, + item["Name"].AsString(), + item["OwnerID"].AsUUID(), + (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()), + item["ParentID"].AsUUID(), + (ushort)item["Version"].AsInteger() + )); + } + } + + return invFolders; + } + + private List GetItemsFromResponse(OSDArray items) + { + List invItems = new List(items.Count); + + for (int i = 0; i < items.Count; i++) + { + OSDMap item = items[i] as OSDMap; + + if (item != null && item["Type"].AsString() == "Item") + { + InventoryItemBase invItem = new InventoryItemBase(); + + invItem.AssetID = item["AssetID"].AsUUID(); + invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()); + invItem.CreationDate = item["CreationDate"].AsInteger(); + invItem.CreatorId = item["CreatorID"].AsString(); + invItem.CreatorIdAsUuid = item["CreatorID"].AsUUID(); + invItem.Description = item["Description"].AsString(); + invItem.Folder = item["ParentID"].AsUUID(); + invItem.ID = item["ID"].AsUUID(); + invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString()); + invItem.Name = item["Name"].AsString(); + invItem.Owner = item["OwnerID"].AsUUID(); + + OSDMap extraData = item["ExtraData"] as OSDMap; + if (extraData != null && extraData.Count > 0) + { + invItem.Flags = extraData["Flags"].AsUInteger(); + invItem.GroupID = extraData["GroupID"].AsUUID(); + invItem.GroupOwned = extraData["GroupOwned"].AsBoolean(); + invItem.SalePrice = extraData["SalePrice"].AsInteger(); + invItem.SaleType = (byte)extraData["SaleType"].AsInteger(); + + OSDMap perms = extraData["Permissions"] as OSDMap; + if (perms != null) + { + invItem.BasePermissions = perms["BaseMask"].AsUInteger(); + invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger(); + invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger(); + invItem.GroupPermissions = perms["GroupMask"].AsUInteger(); + invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger(); + } + } + + if (invItem.BasePermissions == 0) + { + m_log.InfoFormat("[INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})", + invItem.Name, invItem.ID); + invItem.BasePermissions = (uint)PermissionMask.All; + invItem.CurrentPermissions = (uint)PermissionMask.All; + invItem.EveryOnePermissions = (uint)PermissionMask.All; + invItem.GroupPermissions = (uint)PermissionMask.All; + invItem.NextPermissions = (uint)PermissionMask.All; + } + + invItems.Add(invItem); + } + } + + return invItems; + } + + private bool MoveItems(UUID ownerID, List items, UUID destFolderID) + { + string[] itemIDs = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + itemIDs[i] = items[i].ID.ToString(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "MoveInventoryNodes" }, + { "OwnerID", ownerID.ToString() }, + { "FolderID", destFolderID.ToString() }, + { "Items", String.Join(",", itemIDs) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " + + destFolderID + ": " + response["Message"].AsString()); + } + + return success; + } + + private void UpdateGesture(UUID userID, UUID itemID, bool enabled) + { + OSDArray gestures = FetchGestures(userID); + OSDArray newGestures = new OSDArray(); + + for (int i = 0; i < gestures.Count; i++) + { + UUID gesture = gestures[i].AsUUID(); + if (gesture != itemID) + newGestures.Add(OSD.FromUUID(gesture)); + } + + if (enabled) + newGestures.Add(OSD.FromUUID(itemID)); + + SaveGestures(userID, newGestures); + } + + private OSDArray FetchGestures(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDMap user = response["User"] as OSDMap; + if (user != null && response.ContainsKey("Gestures")) + { + OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString()); + if (gestures != null && gestures is OSDArray) + return (OSDArray)gestures; + else + m_log.Error("[INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID); + } + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " + + response["Message"].AsString()); + } + + return new OSDArray(); + } + + private void SaveGestures(UUID userID, OSDArray gestures) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", userID.ToString() }, + { "Gestures", OSDParser.SerializeJsonString(gestures) } + }; + + OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); + if (!response["Success"].AsBoolean()) + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " + + response["Message"].AsString()); + } + } + } +} -- cgit v1.1