From 38ca31b37a6ac8fe74b77e4488112eb77d612827 Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Thu, 4 Dec 2008 19:57:36 +0000
Subject: * Put in the code necessary to allow inventory transfer of whole
folders (and their contents) between agents, not just single items * However,
this is not currently activated since it's not absolutely fully tested and
there's a bug lurking in there to do with the sending of the
BulkInventoryUpdate packets
---
.../Region/ClientStack/LindenUDP/LLClientView.cs | 148 +++++++++++++++++++++
1 file changed, 148 insertions(+)
(limited to 'OpenSim/Region/ClientStack')
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 74bf7e5..42f190f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -1144,6 +1144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
msg.MessageBlock.Message = Utils.StringToBytes(message);
msg.MessageBlock.BinaryBucket = binaryBucket;
+ System.Console.WriteLine("SendInstantMessage: " + msg);
OutPacket(msg, ThrottleOutPacketType.Task);
}
}
@@ -1763,6 +1764,153 @@ namespace OpenSim.Region.ClientStack.LindenUDP
inventoryReply.Header.Zerocoded = true;
OutPacket(inventoryReply, ThrottleOutPacketType.Asset);
}
+
+ /// IClientAPI.SendBulkUpdateInventory(InventoryFolderBase)
+ public void SendBulkUpdateInventory(InventoryFolderBase folderBase)
+ {
+ // XXX: Nasty temporary move that will be resolved shortly
+ InventoryFolderImpl folder = (InventoryFolderImpl)folderBase;
+
+ // We will use the same transaction id for all the separate packets to be sent out in this update.
+ UUID transactionId = UUID.Random();
+
+ List folderDataBlocks
+ = new List();
+
+ SendBulkUpdateInventoryRecursive(folder, ref folderDataBlocks, transactionId);
+
+ if (folderDataBlocks.Count > 0)
+ {
+ // We'll end up with some unsent folder blocks if there were some empty folders at the end of the list
+ // Send these now
+ BulkUpdateInventoryPacket bulkUpdate
+ = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
+ bulkUpdate.Header.Zerocoded = true;
+
+ bulkUpdate.AgentData.AgentID = AgentId;
+ bulkUpdate.AgentData.TransactionID = transactionId;
+ bulkUpdate.FolderData = folderDataBlocks.ToArray();
+
+ Console.WriteLine("SendBulkUpdateInventory :" + bulkUpdate);
+ OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
+ }
+ }
+
+ ///
+ /// Recursively construct bulk update packets to send folders and items
+ ///
+ ///
+ ///
+ ///
+ private void SendBulkUpdateInventoryRecursive(
+ InventoryFolderImpl folder, ref List folderDataBlocks,
+ UUID transactionId)
+ {
+ folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder));
+
+ const int MAX_ITEMS_PER_PACKET = 5;
+
+ // If there are any items then we have to start sending them off in this packet - the next folder will have
+ // to be in its own bulk update packet. Also, we can only fit 5 items in a packet (at least this was the limit
+ // being used on the Linden grid at 20081203).
+ List items = folder.RequestListOfItems();
+ while (items.Count > 0)
+ {
+ BulkUpdateInventoryPacket bulkUpdate
+ = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
+ bulkUpdate.Header.Zerocoded = true;
+
+ bulkUpdate.AgentData.AgentID = AgentId;
+ bulkUpdate.AgentData.TransactionID = transactionId;
+ bulkUpdate.FolderData = folderDataBlocks.ToArray();
+
+ int itemsToSend = (items.Count > MAX_ITEMS_PER_PACKET ? MAX_ITEMS_PER_PACKET : items.Count);
+ bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[itemsToSend];
+
+ for (int i = 0; i < itemsToSend; i++)
+ {
+ // Remove from the end of the list so that we don't incur a performance penalty
+ bulkUpdate.ItemData[i] = GenerateBulkUpdateItemDataBlock(items[items.Count - 1]);
+ items.RemoveAt(items.Count - 1);
+ }
+
+ Console.WriteLine("SendBulkUpdateInventoryRecursive :" + bulkUpdate);
+ OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
+
+ folderDataBlocks = new List();
+
+ // If we're going to be sending another items packet then it needs to contain just the folder to which those
+ // items belong.
+ if (items.Count > 0)
+ folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder));
+ }
+
+ List subFolders = folder.RequestListOfFolderImpls();
+ foreach (InventoryFolderImpl subFolder in subFolders)
+ {
+ SendBulkUpdateInventoryRecursive(subFolder, ref folderDataBlocks, transactionId);
+ }
+ }
+
+ ///
+ /// Generate a bulk update inventory data block for the given folder
+ ///
+ ///
+ ///
+ private BulkUpdateInventoryPacket.FolderDataBlock GenerateBulkUpdateFolderDataBlock(InventoryFolderBase folder)
+ {
+ BulkUpdateInventoryPacket.FolderDataBlock folderBlock = new BulkUpdateInventoryPacket.FolderDataBlock();
+
+ folderBlock.FolderID = folder.ID;
+ folderBlock.ParentID = folder.ParentID;
+ folderBlock.Type = -1;
+ folderBlock.Name = Utils.StringToBytes(folder.Name);
+
+ return folderBlock;
+ }
+
+ ///
+ /// Generate a bulk update inventory data block for the given item
+ ///
+ ///
+ ///
+ private BulkUpdateInventoryPacket.ItemDataBlock GenerateBulkUpdateItemDataBlock(InventoryItemBase item)
+ {
+ BulkUpdateInventoryPacket.ItemDataBlock itemBlock = new BulkUpdateInventoryPacket.ItemDataBlock();
+
+ itemBlock.ItemID = item.ID;
+ itemBlock.AssetID = item.AssetID;
+ itemBlock.CreatorID = item.Creator;
+ itemBlock.BaseMask = item.BasePermissions;
+ itemBlock.Description = Utils.StringToBytes(item.Description);
+ itemBlock.EveryoneMask = item.EveryOnePermissions;
+ itemBlock.FolderID = item.Folder;
+ itemBlock.InvType = (sbyte)item.InvType;
+ itemBlock.Name = Utils.StringToBytes(item.Name);
+ itemBlock.NextOwnerMask = item.NextPermissions;
+ itemBlock.OwnerID = item.Owner;
+ itemBlock.OwnerMask = item.CurrentPermissions;
+ itemBlock.Type = (sbyte)item.AssetType;
+ itemBlock.GroupID = item.GroupID;
+ itemBlock.GroupOwned = item.GroupOwned;
+ itemBlock.GroupMask = item.GroupPermissions;
+ itemBlock.Flags = item.Flags;
+ itemBlock.SalePrice = item.SalePrice;
+ itemBlock.SaleType = item.SaleType;
+ itemBlock.CreationDate = item.CreationDate;
+
+ itemBlock.CRC =
+ Helpers.InventoryCRC(
+ 1000, 0, itemBlock.InvType,
+ itemBlock.Type, itemBlock.AssetID,
+ itemBlock.GroupID, 100,
+ itemBlock.OwnerID, itemBlock.CreatorID,
+ itemBlock.ItemID, itemBlock.FolderID,
+ (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
+ (uint)PermissionMask.All);
+
+ return itemBlock;
+ }
/// IClientAPI.SendBulkUpdateInventory(InventoryItemBase)
public void SendBulkUpdateInventory(InventoryItemBase item)
--
cgit v1.1