From a0f26dc6ec2323ffa09070e80564d3dd691408cb Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Tue, 12 Aug 2014 18:28:01 +0100
Subject:  change XMLIrpgGroups attach to events, using the more correct 
 \addons\Groups\...  model

---
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   | 307 +++++++++++----------
 .../Avatar/XmlRpcGroups/GroupsModule.cs            |  31 ++-
 2 files changed, 180 insertions(+), 158 deletions(-)

diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 62dea07..5387910 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1158,177 +1158,182 @@ namespace OpenSim.Region.Framework.Scenes
 
             m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
 
+/*   this is now done by groups module on TriggerOnMakeRootAgent(this)  below
+    at least XmlIRpcGroups
             UUID groupUUID = UUID.Zero;
             string GroupName = string.Empty;
             ulong groupPowers = 0;
 
-            // ----------------------------------
-            // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
-            try
-            {
-                
-                if (gm != null)
-                {
-                    groupUUID = ControllingClient.ActiveGroupId;
-                    GroupRecord record = gm.GetGroupRecord(groupUUID);
-                    if (record != null)
-                        GroupName = record.GroupName;
-                    GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
-                    if (groupMembershipData != null)
-                        groupPowers = groupMembershipData.GroupPowers;
-                }
-                ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
-                                                      Grouptitle);
-            }
-            catch (Exception e)
-            {
-                m_log.Debug("[AGENTUPDATE]: " + e.ToString());
-            }
-            // ------------------------------------
 
-            if (ParentID == 0)
-            {
-                // Moved this from SendInitialData to ensure that Appearance is initialized
-                // before the inventory is processed in MakeRootAgent. This fixes a race condition
-                // related to the handling of attachments
-
-                if (m_scene.TestBorderCross(pos, Cardinals.E))
-                {
-                    Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
-                    pos.X = crossedBorder.BorderLine.Z - 1;
-                }
 
-                if (m_scene.TestBorderCross(pos, Cardinals.N))
-                {
-                    Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
-                    pos.Y = crossedBorder.BorderLine.Z - 1;
-                }
 
-                CheckAndAdjustLandingPoint(ref pos);
+                        // ----------------------------------
+                        // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
+                        try
+                        {
+                
+                            if (gm != null)
+                            {
+                                groupUUID = ControllingClient.ActiveGroupId;
+                                GroupRecord record = gm.GetGroupRecord(groupUUID);
+                                if (record != null)
+                                    GroupName = record.GroupName;
+                                GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
+                                if (groupMembershipData != null)
+                                    groupPowers = groupMembershipData.GroupPowers;
+                            }
+                            ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
+                                                                    Grouptitle);
+                        }
+                        catch (Exception e)
+                        {
+                            m_log.Debug("[AGENTUPDATE]: " + e.ToString());
+                        }
+                        // ------------------------------------
+*/
+                        if (ParentID == 0)
+                        {
+                            // Moved this from SendInitialData to ensure that Appearance is initialized
+                            // before the inventory is processed in MakeRootAgent. This fixes a race condition
+                            // related to the handling of attachments
 
-                if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
-                {
-                    m_log.WarnFormat(
-                        "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
-                        pos, Name, UUID);
+                            if (m_scene.TestBorderCross(pos, Cardinals.E))
+                            {
+                                Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
+                                pos.X = crossedBorder.BorderLine.Z - 1;
+                            }
 
-                    if (pos.X < 0f) pos.X = 0f;
-                    if (pos.Y < 0f) pos.Y = 0f;
-                    if (pos.Z < 0f) pos.Z = 0f;
-                }
+                            if (m_scene.TestBorderCross(pos, Cardinals.N))
+                            {
+                                Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
+                                pos.Y = crossedBorder.BorderLine.Z - 1;
+                            }
 
-                float localAVHeight = 1.56f;
-                if (Appearance.AvatarHeight > 0)
-                    localAVHeight = Appearance.AvatarHeight;
+                            CheckAndAdjustLandingPoint(ref pos);
 
-                float posZLimit = 0;
+                            if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
+                            {
+                                m_log.WarnFormat(
+                                    "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
+                                    pos, Name, UUID);
 
-                if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
-                    posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
-                
-                float newPosZ = posZLimit + localAVHeight / 2;
-                if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
-                {
-                    pos.Z = newPosZ;
-                }
-                AbsolutePosition = pos;
+                                if (pos.X < 0f) pos.X = 0f;
+                                if (pos.Y < 0f) pos.Y = 0f;
+                                if (pos.Z < 0f) pos.Z = 0f;
+                            }
 
-                if (m_teleportFlags == TeleportFlags.Default)
-                {
-                    Vector3 vel = Velocity;
-                    AddToPhysicalScene(isFlying);
-                    if (PhysicsActor != null)
-                        PhysicsActor.SetMomentum(vel);
-                }
-                else
-                    AddToPhysicalScene(isFlying);
+                            float localAVHeight = 1.56f;
+                            if (Appearance.AvatarHeight > 0)
+                                localAVHeight = Appearance.AvatarHeight;
 
-                // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 
-                // location outside the 'root region' (the south-west 256x256 corner).  This is the earlist we can do it
-                // since it requires a physics actor to be present.  If it is left any later, then physics appears to reset
-                // the value to a negative position which does not trigger the border cross.
-                // This may not be the best location for this.
-                CheckForBorderCrossing();
+                            float posZLimit = 0;
 
-                if (ForceFly)
-                {
-                    Flying = true;
-                }
-                else if (FlyDisabled)
-                {
-                    Flying = false;
-                }
-            }
-            // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 
-            // avatar to return to the standing position in mid-air.  On login it looks like this is being sent
-            // elsewhere anyway
-            // Animator.SendAnimPack();
-
-            m_scene.SwapRootAgentCount(false);
-
-            // The initial login scene presence is already root when it gets here
-            // and it has already rezzed the attachments and started their scripts.
-            // We do the following only for non-login agents, because their scripts
-            // haven't started yet.
-/* moved down
-            if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0)
-            {
-                // Viewers which have a current outfit folder will actually rez their own attachments.  However,
-                // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
-                if (Scene.AttachmentsModule != null)
-                    Util.FireAndForget(
-                        o => 
-                        { 
-//                            if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) 
-//                                System.Threading.Thread.Sleep(7000); 
+                            if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
+                                posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
+                
+                            float newPosZ = posZLimit + localAVHeight / 2;
+                            if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
+                            {
+                                pos.Z = newPosZ;
+                            }
+                            AbsolutePosition = pos;
 
-                            Scene.AttachmentsModule.RezAttachments(this); 
-                        });
-            }
-            else
+                            if (m_teleportFlags == TeleportFlags.Default)
+                            {
+                                Vector3 vel = Velocity;
+                                AddToPhysicalScene(isFlying);
+                                if (PhysicsActor != null)
+                                    PhysicsActor.SetMomentum(vel);
+                            }
+                            else
+                                AddToPhysicalScene(isFlying);
 
-            {
-                // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
-                // and CHANGED_REGION) when the attachments have been rezzed in the new region.  This cannot currently
-                // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
-                // not transporting the required data.
-                //
-                // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
-                // and CHANGED_REGION) when the attachments have been rezzed in the new region.  This cannot currently
-                // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
-                // not transporting the required data.
-                //
-                // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of 
-                // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
-                // which needs to lock m_attachments.  ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
-                //
-                // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
-                // But XEngine starts all scripts unsuspended.  Starting them suspended will not currently work because script rezzing
-                // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the 
-                // script is rezzed.  This means the ResumeScripts() does absolutely nothing when using XEngine.
-                //
-                // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
-                // be locked, allowing race conditions if other code changes the attachments list.
+                            // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 
+                            // location outside the 'root region' (the south-west 256x256 corner).  This is the earlist we can do it
+                            // since it requires a physics actor to be present.  If it is left any later, then physics appears to reset
+                            // the value to a negative position which does not trigger the border cross.
+                            // This may not be the best location for this.
+                            CheckForBorderCrossing();
 
-                List<SceneObjectGroup> attachments = GetAttachments();
+                            if (ForceFly)
+                            {
+                                Flying = true;
+                            }
+                            else if (FlyDisabled)
+                            {
+                                Flying = false;
+                            }
+                        }
+                        // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 
+                        // avatar to return to the standing position in mid-air.  On login it looks like this is being sent
+                        // elsewhere anyway
+                        // Animator.SendAnimPack();
+
+                        m_scene.SwapRootAgentCount(false);
+
+                        // The initial login scene presence is already root when it gets here
+                        // and it has already rezzed the attachments and started their scripts.
+                        // We do the following only for non-login agents, because their scripts
+                        // haven't started yet.
+            /* moved down
+                        if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0)
+                        {
+                            // Viewers which have a current outfit folder will actually rez their own attachments.  However,
+                            // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
+                            if (Scene.AttachmentsModule != null)
+                                Util.FireAndForget(
+                                    o => 
+                                    { 
+            //                            if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) 
+            //                                System.Threading.Thread.Sleep(7000); 
+
+                                        Scene.AttachmentsModule.RezAttachments(this); 
+                                    });
+                        }
+                        else
 
-                if (attachments.Count > 0)
-                {
-                    m_log.DebugFormat(
-                        "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
+                        {
+                            // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
+                            // and CHANGED_REGION) when the attachments have been rezzed in the new region.  This cannot currently
+                            // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
+                            // not transporting the required data.
+                            //
+                            // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
+                            // and CHANGED_REGION) when the attachments have been rezzed in the new region.  This cannot currently
+                            // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
+                            // not transporting the required data.
+                            //
+                            // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of 
+                            // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
+                            // which needs to lock m_attachments.  ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
+                            //
+                            // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
+                            // But XEngine starts all scripts unsuspended.  Starting them suspended will not currently work because script rezzing
+                            // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the 
+                            // script is rezzed.  This means the ResumeScripts() does absolutely nothing when using XEngine.
+                            //
+                            // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
+                            // be locked, allowing race conditions if other code changes the attachments list.
+
+                            List<SceneObjectGroup> attachments = GetAttachments();
+
+                            if (attachments.Count > 0)
+                            {
+                                m_log.DebugFormat(
+                                    "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
 
-                    // Resume scripts  this possible should also be moved down after sending the avatar to viewer ?
-                    foreach (SceneObjectGroup sog in attachments)
-                    {
-// sending attachments before the avatar ?
-// moved to completemovement where it already was
-//                        sog.ScheduleGroupForFullUpdate();
-                        sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
-                        sog.ResumeScripts();
-                    }
-                }
-            }
-*/
+                                // Resume scripts  this possible should also be moved down after sending the avatar to viewer ?
+                                foreach (SceneObjectGroup sog in attachments)
+                                {
+            // sending attachments before the avatar ?
+            // moved to completemovement where it already was
+            //                        sog.ScheduleGroupForFullUpdate();
+                                    sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
+                                    sog.ResumeScripts();
+                                }
+                            }
+                        }
+            */
 /* 
             SendAvatarDataToAllAgents();
 
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index d2a6828..2764465 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -195,6 +195,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
             }
 
             scene.EventManager.OnNewClient += OnNewClient;
+            scene.EventManager.OnMakeRootAgent += OnMakeRoot;
+            scene.EventManager.OnMakeChildAgent += OnMakeChild;
             scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
             // The InstantMessageModule itself doesn't do this, 
             // so lets see if things explode if we don't do it
@@ -245,19 +247,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
         #endregion
 
         #region EventHandlers
+
+        private void OnMakeRoot(ScenePresence sp)
+        {
+            if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+            sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
+            // Used for Notices and Group Invites/Accept/Reject
+            sp.ControllingClient.OnInstantMessage += OnInstantMessage;
+            // Send client their groups information.
+//            SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
+            // only send data viwer will ask rest later
+            OnAgentDataUpdateRequest(sp.ControllingClient, sp.UUID, sp.UUID);
+        }
+
+        private void OnMakeChild(ScenePresence sp)
+        {
+            if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+            sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
+            sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
+        }
+ 
         private void OnNewClient(IClientAPI client)
         {
             if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
 
-            client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
             client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
             client.OnRequestAvatarProperties += OnRequestAvatarProperties;
-
-            // Used for Notices and Group Invites/Accept/Reject
-            client.OnInstantMessage += OnInstantMessage;
-
-            // Send client their groups information.
-            SendAgentGroupDataUpdate(client, client.AgentId);
         }
 
         private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
-- 
cgit v1.1