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); }
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); }); }