diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 868 |
1 files changed, 456 insertions, 412 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index a98ce85..654e202 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
325 | } | 325 | } |
326 | } | 326 | } |
327 | 327 | ||
328 | // This is pethod scoped and will be returned. It will be the | 328 | // This is method scoped and will be returned. It will be the |
329 | // last created asset id | 329 | // last created asset id |
330 | UUID assetID = UUID.Zero; | 330 | UUID assetID = UUID.Zero; |
331 | 331 | ||
@@ -354,9 +354,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
354 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); | 354 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); |
355 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); | 355 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); |
356 | 356 | ||
357 | Dictionary<UUID, string> xmlStrings = | ||
358 | new Dictionary<UUID, string>(); | ||
359 | |||
360 | foreach (SceneObjectGroup objectGroup in objlist) | 357 | foreach (SceneObjectGroup objectGroup in objlist) |
361 | { | 358 | { |
362 | Vector3 inventoryStoredPosition = new Vector3 | 359 | Vector3 inventoryStoredPosition = new Vector3 |
@@ -369,12 +366,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
369 | : objectGroup.AbsolutePosition.Y, | 366 | : objectGroup.AbsolutePosition.Y, |
370 | objectGroup.AbsolutePosition.Z); | 367 | objectGroup.AbsolutePosition.Z); |
371 | 368 | ||
372 | Vector3 originalPosition = objectGroup.AbsolutePosition; | 369 | originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; |
373 | |||
374 | // Restore attachment data after trip through the sim | ||
375 | if (objectGroup.RootPart.AttachPoint > 0) | ||
376 | inventoryStoredPosition = objectGroup.RootPart.AttachOffset; | ||
377 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; | ||
378 | 370 | ||
379 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 371 | objectGroup.AbsolutePosition = inventoryStoredPosition; |
380 | 372 | ||
@@ -388,60 +380,159 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
388 | (uint)PermissionMask.Modify); | 380 | (uint)PermissionMask.Modify); |
389 | objectGroup.RootPart.NextOwnerMask |= | 381 | objectGroup.RootPart.NextOwnerMask |= |
390 | (uint)PermissionMask.Move; | 382 | (uint)PermissionMask.Move; |
383 | |||
384 | coa.Add(objectGroup); | ||
385 | } | ||
391 | 386 | ||
392 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); | 387 | string itemXml; |
393 | 388 | ||
394 | objectGroup.AbsolutePosition = originalPosition; | 389 | if (objlist.Count > 1) |
390 | itemXml = CoalescedSceneObjectsSerializer.ToXml(coa); | ||
391 | else | ||
392 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]); | ||
393 | |||
394 | // Restore the position of each group now that it has been stored to inventory. | ||
395 | foreach (SceneObjectGroup objectGroup in objlist) | ||
396 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; | ||
395 | 397 | ||
396 | xmlStrings[objectGroup.UUID] = sceneObjectXml; | 398 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); |
399 | if (item == null) | ||
400 | return UUID.Zero; | ||
401 | |||
402 | // Can't know creator is the same, so null it in inventory | ||
403 | if (objlist.Count > 1) | ||
404 | { | ||
405 | item.CreatorId = UUID.Zero.ToString(); | ||
406 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
397 | } | 407 | } |
408 | else | ||
409 | { | ||
410 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
411 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | ||
412 | item.SalePrice = objlist[0].RootPart.SalePrice; | ||
413 | } | ||
398 | 414 | ||
399 | string itemXml; | 415 | AssetBase asset = CreateAsset( |
416 | objlist[0].GetPartName(objlist[0].RootPart.LocalId), | ||
417 | objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), | ||
418 | (sbyte)AssetType.Object, | ||
419 | Utils.StringToBytes(itemXml), | ||
420 | objlist[0].OwnerID.ToString()); | ||
421 | m_Scene.AssetService.Store(asset); | ||
422 | |||
423 | item.AssetID = asset.FullID; | ||
424 | assetID = asset.FullID; | ||
400 | 425 | ||
401 | if (objlist.Count > 1) | 426 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
402 | { | 427 | { |
403 | float minX, minY, minZ; | 428 | m_Scene.InventoryService.UpdateItem(item); |
404 | float maxX, maxY, maxZ; | 429 | } |
430 | else | ||
431 | { | ||
432 | AddPermissions(item, objlist[0], objlist, remoteClient); | ||
405 | 433 | ||
406 | Vector3[] offsets = Scene.GetCombinedBoundingBox(objlist, | 434 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
407 | out minX, out maxX, out minY, out maxY, | 435 | item.Description = asset.Description; |
408 | out minZ, out maxZ); | 436 | item.Name = asset.Name; |
437 | item.AssetType = asset.Type; | ||
409 | 438 | ||
410 | // CreateWrapper | 439 | m_Scene.AddInventoryItem(item); |
411 | XmlDocument itemDoc = new XmlDocument(); | ||
412 | XmlElement root = itemDoc.CreateElement("", "CoalescedObject", ""); | ||
413 | itemDoc.AppendChild(root); | ||
414 | 440 | ||
415 | // Embed the offsets into the group XML | 441 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
416 | for ( int i = 0 ; i < objlist.Count ; i++ ) | ||
417 | { | 442 | { |
418 | XmlDocument doc = new XmlDocument(); | 443 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
419 | SceneObjectGroup g = objlist[i]; | 444 | } |
420 | doc.LoadXml(xmlStrings[g.UUID]); | 445 | else |
421 | XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); | 446 | { |
422 | e.SetAttribute("offsetx", offsets[i].X.ToString()); | 447 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); |
423 | e.SetAttribute("offsety", offsets[i].Y.ToString()); | 448 | if (notifyUser != null) |
424 | e.SetAttribute("offsetz", offsets[i].Z.ToString()); | 449 | { |
425 | 450 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | |
426 | XmlNode objectNode = itemDoc.ImportNode(e, true); | 451 | } |
427 | root.AppendChild(objectNode); | ||
428 | } | 452 | } |
453 | } | ||
454 | |||
455 | // This is a hook to do some per-asset post-processing for subclasses that need that | ||
456 | if (remoteClient != null) | ||
457 | ExportAsset(remoteClient.AgentId, assetID); | ||
458 | |||
459 | return assetID; | ||
460 | } | ||
429 | 461 | ||
430 | float sizeX = maxX - minX; | 462 | protected virtual void ExportAsset(UUID agentID, UUID assetID) |
431 | float sizeY = maxY - minY; | 463 | { |
432 | float sizeZ = maxZ - minZ; | 464 | // nothing to do here |
465 | } | ||
433 | 466 | ||
434 | root.SetAttribute("x", sizeX.ToString()); | 467 | /// <summary> |
435 | root.SetAttribute("y", sizeY.ToString()); | 468 | /// Add relevant permissions for an object to the item. |
436 | root.SetAttribute("z", sizeZ.ToString()); | 469 | /// </summary> |
470 | /// <param name="item"></param> | ||
471 | /// <param name="so"></param> | ||
472 | /// <param name="objsForEffectivePermissions"></param> | ||
473 | /// <param name="remoteClient"></param> | ||
474 | /// <returns></returns> | ||
475 | protected InventoryItemBase AddPermissions( | ||
476 | InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, | ||
477 | IClientAPI remoteClient) | ||
478 | { | ||
479 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; | ||
480 | foreach (SceneObjectGroup grp in objsForEffectivePermissions) | ||
481 | effectivePerms &= grp.GetEffectivePermissions(); | ||
482 | effectivePerms |= (uint)PermissionMask.Move; | ||
437 | 483 | ||
438 | itemXml = itemDoc.InnerXml; | 484 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) |
485 | { | ||
486 | uint perms = effectivePerms; | ||
487 | uint nextPerms = (perms & 7) << 13; | ||
488 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
489 | perms &= ~(uint)PermissionMask.Copy; | ||
490 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
491 | perms &= ~(uint)PermissionMask.Transfer; | ||
492 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
493 | perms &= ~(uint)PermissionMask.Modify; | ||
494 | |||
495 | item.BasePermissions = perms & so.RootPart.NextOwnerMask; | ||
496 | item.CurrentPermissions = item.BasePermissions; | ||
497 | item.NextPermissions = perms & so.RootPart.NextOwnerMask; | ||
498 | item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; | ||
499 | item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; | ||
500 | |||
501 | // Magic number badness. Maybe this deserves an enum. | ||
502 | // bit 4 (16) is the "Slam" bit, it means treat as passed | ||
503 | // and apply next owner perms on rez | ||
504 | item.CurrentPermissions |= 16; // Slam! | ||
439 | } | 505 | } |
440 | else | 506 | else |
441 | { | 507 | { |
442 | itemXml = xmlStrings[objlist[0].UUID]; | 508 | item.BasePermissions = effectivePerms; |
443 | } | 509 | item.CurrentPermissions = effectivePerms; |
510 | item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms; | ||
511 | item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms; | ||
512 | item.GroupPermissions = so.RootPart.GroupMask & effectivePerms; | ||
444 | 513 | ||
514 | item.CurrentPermissions &= | ||
515 | ((uint)PermissionMask.Copy | | ||
516 | (uint)PermissionMask.Transfer | | ||
517 | (uint)PermissionMask.Modify | | ||
518 | (uint)PermissionMask.Move | | ||
519 | 7); // Preserve folded permissions | ||
520 | } | ||
521 | |||
522 | return item; | ||
523 | } | ||
524 | |||
525 | /// <summary> | ||
526 | /// Create an item using details for the given scene object. | ||
527 | /// </summary> | ||
528 | /// <param name="action"></param> | ||
529 | /// <param name="remoteClient"></param> | ||
530 | /// <param name="so"></param> | ||
531 | /// <param name="folderID"></param> | ||
532 | /// <returns></returns> | ||
533 | protected InventoryItemBase CreateItemForObject( | ||
534 | DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID) | ||
535 | { | ||
445 | // Get the user info of the item destination | 536 | // Get the user info of the item destination |
446 | // | 537 | // |
447 | UUID userID = UUID.Zero; | 538 | UUID userID = UUID.Zero; |
@@ -453,7 +544,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
453 | // Saving changes requires a local user | 544 | // Saving changes requires a local user |
454 | // | 545 | // |
455 | if (remoteClient == null) | 546 | if (remoteClient == null) |
456 | return UUID.Zero; | 547 | return null; |
457 | 548 | ||
458 | userID = remoteClient.AgentId; | 549 | userID = remoteClient.AgentId; |
459 | } | 550 | } |
@@ -461,13 +552,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
461 | { | 552 | { |
462 | // All returns / deletes go to the object owner | 553 | // All returns / deletes go to the object owner |
463 | // | 554 | // |
464 | 555 | userID = so.RootPart.OwnerID; | |
465 | userID = objlist[0].RootPart.OwnerID; | ||
466 | } | 556 | } |
467 | 557 | ||
468 | if (userID == UUID.Zero) // Can't proceed | 558 | if (userID == UUID.Zero) // Can't proceed |
469 | { | 559 | { |
470 | return UUID.Zero; | 560 | return null; |
471 | } | 561 | } |
472 | 562 | ||
473 | // If we're returning someone's item, it goes back to the | 563 | // If we're returning someone's item, it goes back to the |
@@ -475,13 +565,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
475 | // Delete is treated like return in this case | 565 | // Delete is treated like return in this case |
476 | // Deleting your own items makes them go to trash | 566 | // Deleting your own items makes them go to trash |
477 | // | 567 | // |
478 | 568 | ||
479 | InventoryFolderBase folder = null; | 569 | InventoryFolderBase folder = null; |
480 | InventoryItemBase item = null; | 570 | InventoryItemBase item = null; |
481 | 571 | ||
482 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 572 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
483 | { | 573 | { |
484 | item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); | 574 | item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID); |
485 | item = m_Scene.InventoryService.GetItem(item); | 575 | item = m_Scene.InventoryService.GetItem(item); |
486 | 576 | ||
487 | //item = userInfo.RootFolder.FindItem( | 577 | //item = userInfo.RootFolder.FindItem( |
@@ -491,8 +581,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
491 | { | 581 | { |
492 | m_log.DebugFormat( | 582 | m_log.DebugFormat( |
493 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | 583 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", |
494 | objlist[0].Name, objlist[0].UUID); | 584 | so.Name, so.UUID); |
495 | return UUID.Zero; | 585 | |
586 | return null; | ||
496 | } | 587 | } |
497 | } | 588 | } |
498 | else | 589 | else |
@@ -504,19 +595,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
504 | // Deleting someone else's item | 595 | // Deleting someone else's item |
505 | // | 596 | // |
506 | if (remoteClient == null || | 597 | if (remoteClient == null || |
507 | objlist[0].OwnerID != remoteClient.AgentId) | 598 | so.OwnerID != remoteClient.AgentId) |
508 | { | 599 | { |
509 | |||
510 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 600 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
511 | } | 601 | } |
512 | else | 602 | else |
513 | { | 603 | { |
514 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | 604 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); |
515 | } | 605 | } |
516 | } | 606 | } |
517 | else if (action == DeRezAction.Return) | 607 | else if (action == DeRezAction.Return) |
518 | { | 608 | { |
519 | |||
520 | // Dump to lost + found unconditionally | 609 | // Dump to lost + found unconditionally |
521 | // | 610 | // |
522 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 611 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
@@ -532,8 +621,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
532 | } | 621 | } |
533 | else | 622 | else |
534 | { | 623 | { |
535 | if (remoteClient == null || | 624 | if (remoteClient == null || so.OwnerID != remoteClient.AgentId) |
536 | objlist[0].OwnerID != remoteClient.AgentId) | ||
537 | { | 625 | { |
538 | // Taking copy of another person's item. Take to | 626 | // Taking copy of another person's item. Take to |
539 | // Objects folder. | 627 | // Objects folder. |
@@ -554,9 +642,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
554 | // | 642 | // |
555 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) | 643 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) |
556 | { | 644 | { |
557 | if (objlist[0].RootPart.FromFolderID != UUID.Zero && objlist[0].OwnerID == remoteClient.AgentId) | 645 | if (so.RootPart.FromFolderID != UUID.Zero) |
558 | { | 646 | { |
559 | InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); | 647 | InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID); |
560 | folder = m_Scene.InventoryService.GetFolder(f); | 648 | folder = m_Scene.InventoryService.GetFolder(f); |
561 | } | 649 | } |
562 | } | 650 | } |
@@ -567,380 +655,375 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
567 | 655 | ||
568 | if (folder == null) // Nowhere to put it | 656 | if (folder == null) // Nowhere to put it |
569 | { | 657 | { |
570 | return UUID.Zero; | 658 | return null; |
571 | } | 659 | } |
572 | } | 660 | } |
573 | 661 | ||
574 | item = new InventoryItemBase(); | 662 | item = new InventoryItemBase(); |
575 | // Can't know creator is the same, so null it in inventory | ||
576 | if (objlist.Count > 1) | ||
577 | { | ||
578 | item.CreatorId = UUID.Zero.ToString(); | ||
579 | item.CreatorData = String.Empty; | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
584 | item.CreatorData = objlist[0].RootPart.CreatorData; | ||
585 | } | ||
586 | item.ID = UUID.Random(); | 663 | item.ID = UUID.Random(); |
587 | item.InvType = (int)InventoryType.Object; | 664 | item.InvType = (int)InventoryType.Object; |
588 | item.Folder = folder.ID; | 665 | item.Folder = folder.ID; |
589 | item.Owner = userID; | 666 | item.Owner = userID; |
590 | if (objlist.Count > 1) | 667 | } |
668 | |||
669 | return item; | ||
670 | } | ||
671 | |||
672 | public virtual SceneObjectGroup RezObject( | ||
673 | IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, | ||
674 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | ||
675 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | ||
676 | { | ||
677 | // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); | ||
678 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | ||
679 | item = m_Scene.InventoryService.GetItem(item); | ||
680 | |||
681 | if (item == null) | ||
682 | { | ||
683 | |||
684 | return null; | ||
685 | } | ||
686 | |||
687 | |||
688 | |||
689 | |||
690 | |||
691 | |||
692 | |||
693 | item.Owner = remoteClient.AgentId; | ||
694 | |||
695 | return RezObject( | ||
696 | remoteClient, item, item.AssetID, | ||
697 | RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, | ||
698 | RezSelected, RemoveItem, fromTaskID, attachment); | ||
699 | } | ||
700 | |||
701 | public virtual SceneObjectGroup RezObject( | ||
702 | IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, | ||
703 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | ||
704 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | ||
705 | { | ||
706 | AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); | ||
707 | |||
708 | if (rezAsset == null) | ||
709 | { | ||
710 | if (item != null) | ||
591 | { | 711 | { |
592 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | 712 | m_log.WarnFormat( |
713 | "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", | ||
714 | assetID, item.Name, item.ID, remoteClient.Name); | ||
593 | } | 715 | } |
594 | else | 716 | else |
595 | { | 717 | { |
596 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | 718 | m_log.WarnFormat( |
597 | item.SalePrice = objlist[0].RootPart.SalePrice; | 719 | "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()", |
720 | assetID, remoteClient.Name); | ||
598 | } | 721 | } |
722 | |||
723 | return null; | ||
599 | } | 724 | } |
600 | 725 | ||
601 | AssetBase asset = CreateAsset( | 726 | SceneObjectGroup group = null; |
602 | objlist[0].GetPartName(objlist[0].RootPart.LocalId), | ||
603 | objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), | ||
604 | (sbyte)AssetType.Object, | ||
605 | Utils.StringToBytes(itemXml), | ||
606 | objlist[0].OwnerID.ToString()); | ||
607 | m_Scene.AssetService.Store(asset); | ||
608 | assetID = asset.FullID; | ||
609 | 727 | ||
610 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 728 | string xmlData = Utils.BytesToString(rezAsset.Data); |
729 | List<SceneObjectGroup> objlist = | ||
730 | new List<SceneObjectGroup>(); | ||
731 | List<Vector3> veclist = new List<Vector3>(); | ||
732 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | ||
733 | Vector3 pos; | ||
734 | |||
735 | XmlDocument doc = new XmlDocument(); | ||
736 | doc.LoadXml(xmlData); | ||
737 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
738 | if (e == null || attachment) // Single | ||
611 | { | 739 | { |
612 | item.AssetID = asset.FullID; | 740 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
613 | m_Scene.InventoryService.UpdateItem(item); | 741 | |
742 | objlist.Add(g); | ||
743 | veclist.Add(new Vector3(0, 0, 0)); | ||
744 | |||
745 | float offsetHeight = 0; | ||
746 | pos = m_Scene.GetNewRezLocation( | ||
747 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | ||
748 | BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); | ||
749 | pos.Z += offsetHeight; | ||
614 | } | 750 | } |
615 | else | 751 | else |
616 | { | 752 | { |
617 | item.AssetID = asset.FullID; | 753 | XmlElement coll = (XmlElement)e; |
754 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
755 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
756 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
757 | Vector3 bbox = new Vector3(bx, by, bz); | ||
618 | 758 | ||
619 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; | 759 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, |
620 | foreach (SceneObjectGroup grp in objlist) | 760 | RayTargetID, Quaternion.Identity, |
621 | effectivePerms &= grp.GetEffectivePermissions(); | 761 | BypassRayCast, bRayEndIsIntersection, true, |
622 | effectivePerms |= (uint)PermissionMask.Move; | 762 | bbox, false); |
623 | 763 | ||
624 | if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | 764 | pos -= bbox / 2; |
625 | { | 765 | |
626 | uint perms = effectivePerms; | 766 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); |
627 | uint nextPerms = (perms & 7) << 13; | 767 | foreach (XmlNode n in groups) |
628 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
629 | perms &= ~(uint)PermissionMask.Copy; | ||
630 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
631 | perms &= ~(uint)PermissionMask.Transfer; | ||
632 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
633 | perms &= ~(uint)PermissionMask.Modify; | ||
634 | |||
635 | item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
636 | item.CurrentPermissions = item.BasePermissions; | ||
637 | item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
638 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask; | ||
639 | item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask; | ||
640 | |||
641 | item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; | ||
642 | } | ||
643 | else | ||
644 | { | 768 | { |
645 | item.BasePermissions = effectivePerms; | 769 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); |
646 | item.CurrentPermissions = effectivePerms; | 770 | |
647 | item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms; | 771 | objlist.Add(g); |
648 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms; | 772 | XmlElement el = (XmlElement)n; |
649 | item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms; | 773 | |
650 | 774 | string rawX = el.GetAttribute("offsetx"); | |
651 | item.CurrentPermissions &= | 775 | string rawY = el.GetAttribute("offsety"); |
652 | ((uint)PermissionMask.Copy | | 776 | string rawZ = el.GetAttribute("offsetz"); |
653 | (uint)PermissionMask.Transfer | | 777 | // |
654 | (uint)PermissionMask.Modify | | 778 | // m_log.DebugFormat( |
655 | (uint)PermissionMask.Move | | 779 | // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", |
656 | 7); // Preserve folded permissions | 780 | // g.Name, rawX, rawY, rawZ); |
781 | |||
782 | float x = Convert.ToSingle(rawX); | ||
783 | float y = Convert.ToSingle(rawY); | ||
784 | float z = Convert.ToSingle(rawZ); | ||
785 | veclist.Add(new Vector3(x, y, z)); | ||
657 | } | 786 | } |
787 | } | ||
658 | 788 | ||
659 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 789 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) |
660 | item.Description = asset.Description; | 790 | return null; |
661 | item.Name = asset.Name; | ||
662 | item.AssetType = asset.Type; | ||
663 | 791 | ||
664 | m_Scene.AddInventoryItem(item); | 792 | for (int i = 0; i < objlist.Count; i++) |
793 | { | ||
794 | group = objlist[i]; | ||
665 | 795 | ||
666 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 796 | // Vector3 storedPosition = group.AbsolutePosition; |
797 | if (group.UUID == UUID.Zero) | ||
667 | { | 798 | { |
668 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 799 | m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); |
669 | } | 800 | } |
670 | else | 801 | |
802 | if (!attachment) | ||
671 | { | 803 | { |
672 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); | 804 | // If it's rezzed in world, select it. Much easier to |
673 | if (notifyUser != null) | 805 | // find small items. |
806 | // | ||
807 | foreach (SceneObjectPart part in group.Parts) | ||
674 | { | 808 | { |
675 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | 809 | part.CreateSelected = true; |
676 | } | 810 | } |
677 | } | 811 | } |
812 | |||
813 | group.ResetIDs(); | ||
814 | |||
815 | if (attachment) | ||
816 | { | ||
817 | group.RootPart.Flags |= PrimFlags.Phantom; | ||
818 | group.IsAttachment = true; | ||
819 | } | ||
820 | |||
821 | // If we're rezzing an attachment then don't ask | ||
822 | // AddNewSceneObject() to update the client since | ||
823 | // we'll be doing that later on. Scheduling more than | ||
824 | // one full update during the attachment | ||
825 | // process causes some clients to fail to display the | ||
826 | // attachment properly. | ||
827 | m_Scene.AddNewSceneObject(group, true, false); | ||
828 | |||
829 | // if attachment we set it's asset id so object updates | ||
830 | // can reflect that, if not, we set it's position in world. | ||
831 | if (!attachment) | ||
832 | { | ||
833 | group.ScheduleGroupForFullUpdate(); | ||
834 | |||
835 | group.AbsolutePosition = pos + veclist[i]; | ||
836 | } | ||
837 | |||
838 | SceneObjectPart rootPart = group.RootPart; | ||
839 | |||
840 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | ||
841 | |||
842 | if (!attachment) | ||
843 | { | ||
844 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
845 | group.ClearPartAttachmentData(); | ||
846 | |||
847 | // Fire on_rez | ||
848 | group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); | ||
849 | rootPart.ParentGroup.ResumeScripts(); | ||
850 | |||
851 | rootPart.ScheduleFullUpdate(); | ||
852 | } | ||
853 | |||
854 | // m_log.DebugFormat( | ||
855 | // "[InventoryAccessModule]: Rezzed {0} {1} {2} for {3}", | ||
856 | // group.Name, group.LocalId, group.UUID, remoteClient.Name); | ||
678 | } | 857 | } |
679 | 858 | ||
680 | // This is a hook to do some per-asset post-processing for subclasses that need that | 859 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); |
681 | if (remoteClient != null) | 860 | // TODO: Remove the magic number badness |
682 | ExportAsset(remoteClient.AgentId, assetID); | 861 | if (item != null) |
683 | 862 | DoPostRezWhenFromItem(item, attachment); | |
684 | return assetID; | ||
685 | } | ||
686 | 863 | ||
687 | protected virtual void ExportAsset(UUID agentID, UUID assetID) | 864 | if ((rootPart.OwnerID != item.Owner) || |
688 | { | 865 | (item.CurrentPermissions & 16) != 0 || // Magic number |
689 | // nothing to do here | 866 | (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) |
867 | { | ||
868 | //Need to kill the for sale here | ||
869 | rootPart.ObjectSaleType = 0; | ||
870 | rootPart.SalePrice = 10; | ||
871 | |||
872 | return group; | ||
690 | } | 873 | } |
691 | 874 | ||
692 | /// <summary> | 875 | /// <summary> |
693 | /// Rez an object into the scene from the user's inventory | 876 | /// Do pre-rez processing when the object comes from an item. |
694 | /// </summary> | 877 | /// </summary> |
695 | /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing | ||
696 | /// things to the scene. The caller should be doing that, I think. | ||
697 | /// <param name="remoteClient"></param> | 878 | /// <param name="remoteClient"></param> |
698 | /// <param name="itemID"></param> | 879 | /// <param name="item"></param> |
699 | /// <param name="RayEnd"></param> | 880 | /// <param name="objlist"></param> |
700 | /// <param name="RayStart"></param> | 881 | /// <param name="pos"></param> |
701 | /// <param name="RayTargetID"></param> | 882 | /// <param name="isAttachment"></param> |
702 | /// <param name="BypassRayCast"></param> | 883 | /// <returns>true if we can processed with rezzing, false if we need to abort</returns> |
703 | /// <param name="RayEndIsIntersection"></param> | 884 | private bool DoPreRezWhenFromItem( |
704 | /// <param name="RezSelected"></param> | 885 | IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment) |
705 | /// <param name="RemoveItem"></param> | ||
706 | /// <param name="fromTaskID"></param> | ||
707 | /// <param name="attachment"></param> | ||
708 | /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns> | ||
709 | public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, | ||
710 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | ||
711 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | ||
712 | { | 886 | { |
713 | // Work out position details | 887 | UUID fromUserInventoryItemId = UUID.Zero; |
714 | byte bRayEndIsIntersection = (byte)0; | ||
715 | 888 | ||
716 | if (RayEndIsIntersection) | 889 | // If we have permission to copy then link the rezzed object back to the user inventory |
890 | // item that it came from. This allows us to enable 'save object to inventory' | ||
891 | if (!m_Scene.Permissions.BypassPermissions()) | ||
717 | { | 892 | { |
718 | bRayEndIsIntersection = (byte)1; | 893 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) |
894 | == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | ||
895 | { | ||
896 | fromUserInventoryItemId = item.ID; | ||
897 | } | ||
719 | } | 898 | } |
720 | else | 899 | else |
721 | { | 900 | { |
722 | bRayEndIsIntersection = (byte)0; | 901 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) |
902 | { | ||
903 | // Brave new fullperm world | ||
904 | fromUserInventoryItemId = item.ID; | ||
905 | } | ||
723 | } | 906 | } |
724 | 907 | ||
725 | Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); | 908 | int primcount = 0; |
909 | foreach (SceneObjectGroup g in objlist) | ||
910 | primcount += g.PrimCount; | ||
726 | 911 | ||
912 | if (!m_Scene.Permissions.CanRezObject( | ||
913 | primcount, remoteClient.AgentId, pos) | ||
914 | && !isAttachment) | ||
915 | { | ||
916 | // The client operates in no fail mode. It will | ||
917 | // have already removed the item from the folder | ||
918 | // if it's no copy. | ||
919 | // Put it back if it's not an attachment | ||
920 | // | ||
921 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) | ||
922 | remoteClient.SendBulkUpdateInventory(item); | ||
727 | 923 | ||
728 | Vector3 pos = m_Scene.GetNewRezLocation( | 924 | return false; |
729 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 925 | } |
730 | BypassRayCast, bRayEndIsIntersection, true, scale, false); | ||
731 | |||
732 | // Rez object | ||
733 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | ||
734 | item = m_Scene.InventoryService.GetItem(item); | ||
735 | 926 | ||
736 | if (item != null) | 927 | for (int i = 0; i < objlist.Count; i++) |
737 | { | 928 | { |
738 | if (item.ID == UUID.Zero) | 929 | SceneObjectGroup so = objlist[i]; |
930 | SceneObjectPart rootPart = so.RootPart; | ||
931 | |||
932 | // Since renaming the item in the inventory does not | ||
933 | // affect the name stored in the serialization, transfer | ||
934 | // the correct name from the inventory to the | ||
935 | // object itself before we rez. | ||
936 | // | ||
937 | // Only do these for the first object if we are rezzing a coalescence. | ||
938 | if (i == 0) | ||
739 | { | 939 | { |
740 | m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 1"); | 940 | rootPart.Name = item.Name; |
941 | rootPart.Description = item.Description; | ||
942 | rootPart.ObjectSaleType = item.SaleType; | ||
943 | rootPart.SalePrice = item.SalePrice; | ||
741 | } | 944 | } |
742 | item.Owner = remoteClient.AgentId; | ||
743 | |||
744 | AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); | ||
745 | |||
746 | SceneObjectGroup group = null; | ||
747 | 945 | ||
748 | if (rezAsset != null) | 946 | rootPart.FromFolderID = item.Folder; |
947 | |||
948 | if ((rootPart.OwnerID != item.Owner) || | ||
949 | (item.CurrentPermissions & 16) != 0) | ||
749 | { | 950 | { |
750 | UUID itemId = UUID.Zero; | 951 | //Need to kill the for sale here |
751 | 952 | rootPart.ObjectSaleType = 0; | |
752 | // If we have permission to copy then link the rezzed object back to the user inventory | 953 | rootPart.SalePrice = 10; |
753 | // item that it came from. This allows us to enable 'save object to inventory' | 954 | |
754 | if (!m_Scene.Permissions.BypassPermissions()) | 955 | if (m_Scene.Permissions.PropagatePermissions()) |
755 | { | ||
756 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | ||
757 | { | ||
758 | itemId = item.ID; | ||
759 | } | ||
760 | } | ||
761 | else | ||
762 | { | 956 | { |
763 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | 957 | foreach (SceneObjectPart part in so.Parts) |
764 | { | 958 | { |
765 | // Brave new fullperm world | 959 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) |
766 | itemId = item.ID; | 960 | { |
961 | part.EveryoneMask = item.EveryOnePermissions; | ||
962 | part.NextOwnerMask = item.NextPermissions; | ||
963 | } | ||
964 | part.GroupMask = 0; // DO NOT propagate here | ||
767 | } | 965 | } |
966 | |||
967 | so.ApplyNextOwnerPermissions(); | ||
768 | } | 968 | } |
969 | } | ||
970 | |||
971 | foreach (SceneObjectPart part in so.Parts) | ||
972 | { | ||
973 | part.FromUserInventoryItemID = fromUserInventoryItemId; | ||
769 | 974 | ||
770 | if (item.ID == UUID.Zero) | 975 | if ((part.OwnerID != item.Owner) || |
771 | { | 976 | (item.CurrentPermissions & 16) != 0) |
772 | m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 2"); | ||
773 | } | ||
774 | |||
775 | string xmlData = Utils.BytesToString(rezAsset.Data); | ||
776 | List<SceneObjectGroup> objlist = | ||
777 | new List<SceneObjectGroup>(); | ||
778 | List<Vector3> veclist = new List<Vector3>(); | ||
779 | |||
780 | XmlDocument doc = new XmlDocument(); | ||
781 | doc.LoadXml(xmlData); | ||
782 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
783 | if (e == null || attachment) // Single | ||
784 | { | 977 | { |
785 | SceneObjectGroup g = | 978 | part.LastOwnerID = part.OwnerID; |
786 | SceneObjectSerializer.FromOriginalXmlFormat( | 979 | part.OwnerID = item.Owner; |
787 | itemId, xmlData); | 980 | part.Inventory.ChangeInventoryOwner(item.Owner); |
788 | objlist.Add(g); | 981 | part.GroupMask = 0; // DO NOT propagate here |
789 | veclist.Add(new Vector3(0, 0, 0)); | ||
790 | |||
791 | float offsetHeight = 0; | ||
792 | pos = m_Scene.GetNewRezLocation( | ||
793 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | ||
794 | BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); | ||
795 | pos.Z += offsetHeight; | ||
796 | } | 982 | } |
797 | else | 983 | part.EveryoneMask = item.EveryOnePermissions; |
798 | { | 984 | part.NextOwnerMask = item.NextPermissions; |
799 | XmlElement coll = (XmlElement)e; | 985 | } |
800 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | 986 | |
801 | float by = Convert.ToSingle(coll.GetAttribute("y")); | 987 | rootPart.TrimPermissions(); |
802 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
803 | Vector3 bbox = new Vector3(bx, by, bz); | ||
804 | |||
805 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, | ||
806 | RayTargetID, Quaternion.Identity, | ||
807 | BypassRayCast, bRayEndIsIntersection, true, | ||
808 | bbox, false); | ||
809 | |||
810 | pos -= bbox / 2; | ||
811 | 988 | ||
812 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | 989 | if (isAttachment) |
813 | foreach (XmlNode n in groups) | 990 | so.SetFromItemID(item.ID); |
814 | { | 991 | } |
815 | SceneObjectGroup g = | ||
816 | SceneObjectSerializer.FromOriginalXmlFormat( | ||
817 | itemId, n.OuterXml); | ||
818 | objlist.Add(g); | ||
819 | XmlElement el = (XmlElement)n; | ||
820 | float x = Convert.ToSingle(el.GetAttribute("offsetx")); | ||
821 | float y = Convert.ToSingle(el.GetAttribute("offsety")); | ||
822 | float z = Convert.ToSingle(el.GetAttribute("offsetz")); | ||
823 | veclist.Add(new Vector3(x, y, z)); | ||
824 | } | ||
825 | } | ||
826 | 992 | ||
827 | int primcount = 0; | 993 | return true; |
828 | foreach (SceneObjectGroup g in objlist) | 994 | } |
829 | primcount += g.PrimCount; | ||
830 | 995 | ||
831 | if (!m_Scene.Permissions.CanRezObject( | 996 | /// <summary> |
832 | primcount, remoteClient.AgentId, pos) | 997 | /// Do post-rez processing when the object comes from an item. |
833 | && !attachment) | 998 | /// </summary> |
999 | /// <param name="item"></param> | ||
1000 | /// <param name="isAttachment"></param> | ||
1001 | private void DoPostRezWhenFromItem(InventoryItemBase item, bool isAttachment) | ||
1002 | { | ||
1003 | if (!m_Scene.Permissions.BypassPermissions()) | ||
1004 | { | ||
1005 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1006 | { | ||
1007 | // If this is done on attachments, no | ||
1008 | // copy ones will be lost, so avoid it | ||
1009 | // | ||
1010 | if (!isAttachment) | ||
834 | { | 1011 | { |
835 | // The client operates in no fail mode. It will | 1012 | List<UUID> uuids = new List<UUID>(); |
836 | // have already removed the item from the folder | 1013 | uuids.Add(item.ID); |
837 | // if it's no copy. | 1014 | m_Scene.InventoryService.DeleteItems(item.Owner, uuids); |
838 | // Put it back if it's not an attachment | ||
839 | // | ||
840 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) | ||
841 | remoteClient.SendBulkUpdateInventory(item); | ||
842 | return null; | ||
843 | } | 1015 | } |
844 | 1016 | } | |
845 | for (int i = 0 ; i < objlist.Count ; i++ ) | 1017 | } |
846 | { | 1018 | if ((rootPart.OwnerID != item.Owner) || |
847 | group = objlist[i]; | ||
848 | |||
849 | Vector3 storedPosition = group.AbsolutePosition; | ||
850 | if (group.UUID == UUID.Zero) | ||
851 | { | ||
852 | m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); | ||
853 | } | ||
854 | group.RootPart.FromFolderID = item.Folder; | ||
855 | |||
856 | // If it's rezzed in world, select it. Much easier to | ||
857 | // find small items. | ||
858 | // | ||
859 | if (!attachment) | ||
860 | { | ||
861 | group.RootPart.CreateSelected = true; | ||
862 | foreach (SceneObjectPart child in group.Parts) | ||
863 | child.CreateSelected = true; | ||
864 | } | ||
865 | |||
866 | group.ResetIDs(); | ||
867 | |||
868 | if (attachment) | ||
869 | { | ||
870 | group.RootPart.Flags |= PrimFlags.Phantom; | ||
871 | group.RootPart.IsAttachment = true; | ||
872 | |||
873 | // If we're rezzing an attachment then don't ask | ||
874 | // AddNewSceneObject() to update the client since | ||
875 | // we'll be doing that later on. Scheduling more | ||
876 | // than one full update during the attachment | ||
877 | // process causes some clients to fail to display | ||
878 | // the attachment properly. | ||
879 | // Also, don't persist attachments. | ||
880 | m_Scene.AddNewSceneObject(group, false, false); | ||
881 | } | ||
882 | else | ||
883 | { | ||
884 | m_Scene.AddNewSceneObject(group, true, false); | ||
885 | } | ||
886 | |||
887 | // if attachment we set it's asset id so object updates | ||
888 | // can reflect that, if not, we set it's position in world. | ||
889 | if (!attachment) | ||
890 | { | ||
891 | group.ScheduleGroupForFullUpdate(); | ||
892 | |||
893 | group.AbsolutePosition = pos + veclist[i]; | ||
894 | } | ||
895 | else | ||
896 | { | ||
897 | group.SetFromItemID(itemID); | ||
898 | } | ||
899 | |||
900 | SceneObjectPart rootPart = null; | ||
901 | |||
902 | try | ||
903 | { | ||
904 | rootPart = group.GetChildPart(group.UUID); | ||
905 | } | ||
906 | catch (NullReferenceException) | ||
907 | { | ||
908 | string isAttachment = ""; | ||
909 | |||
910 | if (attachment) | ||
911 | isAttachment = " Object was an attachment"; | ||
912 | |||
913 | m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); | ||
914 | } | ||
915 | |||
916 | // Since renaming the item in the inventory does not | ||
917 | // affect the name stored in the serialization, transfer | ||
918 | // the correct name from the inventory to the | ||
919 | // object itself before we rez. | ||
920 | // On coalesced objects, do the first one | ||
921 | if (((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) || i == 0) | ||
922 | { | ||
923 | rootPart.Name = item.Name; | ||
924 | rootPart.Description = item.Description; | ||
925 | } | ||
926 | if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) | ||
927 | { | ||
928 | rootPart.ObjectSaleType = item.SaleType; | ||
929 | rootPart.SalePrice = item.SalePrice; | ||
930 | } | ||
931 | |||
932 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | ||
933 | // TODO: Remove the magic number badness | ||
934 | |||
935 | if ((rootPart.OwnerID != item.Owner) || | ||
936 | (item.CurrentPermissions & 16) != 0 || // Magic number | 1019 | (item.CurrentPermissions & 16) != 0 || // Magic number |
937 | (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) | 1020 | (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) |
938 | { | 1021 | { |
939 | //Need to kill the for sale here | 1022 | //Need to kill the for sale here |
940 | rootPart.ObjectSaleType = 0; | 1023 | rootPart.ObjectSaleType = 0; |
941 | rootPart.SalePrice = 10; | 1024 | rootPart.SalePrice = 10; |
942 | 1025 | ||
943 | if (m_Scene.Permissions.PropagatePermissions()) | 1026 | if (m_Scene.Permissions.PropagatePermissions()) |
944 | { | 1027 | { |
945 | foreach (SceneObjectPart part in group.Parts) | 1028 | foreach (SceneObjectPart part in group.Parts) |
946 | { | 1029 | { |
@@ -965,58 +1048,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
965 | group.ApplyNextOwnerPermissions(); | 1048 | group.ApplyNextOwnerPermissions(); |
966 | } | 1049 | } |
967 | } | 1050 | } |
968 | 1051 | foreach (SceneObjectPart part in group.Parts) | |
969 | foreach (SceneObjectPart part in group.Parts) | 1052 | { |
970 | { | 1053 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) |
971 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | 1054 | part.EveryoneMask = item.EveryOnePermissions; |
972 | part.EveryoneMask = item.EveryOnePermissions; | 1055 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) |
973 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | 1056 | part.NextOwnerMask = item.NextPermissions; |
974 | part.NextOwnerMask = item.NextPermissions; | 1057 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) |
975 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | 1058 | part.GroupMask = item.GroupPermissions; |
976 | part.GroupMask = item.GroupPermissions; | ||
977 | } | ||
978 | |||
979 | rootPart.TrimPermissions(); | ||
980 | |||
981 | if (!attachment) | ||
982 | { | ||
983 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
984 | { | ||
985 | // Save attachment data | ||
986 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
987 | group.RootPart.AttachOffset = storedPosition; | ||
988 | |||
989 | group.ClearPartAttachmentData(); | ||
990 | } | ||
991 | |||
992 | // Fire on_rez | ||
993 | group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); | ||
994 | rootPart.ParentGroup.ResumeScripts(); | ||
995 | |||
996 | rootPart.ScheduleFullUpdate(); | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | if (!m_Scene.Permissions.BypassPermissions()) | ||
1001 | { | ||
1002 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1003 | { | ||
1004 | // If this is done on attachments, no | ||
1005 | // copy ones will be lost, so avoid it | ||
1006 | // | ||
1007 | if (!attachment) | ||
1008 | { | ||
1009 | List<UUID> uuids = new List<UUID>(); | ||
1010 | uuids.Add(item.ID); | ||
1011 | m_Scene.InventoryService.DeleteItems(item.Owner, uuids); | ||
1012 | } | ||
1013 | } | ||
1014 | } | ||
1015 | } | ||
1016 | return group; | ||
1017 | } | 1059 | } |
1018 | |||
1019 | return null; | ||
1020 | } | 1060 | } |
1021 | 1061 | ||
1022 | protected void AddUserData(SceneObjectGroup sog) | 1062 | protected void AddUserData(SceneObjectGroup sog) |
@@ -1033,11 +1073,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1033 | public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) | 1073 | public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) |
1034 | { | 1074 | { |
1035 | InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); | 1075 | InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); |
1076 | |||
1036 | if (assetRequestItem == null) | 1077 | if (assetRequestItem == null) |
1037 | { | 1078 | { |
1038 | ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>(); | 1079 | ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>(); |
1080 | |||
1039 | if (lib != null) | 1081 | if (lib != null) |
1040 | assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); | 1082 | assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); |
1083 | |||
1041 | if (assetRequestItem == null) | 1084 | if (assetRequestItem == null) |
1042 | return false; | 1085 | return false; |
1043 | } | 1086 | } |
@@ -1068,6 +1111,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1068 | m_log.WarnFormat( | 1111 | m_log.WarnFormat( |
1069 | "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", | 1112 | "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", |
1070 | Name, requestID, itemID, assetRequestItem.AssetID); | 1113 | Name, requestID, itemID, assetRequestItem.AssetID); |
1114 | |||
1071 | return false; | 1115 | return false; |
1072 | } | 1116 | } |
1073 | 1117 | ||