public static OSDMap AgentLoggedOut(UUID AgentID, UUID requestingRegion, AgentPosition agentpos)
        {
            OSDMap llsdBody = new OSDMap
                                  {
                                      {"AgentID", AgentID},
                                      {"AgentPos", agentpos.ToOSD()},
                                      {"RequestingRegion", requestingRegion}
                                  };

            return buildEvent("AgentLoggedOut", llsdBody, AgentID, requestingRegion);
        }
        /// <summary>
        ///     This updates important decision making data about a child agent
        ///     The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
        /// </summary>
        public virtual void ChildAgentDataUpdate(AgentPosition cAgentData, int tRegionX, int tRegionY, int rRegionX,
                                                 int rRegionY)
        {
            if (!IsChildAgent)
                return;

            //MainConsole.Instance.Debug("   >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
            int shiftx = rRegionX - tRegionX;
            int shifty = rRegionY - tRegionY;

            Vector3 offset = new Vector3(shiftx, shifty, 0f);

            DrawDistance = cAgentData.Far;
            m_pos = cAgentData.Position + offset;

            m_CameraCenter = cAgentData.Center + offset;

            TriggerSignificantClientMovement();

            m_savedVelocity = cAgentData.Velocity;
        }
        public virtual void Update()
        {
            if (!IsChildAgent && m_parentID != UUID.Zero)
            {
                SceneObjectPart part = Scene.GetSceneObjectPart(m_parentID) as SceneObjectPart;
                if (part != null)
                {
                    part.SetPhysActorCameraPos((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) ==
                                               AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK
                                                   ? CameraRotation
                                                   : Quaternion.Identity);
                }
            }
            if ((Taints & PresenceTaint.SignificantMovement) == PresenceTaint.SignificantMovement)
            {
                Taints &= ~PresenceTaint.SignificantMovement;
                //Trigger the movement now
                TriggerSignificantClientMovement();
            }
            if ((Taints & PresenceTaint.TerseUpdate) == PresenceTaint.TerseUpdate)
            {
                Taints &= ~PresenceTaint.TerseUpdate;
                //Send the terse update
                SendTerseUpdateToAllClients();
            }
            if ((Taints & PresenceTaint.Movement) == PresenceTaint.Movement)
            {
                Taints &= ~PresenceTaint.Movement;
                //Finish out the event
                UpdatePosAndVelocity();
            }
            if (m_enqueueSendChildAgentUpdate &&
                m_enqueueSendChildAgentUpdateTime != new DateTime())
            {
                if (DateTime.Now > m_enqueueSendChildAgentUpdateTime)
                {
                    Taints &= ~PresenceTaint.Other;
                    //Reset it now
                    m_enqueueSendChildAgentUpdateTime = new DateTime();
                    m_enqueueSendChildAgentUpdate = false;

                    AgentPosition agentpos = new AgentPosition
                                                 {
                                                     AgentID = UUID,
                                                     AtAxis = CameraAtAxis,
                                                     Center = m_lastChildAgentUpdateCamPosition,
                                                     Far = DrawDistance,
                                                     LeftAxis = CameraLeftAxis,
                                                     Position = m_lastChildAgentUpdatePosition,
                                                     RegionHandle = Scene.RegionInfo.RegionHandle,
                                                     UpAxis = CameraUpAxis,
                                                     Velocity = Velocity
                                                 };

                    //Send the child agent data update
                    ISyncMessagePosterService syncPoster = Scene.RequestModuleInterface<ISyncMessagePosterService>();
                    if (syncPoster != null)
                        syncPoster.PostToServer(SyncMessageHelper.SendChildAgentUpdate(agentpos,
                                                                                       m_scene.RegionInfo.RegionID));
                }
                else
                    Scene.SceneGraph.TaintPresenceForUpdate(this, PresenceTaint.Other);
                        //We havn't sent the update yet, keep tainting
            }
        }
        public bool UpdateAgent(GridRegion destination, AgentPosition agentData)
        {
            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.IncomingChildAgentDataUpdate(Scene, agentData);

            return false;
        }
        public static OSDMap SendChildAgentUpdate(AgentPosition agentpos, UUID requestingRegion)
        {
            OSDMap llsdBody = new OSDMap { { "AgentPos", agentpos.ToOSD() } };

            return buildEvent("SendChildAgentUpdate", llsdBody, agentpos.AgentID, requestingRegion);
        }
