public static OSDMap CrossAgent(GridRegion crossingRegion, Vector3 pos,
                                        Vector3 velocity, AgentCircuitData circuit, AgentData cAgent,
                                        UUID RequestingRegion)
        {
            OSDMap llsdBody = new OSDMap
                                  {
                                      {"Pos", pos},
                                      {"Vel", velocity},
                                      {"Region", crossingRegion.ToOSD()},
                                      {"Circuit", circuit.ToOSD()},
                                      {"AgentData", cAgent.ToOSD()}
                                  };

            return buildEvent("CrossAgent", llsdBody, circuit.AgentID, RequestingRegion);
        }
        public bool RetrieveAgent(GridRegion destination, UUID agentID, bool agentIsLeaving, out AgentData agentData,
            out AgentCircuitData circuitData)
        {
            agentData = null;
            circuitData = null;

            IScene Scene = destination == null ? null : GetScene(destination.RegionID);
            if (Scene == null || destination == null)
                return false;

            //MainConsole.Instance.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
            IEntityTransferModule transferModule = Scene.RequestModuleInterface<IEntityTransferModule>();
            if (transferModule != null)
                return transferModule.IncomingRetrieveRootAgent(Scene, agentID, agentIsLeaving, out agentData,
                                                                out circuitData);
            return false;
            //MainConsole.Instance.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
        }
        public bool UpdateAgent(GridRegion destination, AgentData agentData)
        {
            IScene Scene = destination == null ? null : GetScene(destination.RegionID);
            if (destination == null || Scene == null || agentData == null)
                return false;

            bool retVal = false;
            IEntityTransferModule transferModule = Scene.RequestModuleInterface<IEntityTransferModule>();
            if (transferModule != null)
                retVal = transferModule.IncomingChildAgentDataUpdate(Scene, agentData);

            //            MainConsole.Instance.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle);
            return retVal;
        }
 public override void FromOSD(OSDMap map)
 {
     Success = map["Success"];
     if (map.ContainsKey("AgentData"))
     {
         AgentData = new AgentData();
         AgentData.FromOSD((OSDMap)map["AgentData"]);
     }
     if (map.ContainsKey("CircuitData"))
     {
         CircuitData = new AgentCircuitData();
         CircuitData.FromOSD((OSDMap)map["CircuitData"]);
     }
 }
 public override void FromOSD(OSDMap map)
 {
     Destination = new GridRegion();
     Destination.FromOSD((OSDMap)map["Destination"]);
     Update = new AgentData();
     Update.FromOSD((OSDMap)map["Update"]);
 }
        public virtual void CopyFrom(AgentData cAgent)
        {
            try
            {
                m_pos = cAgent.Position;
                if (PhysicsActor != null)
                {
                    AbsolutePosition = cAgent.Position;
                    PhysicsActor.ForceSetPosition(cAgent.Position);
                }
                Velocity = cAgent.Velocity;
                m_CameraCenter = cAgent.Center;
                SetHeight(cAgent.Size.Z);
                m_CameraAtAxis = cAgent.AtAxis;
                m_CameraLeftAxis = cAgent.LeftAxis;
                m_CameraUpAxis = cAgent.UpAxis;

                DrawDistance = cAgent.Far;

                if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                    ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

                m_headrotation = cAgent.HeadRotation;
                m_bodyRot = cAgent.BodyRotation;
                m_AgentControlFlags = (AgentManager.ControlFlags) cAgent.ControlFlags;
                m_savedVelocity = cAgent.Velocity;

                SpeedModifier = cAgent.Speed;
                DrawDistance = cAgent.DrawDistance;
                m_setAlwaysRun = cAgent.AlwaysRun;
                if (cAgent.IsCrossing)
                {
                    m_scene.AuthenticateHandler.GetAgentCircuitData(UUID).TeleportFlags |=
                        (uint) TeleportFlags.ViaRegionID;
                    m_scene.AuthenticateHandler.GetAgentCircuitData(UUID).IsChildAgent = false;
                        //We're going to be a root
                }
                IAvatarAppearanceModule appearance = RequestModuleInterface<IAvatarAppearanceModule>();
                if (appearance != null)
                {
                    appearance.InitialHasWearablesBeenSent = cAgent.SentInitialWearables;
                    appearance.Appearance = new AvatarAppearance(cAgent.Appearance);
                }

                // Animations
                try
                {
                    Animator.ResetAnimations();
                    Animator.Animations.FromArray(cAgent.Anims);
                }
                catch
                {
                }
                try
                {
                    if (cAgent.SittingObjects != null && cAgent.SittingObjects.m_sittingObjectXML != "")
                    {
                        ISceneEntity sceneObject = null;
                        IRegionSerialiserModule mod = Scene.RequestModuleInterface<IRegionSerialiserModule>();
                        if (mod != null)
                            sceneObject = mod.DeserializeGroupFromXml2(cAgent.SittingObjects.m_sittingObjectXML, Scene);

                        if (sceneObject != null)
                        {
                            //We were sitting on something when we crossed
                            if (Scene.SceneGraph.RestorePrimToScene(sceneObject, false))
                            {
                                if (sceneObject.IsSelected)
                                    sceneObject.RootChild.CreateSelected = true;
                                sceneObject.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate);
                                sceneObject.CreateScriptInstances(0, false, StateSource.PrimCrossing, UUID.Zero, false);

                                sceneObject.RootChild.PhysActor.ForceSetVelocity(cAgent.Velocity);
                                sceneObject.RootChild.PhysActor.Velocity = (cAgent.Velocity);
                                sceneObject.AbsolutePosition = cAgent.Position;
                                Animator.TrySetMovementAnimation(cAgent.SittingObjects.m_animation);
                                m_nextSitAnimation = cAgent.SittingObjects.m_animation;
                                cAgent.SittingObjects.m_objectID = sceneObject.UUID;
                                m_objectToSitOn = cAgent.SittingObjects;

                                foreach (ISceneChildEntity child in sceneObject.ChildrenEntities())
                                {
                                    foreach (TaskInventoryItem taskInv in child.Inventory.GetInventoryItems())
                                    {
                                        foreach (ControllerData cd in cAgent.Controllers)
                                        {
                                            if (cd.ItemID == taskInv.ItemID || cd.ItemID == taskInv.OldItemID)
                                            {
                                                cd.ItemID = taskInv.ItemID;
                                            }
                                        }
                                    }
                                }

                                try
                                {
                                    IScriptControllerModule m = RequestModuleInterface<IScriptControllerModule>();
                                    if (m != null)
                                        if (cAgent.Controllers != null)
                                            m.Deserialize(cAgent.Controllers);
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                }
                catch
                {
                }
            }
            catch (Exception ex)
            {
                MainConsole.Instance.Warn("[ScenePresence]: Error in CopyFrom: " + ex);
            }
        }
        /// <summary>
        ///     Async component for informing client of which neighbors exist
        /// </summary>
        /// <remarks>
        ///     This needs to run asynchronously, as a network timeout may block the thread for a long while
        /// </remarks>
        /// <param name="AgentID"></param>
        /// <param name="requestingRegion"></param>
        /// <param name="circuitData"></param>
        /// <param name="neighbor"></param>
        /// <param name="TeleportFlags"></param>
        /// <param name="agentData"></param>
        /// <param name="reason"></param>
        public virtual bool InformClientOfNeighbor(UUID AgentID, UUID requestingRegion, AgentCircuitData circuitData,
                                                   ref GridRegion neighbor,
                                                   uint TeleportFlags, AgentData agentData, out string reason)
        {
            if (neighbor == null || neighbor.RegionHandle == 0)
            {
                reason = "Could not find neighbor to inform";
                return false;
            }
            /*if ((neighbor.Flags & (int)Aurora.Framework.RegionFlags.RegionOnline) == 0 &&
                (neighbor.Flags & (int)(Aurora.Framework.RegionFlags.Foreign | Aurora.Framework.RegionFlags.Hyperlink)) == 0)
            {
                reason = "The region you are attempting to teleport to is offline";
                return false;
            }*/
            MainConsole.Instance.Info("[AgentProcessing]: Starting to inform client about neighbor " +
                                      neighbor.RegionName);

            //Notes on this method
            // 1) the SimulationService.CreateAgent MUST have a fixed CapsUrl for the region, so we have to create (if needed)
            //       a new Caps handler for it.
            // 2) Then we can call the methods (EnableSimulator and EstatablishAgentComm) to tell the client the new Urls
            // 3) This allows us to make the Caps on the grid server without telling any other regions about what the
            //       Urls are.

            ISimulationService SimulationService = m_registry.RequestModuleInterface<ISimulationService>();
            if (SimulationService != null)
            {
                IClientCapsService clientCaps = m_capsService.GetClientCapsService(AgentID);

                IRegionClientCapsService oldRegionService = clientCaps.GetCapsService(neighbor.RegionID);

                //If its disabled, it should be removed, so kill it!
                if (oldRegionService != null && oldRegionService.Disabled)
                {
                    clientCaps.RemoveCAPS(neighbor.RegionID);
                    oldRegionService = null;
                }

                bool newAgent = oldRegionService == null;
                IRegionClientCapsService otherRegionService = clientCaps.GetOrCreateCapsService(neighbor.RegionID,
                                                                                                CapsUtil.GetCapsSeedPath
                                                                                                    (CapsUtil.
                                                                                                         GetRandomCapsObjectPath
                                                                                                         ()),
                                                                                                circuitData, 0);

                if (!newAgent)
                {
                    //Note: if the agent is already there, send an agent update then
                    bool result = true;
                    if (agentData != null)
                    {
                        agentData.IsCrossing = false;
                        result = SimulationService.UpdateAgent(neighbor, agentData);
                    }
                    if (result)
                        oldRegionService.Disabled = false;
                    else
                    {
                        clientCaps.RemoveCAPS(neighbor.RegionID);//Kill the bad client!
                    }
                    reason = "";
                    return result;
                }

                int requestedPort = 0;
                CreateAgentResponse createAgentResponse;
                bool regionAccepted = CreateAgent(neighbor, otherRegionService, ref circuitData, SimulationService, new List<UUID>(),
                                                  out createAgentResponse);
                reason = createAgentResponse.Reason;
                if (regionAccepted)
                {
                    IPAddress ipAddress = neighbor.ExternalEndPoint.Address;
                    //If the region accepted us, we should get a CAPS url back as the reason, if not, its not updated or not an Aurora region, so don't touch it.
                    string ip = createAgentResponse.OurIPForClient;
                    if (!IPAddress.TryParse(ip, out ipAddress))
            #pragma warning disable 618
                        ipAddress = Dns.GetHostByName(ip).AddressList[0];
            #pragma warning restore 618
                    otherRegionService.AddCAPS(createAgentResponse.CapsURIs);

                    if (ipAddress == null)
                        ipAddress = neighbor.ExternalEndPoint.Address;
                    if (requestedPort == 0)
                        requestedPort = neighbor.ExternalEndPoint.Port;
                    otherRegionService = clientCaps.GetCapsService(neighbor.RegionID);
                    otherRegionService.LoopbackRegionIP = ipAddress;
                    otherRegionService.CircuitData.RegionUDPPort = requestedPort;
                    circuitData.RegionUDPPort = requestedPort; //Fix the port

                    IEventQueueService EQService = m_registry.RequestModuleInterface<IEventQueueService>();

                    EQService.EnableSimulator(neighbor.RegionHandle,
                                              ipAddress.GetAddressBytes(),
                                              requestedPort, AgentID,
                                              neighbor.RegionSizeX, neighbor.RegionSizeY, requestingRegion);

                    // EnableSimulator makes the client send a UseCircuitCode message to the destination,
                    // which triggers a bunch of things there.
                    // So let's wait
                    Thread.Sleep(300);
                    EQService.EstablishAgentCommunication(AgentID, neighbor.RegionHandle,
                                                          ipAddress.GetAddressBytes(),
                                                          requestedPort, otherRegionService.CapsUrl,
                                                          neighbor.RegionSizeX,
                                                          neighbor.RegionSizeY,
                                                          requestingRegion);

                    MainConsole.Instance.Info("[AgentProcessing]: Completed inform client about neighbor " +
                                              neighbor.RegionName);
                }
                else
                {
                    clientCaps.RemoveCAPS(neighbor.RegionID);
                    reason = "Could not contact simulator";
                    MainConsole.Instance.Error("[AgentProcessing]: Failed to inform client about neighbor " +
                                               neighbor.RegionName +
                                               ", reason: " + reason);
                    return false;
                }
                return true;
            }
            reason = "SimulationService does not exist";
            MainConsole.Instance.Error("[AgentProcessing]: Failed to inform client about neighbor " +
                                       neighbor.RegionName +
                                       ", reason: " + reason + "!");
            return false;
        }
        public virtual bool IncomingRetrieveRootAgent(IScene scene, UUID id, bool agentIsLeaving, out AgentData agent,
                                                      out AgentCircuitData circuitData)
        {
            agent = null;
            circuitData = null;
            IScenePresence sp = scene.GetScenePresence(id);
            if ((sp != null) && (!sp.IsChildAgent))
            {
                AgentData data = new AgentData();
                sp.CopyTo(data);
                agent = data;
                circuitData = BuildCircuitDataForPresence(sp, sp.AbsolutePosition);
                //if (agentIsLeaving)
                //    sp.SetAgentLeaving(null);//We arn't sure where they are going
                return true;
            }

            return false;
        }
        public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt,
                                       uint teleportFlags)
        {
            sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest");
            if (finalDestination == null)
            {
                sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
                return;
            }

            MainConsole.Instance.DebugFormat(
                "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}",
                finalDestination.ServerURI, finalDestination.RegionName, position);

            sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving");
            sp.SetAgentLeaving(finalDestination);

            // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
            // both regions
            if (sp.ParentID != UUID.Zero)
                sp.StandUp();

            AgentCircuitData agentCircuit = BuildCircuitDataForPresence(sp, position);

            AgentData agent = new AgentData();
            sp.CopyTo(agent);
            //Fix the position
            agent.Position = position;

            ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>();
            if (syncPoster != null)
            {
                //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish
                //  messages if they need to be called and deals with the callback
                syncPoster.PostToServer(SyncMessageHelper.TeleportAgent((int) sp.DrawDistance,
                                                                        agentCircuit, agent, teleportFlags,
                                                                        finalDestination, sp.Scene.RegionInfo.RegionID));
            }
        }
        public bool UpdateAgent(GridRegion destination, AgentData data)
        {
            if (m_blackListedRegions.ContainsKey(destination.ServerURI))
            {
                //Check against time
                if (m_blackListedRegions[destination.ServerURI] > 3 &&
                    Util.EnvironmentTickCountSubtract(m_blackListedRegions[destination.ServerURI]) > 0)
                {
                    MainConsole.Instance.Warn("[SimServiceConnector]: Blacklisted region " + destination.RegionName +
                                              " requested");
                    //Still blacklisted
                    return false;
                }
            }

            UpdateAgentDataRequest request = new UpdateAgentDataRequest();
            request.Update = data;
            request.Destination = destination;

            AutoResetEvent resetEvent = new AutoResetEvent(false);
            OSDMap result = null;
            m_syncMessagePoster.Get(destination.ServerURI, request.ToOSD(), (response) =>
            {
                result = response;
                resetEvent.Set();
            });
            bool success = resetEvent.WaitOne(10000);
            if (!success)
            {
                if (m_blackListedRegions.ContainsKey(destination.ServerURI))
                {
                    if (m_blackListedRegions[destination.ServerURI] == 3)
                    {
                        //add it to the blacklist as the request completely failed 3 times
                        m_blackListedRegions[destination.ServerURI] = Util.EnvironmentTickCount() + 60 * 1000; //60 seconds
                    }
                    else if (m_blackListedRegions[destination.ServerURI] == 0)
                        m_blackListedRegions[destination.ServerURI]++;
                }
                else
                    m_blackListedRegions[destination.ServerURI] = 0;
                return false;
            }

            //Clear out the blacklist if it went through
            m_blackListedRegions.Remove(destination.ServerURI);

            return result["Success"].AsBoolean();
        }
        public bool RetrieveAgent(GridRegion destination, UUID agentID, bool agentIsLeaving, out AgentData agentData,
                                  out AgentCircuitData circuitData)
        {
            agentData = null;
            circuitData = null;

            RetrieveAgentRequest request = new RetrieveAgentRequest();
            request.AgentID = agentID;
            request.Destination = destination;
            request.AgentIsLeaving = agentIsLeaving;

            AutoResetEvent resetEvent = new AutoResetEvent(false);
            OSDMap result = null;
            m_syncMessagePoster.Get(destination.ServerURI, request.ToOSD(), (osdresp) =>
            {
                result = osdresp;
                resetEvent.Set();
            });
            bool success = resetEvent.WaitOne(10000);
            if (!success) return false;

            RetrieveAgentResponse response = new RetrieveAgentResponse();
            response.FromOSD(result);

            circuitData = response.CircuitData;
            agentData = response.AgentData;
            return response.Success;
        }
        private byte[] TeleportLocation(Stream request, UUID agentID)
        {
            OSDMap retVal = new OSDMap();
            if (_isInTeleportCurrently)
            {
                retVal.Add("reason", "Duplicate teleport request.");
                retVal.Add("success", OSD.FromBoolean(false));
                return OSDParser.SerializeLLSDXmlBytes(retVal);
            }
            _isInTeleportCurrently = true;

            OSDMap rm = (OSDMap) OSDParser.DeserializeLLSDXml(HttpServerHandlerHelpers.ReadFully(request));
            OSDMap pos = rm["LocationPos"] as OSDMap;
            Vector3 position = new Vector3((float) pos["X"].AsReal(),
                                           (float) pos["Y"].AsReal(),
                                           (float) pos["Z"].AsReal());
            /*OSDMap lookat = rm["LocationLookAt"] as OSDMap;
            Vector3 lookAt = new Vector3((float)lookat["X"].AsReal(),
                (float)lookat["Y"].AsReal(),
                (float)lookat["Z"].AsReal());*/
            ulong RegionHandle = rm["RegionHandle"].AsULong();
            const uint tpFlags = 16;

            if (m_service.ClientCaps.GetRootCapsService().RegionHandle != m_service.RegionHandle)
            {
                retVal.Add("reason", "Contacted by non-root region for teleport. Protocol implemention is wrong.");
                retVal.Add("success", OSD.FromBoolean(false));
                return OSDParser.SerializeLLSDXmlBytes(retVal);
            }

            string reason = "";
            int x, y;
            Util.UlongToInts(RegionHandle, out x, out y);
            GridRegion destination = m_service.Registry.RequestModuleInterface<IGridService>().GetRegionByPosition(
                m_service.ClientCaps.AccountInfo.AllScopeIDs, x, y);
            ISimulationService simService = m_service.Registry.RequestModuleInterface<ISimulationService>();
            AgentData ad = new AgentData();
            AgentCircuitData circuitData = null;
            if (destination != null)
            {
                simService.RetrieveAgent(m_service.Region, m_service.AgentID, true, out ad, out circuitData);
                if (ad != null)
                {
                    ad.Position = position;
                    ad.Center = position;
                    circuitData.StartingPosition = position;
                }
            }
            if (destination == null || circuitData == null)
            {
                retVal.Add("reason", "Could not find the destination region.");
                retVal.Add("success", OSD.FromBoolean(false));
                return OSDParser.SerializeLLSDXmlBytes(retVal);
            }
            circuitData.IsChildAgent = false;

            if (m_agentProcessing.TeleportAgent(ref destination, tpFlags, circuitData, ad,
                                                m_service.AgentID, m_service.RegionID, out reason) || reason == "")
            {
                retVal.Add("success", OSD.FromBoolean(true));
            }
            else
            {
                if (reason != "Already in a teleport")
                    //If this error occurs... don't kick them out of their current region
                    simService.FailedToMoveAgentIntoNewRegion(m_service.AgentID, destination);
                retVal.Add("reason", reason);
                retVal.Add("success", OSD.FromBoolean(false));
            }

            //Send back data
            _isInTeleportCurrently = false;
            return OSDParser.SerializeLLSDXmlBytes(retVal);
        }
        protected virtual OSDMap OnMessageReceived(OSDMap message)
        {
            if (!message.ContainsKey("Method"))
                return null;

            if (m_capsService == null)
                return null;

            string method = message["Method"].AsString();
            if (method != "RegionIsOnline" && method != "LogoutRegionAgents" &&
                method != "ArrivedAtDestination" && method != "CancelTeleport" &&
                method != "AgentLoggedOut" && method != "SendChildAgentUpdate" &&
                method != "TeleportAgent" && method != "CrossAgent")
                return null;

            UUID AgentID = message["AgentID"].AsUUID();
            UUID requestingRegion = message["RequestingRegion"].AsUUID();

            IClientCapsService clientCaps = m_capsService.GetClientCapsService(AgentID);

            IRegionClientCapsService regionCaps = null;
            if (clientCaps != null)
                regionCaps = clientCaps.GetCapsService(requestingRegion);
            if (message["Method"] == "LogoutRegionAgents")
            {
                LogOutAllAgentsForRegion(requestingRegion);
            }
            else if (message["Method"] == "RegionIsOnline")
                //This gets fired when the scene is fully finished starting up
            {
                //Log out all the agents first, then add any child agents that should be in this region
                //Don't do this, we don't need to kill all the clients right now
                //LogOutAllAgentsForRegion(requestingRegion);
                IGridService GridService = m_registry.RequestModuleInterface<IGridService>();
                if (GridService != null)
                {
                    GridRegion requestingGridRegion = GridService.GetRegionByUUID(null, requestingRegion);
                    if (requestingGridRegion != null)
                        Util.FireAndForget((o) => EnableChildAgentsForRegion(requestingGridRegion));
                }
            }
            else if (message["Method"] == "ArrivedAtDestination")
            {
                if (regionCaps == null || clientCaps == null)
                    return null;
                //Recieved a callback
                if (clientCaps.InTeleport) //Only set this if we are in a teleport,
                    //  otherwise (such as on login), this won't check after the first tp!
                    clientCaps.CallbackHasCome = true;

                regionCaps.Disabled = false;

                //The agent is getting here for the first time (eg. login)
                OSDMap body = ((OSDMap) message["Message"]);

                //Parse the OSDMap
                int DrawDistance = body["DrawDistance"].AsInteger();

                AgentCircuitData circuitData = new AgentCircuitData();
                circuitData.FromOSD((OSDMap)body["Circuit"]);

                //Now do the creation
                EnableChildAgents(AgentID, requestingRegion, DrawDistance, circuitData);
            }
            else if (message["Method"] == "CancelTeleport")
            {
                if (regionCaps == null || clientCaps == null)
                    return null;
                //Only the region the client is root in can do this
                IRegionClientCapsService rootCaps = clientCaps.GetRootCapsService();
                if (rootCaps != null && rootCaps.RegionHandle == regionCaps.RegionHandle)
                {
                    //The user has requested to cancel the teleport, stop them.
                    clientCaps.RequestToCancelTeleport = true;
                    regionCaps.Disabled = false;
                }
            }
            else if (message["Method"] == "AgentLoggedOut")
            {
                //ONLY if the agent is root do we even consider it
                if (regionCaps != null && regionCaps.RootAgent)
                {
                    OSDMap body = ((OSDMap) message["Message"]);

                    AgentPosition pos = new AgentPosition();
                    pos.FromOSD((OSDMap)body["AgentPos"]);

                    regionCaps.Disabled = true;

                    Util.FireAndForget((o) =>
                                           {
                                               LogoutAgent(regionCaps, false); //The root is killing itself
                                               SendChildAgentUpdate(pos, regionCaps);
                                           });
                }
            }
            else if (message["Method"] == "SendChildAgentUpdate")
            {
                if (regionCaps == null || clientCaps == null)
                    return null;
                IRegionClientCapsService rootCaps = clientCaps.GetRootCapsService();
                if (rootCaps != null && rootCaps.RegionHandle == regionCaps.RegionHandle) //Has to be root
                {
                    OSDMap body = ((OSDMap) message["Message"]);

                    AgentPosition pos = new AgentPosition();
                    pos.FromOSD((OSDMap) body["AgentPos"]);

                    SendChildAgentUpdate(pos, regionCaps);
                    regionCaps.Disabled = false;
                }
            }
            else if (message["Method"] == "TeleportAgent")
            {
                if (regionCaps == null || clientCaps == null)
                    return null;
                IRegionClientCapsService rootCaps = clientCaps.GetRootCapsService();
                if (rootCaps != null && rootCaps.RegionHandle == regionCaps.RegionHandle)
                {
                    OSDMap body = ((OSDMap) message["Message"]);

                    GridRegion destination = new GridRegion();
                    destination.FromOSD((OSDMap) body["Region"]);

                    uint TeleportFlags = body["TeleportFlags"].AsUInteger();

                    AgentCircuitData Circuit = new AgentCircuitData();
                    Circuit.FromOSD((OSDMap)body["Circuit"]);

                    AgentData AgentData = new AgentData();
                    AgentData.FromOSD((OSDMap)body["AgentData"]);
                    regionCaps.Disabled = false;

                    //Don't need to wait for this to finish on the main http thread
                    Util.FireAndForget((o) =>
                                           {
                                               string reason = "";
                                               TeleportAgent(ref destination, TeleportFlags,
                                                             Circuit, AgentData, AgentID, requestingRegion, out reason);
                                           });
                    return null;
                }
            }
            else if (message["Method"] == "CrossAgent")
            {
                if (regionCaps == null || clientCaps == null)
                    return null;
                IRegionClientCapsService rootCaps = clientCaps.GetRootCapsService();
                if (rootCaps == null || rootCaps.RegionHandle == regionCaps.RegionHandle)
                {
                    //This is a simulator message that tells us to cross the agent
                    OSDMap body = ((OSDMap) message["Message"]);

                    Vector3 pos = body["Pos"].AsVector3();
                    Vector3 Vel = body["Vel"].AsVector3();
                    GridRegion Region = new GridRegion();
                    Region.FromOSD((OSDMap) body["Region"]);
                    AgentCircuitData Circuit = new AgentCircuitData();
                    Circuit.FromOSD((OSDMap)body["Circuit"]);
                    AgentData AgentData = new AgentData();
                    AgentData.FromOSD((OSDMap)body["AgentData"]);
                    regionCaps.Disabled = false;

                    Util.FireAndForget((o) =>
                                           {
                                               string reason = "";
                                               CrossAgent(Region, pos, Vel, Circuit, AgentData,
                                                          AgentID, requestingRegion, out reason);
                                           });
                    return null;
                }
                else if (clientCaps.InTeleport)
                {
                    OSDMap result = new OSDMap();
                    result["success"] = false;
                    result["Note"] = false;
                    return result;
                }
                else
                {
                    OSDMap result = new OSDMap();
                    result["success"] = false;
                    result["Note"] = false;
                    return result;
                }
            }
            return null;
        }
        public virtual bool TeleportAgent(ref GridRegion destination, uint TeleportFlags,
                                          AgentCircuitData circuit, AgentData agentData, UUID AgentID,
                                          UUID requestingRegion,
                                          out string reason)
        {
            IClientCapsService clientCaps = m_capsService.GetClientCapsService(AgentID);
            IRegionClientCapsService regionCaps = clientCaps.GetCapsService(requestingRegion);
            ISimulationService SimulationService = m_registry.RequestModuleInterface<ISimulationService>();

            if (regionCaps == null || !regionCaps.RootAgent)
            {
                reason = "";
                ResetFromTransit(AgentID);
                return false;
            }

            bool result = false;
            try
            {
                bool callWasCanceled = false;

                if (SimulationService != null)
                {
                    //Set the user in transit so that we block duplicate tps and reset any cancelations
                    if (!SetUserInTransit(AgentID))
                    {
                        reason = "Already in a teleport";
                        SimulationService.FailedToTeleportAgent(regionCaps.Region, destination.RegionID,
                                                                AgentID, reason, false);
                        return false;
                    }

                    IGridService GridService = m_registry.RequestModuleInterface<IGridService>();
                    if (GridService != null)
                    {
                        //Inform the client of the neighbor if needed
                        circuit.IsChildAgent = false; //Force child status to the correct type
                        if (!InformClientOfNeighbor(AgentID, requestingRegion, circuit, ref destination, TeleportFlags,
                                                    agentData, out reason))
                        {
                            ResetFromTransit(AgentID);
                            SimulationService.FailedToTeleportAgent(regionCaps.Region, destination.RegionID,
                                                                    AgentID, reason, false);
                            return false;
                        }
                    }
                    else
                    {
                        reason = "Could not find the grid service";
                        ResetFromTransit(AgentID);
                        SimulationService.FailedToTeleportAgent(regionCaps.Region, destination.RegionID,
                                                                AgentID, reason, false);
                        return false;
                    }

                    IEventQueueService EQService = m_registry.RequestModuleInterface<IEventQueueService>();

                    IRegionClientCapsService otherRegion = clientCaps.GetCapsService(destination.RegionID);

                    EQService.TeleportFinishEvent(destination.RegionHandle, destination.Access,
                                                  otherRegion.LoopbackRegionIP,
                                                  otherRegion.CircuitData.RegionUDPPort,
                                                  otherRegion.CapsUrl,
                                                  4, AgentID, TeleportFlags,
                                                  destination.RegionSizeX, destination.RegionSizeY,
                                                  otherRegion.Region.RegionID);

                    // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
                    // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
                    // that the client contacted the destination before we send the attachments and close things here.

                    result = WaitForCallback(AgentID, out callWasCanceled);
                    if (!result)
                    {
                        reason = !callWasCanceled ? "The teleport timed out" : "Cancelled";
                        if (!callWasCanceled)
                        {
                            MainConsole.Instance.Warn("[AgentProcessing]: Callback never came for teleporting agent " +
                                                      AgentID + ". Resetting.");
                            //Tell the region about it as well
                            SimulationService.FailedToTeleportAgent(regionCaps.Region, destination.RegionID,
                                                                    AgentID, reason, false);
                        }
                        //Close the agent at the place we just created if it isn't a neighbor
                        // 7/22 -- Kill the agent no matter what, it obviously is having issues getting there
                        //if (IsOutsideView (regionCaps.RegionX, destination.RegionLocX, regionCaps.Region.RegionSizeX, destination.RegionSizeX,
                        //    regionCaps.RegionY, destination.RegionLocY, regionCaps.Region.RegionSizeY, destination.RegionSizeY))
                        {
                            SimulationService.CloseAgent(destination, AgentID);
                            clientCaps.RemoveCAPS(destination.RegionID);
                        }
                    }
                    else
                    {
                        //Fix the root agent status
                        otherRegion.RootAgent = true;
                        regionCaps.RootAgent = false;

                        // Next, let's close the child agent connections that are too far away.
                        //if (useCallbacks || oldRegion != destination)//Only close it if we are using callbacks (Aurora region)
                        //Why? OpenSim regions need closed too, even if the protocol is kinda stupid
                        CloseNeighborAgents(regionCaps.Region, destination, AgentID);
                        IAgentInfoService agentInfoService = m_registry.RequestModuleInterface<IAgentInfoService>();
                        if (agentInfoService != null)
                            agentInfoService.SetLastPosition(AgentID.ToString(), destination.RegionID,
                                                             agentData.Position, Vector3.Zero, destination.ServerURI);

                        SimulationService.MakeChildAgent(AgentID, regionCaps.Region, destination, false);
                        reason = "";
                    }
                }
                else
                    reason = "No SimulationService found!";
            }
            catch (Exception ex)
            {
                MainConsole.Instance.WarnFormat("[AgentProcessing]: Exception occured during agent teleport, {0}", ex);
                reason = "Exception occured.";
                if (SimulationService != null)
                    SimulationService.FailedToTeleportAgent(regionCaps.Region, destination.RegionID,
                                                            AgentID, reason, false);
            }
            //All done
            ResetFromTransit(AgentID);
            return result;
        }
        public static OSDMap TeleportAgent(int DrawDistance, AgentCircuitData circuit,
                                           AgentData data, uint TeleportFlags,
                                           GridRegion destination, UUID requestingRegion)
        {
            OSDMap llsdBody = new OSDMap
                                  {
                                      {"DrawDistance", DrawDistance},
                                      {"Circuit", circuit.ToOSD()},
                                      {"TeleportFlags", TeleportFlags},
                                      {"AgentData", data.ToOSD()},
                                      {"Region", destination.ToOSD()}
                                  };

            return buildEvent("TeleportAgent", llsdBody, circuit.AgentID, requestingRegion);
        }
        public virtual void InternalCross(IScenePresence agent, Vector3 attemptedPos, bool isFlying,
                                          GridRegion crossingRegion)
        {
            MainConsole.Instance.DebugFormat("[EntityTransferModule]: Crossing agent {0} to region {1}", agent.Name,
                                             crossingRegion.RegionName);

            try
            {
                agent.SetAgentLeaving(crossingRegion);

                AgentData cAgent = new AgentData();
                agent.CopyTo(cAgent);
                cAgent.Position = attemptedPos;
                if (isFlying)
                    cAgent.ControlFlags |= (uint) AgentManager.ControlFlags.AGENT_CONTROL_FLY;

                AgentCircuitData agentCircuit = BuildCircuitDataForPresence(agent, attemptedPos);
                agentCircuit.TeleportFlags = (uint) TeleportFlags.ViaRegionID;

                //This does UpdateAgent and closing of child agents
                //  messages if they need to be called
                ISyncMessagePosterService syncPoster =
                    agent.Scene.RequestModuleInterface<ISyncMessagePosterService>();
                if (syncPoster != null)
                {
                    syncPoster.PostToServer(SyncMessageHelper.CrossAgent(crossingRegion, attemptedPos,
                                                                         agent.Velocity, agentCircuit, cAgent,
                                                                         agent.Scene.RegionInfo.RegionID));
                }
            }
            catch (Exception ex)
            {
                MainConsole.Instance.Warn("[EntityTransferModule]: Exception in crossing: " + ex);
            }
        }
        public virtual void ChildAgentDataUpdate(AgentData cAgentData)
        {
            //MainConsole.Instance.Debug("   >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
            //if (!IsChildAgent)
            //    return;

            CopyFrom(cAgentData);
        }
        /// <summary>
        ///     We've got an update about an agent that sees into this region,
        ///     send it to ScenePresence for processing  It's the full data.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="cAgentData">
        ///     Agent that contains all of the relevant things about an agent.
        ///     Appearance, animations, position, etc.
        /// </param>
        /// <returns>true if we handled it.</returns>
        public virtual bool IncomingChildAgentDataUpdate(IScene scene, AgentData cAgentData)
        {
            MainConsole.Instance.DebugFormat(
                "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, scene.RegionInfo.RegionName);

            //No null updates!
            if (cAgentData == null)
                return false;

            // We have to wait until the viewer contacts this region after receiving EAC.
            // That calls AddNewClient, which finally creates the ScenePresence and then this gets set up
            // So if the client isn't here yet, save the update for them when they get into the region fully
            IScenePresence SP = scene.GetScenePresence(cAgentData.AgentID);
            if (SP != null)
                SP.ChildAgentDataUpdate(cAgentData);
            else
                lock (m_incomingChildAgentData)
                {
                    if (!m_incomingChildAgentData.ContainsKey(scene))
                        m_incomingChildAgentData.Add(scene, new Dictionary<UUID, AgentData>());
                    m_incomingChildAgentData[scene][cAgentData.AgentID] = cAgentData;
                    return false; //The agent doesn't exist
                }
            return true;
        }
        public virtual void CopyTo(AgentData cAgent)
        {
            cAgent.AgentID = UUID;
            cAgent.RegionID = Scene.RegionInfo.RegionID;

            cAgent.Position = AbsolutePosition + OffsetPosition;
            cAgent.Velocity = Velocity;
            cAgent.Center = m_CameraCenter;
            cAgent.AtAxis = m_CameraAtAxis;
            cAgent.LeftAxis = m_CameraLeftAxis;
            cAgent.UpAxis = m_CameraUpAxis;

            cAgent.Far = DrawDistance;

            // Throttles
            float multiplier = 1;
            int innacurateNeighbors = m_scene.RequestModuleInterface<IGridRegisterModule>().GetNeighbors(m_scene).Count;
            if (innacurateNeighbors != 0)
            {
                multiplier = 1f/innacurateNeighbors;
            }
            if (multiplier <= 0.25f)
            {
                multiplier = 0.25f;
            }
            //MainConsole.Instance.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
            cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier);

            cAgent.HeadRotation = m_headrotation;
            cAgent.BodyRotation = m_bodyRot;
            cAgent.ControlFlags = (uint) m_AgentControlFlags;

            //This is checked by the other sim, so we don't have to validate it at all
            //if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
            cAgent.GodLevel = (byte) m_godLevel;
            //else
            //    cAgent.GodLevel = (byte) 0;

            cAgent.Speed = SpeedModifier;
            cAgent.DrawDistance = DrawDistance;
            cAgent.AlwaysRun = m_setAlwaysRun;
            IAvatarAppearanceModule appearance = RequestModuleInterface<IAvatarAppearanceModule>();
            if (appearance != null)
            {
                cAgent.SentInitialWearables = appearance.InitialHasWearablesBeenSent;
                cAgent.Appearance = new AvatarAppearance(appearance.Appearance);
            }

            IScriptControllerModule m = RequestModuleInterface<IScriptControllerModule>();
            if (m != null)
                cAgent.Controllers = m.Serialize();

            cAgent.SittingObjects = new SittingObjectData();
            if (Sitting)
            {
                ISceneChildEntity child = Scene.GetSceneObjectPart(SittingOnUUID);
                if (child != null && child.ParentEntity != null)
                {
                    cAgent.SittingObjects.m_sittingObjectXML = child.ParentEntity.ToXml2();
                    cAgent.SittingObjects.m_sitTargetPos = OffsetPosition; //Get the difference
                    cAgent.SittingObjects.m_sitTargetRot = m_bodyRot;
                    cAgent.SittingObjects.m_animation = m_nextSitAnimation;
                }
            }

            // Animations
            if (Animator != null)
                cAgent.Anims = Animator.Animations.ToArray();
        }
        public virtual bool CrossAgent(GridRegion crossingRegion, Vector3 pos,
                                       Vector3 velocity, AgentCircuitData circuit, AgentData cAgent, UUID AgentID,
                                       UUID requestingRegion, out string reason)
        {
            IClientCapsService clientCaps = m_capsService.GetClientCapsService(AgentID);
            IRegionClientCapsService requestingRegionCaps = clientCaps.GetCapsService(requestingRegion);
            ISimulationService SimulationService = m_registry.RequestModuleInterface<ISimulationService>();
            IGridService GridService = m_registry.RequestModuleInterface<IGridService>();
            try
            {
                if (SimulationService != null || GridService != null)
                {
                    //Set the user in transit so that we block duplicate tps and reset any cancelations
                    if (!SetUserInTransit(AgentID))
                    {
                        reason = "Already in a teleport";
                        SimulationService.FailedToTeleportAgent(requestingRegionCaps.Region, crossingRegion.RegionID,
                                                                AgentID, reason, true);
                        return false;
                    }

                    bool result = false;

                    IRegionClientCapsService otherRegion = clientCaps.GetCapsService(crossingRegion.RegionID);

                    if (otherRegion == null)
                    {
                        //If we failed before, attempt again
                        if (!InformClientOfNeighbor(AgentID, requestingRegion, circuit, ref crossingRegion, 0,
                                                    cAgent, out reason))
                        {
                            ResetFromTransit(AgentID);
                            SimulationService.FailedToTeleportAgent(requestingRegionCaps.Region,
                                                                    crossingRegion.RegionID,
                                                                    AgentID, reason, true);
                            return false;
                        }
                        else
                            otherRegion = clientCaps.GetCapsService(crossingRegion.RegionID);
                    }

                    //We need to get it from the grid service again so that we can get the simulation service urls correctly
                    // as regions don't get that info
                    crossingRegion = GridService.GetRegionByUUID(clientCaps.AccountInfo.AllScopeIDs,
                                                                 crossingRegion.RegionID);
                    cAgent.IsCrossing = true;
                    if (!SimulationService.UpdateAgent(crossingRegion, cAgent))
                    {
                        MainConsole.Instance.Warn("[AgentProcessing]: Failed to cross agent " + AgentID +
                                                  " because region did not accept it. Resetting.");
                        reason = "Failed to update an agent";
                        SimulationService.FailedToTeleportAgent(requestingRegionCaps.Region, crossingRegion.RegionID,
                                                                AgentID, reason, true);
                    }
                    else
                    {
                        IEventQueueService EQService = m_registry.RequestModuleInterface<IEventQueueService>();

                        //Add this for the viewer, but not for the sim, seems to make the viewer happier
                        int XOffset = crossingRegion.RegionLocX - requestingRegionCaps.RegionX;
                        pos.X += XOffset;

                        int YOffset = crossingRegion.RegionLocY - requestingRegionCaps.RegionY;
                        pos.Y += YOffset;

                        //Tell the client about the transfer
                        EQService.CrossRegion(crossingRegion.RegionHandle, pos, velocity,
                                              otherRegion.LoopbackRegionIP,
                                              otherRegion.CircuitData.RegionUDPPort,
                                              otherRegion.CapsUrl,
                                              AgentID,
                                              circuit.SessionID,
                                              crossingRegion.RegionSizeX,
                                              crossingRegion.RegionSizeY,
                                              requestingRegionCaps.Region.RegionID);

                        result = WaitForCallback(AgentID);
                        if (!result)
                        {
                            MainConsole.Instance.Warn("[AgentProcessing]: Callback never came in crossing agent " +
                                                      circuit.AgentID +
                                                      ". Resetting.");
                            reason = "Crossing timed out";
                            SimulationService.FailedToTeleportAgent(requestingRegionCaps.Region, crossingRegion.RegionID,
                                                                    AgentID, reason, true);
                        }
                        else
                        {
                            // Next, let's close the child agent connections that are too far away.
                            //Fix the root agent status
                            otherRegion.RootAgent = true;
                            requestingRegionCaps.RootAgent = false;

                            CloseNeighborAgents(requestingRegionCaps.Region, crossingRegion, AgentID);
                            reason = "";
                            IAgentInfoService agentInfoService = m_registry.RequestModuleInterface<IAgentInfoService>();
                            if (agentInfoService != null)
                                agentInfoService.SetLastPosition(AgentID.ToString(), crossingRegion.RegionID,
                                                                 pos, Vector3.Zero, crossingRegion.ServerURI);
                            SimulationService.MakeChildAgent(AgentID, requestingRegionCaps.Region, crossingRegion, true);
                        }
                    }

                    //All done
                    ResetFromTransit(AgentID);
                    return result;
                }
                else
                    reason = "Could not find the SimulationService";
            }
            catch (Exception ex)
            {
                MainConsole.Instance.WarnFormat("[AgentProcessing]: Failed to cross an agent into a new region. {0}", ex);
                if (SimulationService != null)
                    SimulationService.FailedToTeleportAgent(requestingRegionCaps.Region, crossingRegion.RegionID,
                                                            AgentID, "Exception occured", true);
            }
            ResetFromTransit(AgentID);
            reason = "Exception occured";
            return false;
        }