diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 242 |
1 files changed, 235 insertions, 7 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1eb3117..87a753e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Diagnostics; | ||
30 | using System.Drawing; | 31 | using System.Drawing; |
31 | using System.Drawing.Imaging; | 32 | using System.Drawing.Imaging; |
32 | using System.IO; | 33 | using System.IO; |
@@ -1975,7 +1976,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1975 | public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) | 1976 | public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) |
1976 | { | 1977 | { |
1977 | return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); | 1978 | return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
1978 | } | 1979 | } |
1979 | 1980 | ||
1980 | /// <summary> | 1981 | /// <summary> |
1981 | /// Delete every object from the scene | 1982 | /// Delete every object from the scene |
@@ -2643,7 +2644,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2643 | public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) | 2644 | public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) |
2644 | { | 2645 | { |
2645 | client.OnRezSingleAttachmentFromInv += RezSingleAttachment; | 2646 | client.OnRezSingleAttachmentFromInv += RezSingleAttachment; |
2646 | client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; | 2647 | client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; |
2647 | client.OnObjectAttach += m_sceneGraph.AttachObject; | 2648 | client.OnObjectAttach += m_sceneGraph.AttachObject; |
2648 | client.OnObjectDetach += m_sceneGraph.DetachObject; | 2649 | client.OnObjectDetach += m_sceneGraph.DetachObject; |
2649 | 2650 | ||
@@ -2695,7 +2696,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2695 | } | 2696 | } |
2696 | 2697 | ||
2697 | protected virtual void UnsubscribeToClientEvents(IClientAPI client) | 2698 | protected virtual void UnsubscribeToClientEvents(IClientAPI client) |
2698 | { | 2699 | { |
2699 | } | 2700 | } |
2700 | 2701 | ||
2701 | /// <summary> | 2702 | /// <summary> |
@@ -2796,13 +2797,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2796 | } | 2797 | } |
2797 | 2798 | ||
2798 | public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) | 2799 | public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) |
2799 | { | 2800 | { |
2800 | client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; | 2801 | client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; |
2801 | client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; | 2802 | client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; |
2802 | client.OnObjectAttach -= m_sceneGraph.AttachObject; | 2803 | client.OnObjectAttach -= m_sceneGraph.AttachObject; |
2803 | client.OnObjectDetach -= m_sceneGraph.DetachObject; | 2804 | client.OnObjectDetach -= m_sceneGraph.DetachObject; |
2804 | 2805 | ||
2805 | if (AttachmentsModule != null) | 2806 | if (AttachmentsModule != null) |
2806 | client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory; | 2807 | client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory; |
2807 | } | 2808 | } |
2808 | 2809 | ||
@@ -3224,6 +3225,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3224 | /// also return a reason.</returns> | 3225 | /// also return a reason.</returns> |
3225 | public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason) | 3226 | public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason) |
3226 | { | 3227 | { |
3228 | TeleportFlags tp = (TeleportFlags)teleportFlags; | ||
3227 | //Teleport flags: | 3229 | //Teleport flags: |
3228 | // | 3230 | // |
3229 | // TeleportFlags.ViaGodlikeLure - Border Crossing | 3231 | // TeleportFlags.ViaGodlikeLure - Border Crossing |
@@ -3257,6 +3259,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3257 | 3259 | ||
3258 | CapsModule.NewUserConnection(agent); | 3260 | CapsModule.NewUserConnection(agent); |
3259 | 3261 | ||
3262 | ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); | ||
3263 | |||
3264 | //On login or border crossing test land permisions | ||
3265 | if (tp != TeleportFlags.Default) | ||
3266 | { | ||
3267 | if (land != null && !TestLandRestrictions(agent, land, out reason)) | ||
3268 | { | ||
3269 | return false; | ||
3270 | } | ||
3271 | } | ||
3272 | |||
3260 | ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); | 3273 | ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); |
3261 | if (sp != null) | 3274 | if (sp != null) |
3262 | { | 3275 | { |
@@ -3329,7 +3342,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3329 | } | 3342 | } |
3330 | } | 3343 | } |
3331 | // Honor parcel landing type and position. | 3344 | // Honor parcel landing type and position. |
3332 | ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); | ||
3333 | if (land != null) | 3345 | if (land != null) |
3334 | { | 3346 | { |
3335 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) | 3347 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) |
@@ -3345,6 +3357,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
3345 | return true; | 3357 | return true; |
3346 | } | 3358 | } |
3347 | 3359 | ||
3360 | private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) | ||
3361 | { | ||
3362 | |||
3363 | bool banned = land.IsBannedFromLand(agent.AgentID); | ||
3364 | bool restricted = land.IsRestrictedFromLand(agent.AgentID); | ||
3365 | |||
3366 | if (banned || restricted) | ||
3367 | { | ||
3368 | ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); | ||
3369 | if (nearestParcel != null) | ||
3370 | { | ||
3371 | //Move agent to nearest allowed | ||
3372 | Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); | ||
3373 | agent.startpos.X = newPosition.X; | ||
3374 | agent.startpos.Y = newPosition.Y; | ||
3375 | } | ||
3376 | else | ||
3377 | { | ||
3378 | if (banned) | ||
3379 | { | ||
3380 | reason = "Cannot regioncross into banned parcel."; | ||
3381 | } | ||
3382 | else | ||
3383 | { | ||
3384 | reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", | ||
3385 | RegionInfo.RegionName); | ||
3386 | } | ||
3387 | return false; | ||
3388 | } | ||
3389 | } | ||
3390 | reason = ""; | ||
3391 | return true; | ||
3392 | } | ||
3393 | |||
3348 | /// <summary> | 3394 | /// <summary> |
3349 | /// Verifies that the user has a presence on the Grid | 3395 | /// Verifies that the user has a presence on the Grid |
3350 | /// </summary> | 3396 | /// </summary> |
@@ -3476,6 +3522,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
3476 | return true; | 3522 | return true; |
3477 | } | 3523 | } |
3478 | 3524 | ||
3525 | private ILandObject GetParcelAtPoint(float x, float y) | ||
3526 | { | ||
3527 | foreach (var parcel in AllParcels()) | ||
3528 | { | ||
3529 | if (parcel.ContainsPoint((int)x,(int)y)) | ||
3530 | { | ||
3531 | return parcel; | ||
3532 | } | ||
3533 | } | ||
3534 | return null; | ||
3535 | } | ||
3536 | |||
3479 | /// <summary> | 3537 | /// <summary> |
3480 | /// Update an AgentCircuitData object with new information | 3538 | /// Update an AgentCircuitData object with new information |
3481 | /// </summary> | 3539 | /// </summary> |
@@ -4748,5 +4806,175 @@ namespace OpenSim.Region.Framework.Scenes | |||
4748 | { | 4806 | { |
4749 | get { return m_allowScriptCrossings; } | 4807 | get { return m_allowScriptCrossings; } |
4750 | } | 4808 | } |
4809 | |||
4810 | public Vector3? GetNearestAllowedPosition(ScenePresence avatar) | ||
4811 | { | ||
4812 | //simulate to make sure we have pretty up to date positions | ||
4813 | PhysicsScene.Simulate(0); | ||
4814 | |||
4815 | ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | ||
4816 | |||
4817 | if (nearestParcel != null) | ||
4818 | { | ||
4819 | Vector3 dir = Vector3.Normalize(Vector3.Multiply(avatar.Velocity, -1)); | ||
4820 | //Try to get a location that feels like where they came from | ||
4821 | Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); | ||
4822 | if (nearestPoint != null) | ||
4823 | { | ||
4824 | Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString()); | ||
4825 | return nearestPoint.Value; | ||
4826 | } | ||
4827 | |||
4828 | //Sometimes velocity might be zero (local teleport), so try finding point along path from avatar to center of nearest parcel | ||
4829 | Vector3 directionToParcelCenter = Vector3.Subtract(GetParcelCenterAtGround(nearestParcel), avatar.AbsolutePosition); | ||
4830 | dir = Vector3.Normalize(directionToParcelCenter); | ||
4831 | nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); | ||
4832 | if (nearestPoint != null) | ||
4833 | { | ||
4834 | Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString()); | ||
4835 | return nearestPoint.Value; | ||
4836 | } | ||
4837 | |||
4838 | //Ultimate backup if we have no idea where they are | ||
4839 | Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString()); | ||
4840 | return avatar.lastKnownAllowedPosition; | ||
4841 | |||
4842 | } | ||
4843 | |||
4844 | //Go to the edge, this happens in teleporting to a region with no available parcels | ||
4845 | Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); | ||
4846 | //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); | ||
4847 | return nearestRegionEdgePoint; | ||
4848 | return null; | ||
4849 | } | ||
4850 | |||
4851 | private Vector3 GetParcelCenterAtGround(ILandObject parcel) | ||
4852 | { | ||
4853 | Vector2 center = GetParcelCenter(parcel); | ||
4854 | return GetPositionAtGround(center.X, center.Y); | ||
4855 | } | ||
4856 | |||
4857 | private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel) | ||
4858 | { | ||
4859 | Vector3 unitDirection = Vector3.Normalize(direction); | ||
4860 | //Making distance to search go through some sane limit of distance | ||
4861 | for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f) | ||
4862 | { | ||
4863 | Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance)); | ||
4864 | if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y)) | ||
4865 | { | ||
4866 | return testPos; | ||
4867 | } | ||
4868 | } | ||
4869 | return null; | ||
4870 | } | ||
4871 | |||
4872 | public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y) | ||
4873 | { | ||
4874 | List<ILandObject> all = AllParcels(); | ||
4875 | float minParcelDistance = float.MaxValue; | ||
4876 | ILandObject nearestParcel = null; | ||
4877 | |||
4878 | foreach (var parcel in all) | ||
4879 | { | ||
4880 | if (!parcel.IsEitherBannedOrRestricted(avatarId)) | ||
4881 | { | ||
4882 | float parcelDistance = GetParcelDistancefromPoint(parcel, x, y); | ||
4883 | if (parcelDistance < minParcelDistance) | ||
4884 | { | ||
4885 | minParcelDistance = parcelDistance; | ||
4886 | nearestParcel = parcel; | ||
4887 | } | ||
4888 | } | ||
4889 | } | ||
4890 | |||
4891 | return nearestParcel; | ||
4892 | } | ||
4893 | |||
4894 | private List<ILandObject> AllParcels() | ||
4895 | { | ||
4896 | return LandChannel.AllParcels(); | ||
4897 | } | ||
4898 | |||
4899 | private float GetParcelDistancefromPoint(ILandObject parcel, float x, float y) | ||
4900 | { | ||
4901 | return Vector2.Distance(new Vector2(x, y), GetParcelCenter(parcel)); | ||
4902 | } | ||
4903 | |||
4904 | //calculate the average center point of a parcel | ||
4905 | private Vector2 GetParcelCenter(ILandObject parcel) | ||
4906 | { | ||
4907 | int count = 0; | ||
4908 | int avgx = 0; | ||
4909 | int avgy = 0; | ||
4910 | for (int x = 0; x < Constants.RegionSize; x++) | ||
4911 | { | ||
4912 | for (int y = 0; y < Constants.RegionSize; y++) | ||
4913 | { | ||
4914 | //Just keep a running average as we check if all the points are inside or not | ||
4915 | if (parcel.ContainsPoint(x, y)) | ||
4916 | { | ||
4917 | if (count == 0) | ||
4918 | { | ||
4919 | avgx = x; | ||
4920 | avgy = y; | ||
4921 | } | ||
4922 | else | ||
4923 | { | ||
4924 | avgx = (avgx * count + x) / (count + 1); | ||
4925 | avgy = (avgy * count + y) / (count + 1); | ||
4926 | } | ||
4927 | count += 1; | ||
4928 | } | ||
4929 | } | ||
4930 | } | ||
4931 | return new Vector2(avgx, avgy); | ||
4932 | } | ||
4933 | |||
4934 | private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar) | ||
4935 | { | ||
4936 | float xdistance = avatar.AbsolutePosition.X < Constants.RegionSize / 2 ? avatar.AbsolutePosition.X : Constants.RegionSize - avatar.AbsolutePosition.X; | ||
4937 | float ydistance = avatar.AbsolutePosition.Y < Constants.RegionSize / 2 ? avatar.AbsolutePosition.Y : Constants.RegionSize - avatar.AbsolutePosition.Y; | ||
4938 | |||
4939 | //find out what vertical edge to go to | ||
4940 | if (xdistance < ydistance) | ||
4941 | { | ||
4942 | if (avatar.AbsolutePosition.X < Constants.RegionSize / 2) | ||
4943 | { | ||
4944 | return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y); | ||
4945 | } | ||
4946 | else | ||
4947 | { | ||
4948 | return GetPositionAtAvatarHeightOrGroundHeight(avatar, Constants.RegionSize, avatar.AbsolutePosition.Y); | ||
4949 | } | ||
4950 | } | ||
4951 | //find out what horizontal edge to go to | ||
4952 | else | ||
4953 | { | ||
4954 | if (avatar.AbsolutePosition.Y < Constants.RegionSize / 2) | ||
4955 | { | ||
4956 | return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f); | ||
4957 | } | ||
4958 | else | ||
4959 | { | ||
4960 | return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, Constants.RegionSize); | ||
4961 | } | ||
4962 | } | ||
4963 | } | ||
4964 | |||
4965 | private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y) | ||
4966 | { | ||
4967 | Vector3 ground = GetPositionAtGround(x, y); | ||
4968 | if (avatar.AbsolutePosition.Z > ground.Z) | ||
4969 | { | ||
4970 | ground.Z = avatar.AbsolutePosition.Z; | ||
4971 | } | ||
4972 | return ground; | ||
4973 | } | ||
4974 | |||
4975 | private Vector3 GetPositionAtGround(float x, float y) | ||
4976 | { | ||
4977 | return new Vector3(x, y, GetGroundHeight(x, y)); | ||
4978 | } | ||
4751 | } | 4979 | } |
4752 | } | 4980 | } |