diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 407 |
1 files changed, 120 insertions, 287 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 090f379..f43de20 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 | { |
@@ -164,9 +165,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
164 | 165 | ||
165 | protected internal void UpdatePresences() | 166 | protected internal void UpdatePresences() |
166 | { | 167 | { |
167 | ScenePresence[] updateScenePresences = GetScenePresences(); | 168 | ForEachScenePresence(delegate(ScenePresence presence) |
168 | for (int i = 0; i < updateScenePresences.Length; i++) | 169 | { |
169 | updateScenePresences[i].Update(); | 170 | presence.Update(); |
171 | }); | ||
170 | } | 172 | } |
171 | 173 | ||
172 | protected internal float UpdatePhysics(double elapsed) | 174 | protected internal float UpdatePhysics(double elapsed) |
@@ -195,9 +197,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
195 | 197 | ||
196 | protected internal void UpdateScenePresenceMovement() | 198 | protected internal void UpdateScenePresenceMovement() |
197 | { | 199 | { |
198 | ScenePresence[] moveEntities = GetScenePresences(); | 200 | ForEachScenePresence(delegate(ScenePresence presence) |
199 | for (int i = 0; i < moveEntities.Length; i++) | 201 | { |
200 | moveEntities[i].UpdateMovement(); | 202 | presence.UpdateMovement(); |
203 | }); | ||
201 | } | 204 | } |
202 | 205 | ||
203 | #endregion | 206 | #endregion |
@@ -464,9 +467,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
464 | { | 467 | { |
465 | SceneObjectGroup group = GetGroupByPrim(objectLocalID); | 468 | SceneObjectGroup group = GetGroupByPrim(objectLocalID); |
466 | if (group != null) | 469 | if (group != null) |
467 | { | 470 | m_parentScene.AttachmentsModule.DetachSingleAttachmentToGround(group.UUID, remoteClient); |
468 | m_parentScene.DetachSingleAttachmentToGround(group.UUID, remoteClient); | ||
469 | } | ||
470 | } | 471 | } |
471 | 472 | ||
472 | protected internal void DetachObject(uint objectLocalID, IClientAPI remoteClient) | 473 | protected internal void DetachObject(uint objectLocalID, IClientAPI remoteClient) |
@@ -475,7 +476,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
475 | if (group != null) | 476 | if (group != null) |
476 | { | 477 | { |
477 | //group.DetachToGround(); | 478 | //group.DetachToGround(); |
478 | m_parentScene.DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); | 479 | m_parentScene.AttachmentsModule.ShowDetachInUserInventory(group.GetFromItemID(), remoteClient); |
479 | } | 480 | } |
480 | } | 481 | } |
481 | 482 | ||
@@ -509,212 +510,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
509 | } | 510 | } |
510 | } | 511 | } |
511 | 512 | ||
512 | /// <summary> | ||
513 | /// Event Handling routine for Attach Object | ||
514 | /// </summary> | ||
515 | /// <param name="remoteClient"></param> | ||
516 | /// <param name="objectLocalID"></param> | ||
517 | /// <param name="AttachmentPt"></param> | ||
518 | /// <param name="rot"></param> | ||
519 | protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) | ||
520 | { | ||
521 | // If we can't take it, we can't attach it! | ||
522 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); | ||
523 | if (part == null) | ||
524 | return; | ||
525 | |||
526 | if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) | ||
527 | return; | ||
528 | |||
529 | // Calls attach with a Zero position | ||
530 | if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) | ||
531 | { | ||
532 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | ||
533 | |||
534 | // Save avatar attachment information | ||
535 | ScenePresence presence; | ||
536 | if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) | ||
537 | { | ||
538 | m_log.Info( | ||
539 | "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
540 | + ", AttachmentPoint: " + AttachmentPt); | ||
541 | |||
542 | m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | |||
547 | /// <summary> | ||
548 | /// Rez an attachment | ||
549 | /// </summary> | ||
550 | /// <param name="remoteClient"></param> | ||
551 | /// <param name="itemID"></param> | ||
552 | /// <param name="AttachmentPt"></param> | ||
553 | /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> | ||
554 | public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | ||
555 | { | ||
556 | SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, | ||
557 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
558 | false, false, remoteClient.AgentId, true); | ||
559 | |||
560 | // m_log.DebugFormat( | ||
561 | // "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}", | ||
562 | // objatt.Name, remoteClient.Name, AttachmentPt); | ||
563 | |||
564 | if (objatt != null) | ||
565 | { | ||
566 | bool tainted = false; | ||
567 | if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) | ||
568 | tainted = true; | ||
569 | |||
570 | AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); | ||
571 | //objatt.ScheduleGroupForFullUpdate(); | ||
572 | |||
573 | if (tainted) | ||
574 | objatt.HasGroupChanged = true; | ||
575 | |||
576 | // Fire after attach, so we don't get messy perms dialogs | ||
577 | // 3 == AttachedRez | ||
578 | objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); | ||
579 | |||
580 | // Do this last so that event listeners have access to all the effects of the attachment | ||
581 | m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); | ||
582 | } | ||
583 | else | ||
584 | { | ||
585 | m_log.WarnFormat( | ||
586 | "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
587 | itemID, remoteClient.Name, AttachmentPt); | ||
588 | } | ||
589 | |||
590 | return objatt; | ||
591 | } | ||
592 | |||
593 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | ||
594 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | ||
595 | public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) | ||
596 | { | ||
597 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | ||
598 | return; | ||
599 | |||
600 | // We can NOT use the dictionries here, as we are looking | ||
601 | // for an entity by the fromAssetID, which is NOT the prim UUID | ||
602 | // | ||
603 | List<EntityBase> detachEntities = GetEntities(); | ||
604 | SceneObjectGroup group; | ||
605 | |||
606 | foreach (EntityBase entity in detachEntities) | ||
607 | { | ||
608 | if (entity is SceneObjectGroup) | ||
609 | { | ||
610 | group = (SceneObjectGroup)entity; | ||
611 | if (group.GetFromItemID() == itemID) | ||
612 | { | ||
613 | m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); | ||
614 | bool hasScripts = false; | ||
615 | foreach (SceneObjectPart part in group.Children.Values) | ||
616 | { | ||
617 | if (part.Inventory.ContainsScripts()) | ||
618 | { | ||
619 | hasScripts = true; | ||
620 | break; | ||
621 | } | ||
622 | } | ||
623 | |||
624 | if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event | ||
625 | System.Threading.Thread.Sleep(100); | ||
626 | group.DetachToInventoryPrep(); | ||
627 | m_log.Debug("[DETACH]: Saving attachpoint: " + | ||
628 | ((uint)group.GetAttachmentPoint()).ToString()); | ||
629 | m_parentScene.UpdateKnownItem(remoteClient, group, | ||
630 | group.GetFromItemID(), group.OwnerID); | ||
631 | m_parentScene.DeleteSceneObject(group, false); | ||
632 | return; | ||
633 | } | ||
634 | } | ||
635 | } | ||
636 | } | ||
637 | |||
638 | /// <summary> | ||
639 | /// Attach a scene object to an avatar. | ||
640 | /// </summary> | ||
641 | /// <param name="remoteClient"></param> | ||
642 | /// <param name="objectLocalID"></param> | ||
643 | /// <param name="AttachmentPt"></param> | ||
644 | /// <param name="rot"></param> | ||
645 | /// <param name="attachPos"></param> | ||
646 | /// <param name="silent"></param> | ||
647 | /// <returns>true if the attachment was successful, false otherwise</returns> | ||
648 | protected internal bool AttachObject( | ||
649 | IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) | ||
650 | { | ||
651 | SceneObjectGroup group = GetGroupByPrim(objectLocalID); | ||
652 | if (group != null) | ||
653 | { | ||
654 | if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) | ||
655 | { | ||
656 | // If the attachment point isn't the same as the one previously used | ||
657 | // set it's offset position = 0 so that it appears on the attachment point | ||
658 | // and not in a weird location somewhere unknown. | ||
659 | if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) | ||
660 | { | ||
661 | attachPos = Vector3.Zero; | ||
662 | } | ||
663 | |||
664 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
665 | if (AttachmentPt == 0) | ||
666 | { | ||
667 | // Check object for stored attachment point | ||
668 | AttachmentPt = (uint)group.GetAttachmentPoint(); | ||
669 | } | ||
670 | |||
671 | // if we still didn't find a suitable attachment point....... | ||
672 | if (AttachmentPt == 0) | ||
673 | { | ||
674 | // Stick it on left hand with Zero Offset from the attachment point. | ||
675 | AttachmentPt = (uint)AttachmentPoint.LeftHand; | ||
676 | attachPos = Vector3.Zero; | ||
677 | } | ||
678 | |||
679 | group.SetAttachmentPoint((byte)AttachmentPt); | ||
680 | group.AbsolutePosition = attachPos; | ||
681 | |||
682 | // Saves and gets itemID | ||
683 | UUID itemId; | ||
684 | |||
685 | if (group.GetFromItemID() == UUID.Zero) | ||
686 | { | ||
687 | m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); | ||
688 | } | ||
689 | else | ||
690 | { | ||
691 | itemId = group.GetFromItemID(); | ||
692 | } | ||
693 | |||
694 | m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); | ||
695 | |||
696 | group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); | ||
697 | // In case it is later dropped again, don't let | ||
698 | // it get cleaned up | ||
699 | // | ||
700 | group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); | ||
701 | group.HasGroupChanged = false; | ||
702 | } | ||
703 | else | ||
704 | { | ||
705 | remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); | ||
706 | return false; | ||
707 | } | ||
708 | } | ||
709 | else | ||
710 | { | ||
711 | m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); | ||
712 | return false; | ||
713 | } | ||
714 | |||
715 | return true; | ||
716 | } | ||
717 | |||
718 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) | 513 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) |
719 | { | 514 | { |
720 | ScenePresence newAvatar = null; | 515 | ScenePresence newAvatar = null; |
@@ -845,18 +640,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
845 | 640 | ||
846 | public void RecalculateStats() | 641 | public void RecalculateStats() |
847 | { | 642 | { |
848 | ScenePresence[] presences = GetScenePresences(); | ||
849 | int rootcount = 0; | 643 | int rootcount = 0; |
850 | int childcount = 0; | 644 | int childcount = 0; |
851 | 645 | ||
852 | for (int i = 0; i < presences.Length; i++) | 646 | ForEachScenePresence(delegate(ScenePresence presence) |
853 | { | 647 | { |
854 | ScenePresence user = presences[i]; | 648 | if (presence.IsChildAgent) |
855 | if (user.IsChildAgent) | ||
856 | ++childcount; | 649 | ++childcount; |
857 | else | 650 | else |
858 | ++rootcount; | 651 | ++rootcount; |
859 | } | 652 | }); |
860 | 653 | ||
861 | m_numRootAgents = rootcount; | 654 | m_numRootAgents = rootcount; |
862 | m_numChildAgents = childcount; | 655 | m_numChildAgents = childcount; |
@@ -903,25 +696,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
903 | #endregion | 696 | #endregion |
904 | 697 | ||
905 | #region Get Methods | 698 | #region Get Methods |
906 | |||
907 | /// <summary> | ||
908 | /// Request a List of all scene presences in this scene. This is a new list, so no | ||
909 | /// locking is required to iterate over it. | ||
910 | /// </summary> | ||
911 | /// <returns></returns> | ||
912 | protected internal ScenePresence[] GetScenePresences() | ||
913 | { | ||
914 | return m_scenePresenceArray; | ||
915 | } | ||
916 | |||
917 | protected internal List<ScenePresence> GetAvatars() | ||
918 | { | ||
919 | List<ScenePresence> result = | ||
920 | GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; }); | ||
921 | |||
922 | return result; | ||
923 | } | ||
924 | |||
925 | /// <summary> | 699 | /// <summary> |
926 | /// Get the controlling client for the given avatar, if there is one. | 700 | /// Get the controlling client for the given avatar, if there is one. |
927 | /// | 701 | /// |
@@ -948,41 +722,83 @@ namespace OpenSim.Region.Framework.Scenes | |||
948 | } | 722 | } |
949 | 723 | ||
950 | /// <summary> | 724 | /// <summary> |
951 | /// Request a filtered list of m_scenePresences in this World | 725 | /// Request a copy of m_scenePresences in this World |
726 | /// There is no guarantee that presences will remain in the scene after the list is returned. | ||
727 | /// This list should remain private to SceneGraph. Callers wishing to iterate should instead | ||
728 | /// pass a delegate to ForEachScenePresence. | ||
952 | /// </summary> | 729 | /// </summary> |
953 | /// <returns></returns> | 730 | /// <returns></returns> |
954 | protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) | 731 | private List<ScenePresence> GetScenePresences() |
955 | { | 732 | { |
956 | // No locking of scene presences here since we're passing back a list... | 733 | lock (m_scenePresences) |
957 | 734 | return new List<ScenePresence>(m_scenePresenceArray); | |
958 | List<ScenePresence> result = new List<ScenePresence>(); | 735 | } |
959 | ScenePresence[] scenePresences = GetScenePresences(); | ||
960 | 736 | ||
961 | for (int i = 0; i < scenePresences.Length; i++) | 737 | /// <summary> |
738 | /// Request a scene presence by UUID. Fast, indexed lookup. | ||
739 | /// </summary> | ||
740 | /// <param name="agentID"></param> | ||
741 | /// <returns>null if the presence was not found</returns> | ||
742 | protected internal ScenePresence GetScenePresence(UUID agentID) | ||
743 | { | ||
744 | ScenePresence sp; | ||
745 | lock (m_scenePresences) | ||
962 | { | 746 | { |
963 | ScenePresence avatar = scenePresences[i]; | 747 | m_scenePresences.TryGetValue(agentID, out sp); |
964 | if (filter(avatar)) | ||
965 | result.Add(avatar); | ||
966 | } | 748 | } |
749 | return sp; | ||
750 | } | ||
967 | 751 | ||
968 | return result; | 752 | /// <summary> |
753 | /// Request the scene presence by name. | ||
754 | /// </summary> | ||
755 | /// <param name="firstName"></param> | ||
756 | /// <param name="lastName"></param> | ||
757 | /// <returns>null if the presence was not found</returns> | ||
758 | protected internal ScenePresence GetScenePresence(string firstName, string lastName) | ||
759 | { | ||
760 | foreach (ScenePresence presence in GetScenePresences()) | ||
761 | { | ||
762 | if (presence.Firstname == firstName && presence.Lastname == lastName) | ||
763 | return presence; | ||
764 | } | ||
765 | return null; | ||
969 | } | 766 | } |
970 | 767 | ||
971 | /// <summary> | 768 | /// <summary> |
972 | /// Request a scene presence by UUID | 769 | /// Request the scene presence by localID. |
973 | /// </summary> | 770 | /// </summary> |
974 | /// <param name="avatarID"></param> | 771 | /// <param name="localID"></param> |
975 | /// <returns>null if the agent was not found</returns> | 772 | /// <returns>null if the presence was not found</returns> |
976 | protected internal ScenePresence GetScenePresence(UUID agentID) | 773 | protected internal ScenePresence GetScenePresence(uint localID) |
774 | { | ||
775 | foreach (ScenePresence presence in GetScenePresences()) | ||
776 | if (presence.LocalId == localID) | ||
777 | return presence; | ||
778 | return null; | ||
779 | } | ||
780 | |||
781 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) | ||
977 | { | 782 | { |
978 | ScenePresence sp; | ||
979 | |||
980 | lock (m_scenePresences) | 783 | lock (m_scenePresences) |
981 | { | 784 | { |
982 | m_scenePresences.TryGetValue(agentID, out sp); | 785 | m_scenePresences.TryGetValue(agentID, out avatar); |
983 | } | 786 | } |
787 | return (avatar != null); | ||
788 | } | ||
984 | 789 | ||
985 | return sp; | 790 | protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) |
791 | { | ||
792 | avatar = null; | ||
793 | foreach (ScenePresence presence in GetScenePresences()) | ||
794 | { | ||
795 | if (String.Compare(name, presence.ControllingClient.Name, true) == 0) | ||
796 | { | ||
797 | avatar = presence; | ||
798 | break; | ||
799 | } | ||
800 | } | ||
801 | return (avatar != null); | ||
986 | } | 802 | } |
987 | 803 | ||
988 | /// <summary> | 804 | /// <summary> |
@@ -1136,34 +952,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1136 | return group.GetChildPart(fullID); | 952 | return group.GetChildPart(fullID); |
1137 | } | 953 | } |
1138 | 954 | ||
1139 | protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) | ||
1140 | { | ||
1141 | lock (m_scenePresences) | ||
1142 | return m_scenePresences.TryGetValue(avatarId, out avatar); | ||
1143 | } | ||
1144 | |||
1145 | protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) | ||
1146 | { | ||
1147 | ScenePresence[] presences = GetScenePresences(); | ||
1148 | |||
1149 | for (int i = 0; i < presences.Length; i++) | ||
1150 | { | ||
1151 | ScenePresence presence = presences[i]; | ||
1152 | |||
1153 | if (!presence.IsChildAgent) | ||
1154 | { | ||
1155 | if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0) | ||
1156 | { | ||
1157 | avatar = presence; | ||
1158 | return true; | ||
1159 | } | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | avatar = null; | ||
1164 | return false; | ||
1165 | } | ||
1166 | |||
1167 | /// <summary> | 955 | /// <summary> |
1168 | /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over | 956 | /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over |
1169 | /// it | 957 | /// it |
@@ -1226,6 +1014,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1226 | return UUID.Zero; | 1014 | return UUID.Zero; |
1227 | } | 1015 | } |
1228 | 1016 | ||
1017 | /// <summary> | ||
1018 | /// Performs action on all scene object groups. | ||
1019 | /// </summary> | ||
1020 | /// <param name="action"></param> | ||
1229 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1021 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1230 | { | 1022 | { |
1231 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1023 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); |
@@ -1242,6 +1034,46 @@ namespace OpenSim.Region.Framework.Scenes | |||
1242 | } | 1034 | } |
1243 | } | 1035 | } |
1244 | } | 1036 | } |
1037 | |||
1038 | |||
1039 | /// <summary> | ||
1040 | /// Performs action on all scene presences. This can ultimately run the actions in parallel but | ||
1041 | /// any delegates passed in will need to implement their own locking on data they reference and | ||
1042 | /// modify outside of the scope of the delegate. | ||
1043 | /// </summary> | ||
1044 | /// <param name="action"></param> | ||
1045 | public void ForEachScenePresence(Action<ScenePresence> action) | ||
1046 | { | ||
1047 | // Once all callers have their delegates configured for parallelism, we can unleash this | ||
1048 | /* | ||
1049 | Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp) | ||
1050 | { | ||
1051 | try | ||
1052 | { | ||
1053 | action(sp); | ||
1054 | } | ||
1055 | catch (Exception e) | ||
1056 | { | ||
1057 | m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); | ||
1058 | m_log.Info("[BUG] Stack Trace: " + e.StackTrace); | ||
1059 | } | ||
1060 | }); | ||
1061 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); | ||
1062 | */ | ||
1063 | // For now, perform actiona serially | ||
1064 | foreach (ScenePresence sp in GetScenePresences()) | ||
1065 | { | ||
1066 | try | ||
1067 | { | ||
1068 | action(sp); | ||
1069 | } | ||
1070 | catch (Exception e) | ||
1071 | { | ||
1072 | m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); | ||
1073 | m_log.Info("[BUG] Stack Trace: " + e.StackTrace); | ||
1074 | } | ||
1075 | } | ||
1076 | } | ||
1245 | 1077 | ||
1246 | #endregion | 1078 | #endregion |
1247 | 1079 | ||
@@ -1924,6 +1756,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1924 | copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); | 1756 | copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); |
1925 | copy.HasGroupChanged = true; | 1757 | copy.HasGroupChanged = true; |
1926 | copy.ScheduleGroupForFullUpdate(); | 1758 | copy.ScheduleGroupForFullUpdate(); |
1759 | copy.ResumeScripts(); | ||
1927 | 1760 | ||
1928 | // required for physics to update it's position | 1761 | // required for physics to update it's position |
1929 | copy.AbsolutePosition = copy.AbsolutePosition; | 1762 | copy.AbsolutePosition = copy.AbsolutePosition; |