public static OSDMap SendChildAgentUpdate(AgentPosition agentpos, ulong requestingRegion) { OSDMap llsdBody = new OSDMap(); llsdBody.Add("AgentPos", agentpos.Pack()); return(buildEvent("SendChildAgentUpdate", llsdBody, agentpos.AgentID, requestingRegion)); }
public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData) { // Try local first if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData)) return true; // else do the remote thing if (!m_localBackend.IsLocalRegion(regionHandle)) { RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); if (regInfo != null) { return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData); } else m_log.Warn("[REST COMMS]: Region not found " + regionHandle); } return false; }
/// <summary> /// This checks for a significant movement and sends a coarselocationchange update /// </summary> protected void CheckForSignificantMovement() { if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = AbsolutePosition; m_scene.EventManager.TriggerSignificantClientMovement(this); } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) { m_lastChildAgentUpdatePosition = AbsolutePosition; // m_lastChildAgentUpdateCamPosition = CameraPosition; /* cadu is not used ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; cadu.AgentID = UUID.Guid; cadu.alwaysrun = SetAlwaysRun; cadu.AVHeight = Appearance.AvatarHeight; cadu.cameraPosition = CameraPosition; cadu.drawdistance = DrawDistance; cadu.GroupAccess = 0; cadu.Position = AbsolutePosition; cadu.regionHandle = RegionHandle; // Throttles float multiplier = 1; int childRegions = KnownRegionCount; if (childRegions != 0) multiplier = 1f / childRegions; // Minimum throttle for a child region is 1/4 of the root region throttle if (multiplier <= 0.25f) multiplier = 0.25f; cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); cadu.Velocity = Velocity; */ AgentPosition agentpos = new AgentPosition(); // agentpos.CopyFrom(cadu, ControllingClient.SessionId); agentpos.AgentID = new UUID(UUID.Guid); agentpos.SessionID = ControllingClient.SessionId; agentpos.Size = Appearance.AvatarSize; agentpos.Center = CameraPosition; agentpos.Far = DrawDistance; agentpos.Position = AbsolutePosition; agentpos.Velocity = Velocity; agentpos.RegionHandle = RegionHandle; agentpos.Throttles = ControllingClient.GetThrottlesPacked(1); // Let's get this out of the update loop Util.FireAndForget( o => m_scene.SendOutChildAgentUpdates(agentpos, this), null, "ScenePresence.SendOutChildAgentUpdates"); } }
public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence) { // m_log.DebugFormat( // "[SCENE COMMUNICATION SERVICE]: Sending child agent position updates for {0} in {1}", // presence.Name, m_scene.Name); // This assumes that we know what our neighbors are. try { uint x = 0, y = 0; List<string> simulatorList = new List<string>(); foreach (ulong regionHandle in presence.KnownRegionHandles) { if (regionHandle != m_regionInfo.RegionHandle) { // we only want to send one update to each simulator; the simulator will // hand it off to the regions where a child agent exists, this does assume // that the region position is cached or performance will degrade Util.RegionHandleToWorldLoc(regionHandle, out x, out y); GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); if (dest == null) continue; if (!simulatorList.Contains(dest.ServerURI)) { // we havent seen this simulator before, add it to the list // and send it an update simulatorList.Add(dest.ServerURI); // Let move this to sync. Mono definitely does not like async networking. m_scene.SimulationService.UpdateAgent(dest, cAgentData); // Leaving this here as a reminder that we tried, and it sucks. //SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; //d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest, // SendChildAgentDataUpdateCompleted, // d); } } } } catch (InvalidOperationException) { // We're ignoring a collection was modified error because this data gets old and outdated fast. } }
public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence) { m_sceneGridService.SendChildAgentDataUpdate(cadu, presence); }
public bool UpdateAgent(GridRegion destination, AgentPosition cAgentData) { if (destination == null) return false; bool retVal = false; foreach (Scene s in m_sceneList) { //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); IEntityTransferModule transferModule = s.RequestModuleInterface<IEntityTransferModule> (); if (transferModule != null) if (retVal) transferModule.IncomingChildAgentDataUpdate (s, cAgentData); else retVal = transferModule.IncomingChildAgentDataUpdate (s, cAgentData); } //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return retVal; }
/// <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 void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { if (!IsChildAgent) return; //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; Vector3 offset = new Vector3(shiftx, shifty, 0f); // When we get to the point of re-computing neighbors everytime this // changes, then start using the agent's drawdistance rather than the // region's draw distance. // DrawDistance = cAgentData.Far; DrawDistance = Scene.DefaultDrawDistance; if (cAgentData.Position != marker) // UGH!! m_pos = cAgentData.Position + offset; if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) { posLastSignificantMove = AbsolutePosition; ReprioritizeUpdates(); } CameraPosition = cAgentData.Center + offset; if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); //cAgentData.AVHeight; RegionHandle = cAgentData.RegionHandle; //m_velocity = cAgentData.Velocity; }
protected void DoAgentPut(Hashtable request, Hashtable responsedata) { OSDMap args = Utils.GetOSDMap((string)request["body"]); if (args == null) { responsedata["int_response_code"] = HttpStatusCode.BadRequest; responsedata["str_response_string"] = "Bad request"; return; } // retrieve the input arguments int x = 0, y = 0; UUID uuid = UUID.Zero; string regionname = string.Empty; if (args.ContainsKey("destination_x") && args["destination_x"] != null) Int32.TryParse(args["destination_x"].AsString(), out x); if (args.ContainsKey("destination_y") && args["destination_y"] != null) Int32.TryParse(args["destination_y"].AsString(), out y); if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) UUID.TryParse(args["destination_uuid"].AsString(), out uuid); if (args.ContainsKey("destination_name") && args["destination_name"] != null) regionname = args["destination_name"].ToString(); GridRegion destination = new GridRegion(); destination.RegionID = uuid; destination.RegionLocX = x; destination.RegionLocY = y; destination.RegionName = regionname; string messageType; if (args["message_type"] != null) messageType = args["message_type"].AsString(); else { m_log.Warn("[AGENT HANDLER]: Agent Put Message Type not found. "); messageType = "AgentData"; } bool result = true; if ("AgentData".Equals(messageType)) { AgentData agent = new AgentData(); try { agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); } catch (Exception ex) { m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); responsedata["int_response_code"] = HttpStatusCode.BadRequest; responsedata["str_response_string"] = "Bad request"; return; } //agent.Dump(); // This is one of the meanings of PUT agent result = UpdateAgent(destination, agent); } else if ("AgentPosition".Equals(messageType)) { AgentPosition agent = new AgentPosition(); try { agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); } catch (Exception ex) { m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); return; } //agent.Dump(); // This is one of the meanings of PUT agent result = m_SimulationService.UpdateAgent(destination, agent); } responsedata["int_response_code"] = HttpStatusCode.OK; responsedata["str_response_string"] = result.ToString(); //responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); ??? instead }
/// <summary> /// This checks for a significant movement and sends a courselocationchange update /// </summary> protected void CheckForSignificantMovement() { // Movement updates for agents in neighboring regions are sent directly to clients. // This value only affects how often agent positions are sent to neighbor regions // for things such as distance-based update prioritization const float SIGNIFICANT_MOVEMENT = 2.0f; if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = AbsolutePosition; m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); m_scene.NotifyMyCoarseLocationChange(); } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) { m_lastChildAgentUpdatePosition = AbsolutePosition; m_lastChildAgentUpdateCamPosition = CameraPosition; ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; cadu.AgentID = UUID.Guid; cadu.alwaysrun = m_setAlwaysRun; cadu.AVHeight = m_avHeight; Vector3 tempCameraCenter = m_CameraCenter; cadu.cameraPosition = tempCameraCenter; cadu.drawdistance = m_DrawDistance; cadu.GroupAccess = 0; cadu.Position = AbsolutePosition; cadu.regionHandle = m_rootRegionHandle; float multiplier = 1; int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); if (innacurateNeighbors != 0) { multiplier = 1f / (float)innacurateNeighbors; } if (multiplier <= 0f) { multiplier = 0.25f; } //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); cadu.Velocity = Velocity; AgentPosition agentpos = new AgentPosition(); agentpos.CopyFrom(cadu); m_scene.SendOutChildAgentUpdates(agentpos, this); } }
/// <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 void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { if (!IsChildAgent) return; //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; Vector3 offset = new Vector3(shiftx, shifty, 0f); m_DrawDistance = cAgentData.Far; if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! m_pos = cAgentData.Position + offset; if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) { posLastSignificantMove = AbsolutePosition; ReprioritizeUpdates(); } m_CameraCenter = cAgentData.Center + offset; m_avHeight = cAgentData.Size.Z; //SetHeight(cAgentData.AVHeight); if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. if (m_scene.m_seeIntoRegionFromNeighbor) m_sceneViewer.Reset(); //cAgentData.AVHeight; m_rootRegionHandle = cAgentData.RegionHandle; //m_velocity = cAgentData.Velocity; }
/// <summary> /// This checks for a significant movement and sends a courselocationchange update /// </summary> protected void CheckForSignificantMovement() { if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5) { posLastSignificantMove = AbsolutePosition; m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); m_scene.NotifyMyCoarseLocationChange(); } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) { ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; cadu.AgentID = UUID.Guid; cadu.alwaysrun = m_setAlwaysRun; cadu.AVHeight = m_avHeight; sLLVector3 tempCameraCenter = new sLLVector3(new Vector3(m_CameraCenter.X, m_CameraCenter.Y, m_CameraCenter.Z)); cadu.cameraPosition = tempCameraCenter; cadu.drawdistance = m_DrawDistance; if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID))) cadu.godlevel = m_godlevel; cadu.GroupAccess = 0; cadu.Position = new sLLVector3(AbsolutePosition); cadu.regionHandle = m_rootRegionHandle; float multiplier = 1; int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); if (innacurateNeighbors != 0) { multiplier = 1f / (float)innacurateNeighbors; } if (multiplier <= 0f) { multiplier = 0.25f; } //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); cadu.Velocity = new sLLVector3(Velocity); AgentPosition agentpos = new AgentPosition(); agentpos.CopyFrom(cadu); m_scene.SendOutChildAgentUpdates(agentpos, this); m_lastChildAgentUpdatePosition = AbsolutePosition; m_lastChildAgentUpdateCamPosition = CameraPosition; } }
/// <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 void ChildAgentPositionUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { // m_log.Warn("[SCENE PRESENCE]: >>> ChildAgentPositionUpdate (" + rRegionX + "," + rRegionY+") at "+cAgentData.Position.ToString()); int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; // m_log.ErrorFormat("[SCENE PRESENCE]: SP.ChildAgentPositionUpdate for R({0},{1}) T({2},{3}) at {4}+{5},{6}+{7},{8}", // rRegionX.ToString(), rRegionY.ToString(), tRegionX.ToString(), tRegionY.ToString(), // cAgentData.Position.X.ToString(), shiftx.ToString(), cAgentData.Position.Y.ToString(), shifty, cAgentData.Position.Z.ToString()); if (!IsChildAgent) { m_log.Error("[SCENE PRESENCE]: ChildAgentPositionUpdate is NOT child agent - refused."); return; } if (IsInTransit) { m_log.Info("[SCENE PRESENCE]: ChildAgentPositionUpdate while in transit - ignored."); return; } if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! { lock (m_posInfo) { if (m_posInfo.Parent != null) { m_log.InfoFormat("[SCENE PRESENCE]: ChildAgentPositionUpdate move to {0} refused for agent already sitting at {1}.", cAgentData.Position.ToString(), cAgentData.Position.ToString()); return; } AbsolutePosition = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); } } // Do this after updating the position! m_DrawDistance = cAgentData.Far; // update the SP draw distance *before* checking culling if (m_sceneView != null && m_sceneView.UseCulling) { //Check for things that may have just entered the draw distance of the user m_sceneView.CheckForDistantEntitiesToShow(); } m_CameraCenter = new Vector3(cAgentData.Center.X + shiftx, cAgentData.Center.Y + shifty, cAgentData.Center.Z); m_avHeight = cAgentData.Size.Z; //SetHeight(cAgentData.AVHeight); if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); }
public void SendChildAgentUpdate() { Vector3 pos = AbsolutePosition; m_LastChildAgentUpdatePosition.X = pos.X; m_LastChildAgentUpdatePosition.Y = pos.Y; m_LastChildAgentUpdatePosition.Z = pos.Z; ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; cadu.AgentID = UUID.Guid; cadu.alwaysrun = m_setAlwaysRun; cadu.AVHeight = m_avHeight; sLLVector3 tempCameraCenter = new sLLVector3(new Vector3(m_CameraCenter.X, m_CameraCenter.Y, m_CameraCenter.Z)); cadu.cameraPosition = tempCameraCenter; cadu.drawdistance = m_DrawDistance; if (!this.IsBot) // bots don't need IsGod checks if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID))) cadu.godlevel = m_godlevel; cadu.GroupAccess = 0; cadu.Position = new sLLVector3(pos); cadu.regionHandle = m_scene.RegionInfo.RegionHandle; float multiplier = CalculateNeighborBandwidthMultiplier(); //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); cadu.Velocity = new sLLVector3(Velocity); AgentPosition agentpos = new AgentPosition(); agentpos.CopyFrom(cadu); m_scene.SendOutChildAgentUpdates(agentpos, this); }
public bool UpdateAgent(GridRegion destination, AgentPosition cAgentData) { if (destination == null) return false; foreach (Scene s in m_sceneList) { if (s.RegionInfo.RegionHandle == destination.RegionHandle) { //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); s.IncomingChildAgentDataUpdate(cAgentData); return true; } } //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return false; }
/// <summary> /// This informs all neighboring regions about the settings of it's child agent. /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// /// </summary> private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, ulong regionHandle) { //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); try { //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); m_interregionCommsOut.SendChildAgentUpdate(regionHandle, cAgentData); } catch { // Ignore; we did our best } //if (regionAccepted) //{ // //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent"); //} //else //{ // //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent"); //} }
public bool UpdateAgent(GridRegion destination, AgentPosition data) { return UpdateAgent(destination, (IAgentData) data); }
public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence) { // This assumes that we know what our neighbors are. try { foreach (ulong regionHandle in presence.KnownChildRegionHandles) { if (regionHandle != m_regionInfo.RegionHandle) { SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; d.BeginInvoke(cAgentData, regionHandle, SendChildAgentDataUpdateCompleted, d); } } } catch (InvalidOperationException) { // We're ignoring a collection was modified error because this data gets old and outdated fast. } }
public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData) { foreach (Scene s in m_sceneList) { if (s.RegionInfo.RegionHandle == regionHandle) { //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); s.IncomingChildAgentDataUpdate(cAgentData); return true; } } //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return false; }
protected OSDMap OnMessageReceived(OSDMap message) { if (!message.ContainsKey("Method")) return null; UUID AgentID = message["AgentID"].AsUUID(); ulong requestingRegion = message["RequestingRegion"].AsULong(); ICapsService capsService = m_registry.RequestModuleInterface<ICapsService>(); if (capsService == null) { //m_log.Info("[AgentProcessing]: Failed OnMessageReceived ICapsService is null"); return new OSDMap(); } IClientCapsService clientCaps = 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 LogOutAllAgentsForRegion(requestingRegion); IGridService GridService = m_registry.RequestModuleInterface<IGridService>(); if (GridService != null) { int x, y; Util.UlongToInts(requestingRegion, out x, out y); GridRegion requestingGridRegion = GridService.GetRegionByPosition(UUID.Zero, x, y); if (requestingGridRegion != null) EnableChildAgentsForRegion(requestingGridRegion); } } else if (message["Method"] == "DisableSimulator") { //KILL IT! if (regionCaps == null || clientCaps == null) return null; IEventQueueService eventQueue = m_registry.RequestModuleInterface<IEventQueueService> (); eventQueue.DisableSimulator (regionCaps.AgentID, regionCaps.RegionHandle); //regionCaps.Close(); //clientCaps.RemoveCAPS(requestingRegion); } 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.UnpackAgentCircuitData((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) { if (regionCaps.RootAgent) { LogoutAgent(regionCaps); } } } else if (message["Method"] == "SendChildAgentUpdate") { if (regionCaps == null || clientCaps == null) return null; IRegionClientCapsService rootCaps = clientCaps.GetRootCapsService (); if (rootCaps != null && rootCaps.RegionHandle == regionCaps.RegionHandle) { OSDMap body = ((OSDMap)message["Message"]); AgentPosition pos = new AgentPosition(); pos.Unpack((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(); int DrawDistance = body["DrawDistance"].AsInteger(); AgentCircuitData Circuit = new AgentCircuitData(); Circuit.UnpackAgentCircuitData((OSDMap)body["Circuit"]); AgentData AgentData = new AgentData(); AgentData.Unpack((OSDMap)body["AgentData"]); regionCaps.Disabled = false; OSDMap result = new OSDMap(); string reason = ""; result["Success"] = TeleportAgent(destination, TeleportFlags, DrawDistance, Circuit, AgentData, AgentID, requestingRegion, out reason); result["Reason"] = reason; return result; } } else if (message["Method"] == "CrossAgent") { if (regionCaps == null || clientCaps == null) return null; if (clientCaps.GetRootCapsService().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.UnpackAgentCircuitData((OSDMap)body["Circuit"]); AgentData AgentData = new AgentData(); AgentData.Unpack((OSDMap)body["AgentData"]); regionCaps.Disabled = false; OSDMap result = new OSDMap(); string reason = ""; result["Success"] = CrossAgent(Region, pos, Vel, Circuit, AgentData, AgentID, requestingRegion, out reason); result["Reason"] = reason; return result; } 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 bool UpdateAgent(GridRegion destination, AgentPosition cAgentData) { if (destination == null) return false; // Try local first if (m_localBackend.IsLocalRegion(destination.RegionID)) return m_localBackend.UpdateAgent(destination, cAgentData); return m_remoteConnector.UpdateAgent(destination, cAgentData); }
public void SendChildAgentUpdate(AgentPosition agentpos, IRegionClientCapsService regionCaps) { Util.FireAndForget(delegate(object o) { SendChildAgentUpdateAsync(agentpos, regionCaps); }); }
/// <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="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(AgentPosition cAgentData) { //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); if (childAgentUpdate != 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 (childAgentUpdate.IsChildAgent) { uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); uint tRegionX = RegionInfo.RegionLocX; uint tRegionY = RegionInfo.RegionLocY; //Send Data to ScenePresence childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); // Not Implemented: //TODO: Do we need to pass the message on to one of our neighbors? } return true; } return false; }
protected 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); } //Also update the service itself regionCaps.LastPosition = agentpos.Position; //Tell all neighbor regions about the new position as well List<GridRegion> ourNeighbors = service.GetNeighbors (regionCaps.Region); foreach (GridRegion region in ourNeighbors) { //Update all the neighbors that we have if (!SimulationService.UpdateAgent(region, agentpos)) { m_log.Info("[AgentProcessing]: Failed to inform " + region.RegionName + " about updating agent. "); } } } } }
/// <summary> /// This informs all neighboring regions about the settings of it's child agent. /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// /// </summary> private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest) { //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); try { m_scene.SimulationService.UpdateAgent(dest, cAgentData); } catch { // Ignore; we did our best } }
public virtual void Update () { if (!IsChildAgent && m_parentID != UUID.Zero) { SceneObjectPart part = (SceneObjectPart)Scene.GetSceneObjectPart (m_parentID); if (part != null) { if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) part.SetPhysActorCameraPos (CameraRotation); else part.SetPhysActorCameraPos (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 (); agentpos.AgentID = UUID; agentpos.AtAxis = CameraAtAxis; agentpos.Center = m_lastChildAgentUpdateCamPosition; agentpos.Far = DrawDistance; agentpos.LeftAxis = CameraLeftAxis; agentpos.Position = m_lastChildAgentUpdatePosition; agentpos.RegionHandle = Scene.RegionInfo.RegionHandle; agentpos.Size = PhysicsActor != null ? PhysicsActor.Size : new Vector3 (0, 0, m_avHeight); agentpos.UpAxis = CameraUpAxis; agentpos.Velocity = Velocity; //Send the child agent data update ISyncMessagePosterService syncPoster = Scene.RequestModuleInterface<ISyncMessagePosterService> (); if (syncPoster != null) syncPoster.Post (SyncMessageHelper.SendChildAgentUpdate (agentpos, m_scene.RegionInfo.RegionHandle), m_scene.RegionInfo.RegionHandle); } else Scene.SceneGraph.TaintPresenceForUpdate(this, PresenceTaint.Other);//We havn't sent the update yet, keep tainting } }
/// <summary> /// Send updated position information about an agent in this region to a neighbor /// This operation may be called very frequently if an avatar is moving about in /// the region. /// </summary> public bool UpdateAgent(GridRegion destination, AgentPosition data) { bool v = true; if (_failedSims.TryGetValue(destination.ServerURI, out v)) return false; // The basic idea of this code is that the first thread that needs to // send an update for a specific avatar becomes the worker for any subsequent // requests until there are no more outstanding requests. Further, only send the most // recent update; this *should* never be needed but some requests get // slowed down and once that happens the problem with service end point // limits kicks in and nothing proceeds string uri = destination.ServerURI + AgentPath() + data.AgentID + "/"; lock (m_updateAgentQueue) { if (m_updateAgentQueue.ContainsKey(uri)) { // Another thread is already handling // updates for this simulator, just update // the position and return, overwrites are // not a problem since we only care about the // last update anyway m_updateAgentQueue[uri] = data; return true; } // Otherwise update the reference and start processing m_updateAgentQueue[uri] = data; } AgentPosition pos = null; bool success = true; while (success) { lock (m_updateAgentQueue) { // save the position AgentPosition lastpos = pos; pos = m_updateAgentQueue[uri]; // this is true if no one put a new // update in the map since the last // one we processed, if thats the // case then we are done if (pos == lastpos) { m_updateAgentQueue.Remove(uri); return true; } } success = UpdateAgent(destination, (IAgentData)pos, 10000); } // we get here iff success == false // blacklist sim for 2 minutes lock (m_updateAgentQueue) { _failedSims.AddOrUpdate(destination.ServerURI, true, 120); m_updateAgentQueue.Remove(uri); } return false; }
/// <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; //m_log.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; m_avHeight = cAgentData.Size.Z; TriggerSignificantClientMovement(); m_savedVelocity = cAgentData.Velocity; }
/// <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 void UpdateChildAgent(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { if (!IsChildAgent) return; RegionHandle = cAgentData.RegionHandle; //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; Vector3 offset = new Vector3(shiftx, shifty, 0f); DrawDistance = cAgentData.Far; if (cAgentData.Position != marker) // UGH!! m_pos = cAgentData.Position + offset; if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) { posLastSignificantMove = AbsolutePosition; ReprioritizeUpdates(); } CameraPosition = cAgentData.Center + offset; if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) { // some scaling factor float x = m_pos.X; if (x > m_scene.RegionInfo.RegionSizeX) x -= m_scene.RegionInfo.RegionSizeX; float y = m_pos.Y; if (y > m_scene.RegionInfo.RegionSizeY) y -= m_scene.RegionInfo.RegionSizeY; x = x * x + y * y; const float distScale = 0.4f / Constants.RegionSize / Constants.RegionSize; float factor = 1.0f - distScale * x; if (factor < 0.2f) factor = 0.2f; ControllingClient.SetChildAgentThrottle(cAgentData.Throttles,factor); } if(cAgentData.ChildrenCapSeeds != null && cAgentData.ChildrenCapSeeds.Count >0) { if (Scene.CapsModule != null) { Scene.CapsModule.SetChildrenSeed(UUID, cAgentData.ChildrenCapSeeds); } KnownRegions = cAgentData.ChildrenCapSeeds; } //cAgentData.AVHeight; //m_velocity = cAgentData.Velocity; }
/// <summary> /// This checks for a significant movement and sends a coarselocationchange update /// </summary> protected void CheckForSignificantMovement() { Vector3 pos = AbsolutePosition; Vector3 diff = pos - posLastMove; if (diff.LengthSquared() > MOVEMENT) { posLastMove = pos; m_scene.EventManager.TriggerOnClientMovement(this); } diff = pos - posLastSignificantMove; if (diff.LengthSquared() > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = pos; m_scene.EventManager.TriggerSignificantClientMovement(this); } // updates priority recalc checkRePrioritization(); if(childUpdatesBusy) return; //possible KnownRegionHandles always contains current region and this check is not needed int minhandles = 0; if(KnownRegionHandles.Contains(RegionHandle)) minhandles++; if(KnownRegionHandles.Count > minhandles) { int tdiff = Util.EnvironmentTickCountSubtract(lastChildUpdatesTime); if(tdiff > CHILDUPDATES_TIME) { diff = pos - m_lastChildAgentUpdatePosition; if (diff.LengthSquared() > CHILDUPDATES_MOVEMENT) { childUpdatesBusy = true; m_lastChildAgentUpdatePosition = pos; // m_lastChildAgentUpdateCamPosition = CameraPosition; AgentPosition agentpos = new AgentPosition(); agentpos.AgentID = new UUID(UUID.Guid); agentpos.SessionID = ControllingClient.SessionId; agentpos.Size = Appearance.AvatarSize; agentpos.Center = CameraPosition; agentpos.Far = DrawDistance; agentpos.Position = AbsolutePosition; agentpos.Velocity = Velocity; agentpos.RegionHandle = RegionHandle; agentpos.Throttles = ControllingClient.GetThrottlesPacked(1); // Let's get this out of the update loop Util.FireAndForget( o => { m_scene.SendOutChildAgentUpdates(agentpos, this); lastChildUpdatesTime = Util.EnvironmentTickCount(); childUpdatesBusy = false; }, null, "ScenePresence.SendOutChildAgentUpdates"); } } } }
protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) { OSDMap args = RegionClient.GetOSDMap((string)request["body"]); if (args == null) { responsedata["int_response_code"] = 400; responsedata["str_response_string"] = "false"; return; } // retrieve the regionhandle ulong regionhandle = 0; if (args.ContainsKey("destination_handle")) UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); string messageType; if (args.ContainsKey("message_type")) messageType = args["message_type"].AsString(); else { m_log.Warn("[REST COMMS]: Agent Put Message Type not found. "); messageType = "AgentData"; } bool result = true; if ("AgentData".Equals(messageType)) { AgentData agent = new AgentData(); try { agent.Unpack(args); } catch (Exception ex) { m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); return; } //agent.Dump(); // This is one of the meanings of PUT agent result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); } else if ("AgentPosition".Equals(messageType)) { AgentPosition agent = new AgentPosition(); try { agent.Unpack(args); } catch (Exception ex) { m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); return; } //agent.Dump(); // This is one of the meanings of PUT agent result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); } responsedata["int_response_code"] = 200; responsedata["str_response_string"] = result.ToString(); }
/// <summary> /// This informs all neighboring regions about the settings of it's child agent. /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// /// </summary> private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, ulong regionHandle) { //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); try { //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); GridRegion destination = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); m_scene.SimulationService.UpdateAgent(destination, cAgentData); } catch { // Ignore; we did our best } //if (regionAccepted) //{ // //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent"); //} //else //{ // //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent"); //} }