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 implementation 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); }
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 (WhiteCore 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; }
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 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; }
/// <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)WhiteCore.Framework.RegionFlags.RegionOnline) == 0 && (neighbor.Flags & (int)(WhiteCore.Framework.RegionFlags.Foreign | WhiteCore.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 WhiteCore 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 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 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 virtual void ChildAgentDataUpdate(AgentData cAgentData) { //MainConsole.Instance.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); //if (!IsChildAgent) // return; CopyFrom(cAgentData); }
public override void FromOSD(OSDMap map) { Destination = new GridRegion(); Destination.FromOSD((OSDMap)map["Destination"]); Update = new AgentData(); Update.FromOSD((OSDMap)map["Update"]); }
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 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 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 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 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 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> /// 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 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 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; }