示例#6
0
        public void OnConnectionClose(IClientAPI client)
        {
            IScenePresence sp = null;
            client.Scene.TryGetScenePresence(client.AgentId, out sp);
            if (client.IsLoggingOut && sp != null & !sp.IsChildAgent)
            {
                MainConsole.Instance.InfoFormat("[ActivityDetector]: Detected logout of user {0} in region {1}",
                                                client.Name,
                                                client.Scene.RegionInfo.RegionName);

                //Inform the grid service about it

                if (m_zombieAgents.Contains(client.AgentId))
                {
                    m_zombieAgents.Remove(client.AgentId);
                    return; //They are a known zombie, just clear them out and go on with life!
                }
                AgentPosition agentpos = new AgentPosition
                                             {
                                                 AgentID = sp.UUID,
                                                 AtAxis = sp.CameraAtAxis,
                                                 Center = sp.CameraPosition,
                                                 Far = sp.DrawDistance,
                                                 LeftAxis = Vector3.Zero,
                                                 Position = sp.AbsolutePosition
                                             };
                if (agentpos.Position.X > sp.Scene.RegionInfo.RegionSizeX)
                    agentpos.Position.X = sp.Scene.RegionInfo.RegionSizeX;
                if (agentpos.Position.Y > sp.Scene.RegionInfo.RegionSizeY)
                    agentpos.Position.Y = sp.Scene.RegionInfo.RegionSizeY;
                if (agentpos.Position.Z > sp.Scene.RegionInfo.RegionSizeZ)
                    agentpos.Position.Z = sp.Scene.RegionInfo.RegionSizeZ;
                if (agentpos.Position.X < 0)
                    agentpos.Position.X = 0;
                if (agentpos.Position.Y < 0)
                    agentpos.Position.Y = 0;
                if (agentpos.Position.Z < 0)
                    agentpos.Position.Z = 0;
                agentpos.RegionHandle = sp.Scene.RegionInfo.RegionHandle;
                agentpos.Size = sp.PhysicsActor != null ? sp.PhysicsActor.Size : new Vector3(0, 0, 1.8f);
                agentpos.UpAxis = Vector3.Zero;
                agentpos.Velocity = sp.Velocity;
                agentpos.UserGoingOffline = true; //Don't attempt to add us into other regions

                //Send the child agent data update
                ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>();
                if (syncPoster != null)
                    syncPoster.PostToServer(SyncMessageHelper.AgentLoggedOut(client.AgentId,
                                                                             client.Scene.RegionInfo.RegionID, agentpos));
            }
        }
 public override void FromOSD(OSDMap map)
 {
     Destination = new GridRegion();
     Destination.FromOSD((OSDMap)map["Destination"]);
     Update = new AgentPosition();
     Update.FromOSD((OSDMap)map["Update"]);
 }
        /// <summary>
        ///     We've got an update about an agent that sees into this region,
        ///     send it to ScenePresence for processing  It's only positional data
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param>
        /// <returns>true if we handled it.</returns>
        public virtual bool IncomingChildAgentDataUpdate(IScene scene, AgentPosition cAgentData)
        {
            //MainConsole.Instance.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
            IScenePresence presence = scene.GetScenePresence(cAgentData.AgentID);
            if (presence != null)
            {
                // I can't imagine *yet* why we would get an update if the agent is a root agent..
                // however to avoid a race condition crossing borders..
                if (presence.IsChildAgent)
                {
                    uint rRegionX = 0;
                    uint rRegionY = 0;
                    //In meters
                    Utils.LongToUInts(cAgentData.RegionHandle, out rRegionX, out rRegionY);
                    //In meters
                    int tRegionX = scene.RegionInfo.RegionLocX;
                    int tRegionY = scene.RegionInfo.RegionLocY;
                    //Send Data to ScenePresence
                    presence.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, (int) rRegionX, (int) rRegionY);
                }

                return true;
            }

            return false;
        }
        public bool UpdateAgent(GridRegion destination, AgentPosition 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;
                }
            }

            UpdateAgentPositionRequest request = new UpdateAgentPositionRequest();
            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) && result != null;
            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();
        }
        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 void SendChildAgentUpdateAsync(AgentPosition agentpos, IRegionClientCapsService regionCaps)
        {
            //We need to send this update out to all the child agents this region has
            IGridService service = m_registry.RequestModuleInterface<IGridService>();
            if (service != null)
            {
                ISimulationService SimulationService = m_registry.RequestModuleInterface<ISimulationService>();
                if (SimulationService != null)
                {
                    //Set the last location in the database
                    IAgentInfoService agentInfoService = m_registry.RequestModuleInterface<IAgentInfoService>();
                    if (agentInfoService != null)
                    {
                        //Find the lookAt vector
                        Vector3 lookAt = new Vector3(agentpos.AtAxis.X, agentpos.AtAxis.Y, 0);

                        if (lookAt != Vector3.Zero)
                            lookAt = Util.GetNormalizedVector(lookAt);
                        //Update the database
                        agentInfoService.SetLastPosition(regionCaps.AgentID.ToString(), regionCaps.Region.RegionID,
                                                         agentpos.Position, lookAt, regionCaps.Region.ServerURI);
                    }

                    //Also update the service itself
                    regionCaps.LastPosition = agentpos.Position;
                    if (agentpos.UserGoingOffline)
                        return; //It just needed a last pos update

                    //Tell all neighbor regions about the new position as well
                    List<GridRegion> ourNeighbors = GetRegions(regionCaps.ClientCaps);
                    foreach (
                        GridRegion region in
                            ourNeighbors.Where(
                                region => region != null && region.RegionID != regionCaps.RegionID && !SimulationService.UpdateAgent(region, agentpos)))
                    {
                        MainConsole.Instance.Info("[AgentProcessing]: Failed to inform " + region.RegionName +
                                                  " about updating agent. ");
                    }
                }
            }
        }
 public virtual void SendChildAgentUpdate(AgentPosition agentpos, IRegionClientCapsService regionCaps)
 {
     Util.FireAndForget(delegate { SendChildAgentUpdateAsync(agentpos, regionCaps); });
 }