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.cs230
-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, 11 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 7b435f5..2dec72d 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 e2986d9..9cb2172 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 c4f2016..a427dd3 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 0c268bf..4f6f709 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 2e59457..a9b5c2b 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;
@@ -4893,7 +4894,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4893 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 4894 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
4894 lastarg = arg; // save this set of arguments for nexttime 4895 lastarg = arg; // save this set of arguments for nexttime
4895 if (handlerAgentUpdate != null) 4896 if (handlerAgentUpdate != null)
4897 {
4898 OnPreAgentUpdate(this, arg);
4896 OnAgentUpdate(this, arg); 4899 OnAgentUpdate(this, arg);
4900 }
4897 4901
4898 handlerAgentUpdate = null; 4902 handlerAgentUpdate = null;
4899 } 4903 }
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index f0c87f4..38f371a 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;
@@ -84,6 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Land
84 85
85 // caches ExtendedLandData 86 // caches ExtendedLandData
86 private Cache parcelInfoCache; 87 private Cache parcelInfoCache;
88 private Vector3? forcedPosition = null;
87 89
88 #region INonSharedRegionModule Members 90 #region INonSharedRegionModule Members
89 91
@@ -136,6 +138,13 @@ namespace OpenSim.Region.CoreModules.World.Land
136 { 138 {
137 } 139 }
138 140
141 private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
142 {
143 ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
144 reason = "You are not allowed to enter this sim.";
145 return nearestParcel != null;
146 }
147
139 void EventManagerOnNewClient(IClientAPI client) 148 void EventManagerOnNewClient(IClientAPI client)
140 { 149 {
141 //Register some client events 150 //Register some client events
@@ -153,6 +162,7 @@ namespace OpenSim.Region.CoreModules.World.Land
153 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 162 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
154 client.OnParcelDwellRequest += ClientOnParcelDwellRequest; 163 client.OnParcelDwellRequest += ClientOnParcelDwellRequest;
155 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 164 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
165 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
156 166
157 EntityBase presenceEntity; 167 EntityBase presenceEntity;
158 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 168 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
@@ -162,6 +172,40 @@ namespace OpenSim.Region.CoreModules.World.Land
162 } 172 }
163 } 173 }
164 174
175 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
176 {
177 //If we are forcing a position for them to go
178 if( forcedPosition != null )
179 {
180 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
181
182 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
183 //When the avatar walks into a ban line on the ground, it prevents getting stuck
184 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
185
186
187 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
188 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) < .2)
189 {
190 Debug.WriteLine(string.Format("Stopping force position because {0} is close enough to position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition));
191 forcedPosition = null;
192 }
193 //if we are far away, teleport
194 else if(Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3 )
195 {
196 Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition));
197 clientAvatar.Teleport(forcedPosition.Value);
198 forcedPosition = null;
199 }
200 else
201 {
202 //Forces them toward the forced position we want if they aren't there yet
203 agentData.UseClientAgentPosition = true;
204 agentData.ClientAgentPosition = forcedPosition.Value;
205 }
206 }
207 }
208
165 209
166 public void PostInitialise() 210 public void PostInitialise()
167 { 211 {
@@ -267,9 +311,6 @@ namespace OpenSim.Region.CoreModules.World.Land
267 { 311 {
268 avatar.ControllingClient.SendAlertMessage( 312 avatar.ControllingClient.SendAlertMessage(
269 "You are not allowed on this parcel because you are banned. Please go away."); 313 "You are not allowed on this parcel because you are banned. Please go away.");
270
271 avatar.PhysicsActor.Position = avatar.lastKnownAllowedPosition;
272 avatar.PhysicsActor.Velocity = Vector3.Zero;
273 } 314 }
274 else 315 else
275 { 316 {
@@ -278,6 +319,24 @@ namespace OpenSim.Region.CoreModules.World.Land
278 } 319 }
279 } 320 }
280 321
322
323
324 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
325 {
326 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
327 if (position.HasValue)
328 {
329 forcedPosition = position;
330 }
331 }
332
333 public void SendYouAreRestrictedNotice(ScenePresence avatar)
334 {
335 avatar.ControllingClient.SendAlertMessage(
336 "You are not allowed on this parcel because the land owner has restricted access.");
337
338 }
339
281 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) 340 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
282 { 341 {
283 if (m_scene.RegionInfo.RegionID == regionID) 342 if (m_scene.RegionInfo.RegionID == regionID)
@@ -295,11 +354,12 @@ namespace OpenSim.Region.CoreModules.World.Land
295 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) 354 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
296 { 355 {
297 SendYouAreBannedNotice(avatar); 356 SendYouAreBannedNotice(avatar);
357 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
298 } 358 }
299 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) 359 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
300 { 360 {
301 avatar.ControllingClient.SendAlertMessage( 361 SendYouAreRestrictedNotice(avatar);
302 "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!)."); 362 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
303 } 363 }
304 else 364 else
305 { 365 {
@@ -400,7 +460,26 @@ namespace OpenSim.Region.CoreModules.World.Land
400 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && 460 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
401 parcel.IsBannedFromLand(clientAvatar.UUID)) 461 parcel.IsBannedFromLand(clientAvatar.UUID))
402 { 462 {
403 SendYouAreBannedNotice(clientAvatar); 463 //once we've sent the message once, keep going toward the target until we are done
464 if (forcedPosition == null)
465 {
466 SendYouAreBannedNotice(clientAvatar);
467 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
468 }
469 }
470 else if ( parcel.IsRestrictedFromLand(clientAvatar.UUID))
471 {
472 //once we've sent the message once, keep going toward the target until we are done
473 if (forcedPosition == null)
474 {
475 SendYouAreRestrictedNotice(clientAvatar);
476 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
477 }
478 }
479 else
480 {
481 //when we are finally in a safe place, lets release the forced position lock
482 forcedPosition = null;
404 } 483 }
405 } 484 }
406 } 485 }
@@ -412,7 +491,7 @@ namespace OpenSim.Region.CoreModules.World.Land
412 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 491 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
413 if (over != null) 492 if (over != null)
414 { 493 {
415 if (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT) 494 if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT))
416 { 495 {
417 avatar.lastKnownAllowedPosition = 496 avatar.lastKnownAllowedPosition =
418 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); 497 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 7fdddc3..d052f38 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 1eb3117..311821a 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;
@@ -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}
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index f2253f2..1885946 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 65445d9..77958eb 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 7b46e95..5fff279 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;