aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie Thielker2008-11-12 06:22:31 +0000
committerMelanie Thielker2008-11-12 06:22:31 +0000
commitc71f0899c255c9415210662273365cad83e40c0e (patch)
treec5f0e684a95c89462229dd6149d84b6b458ed169 /OpenSim
parent* Set defaults on the allowed LSL Compilers to 'lsl' unless you've specified ... (diff)
downloadopensim-SC-c71f0899c255c9415210662273365cad83e40c0e.zip
opensim-SC-c71f0899c255c9415210662273365cad83e40c0e.tar.gz
opensim-SC-c71f0899c255c9415210662273365cad83e40c0e.tar.bz2
opensim-SC-c71f0899c255c9415210662273365cad83e40c0e.tar.xz
Revamp inventory transfer module, step 1. Inventory will now be saved if
destination user is offline/out of range. No more eternal cache is needed for tracking IDs. Code cleanup. Removed some casts from IScene to Scene. Decline now properly places item in trash rather than deleting it outright.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs216
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.Inventory.cs31
2 files changed, 138 insertions, 109 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index b134591..71cc726 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -25,6 +25,8 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Collections;
28using System.Collections.Generic; 30using System.Collections.Generic;
29using System.Reflection; 31using System.Reflection;
30using OpenMetaverse; 32using OpenMetaverse;
@@ -33,6 +35,7 @@ using Nini.Config;
33using OpenSim.Framework; 35using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
38using OpenSim.Framework.Communications.Cache;
36 39
37namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer 40namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer
38{ 41{
@@ -42,14 +45,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer
42 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 46
44 /// <summary> 47 /// <summary>
45 /// We need to keep track of the pending item offers between clients since the itemId offered only
46 /// occurs in the initial offer message, not the accept message. So this dictionary links
47 /// IM Session Ids to ItemIds
48 /// </summary>
49 private IDictionary<UUID, UUID> m_pendingOffers = new Dictionary<UUID, UUID>();
50
51 private List<Scene> m_Scenelist = new List<Scene>(); 48 private List<Scene> m_Scenelist = new List<Scene>();
52 private Dictionary<UUID, Scene> m_AgentRegions = new Dictionary<UUID, Scene>(); 49 private Dictionary<UUID, Scene> m_AgentRegions =
50 new Dictionary<UUID, Scene>();
53 51
54 #region IRegionModule Members 52 #region IRegionModule Members
55 53
@@ -64,6 +62,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer
64 "InventoryTransferModule") 62 "InventoryTransferModule")
65 return; 63 return;
66 } 64 }
65
67 if (!m_Scenelist.Contains(scene)) 66 if (!m_Scenelist.Contains(scene))
68 { 67 {
69 m_Scenelist.Add(scene); 68 m_Scenelist.Add(scene);
@@ -101,136 +100,155 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer
101 client.OnInstantMessage += OnInstantMessage; 100 client.OnInstantMessage += OnInstantMessage;
102 } 101 }
103 102
103 private Scene FindClientScene(UUID agentId)
104 {
105 lock (m_Scenelist)
106 {
107 foreach (Scene scene in m_Scenelist)
108 {
109 ScenePresence presence = scene.GetScenePresence(agentId);
110 if (presence != null)
111 {
112 if (!presence.IsChildAgent)
113 return scene;
114 }
115 }
116 }
117 return null;
118 }
119
104 private void OnInstantMessage(IClientAPI client, UUID fromAgentID, 120 private void OnInstantMessage(IClientAPI client, UUID fromAgentID,
105 UUID fromAgentSession, UUID toAgentID, 121 UUID fromAgentSession, UUID toAgentID,
106 UUID imSessionID, uint timestamp, string fromAgentName, 122 UUID imSessionID, uint timestamp, string fromAgentName,
107 string message, byte dialog, bool fromGroup, byte offline, 123 string message, byte dialog, bool fromGroup, byte offline,
108 uint ParentEstateID, Vector3 Position, UUID RegionID, 124 uint ParentEstateID, Vector3 Position, UUID RegionID,
109 byte[] binaryBucket) 125 byte[] binaryBucket)
110 { 126 {
127 Scene scene = FindClientScene(client.AgentId);
128
129 if (scene == null) // Something seriously wrong here.
130 return;
131
111 if (dialog == (byte) InstantMessageDialog.InventoryOffered) 132 if (dialog == (byte) InstantMessageDialog.InventoryOffered)
112 { 133 {
113 m_log.DebugFormat( 134 ScenePresence user =
114 "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", 135 scene.GetScenePresence(toAgentID);
115 client.AgentId, client.Name, toAgentID);
116 136
117 if (((Scene)(client.Scene)).Entities.ContainsKey(toAgentID) && ((Scene)(client.Scene)).Entities[toAgentID] is ScenePresence) 137 // First byte of the array is probably the item type
118 { 138 // Next 16 bytes are the UUID
119 ScenePresence user = (ScenePresence) ((Scene)(client.Scene)).Entities[toAgentID];
120 139
121 if (!user.IsChildAgent) 140 UUID itemID = new UUID(binaryBucket, 1);
122 {
123 //byte[] rawId = new byte[16];
124 141
125 // First byte of the array is probably the item type 142 m_log.DebugFormat("[AGENT INVENTORY]: Inserting item {0} "+
126 // Next 16 bytes are the UUID 143 "into agent {1}'s inventory",
127 //Array.Copy(binaryBucket, 1, rawId, 0, 16); 144 itemID, toAgentID);
128 145
129 //UUID itemId = new UUID(new Guid(rawId)); 146 InventoryItemBase itemCopy = scene.GiveInventoryItem(toAgentID,
130 UUID itemId = new UUID(binaryBucket, 1); 147 client.AgentId, itemID);
131 148
132 m_log.DebugFormat( 149 byte[] itemCopyID = itemCopy.ID.GetBytes();
133 "[AGENT INVENTORY]: ItemId for giving is {0}", itemId);
134 150
135 m_pendingOffers[imSessionID] = itemId; 151 Array.Copy(itemCopyID, 0, binaryBucket, 1, 16);
136 152
137 user.ControllingClient.SendInstantMessage( 153 // Send the IM to the recipient. The item is already
154 // in their inventory, so it will not be lost if
155 // they are offline.
156 //
157 if (user != null && !user.IsChildAgent)
158 {
159 // User is online. So, let's make the item visible
160 //
161 user.ControllingClient.SendBulkUpdateInventory(itemCopy);
162
163 // And notify. Transaction ID is the item ID. We get that
164 // same ID back on the reply so we know what to act on
165 //
166 user.ControllingClient.SendInstantMessage(
138 fromAgentID, message, toAgentID, fromAgentName, 167 fromAgentID, message, toAgentID, fromAgentName,
139 dialog, timestamp, UUID.Zero, false, binaryBucket); 168 dialog, timestamp, itemCopy.ID, false,
169 binaryBucket);
140 170
141 return; 171 return;
142 }
143 else
144 {
145 m_log.WarnFormat(
146 "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
147 toAgentID, client.AgentId, client.Name, message);
148 }
149 } 172 }
150 else 173 else
151 { 174 {
152 m_log.WarnFormat( 175 // Send via grid services
153 "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", 176 //
154 toAgentID, client.AgentId, client.Name, message); 177 // TODO: Implement grid sending
155 } 178 }
156 } 179 }
157 else if (dialog == (byte) InstantMessageDialog.InventoryAccepted) 180 else if (dialog == (byte) InstantMessageDialog.InventoryAccepted)
158 { 181 {
159 m_log.DebugFormat( 182 ScenePresence user = scene.GetScenePresence(toAgentID);
160 "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}",
161 client.AgentId, client.Name, toAgentID);
162 183
163 if (((Scene)(client.Scene)).Entities.ContainsKey(toAgentID) && ((Scene)(client.Scene)).Entities[toAgentID] is ScenePresence) 184 if (user != null) // Local
164 { 185 {
165 ScenePresence user = (ScenePresence) ((Scene)(client.Scene)).Entities[toAgentID]; 186 user.ControllingClient.SendInstantMessage(
166
167 if (!user.IsChildAgent)
168 {
169 user.ControllingClient.SendInstantMessage(
170 fromAgentID, message, toAgentID, fromAgentName, 187 fromAgentID, message, toAgentID, fromAgentName,
171 dialog, timestamp, UUID.Zero, false, binaryBucket); 188 dialog, timestamp, UUID.Zero, false, binaryBucket);
172
173 if (m_pendingOffers.ContainsKey(imSessionID))
174 {
175 m_log.DebugFormat(
176 "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]);
177
178 // Since the message originates from the accepting client, the toAgentID is
179 // the agent giving the item.
180 ((Scene)(client.Scene)).GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]);
181
182 m_pendingOffers.Remove(imSessionID);
183 }
184 else
185 {
186 m_log.ErrorFormat(
187 "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept",
188 imSessionID);
189 }
190
191 return;
192 }
193 else
194 {
195 m_log.WarnFormat(
196 "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
197 toAgentID, client.AgentId, client.Name, message);
198 }
199 } 189 }
200 else 190 else
201 { 191 {
202 m_log.WarnFormat( 192 // Send via grid
203 "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", 193 //
204 toAgentID, client.AgentId, client.Name, message); 194 // TODO: Implement sending via grid
205 } 195 }
206 } 196 }
207 else if (dialog == (byte) InstantMessageDialog.InventoryDeclined) 197 else if (dialog == (byte) InstantMessageDialog.InventoryDeclined)
208 { 198 {
209 if (((Scene)(client.Scene)).Entities.ContainsKey(toAgentID) && ((Scene)(client.Scene)).Entities[toAgentID] is ScenePresence) 199 UUID itemID = imSessionID; // The item, back from it's trip
200
201 // Here, the recipient is local and we can assume that the
202 // inventory is loaded. Courtesy of the above bulk update,
203 // It will have been pushed to the client, too
204 //
205
206 CachedUserInfo userInfo =
207 scene.CommsManager.UserProfileCacheService.
208 GetUserDetails(client.AgentId);
209
210 if (userInfo != null)
210 { 211 {
211 ScenePresence user = (ScenePresence) ((Scene)(client.Scene)).Entities[toAgentID]; 212 InventoryFolderImpl trashFolder =
213 userInfo.FindFolderForType((int)AssetType.TrashFolder);
212 214
213 if (!user.IsChildAgent) 215 InventoryItemBase item =
216 userInfo.RootFolder.FindItem(itemID);
217
218 if (trashFolder != null && item != null)
214 { 219 {
215 user.ControllingClient.SendInstantMessage( 220 item.Folder = trashFolder.ID;
216 fromAgentID, message, toAgentID, fromAgentName,
217 dialog, timestamp, UUID.Zero, false, binaryBucket);
218 221
219 if (m_pendingOffers.ContainsKey(imSessionID)) 222 userInfo.DeleteItem(itemID);
220 {
221 m_log.DebugFormat(
222 "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]);
223 223
224 m_pendingOffers.Remove(imSessionID); 224 scene.AddInventoryItem(client, item);
225 } 225 }
226 else 226 else
227 { 227 {
228 m_log.ErrorFormat( 228 string reason = "";
229 "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", 229 if (trashFolder == null)
230 imSessionID); 230 reason += " Trash folder not found.";
231 } 231 if (item == null)
232 reason += " Item not found.";
233 client.SendAgentAlertMessage("Unable to delete "+
234 "received item"+reason, false);
232 } 235 }
233 } 236 }
237
238 ScenePresence user = scene.GetScenePresence(toAgentID);
239
240 if (user != null) // Local
241 {
242 user.ControllingClient.SendInstantMessage(
243 fromAgentID, message, toAgentID, fromAgentName,
244 dialog, timestamp, UUID.Zero, false, binaryBucket);
245 }
246 else
247 {
248 // Send via grid
249 //
250 // TODO: Implement sending via grid
251 }
234 } 252 }
235 } 253 }
236 254
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 298b9ff..7e32086 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -407,6 +407,14 @@ namespace OpenSim.Region.Environment.Scenes
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);
411
412 if (itemCopy != null)
413 recipientClient.SendBulkUpdateInventory(itemCopy);
414 }
415
416 public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId)
417 {
410 // Retrieve the item from the sender 418 // Retrieve the item from the sender
411 CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId); 419 CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId);
412 420
@@ -415,7 +423,7 @@ namespace OpenSim.Region.Environment.Scenes
415 m_log.ErrorFormat( 423 m_log.ErrorFormat(
416 "[AGENT INVENTORY]: Failed to find sending user {0} for item {1}", senderId, itemId); 424 "[AGENT INVENTORY]: Failed to find sending user {0} for item {1}", senderId, itemId);
417 425
418 return; 426 return null;
419 } 427 }
420 428
421 if (senderUserInfo.RootFolder != null) 429 if (senderUserInfo.RootFolder != null)
@@ -427,18 +435,21 @@ namespace OpenSim.Region.Environment.Scenes
427 if (!ExternalChecks.ExternalChecksBypassPermissions()) 435 if (!ExternalChecks.ExternalChecksBypassPermissions())
428 { 436 {
429 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 437 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
430 return; 438 return null;
431 } 439 }
432 440
433 // TODO get recipient's root folder 441 // TODO get recipient's root folder
434 CachedUserInfo recipientUserInfo 442 CachedUserInfo recipientUserInfo
435 = CommsManager.UserProfileCacheService.GetUserDetails(recipientClient.AgentId); 443 = CommsManager.UserProfileCacheService.GetUserDetails(recipient);
436 444
437 if (recipientUserInfo != null) 445 if (recipientUserInfo != null)
438 { 446 {
447 if (!recipientUserInfo.HasReceivedInventory)
448 CommsManager.UserProfileCacheService.RequestInventoryForUser(recipient);
449
439 // Insert a copy of the item into the recipient 450 // Insert a copy of the item into the recipient
440 InventoryItemBase itemCopy = new InventoryItemBase(); 451 InventoryItemBase itemCopy = new InventoryItemBase();
441 itemCopy.Owner = recipientClient.AgentId; 452 itemCopy.Owner = recipient;
442 itemCopy.Creator = item.Creator; 453 itemCopy.Creator = item.Creator;
443 itemCopy.ID = UUID.Random(); 454 itemCopy.ID = UUID.Random();
444 itemCopy.AssetID = item.AssetID; 455 itemCopy.AssetID = item.AssetID;
@@ -493,14 +504,13 @@ namespace OpenSim.Region.Environment.Scenes
493 senderUserInfo.DeleteItem(itemId); 504 senderUserInfo.DeleteItem(itemId);
494 } 505 }
495 506
496 // Let the recipient client know about this new item 507 return itemCopy;
497 recipientClient.SendBulkUpdateInventory(itemCopy);
498 } 508 }
499 else 509 else
500 { 510 {
501 m_log.ErrorFormat( 511 m_log.ErrorFormat(
502 "[AGENT INVENTORY]: Could not find userinfo for recipient user {0}, {1} of item {2}, {3} from {4}", 512 "[AGENT INVENTORY]: Could not find userinfo for recipient user {0} of item {1}, {2} from {3}",
503 recipientClient.Name, recipientClient.AgentId, item.Name, 513 recipient, item.Name,
504 item.ID, senderId); 514 item.ID, senderId);
505 } 515 }
506 } 516 }
@@ -509,14 +519,15 @@ namespace OpenSim.Region.Environment.Scenes
509 m_log.ErrorFormat( 519 m_log.ErrorFormat(
510 "[AGENT INVENTORY]: Failed to find item {0} to give to {1}", itemId, senderId); 520 "[AGENT INVENTORY]: Failed to find item {0} to give to {1}", itemId, senderId);
511 521
512 return; 522 return null;
513 } 523 }
514 } 524 }
515 else 525 else
516 { 526 {
517 m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder"); 527 m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder");
518 return; 528 return null;
519 } 529 }
530 return null;
520 } 531 }
521 532
522 public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, 533 public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID,