public AddToPhysicalScene ( bool isFlying ) : void | ||
isFlying | bool | |
리턴 | void |
/// <summary> /// This Closes child agents on neighbouring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// </summary> protected ScenePresence CrossAgentToNewRegionAsync( ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { try { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); Scene m_scene = agent.Scene; if (neighbourRegion != null) { if (!agent.ValidateAttachments()) m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); pos = pos + agent.Velocity; Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); agent.RemoveFromPhysicalScene(); SetInTransit(agent.UUID); AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; // We don't need the callback anymnore cAgent.CallbackURI = String.Empty; if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); ResetFromTransit(agent.UUID); return agent; } //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); agent.ControllingClient.RequestClientInfo(); //m_log.Debug("BEFORE CROSS"); //Scene.DumpChildrenSeeds(UUID); //DumpKnownRegions(); string agentcaps; if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) { m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", neighbourRegion.RegionHandle); return agent; } string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); if (eq != null) { eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, capsPath, agent.UUID, agent.ControllingClient.SessionId); } else { agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, capsPath); } // SUCCESS! agent.MakeChildAgent(); ResetFromTransit(agent.UUID); // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendOtherAgentsAvatarDataToMe(); agent.SendOtherAgentsAppearanceToMe(); // Backwards compatibility. Best effort if (version == "Unknown" || version == string.Empty) { m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); Thread.Sleep(3000); // wait a little now that we're not waiting for the callback CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); } // Next, let's close the child agent connections that are too far away. agent.CloseChildAgents(neighbourx, neighboury); AgentHasMovedAway(agent, false); // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! if (agent.Scene.NeedSceneCacheClear(agent.UUID)) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); } } //m_log.Debug("AFTER CROSS"); //Scene.DumpChildrenSeeds(UUID); //DumpKnownRegions(); } catch (Exception e) { m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); } return agent; }
/// <summary> /// Add a presence to the scene /// </summary> /// <param name="presence"></param> protected internal void AddScenePresence(ScenePresence presence) { bool child = presence.IsChildAgent; if (child) { m_numChildAgents++; } else { m_numRootAgents++; presence.AddToPhysicalScene(false); } Entities[presence.UUID] = presence; lock (m_scenePresences) { if (!m_scenePresences.ContainsKey(presence.UUID)) { m_scenePresences.Add(presence.UUID, presence); // Create a new array of ScenePresence references int oldLength = m_scenePresenceArray.Length; ScenePresence[] newArray = new ScenePresence[oldLength + 1]; Array.Copy(m_scenePresenceArray, newArray, oldLength); newArray[oldLength] = presence; m_scenePresenceArray = newArray; } else { m_scenePresences[presence.UUID] = presence; // Do a linear search through the array of ScenePresence references // and update the modified entry for (int i = 0; i < m_scenePresenceArray.Length; i++) { if (m_scenePresenceArray[i].UUID == presence.UUID) { m_scenePresenceArray[i] = presence; break; } } } } }
public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) { try { AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; // We don't need the callback anymnore cAgent.CallbackURI = String.Empty; // Beyond this point, extra cleanup is needed beyond removing transit state m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", neighbourRegion.RegionName, agent.Name); ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); return false; } } catch (Exception e) { m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. return false; } return true; }
/// <summary> /// Add a presence to the scene /// </summary> /// <param name="presence"></param> protected internal void AddScenePresence(ScenePresence presence) { // Always a child when added to the scene bool child = presence.IsChildAgent; if (child) { m_numChildAgents++; } else { m_numRootAgents++; presence.AddToPhysicalScene(false); } Entities[presence.UUID] = presence; lock (m_presenceLock) { Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); if (!newmap.ContainsKey(presence.UUID)) { newmap.Add(presence.UUID, presence); newlist.Add(presence); } else { // Remember the old presene reference from the dictionary ScenePresence oldref = newmap[presence.UUID]; // Replace the presence reference in the dictionary with the new value newmap[presence.UUID] = presence; // Find the index in the list where the old ref was stored and update the reference newlist[newlist.IndexOf(oldref)] = presence; } // Swap out the dictionary and list with new references m_scenePresenceMap = newmap; m_scenePresenceArray = newlist; } }
/// <summary> /// Add a presence to the scene /// </summary> /// <param name="presence"></param> protected internal void AddScenePresence(ScenePresence presence) { bool child = presence.IsChildAgent; if (child) { Interlocked.Increment(ref m_numChildAgents); } else { Interlocked.Increment(ref m_numRootAgents); presence.AddToPhysicalScene(false); } Entities[presence.LocalId] = presence; lock (ScenePresences) { ScenePresences[presence.UUID] = presence; Monitor.PulseAll(ScenePresences); } }
/// <summary> /// This Closes child agents on neighbouring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// </summary> protected ScenePresence CrossAgentToNewRegionAsync( ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { if (neighbourRegion == null) return agent; if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) { m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName); return agent; } bool transitWasReset = false; try { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); Scene m_scene = agent.Scene; if (!agent.ValidateAttachments()) m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); pos = pos + agent.Velocity; Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); agent.RemoveFromPhysicalScene(); AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; // We don't need the callback anymnore cAgent.CallbackURI = String.Empty; // Beyond this point, extra cleanup is needed beyond removing transit state m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", neighbourRegion.RegionName, agent.Name); ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); return agent; } //m_log.Debug("BEFORE CROSS"); //Scene.DumpChildrenSeeds(UUID); //DumpKnownRegions(); string agentcaps; if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) { m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", neighbourRegion.RegionHandle); return agent; } // No turning back agent.IsChildAgent = true; string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); if (m_eqModule != null) { m_eqModule.CrossRegion( neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, capsPath, agent.UUID, agent.ControllingClient.SessionId); } else { agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, capsPath); } // SUCCESS! m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); agent.MakeChildAgent(); // FIXME: Possibly this should occur lower down after other commands to close other agents, // but not sure yet what the side effects would be. m_entityTransferStateMachine.ResetFromTransit(agent.UUID); transitWasReset = true; // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendOtherAgentsAvatarDataToMe(); agent.SendOtherAgentsAppearanceToMe(); // Backwards compatibility. Best effort if (version == "Unknown" || version == string.Empty) { m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); Thread.Sleep(3000); // wait a little now that we're not waiting for the callback CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); } // Next, let's close the child agent connections that are too far away. agent.CloseChildAgents(neighbourx, neighboury); AgentHasMovedAway(agent, false); //m_log.Debug("AFTER CROSS"); //Scene.DumpChildrenSeeds(UUID); //DumpKnownRegions(); } catch (Exception e) { m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. } finally { if (!transitWasReset) m_entityTransferStateMachine.ResetFromTransit(agent.UUID); } return agent; }
/// <summary> /// Add a presence to the scene /// </summary> /// <param name="presence"></param> protected internal void AddScenePresence(ScenePresence presence) { bool child = presence.IsChildAgent; if (child) { m_numChildAgents++; } else { m_numRootAgents++; presence.AddToPhysicalScene(false); } Entities[presence.UUID] = presence; lock (ScenePresences) { ScenePresences[presence.UUID] = presence; } }