public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); // Reset animations; the viewer does that in teleports. sp.Animator.ResetAnimations(); try { if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", position, sp.Scene.RegionInfo.RegionName); // Teleport within the same region if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, sp.Name, sp.UUID, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = 22; // TODO: Check other Scene HeightField if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) { posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; } float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Teleport(position); foreach (SceneObjectGroup grp in sp.GetAttachments()) { if (grp.IsDeleted) sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } } else // Another region possibly in another simulator { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { GridRegion finalDestination = GetFinalDestination(reg); if (finalDestination == null) { m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); sp.ControllingClient.SendTeleportFailed("Problem at destination"); return; } uint curX = 0, curY = 0; Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); int curCellX = (int)(curX / Constants.RegionSize); int curCellY = (int)(curY / Constants.RegionSize); int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); // // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", // destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); // Check that these are not the same coordinates if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) { // Can't do. Viewer crashes sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); return; } if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) { sp.ControllingClient.SendTeleportFailed( string.Format( "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", finalDestination.RegionName, destCellX, destCellY, sp.Scene.RegionInfo.RegionName, curCellX, curCellY, MaxTransferDistance)); return; } // // This is it // DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); // // // } else { // TP to a place that doesn't exist (anymore) // Inform the viewer about that sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' uint regX, regY; Utils.LongToUInts(regionHandle, out regX, out regY); MapBlockData block = new MapBlockData(); block.X = (ushort)(regX / Constants.RegionSize); block.Y = (ushort)(regY / Constants.RegionSize); block.Access = 254; // == not there List<MapBlockData> blocks = new List<MapBlockData>(); blocks.Add(block); sp.ControllingClient.SendMapBlock(blocks, 0); } } } catch (Exception e) { m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0} {1}", e.Message, e.StackTrace); sp.ControllingClient.SendTeleportFailed("Internal error"); } }
/// <summary> /// Try to teleport an agent to a new region. /// </summary> /// <param name="remoteClient"></param> /// <param name="RegionHandle"></param> /// <param name="position"></param> /// <param name="lookAt"></param> /// <param name="flags"></param> public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) return; bool destRegionUp = true; IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); // Reset animations; the viewer does that in teleports. avatar.Animator.ResetAnimations(); if (regionHandle == m_regionInfo.RegionHandle) { m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", position, m_regionInfo.RegionName); // Teleport within the same region if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, avatar.Name, avatar.UUID, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = 22; // TODO: Check other Scene HeightField if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <=(int)Constants.RegionSize) { posZLimit = (float) avatar.Scene.Heightmap[(int) position.X, (int) position.Y]; } float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } // Only send this if the event queue is null if (eq == null) avatar.ControllingClient.SendTeleportLocationStart(); avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); avatar.Teleport(position); } else { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); GridRegion reg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation to {0} in {1}", position, reg.RegionName); if (eq == null) avatar.ControllingClient.SendTeleportLocationStart(); // Let's do DNS resolution only once in this process, please! // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = reg.ExternalEndPoint; if (endPoint.Address == null) { // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. destRegionUp = false; } if (destRegionUp) { uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (avatar.ParentID != (uint)0) avatar.StandUp(); if (!avatar.ValidateAttachments()) { avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); return; } // the avatar.Close below will clear the child region list. We need this below for (possibly) // closing the child agents, so save it here (we need a copy as it is Clear()-ed). //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // failure at this point (unlike a border crossing failure). So perhaps this can never fail // once we reach here... //avatar.Scene.RemoveCapsHandler(avatar.UUID); string capsPath = String.Empty; AgentCircuitData agentCircuit = avatar.ControllingClient.RequestClientInfo(); agentCircuit.BaseFolder = UUID.Zero; agentCircuit.InventoryFolder = UUID.Zero; agentCircuit.startpos = position; agentCircuit.child = true; if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) { // brand new agent, let's create a new caps seed agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); } string reason = String.Empty; // Let's create an agent there if one doesn't exist yet. //if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agentCircuit)) if (!m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, agentCircuit, teleportFlags, out reason)) { avatar.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", reason)); return; } // OK, it got this agent. Let's close some child agents avatar.CloseChildAgents(newRegionX, newRegionY); if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) { #region IP Translation for NAT IClientIPEndpoint ipepClient; if (avatar.ClientView.TryGet(out ipepClient)) { capsPath = "http://" + NetworkUtil.GetHostFor(ipepClient.EndPoint, reg.ExternalHostName) + ":" + reg.HttpPort + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } else { capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } #endregion if (eq != null) { #region IP Translation for NAT // Uses ipepClient above if (avatar.ClientView.TryGet(out ipepClient)) { endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); } #endregion eq.EnableSimulator(reg.RegionHandle, endPoint, avatar.UUID); // ES makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait Thread.Sleep(2000); eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath); } else { avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint); } } else { agentCircuit.CapsPath = avatar.Scene.CapsModule.GetChildSeed(avatar.UUID, reg.RegionHandle); capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + agentCircuit.CapsPath + "0000/"; } // Expect avatar crossing is a heavy-duty function at the destination. // That is where MakeRoot is called, which fetches appearance and inventory. // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, // position, false); //{ // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); // // We should close that agent we just created over at destination... // List<ulong> lst = new List<ulong>(); // lst.Add(reg.RegionHandle); // SendCloseChildAgentAsync(avatar.UUID, lst); // return; //} SetInTransit(avatar.UUID); // Let's send a full update of the agent. This is a synchronous call. AgentData agent = new AgentData(); avatar.CopyTo(agent); agent.Position = position; agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort + "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); m_log.DebugFormat( "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); if (eq != null) { eq.TeleportFinishEvent(reg.RegionHandle, 13, endPoint, 0, teleportFlags, capsPath, avatar.UUID); } else { avatar.ControllingClient.SendRegionTeleport(reg.RegionHandle, 13, endPoint, 4, teleportFlags, capsPath); } // 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. if (!WaitForCallback(avatar.UUID)) { // Client never contacted destination. Let's restore everything back avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination."); ResetFromTransit(avatar.UUID); // Yikes! We should just have a ref to scene here. avatar.Scene.InformClientOfNeighbours(avatar); // Finally, kill the agent we just created at the destination. m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID); return; } // Can't go back from here if (KiPrimitive != null) { KiPrimitive(avatar.LocalId); } avatar.MakeChildAgent(); // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) { Thread.Sleep(5000); avatar.Close(); CloseConnection(avatar.UUID); } else // now we have a child agent in this region. avatar.Reset(); // if (teleport success) // seems to be always success here // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) { m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: User {0} is going to another region, profile cache removed", avatar.UUID); } } else { avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); } } else { // TP to a place that doesn't exist (anymore) // Inform the viewer about that avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' uint regX, regY; Utils.LongToUInts(regionHandle, out regX, out regY); MapBlockData block = new MapBlockData(); block.X = (ushort)(regX / Constants.RegionSize); block.Y = (ushort)(regY / Constants.RegionSize); block.Access = 254; // == not there List<MapBlockData> blocks = new List<MapBlockData>(); blocks.Add(block); avatar.ControllingClient.SendMapBlock(blocks, 0); } } }
/// <summary> /// Teleports the agent within its current region. /// </summary> /// <param name="sp"></param> /// <param name="position"></param> /// <param name="lookAt"></param> /// <param name="teleportFlags"></param> private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, sp.Scene.RegionInfo.RegionName); // Teleport within the same region if (!sp.Scene.PositionIsInCurrentRegion(position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2} in {3}. Substituting {4}", position, sp.Name, sp.UUID, Scene.Name, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = 22; // TODO: Check other Scene HeightField posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } if (sp.Flying) teleportFlags |= (uint)TeleportFlags.IsFlying; m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; sp.Velocity = Vector3.Zero; sp.Teleport(position); m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); foreach (SceneObjectGroup grp in sp.GetAttachments()) { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); }
public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); // Reset animations; the viewer does that in teleports. sp.Animator.ResetAnimations(); try { if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", position, sp.Scene.RegionInfo.RegionName); // Teleport within the same region if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, sp.Name, sp.UUID, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = 22; // TODO: Check other Scene HeightField if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) { posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; } float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } // Only send this if the event queue is null if (eq == null) sp.ControllingClient.SendTeleportLocationStart(); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Teleport(position); } else // Another region possibly in another simulator { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { GridRegion finalDestination = GetFinalDestination(reg); if (finalDestination == null) { m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); sp.ControllingClient.SendTeleportFailed("Problem at destination"); return; } m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID); // // This is it // DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); // // // } else { // TP to a place that doesn't exist (anymore) // Inform the viewer about that sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' uint regX, regY; Utils.LongToUInts(regionHandle, out regX, out regY); MapBlockData block = new MapBlockData(); block.X = (ushort)(regX / Constants.RegionSize); block.Y = (ushort)(regY / Constants.RegionSize); block.Access = 254; // == not there List<MapBlockData> blocks = new List<MapBlockData>(); blocks.Add(block); sp.ControllingClient.SendMapBlock(blocks, 0); } } } catch (Exception e) { m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); sp.ControllingClient.SendTeleportFailed("Internal error"); } }
public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) { if (m_scene.RegionInfo.RegionID == regionID) { ILandObject parcelAvatarIsEntering = GetLandObject(localLandID); if (parcelAvatarIsEntering != null) { //Tell the clint about it parcelAvatarIsEntering.SendLandUpdateToClient(avatar.ControllingClient); if (UseDwell) parcelAvatarIsEntering.LandData.Dwell += 1; if (avatar.AbsolutePosition.Z < ParcelManagementModule.BAN_LINE_SAFETY_HEIGHT) { if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) { SendYouAreBannedNotice(avatar); Vector3 pos = GetNearestAllowedPosition(avatar); avatar.Teleport(pos); } else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) { SendYouAreRestrictedNotice(avatar); Vector3 pos = GetNearestAllowedPosition(avatar); avatar.Teleport(pos); } } } } }
public void EventManagerOnClientMovement(ScenePresence avatar) //Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance. { ILandObject over = GetLandObject((int)avatar.AbsolutePosition.X, (int)avatar.AbsolutePosition.Y); if (over != null) { if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HEIGHT)) { avatar.lastKnownAllowedPosition = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); } else { //Kick them out Vector3? pos = landChannel.GetNearestAllowedPosition(avatar); if (pos.HasValue) avatar.Teleport(pos.Value); } } }
public virtual void Teleport(ScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { string reason = ""; sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendTeleportProgress(teleportFlags, "requesting"); // Reset animations; the viewer does that in teleports. if(sp.Animator != null) sp.Animator.ResetAnimations(); try { long XShift = (finalDestination.RegionLocX - sp.Scene.RegionInfo.RegionLocX); long YShift = (finalDestination.RegionLocY - sp.Scene.RegionInfo.RegionLocY); if (finalDestination.RegionHandle == sp.Scene.RegionInfo.RegionHandle || //Take region size into account as well (XShift < sp.Scene.RegionInfo.RegionSizeX && YShift < sp.Scene.RegionInfo.RegionSizeY && XShift > 0 && YShift > 0 && //Can't have negatively sized regions sp.Scene.RegionInfo.RegionSizeX != int.MaxValue && sp.Scene.RegionInfo.RegionSizeY != int.MaxValue)) { //First check whether the user is allowed to move at all if (!sp.Scene.Permissions.AllowedOutgoingLocalTeleport(sp.UUID, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } //Now respect things like parcel bans with this if (!sp.Scene.Permissions.AllowedIncomingTeleport(sp.UUID, position, out position, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", position, sp.Scene.RegionInfo.RegionName); //We have to add the shift as it is brought into this as well in regions that have larger RegionSizes position.X += XShift; position.Y += YShift; //Keep users from being underground ITerrainChannel channel = sp.Scene.RequestModuleInterface<ITerrainChannel>(); float groundHeight = channel.GetNormalizedGroundHeight(position.X, position.Y); if (position.Z < groundHeight) { position.Z = groundHeight; } sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Teleport(position); } else // Another region possibly in another simulator { // Make sure the user is allowed to leave this region if (!sp.Scene.Permissions.AllowedOutgoingRemoteTeleport(sp.UUID, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } //m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", // finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID); // Check that these are not the same coordinates if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) { // Can't do. Viewer crashes sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); return; } // // This is it // DoTeleport(sp, finalDestination, position, lookAt, teleportFlags); // // // } } catch (Exception e) { m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); sp.ControllingClient.SendTeleportFailed("Internal error"); } }
public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) { if (m_scene.RegionInfo.RegionID == regionID) { ILandObject parcelAvatarIsEntering = landChannel.GetLandObject(localLandID); if (parcelAvatarIsEntering != null) { if (UseDwell) parcelAvatarIsEntering.LandData.Dwell += 1; if (AllowedForcefulBans) { if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HEIGHT) { if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) { SendYouAreBannedNotice(avatar); Vector3? pos = landChannel.GetNearestAllowedPosition(avatar); if (pos.HasValue) avatar.Teleport(pos.Value); } else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) { SendYouAreRestrictedNotice(avatar); Vector3? pos = landChannel.GetNearestAllowedPosition(avatar); if (pos.HasValue) avatar.Teleport(pos.Value); } } } } } }
public void RemoveAvatarFromParcel(ScenePresence avatar) { EntityBase.PositionInfo posInfo = avatar.GetPosInfo(); if (posInfo.Parent != null) { // can't find the prim seated on, stand up avatar.StandUp(null, false, true); // fall through to unseated avatar code. } // If they are moving, stop them. This updates the physics object as well. avatar.Velocity = Vector3.Zero; Vector3 pos = avatar.AbsolutePosition; // may have changed from posInfo by StandUp above. ParcelPropertiesStatus reason2; if (!avatar.lastKnownAllowedPosition.Equals(Vector3.Zero)) { pos = avatar.lastKnownAllowedPosition; } else { // Still a forbidden parcel, they must have been above the limit or entering region for the first time. // Let's put them up higher, over the restricted parcel. // We could add 50m to avatar.Scene.Heightmap[x,y] but then we need subscript checks, etc. // For now, this is simple and safer than TPing them home. pos.Z += 50.0f; } ILandObject parcel = landChannel.GetLandObject(pos.X, pos.Y); if ((parcel != null) && parcel.DenyParcelAccess(avatar.UUID, out reason2)) { float minZ = LandChannel.BAN_LINE_SAFETY_HEIGHT + AVATAR_BOUNCE; if (pos.Z < minZ) pos.Z = minZ; } // Now force the non-sitting avatar to a position above the parcel avatar.Teleport(pos); // this is really just a move }
public bool SendNoEntryNotice(ScenePresence avatar, ParcelPropertiesStatus reason) { if (!AllowedForcefulBans) { avatar.ControllingClient.SendAlertMessage( "You are not allowed on this parcel, however the grid administrator has disabled ban lines globally. Please respect the land owner's privacy, or you could be banned from the full region."); return false; } if (reason == ParcelPropertiesStatus.CollisionBanned) avatar.ControllingClient.SendAlertMessage( "You are not permitted to enter this parcel because you are banned."); else avatar.ControllingClient.SendAlertMessage( "You are not permitted to enter this parcel due to parcel restrictions."); // If they are moving, stop them. This updates the physics object as well. avatar.Velocity = Vector3.Zero; Vector3 pos; ParcelPropertiesStatus reason2; if (!avatar.lastKnownAllowedPosition.Equals(Vector3.Zero)) { pos = new Vector3(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y, avatar.lastKnownAllowedPosition.Z); } else { // Still a forbidden parcel, they must have been above the limit or entering region for the first time. pos = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); // Let's put them up higher, over the restricted parcel. // We could add 50m to avatar.Scene.Heightmap[x,y] but then we need subscript checks, etc. // For now, this is simple and safer than TPing them home. pos.Z += 50.0f; } ILandObject parcel = landChannel.GetLandObject(pos.X, pos.Y); if (parcel.DenyParcelAccess(avatar.UUID, out reason2)) { // Havent found anywhere safe to put the avatar, TP them home. // avatar.ControllingClient.SendTeleportLocationStart(); // avatar.Scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); // return true; if (pos.Z < 150.0f) pos.Z = 150.0f; } avatar.Teleport(pos); return true; }
public void Teleport(ScenePresence botPresence, Vector3 pos) { botPresence.StandUp(null, false, true); botPresence.Teleport(pos); }
/// <summary> /// Teleports the agent within its current region. /// </summary> /// <param name="sp"></param> /// <param name="position"></param> /// <param name="lookAt"></param> /// <param name="teleportFlags"></param private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, sp.Scene.RegionInfo.RegionName); if (!SetInTransit(sp.UUID)) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", sp.Name, sp.UUID, position); return; } // Teleport within the same region if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, sp.Name, sp.UUID, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = 22; // TODO: Check other Scene HeightField if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) { posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; } float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } UpdateInTransit(sp.UUID, AgentTransferState.Transferring); sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Velocity = Vector3.Zero; sp.Teleport(position); UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); foreach (SceneObjectGroup grp in sp.GetAttachments()) { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); ResetFromTransit(sp.UUID); }
// Bounce constants are how far above a no-entry parcel we'll place an object or avatar. public void RemoveAvatarFromParcel(ScenePresence avatar) { EntityBase.PositionInfo posInfo = avatar.GetPosInfo(); if (posInfo.Parent != null) { // can't find the prim seated on, stand up avatar.StandUp(false, true); // fall through to unseated avatar code. } // If they are moving, stop them. This updates the physics object as well. // The avatar needs to be stopped before entering the parcel otherwise there // are timing windows where the avatar can just pound away at the parcel border // and get across it due to physics placing them there. avatar.Velocity = Vector3.Zero; Vector3 pos = avatar.AbsolutePosition; // may have changed from posInfo by StandUp above. ParcelPropertiesStatus reason2; if (!avatar.lastKnownAllowedPosition.Equals(Vector3.Zero)) { pos = avatar.lastKnownAllowedPosition; } ILandObject parcel = landChannel.GetLandObject(pos.X, pos.Y); float minZ; if ((parcel != null) && m_scene.TestBelowHeightLimit(avatar.UUID, pos, parcel, out minZ, out reason2)) { float groundZ = (float)m_scene.Heightmap.CalculateHeightAt(pos.X, pos.Y); minZ += groundZ; // make them bounce above the banned parcel if being removed if (pos.Z < minZ) pos.Z = minZ + Constants.AVATAR_BOUNCE; } // Now force the non-sitting avatar to a position above the parcel avatar.Teleport(pos); // this is really just a move }