diff options
author | Justin Clarke Casey | 2008-12-04 19:57:36 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-12-04 19:57:36 +0000 |
commit | 38ca31b37a6ac8fe74b77e4488112eb77d612827 (patch) | |
tree | 01c75a28b9f34667910f0992d8f817a5c5a1e5b3 /OpenSim | |
parent | Minor formatting cleanup. (diff) | |
download | opensim-SC-38ca31b37a6ac8fe74b77e4488112eb77d612827.zip opensim-SC-38ca31b37a6ac8fe74b77e4488112eb77d612827.tar.gz opensim-SC-38ca31b37a6ac8fe74b77e4488112eb77d612827.tar.bz2 opensim-SC-38ca31b37a6ac8fe74b77e4488112eb77d612827.tar.xz |
* 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
Diffstat (limited to 'OpenSim')
9 files changed, 380 insertions, 41 deletions
diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index 4212fbc..b4e7bfa 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs | |||
@@ -556,8 +556,10 @@ namespace OpenSim.Framework.Communications.Cache | |||
556 | } | 556 | } |
557 | 557 | ||
558 | /// <summary> | 558 | /// <summary> |
559 | /// Add an item to the user's inventory | 559 | /// Add an item to the user's inventory. |
560 | /// </summary> | 560 | /// </summary> |
561 | /// If the item has no folder set (i.e. it is UUID.Zero), then it is placed in the most appropriate folder | ||
562 | /// for that type. | ||
561 | /// <param name="itemInfo"></param> | 563 | /// <param name="itemInfo"></param> |
562 | public void AddItem(InventoryItemBase item) | 564 | public void AddItem(InventoryItemBase item) |
563 | { | 565 | { |
@@ -572,6 +574,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
572 | item.Folder = RootFolder.ID; | 574 | item.Folder = RootFolder.ID; |
573 | } | 575 | } |
574 | ItemReceive(item, null); | 576 | ItemReceive(item, null); |
577 | |||
575 | if (m_commsManager.SecureInventoryService != null) | 578 | if (m_commsManager.SecureInventoryService != null) |
576 | { | 579 | { |
577 | m_commsManager.SecureInventoryService.AddItem(item, m_session_id); | 580 | m_commsManager.SecureInventoryService.AddItem(item, m_session_id); |
diff --git a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs b/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs index 8e624f9..0704232 100644 --- a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs +++ b/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs | |||
@@ -358,6 +358,10 @@ namespace OpenSim.Framework.Communications.Cache | |||
358 | return folderList; | 358 | return folderList; |
359 | } | 359 | } |
360 | 360 | ||
361 | /// <value> | ||
362 | /// The total number of items in this folder and in the immediate child folders (though not from other | ||
363 | /// descendants). | ||
364 | /// </value> | ||
361 | public int TotalCount | 365 | public int TotalCount |
362 | { | 366 | { |
363 | get | 367 | get |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 15a89d3..8a3c4b6 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -829,6 +829,13 @@ namespace OpenSim.Framework | |||
829 | void SendTaskInventory(UUID taskID, short serial, byte[] fileName); | 829 | void SendTaskInventory(UUID taskID, short serial, byte[] fileName); |
830 | 830 | ||
831 | /// <summary> | 831 | /// <summary> |
832 | /// Used by the server to inform the client of new inventory items. Will transfer the contents of the folder | ||
833 | /// (including all descendent folders) as well as the folder itself. | ||
834 | /// </summary> | ||
835 | /// <param name="folder"></param> | ||
836 | void SendBulkUpdateInventory(InventoryFolderBase folder); | ||
837 | |||
838 | /// <summary> | ||
832 | /// Used by the server to inform the client of a new inventory item. Used when transferring items | 839 | /// Used by the server to inform the client of a new inventory item. Used when transferring items |
833 | /// between avatars, possibly among other things. | 840 | /// between avatars, possibly among other things. |
834 | /// </summary> | 841 | /// </summary> |
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 | |||
1144 | msg.MessageBlock.Message = Utils.StringToBytes(message); | 1144 | msg.MessageBlock.Message = Utils.StringToBytes(message); |
1145 | msg.MessageBlock.BinaryBucket = binaryBucket; | 1145 | msg.MessageBlock.BinaryBucket = binaryBucket; |
1146 | 1146 | ||
1147 | System.Console.WriteLine("SendInstantMessage: " + msg); | ||
1147 | OutPacket(msg, ThrottleOutPacketType.Task); | 1148 | OutPacket(msg, ThrottleOutPacketType.Task); |
1148 | } | 1149 | } |
1149 | } | 1150 | } |
@@ -1763,6 +1764,153 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1763 | inventoryReply.Header.Zerocoded = true; | 1764 | inventoryReply.Header.Zerocoded = true; |
1764 | OutPacket(inventoryReply, ThrottleOutPacketType.Asset); | 1765 | OutPacket(inventoryReply, ThrottleOutPacketType.Asset); |
1765 | } | 1766 | } |
1767 | |||
1768 | /// <see>IClientAPI.SendBulkUpdateInventory(InventoryFolderBase)</see> | ||
1769 | public void SendBulkUpdateInventory(InventoryFolderBase folderBase) | ||
1770 | { | ||
1771 | // XXX: Nasty temporary move that will be resolved shortly | ||
1772 | InventoryFolderImpl folder = (InventoryFolderImpl)folderBase; | ||
1773 | |||
1774 | // We will use the same transaction id for all the separate packets to be sent out in this update. | ||
1775 | UUID transactionId = UUID.Random(); | ||
1776 | |||
1777 | List<BulkUpdateInventoryPacket.FolderDataBlock> folderDataBlocks | ||
1778 | = new List<BulkUpdateInventoryPacket.FolderDataBlock>(); | ||
1779 | |||
1780 | SendBulkUpdateInventoryRecursive(folder, ref folderDataBlocks, transactionId); | ||
1781 | |||
1782 | if (folderDataBlocks.Count > 0) | ||
1783 | { | ||
1784 | // We'll end up with some unsent folder blocks if there were some empty folders at the end of the list | ||
1785 | // Send these now | ||
1786 | BulkUpdateInventoryPacket bulkUpdate | ||
1787 | = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); | ||
1788 | bulkUpdate.Header.Zerocoded = true; | ||
1789 | |||
1790 | bulkUpdate.AgentData.AgentID = AgentId; | ||
1791 | bulkUpdate.AgentData.TransactionID = transactionId; | ||
1792 | bulkUpdate.FolderData = folderDataBlocks.ToArray(); | ||
1793 | |||
1794 | Console.WriteLine("SendBulkUpdateInventory :" + bulkUpdate); | ||
1795 | OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); | ||
1796 | } | ||
1797 | } | ||
1798 | |||
1799 | /// <summary> | ||
1800 | /// Recursively construct bulk update packets to send folders and items | ||
1801 | /// </summary> | ||
1802 | /// <param name="folder"></param> | ||
1803 | /// <param name="folderDataBlocks"></param> | ||
1804 | /// <param name="transactionId"></param> | ||
1805 | private void SendBulkUpdateInventoryRecursive( | ||
1806 | InventoryFolderImpl folder, ref List<BulkUpdateInventoryPacket.FolderDataBlock> folderDataBlocks, | ||
1807 | UUID transactionId) | ||
1808 | { | ||
1809 | folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder)); | ||
1810 | |||
1811 | const int MAX_ITEMS_PER_PACKET = 5; | ||
1812 | |||
1813 | // If there are any items then we have to start sending them off in this packet - the next folder will have | ||
1814 | // to be in its own bulk update packet. Also, we can only fit 5 items in a packet (at least this was the limit | ||
1815 | // being used on the Linden grid at 20081203). | ||
1816 | List<InventoryItemBase> items = folder.RequestListOfItems(); | ||
1817 | while (items.Count > 0) | ||
1818 | { | ||
1819 | BulkUpdateInventoryPacket bulkUpdate | ||
1820 | = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); | ||
1821 | bulkUpdate.Header.Zerocoded = true; | ||
1822 | |||
1823 | bulkUpdate.AgentData.AgentID = AgentId; | ||
1824 | bulkUpdate.AgentData.TransactionID = transactionId; | ||
1825 | bulkUpdate.FolderData = folderDataBlocks.ToArray(); | ||
1826 | |||
1827 | int itemsToSend = (items.Count > MAX_ITEMS_PER_PACKET ? MAX_ITEMS_PER_PACKET : items.Count); | ||
1828 | bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[itemsToSend]; | ||
1829 | |||
1830 | for (int i = 0; i < itemsToSend; i++) | ||
1831 | { | ||
1832 | // Remove from the end of the list so that we don't incur a performance penalty | ||
1833 | bulkUpdate.ItemData[i] = GenerateBulkUpdateItemDataBlock(items[items.Count - 1]); | ||
1834 | items.RemoveAt(items.Count - 1); | ||
1835 | } | ||
1836 | |||
1837 | Console.WriteLine("SendBulkUpdateInventoryRecursive :" + bulkUpdate); | ||
1838 | OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); | ||
1839 | |||
1840 | folderDataBlocks = new List<BulkUpdateInventoryPacket.FolderDataBlock>(); | ||
1841 | |||
1842 | // If we're going to be sending another items packet then it needs to contain just the folder to which those | ||
1843 | // items belong. | ||
1844 | if (items.Count > 0) | ||
1845 | folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder)); | ||
1846 | } | ||
1847 | |||
1848 | List<InventoryFolderImpl> subFolders = folder.RequestListOfFolderImpls(); | ||
1849 | foreach (InventoryFolderImpl subFolder in subFolders) | ||
1850 | { | ||
1851 | SendBulkUpdateInventoryRecursive(subFolder, ref folderDataBlocks, transactionId); | ||
1852 | } | ||
1853 | } | ||
1854 | |||
1855 | /// <summary> | ||
1856 | /// Generate a bulk update inventory data block for the given folder | ||
1857 | /// </summary> | ||
1858 | /// <param name="folder"></param> | ||
1859 | /// <returns></returns> | ||
1860 | private BulkUpdateInventoryPacket.FolderDataBlock GenerateBulkUpdateFolderDataBlock(InventoryFolderBase folder) | ||
1861 | { | ||
1862 | BulkUpdateInventoryPacket.FolderDataBlock folderBlock = new BulkUpdateInventoryPacket.FolderDataBlock(); | ||
1863 | |||
1864 | folderBlock.FolderID = folder.ID; | ||
1865 | folderBlock.ParentID = folder.ParentID; | ||
1866 | folderBlock.Type = -1; | ||
1867 | folderBlock.Name = Utils.StringToBytes(folder.Name); | ||
1868 | |||
1869 | return folderBlock; | ||
1870 | } | ||
1871 | |||
1872 | /// <summary> | ||
1873 | /// Generate a bulk update inventory data block for the given item | ||
1874 | /// </summary> | ||
1875 | /// <param name="item"></param> | ||
1876 | /// <returns></returns> | ||
1877 | private BulkUpdateInventoryPacket.ItemDataBlock GenerateBulkUpdateItemDataBlock(InventoryItemBase item) | ||
1878 | { | ||
1879 | BulkUpdateInventoryPacket.ItemDataBlock itemBlock = new BulkUpdateInventoryPacket.ItemDataBlock(); | ||
1880 | |||
1881 | itemBlock.ItemID = item.ID; | ||
1882 | itemBlock.AssetID = item.AssetID; | ||
1883 | itemBlock.CreatorID = item.Creator; | ||
1884 | itemBlock.BaseMask = item.BasePermissions; | ||
1885 | itemBlock.Description = Utils.StringToBytes(item.Description); | ||
1886 | itemBlock.EveryoneMask = item.EveryOnePermissions; | ||
1887 | itemBlock.FolderID = item.Folder; | ||
1888 | itemBlock.InvType = (sbyte)item.InvType; | ||
1889 | itemBlock.Name = Utils.StringToBytes(item.Name); | ||
1890 | itemBlock.NextOwnerMask = item.NextPermissions; | ||
1891 | itemBlock.OwnerID = item.Owner; | ||
1892 | itemBlock.OwnerMask = item.CurrentPermissions; | ||
1893 | itemBlock.Type = (sbyte)item.AssetType; | ||
1894 | itemBlock.GroupID = item.GroupID; | ||
1895 | itemBlock.GroupOwned = item.GroupOwned; | ||
1896 | itemBlock.GroupMask = item.GroupPermissions; | ||
1897 | itemBlock.Flags = item.Flags; | ||
1898 | itemBlock.SalePrice = item.SalePrice; | ||
1899 | itemBlock.SaleType = item.SaleType; | ||
1900 | itemBlock.CreationDate = item.CreationDate; | ||
1901 | |||
1902 | itemBlock.CRC = | ||
1903 | Helpers.InventoryCRC( | ||
1904 | 1000, 0, itemBlock.InvType, | ||
1905 | itemBlock.Type, itemBlock.AssetID, | ||
1906 | itemBlock.GroupID, 100, | ||
1907 | itemBlock.OwnerID, itemBlock.CreatorID, | ||
1908 | itemBlock.ItemID, itemBlock.FolderID, | ||
1909 | (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All, | ||
1910 | (uint)PermissionMask.All); | ||
1911 | |||
1912 | return itemBlock; | ||
1913 | } | ||
1766 | 1914 | ||
1767 | /// <see>IClientAPI.SendBulkUpdateInventory(InventoryItemBase)</see> | 1915 | /// <see>IClientAPI.SendBulkUpdateInventory(InventoryItemBase)</see> |
1768 | public void SendBulkUpdateInventory(InventoryItemBase item) | 1916 | public void SendBulkUpdateInventory(InventoryItemBase item) |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 73f1761..b41c36f 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -136,42 +136,85 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer | |||
136 | 136 | ||
137 | if (im.dialog == (byte) InstantMessageDialog.InventoryOffered) | 137 | if (im.dialog == (byte) InstantMessageDialog.InventoryOffered) |
138 | { | 138 | { |
139 | ScenePresence user = | 139 | m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); |
140 | scene.GetScenePresence(new UUID(im.toAgentID)); | 140 | |
141 | ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); | ||
142 | UUID copyID; | ||
141 | 143 | ||
142 | // First byte of the array is probably the item type | 144 | // First byte is the asset type |
143 | // Next 16 bytes are the UUID | 145 | AssetType assetType = (AssetType)im.binaryBucket[0]; |
146 | |||
147 | // Temporarily disabled pending test of complex transfers (folders within folders, lots of items, | ||
148 | // empty folders, etc.) | ||
149 | if (AssetType.Folder == assetType) | ||
150 | return; | ||
151 | |||
152 | if (AssetType.Folder == assetType) | ||
153 | { | ||
154 | UUID folderID = new UUID(im.binaryBucket, 1); | ||
155 | |||
156 | m_log.DebugFormat("[AGENT INVENTORY]: Inserting original folder {0} "+ | ||
157 | "into agent {1}'s inventory", | ||
158 | folderID, new UUID(im.toAgentID)); | ||
159 | |||
160 | InventoryFolderImpl folderCopy | ||
161 | = scene.GiveInventoryFolder(new UUID(im.toAgentID), client.AgentId, folderID, UUID.Zero); | ||
162 | |||
163 | if (folderCopy == null) | ||
164 | { | ||
165 | client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); | ||
166 | return; | ||
167 | } | ||
168 | |||
169 | // The outgoing binary bucket should contain only the byte which signals an asset folder is | ||
170 | // being copied and the following bytes for the copied folder's UUID | ||
171 | copyID = folderCopy.ID; | ||
172 | byte[] copyIDBytes = copyID.GetBytes(); | ||
173 | im.binaryBucket = new byte[1 + copyIDBytes.Length]; | ||
174 | im.binaryBucket[0] = (byte)AssetType.Folder; | ||
175 | Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); | ||
176 | |||
177 | if (user != null && !user.IsChildAgent) | ||
178 | { | ||
179 | user.ControllingClient.SendBulkUpdateInventory(folderCopy); | ||
180 | } | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | // First byte of the array is probably the item type | ||
185 | // Next 16 bytes are the UUID | ||
144 | 186 | ||
145 | UUID itemID = new UUID(im.binaryBucket, 1); | 187 | UUID itemID = new UUID(im.binaryBucket, 1); |
146 | 188 | ||
147 | m_log.DebugFormat("[AGENT INVENTORY]: Inserting item {0} "+ | 189 | m_log.DebugFormat("[AGENT INVENTORY]: Inserting item {0} "+ |
148 | "into agent {1}'s inventory", | 190 | "into agent {1}'s inventory", |
149 | itemID, new UUID(im.toAgentID)); | 191 | itemID, new UUID(im.toAgentID)); |
150 | 192 | ||
151 | InventoryItemBase itemCopy = scene.GiveInventoryItem( | 193 | InventoryItemBase itemCopy = scene.GiveInventoryItem( |
152 | new UUID(im.toAgentID), | 194 | new UUID(im.toAgentID), |
153 | client.AgentId, itemID); | 195 | client.AgentId, itemID); |
154 | 196 | ||
155 | if (itemCopy == null) | 197 | if (itemCopy == null) |
156 | { | 198 | { |
157 | client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); | 199 | client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); |
158 | return; | 200 | return; |
201 | } | ||
202 | |||
203 | copyID = itemCopy.ID; | ||
204 | Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); | ||
205 | |||
206 | if (user != null && !user.IsChildAgent) | ||
207 | { | ||
208 | user.ControllingClient.SendBulkUpdateInventory(itemCopy); | ||
209 | } | ||
159 | } | 210 | } |
160 | 211 | ||
161 | byte[] itemCopyID = itemCopy.ID.GetBytes(); | ||
162 | |||
163 | Array.Copy(itemCopyID, 0, im.binaryBucket, 1, 16); | ||
164 | |||
165 | // Send the IM to the recipient. The item is already | 212 | // Send the IM to the recipient. The item is already |
166 | // in their inventory, so it will not be lost if | 213 | // in their inventory, so it will not be lost if |
167 | // they are offline. | 214 | // they are offline. |
168 | // | 215 | // |
169 | if (user != null && !user.IsChildAgent) | 216 | if (user != null && !user.IsChildAgent) |
170 | { | 217 | { |
171 | // User is online. So, let's make the item visible | ||
172 | // | ||
173 | user.ControllingClient.SendBulkUpdateInventory(itemCopy); | ||
174 | |||
175 | // And notify. Transaction ID is the item ID. We get that | 218 | // And notify. Transaction ID is the item ID. We get that |
176 | // same ID back on the reply so we know what to act on | 219 | // same ID back on the reply so we know what to act on |
177 | // | 220 | // |
@@ -179,7 +222,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer | |||
179 | new UUID(im.fromAgentID), im.message, | 222 | new UUID(im.fromAgentID), im.message, |
180 | new UUID(im.toAgentID), | 223 | new UUID(im.toAgentID), |
181 | im.fromAgentName, im.dialog, im.timestamp, | 224 | im.fromAgentName, im.dialog, im.timestamp, |
182 | itemCopy.ID, false, im.binaryBucket); | 225 | copyID, false, im.binaryBucket); |
183 | 226 | ||
184 | return; | 227 | return; |
185 | } | 228 | } |
@@ -208,9 +251,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer | |||
208 | } | 251 | } |
209 | } | 252 | } |
210 | else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) | 253 | else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) |
211 | { | 254 | { |
212 | UUID itemID = new UUID(im.imSessionID); // The item, back from it's trip | ||
213 | |||
214 | // Here, the recipient is local and we can assume that the | 255 | // Here, the recipient is local and we can assume that the |
215 | // inventory is loaded. Courtesy of the above bulk update, | 256 | // inventory is loaded. Courtesy of the above bulk update, |
216 | // It will have been pushed to the client, too | 257 | // It will have been pushed to the client, too |
@@ -224,27 +265,43 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer | |||
224 | { | 265 | { |
225 | InventoryFolderImpl trashFolder = | 266 | InventoryFolderImpl trashFolder = |
226 | userInfo.FindFolderForType((int)AssetType.TrashFolder); | 267 | userInfo.FindFolderForType((int)AssetType.TrashFolder); |
227 | 268 | ||
228 | InventoryItemBase item = | 269 | UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip |
229 | userInfo.RootFolder.FindItem(itemID); | 270 | |
230 | 271 | InventoryItemBase item = userInfo.RootFolder.FindItem(inventoryEntityID); | |
231 | if (trashFolder != null && item != null) | 272 | InventoryFolderBase folder = null; |
273 | |||
274 | if (item != null && trashFolder != null) | ||
232 | { | 275 | { |
233 | item.Folder = trashFolder.ID; | 276 | item.Folder = trashFolder.ID; |
234 | 277 | ||
235 | userInfo.DeleteItem(itemID); | 278 | userInfo.DeleteItem(inventoryEntityID); |
236 | 279 | ||
237 | scene.AddInventoryItem(client, item); | 280 | scene.AddInventoryItem(client, item); |
238 | } | 281 | } |
239 | else | 282 | else |
240 | { | 283 | { |
241 | string reason = ""; | 284 | folder = userInfo.RootFolder.FindFolder(inventoryEntityID); |
285 | |||
286 | if (folder != null & trashFolder != null) | ||
287 | { | ||
288 | userInfo.MoveFolder(inventoryEntityID, trashFolder.ID); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if ((null == item && null == folder) | null == trashFolder) | ||
293 | { | ||
294 | string reason = String.Empty; | ||
295 | |||
242 | if (trashFolder == null) | 296 | if (trashFolder == null) |
243 | reason += " Trash folder not found."; | 297 | reason += " Trash folder not found."; |
244 | if (item == null) | 298 | if (item == null) |
245 | reason += " Item not found."; | 299 | reason += " Item not found."; |
300 | if (folder == null) | ||
301 | reason += " Folder not found."; | ||
302 | |||
246 | client.SendAgentAlertMessage("Unable to delete "+ | 303 | client.SendAgentAlertMessage("Unable to delete "+ |
247 | "received item" + reason, false); | 304 | "received inventory" + reason, false); |
248 | } | 305 | } |
249 | } | 306 | } |
250 | 307 | ||
diff --git a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs index b5a5123..fb1d1ff 100644 --- a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs | |||
@@ -624,6 +624,9 @@ namespace OpenSim.Region.Environment.Modules.World.NPC | |||
624 | public virtual void SendBulkUpdateInventory(InventoryItemBase item) | 624 | public virtual void SendBulkUpdateInventory(InventoryItemBase item) |
625 | { | 625 | { |
626 | } | 626 | } |
627 | |||
628 | public virtual void SendBulkUpdateInventory(InventoryFolderBase folderBase) | ||
629 | {} | ||
627 | 630 | ||
628 | public void SendTakeControls(int controls, bool passToAgent, bool TakeControls) | 631 | public void SendTakeControls(int controls, bool passToAgent, bool TakeControls) |
629 | { | 632 | { |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index d1e0c24..3d6a905 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs | |||
@@ -400,11 +400,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
400 | } | 400 | } |
401 | 401 | ||
402 | /// <summary> | 402 | /// <summary> |
403 | /// Give an inventory item from one avatar to another | 403 | /// Give an inventory item from one user to another |
404 | /// </summary> | 404 | /// </summary> |
405 | /// <param name="recipientClient"></param> | 405 | /// <param name="recipientClient"></param> |
406 | /// <param name="senderId">ID of the sender of the item</param> | 406 | /// <param name="senderId">ID of the sender of the item</param> |
407 | /// <param name="itemId"></param> | 407 | /// <param name="itemId"></param> |
408 | public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId) | 408 | public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId) |
409 | { | 409 | { |
410 | InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId); | 410 | InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId); |
@@ -413,8 +413,34 @@ namespace OpenSim.Region.Environment.Scenes | |||
413 | recipientClient.SendBulkUpdateInventory(itemCopy); | 413 | recipientClient.SendBulkUpdateInventory(itemCopy); |
414 | } | 414 | } |
415 | 415 | ||
416 | /// <summary> | ||
417 | /// Give an inventory item from one user to another | ||
418 | /// </summary> | ||
419 | /// <param name="recipient"></param> | ||
420 | /// <param name="senderId">ID of the sender of the item</param> | ||
421 | /// <param name="itemId"></param> | ||
422 | /// <returns>The inventory item copy given, null if the give was unsuccessful</returns> | ||
416 | public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId) | 423 | public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId) |
417 | { | 424 | { |
425 | return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero); | ||
426 | } | ||
427 | |||
428 | /// <summary> | ||
429 | /// Give an inventory item from one user to another | ||
430 | /// </summary> | ||
431 | /// <param name="recipient"></param> | ||
432 | /// <param name="senderId">ID of the sender of the item</param> | ||
433 | /// <param name="itemId"></param> | ||
434 | /// <param name="recipientFolderId"> | ||
435 | /// The id of the folder in which the copy item should go. If UUID.Zero then the item is placed in the most | ||
436 | /// appropriate default folder. | ||
437 | /// </param> | ||
438 | /// <returns> | ||
439 | /// The inventory item copy given, null if the give was unsuccessful | ||
440 | /// </returns> | ||
441 | public virtual InventoryItemBase GiveInventoryItem( | ||
442 | UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId) | ||
443 | { | ||
418 | // Retrieve the item from the sender | 444 | // Retrieve the item from the sender |
419 | CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId); | 445 | CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId); |
420 | 446 | ||
@@ -438,7 +464,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
438 | return null; | 464 | return null; |
439 | } | 465 | } |
440 | 466 | ||
441 | // TODO get recipient's root folder | ||
442 | CachedUserInfo recipientUserInfo | 467 | CachedUserInfo recipientUserInfo |
443 | = CommsManager.UserProfileCacheService.GetUserDetails(recipient); | 468 | = CommsManager.UserProfileCacheService.GetUserDetails(recipient); |
444 | 469 | ||
@@ -457,7 +482,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
457 | itemCopy.Name = item.Name; | 482 | itemCopy.Name = item.Name; |
458 | itemCopy.AssetType = item.AssetType; | 483 | itemCopy.AssetType = item.AssetType; |
459 | itemCopy.InvType = item.InvType; | 484 | itemCopy.InvType = item.InvType; |
460 | itemCopy.Folder = UUID.Zero; | 485 | itemCopy.Folder = recipientFolderId; |
486 | |||
461 | if (Permissions.PropagatePermissions()) | 487 | if (Permissions.PropagatePermissions()) |
462 | { | 488 | { |
463 | if (item.InvType == 6) | 489 | if (item.InvType == 6) |
@@ -529,8 +555,93 @@ namespace OpenSim.Region.Environment.Scenes | |||
529 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder"); | 555 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder"); |
530 | return null; | 556 | return null; |
531 | } | 557 | } |
558 | |||
532 | return null; | 559 | return null; |
533 | } | 560 | } |
561 | |||
562 | /// <summary> | ||
563 | /// Give an entire inventory folder from one user to another. The entire contents (including all descendent | ||
564 | /// folders) is given. | ||
565 | /// </summary> | ||
566 | /// <param name="recipientId"></param> | ||
567 | /// <param name="senderId">ID of the sender of the item</param> | ||
568 | /// <param name="folderId"></param> | ||
569 | /// <param name="recipientParentFolderId"> | ||
570 | /// The id of the receipient folder in which the send folder should be placed. If UUID.Zero then the | ||
571 | /// recipient folder is the root folder | ||
572 | /// </param> | ||
573 | /// <returns> | ||
574 | /// The inventory folder copy given, null if the copy was unsuccessful | ||
575 | /// </returns> | ||
576 | public virtual InventoryFolderImpl GiveInventoryFolder( | ||
577 | UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId) | ||
578 | { | ||
579 | // Retrieve the folder from the sender | ||
580 | CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId); | ||
581 | |||
582 | if (null == senderUserInfo) | ||
583 | { | ||
584 | m_log.ErrorFormat( | ||
585 | "[AGENT INVENTORY]: Failed to find sending user {0} for folder {1}", senderId, folderId); | ||
586 | |||
587 | return null; | ||
588 | } | ||
589 | |||
590 | if (!senderUserInfo.HasReceivedInventory) | ||
591 | { | ||
592 | m_log.DebugFormat( | ||
593 | "[AGENT INVENTORY]: Could not give inventory folder - have not yet received inventory for {0}", | ||
594 | senderId); | ||
595 | |||
596 | return null; | ||
597 | } | ||
598 | |||
599 | InventoryFolderImpl folder = senderUserInfo.RootFolder.FindFolder(folderId); | ||
600 | |||
601 | if (null == folder) | ||
602 | { | ||
603 | m_log.ErrorFormat( | ||
604 | "[AGENT INVENTORY]: Could not find inventory folder {0} to give", folderId); | ||
605 | |||
606 | return null; | ||
607 | } | ||
608 | |||
609 | CachedUserInfo recipientUserInfo | ||
610 | = CommsManager.UserProfileCacheService.GetUserDetails(recipientId); | ||
611 | |||
612 | if (null == recipientUserInfo) | ||
613 | { | ||
614 | m_log.ErrorFormat( | ||
615 | "[AGENT INVENTORY]: Failed to find receiving user {0} for folder {1}", recipientId, folderId); | ||
616 | |||
617 | return null; | ||
618 | } | ||
619 | |||
620 | if (recipientParentFolderId == UUID.Zero) | ||
621 | recipientParentFolderId = recipientUserInfo.RootFolder.ID; | ||
622 | |||
623 | UUID newFolderId = UUID.Random(); | ||
624 | recipientUserInfo.CreateFolder(folder.Name, newFolderId, (ushort)folder.Type, recipientParentFolderId); | ||
625 | |||
626 | // XXX: Messy - we should really get this back in the CreateFolder call | ||
627 | InventoryFolderImpl copiedFolder = recipientUserInfo.RootFolder.FindFolder(newFolderId); | ||
628 | |||
629 | // Give all the subfolders | ||
630 | List<InventoryFolderImpl> subFolders = folder.RequestListOfFolderImpls(); | ||
631 | foreach (InventoryFolderImpl childFolder in subFolders) | ||
632 | { | ||
633 | GiveInventoryFolder(recipientId, senderId, childFolder.ID, copiedFolder.ID); | ||
634 | } | ||
635 | |||
636 | // Give all the items | ||
637 | List<InventoryItemBase> items = folder.RequestListOfItems(); | ||
638 | foreach (InventoryItemBase item in items) | ||
639 | { | ||
640 | GiveInventoryItem(recipientId, senderId, item.ID, copiedFolder.ID); | ||
641 | } | ||
642 | |||
643 | return copiedFolder; | ||
644 | } | ||
534 | 645 | ||
535 | public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, | 646 | public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, |
536 | UUID newFolderID, string newName) | 647 | UUID newFolderID, string newName) |
diff --git a/OpenSim/Region/Environment/Scenes/Tests/TestClient.cs b/OpenSim/Region/Environment/Scenes/Tests/TestClient.cs index 69e45bb..cecb115 100644 --- a/OpenSim/Region/Environment/Scenes/Tests/TestClient.cs +++ b/OpenSim/Region/Environment/Scenes/Tests/TestClient.cs | |||
@@ -538,6 +538,9 @@ namespace OpenSim.Region.Environment.Scenes.Tests | |||
538 | public virtual void SendBulkUpdateInventory(InventoryItemBase item) | 538 | public virtual void SendBulkUpdateInventory(InventoryItemBase item) |
539 | { | 539 | { |
540 | } | 540 | } |
541 | |||
542 | public void SendBulkUpdateInventory(InventoryFolderBase folderBase) | ||
543 | {} | ||
541 | 544 | ||
542 | public UUID GetDefaultAnimation(string name) | 545 | public UUID GetDefaultAnimation(string name) |
543 | { | 546 | { |
@@ -561,8 +564,8 @@ namespace OpenSim.Region.Environment.Scenes.Tests | |||
561 | int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, | 564 | int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, |
562 | int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent) | 565 | int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent) |
563 | { | 566 | { |
564 | |||
565 | } | 567 | } |
568 | |||
566 | public virtual void SendNameReply(UUID profileId, string firstname, string lastname) | 569 | public virtual void SendNameReply(UUID profileId, string firstname, string lastname) |
567 | { | 570 | { |
568 | } | 571 | } |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 89b3bf6..f1a61bb 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -537,6 +537,9 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
537 | public virtual void SendBulkUpdateInventory(InventoryItemBase item) | 537 | public virtual void SendBulkUpdateInventory(InventoryItemBase item) |
538 | { | 538 | { |
539 | } | 539 | } |
540 | |||
541 | public void SendBulkUpdateInventory(InventoryFolderBase folderBase) | ||
542 | {} | ||
540 | 543 | ||
541 | public UUID GetDefaultAnimation(string name) | 544 | public UUID GetDefaultAnimation(string name) |
542 | { | 545 | { |