aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
diff options
context:
space:
mode:
authorSean McNamara2011-04-10 18:28:54 -0400
committerSean McNamara2011-04-10 18:28:54 -0400
commit9c0f3c73b1fd56ac145e866af0316a3285ddb689 (patch)
tree03541a853c2ecf5829ac296537b14d4553ad4b2e /OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
parentMerge git://opensimulator.org/git/opensim (diff)
parentminor: remove mono compiler warnings (diff)
downloadopensim-SC_OLD-9c0f3c73b1fd56ac145e866af0316a3285ddb689.zip
opensim-SC_OLD-9c0f3c73b1fd56ac145e866af0316a3285ddb689.tar.gz
opensim-SC_OLD-9c0f3c73b1fd56ac145e866af0316a3285ddb689.tar.bz2
opensim-SC_OLD-9c0f3c73b1fd56ac145e866af0316a3285ddb689.tar.xz
Merge git://opensimulator.org/git/opensim
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs735
1 files changed, 424 insertions, 311 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 798547a..9fbfc34 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Xml;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33 34
@@ -205,11 +206,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
205 public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, 206 public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
206 List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) 207 List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
207 { 208 {
208 // HACK: This is only working for lists containing a single item!
209 // It's just a hack to make this WIP compile and run. Nothing
210 // currently calls this with multiple items.
211 UUID ret = UUID.Zero; 209 UUID ret = UUID.Zero;
212 210
211 // The following code groups the SOG's by owner. No objects
212 // belonging to different people can be coalesced, for obvious
213 // reasons.
213 Dictionary<UUID, List<SceneObjectGroup>> deletes = 214 Dictionary<UUID, List<SceneObjectGroup>> deletes =
214 new Dictionary<UUID, List<SceneObjectGroup>>(); 215 new Dictionary<UUID, List<SceneObjectGroup>>();
215 216
@@ -221,262 +222,329 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
221 deletes[g.OwnerID].Add(g); 222 deletes[g.OwnerID].Add(g);
222 } 223 }
223 224
225 // This is pethod scoped and will be returned. It will be the
226 // last created asset id
227 UUID assetID = UUID.Zero;
228
229 // Each iteration is really a separate asset being created,
230 // with distinct destinations as well.
224 foreach (List<SceneObjectGroup> objlist in deletes.Values) 231 foreach (List<SceneObjectGroup> objlist in deletes.Values)
225 { 232 {
226 foreach (SceneObjectGroup g in objlist) 233 Dictionary<UUID, string> xmlStrings =
227 ret = DeleteToInventory(action, folderID, g, remoteClient); 234 new Dictionary<UUID, string>();
228 }
229 235
230 return ret; 236 foreach (SceneObjectGroup objectGroup in objlist)
231 } 237 {
238 Vector3 inventoryStoredPosition = new Vector3
239 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
240 ? 250
241 : objectGroup.AbsolutePosition.X)
242 ,
243 (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
244 ? 250
245 : objectGroup.AbsolutePosition.X,
246 objectGroup.AbsolutePosition.Z);
232 247
233 private UUID DeleteToInventory(DeRezAction action, UUID folderID, 248 Vector3 originalPosition = objectGroup.AbsolutePosition;
234 SceneObjectGroup objectGroup, IClientAPI remoteClient)
235 {
236 UUID assetID = UUID.Zero;
237 249
238 Vector3 inventoryStoredPosition = new Vector3 250 objectGroup.AbsolutePosition = inventoryStoredPosition;
239 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
240 ? 250
241 : objectGroup.AbsolutePosition.X)
242 ,
243 (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
244 ? 250
245 : objectGroup.AbsolutePosition.X,
246 objectGroup.AbsolutePosition.Z);
247 251
248 Vector3 originalPosition = objectGroup.AbsolutePosition; 252 // Make sure all bits but the ones we want are clear
253 // on take.
254 // This will be applied to the current perms, so
255 // it will do what we want.
256 objectGroup.RootPart.NextOwnerMask &=
257 ((uint)PermissionMask.Copy |
258 (uint)PermissionMask.Transfer |
259 (uint)PermissionMask.Modify);
260 objectGroup.RootPart.NextOwnerMask |=
261 (uint)PermissionMask.Move;
249 262
250 objectGroup.AbsolutePosition = inventoryStoredPosition; 263 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
251 264
252 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); 265 objectGroup.AbsolutePosition = originalPosition;
253 266
254 objectGroup.AbsolutePosition = originalPosition; 267 xmlStrings[objectGroup.UUID] = sceneObjectXml;
268 }
255 269
256 // Get the user info of the item destination 270 string itemXml;
257 //
258 UUID userID = UUID.Zero;
259 271
260 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || 272 if (objlist.Count > 1)
261 action == DeRezAction.SaveToExistingUserInventoryItem) 273 {
262 { 274 float minX, minY, minZ;
263 // Take or take copy require a taker 275 float maxX, maxY, maxZ;
264 // Saving changes requires a local user
265 //
266 if (remoteClient == null)
267 return UUID.Zero;
268 276
269 userID = remoteClient.AgentId; 277 Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist,
270 } 278 out minX, out maxX, out minY, out maxY,
271 else 279 out minZ, out maxZ);
272 {
273 // All returns / deletes go to the object owner
274 //
275 280
276 userID = objectGroup.RootPart.OwnerID; 281 // CreateWrapper
277 } 282 XmlDocument itemDoc = new XmlDocument();
283 XmlElement root = itemDoc.CreateElement("", "CoalescedObject", "");
284 itemDoc.AppendChild(root);
278 285
279 if (userID == UUID.Zero) // Can't proceed 286 // Embed the offsets into the group XML
280 { 287 for ( int i = 0 ; i < objlist.Count ; i++ )
281 return UUID.Zero; 288 {
282 } 289 XmlDocument doc = new XmlDocument();
290 SceneObjectGroup g = objlist[i];
291 doc.LoadXml(xmlStrings[g.UUID]);
292 XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup");
293 e.SetAttribute("offsetx", offsets[i].X.ToString());
294 e.SetAttribute("offsety", offsets[i].Y.ToString());
295 e.SetAttribute("offsetz", offsets[i].Z.ToString());
296
297 XmlNode objectNode = itemDoc.ImportNode(e, true);
298 root.AppendChild(objectNode);
299 }
283 300
284 // If we're returning someone's item, it goes back to the 301 float sizeX = maxX - minX;
285 // owner's Lost And Found folder. 302 float sizeY = maxY - minY;
286 // Delete is treated like return in this case 303 float sizeZ = maxZ - minZ;
287 // Deleting your own items makes them go to trash
288 //
289 304
290 InventoryFolderBase folder = null; 305 root.SetAttribute("x", sizeX.ToString());
291 InventoryItemBase item = null; 306 root.SetAttribute("y", sizeY.ToString());
307 root.SetAttribute("z", sizeZ.ToString());
292 308
293 if (DeRezAction.SaveToExistingUserInventoryItem == action) 309 itemXml = itemDoc.InnerXml;
294 { 310 }
295 item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); 311 else
296 item = m_Scene.InventoryService.GetItem(item); 312 {
313 itemXml = xmlStrings[objlist[0].UUID];
314 }
297 315
298 //item = userInfo.RootFolder.FindItem( 316 // Get the user info of the item destination
299 // objectGroup.RootPart.FromUserInventoryItemID); 317 //
318 UUID userID = UUID.Zero;
300 319
301 if (null == item) 320 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
321 action == DeRezAction.SaveToExistingUserInventoryItem)
322 {
323 // Take or take copy require a taker
324 // Saving changes requires a local user
325 //
326 if (remoteClient == null)
327 return UUID.Zero;
328
329 userID = remoteClient.AgentId;
330 }
331 else
332 {
333 // All returns / deletes go to the object owner
334 //
335
336 userID = objlist[0].RootPart.OwnerID;
337 }
338
339 if (userID == UUID.Zero) // Can't proceed
302 { 340 {
303 m_log.DebugFormat(
304 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
305 objectGroup.Name, objectGroup.UUID);
306 return UUID.Zero; 341 return UUID.Zero;
307 } 342 }
308 } 343
309 else 344 // If we're returning someone's item, it goes back to the
310 { 345 // owner's Lost And Found folder.
311 // Folder magic 346 // Delete is treated like return in this case
347 // Deleting your own items makes them go to trash
312 // 348 //
313 if (action == DeRezAction.Delete) 349
350 InventoryFolderBase folder = null;
351 InventoryItemBase item = null;
352
353 if (DeRezAction.SaveToExistingUserInventoryItem == action)
314 { 354 {
315 // Deleting someone else's item 355 item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID);
316 // 356 item = m_Scene.InventoryService.GetItem(item);
317 if (remoteClient == null ||
318 objectGroup.OwnerID != remoteClient.AgentId)
319 {
320 357
321 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 358 //item = userInfo.RootFolder.FindItem(
322 } 359 // objectGroup.RootPart.FromUserInventoryItemID);
323 else 360
361 if (null == item)
324 { 362 {
325 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); 363 m_log.DebugFormat(
364 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
365 objlist[0].Name, objlist[0].UUID);
366 return UUID.Zero;
326 } 367 }
327 } 368 }
328 else if (action == DeRezAction.Return) 369 else
329 { 370 {
330 371 // Folder magic
331 // Dump to lost + found unconditionally
332 // 372 //
333 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
334 }
335
336 if (folderID == UUID.Zero && folder == null)
337 {
338 if (action == DeRezAction.Delete) 373 if (action == DeRezAction.Delete)
339 { 374 {
340 // Deletes go to trash by default 375 // Deleting someone else's item
341 // 376 //
342 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
343 }
344 else
345 {
346 if (remoteClient == null || 377 if (remoteClient == null ||
347 objectGroup.OwnerID != remoteClient.AgentId) 378 objlist[0].OwnerID != remoteClient.AgentId)
348 { 379 {
349 // Taking copy of another person's item. Take to 380
350 // Objects folder. 381 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
351 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
352 } 382 }
353 else 383 else
354 { 384 {
355 // Catch all. Use lost & found 385 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
386 }
387 }
388 else if (action == DeRezAction.Return)
389 {
390
391 // Dump to lost + found unconditionally
392 //
393 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
394 }
395
396 if (folderID == UUID.Zero && folder == null)
397 {
398 if (action == DeRezAction.Delete)
399 {
400 // Deletes go to trash by default
356 // 401 //
402 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
403 }
404 else
405 {
406 if (remoteClient == null ||
407 objlist[0].OwnerID != remoteClient.AgentId)
408 {
409 // Taking copy of another person's item. Take to
410 // Objects folder.
411 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
412 }
413 else
414 {
415 // Catch all. Use lost & found
416 //
357 417
358 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 418 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
419 }
359 } 420 }
360 } 421 }
361 }
362 422
363 // Override and put into where it came from, if it came 423 // Override and put into where it came from, if it came
364 // from anywhere in inventory 424 // from anywhere in inventory
365 // 425 //
366 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) 426 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
367 {
368 if (objectGroup.RootPart.FromFolderID != UUID.Zero)
369 { 427 {
370 InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID); 428 if (objlist[0].RootPart.FromFolderID != UUID.Zero)
371 folder = m_Scene.InventoryService.GetFolder(f); 429 {
430 InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID);
431 folder = m_Scene.InventoryService.GetFolder(f);
432 }
372 } 433 }
373 }
374 434
375 if (folder == null) // None of the above 435 if (folder == null) // None of the above
376 { 436 {
377 folder = new InventoryFolderBase(folderID); 437 folder = new InventoryFolderBase(folderID);
378 438
379 if (folder == null) // Nowhere to put it 439 if (folder == null) // Nowhere to put it
440 {
441 return UUID.Zero;
442 }
443 }
444
445 item = new InventoryItemBase();
446 // Can't know creator is the same, so null it in inventory
447 if (objlist.Count > 1)
448 item.CreatorId = UUID.Zero.ToString();
449 else
450 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
451 item.ID = UUID.Random();
452 item.InvType = (int)InventoryType.Object;
453 item.Folder = folder.ID;
454 item.Owner = userID;
455 if (objlist.Count > 1)
380 { 456 {
381 return UUID.Zero; 457 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
458 }
459 else
460 {
461 item.SaleType = objlist[0].RootPart.ObjectSaleType;
462 item.SalePrice = objlist[0].RootPart.SalePrice;
382 } 463 }
383 } 464 }
384 465
385 item = new InventoryItemBase(); 466 AssetBase asset = CreateAsset(
386 item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); 467 objlist[0].GetPartName(objlist[0].RootPart.LocalId),
387 item.CreatorData = objectGroup.RootPart.CreatorData; 468 objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
388 item.ID = UUID.Random(); 469 (sbyte)AssetType.Object,
389 item.InvType = (int)InventoryType.Object; 470 Utils.StringToBytes(itemXml),
390 item.Folder = folder.ID; 471 objlist[0].OwnerID.ToString());
391 item.Owner = userID; 472 m_Scene.AssetService.Store(asset);
392 } 473 assetID = asset.FullID;
393
394 AssetBase asset = CreateAsset(
395 objectGroup.GetPartName(objectGroup.RootPart.LocalId),
396 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
397 (sbyte)AssetType.Object,
398 Utils.StringToBytes(sceneObjectXml),
399 objectGroup.OwnerID.ToString());
400 m_Scene.AssetService.Store(asset);
401 assetID = asset.FullID;
402
403 if (DeRezAction.SaveToExistingUserInventoryItem == action)
404 {
405 item.AssetID = asset.FullID;
406 m_Scene.InventoryService.UpdateItem(item);
407 }
408 else
409 {
410 item.AssetID = asset.FullID;
411 474
412 if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 475 if (DeRezAction.SaveToExistingUserInventoryItem == action)
413 { 476 {
414 uint perms = objectGroup.GetEffectivePermissions(); 477 item.AssetID = asset.FullID;
415 uint nextPerms = (perms & 7) << 13; 478 m_Scene.InventoryService.UpdateItem(item);
416 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
417 perms &= ~(uint)PermissionMask.Copy;
418 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
419 perms &= ~(uint)PermissionMask.Transfer;
420 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
421 perms &= ~(uint)PermissionMask.Modify;
422
423 // Make sure all bits but the ones we want are clear
424 // on take.
425 // This will be applied to the current perms, so
426 // it will do what we want.
427 objectGroup.RootPart.NextOwnerMask &=
428 ((uint)PermissionMask.Copy |
429 (uint)PermissionMask.Transfer |
430 (uint)PermissionMask.Modify);
431 objectGroup.RootPart.NextOwnerMask |=
432 (uint)PermissionMask.Move;
433
434 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
435 item.CurrentPermissions = item.BasePermissions;
436 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
437 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
438 item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
439
440 item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
441 } 479 }
442 else 480 else
443 { 481 {
444 item.BasePermissions = objectGroup.GetEffectivePermissions(); 482 item.AssetID = asset.FullID;
445 item.CurrentPermissions = objectGroup.GetEffectivePermissions();
446 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
447 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
448 item.GroupPermissions = objectGroup.RootPart.GroupMask;
449 483
450 item.CurrentPermissions &= 484 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
451 ((uint)PermissionMask.Copy | 485 foreach (SceneObjectGroup grp in objlist)
452 (uint)PermissionMask.Transfer | 486 effectivePerms &= grp.GetEffectivePermissions();
453 (uint)PermissionMask.Modify | 487 effectivePerms |= (uint)PermissionMask.Move;
454 (uint)PermissionMask.Move | 488
455 7); // Preserve folded permissions 489 if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
456 } 490 {
491 uint perms = effectivePerms;
492 uint nextPerms = (perms & 7) << 13;
493 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
494 perms &= ~(uint)PermissionMask.Copy;
495 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
496 perms &= ~(uint)PermissionMask.Transfer;
497 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
498 perms &= ~(uint)PermissionMask.Modify;
499
500 item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask;
501 item.CurrentPermissions = item.BasePermissions;
502 item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask;
503 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask;
504 item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask;
505
506 // Magic number badness. Maybe this deserves an enum.
507 // bit 4 (16) is the "Slam" bit, it means treat as passed
508 // and apply next owner perms on rez
509 item.CurrentPermissions |= 16; // Slam!
510 }
511 else
512 {
513 item.BasePermissions = effectivePerms;
514 item.CurrentPermissions = effectivePerms;
515 item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms;
516 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms;
517 item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms;
518
519 item.CurrentPermissions &=
520 ((uint)PermissionMask.Copy |
521 (uint)PermissionMask.Transfer |
522 (uint)PermissionMask.Modify |
523 (uint)PermissionMask.Move |
524 7); // Preserve folded permissions
525 }
457 526
458 // TODO: add the new fields (Flags, Sale info, etc) 527 item.CreationDate = Util.UnixTimeSinceEpoch();
459 item.CreationDate = Util.UnixTimeSinceEpoch(); 528 item.Description = asset.Description;
460 item.Description = asset.Description; 529 item.Name = asset.Name;
461 item.Name = asset.Name; 530 item.AssetType = asset.Type;
462 item.AssetType = asset.Type;
463 531
464 m_Scene.AddInventoryItem(item); 532 m_Scene.AddInventoryItem(item);
465 533
466 if (remoteClient != null && item.Owner == remoteClient.AgentId) 534 if (remoteClient != null && item.Owner == remoteClient.AgentId)
467 {
468 remoteClient.SendInventoryItemCreateUpdate(item, 0);
469 }
470 else
471 {
472 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
473 if (notifyUser != null)
474 { 535 {
475 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); 536 remoteClient.SendInventoryItemCreateUpdate(item, 0);
537 }
538 else
539 {
540 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
541 if (notifyUser != null)
542 {
543 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
544 }
476 } 545 }
477 } 546 }
478 } 547 }
479
480 return assetID; 548 return assetID;
481 } 549 }
482 550
@@ -531,6 +599,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
531 599
532 AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); 600 AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
533 601
602 SceneObjectGroup group = null;
603
534 if (rezAsset != null) 604 if (rezAsset != null)
535 { 605 {
536 UUID itemId = UUID.Zero; 606 UUID itemId = UUID.Zero;
@@ -539,34 +609,78 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
539 // item that it came from. This allows us to enable 'save object to inventory' 609 // item that it came from. This allows us to enable 'save object to inventory'
540 if (!m_Scene.Permissions.BypassPermissions()) 610 if (!m_Scene.Permissions.BypassPermissions())
541 { 611 {
542 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) 612 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
543 { 613 {
544 itemId = item.ID; 614 itemId = item.ID;
545 } 615 }
546 } 616 }
547 else 617 else
548 { 618 {
549 // Brave new fullperm world 619 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
550 // 620 {
551 itemId = item.ID; 621 // Brave new fullperm world
622 itemId = item.ID;
623 }
552 } 624 }
553 625
554 string xmlData = Utils.BytesToString(rezAsset.Data); 626 string xmlData = Utils.BytesToString(rezAsset.Data);
555 SceneObjectGroup group 627 List<SceneObjectGroup> objlist =
556 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); 628 new List<SceneObjectGroup>();
629 List<Vector3> veclist = new List<Vector3>();
630
631 XmlDocument doc = new XmlDocument();
632 doc.LoadXml(xmlData);
633 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
634 if (e == null || attachment) // Single
635 {
636 SceneObjectGroup g =
637 SceneObjectSerializer.FromOriginalXmlFormat(
638 itemId, xmlData);
639 objlist.Add(g);
640 veclist.Add(new Vector3(0, 0, 0));
557 641
558 Util.FireAndForget(delegate { AddUserData(group); }); 642 float offsetHeight = 0;
559 643 pos = m_Scene.GetNewRezLocation(
560 group.RootPart.FromFolderID = item.Folder; 644 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
645 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
646 pos.Z += offsetHeight;
647 }
648 else
649 {
650 XmlElement coll = (XmlElement)e;
651 float bx = Convert.ToSingle(coll.GetAttribute("x"));
652 float by = Convert.ToSingle(coll.GetAttribute("y"));
653 float bz = Convert.ToSingle(coll.GetAttribute("z"));
654 Vector3 bbox = new Vector3(bx, by, bz);
561 655
562 // If it's rezzed in world, select it. Much easier to 656 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
563 // find small items. 657 RayTargetID, Quaternion.Identity,
564 // 658 BypassRayCast, bRayEndIsIntersection, true,
565 if (!attachment) 659 bbox, false);
566 group.RootPart.CreateSelected = true; 660
661 pos -= bbox / 2;
662
663 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
664 foreach (XmlNode n in groups)
665 {
666 SceneObjectGroup g =
667 SceneObjectSerializer.FromOriginalXmlFormat(
668 itemId, n.OuterXml);
669 objlist.Add(g);
670 XmlElement el = (XmlElement)n;
671 float x = Convert.ToSingle(el.GetAttribute("offsetx"));
672 float y = Convert.ToSingle(el.GetAttribute("offsety"));
673 float z = Convert.ToSingle(el.GetAttribute("offsetz"));
674 veclist.Add(new Vector3(x, y, z));
675 }
676 }
677
678 int primcount = 0;
679 foreach (SceneObjectGroup g in objlist)
680 primcount += g.PrimCount;
567 681
568 if (!m_Scene.Permissions.CanRezObject( 682 if (!m_Scene.Permissions.CanRezObject(
569 group.PrimCount, remoteClient.AgentId, pos) 683 primcount, remoteClient.AgentId, pos)
570 && !attachment) 684 && !attachment)
571 { 685 {
572 // The client operates in no fail mode. It will 686 // The client operates in no fail mode. It will
@@ -579,131 +693,131 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
579 return null; 693 return null;
580 } 694 }
581 695
582 group.ResetIDs(); 696 for (int i = 0 ; i < objlist.Count ; i++ )
583
584 if (attachment)
585 { 697 {
586 group.RootPart.Flags |= PrimFlags.Phantom; 698 group = objlist[i];
587 group.RootPart.IsAttachment = true; 699
700 Vector3 storedPosition = group.AbsolutePosition;
701 if (group.UUID == UUID.Zero)
702 {
703 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3");
704 }
705 group.RootPart.FromFolderID = item.Folder;
706
707 // If it's rezzed in world, select it. Much easier to
708 // find small items.
709 //
710 if (!attachment)
711 {
712 group.RootPart.CreateSelected = true;
713 foreach (SceneObjectPart child in group.Parts)
714 child.CreateSelected = true;
715 }
716 group.ResetIDs();
717
718 if (attachment)
719 {
720 group.RootPart.Flags |= PrimFlags.Phantom;
721 group.RootPart.IsAttachment = true;
722 }
588 723
589 // If we're rezzing an attachment then don't ask 724 // If we're rezzing an attachment then don't ask
590 // AddNewSceneObject() to update the client since 725 // AddNewSceneObject() to update the client since
591 // we'll be doing that later on. Scheduling more 726 // we'll be doing that later on. Scheduling more than
592 // than one full update during the attachment 727 // one full update during the attachment
593 // process causes some clients to fail to display 728 // process causes some clients to fail to display the
594 // the attachment properly. 729 // attachment properly.
595 // Also, don't persist attachments.
596 m_Scene.AddNewSceneObject(group, false, false);
597 }
598 else
599 {
600 m_Scene.AddNewSceneObject(group, true, false); 730 m_Scene.AddNewSceneObject(group, true, false);
601 }
602 731
603 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); 732 // if attachment we set it's asset id so object updates
604 // if attachment we set it's asset id so object updates can reflect that 733 // can reflect that, if not, we set it's position in world.
605 // if not, we set it's position in world. 734 if (!attachment)
606 if (!attachment) 735 {
607 { 736 group.ScheduleGroupForFullUpdate();
608 group.ScheduleGroupForFullUpdate(); 737
609 738 group.AbsolutePosition = pos + veclist[i];
610 float offsetHeight = 0; 739 }
611 pos = m_Scene.GetNewRezLocation( 740 else
612 RayStart, RayEnd, RayTargetID, Quaternion.Identity, 741 {
613 BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); 742 group.SetFromItemID(itemID);
614 pos.Z += offsetHeight; 743 }
615 group.AbsolutePosition = pos;
616 // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);
617
618 }
619 else
620 {
621 group.SetFromItemID(itemID);
622 }
623 744
624 SceneObjectPart rootPart = null; 745 SceneObjectPart rootPart = null;
625 try
626 {
627 rootPart = group.GetChildPart(group.UUID);
628 }
629 catch (NullReferenceException)
630 {
631 string isAttachment = "";
632 746
633 if (attachment) 747 try
634 isAttachment = " Object was an attachment"; 748 {
749 rootPart = group.GetChildPart(group.UUID);
750 }
751 catch (NullReferenceException)
752 {
753 string isAttachment = "";
635 754
636 m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); 755 if (attachment)
637 } 756 isAttachment = " Object was an attachment";
638 757
639 // Since renaming the item in the inventory does not affect the name stored 758 m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
640 // in the serialization, transfer the correct name from the inventory to the 759 }
641 // object itself before we rez.
642 rootPart.Name = item.Name;
643 rootPart.Description = item.Description;
644 760
645 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) 761 // Since renaming the item in the inventory does not
646 { 762 // affect the name stored in the serialization, transfer
763 // the correct name from the inventory to the
764 // object itself before we rez.
765 rootPart.Name = item.Name;
766 rootPart.Description = item.Description;
647 rootPart.ObjectSaleType = item.SaleType; 767 rootPart.ObjectSaleType = item.SaleType;
648 rootPart.SalePrice = item.SalePrice; 768 rootPart.SalePrice = item.SalePrice;
649 }
650 769
651 group.SetGroup(remoteClient.ActiveGroupId, remoteClient); 770 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
652 if ((rootPart.OwnerID != item.Owner) || 771 if ((rootPart.OwnerID != item.Owner) ||
653 (item.CurrentPermissions & 16) != 0 || // Magic number 772 (item.CurrentPermissions & 16) != 0)
654 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
655 {
656 //Need to kill the for sale here
657 rootPart.ObjectSaleType = 0;
658 rootPart.SalePrice = 10;
659
660 if (m_Scene.Permissions.PropagatePermissions())
661 { 773 {
662 foreach (SceneObjectPart part in group.Parts) 774 //Need to kill the for sale here
775 rootPart.ObjectSaleType = 0;
776 rootPart.SalePrice = 10;
777
778 if (m_Scene.Permissions.PropagatePermissions())
663 { 779 {
664 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) 780 foreach (SceneObjectPart part in group.Parts)
665 part.EveryoneMask = item.EveryOnePermissions; 781 {
666 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) 782 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
667 part.NextOwnerMask = item.NextPermissions; 783 {
668 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) 784 part.EveryoneMask = item.EveryOnePermissions;
669 part.GroupMask = item.GroupPermissions; 785 part.NextOwnerMask = item.NextPermissions;
786 }
787 part.GroupMask = 0; // DO NOT propagate here
788 }
789
790 group.ApplyNextOwnerPermissions();
670 } 791 }
671
672 group.ApplyNextOwnerPermissions();
673 } 792 }
674 }
675 793
676 foreach (SceneObjectPart part in group.Parts) 794 foreach (SceneObjectPart part in group.Parts)
677 {
678 if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0)
679 { 795 {
680 part.LastOwnerID = part.OwnerID; 796 if ((part.OwnerID != item.Owner) ||
681 part.OwnerID = item.Owner; 797 (item.CurrentPermissions & 16) != 0)
682 part.Inventory.ChangeInventoryOwner(item.Owner); 798 {
683 part.GroupMask = 0; // DO NOT propagate here 799 part.LastOwnerID = part.OwnerID;
684 } 800 part.OwnerID = item.Owner;
685 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) 801 part.Inventory.ChangeInventoryOwner(item.Owner);
802 part.GroupMask = 0; // DO NOT propagate here
803 }
686 part.EveryoneMask = item.EveryOnePermissions; 804 part.EveryoneMask = item.EveryOnePermissions;
687 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
688 part.NextOwnerMask = item.NextPermissions; 805 part.NextOwnerMask = item.NextPermissions;
689 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) 806 }
690 part.GroupMask = item.GroupPermissions;
691 }
692 807
693 rootPart.TrimPermissions(); 808 rootPart.TrimPermissions();
694 809
695 if (!attachment) 810 if (!attachment)
696 {
697 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
698 { 811 {
699 group.ClearPartAttachmentData(); 812 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
700 } 813 group.ClearPartAttachmentData();
701 814
702 // Fire on_rez 815 // Fire on_rez
703 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); 816 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
704 rootPart.ParentGroup.ResumeScripts(); 817 rootPart.ParentGroup.ResumeScripts();
705 818
706 rootPart.ScheduleFullUpdate(); 819 rootPart.ScheduleFullUpdate();
820 }
707 } 821 }
708 822
709 if (!m_Scene.Permissions.BypassPermissions()) 823 if (!m_Scene.Permissions.BypassPermissions())
@@ -721,9 +835,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
721 } 835 }
722 } 836 }
723 } 837 }
724
725 return rootPart.ParentGroup;
726 } 838 }
839 return group;
727 } 840 }
728 841
729 return null; 842 return null;