aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs229
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;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Framework.Scenes.Types; 36using OpenSim.Region.Framework.Scenes.Types;
37using OpenSim.Region.Physics.Manager; 37using OpenSim.Region.Physics.Manager;
38using OpenSim.Region.Framework.Interfaces;
38 39
39namespace OpenSim.Region.Framework.Scenes 40namespace 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;