diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | 216 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.Inventory.cs | 31 |
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 | ||
28 | using System; | ||
29 | using System.Collections; | ||
28 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
29 | using System.Reflection; | 31 | using System.Reflection; |
30 | using OpenMetaverse; | 32 | using OpenMetaverse; |
@@ -33,6 +35,7 @@ using Nini.Config; | |||
33 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
38 | using OpenSim.Framework.Communications.Cache; | ||
36 | 39 | ||
37 | namespace OpenSim.Region.Environment.Modules.Avatar.Inventory.Transfer | 40 | namespace 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, |