From 5be6954e5dc6258cc7f20fc802411569cfe40b17 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 15 Jul 2013 15:26:18 +0300 Subject: [PATCH] When giving items between avatars in different simulators, only add the item to the receiving avatar's inventory once. When a user gives an item, the user's client sends an InventoryOffered IM message to its simulator. This adds the item to the receiver's inventory. If the receiver isn't in the same simulator then XMLRPC is used to forward the IM to the correct simulator. The bug was that the receiving simulator handled the message by calling OnInstantMessage() again, which added a second copy of the item to the inventory. Instead, the receiving simulator should only notify the avatar that the item was offered. --- .../Transfer/InventoryTransferModule.cs | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 1417a19605..f52654f4fd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -148,9 +148,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { -// m_log.DebugFormat( -// "[INVENTORY TRANSFER]: {0} IM type received from {1}", -// (InstantMessageDialog)im.dialog, client.Name); + m_log.DebugFormat( + "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", + (InstantMessageDialog)im.dialog, client.Name, + im.fromAgentID, im.fromAgentName, im.toAgentID); Scene scene = FindClientScene(client.AgentId); @@ -450,23 +451,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer /// /// /// - /// - private void OnGridInstantMessage(GridInstantMessage msg) + /// + private void OnGridInstantMessage(GridInstantMessage im) { + // Check if it's a type of message that we should handle + if (!((im.dialog == (byte) InstantMessageDialog.InventoryOffered) + || (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) + || (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) + || (im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined))) + return; + + m_log.DebugFormat( + "[INVENTORY TRANSFER]: {0} IM type received from grid. From={1} ({2}), To={3}", + (InstantMessageDialog)im.dialog, im.fromAgentID, im.fromAgentName, im.toAgentID); + // Check if this is ours to handle // - Scene scene = FindClientScene(new UUID(msg.toAgentID)); + Scene scene = FindClientScene(new UUID(im.toAgentID)); if (scene == null) return; // Find agent to deliver to // - ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); + ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); - // Just forward to local handling - OnInstantMessage(user.ControllingClient, msg); + if (user != null) + { + user.ControllingClient.SendInstantMessage(im); + if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) + { + AssetType assetType = (AssetType)im.binaryBucket[0]; + UUID inventoryID = new UUID(im.binaryBucket, 1); + + IInventoryService invService = scene.InventoryService; + InventoryNodeBase node = null; + if (AssetType.Folder == assetType) + { + InventoryFolderBase folder = new InventoryFolderBase(inventoryID, new UUID(im.toAgentID)); + node = invService.GetFolder(folder); + } + else + { + InventoryItemBase item = new InventoryItemBase(inventoryID, new UUID(im.toAgentID)); + node = invService.GetItem(item); + } + + if (node != null) + user.ControllingClient.SendBulkUpdateInventory(node); + } + } } } }