aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs1
-rw-r--r--OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs1
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs1
-rw-r--r--OpenSim/Framework/IClientAPI.cs1
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs93
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs9
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs229
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs1
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs1
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs1
12 files changed, 333 insertions, 10 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 7b9faa9..f8cfe44 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -598,6 +598,7 @@ namespace OpenSim.Client.MXP.ClientStack
598 public event Action<IClientAPI> OnRegionHandShakeReply; 598 public event Action<IClientAPI> OnRegionHandShakeReply;
599 public event GenericCall2 OnRequestWearables; 599 public event GenericCall2 OnRequestWearables;
600 public event GenericCall1 OnCompleteMovementToRegion; 600 public event GenericCall1 OnCompleteMovementToRegion;
601 public event UpdateAgent OnPreAgentUpdate;
601 public event UpdateAgent OnAgentUpdate; 602 public event UpdateAgent OnAgentUpdate;
602 public event AgentRequestSit OnAgentRequestSit; 603 public event AgentRequestSit OnAgentRequestSit;
603 public event AgentSit OnAgentSit; 604 public event AgentSit OnAgentSit;
diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs
index b7ead6e..3bf73d6 100644
--- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs
+++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs
@@ -244,6 +244,7 @@ namespace OpenSim.Client.Sirikata.ClientStack
244 public event Action<IClientAPI> OnRegionHandShakeReply; 244 public event Action<IClientAPI> OnRegionHandShakeReply;
245 public event GenericCall2 OnRequestWearables; 245 public event GenericCall2 OnRequestWearables;
246 public event GenericCall1 OnCompleteMovementToRegion; 246 public event GenericCall1 OnCompleteMovementToRegion;
247 public event UpdateAgent OnPreAgentUpdate;
247 public event UpdateAgent OnAgentUpdate; 248 public event UpdateAgent OnAgentUpdate;
248 public event AgentRequestSit OnAgentRequestSit; 249 public event AgentRequestSit OnAgentRequestSit;
249 public event AgentSit OnAgentSit; 250 public event AgentSit OnAgentSit;
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index d51277b..894fdac 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -247,6 +247,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
247 public event Action<IClientAPI> OnRegionHandShakeReply = delegate { }; 247 public event Action<IClientAPI> OnRegionHandShakeReply = delegate { };
248 public event GenericCall2 OnRequestWearables = delegate { }; 248 public event GenericCall2 OnRequestWearables = delegate { };
249 public event GenericCall1 OnCompleteMovementToRegion = delegate { }; 249 public event GenericCall1 OnCompleteMovementToRegion = delegate { };
250 public event UpdateAgent OnPreAgentUpdate;
250 public event UpdateAgent OnAgentUpdate = delegate { }; 251 public event UpdateAgent OnAgentUpdate = delegate { };
251 public event AgentRequestSit OnAgentRequestSit = delegate { }; 252 public event AgentRequestSit OnAgentRequestSit = delegate { };
252 public event AgentSit OnAgentSit = delegate { }; 253 public event AgentSit OnAgentSit = delegate { };
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 7219bf8..3126e57 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -881,6 +881,7 @@ namespace OpenSim.Framework
881 event Action<IClientAPI> OnRegionHandShakeReply; 881 event Action<IClientAPI> OnRegionHandShakeReply;
882 event GenericCall2 OnRequestWearables; 882 event GenericCall2 OnRequestWearables;
883 event GenericCall1 OnCompleteMovementToRegion; 883 event GenericCall1 OnCompleteMovementToRegion;
884 event UpdateAgent OnPreAgentUpdate;
884 event UpdateAgent OnAgentUpdate; 885 event UpdateAgent OnAgentUpdate;
885 event AgentRequestSit OnAgentRequestSit; 886 event AgentRequestSit OnAgentRequestSit;
886 event AgentSit OnAgentSit; 887 event AgentSit OnAgentSit;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 2c8d88b..ea73abb 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
127 public event ObjectDeselect OnObjectDetach; 127 public event ObjectDeselect OnObjectDetach;
128 public event ObjectDrop OnObjectDrop; 128 public event ObjectDrop OnObjectDrop;
129 public event GenericCall1 OnCompleteMovementToRegion; 129 public event GenericCall1 OnCompleteMovementToRegion;
130 public event UpdateAgent OnPreAgentUpdate;
130 public event UpdateAgent OnAgentUpdate; 131 public event UpdateAgent OnAgentUpdate;
131 public event AgentRequestSit OnAgentRequestSit; 132 public event AgentRequestSit OnAgentRequestSit;
132 public event AgentSit OnAgentSit; 133 public event AgentSit OnAgentSit;
@@ -4880,7 +4881,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4880 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 4881 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
4881 lastarg = arg; // save this set of arguments for nexttime 4882 lastarg = arg; // save this set of arguments for nexttime
4882 if (handlerAgentUpdate != null) 4883 if (handlerAgentUpdate != null)
4884 {
4885 OnPreAgentUpdate(this, arg);
4883 OnAgentUpdate(this, arg); 4886 OnAgentUpdate(this, arg);
4887 }
4884 4888
4885 handlerAgentUpdate = null; 4889 handlerAgentUpdate = null;
4886 } 4890 }
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 8c3d17d..e0cdb36 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics;
31using System.Reflection; 32using System.Reflection;
32using log4net; 33using log4net;
33using Nini.Config; 34using Nini.Config;
@@ -86,6 +87,7 @@ namespace OpenSim.Region.CoreModules.World.Land
86 87
87 // caches ExtendedLandData 88 // caches ExtendedLandData
88 private Cache parcelInfoCache; 89 private Cache parcelInfoCache;
90 private Vector3? forcedPosition = null;
89 91
90 #region INonSharedRegionModule Members 92 #region INonSharedRegionModule Members
91 93
@@ -144,6 +146,13 @@ namespace OpenSim.Region.CoreModules.World.Land
144 { 146 {
145 } 147 }
146 148
149 private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
150 {
151 ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
152 reason = "You are not allowed to enter this sim.";
153 return nearestParcel != null;
154 }
155
147 void EventManagerOnNewClient(IClientAPI client) 156 void EventManagerOnNewClient(IClientAPI client)
148 { 157 {
149 //Register some client events 158 //Register some client events
@@ -161,6 +170,7 @@ namespace OpenSim.Region.CoreModules.World.Land
161 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 170 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
162 client.OnParcelDwellRequest += ClientOnParcelDwellRequest; 171 client.OnParcelDwellRequest += ClientOnParcelDwellRequest;
163 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 172 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
173 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
164 174
165 EntityBase presenceEntity; 175 EntityBase presenceEntity;
166 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 176 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
@@ -170,6 +180,40 @@ namespace OpenSim.Region.CoreModules.World.Land
170 } 180 }
171 } 181 }
172 182
183 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
184 {
185 //If we are forcing a position for them to go
186 if( forcedPosition != null )
187 {
188 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
189
190 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
191 //When the avatar walks into a ban line on the ground, it prevents getting stuck
192 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
193
194
195 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
196 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) < .2)
197 {
198 Debug.WriteLine(string.Format("Stopping force position because {0} is close enough to position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition));
199 forcedPosition = null;
200 }
201 //if we are far away, teleport
202 else if(Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3 )
203 {
204 Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition));
205 clientAvatar.Teleport(forcedPosition.Value);
206 forcedPosition = null;
207 }
208 else
209 {
210 //Forces them toward the forced position we want if they aren't there yet
211 agentData.UseClientAgentPosition = true;
212 agentData.ClientAgentPosition = forcedPosition.Value;
213 }
214 }
215 }
216
173 217
174 public void PostInitialise() 218 public void PostInitialise()
175 { 219 {
@@ -275,9 +319,6 @@ namespace OpenSim.Region.CoreModules.World.Land
275 { 319 {
276 avatar.ControllingClient.SendAlertMessage( 320 avatar.ControllingClient.SendAlertMessage(
277 "You are not allowed on this parcel because you are banned. Please go away."); 321 "You are not allowed on this parcel because you are banned. Please go away.");
278
279 avatar.PhysicsActor.Position = avatar.lastKnownAllowedPosition;
280 avatar.PhysicsActor.Velocity = Vector3.Zero;
281 } 322 }
282 else 323 else
283 { 324 {
@@ -286,6 +327,24 @@ namespace OpenSim.Region.CoreModules.World.Land
286 } 327 }
287 } 328 }
288 329
330
331
332 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
333 {
334 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
335 if (position.HasValue)
336 {
337 forcedPosition = position;
338 }
339 }
340
341 public void SendYouAreRestrictedNotice(ScenePresence avatar)
342 {
343 avatar.ControllingClient.SendAlertMessage(
344 "You are not allowed on this parcel because the land owner has restricted access.");
345
346 }
347
289 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) 348 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
290 { 349 {
291 if (m_scene.RegionInfo.RegionID == regionID) 350 if (m_scene.RegionInfo.RegionID == regionID)
@@ -303,11 +362,12 @@ namespace OpenSim.Region.CoreModules.World.Land
303 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) 362 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
304 { 363 {
305 SendYouAreBannedNotice(avatar); 364 SendYouAreBannedNotice(avatar);
365 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
306 } 366 }
307 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) 367 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
308 { 368 {
309 avatar.ControllingClient.SendAlertMessage( 369 SendYouAreRestrictedNotice(avatar);
310 "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!)."); 370 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
311 } 371 }
312 else 372 else
313 { 373 {
@@ -408,7 +468,26 @@ namespace OpenSim.Region.CoreModules.World.Land
408 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && 468 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
409 parcel.IsBannedFromLand(clientAvatar.UUID)) 469 parcel.IsBannedFromLand(clientAvatar.UUID))
410 { 470 {
411 SendYouAreBannedNotice(clientAvatar); 471 //once we've sent the message once, keep going toward the target until we are done
472 if (forcedPosition == null)
473 {
474 SendYouAreBannedNotice(clientAvatar);
475 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
476 }
477 }
478 else if ( parcel.IsRestrictedFromLand(clientAvatar.UUID))
479 {
480 //once we've sent the message once, keep going toward the target until we are done
481 if (forcedPosition == null)
482 {
483 SendYouAreRestrictedNotice(clientAvatar);
484 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
485 }
486 }
487 else
488 {
489 //when we are finally in a safe place, lets release the forced position lock
490 forcedPosition = null;
412 } 491 }
413 } 492 }
414 } 493 }
@@ -420,7 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Land
420 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 499 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
421 if (over != null) 500 if (over != null)
422 { 501 {
423 if (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT) 502 if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT))
424 { 503 {
425 avatar.lastKnownAllowedPosition = 504 avatar.lastKnownAllowedPosition =
426 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); 505 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 1fa8630..27d9fdb 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.World.Land
104 /// <returns>Returns true if the piece of land contains the specified point</returns> 104 /// <returns>Returns true if the piece of land contains the specified point</returns>
105 public bool ContainsPoint(int x, int y) 105 public bool ContainsPoint(int x, int y)
106 { 106 {
107 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) 107 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize)
108 { 108 {
109 return (LandBitmap[x / 4, y / 4] == true); 109 return (LandBitmap[x / 4, y / 4] == true);
110 } 110 }
@@ -286,7 +286,8 @@ namespace OpenSim.Region.CoreModules.World.Land
286 entry.AgentID = avatar; 286 entry.AgentID = avatar;
287 entry.Flags = AccessList.Ban; 287 entry.Flags = AccessList.Ban;
288 entry.Time = new DateTime(); 288 entry.Time = new DateTime();
289 if (LandData.ParcelAccessList.Contains(entry)) 289 //See if they are on the list, but make sure the owner isn't banned
290 if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar )
290 { 291 {
291 //They are banned, so lets send them a notice about this parcel 292 //They are banned, so lets send them a notice about this parcel
292 return true; 293 return true;
@@ -303,7 +304,9 @@ namespace OpenSim.Region.CoreModules.World.Land
303 entry.AgentID = avatar; 304 entry.AgentID = avatar;
304 entry.Flags = AccessList.Access; 305 entry.Flags = AccessList.Access;
305 entry.Time = new DateTime(); 306 entry.Time = new DateTime();
306 if (!LandData.ParcelAccessList.Contains(entry)) 307
308 //If they are not on the access list and are not the owner
309 if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar)
307 { 310 {
308 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel 311 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
309 return true; 312 return true;
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 58e3de9..c2753d9 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -84,6 +84,7 @@ namespace OpenSim.Region.Examples.SimpleModule
84 public event Action<IClientAPI> OnRegionHandShakeReply; 84 public event Action<IClientAPI> OnRegionHandShakeReply;
85 public event GenericCall2 OnRequestWearables; 85 public event GenericCall2 OnRequestWearables;
86 public event GenericCall1 OnCompleteMovementToRegion; 86 public event GenericCall1 OnCompleteMovementToRegion;
87 public event UpdateAgent OnPreAgentUpdate;
87 public event UpdateAgent OnAgentUpdate; 88 public event UpdateAgent OnAgentUpdate;
88 public event AgentRequestSit OnAgentRequestSit; 89 public event AgentRequestSit OnAgentRequestSit;
89 public event AgentSit OnAgentSit; 90 public event AgentSit OnAgentSit;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 388bc99..884f13a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.Drawing; 31using System.Drawing;
31using System.Drawing.Imaging; 32using System.Drawing.Imaging;
32using System.IO; 33using System.IO;
@@ -3251,6 +3252,7 @@ namespace OpenSim.Region.Framework.Scenes
3251 /// also return a reason.</returns> 3252 /// also return a reason.</returns>
3252 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason) 3253 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason)
3253 { 3254 {
3255 TeleportFlags tp = (TeleportFlags)teleportFlags;
3254 //Teleport flags: 3256 //Teleport flags:
3255 // 3257 //
3256 // TeleportFlags.ViaGodlikeLure - Border Crossing 3258 // TeleportFlags.ViaGodlikeLure - Border Crossing
@@ -3284,6 +3286,17 @@ namespace OpenSim.Region.Framework.Scenes
3284 3286
3285 CapsModule.NewUserConnection(agent); 3287 CapsModule.NewUserConnection(agent);
3286 3288
3289 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3290
3291 //On login or border crossing test land permisions
3292 if (tp != TeleportFlags.Default)
3293 {
3294 if (land != null && !TestLandRestrictions(agent, land, out reason))
3295 {
3296 return false;
3297 }
3298 }
3299
3287 ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); 3300 ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
3288 if (sp != null) 3301 if (sp != null)
3289 { 3302 {
@@ -3377,6 +3390,40 @@ namespace OpenSim.Region.Framework.Scenes
3377 return true; 3390 return true;
3378 } 3391 }
3379 3392
3393 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason)
3394 {
3395
3396 bool banned = land.IsBannedFromLand(agent.AgentID);
3397 bool restricted = land.IsRestrictedFromLand(agent.AgentID);
3398
3399 if (banned || restricted)
3400 {
3401 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y);
3402 if (nearestParcel != null)
3403 {
3404 //Move agent to nearest allowed
3405 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3406 agent.startpos.X = newPosition.X;
3407 agent.startpos.Y = newPosition.Y;
3408 }
3409 else
3410 {
3411 if (banned)
3412 {
3413 reason = "Cannot regioncross into banned parcel.";
3414 }
3415 else
3416 {
3417 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
3418 RegionInfo.RegionName);
3419 }
3420 return false;
3421 }
3422 }
3423 reason = "";
3424 return true;
3425 }
3426
3380 /// <summary> 3427 /// <summary>
3381 /// Verifies that the user has a presence on the Grid 3428 /// Verifies that the user has a presence on the Grid
3382 /// </summary> 3429 /// </summary>
@@ -3508,6 +3555,18 @@ namespace OpenSim.Region.Framework.Scenes
3508 return true; 3555 return true;
3509 } 3556 }
3510 3557
3558 private ILandObject GetParcelAtPoint(float x, float y)
3559 {
3560 foreach (var parcel in AllParcels())
3561 {
3562 if( parcel.ContainsPoint((int)x,(int)y))
3563 {
3564 return parcel;
3565 }
3566 }
3567 return null;
3568 }
3569
3511 /// <summary> 3570 /// <summary>
3512 /// Update an AgentCircuitData object with new information 3571 /// Update an AgentCircuitData object with new information
3513 /// </summary> 3572 /// </summary>
@@ -4780,5 +4839,175 @@ namespace OpenSim.Region.Framework.Scenes
4780 { 4839 {
4781 get { return m_allowScriptCrossings; } 4840 get { return m_allowScriptCrossings; }
4782 } 4841 }
4842
4843 public Vector3? GetNearestAllowedPosition(ScenePresence avatar)
4844 {
4845 //simulate to make sure we have pretty up to date positions
4846 PhysicsScene.Simulate(0);
4847
4848 ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
4849
4850 if (nearestParcel != null)
4851 {
4852 Vector3 dir = Vector3.Normalize(Vector3.Multiply(avatar.Velocity, -1));
4853 //Try to get a location that feels like where they came from
4854 Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
4855 if (nearestPoint != null)
4856 {
4857 Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString());
4858 return nearestPoint.Value;
4859 }
4860
4861 //Sometimes velocity might be zero (local teleport), so try finding point along path from avatar to center of nearest parcel
4862 Vector3 directionToParcelCenter = Vector3.Subtract(GetParcelCenterAtGround(nearestParcel), avatar.AbsolutePosition);
4863 dir = Vector3.Normalize(directionToParcelCenter);
4864 nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
4865 if (nearestPoint != null)
4866 {
4867 Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString());
4868 return nearestPoint.Value;
4869 }
4870
4871 //Ultimate backup if we have no idea where they are
4872 Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString());
4873 return avatar.lastKnownAllowedPosition;
4874
4875 }
4876
4877 //Go to the edge, this happens in teleporting to a region with no available parcels
4878 Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar);
4879 //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString());
4880 return nearestRegionEdgePoint;
4881 return null;
4882 }
4883
4884 private Vector3 GetParcelCenterAtGround(ILandObject parcel)
4885 {
4886 Vector2 center = GetParcelCenter(parcel);
4887 return GetPositionAtGround(center.X, center.Y);
4888 }
4889
4890 private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel)
4891 {
4892 Vector3 unitDirection = Vector3.Normalize(direction);
4893 //Making distance to search go through some sane limit of distance
4894 for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f)
4895 {
4896 Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance));
4897 if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y))
4898 {
4899 return testPos;
4900 }
4901 }
4902 return null;
4903 }
4904
4905 public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y)
4906 {
4907 List<ILandObject> all = AllParcels();
4908 float minParcelDistance = float.MaxValue;
4909 ILandObject nearestParcel = null;
4910
4911 foreach (var parcel in all)
4912 {
4913 if (!parcel.IsEitherBannedOrRestricted(avatarId))
4914 {
4915 float parcelDistance = GetParcelDistancefromPoint(parcel, x, y);
4916 if (parcelDistance < minParcelDistance)
4917 {
4918 minParcelDistance = parcelDistance;
4919 nearestParcel = parcel;
4920 }
4921 }
4922 }
4923
4924 return nearestParcel;
4925 }
4926
4927 private List<ILandObject> AllParcels()
4928 {
4929 return LandChannel.AllParcels();
4930 }
4931
4932 private float GetParcelDistancefromPoint(ILandObject parcel, float x, float y)
4933 {
4934 return Vector2.Distance(new Vector2(x, y), GetParcelCenter(parcel));
4935 }
4936
4937 //calculate the average center point of a parcel
4938 private Vector2 GetParcelCenter(ILandObject parcel)
4939 {
4940 int count = 0;
4941 int avgx = 0;
4942 int avgy = 0;
4943 for (int x = 0; x < Constants.RegionSize; x++)
4944 {
4945 for (int y = 0; y < Constants.RegionSize; y++)
4946 {
4947 //Just keep a running average as we check if all the points are inside or not
4948 if (parcel.ContainsPoint(x, y))
4949 {
4950 if (count == 0)
4951 {
4952 avgx = x;
4953 avgy = y;
4954 }
4955 else
4956 {
4957 avgx = (avgx * count + x) / (count + 1);
4958 avgy = (avgy * count + y) / (count + 1);
4959 }
4960 count += 1;
4961 }
4962 }
4963 }
4964 return new Vector2(avgx, avgy);
4965 }
4966
4967 private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)
4968 {
4969 float xdistance = avatar.AbsolutePosition.X < Constants.RegionSize / 2 ? avatar.AbsolutePosition.X : Constants.RegionSize - avatar.AbsolutePosition.X;
4970 float ydistance = avatar.AbsolutePosition.Y < Constants.RegionSize / 2 ? avatar.AbsolutePosition.Y : Constants.RegionSize - avatar.AbsolutePosition.Y;
4971
4972 //find out what vertical edge to go to
4973 if (xdistance < ydistance)
4974 {
4975 if (avatar.AbsolutePosition.X < Constants.RegionSize / 2)
4976 {
4977 return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y);
4978 }
4979 else
4980 {
4981 return GetPositionAtAvatarHeightOrGroundHeight(avatar, Constants.RegionSize, avatar.AbsolutePosition.Y);
4982 }
4983 }
4984 //find out what horizontal edge to go to
4985 else
4986 {
4987 if (avatar.AbsolutePosition.Y < Constants.RegionSize / 2)
4988 {
4989 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f);
4990 }
4991 else
4992 {
4993 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, Constants.RegionSize);
4994 }
4995 }
4996 }
4997
4998 private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y)
4999 {
5000 Vector3 ground = GetPositionAtGround(x, y);
5001 if( avatar.AbsolutePosition.Z > ground.Z)
5002 {
5003 ground.Z = avatar.AbsolutePosition.Z;
5004 }
5005 return ground;
5006 }
5007
5008 private Vector3 GetPositionAtGround(float x, float y)
5009 {
5010 return new Vector3(x, y, GetGroundHeight(x, y));
5011 }
4783 } 5012 }
4784} 5013}
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 99e5b84..711052c 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -680,6 +680,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
680 public event Action<IClientAPI> OnRegionHandShakeReply; 680 public event Action<IClientAPI> OnRegionHandShakeReply;
681 public event GenericCall2 OnRequestWearables; 681 public event GenericCall2 OnRequestWearables;
682 public event GenericCall1 OnCompleteMovementToRegion; 682 public event GenericCall1 OnCompleteMovementToRegion;
683 public event UpdateAgent OnPreAgentUpdate;
683 public event UpdateAgent OnAgentUpdate; 684 public event UpdateAgent OnAgentUpdate;
684 public event AgentRequestSit OnAgentRequestSit; 685 public event AgentRequestSit OnAgentRequestSit;
685 public event AgentSit OnAgentSit; 686 public event AgentSit OnAgentSit;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 15473d8..ebf9333 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -190,6 +190,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
190 public event Action<IClientAPI> OnRegionHandShakeReply; 190 public event Action<IClientAPI> OnRegionHandShakeReply;
191 public event GenericCall2 OnRequestWearables; 191 public event GenericCall2 OnRequestWearables;
192 public event GenericCall1 OnCompleteMovementToRegion; 192 public event GenericCall1 OnCompleteMovementToRegion;
193 public event UpdateAgent OnPreAgentUpdate;
193 public event UpdateAgent OnAgentUpdate; 194 public event UpdateAgent OnAgentUpdate;
194 public event AgentRequestSit OnAgentRequestSit; 195 public event AgentRequestSit OnAgentRequestSit;
195 public event AgentSit OnAgentSit; 196 public event AgentSit OnAgentSit;
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 0d9dcc6..715e1a4 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -96,6 +96,7 @@ namespace OpenSim.Tests.Common.Mock
96 public event Action<IClientAPI> OnRegionHandShakeReply; 96 public event Action<IClientAPI> OnRegionHandShakeReply;
97 public event GenericCall2 OnRequestWearables; 97 public event GenericCall2 OnRequestWearables;
98 public event GenericCall1 OnCompleteMovementToRegion; 98 public event GenericCall1 OnCompleteMovementToRegion;
99 public event UpdateAgent OnPreAgentUpdate;
99 public event UpdateAgent OnAgentUpdate; 100 public event UpdateAgent OnAgentUpdate;
100 public event AgentRequestSit OnAgentRequestSit; 101 public event AgentRequestSit OnAgentRequestSit;
101 public event AgentSit OnAgentSit; 102 public event AgentSit OnAgentSit;