diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 229 |
1 files changed, 22 insertions, 207 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e28d29f..db70d6a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -35,6 +35,7 @@ using log4net; | |||
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Framework.Scenes.Types; | 36 | using OpenSim.Region.Framework.Scenes.Types; |
37 | using OpenSim.Region.Physics.Manager; | 37 | using OpenSim.Region.Physics.Manager; |
38 | using OpenSim.Region.Framework.Interfaces; | ||
38 | 39 | ||
39 | namespace OpenSim.Region.Framework.Scenes | 40 | namespace OpenSim.Region.Framework.Scenes |
40 | { | 41 | { |
@@ -252,7 +253,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
252 | sceneObject.HasGroupChanged = true; | 253 | sceneObject.HasGroupChanged = true; |
253 | } | 254 | } |
254 | 255 | ||
255 | return AddSceneObject(sceneObject, attachToBackup); | 256 | return AddSceneObject(sceneObject, attachToBackup, true); |
256 | } | 257 | } |
257 | 258 | ||
258 | /// <summary> | 259 | /// <summary> |
@@ -267,12 +268,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
267 | /// <returns> | 268 | /// <returns> |
268 | /// true if the object was added, false if an object with the same uuid was already in the scene | 269 | /// true if the object was added, false if an object with the same uuid was already in the scene |
269 | /// </returns> | 270 | /// </returns> |
270 | protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) | 271 | protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) |
271 | { | 272 | { |
272 | // Ensure that we persist this new scene object | 273 | // Ensure that we persist this new scene object |
273 | sceneObject.HasGroupChanged = true; | 274 | sceneObject.HasGroupChanged = true; |
274 | 275 | ||
275 | return AddSceneObject(sceneObject, attachToBackup); | 276 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
276 | } | 277 | } |
277 | 278 | ||
278 | /// <summary> | 279 | /// <summary> |
@@ -284,12 +285,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
284 | /// If true, the object is made persistent into the scene. | 285 | /// If true, the object is made persistent into the scene. |
285 | /// If false, the object will not persist over server restarts | 286 | /// If false, the object will not persist over server restarts |
286 | /// </param> | 287 | /// </param> |
287 | /// <returns>true if the object was added, false if an object with the same uuid was already in the scene | 288 | /// <param name="sendClientUpdates"> |
289 | /// If true, updates for the new scene object are sent to all viewers in range. | ||
290 | /// If false, it is left to the caller to schedule the update | ||
291 | /// </param> | ||
292 | /// <returns> | ||
293 | /// true if the object was added, false if an object with the same uuid was already in the scene | ||
288 | /// </returns> | 294 | /// </returns> |
289 | protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) | 295 | protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) |
290 | { | 296 | { |
291 | if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) | 297 | if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) |
292 | return false; | 298 | return false; |
299 | |||
300 | bool alreadyExisted = false; | ||
293 | 301 | ||
294 | if (m_parentScene.m_clampPrimSize) | 302 | if (m_parentScene.m_clampPrimSize) |
295 | { | 303 | { |
@@ -310,6 +318,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
310 | 318 | ||
311 | sceneObject.AttachToScene(m_parentScene); | 319 | sceneObject.AttachToScene(m_parentScene); |
312 | 320 | ||
321 | if (sendClientUpdates) | ||
322 | sceneObject.ScheduleGroupForFullUpdate(); | ||
323 | |||
313 | lock (sceneObject) | 324 | lock (sceneObject) |
314 | { | 325 | { |
315 | if (!Entities.ContainsKey(sceneObject.UUID)) | 326 | if (!Entities.ContainsKey(sceneObject.UUID)) |
@@ -333,12 +344,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
333 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | 344 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; |
334 | } | 345 | } |
335 | } | 346 | } |
336 | 347 | } | |
337 | return true; | 348 | else |
349 | { | ||
350 | alreadyExisted = true; | ||
338 | } | 351 | } |
339 | } | 352 | } |
340 | 353 | ||
341 | return false; | 354 | return alreadyExisted; |
342 | } | 355 | } |
343 | 356 | ||
344 | /// <summary> | 357 | /// <summary> |
@@ -463,7 +476,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
463 | if (group != null) | 476 | if (group != null) |
464 | { | 477 | { |
465 | //group.DetachToGround(); | 478 | //group.DetachToGround(); |
466 | m_parentScene.DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); | 479 | m_parentScene.AttachmentsModule.ShowDetachInUserInventory(group.GetFromItemID(), remoteClient); |
467 | } | 480 | } |
468 | } | 481 | } |
469 | 482 | ||
@@ -497,204 +510,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
497 | } | 510 | } |
498 | } | 511 | } |
499 | 512 | ||
500 | /// <summary> | ||
501 | /// Event Handling routine for Attach Object | ||
502 | /// </summary> | ||
503 | /// <param name="remoteClient"></param> | ||
504 | /// <param name="objectLocalID"></param> | ||
505 | /// <param name="AttachmentPt"></param> | ||
506 | /// <param name="rot"></param> | ||
507 | protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) | ||
508 | { | ||
509 | // If we can't take it, we can't attach it! | ||
510 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); | ||
511 | if (part == null) | ||
512 | return; | ||
513 | |||
514 | if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) | ||
515 | return; | ||
516 | |||
517 | // Calls attach with a Zero position | ||
518 | if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) | ||
519 | { | ||
520 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | ||
521 | |||
522 | // Save avatar attachment information | ||
523 | ScenePresence presence; | ||
524 | if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) | ||
525 | { | ||
526 | m_log.Info( | ||
527 | "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
528 | + ", AttachmentPoint: " + AttachmentPt); | ||
529 | |||
530 | m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | |||
535 | /// <summary> | ||
536 | /// Rez an attachment | ||
537 | /// </summary> | ||
538 | /// <param name="remoteClient"></param> | ||
539 | /// <param name="itemID"></param> | ||
540 | /// <param name="AttachmentPt"></param> | ||
541 | /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> | ||
542 | public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | ||
543 | { | ||
544 | SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, | ||
545 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
546 | false, false, remoteClient.AgentId, true); | ||
547 | |||
548 | if (objatt != null) | ||
549 | { | ||
550 | bool tainted = false; | ||
551 | if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) | ||
552 | tainted = true; | ||
553 | |||
554 | if (AttachObject( | ||
555 | remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false)) | ||
556 | { | ||
557 | objatt.ScheduleGroupForFullUpdate(); | ||
558 | if (tainted) | ||
559 | objatt.HasGroupChanged = true; | ||
560 | |||
561 | // Fire after attach, so we don't get messy perms dialogs | ||
562 | // 3 == AttachedRez | ||
563 | objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); | ||
564 | |||
565 | // Do this last so that event listeners have access to all the effects of the attachment | ||
566 | m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); | ||
567 | } | ||
568 | } | ||
569 | |||
570 | return objatt; | ||
571 | } | ||
572 | |||
573 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | ||
574 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | ||
575 | public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) | ||
576 | { | ||
577 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | ||
578 | return; | ||
579 | |||
580 | // We can NOT use the dictionries here, as we are looking | ||
581 | // for an entity by the fromAssetID, which is NOT the prim UUID | ||
582 | // | ||
583 | List<EntityBase> detachEntities = GetEntities(); | ||
584 | SceneObjectGroup group; | ||
585 | |||
586 | foreach (EntityBase entity in detachEntities) | ||
587 | { | ||
588 | if (entity is SceneObjectGroup) | ||
589 | { | ||
590 | group = (SceneObjectGroup)entity; | ||
591 | if (group.GetFromItemID() == itemID) | ||
592 | { | ||
593 | m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); | ||
594 | bool hasScripts = false; | ||
595 | foreach (SceneObjectPart part in group.Children.Values) | ||
596 | { | ||
597 | if (part.Inventory.ContainsScripts()) | ||
598 | { | ||
599 | hasScripts = true; | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event | ||
605 | System.Threading.Thread.Sleep(100); | ||
606 | group.DetachToInventoryPrep(); | ||
607 | m_log.Debug("[DETACH]: Saving attachpoint: " + | ||
608 | ((uint)group.GetAttachmentPoint()).ToString()); | ||
609 | m_parentScene.UpdateKnownItem(remoteClient, group, | ||
610 | group.GetFromItemID(), group.OwnerID); | ||
611 | m_parentScene.DeleteSceneObject(group, false); | ||
612 | return; | ||
613 | } | ||
614 | } | ||
615 | } | ||
616 | } | ||
617 | |||
618 | /// <summary> | ||
619 | /// Attach a scene object to an avatar. | ||
620 | /// </summary> | ||
621 | /// <param name="remoteClient"></param> | ||
622 | /// <param name="objectLocalID"></param> | ||
623 | /// <param name="AttachmentPt"></param> | ||
624 | /// <param name="rot"></param> | ||
625 | /// <param name="attachPos"></param> | ||
626 | /// <param name="silent"></param> | ||
627 | /// <returns>true if the attachment was successful, false otherwise</returns> | ||
628 | protected internal bool AttachObject( | ||
629 | IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) | ||
630 | { | ||
631 | SceneObjectGroup group = GetGroupByPrim(objectLocalID); | ||
632 | if (group != null) | ||
633 | { | ||
634 | if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) | ||
635 | { | ||
636 | // If the attachment point isn't the same as the one previously used | ||
637 | // set it's offset position = 0 so that it appears on the attachment point | ||
638 | // and not in a weird location somewhere unknown. | ||
639 | if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) | ||
640 | { | ||
641 | attachPos = Vector3.Zero; | ||
642 | } | ||
643 | |||
644 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
645 | if (AttachmentPt == 0) | ||
646 | { | ||
647 | // Check object for stored attachment point | ||
648 | AttachmentPt = (uint)group.GetAttachmentPoint(); | ||
649 | } | ||
650 | |||
651 | // if we still didn't find a suitable attachment point....... | ||
652 | if (AttachmentPt == 0) | ||
653 | { | ||
654 | // Stick it on left hand with Zero Offset from the attachment point. | ||
655 | AttachmentPt = (uint)AttachmentPoint.LeftHand; | ||
656 | attachPos = Vector3.Zero; | ||
657 | } | ||
658 | |||
659 | group.SetAttachmentPoint((byte)AttachmentPt); | ||
660 | group.AbsolutePosition = attachPos; | ||
661 | |||
662 | // Saves and gets itemID | ||
663 | UUID itemId; | ||
664 | |||
665 | if (group.GetFromItemID() == UUID.Zero) | ||
666 | { | ||
667 | m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); | ||
668 | } | ||
669 | else | ||
670 | { | ||
671 | itemId = group.GetFromItemID(); | ||
672 | } | ||
673 | |||
674 | m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); | ||
675 | |||
676 | group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); | ||
677 | // In case it is later dropped again, don't let | ||
678 | // it get cleaned up | ||
679 | // | ||
680 | group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); | ||
681 | group.HasGroupChanged = false; | ||
682 | } | ||
683 | else | ||
684 | { | ||
685 | remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); | ||
686 | return false; | ||
687 | } | ||
688 | } | ||
689 | else | ||
690 | { | ||
691 | m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); | ||
692 | return false; | ||
693 | } | ||
694 | |||
695 | return true; | ||
696 | } | ||
697 | |||
698 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) | 513 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) |
699 | { | 514 | { |
700 | ScenePresence newAvatar = null; | 515 | ScenePresence newAvatar = null; |