diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs | 50 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs | 31 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 1219 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 158 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 115 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 34 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 24 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 19 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 137 |
10 files changed, 689 insertions, 1104 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs index 4224198..5d65f98 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs | |||
@@ -201,31 +201,31 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid | |||
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | public InventoryItemBase Get(InventoryItemBase item, UUID rootFolder, CachedUserInfo userInfo) | 204 | //public InventoryItemBase Get(InventoryItemBase item, UUID rootFolder, CachedUserInfo userInfo) |
205 | { | 205 | //{ |
206 | InventoryClient invCli = null; | 206 | // InventoryClient invCli = null; |
207 | string inventoryURL = UserInventoryURL(item.Owner); | 207 | // string inventoryURL = UserInventoryURL(item.Owner); |
208 | if (!m_inventoryServers.TryGetValue(inventoryURL, out invCli)) | 208 | // if (!m_inventoryServers.TryGetValue(inventoryURL, out invCli)) |
209 | { | 209 | // { |
210 | m_log.Debug("[HGScene]: Starting new InventorytClient for " + inventoryURL); | 210 | // m_log.Debug("[HGScene]: Starting new InventorytClient for " + inventoryURL); |
211 | invCli = new InventoryClient(inventoryURL); | 211 | // invCli = new InventoryClient(inventoryURL); |
212 | m_inventoryServers.Add(inventoryURL, invCli); | 212 | // m_inventoryServers.Add(inventoryURL, invCli); |
213 | } | 213 | // } |
214 | 214 | ||
215 | item = invCli.GetInventoryItem(item); | 215 | // item = invCli.GetInventoryItem(item); |
216 | if (item != null) | 216 | // if (item != null) |
217 | { | 217 | // { |
218 | // Change the folder, stick it in root folder, all items flattened out here in this region cache | 218 | // // Change the folder, stick it in root folder, all items flattened out here in this region cache |
219 | item.Folder = rootFolder; | 219 | // item.Folder = rootFolder; |
220 | //userInfo.AddItem(item); don't use this, it calls back to the inventory server | 220 | // //userInfo.AddItem(item); don't use this, it calls back to the inventory server |
221 | lock (userInfo.RootFolder.Items) | 221 | // lock (userInfo.RootFolder.Items) |
222 | { | 222 | // { |
223 | userInfo.RootFolder.Items[item.ID] = item; | 223 | // userInfo.RootFolder.Items[item.ID] = item; |
224 | } | 224 | // } |
225 | 225 | ||
226 | } | 226 | // } |
227 | return item; | 227 | // return item; |
228 | } | 228 | //} |
229 | 229 | ||
230 | public void Post(UUID assetID, UUID ownerID) | 230 | public void Post(UUID assetID, UUID ownerID) |
231 | { | 231 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs index cb6794e..dd6928f 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs | |||
@@ -117,25 +117,20 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid | |||
117 | 117 | ||
118 | if (fromTaskID.Equals(UUID.Zero)) | 118 | if (fromTaskID.Equals(UUID.Zero)) |
119 | { | 119 | { |
120 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 120 | InventoryItemBase item = new InventoryItemBase(itemID); |
121 | if (userInfo != null) | 121 | item.Owner = remoteClient.AgentId; |
122 | item = InventoryService.GetItem(item); | ||
123 | //if (item == null) | ||
124 | //{ // Fetch the item | ||
125 | // item = new InventoryItemBase(); | ||
126 | // item.Owner = remoteClient.AgentId; | ||
127 | // item.ID = itemID; | ||
128 | // item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo); | ||
129 | //} | ||
130 | if (item != null) | ||
122 | { | 131 | { |
123 | if (userInfo.RootFolder != null) | 132 | m_assMapper.Get(item.AssetID, remoteClient.AgentId); |
124 | { | 133 | |
125 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | ||
126 | if (item == null) | ||
127 | { // Fetch the item | ||
128 | item = new InventoryItemBase(); | ||
129 | item.Owner = remoteClient.AgentId; | ||
130 | item.ID = itemID; | ||
131 | item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo); | ||
132 | } | ||
133 | if (item != null) | ||
134 | { | ||
135 | m_assMapper.Get(item.AssetID, remoteClient.AgentId); | ||
136 | |||
137 | } | ||
138 | } | ||
139 | } | 134 | } |
140 | } | 135 | } |
141 | 136 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index facd301..46777e1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -80,17 +80,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
80 | 80 | ||
81 | public bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item) | 81 | public bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item) |
82 | { | 82 | { |
83 | CachedUserInfo userInfo | 83 | if (InventoryService.AddItem(item)) |
84 | = CommsManager.UserProfileCacheService.GetUserDetails(AgentId); | ||
85 | if (userInfo != null) | ||
86 | { | ||
87 | userInfo.AddItem(item); | ||
88 | return true; | 84 | return true; |
89 | } | ||
90 | else | 85 | else |
91 | { | 86 | { |
92 | m_log.ErrorFormat( | 87 | m_log.WarnFormat( |
93 | "[AGENT INVENTORY]: Agent was not found for add of item {1} {2}", item.Name, item.ID); | 88 | "[AGENT INVENTORY]: Unable to add item {1} to agent {2} inventory", item.Name, AgentId); |
94 | 89 | ||
95 | return false; | 90 | return false; |
96 | } | 91 | } |
@@ -98,13 +93,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
98 | 93 | ||
99 | public void AddInventoryItem(UUID AgentID, InventoryItemBase item) | 94 | public void AddInventoryItem(UUID AgentID, InventoryItemBase item) |
100 | { | 95 | { |
101 | CachedUserInfo userInfo | ||
102 | = CommsManager.UserProfileCacheService.GetUserDetails(AgentID); | ||
103 | 96 | ||
104 | if (userInfo != null) | 97 | if (InventoryService.AddItem(item)) |
105 | { | 98 | { |
106 | userInfo.AddItem(item); | ||
107 | |||
108 | int userlevel = 0; | 99 | int userlevel = 0; |
109 | if (Permissions.IsGod(AgentID)) | 100 | if (Permissions.IsGod(AgentID)) |
110 | { | 101 | { |
@@ -120,8 +111,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
120 | } | 111 | } |
121 | else | 112 | else |
122 | { | 113 | { |
123 | m_log.ErrorFormat( | 114 | m_log.WarnFormat( |
124 | "[AGENT INVENTORY]: Agent {1} was not found for add of item {2} {3}", | 115 | "[AGENT INVENTORY]: Agent {1} could not add item {2} {3}", |
125 | AgentID, item.Name, item.ID); | 116 | AgentID, item.Name, item.ID); |
126 | 117 | ||
127 | return; | 118 | return; |
@@ -136,20 +127,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
136 | /// in which the item is to be placed.</param> | 127 | /// in which the item is to be placed.</param> |
137 | public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item) | 128 | public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item) |
138 | { | 129 | { |
139 | CachedUserInfo userInfo | 130 | AddInventoryItem(remoteClient.AgentId, item); |
140 | = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 131 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
141 | |||
142 | if (userInfo != null) | ||
143 | { | ||
144 | AddInventoryItem(remoteClient.AgentId, item); | ||
145 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
146 | } | ||
147 | else | ||
148 | { | ||
149 | m_log.ErrorFormat( | ||
150 | "[AGENT INVENTORY]: Could not resolve user {0} for adding an inventory item", | ||
151 | remoteClient.AgentId); | ||
152 | } | ||
153 | } | 132 | } |
154 | 133 | ||
155 | /// <summary> | 134 | /// <summary> |
@@ -161,47 +140,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
161 | /// <returns></returns> | 140 | /// <returns></returns> |
162 | public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) | 141 | public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) |
163 | { | 142 | { |
164 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 143 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
165 | if (userInfo != null) | 144 | |
145 | if (item != null) | ||
166 | { | 146 | { |
167 | if (userInfo.RootFolder != null) | 147 | if ((InventoryType)item.InvType == InventoryType.Notecard) |
168 | { | 148 | { |
169 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | 149 | if (!Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId)) |
170 | |||
171 | if (item != null) | ||
172 | { | 150 | { |
173 | if ((InventoryType)item.InvType == InventoryType.Notecard) | 151 | remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false); |
174 | { | 152 | return UUID.Zero; |
175 | if (!Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId)) | 153 | } |
176 | { | ||
177 | remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false); | ||
178 | return UUID.Zero; | ||
179 | } | ||
180 | 154 | ||
181 | remoteClient.SendAgentAlertMessage("Notecard saved", false); | 155 | remoteClient.SendAgentAlertMessage("Notecard saved", false); |
182 | } | 156 | } |
183 | else if ((InventoryType)item.InvType == InventoryType.LSL) | 157 | else if ((InventoryType)item.InvType == InventoryType.LSL) |
184 | { | 158 | { |
185 | if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) | 159 | if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) |
186 | { | 160 | { |
187 | remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); | 161 | remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); |
188 | return UUID.Zero; | 162 | return UUID.Zero; |
189 | } | 163 | } |
190 | 164 | ||
191 | remoteClient.SendAgentAlertMessage("Script saved", false); | 165 | remoteClient.SendAgentAlertMessage("Script saved", false); |
192 | } | 166 | } |
193 | 167 | ||
194 | AssetBase asset = | 168 | AssetBase asset = |
195 | CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data); | 169 | CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data); |
196 | item.AssetID = asset.FullID; | 170 | item.AssetID = asset.FullID; |
197 | AssetService.Store(asset); | 171 | AssetService.Store(asset); |
198 | 172 | ||
199 | userInfo.UpdateItem(item); | 173 | InventoryService.UpdateItem(item); |
200 | 174 | ||
201 | // remoteClient.SendInventoryItemCreateUpdate(item); | 175 | // remoteClient.SendInventoryItemCreateUpdate(item); |
202 | return (asset.FullID); | 176 | return (asset.FullID); |
203 | } | ||
204 | } | ||
205 | } | 177 | } |
206 | else | 178 | else |
207 | { | 179 | { |
@@ -343,63 +315,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
343 | public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, | 315 | public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, |
344 | UUID itemID, InventoryItemBase itemUpd) | 316 | UUID itemID, InventoryItemBase itemUpd) |
345 | { | 317 | { |
346 | CachedUserInfo userInfo | 318 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
347 | = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
348 | 319 | ||
349 | if (userInfo != null && userInfo.RootFolder != null) | 320 | if (item != null) |
350 | { | 321 | { |
351 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | 322 | if (UUID.Zero == transactionID) |
352 | |||
353 | if (item != null) | ||
354 | { | 323 | { |
355 | if (UUID.Zero == transactionID) | 324 | item.Name = itemUpd.Name; |
356 | { | 325 | item.Description = itemUpd.Description; |
357 | item.Name = itemUpd.Name; | 326 | item.NextPermissions = itemUpd.NextPermissions; |
358 | item.Description = itemUpd.Description; | 327 | item.CurrentPermissions |= 8; // Slam! |
359 | item.NextPermissions = itemUpd.NextPermissions; | 328 | item.EveryOnePermissions = itemUpd.EveryOnePermissions; |
360 | item.CurrentPermissions |= 8; // Slam! | 329 | item.GroupPermissions = itemUpd.GroupPermissions; |
361 | item.EveryOnePermissions = itemUpd.EveryOnePermissions; | ||
362 | item.GroupPermissions = itemUpd.GroupPermissions; | ||
363 | |||
364 | item.GroupID = itemUpd.GroupID; | ||
365 | item.GroupOwned = itemUpd.GroupOwned; | ||
366 | item.CreationDate = itemUpd.CreationDate; | ||
367 | // The client sends zero if its newly created? | ||
368 | |||
369 | if (itemUpd.CreationDate == 0) | ||
370 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
371 | else | ||
372 | item.CreationDate = itemUpd.CreationDate; | ||
373 | 330 | ||
374 | // TODO: Check if folder changed and move item | 331 | item.GroupID = itemUpd.GroupID; |
375 | //item.NextPermissions = itemUpd.Folder; | 332 | item.GroupOwned = itemUpd.GroupOwned; |
376 | item.InvType = itemUpd.InvType; | 333 | item.CreationDate = itemUpd.CreationDate; |
377 | item.SalePrice = itemUpd.SalePrice; | 334 | // The client sends zero if its newly created? |
378 | item.SaleType = itemUpd.SaleType; | ||
379 | item.Flags = itemUpd.Flags; | ||
380 | 335 | ||
381 | userInfo.UpdateItem(item); | 336 | if (itemUpd.CreationDate == 0) |
382 | } | 337 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
383 | else | 338 | else |
384 | { | 339 | item.CreationDate = itemUpd.CreationDate; |
385 | IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); | 340 | |
386 | if (agentTransactions != null) | 341 | // TODO: Check if folder changed and move item |
387 | { | 342 | //item.NextPermissions = itemUpd.Folder; |
388 | agentTransactions.HandleItemUpdateFromTransaction( | 343 | item.InvType = itemUpd.InvType; |
389 | remoteClient, transactionID, item); | 344 | item.SalePrice = itemUpd.SalePrice; |
390 | } | 345 | item.SaleType = itemUpd.SaleType; |
391 | } | 346 | item.Flags = itemUpd.Flags; |
347 | |||
348 | InventoryService.UpdateItem(item); | ||
392 | } | 349 | } |
393 | else | 350 | else |
394 | { | 351 | { |
395 | m_log.Error( | 352 | IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); |
396 | "[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update."); | 353 | if (agentTransactions != null) |
354 | { | ||
355 | agentTransactions.HandleItemUpdateFromTransaction( | ||
356 | remoteClient, transactionID, item); | ||
357 | } | ||
397 | } | 358 | } |
398 | } | 359 | } |
399 | else | 360 | else |
400 | { | 361 | { |
401 | m_log.Error( | 362 | m_log.Error( |
402 | "[AGENT INVENTORY]: Agent ID " + remoteClient.AgentId + " not found for an inventory item update."); | 363 | "[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update."); |
403 | } | 364 | } |
404 | } | 365 | } |
405 | 366 | ||
@@ -445,123 +406,85 @@ namespace OpenSim.Region.Framework.Scenes | |||
445 | public virtual InventoryItemBase GiveInventoryItem( | 406 | public virtual InventoryItemBase GiveInventoryItem( |
446 | UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId) | 407 | UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId) |
447 | { | 408 | { |
448 | // Retrieve the item from the sender | ||
449 | CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId); | ||
450 | |||
451 | Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem"); | 409 | Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem"); |
452 | 410 | ||
453 | if (senderUserInfo == null) | 411 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemId)); |
454 | { | ||
455 | m_log.ErrorFormat( | ||
456 | "[AGENT INVENTORY]: Failed to find sending user {0} for item {1}", senderId, itemId); | ||
457 | |||
458 | return null; | ||
459 | } | ||
460 | 412 | ||
461 | if (senderUserInfo.RootFolder != null) | 413 | if ((item != null) && (item.Owner == senderId)) |
462 | { | 414 | { |
463 | InventoryItemBase item = senderUserInfo.RootFolder.FindItem(itemId); | 415 | if (!Permissions.BypassPermissions()) |
464 | |||
465 | if (item != null) | ||
466 | { | 416 | { |
467 | if (!Permissions.BypassPermissions()) | 417 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) |
468 | { | 418 | return null; |
469 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | 419 | } |
470 | return null; | ||
471 | } | ||
472 | 420 | ||
473 | CachedUserInfo recipientUserInfo | 421 | // Insert a copy of the item into the recipient |
474 | = CommsManager.UserProfileCacheService.GetUserDetails(recipient); | 422 | InventoryItemBase itemCopy = new InventoryItemBase(); |
423 | itemCopy.Owner = recipient; | ||
424 | itemCopy.CreatorId = item.CreatorId; | ||
425 | itemCopy.ID = UUID.Random(); | ||
426 | itemCopy.AssetID = item.AssetID; | ||
427 | itemCopy.Description = item.Description; | ||
428 | itemCopy.Name = item.Name; | ||
429 | itemCopy.AssetType = item.AssetType; | ||
430 | itemCopy.InvType = item.InvType; | ||
431 | itemCopy.Folder = recipientFolderId; | ||
475 | 432 | ||
476 | if (recipientUserInfo != null) | 433 | if (Permissions.PropagatePermissions()) |
434 | { | ||
435 | if (item.InvType == (int)InventoryType.Object) | ||
477 | { | 436 | { |
478 | if (!recipientUserInfo.HasReceivedInventory) | 437 | itemCopy.BasePermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); |
479 | recipientUserInfo.FetchInventory(); | 438 | itemCopy.BasePermissions |= (item.CurrentPermissions & 7) << 13; |
480 | |||
481 | // Insert a copy of the item into the recipient | ||
482 | InventoryItemBase itemCopy = new InventoryItemBase(); | ||
483 | itemCopy.Owner = recipient; | ||
484 | itemCopy.CreatorId = item.CreatorId; | ||
485 | itemCopy.ID = UUID.Random(); | ||
486 | itemCopy.AssetID = item.AssetID; | ||
487 | itemCopy.Description = item.Description; | ||
488 | itemCopy.Name = item.Name; | ||
489 | itemCopy.AssetType = item.AssetType; | ||
490 | itemCopy.InvType = item.InvType; | ||
491 | itemCopy.Folder = recipientFolderId; | ||
492 | |||
493 | if (Permissions.PropagatePermissions()) | ||
494 | { | ||
495 | if (item.InvType == (int)InventoryType.Object) | ||
496 | { | ||
497 | itemCopy.BasePermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); | ||
498 | itemCopy.BasePermissions |= (item.CurrentPermissions & 7) << 13; | ||
499 | } | ||
500 | else | ||
501 | { | ||
502 | itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions; | ||
503 | } | ||
504 | |||
505 | itemCopy.CurrentPermissions = itemCopy.BasePermissions; | ||
506 | if ((item.CurrentPermissions & 8) != 0) // Propagate slam bit | ||
507 | { | ||
508 | itemCopy.BasePermissions &= item.NextPermissions; | ||
509 | itemCopy.CurrentPermissions = itemCopy.BasePermissions; | ||
510 | itemCopy.CurrentPermissions |= 8; | ||
511 | } | ||
512 | |||
513 | itemCopy.NextPermissions = item.NextPermissions; | ||
514 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; | ||
515 | itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; | ||
516 | } | ||
517 | else | ||
518 | { | ||
519 | itemCopy.CurrentPermissions = item.CurrentPermissions; | ||
520 | itemCopy.NextPermissions = item.NextPermissions; | ||
521 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; | ||
522 | itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; | ||
523 | itemCopy.BasePermissions = item.BasePermissions; | ||
524 | } | ||
525 | |||
526 | itemCopy.GroupID = UUID.Zero; | ||
527 | itemCopy.GroupOwned = false; | ||
528 | itemCopy.Flags = item.Flags; | ||
529 | itemCopy.SalePrice = item.SalePrice; | ||
530 | itemCopy.SaleType = item.SaleType; | ||
531 | |||
532 | recipientUserInfo.AddItem(itemCopy); | ||
533 | |||
534 | if (!Permissions.BypassPermissions()) | ||
535 | { | ||
536 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
537 | senderUserInfo.DeleteItem(itemId); | ||
538 | } | ||
539 | |||
540 | return itemCopy; | ||
541 | } | 439 | } |
542 | else | 440 | else |
543 | { | 441 | { |
544 | m_log.ErrorFormat( | 442 | itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions; |
545 | "[AGENT INVENTORY]: Could not find userinfo for recipient user {0} of item {1}, {2} from {3}", | 443 | } |
546 | recipient, item.Name, | 444 | |
547 | item.ID, senderId); | 445 | itemCopy.CurrentPermissions = itemCopy.BasePermissions; |
446 | if ((item.CurrentPermissions & 8) != 0) // Propagate slam bit | ||
447 | { | ||
448 | itemCopy.BasePermissions &= item.NextPermissions; | ||
449 | itemCopy.CurrentPermissions = itemCopy.BasePermissions; | ||
450 | itemCopy.CurrentPermissions |= 8; | ||
548 | } | 451 | } |
452 | |||
453 | itemCopy.NextPermissions = item.NextPermissions; | ||
454 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; | ||
455 | itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; | ||
549 | } | 456 | } |
550 | else | 457 | else |
551 | { | 458 | { |
552 | m_log.ErrorFormat( | 459 | itemCopy.CurrentPermissions = item.CurrentPermissions; |
553 | "[AGENT INVENTORY]: Failed to find item {0} to give to {1}", itemId, senderId); | 460 | itemCopy.NextPermissions = item.NextPermissions; |
461 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; | ||
462 | itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; | ||
463 | itemCopy.BasePermissions = item.BasePermissions; | ||
464 | } | ||
465 | |||
466 | itemCopy.GroupID = UUID.Zero; | ||
467 | itemCopy.GroupOwned = false; | ||
468 | itemCopy.Flags = item.Flags; | ||
469 | itemCopy.SalePrice = item.SalePrice; | ||
470 | itemCopy.SaleType = item.SaleType; | ||
554 | 471 | ||
555 | return null; | 472 | InventoryService.AddItem(itemCopy); |
473 | |||
474 | if (!Permissions.BypassPermissions()) | ||
475 | { | ||
476 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
477 | InventoryService.DeleteItem(new InventoryItemBase(itemId)); | ||
556 | } | 478 | } |
479 | |||
480 | return itemCopy; | ||
557 | } | 481 | } |
558 | else | 482 | else |
559 | { | 483 | { |
560 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder"); | 484 | m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId); |
561 | return null; | 485 | return null; |
562 | } | 486 | } |
563 | 487 | ||
564 | return null; | ||
565 | } | 488 | } |
566 | 489 | ||
567 | /// <summary> | 490 | /// <summary> |
@@ -578,31 +501,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
578 | /// <returns> | 501 | /// <returns> |
579 | /// The inventory folder copy given, null if the copy was unsuccessful | 502 | /// The inventory folder copy given, null if the copy was unsuccessful |
580 | /// </returns> | 503 | /// </returns> |
581 | public virtual InventoryFolderImpl GiveInventoryFolder( | 504 | public virtual InventoryFolderBase GiveInventoryFolder( |
582 | UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId) | 505 | UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId) |
583 | { | 506 | { |
584 | // Retrieve the folder from the sender | 507 | //// Retrieve the folder from the sender |
585 | CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId); | 508 | InventoryFolderBase folder = InventoryService.GetFolder(new InventoryFolderBase(folderId)); |
586 | |||
587 | if (null == senderUserInfo) | ||
588 | { | ||
589 | m_log.ErrorFormat( | ||
590 | "[AGENT INVENTORY]: Failed to find sending user {0} for folder {1}", senderId, folderId); | ||
591 | |||
592 | return null; | ||
593 | } | ||
594 | |||
595 | if (!senderUserInfo.HasReceivedInventory) | ||
596 | { | ||
597 | m_log.DebugFormat( | ||
598 | "[AGENT INVENTORY]: Could not give inventory folder - have not yet received inventory for {0}", | ||
599 | senderId); | ||
600 | |||
601 | return null; | ||
602 | } | ||
603 | |||
604 | InventoryFolderImpl folder = senderUserInfo.RootFolder.FindFolder(folderId); | ||
605 | |||
606 | if (null == folder) | 509 | if (null == folder) |
607 | { | 510 | { |
608 | m_log.ErrorFormat( | 511 | m_log.ErrorFormat( |
@@ -611,48 +514,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
611 | return null; | 514 | return null; |
612 | } | 515 | } |
613 | 516 | ||
614 | CachedUserInfo recipientUserInfo | ||
615 | = CommsManager.UserProfileCacheService.GetUserDetails(recipientId); | ||
616 | |||
617 | if (null == recipientUserInfo) | ||
618 | { | ||
619 | m_log.ErrorFormat( | ||
620 | "[AGENT INVENTORY]: Failed to find receiving user {0} for folder {1}", recipientId, folderId); | ||
621 | |||
622 | return null; | ||
623 | } | ||
624 | 517 | ||
625 | if (!recipientUserInfo.HasReceivedInventory) | 518 | if (recipientParentFolderId == UUID.Zero) |
626 | { | 519 | { |
627 | recipientUserInfo.FetchInventory(); | 520 | InventoryFolderBase recipientRootFolder = InventoryService.GetRootFolder(recipientId); |
628 | if (!WaitForInventory(recipientUserInfo)) | 521 | if (recipientRootFolder != null) |
522 | recipientParentFolderId = recipientRootFolder.ID; | ||
523 | else | ||
524 | { | ||
525 | m_log.WarnFormat("[AGENT INVENTORY]: Unable to find root folder for receiving agent"); | ||
629 | return null; | 526 | return null; |
527 | } | ||
630 | } | 528 | } |
631 | 529 | ||
632 | if (recipientParentFolderId == UUID.Zero) | ||
633 | recipientParentFolderId = recipientUserInfo.RootFolder.ID; | ||
634 | |||
635 | UUID newFolderId = UUID.Random(); | 530 | UUID newFolderId = UUID.Random(); |
636 | recipientUserInfo.CreateFolder(folder.Name, newFolderId, (ushort)folder.Type, recipientParentFolderId); | 531 | InventoryFolderBase newFolder = new InventoryFolderBase(newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version); |
637 | 532 | InventoryService.AddFolder(newFolder); | |
638 | // XXX: Messy - we should really get this back in the CreateFolder call | ||
639 | InventoryFolderImpl copiedFolder = recipientUserInfo.RootFolder.FindFolder(newFolderId); | ||
640 | 533 | ||
641 | // Give all the subfolders | 534 | // Give all the subfolders |
642 | List<InventoryFolderImpl> subFolders = folder.RequestListOfFolderImpls(); | 535 | InventoryCollection contents = InventoryService.GetFolderContent(senderId, folderId); |
643 | foreach (InventoryFolderImpl childFolder in subFolders) | 536 | foreach (InventoryFolderBase childFolder in contents.Folders) |
644 | { | 537 | { |
645 | GiveInventoryFolder(recipientId, senderId, childFolder.ID, copiedFolder.ID); | 538 | GiveInventoryFolder(recipientId, senderId, childFolder.ID, newFolder.ID); |
646 | } | 539 | } |
647 | 540 | ||
648 | // Give all the items | 541 | // Give all the items |
649 | List<InventoryItemBase> items = folder.RequestListOfItems(); | 542 | foreach (InventoryItemBase item in contents.Items) |
650 | foreach (InventoryItemBase item in items) | ||
651 | { | 543 | { |
652 | GiveInventoryItem(recipientId, senderId, item.ID, copiedFolder.ID); | 544 | GiveInventoryItem(recipientId, senderId, item.ID, newFolder.ID); |
653 | } | 545 | } |
654 | 546 | ||
655 | return copiedFolder; | 547 | return newFolder; |
656 | } | 548 | } |
657 | 549 | ||
658 | public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, | 550 | public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, |
@@ -666,24 +558,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
666 | 558 | ||
667 | if (item == null) | 559 | if (item == null) |
668 | { | 560 | { |
669 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(oldAgentID); | 561 | item = InventoryService.GetItem(new InventoryItemBase(oldItemID)); |
670 | if (userInfo == null) | ||
671 | { | ||
672 | m_log.Error("[AGENT INVENTORY]: Failed to find user " + oldAgentID.ToString()); | ||
673 | return; | ||
674 | } | ||
675 | |||
676 | if (userInfo.RootFolder != null) | ||
677 | { | ||
678 | item = userInfo.RootFolder.FindItem(oldItemID); | ||
679 | 562 | ||
680 | if (item == null) | 563 | if (item == null) |
681 | { | ||
682 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString()); | ||
683 | return; | ||
684 | } | ||
685 | } | ||
686 | else | ||
687 | { | 564 | { |
688 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString()); | 565 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString()); |
689 | return; | 566 | return; |
@@ -759,41 +636,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
759 | m_log.DebugFormat( | 636 | m_log.DebugFormat( |
760 | "[AGENT INVENTORY]: Moving item {0} to {1} for {2}", itemID, folderID, remoteClient.AgentId); | 637 | "[AGENT INVENTORY]: Moving item {0} to {1} for {2}", itemID, folderID, remoteClient.AgentId); |
761 | 638 | ||
762 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 639 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
763 | |||
764 | if (userInfo == null) | ||
765 | { | ||
766 | m_log.Error("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString()); | ||
767 | |||
768 | return; | ||
769 | } | ||
770 | 640 | ||
771 | if (userInfo.RootFolder != null) | 641 | if (item != null) |
772 | { | 642 | { |
773 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | 643 | if (newName != String.Empty) |
774 | |||
775 | if (item != null) | ||
776 | { | 644 | { |
777 | if (newName != String.Empty) | 645 | item.Name = newName; |
778 | { | ||
779 | item.Name = newName; | ||
780 | } | ||
781 | item.Folder = folderID; | ||
782 | |||
783 | userInfo.DeleteItem(item.ID); | ||
784 | |||
785 | AddInventoryItem(remoteClient, item); | ||
786 | } | 646 | } |
787 | else | 647 | item.Folder = folderID; |
788 | { | ||
789 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString()); | ||
790 | 648 | ||
791 | return; | 649 | // Diva comment: can't we just update? |
792 | } | 650 | InventoryService.DeleteItem(item); |
651 | |||
652 | AddInventoryItem(remoteClient, item); | ||
793 | } | 653 | } |
794 | else | 654 | else |
795 | { | 655 | { |
796 | m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString() + ", no root folder"); | 656 | m_log.Warn("[AGENT INVENTORY]: Failed to find item " + itemID.ToString()); |
797 | 657 | ||
798 | return; | 658 | return; |
799 | } | 659 | } |
@@ -830,37 +690,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
830 | IClientAPI remoteClient, string creatorID, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType, | 690 | IClientAPI remoteClient, string creatorID, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType, |
831 | uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) | 691 | uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) |
832 | { | 692 | { |
833 | CachedUserInfo userInfo | 693 | InventoryItemBase item = new InventoryItemBase(); |
834 | = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 694 | item.Owner = remoteClient.AgentId; |
835 | 695 | item.CreatorId = creatorID; | |
836 | if (userInfo != null) | 696 | item.ID = UUID.Random(); |
837 | { | 697 | item.AssetID = asset.FullID; |
838 | InventoryItemBase item = new InventoryItemBase(); | 698 | item.Description = asset.Description; |
839 | item.Owner = remoteClient.AgentId; | 699 | item.Name = name; |
840 | item.CreatorId = creatorID; | 700 | item.Flags = flags; |
841 | item.ID = UUID.Random(); | 701 | item.AssetType = asset.Type; |
842 | item.AssetID = asset.FullID; | 702 | item.InvType = invType; |
843 | item.Description = asset.Description; | 703 | item.Folder = folderID; |
844 | item.Name = name; | 704 | item.CurrentPermissions = currentMask; |
845 | item.Flags = flags; | 705 | item.NextPermissions = nextOwnerMask; |
846 | item.AssetType = asset.Type; | 706 | item.EveryOnePermissions = everyoneMask; |
847 | item.InvType = invType; | 707 | item.GroupPermissions = groupMask; |
848 | item.Folder = folderID; | 708 | item.BasePermissions = baseMask; |
849 | item.CurrentPermissions = currentMask; | 709 | item.CreationDate = creationDate; |
850 | item.NextPermissions = nextOwnerMask; | 710 | |
851 | item.EveryOnePermissions = everyoneMask; | 711 | if (InventoryService.AddItem(item)) |
852 | item.GroupPermissions = groupMask; | ||
853 | item.BasePermissions = baseMask; | ||
854 | item.CreationDate = creationDate; | ||
855 | |||
856 | userInfo.AddItem(item); | ||
857 | remoteClient.SendInventoryItemCreateUpdate(item, callbackID); | 712 | remoteClient.SendInventoryItemCreateUpdate(item, callbackID); |
858 | } | ||
859 | else | 713 | else |
860 | { | 714 | { |
715 | m_dialogModule.SendAlertToUser(remoteClient, "Failed to create item"); | ||
861 | m_log.WarnFormat( | 716 | m_log.WarnFormat( |
862 | "No user details associated with client {0} uuid {1} in CreateNewInventoryItem!", | 717 | "Failed to add item for {0} in CreateNewInventoryItem!", |
863 | remoteClient.Name, remoteClient.AgentId); | 718 | remoteClient.Name); |
864 | } | 719 | } |
865 | } | 720 | } |
866 | 721 | ||
@@ -941,19 +796,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
941 | /// <param name="itemID"></param> | 796 | /// <param name="itemID"></param> |
942 | private void RemoveInventoryItem(IClientAPI remoteClient, UUID itemID) | 797 | private void RemoveInventoryItem(IClientAPI remoteClient, UUID itemID) |
943 | { | 798 | { |
944 | CachedUserInfo userInfo | 799 | InventoryService.DeleteItem(new InventoryItemBase(itemID)); |
945 | = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
946 | |||
947 | if (userInfo == null) | ||
948 | { | ||
949 | m_log.WarnFormat( | ||
950 | "[AGENT INVENTORY]: Failed to find user {0} {1} to delete inventory item {2}", | ||
951 | remoteClient.Name, remoteClient.AgentId, itemID); | ||
952 | |||
953 | return; | ||
954 | } | ||
955 | |||
956 | userInfo.DeleteItem(itemID); | ||
957 | } | 800 | } |
958 | 801 | ||
959 | /// <summary> | 802 | /// <summary> |
@@ -964,28 +807,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
964 | /// <param name="folderID"></param> | 807 | /// <param name="folderID"></param> |
965 | private void RemoveInventoryFolder(IClientAPI remoteClient, UUID folderID) | 808 | private void RemoveInventoryFolder(IClientAPI remoteClient, UUID folderID) |
966 | { | 809 | { |
967 | CachedUserInfo userInfo | 810 | // Unclear is this handler is ever called by the Linden client, but it might |
968 | = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
969 | 811 | ||
970 | if (userInfo == null) | 812 | InventoryFolderBase folder = new InventoryFolderBase(folderID); |
813 | folder.Owner = remoteClient.AgentId; | ||
814 | InventoryFolderBase trash = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.TrashFolder); | ||
815 | if (trash != null) | ||
971 | { | 816 | { |
972 | m_log.Warn("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString()); | 817 | folder.ParentID = trash.ID; |
973 | return; | 818 | InventoryService.MoveFolder(folder); |
974 | } | ||
975 | |||
976 | if (userInfo.RootFolder != null) | ||
977 | { | ||
978 | InventoryItemBase folder = userInfo.RootFolder.FindItem(folderID); | ||
979 | |||
980 | if (folder != null) | ||
981 | { | ||
982 | m_log.WarnFormat( | ||
983 | "[AGENT INVENTORY]: Remove folder not implemented in request by {0} {1} for {2}", | ||
984 | remoteClient.Name, remoteClient.AgentId, folderID); | ||
985 | |||
986 | // doesn't work just yet, commented out. will fix in next patch. | ||
987 | // userInfo.DeleteItem(folder); | ||
988 | } | ||
989 | } | 819 | } |
990 | } | 820 | } |
991 | 821 | ||
@@ -1202,20 +1032,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1202 | return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId); | 1032 | return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId); |
1203 | } | 1033 | } |
1204 | else | 1034 | else |
1205 | { | 1035 | { |
1206 | CachedUserInfo profile = CommsManager.UserProfileCacheService.GetUserDetails(avatarId); | ||
1207 | if (profile == null || profile.RootFolder == null) | ||
1208 | { | ||
1209 | m_log.ErrorFormat( | ||
1210 | "[PRIM INVENTORY]: " + | ||
1211 | "Avatar {0} cannot be found to add item", | ||
1212 | avatarId); | ||
1213 | return null; | ||
1214 | } | ||
1215 | |||
1216 | if (!profile.HasReceivedInventory) | ||
1217 | profile.FetchInventory(); | ||
1218 | |||
1219 | InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId); | 1036 | InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId); |
1220 | 1037 | ||
1221 | if (agentItem == null) | 1038 | if (agentItem == null) |
@@ -1332,19 +1149,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1332 | 1149 | ||
1333 | public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) | 1150 | public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) |
1334 | { | 1151 | { |
1335 | CachedUserInfo profile = CommsManager.UserProfileCacheService.GetUserDetails(destID); | 1152 | InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID); |
1336 | if (profile == null || profile.RootFolder == null) | ||
1337 | { | ||
1338 | m_log.ErrorFormat( | ||
1339 | "[PRIM INVENTORY]: " + | ||
1340 | "Avatar {0} cannot be found to add items", | ||
1341 | destID); | ||
1342 | return UUID.Zero; | ||
1343 | } | ||
1344 | 1153 | ||
1345 | UUID newFolderID = UUID.Random(); | 1154 | UUID newFolderID = UUID.Random(); |
1346 | 1155 | ||
1347 | profile.CreateFolder(category, newFolderID, 0xffff, profile.RootFolder.ID); | 1156 | InventoryFolderBase newFolder = new InventoryFolderBase(newFolderID, category, destID, 0xff, rootFolder.ID, rootFolder.Version); |
1157 | InventoryService.AddFolder(newFolder); | ||
1348 | 1158 | ||
1349 | foreach (UUID itemID in items) | 1159 | foreach (UUID itemID in items) |
1350 | { | 1160 | { |
@@ -1358,19 +1168,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1358 | } | 1168 | } |
1359 | } | 1169 | } |
1360 | 1170 | ||
1361 | ScenePresence avatar; | 1171 | ScenePresence avatar = null; |
1362 | |||
1363 | if (TryGetAvatar(destID, out avatar)) | 1172 | if (TryGetAvatar(destID, out avatar)) |
1364 | { | 1173 | { |
1365 | profile.SendInventoryDecendents(avatar.ControllingClient, | 1174 | //profile.SendInventoryDecendents(avatar.ControllingClient, |
1366 | profile.RootFolder.ID, true, false); | 1175 | // profile.RootFolder.ID, true, false); |
1367 | profile.SendInventoryDecendents(avatar.ControllingClient, | 1176 | //profile.SendInventoryDecendents(avatar.ControllingClient, |
1368 | newFolderID, false, true); | 1177 | // newFolderID, false, true); |
1178 | |||
1179 | SendInventoryUpdate(avatar.ControllingClient, rootFolder, true, false); | ||
1180 | SendInventoryUpdate(avatar.ControllingClient, newFolder, false, true); | ||
1369 | } | 1181 | } |
1370 | 1182 | ||
1371 | return newFolderID; | 1183 | return newFolderID; |
1372 | } | 1184 | } |
1373 | 1185 | ||
1186 | private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) | ||
1187 | { | ||
1188 | InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); | ||
1189 | client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, fetchFolders, fetchItems); | ||
1190 | } | ||
1191 | |||
1374 | /// <summary> | 1192 | /// <summary> |
1375 | /// Update an item in a prim (task) inventory. | 1193 | /// Update an item in a prim (task) inventory. |
1376 | /// This method does not handle scripts, <see>RezScript(IClientAPI, UUID, unit)</see> | 1194 | /// This method does not handle scripts, <see>RezScript(IClientAPI, UUID, unit)</see> |
@@ -1406,39 +1224,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1406 | UUID copyID = UUID.Random(); | 1224 | UUID copyID = UUID.Random(); |
1407 | if (itemID != UUID.Zero) | 1225 | if (itemID != UUID.Zero) |
1408 | { | 1226 | { |
1409 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 1227 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
1410 | 1228 | ||
1411 | if (userInfo != null && userInfo.RootFolder != null) | 1229 | // Try library |
1230 | if (null == item) | ||
1412 | { | 1231 | { |
1413 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | 1232 | item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID); |
1414 | 1233 | } | |
1415 | // Try library | ||
1416 | // XXX clumsy, possibly should be one call | ||
1417 | if (null == item) | ||
1418 | { | ||
1419 | item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID); | ||
1420 | } | ||
1421 | 1234 | ||
1422 | if (item != null) | 1235 | if (item != null) |
1423 | { | 1236 | { |
1424 | part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID); | 1237 | part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID); |
1425 | m_log.InfoFormat( | 1238 | m_log.InfoFormat( |
1426 | "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", | 1239 | "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", |
1427 | item.Name, primLocalID, remoteClient.Name); | 1240 | item.Name, primLocalID, remoteClient.Name); |
1428 | part.GetProperties(remoteClient); | 1241 | part.GetProperties(remoteClient); |
1429 | if (!Permissions.BypassPermissions()) | 1242 | if (!Permissions.BypassPermissions()) |
1430 | { | ||
1431 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1432 | RemoveInventoryItem(remoteClient, itemID); | ||
1433 | } | ||
1434 | } | ||
1435 | else | ||
1436 | { | 1243 | { |
1437 | m_log.ErrorFormat( | 1244 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) |
1438 | "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!", | 1245 | RemoveInventoryItem(remoteClient, itemID); |
1439 | itemID, remoteClient.Name); | ||
1440 | } | 1246 | } |
1441 | } | 1247 | } |
1248 | else | ||
1249 | { | ||
1250 | m_log.ErrorFormat( | ||
1251 | "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!", | ||
1252 | itemID, remoteClient.Name); | ||
1253 | } | ||
1442 | } | 1254 | } |
1443 | } | 1255 | } |
1444 | else // Updating existing item with new perms etc | 1256 | else // Updating existing item with new perms etc |
@@ -1475,53 +1287,48 @@ namespace OpenSim.Region.Framework.Scenes | |||
1475 | 1287 | ||
1476 | if (itemID != UUID.Zero) // transferred from an avatar inventory to the prim's inventory | 1288 | if (itemID != UUID.Zero) // transferred from an avatar inventory to the prim's inventory |
1477 | { | 1289 | { |
1478 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 1290 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
1479 | 1291 | ||
1480 | if (userInfo != null && userInfo.RootFolder != null) | 1292 | // Try library |
1293 | // XXX clumsy, possibly should be one call | ||
1294 | if (null == item) | ||
1481 | { | 1295 | { |
1482 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | 1296 | item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID); |
1483 | 1297 | } | |
1484 | // Try library | ||
1485 | // XXX clumsy, possibly should be one call | ||
1486 | if (null == item) | ||
1487 | { | ||
1488 | item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID); | ||
1489 | } | ||
1490 | 1298 | ||
1491 | if (item != null) | 1299 | if (item != null) |
1300 | { | ||
1301 | SceneObjectPart part = GetSceneObjectPart(localID); | ||
1302 | if (part != null) | ||
1492 | { | 1303 | { |
1493 | SceneObjectPart part = GetSceneObjectPart(localID); | 1304 | if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) |
1494 | if (part != null) | 1305 | return; |
1495 | { | ||
1496 | if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) | ||
1497 | return; | ||
1498 | 1306 | ||
1499 | part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID); | 1307 | part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID); |
1500 | // TODO: switch to posting on_rez here when scripts | 1308 | // TODO: switch to posting on_rez here when scripts |
1501 | // have state in inventory | 1309 | // have state in inventory |
1502 | part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0); | 1310 | part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0); |
1503 | 1311 | ||
1504 | // m_log.InfoFormat("[PRIMINVENTORY]: " + | 1312 | // m_log.InfoFormat("[PRIMINVENTORY]: " + |
1505 | // "Rezzed script {0} into prim local ID {1} for user {2}", | 1313 | // "Rezzed script {0} into prim local ID {1} for user {2}", |
1506 | // item.inventoryName, localID, remoteClient.Name); | 1314 | // item.inventoryName, localID, remoteClient.Name); |
1507 | part.GetProperties(remoteClient); | 1315 | part.GetProperties(remoteClient); |
1508 | } | ||
1509 | else | ||
1510 | { | ||
1511 | m_log.ErrorFormat( | ||
1512 | "[PRIM INVENTORY]: " + | ||
1513 | "Could not rez script {0} into prim local ID {1} for user {2}" | ||
1514 | + " because the prim could not be found in the region!", | ||
1515 | item.Name, localID, remoteClient.Name); | ||
1516 | } | ||
1517 | } | 1316 | } |
1518 | else | 1317 | else |
1519 | { | 1318 | { |
1520 | m_log.ErrorFormat( | 1319 | m_log.ErrorFormat( |
1521 | "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!", | 1320 | "[PRIM INVENTORY]: " + |
1522 | itemID, remoteClient.Name); | 1321 | "Could not rez script {0} into prim local ID {1} for user {2}" |
1322 | + " because the prim could not be found in the region!", | ||
1323 | item.Name, localID, remoteClient.Name); | ||
1523 | } | 1324 | } |
1524 | } | 1325 | } |
1326 | else | ||
1327 | { | ||
1328 | m_log.ErrorFormat( | ||
1329 | "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!", | ||
1330 | itemID, remoteClient.Name); | ||
1331 | } | ||
1525 | } | 1332 | } |
1526 | else // script has been rezzed directly into a prim's inventory | 1333 | else // script has been rezzed directly into a prim's inventory |
1527 | { | 1334 | { |
@@ -1811,26 +1618,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1811 | } | 1618 | } |
1812 | } | 1619 | } |
1813 | 1620 | ||
1814 | private bool WaitForInventory(CachedUserInfo info) | ||
1815 | { | ||
1816 | // 200 Seconds wait. This is called in the context of the | ||
1817 | // background delete thread, so we can afford to waste time | ||
1818 | // here. | ||
1819 | // | ||
1820 | int count = 200; | ||
1821 | |||
1822 | while (count > 0) | ||
1823 | { | ||
1824 | System.Threading.Thread.Sleep(100); | ||
1825 | count--; | ||
1826 | if (info.HasReceivedInventory) | ||
1827 | return true; | ||
1828 | } | ||
1829 | m_log.DebugFormat("Timed out waiting for inventory of user {0}", | ||
1830 | info.UserProfile.ID.ToString()); | ||
1831 | return false; | ||
1832 | } | ||
1833 | |||
1834 | /// <summary> | 1621 | /// <summary> |
1835 | /// Delete a scene object from a scene and place in the given avatar's inventory. | 1622 | /// Delete a scene object from a scene and place in the given avatar's inventory. |
1836 | /// Returns the UUID of the newly created asset. | 1623 | /// Returns the UUID of the newly created asset. |
@@ -1848,7 +1635,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1848 | 1635 | ||
1849 | // Get the user info of the item destination | 1636 | // Get the user info of the item destination |
1850 | // | 1637 | // |
1851 | CachedUserInfo userInfo; | 1638 | UUID userID = UUID.Zero; |
1852 | 1639 | ||
1853 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || | 1640 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || |
1854 | action == DeRezAction.SaveToExistingUserInventoryItem) | 1641 | action == DeRezAction.SaveToExistingUserInventoryItem) |
@@ -1859,28 +1646,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1859 | if (remoteClient == null) | 1646 | if (remoteClient == null) |
1860 | return UUID.Zero; | 1647 | return UUID.Zero; |
1861 | 1648 | ||
1862 | userInfo = CommsManager.UserProfileCacheService.GetUserDetails( | 1649 | userID = remoteClient.AgentId; |
1863 | remoteClient.AgentId); | ||
1864 | } | 1650 | } |
1865 | else | 1651 | else |
1866 | { | 1652 | { |
1867 | // All returns / deletes go to the object owner | 1653 | // All returns / deletes go to the object owner |
1868 | // | 1654 | // |
1869 | userInfo = CommsManager.UserProfileCacheService.GetUserDetails( | ||
1870 | objectGroup.RootPart.OwnerID); | ||
1871 | } | ||
1872 | 1655 | ||
1873 | if (userInfo == null) // Can't proceed | 1656 | userID = objectGroup.RootPart.OwnerID; |
1874 | { | ||
1875 | return UUID.Zero; | ||
1876 | } | 1657 | } |
1877 | 1658 | ||
1878 | if (!userInfo.HasReceivedInventory) | 1659 | if (userID == UUID.Zero) // Can't proceed |
1879 | { | 1660 | { |
1880 | // Async inventory requests will queue, but they will never | 1661 | return UUID.Zero; |
1881 | // execute unless inventory is actually fetched | ||
1882 | // | ||
1883 | userInfo.FetchInventory(); | ||
1884 | } | 1662 | } |
1885 | 1663 | ||
1886 | // If we're returning someone's item, it goes back to the | 1664 | // If we're returning someone's item, it goes back to the |
@@ -1894,8 +1672,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1894 | 1672 | ||
1895 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 1673 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
1896 | { | 1674 | { |
1897 | item = userInfo.RootFolder.FindItem( | 1675 | item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID); |
1898 | objectGroup.RootPart.FromUserInventoryItemID); | 1676 | item = InventoryService.GetItem(item); |
1677 | |||
1678 | //item = userInfo.RootFolder.FindItem( | ||
1679 | // objectGroup.RootPart.FromUserInventoryItemID); | ||
1899 | 1680 | ||
1900 | if (null == item) | 1681 | if (null == item) |
1901 | { | 1682 | { |
@@ -1920,53 +1701,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
1920 | // have to wait for the inventory to find | 1701 | // have to wait for the inventory to find |
1921 | // the destination folder | 1702 | // the destination folder |
1922 | // | 1703 | // |
1923 | if (!WaitForInventory(userInfo)) | 1704 | folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
1924 | return UUID.Zero; | ||
1925 | folder = userInfo.FindFolderForType( | ||
1926 | (int)AssetType.LostAndFoundFolder); | ||
1927 | } | 1705 | } |
1928 | else | 1706 | else |
1929 | { | 1707 | { |
1930 | // Assume inventory skeleton was loaded during login | 1708 | // Assume inventory skeleton was loaded during login |
1931 | // and all folders can be found | 1709 | // and all folders can be found |
1932 | // | 1710 | // |
1933 | folder = userInfo.FindFolderForType( | 1711 | folder = InventoryService.GetFolderForType(userID, AssetType.TrashFolder); |
1934 | (int)AssetType.TrashFolder); | ||
1935 | } | 1712 | } |
1936 | } | 1713 | } |
1937 | else if (action == DeRezAction.Return) | 1714 | else if (action == DeRezAction.Return) |
1938 | { | 1715 | { |
1939 | // Wait if needed | ||
1940 | // | ||
1941 | if (!userInfo.HasReceivedInventory) | ||
1942 | { | ||
1943 | if (!WaitForInventory(userInfo)) | ||
1944 | return UUID.Zero; | ||
1945 | } | ||
1946 | 1716 | ||
1947 | // Dump to lost + found unconditionally | 1717 | // Dump to lost + found unconditionally |
1948 | // | 1718 | // |
1949 | folder = userInfo.FindFolderForType( | 1719 | folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
1950 | (int)AssetType.LostAndFoundFolder); | ||
1951 | } | 1720 | } |
1952 | 1721 | ||
1953 | if (folderID == UUID.Zero && folder == null) | 1722 | if (folderID == UUID.Zero && folder == null) |
1954 | { | 1723 | { |
1955 | // Catch all. Use lost & found | 1724 | // Catch all. Use lost & found |
1956 | // | 1725 | // |
1957 | if (!userInfo.HasReceivedInventory) | ||
1958 | { | ||
1959 | if (!WaitForInventory(userInfo)) | ||
1960 | return UUID.Zero; | ||
1961 | } | ||
1962 | 1726 | ||
1963 | folder = userInfo.FindFolderForType( | 1727 | folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
1964 | (int)AssetType.LostAndFoundFolder); | ||
1965 | } | 1728 | } |
1966 | 1729 | ||
1967 | if (folder == null) // None of the above | 1730 | if (folder == null) // None of the above |
1968 | { | 1731 | { |
1969 | folder = userInfo.RootFolder.FindFolder(folderID); | 1732 | //folder = userInfo.RootFolder.FindFolder(folderID); |
1733 | folder = new InventoryFolderBase(folderID); | ||
1970 | 1734 | ||
1971 | if (folder == null) // Nowhere to put it | 1735 | if (folder == null) // Nowhere to put it |
1972 | { | 1736 | { |
@@ -1979,7 +1743,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1979 | item.ID = UUID.Random(); | 1743 | item.ID = UUID.Random(); |
1980 | item.InvType = (int)InventoryType.Object; | 1744 | item.InvType = (int)InventoryType.Object; |
1981 | item.Folder = folder.ID; | 1745 | item.Folder = folder.ID; |
1982 | item.Owner = userInfo.UserProfile.ID; | 1746 | item.Owner = userID; |
1983 | } | 1747 | } |
1984 | 1748 | ||
1985 | AssetBase asset = CreateAsset( | 1749 | AssetBase asset = CreateAsset( |
@@ -1993,7 +1757,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1993 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 1757 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
1994 | { | 1758 | { |
1995 | item.AssetID = asset.FullID; | 1759 | item.AssetID = asset.FullID; |
1996 | userInfo.UpdateItem(item); | 1760 | InventoryService.UpdateItem(item); |
1997 | } | 1761 | } |
1998 | else | 1762 | else |
1999 | { | 1763 | { |
@@ -2034,7 +1798,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2034 | item.Name = asset.Name; | 1798 | item.Name = asset.Name; |
2035 | item.AssetType = asset.Type; | 1799 | item.AssetType = asset.Type; |
2036 | 1800 | ||
2037 | userInfo.AddItem(item); | 1801 | InventoryService.AddItem(item); |
2038 | 1802 | ||
2039 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 1803 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
2040 | { | 1804 | { |
@@ -2053,7 +1817,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2053 | return assetID; | 1817 | return assetID; |
2054 | } | 1818 | } |
2055 | 1819 | ||
2056 | public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID) | 1820 | public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) |
2057 | { | 1821 | { |
2058 | SceneObjectGroup objectGroup = grp; | 1822 | SceneObjectGroup objectGroup = grp; |
2059 | if (objectGroup != null) | 1823 | if (objectGroup != null) |
@@ -2070,65 +1834,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
2070 | 1834 | ||
2071 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); | 1835 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); |
2072 | 1836 | ||
2073 | CachedUserInfo userInfo = | 1837 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
2074 | CommsManager.UserProfileCacheService.GetUserDetails(agentID); | 1838 | |
2075 | if (userInfo != null && userInfo.RootFolder != null) | 1839 | if (item != null) |
2076 | { | 1840 | { |
2077 | Queue<InventoryFolderImpl> searchfolders = new Queue<InventoryFolderImpl>(); | 1841 | AssetBase asset = CreateAsset( |
2078 | searchfolders.Enqueue(userInfo.RootFolder); | 1842 | objectGroup.GetPartName(objectGroup.LocalId), |
1843 | objectGroup.GetPartDescription(objectGroup.LocalId), | ||
1844 | (sbyte)AssetType.Object, | ||
1845 | Utils.StringToBytes(sceneObjectXml)); | ||
1846 | AssetService.Store(asset); | ||
2079 | 1847 | ||
2080 | UUID foundFolder = UUID.Zero; | 1848 | item.AssetID = asset.FullID; |
2081 | InventoryItemBase item = null; | 1849 | item.Description = asset.Description; |
1850 | item.Name = asset.Name; | ||
1851 | item.AssetType = asset.Type; | ||
1852 | item.InvType = (int)InventoryType.Object; | ||
2082 | 1853 | ||
2083 | // search through folders to find the asset. | 1854 | InventoryService.UpdateItem(item); |
2084 | while (searchfolders.Count > 0) | ||
2085 | { | ||
2086 | InventoryFolderImpl fld = searchfolders.Dequeue(); | ||
2087 | lock (fld) | ||
2088 | { | ||
2089 | if (fld != null) | ||
2090 | { | ||
2091 | if (fld.Items.ContainsKey(assetID)) | ||
2092 | { | ||
2093 | item = fld.Items[assetID]; | ||
2094 | foundFolder = fld.ID; | ||
2095 | searchfolders.Clear(); | ||
2096 | break; | ||
2097 | } | ||
2098 | else | ||
2099 | { | ||
2100 | foreach (InventoryFolderImpl subfld in fld.RequestListOfFolderImpls()) | ||
2101 | { | ||
2102 | searchfolders.Enqueue(subfld); | ||
2103 | } | ||
2104 | } | ||
2105 | } | ||
2106 | } | ||
2107 | } | ||
2108 | 1855 | ||
2109 | if (foundFolder != UUID.Zero && item != null) | 1856 | // this gets called when the agent loggs off! |
1857 | if (remoteClient != null) | ||
2110 | { | 1858 | { |
2111 | AssetBase asset = CreateAsset( | 1859 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
2112 | objectGroup.GetPartName(objectGroup.LocalId), | ||
2113 | objectGroup.GetPartDescription(objectGroup.LocalId), | ||
2114 | (sbyte)AssetType.Object, | ||
2115 | Utils.StringToBytes(sceneObjectXml)); | ||
2116 | AssetService.Store(asset); | ||
2117 | |||
2118 | item.AssetID = asset.FullID; | ||
2119 | item.Description = asset.Description; | ||
2120 | item.Name = asset.Name; | ||
2121 | item.AssetType = asset.Type; | ||
2122 | item.InvType = (int)InventoryType.Object; | ||
2123 | item.Folder = foundFolder; | ||
2124 | |||
2125 | userInfo.UpdateItem(item); | ||
2126 | |||
2127 | // this gets called when the agent loggs off! | ||
2128 | if (remoteClient != null) | ||
2129 | { | ||
2130 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
2131 | } | ||
2132 | } | 1860 | } |
2133 | } | 1861 | } |
2134 | } | 1862 | } |
@@ -2140,59 +1868,54 @@ namespace OpenSim.Region.Framework.Scenes | |||
2140 | if (grp != null) | 1868 | if (grp != null) |
2141 | { | 1869 | { |
2142 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); | 1870 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); |
1871 | |||
1872 | AssetBase asset = CreateAsset( | ||
1873 | grp.GetPartName(grp.LocalId), | ||
1874 | grp.GetPartDescription(grp.LocalId), | ||
1875 | (sbyte)AssetType.Object, | ||
1876 | Utils.StringToBytes(sceneObjectXml)); | ||
1877 | AssetService.Store(asset); | ||
2143 | 1878 | ||
2144 | CachedUserInfo userInfo = | 1879 | InventoryItemBase item = new InventoryItemBase(); |
2145 | CommsManager.UserProfileCacheService.GetUserDetails(AgentId); | 1880 | item.CreatorId = grp.RootPart.CreatorID.ToString(); |
2146 | 1881 | item.Owner = remoteClient.AgentId; | |
2147 | if (userInfo != null) | 1882 | item.ID = UUID.Random(); |
2148 | { | 1883 | item.AssetID = asset.FullID; |
2149 | AssetBase asset = CreateAsset( | 1884 | item.Description = asset.Description; |
2150 | grp.GetPartName(grp.LocalId), | 1885 | item.Name = asset.Name; |
2151 | grp.GetPartDescription(grp.LocalId), | 1886 | item.AssetType = asset.Type; |
2152 | (sbyte)AssetType.Object, | 1887 | item.InvType = (int)InventoryType.Object; |
2153 | Utils.StringToBytes(sceneObjectXml)); | ||
2154 | AssetService.Store(asset); | ||
2155 | |||
2156 | InventoryItemBase item = new InventoryItemBase(); | ||
2157 | item.CreatorId = grp.RootPart.CreatorID.ToString(); | ||
2158 | item.Owner = remoteClient.AgentId; | ||
2159 | item.ID = UUID.Random(); | ||
2160 | item.AssetID = asset.FullID; | ||
2161 | item.Description = asset.Description; | ||
2162 | item.Name = asset.Name; | ||
2163 | item.AssetType = asset.Type; | ||
2164 | item.InvType = (int)InventoryType.Object; | ||
2165 | 1888 | ||
2166 | item.Folder = UUID.Zero; // Objects folder! | 1889 | item.Folder = UUID.Zero; // Objects folder! |
2167 | 1890 | ||
2168 | if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions()) | 1891 | if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions()) |
2169 | { | 1892 | { |
2170 | item.BasePermissions = grp.RootPart.NextOwnerMask; | 1893 | item.BasePermissions = grp.RootPart.NextOwnerMask; |
2171 | item.CurrentPermissions = grp.RootPart.NextOwnerMask; | 1894 | item.CurrentPermissions = grp.RootPart.NextOwnerMask; |
2172 | item.NextPermissions = grp.RootPart.NextOwnerMask; | 1895 | item.NextPermissions = grp.RootPart.NextOwnerMask; |
2173 | item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; | 1896 | item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; |
2174 | item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; | 1897 | item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; |
2175 | } | 1898 | } |
2176 | else | 1899 | else |
2177 | { | 1900 | { |
2178 | item.BasePermissions = grp.RootPart.BaseMask; | 1901 | item.BasePermissions = grp.RootPart.BaseMask; |
2179 | item.CurrentPermissions = grp.RootPart.OwnerMask; | 1902 | item.CurrentPermissions = grp.RootPart.OwnerMask; |
2180 | item.NextPermissions = grp.RootPart.NextOwnerMask; | 1903 | item.NextPermissions = grp.RootPart.NextOwnerMask; |
2181 | item.EveryOnePermissions = grp.RootPart.EveryoneMask; | 1904 | item.EveryOnePermissions = grp.RootPart.EveryoneMask; |
2182 | item.GroupPermissions = grp.RootPart.GroupMask; | 1905 | item.GroupPermissions = grp.RootPart.GroupMask; |
2183 | } | 1906 | } |
2184 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 1907 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
2185 | 1908 | ||
2186 | // sets assetID so client can show asset as 'attached' in inventory | 1909 | // sets itemID so client can show item as 'attached' in inventory |
2187 | grp.SetFromAssetID(item.ID); | 1910 | grp.SetFromItemID(item.ID); |
2188 | 1911 | ||
2189 | userInfo.AddItem(item); | 1912 | if (InventoryService.AddItem(item)) |
2190 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 1913 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
1914 | else | ||
1915 | m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); | ||
2191 | 1916 | ||
2192 | itemID = item.ID; | 1917 | itemID = item.ID; |
2193 | return item.AssetID; | 1918 | return item.AssetID; |
2194 | } | ||
2195 | return UUID.Zero; | ||
2196 | } | 1919 | } |
2197 | return UUID.Zero; | 1920 | return UUID.Zero; |
2198 | } | 1921 | } |
@@ -2261,180 +1984,164 @@ namespace OpenSim.Region.Framework.Scenes | |||
2261 | BypassRayCast, bRayEndIsIntersection,true,scale, false); | 1984 | BypassRayCast, bRayEndIsIntersection,true,scale, false); |
2262 | 1985 | ||
2263 | // Rez object | 1986 | // Rez object |
2264 | CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 1987 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
2265 | if (userInfo != null) | 1988 | |
1989 | if (item != null) | ||
2266 | { | 1990 | { |
2267 | // Do NOT use HasReceivedInventory here, this is called | 1991 | AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); |
2268 | // from within ItemReceive during login for attachments. | 1992 | |
2269 | // Using HasReceivedInventory here will break attachment | 1993 | if (rezAsset != null) |
2270 | // persistence! | ||
2271 | // | ||
2272 | if (userInfo.RootFolder != null) | ||
2273 | { | 1994 | { |
2274 | InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); | 1995 | UUID itemId = UUID.Zero; |
2275 | 1996 | ||
2276 | if (item != null) | 1997 | // If we have permission to copy then link the rezzed object back to the user inventory |
1998 | // item that it came from. This allows us to enable 'save object to inventory' | ||
1999 | if (!Permissions.BypassPermissions()) | ||
2277 | { | 2000 | { |
2278 | AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); | 2001 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) |
2279 | |||
2280 | if (rezAsset != null) | ||
2281 | { | 2002 | { |
2282 | UUID itemId = UUID.Zero; | 2003 | itemId = item.ID; |
2283 | 2004 | } | |
2284 | // If we have permission to copy then link the rezzed object back to the user inventory | 2005 | } |
2285 | // item that it came from. This allows us to enable 'save object to inventory' | 2006 | else |
2286 | if (!Permissions.BypassPermissions()) | 2007 | { |
2287 | { | 2008 | // Brave new fullperm world |
2288 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) | 2009 | // |
2289 | { | 2010 | itemId = item.ID; |
2290 | itemId = item.ID; | 2011 | } |
2291 | } | ||
2292 | } | ||
2293 | else | ||
2294 | { | ||
2295 | // Brave new fullperm world | ||
2296 | // | ||
2297 | itemId = item.ID; | ||
2298 | } | ||
2299 | |||
2300 | string xmlData = Utils.BytesToString(rezAsset.Data); | ||
2301 | SceneObjectGroup group | ||
2302 | = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); | ||
2303 | 2012 | ||
2304 | if (!Permissions.CanRezObject( | 2013 | string xmlData = Utils.BytesToString(rezAsset.Data); |
2305 | group.Children.Count, remoteClient.AgentId, pos) | 2014 | SceneObjectGroup group |
2306 | && !attachment) | 2015 | = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); |
2307 | { | ||
2308 | return null; | ||
2309 | } | ||
2310 | 2016 | ||
2311 | group.ResetIDs(); | 2017 | if (!Permissions.CanRezObject( |
2018 | group.Children.Count, remoteClient.AgentId, pos) | ||
2019 | && !attachment) | ||
2020 | { | ||
2021 | return null; | ||
2022 | } | ||
2312 | 2023 | ||
2313 | if (attachment) | 2024 | group.ResetIDs(); |
2314 | group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom; | ||
2315 | 2025 | ||
2316 | AddNewSceneObject(group, true); | 2026 | if (attachment) |
2027 | group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom; | ||
2317 | 2028 | ||
2318 | // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); | 2029 | AddNewSceneObject(group, true); |
2319 | // if attachment we set it's asset id so object updates can reflect that | ||
2320 | // if not, we set it's position in world. | ||
2321 | if (!attachment) | ||
2322 | { | ||
2323 | float offsetHeight = 0; | ||
2324 | pos = GetNewRezLocation( | ||
2325 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | ||
2326 | BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); | ||
2327 | pos.Z += offsetHeight; | ||
2328 | group.AbsolutePosition = pos; | ||
2329 | // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); | ||
2330 | 2030 | ||
2331 | } | 2031 | // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); |
2332 | else | 2032 | // if attachment we set it's asset id so object updates can reflect that |
2333 | { | 2033 | // if not, we set it's position in world. |
2334 | group.SetFromAssetID(itemID); | 2034 | if (!attachment) |
2335 | } | 2035 | { |
2036 | float offsetHeight = 0; | ||
2037 | pos = GetNewRezLocation( | ||
2038 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | ||
2039 | BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); | ||
2040 | pos.Z += offsetHeight; | ||
2041 | group.AbsolutePosition = pos; | ||
2042 | // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); | ||
2336 | 2043 | ||
2337 | SceneObjectPart rootPart = null; | 2044 | } |
2338 | try | 2045 | else |
2339 | { | 2046 | { |
2340 | rootPart = group.GetChildPart(group.UUID); | 2047 | group.SetFromItemID(itemID); |
2341 | } | 2048 | } |
2342 | catch (NullReferenceException) | ||
2343 | { | ||
2344 | string isAttachment = ""; | ||
2345 | 2049 | ||
2346 | if (attachment) | 2050 | SceneObjectPart rootPart = null; |
2347 | isAttachment = " Object was an attachment"; | 2051 | try |
2052 | { | ||
2053 | rootPart = group.GetChildPart(group.UUID); | ||
2054 | } | ||
2055 | catch (NullReferenceException) | ||
2056 | { | ||
2057 | string isAttachment = ""; | ||
2348 | 2058 | ||
2349 | m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); | 2059 | if (attachment) |
2350 | } | 2060 | isAttachment = " Object was an attachment"; |
2351 | 2061 | ||
2352 | // Since renaming the item in the inventory does not affect the name stored | 2062 | m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); |
2353 | // in the serialization, transfer the correct name from the inventory to the | 2063 | } |
2354 | // object itself before we rez. | ||
2355 | rootPart.Name = item.Name; | ||
2356 | rootPart.Description = item.Description; | ||
2357 | 2064 | ||
2358 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); | 2065 | // Since renaming the item in the inventory does not affect the name stored |
2066 | // in the serialization, transfer the correct name from the inventory to the | ||
2067 | // object itself before we rez. | ||
2068 | rootPart.Name = item.Name; | ||
2069 | rootPart.Description = item.Description; | ||
2359 | 2070 | ||
2360 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | 2071 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); |
2361 | if (rootPart.OwnerID != item.Owner) | ||
2362 | { | ||
2363 | //Need to kill the for sale here | ||
2364 | rootPart.ObjectSaleType = 0; | ||
2365 | rootPart.SalePrice = 10; | ||
2366 | 2072 | ||
2367 | if (Permissions.PropagatePermissions()) | 2073 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); |
2368 | { | 2074 | if (rootPart.OwnerID != item.Owner) |
2369 | if ((item.CurrentPermissions & 8) != 0) | 2075 | { |
2370 | { | 2076 | //Need to kill the for sale here |
2371 | foreach (SceneObjectPart part in partList) | 2077 | rootPart.ObjectSaleType = 0; |
2372 | { | 2078 | rootPart.SalePrice = 10; |
2373 | part.EveryoneMask = item.EveryOnePermissions; | ||
2374 | part.NextOwnerMask = item.NextPermissions; | ||
2375 | part.GroupMask = 0; // DO NOT propagate here | ||
2376 | } | ||
2377 | } | ||
2378 | group.ApplyNextOwnerPermissions(); | ||
2379 | } | ||
2380 | } | ||
2381 | 2079 | ||
2382 | foreach (SceneObjectPart part in partList) | 2080 | if (Permissions.PropagatePermissions()) |
2081 | { | ||
2082 | if ((item.CurrentPermissions & 8) != 0) | ||
2383 | { | 2083 | { |
2384 | if (part.OwnerID != item.Owner) | 2084 | foreach (SceneObjectPart part in partList) |
2385 | { | ||
2386 | part.LastOwnerID = part.OwnerID; | ||
2387 | part.OwnerID = item.Owner; | ||
2388 | part.Inventory.ChangeInventoryOwner(item.Owner); | ||
2389 | } | ||
2390 | else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam! | ||
2391 | { | 2085 | { |
2392 | part.EveryoneMask = item.EveryOnePermissions; | 2086 | part.EveryoneMask = item.EveryOnePermissions; |
2393 | part.NextOwnerMask = item.NextPermissions; | 2087 | part.NextOwnerMask = item.NextPermissions; |
2394 | |||
2395 | part.GroupMask = 0; // DO NOT propagate here | 2088 | part.GroupMask = 0; // DO NOT propagate here |
2396 | } | 2089 | } |
2397 | } | 2090 | } |
2091 | group.ApplyNextOwnerPermissions(); | ||
2092 | } | ||
2093 | } | ||
2398 | 2094 | ||
2399 | rootPart.TrimPermissions(); | 2095 | foreach (SceneObjectPart part in partList) |
2096 | { | ||
2097 | if (part.OwnerID != item.Owner) | ||
2098 | { | ||
2099 | part.LastOwnerID = part.OwnerID; | ||
2100 | part.OwnerID = item.Owner; | ||
2101 | part.Inventory.ChangeInventoryOwner(item.Owner); | ||
2102 | } | ||
2103 | else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam! | ||
2104 | { | ||
2105 | part.EveryoneMask = item.EveryOnePermissions; | ||
2106 | part.NextOwnerMask = item.NextPermissions; | ||
2400 | 2107 | ||
2401 | if (!attachment) | 2108 | part.GroupMask = 0; // DO NOT propagate here |
2402 | { | 2109 | } |
2403 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | 2110 | } |
2404 | { | ||
2405 | group.ClearPartAttachmentData(); | ||
2406 | } | ||
2407 | } | ||
2408 | 2111 | ||
2409 | if (!attachment) | 2112 | rootPart.TrimPermissions(); |
2410 | { | ||
2411 | // Fire on_rez | ||
2412 | group.CreateScriptInstances(0, true, DefaultScriptEngine, 0); | ||
2413 | 2113 | ||
2414 | rootPart.ScheduleFullUpdate(); | 2114 | if (!attachment) |
2415 | } | 2115 | { |
2116 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
2117 | { | ||
2118 | group.ClearPartAttachmentData(); | ||
2119 | } | ||
2120 | } | ||
2416 | 2121 | ||
2417 | if (!Permissions.BypassPermissions()) | 2122 | if (!attachment) |
2418 | { | 2123 | { |
2419 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | 2124 | // Fire on_rez |
2420 | { | 2125 | group.CreateScriptInstances(0, true, DefaultScriptEngine, 0); |
2421 | // If this is done on attachments, no | ||
2422 | // copy ones will be lost, so avoid it | ||
2423 | // | ||
2424 | if (!attachment) | ||
2425 | userInfo.DeleteItem(item.ID); | ||
2426 | } | ||
2427 | } | ||
2428 | 2126 | ||
2429 | return rootPart.ParentGroup; | 2127 | rootPart.ScheduleFullUpdate(); |
2128 | } | ||
2129 | |||
2130 | if (!Permissions.BypassPermissions()) | ||
2131 | { | ||
2132 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
2133 | { | ||
2134 | // If this is done on attachments, no | ||
2135 | // copy ones will be lost, so avoid it | ||
2136 | // | ||
2137 | if (!attachment) | ||
2138 | InventoryService.DeleteItem(item); | ||
2430 | } | 2139 | } |
2431 | } | 2140 | } |
2141 | |||
2142 | return rootPart.ParentGroup; | ||
2432 | } | 2143 | } |
2433 | else | ||
2434 | m_log.WarnFormat("[AGENT INVENTORY]: Root folder not found in {0}", RegionInfo.RegionName); | ||
2435 | } | 2144 | } |
2436 | else | ||
2437 | m_log.WarnFormat("[AGENT INVENTORY]: User profile not found in {0}", RegionInfo.RegionName); | ||
2438 | 2145 | ||
2439 | return null; | 2146 | return null; |
2440 | } | 2147 | } |
@@ -2602,7 +2309,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2602 | ScenePresence presence; | 2309 | ScenePresence presence; |
2603 | if (TryGetAvatar(remoteClient.AgentId, out presence)) | 2310 | if (TryGetAvatar(remoteClient.AgentId, out presence)) |
2604 | { | 2311 | { |
2605 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, att.UUID); | 2312 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID, remoteClient.AgentId)); |
2313 | |||
2314 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); | ||
2606 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); | 2315 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); |
2607 | if (ava != null) | 2316 | if (ava != null) |
2608 | { | 2317 | { |
@@ -2650,7 +2359,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2650 | ScenePresence presence; | 2359 | ScenePresence presence; |
2651 | if (TryGetAvatar(remoteClient.AgentId, out presence)) | 2360 | if (TryGetAvatar(remoteClient.AgentId, out presence)) |
2652 | { | 2361 | { |
2653 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, att.UUID); | 2362 | // XXYY!! |
2363 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); | ||
2364 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); | ||
2654 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); | 2365 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); |
2655 | if (ava != null) | 2366 | if (ava != null) |
2656 | { | 2367 | { |
@@ -2666,7 +2377,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2666 | if (part == null || part.ParentGroup == null) | 2377 | if (part == null || part.ParentGroup == null) |
2667 | return; | 2378 | return; |
2668 | 2379 | ||
2669 | UUID inventoryID = part.ParentGroup.GetFromAssetID(); | 2380 | UUID inventoryID = part.ParentGroup.GetFromItemID(); |
2670 | 2381 | ||
2671 | ScenePresence presence; | 2382 | ScenePresence presence; |
2672 | if (TryGetAvatar(remoteClient.AgentId, out presence)) | 2383 | if (TryGetAvatar(remoteClient.AgentId, out presence)) |
@@ -2681,13 +2392,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2681 | ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | 2392 | ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); |
2682 | } | 2393 | } |
2683 | part.ParentGroup.DetachToGround(); | 2394 | part.ParentGroup.DetachToGround(); |
2684 | CachedUserInfo userInfo = | 2395 | |
2685 | CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 2396 | InventoryService.DeleteItem(new InventoryItemBase(inventoryID)); |
2686 | if (userInfo != null) | 2397 | remoteClient.SendRemoveInventoryItem(inventoryID); |
2687 | { | ||
2688 | userInfo.DeleteItem(inventoryID); | ||
2689 | remoteClient.SendRemoveInventoryItem(inventoryID); | ||
2690 | } | ||
2691 | } | 2398 | } |
2692 | SendAttachEvent(part.ParentGroup.LocalId, itemID, UUID.Zero); | 2399 | SendAttachEvent(part.ParentGroup.LocalId, itemID, UUID.Zero); |
2693 | } | 2400 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 4fee4c9..2bf4ea8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -404,31 +404,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
404 | return; | 404 | return; |
405 | } | 405 | } |
406 | 406 | ||
407 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 407 | InventoryItemBase item = InventoryService.GetItem(new InventoryItemBase(itemID)); |
408 | 408 | ||
409 | if (null == userProfile) | 409 | if (item != null) |
410 | { | ||
411 | m_log.ErrorFormat( | ||
412 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
413 | remoteClient.Name, remoteClient.AgentId); | ||
414 | return; | ||
415 | } | ||
416 | |||
417 | if (userProfile.HasReceivedInventory) | ||
418 | { | 410 | { |
419 | InventoryItemBase item = null; | 411 | remoteClient.SendInventoryItemDetails(ownerID, item); |
420 | if (userProfile.RootFolder == null) | ||
421 | m_log.ErrorFormat( | ||
422 | "[AGENT INVENTORY]: User {0} {1} does not have a root folder.", | ||
423 | remoteClient.Name, remoteClient.AgentId); | ||
424 | else | ||
425 | item = userProfile.RootFolder.FindItem(itemID); | ||
426 | |||
427 | if (item != null) | ||
428 | { | ||
429 | remoteClient.SendInventoryItemDetails(ownerID, item); | ||
430 | } | ||
431 | } | 412 | } |
413 | // else shouldn't we send an alert message? | ||
432 | } | 414 | } |
433 | 415 | ||
434 | /// <summary> | 416 | /// <summary> |
@@ -457,23 +439,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
457 | return; | 439 | return; |
458 | } | 440 | } |
459 | 441 | ||
460 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 442 | SendInventoryUpdate(remoteClient, new InventoryFolderBase(folderID), fetchFolders, fetchItems); |
461 | |||
462 | if (null == userProfile) | ||
463 | { | ||
464 | m_log.ErrorFormat( | ||
465 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
466 | remoteClient.Name, remoteClient.AgentId); | ||
467 | return; | ||
468 | } | ||
469 | |||
470 | userProfile.SendInventoryDecendents(remoteClient, folderID, fetchFolders, fetchItems); | ||
471 | } | 443 | } |
472 | 444 | ||
473 | /// <summary> | 445 | /// <summary> |
474 | /// Handle the caps inventory descendents fetch. | 446 | /// Handle the caps inventory descendents fetch. |
475 | /// | 447 | /// |
476 | /// Since the folder structure is sent to the client on login, I believe we only need to handle items. | 448 | /// Since the folder structure is sent to the client on login, I believe we only need to handle items. |
449 | /// Diva comment 8/13/2009: what if someone gave us a folder in the meantime?? | ||
477 | /// </summary> | 450 | /// </summary> |
478 | /// <param name="agentID"></param> | 451 | /// <param name="agentID"></param> |
479 | /// <param name="folderID"></param> | 452 | /// <param name="folderID"></param> |
@@ -499,59 +472,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
499 | { | 472 | { |
500 | return fold.RequestListOfItems(); | 473 | return fold.RequestListOfItems(); |
501 | } | 474 | } |
502 | |||
503 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(agentID); | ||
504 | |||
505 | if (null == userProfile) | ||
506 | { | ||
507 | m_log.ErrorFormat("[AGENT INVENTORY]: Could not find user profile for {0}", agentID); | ||
508 | return null; | ||
509 | } | ||
510 | |||
511 | // XXX: When a client crosses into a scene, their entire inventory is fetched | ||
512 | // asynchronously. If the client makes a request before the inventory is received, we need | ||
513 | // to give the inventory a chance to come in. | ||
514 | // | ||
515 | // This is a crude way of dealing with that by retrying the lookup. It's not quite as bad | ||
516 | // in CAPS as doing this with the udp request, since here it won't hold up other packets. | ||
517 | // In fact, here we'll be generous and try for longer. | ||
518 | if (!userProfile.HasReceivedInventory) | ||
519 | { | ||
520 | int attempts = 0; | ||
521 | while (attempts++ < 30) | ||
522 | { | ||
523 | m_log.DebugFormat( | ||
524 | "[INVENTORY CACHE]: Poll number {0} for inventory items in folder {1} for user {2}", | ||
525 | attempts, folderID, agentID); | ||
526 | |||
527 | Thread.Sleep(2000); | ||
528 | 475 | ||
529 | if (userProfile.HasReceivedInventory) | 476 | InventoryCollection contents = InventoryService.GetFolderContent(agentID, folderID); |
530 | { | 477 | return contents.Items; |
531 | break; | ||
532 | } | ||
533 | } | ||
534 | } | ||
535 | 478 | ||
536 | if (userProfile.HasReceivedInventory) | ||
537 | { | ||
538 | if ((fold = userProfile.RootFolder.FindFolder(folderID)) != null) | ||
539 | { | ||
540 | return fold.RequestListOfItems(); | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | m_log.WarnFormat( | ||
545 | "[AGENT INVENTORY]: Could not find folder {0} requested by user {1}", | ||
546 | folderID, agentID); | ||
547 | return null; | ||
548 | } | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID); | ||
553 | return null; | ||
554 | } | ||
555 | } | 479 | } |
556 | 480 | ||
557 | /// <summary> | 481 | /// <summary> |
@@ -565,19 +489,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
565 | public void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType, | 489 | public void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType, |
566 | string folderName, UUID parentID) | 490 | string folderName, UUID parentID) |
567 | { | 491 | { |
568 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | 492 | InventoryFolderBase folder = new InventoryFolderBase(folderID, folderName, remoteClient.AgentId, (short)folderType, parentID, 1); |
569 | 493 | if (!InventoryService.AddFolder(folder)) | |
570 | if (null == userProfile) | ||
571 | { | ||
572 | m_log.ErrorFormat( | ||
573 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
574 | remoteClient.Name, remoteClient.AgentId); | ||
575 | return; | ||
576 | } | ||
577 | |||
578 | if (!userProfile.CreateFolder(folderName, folderID, folderType, parentID)) | ||
579 | { | 494 | { |
580 | m_log.ErrorFormat( | 495 | m_log.WarnFormat( |
581 | "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", | 496 | "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", |
582 | remoteClient.Name, remoteClient.AgentId); | 497 | remoteClient.Name, remoteClient.AgentId); |
583 | } | 498 | } |
@@ -620,36 +535,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
620 | } | 535 | } |
621 | } | 536 | } |
622 | 537 | ||
623 | /// <summary> | ||
624 | /// Handle an inventory folder move request from the client. | ||
625 | /// </summary> | ||
626 | /// <param name="remoteClient"></param> | ||
627 | /// <param name="folderID"></param> | ||
628 | /// <param name="parentID"></param> | ||
629 | public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID) | 538 | public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID) |
630 | { | 539 | { |
631 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
632 | |||
633 | if (null == userProfile) | ||
634 | { | ||
635 | m_log.ErrorFormat( | ||
636 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
637 | remoteClient.Name, remoteClient.AgentId); | ||
638 | return; | ||
639 | } | ||
640 | |||
641 | if (!userProfile.MoveFolder(folderID, parentID)) | ||
642 | { | ||
643 | m_log.ErrorFormat( | ||
644 | "[AGENT INVENTORY]: Failed to move folder {0} to {1} for user {2}", | ||
645 | folderID, parentID, remoteClient.Name); | ||
646 | } | ||
647 | } | ||
648 | |||
649 | public void HandleMoveInventoryFolder2(IClientAPI remoteClient, UUID folderID, UUID parentID) | ||
650 | { | ||
651 | InventoryFolderBase folder = new InventoryFolderBase(folderID); | 540 | InventoryFolderBase folder = new InventoryFolderBase(folderID); |
652 | folder = InventoryService.QueryFolder(folder); | 541 | folder = InventoryService.GetFolder(folder); |
653 | if (folder != null) | 542 | if (folder != null) |
654 | { | 543 | { |
655 | folder.ParentID = parentID; | 544 | folder.ParentID = parentID; |
@@ -669,27 +558,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
669 | /// </summary> | 558 | /// </summary> |
670 | /// <param name="remoteClient"></param> | 559 | /// <param name="remoteClient"></param> |
671 | /// <param name="folderID"></param> | 560 | /// <param name="folderID"></param> |
672 | public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID) | ||
673 | { | ||
674 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
675 | |||
676 | if (null == userProfile) | ||
677 | { | ||
678 | m_log.ErrorFormat( | ||
679 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
680 | remoteClient.Name, remoteClient.AgentId); | ||
681 | return; | ||
682 | } | ||
683 | |||
684 | if (!userProfile.PurgeFolder(folderID)) | ||
685 | { | ||
686 | m_log.ErrorFormat( | ||
687 | "[AGENT INVENTORY]: Failed to purge folder for user {0} {1}", | ||
688 | remoteClient.Name, remoteClient.AgentId); | ||
689 | } | ||
690 | } | ||
691 | 561 | ||
692 | public void HandlePurgeInventoryDescendents2(IClientAPI remoteClient, UUID folderID) | 562 | public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID) |
693 | { | 563 | { |
694 | InventoryFolderBase folder = new InventoryFolderBase(folderID); | 564 | InventoryFolderBase folder = new InventoryFolderBase(folderID); |
695 | 565 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a2275f8..d1f7a4b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1962,7 +1962,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1962 | m_log.DebugFormat("[ATTACHMENT]: Received " + | 1962 | m_log.DebugFormat("[ATTACHMENT]: Received " + |
1963 | "attachment {0}, inworld asset id {1}", | 1963 | "attachment {0}, inworld asset id {1}", |
1964 | //grp.RootPart.LastOwnerID.ToString(), | 1964 | //grp.RootPart.LastOwnerID.ToString(), |
1965 | grp.GetFromAssetID(), | 1965 | grp.GetFromItemID(), |
1966 | grp.UUID.ToString()); | 1966 | grp.UUID.ToString()); |
1967 | 1967 | ||
1968 | //grp.SetFromAssetID(grp.RootPart.LastOwnerID); | 1968 | //grp.SetFromAssetID(grp.RootPart.LastOwnerID); |
@@ -2042,13 +2042,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
2042 | } | 2042 | } |
2043 | else | 2043 | else |
2044 | { | 2044 | { |
2045 | AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); | ||
2046 | |||
2045 | m_log.DebugFormat( | 2047 | m_log.DebugFormat( |
2046 | "[SCENE]: Adding new child agent for {0} in {1}", | 2048 | "[SCENE]: Adding new {0} agent for {1} in {2}", |
2047 | client.Name, RegionInfo.RegionName); | 2049 | ((aCircuit.child == true) ? "child" : "root"), client.Name, RegionInfo.RegionName); |
2048 | 2050 | ||
2049 | CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); | 2051 | CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); |
2050 | 2052 | ||
2051 | CreateAndAddScenePresence(client); | 2053 | ScenePresence sp = CreateAndAddScenePresence(client); |
2054 | |||
2055 | // HERE!!! Do the initial attachments right here | ||
2056 | // first agent upon login is a root agent by design. | ||
2057 | // All other AddNewClient calls find aCircuit.child to be true | ||
2058 | if (aCircuit.child == false) | ||
2059 | { | ||
2060 | sp.IsChildAgent = false; | ||
2061 | sp.RezAttachments(); | ||
2062 | } | ||
2052 | } | 2063 | } |
2053 | 2064 | ||
2054 | m_LastLogin = Environment.TickCount; | 2065 | m_LastLogin = Environment.TickCount; |
@@ -3673,59 +3684,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
3673 | case 2: // Sell a copy | 3684 | case 2: // Sell a copy |
3674 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); | 3685 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); |
3675 | 3686 | ||
3676 | CachedUserInfo userInfo = | 3687 | uint perms=group.GetEffectivePermissions(); |
3677 | CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
3678 | 3688 | ||
3679 | if (userInfo != null) | 3689 | if ((perms & (uint)PermissionMask.Transfer) == 0) |
3680 | { | 3690 | { |
3681 | uint perms=group.GetEffectivePermissions(); | 3691 | m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); |
3682 | 3692 | return false; | |
3683 | if ((perms & (uint)PermissionMask.Transfer) == 0) | 3693 | } |
3684 | { | ||
3685 | m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); | ||
3686 | return false; | ||
3687 | } | ||
3688 | 3694 | ||
3689 | AssetBase asset = CreateAsset( | 3695 | AssetBase asset = CreateAsset( |
3690 | group.GetPartName(localID), | 3696 | group.GetPartName(localID), |
3691 | group.GetPartDescription(localID), | 3697 | group.GetPartDescription(localID), |
3692 | (sbyte)AssetType.Object, | 3698 | (sbyte)AssetType.Object, |
3693 | Utils.StringToBytes(sceneObjectXml)); | 3699 | Utils.StringToBytes(sceneObjectXml)); |
3694 | AssetService.Store(asset); | 3700 | AssetService.Store(asset); |
3695 | 3701 | ||
3696 | InventoryItemBase item = new InventoryItemBase(); | 3702 | InventoryItemBase item = new InventoryItemBase(); |
3697 | item.CreatorId = part.CreatorID.ToString(); | 3703 | item.CreatorId = part.CreatorID.ToString(); |
3698 | 3704 | ||
3699 | item.ID = UUID.Random(); | 3705 | item.ID = UUID.Random(); |
3700 | item.Owner = remoteClient.AgentId; | 3706 | item.Owner = remoteClient.AgentId; |
3701 | item.AssetID = asset.FullID; | 3707 | item.AssetID = asset.FullID; |
3702 | item.Description = asset.Description; | 3708 | item.Description = asset.Description; |
3703 | item.Name = asset.Name; | 3709 | item.Name = asset.Name; |
3704 | item.AssetType = asset.Type; | 3710 | item.AssetType = asset.Type; |
3705 | item.InvType = (int)InventoryType.Object; | 3711 | item.InvType = (int)InventoryType.Object; |
3706 | item.Folder = categoryID; | 3712 | item.Folder = categoryID; |
3707 | 3713 | ||
3708 | uint nextPerms=(perms & 7) << 13; | 3714 | uint nextPerms=(perms & 7) << 13; |
3709 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | 3715 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) |
3710 | perms &= ~(uint)PermissionMask.Copy; | 3716 | perms &= ~(uint)PermissionMask.Copy; |
3711 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | 3717 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) |
3712 | perms &= ~(uint)PermissionMask.Transfer; | 3718 | perms &= ~(uint)PermissionMask.Transfer; |
3713 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | 3719 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) |
3714 | perms &= ~(uint)PermissionMask.Modify; | 3720 | perms &= ~(uint)PermissionMask.Modify; |
3715 | 3721 | ||
3716 | item.BasePermissions = perms & part.NextOwnerMask; | 3722 | item.BasePermissions = perms & part.NextOwnerMask; |
3717 | item.CurrentPermissions = perms & part.NextOwnerMask; | 3723 | item.CurrentPermissions = perms & part.NextOwnerMask; |
3718 | item.NextPermissions = part.NextOwnerMask; | 3724 | item.NextPermissions = part.NextOwnerMask; |
3719 | item.EveryOnePermissions = part.EveryoneMask & | 3725 | item.EveryOnePermissions = part.EveryoneMask & |
3720 | part.NextOwnerMask; | 3726 | part.NextOwnerMask; |
3721 | item.GroupPermissions = part.GroupMask & | 3727 | item.GroupPermissions = part.GroupMask & |
3722 | part.NextOwnerMask; | 3728 | part.NextOwnerMask; |
3723 | item.CurrentPermissions |= 8; // Slam! | 3729 | item.CurrentPermissions |= 8; // Slam! |
3724 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 3730 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
3725 | 3731 | ||
3726 | userInfo.AddItem(item); | 3732 | if (InventoryService.AddItem(item)) |
3727 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 3733 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
3728 | } | ||
3729 | else | 3734 | else |
3730 | { | 3735 | { |
3731 | m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); | 3736 | m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); |
@@ -3740,8 +3745,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3740 | 3745 | ||
3741 | foreach (UUID invID in invList) | 3746 | foreach (UUID invID in invList) |
3742 | { | 3747 | { |
3743 | TaskInventoryItem item = part.Inventory.GetInventoryItem(invID); | 3748 | TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID); |
3744 | if ((item.CurrentPermissions & | 3749 | if ((item1.CurrentPermissions & |
3745 | (uint)PermissionMask.Transfer) == 0) | 3750 | (uint)PermissionMask.Transfer) == 0) |
3746 | { | 3751 | { |
3747 | okToSell = false; | 3752 | okToSell = false; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index c1e39a9..65c97e8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | |||
@@ -1086,11 +1086,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1086 | 1086 | ||
1087 | public bool WaitForCallback(UUID id) | 1087 | public bool WaitForCallback(UUID id) |
1088 | { | 1088 | { |
1089 | int count = 20; | 1089 | int count = 200; |
1090 | while (m_agentsInTransit.Contains(id) && count-- > 0) | 1090 | while (m_agentsInTransit.Contains(id) && count-- > 0) |
1091 | { | 1091 | { |
1092 | //m_log.Debug(" >>> Waiting... " + count); | 1092 | //m_log.Debug(" >>> Waiting... " + count); |
1093 | Thread.Sleep(1000); | 1093 | Thread.Sleep(100); |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | if (count > 0) | 1096 | if (count > 0) |
@@ -1207,16 +1207,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1207 | { | 1207 | { |
1208 | pos = pos + (agent.Velocity); | 1208 | pos = pos + (agent.Velocity); |
1209 | 1209 | ||
1210 | CachedUserInfo userInfo = m_commsProvider.UserProfileCacheService.GetUserDetails(agent.UUID); | 1210 | //CachedUserInfo userInfo = m_commsProvider.UserProfileCacheService.GetUserDetails(agent.UUID); |
1211 | if (userInfo != null) | 1211 | //if (userInfo != null) |
1212 | { | 1212 | //{ |
1213 | userInfo.DropInventory(); | 1213 | // userInfo.DropInventory(); |
1214 | } | 1214 | //} |
1215 | else | 1215 | //else |
1216 | { | 1216 | //{ |
1217 | m_log.WarnFormat("[SCENE COMM]: No cached user info found for {0} {1} on leaving region {2}", | 1217 | // m_log.WarnFormat("[SCENE COMM]: No cached user info found for {0} {1} on leaving region {2}", |
1218 | agent.Name, agent.UUID, agent.Scene.RegionInfo.RegionName); | 1218 | // agent.Name, agent.UUID, agent.Scene.RegionInfo.RegionName); |
1219 | } | 1219 | //} |
1220 | 1220 | ||
1221 | //bool crossingSuccessful = | 1221 | //bool crossingSuccessful = |
1222 | // CrossToNeighbouringRegion(neighbourHandle, agent.ControllingClient.AgentId, pos, | 1222 | // CrossToNeighbouringRegion(neighbourHandle, agent.ControllingClient.AgentId, pos, |
@@ -1315,11 +1315,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1315 | } | 1315 | } |
1316 | else // Not successful | 1316 | else // Not successful |
1317 | { | 1317 | { |
1318 | CachedUserInfo userInfo = m_commsProvider.UserProfileCacheService.GetUserDetails(agent.UUID); | 1318 | //CachedUserInfo userInfo = m_commsProvider.UserProfileCacheService.GetUserDetails(agent.UUID); |
1319 | if (userInfo != null) | 1319 | //if (userInfo != null) |
1320 | { | 1320 | //{ |
1321 | userInfo.FetchInventory(); | 1321 | // userInfo.FetchInventory(); |
1322 | } | 1322 | //} |
1323 | agent.RestoreInCurrentScene(); | 1323 | agent.RestoreInCurrentScene(); |
1324 | } | 1324 | } |
1325 | // In any case | 1325 | // In any case |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 7771831..3007598 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -442,7 +442,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
442 | if (group != null) | 442 | if (group != null) |
443 | { | 443 | { |
444 | //group.DetachToGround(); | 444 | //group.DetachToGround(); |
445 | m_parentScene.DetachSingleAttachmentToInv(group.GetFromAssetID(), remoteClient); | 445 | m_parentScene.DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); |
446 | } | 446 | } |
447 | } | 447 | } |
448 | 448 | ||
@@ -489,7 +489,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
489 | // Calls attach with a Zero position | 489 | // Calls attach with a Zero position |
490 | // | 490 | // |
491 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); | 491 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); |
492 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromAssetID(), remoteClient.AgentId); | 492 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
493 | } | 493 | } |
494 | 494 | ||
495 | public SceneObjectGroup RezSingleAttachment( | 495 | public SceneObjectGroup RezSingleAttachment( |
@@ -536,14 +536,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
536 | if (entity is SceneObjectGroup) | 536 | if (entity is SceneObjectGroup) |
537 | { | 537 | { |
538 | group = (SceneObjectGroup)entity; | 538 | group = (SceneObjectGroup)entity; |
539 | if (group.GetFromAssetID() == itemID) | 539 | if (group.GetFromItemID() == itemID) |
540 | { | 540 | { |
541 | m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); | 541 | m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); |
542 | group.DetachToInventoryPrep(); | 542 | group.DetachToInventoryPrep(); |
543 | m_log.Debug("[DETACH]: Saving attachpoint: " + | 543 | m_log.Debug("[DETACH]: Saving attachpoint: " + |
544 | ((uint)group.GetAttachmentPoint()).ToString()); | 544 | ((uint)group.GetAttachmentPoint()).ToString()); |
545 | m_parentScene.updateKnownAsset(remoteClient, group, | 545 | m_parentScene.UpdateKnownItem(remoteClient, group, |
546 | group.GetFromAssetID(), group.OwnerID); | 546 | group.GetFromItemID(), group.OwnerID); |
547 | m_parentScene.DeleteSceneObject(group, false); | 547 | m_parentScene.DeleteSceneObject(group, false); |
548 | return; | 548 | return; |
549 | } | 549 | } |
@@ -572,7 +572,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
572 | { | 572 | { |
573 | // Check object for stored attachment point | 573 | // Check object for stored attachment point |
574 | AttachmentPt = (uint)group.GetAttachmentPoint(); | 574 | AttachmentPt = (uint)group.GetAttachmentPoint(); |
575 | } | 575 | } |
576 | 576 | ||
577 | // if we still didn't find a suitable attachment point....... | 577 | // if we still didn't find a suitable attachment point....... |
578 | if (AttachmentPt == 0) | 578 | if (AttachmentPt == 0) |
@@ -580,21 +580,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
580 | // Stick it on left hand with Zero Offset from the attachment point. | 580 | // Stick it on left hand with Zero Offset from the attachment point. |
581 | AttachmentPt = (uint)AttachmentPoint.LeftHand; | 581 | AttachmentPt = (uint)AttachmentPoint.LeftHand; |
582 | attachPos = Vector3.Zero; | 582 | attachPos = Vector3.Zero; |
583 | |||
583 | } | 584 | } |
584 | 585 | ||
586 | |||
585 | group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); | 587 | group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); |
586 | group.AbsolutePosition = attachPos; | 588 | group.AbsolutePosition = attachPos; |
587 | 589 | ||
588 | // Saves and gets assetID | 590 | // Saves and gets itemID |
589 | UUID itemId; | 591 | UUID itemId; |
590 | 592 | ||
591 | if (group.GetFromAssetID() == UUID.Zero) | 593 | if (group.GetFromItemID() == UUID.Zero) |
592 | { | 594 | { |
593 | m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); | 595 | m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); |
594 | } | 596 | } |
595 | else | 597 | else |
596 | { | 598 | { |
597 | itemId = group.GetFromAssetID(); | 599 | itemId = group.GetFromItemID(); |
598 | } | 600 | } |
599 | 601 | ||
600 | m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); | 602 | m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); |
@@ -611,6 +613,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
611 | remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); | 613 | remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); |
612 | } | 614 | } |
613 | } | 615 | } |
616 | else | ||
617 | m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); | ||
614 | } | 618 | } |
615 | 619 | ||
616 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) | 620 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) |
@@ -1304,7 +1308,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1304 | group.UpdateGroupPosition(pos); | 1308 | group.UpdateGroupPosition(pos); |
1305 | group.RootPart.IsAttachment = false; | 1309 | group.RootPart.IsAttachment = false; |
1306 | group.AbsolutePosition = group.RootPart.AttachedPos; | 1310 | group.AbsolutePosition = group.RootPart.AttachedPos; |
1307 | m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(), group.OwnerID); | 1311 | m_parentScene.UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); |
1308 | group.SetAttachmentPoint(attachmentPoint); | 1312 | group.SetAttachmentPoint(attachmentPoint); |
1309 | 1313 | ||
1310 | } | 1314 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index bc3d5c0..1b541c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -447,22 +447,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
447 | } | 447 | } |
448 | } | 448 | } |
449 | 449 | ||
450 | public void SetFromAssetID(UUID AssetId) | 450 | public void SetFromItemID(UUID AssetId) |
451 | { | 451 | { |
452 | lock (m_parts) | 452 | lock (m_parts) |
453 | { | 453 | { |
454 | foreach (SceneObjectPart part in m_parts.Values) | 454 | foreach (SceneObjectPart part in m_parts.Values) |
455 | { | 455 | { |
456 | part.FromAssetID = AssetId; | 456 | part.FromItemID = AssetId; |
457 | } | 457 | } |
458 | } | 458 | } |
459 | } | 459 | } |
460 | 460 | ||
461 | public UUID GetFromAssetID() | 461 | public UUID GetFromItemID() |
462 | { | 462 | { |
463 | if (m_rootPart != null) | 463 | if (m_rootPart != null) |
464 | { | 464 | { |
465 | return m_rootPart.FromAssetID; | 465 | return m_rootPart.FromItemID; |
466 | } | 466 | } |
467 | return UUID.Zero; | 467 | return UUID.Zero; |
468 | } | 468 | } |
@@ -935,6 +935,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
935 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); | 935 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); |
936 | 936 | ||
937 | avatar.AddAttachment(this); | 937 | avatar.AddAttachment(this); |
938 | m_log.DebugFormat("[SOG]: Added att {0} to avie {1}", UUID, avatar.UUID); | ||
938 | 939 | ||
939 | if (!silent) | 940 | if (!silent) |
940 | { | 941 | { |
@@ -3349,19 +3350,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
3349 | 3350 | ||
3350 | public virtual string ExtraToXmlString() | 3351 | public virtual string ExtraToXmlString() |
3351 | { | 3352 | { |
3352 | return "<ExtraFromAssetID>" + GetFromAssetID().ToString() + "</ExtraFromAssetID>"; | 3353 | return "<ExtraFromItemID>" + GetFromItemID().ToString() + "</ExtraFromItemID>"; |
3353 | } | 3354 | } |
3354 | 3355 | ||
3355 | public virtual void ExtraFromXmlString(string xmlstr) | 3356 | public virtual void ExtraFromXmlString(string xmlstr) |
3356 | { | 3357 | { |
3357 | string id = xmlstr.Substring(xmlstr.IndexOf("<ExtraFromAssetID>")); | 3358 | string id = xmlstr.Substring(xmlstr.IndexOf("<ExtraFromItemID>")); |
3358 | id = xmlstr.Replace("<ExtraFromAssetID>", ""); | 3359 | id = xmlstr.Replace("<ExtraFromItemID>", ""); |
3359 | id = id.Replace("</ExtraFromAssetID>", ""); | 3360 | id = id.Replace("</ExtraFromItemID>", ""); |
3360 | 3361 | ||
3361 | UUID uuid = UUID.Zero; | 3362 | UUID uuid = UUID.Zero; |
3362 | UUID.TryParse(id, out uuid); | 3363 | UUID.TryParse(id, out uuid); |
3363 | 3364 | ||
3364 | SetFromAssetID(uuid); | 3365 | SetFromItemID(uuid); |
3365 | } | 3366 | } |
3366 | #endregion | 3367 | #endregion |
3367 | 3368 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5a74bad..cf716e8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -139,7 +139,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
139 | public uint TimeStampTerse = 0; | 139 | public uint TimeStampTerse = 0; |
140 | 140 | ||
141 | [XmlIgnore] | 141 | [XmlIgnore] |
142 | public UUID FromAssetID = UUID.Zero; | 142 | public UUID FromItemID = UUID.Zero; |
143 | 143 | ||
144 | /// <value> | 144 | /// <value> |
145 | /// The UUID of the user inventory item from which this object was rezzed if this is a root part. | 145 | /// The UUID of the user inventory item from which this object was rezzed if this is a root part. |
@@ -2389,7 +2389,7 @@ if (m_shape != null) { | |||
2389 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, | 2389 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, |
2390 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, | 2390 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, |
2391 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | 2391 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, |
2392 | AttachmentPoint,FromAssetID, Sound, SoundGain, SoundFlags, SoundRadius); | 2392 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius); |
2393 | } | 2393 | } |
2394 | 2394 | ||
2395 | /// <summary> | 2395 | /// <summary> |
@@ -3765,7 +3765,7 @@ if (m_shape != null) { | |||
3765 | (ushort)(m_parentGroup.GetTimeDilation() * | 3765 | (ushort)(m_parentGroup.GetTimeDilation() * |
3766 | (float)ushort.MaxValue), LocalId, lPos, | 3766 | (float)ushort.MaxValue), LocalId, lPos, |
3767 | RotationOffset, Velocity, | 3767 | RotationOffset, Velocity, |
3768 | RotationalVelocity, state, FromAssetID, | 3768 | RotationalVelocity, state, FromItemID, |
3769 | OwnerID, (int)AttachmentPoint); | 3769 | OwnerID, (int)AttachmentPoint); |
3770 | } | 3770 | } |
3771 | 3771 | ||
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4695df7..ff97183 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -652,9 +652,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
652 | RegisterToEvents(); | 652 | RegisterToEvents(); |
653 | SetDirectionVectors(); | 653 | SetDirectionVectors(); |
654 | 654 | ||
655 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); | ||
656 | if (userInfo != null) | ||
657 | userInfo.OnItemReceived += ItemReceived; | ||
658 | } | 655 | } |
659 | 656 | ||
660 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, | 657 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, |
@@ -833,11 +830,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
833 | 830 | ||
834 | m_scene.SwapRootAgentCount(false); | 831 | m_scene.SwapRootAgentCount(false); |
835 | 832 | ||
836 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); | 833 | //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); |
837 | if (userInfo != null) | 834 | //if (userInfo != null) |
838 | userInfo.FetchInventory(); | 835 | // userInfo.FetchInventory(); |
839 | else | 836 | //else |
840 | m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); | 837 | // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); |
841 | 838 | ||
842 | // On the next prim update, all objects will be sent | 839 | // On the next prim update, all objects will be sent |
843 | // | 840 | // |
@@ -1021,7 +1018,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1021 | } | 1018 | } |
1022 | 1019 | ||
1023 | /// <summary> | 1020 | /// <summary> |
1024 | /// Complete Avatar's movement into the region | 1021 | /// Complete Avatar's movement into the region. |
1022 | /// This is called upon a very important packet sent from the client, | ||
1023 | /// so it's client-controlled. Never call this method directly. | ||
1025 | /// </summary> | 1024 | /// </summary> |
1026 | public void CompleteMovement() | 1025 | public void CompleteMovement() |
1027 | { | 1026 | { |
@@ -1042,22 +1041,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1042 | AbsolutePosition = pos; | 1041 | AbsolutePosition = pos; |
1043 | } | 1042 | } |
1044 | 1043 | ||
1045 | if (m_isChildAgent) | 1044 | m_isChildAgent = false; |
1046 | { | 1045 | bool m_flying = ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1047 | m_isChildAgent = false; | 1046 | MakeRootAgent(AbsolutePosition, m_flying); |
1048 | bool m_flying = ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | ||
1049 | MakeRootAgent(AbsolutePosition, m_flying); | ||
1050 | |||
1051 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) | ||
1052 | { | ||
1053 | m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); | ||
1054 | Scene.SendReleaseAgent(m_rootRegionHandle, UUID, m_callbackURI); | ||
1055 | m_callbackURI = null; | ||
1056 | } | ||
1057 | 1047 | ||
1058 | //m_log.DebugFormat("Completed movement"); | 1048 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) |
1049 | { | ||
1050 | m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); | ||
1051 | Scene.SendReleaseAgent(m_rootRegionHandle, UUID, m_callbackURI); | ||
1052 | m_callbackURI = null; | ||
1059 | } | 1053 | } |
1060 | 1054 | ||
1055 | //m_log.DebugFormat("Completed movement"); | ||
1056 | |||
1061 | m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); | 1057 | m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); |
1062 | SendInitialData(); | 1058 | SendInitialData(); |
1063 | 1059 | ||
@@ -3154,6 +3150,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3154 | m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); | 3150 | m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); |
3155 | } | 3151 | } |
3156 | 3152 | ||
3153 | //Attachments | ||
3154 | List<int> attPoints = m_appearance.GetAttachedPoints(); | ||
3155 | if (attPoints != null) | ||
3156 | { | ||
3157 | m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); | ||
3158 | int i = 0; | ||
3159 | AttachmentData[] attachs = new AttachmentData[attPoints.Count]; | ||
3160 | foreach (int point in attPoints) | ||
3161 | { | ||
3162 | attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); | ||
3163 | } | ||
3164 | cAgent.Attachments = attachs; | ||
3165 | } | ||
3166 | |||
3157 | // Animations | 3167 | // Animations |
3158 | try | 3168 | try |
3159 | { | 3169 | { |
@@ -3219,6 +3229,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
3219 | m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); | 3229 | m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); |
3220 | } | 3230 | } |
3221 | 3231 | ||
3232 | // Attachments | ||
3233 | try | ||
3234 | { | ||
3235 | if (cAgent.Attachments != null) | ||
3236 | { | ||
3237 | foreach (AttachmentData att in cAgent.Attachments) | ||
3238 | { | ||
3239 | m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); | ||
3240 | } | ||
3241 | } | ||
3242 | } | ||
3243 | catch { } | ||
3244 | |||
3222 | // Animations | 3245 | // Animations |
3223 | try | 3246 | try |
3224 | { | 3247 | { |
@@ -3729,69 +3752,49 @@ namespace OpenSim.Region.Framework.Scenes | |||
3729 | return flags; | 3752 | return flags; |
3730 | } | 3753 | } |
3731 | 3754 | ||
3732 | private void ItemReceived(UUID itemID) | 3755 | /// <summary> |
3756 | /// RezAttachments. This should only be called upon login on the first region. | ||
3757 | /// Attachment rezzings on crossings and TPs are done in a different way. | ||
3758 | /// </summary> | ||
3759 | public void RezAttachments() | ||
3733 | { | 3760 | { |
3734 | if (IsChildAgent) | ||
3735 | return; | ||
3736 | |||
3737 | if (null == m_appearance) | 3761 | if (null == m_appearance) |
3738 | { | 3762 | { |
3739 | m_log.Warn("[ATTACHMENT] Appearance has not been initialized"); | 3763 | m_log.WarnFormat("[ATTACHMENT] Appearance has not been initialized for agent {0}", UUID); |
3740 | return; | 3764 | return; |
3741 | } | 3765 | } |
3742 | 3766 | ||
3743 | int attachpoint = m_appearance.GetAttachpoint(itemID); | 3767 | List<int> attPoints = m_appearance.GetAttachedPoints(); |
3744 | if (attachpoint == 0) | 3768 | foreach (int p in attPoints) |
3745 | return; | ||
3746 | |||
3747 | UUID asset = m_appearance.GetAttachedAsset(attachpoint); | ||
3748 | if (UUID.Zero == asset) // We have just logged in | ||
3749 | { | 3769 | { |
3770 | UUID itemID = m_appearance.GetAttachedItem(p); | ||
3771 | UUID assetID = m_appearance.GetAttachedAsset(p); | ||
3772 | |||
3773 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down | ||
3774 | // But they're not used anyway, the item is being looked up for now, so let's proceed. | ||
3775 | //if (UUID.Zero == assetID) | ||
3776 | //{ | ||
3777 | // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); | ||
3778 | // continue; | ||
3779 | //} | ||
3780 | |||
3750 | try | 3781 | try |
3751 | { | 3782 | { |
3752 | // Rez from inventory | 3783 | // Rez from inventory |
3753 | asset = m_scene.RezSingleAttachment(ControllingClient, | 3784 | UUID asset = m_scene.RezSingleAttachment(ControllingClient, |
3754 | itemID, (uint)attachpoint); | 3785 | itemID, (uint)p); |
3755 | // Corner case: We are not yet a Scene Entity | 3786 | |
3756 | // Setting attachment info in RezSingleAttachment will fail | 3787 | m_log.InfoFormat("[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", |
3757 | // Set it here | 3788 | p, itemID, assetID, asset); |
3758 | // | ||
3759 | m_appearance.SetAttachment((int)attachpoint, itemID, | ||
3760 | asset); | ||
3761 | m_log.InfoFormat("[ATTACHMENT] Rezzed attachment {0}, inworld asset {1}", | ||
3762 | itemID.ToString(), asset); | ||
3763 | 3789 | ||
3764 | } | 3790 | } |
3765 | catch (Exception e) | 3791 | catch (Exception e) |
3766 | { | 3792 | { |
3767 | m_log.ErrorFormat("[ATTACHMENT] Unable to rez attachment: {0}", e.ToString()); | 3793 | m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); |
3768 | } | 3794 | } |
3769 | 3795 | ||
3770 | return; | ||
3771 | } | 3796 | } |
3772 | 3797 | ||
3773 | SceneObjectPart att = m_scene.GetSceneObjectPart(asset); | ||
3774 | |||
3775 | // If this is null, then the asset has not yet appeared in world | ||
3776 | // so we revisit this when it does | ||
3777 | // | ||
3778 | if (att != null && att.UUID != asset) // Yes. It's really needed | ||
3779 | { | ||
3780 | m_log.DebugFormat("[ATTACHMENT]: Attach from in world: ItemID {0}, Asset ID {1}, Attachment inworld: {2}", itemID.ToString(), asset.ToString(), att.UUID.ToString()); | ||
3781 | |||
3782 | // This will throw if crossing katty-korner | ||
3783 | // So catch it here to avoid the noid | ||
3784 | // | ||
3785 | try | ||
3786 | { | ||
3787 | // Attach from world, if not already attached | ||
3788 | if (att.ParentGroup != null && !att.IsAttachment) | ||
3789 | m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, 0, Quaternion.Identity, att.ParentGroup.AbsolutePosition, false); | ||
3790 | } | ||
3791 | catch (NullReferenceException) | ||
3792 | { | ||
3793 | } | ||
3794 | } | ||
3795 | } | 3798 | } |
3796 | } | 3799 | } |
3797 | } | 3800 | } |