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/Region/Environment | |
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/Region/Environment')
4 files changed, 214 insertions, 40 deletions
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 | } |